---
mode: CREATE
adr_id: ADR-0.29.0
branch: main
timestamp: "2026-06-06T11:02:44Z"
agent: claude-code
obpi_id:
session_id:
continues_from:
---

<!-- Handoff document for ADR-0.29.0 — created by claude-code at 2026-06-06T11:02:44Z -->

## ⚠️ This handoff ADVISES next moves — it is NOT authorization to execute them

**Read this before anything else.** A handoff records a *proposed* plan and its
context. It is **NOT** a clearance to unilaterally execute that plan. On resume —
at **every** freshness level, Fresh included — you MUST:

1. Present the advised next steps and current state to the operator.
2. **Obtain explicit operator authorization before executing any of them** — no
   file mutation, no `gz` ceremony, no migration until the operator says go.
3. Treat the human-as-final-witness doctrine as binding from the first step: you
   advise; the operator rules; you note variance and stop.

Barreling into execution from this document is the exact failure this handoff
exists to prevent. The plan is the destination; operator authorization is the
ignition.

## Current State Summary

Three threads moved this session; the tree is clean and synced (`0/0` vs
`origin/main`, HEAD `25ec87d6`).

1. **OBPI-0.0.37-08-obpi-complete-gate — COMPLETE.** The Stage-5
   reconcile-receipt fail-close gate + `--accept-stale-reconciliation --reason`
   escape hatch (CIC-2 in-flight-drift half) shipped via the full
   `gz-obpi-pipeline`: attested (operator-verbatim, Jeffry Babb), reconcile
   PASS, two git-syncs committed and pushed. Completion required
   `--accept-security-floor` (the brief touches the `auth_boundaries` security
   surface and the scanner slot is structurally unfilled) — the operator chose
   Path B (override + declare `sensitivity: security`) over stopping. Several
   in-flight corrections landed to complete it: brief FAIL-CLOSED #8 demoted to
   a scope-boundary note (req_count drift), REQ-07 classified SUPPORT-kind with
   a behave waiver, the Stage-5 gate consolidated onto OBPI-07's canonical
   allowlist helpers (closed a Stage-1/Stage-5 divergence), and a xenon-D
   refactor of `_enforce_reconcile_receipt_gate`.

2. **GHI #583 → ADR-0.29.0 — BOOKED, awaiting implementation.** The security
   floor's structural gap (coarse whole-file `auth_boundaries` registration +
   un-witnessed override) was designed via `gz-design` and booked as
   **ADR-0.29.0** (feature, heavy, `sensitivity: security`, status Proposed,
   evaluated 4.00/4.0). Three OBPIs authored and registered. GHI #583 closed
   `superseded` against it (dimension A — the scanner — routed to
   `ADR-pool.agentic-security-review`). Package committed and pushed.

3. **GHI #584 — OPEN, blocked on operator strategy.** Investigating the orphan
   events flagged during ADR-0.29.0 authoring revealed **233 orphaned
   `obpi_created` ledger events across 24 feature ADRs (0.27.0–0.51.0)** — a
   systemic Layer-2/Layer-1 incoherence, not the 7 first seen. Filed
   open-with-blocker; remediation needs a per-ADR disposition call.

## Important Context

- **ADR-0.29.0 mechanism is module-extraction, NOT symbol-detection.** The
  security floor detects on a brief's declared Allowed *Paths*, never diffs;
  symbol-level detection would require re-architecting the brief contract
  (allowed-symbols) and was rejected. Precision is achieved by MOVING the
  auth-bearing security-scan cluster into its own registered module.
- **The narrow extraction boundary is operator-chosen.** Keep `adr_audit.py`
  registered (it holds the genuine who-must-attest / authenticity authority);
  extract only the security-scan cluster from `obpi_complete.py` into
  `obpi_security_gate.py`; de-register `obpi_complete.py` + `obpi_cmd.py`. The
  shakiest assumption (recorded in the ADR): that `obpi_complete.py`'s
  receipt-binding / coverage gates are mere wrappers delegating to
  `adr_audit.py` — **OBPI-0.29.0-01 MUST verify this** before de-registering;
  any local-authority function must move into `obpi_security_gate.py`.
- **Editing `data/security_surfaces.json` self-requires `sensitivity: security`**
  — all three OBPI-0.29.0 briefs already carry it. Expect every OBPI-0.29.0
  completion to re-encounter the security floor; the escape is the same
  `--accept-security-floor` (until this very ADR makes the registration precise,
  the floor still fires on these auth-surface edits — which is correct here).
- **OBPI completion lessons baked in (learned the hard way on 0.0.37-08):** keep
  `## Requirements (FAIL-CLOSED)` count == `## Acceptance Criteria` REQ count;
  tag every REQ `[behavior|support|structural-fence]`; SUPPORT REQs need a
  proof clause with both a `gz validate --<scope>` citation and a ledger-event
  keyword; SUPPORT REQs that overlap a heavy-lane brief need a
  `data/behave_coverage_waivers.json` entry (`default_rationale` code +
  `waivers` OBPI-id entry).
- **`security_floor_overridden` (OBPI-0.29.0-02)** mirrors the existing
  `brief_reconcile_drift_overridden` five-surface pattern (factory in
  `src/gzkit/ledger_events.py`, Pydantic model + discriminated-union member in
  `src/gzkit/events.py`, schema in BOTH `.gzkit/schemas/ledger_events.json` and
  `src/gzkit/schemas/ledger.json`, `_NO_GRAPH_IMPACT` waiver in
  `src/gzkit/governance/trust_audits/events.py`). Use it as the worked exemplar.

## Decisions Made

- **Decision:** Complete OBPI-0.0.37-08 via `--accept-security-floor` (Path B)
  rather than stopping.
  **Rationale:** the change is additive/defensive (a new fail-close gate whose
  only bypass is ledger-witnessed) and touches no who-can-attest semantics; the
  scanner slot is structurally unfilled so the override is the GHI #462
  deadlock escape; Gate-5 human attestation was preserved.
  **Alternatives rejected:** stop-and-reassess (would strand the OBPI and the
  ADR-0.0.37 cluster behind an unrelated scanner ADR).

- **Decision:** Fix the GHI #583 structural gap now as ADR-0.29.0 (feature
  kind), module-extraction mechanism, narrow boundary, with dimension C
  (witnessed override) folded in.
  **Rationale:** ADR-0.0.22 is the foundation security invariant; this is a
  mechanical-defense refinement of its detection mechanism (feature, per
  ports-point-to-invariance / adapters-are-features); precision is the leverage
  fix; witnessing shares the extracted surface's commit-window.
  **Alternatives rejected:** symbol/AST-level detection (path-based detection
  makes it disproportionate); foundation kind (66 foundation ADRs already;
  invariance test fails); keeping C separate (incoherent to fix the surface but
  leave the override on it un-witnessed).

- **Decision:** Two REQs folded into ADR-0.29.0 as acceptance criteria — the
  2am "name the matched surface + category" message (OBPI-01) and the
  drift-back validator `gz validate --auth-surface-coherence` (OBPI-03).
  **Rationale:** they mechanize the two shakiest forcing-function findings
  (assumption-surfacing delegation risk; WWHTBT drift-back risk).
  **Alternatives rejected:** leaving them as prose-only consequences.

- **Decision:** File the 233-orphan finding as GHI #584 open-with-blocker, not
  an inline fix.
  **Rationale:** 24 ADRs span dead / deferred / to-be-built; remediation
  differs per ADR and is a write-forward ledger reconciliation needing operator
  strategy.
  **Alternatives rejected:** withdrawing all 233 inline (would mass-apply one
  disposition to a heterogeneous set).

## Immediate Next Steps

ADVISORY ONLY — present these and wait for operator authorization before acting.

1. **Decide the GHI #584 reconciliation strategy** (the operator's open
   question): withdraw / accept-as-parked / re-author per ADR, or a triage pass
   classifying the 24 ADRs (0.27.0–0.51.0) into those three buckets, and whether
   it routes to a governance reconciliation chore or its own ADR. See the
   blocker comment on GHI #584.
2. **Decide whether to start implementing ADR-0.29.0.** If yes, begin with
   **OBPI-0.29.0-01** (the MVP that kills the false-positive deadlock) via
   `/gz-obpi-pipeline OBPI-0.29.0-01-precise-auth-boundaries-registration`.
   First substantive step inside it: verify each de-registered gate in
   `src/gzkit/commands/obpi_complete.py` delegates its auth decision to
   `adr_audit.py` (the assumption-surfacing REQ) before narrowing the registry.
3. **(Forced subsequent decision, lower priority)** consider promoting
   `ADR-pool.agentic-security-review` (GHI #583 dimension A) — the floor will be
   precise after ADR-0.29.0 but still incapable of an actual scan until the
   canonical slot is filled.

## Pending Work / Open Loops

- **GHI #583** — closed superseded; dimension A (scanner) remains parked in
  `ADR-pool.agentic-security-review`.
- **GHI #584** — open; 233 orphan `obpi_created` events await an operator
  reconciliation strategy.
- **ADR-0.29.0** — status Proposed; three OBPIs Pending, none implemented. Needs
  a review cadence decision for `security_floor_overridden` events (named as a
  forced subsequent decision in the ADR) so witnessing does not become theater.
- No uncommitted work; nothing mid-edit.

## Verification Checklist

- [ ] `git branch --show-current` returns `main`
- [ ] `git rev-list --left-right --count origin/main...main` returns `0	0` (synced)
- [ ] `git status --short` is empty (clean tree)
- [ ] `uv run gz adr status ADR-0.29.0 --json` shows status Proposed, 3 OBPIs
- [ ] `uv run gz obpi validate --adr ADR-0.29.0 --authored` passes 3/3
- [ ] `gh issue view 584 --json state` shows OPEN; `gh issue view 583` shows CLOSED
- [ ] `uv run gz register-adrs 2>&1 | grep -ci orphan` still reports the 233 (unchanged until #584 is actioned)

## Evidence / Artifacts

- `docs/design/adr/pre-release/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override.md` — the booked ADR body (Decision, Boundary Invariants, 7 forcing functions, rejected symbol-detection alternative)
- `docs/design/adr/pre-release/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override/obpis/OBPI-0.29.0-01-precise-auth-boundaries-registration.md` — extract + re-point + delegation-verification + 2am message
- `docs/design/adr/pre-release/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override/obpis/OBPI-0.29.0-02-security-floor-overridden-event.md` — witnessed ledger event across five surfaces
- `docs/design/adr/pre-release/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override/obpis/OBPI-0.29.0-03-auth-surface-coherence-validator.md` — drift-back validator + docs
- `docs/design/adr/pre-release/ADR-0.29.0-precise-auth-boundaries-registration-and-witnessed-floor-override/EVALUATION_SCORECARD.md` — 4.00/4.0 GO
- `docs/design/adr/foundation/ADR-0.0.37-constitutional-invariant-composition/obpis/OBPI-0.0.37-08-obpi-complete-gate.md` — completed brief (Status Completed, attested)
- `data/security_surfaces.json` — current `auth_boundaries` whole-file registration that ADR-0.29.0 makes precise
- `.gzkit/insights/agent-insights.jsonl` — course-correction record for the OBPI-0.0.37-08 security-floor stop-and-reassess decision

## Environment State

- Platform darwin; Python 3.13 via `uv`; CLI entrypoint handles UTF-8 (never prefix `uv run gz` with `PYTHONUTF8=1`).
- GitHub remote `tvproductions/gzkit`; `gh` authenticated.
- Operator attribution: use the name `Jeffry Babb` only (never the personal email) in any repo-bound artifact.
