Files
stack/tests/cli/test_bib_pull_open.py
kert 592b845584
All checks were successful
CI / lint (push) Successful in 1m9s
CI / notebooks-smoke (push) Successful in 1m54s
Deploy / changes (push) Successful in 23s
CI / test (push) Successful in 4m25s
Infra CI / notebooks (push) Successful in 1m8s
Infra CI / zotero (push) Successful in 19s
Infra CI / docs (push) Successful in 1m21s
Infra CI / api (push) Successful in 1m15s
Infra CI / llm (push) Successful in 52s
Infra CI / mc (push) Successful in 17s
Infra CI / bcda (push) Successful in 1m47s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / docs (push) Successful in 46s
Package Supply Chain / pkg-supply-chain (push) Successful in 1m31s
Deploy / api (push) Successful in 1m12s
Deploy / bcda (push) Successful in 1m47s
Deploy / mc (push) Has been skipped
Deploy / llm (push) Successful in 1m13s
Deploy / report (push) Successful in 14s
feat(bib): nightly pull of every open regulations.gov docket
Nothing pulled open dockets on a schedule, so the FY2027 Hospice
(CMS-2026-1156, 215 comments) and CY2027 ESRD (CMS-2026-2245, 228)
proposed-rule dockets sat unpulled for months.

- `stack bib pull-open-dockets`: walk every unsealed docket from its
  watermark (attachments on), then enrich the new stubs at the 1000/hr
  reg.gov budget. Sealed dockets cost nothing; a docket quiet long enough
  after its period closes seals itself, so the job idles between seasons.
- Comment Pull workflow (02:30 nightly, generated): register this year's
  PFS proposed rule when it appears, pull + enrich the open dockets in
  the api container, index new comments in the llm container.
- compose: api gets REGULATIONS_GOV_API_KEY and ./.state/comments (rw);
  the llm extra gains typer so `stack llm index` runs inside llm.
- CLI reference regenerated for the new command.

Security: streamlit 1.66.0 capped pillow <13, leaving pillow 12.3.0 with
41 advisories (5 critical) fixed only in 13.0. streamlit 1.66.1 (Oct 21)
lifts the cap; exempted from the 7-day cooldown via exclude-newer-package,
and constraint-dependencies holds pillow >=13. Lock scans clean.
2026-10-27 15:40:05 -04:00

69 lines
2.4 KiB
Python

"""stack bib pull-open-dockets — the nightly walk over unsealed dockets."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
from typer.testing import CliRunner
from bib.dockets import Docket
from bib.regulations_gov import WalkResult
from bib.store import Store
from cli.bib import app
runner = CliRunner()
def _store() -> Store:
return Store(":memory:", storage_dir="/tmp/nope")
def _api():
api = MagicMock()
api.__enter__ = MagicMock(return_value=api)
api.__exit__ = MagicMock(return_value=False)
return api
@patch("bib.regulations_gov.Client")
@patch("bib.connect")
def test_nothing_open_means_no_api_client(mc_connect, mc_client):
s = _store()
s.docket_upsert(
Docket(id="CMS-2025-0304", fr_object_id="o", sealed_at="2026-01-01T00:00:00Z")
)
mc_connect.return_value = s
r = runner.invoke(app, ["pull-open-dockets"])
assert r.exit_code == 0, r.output
assert "no open dockets" in r.output
mc_client.assert_not_called()
@patch("bib.regulations_gov.backfill_details", return_value={"seen": 3, "errors": 0})
@patch("bib.regulations_gov.walk_docket", return_value=WalkResult(created=3))
@patch("bib.regulations_gov.Client")
@patch("bib.connect")
def test_walks_and_enriches_only_open_dockets(mc_connect, mc_client, mc_walk, mc_fill):
s = _store()
s.docket_upsert(Docket(id="CMS-2026-3533", fr_object_id="o1"))
s.docket_upsert(Docket(id="CMS-2026-9999", fr_object_id="")) # never resolved
s.docket_upsert(
Docket(id="CMS-2025-0304", fr_object_id="o2", sealed_at="2026-01-01T00:00:00Z")
)
mc_connect.return_value = s
mc_client.return_value = _api()
r = runner.invoke(app, ["pull-open-dockets", "--no-attachments"])
assert r.exit_code == 0, r.output
assert "2 open docket(s): CMS-2026-3533, CMS-2026-9999" in r.output
walked = [c.args[2].id for c in mc_walk.call_args_list]
assert walked == ["CMS-2026-3533"] # sealed skipped; unresolved skipped
assert mc_walk.call_args.kwargs["attachments"] is False
assert "CMS-2026-9999: no commentable FR document found" in r.output
enriched = [c.kwargs["docket"] for c in mc_fill.call_args_list]
assert enriched == ["CMS-2026-3533", "CMS-2026-9999"]
# force bypasses only the seal, so a docket sealed mid-walk is still enriched
assert all(c.kwargs["force"] is True for c in mc_fill.call_args_list)
assert "CMS-2026-3533 enrich: seen=3 errors=0" in r.output