Skip to content

fix(cli): evaluate policies against the material on disk in policy devel eval - #3379

Merged
matiasinsaurralde merged 1 commit into
mainfrom
miguel/pfm-7061-policy-devel-eval-evaluates-policies-against-redacted
Aug 26, 2026
Merged

fix(cli): evaluate policies against the material on disk in policy devel eval#3379
matiasinsaurralde merged 1 commit into
mainfrom
miguel/pfm-7061-policy-devel-eval-evaluates-policies-against-redacted

Conversation

@migmartri

@migmartrimigmartri commented Aug 26, 2026

Copy link
Copy Markdown
Member

chainloop policy devel eval fed policies the redacted copy of a material instead of the file on disk. A policy hunting for leaked credentials in a CHAINLOOP_AI_CODING_SESSION saw sanitized input and reported no violations — silently, with no error. The tool used to author policies therefore disagreed with what production does.

Cause

The crafter marks a redacted material with chainloop.material.redacted, and that marker is what makes GetEvaluableContent read the untouched local file rather than the stored content. devel eval replaced the crafter's annotation map with the one built from --annotation flags, dropping the marker. With no flags at all the map was emptied outright, and since a dry run always stages inline, the sanitized bytes were what policies evaluated.

Change

User annotations are now layered on top of the crafter's rather than replacing them, so the redaction marker and the rest of the crafted metadata survive.

The chainloop. namespace is treated as crafter-owned and is not overridable, so an --annotation chainloop.material.redacted=false cannot put the old behaviour back. This matches how Crafter.stageMaterial protects contract-provided annotations on attestation add.

Only the stored copy stays redacted; that part is unchanged.

AI disclosure

Assisted by Claude Code.

🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri

Review in cubic

…vel eval
`policy devel eval` fed policies the redacted copy of a material instead of the
file on disk. A policy hunting for leaked credentials in a
CHAINLOOP_AI_CODING_SESSION saw sanitized input and reported no violations,
silently and without an error, so the tool used to author policies disagreed
with what production does.
The crafter marks a redacted material with `chainloop.material.redacted`, which
is what makes `GetEvaluableContent` read the untouched local file rather than
the stored content. `devel eval` replaced the crafter's annotation map with the
one built from `--annotation` flags, dropping that marker; with no flags the map
was emptied outright.
User annotations are now layered on top of the crafter's instead of replacing
them. The `chainloop.` namespace is crafter-owned and not overridable, so an
`--annotation` flag cannot put the old behaviour back, matching how
`Crafter.stageMaterial` protects contract-provided annotations on
`attestation add`.
Assisted-by: Claude Code
Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
Chainloop-Trace-Sessions: 84e77448-d9b9-48d5-8599-9337da722d02
@chainloop-platform

chainloop-platformBot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

AI Session Checks — 🟢 93% · ⚠️ 1 failing

Avg scoreSessionsFailing policiesAttributionFilesLinesTotal Duration
🟢 93%1⚠️ 1100% AI / 0% Human4+197 / -115m6s

🟢 93% — 100% AI — ⚠️ 1 policies failing

Aug 26, 2026 22:39 UTC · 15m6s · $20.12 · 574 in / 119.9k out · claude-code 2.1.246 (claude-opus-5)

View session details ↗

Change Summary

  • Updates policydevel evaluation to merge crafter and user annotations instead of replacing them.
  • Adds regression coverage that evaluates the on-disk AI session fixture rather than the redacted staged copy.
  • Adds helper testdata for a secret-bearing AI coding session and the matching policy fixture.
  • Hardens annotation handling around the reserved chainloop namespace before commit.

AI Session Overall Score

🟢 93% — Clean session with strong planning, root-cause fix, and repeated green verification.

AI Session Analysis Breakdown

🟢 96% · verification

🟢 A focused regression test failed before the fix and passed after it. · High Impact

🟢 95% · scope-discipline

🟢 The final diff stayed within policydevel plus two dedicated testdata fixtures. · High Impact

🟢 94% · alignment

No notes.

🟢 93% · solution-quality

No notes.

🟢 90% · context-and-planning

🟢 AI re-validated the plan after rebasing instead of coding against stale assumptions. · High Impact

🟢 87% · user-trust-signal

No notes.


File Attribution

████████████████████ 100% AI / 0% Human

StatusAttributionFileLines
modifiedaiapp/cli/internal/policydevel/eval_test.go+116 / -0
modifiedaiapp/cli/internal/policydevel/eval.go+36 / -1
createdaiapp/cli/internal/policydevel/testdata/ai-coding-session-with-secret.json+26 / -0
createdaiapp/cli/internal/policydevel/testdata/ai-coding-session-no-secrets-policy.yaml+19 / -0

Policies (4, 1 failing)

StatusPolicyMaterialMessages
✅ Passedai-config-ai-agents-allowedai-coding-session-84e774-
✅ Passedai-config-no-dangerous-commandsai-coding-session-84e774-
⚠️ Failedai-config-no-secretsai-coding-session-84e774
  • Potential secret (AWS access key) found in session content [turn=261, source=tool_result, line=21, value=AKIA4G7T...S4GW]
  • Potential secret (Quoted API key/password) found in session content [turn=154, source=tool_result, line=9, value=Secret ...tY6"]
  • Potential secret (Quoted API key/password) found in session content [turn=32, source=tool_result, line=19, value=Secret ...tY6"]
  • Potential secret (Quoted API key/password) found in session content [turn=38, source=tool_result, line=20, value=Secret ...tY6"]
  • Potential secret (Quoted API key/password) found in session content [turn=42, source=tool_result, line=24, value=Secret ...tY6"]
  • Potential secret (Quoted API key/password) found in session content [turn=42, source=tool_result, line=87, value=Secret ...tY6"]
✅ Passedai-config-mcp-servers-allowedai-coding-session-84e774-

Security Checks — ✅ 3 passing

iac-scan

StatusPolicyMessages
✅ Passediac-misconfiguration-

PR info

StatusPolicyMessages
✅ Passedpr-description-required-
✅ Passedpr-user-story-linked-

⏭️ 2 scans not applied

ScanReason
vulnerability-scanno manifest/lockfile changed
github-actions-scanno workflow files changed

View attestation ↗


Powered by Chainloop and Chainloop Trace

@migmartri
migmartri requested a review from a teamAugust 26, 2026 22:55

@cubic-dev-aicubic-dev-aiBot 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.

No issues found across 4 files

Re-trigger cubic

@matiasinsaurraldematiasinsaurralde left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@matiasinsaurralde
matiasinsaurralde merged commit ed71396 into mainAug 26, 2026
16 of 17 checks passed
@matiasinsaurralde
matiasinsaurralde deleted the miguel/pfm-7061-policy-devel-eval-evaluates-policies-against-redacted branch August 26, 2026 23:47
Sign up for freeto 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.

2 participants

@migmartri@matiasinsaurralde