Skip to content

feat(trace): record the skills that an agent used in a session - #3551

Merged
jiparis merged 4 commits into
chainloop-dev:mainfrom
jiparis:feat/trace-skills-used
Oct 7, 2026
Merged

jiparis merged 4 commits into
chainloop-dev:mainfrom
jiparis:feat/trace-skills-used

Conversation

@jiparis

@jiparis jiparis commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Chainloop Trace records the skills that an agent used in a coding session. This change implements Spec issue-3540, requirements R-001 to R-010.

Closes #3540

What changes

  • Spec entries. Each skill that the session used gives one spec entry of the new kind skill (R-001). The CLI makes these entries from the transcript. The agent does not write them. When the agent writes a spec file with kind: skill, the CLI records the file as kind text.

  • Materials. Each skill gives two EVIDENCE materials (R-003):

    • The definition: the redacted SKILL.md file. The digest of the entry points to it.
    • The package: a reproducible archive of the full redacted skill folder.

    The annotation chainloop.spec.skill.content tells the two materials apart.

  • Metadata. A spec entry can hold a new metadata object (R-005 to R-008). For a skill, the object holds these fields:

    • The source: project, user, organization, plugin or unknown.
    • The digest of the package.
    • The use counts: the total, the uses that the model started, the uses that the user started, and the uses from subagents.

    The schema change is additive. The schema version does not change (R-010).

  • Copy at use time. A hook copies the skill folder into the Trace state when the session uses the skill (R-002). The CLI never replaces a copy. If no hook ran after the use, the push copies the folder and records a warning.

  • Package limits. The CLI reads only a folder that holds SKILL.md (R-004). It leaves out links that point out of the folder, and version-control folders. If a package is larger than 5 MB, the CLI does not upload it. The definition and the counts still go into the evidence.

  • Entry limit. Skill entries have their own limit of 25 for each session (R-009).

  • Skills with no folder. A skill that is part of the agent, for example /simplify in Claude Code, has no folder on disk. The CLI does not record it, and writes a warning to the local log.

  • Providers (R-010):

    • Claude Code: the CLI finds skill tool calls and skill slash commands, also in subagent transcripts. The PostToolUse hook matcher now includes the Skill tool.
    • OpenCode: the CLI finds completed calls to the skill tool. The plugin sends the skill folder to the hook.
    • Cursor and Pi: the CLI records no skill entries yet.

Portion of a sample attestation (for this very same session):

     {
        "name": "spec-ee05bc-skill-asd-ste100-pkg",
        "value": "",
        "hash": "sha256:3eae757c2794d1f424c8195d08fb4e92b91f83ef81c9566f677f08cd085a7345",
        "tag": "",
        "filename": "asd-ste100.tar.gz",
        "type": "EVIDENCE",
        "annotations": [
          {
            "name": "chainloop.material.cas",
            "value": "true"
          },
          {
            "name": "chainloop.material.name",
            "value": "spec-ee05bc-skill-asd-ste100-pkg"
          },
          {
            "name": "chainloop.material.size",
            "value": "20269"
          },
          {
            "name": "chainloop.material.type",
            "value": "EVIDENCE"
          },
          {
            "name": "chainloop.spec.kind",
            "value": "skill"
          },
          {
            "name": "chainloop.spec.session_id",
            "value": "ee05bc4f-cf05-4433-b614-415b89577db7"
          },
          {
            "name": "chainloop.spec.skill.content",
            "value": "package"
          },
          {
            "name": "chainloop.spec.title",
            "value": "asd-ste100"
          }
        ],
        "uploadedToCAS": true
      },

Departures from the spec

  • The spec says that a copy MUST stay in the Trace state until the session ends. The copies stay longer, until the CLI cleans up the session records. A push after the session end thus uses the copy from the time of use.
  • OpenCode runs each subagent in a child session with its own export. For OpenCode, in_subagents stays at zero. This change implements R-007 only in part.

AI disclosure

Claude Code helped to write this change.

View guided diff

Each skill that a Claude Code or OpenCode session used becomes a spec
entry of kind skill. The entry holds the use counts and the skill source
in a new metadata object. The redacted SKILL.md file and a reproducible
archive of the full skill folder are stored as EVIDENCE materials. Hooks
copy the skill folder when the session uses the skill.

Implements R-001 to R-010 of docs/specs/issue-3540-trace-skills-used.md.

Refs chainloop-dev#3540

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: ee05bc4f-cf05-4433-b614-415b89577db7
@chainloop-platform

chainloop-platform Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

PR validation — ✅ 3 passing

Status Policy Material Messages
✅ Passed pr-min-approvals pr-info -
✅ Passed pr-description-required pr-info -
✅ Passed pr-user-story-linked pr-info -

View attestation ↗

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

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 88% 1 ⚠️ 1 100% AI / 0% Human 30 +3785 / -291 1h38m59s

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

Oct 7, 2026 15:19 UTC · 1h38m59s · $53.19 · 990 in / 581.4k out · claude-code 2.1.292 (claude-opus-5-5)

View session details ↗

Change Summary

  • Adds Trace support for recording Claude Code and OpenCode skill use in session evidence.
  • Stores redacted SKILL.md content and packaged skill folders as materials in the trace output.
  • Adds scenario coverage from hook events through attestation creation, plus warnings for skills without folders.

AI Session Overall Score

🟢 88% — Strong implementation and verification after one late testing gap.

AI Session Analysis Breakdown

🟢 92% · alignment

🟢 AI admitted missing scenario coverage instead of overstating what was verified. · High Impact

🟢 91% · solution-quality

🟢 Built-in skills became warnings instead of a fake recorded artifact. · Medium Impact

🟢 90% · scope-discipline

No notes.

🟢 89% · verification

🟢 AI added and exercised a scenario test for the full hook-to-attestation path. · High Impact

🟠 The first PR revision lacked a real scenario test, and the user had to ask for one. · Medium Severity

💡 Before opening a PR on workflow-heavy changes, ask whether a real-path scenario test is still missing.

🟢 84% · user-trust-signal

No notes.

🟡 72% · context-and-planning

🟠 The multi-package change had deep exploration but no visible plan or TODO checkpoint. · Medium Severity

💡 For multi-package work, sketch the files and steps before editing so later corrections have a shared baseline.


File Attribution

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

Status Attribution File Lines
created ai app/cli/internal/trace/skill/skill.go +552 / -0
modified ai app/cli/internal/trace/claude/skills.go +458 / -16
modified ai app/cli/pkg/action/trace_skills_scenario_test.go +308 / -81
modified ai app/cli/pkg/action/trace_skills_test.go +339 / -7
modified ai app/cli/internal/trace/claude/skills_test.go +340 / -4
modified ai app/cli/pkg/action/trace_skills.go +291 / -5
modified ai app/cli/pkg/action/trace_hook_handler.go +163 / -130
created ai app/cli/internal/trace/skill/skill_test.go +287 / -0
created ai app/cli/internal/trace/opencode/skills.go +143 / -0
created ai app/cli/internal/trace/opencode/skills_test.go +114 / -0
created ai app/cli/internal/trace/state/skills.go +103 / -0
modified ai app/cli/internal/trace/provider.go +95 / -1
created ai app/cli/internal/trace/skill/source.go +90 / -0
created ai app/cli/internal/trace/state/skills_test.go +83 / -0
created ai app/cli/internal/trace/skill/source_test.go +54 / -0
modified ai app/cli/internal/trace/opencode/hooks_test.go +48 / -2
modified ai pkg/attestation/crafter/materials/aicodingsession/aicodingsession.go +48 / -1
modified ai app/cli/internal/trace/opencode/hooks.go +36 / -4
modified ai internal/schemavalidators/internal_schemas/aicodingsession/ai-coding-session-0.1.schema.json +38 / -2
modified ai app/cli/pkg/action/trace_spec_materials_test.go +34 / -4
modified ai app/cli/internal/trace/state/state.go +22 / -14
modified ai app/cli/internal/trace/opencode/testdata/plugin_full.ts +26 / -4
modified ai app/cli/internal/trace/opencode/testdata/plugin_tracerun.ts +26 / -4
modified ai app/cli/internal/trace/opencode/parse.go +18 / -4
modified ai pkg/attestation/crafter/materials/aicodingsession/spec_test.go +21 / -0

…and 5 more file(s).


Policies (4, 1 failing)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-ee05bc -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-ee05bc -
⚠️ Failed ai-config-no-secrets ai-coding-session-ee05bc Secret (unknown rule) detected in session content [turn=373, source=assistant-tool_use:Write, line=1]: {"content":"//\n// Copyright 2026 The Chainloop Authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\...
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-ee05bc -

Security Checks — ✅ 6 passing

✅ secret-scan

Status Policy Messages
✅ Passed secrets-detection -

✅ sast-scan

Status Policy Messages
✅ Passed owasp-top10-2025 -
✅ Passed sast -
✅ Passed cwe-top25 -
✅ Passed cwe-top26-40-cusp -

✅ iac-scan

Status Policy Messages
✅ Passed iac-misconfiguration -
Scans not applied (2)
Scan Reason
vulnerability-scan no manifest/lockfile changed
github-actions-scan no workflow files changed

View attestation ↗

Security context

This change touches code with 6 recorded security-fix advisories. These are pointers to what past fixes established, not findings in this diff, and they never fail the check.

View in Chainloop ↗ · How this works ↗


Powered by Chainloop and Chainloop Trace

Split RunTracePush into a step that builds the session evidence and a
step that adds the materials, so that a test can run the push up to the
upload. A new scenario test drives the Claude Code hooks for a skill
that the model starts and one that the user starts, and checks the
definition, the package and the session material that the push adds.

Refs chainloop-dev#3540

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: ee05bc4f-cf05-4433-b614-415b89577db7
Use one fake material adder, with an option for real digests, and the
existing helpers for the Claude Code project folder and skill folders.

Refs chainloop-dev#3540

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: ee05bc4f-cf05-4433-b614-415b89577db7
A skill that is part of the agent, such as /simplify in Claude Code, has
no folder on disk. The CLI does not record it, and writes a warning to
the local log so that the gap is visible.

Refs chainloop-dev#3540

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: ee05bc4f-cf05-4433-b614-415b89577db7
@jiparis
jiparis requested a review from a team October 7, 2026 17:06

@migmartri migmartri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

awesome!

@jiparis
jiparis merged commit 4db0cf8 into chainloop-dev:main Oct 7, 2026
16 of 17 checks passed
@jiparis
jiparis deleted the feat/trace-skills-used branch October 7, 2026 18:33
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.

feat(trace): record the skills that an agent used in a session

2 participants