The revocation-bundle freshness path still has two public-boundary gaps that are separate from the existing freshness work in #239.
sign.verify_record() already rejects boolean now, but its bundle-specific max_bundle_age_seconds input is only checked with < 0:
if max_bundle_age_seconds < 0:
...
In Python, bool is an int subclass, so True is acted on as 1 second and False as 0 seconds.
The lower-level public revocation.check_bundle() accepts now, max_bundle_age_seconds, and max_future_skew_seconds and immediately uses them in freshness arithmetic without runtime primitive checks. The same boolean-as-0/1 behavior therefore exists when callers use that public entry point directly.
These inputs change the revocation result rather than merely formatting an error: a boolean configuration can make a bundle appear fresh, expired, or future-dated under a 0/1-second policy instead of being refused as malformed configuration.
Ownership boundary
PR #239 already owns top-level Trust Record freshness validation for sign.verify_record(max_age_seconds=...) and sign.verify_record(max_future_skew_seconds=...). This issue does not duplicate or modify that lane.
The bounded surface here is only:
sign.verify_record(max_bundle_age_seconds=...);
revocation.check_bundle(now=...);
revocation.check_bundle(max_bundle_age_seconds=...);
revocation.check_bundle(max_future_skew_seconds=...).
Reproduction
Against current main at fc38496f3ddacaa7ce922e1218b6fcd91735d751:
sign.verify_record(..., max_bundle_age_seconds=True) -> treated as 1
sign.verify_record(..., max_bundle_age_seconds=False) -> treated as 0
revocation.check_bundle(..., now=True, ...) -> treated as 1
revocation.check_bundle(..., max_bundle_age_seconds=True, ...) -> treated as 1
revocation.check_bundle(..., max_future_skew_seconds=False, ...) -> treated as 0
The repository's public-function sweep varies check_bundle's first positional bundle argument while holding these keyword policy arguments valid, so it does not exercise this surface.
Proposed bounded fix
Hold the bundle-freshness policy inputs to integer seconds before they are acted on, explicitly excluding bool. Preserve all existing defaults and freshness semantics. Do not absorb #239's top-level max_age_seconds / max_future_skew_seconds work.
AI-assistance disclosure: ChatGPT assisted with source triage, adversarial-case design, duplicate/ownership review, and issue drafting. altrudev reviewed the bounded claim and remains responsible for the contribution.
The revocation-bundle freshness path still has two public-boundary gaps that are separate from the existing freshness work in #239.
sign.verify_record()already rejects booleannow, but its bundle-specificmax_bundle_age_secondsinput is only checked with< 0:In Python,
boolis anintsubclass, soTrueis acted on as1second andFalseas0seconds.The lower-level public
revocation.check_bundle()acceptsnow,max_bundle_age_seconds, andmax_future_skew_secondsand immediately uses them in freshness arithmetic without runtime primitive checks. The same boolean-as-0/1 behavior therefore exists when callers use that public entry point directly.These inputs change the revocation result rather than merely formatting an error: a boolean configuration can make a bundle appear fresh, expired, or future-dated under a 0/1-second policy instead of being refused as malformed configuration.
Ownership boundary
PR #239 already owns top-level Trust Record freshness validation for
sign.verify_record(max_age_seconds=...)andsign.verify_record(max_future_skew_seconds=...). This issue does not duplicate or modify that lane.The bounded surface here is only:
sign.verify_record(max_bundle_age_seconds=...);revocation.check_bundle(now=...);revocation.check_bundle(max_bundle_age_seconds=...);revocation.check_bundle(max_future_skew_seconds=...).Reproduction
Against current
mainatfc38496f3ddacaa7ce922e1218b6fcd91735d751:The repository's public-function sweep varies
check_bundle's first positionalbundleargument while holding these keyword policy arguments valid, so it does not exercise this surface.Proposed bounded fix
Hold the bundle-freshness policy inputs to integer seconds before they are acted on, explicitly excluding
bool. Preserve all existing defaults and freshness semantics. Do not absorb #239's top-levelmax_age_seconds/max_future_skew_secondswork.AI-assistance disclosure: ChatGPT assisted with source triage, adversarial-case design, duplicate/ownership review, and issue drafting.
altrudevreviewed the bounded claim and remains responsible for the contribution.