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
73 changes: 56 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ marketplace.

- Git
- Node.js 20.9 or newer
- CodeTruss CLI v0.2.30 or newer from <https://codetruss.com/cli>
- CodeTruss CLI v0.2.35 or newer from <https://codetruss.com/cli>

Skill instructions in this repository are verified against the shipped CLI
v0.2.30. The skill can explain the official installer when the CLI is missing,
v0.2.35. The skill can explain the official installer when the CLI is missing,
but it must not install software without the developer's confirmation.

## What a receipt looks like
Expand All @@ -59,24 +59,25 @@ also touched a denied path and committed a live key:
```markdown
# CodeTruss receipt — FAILED

- **Session:** `20260807T032401919Z-42bd50`
- **Session:** `20260807T051345990Z-4f2f16`
- **Task:** Add a SESSION_TTL constant to src/auth.ts
- **Starting commit:** `decff98665b27d53ec643546829342bbb1b4c878`
- **Starting commit:** `14482ad37ea1f3ea5c9547071b58c3cdffb7c0b0`
- **Policy SHA-256:** `d13f4367129bb7683c486d4d4e8e876bc1e9a7f541cd0e539945743b16d95a03`

## Verdict: FAILED

- 1 high/critical security or dependency finding(s) affect changed files
- 1 file(s) changed in denied paths: infra/deploy.sh
- 1 file(s) changed outside approved scope: .codetruss.yml
- sensitive surfaces changed: .codetruss.yml (policy)

## Changed files (3)

| Path | Change | Scope | Sensitive | Lines |
|---|---|---|---|---:|
| `.codetruss.yml` | added | unexpected | policy | +16/−0 |
| `.codetruss.yml` | added | unexpected | policy | +5/−0 |
| `infra/deploy.sh` | added | denied | — | +3/−0 |
| `src/auth.ts` | modified | allowed | — | +2/−0 |
| `src/auth.ts` | modified | allowed | — | +1/−0 |

## Introduced or worsened analyzer findings (1)

Expand All @@ -86,24 +87,59 @@ also touched a denied path and committed a live key:

## Analysis profile

The 13 deterministic registry analyzers ran locally on this machine.
Profile: `local-registry-v2`.

The 13 deterministic registry analyzers ran locally on this machine, plus a local
security pass: the shared SAST engine — the same rules and the same
source-to-sink taint tracking as the hosted audit — over the JavaScript,
TypeScript and TSX in this repository.

### What the local security pass checked

- **SQL injection (CWE-89).** Untrusted input tracked from request sources
through string building into query execution.
- **Mass assignment (CWE-915).** A raw request body spread into a database
write, and write helpers whose payload type accepts arbitrary keys.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- **Un-awaited database writes, swallowed errors, coercion-prone `==`
comparisons, and N+1 queries in loops** — the defect classes coding agents
most often introduce.

### What did not run

- **Security static analysis (SAST).** No injection or taint analysis was
performed. SQL injection, command injection, code injection, path traversal,
SSRF, open redirect, XSS and insecure deserialization were never checked, so
this receipt says nothing either way about those classes.
- **The rest of the security rule pack.** Command injection, code injection,
path traversal, SSRF, open redirect, XSS and insecure deserialization were
**not** checked here. Those rules run in a hosted scan; absence of a finding
in those classes means they were not analyzed, not that the code is clean.
- **Non-JavaScript languages.** The local pass covers JavaScript, TypeScript and
TSX only. Python, Go, Java, C#, PHP, Ruby and Rust in this repository received
secret scanning and the other registry passes, but no security rule or taint
analysis.
- **Hosted symbol graph.** No cross-file call or data-flow graph was built, so
architecture and dead-code conclusions cover only what the local passes can
see in isolation.
- **Optional LLM review.** No model read this diff. It is opt-in via `--llm` and
is force-disabled under agent hooks, so a hook receipt is always deterministic
evidence only.
- **Hosted Health scores.** Not calculated, reported as **N/A**. The scores are
defined over the graph and the complete SAST pass; a number derived from this
pass set would overstate what ran.

Local security findings are reported for review and do not fail the verdict on
their own.
```

`codetruss verify latest` re-checks the signature over those bytes and prints
`verified 20260807T032401919Z-42bd50 (FAILED)`.
`verified 20260807T051345990Z-4f2f16 (FAILED)`.

## What runs where

Local and deterministic, with no account and no network required:

- the 13 registry analyzers listed in the receipt's analysis profile;
- since CLI v0.2.35, a security pass running the shared SAST engine and its
source-to-sink taint tracking over the repository's JavaScript, TypeScript and
TSX: SQL injection, mass assignment, un-awaited database writes, swallowed
errors, coercion-prone `==`, and N+1 queries in loops;
- scope classification of every changed file against the approved allow/deny
boundary, including untracked and sensitive-surface detection;
- secret detection on changed files;
Expand All @@ -113,14 +149,17 @@ Local and deterministic, with no account and no network required:

Hosted, and only when the developer explicitly asks for it:

- security static analysis and the cross-file symbol graph, which back the
- the rest of the security rule pack — command injection, code injection, path
traversal, SSRF, open redirect, XSS, insecure deserialization — and every
non-JavaScript language;
- the cross-file symbol graph, which together with the full rule pack backs the
full-codebase audit and the Health scores;
- receipt `sync` to a CodeTruss account.

A local receipt never contains injection or taint analysis, and it says so in
its own "What did not run" section. Optional provider-backed `--llm` review is
force-disabled under agent hooks, so a hook receipt is always deterministic
evidence only.
A local receipt names its own remaining gaps in its "What did not run" section,
and local security findings are `REVIEW_REQUIRED` at most — they never fail a
verdict on their own. Optional provider-backed `--llm` review is force-disabled
under agent hooks, so a hook receipt is always deterministic evidence only.

Measured behaviour on public repositories is published at
<https://codetruss.com/benchmark>. CLI downloads, checksums, and the SBOM are at
Expand Down
6 changes: 3 additions & 3 deletions plugins/codetruss-claude/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Prerequisites:

- Git
- Node.js 20.9 or newer
- CodeTruss CLI v0.2.30 or newer from <https://codetruss.com/cli>
- CodeTruss CLI v0.2.35 or newer from <https://codetruss.com/cli>

Skill instructions are verified against the shipped CLI v0.2.30.
Skill instructions are verified against the shipped CLI v0.2.35.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

The plugin contains no analyzer, bundled hook, MCP server, background service,
or upload path. It delegates hook installation to the tested CLI after developer
Expand All @@ -36,7 +36,7 @@ receipt sync require separate explicit developer actions.
Troubleshooting:

- Run `codetruss --version`; install or upgrade from the CLI page when it is
missing or older than v0.2.30.
missing or older than v0.2.35.
- Run `codetruss setup` for the guided local policy, verification-fingerprint,
and hook flow. Do not replace it with hand-edited setup steps.
- Run `codetruss hooks status claude` and `codetruss hooks doctor claude`
Expand Down
24 changes: 21 additions & 3 deletions plugins/codetruss-claude/skills/codetruss/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ agent.

- Work inside the developer's Git repository and inspect existing policy before
proposing changes.
- Run `codetruss --version` first. This skill targets v0.2.30 or newer. If the
- Run `codetruss --version` first. This skill targets v0.2.35 or newer. If the
CLI is missing or older, explain the prerequisite, then
obtain explicit consent before downloading or installing software, including an upgrade.
- Offer only the official install paths from `https://codetruss.com/cli`. Let
Expand All @@ -29,10 +29,19 @@ agent.
as `REVIEW_REQUIRED`, exit `2` as `FAILED`, and exit `3` as a usage or
environment failure. Exits 1 and 2 still produce receipts; other commands
may use nonzero exits differently, so read their output.
- A receipt also names what did not run. SAST and the hosted symbol graph are
hosted-only, so a local run never performs injection or taint analysis.
- A receipt also names what did not run, and that boundary moved in v0.2.35. A
local run now executes the shared SAST engine over the JavaScript, TypeScript
and TSX in the repository, covering SQL injection, mass assignment,
un-awaited database writes, swallowed errors, coercion-prone `==`, and N+1
queries in loops. The rest of the rule pack (command injection, code
injection, path traversal, SSRF, open redirect, XSS, insecure
deserialization), every non-JavaScript language, and the hosted symbol graph
stay hosted-only. Read the receipt's own "What did not run" section instead
of asserting either way from memory.
Report a `PASS` as the deterministic passes finding nothing new, never as
evidence that the change is secure.
- Local security findings are `REVIEW_REQUIRED` at most. They never fail a
verdict on their own, so do not report one as a blocking failure.
- Describe a valid signature as post-generation integrity evidence. Do not call
it trusted execution, proof of authorship, or automatic compliance evidence.

Expand Down Expand Up @@ -94,6 +103,15 @@ plugin-bundled hook logic.
verification results, evidence limitations, and receipt path. Distinguish a
policy dispute from a product or shell failure.

Since v0.2.32, a run with no allow policy infers the scope of the turn and marks
those files `allowed (inferred)` on the receipt: treat an inferred allow as
weaker evidence than a declared boundary and still propose a real `.codetruss.yml`.

Since v0.2.34, a finding may carry a **Suggested fixes** entry with a diff and a
required safety note: present it, never apply it automatically, and keep the
note's rotation-first ordering for a credential, whose diff is deliberately
masked and cannot apply cleanly.

For a wrapped agent run, preserve the exact task and policy:

```bash
Expand Down
4 changes: 2 additions & 2 deletions plugins/codetruss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Prerequisites:

- Git
- Node.js 20.9 or newer
- CodeTruss CLI v0.2.30 or newer from <https://codetruss.com/cli>
- CodeTruss CLI v0.2.35 or newer from <https://codetruss.com/cli>

The plugin contains no analyzer, MCP server, background service, or upload path.
Deterministic checks stay local. Provider-backed review, authentication, and
Expand All @@ -16,7 +16,7 @@ receipt sync require separate explicit developer actions.
Troubleshooting:

- Run `codetruss --version`; install or upgrade from the CLI page when it is
missing or older than v0.2.30.
missing or older than v0.2.35.
- Run `codetruss setup` for the guided local policy, verification-fingerprint,
and hook flow. Do not replace it with hand-edited setup steps.
- Run `codetruss hooks status codex` and `codetruss hooks doctor codex` before
Expand Down
24 changes: 21 additions & 3 deletions plugins/codetruss/skills/codetruss/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ agent.

- Work inside the developer's Git repository and inspect existing policy before
proposing changes.
- Run `codetruss --version` first. This skill targets v0.2.30 or newer. If the
- Run `codetruss --version` first. This skill targets v0.2.35 or newer. If the
CLI is missing or older, explain the prerequisite, then
obtain explicit consent before downloading or installing software, including an upgrade.
- Offer only the official install paths from `https://codetruss.com/cli`. Let
Expand All @@ -29,10 +29,19 @@ agent.
as `REVIEW_REQUIRED`, exit `2` as `FAILED`, and exit `3` as a usage or
environment failure. Exits 1 and 2 still produce receipts; other commands
may use nonzero exits differently, so read their output.
- A receipt also names what did not run. SAST and the hosted symbol graph are
hosted-only, so a local run never performs injection or taint analysis.
- A receipt also names what did not run, and that boundary moved in v0.2.35. A
local run now executes the shared SAST engine over the JavaScript, TypeScript
and TSX in the repository, covering SQL injection, mass assignment,
un-awaited database writes, swallowed errors, coercion-prone `==`, and N+1
queries in loops. The rest of the rule pack (command injection, code
injection, path traversal, SSRF, open redirect, XSS, insecure
deserialization), every non-JavaScript language, and the hosted symbol graph
stay hosted-only. Read the receipt's own "What did not run" section instead
of asserting either way from memory.
Report a `PASS` as the deterministic passes finding nothing new, never as
evidence that the change is secure.
- Local security findings are `REVIEW_REQUIRED` at most. They never fail a
verdict on their own, so do not report one as a blocking failure.
- Describe a valid signature as post-generation integrity evidence. Do not call
it trusted execution, proof of authorship, or automatic compliance evidence.

Expand Down Expand Up @@ -94,6 +103,15 @@ plugin-bundled hook logic.
verification results, evidence limitations, and receipt path. Distinguish a
policy dispute from a product or shell failure.

Since v0.2.32, a run with no allow policy infers the scope of the turn and marks
those files `allowed (inferred)` on the receipt: treat an inferred allow as
weaker evidence than a declared boundary and still propose a real `.codetruss.yml`.

Since v0.2.34, a finding may carry a **Suggested fixes** entry with a diff and a
required safety note: present it, never apply it automatically, and keep the
note's rotation-first ordering for a credential, whose diff is deliberately
masked and cannot apply cleanly.

For a wrapped agent run, preserve the exact task and policy:

```bash
Expand Down
16 changes: 9 additions & 7 deletions scripts/validate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ assert.match(canonicalSkill, /^---\nname: codetruss\ndescription: .{80,1024}\n--

for (const required of [
'obtain explicit consent before downloading or installing software',
'This skill targets v0.2.30 or newer.',
'This skill targets v0.2.35 or newer.',
'use `codetruss setup` as the single guided setup path',
'`codetruss verify-policy status` and require exit 0 with the same fingerprint',
'An existing `.codetruss.yml` remains authoritative',
'Do not run `--llm`, `codetruss auth login`, or `codetruss sync` unless',
'Do not broaden `allow`, remove `deny`, add `--no-verify`',
'For `codetruss run` and `codetruss review`, treat exit `0` as `PASS`',
'post-generation integrity evidence',
'a local run never performs injection or taint analysis',
'stay hosted-only',
'Read the receipt\'s own "What did not run" section instead',
'Local security findings are `REVIEW_REQUIRED` at most.',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
'never as\n evidence that the change is secure',
]) {
assert.ok(canonicalSkill.includes(required), `missing trust-boundary rule: ${required}`)
Expand Down Expand Up @@ -171,7 +173,7 @@ assert.deepEqual(codexMarketplace.plugins[0].policy, {
})

const readme = await read('README.md')
assert.match(readme, /CodeTruss CLI v0\.2\.30 or newer/)
assert.match(readme, /CodeTruss CLI v0\.2\.35 or newer/)
assert.match(readme, /--skill codetruss --agent claude-code codex -y/)
assert.match(readme, /codetruss-plugins\/tree\/v0\.1\.5/)
assert.doesNotMatch(readme, /official listing remains pending review/)
Expand All @@ -183,8 +185,8 @@ assert.match(
)
assert.match(readme, /\/plugin marketplace add DeliriumPulse\/codetruss-plugins/)
assert.match(readme, /\/plugin install codetruss@codetruss/)
assert.match(readme, /verified against the shipped CLI\s+v0\.2\.30/)
assert.match(readme, /The 13 deterministic registry analyzers ran locally on this machine\./)
assert.match(readme, /verified against the shipped CLI\s+v0\.2\.35/)
assert.match(readme, /The 13 deterministic registry analyzers ran locally on this machine, plus a local\s+security pass/)
assert.match(readme, /https:\/\/codetruss\.com\/benchmark/)
assert.match(readme, /https:\/\/codetruss\.com\/cli/)

Expand All @@ -193,13 +195,13 @@ for (const path of [
'plugins/codetruss-claude/README.md',
]) {
const pluginReadme = await read(path)
assert.match(pluginReadme, /CodeTruss CLI v0\.2\.30 or newer/)
assert.match(pluginReadme, /CodeTruss CLI v0\.2\.35 or newer/)
assert.match(pluginReadme, /Run `codetruss setup` for the guided local policy/)
}

const claudePluginReadme = await read('plugins/codetruss-claude/README.md')
assert.match(claudePluginReadme, /\/plugin install codetruss@codetruss/)
assert.match(claudePluginReadme, /verified against the shipped CLI v0\.2\.30/)
assert.match(claudePluginReadme, /verified against the shipped CLI v0\.2\.35/)

const submission = await read('PLUGIN-SUBMISSION.md')
assert.match(submission, /platform\.claude\.com\/plugins\/submit/)
Expand Down
24 changes: 21 additions & 3 deletions skills/codetruss/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ agent.

- Work inside the developer's Git repository and inspect existing policy before
proposing changes.
- Run `codetruss --version` first. This skill targets v0.2.30 or newer. If the
- Run `codetruss --version` first. This skill targets v0.2.35 or newer. If the
CLI is missing or older, explain the prerequisite, then
obtain explicit consent before downloading or installing software, including an upgrade.
- Offer only the official install paths from `https://codetruss.com/cli`. Let
Expand All @@ -29,10 +29,19 @@ agent.
as `REVIEW_REQUIRED`, exit `2` as `FAILED`, and exit `3` as a usage or
environment failure. Exits 1 and 2 still produce receipts; other commands
may use nonzero exits differently, so read their output.
- A receipt also names what did not run. SAST and the hosted symbol graph are
hosted-only, so a local run never performs injection or taint analysis.
- A receipt also names what did not run, and that boundary moved in v0.2.35. A
local run now executes the shared SAST engine over the JavaScript, TypeScript
and TSX in the repository, covering SQL injection, mass assignment,
un-awaited database writes, swallowed errors, coercion-prone `==`, and N+1
queries in loops. The rest of the rule pack (command injection, code
injection, path traversal, SSRF, open redirect, XSS, insecure
deserialization), every non-JavaScript language, and the hosted symbol graph
stay hosted-only. Read the receipt's own "What did not run" section instead
of asserting either way from memory.
Report a `PASS` as the deterministic passes finding nothing new, never as
evidence that the change is secure.
- Local security findings are `REVIEW_REQUIRED` at most. They never fail a
verdict on their own, so do not report one as a blocking failure.
- Describe a valid signature as post-generation integrity evidence. Do not call
it trusted execution, proof of authorship, or automatic compliance evidence.

Expand Down Expand Up @@ -94,6 +103,15 @@ plugin-bundled hook logic.
verification results, evidence limitations, and receipt path. Distinguish a
policy dispute from a product or shell failure.

Since v0.2.32, a run with no allow policy infers the scope of the turn and marks
those files `allowed (inferred)` on the receipt: treat an inferred allow as
weaker evidence than a declared boundary and still propose a real `.codetruss.yml`.

Since v0.2.34, a finding may carry a **Suggested fixes** entry with a diff and a
required safety note: present it, never apply it automatically, and keep the
note's rotation-first ordering for a credential, whose diff is deliberately
masked and cannot apply cleanly.

For a wrapped agent run, preserve the exact task and policy:

```bash
Expand Down