Make fresh ERC-8004 policy executable from MCP alone - #97
Open
thetangstr wants to merge 28 commits into
Open
Conversation
Constraint: Fresh Codex and Claude Code clients must not need blockchain constants in the stakeholder prompt. Rejected: Adding Sepolia plumbing to the business prompt | it makes the public MCP contract non-portable and easy to mis-specify. Confidence: high Scope-risk: narrow Directive: Keep the public identity-policy schema conditionally exact whenever supported chains or registries change. Tested: MCP build plus v2 public-server, coordinator, protocol, and v1 compatibility tests. Not-tested: Live cross-client canaries run after deployment.
Constraint: Claude Code must distinguish stakeholder-authorized local signing from prompt injection without weakening hash or policy checks. Rejected: Hiding bearer access from the local stakeholder | conflicts with transparent client safety boundaries Confidence: high Scope-risk: narrow Directive: Keep role access out of counterpart channels and logs, while allowing the local stakeholder to audit its use. Tested: npm run build; targeted public initialization test Not-tested: live cross-client canary pending
Constraint: Fresh Claude Code must receive informed consent from the local stakeholder prompt, not infer authority from MCP-delivered content. Rejected: Treating server instructions as authorization | correctly triggers prompt-injection defenses Confidence: high Scope-risk: narrow Directive: Keep initial stakeholder prompts explicit about expected handshake, pinned helper execution, Sepolia registration, and signing scope. Tested: npm run build; targeted public initialization test Not-tested: live Sonnet canary pending
Return a narrow pinned-helper action at the exact funded registration boundary so stateless clients do not poll until expiry. Constraint: Keep the public surface at seven tools and preserve generic v1 behavior. Rejected: Add a registration MCP tool | It would move local signing authority into the server boundary. Confidence: high Scope-risk: narrow Directive: Keep registration local and express future local steps as explicit machine-actionable coordinator output. Tested: npm test in packages/mcp-server (286/286). Not-tested: Live cross-client canary pending production deployment.
Accept the canonical decimal session-opened block before converting provider requests to JSON-RPC hex quantities. Constraint: V2 discovery carries decimal block strings while Ethereum JSON-RPC responses use hex quantities. Rejected: Scan from registry creation on every fresh run | It adds unnecessary provider load and weakens the fresh-identity boundary. Confidence: high Scope-risk: narrow Directive: Keep external protocol encodings explicit at RPC boundaries. Tested: npm test in packages/mcp-server (287/287), plus live reproduction against Sepolia. Not-tested: End-to-end fresh-agent canary pending production deployment.
Give fresh clients one deterministic state-directory bootstrap so the helper can preserve its fail-closed file-permission boundary. Constraint: The workflow must remain plugin-free and keep private keys local. Rejected: Relax private-directory validation | It would weaken signer isolation for the sake of the demo. Confidence: high Scope-risk: narrow Directive: Keep local signer prerequisites explicit in MCP instructions and client allowlists. Tested: Public v2 server tests 3/3; prior full MCP suite 287/287. Not-tested: Fresh production canary pending deployment.
Accept checksummed helper output and lower-case it before every identity, funding, and signature binding. Constraint: The helper emits a standard checksummed address while protocol artifacts require one canonical form. Rejected: Require fresh agents to guess a lowercase retry | Public errors are intentionally opaque and should not force model heuristics. Confidence: high Scope-risk: narrow Directive: Normalize equivalent public encodings once at the coordinator boundary. Tested: npm test in packages/mcp-server (287/287). Not-tested: Fresh production canary pending deployment.
Constraint: Responder invitations are one-time bearer capabilities and fresh agents must retain the first successful acceptance result. Rejected: Making invitation acceptance idempotent | Replay rejection is a deliberate security property. Confidence: high Scope-risk: narrow Directive: Keep the one-time invitation invariant and teach clients to treat the first success as authoritative. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs Not-tested: Live production canary pending deployment.
Constraint: Waiting and party-ready states are protocol progress, not terminal success. Rejected: Retrying invitations or treating registration as completion | Invitations are one-time and certification requires both parties plus the checker. Confidence: high Scope-risk: narrow Directive: All nonterminal next responses must carry an explicit continuation signal. Tested: MCP build; v2 coordinator and public-server tests; fresh-client prompt contract. Not-tested: Live production canary pending deployment.
Constraint: Fresh agents must not infer the helper policy schema from prose. Rejected: Adding more schema prose to stakeholder prompts | The server can return the exact role-specific policy object it already validates. Confidence: high Scope-risk: narrow Directive: Treat returned localPolicy bytes as immutable input to the helper policy operation. Tested: MCP build; v2 coordinator and public-server tests; fresh-client prompt contract. Not-tested: Live production canary pending deployment.
Constraint: Fresh agents must retry temporary RPC or relay failures without retrying invalid role state or consumed invitations. Rejected: Treating every internal exception as terminal | It made healthy handshakes fail on one transient read. Confidence: high Scope-risk: narrow Directive: Preserve generic errors while carrying an explicit retryable boolean and delay. Tested: MCP build and four public-server tests; fresh-client prompt contract. Not-tested: Live production canary pending deployment.
Constraint: Fresh independent agents can observe an anchor before every ledger and chain projection is durably visible.\nRejected: Treat every coordinator error as retryable | protocol-integrity mismatches must remain terminal.\nConfidence: high\nScope-risk: narrow\nDirective: Preserve the distinction between absent propagation state and explicit binding mismatches.\nTested: npm test in packages/mcp-server (289/289)\nNot-tested: Fresh production canary after deployment
Constraint: Fresh agents must authenticate each role-scoped MCP call while never sharing bearer access with the counterparty or logs.\nRejected: Remove role-scoped access | distinct principals and role isolation require it.\nConfidence: high\nScope-risk: narrow\nDirective: Describe same-server access arguments as required credential use, not stakeholder disclosure.\nTested: agent-handshake-v2-public-server.test.mjs (4/4)\nNot-tested: Fresh production canary after deployment
Constraint: The invite response contains one copyable invitation and one private Initiator capability with different allowed tools.\nRejected: Infer the intended field from token shape | both values deliberately share the same signed capability encoding.\nConfidence: high\nScope-risk: narrow\nDirective: Name initiatorAccess, responderInvitation, and responderAccess explicitly in every autonomous-client instruction.\nTested: agent-handshake-v2-public-server.test.mjs (4/4)\nNot-tested: Fresh production canary after deployment
Constraint: Clockchain represents a submitted but not-yet-anchored ledger record with blockHeight null.\nRejected: Accept null as an integrity value | only a confirmed decimal height may enter receipt verification.\nConfidence: high\nScope-risk: narrow\nDirective: Retry null projection fields, but keep non-null binding mismatches terminal.\nTested: npm test in packages/mcp-server (289/289)\nNot-tested: Fresh production canary after deployment
Advance the dedicated handshake endpoint, join schema, verified bootstrap, and deployment validator to helper 2.1.1 so fresh clients can sign the final evidence shape that production actually emits. Constraint: MCP, SSM deployment metadata, and client bootstrap must agree on one exact helper release. Rejected: Continue accepting v2.1.0 | that helper deterministically rejects valid evidence and cannot complete a certificate. Confidence: high Scope-risk: moderate Directive: Deploy only with manifest digest 681f61d4cde2537ec6953b134e8385e6a716c8d889db0f46fd566c10407c9402 and source 8f74f6d953631cbac057426e3540ba73bf607f3b. Tested: MCP build plus 289 tests; 29 infrastructure tests; git diff --check. Not-tested: Live endpoint awaits SSM pin update and EC2 restart.
Constraint: systemd executes an out-of-checkout wrapper under /opt/clockchain-mcp.\nRejected: restarting systemd directly after checkout updates | leaves the prior validator installed.\nConfidence: high\nScope-risk: narrow\nDirective: run the deploy-asset installer from the exact checkout before every restart.\nTested: node --test infra/test/deploy-assets.test.mjs; git diff --check\nNot-tested: no additional production restart was needed for this documentation guard.
Constraint: public clients must keep receiving the same generic fail-closed errors.\nRejected: returning internal failure details through MCP | creates an unnecessary protocol oracle.\nConfidence: high\nScope-risk: narrow\nDirective: structured diagnostics may include only the tool name and sanitized error class, never inputs or messages.\nTested: full npm test; focused public-server test; git diff --check\nNot-tested: the production log classification requires one new failed or successful canary after deploy.
Constraint: Claude Code dontAsk requires the emitted shell command to match an allow rule exactly, and zsh rejects unquoted =https arguments. Rejected: Broaden Bash access | unnecessary and weakens the fresh-agent containment contract Confidence: high Scope-risk: narrow Directive: Keep MCP download instructions byte-aligned with the Claude allowlist. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs; isolated Claude Code sonnet quoted-download probe Not-tested: Full production cross-client handshake pending deployment
Constraint: Claude Code dontAsk evaluates each emitted Bash shape against the narrow allowlist, and Sonnet followed an MCP semicolon hint by combining downloads. Rejected: Permit compound Bash | unnecessary and expands the local-authority surface Confidence: high Scope-risk: narrow Directive: Describe every allowlisted Bash action as a separate tool call without shell wrappers or separators. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs; live Sonnet trace isolated the denied compound shape Not-tested: Full production cross-client handshake pending deployment
Constraint: Sonnet optimized the download and state-directory steps into one four-operator Bash call, which dontAsk correctly denied. Rejected: Allow compound shell commands | obscures the local-authority boundary and admits unintended command composition Confidence: high Scope-risk: narrow Directive: Each Bash action in MCP instructions must remain ordered, standalone, and byte-aligned with one allow rule. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs; safe live command-shape trace identified curl plus mkdir in the denied compound Not-tested: Full production cross-client handshake pending deployment
Constraint: Fresh clients must validate exact returned terms without mistaking the canonical terms digest for a raw-text hash. Rejected: Letting agents infer the digest scheme | it caused a safe but unnecessary live refusal. Confidence: high Scope-risk: narrow Directive: Keep statementDigest defined as SHA-256 over Clockchain canonical full terms. Tested: MCP build and focused public-server tests, 4/4. Not-tested: Live cross-client canary follows after deployment.
Constraint: Fresh clients must complete policy, signing, and certificate verification without repository knowledge or guessed JSON shapes. Rejected: Expanding the stakeholder prompt with CLI mechanics | the MCP should carry executable local actions. Confidence: high Scope-risk: moderate Directive: Every helper payload must remain exact, role-scoped, and free of bearer credentials or private keys. Tested: MCP build plus focused coordinator and public-server suites, 7/7. Not-tested: Live Terra-to-Sonnet canary follows after deployment.
Constraint: Claude native sandbox exposes a shared runtime temp root that must never hold reusable handshake state. Rejected: Reusing or cleaning shared temp paths | would weaken fresh-agent provenance and risk deleting unrelated files. Confidence: high Scope-risk: narrow Directive: Keep manifest and helper asset digests explicit and distinct in all client instructions. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs test/agent-handshake-v2-coordinator.test.mjs; git diff --check Not-tested: live cross-client canary pending this deployment
Constraint: Fresh ERC-8004 keys begin with no Sepolia gas and must be funded by the host after join. Rejected: Letting clients infer registration timing | Sonnet safely attempted registration before Clockchain knew which address to fund. Confidence: high Scope-risk: narrow Directive: Keep the join then fund then register gate explicit in both instructions and structured local actions. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs test/agent-handshake-v2-coordinator.test.mjs; git diff --check Not-tested: live cross-client canary pending this deployment
Constraint: Fresh Codex and Claude Code clients must not infer helper flags or re-encode protocol payloads. Rejected: More prompt prose | the failing clients needed typed executable arguments, not additional narrative. Confidence: high Scope-risk: moderate Directive: Return exact helper argv and encoded payload for every local action; clients may replace only the absolute state-directory placeholder. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs test/agent-handshake-v2-coordinator.test.mjs; git diff --check Not-tested: live cross-client canary pending this deployment
Constraint: Codex and Claude Code execute helper actions in separate shell processes where PWD-derived variables are not durable. Rejected: Persisting a shell variable or client-chosen path | both reintroduced inference and cross-call drift. Confidence: high Scope-risk: moderate Directive: Use the exact session-and-role-scoped HOME path and shell suffix returned by each local action. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs test/agent-handshake-v2-coordinator.test.mjs; git diff --check Not-tested: live cross-client canary pending this deployment
Constraint: Codex workspace-write intentionally denies the client's home directory. Rejected: Expanding client home permissions | the signer needs only its fresh workspace and broader access weakens the demo boundary. Confidence: high Scope-risk: narrow Directive: Keep the exact session-scoped state path under PWD and preserve typed helper suffixes. Tested: npm run build; node --test test/agent-handshake-v2-public-server.test.mjs test/agent-handshake-v2-coordinator.test.mjs; git diff --check Not-tested: live cross-client canary pending this deployment
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.
Summary
Verification