Skip to content

feat: add shared GuardScan distribution catalog foundation - #35

Open
ntanwir10 wants to merge 2 commits into
review/1.1.0-corefrom
review/1.1.0-catalog
Open

feat: add shared GuardScan distribution catalog foundation#35
ntanwir10 wants to merge 2 commits into
review/1.1.0-corefrom
review/1.1.0-catalog

Conversation

@ntanwir10

Copy link
Copy Markdown
Owner

Stack 2 of 4 for #32; depends on #34. Review boundary: d1d2616..3335331 (81 changed files). Adds the shared Homebrew and Scoop catalog engine plus hardened scan and release contracts. Automation and publication remain disabled.

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 51 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b158868-10c4-4eb1-a379-9cb76c2c9bdc

📥 Commits

Reviewing files that changed from the base of the PR and between d1d2616 and 3335331.

📒 Files selected for processing (81)
  • .github/workflows/ci.yml
  • .github/workflows/release-build.yml
  • .github/workflows/release-canary.yml
  • .github/workflows/release-please.yml
  • .github/workflows/release-publish.yml
  • .github/workflows/release-train.yml
  • .release-please-manifest.json
  • cli/__tests__/commands/cache.test.ts
  • cli/__tests__/commands/config.test.ts
  • cli/__tests__/commands/init.test.ts
  • cli/__tests__/commands/run.test.ts
  • cli/__tests__/commands/sbom.test.ts
  • cli/__tests__/commands/scan-policy.test.ts
  • cli/__tests__/commands/vuln.test.ts
  • cli/__tests__/contracts/monitoring-api.contract.test.ts
  • cli/__tests__/contracts/release-contracts.test.ts
  • cli/__tests__/core/ai-cache.test.ts
  • cli/__tests__/core/cisa-kev.test.ts
  • cli/__tests__/core/config.test.ts
  • cli/__tests__/core/dependency-scanner.test.ts
  • cli/__tests__/core/license-scanner.test.ts
  • cli/__tests__/core/linter-integration.test.ts
  • cli/__tests__/core/metrics-collector.test.ts
  • cli/__tests__/core/mutation-tester.test.ts
  • cli/__tests__/core/osv-client.test.ts
  • cli/__tests__/core/package-inventory.test.ts
  • cli/__tests__/core/scan-engine.test.ts
  • cli/__tests__/core/telemetry.test.ts
  • cli/__tests__/core/test-runner.test.ts
  • cli/__tests__/e2e/all-commands.test.ts
  • cli/__tests__/e2e/cli-commands.test.ts
  • cli/__tests__/integration/config-lifecycle.test.ts
  • cli/__tests__/performance/load-testing.test.ts
  • cli/__tests__/providers/decorators/cached-provider.test.ts
  • cli/__tests__/providers/decorators/circuit-breaker-provider.test.ts
  • cli/__tests__/providers/decorators/observable-provider.test.ts
  • cli/__tests__/providers/factory.test.ts
  • cli/__tests__/providers/ollama.test.ts
  • cli/__tests__/providers/openai-redirect.test.ts
  • cli/__tests__/providers/token-counter.test.ts
  • cli/__tests__/scripts/eslint-ratchet.test.ts
  • cli/__tests__/scripts/package-manager-smoke.test.ts
  • cli/__tests__/scripts/release-please-config.test.ts
  • cli/__tests__/scripts/release-renderers.test.ts
  • cli/__tests__/scripts/release-tool.test.ts
  • cli/__tests__/scripts/release-train.test.ts
  • cli/__tests__/scripts/release-workflows.test.ts
  • cli/__tests__/scripts/standalone-builder.test.ts
  • cli/__tests__/security/injection-tests.test.ts
  • cli/__tests__/setup-env.ts
  • cli/__tests__/utils/api-client.test.ts
  • cli/__tests__/utils/execution-policy.test.ts
  • cli/__tests__/utils/path-helper.test.ts
  • cli/__tests__/utils/private-state.test.ts
  • cli/__tests__/utils/process-runner.test.ts
  • cli/__tests__/utils/reporter.test.ts
  • cli/jest.config.js
  • cli/schemas/guardscan.promotion-decision.v1.schema.json
  • cli/schemas/guardscan.release-approval.v1.schema.json
  • cli/schemas/guardscan.release-event.v1.schema.json
  • cli/schemas/guardscan.release-manifest.v1.schema.json
  • cli/schemas/guardscan.release-state.v1.schema.json
  • cli/schemas/guardscan.release-state.v2.schema.json
  • cli/scripts/release/archive.js
  • cli/scripts/release/artifact-sbom.js
  • cli/scripts/release/candidate.js
  • cli/scripts/release/events.js
  • cli/scripts/release/index.js
  • cli/scripts/release/ledger.js
  • cli/scripts/release/lib.js
  • cli/scripts/release/manifest.js
  • cli/scripts/release/npm-artifact.js
  • cli/scripts/release/promotion.js
  • cli/scripts/release/python-wheel.js
  • cli/scripts/release/reconcile.js
  • cli/scripts/release/remote.js
  • cli/scripts/release/renderers.js
  • cli/scripts/release/standalone-artifact.js
  • cli/scripts/release/standalone.js
  • cli/scripts/release/validators.js
  • release-please-config.json

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ntanwir10

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@ntanwir10

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 3335331e97

ℹ️ 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".

Comment on lines +239 to +242
platformId: [platform.os, platform.arch, platform.libc].filter(Boolean).join('-'),
nodeVersion: process.version.slice(1),
executable,
}, options.outputDir).metadata;

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 Include bundled dependencies in artifact SBOMs

The production artifact-sbom path supplies only the Node version and executable metadata. Since createArtifactSboms adds third-party components solely from input.components, every published SPDX and CycloneDX document contains just Node and GuardScan while omitting all packages bundled into the SEA. Consumers relying on these release SBOMs therefore miss dependency vulnerabilities and licenses; populate the component inventory from the lockfile or bundle metafile before writing the SBOMs.

Useful? React with 👍 / 👎.

Comment on lines +548 to +551
appendEvent(ledger, {
version, tag, commit,
timestamp: report.checkedAt,
type: 'canary_recorded',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Append canary events with a monotonic timestamp

When canary workflows overlap or another ledger writer records an event after this report captures checkedAt but before the record job obtains its concurrency slot, this timestamp is older than the ledger tail. appendEvent then rejects it because release event timestamps may not move backward, causing the whole evidence-recording job to fail. Use an append-time monotonic timestamp and preserve checkedAt separately in the payload.

Useful? React with 👍 / 👎.

Comment on lines +238 to +242
remote_files = {item["filename"]: item["digests"]["sha256"] for item in remote["urls"]}
for wheel in pathlib.Path("dist").glob("*.whl"):
digest = hashlib.sha256(wheel.read_bytes()).hexdigest()
if wheel.name in remote_files and remote_files[wheel.name] != digest:
raise SystemExit(f"PyPI integrity conflict for {wheel.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.

P1 Badge Reject unexpected files in an existing PyPI release

When this version already exists on PyPI, the preflight checks only local filenames that also occur remotely; it never rejects remote filenames absent from dist. A partially published or conflicting version containing an extra wheel or sdist therefore passes, and skip-existing: true proceeds to produce a registry release that is not the immutable artifact set in the GuardScan manifest. Compare the complete remote filename-and-digest map with the intended wheel set before publishing.

Useful? React with 👍 / 👎.

Comment on lines +196 to +201
node cli/scripts/release/index.js promote \
--promotion-input promotion-input.json \
--output promotion-decision.json \
--ledger release-events.jsonl \
--idempotency-key "promotion:${{ inputs.version }}:${GITHUB_RUN_ID}:${GITHUB_RUN_ATTEMPT}" \
--tag "$RC_TAG"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist denied promotion decisions before exiting

When the machine policy denies promotion, the promote command writes the local decision and ledger event but exits with status 2. GitHub's bash runner executes run blocks with error-exit enabled, so this command stops the step before the following worktree copy and push; denied decisions—such as a changed release-PR head or incomplete soak—are never recorded in the protected ledger. Capture status 2, persist the decision, and only then prevent the merge.

Useful? React with 👍 / 👎.

Comment on lines +316 to +319
PR_STATE="$(gh pr view --repo "ntanwir10/$REPO" "$PR_NUMBER" --json state --jq .state)"
if [ "${{ inputs.channel }}" = stable ] && [ "$PR_STATE" != MERGED ]; then
gh pr merge --repo "ntanwir10/$REPO" "$PR_NUMBER" --auto --squash
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wait for adapter PRs to merge before recording publication

For stable releases this only invokes gh pr merge --auto and never verifies that the PR reaches MERGED. As confirmed by gh pr merge --help, --auto means “Automatically merge only after necessary requirements are met,” so the command can succeed merely by enabling auto-merge while checks or a merge queue remain pending; the reusable publication job then succeeds and the downstream record job marks Homebrew and Scoop as channel_published even though their catalogs still contain the old release.

Useful? React with 👍 / 👎.

Comment on lines +360 to +364
brew install ntanwir10/tap/guardscan
brew test ntanwir10/tap/guardscan
brew upgrade --dry-run ntanwir10/tap/guardscan
guardscan --version
brew uninstall guardscan

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Assert the installed adapter version in canaries

For stable trains, the Homebrew canary installs the mutable current tap formula and treats any successful guardscan --version invocation as evidence for matrix.train.version. If the adapter PR is still pending or a newer stable formula has replaced an older active train, this installs a different version yet records a passing canary for the requested release. Compare the command output with $VERSION; the Scoop path has the same unchecked-version behavior.

Useful? React with 👍 / 👎.

Comment on lines +522 to +525
node cli/scripts/release/index.js rollback "${ARGS[@]}" > rollback-plan.json
cat rollback-plan.json
git worktree add ledger-branch origin/release-ledger
cp release-events.jsonl "ledger-branch/events/v${{ inputs.version }}.jsonl"

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 Deactivate rolled-back trains before future promotion

For an RC rollback, this persists only rollback_started; it neither removes the version from active-versions.json nor changes any channel or incident state used by eligibility checks. The scheduler therefore continues dispatching reconciliation for the rolled-back RC, and the reconciliation step can trigger action=promote as soon as its existing canary counts pass because it checks only samples and open incidents. Mark the train inactive or explicitly make rollback state block reconciliation and promotion before pushing this ledger update.

Useful? React with 👍 / 👎.

Comment on lines +121 to +126
run: npm run release:npm-preflight -- --artifact-dir ../npm-artifact --github-output "$GITHUB_OUTPUT"
- name: Publish exact tested tarball
if: steps.preflight.outputs.publish-required == 'true'
working-directory: cli
run: |
DIST_TAG=latest

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore the expected npm dist-tag on idempotent retries

When guardscan@version already exists with matching integrity but its latest or next dist-tag is absent or has been moved, npm-preflight returns publish-required=false. This skips the only block that selects and writes the intended dist-tag, while the final preflight—which also checks only integrity—still succeeds, so the release is recorded as published but normal installs through that tag continue resolving another version. Query and reconcile the expected dist-tag even when the tarball itself does not need publishing.

Useful? React with 👍 / 👎.

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.

1 participant