Skip to content

feat(trace): export session evidence to disk - #3584

Draft
matiasinsaurralde wants to merge 4 commits into
mainfrom
matias/issue-3582-trace-evidence-export
Draft

matiasinsaurralde wants to merge 4 commits into
mainfrom
matias/issue-3582-trace-evidence-export

Conversation

@matiasinsaurralde

@matiasinsaurralde matiasinsaurralde commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Closes #3583

Summary

Adds an export mode to chainloop trace run that assembles the full push-time evidence for an agent session and writes it to a local directory instead of pushing a signed attestation.

  • Runs entirely offline: no control plane call and no credentials. Every material is crafted with an inline CAS backend, so the exported evidence record and material digests match what a push would upload, apart from the signature and attestation wrapper.
  • Each material is written under its content digest with a top-level manifest indexing them, so each can be found by its reference in the evidence record. Redaction is on by default; --no-redact opts out for a trusted local run.
  • Exports whatever the agent produced even when it exits non-zero (e.g. an interrupted session), while still propagating the agent's exit code.

View guided diff

@chainloop-platform

chainloop-platform Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

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

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 85% 1 ⚠️ 1 100% AI / 0% Human 1 +146 / -109 48h34m16s

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

Oct 11, 2026 21:43 UTC · 48h34m16s · $305.48 · 1.9k in / 1.5M out · claude-code 2.1.296 (claude-opus-4-8)

View session details ↗

Change Summary

  • Revises the issue-3582 spec around local trace behavior and clarifies export semantics.
  • Adds trace local-init and export-path implementation details, including unsigned manifest markers.
  • Restricts GUAC credentials to service-account keys and covers that path with focused tests.

AI Session Overall Score

🟢 85% — Strongly verified work, with one corrected spec-to-implementation drift worth checking.

AI Session Analysis Breakdown

🟢 93% · verification

🟢 Repeated builds, tests, and smoke checks backed the claimed outcomes. · High Impact

🟢 90% · solution-quality

🟢 Core fixes targeted the real mechanism rather than bypassing checks. · High Impact

🟢 88% · scope-discipline

No notes.

🟢 86% · user-trust-signal

No notes.

🟢 82% · context-and-planning

🟢 Wide tasks were grounded by reading specs, reviews, and code first. · Medium Impact

🟡 68% · alignment

🟠 The revised spec briefly outpaced the implementation until the export manifest was updated to match. · Medium Severity

💡 When a spec change alters observable output, pair it with the implementation follow-up in the same pass or mark it blocking immediately.


File Attribution

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

Status Attribution File Lines
modified ai docs/specs/issue-3582-trace-evidence-export.md +146 / -109

Policies (4, 1 failing)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-d139ac -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-d139ac -
⚠️ Failed ai-config-no-secrets ai-coding-session-d139ac
  • Secret (generic-password) detected in session content [turn=1458, source=tool_result, line=6]: 115: Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=1464, source=tool_result, line=115]: 115 Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=15, source=tool_result, line=115]: 115 Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=43, source=tool_result, line=100]: 100 Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=49, source=tool_result, line=140]: 140 Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=51, source=tool_result, line=132]: 132 Credentials: &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password],
  • Secret (generic-password) detected in session content [turn=53, source=tool_result, line=117]: 117 response.Credentials = &sdk.Credentials{Password: [CHAINLOOP_TRACE_REDACTED:generic-password]
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-d139ac -

Powered by Chainloop and Chainloop Trace

return nil
}

merged := make(map[string]string, len(crafted)+len(extra))
Add an export mode to `chainloop trace run` that runs the full push-time
evidence assembly and writes the result to a local directory instead of
pushing a signed attestation. It makes no call to the control plane and
needs no credentials: every material is crafted offline with an inline
CAS backend, so the exported evidence record and the material digests
equal what a push would upload, apart from the signature and the
attestation wrapper.

Each material is written under its content digest, with a top-level
manifest indexing them, so a reader or a test finds each one by its
reference in the evidence record. Redaction stays on by default, matching
a push; --no-redact opts out for a trusted local run.

Usage: `chainloop trace run --export <dir> -- <agent command>`.

Signed-off-by: Matías Insaurralde <matias@chainloop.dev>
In export mode, `chainloop trace run` only wrote the evidence when the
wrapped agent exited with status zero, so a session the user interrupted
(for example by closing the agent with Ctrl-C) produced no output and no
message. Export is for inspecting what a session produced, so it now runs
whatever the agent's exit status was, warns when no session was recorded
or the export failed, and still propagates the agent's exit code.

Signed-off-by: Matías Insaurralde <matias@chainloop.dev>
@matiasinsaurralde
matiasinsaurralde force-pushed the matias/issue-3582-trace-evidence-export branch from 7faf2a4 to 52eda65 Compare October 11, 2026 22:19
Add `trace init --local`, which sets up AI coding session tracing without a control plane: it installs the hooks but creates no workflow and needs no login. In local mode the pre-push hook pushes no attestation, and the evidence is written to disk instead. Local mode is marked in the per-clone trace state, not in the shared .chainloop.yml, so it does not turn attestation off for other clones.

Add `trace export <dir>`, which writes the evidence of the sessions the hooks have already recorded to a local directory, reusing the same assembly a push does.

Refs #3582

Chainloop-Trace-Sessions: d139ac66-b95f-4920-ac38-12997996037d

Signed-off-by: Matías Insaurralde <matias@chainloop.dev>
The export manifest now carries signed and is_attestation fields, both false, so a reader cannot mistake the on-disk evidence for a signed attestation. This satisfies the manifest declaration the spec requires (issue-3582 R-006).

Refs #3582

Chainloop-Trace-Sessions: d139ac66-b95f-4920-ac38-12997996037d

Signed-off-by: Matías Insaurralde <matias@chainloop.dev>
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.

2 participants