Cairnet bridge principal binding — canonical value is `agent:petrova-cairnet-bridge`
title: Cairnet bridge principal binding — canonical value is agent:petrova-cairnet-bridge
date: 2026-05-18
status: accepted
outranks: []
mr_compliance: [MR-4, MR-7]
relates_to:
- docs/findings/2026-05-18-sp1-5-agent-prefix-seam-defect.md
- docs/findings/2026-05-17-sp1-seam-defect.md
- docs/plans/2026-05-17-sp1.5-seam-remediation-implementation.md
- docs/specs/2026-05-17-sp1.5-seam-remediation-design.md
Cairnet bridge principal binding — canonical value is agent:petrova-cairnet-bridge
Section titled “Cairnet bridge principal binding — canonical value is agent:petrova-cairnet-bridge”Context
Section titled “Context”The ROCKY cairnet seam requires four surfaces to agree on ONE identity for the wire-time governance stone: airlock (bridge OAuth client) → Pebble (auth + stone record) → petrova-codes (rocky probe query) → eva-hq (operator prompt / evidence block). SP-1.5 remediated the SP-1 seam-defect; during it the binding contract was reconciled twice.
Decision (append-only history)
Section titled “Decision (append-only history)”- Plan-as-written assumed
petrova-cairnet-bridge-001(a per-repo<slug>-bridge-001form) carried via airlock clientmetadata. Superseded — see step 2. - 2026-05-18, reconciliation 1 (plan owner): airlock only
projects
metadata.customClaimsonto tokens, and Pebble (R1, faithful KAHN port) derives the principal from the introspectionsub/client_idfor client_credentials tokens — never a custom claim. So the principal is the OAuth client_idpetrova-cairnet-bridge(no-001). The airlock clientmetadatawas reverted to{}(R2 net change = only thecairn:readscope add). The collection-owner id<slug>-<role>-001is a SEPARATE identity (agent registration / lore-collection ownership), never the probe query key — R5 split the conflated<<CAIRNET_AGENT_ID>>placeholder into owner vs<<CAIRNET_PRODUCER_PRINCIPAL>>. - 2026-05-18, reconciliation 2 (terminal gate + plan owner,
Option A): the SP-1.5 terminal whole-seam gate found Pebble’s
_principal_triple(cairn.py:148-154) records machine-agent stones asf"agent:{binding}". The stone is therefore recorded underagent:petrova-cairnet-bridge; the bare form matches zero stones. CR1 proved this empirically (real auth + cairn POST + Postgres). Plan owner chose the probe/prompt-side correction (no Pebble doctrine change). Canonical binding value:agent:petrova-cairnet-bridge.
Consequences
Section titled “Consequences”- The rocky evidence block
cairnet_agent_id, the rocky probe?agent=query (URL-encoded to?agent=agent%3Apetrova-cairnet-bridge, Pebble decodes it server-side), and the eva-hq prompt’s<<CAIRNET_PRODUCER_PRINCIPAL>>all resolve toagent:petrova-cairnet-bridge. - No new Pebble or petrova-codes source code: the probe passes
ev.cairnet_agent_idthrough verbatim; R1’s KAHN-faithful auth is unchanged. The change is the documented/contract VALUE only. - A cross-repo POST→GET-by-
?agent=test now exists in pebble (tests/integration/test_cairn_bridge_principal_seam.py) and a petrova-codes contract-pin test (cli/tests/probes/cairnet-binding-contract.test.ts) locks the prefixed literal +%3Aencoding. Their absence was the structural root cause that let the original defect pass 18 + 5 green tasks. - The
cairnet_agent_idfield name now carries anagent:-prefixed value (a documented naming wart; the field is named for the recorded producer principal). - Pebble’s
agent:/human:identity-provenance doctrine is unchanged (Option A deliberately did not touch it).
Status
Section titled “Status”Accepted. Terminal whole-seam gate round 2 = GREEN; SC-1 delivered
end-to-end. Two doc-correctness residuals tracked as next-round input
in docs/findings/2026-05-18-sp1-5-agent-prefix-seam-defect.md
(MR-2 — not bolted onto the GREEN round).