Release CodeTruss CLI v0.2.30 - #16
Conversation
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>
|
Warning Review limit reached
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 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. 📝 WalkthroughWalkthroughThe 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. ChangesCodeTruss CLI 0.2.30
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
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (3)
packages/cli/scripts/build-release.mjs (1)
51-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove the immutability check out of the
catch-based control flow.The immutability error is thrown inside the same
trythat thecatchguards. The current code works because that error has nocodeproperty, so theelse throw errorbranch rethrows it. The flow is fragile: any future error inside the block that carriescode === '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 valueDocument why the manifest is read from
packageDirand notarchivePackageDir.
writeReleasebuilds the archive and SBOM fromarchivePackageDirbut readspackage.jsonfrompackageDir. The published names, version, andnodefields therefore describe the untampered package while the archive contains the tampered one. The tampered cases still pass becauseassertReleasePackagePolicyrejects 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 winExtract the canonical metadata shape into one shared module.
The same metadata object literal now exists in three places: here,
packages/cli/scripts/build-release.mjslines 74-86, andpackages/cli/scripts/test-release-verifier.mjslines 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 newrelease-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
📒 Files selected for processing (41)
CHANGELOG.mdREADME.mddocs/RELEASE.mdpackages/analyzer-engine/package.jsonpackages/analyzer-engine/src/coverage.tspackages/analyzer-engine/src/dead-code.tspackages/analyzer-engine/src/detect.tspackages/analyzer-engine/src/env-vars.tspackages/analyzer-engine/src/indexer.tspackages/analyzer-engine/src/runner.tspackages/analyzer-engine/src/secrets.tspackages/analyzer-engine/src/structure.tspackages/analyzer-engine/src/types.tspackages/cli/CHANGELOG.mdpackages/cli/package.jsonpackages/cli/scripts/build-release.mjspackages/cli/scripts/test-release-verifier.mjspackages/cli/scripts/verify-release.mjspackages/cli/src/analysis.tspackages/cli/src/cli.tspackages/cli/src/config.tspackages/cli/src/hook-runtime.tspackages/cli/src/receipt.tspackages/cli/src/setup.tspackages/cli/src/signing.tspackages/cli/src/types.tspackages/cli/test/analysis-profile.test.tspackages/cli/test/command-e2e.test.tspackages/cli/test/config.test.tspackages/cli/test/hooks.test.tspackages/cli/test/policy-fingerprint.test.tspackages/cli/test/policy-verdict.test.tspackages/cli/test/receipt.test.tspublic/downloads/codetruss-cli-0.2.30.sbom.cdx.jsonpublic/downloads/codetruss-cli-0.2.30.tgzpublic/downloads/codetruss-cli-0.2.30.tgz.sha256public/downloads/codetruss-cli-latest.jsonpublic/downloads/codetruss-cli-latest.sbom.cdx.jsonpublic/downloads/codetruss-cli-latest.tgzpublic/downloads/codetruss-cli-latest.tgz.sha256release-reference.json
💤 Files with no reviewable changes (1)
- packages/analyzer-engine/package.json
- Tag the command-reference fence as `text` (markdownlint MD040). - Use the American spelling "afterward". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
On the review findingsTwo of the nits were mine and are fixed: the The rest land on They cannot be fixed in this PR. The findings still look worth triaging upstream in the monorepo, behind a
The The changelog wording flagged on |
"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>
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:artifactrebuilt the bundle to the exact published digest9c97f573aa7e7a052fe8d4c578efda6a8d43f2bcfec9a74ab7d2fdf6b53eccdcpnpm release:verifypassed byte-for-byte against the immutable website archivepnpm typecheckclean,pnpm test230/230 across 19 files,pnpm test:installexit 0Artifacts
Added the immutable 0.2.30 archive, checksum, and SBOM to
public/downloads,repointed the
latest.*aliases and manifest, and updatedrelease-reference.json. The added bytes were downloaded fromcodetruss.com and their SHA-256 matched the published
.sha256sidecar.README, corrected against the shipped 0.2.30 binary
verify-policy trust-key, which the CLI accepts but omits from its own--helpbanner.Follow-ups for a maintainer
v0.2.30to trigger the attested release. Cutting it by hand would produce a release with no attestation, which would break the documentedgh attestation verifystep.Publish npmdispatch.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Documentation