cc-os/plugins/os-doc-hygiene/openspec/changes/lifecycle-aware-doc-hygiene/tasks.md

5.6 KiB

Tasks: lifecycle-aware-doc-hygiene

1. Rulebook loader (TDD)

  • 1.1 Red: tests for scripts/rulebook.py — envelope parsing, hard-fail on unparseable JSON/unknown schema_version, skip-and-warn on invalid/unconfirmed rules (missing confirmed_by → inactive), glob compilation via glob.translate(recursive=True, include_hidden=True) with a Python ≥3.13 version check + clear error
  • 1.2 Red: tests for add-only merge + two-axis precedence (project file > project dir > global file > global dir; longest pattern, then last-defined), keep-shadowing neutralization, unmatched → None, file-vs-directory match distinction, IGNORE-sentinel rules (no lifetime → zero-emission prune)
  • 1.3 Green: implement scripts/rulebook.py (stdlib-only, single query surface per design §1)
  • 1.4 Author shipped rulebook.json (global): IGNORE seeds graphify-out/**, .dochygiene/**; envelope {"schema_version": 1, "rules": [...]}

2. Scanner lifecycle signals (TDD)

  • 2.1 Red: scanner tests — directory-rule match prunes the walk and emits one aggregate entry with lifecycle signal; IGNORE-surface rules prune with zero emission; file-rule match attaches lifecycle signal alongside existing signals; unmatched files flow through unchanged
  • 2.2 Red: temporary-tier tests — age from git log -1 --format=%cI, mtime fallback for untracked, directory-inode mtime for untracked dirs (no recursive walk); retain-recent-N grouping by rule match entry, newest 3 kept regardless of age, 4th+ deleted past max_age_days
  • 2.3 Red: delete-once-served tests — served_when_path (with {id}/{name} substitution) proven from filesystem → deterministic served signal; served_when free text → classifier-judged marker only
  • 2.4 Green: implement lifecycle signal class + rulebook consumption + tier computations in scanner.py

3. Report schema + tier derivation (TDD)

  • 3.1 Red: report_builder.py/validate_report.py tests — new op kinds delete/extract-then-delete in KIND_TABLE; lifecycle entry fields (rule_ref, lifetime, served evidence, git_state); derive_safety_tier lifecycle branch (scanner-proven + tracked+clean = auto; dirty/untracked/classifier-judged = confirm; existing branches unchanged); build-time git ls-files + dirty check populates git_state
  • 3.2 Red: promotion-candidates tests — deterministic promotion_candidates report section from conventions.json for classifier-judged rules (no model)
  • 3.3 Green: implement report_builder/validate_report extensions
  • 3.4 Author conventions.json (v1: archive-bucket, status-frontmatter exactly)

4. Clean applier deletion ops (TDD)

  • 4.1 Red: patch_applier.py tests — apply-time re-verification (git ls-files + dirty per path; downgrade to skip git-state-changed-since-check on mismatch); delete = git rm/git rm -r staged into the single hygiene commit; extract-then-delete fails closed per entry when extraction fails; confirm-tier gating for lifecycle ops
  • 4.2 Green: implement applier delete/extract-then-delete handling

5. Skills wiring

  • 5.1 Update skills/check/SKILL.md — lifecycle signals into classification, promotion-candidates section in reports
  • 5.2 Update skills/clean/SKILL.md — lifecycle op application, confirm gates, extraction routing (repo-durable → docs/ADR/CLAUDE.md via existing generative path; cross-repo → /os-vault:write from the skill, not the applier)
  • 5.3 Read ~/Documents/SecondBrain/cc-os-plugin-skill-naming-convention.md, then create skills/calibrate/SKILL.md (NO name: frontmatter) implementing the 6-step protocol: deterministic cluster-and-sample helper script, haiku nomination, strong-model batched judge (confirm/reject/amend/consult), 5-element human rule report before persistence, persistence rules (project on confirm, global human-gated, removals HITL-only), retest loop (<2 rules or <10% shrink, cap 3)
  • 5.4 Red-green the deterministic calibrate helpers (clustering/sampling, rule-report assembly, class-not-path + prefer-narrower checks)
  • 5.5 Full test suite green (existing 286 + new); run bin/refresh-plugins

6. Calibration pass #1 (cc-os, spec §9)

  • 6.1 Write the protected set fixed before the pass (eval scenarios/reserve/fixture/judge-rubric, openspec/specs/, docs/adr/**, mirrored .claude/.codex/.pi skill dirs, CLAUDE.md, plugin source)
  • 6.2 Run :calibrate against cc-os with #41 cc-os seed rows HELD OUT of judge intake (pass #1 one-off)
  • 6.3 Grade: protected-set hard gate (no persisted rule glob matches a protected path); recall floor 8/10 with 4 mandatory (autoresearch/<run-id>/, HANDOFF-*.md, docs/adr/migration-report.md, .dochygiene/report.{json,md}); graphify-out is void-not-miss; spot-check novel matches (wrong novel match → rule adjustment + retest round)
  • 6.4 Record pass results in the change; persist confirmed cc-os rules to .dochygiene-rules.json (repo root, committed) — human-approved and persisted 2026-07-15

7. Records

  • 7.1 One-line headline in docs/implementation-status.md + detail in docs/implementation-status/os-doc-hygiene.md. (No docs/memory-system/04-build-plan.md step covers this effort — tracked by wayfinder map #31, not the memory-system build plan; nothing to mark there.)
  • 7.2 Updated plugin CLAUDE.md/scripts/CONTEXT.md for the new lifecycle layer (two prune mechanisms documented). invariants.md #3 (.cc-os/dochygiene/ per ADR-0027, legacy fallback noted) and #9 (rulebook IGNORE-sentinel added to the never-flagged enumeration) corrected with explicit human approval 2026-07-15 per the META-RULE.