Skip to content
EvalBook

Remediation

How a proposal is dispatched to CodeBook as a card, how progress and outcomes come back, and what EvalBook does and does not do while a fix is attempted.

Remediation is the attempt to fix what a proposal describes. EvalBook does not attempt it. It dispatches the proposal to a linked CodeBook workspace, where a card is worked within the proposal's bound, and it records what CodeBook reports back. EvalBook never runs customer code outside the separately installed, outbound-only runner, and it never authorizes a change; the fix is CodeBook's work, under whatever governance that workspace is linked to.

Status (25 October 2026). The improvement component is an empty shell in the application today (one model, no routes, no pages); requirements EV-041 to EV-044, EV-046 and EV-047 are not started in the requirements ledger. This page describes the contract the component is being built to, and nothing on it is available yet.

Dispatch

The integrations component serves the call:

codebook.dispatchImprovement(ctx, { proposal, workspaceLink, principalSub }) → { card, duplicate }

It posts the proposal body to {codebook}/workspace/api/peer/improvements on an active link, acting for the person with proposal.dispatch (sub), with the idempotency key evalbook:proposal:<id>. Every peer call carries the shared peer secret, X-Peer-App: evalbook and an HMAC-SHA256 signature over the raw body. CodeBook answers { data: true, card: { id, url }, duplicate }; a refusal is a non-2xx answer with a code, never a silent success.

An answer that was lost after the request was sent is outcome_unknown. It is reconciled by sending the same bytes again under the same key: CodeBook answers the one card it made, and duplicate: true says so. The capability register lists codebook.improvements.dispatch as verified_standin with assurance platform_enforced: tested against a fake CodeBook that answers as CodeBook's code does, including the duplicate card, the refusal codes and the unknown-outcome reconciliation, and not yet against the real product. See the capability register and CodeBook.

What CodeBook enforces

On its side CodeBook makes one card per proposal id in the named workflow's first station, records the protected paths as a refusal list that every repository-writing tool checks before anything reaches the host (a refused write is recorded on the run), and enforces the bound through its run limits: at most max_attempts runs, the deadline, the budget. An unpriced model counts as unmeasured, not as free. If the CodeBook workspace is linked to MadeBook, the card's runs are governed sessions there; EvalBook is not party to that decision. CodeBook's description is at https://codebook.work/docs/integrations/linked-products.

Progress coming back

CodeBook reports to {evalbook}/project/api/peer/events as improvement.updated, keyed improvement.updated:<card id>:<revision>, with body { link, proposal_id, card_id, card_url, revision, state, pull_request? }. The states are queued, in_progress, in_review, blocked, done, dropped and reopened; pull_request carries { number, head_sha, url } when there is one. A higher revision supersedes a lower one; an older revision arriving late is recorded and ignored.

The receiver is EvalBook's inbox: every inbound event is keyed by source app and idempotency key with a payload digest, so a replay is acknowledged once and the same key with a different body is a recorded conflict, never a second effect. An event for a link that has ended is acknowledged and ignored. The capability register lists codebook.improvement_updated.receive as in_progress, owned by the improvement component, with no evidence yet; until the handler exists the inbox records the event and the improvement component applies nothing.

Verifying the fix

A card's pull request is a candidate like any other. If the station it passes through requires an EvalBook suite, CodeBook asks EvalBook to evaluate that exact commit under the suite's active version, waits for the report, fetches it by id, recomputes its digest and decides from it; a pass needs every required check passed with complete evidence, and anything else blocks a required evaluator. That path is described under release gates and reports. The proposal's source_report_ids and the new report give the before and after of the same suite on the same repository.

What became of it

Progress is not outcome. CodeBook's outcome.observed events (merged, reverted, reopened, deployed, production issue, override, retraction) are the proposed way outcomes reach EvalBook's impact component, where a proposal is a work unit evalbook:proposal:<id> and done is self-declared, not accepted. That event is a proposed amendment to the peer protocol; CodeBook does not send it yet, and nothing is inferred in the meantime.

Who may do what

proposal.dispatch, held by the release admin, sends a proposal; proposal.write alone does not. Dispatch needs an active CodeBook link, which a project admin manages with link.manage. See roles and access and peer links.