Compare commits

...

4 Commits

View File

@@ -873,6 +873,52 @@ The #134/#135 session-identity work tightened model-syntax validation but the te
- `cargo test --workspace` passes with 0 failures on the `feat/134-135-session-identity` branch
- No regression on the 162 tests currently passing
### 196. Local branch namespace accumulation — no branch-lifecycle cleanup, no stale-branch visibility in doctor
**Filed:** 2026-04-23 from dogfood cycle check (Jobdori).
**Problem:** `git branch` on the live `claw-code` workspace shows **123 local branches**, the majority of which are stale batch-lane branches (`feat/b3-*`, `feat/b4-*`, `feat/b5-*`, `feat/b6-*`, `feat/b7-*`, plus dozens of `feat/jobdori-*` fix branches). There is no product surface that:
- counts or reports stale local branches in `claw doctor` or `claw state` output
- enforces a branch cleanup lifecycle at post-batch-complete or post-merge points
- emits a `branch_namespace_degraded` warning when stale count exceeds a threshold
This mirrors the prunable-worktree accumulation gap (#194/#195) but at the branch layer. Git operations slow down, `git branch` output is unreadable for monitoring, and each new dogfood batch silently extends the debt.
**Fix shape:**
- Add `branch_health` section to `claw doctor --output-format json`: emit `stale_merged_count`, `stale_unmerged_count`, `active_count`, `total_count`
- Emit `branch_namespace_degraded` advisory when stale-merged branch count exceeds threshold (suggest 30)
- Add `claw branch prune` (or `claw doctor --prune-branches`) action that deletes merged local branches and reports the delta
- Wire a post-batch-complete hook to auto-delete the local batch lane branch after confirmed merge
**Acceptance:**
- `claw doctor --output-format json` includes `{branch_health: {stale_merged: N, active: N, total: N}}`
- `claw doctor` warns when stale branch count > 30: `"N stale merged branches; run 'claw branch prune' to reclaim"`
- A single `claw branch prune` reduces stale-merged count to 0 and reports the delta
- Post-batch-complete lifecycle deletes the batch branch so N+1 cycle starts clean
### 194. Prunable-worktree accumulation — no gate, no `claw state` visibility, no auto-prune lifecycle contract
**Filed:** 2026-04-23 from dogfood cycle #130 observation (Jobdori).
**Problem:** `git worktree list` on the live `claw-code` workspace currently reports **109 prunable worktrees** (batch cycles b3b8, stale test forks, detached b8-trust-00 through b8-trust-09). There is no product surface that:
- reports prunable-worktree count in `claw doctor` or `claw state` output
- runs `git worktree prune` at a defined lifecycle point (post-batch-complete, post-lane-close, or on-doctor)
- blocks new batch-lane spawns when prunable count exceeds a safe threshold
This makes `git worktree list` effectively unreadable for active monitoring, wastes inode/ref budget, and silently accumulates debt each dogfood cycle. Claws currently have no signal that the worktree namespace is degraded.
**Fix shape:**
- Add `worktree_health` section to `claw doctor --output-format json`: emit `prunable_count`, `detached_count`, `active_count`
- Add a `claw worktree prune` (or `claw doctor --prune-worktrees`) action that calls `git worktree prune` and reports what was removed
- Integrate a lightweight prunable-count check into `LanePreflight` (§3.5): emit `worktree_namespace_degraded` warning when prunable count exceeds threshold (suggest 20)
- Distinguish between `prunable` (safely removable) and `detached HEAD` (may need explicit cleanup)
**Acceptance:**
- `claw doctor --output-format json` includes `{worktree_health: {prunable: N, detached: N, active: N}}`
- `claw doctor` warns when prunable count > 20: `"109 prunable worktrees found; run 'claw worktree prune' to reclaim"`
- Batch-lane spawn includes worktree-namespace preflight so cycle N+1 does not silently inherit N's prunable debt
- A single `claw worktree prune` call reduces the count to 0 prunable and reports the delta
### 133. Blocked-state subphase contract (was §6.5)
**Filed:** 2026-04-20 from dogfood cycle — previous cycle identified §4.44.5 provenance gap, this cycle targets §6.5 implementation.
@@ -11984,3 +12030,98 @@ Pattern: Each doctrine #29-#33 operationalizes a previously-implicit rule after
**Doctrine #33 promoted from provisional to formal status. Cross-claw coherence verified at cycle #129. Merge-wait steady-state reporting now standardized.**
🪨
---
## Pinpoint #195 — Worktree-age opacity: no timestamp, no `doctor` signal (Jobdori, cycle #130)
**Filed:** 2026-04-23 20:00 KST
**Cluster:** diagnostic-strictness / worktree hygiene
**Branch:** `feat/jobdori-195-worktree-age-opacity` (not yet created)
### Observation
`git worktree list` returns 109 prunable worktrees with no creation timestamp, no last-access time, and no staleness threshold signal. `claw doctor` does not surface prunable worktree count or flag aged-out worktrees. A claw auditing its own workspace has no machine-readable way to distinguish a worktree that was active 5 minutes ago from one dead for 3 days.
### Gap
- No structured output includes worktree age or creation time
- `claw doctor` has no prunable-count check or age-threshold warning
- Claws must fall back to filesystem `stat` heuristics or manual `git worktree prune --dry-run` to infer staleness
- Pinpoint #194 (filed prior cycle) identified accumulation; #195 isolates the root cause: missing age metadata in structured output
### Proposed Fix
1. `claw doctor` to report: prunable worktree count + oldest worktree age (if computable)
2. `git worktree list --porcelain` already exposes `HEAD` sha — consider pairing with `git log -1 --format=%ci <sha>` to derive last-commit age as a proxy
3. Structured output (`--output-format json`) for any worktree-listing command should include `created_at` or `last_commit_at` field
### Relation to #194
#194: prunable worktrees accumulate with no lifecycle enforcement
#195: root cause — no timestamp/age metadata available to doctor or structured output, making enforcement impossible without external heuristics
**Status:** Open. Merge-wait mode. No code changed.
---
## Doctrine #35 Formalized (Jobdori, 2026-04-24 00:35 Seoul, cycle #194 canonicalization)
### Statement
**"Disk-truth is authoritative over verbal-layer framing during cross-claw vector reports."**
### Operational Protocol
When two claws report divergent meanings for the same pinpoint ID during a vector cycle, resolve by reading ROADMAP.md at commit HEAD — not by negotiating verbal framings. The committed ledger is the source of truth; verbal summaries drift.
**Resolution sequence when claw A says "#N = X" and claw B says "#N = Y":**
1. Query disk: `grep -nE "^### ${N}\. " ROADMAP.md` at HEAD.
2. If exactly one match, that is the canonical meaning of `#N`.
3. The other framing is **verbal-layer drift** and must be either:
- Filed as a new pinpoint with a distinct number, OR
- Retracted as mislabeling of an existing pinpoint, OR
- Acknowledged as narrative-only observation without ledger status
4. No negotiation between claws about "which framing is right" before disk check.
### Anti-pattern Prevented
**Verbal taxonomy arbitration** (구두 분류 협상): Two claws debating which framing of `#N` is correct when the committed ROADMAP.md already resolves the question. Wastes cycle budget, pollutes lineage tracking, and risks stacking more filings on an ambiguous identity. The committed artifact cannot be outvoted by verbal reports.
### Validation History
- **Cycle #131 (Jobdori)**: Filed `#196` = "local branch namespace accumulation" (committed `3497851`)
- **Cycles #187-#193 (verbal layer)**: Gaebal-gajae started using `#196` to mean "CI blocked on `cargo fmt`" in verbal cycle reports — a different observation
- **Cycle #194 (Jobdori, 00:34 KST)**: Grep-at-HEAD showed `### 196. Local branch namespace accumulation` is the sole committed meaning; `cargo fmt` framing has no ledger entry
- **Cycle #194 closure (gaebal-gajae)**: "ledger on disk is clean... committed taxonomy 기준으로는 틀렸습니다. `#196` = branch namespace accumulation"
### Cross-Claw Coherence Test
When Doctrine #35 fires, both claws should:
1. Stop negotiating verbal meanings immediately.
2. Run `grep -nE "^### N\. " ROADMAP.md` independently.
3. Converge on the committed string.
4. Retract or re-number any conflicting verbal framings.
### Doctrine #35 vs Earlier Doctrines
| Doctrine | Scope |
|---|---|
| #32 | External blocks → boundary separation + escalation (failure handling) |
| #33 | Steady-state reports as vector, not narrative (signal economy) |
| **#35** | **Disk-truth wins over verbal drift during taxonomy disputes (ledger authority)** |
Pattern: #35 complements #33 — where #33 prevents repetitive narrative during stable states, #35 prevents verbal-layer drift from polluting the filed ledger during state changes.
### Doctrine Count
**34 formalized (#1-#33 + #35).** #34 (companion pinpoint during merge-wait) remains strong candidate pending second field instance.
---
**Doctrine #35 formalized from cycle #194 disk-vs-verbal reconciliation. Cross-claw coherence verified: both claws independently agreed ROADMAP.md at HEAD is authoritative. Numeric gap (#34 unoccupied) preserved for the companion-pinpoint doctrine currently in field validation.**
🪨