Context
Twice now (2026-06-09) a stale broker contract-address env caused the #225 Touch-ID accept to fail with a confusing, misleading symptom — the broker read operatorMasterWallet from an old registry while the redeployed one was live, surfacing as "operator master 0x… is a legacy EOA" / "wrong passkey (SIG_VALIDATION_FAILED)". Both incidents cost a long diagnosis loop before the real cause (registry drift) was found.
- 1st incident: broker on the pre-cutover registry
0x1ac62f1c while the repo had 0xdA44a8D6.
- 2nd incident: after a v0.2 redeploy (
0xF50e…), setup-broker-host.sh resolved the registry from the host's stale worker env with precedence over operator-workstation.env — fixed in de4bbd1 (precedence: CLI flag > operator-workstation.env > worker-env). But nothing in the broker itself caught the drift; it silently built doomed UserOps.
Scope
Add a drift guard in the broker (crates/agentkeys-broker-server/src/handlers/accept.rs::load_accept_config, or broker startup): cross-check the accept-config SIDECAR_REGISTRY_ADDRESS / SCOPE_CONTRACT_ADDRESS / ENTRYPOINT_ADDRESS (from env) against the compiled-in agentkeys_core::chain_profile::ChainProfile (the source of truth, include_str!'d heima.json). On mismatch → fail loud with an actionable error naming BOTH addresses + the re-sync command, instead of serving the accept against the wrong contracts.
This was deferred as step 4 of the onboarding-P256Account plan (docs/plan/web-flow/onboarding-p256account-master.md §4 "Broker drift guard").
Acceptance
Effort
~S — a config-load cross-check (the ChainProfile::resolve + .contract(name).address comparison is already sketched in the plan §4), an override escape, and a unit test.
Metadata
Kind: Bug · Priority: High (recurring, high diagnosis cost) · Size: S · Area: broker
Context
Twice now (2026-06-09) a stale broker contract-address env caused the #225 Touch-ID accept to fail with a confusing, misleading symptom — the broker read
operatorMasterWalletfrom an old registry while the redeployed one was live, surfacing as"operator master 0x… is a legacy EOA"/"wrong passkey (SIG_VALIDATION_FAILED)". Both incidents cost a long diagnosis loop before the real cause (registry drift) was found.0x1ac62f1cwhile the repo had0xdA44a8D6.0xF50e…),setup-broker-host.shresolved the registry from the host's stale worker env with precedence overoperator-workstation.env— fixed inde4bbd1(precedence: CLI flag > operator-workstation.env > worker-env). But nothing in the broker itself caught the drift; it silently built doomed UserOps.Scope
Add a drift guard in the broker (
crates/agentkeys-broker-server/src/handlers/accept.rs::load_accept_config, or broker startup): cross-check the accept-configSIDECAR_REGISTRY_ADDRESS/SCOPE_CONTRACT_ADDRESS/ENTRYPOINT_ADDRESS(from env) against the compiled-inagentkeys_core::chain_profile::ChainProfile(the source of truth,include_str!'dheima.json). On mismatch → fail loud with an actionable error naming BOTH addresses + the re-sync command, instead of serving the accept against the wrong contracts.This was deferred as step 4 of the onboarding-P256Account plan (
docs/plan/web-flow/onboarding-p256account-master.md§4 "Broker drift guard").Acceptance
/v1/accept/*route) withaccept-env SIDECAR_REGISTRY_ADDRESS=0xA != chain profile 0xB — the broker is on a STALE deployment; re-sync: setup-broker-host.sh --ref <branch>.AGENTKEYS_ACCEPT_ALLOW_ADDR_OVERRIDE=1→ downgrade to atracing::warn!). The CI materializer sets the override.Effort
~S — a config-load cross-check (the
ChainProfile::resolve+.contract(name).addresscomparison is already sketched in the plan §4), an override escape, and a unit test.Metadata
Kind: Bug · Priority: High (recurring, high diagnosis cost) · Size: S · Area: broker