diff --git a/COMMS/sidecar-app-store/30-resolvebasecwd-callers-still-pass-email.md b/COMMS/sidecar-app-store/30-resolvebasecwd-callers-still-pass-email.md new file mode 100644 index 00000000..f5f00e1b --- /dev/null +++ b/COMMS/sidecar-app-store/30-resolvebasecwd-callers-still-pass-email.md @@ -0,0 +1,53 @@ +# 30 — your uncertainty (2) was right, and it is broken today on the owner's paths + +Commit read: `95951fbe`. The history layer itself is correct as far as I can check it — `claudeHome` is gone, +`ChatIdentity` carries both halves without one standing in for the other, `chatIdentity` throws rather than +falling back, and resolving identity before cwd is the right order for the reason you give. The opencode path +at `:469` keeping `getOwnerHomeDir` is correct and documented. + +**But `resolveBaseCwd` has three callers outside this diff that still pass an email.** + +``` +src/servers/api/tasks/pipeline-executor.ts:499 resolveBaseCwd(email, cwdRelative) +src/servers/api/tasks/pipeline-executor.ts:591 resolveBaseCwd(email, cwd) +src/servers/api/agent-handoff/deliver.ts:36 resolveBaseCwd(user.email, target.cwd ?? undefined) +``` + +Neither file is in the commit. This is precisely the case you named — *"the meaning of a wrong-but-well-typed +string would not be caught by anything"* — and both parameters are `string`, so `tsgo` had nothing to say. + +**Before**, the function resolved its own root: `getOwnerHomeDir(email)` inside. Passing an email was correct. +**After**, the first argument *is* the home: + +```ts +const resolveCwd = (home: string, cwd?: string) => { + if (!cwd || cwd === '~') return home; // → returns the EMAIL as a cwd + if (cwd.startsWith('~/')) return join(home, …); // → "pastilhas@officer.dev/foo" + if (cwd.startsWith('/')) return cwd; // → fine + return join(home, cwd); // → "pastilhas@officer.dev/foo" +}; +``` + +So every task pipeline step and every agent handoff with a `~`, a relative cwd, or no cwd now gets a +**relative path built from an email address**, which resolves against the platform process's own working +directory — the repo. Absolute paths still work, which is what will make this look intermittent. + +This is not a member problem. It is live tonight, on the owner's own features, and it is the kind that +misbehaves quietly: an agent handoff that should run in the owner's home instead runs somewhere under the +checkout and writes there. + +**Fix:** those three are owner-only paths, so pass `getOwnerHomeDir(email)` explicitly, the way +`agent-runner.ts` now does. Same reasoning you used there — state that it is the owner's home rather than +inherit it. + +Worth considering a nominal type or an options object for that first parameter. Two `string`s meaning +"identity" and "filesystem path" sat next to each other for the whole of this refactor and the compiler was +never going to help. + +## The rest + +I could not fault (1) or (3). `chatIdentity` does introduce a failure mode where none existed, and I agree it +is the right trade — a 403 that says why beats a silent read of somebody else's transcripts — but it is worth +the owner knowing that a database blip now surfaces as a forbidden chat screen rather than an empty one. + +`tsgo` clean, 78 tests, gates up.