Repository navigation
Run launched agent sessions in the project's checkout with the session plugin; delete the context assembler - #3647
Conversation
Pragmatic Code Review: PR #3647 (issue #3547)Review Type: Initial Review (no prior reviews or comments on the PR; one commit, SummaryThe change does what the issue asks and is a clear net improvement: about 2,100 lines of dead or wrong code go (the assembler that always wrote an empty context file, the directory-based session id lookup, the resume flag), and the launch path gets a typed What I did not do: I read the code and docs but ran no tests, Requirements CheckWorking directory
Environment
Plugin
Removal and fixes
Code Review Findings🟡 Important1. The private session folder ignores let dir = dirs::home_dir()
.context("HOME not set")?
.join(".nodespace")
.join("agent-sessions")The test sets Recommendation: have the daemon pass the base folder ( 2. A harness started inside a launched session overwrites the recorded id
"Latest stands" is needed for 3. One variable for "task or chat node" makes the plugin depend on a second call succeeding The daemon sets Recommendation: in 4. A stored folder is trusted without the checks a named one gets, and the folder is stored before the launch is known to be valid
Principle: validate at the trust boundary, not at one of its entrances; no side effects before validation completes. 🟢 Suggestions5. 6. Double cast where a guard exists 7. Leftover references
8. Tests that pin less than their comments say
9. The search path is rebuilt on every call
On the stated decisions
Security
Recommendation: APPROVENo blocker. Findings 1 to 4 are small and worth doing in this PR: 1 because the gate itself writes into a real home, 3 because it is a one-line fail-closed fix, 2 at least as a documented limit. |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review: APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Review addressedAll four important findings and suggestions 5 to 9 are fixed. One nit is skipped. Important
Suggestions
Skipped
Checks: Re-Review DecisionDecision: RE-REVIEW NEEDED Rationale: Findings 1 to 4 changed behaviour, not wording: where the session folder is created, the order of validation and the write in the launch handler, and how the plugin holds and removes the launch variables. Those deserve a second look. |
Pragmatic Code Review: PR #3647 (issue #3547)Review Type: Re-Review (commit Previous Review Summary: 11 recommendations (findings 1 to 9 and 2 nits). 10 addressed, 1 not addressed (a nit, skipped on purpose with a sound reason). 4 new findings, none blocking. What I did not do: I read the diff, the surrounding code and the uncommitted docs. I ran no tests, and I did not check in a live Claude Code session that unsetting a variable through the plugin API removes it from what the shell tool's children inherit. The fix for finding 2 depends on that. Earlier findings
The new e2e assertions pin what they claim. The unknown-task launch would have stored the folder under the old order, so the The docs in New findings1. 🟡 Important: no test pins that the launch survives in state once the variables are gone The test host's Recommendation: make the handler remove the variable from the mocked environment (or pass the call on to 2. 🟡 Important: the variables are unset before the launch is stored
A related ordering point: Recommendation: read the environment first and fall back to 3. 🟢 Suggestion: a session that cannot reach the CLI or daemon at start never opens with its task unless the user clears Not introduced by this commit, but now more visible. When 4. 🟢 Nit: the spawn now runs on the async executor With the search path passed in, SecurityNo change to the trust model. The private folder is created under the daemon's owner-only state directory. Removing the two session-naming variables from the harness's environment narrows what child processes hold. Recommendation: APPROVEEvery earlier finding is fixed or deliberately declined. New findings 1 and 2 are small, sit in the plugin (outside the merge gate), and are worth doing in this PR: 1 because the fix for finding 2 is currently unpinned, 2 because it is a reorder of two steps. The unverified part remains the one the PR already states: no live Claude Code session was launched, which is also the only way to confirm the unset reaches the shell tool's children. |
malibio
left a comment
There was a problem hiding this comment.
Automated pragmatic-code-review (re-review): APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.
Re-review addressedFixed
Documented, not changed
Checks: Still not verified: no live Claude Code session was launched from the app, so it is unconfirmed that unsetting a variable through the plugin API removes it from what the shell tool's children inherit. Re-Review DecisionDecision: NO RE-REVIEW NEEDED Rationale: The changes are a reorder of two steps in the plugin, a test host that models the environment, one |
b1f3bd7 to
52b2c6e
Compare
…n plugin; delete the context assembler (closes #3547) A session NodeSpace launches now runs in the project's folder on this machine, with an environment that names the database, the daemon socket, the session and what it was launched for. Nothing is written at launch. - project gains checkout_path, a local_only field: the per-machine folder. A launch that names a folder has it checked and stored on the project. - LaunchSession takes project_id, project_folder and task_id, and ReportHarnessSession takes the harness's own session id from its plugin. - The Claude Code plugin reports its session id and opens the first prompt with the launched task's context. - GraphContextAssembler, the per-agent context file, the embedded skill copies, the resume flag and the directory-based session id lookup are deleted. - Detection and launch resolve the agent binary on one search path, and one set of agent ids serves the daemon, the CLI and the skill installer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es before storing, plugin takes the launch out of the environment - The daemon says where a private session folder is created. - A stored project folder gets the checks a named one gets; the task is validated before the folder is stored; a conflict on that write is ABORTED. - The plugin keeps the launch variables in its state and unsets them, names the session with --session, and opens with nothing when its report is not answered. - The search path is built once per launch. - Tests: absent vs empty variable, the session's PATH, a relative stored folder, an unknown task storing nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in the state fallback - The plugin reads the launch from the environment first, falls back to its state, and unsets the variables only after the state is written. - The plugin test host models the environment, so the /clear and compaction tests fail without the fallback. - PtySessionManager::launch runs the launch off the async executor again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52b2c6e to
3684ac9
Compare
Closes #3547. Implements ADR-093 §8 and the launched-session part of §9.
A session NodeSpace launches now runs in the project's folder on this machine, with an environment that points
nodespaceat the database it was launched from. Nothing is written at launch: the harness plugin delivers the context, as it does for a session started from a terminal.What changed
Working directory
LaunchSessiontakesproject_id,project_folderandtask_id. A session launched for a project runs in that project'scheckout_path.nodespace session launchtakes--project,--folderand--task.Environment
NODESPACE_DATABASE(the database's id),NODESPACED_SOCKET,NODESPACE_SESSION(the PTY session's id) andNODESPACE_LAUNCHED_FOR(the task, otherwise the chat node). A value that is not known is left out.CLAUDE_CONFIG_DIRis forwarded to Claude Code when the daemon has it.Plugin
ReportHarnessSessionRPC andnodespace session report-harness-session <id>. The Claude Code plugin calls it at session start (and again after a/clear); the daemon writes the id to the chat node when the session ends.Removed and fixed
GraphContextAssembler,ContextFile,ContextError, the embeddedSKILL.mdand reference copies, the catalog's resume flag and session-store field, andharness_session.rs(finding the id by a unique working directory).PtySessionManager. The session gets that path as itsPATH.claude-code,codex,antigravity,pi,opencode. The daemon'santigravity-cliandopen-codeare gone. A test reads the skill installer'sAgentNameand compares it withAgentType.Node type change
project, a flat core type (category unchanged).checkout_path, string, optional,local_only, user-editable. Wire namecheckoutPath. It is inProjectNodeand in the typed update (set and clear).components/node-types.md(theprojectsheet). The docs commit is local innodespace-docsand is pushed just beforebun run merge, as the node type sequence requires.Decisions to review
~/.nodespace/agent-sessions/<session id>/, as before. It is still never deleted. Launches for a project create nothing.session_idstays empty for them.agentvalues ofantigravity-clioropen-codeon existing chat nodes no longer match an agent. No migration, per the pre-release rule.Tests
packages/cli/tests/it/launched_session.rs: a daemon serving two databases launches a stand-inclaude(a shell script on a search path the test owns) in the second one. It asserts the working directory, that nothing is written there, the environment, thatnodespace node getwith no flags reads the second database, that the folder is remembered, and that two sessions in one project each record their own harness session id. With the database variable removed from the launch, two of the three tests fail.CLAUDE_CONFIG_DIR, the catalog and the CLI's arguments; the typed update ofcheckout_path; the launch form; and the plugin (claude plugin test, 39 passing, not part of the merge gate).bun run test:changedpasses on every tier;bun run quality:fixis clean.Not verified
Docs
nodespace-docs:architecture/agent-session.md,decisions/032-pty-agent-session-architecture.md(context-file, temp-directory and shim provisions marked as amended by ADR-093),components/node-types.md.🤖 Generated with Claude Code