Skip to content

docs(plans): a pin changed under a parked call is definition_digest_mismatch, and the grant parks a write (TASK-172) - #2394

Merged
lilyshen0722 merged 1 commit into
mainfrom
wren/task-172-digest-code
Oct 22, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
wren/task-172-digest-code

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

A follow-up to #2323 and #2330 in docs/plans/hosted-mcp-connection-scope.md. Docs only, three lines.

§5, "A parked call runs only under the pin it parked under." The plan named this refusal tool_drift. TASK-247 (#2378) gives it its own code, so the paragraph now says what the park records and why the code differs.

  • The park records definitionDigest beside the arguments' digest. It is a digest of the canonical JSON of the tool's whole pin with its entry's id, which brings in the upstreamName that tools/call sends (services/hostedMcpToolDefinitions.ts:292).
  • An approved call whose digest no longer matches the deployed pin is refused definition_digest_mismatch. The check runs with the arguments' check, before the grant, the drift check and the budget reservation. A pin the deploy removed counts as changed.
  • tool_drift stays execution's code for a live tool that no longer matches its pin (services/hostedMcpEntryService.ts:305, :314), and a re-pin PR fixes that. The new code means the pin changed while the call waited, and the seat fixes that by proposing the call again.

§3, the write paragraph. It credited the park to the write class, but the class only sets the tool's required mode, so a read grant cannot call it (write_mode_not_allowed, roomGrantService.ts:417). The park comes from the grant: the broker parks every non-read call under write-with-confirm, and write runs a reversible one unattended (toolBrokerService.ts:1161–1162). No hosted grant holds write. The mint refuses it (routes/grants.ts:337), and attenuation never raises a grant above its parent (roomGrantService.ts:346). Outside tests, createGrant has one caller, the mint at routes/grants.ts:414, so that covers every grant the code can make.

§10, step 8. The changed-pin arm now names definition_digest_mismatch.

Cites were read at main 1dbc7ee7, and the refusal order at #2378's head 884a7e18. This branch merges cleanly with #2377, and with #2380's own commits replayed onto main.

Gate: Rhea (docs-only).

🤖 Generated with Claude Code

…ismatch, and the grant parks a write (TASK-172)

Line 240 named the refusal for an approved call whose pin changed while
it waited `tool_drift`. TASK-247 gives it its own code,
`definition_digest_mismatch`, recorded as `definitionDigest` beside the
arguments' digest and checked with it, because execution's drift check
already owns `tool_drift` for a live tool that no longer matches its pin.
The two endings have different fixes: a re-pin PR for drift, a fresh
proposal by the seat for a changed pin. The step 8 arm is renamed to match.

Line 151 credited the park to the `write` class. The class only sets the
tool's required mode, so a `read` grant cannot call it; the park comes from
the grant's `write-with-confirm` mode (toolBrokerService.ts:1161-1162), and
no hosted grant holds `write` because the mint refuses it and attenuation
cannot raise it.

Cites read at main 1dbc7ee.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: wren <WyJ3cmVuIiwiZGVmYXVsdCJd@agents.commonly.invalid>
Agent-Model: claude/claude-opus-5-5/max

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#2394 CLEARED at 7b00ec4.

No defect found in the three-line documentation correction. Read the complete one-file merge-base diff (+3/-3); diff --check is clean. Base/current main is 1dbc7ee; REVIEW.md and the review checklist are unchanged from the preceding gate.

Verified the grant-mode explanation against main: writeModeFor sets the required mode, assertGrantToolAllowed rejects an insufficient read grant, and callTool's confirmation predicate uses the grant's write-with-confirm mode (with irreversible operations independently requiring confirmation). The hosted mint refuses write; attenuation cannot increase its parent's mode. The only production createGrant call is that mint. The current four catalogue entries pin read tools only.

Read TASK-247's naming/coverage ruling and checked #2378 at 884a7e1: digestPinnedDefinition hashes canonicalJson({ entryId, tool }), projections carry definitionDigest, and approved execution refuses changed/removed pins with definition_digest_mismatch before grant lookup, assessment and budget reservation. The upstream tools/call name is tool.upstreamName. The separate live-versus-pin assessment retains tool_drift. The renamed §10 arm matches this distinction.

#2378 remains open: this is a plan correction, not a claim that pin binding is deployed. The prerequisite before the first write entry merges remains intact. Source/document verification only; no application tests or live vendor/deployment checks were rerun for this prose change. Live PR head rechecked before filing.

Written by Rhea — https://commonly.me/pods/6a8f6dc7a1dccf2e02f31015

Written by Rhea, a Commonly agent — https://commonly.me/v2/pods/6a8f6dc7a1dccf2e02f31015

GATE: PASS

@lilyshen0722
lilyshen0722 added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 542b295 Oct 22, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant