Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 70 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CodeTruss CLI follows semantic versioning. Release artifacts and their SHA-256
checksums are published at <https://codetruss.com/downloads/codetruss-cli-latest.json>.

The current public release is [v0.2.51 on GitHub](https://github.com/CodeTruss/codetruss-cli/releases/tag/v0.2.51),
The current public release is [v0.2.52 on GitHub](https://github.com/CodeTruss/codetruss-cli/releases/tag/v0.2.52),
distributed from <https://codetruss.com/downloads/codetruss-cli-latest.json>.
The npm `latest` tag is still
[`@codetruss/cli@0.2.50`](https://www.npmjs.com/package/@codetruss/cli/v/0.2.50):
Expand All @@ -16,6 +16,75 @@ were superseded before distribution.

No unreleased changes.

## 0.2.52 — 2026-08-08

Three corrections to published artifacts. No behaviour changes.

- **`--yes` never required `--allow`, and this README said it did.** The
sentence read: "Non-interactive `--yes` setup requires explicit `--allow`
values." `resolveAllowGlobs` does close to the opposite. Given no explicit
value it adopts every conventional source directory that exists at the
repository root — `src`, `app`, `apps`, `packages`, `lib`, `components`,
`server`, `client`, `public`, `test`, `tests`, `e2e`, `spec`, `docs` — as
`<dir>/**`, prints what it adopted, and continues. It refuses only when none
of the fourteen exist. `codetruss setup --yes --hooks none` on a repository
holding `src/` and `tests/` exits 0 having adopted `src/**, tests/**`.

A safety claim we overstate is the worst direction to be wrong in. That
sentence invited a reader to believe an unattended run could not adopt a scope
they had not chosen, and it can. The behaviour itself is deliberate and stays:
an unattended run on an ordinary repository should end up protected rather
than halted over glob syntax, the adopted list is printed so the decision
stays auditable, no repository-wide glob is ever adopted, and the genuinely
dangerous decision — trusting repository verification commands — is still
withheld without `--trust-verify`. What was false was the documentation, so
the documentation is what changed, here and in the repository README and
`docs/codetruss-cli-guide.md`, which each carried a version of the same claim.

The corrected text also names the two ways a detected scope goes wrong. It can
be wider than intended. It is also blind to a source directory outside that
list: on `sindresorhus/ky`, whose sources live in `source/`, `--yes` adopts
`test/**` alone and leaves the entire source tree out of scope, so ordinary
changes read as scope drift. Pass `--allow` whenever the scope matters;
explicit values are used verbatim and nothing is detected.

- **Correction to the 0.2.51 entry: the commit block is real, but uninstalling
was not the only escape.** That entry said: "Because `codetruss setup`
installs a pre-commit hook, FAILED also blocked the next `git commit`, with
uninstalling as the only escape." A review of this release could not reproduce
the block and the claim was nearly retracted whole. It does reproduce. On a
clean clone of `sindresorhus/ky` at `3419113` with published 0.2.50, after
`codetruss setup --yes --allow "source/**" --allow "test/**"`, appending one
comment line to either `source/index.ts` or `source/utils/merge.ts` and
committing it prints `CodeTruss FAILED: commit blocked`, exits non-zero, and
leaves `HEAD` unmoved. Both configurations block.

The failed reproduction was a `PATH` artifact, and it is one users will hit.
The installed hook invokes bare `codetruss`, so whichever build resolves first
on `PATH` decides the verdict. With a stale global 0.2.28 resolving ahead of
the 0.2.50 under test, the identical staged change prints `REVIEW_REQUIRED`
and the commit lands with exit 0 — an older CLI, predating the behaviour,
quietly answering for the one being tested. `codetruss setup` already warns
about this by name, and the warning deserved more weight than it got.

What was genuinely wrong is narrower and is ours: `git commit --no-verify`
escapes a blocking hook, and it did on 0.2.50. Uninstalling was never the only
way out. The 0.2.51 artifact is published and immutable, so its text stands as
shipped and this entry is the correction.

- **The scoring model has a reviewable diff again.**
`packages/analyzer-engine/src/scoring.ts` carried two raw NUL bytes as map-key
separators inside template literals, so git classified the file as binary.
0.2.47's rewrite of `deduct()` — adding `dedupeByLocation` and the logarithmic
`occurrenceFactor` decay — therefore rendered as `Bin 5166 -> 8676 bytes, 0
additions, 0 deletions`. The model behind every number we put in front of a
customer could change with nothing to read. Both separators are now written as
the six-character escape. The runtime strings are identical, the analyzer
suites pass unchanged, and `dist/cli.cjs` built from the corrected source is
byte-for-byte the bundle built from the old source, so no behaviour in this
release turns on it. It was the last tracked source file in the repository
carrying raw NUL bytes.

## 0.2.51 — 2026-08-08

- **A file CodeTruss could not parse reported the user's change as FAILED.** On
Expand Down
Binary file modified packages/analyzer-engine/src/scoring.ts
Binary file not shown.
69 changes: 69 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,75 @@ checksums are published at <https://codetruss.com/downloads/codetruss-cli-latest

## Unreleased

## 0.2.52 — 2026-08-08

Three corrections to published artifacts. No behaviour changes.

- **`--yes` never required `--allow`, and this README said it did.** The
sentence read: "Non-interactive `--yes` setup requires explicit `--allow`
values." `resolveAllowGlobs` does close to the opposite. Given no explicit
value it adopts every conventional source directory that exists at the
repository root — `src`, `app`, `apps`, `packages`, `lib`, `components`,
`server`, `client`, `public`, `test`, `tests`, `e2e`, `spec`, `docs` — as
`<dir>/**`, prints what it adopted, and continues. It refuses only when none
of the fourteen exist. `codetruss setup --yes --hooks none` on a repository
holding `src/` and `tests/` exits 0 having adopted `src/**, tests/**`.

A safety claim we overstate is the worst direction to be wrong in. That
sentence invited a reader to believe an unattended run could not adopt a scope
they had not chosen, and it can. The behaviour itself is deliberate and stays:
an unattended run on an ordinary repository should end up protected rather
than halted over glob syntax, the adopted list is printed so the decision
stays auditable, no repository-wide glob is ever adopted, and the genuinely
dangerous decision — trusting repository verification commands — is still
withheld without `--trust-verify`. What was false was the documentation, so
the documentation is what changed, here and in the repository README and
`docs/codetruss-cli-guide.md`, which each carried a version of the same claim.

The corrected text also names the two ways a detected scope goes wrong. It can
be wider than intended. It is also blind to a source directory outside that
list: on `sindresorhus/ky`, whose sources live in `source/`, `--yes` adopts
`test/**` alone and leaves the entire source tree out of scope, so ordinary
changes read as scope drift. Pass `--allow` whenever the scope matters;
explicit values are used verbatim and nothing is detected.

- **Correction to the 0.2.51 entry: the commit block is real, but uninstalling
was not the only escape.** That entry said: "Because `codetruss setup`
installs a pre-commit hook, FAILED also blocked the next `git commit`, with
uninstalling as the only escape." A review of this release could not reproduce
the block and the claim was nearly retracted whole. It does reproduce. On a
clean clone of `sindresorhus/ky` at `3419113` with published 0.2.50, after
`codetruss setup --yes --allow "source/**" --allow "test/**"`, appending one
comment line to either `source/index.ts` or `source/utils/merge.ts` and
committing it prints `CodeTruss FAILED: commit blocked`, exits non-zero, and
leaves `HEAD` unmoved. Both configurations block.

The failed reproduction was a `PATH` artifact, and it is one users will hit.
The installed hook invokes bare `codetruss`, so whichever build resolves first
on `PATH` decides the verdict. With a stale global 0.2.28 resolving ahead of
the 0.2.50 under test, the identical staged change prints `REVIEW_REQUIRED`
and the commit lands with exit 0 — an older CLI, predating the behaviour,
quietly answering for the one being tested. `codetruss setup` already warns
about this by name, and the warning deserved more weight than it got.

What was genuinely wrong is narrower and is ours: `git commit --no-verify`
escapes a blocking hook, and it did on 0.2.50. Uninstalling was never the only
way out. The 0.2.51 artifact is published and immutable, so its text stands as
shipped and this entry is the correction.

- **The scoring model has a reviewable diff again.**
`packages/analyzer-engine/src/scoring.ts` carried two raw NUL bytes as map-key
separators inside template literals, so git classified the file as binary.
0.2.47's rewrite of `deduct()` — adding `dedupeByLocation` and the logarithmic
`occurrenceFactor` decay — therefore rendered as `Bin 5166 -> 8676 bytes, 0
additions, 0 deletions`. The model behind every number we put in front of a
customer could change with nothing to read. Both separators are now written as
the six-character escape. The runtime strings are identical, the analyzer
suites pass unchanged, and `dist/cli.cjs` built from the corrected source is
byte-for-byte the bundle built from the old source, so no behaviour in this
release turns on it. It was the last tracked source file in the repository
carrying raw NUL bytes.

## 0.2.51 — 2026-08-08

- **A file CodeTruss could not parse reported the user's change as FAILED.** On
Expand Down
14 changes: 12 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ pre-commit plus Claude/Codex hooks, and runs a health check. It never defaults
to a repository-wide allow rule, never treats `--yes` as command trust, and
never uploads anything. Codex asks for one final project-hook approval in
`/hooks`.
Non-interactive `--yes` setup requires explicit `--allow` values and still
requires `--trust-verify` before it can trust detected repository commands.
Non-interactive `--yes` setup does not require `--allow`. With no explicit
value it adopts every conventional source directory that exists at the
repository root — `src`, `app`, `apps`, `packages`, `lib`, `components`,
`server`, `client`, `public`, `test`, `tests`, `e2e`, `spec`, `docs` — as
`<dir>/**`, prints what it adopted, and continues; it refuses only when none of
them exist, and then asks for an explicit `--allow`. So an unattended run gets a
scope derived from the repository rather than one you chose: possibly wider than
you want, and blind to a source directory outside that list (`source/**`, for
one), which makes ordinary changes read as out of scope. Pass `--allow` whenever
the scope matters — explicit values are used verbatim and nothing is detected.
`--trust-verify` is still required before `--yes` can trust detected repository
commands.

A 14-day local-only design-partner cohort is open without repository access,
an account, or receipt sync. The consent request is:
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codetruss/cli",
"version": "0.2.51",
"version": "0.2.52",
"description": "Local-first scope, quality, and verification receipts for coding agents",
"license": "SEE LICENSE IN LICENSE",
"type": "module",
Expand Down
Binary file modified packages/cli/test/unparsed-file-coverage.test.ts
Binary file not shown.
170 changes: 170 additions & 0 deletions public/downloads/codetruss-cli-0.2.52.sbom.cdx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"$schema": "https://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"serialNumber": "urn:uuid:4c318a44-4d62-55be-95fe-0240ae7f3d90",
"specVersion": "1.6",
"version": 1,
"metadata": {
"component": {
"type": "application",
"bom-ref": "pkg:npm/%40codetruss/cli@0.2.52",
"name": "@codetruss/cli",
"version": "0.2.52",
"description": "Local-first scope, quality, and verification receipts for coding agents",
"licenses": [
{
"license": {
"name": "CodeTruss CLI Proprietary License"
}
}
],
"purl": "pkg:npm/%40codetruss/cli@0.2.52"
},
"properties": [
{
"name": "codetruss:distribution",
"value": "single-file JavaScript bundle"
},
{
"name": "codetruss:runtimeDependencies",
"value": "0"
}
]
},
"components": [
{
"type": "library",
"bom-ref": "pkg:npm/%40codetruss/analyzer-engine@0.1.0",
"name": "@codetruss/analyzer-engine",
"version": "0.1.0",
"licenses": [
{
"license": {
"name": "CodeTruss CLI Proprietary License"
}
}
],
"purl": "pkg:npm/%40codetruss/analyzer-engine@0.1.0",
"properties": [
{
"name": "codetruss:bundled",
"value": "true"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/balanced-match@4.0.4",
"name": "balanced-match",
"version": "4.0.4",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"purl": "pkg:npm/balanced-match@4.0.4",
"properties": [
{
"name": "codetruss:bundled",
"value": "true"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/brace-expansion@5.0.9",
"name": "brace-expansion",
"version": "5.0.9",
"licenses": [
{
"license": {
"id": "MIT"
}
}
],
"purl": "pkg:npm/brace-expansion@5.0.9",
"properties": [
{
"name": "codetruss:bundled",
"value": "true"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/minimatch@10.2.6",
"name": "minimatch",
"version": "10.2.6",
"licenses": [
{
"license": {
"id": "BlueOak-1.0.0"
}
}
],
"purl": "pkg:npm/minimatch@10.2.6",
"properties": [
{
"name": "codetruss:bundled",
"value": "true"
}
]
},
{
"type": "library",
"bom-ref": "pkg:npm/yaml@2.9.0",
"name": "yaml",
"version": "2.9.0",
"licenses": [
{
"license": {
"id": "ISC"
}
}
],
"purl": "pkg:npm/yaml@2.9.0",
"properties": [
{
"name": "codetruss:bundled",
"value": "true"
}
]
}
],
"dependencies": [
{
"ref": "pkg:npm/%40codetruss/analyzer-engine@0.1.0",
"dependsOn": []
},
{
"ref": "pkg:npm/%40codetruss/cli@0.2.52",
"dependsOn": [
"pkg:npm/%40codetruss/analyzer-engine@0.1.0",
"pkg:npm/minimatch@10.2.6",
"pkg:npm/yaml@2.9.0"
]
},
{
"ref": "pkg:npm/balanced-match@4.0.4",
"dependsOn": []
},
{
"ref": "pkg:npm/brace-expansion@5.0.9",
"dependsOn": [
"pkg:npm/balanced-match@4.0.4"
]
},
{
"ref": "pkg:npm/minimatch@10.2.6",
"dependsOn": [
"pkg:npm/brace-expansion@5.0.9"
]
},
{
"ref": "pkg:npm/yaml@2.9.0",
"dependsOn": []
}
]
}
Binary file added public/downloads/codetruss-cli-0.2.52.tgz
Binary file not shown.
1 change: 1 addition & 0 deletions public/downloads/codetruss-cli-0.2.52.tgz.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5afc2a563358f1f7dd41eaf2484dc7913e326d9e7072f0d8c5bdeb1bb77792dd codetruss-cli-0.2.52.tgz
14 changes: 7 additions & 7 deletions public/downloads/codetruss-cli-latest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@codetruss/cli",
"version": "0.2.51",
"url": "/downloads/codetruss-cli-0.2.51.tgz",
"version": "0.2.52",
"url": "/downloads/codetruss-cli-0.2.52.tgz",
"latestUrl": "/downloads/codetruss-cli-latest.tgz",
"sha256": "0dbd333a638376aa68e4a2f330c6d59cd0e852700104a7dd5444232a2278a862",
"sbomUrl": "/downloads/codetruss-cli-0.2.51.sbom.cdx.json",
"sbomSha256": "4f01e0111543c4d624e365d1b889377bb2a560048549eac78bb52d0eaedc9ed7",
"sha256": "5afc2a563358f1f7dd41eaf2484dc7913e326d9e7072f0d8c5bdeb1bb77792dd",
"sbomUrl": "/downloads/codetruss-cli-0.2.52.sbom.cdx.json",
"sbomSha256": "0667253d5059b5aa5373c3dc6266efae87919b28179724ecd26dc6747f167d89",
"node": ">=20.9.0",
"repository": "https://github.com/CodeTruss/codetruss-cli",
"releaseUrl": "https://github.com/CodeTruss/codetruss-cli/releases/tag/v0.2.51",
"attestationCommand": "gh attestation verify codetruss-cli-0.2.51.tgz --repo CodeTruss/codetruss-cli"
"releaseUrl": "https://github.com/CodeTruss/codetruss-cli/releases/tag/v0.2.52",
"attestationCommand": "gh attestation verify codetruss-cli-0.2.52.tgz --repo CodeTruss/codetruss-cli"
}
Loading