* feat(secrev): plan-groomer Plane-1 Phase 4 planner (report-only)
Aggregates the OTHER Plane-1 checkers' latest reports (compliance-drift,
dependency-cve, doc-drift, confluence-doc) into one prioritized, deduped
"groomed weekly plan" written into the mode-600 report. REPORT-ONLY per
decision D3: posts NOTHING to Slack; auto-write to Notion/Jira is a later
toggle (inert --notify seam). Reuses lib/sweep_substrate.sh redact().
Offline --canary asserts the groomed-plan item count (5) against a fixture
report set, exercising latest-date selection, dedup, multi-source aggregation,
and no-data discipline (a missing source is noted, never invented as work).
shellcheck-clean (only the shared SC1091 substrate-source info, at parity with
compliance-drift/dependency-cve). PROVISIONING (auto-write toggle, systemd
wiring, coordinator registry) deferred — gated.
* feat(secrev): confluence-doc Plane-1 Phase 4 doc-gap detector (recommend-only)
Scheduled, read-only documentation gap detector. Diffs the org repo set + an
optional read-only AWS inventory + the IT page-ID map (project_confluence_
migration) against Confluence and REPORTS doc gaps / stale pages / missing
runbooks into the mode-600 report. RECOMMEND-ONLY per D3/D7: NEVER auto-writes
Confluence; the on-demand SSH-invoked write path (incl. Mermaid edits via
~/.claude/scripts/confluence_mermaid.py) is a separate, gated provisioning path.
LIVE Confluence API reads need the gated confluence-bot service-account token
(D6); when creds are absent OR --no-api/--canary, the API checks are SKIPPED and
noted, NEVER reported as a gap on missing data (mirrors compliance-drift's
status-code-aware API-skip pattern: 200 parse, 404 real gap, else skip).
Offline --canary asserts the doc-gap count (3) against a fixture (repo list +
mock page-map + mock AWS inventory): a repo with no IT page, an AWS resource not
in the map, and a missing required runbook page; precision non-gaps (matched
repos/resources, doc-exempt repo, present required pages, skipped API) must not
inflate the count. shellcheck-clean (only the shared SC1091 substrate-source
info). PROVISIONING (confluence-bot account + 90-day rotation, page-1540098 live
dry-run expecting 16 weweave macros, systemd wiring, coordinator registry)
documented in the footer, deferred — gated.
* fix(secrev): commit compliance-drift secret fixture as dotenv.fixture (canary broke on fresh clone)
The compliance-drift canary's planted tracked-secret fixture was BadName_repo/.env,
but the repo root .gitignore lists '.env' — so it was never committed. On a fresh
clone of main the file is absent, the secrets-committed check stops firing, and the
canary FAILS (expected 6, got 5). It only passed where a gitignored, untracked
'.env' happened to exist locally. Verified the failure reproduces in a clean clone
of origin/main (3d97139) and in a fresh worktree.
Fix (in-convention, mirrors the dependency-cve .fixture-suffix trick): ship the
secret as BadName_repo/dotenv.fixture (committable, not gitignored); the --canary
materialization renames dotenv.fixture -> .env in its temp work area. The dotgit/
index already TRACKS .env, so git ls-files still reports it and the drift fires.
Restores the documented 6/6 canary on any fresh checkout. shellcheck stays clean.
39 lines
2.2 KiB
Markdown
39 lines
2.2 KiB
Markdown
# plan-groomer canary fixtures
|
|
|
|
Sample sibling-checker reports for `checkers/plan-groomer.sh --canary` (offline, no network/
|
|
token). The planner asserts the groomed-plan **item count** equals `EXPECTED_PLAN_ITEMS`
|
|
(anti-complacency floor, design §6.4). If aggregation or dedup regresses, the count drifts
|
|
and the canary FAILS (exit 3).
|
|
|
|
## How the canary works
|
|
|
|
`--canary` points `$REPORT_ROOT_BASE` at `sample-reports/` and writes the groomed plan into a
|
|
mode-700 temp dir (so the canary writes nothing under `$HOME`). It reads each source checker's
|
|
**latest** `<date>/<checker>.json`, normalizes every `.findings[]` into a plan item
|
|
`{repo, severity, source, title, action}`, **dedupes** on `repo|source|title`, prioritizes by
|
|
severity, and writes the plan into the mode-600 report.
|
|
|
|
These are plain report JSON files (no `dotgit/` trick needed — plan-groomer reads sibling
|
|
reports, it does not scan git checkouts).
|
|
|
|
## Fixture report set
|
|
|
|
| Source checker | Date dir | Findings | Contributes to plan |
|
|
|---|---|---|---|
|
|
| `compliance-drift` | `2026-06-10` (OLD) | 1 | **0** — sentinel: older date MUST be skipped (latest-date selection) |
|
|
| `compliance-drift` | `2026-06-17` (latest) | 3 | **2** — two of the three are an exact duplicate (`payments-dashboard` / README) that must dedup to one |
|
|
| `dependency-cve` | `2026-06-17` | 2 | **2** — `jinja2` (high) + `lodash` (critical) |
|
|
| `doc-drift` | `2026-06-17` | 1 | **1** — stale README arch section |
|
|
| `confluence-doc` | (none) | — | **0** — no report present; noted in `missing_sources`, NEVER invented as work |
|
|
|
|
Total groomed plan items = **5** (`EXPECTED_PLAN_ITEMS`).
|
|
|
|
This exercises four invariants in one run:
|
|
1. **latest-date selection** — the `2026-06-10` sentinel must not leak into the plan.
|
|
2. **dedup** — the duplicate README finding collapses to one item.
|
|
3. **multi-source aggregation** — three different checkers feed one prioritized plan.
|
|
4. **no-data discipline** — a missing source (`confluence-doc`) is noted, never fabricated.
|
|
|
|
When you add/remove a source checker, a fixture report, or a finding, update the fixture(s)
|
|
and `EXPECTED_PLAN_ITEMS` in the same commit (the canary edit is itself caught on the next run
|
|
— design §6.4).
|