# Tasks: calibrate-assessment-inventory

TDD (red-green-refactor) throughout; run the full suite (407 existing tests)
after each group. Source of truth for behavior: `lifecycle-spec.md` §1/§2/§8.

## 1. Canonical rules-file writer (calibrate_helpers.py)

- [x] 1.1 Write failing tests: canonical ordering (rules grouped delete-once-served → temporary → keep, glob-sorted; nominations after rules; consults before rejected, glob-sorted), idempotent round-trip (byte-identical rewrite), hand-edit re-canonicalization, unknown-field warn-and-round-trip (rules and nomination entries)
- [x] 1.2 Implement the writer as the single serialization path for `.dochygiene-rules.json`, including the nominations read/validate/warn path (`rulebook.py` untouched)
- [x] 1.3 Route every existing calibrate persistence write through the writer

## 2. NominationIntakeFilter (calibrate_helpers.py)

- [x] 2.1 Write failing tests: exact glob+lifetime repeat is dropped and logged; the two #52 worked cases (exact repeat of `docs/research/** -> temporary` dropped; variant `docs/research/drafts/** -> temporary` survives annotated); match-set-intersection relatedness computed from an injected shortlist; open consults always passed through to the judge input
- [x] 2.2 Implement `NominationIntakeFilter` (deterministic, injected rules-file data + shortlist; returns survivors-with-annotations + dropped log)

## 3. Calibrate skill wiring (SKILL.md + workflows)

- [x] 3.1 Wire Step 3.5: run the intake filter between nomination and judgment; feed annotations + open consults into the judge prompt's "Nominations memory" section; surface drops in the run summary
- [x] 3.2 Wire Step 5: add the "Open consults" report section with the three exits (answer → rule + consult deleted; decline → rejected with `rejected_by: "human"`; defer → stays); new rejections/consults shown but not individually gated
- [x] 3.3 Wire Step 6: persist keep verdicts as plain keep rules (exact-path singletons allowed — keep-tier relaxation), human declines as rejections, consult verdicts into `nominations.consults` deduped by glob — all through the canonical writer
- [x] 3.4 Remove the "design-level pending pipeline wiring" marker from the SKILL.md consult-loop worked example; verify judge.md needs no further edits (its map-#49 sections landed with the design commit)

## 4. Extract-op extracted.md append (patch_applier.py)

- [x] 4.1 Write failing tests: vault extraction appends the pointer entry (correct format: vault note name, why, source filename, date) to `<dir>/extracted.md`, creating it if absent, staged in the same hygiene commit as the `git rm`; repo-durable extraction (ADR/CLAUDE.md/docs) writes no entry; failed vault write skips append and delete; failed append skips the delete
- [x] 4.2 Implement the append in the extract-then-delete path (distill → vault write → append → git rm, one per-file transaction)

## 5. Verification and rollout

- [x] 5.1 Full test suite green (existing 407 + new); no informal runs of held-out eval scenarios
- [x] 5.2 Run `bin/refresh-plugins` and update the SKILL.md/workflow cache-sensitive docs if the refresh surfaces anything
- [x] 5.3 Record completion per repo convention: build-plan/status index untouched unless design changed; note in `docs/implementation-status/` leaf if warranted
