An approved context packet can now accompany a work order and its independent review. Every host uses the same evidence renderer and authorization checks. The calling host remains the orchestrator; a context provider gains no builder, reviewer, tracker-write, or merge authority. Ordinary sessions without context keep their existing behavior and do not load the optional Coworker SDK.
Start with a verified private connection. The guided
path below fetches once for the work item and retains the opaque packet handle;
the lower-level workflow can still fetch it explicitly. Every delivery verifies
authorization online; it does not repeat the search.
Only Claude, Codex, and Devin orchestrator, builder, and reviewer roles are
supported for private delivery in this release. Each role must be explicitly
approved in the private connection configuration as <host>:<role>; a
connection without devin:* recipients never delivers to Devin.
For the normal workflow, bind the work item when starting the session and let Code Mower carry the private identity into retrieval and work-order creation:
code-mower session start --repo OWNER/REPO --host codex --work-item EXAMPLE-123
code-mower session context prepare .code-mower/sessions/SESSION.json
code-mower session context deliver .code-mower/sessions/SESSION.jsonUse --host claude when Claude starts the session. The selected host is the
implicit orchestrator. It is also the default builder; prepare --builder NAME
selects another configured builder for a handoff. The work order names review
lanes selected for the session while excluding the builder, so a builder's own
review cannot satisfy the peer-review requirement. No optional reviewer is
added unless it was selected for the session.
The prepare command uses the selected work-item identity as its bounded private query by default. For a more specific query, use private stdin:
cat /private/path/query.txt | code-mower session context prepare \
.code-mower/sessions/SESSION.json --query-stdinThe query is hashed for retry consistency and is not saved or rendered. The
command performs the existing online authorization and packet fetch, writes a
local context-aware work order, and records its opaque references in protected
session state. Repeating it reauthorizes the packet without repeating the
search. Use --refresh only to retry a failed/interrupted search or intentionally
replace changed retrieval input. Refreshes and builder handoffs create a new
generated work-order path so local edits to the previous work order are not
overwritten. The lower-level commands below remain useful for expert scripting
and diagnostics.
session context deliver derives the repository, work item, connection, policy,
packet, and selected builder from protected state. It writes the private
evidence to stdout for the builder's prompt; keep that output out of tracked
files and public logs. The selected builder must be Claude, Codex, or Devin in
this release.
work-order draft --context-packet HANDLE adds the opaque identity and a delivery
instruction to the existing work-order format. It adds no source text, account
binding, or new cloud telemetry fields.
Before a PR exists, the approved builder or orchestrator can receive the packet:
code-mower context deliver --packet HANDLE --connection example-context \
--recipient codex:builder --request-stdin < /private/path/delivery-request.jsonThe private JSON request has exactly repository, work_item, and policy.
Use the same scope and policy as the original fetch. Evidence is written to
stdout for the approved participant's prompt. Keep it out of public terminal
logs, tracked files, PR descriptions, and shared artifacts.
A trusted hosted work order can carry the packet to devin:builder without a
local prompt file. The trusted context decision is part of the work order:
WorkOrder.context_policy is none, optional, or required, comes from
dispatcher policy, and is included in the durable binding. A context-bearing
order also carries the trusted WorkOrder.context_work_item: the tracker-neutral
identity from the session or manifest context binding (a Jira key, for example),
which may differ from the integer GitHub delivery issue WorkOrder.issue. Only
the integer issue closes and verifies the pull request; only the work item binds
the packet. When a key is supplied the prepared source may omit issue_number,
though a present one must still match. Context-free orders carry no key, and
their serialized binding is unchanged.
The embedding binds one packet with devin_work_orders.packet_context(store, name, handle, policy, order=order), which validates the handle and the trusted
policy (its required flag must agree with the order) and returns a
PacketContext holding only the protected store, connection name, packet
handle, normalized policy, and backend. It carries no packet, evidence, callable,
or identity of its own: the request is derived from the order it is used with.
That value is passed as context= to dispatch, clarify, or fix.
Immediately before each paid create or message write, and never in preview, the
work-order boundary itself calls load_authorized() with the order's repository,
work item, and devin:builder: a new online authorization under the store lock
for the selected account, current authorization, revocation and expiry, then the
packet's own binding, freshness, and recipients. The evidence is rendered inside
that boundary from the exact packet the authorized load returned, under the
exact authorized packet handle as its Packet identity, the same identity the
Claude and Codex peer paths render; no separately supplied packet or evidence is
ever accepted, and a synthetic local packet with matching binding fields never
reaches the store lookup. A handle for another ticket, a packet without the
recipient, or a store without an authorizable connection is unavailable; a
bare handle, packet, string, look-alike object, store subclass, or any context
on a none order fails as context_binding_mismatch. Rendering and the 64 KiB
combined-size check (context_budget_exceeded) happen before the work-order
record, branch reservation, or a new round is written, so a rejected input
leaves no undispatched reservation and consumes no round. Evidence text is
appended only to the provider input; records keep only digests plus the safe
state enum, and status, collect, and cancel reject a context argument.
A required order fails closed when no packet is supplied or it cannot be
reauthorized (wrong account, revoked or expired authorization, refreshed or
invalidated packet). run then returns, rather than raises, the issue's closed
outcome: {"outcome": "UNKNOWN", "state": "paused", "reason": "context_unavailable", "context": {"policy": "required", "dispatch" | "message": "unavailable"}, "merge_authority": false}; nothing was reserved, persisted, or
sent, and an already dispatched order keeps its prior round and state. Only an
optional order degrades to a code-only input (degraded) or runs without a
packet (omitted).
The complete intended input, including the evidence and its safe state, is
digested before the local dispatch or message intent becomes durable, and the
remote session's input fingerprint covers the same text. A retry after a stop
between the two writes must regenerate the identical input; changed, refreshed,
or dropped evidence fails as request_conflict and the saved state keeps
reporting what was actually intended. The state chosen for the create input and
for each message intent is persisted and reported by every command as
context: {policy, dispatch, message}; replay, acknowledgement, status, and
collect return the saved state rather than recomputing it. Durable records
written before the context field existed keep their original binding and
dispatch input: a none order serializes without context_policy or
context_work_item, and records without context or input digests are read as
context-free.
After creating the PR, attach the packet to its current code head without a request file or copied packet handle:
code-mower session context attach .code-mower/sessions/SESSION.json --pr 42The guided command derives every private input from the session. It verifies the live session lease, trusted-base control authority, current PR head, packet, and online authorization before publishing. Repeating it on the same current head and input succeeds without another comment or revision. A changed code head gets a new saved intent and requires a new review.
The session saves its random revision before the first GitHub write. If a
process stops after GitHub accepted the comment, rerunning attach reconciles
that exact revision from the trusted current comment. If a write returns an
uncertain result and the revision is not current, status pauses the workflow;
after independently checking the PR, attach --retry-uncertain republishes the
same revision rather than creating another one. No uncertain or unpublished
binding can deliver evidence. A saved uncertain or pending intent is never
cleared just because a later attach was asked for: it may already be the
GitHub-accepted state a lost response only looked like it missed.
Before attempting a fresh reservation, the session first saves a durable
reserving marker -- proof that no GitHub write has happened yet, because
publication only ever follows a reservation that has itself already become
durable. If that reservation then fails within the same attach call -- for
example because the actual consuming checkout has moved past the evidence it
was prepared from, or the local graph was rebuilt in the meantime -- the same
call rolls the session back to its prior prepared, unattached state inline,
keeping the failure reason visible in status. If the process instead stops
before that same-call rollback, or before the reservation's own durable
transition out of reserving completes -- a crash, or a storage fault like
the one that also surfaces as a ContextError from a saved-state transition
that did not complete -- the saved intent is left as reserving instead. The
next attach recognizes a saved reserving marker, finishes abandoning it
and clearing the session back to its prior prepared, unattached state, and
asks the caller to rerun attach rather than completing a fresh attempt in
that same call, since resuming immediately could race a concurrent recovery.
Only once that cleanup has actually finished is the session safe to
explicitly rebuild, rerun prepare --refresh, or attach again; refresh must
not be used while a reserving cleanup is still outstanding, and a storage or
other fault surfaced while attach itself was trying to advance a saved intent
does not promise that this cleanup has already happened -- rerunning attach is
what finishes it.
A saved pending or uncertain intent is different: its reservation is
already durable, and GitHub publication may have begun or even completed
before a lost response left the local state unconfirmed, so it is never
blanket-cleared the way a reserving marker is. Once the trusted current pull
request head has genuinely moved past such a saved intent, that old identity
is retired before any new evidence is authorized, so a checkout that has since
moved on cannot block its own recovery. This retirement, like the reserving
cleanup above, is safe to retry after an interruption partway through.
The lower-level expert form remains available for scripts that intentionally manage request files and revisions:
code-mower context attach --connection example-context --host codex \
--repo-path /path/to/repository --base-ref origin/main \
--request-stdin < /private/path/attachment-request.jsonThe private request has exactly repository, work_item, policy, packet
(the handle), and pr (a positive integer). --host may come from
CODE_MOWER_HOST. Use origin/develop when that is the trusted target branch.
The GitHub actor must already be a configured control authority: the trusted
base's owner_surface.owner_login or decisions.authorities, or the equivalent
trusted runtime setting. Configure the same authority for the gate and local
auditor. PR-supplied configuration cannot grant that authority. Updating existing
repositories requires the current generated gate workflow and support helpers.
If trusted repository policy requires context, both audit wrappers and the
generated gate reject a review without its first required input declaration.
If local policy discovery itself fails, ordinary audits remain usable; explicit
input revisions and known declarations still require context. The generated
gate independently reads current policy from its trusted default-branch checkout
and rejects a code-only PASS. Changing context.required does not require
regenerating the workflow. A selected but malformed context policy fails closed;
an absent context section leaves ordinary workflows usable.
Attachment sets code-mower/gate pending and publishes a small control comment
containing only a random input revision, code head, required/available state,
and expiry. The packet hash, handle, account, alias, query, citations, and source
text stay local. A failed or uncertain publication leaves the local binding
unusable. The lower-level explicit attachment always creates a new review input
revision; the guided path reconciles its saved revision instead.
Run the usual independent audit on the machine that holds the private connection:
code-mower claude-audit --repo owner/repo --pr 42 \
--repo-paths owner/repo:/path/to/repository --base-ref origin/main \
--context-revision REVISIONThe corresponding codex-audit command uses the same options. The explicit
revision is optional: both wrappers discover current control declarations from
trusted authorities. It is useful when dispatching a specific work order.
Use --context-state-dir for a nondefault private store. A remote runner without
the selected authorization cannot review private context; it reports UNKNOWN.
Do not copy credentials or private packets into GitHub Actions to bypass this.
Both wrappers frame source material as evidence outside trusted project doctrine and owner decisions. They preserve citations, uncertainty, and contradictions. The model receives neither credentials nor account-binding metadata. Existing sandbox and ambient-MCP restrictions remain in force.
Before accepting the verdict, the wrapper checks the current code head, current input revision, packet identity, expiry, and fresh online authorization again. Missing required context, authorization failure, or changed input yields UNKNOWN. An explicitly declared optional-unavailable input can receive an ordinary code review, but that review must still name its input revision. Neither wrapper silently drops selected private evidence to fit a truncated diff.
When private evidence was supplied, public review comments and saved verdict artifacts contain only review status, severity counts, input metadata, and the standard audit provenance. Model-authored findings stay in the protected local binding because they may quote private sources. Raw CLI sidecars are disabled for this path. Retrieve detailed findings for the session's selected builder without copying the review revision:
code-mower session context feedback .code-mower/sessions/SESSION.json \
--reviewer claudeThis command derives the current revision and builder recipient, then checks the
current PR head, trusted input, and online authorization before printing private
findings. It records the session as reviewed after the first successful read.
The lower-level context feedback --revision REVISION ... and analogous
context deliver --revision REVISION commands remain available. All three have
private stdout.
Changed material context requires an explicit fetch with --refresh, followed
by attachment and a new audit, even when code is unchanged. A changed code head
also requires a new attachment. The gate checks both identities; an old PASS
cannot satisfy a newly attached input. UNKNOWN from a later authorization check
supersedes a prior PASS on the same input. Context-bound verdict artifacts cannot
be reposted offline; run a fresh authorized audit.
Gate status is updated by GitHub events, not a continuous authorization monitor. Do not treat a previously displayed green status as permission to replay expired evidence. Recheck the selected input when resuming work. Deleting or manually rewriting control comments is not a supported way to change the selected input; use the context commands and review the new revision.
Refresh, eviction, and disconnect delete the packet's local delivery bindings and private findings. At most eight bindings are retained per packet. Deletion cannot recall evidence already sent to an approved model. Provider billing that was not returned stays unknown; replay performs authorization, not another organization search.
The synthetic local-repository graph fixture uses the common packet validation and evidence renderer for all six roles without OAuth identity fields. It exercises the extension point that the shipped optional Graphify provider uses; a passing fixture neither installs Graphify nor qualifies a provider build. See Optional Graphify Setup.