Context
PR #95 (issue #82 ERC-7730 + EIP-712 sign) added signed_intent_text + signed_intent_hash to the audit-row schema, but only for typed-data signs. AuditEnvelope v1 is the canonical abstract format every audit-producing surface emits going forward.
Phase A — the canonical schema + non-break design — landed in PR #95 under arch.md §15.3a. This issue tracks the implementation phases B / C / F.
2026-06-11 sync to current design (checkbox audit against main @ b75597c): Phases B + C are fully shipped; Phase F's data-plane families (cred/memory/config) are live via #229 / PR #261. Deviations from the original plan are called out inline below. Remaining work: the control-plane emit sites (sign / scope / device — in progress), then email / K3 / payments / K10-rotate.
Phase B — worker + core migration ✅ SHIPPED
Phase C — contract revision ✅ SHIPPED (prod); test-stack redeploy pending
Phase F — extend op_kind coverage
All bytes were pre-claimed in the Phase A table, so the per-row work is: emit-site wiring + the 3-test ritual (arch.md row already exists).
Live (data plane, #229 / PR #261):
In progress (control plane — PR forthcoming from this issue):
Remaining (each a follow-up PR):
Open design item (deferred from #229): audit-worker-initiated on-chain submission of appendRootV2 (tier-A relay). Today flush returns the inputs and the operator master submits (worker smoke + harness do this). True worker-initiated anchoring needs a master-delegated relay wallet or a contract-side allowance — design TBD here.
Non-break invariants (per arch.md §15.3a)
Unchanged — every PR landing a new op_kind MUST preserve all 8 invariants (open u8 enum, stable envelope-level fields, version gated on envelope-level breakage only, explorer Unknown(byte) fallback, opaque op_body passthrough, op-kind-agnostic contract, canonical table append-only in arch.md, 3 tests per op_kind).
Companion issue
Explorer-side work (phases D/E) tracked at litentry/subscan-essentials#12.
Acceptance
Related: #82 (closed by #95), #90 (Stage 2 hardening), #91 (worker hardening), #201 (config data class), #229 (worker durable audit, PR #261).
Context
PR #95 (issue #82 ERC-7730 + EIP-712 sign) added
signed_intent_text+signed_intent_hashto the audit-row schema, but only for typed-data signs.AuditEnvelope v1is the canonical abstract format every audit-producing surface emits going forward.Phase A — the canonical schema + non-break design — landed in PR #95 under arch.md §15.3a. This issue tracks the implementation phases B / C / F.
Phase B — worker + core migration ✅ SHIPPED
AuditEnvelope v1struct inagentkeys-core(audit/mod.rs, CBOR-canonical per RFC 8949 §4.2.1 inaudit/cbor.rs).AuditOpKindu8 + per-kindop_bodyschemas (op_kind.rs+bodies.rs+TypedAuditBody) — every byte in the canonical table has a typed body, including the config family 80–82 added by Config data class + lazy, config-driven memory list (Phases 1–5) #201/Worker-side durable audit for memory + cred data-plane ops (store/fetch) #229.GET /v1/audit/envelope/<hash>onagentkeys-worker-audit(returns canonical CBOR,application/cbor).POST /v1/audit/append; the envelope shape landed atPOST /v1/audit/append/v2. Same one-cycle compatibility property (old callers keep working untouched), simpler migration.AuditEnvelope— cred + memory + config (Worker-side durable audit for memory + cred data-plane ops (store/fetch) #229 / PR feat: #229 worker-side durable audit for memory + cred + config data-plane ops #261): one envelope per store/fetch/teardown, after cap-verify, before the success response, via the sharedAuditEmitter. Responses carry theaudit_envelope_hashreceipt;AGENTKEYS_WORKER_REQUIRE_AUDIT=1fails closed (staged rollout, default best-effort).envelope_hash = keccak256(canonical_cbor(envelope)).Phase C — contract revision ✅ SHIPPED (prod); test-stack redeploy pending
appendV2(operatorOmni, actorOmni, opKind, envelopeHash)inCredentialAudit.sol— additive, v1 retained. Design refinement: V2 is event-only (no on-chain entry/root storage; the indexed event log is the canonical history — entry position derivable from block number + log index).appendRootV2(operatorOmni, merkleRoot, opKindBitmap, entryCount)—opKindBitmap: bytes32, bit N = op_kind N; gated to the operator master wallet like V1appendRoot. The audit worker queues V2 envelope hashes per operator and flush returns theappendRootV2inputs (Worker-side durable audit for memory + cred data-plane ops (store/fetch) #229).AuditAppendedV2+AuditRootAppendedV2events withindexed opKindtopic.AgentKeysV1.t.sol).heima-bring-up.sh).appendRootV2anchors soft-skip there by design until its next contract-set redeploy (VERSION bump ceremony).heima.json(contract_set_version 0.3);deployed-contracts.mdcarries the prose (the doc no longer holds an address table).Phase F — extend op_kind coverage
All bytes were pre-claimed in the Phase A table, so the per-row work is: emit-site wiring + the 3-test ritual (arch.md row already exists).
Live (data plane, #229 / PR #261):
CredStore(0) +CredFetch(1) +CredTeardown(2) — credentials worker.MemoryPut(10) +MemoryGet(11) +MemoryTeardown(12) — memory worker.ConfigPut(80) +ConfigGet(81) +ConfigTeardown(82) — config worker (family 80–89 claimed via the §15.3b ritual; not in this issue's original table).In progress (control plane — PR forthcoming from this issue):
SignEip191(20) — emitted by the CLI sign orchestrator (agentkeys signer sign) after the signer returns. Emit-site deviation: the original table said "signer via daemon callback"; the CLI command is the component that orchestrates the sign and (for 712) holds the ERC-7730 intent text, so it emits.SignEip712(21) — same site (agentkeys signer sign-typed-data); carriesintent_text+intent_commitmentfrom PR issue #82: ERC-7730 clear-signing + EIP-712 typed-data sign (v2-aligned) #95's ERC-7730 preview when--preview-7730is active.ScopeGrant(40) +ScopeRevoke(41) — broker submit relay decodes the landedexecuteBatchcalldata after the UserOp receipt confirms:setScopewith services →ScopeGrant(body carries the FULL replacement set — set-replace semantics per Permissions panel READ/R+W toggle is local-only — never commits setScope on chain (header claims it does) #248); empty services →ScopeRevoke. Covers both the accept batch and/v1/scope/submitre-grants. Schema alignment: theop_bodyrows for 40/41 predate the Migrate master authority to an ERC-4337 P-256 smart-account (resolves §11 gating findings) #164/On-chain K11 gate for agent accept (passkey-account master UserOp) #225 set-replacesetScopeand are updated to the on-chain truth in the same PR (bytes never emitted before — not a break).DeviceAdd(50) +DeviceRevoke(51) — same broker decode path:registerAgentDevice→DeviceAdd(role_bits = ROLE_CAP_MINT, attestation hash zero for agent binds),revokeAgentDevice→DeviceRevoke(covers/v1/revoke/submitunpair).Remaining (each a follow-up PR):
K10Rotate(52) — blocked: no runtime K10 rotation flow exists yet.PaymentEscrowRedeem(30) +PaymentDirect(31) — blocked on the §15.5 payment-service worker.EmailSend(60) +EmailReceive(61) — email-service worker emit (worker exists; wireAuditEmitterlike Worker-side durable audit for memory + cred data-plane ops (store/fetch) #229).K3EpochAdvance(70) —advanceEpoch()is operator-script-driven today; the emit site lands with whatever runtime component calls it.Open design item (deferred from #229): audit-worker-initiated on-chain submission of
appendRootV2(tier-A relay). Today flush returns the inputs and the operator master submits (worker smoke + harness do this). True worker-initiated anchoring needs a master-delegated relay wallet or a contract-side allowance — design TBD here.Non-break invariants (per arch.md §15.3a)
Unchanged — every PR landing a new op_kind MUST preserve all 8 invariants (open u8 enum, stable envelope-level fields, version gated on envelope-level breakage only, explorer
Unknown(byte)fallback, opaqueop_bodypassthrough, op-kind-agnostic contract, canonical table append-only in arch.md, 3 tests per op_kind).Companion issue
Explorer-side work (phases D/E) tracked at litentry/subscan-essentials#12.
Acceptance
appendRootV2batching, asserted byharness/v2-stage3-demo.shsteps 11-12 +heima-worker-smoke.sh).Unknown(byte)fallback (subscan-essentials#12).Related: #82 (closed by #95), #90 (Stage 2 hardening), #91 (worker hardening), #201 (config data class), #229 (worker durable audit, PR #261).