Files
cyclone/docs/superpowers/specs/2026-07-08-cyclone-doc-pass-design.md
T
2026-07-08 23:01:55 -06:00

13 KiB
Raw Blame History

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 logusers, 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.