mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-10 12:37:55 +01:00
fix(runner): name the local app-server process in Codex session start
Local Codex and OpenCode (through the app-server proxy, which keeps opencode serve in its process group) run behind the Codex app-server driver. Its session.started carried no process identity, so the control plane's stop proof never checked that process. Emit its pid, process group and OS start time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
22fb7a67e2
commit
da14022655
2 files changed
+19
No files matched your search
@@ -311,6 +311,17 @@ describe("Codex app-server Codex driver", () => {
|
||||
expect(transport.calls[0]?.method).toBe("initialize");
|
||||
});
|
||||
|
||||
it("names the local app-server process in session.started for the control plane's stop proof", async () => {
|
||||
const transport = new FakeCodexTransport();
|
||||
Object.assign(transport, {
|
||||
processInfo: () => ({ pid: process.pid, processGroupId: null, startedAt: "2026-08-18T18:00:00.000Z", exited: false, exitCode: null, signal: null }),
|
||||
});
|
||||
const session = await makeDriver([transport]).openSession({ runId: "run-identity", normalizedSessionId: "normalized-identity", workingDirectory: WORKSPACE });
|
||||
const started = await session.events()[Symbol.asyncIterator]().next();
|
||||
expect(started.value).toMatchObject({ eventType: "session.started",
|
||||
payload: { processId: process.pid, processGroupId: null, processStartedAt: expect.stringMatching(/^\d{4}-\d{2}-\d{2}T/) } });
|
||||
});
|
||||
|
||||
it("persists process ownership after a lazy transport launches during session open", async () => {
|
||||
const transport = new FakeCodexTransport();
|
||||
Object.assign(transport, {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { type CodexUsageBaseline, codexRunUsage } from "./codex-usage-baseline.js";
|
||||
import { readLocalProcessStartedAt } from "../../live/linux-process-start.js";
|
||||
import type { ProviderRateLimitSnapshot } from "../provider-rate-limits.js";
|
||||
import { workspaceRootsFor } from "../../tool-file-changes.js";
|
||||
import type {
|
||||
@@ -626,9 +627,16 @@ export function initializeCodexSessionEvents(
|
||||
state: CodexSessionState,
|
||||
input: CodexSessionStateInput,
|
||||
): void {
|
||||
// Name the local app-server process (Codex, or the OpenCode proxy that owns `opencode serve`
|
||||
// in its process group) so the control plane's stop proof can verify that exact process exited.
|
||||
const processInfo = state.transport.processInfo?.();
|
||||
const processIdentity = processInfo && !processInfo.exited && processInfo.pid !== null
|
||||
? { processId: processInfo.pid, processGroupId: processInfo.processGroupId, processStartedAt: readLocalProcessStartedAt(processInfo.pid) }
|
||||
: {};
|
||||
state.emit(input.resumed ? "session.resumed" : "session.started", {
|
||||
driverSessionId: input.opened.threadId,
|
||||
providerSessionId: input.opened.providerSessionId,
|
||||
...processIdentity,
|
||||
context: input.opened.context,
|
||||
});
|
||||
state.emitGoalCapabilities();
|
||||
|
||||
Reference in new issue
Block a user