# Plan: OBPI-0.0.36-05-skill-prose-sweep-self-close

**OBPI:** OBPI-0.0.36-05-skill-prose-sweep-self-close
**ADR:** ADR-0.0.36-universal-obpi-attestation
**Lane:** Heavy
**Date:** 2026-05-18

## Context

ADR-0.0.36 Decision item #5: "Skill and rule prose sweep across gz-obpi-pipeline,
gz-obpi-reconcile, ghi-close, gz-adr-closeout-ceremony, plus any .gzkit/rules/ or
.claude/rules/ file referencing the deleted lite-lane self-close path; sync to all
vendor mirrors."

Current audit findings:
- `.gzkit/skills/gz-obpi-pipeline/SKILL.md` v6.16.0 — contains "Exception Mode — SELF-CLOSE"
  (lines 131, 137, 158, 203, 545-555, 559, 607, 687): the deprecated SVFR execution path
- `.gzkit/rules/security-sensitivity.md` v0.2.0 — line 18: "is never self-closeable"
  (uses the deprecated concept as if self-close were normally permitted)
- `.gzkit/skills/gz-obpi-reconcile/SKILL.md` — CLEAN, no self-close references
- `.gzkit/skills/ghi-close/SKILL.md` v2.4.0 — CLEAN; dead-letter doctrine present
- `.gzkit/skills/gz-adr-closeout-ceremony/SKILL.md` v7.10.0 — CLEAN; needs dead-letter
  cross-reference added (REQ 7) where GHI lifecycle is discussed
- Vendor mirrors (.claude/skills/, .github/skills/, .agents/skills/): ~30 stale hits
  (will be fixed by sync after canon edits)
- `tests/governance/test_skill_self_close_drift.py` — MISSING (must create)

## Files

### Create
- `tests/governance/test_skill_self_close_drift.py`

### Modify
- `.gzkit/skills/gz-obpi-pipeline/SKILL.md` (bump 6.16.0 → 6.17.0)
- `.gzkit/rules/security-sensitivity.md` (bump 0.2.0 → 0.3.0)
- `.gzkit/skills/gz-adr-closeout-ceremony/SKILL.md` (bump 7.10.0 → 7.11.0)

### Generated by sync (not direct edits)
- `.claude/skills/**`, `.github/skills/**`, `.agents/skills/**`
- `.claude/rules/**`, `.github/instructions/**`

## Steps

### Step 1: TDD RED — Write failing drift test

Create `tests/governance/test_skill_self_close_drift.py`:

- `test_zero_self_close_references_in_canon_and_mirrors` (REQ-0.0.36-05-05):
  - Grep for patterns: "self-clos", "Self-closeable", "self-close-exception",
    "Exception Mode.*SELF.CLOSE", "SVFR", "attestation_type.*self-close"
  - Scan: `.gzkit/skills/`, `.gzkit/rules/`, `.claude/skills/`, `.claude/rules/`,
    `.github/skills/`, `.github/instructions/`, `.agents/skills/`
  - Allow-list: paths containing "OBPI-0.0.36-05", "ADR-0.0.36", "GHI #332",
    "GHI_332", "security-sensitivity" for the "is never self-closeable" → will be
    absent after sweep, so no allow-list needed for that path
  - This test FAILS before edits (expected RED state)

Run to confirm RED: `uv run -m unittest tests.governance.test_skill_self_close_drift -v`

### Step 2: Edit gz-obpi-pipeline/SKILL.md

Remove/replace all Exception Mode (SVFR) / self-close execution path content:

a. Pipeline diagram (lines ~129-137):
   - Remove "Exception: Self-close, then Stage 5" row
   - Remove "Exception mode: Stage 4 = SELF-CLOSE" label line
   - Keep only "Normal mode: Stage 4 = HUMAN GATE (wait for attestation)"

b. Stage 1 step (line ~158): Remove `Exception (SVFR) → set mode=exception` detection.
   Stage 1 always sets mode=normal. Remove the mode detection block entirely.

c. Stage 2 task list (line ~203): Remove the exception-mode last-task variant:
   - Remove "Exception mode: Last task MUST be 'Record OBPI Evidence and Self-Close'"
   - Only Normal mode task list remains

d. Stage 4 Exception Mode section (lines ~545-553):
   - Remove the "#### Exception Mode — SELF-CLOSE" subsection entirely
   - The section begins at "#### Exception Mode — SELF-CLOSE" and ends before
     "**MANDATORY TRANSITION → Stage 5**"

e. Stage 5 references (lines ~559, 607):
   - Replace "After attestation (Normal) or self-close (Exception):" → "After attestation:"
   - Remove "Exception mode: pass --attestation-text 'self-close-exception'" variant

f. Parallel Execution section (line ~687-694):
   - Remove "1. ADR has ## Execution Mode: Exception (SVFR) section (granted at ADR Defense)"
   - This section can stay but should clarify that Exception SVFR is for PARALLEL
     execution coordination only, NOT for skipping human attestation. Or simplify to
     note that parallel OBPIs each require their own human attestation.

g. Add ghi-close dead-letter cross-reference (REQ 7):
   - In Stage 5 or wherever GHI lifecycle is discussed, add a note referencing
     `ghi-close` v2.4.0 "NEVER, EVER, EVER dead-letter" doctrine for any GHI
     closures that emerge from pipeline execution.

h. Bump frontmatter: `skill-version: "6.16.0"` → `skill-version: "6.17.0"`

### Step 3: Edit security-sensitivity.md rule

Update "is never self-closeable" language:
- Current: "A brief carrying `sensitivity: security` is never self-closeable."
- Replace with: "A brief carrying `sensitivity: security` always requires human
  attestation for completion — consistent with the universal attestation rule in
  ADR-0.0.36."
- Bump rule-version comment AND blockquote: `0.2.0` → `0.3.0`

### Step 4: Edit gz-adr-closeout-ceremony/SKILL.md (REQ 7 cross-reference)

- Find the section discussing GHI close comments or GHI lifecycle (near line 246)
- Add a brief cross-reference: where GHIs are closed as part of ADR closeout,
  reference `ghi-close` v2.4.0 "NEVER, EVER, EVER dead-letter" doctrine —
  a GHI cited in an ADR's closeout must resolve to a registered, traceable artifact.
- Bump frontmatter: `skill-version: "7.10.0"` → `skill-version: "7.11.0"`

### Step 5: Run gz agent sync

`uv run gz agent sync control-surfaces`

Confirm: `git diff --stat` shows coordinated canon + mirror surface edits.
Check: no remaining self-close references in vendor mirrors.

### Step 6: TDD GREEN — Verify tests pass

`uv run -m unittest tests.governance.test_skill_self_close_drift -v`
`uv run -m unittest -q`  (full suite)

### Step 7: Quality gates

```bash
uv run gz arb ruff
uv run gz arb typecheck
uv run gz arb step --name unittest -- uv run -m unittest -q
uv run gz arb step --name mkdocs -- uv run mkdocs build --strict
```

## Verification

```bash
# Zero self-close hits in canon + mirrors (allow-listed refs only)
rg -i "self.clos|SVFR|self-close-exception" .gzkit/skills/ .gzkit/rules/ .claude/skills/ .claude/rules/ .github/skills/ .github/instructions/ .agents/skills/

# Drift test
uv run -m unittest tests.governance.test_skill_self_close_drift -v

# Sync ceremony
uv run gz agent sync control-surfaces
git diff --stat
```

## Destination-in-mind disclosure (Plan-Before-Exploration)

Before writing this plan, the conclusion already formed was: gz-obpi-pipeline
is the primary file needing the Exception Mode removal; security-sensitivity.md
needs a phrasing update; the vendor mirrors need sync. Approach: TDD RED first,
then canon edits, then sync.

## Rejected alternatives

1. **Leave the Exception SVFR mode in the skill** — rejected because ADR-0.0.36
   Decision says "There is no self-close path." The SVFR mode is exactly that path.
2. **Update vendor mirrors directly** — rejected because skill-surface-sync rule
   mandates sync-only authoring for vendor mirrors.
3. **Skip the new test module** — rejected because REQ 5 / REQ 6 explicitly
   require `test_skill_self_close_drift.py`.
