Skip to content

Release CodeTruss CLI v0.2.30 - #16

Merged
DeliriumPulse merged 3 commits into
mainfrom
release/v0.2.30
Aug 7, 2026
Merged

Release CodeTruss CLI v0.2.30#16
DeliriumPulse merged 3 commits into
mainfrom
release/v0.2.30

Conversation

@DeliriumPulse

@DeliriumPulse DeliriumPulse commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

The public mirror was still at 0.2.24 while the website served 0.2.30.

Source

Mirrored from the 0.2.30 release commit in the monorepo, deliberately not from
the current working tree, which carries unreleased post-0.2.30 work.

Local verification before pushing:

  • pnpm release:artifact rebuilt the bundle to the exact published digest 9c97f573aa7e7a052fe8d4c578efda6a8d43f2bcfec9a74ab7d2fdf6b53eccdc
  • pnpm release:verify passed byte-for-byte against the immutable website archive
  • pnpm typecheck clean, pnpm test 230/230 across 19 files, pnpm test:install exit 0

Artifacts

Added the immutable 0.2.30 archive, checksum, and SBOM to public/downloads,
repointed the latest.* aliases and manifest, and updated
release-reference.json. The added bytes were downloaded from
codetruss.com and their SHA-256 matched the published .sha256 sidecar.

README, corrected against the shipped 0.2.30 binary

  • Leads with the current positioning: the deterministic first-pass verification gate for AI-written code.
  • Removes the stale claim that receipts "report hosted Health scores as N/A". Since 0.2.29 receipts carry a What did not run section; the README now shows it from a real run and says plainly that a local run never performs injection or taint analysis.
  • Documents verify-policy trust-key, which the CLI accepts but omits from its own --help banner.
  • Fixes the install section to lead with the channels that actually serve 0.2.30, and states that the npm registry package still trails at 0.2.24 because publication is a separate manual dispatch.
  • Adds the benchmark result and link, and the free-forever CLI pledge with hosted pricing.

Follow-ups for a maintainer

  1. After merge, push the annotated tag v0.2.30 to trigger the attested release. Cutting it by hand would produce a release with no attestation, which would break the documented gh attestation verify step.
  2. Releases v0.2.25 through v0.2.29 were intentionally not backfilled: the release workflow enforces tag/package-version parity, so those tags cannot be built from this tree. Their archives remain downloadable and checksummed on the website, and all five are now documented in the changelog.
  3. npm publication of 0.2.30 remains a separate manual Publish npm dispatch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for multiple trusted signing keys and local key trust management.
    • Improved unattended setup with automatic root detection and clearer verification-command trust options.
    • Added signed release metadata, checksums, SBOMs, and artifact verification for v0.2.30.
  • Improvements

    • Enhanced secret, dead-code, test-file, generated-file, and bundled-asset detection.
    • Receipts now clearly disclose analysis coverage and remain compatible with historical formats.
    • Coverage reporting distinguishes advisory limitations from blocking evidence gaps.
  • Documentation

    • Updated installation, setup, privacy, pricing, policy, receipt, and release guidance.

Bring the public mirror up to the shipped release. The mirror had been sitting
at 0.2.24 while the website served 0.2.30.

Source is mirrored from the 0.2.30 release commit, not from in-progress work.
`pnpm release:artifact` rebuilds the bundle to the exact published digest
9c97f573aa7e7a052fe8d4c578efda6a8d43f2bcfec9a74ab7d2fdf6b53eccdc, and
`pnpm release:verify` confirms it byte-for-byte against the immutable website
archive now recorded in release-reference.json.

- Mirror packages/cli and packages/analyzer-engine at 0.2.30, including the
  0.2.25 through 0.2.30 changelog entries.
- Add the immutable 0.2.30 archive, checksum, and SBOM to public/downloads and
  repoint the latest.* aliases and manifest.
- Update release-reference.json to the published archive, SBOM, and bundle
  digests.

README rewrite, corrected against the shipped 0.2.30 binary:

- Lead with the current positioning, the deterministic first-pass verification
  gate for AI-written code. Receipt stays the mechanism noun.
- Drop the stale "reports hosted Health scores as N/A" line. Since 0.2.29 the
  receipt carries a "What did not run" section, and the README now shows it
  from a real run and states plainly that a local run never performs injection
  or taint analysis.
- Document `verify-policy trust-key`, which the CLI accepts but leaves out of
  its own --help banner.
- Lead the install section with the channels that actually serve 0.2.30, and
  say that the npm registry package still trails at 0.2.24 because publication
  is a separate manual dispatch.
- Add the benchmark result and link, and the free-forever CLI pledge with the
  hosted pricing line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@DeliriumPulse, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 52 minutes

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

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3fe44d01-dfbb-4341-b3a8-c8351c7bd47b

📥 Commits

Reviewing files that changed from the base of the PR and between 8503564 and f115871.

📒 Files selected for processing (1)
  • README.md
📝 Walkthrough

Walkthrough

The pull request updates CodeTruss CLI to version 0.2.30. It expands analyzer coverage and detection rules, adds multi-key signing trust, changes receipt and setup behavior, and moves release verification to published download artifacts with checksums and SBOMs.

Changes

CodeTruss CLI 0.2.30

Layer / File(s) Summary
Analyzer context and detection updates
packages/analyzer-engine/src/*
Analyzer execution now carries SAST context. Coverage, credential, dead-code, test-file, environment-file, minified-file, and generated-file detection are expanded.
Coverage verdicts and receipt compatibility
packages/cli/src/analysis.ts, packages/cli/src/receipt.ts, packages/cli/test/*
The CLI separates advisory and blocking coverage limits. Receipts report omitted analysis passes and verify current and historical formats.
Trusted signers and unattended workflows
packages/cli/src/config.ts, packages/cli/src/signing.ts, packages/cli/src/setup.ts, packages/cli/src/hook-runtime.ts, packages/cli/src/cli.ts, packages/cli/test/*
Configuration supports multiple trusted public keys. Setup, hooks, trust commands, structured task handling, and warning deduplication use the updated policy.
Published artifact build and verification
packages/cli/scripts/*, public/downloads/*, release-reference.json, packages/cli/package.json
Release scripts build temporary archives, publish checksums and SBOMs, update download metadata, and verify hosted versioned and latest artifacts.
Release history and product documentation
README.md, CHANGELOG.md, packages/cli/CHANGELOG.md, docs/RELEASE.md
Documentation and changelogs describe version 0.2.30, installation, verification, policy behavior, analyzer limits, receipts, and release validation.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReleaseBuilder
  participant PublicDownloads
  participant ReleaseVerifier
  ReleaseBuilder->>PublicDownloads: Publish archive, SBOM, checksum, and metadata
  ReleaseVerifier->>PublicDownloads: Load versioned and latest artifacts
  ReleaseVerifier-->>ReleaseBuilder: Report verified version and archive SHA-256
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: releasing CodeTruss CLI version 0.2.30.
Description check ✅ Passed The description clearly explains the release scope, validation results, artifacts, documentation updates, and maintainer follow-ups.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v0.2.30

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.

@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: 10

🧹 Nitpick comments (3)
packages/cli/scripts/build-release.mjs (1)

51-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Move the immutability check out of the catch-based control flow.

The immutability error is thrown inside the same try that the catch guards. The current code works because that error has no code property, so the else throw error branch rethrows it. The flow is fragile: any future error inside the block that carries code === 'ENOENT' would silently overwrite the published archive path instead of failing the release.

Use an explicit existence read and keep the comparison outside the error handler.

♻️ Proposed refactor
-  try {
-    const publishedBytes = await readFile(versioned)
-    const publishedSha256 = createHash('sha256').update(publishedBytes).digest('hex')
-    if (publishedSha256 !== sha256) {
-      throw new Error(
-        `refusing to replace immutable ${versionedName}: existing ${publishedSha256}, new ${sha256}; bump the CLI version`,
-      )
-    }
-  } catch (error) {
-    if ((error).code === 'ENOENT') await copyFile(source, versioned)
-    else throw error
-  }
+  let publishedBytes
+  try {
+    publishedBytes = await readFile(versioned)
+  } catch (error) {
+    if (error.code !== 'ENOENT') throw error
+  }
+  if (publishedBytes === undefined) {
+    await copyFile(source, versioned)
+  } else {
+    const publishedSha256 = createHash('sha256').update(publishedBytes).digest('hex')
+    if (publishedSha256 !== sha256) {
+      throw new Error(
+        `refusing to replace immutable ${versionedName}: existing ${publishedSha256}, new ${sha256}; bump the CLI version`,
+      )
+    }
+  }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/scripts/build-release.mjs` around lines 51 - 62, Refactor the
versioned archive handling around the publishedBytes read so only an ENOENT from
the existence read triggers copyFile(source, versioned). Perform the SHA-256
comparison and immutable-version error check after that error handling, outside
the catch, and propagate all other read errors without overwriting the published
archive.
packages/cli/scripts/test-release-verifier.mjs (1)

16-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Document why the manifest is read from packageDir and not archivePackageDir.

writeRelease builds the archive and SBOM from archivePackageDir but reads package.json from packageDir. The published names, version, and node fields therefore describe the untampered package while the archive contains the tampered one. The tampered cases still pass because assertReleasePackagePolicy rejects them before the metadata comparison runs. Add a short comment to record that dependency, so a later change to the policy order does not turn these tests into false passes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/scripts/test-release-verifier.mjs` around lines 16 - 17, In
writeRelease, add a short comment beside the package.json read explaining that
packageDir is intentionally used to retain untampered manifest metadata, while
assertReleasePackagePolicy rejects tampered archive contents before metadata
comparison. Keep the existing packageDir behavior unchanged.
packages/cli/scripts/verify-release.mjs (1)

27-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the canonical metadata shape into one shared module.

The same metadata object literal now exists in three places: here, packages/cli/scripts/build-release.mjs lines 74-86, and packages/cli/scripts/test-release-verifier.mjs lines 30-42. The verification compares serialized bytes, so it also depends on identical key insertion order across all three copies. If a future change adds a field or reorders keys in only one copy, the release fails at verification time with a message that does not identify the drift.

Export a single releaseMetadata(pkg, { sha256, sbomSha256 }) helper (for example from a new release-metadata.mjs) and call it from all three scripts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/scripts/verify-release.mjs` around lines 27 - 44, Extract the
duplicated canonical metadata object into a shared releaseMetadata(pkg, {
sha256, sbomSha256 }) helper, preserving the existing key order and all computed
URLs and fields. Update the metadata construction in verify-release.mjs,
build-release.mjs, and test-release-verifier.mjs to call this helper so
serialization remains identical across all scripts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Around line 21-24: Clarify the v0.2.30 changelog wording in CHANGELOG.md lines
21-24 and packages/cli/CHANGELOG.md lines 10-13 to state that v0.2.30 only adds
the missing 0.2.25–0.2.29 release history and introduces no new CLI behavior;
apply the same wording in both files.

In `@packages/analyzer-engine/src/coverage.ts`:
- Around line 218-258: Update the coverage analysis flow around the
structureLimited branch and the omitted-SAST check so both caveats are collected
and returned for the same repository. Remove the early return that prevents
execution from reaching the SAST disclosure, preserving each finding’s existing
conditions and content while returning the combined findings together.

In `@packages/analyzer-engine/src/secrets.ts`:
- Around line 26-44: Update the match-processing logic around SECRET_PATTERNS to
extract the literal credential value from each detector match before testing it
with FAKE_LITERAL_VALUE. Use that extracted value—not match[0] or surrounding
assignment text—for fake-literal and related value classification, while
preserving normal credential detection for real values whose keys contain words
such as EXAMPLE, SAMPLE, or FAKE.

In `@packages/cli/src/config.ts`:
- Around line 18-29: Update signingPins to reject malformed configured signing
fields instead of silently ignoring them: if publicKey is present, require a
non-empty string, and if publicKeys is present, require an array containing only
non-empty string entries. Preserve the empty trusted-key result only when
neither field is configured, while continuing to normalize and deduplicate valid
keys.
- Around line 273-286: Validate the result of parse(text) before modifying the
document in the signing-pin update flow. Reject scalar, array, or null YAML
values rather than falling back to {}, and only assign document.signing and
write the file when the top-level value is a non-array object.

In `@packages/cli/src/setup.ts`:
- Line 221: Update the existing-policy path in setup so untrusted verification
commands are detected even when initialize is bypassed: return status 3 with the
existing trust instructions before installing hooks, rather than reporting
commands as withheld. Preserve normal setup for trusted or absent verification
commands, and add an end-to-end test covering an existing policy with untrusted
commands.

In `@public/downloads/codetruss-cli-latest.json`:
- Around line 11-12: Publish the v0.2.30 Git tag and upload its attestation
before deploying the site that serves this metadata file. Verify that the
release URL resolves and the attestationCommand succeeds before making the
manifest live.

In `@README.md`:
- Line 106: Update the command-reference code fence in README.md around line 106
to include an explicit language tag such as text, resolving the markdownlint
MD040 violation while preserving the enclosed content.
- Line 128: Update the sentence about committing `.codetruss.yml` in README.md
to use the American English spelling “afterward” instead of “afterwards,”
without changing the rest of the sentence.

In `@release-reference.json`:
- Around line 3-7: Update verifyRelease to validate the release-reference.json
fields, including version, archiveSha256, sbomSha256, and bundleSha256, against
the generated release artifacts and current package version; alternatively,
explicitly document in docs/RELEASE.md that these digest fields are maintained
manually.

---

Nitpick comments:
In `@packages/cli/scripts/build-release.mjs`:
- Around line 51-62: Refactor the versioned archive handling around the
publishedBytes read so only an ENOENT from the existence read triggers
copyFile(source, versioned). Perform the SHA-256 comparison and
immutable-version error check after that error handling, outside the catch, and
propagate all other read errors without overwriting the published archive.

In `@packages/cli/scripts/test-release-verifier.mjs`:
- Around line 16-17: In writeRelease, add a short comment beside the
package.json read explaining that packageDir is intentionally used to retain
untampered manifest metadata, while assertReleasePackagePolicy rejects tampered
archive contents before metadata comparison. Keep the existing packageDir
behavior unchanged.

In `@packages/cli/scripts/verify-release.mjs`:
- Around line 27-44: Extract the duplicated canonical metadata object into a
shared releaseMetadata(pkg, { sha256, sbomSha256 }) helper, preserving the
existing key order and all computed URLs and fields. Update the metadata
construction in verify-release.mjs, build-release.mjs, and
test-release-verifier.mjs to call this helper so serialization remains identical
across all scripts.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 636465b6-1796-4d6e-a407-158cf41641fe

📥 Commits

Reviewing files that changed from the base of the PR and between 2e3b582 and 8503564.

📒 Files selected for processing (41)
  • CHANGELOG.md
  • README.md
  • docs/RELEASE.md
  • packages/analyzer-engine/package.json
  • packages/analyzer-engine/src/coverage.ts
  • packages/analyzer-engine/src/dead-code.ts
  • packages/analyzer-engine/src/detect.ts
  • packages/analyzer-engine/src/env-vars.ts
  • packages/analyzer-engine/src/indexer.ts
  • packages/analyzer-engine/src/runner.ts
  • packages/analyzer-engine/src/secrets.ts
  • packages/analyzer-engine/src/structure.ts
  • packages/analyzer-engine/src/types.ts
  • packages/cli/CHANGELOG.md
  • packages/cli/package.json
  • packages/cli/scripts/build-release.mjs
  • packages/cli/scripts/test-release-verifier.mjs
  • packages/cli/scripts/verify-release.mjs
  • packages/cli/src/analysis.ts
  • packages/cli/src/cli.ts
  • packages/cli/src/config.ts
  • packages/cli/src/hook-runtime.ts
  • packages/cli/src/receipt.ts
  • packages/cli/src/setup.ts
  • packages/cli/src/signing.ts
  • packages/cli/src/types.ts
  • packages/cli/test/analysis-profile.test.ts
  • packages/cli/test/command-e2e.test.ts
  • packages/cli/test/config.test.ts
  • packages/cli/test/hooks.test.ts
  • packages/cli/test/policy-fingerprint.test.ts
  • packages/cli/test/policy-verdict.test.ts
  • packages/cli/test/receipt.test.ts
  • public/downloads/codetruss-cli-0.2.30.sbom.cdx.json
  • public/downloads/codetruss-cli-0.2.30.tgz
  • public/downloads/codetruss-cli-0.2.30.tgz.sha256
  • public/downloads/codetruss-cli-latest.json
  • public/downloads/codetruss-cli-latest.sbom.cdx.json
  • public/downloads/codetruss-cli-latest.tgz
  • public/downloads/codetruss-cli-latest.tgz.sha256
  • release-reference.json
💤 Files with no reviewable changes (1)
  • packages/analyzer-engine/package.json

Comment thread CHANGELOG.md
Comment thread packages/analyzer-engine/src/coverage.ts
Comment thread packages/analyzer-engine/src/secrets.ts
Comment thread packages/cli/src/config.ts
Comment thread packages/cli/src/config.ts
Comment thread packages/cli/src/setup.ts
Comment thread public/downloads/codetruss-cli-latest.json
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread release-reference.json
- Tag the command-reference fence as `text` (markdownlint MD040).
- Use the American spelling "afterward".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DeliriumPulse

Copy link
Copy Markdown
Collaborator Author

On the review findings

Two of the nits were mine and are fixed: the text fence tag and "afterward".

The rest land on packages/analyzer-engine/src/coverage.ts, secrets.ts,
packages/cli/src/config.ts, and setup.ts. Those are not changes authored in
this PR.
This is a mirror sync: that source is the shipped 0.2.30 release,
copied verbatim from the release commit. It only looks like a diff here because
the mirror had been sitting at 0.2.24.

They cannot be fixed in this PR. pnpm release:verify compares the rebuilt
bundle byte-for-byte against the immutable published archive
9c97f573aa7e7a052fe8d4c578efda6a8d43f2bcfec9a74ab7d2fdf6b53eccdc. Any source
edit here changes dist/cli.cjs, fails that check, and would mean the mirror no
longer represents the release that is actually installed on users' machines.

The findings still look worth triaging upstream in the monorepo, behind a
version bump. Summarized so they are not lost:

File Finding
coverage.ts The structureLimited branch returns before the omitted-SAST disclosure, so a repo with an unsupported primary language and 300+ lines of TS/JS/Python may not get the "what did not run" INFO finding. Directly weakens the 0.2.29 disclosure guarantee.
secrets.ts FAKE_LITERAL_VALUE.test(match[0]) tests the whole detector match, so a real credential under a key containing EXAMPLE/SAMPLE could be downgraded to INFO.
config.ts signingPins ignores a scalar or null signing.publicKeys, yielding an empty trusted-key set that then accepts the local key without repository signer trust.
config.ts A .codetruss.yml that parses as a scalar, array, or null gets replaced by a document containing only signing, dropping existing policy.
setup.ts With an existing .codetruss.yml, setup --yes can report withheld verification commands that were never actually removed.

The latest.json note about the missing v0.2.30 tag is correct and is the
first follow-up in the PR description: the tag has to be pushed after merge so
the release workflow produces the attestation that attestationCommand
tells users to check.

The changelog wording flagged on CHANGELOG.md is quoted from the shipped
packages/cli/CHANGELOG.md, which is one of the eight files byte-compared
against the release archive, so it also cannot be reworded without a version bump.

"Plans start at $19 per seat" contradicted the $9 History tier named in the
same sentence. Match the pricing page: free, History $9/mo, Pro $19/seat,
Team $15/seat with a 5-seat minimum, Agency $249/mo with 15 client workspaces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DeliriumPulse
DeliriumPulse merged commit aa4e6e5 into main Aug 7, 2026
10 checks passed
@DeliriumPulse
DeliriumPulse deleted the release/v0.2.30 branch August 7, 2026 15:10
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