docs(spec): SP42 doc-pass design

This commit is contained in:
Nora
2026-07-08 23:01:55 -06:00
parent c9588f782d
commit 90a2055c20
@@ -0,0 +1,117 @@
# Sub-project 42 — Doc-Pass: Reconcile Stale Docs with SP23SP41 Reality: Design Spec
**Date:** 2026-07-08
**Status:** Draft, awaiting user sign-off
**Branch:** `sp42-doc-pass`
**Aesthetic direction:** No new UI (docs-only increment; no code paths change).
## 1. Scope
Between SP23 (Ubuntu + Docker + auth + RBAC + LAN-bind product fork, merged `07a7ecb` on 2026-06-23) and SP41 (in-window rebill pipeline, merged `309e6c0` on 2026-07-08), 19 increments landed on `main` without a corresponding documentation alignment pass. The CLAUDE.md, README.md, ARCHITECTURE.md, REQUIREMENTS.md, and the eight `.superpowers/skills/*/SKILL.md` files all carry stale references to:
- the pre-SP21 monolithic `store.py` (~2,423 LOC) and pre-SP36 monolithic `api.py` (~3,548 LOC) — both have since been split;
- `127.0.0.1` as the bind address — SP23 moved the bind to `0.0.0.0` with the host firewall now controlling reachability;
- the "no auth" posture — SP23 landed bcrypt + HttpOnly session cookies via `cyclone.auth.*`;
- the SP23 product fork being "awaiting user decision" — SP23 is in `main`;
- the "SP22 used, next is SP24" / "SP22 used, next is SP25" framing in skill files — last merged SP is SP41, next free is SP42;
- the "12 SQL migrations" claim — 23 migrations are on disk (0001_initial through 0023_visits);
- the "4 router modules" claim in `cyclone-api-router/SKILL.md` — SP36 split `api.py` into 22 routers under `api_routers/`;
- the "Seven subcommands" claim in `cyclone-cli/SKILL.md` — SP24 / SP25 / SP27 / SP28 / SP33 / SP37 / SP38 / SP39 / SP40 / SP41 added ~12 more;
- the "22 specs / 27 plans" / "17 specs / 13 plans" framing — 42 specs and 37 plans are on disk;
- the "single 2412-line module" claim in `cyclone-store/SKILL.md` — SP21 shipped the split into 16 modules.
SP42 is a **docs-only** increment: every change is to `*.md` files. No code paths change; no API endpoints change; no test assertions change.
**In scope:**
- `CLAUDE.md` — refresh the SP-N section (last merged SP, next free, file-size + subpackage claims), the migration count, and the CLI subcommand list (drop the three phantom `parse-999` / `parse-ta1` / `parse-277ca` entries that contradict the body text).
- `README.md` — replace the "binds to `127.0.0.1`, no auth, no internet exposure" lead with the SP23 posture ("always binds to `0.0.0.0`, requires login, LAN-only by design"), update the project-layout block to reflect the post-SP21/SP36 split, and refresh the "Sub-projects 2 through 19 are shipped" framing.
- `docs/ARCHITECTURE.md` — refresh the §1 / §2 / §4.1 / §4.3 / §5.4 / §6.2 / §7.4 / §8.1 / §11.2 / §13.2 blocks. SP23 is shipped (drop "awaiting user decision"). The package-layout map gets `auth/`, `handlers/`, `rebill/`, `reissue/`, `store/` (the SP21 facade), and the full 22-router `api_routers/`. The SP21 split is present-tense. The endpoint enumeration in §8.1 gets refreshed. The §6.3 claim-state diagram gains `partial` (REQUIREMENTS FR-6 already lists it). The §7.4 audit strategy list gets `pcn-exact` (SP31) replacing the stale `auto:pcn_npi_charge` / `auto:pcn_charge` labels. The migration table goes from 12 to 23.
- `docs/REQUIREMENTS.md` — move SP23 from §6.2 backlog to §6.1 shipped. Close R-1 (auth shipped), R-3 (Dockerfile / docker-compose shipped), R-11 (SP21 store split shipped), R-12 (SP36 api.py split shipped) with concrete evidence. Update R-13's migration count to 23. Add SP23SP41 rows to the §6.1 SP table. Update §5.1 LOC claims and module list. Update §5.2 migration table. Update §12.1 / §12.2 spec-and-plan lists.
- `docs/RUNBOOK.md` — replace "the SP23 Docker stack" with "the Docker stack"; keep the existing "Reissue claims (SP24)" section as-is (already correct).
- `.superpowers/skills/cyclone-spec/SKILL.md` — refresh the "As of this writing" header line.
- `.superpowers/skills/cyclone-tests/SKILL.md` — refresh test counts (178 backend tests, 22 fixtures, 130+ frontend test files) and the SP-N "next" pointer.
- `.superpowers/skills/cyclone-store/SKILL.md` — drop the "single 2412-line module, SP21 in progress" framing; update line refs from `store.py:882` to `store/__init__.py:148`; complete the SP21 module list (add `backfill.py`, `claim_acks.py`, `kpis.py`, `resubmissions.py`, `submission_dedup.py`); update line refs from `api.py:1380-1401` / `api.py:1891,2002` to the post-SP36 router files.
- `.superpowers/skills/cyclone-api-router/SKILL.md` — replace "4 router modules" with "22 router modules"; replace the "next refactor target is the parse endpoints" note with the post-SP36 reality; update line refs in the "Mounting in `api.py`" example.
- `.superpowers/skills/cyclone-edi/SKILL.md` — refresh the SP-N "next" pointer.
- `.superpowers/skills/cyclone-frontend-page/SKILL.md` — refresh page / hook / drawer counts (12 pages, 19 hooks, 4 drawers including `ProviderDrawer/` + `AckDrawer/`); refresh SP-N "next" pointer.
- `.superpowers/skills/cyclone-cli/SKILL.md` — replace the "Seven subcommands" claim with the canonical 15+ subcommand list per the actual `cyclone/cli.py`; refresh SP-N "next" pointer.
- `.superpowers/skills/cyclone-tail/SKILL.md` — refresh the "three streaming pages" claim (add `Acks` per SP25 ack-live-tail); replace `api.py:1357-2006` line refs with the post-SP36 router files.
**Out of scope:**
- Any code change. SP42 is docs-only.
- Any new feature description beyond what already exists in code. The spec is a *reconciliation* pass, not a *content* pass.
- Documenting SP34 (`999-acceptance-restore`). The branch was orphaned; SP31 supersedes the underlying race via the 2-of-3 match rule. The doc-pass must not list SP34 as shipped.
- Documenting SP25's three-topic reuse as separate SPs. The historical anomaly is acknowledged in the SP42 spec but the doc pass keeps the merged-message convention (one row per merge commit).
- Resolving the SP24 number collision (reissue-claims vs auth-posture alignment). The current main HEAD merge commit `c9588f7` carries the subject "merge: SP24 reissue-claims into main", so SP24 is the reissue work; the 2026-06-23 docs-only auth-posture-alignment work landed as a sub-task of SP23 and is documented there.
- A full rewrite of any section. The doc-pass updates only the lines that are stale; it does not restructure narrative.
- The dead `backend/src/cyclone/workflow/` directory. R-27 is left Open; deletion is a follow-up increment.
## 2. Decisions (locked during brainstorming)
1. **Docs-only — no code paths change.** Per the cyclone-spec skill convention, this is documented but enforced by reading the diff before each commit. Every commit in the SP42 branch must touch only `*.md` files (plus the spec/plan docs themselves).
2. **One commit per file, prefixed `docs(sp42): <file> …`.** Keeps the SP42 merge commit readable and lets reviewers bisect a single stale doc back to a specific commit if a future refactor pulls a doc claim back out of date.
3. **Mechanical fixes only.** Where the existing prose is correct (RUNBOOK.md §"Submitting claims (canonical — SP37)", the SP38 `ack-orphans` section, the SP41 §3.1 FR-RB-* block in REQUIREMENTS.md, the live-tail wire format table in CLAUDE.md), the doc-pass does not touch them. The pass targets the lines where the prose is provably inconsistent with `git log` + `list_dir` + the actual `backend/src/cyclone/` inventory.
4. **SP23 is shipped everywhere.** Every "SP23 awaiting user decision" / "SP23 product fork" / "SP23 candidate" line in the docs gets rewritten as past tense. This is the single biggest correctness win and the highest-blast-radius fix.
5. **Migration count goes from 12 to 23, every time it appears.** Three docs (CLAUDE.md, ARCHITECTURE.md, REQUIREMENTS.md) all say "12" — they all become "23."
6. **Router count goes from 4 to 22, every time it appears.** `cyclone-api-router/SKILL.md` says "4 router modules"; ARCHITECTURE.md §2 says "4 routers"; REQUIREMENTS.md R-12 says "4 sub-routes". All three become "22."
7. **Store split is present-tense everywhere.** The "SP21 in flight" / "SP21 split is in progress" / "SP21 split is in-flight on `refactor/store-split`" framing in CLAUDE.md, ARCHITECTURE.md, REQUIREMENTS.md, and `cyclone-store/SKILL.md` all become past tense with the merge commit (`4360ef7`) cited as evidence.
8. **CLI subcommand list gets the canonical 15+ enumeration in `cyclone-cli/SKILL.md`.** The "Seven subcommands" line is replaced with the full list from `cyclone/cli.py` (verified against `git log``users`, `submit-batch`, `reissue-claims`, `resubmit-rejected-claims`, `resubmissions`, `validate-837`, `recover-ingest`, `ack-orphans`, `seed`, `backfill-rendering-npi`, `backfill-999-rejections`, `pull-inbound`, `rebill-from-835`, plus the existing `parse-837`, `parse-835`, `validate-npi`, `validate-tax-id`, and the `backup` group).
9. **SP25 reuse is acknowledged in `cyclone-spec/SKILL.md`.** The "Three SP25s (sftp-polling-enablement, ack-live-tail, orphan-data-recovery)" anomaly gets a one-line note in the skill's SP-N overview so future agents don't conflate the three SP25s with one another.
10. **No new skill files.** The exploration found that the SP23 auth work arguably warrants a `cyclone-auth` skill, but adding one is outside the doc-pass scope. It's flagged as a follow-up increment.
## 3. Threat model
The doc-pass changes no code paths and no auth gates. The threat model is unchanged from SP41 (the last shipped SP): the auth boundary is HTTP (login required, bcrypt + HttpOnly session cookie); the file-system threat is local-only and handled by SQLCipher at rest and the macOS Keychain. The doc-pass does not weaken any posture; the README.md "binds to 0.0.0.0, requires login" claim actually tightens the operator's mental model by removing the false "no auth, no internet exposure" framing that was inherited from the pre-SP23 posture.
The doc-pass is itself shipped via the same SP-N merge flow (single atomic merge, no squash, no rebase). The merge commit is the audit trail — `merge: SP42 doc-pass into main`.
## 4. Test impact
Per the cyclone-tests skill convention:
- **No new tests.** SP42 is docs-only; nothing in the codebase is exercised differently.
- **Existing tests:** the full pytest suite (`cd backend && .venv/bin/pytest -q`) plus the full vitest suite (`npm test`) must continue to pass — the doc-pass is a non-regression increment.
- **CI posture:** unchanged (R-26 "no CI workflow" is left Open).
- **Fixtures:** none added.
- **Frontend tests:** none added.
## 5. Spec & plan anchors
- **Spec anchor (this file):** `docs/superpowers/specs/2026-07-08-cyclone-doc-pass-design.md`
- **Plan anchor:** `docs/superpowers/plans/2026-07-08-cyclone-doc-pass.md`
- **Source-of-truth inputs:**
- `git log --all --oneline --grep='merge: SP' | sed 's/.*merge: //' | awk '{print $1}' | sort -V | uniq` — proves the SPs that have actually merged (5, 9-21, 23-41)
- `ls docs/superpowers/specs/ | wc -l` → 42; `ls docs/superpowers/plans/ | wc -l` → 37
- `find backend/src/cyclone/migrations -name '*.sql' | wc -l` → 23
- `ls backend/src/cyclone/api_routers/*.py | wc -l` → 21 routers + `_shared.py` + `__init__.py`
- `ls backend/src/cyclone/store/*.py | wc -l` → 17 modules
- `find backend/src/cyclone -maxdepth 1 -type d` — proves the subpackage list
- `backend/src/cyclone/__main__.py:48` — proves `host=os.environ.get("CYCLONE_HOST", "0.0.0.0")`
## 6. Acceptance criteria
1. `grep -rE 'SP22.*SP24|next free increment is SP24|next increment is SP24|next free is SP24|next is SP25' CLAUDE.md README.md docs/ARCHITECTURE.md docs/REQUIREMENTS.md docs/RUNBOOK.md .superpowers/skills/ 2>/dev/null` returns zero matches.
2. `grep -rE 'awaiting user decision|SP23.*candidate|SP23.*product fork' docs/ARCHITECTURE.md docs/REQUIREMENTS.md 2>/dev/null` returns zero matches (in the SP23 context).
3. `grep -rE 'api\.py.*3,548|3,548 LOC|store\.py.*2,423|2,423 LOC|2,172 LOC|3,145 LOC' CLAUDE.md README.md docs/ARCHITECTURE.md docs/REQUIREMENTS.md .superpowers/skills/ 2>/dev/null` returns zero matches.
4. `grep -rE '127\.0\.0\.1' CLAUDE.md README.md docs/ARCHITECTURE.md docs/REQUIREMENTS.md 2>/dev/null` returns zero matches in the bind-address context.
5. `grep -rE 'no auth, no internet exposure' README.md` returns zero matches.
6. `grep -rE '4 router modules|four router modules' .superpowers/skills/cyclone-api-router/SKILL.md docs/ARCHITECTURE.md docs/REQUIREMENTS.md 2>/dev/null` returns zero matches.
7. `grep -rE 'Seven subcommands|7 subcommands' .superpowers/skills/cyclone-cli/SKILL.md` returns zero matches.
8. `grep -rE 'single 2412-line module|SP21.*in.progress|SP21.*in-flight' .superpowers/skills/cyclone-store/SKILL.md` returns zero matches.
9. `grep -rE '12 SQL migrations' CLAUDE.md docs/ARCHITECTURE.md docs/REQUIREMENTS.md 2>/dev/null` returns zero matches.
10. `cd backend && .venv/bin/pytest -q` exits 0; no regressions.
11. `npm test` exits 0; no regressions.
12. `git log --oneline sp42-doc-pass` shows one `docs(spec):` + one `docs(plan):` commit plus ~13 `docs(sp42):` commits (one per file touched).
13. After the merge to `main`, `git log --oneline main -1` shows the SP42 merge commit with subject `merge: SP42 doc-pass into main`.
14. The single-file diff for `CLAUDE.md`, `README.md`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `RUNBOOK.md`, and each of the 8 skill files shows the stale lines updated and no semantic rewrites of unrelated prose.