Skip to content

ci(META-337): a missing parity receipt must fail, not skip to green - #15

Merged
qmarcelle merged 3 commits into
mainfrom
meta/337-required-checks
Aug 13, 2026
Merged

ci(META-337): a missing parity receipt must fail, not skip to green#15
qmarcelle merged 3 commits into
mainfrom
meta/337-required-checks

Conversation

@qmarcelle

@qmarcelle qmarcelle commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Prerequisite for promoting parity-receipt-reproduction to a required check under META-337.

The defect

Both substantive steps of parity-receipt-reproduction were gated on steps.check-receipt.outputs.has_receipt == 'true'. With no committed receipt they skipped, the job concluded success, and the log read "No committed parity receipt found — skipping reproduction check."

The receipt is present on main today, so the job is currently doing real work. The hazard is structural, and it is about to matter: docs/review/merge-policy.md records this job as produced-but-not-required, and META-337 promotes it. The moment it is required, the cheapest way to satisfy a failing parity gate is to delete the receipt — and the gate would reward that with green.

This is the same rule merge-policy.md §5 already applies to reviewers ("a check that has not run is not a pass"), applied to CI itself.

The change

  • Absence of docs/migration/parity-receipt.json is now a hard failure.
  • The two reproduction steps run unconditionally.
  • The failure output names the invariant, why it matters, the authority, the evidence that discharges it, and what must not be weakened — so an agent can act on it without a human relay (META-337 §7).

If the migration this receipt records is genuinely retired, the job should be removed in the same change that removes the receipt. That is a reviewable decision; silently losing the coverage is not.

Scope

CI only. No product code, packaging, or adapter behavior is touched — workspacejson/integrations remains read/inspect for product work under HAC-328.

Proof

Bidirectional red/green proof of this gate is recorded on a separate DO NOT MERGE branch and linked in this PR before the required-check promotion lands.

Refs META-337.

Summary by Sourcery

Enforce parity-receipt-reproduction as a failing check when the committed parity receipt is missing, ensuring the job cannot silently pass without running.

CI:

  • Change the parity-receipt-reproduction workflow step to hard-fail if docs/migration/parity-receipt.json is absent instead of skipping to success.
  • Run the parity receipt reproduction and comparison steps unconditionally now that receipt absence is treated as an error.

…to green

`parity-receipt-reproduction` gated both of its substantive steps on
`steps.check-receipt.outputs.has_receipt == 'true'`. On a branch with no
committed receipt the two steps skipped, the job concluded `success`, and the
log said "skipping reproduction check" — a green result that had reproduced
nothing.

That is tolerable while the job is advisory. It is not tolerable once the check
is required, which META-337 intends: at that point the cheapest way to satisfy a
failing parity gate is to delete the receipt, and the gate would reward it.
"Missing is not green" has to hold for the gate itself, not only for the product
code it inspects.

Absence of the receipt is now a hard failure, and the two reproduction steps run
unconditionally. The failure output names the invariant, the authority, the
evidence that discharges it, and what must not be weakened to recover green, so
an implementation agent can act on it without a human relay.

This changes CI only. No product code, no packaging, and no adapter behavior is
touched.

Refs META-337.
Copilot AI lite review requested due to automatic review settings August 13, 2026 00:38
@sourcery-ai

sourcery-ai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR changes the parity-receipt-reproduction CI job so that a missing parity receipt is a hard failure and the reproduction steps always run, with detailed failure messaging suitable for automated agents.

Flow diagram for updated parity-receipt-reproduction CI job

flowchart TD
  J[parity-receipt-reproduction job start]

  J --> R[Require a committed parity receipt]
  R -->|docs/migration/parity-receipt.json missing| F[Fail job and write invariant to GITHUB_STEP_SUMMARY]
  R -->|docs/migration/parity-receipt.json present| P[Reproduce parity receipt using verify-clone-parity.mjs]
  P --> C[Compare CI receipt against committed reference using verify-receipt.mjs]
  C --> S[Job succeeds]
Loading

File-Level Changes

Change Details Files
Make absence of docs/migration/parity-receipt.json a hard CI failure instead of causing the job to skip and succeed.
  • Replace the previous check-receipt step with a require-receipt step that exits with status 1 when the receipt file is missing.
  • Emit a GitHub Actions formatted error pointing at the missing docs/migration/parity-receipt.json file.
  • Write a structured explanatory section to GITHUB_STEP_SUMMARY documenting the invariant, rationale, authority, required evidence, and non-weakenable behavior when the receipt is absent.
.github/workflows/ci.yml
Run the parity receipt reproduction and comparison steps unconditionally when the workflow reaches them.
  • Remove the conditional if: steps.check-receipt.outputs.has_receipt == 'true' from the reproduction step.
  • Remove the same conditional from the comparison step so both always execute after the receipt presence gate passes.
.github/workflows/ci.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qmarcelle has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Consider extracting the long failure explanation block into a reusable script or template so the workflow YAML stays compact and easier to maintain.
  • Since the receipt check is now hard-failing, you may want to add an explicit shell: bash to the step to avoid subtle differences if the default shell changes in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the long failure explanation block into a reusable script or template so the workflow YAML stays compact and easier to maintain.
- Since the receipt check is now hard-failing, you may want to add an explicit `shell: bash` to the step to avoid subtle differences if the default shell changes in the future.

## Individual Comments

### Comment 1
<location path=".github/workflows/ci.yml" line_range="88" />
<code_context>
+      # it becomes a merge-authorizing false green the moment the check is
+      # required: the cheapest way to satisfy a failing parity gate would be to
+      # delete the receipt. Absence is now a failure.
+      - name: Require a committed parity receipt
         run: |
-          if [ -f docs/migration/parity-receipt.json ]; then
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Explicitly set the shell for this step to ensure `set -euo pipefail` behaves as expected.

GitHub-hosted Ubuntu runners default to bash today, but that’s an implementation detail. Since this step depends on `set -euo pipefail`, explicitly setting `shell: bash` (or your chosen shell) will ensure consistent behavior if runner defaults change or this job runs in a different environment.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .github/workflows/ci.yml
qmarcelle added a commit that referenced this pull request Aug 13, 2026
DO NOT MERGE. Tree is now identical to the #15 fix branch. Expect all four CI
checks GREEN, closing both bidirectional proofs.

Correction to PROOF 3/4: rewriting package.json with a JSON.stringify round trip
reformatted the `files` array and tripped biome, so `build-and-smoke` went red
for a formatting reason rather than the injected one. That commit is not
admissible as a proof and is not cited as one. The two gates are proven by
PROOF 1/4 and 2/4, whose reds were verified against the failing step.
The step's failure semantics depend on `set -euo pipefail`. GitHub-hosted
runners default `run:` to bash today, but that is an implementation detail,
and this step exists precisely to stop a gate from passing without doing
work — resting its own strictness on an undeclared default is the same bet
the change removes.

Addresses the Sourcery review note on the step.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qmarcelle has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@qmarcelle

Copy link
Copy Markdown
Contributor Author

@greptileai review

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qmarcelle has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

The §2 table claimed three required contexts. The API returns five —
`standard-candidate-consumption` and `SonarCloud Code Analysis` were promoted
without the change reaching this file.

This is the case §2 already legislates for ("the API is right and this file is
stale — treat that as a documentation defect, and correct it in the PR that
noticed"), exercised for the first time. The drift is its own argument: the
stale table said `SonarCloud Code Analysis` was non-blocking, so a reader
trusting it would have concluded PR #12 was mergeable while it was blocked on
exactly that context.

Corrected:
- §2 required-context row and the sentence restating it.
- §2 "Observed gap" — `standard-candidate-consumption` is now required, leaving
  `parity-receipt-reproduction` as the only CI job whose failure does not block.
  That is this PR's subject, so the section now names the dependency rather than
  describing a gap that has since narrowed.
- §2 and §4 PR #12 observations re-dated to the protection in force when they
  were taken. They are kept, not rewritten — the mechanism they demonstrate is
  unaffected, only the non-blocking claim expired.
- Provenance line re-measured: 2026-08-13 against `main` at `70cfd57`.

No protection setting was changed by this commit. It only makes the file agree
with what the API already returns.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qmarcelle has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@sonarqubecloud

Copy link
Copy Markdown

@qmarcelle
qmarcelle merged commit 4e8204e into main Aug 13, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants