Files
stack/docs/superpowers/plans/2026-08-17-ecfr-jump-links-p41.md
kert 77751de9fc
All checks were successful
CI / lint (push) Successful in 32s
CI / notebooks-smoke (push) Successful in 1m29s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / docs (push) Has been skipped
Deploy / api (push) Has been skipped
Deploy / llm (push) Has been skipped
Deploy / mc (push) Has been skipped
Infra CI / notebooks (push) Successful in 56s
Infra CI / zotero (push) Successful in 13s
Infra CI / docs (push) Successful in 1m26s
Infra CI / api (push) Successful in 1m1s
Infra CI / llm (push) Successful in 52s
Infra CI / mc (push) Successful in 22s
Deploy / report (push) Successful in 13s
CI / test (push) Successful in 13m16s
Notebooks Integration / notebooks-integration (push) Successful in 7m55s
Zotero Sync / zotero-sync (push) Successful in 1m21s
Package Supply Chain / pkg-supply-chain (push) Successful in 58s
docs(spec): P41 build outcomes; plan checked off (refs #639-#641)
2026-08-17 15:08:32 -04:00

63 lines
5.9 KiB
Markdown

# P41: eCFR Jump Links Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Bidirectional CFR cite ↔ eCFR URL transmutation (`bib.cfrlink`) with the P40 consumer set: notebook links, `:pincite:` URLs, Zotero child links, CLI.
**Architecture:** One pure-function module `src/bib/cfrlink.py` (parse/url/cite_of — deterministic, no network, no grab), plus `item_for`/`place` over the existing bib regulation index and the P40 `fr_links`→Zotero path unchanged. Hooks: `bib/pincite.py` cfr branch, notebook `cfr_md()`, CLI `cfr-jump`.
**Tech Stack:** pytest TDD; existing `bib.Store` / sync / nb_integration gates.
**Spec:** `docs/superpowers/specs/2026-08-17-ecfr-jump-links-design.md` (committed). Tracker:
- Milestone [P41](https://git.fhirworx.io/homelab/stack/milestone/42)
- [#639 — cfrlink core + round-trip law](https://git.fhirworx.io/homelab/stack/issues/639)
- [#640 — context + placement + CLI](https://git.fhirworx.io/homelab/stack/issues/640)
- [#641 — rollout: pincite + notebook + Zotero](https://git.fhirworx.io/homelab/stack/issues/641)
## Global Constraints
- Conventional commits `(closes #N)`; **no Co-Authored-By trailer**; TDD per task.
- `parse_cite`/`url`/`cite_of` are pure — no network, no store. Only `place`/`item_for` touch bib.
- Placement reuses `fr_links` (page=0, p_id NULL for CFR) and `_sync_fr_links` untouched.
- URL form: `https://www.ecfr.gov/current/title-{t}/section-{s}[#p-{s}{paras}]`, part form `…/part-{p}`; `/on/{date}/` replaces `/current/` when date-pinned. Fragments use the cite's own paragraph path verbatim (verified semantic anchors).
### Task 1: Core transmuter ([#639](https://git.fhirworx.io/homelab/stack/issues/639))
**Files:** Create `src/bib/cfrlink.py`; Test `tests/bib/test_cfrlink.py` (new).
**Interfaces:** `CfrCite(title: int, part: str, section: str, paras: tuple[str, ...], date: str)`; `parse_cite(ref) -> CfrCite`; `url(cite) -> str`; `cite_of(url) -> str`; `canonical(cite) -> str` (the canonical spelling used by cite_of and tests).
- [x] **Step 1 (failing tests):** spellings (`42 CFR 425.400(c)(1)(iv)`, `42 C.F.R. § 425.400`, `42 CFR § 414.1425`, `42 CFR Part 425`, case/dots/spacing variants); title-required rejection; URL emission incl. fragment + part + date pin; `cite_of` over short, canonical-hierarchy (`/current/title-42/chapter-IV/…/section-425.400`), `/on/2026-01-01/…`, and fragmented URLs; **both round-trip laws**.
- [x] **Step 2:** red → **Step 3:** implement → **Step 4:** green (`uv run pytest tests/bib/test_cfrlink.py -q`).
- [x] **Step 5:** Live smoke (one-off): GET `url(parse_cite("42 CFR 425.400(c)(1)(iv)"))` with browser UA → 200 and the body contains `id="p-425.400(c)(1)(iv)"`.
- [x] **Step 6:** Commit `feat(bib): cfrlink — bidirectional CFR cite/eCFR URL transmuter (closes #639)`.
### Task 2: Context + placement + CLI ([#640](https://git.fhirworx.io/homelab/stack/issues/640))
**Files:** Modify `src/bib/cfrlink.py`, `src/cli/bib.py`; Test `tests/bib/test_cfrlink.py`.
**Interfaces:** `item_for(cite, store) -> str` ("" when absent; exact-section item beats part item); `place(store, ref, *, label="") -> JumpLink` (frlink.JumpLink reused; raises when no regulation item matches); `md_link(ref, *, text="") -> str` (store-free); CLI `cfr-jump`.
- [x] **Step 1 (failing tests):** fixture store with a part item (`…/title-42/part-425`) + a section item (`…/part-425/section-425.400`) + an unrelated part; `item_for` section-preference + part fallback (cite `425.402` → part item) + miss (""); `place` writes `fr_links` row (page=0, correct label/url) on the section item; place-without-item raises; double-place no-ops; one sync test in `tests/bib/test_sync.py`: a CFR-placed row becomes a linkMode=3 child (reuses P40 fixtures).
- [x] **Step 2:** red → **Step 3:** implement + CLI (`--url` reverse mode prints `cite_of`) → **Step 4:** green (cfrlink + sync files).
- [x] **Step 5:** Commit `feat(bib): cfrlink context + placement over regulation items + cfr-jump CLI (closes #640)`.
### Task 3: Rollout ([#641](https://git.fhirworx.io/homelab/stack/issues/641))
**Files:** Modify `src/bib/pincite.py` (+test), `notebooks/cy2027_pfs_proposed_rule.py`. Data: bib/zotero.
- [x] **Step 1:** `jump_url` cfr branch (failing test first: locator `42 CFR 425.400(c)` → URL; `§ 3.2` stays ""); green; part of the Task-3 commit.
- [x] **Step 2:** Notebook: `cfr_md()` in the setup cell (store-free, same fallback shape); live-link `42 CFR 414.1450(b)(1)` (APM revival cell), spell the QP-alignment cite `42 CFR 414.1425(c)(5)(ii)` and link it, and link `42 CFR 425.400(c)` in the PQM definition cell. Gate: single-notebook `nb_integration` `pass=1`.
- [x] **Step 3:** Place `42 CFR 414.1450(b)(1)`, `42 CFR 414.1425(c)(5)(ii)`, `42 CFR 425.400(c)` on their regulation items; `sync-zotero` scoped to those items' tags (check what tag scopes cover regulation items — fall back to `--tag` on a per-item tag or run the sync via a small scoped call); verify linkMode=3 children in zotero.sqlite.
- [x] **Step 4:** Commit `feat(bib,notebooks): cfr locator jump URLs + live eCFR links in CY2027 notebook (closes #641)`.
### Task 4: Close the loop
- [x] Push; CI green on HEAD (skipped=terminal); issues closed; close [milestone P41](https://git.fhirworx.io/homelab/stack/milestone/42); outcomes appended to spec; memory updated (`fr_jump_links.md` gains the cfrlink section).
## Self-Review
- Coverage: #639→T1, #640→T2, #641→T3, closure→T4; spec sections all mapped.
- Placeholders: none; the only open lookup (which sync tag scope covers regulation items) is explicitly a Step-3 check with a fallback.
- Consistency: `CfrCite` fields used identically across tasks; `place` returns frlink's `JumpLink`; canonical spelling defined once (Task 1) and reused by cite_of tests.