Wayfinder map: lifecycle-aware doc hygiene (ruthless os-doc-hygiene) #31

Open
opened 2026-07-14 16:50:18 +00:00 by jared · 0 comments
Owner

Destination

A locked design — spec + ADR set — for lifecycle-aware doc hygiene in os-doc-hygiene: rulebook (global + per-project overrides), three-lifetime taxonomy, extended check/clean pipeline, and the new :calibrate skill; validated against one calibration project.

Notes

Domain: cc-os plugin design (plugins/os-doc-hygiene). Skills to consult: /grilling, /domain-modeling for HITL tickets; /os-adr:find before design decisions; /os-adr:create for the destination ADRs. Standing preferences: markdown-as-truth, Ruby/Sandi-Metz for new CLIs (existing pipeline is Python — extend in kind), lowercase-kebab-case filenames. Source inspiration: reddit clipping "How are you managing spec-driven AI workflows without ending up with tons of docs" (~/Documents/Main/Clippings/). Blocking is expressed as a "Blocked by #N" line in ticket bodies (tea/Forgejo, no native dependencies).

Decisions so far

  • Destination: spec + ADR for lifecycle-aware doc hygiene — spec+ADR destination; recurring skill stays fog

  • Taxonomy: three lifetimes plus extract modifier — keep / temporary / delete-once-served + extract modifier

  • Rulebook is global in the plugin with per-project overrides — global rulebook in plugin, thin per-project overrides

  • Delete means true git deletion, no archive dirs — git history is the archive; confirm gate for untracked

  • Extraction routes through existing knowledge routing — extract via existing repo/vault routing, no new piles

  • Extend check/clean pipeline; new skill is :calibrate — extend scanner/report pipeline; only new skill is :calibrate

  • Directory-level glob rules are first-class — glob/directory rules first-class, file rules override

  • Weak-model discoveries need strong-model confirmation — Opus/Fable must confirm weak-model rule discoveries

  • Inventory clutter patterns across local projects to seed the rulebook — 19 seed rule candidates cataloged across 4 repos; findings on branch research/clutter-inventory (docs/research/clutter-pattern-inventory.md)

  • Design the rulebook schema — JSON; global rulebook.json in plugin + committed repo-root .dochygiene-rules.json override (ADR flagged); glob.translate globs; source-then-specificity precedence; unmatched = unmanaged; lifecycle signal class; skip-and-warn validation

  • Decide deletion confirm-gates and temporary-tier durations — rule-backed deletes of tracked+clean files are auto (human-only confirm: true escape hatch); dirty/untracked stay confirm; graphify-out/** + .dochygiene/** are an IGNORE surface, never walked (gitignored ≠ deletable); temporary = retain_recent: 3 + max_age_days: 3 on git-commit age; delete-once-served splits into scanner-proven served_when_path (auto) vs classifier-judged served_when (forced confirm)

  • Design the :calibrate protocol — cluster-and-sample over unmatched files; haiku nominates bare glob+lifetime per cluster, one batched Opus/Fable judge gathers its own evidence and authors final entries; verdicts confirm/reject/amend/consult (consult mandatory when artifact purpose is unclear — regenerable ≠ removable); project rules land on judge confirmation, global-rulebook writes are human-gated (cross-repo write into cc-os — ADR in #46); rule removals HITL-only with recorded reasoning; retest loop stops at <2 new rules or <10% unmatched shrink, hard cap 3 rounds; #41 seeds enter at judge intake

  • Design ignore-surface propagation (.graphifyignore etc.) — NO propagation: a rule never writes into another tool's ignore surface. propagate_ignore dropped from #40's schema (#46 must assemble without it). .dochygiene-ignore stays a hand-authored human escape hatch (rulebook already IS the scanner's skip instruction); .graphifyignore ownership stays with os-vault:onboard-project per ADR-017; memsearch has no such surface. Glob-dialect mismatch dissolves — nothing is ever translated.

  • Pick calibration project #1 and success criteria — calibration #1 = cc-os (prove the protocol works before testing generalization). Validated = (a) HARD GATE: the pass fails if any rule persisted to the rulebook has a glob matching a protected path, whatever its behavior tier — exploration-time consult on a protected path is free and counts as correct; (b) protected set derived from cc-os's pre-existing declarations (eval scenarios/reserves, openspec/specs/, docs/adr/, mirrored skill dirs, plugin source), human-edited by @jared before the run, never revised after seeing proposals; (c) recall floor 8 of 10 against a SEALED answer key — all ten cc-os rows of #41 (graphify-out/ void: already an ignore surface per #43), with four mandatory (autoresearch/<run-id>/, HANDOFF-*.md, docs/adr/migration-report.md, .dochygiene/report.*); the cc-os seeds are held out of judge intake for this pass only (scoped one-off deviation from #42, else it's an open-book exam); (d) novel matches are expected, human-spot-checked, and a wrong one triggers a retest round rather than failing the pass. Retest cap already settled in #42. Rule-authoring rules handed to #46: report the glob verbatim + matches + near-misses + tier + plain-language why, before persisting; a glob may hardcode a conventional name (PRD.md) but never an instance identifier (classic-260703-1522); when two globs are both defensible take the narrower — too-narrow fails safe and self-heals next pass, too-broad deletes a keeper. PRD.md is delete-once-served + forced confirm (purpose-triggered), not temporary (age would delete the PRD of an unbuilt feature).

  • Age signal for the temporary tier: commit-age vs mtime for untracked artifacts#43 mtime-fallback stands; directory-entry age = directory inode mtime (no schema change)

  • Catalog recommended completion conventions (determinism-promotion path) — v1 catalog = archive-bucket + status-frontmatter, in plugin conventions.json (global-only); :check names promotion candidates every report, :calibrate may draft the adoption for human approval

  • Assemble the spec + ADR set — destination reached: plugins/os-doc-hygiene/lifecycle-spec.md consolidates #32–#48 (schema minus propagate_ignore, seed hold-out recorded as pass-#1-only); ADR-0038 (repo-root .dochygiene-rules.json), ADR-0039 (evidence-quality deletion tiers), ADR-0040 (no ignore propagation), ADR-0041 (determinism promotion + conventions.json)

Not yet specified

  • A recurring standalone "categorize-and-learn" skill run occasionally per project, which offers to hunt newly confirmed rule types across other projects — depends on :calibrate protocol proving out.
  • Rollout across further projects after calibration project #1 (revise/retest loop until diminishing returns).
  • Interaction with the upcoming os-sdlc plugin's spec lifecycle (openspec archive is #43's canonical served_when_path example; what os-sdlc's own lifecycle events add is still open).
  • Exact report-schema field changes and eval discipline for the new lifecycle classifier.

Out of scope

  • Bulk-cleaning every project as part of this map — only calibration project #1 is in scope; wider rollout is a follow-on effort.
## Destination A locked design — spec + ADR set — for lifecycle-aware doc hygiene in os-doc-hygiene: rulebook (global + per-project overrides), three-lifetime taxonomy, extended check/clean pipeline, and the new :calibrate skill; validated against one calibration project. ## Notes Domain: cc-os plugin design (plugins/os-doc-hygiene). Skills to consult: /grilling, /domain-modeling for HITL tickets; /os-adr:find before design decisions; /os-adr:create for the destination ADRs. Standing preferences: markdown-as-truth, Ruby/Sandi-Metz for new CLIs (existing pipeline is Python — extend in kind), lowercase-kebab-case filenames. Source inspiration: reddit clipping "How are you managing spec-driven AI workflows without ending up with tons of docs" (~/Documents/Main/Clippings/). Blocking is expressed as a "Blocked by #N" line in ticket bodies (tea/Forgejo, no native dependencies). ## Decisions so far - [Destination: spec + ADR for lifecycle-aware doc hygiene](https://forgejo.swansoncloud.com/jared/cc-os/issues/32) — spec+ADR destination; recurring skill stays fog - [Taxonomy: three lifetimes plus extract modifier](https://forgejo.swansoncloud.com/jared/cc-os/issues/33) — keep / temporary / delete-once-served + extract modifier - [Rulebook is global in the plugin with per-project overrides](https://forgejo.swansoncloud.com/jared/cc-os/issues/34) — global rulebook in plugin, thin per-project overrides - [Delete means true git deletion, no archive dirs](https://forgejo.swansoncloud.com/jared/cc-os/issues/35) — git history is the archive; confirm gate for untracked - [Extraction routes through existing knowledge routing](https://forgejo.swansoncloud.com/jared/cc-os/issues/36) — extract via existing repo/vault routing, no new piles - [Extend check/clean pipeline; new skill is :calibrate](https://forgejo.swansoncloud.com/jared/cc-os/issues/37) — extend scanner/report pipeline; only new skill is :calibrate - [Directory-level glob rules are first-class](https://forgejo.swansoncloud.com/jared/cc-os/issues/38) — glob/directory rules first-class, file rules override - [Weak-model discoveries need strong-model confirmation](https://forgejo.swansoncloud.com/jared/cc-os/issues/39) — Opus/Fable must confirm weak-model rule discoveries - [Inventory clutter patterns across local projects to seed the rulebook](https://forgejo.swansoncloud.com/jared/cc-os/issues/41) — 19 seed rule candidates cataloged across 4 repos; findings on branch `research/clutter-inventory` (`docs/research/clutter-pattern-inventory.md`) - [Design the rulebook schema](https://forgejo.swansoncloud.com/jared/cc-os/issues/40) — JSON; global `rulebook.json` in plugin + committed repo-root `.dochygiene-rules.json` override (ADR flagged); `glob.translate` globs; source-then-specificity precedence; unmatched = unmanaged; lifecycle signal class; skip-and-warn validation - [Decide deletion confirm-gates and temporary-tier durations](https://forgejo.swansoncloud.com/jared/cc-os/issues/43) — rule-backed deletes of tracked+clean files are `auto` (human-only `confirm: true` escape hatch); dirty/untracked stay confirm; `graphify-out/**` + `.dochygiene/**` are an IGNORE surface, never walked (gitignored ≠ deletable); `temporary` = `retain_recent: 3` + `max_age_days: 3` on git-commit age; `delete-once-served` splits into scanner-proven `served_when_path` (auto) vs classifier-judged `served_when` (forced confirm) - [Design the :calibrate protocol](https://forgejo.swansoncloud.com/jared/cc-os/issues/42) — cluster-and-sample over unmatched files; haiku nominates bare glob+lifetime per cluster, one batched Opus/Fable judge gathers its own evidence and authors final entries; verdicts confirm/reject/amend/**consult** (consult mandatory when artifact purpose is unclear — regenerable ≠ removable); project rules land on judge confirmation, global-rulebook writes are human-gated (cross-repo write into cc-os — ADR in #46); rule removals HITL-only with recorded reasoning; retest loop stops at <2 new rules or <10% unmatched shrink, hard cap 3 rounds; #41 seeds enter at judge intake - [Design ignore-surface propagation (.graphifyignore etc.)](https://forgejo.swansoncloud.com/jared/cc-os/issues/44) — NO propagation: a rule never writes into another tool's ignore surface. `propagate_ignore` **dropped from #40's schema** (#46 must assemble without it). `.dochygiene-ignore` stays a hand-authored human escape hatch (rulebook already IS the scanner's skip instruction); `.graphifyignore` ownership stays with `os-vault:onboard-project` per ADR-017; memsearch has no such surface. Glob-dialect mismatch dissolves — nothing is ever translated. - [Pick calibration project #1 and success criteria](https://forgejo.swansoncloud.com/jared/cc-os/issues/45) — calibration #1 = **cc-os** (prove the protocol works before testing generalization). **Validated** = (a) HARD GATE: the pass fails if any rule *persisted to the rulebook* has a glob matching a protected path, whatever its behavior tier — exploration-time `consult` on a protected path is free and counts as correct; (b) protected set derived from cc-os's pre-existing declarations (eval scenarios/reserves, `openspec/specs/`, `docs/adr/`, mirrored skill dirs, plugin source), **human-edited by @jared before the run**, never revised after seeing proposals; (c) **recall floor 8 of 10** against a SEALED answer key — all ten cc-os rows of #41 (`graphify-out/` void: already an ignore surface per #43), with four **mandatory** (`autoresearch/<run-id>/`, `HANDOFF-*.md`, `docs/adr/migration-report.md`, `.dochygiene/report.*`); the cc-os seeds are **held out of judge intake for this pass only** (scoped one-off deviation from #42, else it's an open-book exam); (d) novel matches are expected, human-spot-checked, and a wrong one triggers a retest round rather than failing the pass. Retest cap already settled in #42. **Rule-authoring rules handed to #46:** report the glob verbatim + matches + **near-misses** + tier + plain-language why, before persisting; a glob may hardcode a *conventional name* (`PRD.md`) but never an *instance identifier* (`classic-260703-1522`); when two globs are both defensible **take the narrower** — too-narrow fails safe and self-heals next pass, too-broad deletes a keeper. `PRD.md` is `delete-once-served` + forced confirm (purpose-triggered), **not** `temporary` (age would delete the PRD of an unbuilt feature). - [Age signal for the temporary tier: commit-age vs mtime for untracked artifacts](https://forgejo.swansoncloud.com/jared/cc-os/issues/48) — #43 mtime-fallback stands; directory-entry age = directory inode mtime (no schema change) - [Catalog recommended completion conventions (determinism-promotion path)](https://forgejo.swansoncloud.com/jared/cc-os/issues/47) — v1 catalog = archive-bucket + status-frontmatter, in plugin conventions.json (global-only); :check names promotion candidates every report, :calibrate may draft the adoption for human approval - [Assemble the spec + ADR set](https://forgejo.swansoncloud.com/jared/cc-os/issues/46) — destination reached: `plugins/os-doc-hygiene/lifecycle-spec.md` consolidates #32–#48 (schema minus `propagate_ignore`, seed hold-out recorded as pass-#1-only); ADR-0038 (repo-root `.dochygiene-rules.json`), ADR-0039 (evidence-quality deletion tiers), ADR-0040 (no ignore propagation), ADR-0041 (determinism promotion + conventions.json) ## Not yet specified - A recurring standalone "categorize-and-learn" skill run occasionally per project, which offers to hunt newly confirmed rule types across other projects — depends on :calibrate protocol proving out. - Rollout across further projects after calibration project #1 (revise/retest loop until diminishing returns). - Interaction with the upcoming os-sdlc plugin's spec lifecycle (openspec archive is #43's canonical `served_when_path` example; what os-sdlc's own lifecycle events add is still open). - Exact report-schema field changes and eval discipline for the new lifecycle classifier. ## Out of scope - Bulk-cleaning every project as part of this map — only calibration project #1 is in scope; wider rollout is a follow-on effort.
jared added the
wayfinder:map
label 2026-07-14 16:50:18 +00:00
Sign in to join this conversation.
No description provided.