* 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 (
|
||
|---|---|---|
| .. | ||
| BadName_repo | ||
| clean-repo | ||
| docs-repo | ||
| EXPECTED_DRIFT_COUNT | ||
| README.md | ||
compliance-drift canary fixtures
Planted-drift corpus for checkers/compliance-drift.sh --canary (offline, no network/token).
The checker asserts the total drift count equals EXPECTED_DRIFT_COUNT (anti-complacency floor,
design §6.4). If a check regresses (stops firing), the count drops and the canary FAILS (exit 3).
Fixtures (each a real git checkout so the tracked-.env / ls-files checks work):
| Fixture | Planted drift | Count |
|---|---|---|
clean-repo |
none — kebab name, README, ci.yaml, dependabot.yml, .env is gitignored (must NOT fire) |
0 |
BadName_repo |
non-kebab name; no README; no ci.yaml; has package.json but no dependabot.yml; tracked .env with values |
5 |
docs-repo |
docs-only (CI skipped via DOCS_ONLY_REPOS), kebab name, no README | 1 |
Total = 6 (EXPECTED_DRIFT_COUNT). The canary pins DOCS_ONLY_REPOS=docs-repo and
COMPLIANCE_EXEMPT="" internally so it is deterministic regardless of the operator's env.
Secret-fixture naming: BadName_repo's planted tracked-secret env file is committed as
dotenv.fixture, NOT .env. The repo's root .gitignore lists .env, so a literal .env
fixture would silently never be committed — on a fresh clone the secrets-committed drift would
vanish and the count would drop to 5 (this regression was caught by this very canary). 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. This mirrors the
.fixture-suffix convention the dependency-cve fixtures use for their manifests. Keep any new
committed secret fixture under a non-gitignored name and rename it in the canary.
When you add/remove a check or fixture, update both the fixture and EXPECTED_DRIFT_COUNT
in the same commit (the canary edit is itself caught on the next run — design §6.4).