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

5.9 KiB

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:

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)

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).

  • 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.
  • Step 2: red → Step 3: implement → Step 4: green (uv run pytest tests/bib/test_cfrlink.py -q).
  • 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)".
  • Step 6: Commit feat(bib): cfrlink — bidirectional CFR cite/eCFR URL transmuter (closes #639).

Task 2: Context + placement + CLI (#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.

  • 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).
  • Step 2: red → Step 3: implement + CLI (--url reverse mode prints cite_of) → Step 4: green (cfrlink + sync files).
  • Step 5: Commit feat(bib): cfrlink context + placement over regulation items + cfr-jump CLI (closes #640).

Task 3: Rollout (#641)

Files: Modify src/bib/pincite.py (+test), notebooks/cy2027_pfs_proposed_rule.py. Data: bib/zotero.

  • 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.
  • 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.
  • 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.
  • Step 4: Commit feat(bib,notebooks): cfr locator jump URLs + live eCFR links in CY2027 notebook (closes #641).

Task 4: Close the loop

  • Push; CI green on HEAD (skipped=terminal); issues closed; close milestone P41; 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.