feat: add fail-closed runtime evidence aggregate - #143
Conversation
Co-Authored-By: Codex <noreply@openai.com>
|
Closing unmerged: required CI fails in the QPK pin guard because current base still pins 92458590a463 while the fresh upstream guard requires 61783fdaee86. This is reproducible on exact origin/main, outside the frozen runtime_support.py write set, and cannot be repaired without expanding scope. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c1c5201bc4
ℹ️ 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 str(field).lower() in _RUNTIME_EVIDENCE_FORBIDDEN_FIELDS: | ||
| errors.append(f"runtime_evidence_aggregate contains forbidden field: {field}") |
There was a problem hiding this comment.
Reject credential aliases in redaction checks
When a component mapping contains this repository's tg_token field—or variants such as apiKey or private_key—the exact lowercase lookup does not match token or api_key. Because the component validators also permit unknown keys, build_runtime_evidence_aggregate() returns a supposedly redacted aggregate containing the live secret; use closed per-component field allowlists or normalize and reject credential aliases.
Useful? React with 👍 / 👎.
| def _is_utc_timestamp(value: Any) -> bool: | ||
| if not isinstance(value, str) or not value.endswith("Z"): | ||
| return False | ||
| try: | ||
| datetime.fromisoformat(value.replace("Z", "+00:00")) |
There was a problem hiding this comment.
Require a time component in UTC timestamps
When input_timestamp is date-only, such as 2026-03-13Z, replacing Z produces 2026-03-13+00:00, which datetime.fromisoformat() accepts as a naive midnight datetime. The helper therefore accepts a value that identifies neither an explicit time nor an aware UTC instant, allowing ambiguous release provenance; require a time component and verify that the parsed datetime is UTC-aware.
Useful? React with 👍 / 👎.
| def _is_sha256(value: Any) -> bool: | ||
| return isinstance(value, str) and bool(re.fullmatch(r"[0-9a-f]{64}", value.strip())) |
There was a problem hiding this comment.
Validate the stored digest instead of a stripped copy
When a digest has leading or trailing whitespace, the regex succeeds against value.strip(), but the original malformed value remains in the aggregate. Consumers performing exact identity or reconciliation comparisons can consequently receive a non-digest even though validation reported success; either reject whitespace by matching value directly or normalize the value before storing it.
Useful? React with 👍 / 👎.
| """Build a fail-closed aggregate that cannot claim runtime activity.""" | ||
| aggregate = { | ||
| "contract_version": RUNTIME_EVIDENCE_CONTRACT_VERSION, | ||
| "release_identity": dict(release_identity), |
There was a problem hiding this comment.
Detach nested inputs before returning the aggregate
When the caller retains and later updates a nested source object, especially release_identity["artifacts"][name], this outer dict() copy leaves that object shared with the returned aggregate. A routine update to the source after construction can therefore replace a validated digest or otherwise invalidate the aggregate without touching the returned value or triggering revalidation; deep-copy the inputs or reconstruct the closed validated schema.
Useful? React with 👍 / 👎.
| status = reconciliation.get("status") | ||
| if status not in RECONCILIATION_STATUSES: | ||
| errors.append(f"{label} status must be one of MISSING, MATCHED, MISMATCHED") | ||
| return | ||
| if status == "MATCHED": |
There was a problem hiding this comment.
Reject digest fields on missing reconciliations
When status is MISSING, this function skips all validation of reconciliation digest fields, so an object such as {"status": "MISSING", "durable_receipt_sha256": "invalid"} is accepted as valid evidence. This permits malformed or contradictory receipt provenance to survive validation; reject digest fields for MISSING, or validate every supplied digest and define which ones are allowed for that status.
Useful? React with 👍 / 👎.
Scope
MATCHEDclaimsValidation
python3 -m pytest tests/test_runtime_support.py tests/test_binance_runtime_infra.py tests/test_contract_governance.py -qpython3 -m compileall -q runtime_support.pypython3 -m ruff check runtime_support.py tests/test_runtime_support.py