SP-1 seam-defect — cross-repo assembly does not deliver SC-1
REMEDIATED (2026-05-18). SP-1.5 (R1–R5) plus the Option-A corrective round (CR1–CR3) closed C1/C2/C3/I1/I2/I3. The terminal whole-seam gate (round 2) returned GREEN — SC-1 delivered end-to-end, including the round-1
agent:-prefix join and the%3AURL round-trip. Nothing merged at time of this note; all work on the four feature branches. Seedocs/findings/2026-05-18-sp1-5-agent-prefix-seam-defect.mdfor the full remediation record and the two tracked next-round residuals.
SP-1 seam-defect — cross-repo assembly does not deliver SC-1
Section titled “SP-1 seam-defect — cross-repo assembly does not deliver SC-1”Disposition
Section titled “Disposition”All 18 SP-1 tasks individually passed implement → spec-review → code-quality-review. The final whole-implementation review (the subagent-driven-development terminal gate) found that the assembled cross-repo seam does not deliver SC-1 end-to-end. Per-task reviews were correctly scoped but structurally could not see the integration gaps — which is exactly the defect class the final gate exists to catch.
Verdict: SEAM-DEFECT-FOUND. Nothing is merged; all work is on
feature branches; no repo’s main is affected. Branch-finishing was
not invoked and SC-1 success is not claimed.
This doc is the honest durable record. It supersedes the
implementation-complete framing in
docs/findings/2026-05-17-sp1-acceptance.md (whose status line is
amended to point here). It records new findings only; the 3
carry-forward caveats in the acceptance doc remain accurate and
non-blocking and are separate from these findings.
Critical defects (3)
Section titled “Critical defects (3)”C1 — Pebble has no Authorization: Bearer auth path (re-verified, primary source)
Section titled “C1 — Pebble has no Authorization: Bearer auth path (re-verified, primary source)”devarno-cloud/pebble @ feat/cairn-idempotency,
src/pebble/api/middleware/auth.py AuthMiddleware.dispatch: exactly
two identity-resolution paths — (1) airlock session cookie via
session_service.get_session_from_cookies, (2) X-API-Key header via
apikey_service.validate_key. No Authorization: Bearer branch,
no airlock RFC-7662 introspection, no JWKS path. The
WWW-Authenticate: Bearer header in require_auth
(src/pebble/api/dependencies/auth.py) is cosmetic — nothing consumes
a Bearer token.
Consequence: an emitter sending Authorization: Bearer <airlock access token> (the shape the SP-1 design assumed, and literally what
2026-05-17-sp1-acceptance.md line 183 prescribes:
PETROVA_PEBBLE_TOKEN=<airlock-access-token>) resolves to no
identity. require_permission("cairn:emit") then hits user is None,
returns an anonymous UserContext(permissions=[]), fails the
permission check, and returns HTTP 403 on every emitter→Pebble
stone POST/GET.
Root cause: the design statement “Pebble validates via airlock
introspection (existing pattern)” is false for Pebble. That
introspection pattern lives in KAHN’s backend/kahn/cloud_auth.py,
not in Pebble. This is a design under-specification, not a task
defect — T4’s tests legitimately pass because they mock UserContext
via dependency_overrides, so the real auth path never fires.
C2 — wire_integration.ts was never modified (seam-review-reported)
Section titled “C2 — wire_integration.ts was never modified (seam-review-reported)”The plan’s file list included wire_integration.ts (emit the
wire-time integration stone + set first_emitted_at). T12 wired only
the 5 governance verbs; no task picked up wire_integration. The T16
prompt’s --emit-wire-stone flag does not exist in the CLI. The
wire-time integration stone — the entire SC-1 mechanism — is never
emitted. Root cause: task decomposition orphaned this between T12 and
T16.
C3 — user.scopes never populated by Pebble _build_user_context (seam-review-reported; corollary of C1)
Section titled “C3 — user.scopes never populated by Pebble _build_user_context (seam-review-reported; corollary of C1)”The cairn:emit gate would fail for real tokens even if Bearer auth
existed, because Pebble’s user-context builder does not populate
scopes. With C1 in place there is no Bearer caller path at all, so this
is currently moot but must be fixed alongside C1.
Important defects (3) (seam-review-reported)
Section titled “Important defects (3) (seam-review-reported)”- I1 — Pebble
GET /api/cairn/stonestakes?agent=not?agent_id=and has nosincefilter; the rocky probe silently counts the global feed. - I2 — Stone field shape is camelCase (
stoneType) vs the probe’s snake_case (emitted_at); TS5 capture yieldsundefined. - I3 — Airlock seed metadata
{}→ principalagent_id≠<slug>-bridge-001(the binding the probe and registry assume).
Verification status of these findings
Section titled “Verification status of these findings”- C1: independently re-verified in this pickup against primary source (file + dispatch logic above). High confidence.
- C2, C3, I1, I2, I3: as reported by the final whole-implementation seam review (153 tool uses, full cross-repo read). Not independently re-verified in this pickup; treat as high-confidence pending the remediation round’s per-fix verification.
Root-cause summary
Section titled “Root-cause summary”Two design under-specifications, not task-execution failures:
- Pebble-auth-assumed-but-absent (drives C1, C3) — the design assumed an introspection pattern that does not exist in Pebble.
- wire-time-emit-orphaned (drives C2) — decomposition left the SC-1 emit mechanism unowned between T12 and T16; the T16 prompt references a CLI flag that was never built.
The remaining I-class items are integration-contract mismatches (query-param name, field casing, principal binding) discoverable only at the assembled seam.
Next step
Section titled “Next step”Remediation round (working name SP-1.5), scoped from this doc’s exact file list, driven through the same subagent-driven loop to a green re-review. Because the two root causes are design under-specifications, a short design reconciliation on (1) the Pebble cairnet-emit auth model and (2) the wire-time-emit hook + T16-prompt flag reconciliation should precede coding. Strategy selection (remediate-now vs. design-first) is an operator decision — recorded against this finding when made.
Per MR-2: friction surfaced by a verification gate becomes the input to the next round, not a retrofit into the delivered scope.