wire the member branch into the SDK spawn, still unreachable
ClaudeSpawnStreamingParams takes an optional member {osUser, home}; createSession
branches on it, using their binary and spawnClaudeAsMember together, or the
owner's CLAUDE_BIN as before.
THE BINARY AND THE PRIVILEGE DROP ARE ONE BRANCH ON PURPOSE. settingSources
makes ~/.claude authoritative for settings and ~ is whatever HOME the process
gets, so pointing the SDK at a member's binary while spawning as the service
user would read the OWNER'S settings and credential while running the member's
code — and it would look like it worked.
cwd defaults to member.home before HOST_HOME for the same reason: HOST_HOME is
this process's home, so a member would start in a directory they cannot read and
the failure would present as a broken agent rather than a wrong cwd.
Nothing populates `member`. Both gates refuse non-owners before any of this is
reached, so the delta is that spawnClaudeAsMember now has two importers instead
of one, and neither path a user can take changes. Verified rather than assumed,
since host made it a condition: both gates intact, 84 tests pass.
Not authorization: host gave an opinion on wire-first and deferred to the owner,
who has not ruled. Corrected in COMMS, where 01 had overstated it. The gates
come off on the owner's word alone; this reverts as one commit if the answer is
no.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -181,6 +181,16 @@ export type ClaudeSpawnStreamingParams = {
|
||||
// it — that is what survives an officer restart. A pipeline step does not: its sessionKey is a throwaway
|
||||
// uuid no browser will ever replay, and the job's own event log is its record.
|
||||
durable?: boolean;
|
||||
// Run this turn as a member's own Linux account, with their `claude` and their credential.
|
||||
//
|
||||
// Absent means the owner, which is every caller today: `api/chat/chat.ts` and the socket in `server.tsx`
|
||||
// both refuse non-owners, so nothing can currently populate this. That is deliberate — the field exists so
|
||||
// the sidecar side is testable and reviewable before the gates come off, not because anything sets it yet.
|
||||
//
|
||||
// Resolved by the platform from `resolveHomeDir`, NEVER taken from a client. Same rule as the pty sidecar,
|
||||
// where `server.tsx` deletes any client-supplied `osUser`/`home` from the query string before setting its
|
||||
// own — a member's identity is not a parameter they get to choose.
|
||||
member?: { osUser: string; home: string };
|
||||
};
|
||||
|
||||
export type ClaudeCodeResult = {
|
||||
|
||||
Reference in New Issue
Block a user