Skip to content

Release CodeTruss CLI v0.2.57 - #48

Merged
DeliriumPulse merged 1 commit into
mainfrom
release/v0.2.57
Aug 8, 2026
Merged

Release CodeTruss CLI v0.2.57#48
DeliriumPulse merged 1 commit into
mainfrom
release/v0.2.57

Conversation

@DeliriumPulse

@DeliriumPulse DeliriumPulse commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Syncs the 0.2.57 source from the private monorepo, byte for byte against the monorepo git objects (230 paths compared by blob hash, 0 mismatches, 0 missing).

codetruss-cli-0.2.57.tgz
sha256 533bd51c59e88febe5a3a1df88c0fcb3e6966970280017c7b84efb63a421ce9f

That digest was not copied into release-reference.json: pnpm release:artifact was run against this tree, resolved from this repository's own lockfile, and the rebuilt archive cmps clean against the monorepo's copy, against this repo's latest pointer, and against the bytes codetruss.com is serving right now. All three digests in release-reference.json were re-measured off the files — archive, SBOM, and the dist/cli.cjs extracted from inside the archive — rather than transcribed.

The blob-hash comparison was run a second time against the 0.2.55 monorepo tree as a negative control: it reported 21 mismatched paths and exited 1, so a sync that silently dropped or stale-copied a file would not have passed. The cmp chain has two negative controls of its own: against the published 0.2.55 archive, and against a byte-identical copy with one NUL appended. Both exit 1.

Why this one is urgent

https://codetruss.com/downloads/codetruss-cli-latest.json already advertises 0.2.57, and its releaseUrl.../releases/tag/v0.2.57currently 404s, because the release does not exist yet. Tagging this merge is what makes the advertised URL resolve. Homebrew still installs 0.2.55.

What users are actually waiting on

Both changes in this archive are false-positive fixes, which for a tool whose output is a security verdict is the failure mode that costs the most trust.

0.2.56 — Firebase web API keys are no longer reported as committed credentials. A VITE_/NEXT_PUBLIC_-prefixed key, and a Firebase config object passed straight to initializeApp({…}), are published to every visitor by design; reporting them as leaks was CRITICAL and HIGH noise respectively. These were the last two CRITICAL false positives on the ten-repo benchmark corpus.

0.2.57 — an error-code enum is no longer three leaked passwords. A value that merely spells out its own key (IncorrectEmailPassword = "incorrect-email-password") carries nothing the identifier beside it did not. Repo-supplied scope globs are also bounded before they reach the matcher.

The downgrade is deliberately narrow, and the narrowness is pinned by a fixture rather than by prose: a server-side Google API key in the same .env, under a name the build tool does not publish, is asserted to stay CRITICAL.

This release supersedes an unreleased one

0.2.56 was merged to the monorepo and never released — no tag, no GitHub release, no Homebrew bump. That has precedent here (0.2.42, 0.2.47 through 0.2.49, and 0.2.54 are all merged-but-unreleased, served from the site). It is not retroactively released; its changelog entry rides along in the chain and its change ships inside these bytes. The mirror carries download artifacts only for versions that were actually released, so public/downloads/codetruss-cli-0.2.56.* is deliberately absent, exactly as 0.2.54 and 0.2.47 through 0.2.49 are.

The mirror's own .gitignore would have silently dropped the new fixture

This is the one mirror-owned source change here, and it is not cosmetic.

secrets escalates on a path matching /\.env/, so a fixture that reproduces the Firebase false positive has to be named like one — packages/cli/scripts/fixtures/acceptance/.env.production.fixture. The mirror's .gitignore carries .env.*, which matches it. A naive sync would have committed the 0.2.56 acceptance assertions with no fixture for them to run against.

To be precise about the blast radius rather than overstating it: this would not have been silent. Deleting the fixture and running the script fails with an expectation names .env.production, which no fixture produces and exits 1, so CI would have gone red on all six contexts that run the suite — a blocked release, not a false green. The fixture was restored byte-exactly afterwards. It is still a real defect, because the failure would have looked like a broken test rather than a missing file, and the obvious fix under time pressure is to delete the assertion.

Measured, not assumed. Before the change, git check-ignore -q on that path exited 0 (ignored) and named .gitignore:11:.env.* as the matching rule. After, it exits 1, and git status --untracked-files=all lists the file as addable. The negation is scoped to that one directory, which holds fabricated keys: .env.local and packages/cli/.env.production both still exit 0. The monorepo hit this same trap and carries the same negation with the same reasoning; this brings the mirror in line.

Note that git check-ignore -v exits 0 on any pattern match, including a negation, so it cannot answer this question — -q and git status can.

The acceptance check is capable of failing, in both directions

packages/cli/scripts/test-acceptance.mjs grew from 2 fixtures / 2 verdicts to 4 fixtures / 6 verdicts. It executes the built dist/cli.cjs — not src/, not the hosted implementation — and locates each assertion by an anchor string in the fixture text rather than a written-down line number, so editing a fixture cannot silently retarget it.

Demonstrated red from inside this repository before being trusted:

tamper result
empty PUBLISHABLE_CREDENTIAL_TYPES (revert the 0.2.56 exemption) red — 9 failures, incl. .env.production:6 … severity CRITICAL, expected INFO and src/firebase.ts:8 … severity HIGH, expected INFO
widen PUBLISHABLE_ENV_BINDING to match any binding (over-apply the exemption) red — .env.production:21 (MAPS_SERVER_KEY): severity LOW, expected CRITICAL — the negative control … must keep firing

So the check fails if the fix is missing and fails if the fix is too broad. packages/analyzer-engine/src/secrets.ts was restored byte-exactly afterwards (blob 50bae10a…, matching the monorepo), the 230-path blob comparison was re-run and still reported 230 identical, and the archive still cmps clean against the monorepo copy — so the tree in this PR is not a patched-back approximation.

Where it runs. .github/workflows/ci.yml still gates its Test step on matrix.node != '20.9.0', so the acceptance script runs in six of the nine compatibility contexts (Node 22 and 24 on ubuntu, macos, windows) and in the tag-triggered release job, which runs pnpm test unconditionally. The 0.2.55 changelog claimed "all nine"; that was recorded as a known wart in the 0.2.55 formula bump. It is stated correctly here.

Bundle delta

dist/cli.cjs goes from 828,065 bytes (0.2.55) to 834,037 (+5,972), 32 changed lines out of 296, first difference at byte offset 169,475. The archive grows 962,141 → 979,549 bytes. The eight-file archive membership is unchanged.

Unlike 0.2.55, this delta is real behaviour: packages/analyzer-engine/src/secrets.ts gains the publishable-client-identifier logic, packages/cli/src/config.ts bounds repo-supplied scope globs, and receipt.ts is split into receipt-markdown.ts, receipt-store.ts and receipt-verify.ts (1,042 lines out, 1,053 across three new files).

The frozen renderers still reproduce

Receipts stay on local-registry-v5. No frozen digest moved. packages/cli/test/verify-receipt.test.ts is byte-identical between the 0.2.55 and 0.2.57 monorepo trees — the pinned block still reads v1 928da3c4…, v2 113d62de…, v3 f38a8bde…, v4 288de3e2…, v5 6ae337ce….

That matters here more than usual, because receipt.ts was split across three files. The test is not decoration: flipping the last hex character of the v4 expected digest fails with renders 'local-registry-v4' to the exact bytes its signature covers (1 failed, 20 passed), and the file was restored byte-exactly afterwards (blob 3ffadf4a…) and re-run green (21 passed).

No published artifact was modified

git status under public/downloads/ reports nothing outside codetruss-cli-0.2.57.* and the latest pointers, so 0.2.44 through 0.2.55 still carry exactly the bytes they were attested with. packages/cli/CHANGELOG.md is 168 additions, 0 deletions; the published 0.2.55 section hashes identically (a477e1a8…) before and after.

pnpm-workspace.yaml, .npmrc, pnpm-lock.yaml, package.json (root), README.md, CONTRIBUTING.md and .github/ are unchanged — a blob-hash sweep of the whole repository shows the tree diverging from the monorepo on exactly the same 25 mirror-owned paths as at the 0.2.55 sync point, plus .gitignore's intended edit.

CHANGELOG.md at the root is regenerated from packages/cli/CHANGELOG.md. The generator was checked by feeding it the 0.2.55 package changelog and confirming it reproduces the committed 0.2.55 root changelog byte-for-byte; run with a release version that has no section it throws, and with a wrong npm-trail version its output cmps non-zero, so it is capable of failing. Its npm-trail sentence stays at 0.2.50, because npm view @codetruss/cli dist-tags still reports latest as 0.2.50.

Checked locally before opening

pnpm install --frozen-lockfile resolves with the lockfile untouched (the only source change to packages/cli/package.json is the version string). pnpm validate passes against this branch: typecheck, release:artifact, pnpm test (35 files, 440 tests, plus the deterministic-package, release-verifier, changelog-policy and acceptance suites), release:verify, and test:install. The rebuilt archive reproduced 533bd51c… exactly, and the acceptance script printed:

acceptance: dist/cli.cjs 0.2.57 (newer than packages/cli/src and packages/analyzer-engine/src) reproduced 6 adjudicated verdicts over 4 fixtures

release:artifact is itself the byte-identity gate: it refuses to replace an existing versioned archive whose digest differs from the one it just built. It ran with the monorepo's copy in place and did not throw.

The release workflow's awk extraction of the changelog entry was dry-run against the regenerated CHANGELOG.md and returns 47 non-empty lines (3,569 bytes), so the release note will not be install-steps-only; the same awk for a version with no entry returns 0 bytes, which is the case the workflow refuses to publish.

🤖 Generated with Claude Code

Syncs the 0.2.57 source from the private monorepo. Two false-positive fixes
reach users here: Firebase web API keys stop being reported as committed
credentials (0.2.56), and an error-code enum stops being reported as three
leaked passwords (0.2.57).

The mirror's own .gitignore would have silently swallowed the new
`.env.production.fixture` — `.env.*` matches it — which would have shipped the
0.2.56 acceptance assertions with no fixture to run against. The monorepo hit
the same trap and carries the same negation; this adds it here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DeliriumPulse
DeliriumPulse merged commit 57e4aeb into main Aug 8, 2026
9 checks passed
@DeliriumPulse
DeliriumPulse deleted the release/v0.2.57 branch August 8, 2026 20:28
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