docs(configuration): the retry-cap row still promised a zero that the loader refuses (BACKLOG #1217, half 1) - #591
Merged
Conversation
… loader refuses (BACKLOG #1217, half 1) PR #383 floored the operator-facing `retry_max_attempts` at `ge=1`. The catalog row in docs/CONFIGURATION.md was not moved with it and still asserted: `0` or a negative value is accepted and dead-letters on the first failure That has been false since #383. A catalog row describing a configuration the loader REFUSES is worse than silence: an operator writes it, the start fails, and the document that sent them there still reads as authoritative. DRIVEN, NOT READ OFF THE FIELD DECLARATION: retry_max_attempts = 0 REJECTED = -1 REJECTED = 1 LOADS -> 1 = 100 LOADS -> 100 = None LOADS -> None key omitted LOADS -> 100 RetryPolicy(max_attempts=0) STILL LEGAL The row now says what the loader does, and keeps naming the internal idiom the floor deliberately does NOT touch. THAT LAST CLAUSE IS THE POINT OF THE WHOLE ITEM AND IT IS EASY TO DELETE BY ACCIDENT. The obvious "remaining half" -- adding `ge=1` to `models.py` -- looks like the symmetrical completion of the same tightening and would instead DELETE A USED MECHANISM: `RetryPolicy(max_attempts=0)` is the deliberate idiom for a permanent, no-retry failure and FOUR test modules depend on it (test_batch_completion, test_postgres_store, test_resend, test_sqlserver_store). settings.py anticipates the mistake in its own comment; the new `test_the_internal_no_retry_idiom_is_untouched_by_the_operator_facing_floor` makes that executable rather than advisory. THE PROSE TEST IS NEGATIVE ON PURPOSE. It asserts the false CLAIM cannot come back, not that the new sentence matches word for word. An exact-sentence assertion reds on any rewording, which trains the next author to edit the test instead of the doc. RED-FIRST: restoring the old sentence verbatim reds `test_the_configuration_catalog_does_not_still_promise_the_pre_floor_behaviour`, 1 of 15 in that selection, with the anchor asserted unique and the file hash asserted changed before scoring, then restored byte-identical. HALF 2 IS NOT IN THIS COMMIT AND IS NOT MINE TO DECIDE. Whether the retry-forever posture needs a TOML or env spelling is a product question -- the row says choosing the spelling IS the item. Measured here rather than quoted, every plausible spelling driven through the real model: 0, -1, "", "none", "null", "forever", "inf" ALL REJECTED key omitted -> 100 python None -> None <- code-first ONLY So retry-forever is reachable in code-first configuration and nowhere else, because TOML has no null literal. The row recommends a string spelling coerced by a field validator; adopting one changes the accepted-configuration set, so it is routed for a ruling rather than settled in a build. Verification, with scope: tests/test_retry_cap_default.py, tests/test_delivery_settings.py and tests/test_settings.py, on .venv/Scripts/python.exe (CPython 3.14.6 non-freethreaded, seven CI extras). ruff 0.15.22 (== the constraints.lock pin) check and format --check clean. NOT the full suite. No test was removed or weakened. The ledger row is not mine to author and is not in this commit; #1217 stays OPEN on half 2. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
wshallwshall
enabled auto-merge (squash)
August 25, 2026 18:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The retry-cap catalog row in docs/CONFIGURATION.md still asserted "0 or a negative value is accepted and dead-letters on the first failure" -- false since PR #383 floored the setting at
ge=1. A catalog row describing a configuration the loader refuses is worse than silence: an operator writes it, startup fails, and the document that sent them there still reads authoritative. docs/BACKLOG.md untouched. Item #1217 stays OPEN -- this is half 1 only, not a closure.Driven, not read off the field: 0 and -1 rejected; 1, 100, and None load; key omitted loads 100;
RetryPolicy(max_attempts=0)(the code-level type, unrelated to the operator setting) still legal.Why
models.pywas deliberately left alone, since it looks like an omission: the floor applies to the operator-facing setting only. Addingge=1tomodels.pywould look like the symmetric completion of the same tightening and would instead delete a used mechanism --RetryPolicy(max_attempts=0)is the deliberate permanent-no-retry idiom, and four test modules depend on it.settings.pyalready anticipates this exact mistake in its own comment; the new test makes that comment executable rather than advisory.The prose test is negative on purpose -- it asserts the false claim cannot come back, not that the new sentence matches word for word. An exact-sentence assertion reds on any rewording, which just trains the next author to edit the test instead of the doc.
Red-first: restoring the old sentence verbatim reds exactly the catalog test (1 of 15 in that selection), anchor asserted unique and file hash asserted changed before scoring, then restored byte-identical.
Half 2 deliberately not in this branch. Whether retry-forever needs a TOML or env spelling is a product question -- the item's own text says choosing the spelling IS the item. Measured rather than assumed:
0,-1,"","none","null","forever","inf"all rejected; key omitted gives 100; PythonNonegivesNone. So retry-forever is reachable in code-first configuration and nowhere else, since TOML has no null literal. Routed to the Dispatcher for a ruling separately.Verification, explicitly scoped: test_retry_cap_default.py + test_delivery_settings.py + test_settings.py, 149 passed. ruff/ruff format clean. Full suite not run.