Skip to content

fix(core): mint the CLI session id instead of inferring it (#357) - #431

Open
edspencer wants to merge 3 commits into
mainfrom
fix/357-minted-session-id
Open

fix(core): mint the CLI session id instead of inferring it (#357)#431
edspencer wants to merge 3 commits into
mainfrom
fix/357-minted-session-id

Conversation

@edspencer

@edspencer edspencer commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Reopens and finishes #357. Found via paddock#548.

What #357 left behind

#357 fixed the case where a co-located agent is appending to its own session:
a pre-spawn snapshot identifies the new transcript by set difference instead of
by mtime. It did not fix the case where a co-located agent creates a file,
and said so in a comment:

// Normally exactly one; if several appeared (e.g. multiple co-located
// spawns raced), the newest is ours.
const newest = await newestSessionFileByMtime(sessionDir, brandNew);

The newest is not ours — it is whoever spawned last. Two agents sharing a
working_directory share one ~/.claude/projects/<encoded-cwd>/, so two
concurrent resume:null spawns produce two brand-new files that are
indistinguishable by name or mtime. The agents trade session ids: each
adopts the other's transcript and writes a job record claiming it.

Reproduced against a build of main (5.27.0), no paddock and no vitest —
pre-existing file, snapshot, write bbbb.jsonl, sleep 20 ms, write cccc.jsonl:

returned cccc.jsonl, should be bbbb.jsonl -> WRONG SESSION

The fix: stop inferring

Claude Code accepts --session-id <uuid> and names the transcript after it. I
verified both that the file is named exactly as requested and that it composes
with --fork-session (the fork wrote the requested id).

So a turn that starts a new session — a fresh run, or a fork — now mints its own
id and passes it. The transcript is known by name: no snapshot, no mtime, no
tie-break. A plain resume already knows its id and is untouched.

Two details that matter:

  • While polling, the inference paths are disabled. Falling back to "take
    whichever brand-new file shows up" mid-wait would reintroduce exactly the
    collision this removes. Only once the deadline passes without our file
    appearing — a CLI too old to know the flag — do we warn and fall back, so the
    turn still runs rather than failing.
  • HERDCTL_CLI_MINT_SESSION_ID=0 restores the old behaviour.

Verified under the hostile ordering: with the co-located agent's file created
first and newest by mtime, we still take ours.

Also: #357's "secondary hardening", which was never implemented

#357 proposed it in as many words:

Secondary hardening (defense in depth): in buildJobIndex, a job should not
be allowed to (re)attribute a session_id to an agent when the winning record's
agent differs from an already-known owner…

AttributionIndexBuilder filled its session→agent map by iterating a cache
populated inside an unordered Promise.all, then index.set(sessionId, …)
last writer wins. So when two records claim one session id, the winner is
whichever file's stat+parse finished last.

That is not random, which is worse than it sounds — it is a function of record
size and machine load. With the same two records on disk, enlarging one flips the
result:

Fixture Winner
keeper record larger (slower parse) keeper 10/10
sweeper record larger sweeper 10/10

Claims are now ordered explicitly: newest started_at wins, ties broken on job
id
, so the answer is a pure function of what is on disk.

Newest-wins rather than the literal "first owner keeps it" #357 suggested,
because adopting or promoting a session is a legitimate change of owner
paddock's writeAgentAdoptionJob and reattributeSession do exactly that, and a
hard owner lock would break them. (reattributeSession rewrites every matching
record in place, so a promote leaves no conflict at all; the ordering rule is
what covers adoption and any accidental collision that still gets through.)

Tests

7 new cases, all of which fail against the current source and pass here:

  • the minted id is honoured even when a co-located brand-new file lands first and is newest by mtime
  • the deadline fallback still resolves rather than failing the turn
  • a contrast case pinning the old inference behaviour (still takes the wrong file)
  • attribution resolves identically regardless of the order files are read, is stable across repeated builds, still lets a deliberate re-attribution win, and breaks an exact timestamp tie on job id

packages/core: 3488 passed, 1 pre-existing failure
(directory.test.ts "parent directory is not writable" — fails identically on a
clean checkout when the suite runs as root, since root can write to the
restricted dir). Typecheck and lint clean.

⚠️ Requires a companion paddock change before paddock upgrades

paddock's integration suite drives a fake claude (test/bin/claude) that
mints its own uuid and ignores --session-id. Against this version the expected
file would never appear, so every new-session turn would burn the full 60 s
timeout before falling back — technically passing, practically unusable.

test/bin/claude needs to honour --session-id when present. Happy to open that
PR alongside; it should land before paddock bumps @herdctl/core.

One thing I could not verify

I don't know which Claude Code version introduced --session-id (confirmed
present in 2.1.220), and herdctl declares no minimum. If an older CLI errors on
an unknown flag rather than ignoring it, the deadline fallback never gets a
chance and the turn fails loudly. That is the reason for the env escape hatch. If
you know the introducing version, a documented minimum would be better than the
fallback.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • New CLI sessions now receive explicit identifiers, improving transcript tracking and attribution.
    • Forked sessions retain reliable links to their source while writing to distinct transcripts.
    • Session discovery can gracefully fall back to legacy behavior when explicit identification is unavailable.
  • Bug Fixes

    • Improved handling when a CLI exits before creating its transcript.
    • Resolved conflicting session claims deterministically, favoring the newest activity and providing stable tie-breaking.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds UUID-based CLI session IDs, expected-transcript discovery with exit-aware fallback, fake CLI support for explicit IDs, and deterministic session attribution based on started_at and job ID.

Changes

CLI session identity and discovery

Layer / File(s) Summary
Minted session IDs and transcript discovery
packages/core/src/runner/runtime/cli-runtime.ts, packages/core/src/runner/runtime/cli-session-path.ts, packages/web/test-ui/fixtures/bin/claude, .changeset/cli-minted-session-id.md
New and forked sessions pass UUIDs through --session-id, unless disabled by HERDCTL_CLI_MINT_SESSION_ID=0. Transcript discovery waits for the expected file, tracks CLI exit, and then falls back to inference. The fake CLI honors explicit IDs.
Expected session ID resolution tests
packages/core/src/runner/runtime/__tests__/cli-session-path.test.ts
Tests cover matching files, newer co-located files, missing expected files, process exit, continued polling, and legacy inference.

Deterministic session attribution

Layer / File(s) Summary
Deterministic duplicate-session attribution
packages/core/src/state/session-attribution.ts, packages/core/src/state/__tests__/session-attribution.test.ts
Cached job records retain started_at and job ID. Duplicate claims select the newest start time, then the highest job ID. Tests cover file order, repeated builds, re-attribution, and timestamp ties.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant cliRuntime
  participant claudeCli
  participant sessionPath
  cliRuntime->>claudeCli: Pass minted --session-id
  claudeCli->>sessionPath: Write transcript with explicit ID
  cliRuntime->>sessionPath: Wait for expected transcript
  sessionPath-->>cliRuntime: Return match or fallback result
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: minting CLI session IDs instead of inferring them.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/357-minted-session-id

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 1, 2026

Copy link
Copy Markdown

Deploying herdctl with  Cloudflare Pages  Cloudflare Pages

Latest commit: 96150c1
Status: ✅  Deploy successful!
Preview URL: https://479dba24.herdctl.pages.dev
Branch Preview URL: https://fix-357-minted-session-id.herdctl.pages.dev

View logs

@edspencer edspencer left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

This PR fixes co-located session-id collisions by minting the CLI session id (--session-id <uuid>) instead of inferring the transcript file, with a deadline fallback to the old inference and an HERDCTL_CLI_MINT_SESSION_ID=0 escape hatch. It also makes the incremental AttributionIndexBuilder resolve doubly-claimed session ids deterministically (newest started_at wins, tie-break on job id) instead of by Promise.all completion order.

I read cli-session-path.ts, cli-runtime.ts (spawn/mint/watch flow), session-attribution.ts, the JobMetadataSchema (confirmed started_at/id are always present, so claimWins never dereferences undefined), and job-metadata.ts's listJobs ordering. The mint logic, the "keep waiting for exactly our file while polling" invariant, and the new tie-break all look correct and well-tested. Two lower-severity gaps below.

if (held && !claimWins(entry, held)) continue;
winners.set(entry.sessionId, { startedAt: entry.startedAt, jobId: entry.jobId });
index.set(entry.sessionId, { agent: entry.agent, triggerType: entry.triggerType });
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

LOW · correctness — Non-incremental buildJobIndex still resolves collisions by order (oldest-wins, non-deterministic on ties)

This PR makes the incremental AttributionIndexBuilder resolve a doubly-claimed session id deterministically (newest started_at wins, tie-break on job id). But its sibling buildJobIndex (lines 100-115), used by the exported buildAttributionIndex, was left unchanged: it iterates result.jobs and does last-write-wins via index.set.

listJobs sorts jobs by started_at descending (job-metadata.ts:443-447), so last-write-wins there resolves a collision to the oldest claim — the opposite of the new newest-wins rule this PR argues is correct (adopt/promote should win). And for exact started_at ties the result still depends on V8's stable sort preserving readdir order, i.e. the same filesystem-order non-determinism this PR set out to remove.

The two builders are documented as parallel (createAttributionIndex is "Shared by the full buildAttributionIndex and the incremental AttributionIndexBuilder"), so having them disagree on collision resolution is a latent surprise. buildAttributionIndex currently has no production callers besides being a public export, which is why this is low rather than higher — but it's still reachable API. Consider applying the same claimWins ordering in buildJobIndex, or documenting that the full builder is deprecated in favor of the incremental one.

// file was ours (issue #357). A plain resume keeps its existing id and needs
// nothing. Opt out with HERDCTL_CLI_MINT_SESSION_ID=0.
const mintedSessionId =
(!options.resume || options.fork) && process.env.HERDCTL_CLI_MINT_SESSION_ID !== "0"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

LOW · bug — --session-id defaults on; an older CLI that errors on the unknown flag fails every new-session turn

mintedSessionId is enabled by default (HERDCTL_CLI_MINT_SESSION_ID !== "0") and pushed as --session-id. The deadline fallback in waitForNewSessionFile only helps if the CLI ignores an unknown flag. If an older claude binary instead errors on the unknown --session-id flag, the subprocess exits non-zero and no fallback runs — every fresh/fork turn fails loudly, by default, with no minimum-CLI-version guard in the repo.

The author acknowledged this in the PR body ("One thing I could not verify"), and the env escape hatch exists — recording it here so it isn't lost in prose. Worth either documenting a minimum Claude Code version, or gating the flag behind a capability probe, before this ships as the default.

@edspencer

edspencer commented Aug 1, 2026

Copy link
Copy Markdown
Owner Author

Verified the three spawn shapes core produces:

  • New (--session-id <minted>, no resume): writes <minted>.jsonl, no prior text — this is the case that previously timed out.
  • Resume (--resume <id>, no session-id): flags.sessionId is undefined so ?? falls through to flags.resume; reads and appends the same file.
  • Fork (--resume <src> --fork-session --session-id <new>): sessionId (=<new>) wins for the written file, while priorText deliberately reads <src>.jsonl for continuity.

The key subtlety — writing to the sessionId-named file but reading prior text from the resume source — is handled correctly, and readPriorText tolerates a missing source. Transcript sessionId/session_id fields stay consistent with the filename. Clean pass.

Reviewed 1 changed file (3 hunks); 0 findings.

@edspencer

Copy link
Copy Markdown
Owner Author

Pushed 0682236: the fake claude in this repo's own web-UI harness needed the companion change too — I flagged that risk for paddock and then walked straight into it here.

The harness's fake minted its own uuid and ignored --session-id, so once the runtime started passing a minted id, every new-session turn waited out the full 60 s timeout before falling back to inference. That is what the Web UI Tests failure was: 04-jobs "triggering a job via the modal" failed outright, 02-schedules went flaky, and the suite took 8.5 minutes.

Verified load-bearing rather than assumed: with the fake reverted, that one job test fails and takes 48 s; with the fix, the whole suite is 27 passed in 55 s. (One flaky — 07-sessions-and-errors:46, passed on retry. I have not checked whether it is also flaky on main, so I am not claiming it is unrelated.)

--session-id now names the transcript whenever supplied, winning over --resume so a fork lands in a new file rather than appending to its source, with continuity read from the resumed session.

This is the same companion change paddock's test/bin/claude will need before it bumps @herdctl/core.

@edspencer edspencer left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Companion test-fixture change: the fake claude CLI used by @herdctl/web's UI/integration tests now honours --session-id, matching core's new mint-and-pass behaviour (#357). Without it, every new-session turn in the web tests would burn the full 60s timeout waiting for a file named after the minted id the fixture ignored.

I read the full fixture and cross-checked its flag handling against how core actually passes --resume/--fork-session/--session-id (verified in the sibling core PR): new session, plain resume, and fork all resolve to the correct transcript filename and continuity source. No issues found — the change is correct and well-commented.

Paddock and others added 3 commits August 2, 2026 14:54
waitForNewSessionFile worked out which transcript a freshly-spawned claude had
created by inspecting the session directory. #357 fixed half of that with a
pre-spawn snapshot, so a co-located agent APPENDING to its own session can no
longer be mistaken for ours. The other half stayed a guess — 'if several
appeared, the newest is ours' — and the newest is not ours, it is whoever
spawned last. Two agents sharing a working directory share one session dir, so
two concurrent resume:null spawns trade session ids.

Claude Code accepts --session-id <uuid> and names the transcript after it
(composing with --fork-session), so a new-session turn now mints its own id and
passes it; the file is known by name. While polling, the inference paths are
disabled — taking whichever brand-new file shows up is the collision we are
removing. Only if the deadline passes without our file appearing (a CLI that
ignores the flag) do we warn and fall back. HERDCTL_CLI_MINT_SESSION_ID=0 opts
out.

Also implement #357's proposed secondary hardening: AttributionIndexBuilder
filled its map in Promise.all completion order, so when two records claimed one
session id the winner was whichever file's stat+parse finished last — decided by
record size and machine load (enlarging either record flips it, 10/10 each way).
Order claims explicitly: newest started_at wins, ties broken on job id. Newest
rather than first-owner because adopt/promote legitimately change a session's
owner and write a newer record.

Found via paddock#548.

Co-Authored-By: Claude <noreply@anthropic.com>
The web UI harness drives a fake `claude` that minted its own uuid and ignored
--session-id. Now that the runtime passes the id it minted, the fake wrote a
differently-named transcript, so every new-session turn waited out the full 60s
timeout before falling back to inference — the job-trigger specs failed and the
suite took 8.5 minutes.

--session-id now names the transcript whenever supplied, winning over --resume so
a fork lands in a new file instead of appending to its source; continuity is read
from the resumed session, which for a fork is that source.

Full web UI suite: 55s, down from 8.5 minutes.

Co-Authored-By: Claude <noreply@anthropic.com>
Rebasing onto main surfaced three more test files (herdctl#423 CLAUDE_CONFIG_DIR
/ claude-home threading) whose fake spawners write a session id of their own
choosing and ignore --session-id. They did not fail because the fix was wrong;
they failed because waiting out the whole 60s timeout is an unreasonable cost to
impose on every fake-CLI harness in the ecosystem — this was the third one.

So stop waiting on the clock and start waiting on evidence. While the process is
alive we still refuse to infer, which is the guarantee that matters: a co-located
agent's brand-new file must not be claimed just because it landed first. But once
the CLI has EXITED without writing the file we asked for, it never will, so fall
back immediately (after a 500ms grace for a late flush).

All three #423 files now pass UNMODIFIED — no other author's tests touched.

Co-Authored-By: Claude <noreply@anthropic.com>
@edspencer
edspencer force-pushed the fix/357-minted-session-id branch from 0682236 to 96150c1 Compare August 2, 2026 19:00
@edspencer

Copy link
Copy Markdown
Owner Author

Rebased onto main (was 11 commits behind, at core 5.27.0 → now 5.30.0) and changed the fallback design, because the rebase surfaced something worth acting on.

The conflict was trivial; what it revealed was not

The only conflict was additive-vs-additive in session-attribution.ts#438 added the ownership predicates, this PR added claimWins. Both kept, no behaviour reconciled away. Confirmed main still has the unfixed assembly loop, so this PR is still needed.

But the rebase also pulled in three test files from #423 (CLAUDE_CONFIG_DIR / claude-home threading) whose fake spawners write a session id of their own choosing and ignore --session-id. All three failed. Verified the cause exactly: with HERDCTL_CLI_MINT_SESSION_ID=0, all 28 of their tests pass.

They were not failing because the fix is wrong. They were failing because waiting out the full 60 s timeout is an unreasonable cost to impose on every fake-CLI harness — and this was the third one (herdctl's web-UI fake, these, and paddock's still to come).

So: wait on evidence, not on the clock

  • While the process is alive, still refuse to infer. That is the guarantee that matters — a co-located agent's brand-new file must not be claimed just because it landed first.
  • Once the CLI has exited without writing the file we asked for, it never will. That is settled, not unknown, so fall back immediately (500 ms grace for a late flush).

All three #423 files now pass unmodified — no other author's tests touched. Two new tests cover it: the fast fallback completes in <5 s against a 30 s timeout, and the co-located race still resolves to our file while the process is alive.

packages/core: 3675 passed, 1 pre-existing failure (directory.test.ts "parent directory is not writable" — fails identically on a clean checkout when run as root). Web UI suite: 27 passed in 59 s. Typecheck and lint clean.

The test(web) commit teaching herdctl's own fake to honour the flag is still here and still worth having — the fallback makes a non-honouring fake survivable, but honouring it is what makes those runs deterministic.

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

🧹 Nitpick comments (4)
packages/core/src/state/__tests__/session-attribution.test.ts (3)

931-939: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse one AttributionIndexBuilder in the loop.

The loop creates a new builder each time. It does not exercise cached claim metadata. Create the builder before the loop, then call build repeatedly on that instance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/state/__tests__/session-attribution.test.ts` around lines
931 - 939, Update the “is stable across repeated builds” test to instantiate a
single AttributionIndexBuilder before the loop and reuse that instance for every
build(tempDir) call, so repeated builds exercise cached claim metadata while
preserving the existing seen-set assertion.

896-912: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add explicit helper types.

Define an interface for opts. Add the Promise<void> return type to writeCompeting.

As per coding guidelines, “Use strict TypeScript with explicit types” and “Prefer interface over type for defining object shapes in TypeScript”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/state/__tests__/session-attribution.test.ts` around lines
896 - 912, Update the writeCompeting helper to return Promise<void> explicitly,
and define its opts parameter through a dedicated interface rather than an
inline object type. Use the interface for the keeperFirst property while
preserving the helper’s existing behavior.

Source: Coding guidelines


914-978: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Mock file-system operations in these unit tests.

These tests create directories and files through node:fs/promises. Mock the file-system dependency and control the directory-entry order in the test fixture.

As per coding guidelines, “Mock external dependencies (SDK, file system, GitHub API) in tests”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/state/__tests__/session-attribution.test.ts` around lines
914 - 978, Mock the node:fs/promises operations used by the attribution tests
instead of creating real directories and files through writeCompeting and
writeJobFile. Configure the mock fixture to return controlled directory-entry
orders for each build, while preserving the existing assertions for newest
claims, repeated-build stability, re-attribution, and timestamp tie-breaking in
AttributionIndexBuilder.

Source: Coding guidelines

packages/core/src/state/session-attribution.ts (1)

396-402: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Define named interfaces for claim metadata.

Lines 396-421 and Line 543 define related object shapes inline. Define interfaces such as SessionClaimOrder and CachedSessionClaim. Use them for claimWins, CachedJobFile.entry, and winners.

As per coding guidelines, “Prefer interface over type for defining object shapes in TypeScript”.

Also applies to: 413-421, 542-549

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/state/session-attribution.ts` around lines 396 - 402,
Define named interfaces for the related claim metadata object shapes, such as
SessionClaimOrder and CachedSessionClaim, near the existing claim logic. Replace
the inline shapes used by claimWins, CachedJobFile.entry, and winners with the
appropriate interfaces while preserving their current fields and behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/core/src/state/__tests__/session-attribution.test.ts`:
- Around line 931-939: Update the “is stable across repeated builds” test to
instantiate a single AttributionIndexBuilder before the loop and reuse that
instance for every build(tempDir) call, so repeated builds exercise cached claim
metadata while preserving the existing seen-set assertion.
- Around line 896-912: Update the writeCompeting helper to return Promise<void>
explicitly, and define its opts parameter through a dedicated interface rather
than an inline object type. Use the interface for the keeperFirst property while
preserving the helper’s existing behavior.
- Around line 914-978: Mock the node:fs/promises operations used by the
attribution tests instead of creating real directories and files through
writeCompeting and writeJobFile. Configure the mock fixture to return controlled
directory-entry orders for each build, while preserving the existing assertions
for newest claims, repeated-build stability, re-attribution, and timestamp
tie-breaking in AttributionIndexBuilder.

In `@packages/core/src/state/session-attribution.ts`:
- Around line 396-402: Define named interfaces for the related claim metadata
object shapes, such as SessionClaimOrder and CachedSessionClaim, near the
existing claim logic. Replace the inline shapes used by claimWins,
CachedJobFile.entry, and winners with the appropriate interfaces while
preserving their current fields and behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8e57c3b1-a3fb-4e79-a0ff-b7d6a5d42fa2

📥 Commits

Reviewing files that changed from the base of the PR and between 9f15eac and 96150c1.

📒 Files selected for processing (7)
  • .changeset/cli-minted-session-id.md
  • packages/core/src/runner/runtime/__tests__/cli-session-path.test.ts
  • packages/core/src/runner/runtime/cli-runtime.ts
  • packages/core/src/runner/runtime/cli-session-path.ts
  • packages/core/src/state/__tests__/session-attribution.test.ts
  • packages/core/src/state/session-attribution.ts
  • packages/web/test-ui/fixtures/bin/claude

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.

1 participant