feat(doc-sync): MINOR-shape oracle + fail-loud commit (strengthen MINOR gate)

(1) lib/doc-shape.sh — deterministic shape oracle re-checks each LLM-classified
MINOR patch before the silent auto-commit; a shape-suspect patch (added heading
/ oversize / new file / non-doc) escalates to the EXISTING SIGNIFICANT gate.
Genuine MINOR still auto-commits (zero friction, BDR-036 preserved). A structural
floor under the LLM call, not a semantic SIGNIFICANT-detector (BDR-040).

(2) lib/doc-commit.sh — guard the commit itself: a rejected git commit (pre-commit
hook / protected branch / signing) now fails loud with exit 5 + empty stdout,
instead of a false "committed" + the previous HEAD's hash + exit 0 that left docs
silently uncommitted (LRN-071, 3rd occurrence of the swallowed-commit pattern
after LRN-066 and LRN-068/BLK-012).

Wired doc-syncer STEP A4 (whole-set escalation: no=revert all, select=keep subset)
+ doc-commit.md (rc-5 consumer row + ACKNOWLEDGMENTS coherence).
TDD RED->GREEN: run-doc-commit.sh 32/32, run-doc-shape.sh 19/19, behavioral C/D.
shellcheck clean. Branch-guard (3) deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6bUdvHnajCNzgVQefZowj
This commit is contained in:
Bastien Chanot
2026-06-29 17:41:24 +02:00
co-authored by Claude Opus 4.8
parent 4da2b905de
commit 09f5b28d99
8 changed files with 398 additions and 11 deletions
+20 -3
View File
@@ -792,9 +792,26 @@ Categorize:
- **NONE** → exit completely silent. No output (no `PATCHED_FILES` → the doc-commit step
sees an empty list and no-ops).
- **MINOR** → patch silently. One-line confirmation per file:
`doc-sync: patched <file> (<what changed>)`
- **SIGNIFICANT** → surface to user before patching:
- **MINOR** → patch, then VERIFY SHAPE with the deterministic oracle BEFORE the
silent auto-commit. The LLM made the MINOR call; the oracle re-checks that the
patch's SHAPE actually holds, catching a SIGNIFICANT mislabeled MINOR (RISK-1):
```
bash "$HOME/.claude/lib/doc-shape.sh" check <every patched path> # all paths, ONE call
```
- **exit 0** (within the MINOR envelope) → genuine MINOR: keep the silent patch.
One-line confirmation per file: `doc-sync: patched <file> (<what changed>)`.
Proceed to `PATCHED_FILES` + the doc-commit step.
- **exit 1** (shape EXCEEDS — oracle stderr names the offender(s) and why) → the
deterministic oracle OVERRULES the LLM's MINOR call (LRN-046). Do NOT auto-commit.
ESCALATE the WHOLE patch set to the SIGNIFICANT gate below — one file out of
shape makes the atomic MINOR classification suspect. Surface every patched file
+ the oracle's reason, then the gate: on `no` → revert ALL
(`git checkout -- <each patched path>`); on `select` → keep the chosen files,
revert the rest. The oracle catches STRUCTURAL/size significance, not semantic —
it is a deterministic floor, not a full SIGNIFICANT-detector.
- **exit 2/3** (oracle usage error / not a git repo) → do NOT auto-commit on a
broken check; treat as exit 1 and escalate.
- **SIGNIFICANT** (or a MINOR the oracle escalated) → surface to user before patching:
```
DOC SYNC — drift detected after this session:
<list of significant items with proposed fixes>