Repository navigation
fix(trace): register checkouts that shell commands work in - #3623
Conversation
A session that works in another checkout through shell commands only, for example in a fresh clone, never registered that checkout. Agent hooks run from the directory the session started in, so the clone got no git hooks, and its commits and pushes carried no session. The pre and post shell hooks now read the command text and find the checkouts it names: the target of cd or pushd, the path of git -C, and the folder that git clone or gh repo clone creates. Each one is handled as a file tool edit there is: the git hooks are installed, the session is recorded, and the checkout is added to the session's checkouts. Claude Code and OpenCode send the command text. Cursor does not, as the provider installs no shell hooks yet. Refs: PFM-7614 Assisted-by: Claude Code Signed-off-by: Jose I. Paris <jiparis@chainloop.dev> Chainloop-Trace-Sessions: 2256cda0-6d1f-4a81-ae6a-f07a6a67c3dc
PR validation — ✅ 3 passing
AI Session Checks — 🟢 89% · ✅ 0 failing
|
| Status | Attribution | File | Lines |
|---|---|---|---|
| modified | ai | app/cli/pkg/action/trace_command_dirs.go |
+551 / -126 |
| modified | ai | app/cli/pkg/action/trace_shell_checkout_test.go |
+198 / -5 |
| modified | ai | app/cli/pkg/action/trace_command_dirs_test.go |
+117 / -25 |
| modified | ai | app/cli/pkg/action/trace_agent_hook.go |
+42 / -1 |
| modified | ai | app/cli/internal/trace/claude/hooks_test.go |
+13 / -0 |
| modified | ai | app/cli/internal/trace/opencode/hooks_test.go |
+8 / -5 |
| modified | ai | app/cli/internal/trace/README.md |
+8 / -4 |
| modified | ai | app/cli/internal/trace/opencode/hooks.go |
+7 / -4 |
| modified | ai | app/cli/internal/trace/opencode/testdata/plugin_full.ts |
+3 / -2 |
| modified | ai | app/cli/internal/trace/opencode/testdata/plugin_tracerun.ts |
+3 / -2 |
| modified | ai | app/cli/pkg/action/trace_agent_hook_test.go |
+2 / -2 |
| modified | ai | app/cli/internal/trace/provider.go |
+3 / -0 |
| modified | ai | app/cli/internal/trace/claude/hooks.go |
+2 / -0 |
Policies (4)
| Status | Policy | Material | Messages |
|---|---|---|---|
| ✅ Passed | ai-config-ai-agents-allowed |
ai-coding-session-2256cd |
- |
| ✅ Passed | ai-config-no-dangerous-commands |
ai-coding-session-2256cd |
- |
| ✅ Passed | ai-config-no-secrets |
ai-coding-session-2256cd |
- |
| ✅ Passed | ai-config-mcp-servers-allowed |
ai-coding-session-2256cd |
- |
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 |
Security context
This change touches code with 2 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
There was a problem hiding this comment.
All reported issues were addressed across 13 files
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
…ll dir detection Address review findings on the command parser: - A cd inside parentheses applies only until the closing parenthesis. - A cd without arguments moves to the home directory. - A leading assignment with an expansion in its value is skipped, so the command after it is still read. Split the tokenizer into a small lexer type to bring its complexity under the lint limit, and fix the other lint findings in the tests. The trace README tells OpenCode users to install the hooks again. Refs: PFM-7614 Assisted-by: Claude Code Signed-off-by: Jose I. Paris <jiparis@chainloop.dev> Chainloop-Trace-Sessions: 2256cda0-6d1f-4a81-ae6a-f07a6a67c3dc
Resolve the trace README conflicts with the Cursor shell hooks from chainloop-dev#3624: take the upstream text for the Cursor rows. Cursor now sends the command text through the same HookInput field, so the shell checkout detection works for Cursor too. Rate it Partial, as the shell hooks are verified for the IDE only and relative paths resolve against the first workspace root. Cover OpenCode and Cursor in one table-driven test. Refs: PFM-7614 Assisted-by: Claude Code Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>
A traced session can work in a second checkout through shell commands only, for example in a fresh clone. Before this change, the trace did not see that checkout. Agent hooks run from the directory where the session started, so the clone got no git hooks, and its commits and pushes carried no session.
This change finds the checkout from the command text. The shell hooks read the command and get these directories from it:
cdorpushdgit -Cgit cloneorgh repo clonecreatesThe trace handles each directory the same as a file tool edit there: it installs the git hooks, records the session, and adds the checkout to the checkouts of the session. A hand-written tokenizer reads the command. This change adds no shell-parsing dependency.
Provider support:
Known limit: when one shell call clones a repository and also commits in it, that commit does not carry the session. The clone does not exist before the call, so the git hooks are installed only after the call.
Closes #3533 (PFM-7614)
AI disclosure: this change was made with Claude Code.