fix: refuse a window whose declarations could not be read, instead of reporting it empty - #18
Conversation
… reporting it empty `facts.collect` skipped every module page whose read raised `DocsError`, as though the page were unpublished. But `Docs.declarations` also raises `DocsError` for a page from another build while the site redeploys (a refusal, by design), and the transport raises it for timeouts and 403/429/5xx. A run that straddled a deploy therefore dropped every page read after it, and the writing model reported that nothing had landed: TauCetiRoadmap's ClassFieldTheory report said "No new ClassFieldTheory declaration is recorded in this window" for 72 pull requests whose window holds 501 declarations. - docs: a 404 raises the new `DocsNotFound`; other failures stay `DocsError`. - facts: only `DocsNotFound` is skipped; any other `DocsError` is a `FactsError`. - facts: a window with pull requests and no attributable declaration is refused. - cli: `facts` reports a `FactsError` and exits 1 without writing its output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
There is still a mixed-build correctness hole that can publish a partial report. DocsNotFound is inferred solely from an HTTP 404, but a 404 does not identify which docs build answered. With the per-page disk cache, this sequence is possible: source_commit() is anchored to build A from a still-fresh cached probe page. That is the same redeploy incoherence this PR is fixing, except it loses only some pages rather than all of them. A 404 should only be accepted as “unpublished” if the absence can be validated against the build already chosen by source_commit(); otherwise the window should be refused conservatively. Please add a regression test with one contributing cached page from the old build plus one uncached page that becomes 404 after the deploy, and assert that collection refuses rather than emitting partial facts. Generated by GPT-6 Pro. |
facts.collectskips any module page whose read raisesDocsError, on the understanding that the page is unpublished. ButDocsErroris also whatDocs.declarationsraises when a page comes from a different build than the one the run committed to ("the site is redeploying and this run cannot describe one build"), and what the transport raises for a timeout, a 403, a 429 or a 5xx.test_docs.pydescribes the redeploy case as a refusal ("Refusing is the honest outcome ... the next run closes the window cleanly"), but infactsit became a silent skip. A run that straddles a deploy drops every page it reads after the deploy, the writing model is handed a window with few or no declarations, and it reports that nothing happened.Three reports on TauCetiRoadmap have come out of this, each opened within an hour of a docs deploy (the cache TTL, during which a run can straddle two builds):
93386bc..de52a34: "No new ClassFieldTheory declaration is recorded in this window", for 72 merged pull requests. Extracting the same window finds 501 declarations (336 new) in 87 files. The docs deployed at 20:08 UTC on 2026-09-26 and the report was opened at 20:53. It landed and was announced on Zulip.759eb3e. PDE says "No new mathematical declarations are recorded in this window" for 56 pull requests. AlgebraicCodingTheory marks every layerunassessed. The docs deployed at 04:13 UTC on 2026-09-27 and they were opened at 04:17 and 04:19. Neither has landed.Changes
docs.py: a 404 from the site raises the newDocsNotFound, a subclass ofDocsError. Every other transport failure stays a plainDocsError.facts.py: onlyDocsNotFoundis skipped. Any otherDocsErrorfrom a module page, including the redeploy refusal, raisesFactsError.facts.py, a backstop: if the window has pull requests but no declaration can be attributed to any of them,collectraisesFactsErrorwhatever the cause. The message gives the counts: pull requests, merge commits found, Lean files changed, and pages with no published page.cli.py:factsprints aFactsErrorto stderr and exits 1 without writing its output. The worker already treats a non-zerofactsas a failed round, so no model is started and no pull request is opened.Tradeoffs
MIN_PRS = 10, an empty window is much more likely to be a failed extraction than a real one.source_commit()on the old build. A run in that period now refuses instead of publishing a hollow report. The first run after the probe expires plans against the new build.Tests
test_facts.pygains three tests: a redeploy-mid-run regression, the empty-window backstop, and the CLI exit code.test_an_undocumented_module_contributes_nothingnow checks that an unpublished module is skipped while the rest of the window is still reported.test_docs.pychecks that only a 404 becomesDocsNotFound; a 403, 429, 503 and an unreachable host do not.Each new test fails when the corresponding part of the fix is reverted.
./tests/runpasses.Not addressed here: the ClassFieldTheory entry already in TauCetiRoadmap's
PROGRESS.md, which needs a reviewed correction in that repository.🤖 Generated with Claude Code