cc-os/plugins/os-doc-hygiene/HANDOFF-add-deterministic-c...

58 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Handoff — `add-deterministic-core` apply (paused at build-spike gate)
**Status: 15 / 25 tasks complete.** Resume with `/opsx:apply add-deterministic-core`.
Nothing below is blocked on code — it is blocked on one human visual check.
## Where we are
| Group | Tasks | State |
|---|---|---|
| 1 — build-spike (SessionStart banner) | 1.1 ✓ · 1.2 ⛔ gate · 1.3 ⛔ | **AWAITING VISUAL CONFIRMATION** |
| 2 — scanner (`doc-scanner`) | 2.12.6 ✓ | done — `scripts/scanner.py`, 56 tests pass |
| 3 — state store (`state-store`) | 3.13.8 ✓ | done — `scripts/state_store.py`, 30 tests pass |
| 4 — reminder hook (`session-reminder`) | 4.14.4 | NOT STARTED — needs Group 3 + confirmed hook format (1.3) |
| 5 — cross-seam verification | 5.15.4 | NOT STARTED — run last; 5.3 writes `scripts/CONTEXT.md`, 5.4 is `openspec validate --strict` |
## THE GATE (task 1.2) — do this first on resume
Task 1.2 requires a human to start a real Claude Code session and **visually confirm** the spike banner renders. Everything downstream (1.3 → Group 4 → Group 5) is gated on it. The enable path is ALREADY fully set up — do NOT re-derive it:
- The plugin `doc-hygiene@cc-plugins` is **already installed, enabled, and cached**. (`enabledPlugins."doc-hygiene@cc-plugins": true` in `~/.claude/settings.json`; marketplace registered under `extraKnownMarketplaces.cc-plugins` → directory `/home/jared/dev/cc-plugins`.)
- There is **no `/install` slash command** in this build (v2.1.181) — plugin management is the `claude plugin ...` CLI, already run.
- CC loads hooks from the cache snapshot `~/.claude/plugins/cache/cc-plugins/doc-hygiene/0.0.1/hooks/hooks.json`, which is **byte-identical to source**. If `hooks/hooks.json` is edited later, run `claude plugin update doc-hygiene@cc-plugins` to re-snapshot before testing.
- The `systemMessage` banner mechanism is **proven** in this build — memsearch's SessionStart banner renders the same way.
**To confirm:** start a fresh Claude Code session (any directory; plugin is user-scoped) and look for, alongside the memsearch line:
[doc-hygiene] Documentation health reminder is active. Run /os-doc-hygiene:check to scan for stale or bloated docs.
- **Renders** → check task 1.2, then do task 1.3 (record the confirmed format: plugin-root `hooks/hooks.json`, top-level `hooks` key, per-matcher nested `hooks` array, `systemMessage` field, `matcher: startup|resume`, `timeout: 5`). Then build Group 4, then Group 5.
- **Blank** → the hooks.json format or loading is wrong for this build; debug BEFORE Group 4 inherits the format. (Format currently mirrors the canonical corrected shape from commit `4d595a9`, avoiding the 3 prior hook-format bugs.)
## Group 4 build notes (when unblocked)
- 4.1: `Reminder` decision PURE over `(last_check, last_reminded, now, threshold)` per design D5 — silent when fresh; banner when stale and not snoozed; snooze keyed on **calendar day** via `last_reminded`.
- 4.2: reminder script reads state via the Group 3 `StateStore` (already built) with an injected clock; on banner emit `systemMessage` naming the slash command + write `last_reminded = now`; on silent write nothing; always exit 0; missing/unreadable state = never-checked (stale). No scan, no model (invariant #1).
- 4.3: update `hooks/hooks.json` to invoke the reminder script (reuse confirmed format from 1.3), `timeout` ≤ 5s. This REPLACES the spike's fixed banner.
- 4.4: tests with injected clock (invariants #1, #2): fresh→silent; stale+never→banner; stale+reminded-same-day→silent; stale+reminded-prior-day→banner; assert only `last_reminded` mutated, only on banner.
- Build Group 4 with **Sonnet** (real systems Python), not Haiku.
## Open decision for the user (flag, not yet resolved)
Scanner deviation (tasks 2.2/2.3): the implementer read design **D7** as placing *append-only* in the **exclusion pipeline only**, NOT as a per-path signal (an append-only file is excluded before signals run, so an `append_only_growth` signal would be self-contradictory). The dead signal was removed. The spec's signal list mentioned "append-only growth" only as an illustrative "for example." **Confirm this reading is acceptable**, or restore append-only as a signal.
## Conventions for the resuming session
- Orchestrator-subagent pattern (project CLAUDE.md): delegate via Agent tool; do NOT call Read/Write/Bash/Grep/Glob/Edit directly. Model routing: scripts=no model (author with Sonnet for real logic), classification=Sonnet, orchestration=Opus.
- Each parallel agent owns disjoint files; serialize `tasks.md` checkbox edits in the orchestrator to avoid write races.
- Do NOT push commits. Do NOT commit `map-driven-planning/docs/`.
- Changing any invariant requires `invariants.md` + golden-examples update + explicit human META-RULE approval. (Known pre-existing: `invariants.md` #2 "Why" prose still has stale `clear`/`compact` wording — behavior is correct; prose fix is META-RULE-gated and untouched.)
## Files created this session
- `hooks/hooks.json` (spike banner)
- `scripts/scanner.py`, `scripts/state_store.py`
- `tests/test_scanner_exclusions.py`, `tests/test_scanner_signals.py`, `tests/test_state_store.py`
- `tests/fixtures/scanner/...`, `tests/fixtures/state_store/...`
- `.claude-plugin/marketplace.json` (parent repo — doc-hygiene registration)
- `openspec/changes/add-deterministic-core/tasks.md` (15 boxes checked)