os-doc-hygiene: post-calibration follow-ups

- Rules: 4 new lifecycle rules for OpenSpec trees (specs/** keep;
  changes/archive/*/ temporary retain 3 / 90d), root + plugins/*
- Fill TBD Purpose placeholders in doc-check + doc-clean specs (the
  doc-check one was a check-run miss: sat under file_length thresholds)
- Report header: "findings: N" + "cleared: K of M evaluated entries"
  (cleared no longer masquerades as files-scanned)
- CLAUDE.md: vault user-guide pointer; fix stale .dochygiene/ state
  path to .cc-os/dochygiene/ (ADR-0027)

Suite: 408 passed, 3 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LAw7YxP71Fk6K9AHNaYPj2
This commit is contained in:
jared 2026-07-15 10:22:41 -04:00
parent fe04297604
commit 807dcc8d90
6 changed files with 60 additions and 7 deletions

View File

@ -31,6 +31,42 @@
"source": "calibration pass #1 (lifecycle-aware-doc-hygiene)",
"note": "Regenerable pytest cache. Judge noted a .gitignore entry may be preferable long-term."
},
{
"glob": "openspec/specs/**",
"lifetime": "keep",
"confirmed_by": "human",
"confirmed_on": "2026-07-15",
"source": "conversation 2026-07-15 (openspec lifecycle rules)",
"note": "Live OpenSpec capability specs — source of truth future changes diff against; never age out."
},
{
"glob": "plugins/*/openspec/specs/**",
"lifetime": "keep",
"confirmed_by": "human",
"confirmed_on": "2026-07-15",
"source": "conversation 2026-07-15 (openspec lifecycle rules)",
"note": "Live OpenSpec capability specs — source of truth future changes diff against; never age out."
},
{
"glob": "openspec/changes/archive/*/",
"lifetime": "temporary",
"retain_recent": 3,
"max_age_days": 90,
"confirmed_by": "human",
"confirmed_on": "2026-07-15",
"source": "conversation 2026-07-15 (openspec lifecycle rules)",
"note": "Archived change dirs are redundant once synced into specs/ and stay recoverable from git history; age out after a quarter."
},
{
"glob": "plugins/*/openspec/changes/archive/*/",
"lifetime": "temporary",
"retain_recent": 3,
"max_age_days": 90,
"confirmed_by": "human",
"confirmed_on": "2026-07-15",
"source": "conversation 2026-07-15 (openspec lifecycle rules)",
"note": "Archived change dirs are redundant once synced into specs/ and stay recoverable from git history; age out after a quarter."
},
{
"glob": "plugins/*/HANDOFF-*.md",
"lifetime": "delete-once-served",

View File

@ -7,6 +7,9 @@ zero-token) on `SessionStart`; checks and cleans on demand via skills.
> Read `PRD.md` first — it is the source of truth for scope, decisions, and
> rationale. This file is the build map.
> Vault user guide (nuance/mental-model, not a how-to):
> `~/Documents/SecondBrain/user-guide/os-doc-hygiene-user-guide.md`.
## Lifecycle layer (2026-07-15)
A rulebook layer sits on top of the scan/classify/clean core: global
@ -31,7 +34,8 @@ Severity scales with **injection frequency** — a stale line in `CLAUDE.md` (au
1. The `SessionStart` hook **only reminds** — it never runs analysis or mutates
anything, and spends no AI tokens. All mutation is user-invoked.
2. Reminder **snoozes** (≤ once/day while stale) via `last_reminded`.
3. State lives **in-project** under gitignored `.dochygiene/`. No global index.
3. State lives **in-project** under gitignored `.cc-os/dochygiene/` (ADR-0027;
legacy `.dochygiene/` is fallback-read only). No global index.
4. **Report rollover**: keep only the latest report. The tool must not become
the bloat it polices.
5. Cleanup is **git-safe**: clean/committed tree required (or auto WIP

View File

@ -1,7 +1,13 @@
# doc-check Specification
## Purpose
TBD - created by archiving change add-check. Update Purpose after archive.
Defines the `/os-doc-hygiene:check` command and the `check` skill it dispatches to:
the deterministic scan-classify-finalize-validate pipeline that turns a project's
docs into a schema-valid machine + human report pair, including rulebook-driven
scanning, judgment-only Sonnet classification, the model-free finalize pass that
authors safety-critical fields, and validation-gated report writes.
## Requirements
### Requirement: `/hygiene` Command Surface

View File

@ -1,7 +1,14 @@
# doc-clean Specification
## Purpose
TBD - created by archiving change add-clean. Update Purpose after archive.
Defines the `clean` skill and patch applier that consume a validated `check`
report and apply its findings git-safely: per-file transactional edits guarded
by content hashes, safety-tier gating that escalates destructive or generative
ops for confirmation, tracked-only true deletion under the lifecycle tier
matrix, and a single reviewable commit per run (with `sweep` composing `check`
then `clean`).
## Requirements
### Requirement: Per-File Transaction with Content-Hash Guard

View File

@ -572,8 +572,8 @@ class ReportBuilder:
lines.append(f"- generated_at: {generated_at}")
lines.append(f"- scope: {', '.join(scope_globs) if scope_globs else '(default)'}")
lines.append(f"- files scanned: {scan.get('files_scanned', 0)}")
lines.append(f"- candidates: {len(entries)}")
lines.append(f"- cleared: {len(cleared)}")
lines.append(f"- findings: {len(entries)}")
lines.append(f"- cleared: {len(cleared)} of {len(shortlist)} evaluated entries")
lines.append("")
stale = [e for e in entries if e["category"].get("class") == "stale"]

View File

@ -367,8 +367,8 @@ class TestClearedFiles:
result = _build(doc_tree, scan_artifact, _proposals())
md = result["human_report"]
# 7 shortlisted, 6 entries → 1 cleared
assert "candidates: 6" in md
assert "cleared: 1" in md
assert "findings: 6" in md
assert "cleared: 1 of 7 evaluated entries" in md
assert "docs/clean.md" in md