Skip to content

fix(release): require verified version-tag pushes for GHCR - #1205

Open
qnbs wants to merge 8 commits into
mainfrom
fix/docker-tag-publish-gate-20261108
Open

qnbs wants to merge 8 commits into
mainfrom
fix/docker-tag-publish-gate-20261108

Conversation

@qnbs

@qnbs qnbs commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

User description

Summary

Harden GHCR publishing so an image can be published only from a real push of a version tag whose annotated tag and target commit pass the repository GitHub signature verifier, and whose exact commit passes the three-lockfile OSV audit. Manual Docker dispatch remains audit-only.

Security controls

  • Add a read-only tag-verification job using the existing signature verifier and full tag history.
  • Require both verifier success and exact-SHA audit success in the Docker publishing job.
  • Require the release-policy checker to match the complete approved conjunction and reject permissive alternatives.
  • Reject skipped or non-blocking steps in the verifier job.
  • Keep the proof workflow write-free; its explicit inputs simulate event, ref, and signature outcomes and do not verify a real tag.

Validation

  • Release-security tests: 42 passed, including negative cases for step-level if and continue-on-error.
  • Workflow-policy and release-security checks: passed.
  • The current main changelog checker was exercised with PR 1205 metadata: passed.
  • Biome, git diff check, PR budget, and pnpm run ci:prepush: passed.
  • Budget: 8 files, 621 meaningful lines, 4 signed commits; below hard limits, with the repository target-tier caution.
  • Exact-head hosted CodeScene, CodeQL, Security Audit, Verified Signatures, Workflow Policy, Changelog Guard, Semgrep, Sourcery, and CodeAnt checks: passed. Node 22 and Node 24 quality gates are still running.
  • All existing actionable inline review findings are resolved. CodeRabbit latest review attempt was rate-limited; this is not represented as a pass. The local CodeScene CLI could not complete its license check, so the hosted CodeScene result is the available evidence.

Release boundary

No Docker publishing workflow or release was dispatched. This PR does not authorize the v1.29.3 tag; release status remains HOLD pending its separate exact-candidate qualification.

Summary by Sourcery

Require GHCR images to publish only from fully verified protected version-tag pushes that pass the exact-commit security audit.

New Features:

  • Require GHCR publishing to originate from protected version-tag pushes whose annotated tag and target commit are GitHub-verified and bound to the pushed commit.
  • Add protected-main ancestry and tag-integrity checks to release signature verification.
  • Keep manual Docker dispatch available for audit diagnostics while preventing it from publishing images.

Bug Fixes:

  • Prevent retargeted, lightweight, unsigned, unprotected, or changed release tags from publishing container images.
  • Prevent permissive workflow conditions, skipped verifier steps, and ignored verifier failures from bypassing release security gates.

Enhancements:

  • Strengthen release-policy validation to require exact fail-closed conditions and the complete verifier-plus-audit dependency conjunction.
  • Add a no-write release-gate proof workflow that simulates valid and invalid publishing inputs.
  • Update release, CI, and testing documentation and published test metrics.

Documentation:

  • Document the protected-tag, signature-verification, exact-commit audit, and manual-dispatch publishing boundaries.

Tests:

  • Expand release-security policy coverage with negative cases for bypass conditions, environment injection, skipped steps, and non-blocking verifier failures.
  • Add coverage for tag target binding, protected-main ancestry, tag retargeting, tag-name mismatches, and verification races.

Chores:

  • Update the unreleased changelog with the GHCR publishing security requirements.

CodeAnt-AI Description

Require verified protected version tags for GHCR publishing

What Changed

  • GHCR images publish only after a real push of a protected v* tag whose annotated tag and target commit are signed and match the pushed commit in protected main history.
  • Publishing also requires a successful security audit of that exact commit. Manual Docker runs can audit but never publish.

Impact

✅ GHCR publishes only verified protected version tags
✅ Manual dispatch cannot publish container images
✅ Retargeted tags cannot publish images

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • Release Security

    • Container images now publish only from protected v* tag pushes after the tag signature and commit are verified and the exact commit passes the security audit. Manual dispatches do not publish images.
    • Release-tag checks confirm the signed tag matches the triggering commit and belongs to protected main history.
  • Documentation

    • Clarified release-publishing requirements and that the release-gate proof simulates inputs rather than verifying a real tag.
    • Updated documented test totals.

Require a real push event for v-prefixed tag refs in the Docker publish job while preserving the exact audited-SHA gate. Keep workflow_dispatch available only for the no-write release-gate proof, with explicit simulated tag-push inputs and negative coverage for manual dispatch.
@vercel

vercel Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
worldscript-studio Ignored Ignored Preview Nov 8, 2026 9:11pm UTC

@sourcery-ai

sourcery-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Data structures

Expose the release-condition and workflow-specification fields used by the policy checker to validate tag-push requirements.

  • scripts/release-security-gate.d.mts L10-24

API

Make remote tag verification require an expected commit SHA and expose the helper that binds the push event target to the GitHub commit context.

  • scripts/signing/verify-remote.d.mts L47, L54

Implementation

Bind the signature-verifier entry point to the actual pushed version-tag ref and its event payload before verifying the remote tag.

  • scripts/signing/verify-github-signatures.mjs L6, L52-56, L61

Verify that the annotated tag and target commit are signed, match the pushed commit, belong to protected main history, and remain unchanged during verification.

  • scripts/signing/verify-remote.mjs L37-62, L106-120, L146-160 (+3 small edits)

Define and enforce exact fail-closed release conditions, including the trusted verifier job, its pinned checkout and environment, and mandatory verifier dependencies for Docker publishing.

  • scripts/release-security-gate.mjs L21-64, L200-222, L229-347 (+3 small edits)

Configuration

Gate GHCR publication on a protected real version-tag push, successful tag verification, and a successful exact-SHA security audit, while keeping manual dispatch non-publishing.

  • .github/workflows/docker.yml L8, L72-114

Extend the dispatch-only proof workflow with explicit simulated tag-push and signature inputs while retaining an echo-only, no-write stand-in.

  • .github/workflows/release-gate-proof.yml L1-5, L16-38, L103

Documentation

Record the GHCR publishing boundary and update the README's synchronized test-count metrics.

  • CHANGELOG.md L10-11
  • README.md L23-1032 (4 small edits)

Document the additional GHCR tag-verification gate, its manual-dispatch behavior, and the simulated nature of the no-write proof; retain the surrounding CI reference and table formatting updates in this documentation change.

  • docs/CI.md L68-78, L139-158, L544-564 (+10 small edits)

Tests

Cover event-to-commit binding and verified annotated-tag checks in the existing GitHub signature API tests.

  • tests/unit/signing.test.ts L883-896 (+3 small edits)

Add positive and negative tests for the release workflow policy, including bypass conditions, verifier configuration, and simulated proof inputs.

  • tests/unit/tooling/releaseSecurityGate.test.ts L33-42, L57-259, L452-478 (+3 small edits)

Exercise release-tag SHA binding, signature checks, protected-main ancestry, tag stability, and fail-closed handling of malformed or lightweight tags.

  • tests/unit/tooling/verifyRemoteTag.test.ts L1-257

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

@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

CodeAnt  CodeAnt Review Status

✅  Review completed

Status Commit Started (UTC) Finished (UTC)
✅  #4ad9a Incremental review completed d9461b4 Nov 08, 2026 · 21:03 21:04
✅  #0d583 Reviewed your PR f5d843b Nov 08, 2026 · 20:05 20:10
✅  #fdbb7 Reviewed your PR e9b8e22 Nov 08, 2026 · 19:19 19:23

@codeant-ai

codeant-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-08T21:12:35.801095Z 9fe3583 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Explain Change →

Warning

Review limit reached

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Next included review available in 50 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 80 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between d9461b4 and 9fe3583.

Files selected for processing: 3

  • .github/workflows/docker.yml
  • scripts/release-security-gate.mjs
  • tests/unit/tooling/releaseSecurityGate.test.ts
Walkthrough

The release verifier now checks that a signed version tag targets the triggering commit and that the commit belongs to protected main. Docker publishing requires protected tag-push conditions, verifier success, and a successful exact-commit audit. The proof workflow simulates these inputs. The README updates its test totals.

Changes: Release Security Gates

Layer / File(s) Summary
Bind tag verification to the pushed commit
scripts/signing/verify-remote.mjs, scripts/signing/verify-remote.d.mts, scripts/signing/verify-github-signatures.mjs, tests/unit/signing.test.ts, tests/unit/tooling/verifyRemoteTag.test.ts
The verifier checks the pushed commit SHA, annotated tag name and target, protected-main ancestry, and tag-ref stability. Tests cover valid and rejected verification paths.
Verify tags before Docker publishing
.github/workflows/docker.yml
A pinned verifier job runs for protected version-tag pushes. The publishing job requires verifier success, audit success, and an audited SHA that matches github.sha.
Validate workflow-specific release conditions
scripts/release-security-gate.mjs, scripts/release-security-gate.d.mts, tests/unit/tooling/releaseSecurityGate.test.ts
The gate validator checks exact event conditions, dependencies, and verifier settings. Tests cover weakened conditions and altered verifier configuration.
Define proof inputs and document release behavior
.github/workflows/release-gate-proof.yml, CHANGELOG.md, docs/CI.md, tests/unit/tooling/releaseSecurityGate.test.ts
The proof workflow requires inputs that simulate a verified version-tag push. The changelog and CI documentation describe Docker publishing conditions and clarify that the proof does not verify a real tag.

README Test Count

Layer / File(s) Summary
Update synchronized test counts
README.md
The README updates its reported test count to 8,724+ across 656 files.
Merge Risk: Low · previous review d9461

The release-tag verification logic looks sound. Before merge, tidy the duplicated test calls that fail the CodeScene gate and bound the verifier-job slice in the policy test so it actually checks that job.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Nov 8, 2026
@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

View results CodeAnt  CodeAnt Quality Gate Results

Commit 9fe35835 · Scanned Nov 08, 2026 at 21:11 UTC

❌  Overall Status: FAILED

Quality Gate Status Details
New code coverage ⚪  Not applicable Not applicable — no applicable code changes
Secrets ✅  Passed 0 secrets found, 3 false positive secrets suppressed
Duplicate code ✅  Passed 0.0% duplicated
SAST ✅  Passed No security issues
Bugs ❌  Failed Rating C · 1 bugs (1 high)
IaC ✅  Passed Rating B · 1 issues (1 medium)

Fix in Cursor Fix in VSCode Claude

View failure details
🐛 Bugs — 1 issues
Severity File Line Message
HIGH .github/workflows/docker.yml 94 The verifier looks up this mutable tag name but never compares its target with github.sha; a retag between push and lookup can verify one commit while publishing another.

@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

View results CodeAnt  CodeAnt Coverage Report

Commit 9fe35835 · Scanned Nov 08, 2026 at 21:11 UTC

⚪  Overall Status: Not applicable

Coverage Status Details
New Code Coverage ⚪  Not applicable Not applicable — no applicable code changes

New-code coverage threshold not configured; coverage is reported but not enforced.

codescene-access[bot]

This comment was marked as outdated.

Record the release-pipeline boundary under the actual successor PR number so the changelog guard and release history remain traceable.

@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 3 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/docker.yml" line_range="77" />
<code_context>
     needs: [security-audit]
     if: >-
-      ${{ needs.security-audit.result == 'success' && needs.security-audit.outputs.audited-sha == github.sha }}
+      ${{ github.event_name == 'push' && github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') && needs.security-audit.result == 'success' && needs.security-audit.outputs.audited-sha == github.sha }}
     runs-on: ubuntu-latest
     timeout-minutes: 20
</code_context>
<issue_to_address>
**Unsigned tags publish images**

When an unsigned `v*` tag is pushed and its commit passes the audit, `build-push` checks the tag ref and audit result but not the tag signature, so it publishes the image to GHCR from an unsigned tag.

Require successful signature verification of the exact tag before allowing `build-push` to publish.

Also at `.github/workflows/docker.yml:75`.
</issue_to_address>

### Comment 2
<location path="scripts/release-security-gate.mjs" line_range="179-180" />
<code_context>
-function checkGateCondition(jobName, condition, fail) {
-  const missing = REQUIRED_GATE_CONDITIONS.filter((required) => !condition.includes(required));
+function checkGateCondition(jobName, condition, fail, requiredEventConditions = []) {
+  const missing = [...REQUIRED_GATE_CONDITIONS, ...requiredEventConditions].filter(
+    (required) => !condition.includes(required),
+  );
   for (const required of missing) fail(`job "${jobName}" if: must require ${required}`);
</code_context>
<issue_to_address>
**Publish gate bypasses pass checks**

When a publish condition retains the required text in one branch but adds a permissive `||` branch, `checkGateCondition` and the substring assertions in `releaseSecurityGate.test.ts` accept the condition, so a workflow can publish through the alternate branch while the policy check and test pass.

Validate that every required predicate applies to every publishing branch, and add tests that reject conditions with permissive `||` branches.

Also at `scripts/release-security-gate.mjs:181`, `tests/unit/tooling/releaseSecurityGate.test.ts:46`, `tests/unit/tooling/releaseSecurityGate.test.ts:261`.
</issue_to_address>

### Comment 3
<location path=".github/workflows/release-gate-proof.yml" line_range="97" />
<code_context>
     needs: [security-audit]
     if: >-
-      ${{ needs.security-audit.result == 'success' && needs.security-audit.outputs.audited-sha == github.sha }}
+      ${{ github.event_name == 'workflow_dispatch' && inputs.simulated_event == 'push' && inputs.simulated_ref_type == 'tag' && startsWith(inputs.simulated_ref, 'refs/tags/v') && needs.security-audit.result == 'success' && needs.security-audit.outputs.audited-sha == github.sha }}
     runs-on: ubuntu-latest
     timeout-minutes: 2
</code_context>
<issue_to_address>
**Proof gate no longer matches publishing**

The stand-in now requires simulated-event inputs, while Docker checks the actual push event and ref. The proof therefore validates a different condition from the real publishing gate, so callers no longer get the required parity assurance.

Preserve the proof workflow’s required condition parity with the actual publish gate, or update the applicable repository guidance if the simulation model intentionally replaces that requirement.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 3 findings to address first, and a pushed tag beginning with v can now authorize the GHCR publish job once its commit passes the audit; the condition does not verify that the tag is signed or otherwise approved. If an unintended tag publishes an image, reverting restores the previous gate but does not retract an image that was already pushed.

Blocking findings: .github/workflows/docker.yml:77, scripts/release-security-gate.mjs:180, .github/workflows/release-gate-proof.yml:97


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread .github/workflows/docker.yml Resolved
Comment thread scripts/release-security-gate.mjs Resolved
Comment thread .github/workflows/docker.yml Resolved
Comment thread scripts/release-security-gate.mjs Resolved
@codeant-ai

codeant-ai Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

CodeAnt  CodeAnt PR Risk

🟢  Low Risk

  • The PR appears safe to merge; Docker publishing requires a protected signed tag push and a successful audit of the exact triggering commit.
  • The verifier binds the tag target to the push SHA, checks signatures and protected-main ancestry, then confirms the tag did not change during verification.

Assessed commit: d9461b43b8dc

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between d9c02fc and e9b8e22.

Files selected for processing: 5

  • .github/workflows/docker.yml
  • .github/workflows/release-gate-proof.yml
  • README.md
  • scripts/release-security-gate.mjs
  • tests/unit/tooling/releaseSecurityGate.test.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Comment thread scripts/release-security-gate.mjs Resolved
@codecov

codecov Bot commented Nov 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Require Docker publication to depend on the repository's annotated-tag and target-commit signature verifier, in addition to the exact-SHA OSV audit and real version-tag push. Make the release-security checker require an exact conjunctive condition and reject alternate OR paths; model signature success explicitly in the no-write proof and document the distinction.
@qnbs qnbs changed the title fix(release): require version-tag pushes for GHCR publishing fix(release): require verified version-tag pushes for GHCR Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

[check-pr-size] PR size is over the target tier (normal profile): 13 files, 1149 meaningful lines, 8 commits — limit ≤8 files / ≤400 lines / ≤6 commits. Consider splitting into smaller, independently reviewable PRs.

codescene-access[bot]

This comment was marked as outdated.

Comment thread scripts/release-security-gate.mjs Resolved
codescene-access[bot]

This comment was marked as outdated.

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

The earlier CodeAnt PR Risk summary was assessed against e89e8d38491c; it is superseded by the later fixes. Signed commit c548ef2456c171cb3ee7ccb24f81b18960df9c40 added exact tag-signature verification and fail-closed condition validation; f5d843bbdd02fc46c38e96f9829de67939861574 additionally rejects verifier steps with if: or continue-on-error. The current CodeAnt Quality Gates report for f5d843bb is PASS, and the focused release-security suite is 42/42 locally. Please assess the current PR head for any remaining actionable finding.

qnbs commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_EVENT_PATH: ${{ github.event_path }}
GITHUB_REF_NAME: ${{ github.ref_name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The verifier looks up this mutable tag name but never compares its target with github.sha; a retag between push and lookup can verify one commit while publishing another.

Assessment: 🔴 Critical · 🔁 Occurrence: Rarely · 🏷️ Race condition

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .github/workflows/docker.yml
**Line:** 89:89
**Comment:**
	*Race Condition: The verifier looks up this mutable tag name but never compares its target with `github.sha`; a retag between push and lookup can verify one commit while publishing another.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread .github/workflows/docker.yml Resolved
Comment thread scripts/release-security-gate.mjs Resolved
Compare the annotated tag target with the push event's after SHA and GitHub's commit SHA before accepting the tag signature. Reject missing, malformed, or retargeted targets and cover the failure paths with focused tests.
@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels Nov 8, 2026
codescene-access[bot]

This comment was marked as outdated.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9461b43b8

ℹ️ 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 (
!['ahead', 'identical'].includes(comparison.status) ||
comparison.base_commit?.sha?.toLowerCase() !== sha ||
comparison.head_commit?.sha?.toLowerCase() !== mainSha

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate ancestry using fields the compare API actually returns

For a valid signed release tag targeting protected main, this condition still throws because GitHub's compare-commits response contains base_commit, merge_base_commit, and commits, but no head_commit. Consequently, undefined !== mainSha is always true, blocking both GHCR publishing and the Tauri tag-release workflow. The new tests hide this by fabricating head_commit in their responses. Validate ancestry against the actual response contract and update the fixtures accordingly; also advance Docker's trusted-verifier pin, since revision 71dd3b6 contains the same check and would remain broken after a source-only fix.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai 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.

Nitpick comments: 2

tests/unit/tooling/verifyRemoteTag.test.ts: 1

76-82: Trivial · Maintainability & Code Quality · Low value

Extract a helper for the repeated verifyRemoteTag call.

Nearly every test repeats the same owner, repo, tag, and expectedCommitSha arguments. The CodeScene gate fails on this file with a code-duplication finding (score 9.39). A small verify(fetchImpl, overrides) helper clears the finding. It also keeps later argument changes in one place.

const verify = (fetchImpl: typeof fetch, overrides: { expectedCommitSha?: string } = {}) =>
  verifyRemoteTag({
    owner: 'qnbs',
    repo: 'WorldScript-Studio',
    tag: 'v1.29.3',
    expectedCommitSha: pushedCommitSha,
    fetchImpl,
    ...overrides,
  });

Source: Pipeline failures

tests/unit/tooling/releaseSecurityGate.test.ts: 1

65-65: Trivial · Maintainability & Code Quality · Quick win

Bound the verifier slice to the verify-release-tag job.

The slice call runs from verify-release-tag: to the end of docker.yml. The build-push job is therefore inside verifier. Substring assertions such as persist-credentials: false, fetch-depth: 1, and GITHUB_TOKEN: ${{ github.token }} can pass because of text in a later job. The test then misses a regression in the verifier job.

Cut the slice at the next job boundary so that the assertions apply only to the verifier job.

♻️ Proposed fix

-    const verifier = source(DOCKER).slice(source(DOCKER).indexOf('  verify-release-tag:\n'));
+    const docker = source(DOCKER);
+    const start = docker.indexOf('  verify-release-tag:\n');
+    const end = docker.indexOf('\n  build-push:\n', start);
+    expect(start).toBeGreaterThanOrEqual(0);
+    expect(end).toBeGreaterThan(start);
+    const verifier = docker.slice(start, end);

As per path instructions: "Focus on behavioral coverage, race edges, and false-positive/false-negative test design."

Source: Path instructions

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between e9b8e22 and d9461b4.

Files selected for processing: 13

  • .github/workflows/docker.yml
  • .github/workflows/release-gate-proof.yml
  • CHANGELOG.md
  • README.md
  • docs/CI.md
  • scripts/release-security-gate.d.mts
  • scripts/release-security-gate.mjs
  • scripts/signing/verify-github-signatures.mjs
  • scripts/signing/verify-remote.d.mts
  • scripts/signing/verify-remote.mjs
  • tests/unit/signing.test.ts
  • tests/unit/tooling/releaseSecurityGate.test.ts
  • tests/unit/tooling/verifyRemoteTag.test.ts
Files skipped from review as they are similar to previous changes: 1

  • README.md

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

@codescene-access codescene-access 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.

Gates Failed
New code is healthy (1 new file with code health below 10.00)

Our agent can fix these. Install it.

Gates Passed
2 Quality Gates Passed

Reason for failure
New code is healthy Violations Code Health Impact
verifyRemoteTag.test.ts 1 rule 9.39 Suppress

See analysis details in CodeScene

Absence of Expected Change Pattern

  • WorldScript-Studio/tests/unit/signing.test.ts is usually changed with: WorldScript-Studio/scripts/signing/signing-core.mjs

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

This branch was successfully deployed

1 active (outdated) deployment
Preview — e9b8e223 Deployed Nov 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant