Let an agent stage a capture without handing it the bindings (#201) - #244
Merged
Conversation
CommitLore — record lintTrailers: clean — 2 commits in Active constraints for the paths this PR touchesLimits (54)
Ruled out (102)
Warnings (43)
Trailer violations fail this check. Active constraints are informational — they are what the repository already decided, not a verdict on this PR. |
stage_capture completes the MCP write side. Its input schema accepts one field, a nonce, and the server computes everything the staged record commits to: the base HEAD, the staged diff hash, the policy identity, the staged timestamp and the expiry derived from it. An agent cannot assert what a record is bound to; it can only ask for the record it prepared to be staged. Expiry starts here and nowhere earlier. A prepared or verified record carries a null expires_at, so a capture being verified slowly cannot expire while someone is still reading it. Ruled-out: accepting base_head or a diff hash from the caller for efficiency | the caller is the party the transaction exists to constrain, so taking its word for the binding removes the point of the binding Ruled-out: a single write_record tool that skips the transaction | PRD-F9 forbids it, and it would let a draft reach Git without ever being verified Limit: the nonce pattern check bounds what a caller can send, but a caller holding a valid nonce for its own repository can stage repeatedly until the record is consumed Blast: local Undo: easy Certainty: firm Record-Id: r-t1009stage
MongLong0214
force-pushed
the
feat-issue-201
branch
from
July 30, 2026 13:27
4c7ea4d to
b5fcf4e
Compare
test/mcp.test.ts asserted the exact tool list under a title that said "the three tools of the ticket". The list had already grown past three, and each tool added since has had to edit an assertion whose name no longer described it. Adding stage_capture broke it again. The assertion is worth keeping — an unexpected tool appearing on the MCP surface should fail a test — so it now lists what the server exposes and the title says that instead of a number that was wrong four tools ago. Ruled-out: relaxing the assertion to a subset check | an unexpected tool on the write surface is exactly what this test should catch, and a subset check would not catch it Limit: the list is still maintained by hand, so it will need editing for every future tool; that is the cost of catching an unintended one Blast: local Undo: easy Certainty: firm Record-Id: r-t1009list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #201 — T-1009. Governing: ADR-0021, PRD-F9.
commitlore_stage_captureaccepts only{ nonce }, validated against^[0-9a-f]{32}$before any path resolution. Every binding is server-owned.expires_at = staged_at + 5 minutes, stamped only on stage success,nullbefore it.readOnlyHint: false.Evidence:
npx vitest run test/mcp-capture.test.ts26/26 including the expiry-anchor oracle;npm run buildexit 0; both typechecks exit 0; rebuiltdist/committed.