Skip to content

Make fresh ERC-8004 policy executable from MCP alone - #97

Open
thetangstr wants to merge 28 commits into
mainfrom
codex/apple-demo-deploy
Open

Make fresh ERC-8004 policy executable from MCP alone#97
thetangstr wants to merge 28 commits into
mainfrom
codex/apple-demo-deploy

Conversation

@thetangstr

Copy link
Copy Markdown
Owner

Summary

  • encode exact conditional ERC-8004 chain and registry constants in the public invite schema
  • keep all seven tools and v1 compatibility unchanged

Verification

  • MCP build
  • v2 public-server, coordinator, and protocol tests
  • v1 compatibility test
  • live production tools/list schema and health probe

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
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