Skip to content

fix(trace): record the skills of OpenCode 2 sessions - #3661

Merged
jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:fix/trace-opencode2-skills
Oct 19, 2026
Merged

jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:fix/trace-opencode2-skills

Conversation

@jiparis

@jiparis jiparis commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Fixes #3660.

The OpenCode provider of Chainloop Trace read the skill tool call in the OpenCode 1.x shape only, so an OpenCode 2 session recorded no skill and no copy of it.

  • The session export reader takes the skill name from the id input field (OpenCode 2) when there is no name field (OpenCode 1.x), and the skill folder from the directory metadata field when there is no dir field.
  • The plugin finds the skill folder in the directory metadata field and in the text items of an OpenCode 2 tool result, so the hook after the skill tool sends the folder and the push stores a copy of the skill. A plugin installed by an earlier version must be installed again.
  • The Trace README tells about the reinstall.

The end-to-end suite (spec issue-3635) found the problem. With this fix, its "Skills tracking" cell for OpenCode 2 passes in 3 of 3 runs (it was 0 of 3).

AI disclosure: Claude Code helped to write this change.

View guided diff

OpenCode 2 names the skill of a skill tool call in the id input and puts
its folder in the directory metadata. The provider and the plugin read
only the OpenCode 1.x fields, so an OpenCode 2 session recorded no skill
and no copy of it.

Fixes chainloop-dev#3660

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

Chainloop-Trace-Sessions: be5af72c-30e7-48f4-b46c-dc7a5a754c41
@chainloop-platform

chainloop-platform Bot commented Oct 19, 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 — 🟢 89% · ⚠️ 2 failing

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 89% 1 ⚠️ 2 94% AI / 6% Human 7 +79 / -26 73h49m51s

🟢 89% — 94% AI — ⚠️ 2 policies failing

Oct 16, 2026 16:40 UTC · 73h49m51s · $59.13 · 1.4k in / 652.8k out · claude-code 2.1.301 (claude-opus-5-5)

View session details ↗

Change Summary

  • Updates OpenCode skill extraction to accept 2.x id and directory fields in the provider and hook plugin.
  • Adds an OpenCode 2 export regression case and refreshes the plugin test fixtures.
  • Notes the OpenCode 2 plugin reinstall caveat in the Trace README.

AI Session Overall Score

🟢 89% — Focused OpenCode fix, root cause addressed and verified with tests plus live rerun.

AI Session Analysis Breakdown

🟢 94% · scope-discipline

🟢 The diff stayed inside OpenCode tracing files, tests, fixtures, and one README note. · High Impact

🟢 91% · verification

🟢 Provider tests passed and Skills tracking reran cleanly to 3/3. · High Impact

🟡 The fix phase ended without a user confirmation turn, so validation rests on AI-run checks. · Low Severity

🟢 90% · alignment

No notes.

🟢 90% · solution-quality

🟢 The fix updated both provider parsing and plugin result handling. · High Impact

🟢 88% · user-trust-signal

No notes.

🟢 84% · context-and-planning

No notes.


File Attribution

██████████████████░░ 94% AI / 6% Human

Status Attribution File Lines
modified ai app/cli/internal/trace/opencode/hooks.go +16 / -7
modified ai app/cli/internal/trace/opencode/testdata/plugin_full.ts +16 / -7
modified ai app/cli/internal/trace/opencode/testdata/plugin_tracerun.ts +16 / -7
modified ai app/cli/internal/trace/opencode/skills.go +13 / -4
modified ai app/cli/internal/trace/opencode/skills_test.go +14 / -0
modified ai app/cli/internal/trace/opencode/types.go +3 / -0
modified ai app/cli/internal/trace/README.md +1 / -1

Policies (5, 2 failing)

Status Policy Material Messages
⚠️ Failed ai-session-no-auto-pr ai-coding-session-be5af7
  • Pull request opened without human approval (auto-approved: source=config, reason=classifier): git push -q -u origin feat/trace-e2e-claude-remaining 2>&1 | grep -iE "error|rejected"; gh pr create --repo chainloop-dev/chainloop --base main --head jiparis:f...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api -X PUT repos/chainloop-dev/chainloop/pulls/3648/merge -f merge_method=squash -f commit_title="feat(trace): end-to-end test matrix for Claude Code (feat(trace): end-to-end test matrix for Claude Code #3648)...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api repos/chainloop-dev/chainloop/pulls/3648/comments/4311478018/replies -f body="Fixed in b7504e5. The section now says that the suite runs the Claude Code ...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api repos/chainloop-dev/chainloop/pulls/3651/comments/4313920106/replies -F body=@/private/tmp/claude-501/-Users-jiparis-projects-chainloop/be5af72c-30e7-48f...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api repos/chainloop-dev/chainloop/pulls/3651/comments/4313920123/replies -F body=@/private/tmp/claude-501/-Users-jiparis-projects-chainloop/be5af72c-30e7-48f...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api repos/chainloop-dev/chainloop/pulls/3651/comments/4313920134/replies -F body=@/private/tmp/claude-501/-Users-jiparis-projects-chainloop/be5af72c-30e7-48f...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh api repos/chainloop-dev/chainloop/pulls/3651/comments/4313920140/replies -F body=@/private/tmp/claude-501/-Users-jiparis-projects-chainloop/be5af72c-30e7-48f...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh pr create --repo chainloop-dev/chainloop --base main --head jiparis:feat/trace-e2e-claude-gaps --title "feat(trace): review feature table and add e2e checks ...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh pr create --repo chainloop-dev/chainloop --base main --head jiparis:feat/trace-e2e-matrix --title "feat(trace): end-to-end test matrix for Claude Code" --bod...
  • Pull request opened without human approval (auto-approved: source=config, reason=subcommandResults): gh pr create --repo chainloop-dev/chainloop --base main --head jiparis:fix/trace-claude-api-request-blob --title "fix(trace): replace spec copies in Claude Code...
✅ Passed ai-config-ai-agents-allowed ai-coding-session-be5af7 -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-be5af7 -
⚠️ Failed ai-config-no-secrets ai-coding-session-be5af7
  • Secret (github-pat) detected in session content [turn=1343, source=tool_result, line=9]: | ⚠️ Failed | ai-config-no-secrets | [ai-coding-session-be5af7](https://app.chainloop.dev/u/chainloop/projects/chainloop/versi...
  • Secret (github-pat) detected in session content [turn=1386, source=assistant-text, line=10]: - AI session policy ai-config-no-secrets: it flags the fake tokens in this session's transcript. Most of the matches are already the [CHAINLOOP_TRACE_REDACTED:github-pat] placeholder, so this ...
  • Secret (github-pat) detected in session content [turn=1412, source=tool_result, line=6]: 33 fakeSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]" //nolint:gosec // a fake token that the suite expects redaction to remove
  • Secret (github-pat) detected in session content [turn=1412, source=tool_result, line=9]: 36 fakeAllowedSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]" //nolint:gosec // a fake token on a line with an allow marker
  • Secret (github-pat) detected in session content [turn=1424, source=assistant-tool_use:Edit, line=1]: {"file_path":"/Users/jiparis/projects/chainloop/.claude/worktrees/cosmic-enchanting-flute/app/cli/internal/trace/e2e/scenarios.go","new_string":"// secret scanner, and they are not real tokens. The al...
  • Secret (github-pat) detected in session content [turn=4719, source=tool_result, line=1]: Run this shell command: git add greeting.txt shell.txt && git commit -m \\\"add greeting\\\"\n5. Run this shell command: git push\nThe deploy token [CHAINLOOP_TRACE_REDACTED:github-pat] is for a later...
  • Secret (github-pat) detected in session content [turn=525, 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.\...
  • Secret (github-pat) detected in session content [turn=672, source=tool_result, line=1]: deploy token [CHAINLOOP_TRACE_REDACTED:github-pat]
  • Secret (github-pat) detected in session content [turn=971, source=tool_result, line=19]: fakeSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"
  • Secret (github-pat) detected in session content [turn=971, source=tool_result, line=22]: fakeAllowedSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"
  • Secret (github-pat) detected in session content [turn=971, source=tool_result, line=48]: fakeSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"
  • Secret (github-pat) detected in session content [turn=971, source=tool_result, line=51]: fakeAllowedSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"
  • Secret (github-pat) detected in session content [turn=999, source=assistant-tool_use:Bash, line=42]: s=s.replace('fakeSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"','fakeSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]" //nolint:gosec // a fake token that the suite expects redaction to remove')
  • Secret (github-pat) detected in session content [turn=999, source=assistant-tool_use:Bash, line=43]: s=s.replace('fakeAllowedSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]"','fakeAllowedSecret = "[CHAINLOOP_TRACE_REDACTED:github-pat]" //nolint:gosec // a fake token on a line with an allow marker')
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-be5af7 -

Security Checks — ✅ 5 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 -
Scans not applied (3)
Scan Reason
vulnerability-scan no manifest/lockfile changed
github-actions-scan no workflow files changed
iac-scan no IaC files changed

View attestation ↗

Security context

✅ Nothing this change touches has a recorded security-fix history.

View in Chainloop ↗ · How this works ↗


Powered by Chainloop and Chainloop Trace

@jiparis
jiparis requested a review from a team October 19, 2026 18:31

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 7 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread app/cli/internal/trace/opencode/hooks.go

@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.

are you managing to figure this oue because of the end to end tests?

@jiparis

jiparis commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

are you managing to figure this oue because of the end to end tests?

Yes, this was detected during the e2e tests.

@jiparis
jiparis merged commit 1808a84 into chainloop-dev:main Oct 19, 2026
16 of 17 checks passed
@jiparis
jiparis deleted the fix/trace-opencode2-skills branch October 19, 2026 19:09
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.

Trace: OpenCode 2 sessions record no skills

2 participants