Skip to content

0.5.215: keys now reach the canonical but no attestation does — a federation-scoped consent:replication grant written before the round is never received #632

Description

@emooreatx

Follow-on from #629, as its own ladder asked: step 1 passes, step 2 fails. The node keys now reach the canonical; no attestation row does — including a consent:replication:v1 grant that the agent did write, federation-scoped, before the round that should have carried it.

Agent side: ciris-server 0.5.215, CIRISAgent five-platform gate run 35896050806. Canonical: 0.5.215 since 17:33Z.

Canonical side (operator, read-only mode=ro)

Agent side: the grant is written, and it's the right scope

From the agent's own database (federation_attestations, gate artifact db-android.db; db-ios.db is identical in shape):

consent:replication:v1
  attesting_key_id  qa-node-1790186668-…            (the OWNER)
  attested_key_id   ciris-canonical-1-d7bdeu223k
  cohort_scope      federation
  tier              federation
  admitted_at       2026-09-23T18:05:21.951Z
  promoted_at       NULL

So this isn't a scoping mistake — the grant is written the way peer.rs::emit_grant_row intends. And it exists six seconds before the round below.

All 19 rows on the agent after the run:

dimension attester cohort_scope tier
(3 rows with no dimension — key/occurrence envelopes) A1 / agent federation federation
accord:lifecycle:v1 A1 federation federation
ownership:responsible_party:node:v1 owner self federation
age_self_declared:adult:v1 owner federation federation
ownership:responsible_party:node:v1 owner federation federation
config:net.announce_ownership:v1 (×2) agent self federation
consent:replication:v1 owner federation federation
consent:state:granted:v1 (×2) owner federation federation
consent:community_trust:v1 (×2) agent self federation
consent:community_trust:v1 (×2) agent federation federation
consent:partnership_grant:v1 owner self local
consent:partnership_accept:v1 agent self local
self:delegates_to:agent_occurrence:v1 owner federation federation

Eleven rows are federation-scoped and signed by keys the canonical now holds. None arrived.

The round that should have carried it (android node log)

18:05:21.951  consent:replication:v1 admitted locally (above)
18:05:27.687  anti_entropy_round{peer=canonical kind=Attestation kicked=true}
              attestation send-set resolved (consent ∪ owner-bound ∪ self-collective)
              consent=1 owner_routed=0 collective_routed=1 complete=true
18:05:27.698  attestation withheld — recipient not in the row's audience   attester=qa-node-…  audience="self"
18:05:27.699  attestation withheld — recipient not in the row's audience   attester=ciris-agent-…  audience="self"
18:05:27.700  attestation withheld — recipient not in the row's audience   attester=ciris-agent-…  audience="self"
18:05:28.683  CRPL reply ROUTED into our INITIATOR's round inbox  kind=TransportDestination   (×3)
              — no reply routed for kind=Attestation in this window
round timed out waiting for peer reply: 7 over the run

The three withheld rows are correct to withhold. They're audience=self, and the self-scoped rows above match their attesters (owner ×1, agent ×2). A self row belongs on the owner's own nodes, not on the canonical. (The log names neither the row nor its dimension, so I can't say which self rows they were.)

The federation rows are invisible in that log either way. In bridge.rs the audience filter has Audience::Federation => true and only logs on withhold, so a federation row that passes produces no line. The log can't tell us whether the grant was in the offer.

The question

The grant was written, scoped to federation, before the round. So either:

  1. it was not in the round's offer — something between "admitted locally" and "advertised" (the publish-own set, the send-set's per-scope reach, CIRISPersist#884) doesn't include an owner-signed federation row on a split home; or
  2. it was offered and the round never completed — the Attestation round got no reply we can see (only TransportDestination replies routed back) and rounds kept timing out, so nothing transferred.

Separating these needs one of:

  • the canonical's view of what the qa-node-*/agent peers offered in Attestation rounds after 17:44Z — any summary or inbound frame from them for kind=Attestation; or
  • edge naming each row offered and each row withheld (row id + dimension) at debug. Today's withhold line carries peer, attester, audience, site only, and rows that pass the filter aren't logged at all — so raising RUST_LOG on our side won't list them. We already run ciris_edge=debug.

Not this

  • The grant's scope. It's federation, as intended. The audience="self" lines are self-plane rows being withheld correctly.
  • The c3dc6f27… Key refusal. Still logged, confirmed non-blocking earlier.
  • CIRISClient#66 — macOS stuck on Startup after the run-without-AI hand-off. That's a client issue and unrelated to this.

Refs #629, #628, CIRISPersist#884, CIRISAgent#1184.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions