H2B: make canonical status bytes the evidence boundary - #47
Conversation
Co-Authored-By: Codex <noreply@openai.com>
🤖 Codex PR Review✅ Merge allowed: blocking findings were cleared by independent Codex arbitration ⚖️ Codex Review Arbitration✅ clear: Current source does not establish the contract asserted by this finding. ℹ️ Other Findings1. 🟡 [MEDIUM] Reliability in
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6542c51ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if data["configured_feed_count"] != len(feeds) or data["feed_count"] != len(feeds): | ||
| _fail("status_counter_invalid") |
There was a problem hiding this comment.
Reject empty feed evidence on readback
When persisted bytes are read from the evidence boundary, a canonical status with feeds: [], all counters set to 0, and eligible_for_live_publication: true passes this check, even though build_decision() rejects the same condition with feed_config_empty. In a missing or misconfigured feed snapshot, read_status() can therefore return live-publication-eligible evidence that the producer would never emit.
Useful? React with 👍 / 👎.
| if state in {"accepted", "quarantined"} and kind not in {"rss2", "atom"}: | ||
| _fail("feed_kind_invalid") | ||
| accepted_count = _integer(item["accepted_row_count"], "feed_counter_invalid") | ||
| _integer(item["rejected_row_count"], "feed_counter_invalid") |
There was a problem hiding this comment.
Reconcile rejected row counters
This only type-checks each feed's rejected_row_count; the top-level rejected_row_count is never compared with the per-feed totals or with the producer's zero-rejection invariant. As a result, canonical status bytes can contain arbitrary rejected counters and still be accepted by read_status(), which can corrupt downstream quality gates or summaries that trust those counters.
Useful? React with 👍 / 👎.
| aggregate = _string(data["aggregate_row_digest"], "status_digest_invalid") | ||
| if not _DIGEST_RE.fullmatch(aggregate): | ||
| _fail("status_digest_invalid") |
There was a problem hiding this comment.
Enforce the empty aggregate digest
When accepted_row_count is 0 (all feeds are failed/quarantined), the aggregate row set is known to be empty and build_decision() always emits _digest([]), but readback only checks that aggregate_row_digest is hex. A canonical status for an all-failed or all-quarantined run can therefore change this digest to any 64 hex characters and still pass read_status(), which breaks consumers using the aggregate digest as the row-set evidence.
Useful? React with 👍 / 👎.
| digest = _string(item["row_digest"], "status_digest_invalid") | ||
| if not _DIGEST_RE.fullmatch(digest): | ||
| _fail("status_digest_invalid") |
There was a problem hiding this comment.
Enforce empty row digests for non-accepted feeds
For failed or quarantined feeds there are no rows by invariant, and build_decision() always emits the digest of an empty row list for those feed entries. read_status() only verifies that row_digest is shaped like hex, so canonical bytes for a failed/quarantined feed can carry any digest and still be accepted, breaking per-feed digest evidence for exactly the feeds whose rows are known to be empty.
Useful? React with 👍 / 👎.
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef5b22da3e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if state != "accepted" and digest != _EMPTY_DIGEST: | ||
| _fail("empty_digest_invalid") |
There was a problem hiding this comment.
Reject empty feed digests for accepted rows
When a feed is accepted with accepted_row_count > 0, read_status() still accepts row_digest equal to the known empty-row digest because this empty-digest check only applies to non-accepted feeds. build_decision() cannot emit the digest of [] for a nonempty accepted row list, so tampered canonical bytes can claim accepted rows while preserving empty feed evidence for consumers that trust the per-feed digest.
Useful? React with 👍 / 👎.
| if accepted_rows == 0 and data["aggregate_row_digest"] != _EMPTY_DIGEST: | ||
| _fail("empty_digest_invalid") |
There was a problem hiding this comment.
Reject empty aggregate digest with accepted rows
When accepted_rows > 0, there is no inverse check to reject aggregate_row_digest == _EMPTY_DIGEST; a canonical payload with accepted_row_count set to 1 and the aggregate digest set to sha256(b"[]") passes read_status(). build_decision() would not emit that digest for a nonempty accepted row set, so this lets persisted status evidence contradict its own row counters.
Useful? React with 👍 / 👎.
Scope
Fresh H2B from latest
origin/main@294e30b8eed36f070299b1dc01d34955fb262918; PR #46 is permanently frozen evidence and was not reused.This pure decision slice uses canonical JSON bytes as the sole persisted status evidence:
build_decision(validated_outcomes)returnsstatus_bytes: bytesplus explicitProducerDecision;read_status(bytes)revalidates canonical encoding and semantic invariants, then returns fresh JSON-native built-in dict/list values;No MappingProxy/tuple wire payload, parser, I/O, workflow, publish, weekly, QAR, permission, or automation changes.
Validation