From 3e8b40b592b3aeb9e32af4ec7110e0a6a0b2e060 Mon Sep 17 00:00:00 2001 From: Alex Lavaee Date: Sun, 18 Oct 2026 21:26:28 -0700 Subject: [PATCH] Upgrade Atomic to the stable 0.9.39 release The harness catalog now pins @bastani/atomic 0.9.39, and the lockfile resolves @bastani/atomic, @bastani/atomic-natives and @bastani/pi-ai at 0.9.39. Atomic 0.9.39 lets each SDK session choose its workflow journal through createAgentSession({ journal }). The atomic adapter used to set the process-wide ATOMIC_WORKFLOW_JOURNAL_PATH while it ran and restore it on shutdown, because that variable was the only way to move the journal. Each Planner session is now given the journal directly, at the same location, $XDG_STATE_HOME/chopin/atomic/workflows.sqlite, and the process environment is left unchanged. Atomic still reads ATOMIC_WORKFLOW_JOURNAL_PATH, so an operator who sets it still chooses the file: workflowJournal() returns that path when it is non-empty. The hosted-agent and self-hosting guides name the new version and describe the per-session journal. Assistant-model: Claude Opus 5.5 (fast) Assistant-workflow: inline (fast subagents) Assistant-verification: bun test (6198 pass, 21 skip, 0 fail), bun run types, bun run ci Assistant-verification: journal tests failed before the per-session wiring and pass after it Assistant-verification: docker build of the server image; container started healthy with HARNESS=atomic Assistant-verification: targeted bun run e2e (38 passed) Co-authored-by: Alex Lavaee --- apps/server/src/harness/atomic/adapter.ts | 12 ++++------- apps/server/src/harness/atomic/full.test.ts | 5 ++++- apps/server/src/harness/atomic/workspace.ts | 6 ++++-- apps/server/src/harness/harnesses.test.ts | 13 ++++++----- apps/server/src/harness/harnesses.ts | 2 +- bun.lock | 24 ++++++++++----------- docs/hosted-agent.md | 4 +++- docs/self-hosting.md | 5 +++-- package.json | 2 +- 9 files changed, 40 insertions(+), 33 deletions(-) diff --git a/apps/server/src/harness/atomic/adapter.ts b/apps/server/src/harness/atomic/adapter.ts index 65912288d..8845644c6 100644 --- a/apps/server/src/harness/atomic/adapter.ts +++ b/apps/server/src/harness/atomic/adapter.ts @@ -156,9 +156,9 @@ export type AtomicSettings = { extensions?: readonly string[]; /** * The SQLite file the workflows of Planner sessions are journaled in, in place - * of Atomic's default beside its agent directory. Atomic reads the journal - * location only from `ATOMIC_WORKFLOW_JOURNAL_PATH` and the on-disk settings, - * so the adapter sets that variable until it shuts down. + * of Atomic's default beside its agent directory. Each Planner session is given + * it through `createAgentSession({ journal })`, which takes precedence over + * `ATOMIC_WORKFLOW_JOURNAL_PATH`; the process environment is left unchanged. */ journal?: string; }; @@ -472,8 +472,6 @@ export function createAtomicAdapter( } let runtime: Promise | undefined; let open = new Set(); - let journal = process.env.ATOMIC_WORKFLOW_JOURNAL_PATH; - if (settings.journal) process.env.ATOMIC_WORKFLOW_JOURNAL_PATH = settings.journal; return { specificationVersion: "harness-v1", @@ -660,6 +658,7 @@ export function createAtomicAdapter( builtins: full ? undefined : BUILTINS_OFF, tools: full ? undefined : [...hostNames, ATOMIC_RESULT_TOOL_NAME], extensionBindings: full ? { humanInput: full.humanInput } : undefined, + journal: full && settings.journal ? { path: settings.journal } : undefined, customTools: turn.tools.map(hostTool), }); let session = created.session; @@ -838,9 +837,6 @@ export function createAtomicAdapter( async shutdown() { await Promise.allSettled([...open].map(session => session.doDestroy())); - if (!settings.journal) return; - if (journal === undefined) delete process.env.ATOMIC_WORKFLOW_JOURNAL_PATH; - else process.env.ATOMIC_WORKFLOW_JOURNAL_PATH = journal; }, }; } diff --git a/apps/server/src/harness/atomic/full.test.ts b/apps/server/src/harness/atomic/full.test.ts index 12765c1bc..4b9fe904a 100644 --- a/apps/server/src/harness/atomic/full.test.ts +++ b/apps/server/src/harness/atomic/full.test.ts @@ -320,6 +320,7 @@ export default workflow({ operator: await Bun.file(join(agentDir, "settings.json")).exists(), journal: await Bun.file(journal).exists(), defaultJournal: await Bun.file(join(root, "workflows", "journal.sqlite")).exists(), + environment: process.env.ATOMIC_WORKFLOW_JOURNAL_PATH, project: projectPackage ? await Bun.file(join(cwd, ".atomic", "settings.json")).text() : undefined, @@ -531,8 +532,10 @@ test( expect(stage.toolNames).toContain("write"); expect(stage.toolNames).not.toContain(ATOMIC_RESULT_TOOL_NAME); expect(stage.system).not.toContain("CHOPIN-INSTRUCTIONS-MARKER"); - // The run is journaled where Chopin chose, not in Atomic's default beside its agent directory. + // The run is journaled where Chopin chose, not in Atomic's default beside its agent directory, + // and through the session rather than the process-wide environment variable. expect(result.files).toMatchObject({ journal: true, defaultJournal: false }); + expect(result.files?.environment).toBeUndefined(); } finally { if (environment !== undefined) process.env.NODE_ENV = environment; await room.close(); diff --git a/apps/server/src/harness/atomic/workspace.ts b/apps/server/src/harness/atomic/workspace.ts index 79e49e141..9a8cc6a96 100644 --- a/apps/server/src/harness/atomic/workspace.ts +++ b/apps/server/src/harness/atomic/workspace.ts @@ -53,10 +53,12 @@ export function stateDirectory(): string { /** * Where Planner sessions journal their workflow runs. A run resumes only with * the journal and working directory it started with, so the journal lives - * beside the channel directories rather than in Atomic's own home. + * beside the channel directories rather than in Atomic's own home. An + * operator's non-empty `ATOMIC_WORKFLOW_JOURNAL_PATH` still names the file. */ export function workflowJournal(): string { - return join(stateDirectory(), "atomic", "workflows.sqlite"); + return process.env.ATOMIC_WORKFLOW_JOURNAL_PATH + || join(stateDirectory(), "atomic", "workflows.sqlite"); } /** diff --git a/apps/server/src/harness/harnesses.test.ts b/apps/server/src/harness/harnesses.test.ts index 297fc1a4d..b6bca700e 100644 --- a/apps/server/src/harness/harnesses.test.ts +++ b/apps/server/src/harness/harnesses.test.ts @@ -2,6 +2,7 @@ import { afterEach, expect, it } from "bun:test"; import { tmpdir } from "node:os"; import { join } from "node:path"; +import { workflowJournal } from "./atomic/workspace"; import { harnesses, harnessFor, registerCredential, shutdownHarnesses } from "./harnesses"; afterEach(shutdownHarnesses); @@ -60,20 +61,22 @@ it("journals Atomic workflow runs in Chopin's state directory unless the operato let state = join(tmpdir(), `chopin-state-${crypto.randomUUID()}`); let restore = (name: string, value: string | undefined) => value === undefined ? delete process.env[name] : process.env[name] = value; - let journal = (): string | undefined => process.env.ATOMIC_WORKFLOW_JOURNAL_PATH; try { process.env.XDG_STATE_HOME = state; delete process.env.ATOMIC_WORKFLOW_JOURNAL_PATH; - harnessFor({ harness: "atomic", harnessAuth: "ai-gateway", host: "0.0.0.0" }); if (process.platform === "linux") { - expect(journal()).toBe(join(state, "chopin", "atomic", "workflows.sqlite")); + expect(workflowJournal()).toBe(join(state, "chopin", "atomic", "workflows.sqlite")); } + // Each Planner session is given its journal; the process environment is left alone. + harnessFor({ harness: "atomic", harnessAuth: "ai-gateway", host: "0.0.0.0" }); + expect(process.env.ATOMIC_WORKFLOW_JOURNAL_PATH).toBeUndefined(); await shutdownHarnesses(); - expect(journal()).toBeUndefined(); process.env.ATOMIC_WORKFLOW_JOURNAL_PATH = "/srv/atomic/runs.sqlite"; + expect(workflowJournal()).toBe("/srv/atomic/runs.sqlite"); harnessFor({ harness: "atomic", harnessAuth: "ai-gateway", host: "0.0.0.0" }); - expect(journal()).toBe("/srv/atomic/runs.sqlite"); + await shutdownHarnesses(); + expect(process.env.ATOMIC_WORKFLOW_JOURNAL_PATH).toBe("/srv/atomic/runs.sqlite"); } finally { await shutdownHarnesses(); restore("XDG_STATE_HOME", previous.state); diff --git a/apps/server/src/harness/harnesses.ts b/apps/server/src/harness/harnesses.ts index 9aede6d57..67dc5149e 100644 --- a/apps/server/src/harness/harnesses.ts +++ b/apps/server/src/harness/harnesses.ts @@ -22,7 +22,7 @@ function createAtomicHarness( return createAtomicAdapter({ auth: settings.auth as AtomicAuthMode, extensions: settings.extensions, - journal: process.env.ATOMIC_WORKFLOW_JOURNAL_PATH || workflowJournal(), + journal: workflowJournal(), }); } diff --git a/bun.lock b/bun.lock index 5d0914a8f..c3f2b17a5 100644 --- a/bun.lock +++ b/bun.lock @@ -309,7 +309,7 @@ "@ai-sdk/harness": "1.0.146", "@ai-sdk/mcp": "2.0.72", "@ai-sdk/sandbox-just-bash": "1.0.146", - "@bastani/atomic": "0.9.38-alpha.9", + "@bastani/atomic": "0.9.39", "ai": "7.0.135", "typebox": "1.3.7", "zod": "4.4.3", @@ -450,27 +450,27 @@ "@base-ui/utils": ["@base-ui/utils@0.3.2", "", { "dependencies": { "@babel/runtime": "^7.29.2", "@floating-ui/utils": "^0.2.12", "reselect": "^5.2.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-oWy1aq/I2GmYjpl4PhEAhzflF8VPGKgZeq0xAWTbfD5KBWyxcN0ZP2+WHSUm/5Z6lVMBDLReLcoXwSYoRc/zNQ=="], - "@bastani/atomic": ["@bastani/atomic@0.9.38-alpha.9", "", { "dependencies": { "@bastani/atomic-natives": "0.9.38-alpha.9", "@bastani/pi-ai": "0.9.38-alpha.9", "@earendil-works/pi-agent-core": "1.3.0", "@earendil-works/pi-codemode": "1.3.0", "@earendil-works/pi-tui": "1.3.0", "@modelcontextprotocol/ext-apps": "^1.7.5", "@modelcontextprotocol/sdk": "1.32.1", "@mozilla/readability": "^0.6.0", "@silvia-odwyer/photon-node": "0.3.4", "@typesafe-ai/sdk": "0.6.0", "brace-expansion": "5.0.12", "chalk": "6.0.0", "cross-spawn": "7.0.6", "diff": "8.0.4", "glob": "13.0.6", "grok-mermaid": "0.2.3", "highlight.js": "10.7.3", "hosted-git-info": "9.0.3", "ignore": "7.0.8", "jiti": "2.7.0", "linkedom": "^0.18.13", "lru-cache": "11.5.3", "markit-ai": "0.5.3", "minimatch": "10.2.6", "open": "^11.0.1", "p-limit": "^7.3.2", "proper-lockfile": "4.1.2", "quickjs-wasi": "3.6.2", "semver": "7.8.5", "turndown": "^7.2.0", "typebox": "1.3.27", "undici": "8.10.2", "unpdf": "1.8.1", "yaml": "2.9.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalDependencies": { "@mariozechner/clipboard": "0.3.9" }, "bin": { "atomic": "dist/cli.js" } }, "sha512-6i8lc2intSDy5kP3/lqCcUDD8HlA+AUiayhMp8Qzmfs5IiYZB2GrbddmzAlHJ9Qr8rPTaanIC8y6Qnv8ID07sQ=="], + "@bastani/atomic": ["@bastani/atomic@0.9.39", "", { "dependencies": { "@bastani/atomic-natives": "0.9.39", "@bastani/pi-ai": "0.9.39", "@earendil-works/pi-agent-core": "1.3.0", "@earendil-works/pi-codemode": "1.3.0", "@earendil-works/pi-tui": "1.3.0", "@modelcontextprotocol/ext-apps": "^1.7.5", "@modelcontextprotocol/sdk": "1.32.1", "@mozilla/readability": "^0.6.0", "@silvia-odwyer/photon-node": "0.3.4", "@typesafe-ai/sdk": "0.6.0", "brace-expansion": "5.0.12", "chalk": "6.0.0", "cross-spawn": "7.0.6", "diff": "8.0.4", "glob": "13.0.6", "grok-mermaid": "0.2.3", "highlight.js": "10.7.3", "hosted-git-info": "9.0.3", "ignore": "7.0.8", "jiti": "2.7.0", "linkedom": "^0.18.13", "lru-cache": "11.5.3", "markit-ai": "0.5.3", "minimatch": "10.2.6", "open": "^11.0.1", "p-limit": "^7.3.2", "proper-lockfile": "4.1.2", "quickjs-wasi": "3.6.2", "semver": "7.8.5", "turndown": "^7.2.0", "typebox": "1.3.27", "undici": "8.10.2", "unpdf": "1.8.1", "yaml": "2.9.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalDependencies": { "@mariozechner/clipboard": "0.3.9" }, "bin": { "atomic": "dist/cli.js" } }, "sha512-H3y7cfb0aTrhGc9b3UrK0QEN+i7OEYbapbN5EmNDc75CUj7ATi+Ri+E+AzpGck+6eup5Ty7elCy/0sNXKrYbSg=="], - "@bastani/atomic-natives": ["@bastani/atomic-natives@0.9.38-alpha.9", "", { "optionalDependencies": { "@bastani/atomic-natives-darwin-arm64": "0.9.38-alpha.9", "@bastani/atomic-natives-darwin-x64": "0.9.38-alpha.9", "@bastani/atomic-natives-linux-arm64-gnu": "0.9.38-alpha.9", "@bastani/atomic-natives-linux-arm64-musl": "0.9.38-alpha.9", "@bastani/atomic-natives-linux-x64-gnu": "0.9.38-alpha.9", "@bastani/atomic-natives-linux-x64-musl": "0.9.38-alpha.9", "@bastani/atomic-natives-win32-arm64-msvc": "0.9.38-alpha.9", "@bastani/atomic-natives-win32-x64-msvc": "0.9.38-alpha.9" } }, "sha512-yN7eLytoNYRKmxm2HABjV1qMk70ey+NmQP7gEo5kmEwecOJIkPdLsnbRJs3l5KBIC9DUrP7/J/cFWJ9PIxr4Fg=="], + "@bastani/atomic-natives": ["@bastani/atomic-natives@0.9.39", "", { "optionalDependencies": { "@bastani/atomic-natives-darwin-arm64": "0.9.39", "@bastani/atomic-natives-darwin-x64": "0.9.39", "@bastani/atomic-natives-linux-arm64-gnu": "0.9.39", "@bastani/atomic-natives-linux-arm64-musl": "0.9.39", "@bastani/atomic-natives-linux-x64-gnu": "0.9.39", "@bastani/atomic-natives-linux-x64-musl": "0.9.39", "@bastani/atomic-natives-win32-arm64-msvc": "0.9.39", "@bastani/atomic-natives-win32-x64-msvc": "0.9.39" } }, "sha512-40juvjggMlCQHSsCHqKUnoa3jhTCrUWMJwjhdvKczpg82fQwwWcoMHHsUXEgh+TXh3gbWyYElpX/dZeQcfw4Vw=="], - "@bastani/atomic-natives-darwin-arm64": ["@bastani/atomic-natives-darwin-arm64@0.9.38-alpha.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-r3YA8iXAGp+QsxQeTPJHFFCFMqL34lHjg5bXGWWeVN8qQdxt54yvk1QPfe1DplhnIXhYrDNbNtXTmzQAo1ShvQ=="], + "@bastani/atomic-natives-darwin-arm64": ["@bastani/atomic-natives-darwin-arm64@0.9.39", "", { "os": "darwin", "cpu": "arm64" }, "sha512-M59UUF0SEmET2etrKoSJMcbq/lWsLP3wolSqhLGA56oVQFD6XqiF6gx1VOn0KEsk0cD4psB3MUvW70DCYlRNjw=="], - "@bastani/atomic-natives-darwin-x64": ["@bastani/atomic-natives-darwin-x64@0.9.38-alpha.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-cBQByncHUKUaJUNTHIutK8J5Z2MX9jAw/EFIy6NldxdbIc4WStjXqwRoAbiRArzGRpLO7uCqPCmi3iKatXF2fQ=="], + "@bastani/atomic-natives-darwin-x64": ["@bastani/atomic-natives-darwin-x64@0.9.39", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYWzmUqii1vL1eyOgQf6mvIDHGe25/XCszMqrnyqTuBsABKUp2SAZbfZ6CqbbVTIbOAwJUm82X1o2FKC+CMqow=="], - "@bastani/atomic-natives-linux-arm64-gnu": ["@bastani/atomic-natives-linux-arm64-gnu@0.9.38-alpha.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-yOvXM7qSSIb8YX0eDDyXxvHV0CbiPFh/KE/CPBkpfyVE+538tLQpQb3pQHTNcDFbhNl4evZivHSoNk4QYhrujQ=="], + "@bastani/atomic-natives-linux-arm64-gnu": ["@bastani/atomic-natives-linux-arm64-gnu@0.9.39", "", { "os": "linux", "cpu": "arm64" }, "sha512-6HSW145Dzhe19zJRSeogISuCUi9cVqRnEItWPd2YbOOT/bFu5BS3VU81OtfGCFnkLyyZB6ovmfhaO4woOBNuLw=="], - "@bastani/atomic-natives-linux-arm64-musl": ["@bastani/atomic-natives-linux-arm64-musl@0.9.38-alpha.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-VQyhpKNLwxHMY1xUQFetLTRi1BayqQ7C4sVpYpwB38rNltInufLhjbbK6XwIVYq1OrkIFccIqwbKuFUGHKGzFw=="], + "@bastani/atomic-natives-linux-arm64-musl": ["@bastani/atomic-natives-linux-arm64-musl@0.9.39", "", { "os": "linux", "cpu": "arm64" }, "sha512-FxXJS8QWO2giy8YGxUYopUW7Q9OeyHFGryASpOLouirasaOwpaNOeMXsZCN3rXd3b6dkfJrcVRYw+pCih8w0Mw=="], - "@bastani/atomic-natives-linux-x64-gnu": ["@bastani/atomic-natives-linux-x64-gnu@0.9.38-alpha.9", "", { "os": "linux", "cpu": "x64" }, "sha512-4JGo4I8stKgAXWudGKwJNMgzeO6ZJBjTHW5odcNWKnn2rQIpjhZGBSCq5sJpEcYOJD1JGUJ+iZs2KvyIPKXARg=="], + "@bastani/atomic-natives-linux-x64-gnu": ["@bastani/atomic-natives-linux-x64-gnu@0.9.39", "", { "os": "linux", "cpu": "x64" }, "sha512-9gvfFYDxWgZRWDf+bo9IXGZimGnEaQ/bJ5gCB6KTJRxc2OF4tpUYUrQlt+JRR3HaziHVbGneI0E74mZziPZRCQ=="], - "@bastani/atomic-natives-linux-x64-musl": ["@bastani/atomic-natives-linux-x64-musl@0.9.38-alpha.9", "", { "os": "linux", "cpu": "x64" }, "sha512-jtetHCxqz4GaBz/+3R4PWlX178snWWI/7PwxzEqUpONbJBMCA/JolYSXa9YZLm9VA8kRndW2DxIMVr0cRxy+Lg=="], + "@bastani/atomic-natives-linux-x64-musl": ["@bastani/atomic-natives-linux-x64-musl@0.9.39", "", { "os": "linux", "cpu": "x64" }, "sha512-yIrNUcZVi1UAm4nEK+u+CTskYatU3FIMJg262Ebiu+vyCi+YgqkfMjIZ/pOc0+80i0JotNCFSl94kaw6Qy2d0w=="], - "@bastani/atomic-natives-win32-arm64-msvc": ["@bastani/atomic-natives-win32-arm64-msvc@0.9.38-alpha.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-CTMtzHbHtdRwJ0dnHyy/ZK9m+89LYGIPUBp2Ee4ydREgtc4tlLsWW3iFpx20/tTOisQPieuTz7uZ0ze4CIoKZw=="], + "@bastani/atomic-natives-win32-arm64-msvc": ["@bastani/atomic-natives-win32-arm64-msvc@0.9.39", "", { "os": "win32", "cpu": "arm64" }, "sha512-JtZ34FBgEBOvDZzG6NP5GVJxpTMTwVjTTi4aa0TcCFGQy+s1igqVapoin/646KUWJQfZhCxBWMZqTgf1r7kpPw=="], - "@bastani/atomic-natives-win32-x64-msvc": ["@bastani/atomic-natives-win32-x64-msvc@0.9.38-alpha.9", "", { "os": "win32", "cpu": "x64" }, "sha512-AbTr4sCS3BdxUMWoiWq8XFKvPH2AtHf222sr+vZMsTQ9wB/eILdv/wPy38+gB66HOWf5OTUyCPvDNrGeVtV4oQ=="], + "@bastani/atomic-natives-win32-x64-msvc": ["@bastani/atomic-natives-win32-x64-msvc@0.9.39", "", { "os": "win32", "cpu": "x64" }, "sha512-X8jczUdnorN5lsFyMwoQCI/u/LvzxcsdQge9r//AwDQdW56QaNqhimuP1yv5OMPsWdf5Q8RD5iGctchg0PzXTQ=="], - "@bastani/pi-ai": ["@bastani/pi-ai@0.9.38-alpha.9", "", { "dependencies": { "@anthropic-ai/sdk": "0.129.0", "@aws-sdk/client-bedrock-runtime": "3.1127.0", "@earendil-works/pi-telemetry": "1.3.0", "@google/genai": "2.21.0", "@smithy/node-http-handler": "4.12.1", "http-proxy-agent": "9.1.0", "https-proxy-agent": "9.1.0", "openai": "7.19.0", "partial-json": "0.1.7", "typebox": "1.3.27" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-pVnnc3AlV3PXNZrQCPrmIPgrIrHvFT/CQnA/ok3HUM74/BugfYGRPMZSj1XQQYb5ZZDTGnBZygoLQ3+DPsOkSA=="], + "@bastani/pi-ai": ["@bastani/pi-ai@0.9.39", "", { "dependencies": { "@anthropic-ai/sdk": "0.129.0", "@aws-sdk/client-bedrock-runtime": "3.1127.0", "@earendil-works/pi-telemetry": "1.3.0", "@google/genai": "2.21.0", "@smithy/node-http-handler": "4.12.1", "http-proxy-agent": "9.1.0", "https-proxy-agent": "9.1.0", "openai": "7.19.0", "partial-json": "0.1.7", "typebox": "1.3.27" }, "bin": { "pi-ai": "dist/cli.js" } }, "sha512-NY4dYidvG3OP6L16/1xkjtYaGeWK0/FVm7WPW3BHVOHpVCfCKTeAB57vEuGduG3e7g/XLIUgz4NjQYqatjPE1A=="], "@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], diff --git a/docs/hosted-agent.md b/docs/hosted-agent.md index ac5d23f88..d30206579 100644 --- a/docs/hosted-agent.md +++ b/docs/hosted-agent.md @@ -612,7 +612,9 @@ workflow journal, so runs interrupted that way can be resumed from a later session. Chopin keeps that journal at `$XDG_STATE_HOME/chopin/atomic/workflows.sqlite` under the same per-user state directory as the documents' own directories, because a run resumes only with -the journal and working directory it started in. A non-empty +the journal and working directory it started in. Each Planner session is +given that file through Atomic's `createAgentSession({ journal })`, so the +server's process environment is left unchanged. An operator's non-empty `ATOMIC_WORKFLOW_JOURNAL_PATH` names another file instead; Atomic's `workflows.journal` setting is not used for Planner sessions. A Build is not a workflow run and has no card in Chat: its tasks, their state and pull requests show under **Build**, whichever machine runs it. The diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 0d7eabe3e..4a7a22365 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -75,7 +75,7 @@ each owner's GitHub App user token and does not consume `HARNESS_AUTH`; setting `auto` on loopback passes the startup guard but does not enable host login in that adapter. -`HARNESS=atomic` runs Atomic 0.9.38-alpha.9 in the Chopin server process through its +`HARNESS=atomic` runs Atomic 0.9.39 in the Chopin server process through its headless SDK (`createAgentSession()`). It does not spawn the `atomic` CLI or use RPC mode. @@ -152,7 +152,8 @@ Atomic caveats: x64, including glibc and musl native modules. Expect a larger image. - Atomic workflows need no database server. Their runs are journaled in a SQLite file, `$XDG_STATE_HOME/chopin/atomic/workflows.sqlite`, beside the - documents' Planner directories (see + documents' Planner directories, which Chopin passes to each Planner session + as its `journal` rather than through the process environment (see [Full Atomic Planner](hosted-agent.md#full-atomic-planner)). The Docker image sets `XDG_STATE_HOME=/var/lib/chopin`; mount a volume there to keep runs and those directories when the container is replaced. diff --git a/package.json b/package.json index 3567a2541..cddac5fc3 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@ai-sdk/harness": "1.0.146", "@ai-sdk/mcp": "2.0.72", "@ai-sdk/sandbox-just-bash": "1.0.146", - "@bastani/atomic": "0.9.38-alpha.9", + "@bastani/atomic": "0.9.39", "ai": "7.0.135", "typebox": "1.3.7", "zod": "4.4.3"