Repository navigation
Conversation
806933d to
7f84e71
Compare
11e49fe to
70a8d17
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — fail-closed coverage-period budget, additive and backward-compatible.
The PR adds two defaulted keyword bounds (max_periods, max_iterations) to expected_subscription_periods, raising CoverageInputError.budget_exceeded with the spec's COVERAGE_BUDGET_EXCEEDED code when exceeded. The reviewer verified: counters are cumulative across buys/regimes so total work is properly bounded; the media_buy_ids.add → guarded-add rewrite is set-identical with no output change; budget_exceeded validates its own budget arg and inherits recovery="correctable"/dispatched=None correctly; non-positive budget routes to COVERAGE_INPUT_INVALID; type(budget) is not int correctly rejects bool. Change is additive, backward-compatible, with correct feat: semver signal, and tests cover both budgets at/over limit plus validation.
No Critical/High/Medium findings. high_risk is false, gated_paths is false, no author team gate, no prior decision. None of rows 1–8 fire → row 9 approve.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean additive change with no blocking or medium findings.
This PR adds max_periods/max_iterations budgets to expected_subscription_periods plus a CoverageInputError.budget_exceeded factory. Reviewer confirmed: correct semver signal (feat:, additive public surface), sound error construction (recovery/dispatched sourced from class attrs, intentional allowlist bypass for the budget-exceeded detail), behavior-preserving pair/iteration counting, validation fails closed on bool and non-positive budgets, and TestCoverageBudget covers at-limit, one-over, iteration, and validation cases. Pure local computation with no operational surface.
Gate checks:
- No critical/high/medium findings (rows 1, 4, 5, 8 N/A).
- gated_paths: false; review_decision: APPROVED (row 2 N/A).
- high_risk: false (rows 3, 5 N/A).
- No no-auto-approve team match (row 7 N/A).
- Prior decision was
approve, so sticky escalation (row 6) N/A.
Falls through to row 9 → approve.
7f84e71 to
1c4b160
Compare
70a8d17 to
d867874
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean pass, no blocking findings.
This PR adds fail-closed budget guards (max_periods/max_iterations with TS-SDK parity) to expected_subscription_periods, a COVERAGE_BUDGET_EXCEEDED error constructed via __new__ to bypass the frozen-detail check while correctly preserving dispatched=None and recovery="correctable", two new public constants, and accompanying tests across _clock.py, coverage.py, and the test file.
Checked: the pairs counter preserves the original idempotent set-add semantics while counting distinct (buy, period) pairs; the iterations increment precedes the end>now break (correct fail-closed direction); budget validation rejects bool/<1. The change is additive and non-breaking to the public surface, so the semver signal is satisfied — no feat!/BREAKING CHANGE required.
Gates: gated_paths is false and review_decision is APPROVED; no high-risk files; no no-auto-approve team match. No critical/high/medium findings. Rows 1–8 do not fire → row 9 approve. Consistent with the prior approve on the preceding head.
1c4b160 to
1676126
Compare
d867874 to
49eb66a
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean additive change.
This PR adds a fail-closed period/iteration budget on expected_subscription_periods that raises COVERAGE_BUDGET_EXCEEDED. The reviewer verified: __new__-based error construction, boundary-exact counting (set-membership guard preserves happy-path semantics), positive-int/bool-rejecting validation, correct feat: semver signal, and that the change is a local computation with no wire-shape or DR-0032/0033 pathway implications. New test coverage is included.
Checks:
- No critical/high/medium findings (clean pass).
- high_risk: false; no high-risk path modifications or deletions.
- gated_paths: false; review_decision: APPROVED.
- No no-auto-approve team match.
- No public-surface break; semver signal correct.
Decision table: none of rows 1–8 fire → row 9 (approve). Prior decision was also approve on a clean run; this remains a net-clean additive change.
1676126 to
454dc8a
Compare
133beef to
bd1fe9f
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean delta, no blocking findings.
This PR adds fail-closed budget guards (max_periods/max_iterations, defaults 100K/2M matching the TS SDK) to expected_subscription_periods, a CoverageInputError.budget_exceeded constructor (code COVERAGE_BUDGET_EXCEEDED), and validation rejecting non-positive budgets. Reviewer verified the __new__ bypass stays consistent with the normal constructor, subscription_id/account_id are in scope at both guard sites, the media-buy-id guard preserves set idempotence while counting distinct pairs, off-by-one is correct, and the new params are backward-compatible keyword defaults. Tests cover both budgets and the positive-integer check.
No critical/high/medium findings. Checked gates:
- gated_paths: false
- No no-auto-approve team match
- high_risk: false
- Prior decision was
approve; clean pass stands.
No decision-table trigger fires (rows 1–8); falls through to row 9 → approve.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean three-file delta adding a fail-closed coverage budget.
What I checked:
- No critical/high/medium findings from the reviewer.
gated_paths: falseandreview_decision: APPROVED— no hard gate blocks this.high_risk: false; no author team gate.- Additive public surface (fail-closed coverage budget raising
COVERAGE_BUDGET_EXCEEDED,max_periods=100,000,max_iterations=2,000,000) correctly shipped underfeat(reporting)— correct semver signal for a non-breaking addition. budget_exceededclassmethod bypasses input-detail validation while inheritingrecovery="correctable"/dispatched=None(_clock.py:9-18); iteration counting bounds the previously-unbounded generator before materialization (coverage.py:73-80); pair counting is idempotent so the happy path is unchanged (coverage.py:89-98); validation fail-closes on bool viatype(...) is not int(coverage.py:62-65).- New branches are covered by
tests/test_reporting_subscription_coverage.py.
No decision-table rows 1–8 fired; falls through to row 9. Prior decision was also approve.
cc13b0f to
7873bac
Compare
expected_subscription_periods gains max_periods (100,000 owed buy-period pairs) and max_iterations (2,000,000 examined boundaries), matching the TypeScript SDK's defaults. Exceeding either raises CoverageInputError with code COVERAGE_BUDGET_EXCEEDED, detail naming the budget, and recovery correctable. The SDK never returns a partial set. The seller engine keeps isolating such a failure per subscription in evaluation_errors. Until now Python never raised this code from the spec's error-codes.json. Refs #1695 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
bd1fe9f to
b502e8e
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve.
Clean pass with no blocking or medium findings. This delta adds a fail-closed coverage budget (max_periods/max_iterations) to expected_subscription_periods, matching the TS SDK defaults and raising the spec's COVERAGE_BUDGET_EXCEEDED.
Checked:
- budget_exceeded factory bypasses init correctly (code/detail set, recovery="correctable", dispatched=None from class attrs)
- pairs counting is behavior-preserving with correct strictly-greater at-limit semantics
- iterations/pairs reset per call
- type-strict positive-int validation
- additive params + alphabetized all exports under a non-breaking feat prefix
- no wire-field change, so no DR-0032/0033 pathway owed
- tests cover at-limit, one-over, iteration budget, and validation
No no-auto-approve team match; gated_paths false; review_decision APPROVED; high_risk false. No rows 1–8 fire → row 9 approve. Prior decision was approve; this remains clean.
…udget Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean pass, no blocking findings.
Checked: this delta adds a fail-closed budget (max_periods/max_iterations, defaults 100k/2M) to the previously unbounded local coverage loop in expected_subscription_periods, plus a budget_exceeded classmethod on CoverageInputError (COVERAGE_BUDGET_EXCEEDED). The change is additive/non-breaking (new kwargs with defaults, two new constants), correctly shipped under feat:, happy path unchanged, no wire change (DR-0032/0033 N/A), and all three branches are tested.
Decision-table walk: no critical/high findings (row 1 n/a); gated_paths false and review_decision APPROVED (row 2 n/a); high_risk false, no deletions/modifications triggers (rows 3–5 n/a); prior decision was approve so sticky-escalate does not apply (row 6 n/a); no no-auto-approve team match (row 7 n/a); zero medium findings (row 8 n/a). Falls through to row 9 → approve.
Summary
A small slice stacked on #1743, ahead of the P9 docs. Review only
feat(reporting): fail closed on a coverage period budget.Python had no coverage period budget, so the spec's
COVERAGE_BUDGET_EXCEEDED(error-codes.json, raised by both sides) was never raised.expected_subscription_periodsnow takes:max_periods: owed (buy, period) pairs, default 100,000;max_iterations: examined period boundaries, default 2,000,000.These are the TypeScript SDK's
max_periods/max_iterationswith the same defaults.Exceeding either raises
CoverageInputErrorwith:code="COVERAGE_BUDGET_EXCEEDED";detailset tomax_periodsormax_iterations;recovery="correctable";dispatched;Coverage never returns a partial set. A non-positive budget is
COVERAGE_INPUT_INVALID. The seller engine already isolates a failing subscription inevaluation_errors, so one subscription that blows the budget never stops another.Tests
TestCoverageBudgetintests/test_reporting_subscription_coverage.pycovers the period budget exactly at and one over its limit, the iteration budget, and budget validation. The coverage, parity and engine suites pass, as do ruff and mypy.Refs #1695
🤖 Generated with Claude Code