@elpapi42/pi-fleet 0.1.0-beta.10 → 0.1.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -1
- package/README.md +99 -167
- package/dist/cli-meta.json +313 -315
- package/dist/cli.mjs +2504 -1812
- package/dist/cli.mjs.map +4 -4
- package/dist/client/agent-target.d.ts +33 -0
- package/dist/client/contracts.d.ts +81 -0
- package/dist/client/fleet-client.d.ts +118 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/sdk-connector.d.ts +7 -0
- package/dist/client/sdk-facade.d.ts +84 -0
- package/dist/client/sdk-transport.d.ts +24 -0
- package/dist/client/shared-client.d.ts +18 -0
- package/dist/client/socket-fleet-client.d.ts +21 -0
- package/dist/client-meta.json +5736 -0
- package/dist/client.mjs +4434 -0
- package/dist/client.mjs.map +7 -0
- package/dist/installer-meta.json +7 -7
- package/dist/installer.mjs +47 -13
- package/dist/installer.mjs.map +2 -2
- package/dist/journal-sqlite-worker-meta.json +149 -0
- package/dist/journal-sqlite-worker.mjs +1110 -0
- package/dist/journal-sqlite-worker.mjs.map +7 -0
- package/dist/pi/external-installation.d.ts +23 -0
- package/dist/platform/client/start-runtime.d.ts +25 -0
- package/dist/platform/install/runtime-release.d.ts +8 -0
- package/dist/platform/install/tree-integrity.d.ts +7 -0
- package/dist/platform/shared/paths.d.ts +8 -0
- package/dist/platform/shared/runtime-ownership.d.ts +14 -0
- package/dist/protocol/jsonl.d.ts +3 -0
- package/dist/protocol/pi-identity.d.ts +16 -0
- package/dist/protocol/semantic-segmentation.d.ts +22 -0
- package/dist/protocol/version.d.ts +2 -0
- package/dist/runtime/semantic-events.d.ts +43 -0
- package/dist/runtime-manifest.json +156 -31
- package/dist/runtime-meta.json +378 -53
- package/dist/runtime.mjs +3161 -581
- package/dist/runtime.mjs.map +4 -4
- package/dist/shared/result.d.ts +9 -0
- package/package.json +14 -1
- package/dist/sqlite-worker-meta.json +0 -84
- package/dist/sqlite-worker.mjs +0 -359
- package/dist/sqlite-worker.mjs.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/store/journal-sqlite-worker.ts", "../src/store/journal-worker-dispatch.ts", "../src/store/sqlite-journal-store.ts", "../src/platform/shared/state-security.ts", "../src/store/journal-store.ts"],
|
|
4
|
+
"sourcesContent": ["import { parentPort, workerData } from \"node:worker_threads\";\n\nimport { dispatchJournalStoreRequest } from \"./journal-worker-dispatch.js\";\nimport type { JournalWorkerRequest } from \"./journal-worker-protocol.js\";\nimport { SqliteJournalStore } from \"./sqlite-journal-store.js\";\n\nconst port = parentPort;\nif (port === null) throw new Error(\"Journal SQLite worker requires a parent port\");\nconst options = workerData as {\n readonly path?: unknown;\n readonly checkpointCommitInterval?: unknown;\n readonly reclaimPagesPerPass?: unknown;\n};\nif (typeof options.path !== \"string\") {\n throw new Error(\"Journal SQLite worker requires a database path\");\n}\nif (\n typeof options.checkpointCommitInterval !== \"number\" ||\n typeof options.reclaimPagesPerPass !== \"number\"\n) {\n throw new Error(\"Journal SQLite worker requires maintenance limits\");\n}\nconst store = new SqliteJournalStore(options.path, {\n checkpointCommitInterval: options.checkpointCommitInterval,\n reclaimPagesPerPass: options.reclaimPagesPerPass,\n});\n\nport.on(\"message\", (request: JournalWorkerRequest) => {\n void dispatchJournalStoreRequest(store, request)\n .then((value) => port.postMessage({ id: request.id, ok: true, value }))\n .catch((error: unknown) =>\n port.postMessage({\n id: request.id,\n ok: false,\n error: error instanceof Error ? error.message : \"Journal SQLite worker failed\",\n }),\n );\n});\n", "import type {\n AgentId,\n ContinuityEpoch,\n IncarnationId,\n ProjectorState,\n} from \"../runtime/semantic-events.js\";\nimport type {\n JournalAgent,\n JournalAppend,\n JournalCompact,\n JournalDestroyReceipt,\n JournalEpoch,\n JournalEventRange,\n JournalIncarnation,\n JournalOperation,\n JournalSend,\n JournalStore,\n} from \"./journal-store.js\";\nimport type { JournalWorkerRequest } from \"./journal-worker-protocol.js\";\n\nexport async function dispatchJournalStoreRequest(\n store: JournalStore,\n request: JournalWorkerRequest,\n): Promise<unknown> {\n switch (request.method) {\n case \"createAgent\":\n return store.createAgent(request.args[0] as JournalAgent);\n case \"createAgentWithOperation\":\n return store.createAgentWithOperation(\n request.args[0] as JournalAgent,\n request.args[1] as JournalOperation,\n );\n case \"rollbackProvisionalCreate\":\n return store.rollbackProvisionalCreate(\n request.args[0] as AgentId,\n request.args[1] as JournalOperation,\n );\n case \"getAgentByName\":\n return store.getAgentByName(request.args[0] as string);\n case \"getAgentById\":\n return store.getAgentById(request.args[0] as AgentId);\n case \"listAgents\":\n return store.listAgents();\n case \"putAgent\":\n return store.putAgent(request.args[0] as JournalAgent);\n case \"putOperation\":\n return store.putOperation(request.args[0] as JournalOperation);\n case \"getOperation\":\n return store.getOperation(request.args[0] as string);\n case \"listPendingOperations\":\n return store.listPendingOperations();\n case \"deleteOperation\":\n return store.deleteOperation(request.args[0] as string);\n case \"putSend\":\n return store.putSend(request.args[0] as JournalSend);\n case \"getSend\":\n return store.getSend(request.args[0] as string);\n case \"nextSendOrdinal\":\n return store.nextSendOrdinal(request.args[0] as AgentId);\n case \"listNonterminalSends\":\n return store.listNonterminalSends();\n case \"putCompact\":\n return store.putCompact(request.args[0] as JournalCompact);\n case \"getCompact\":\n return store.getCompact(request.args[0] as string);\n case \"listNonterminalCompacts\":\n return store.listNonterminalCompacts();\n case \"putIncarnation\":\n return store.putIncarnation(request.args[0] as JournalIncarnation);\n case \"listActiveIncarnations\":\n return store.listActiveIncarnations();\n case \"putEpoch\":\n return store.putEpoch(request.args[0] as JournalEpoch);\n case \"getEpochs\":\n return store.getEpochs(request.args[0] as AgentId);\n case \"beginIncarnation\":\n return store.beginIncarnation(\n request.args[0] as AgentId,\n request.args[1] as IncarnationId,\n request.args[2] as ContinuityEpoch,\n request.args[3] as ProjectorState,\n );\n case \"append\":\n return store.append(normalizeAppend(request.args[0]));\n case \"openReceive\":\n return store.openReceive(request.args[0] as AgentId);\n case \"readEvents\":\n return store.readEvents(request.args[0] as JournalEventRange);\n case \"getProjectorState\":\n return store.getProjectorState(\n request.args[0] as AgentId,\n request.args[1] as IncarnationId,\n request.args[2] as ContinuityEpoch,\n );\n case \"getHighWater\":\n return store.getHighWater(request.args[0] as AgentId);\n case \"markIdle\":\n return store.markIdle(request.args[0] as AgentId, request.args[1] as ContinuityEpoch);\n case \"getRawRecords\":\n return store.getRawRecords(\n request.args[0] as AgentId,\n request.args[1] as number,\n request.args[2] as number,\n );\n case \"destroyAgent\":\n return store.destroyAgent(\n request.args[0] as AgentId,\n request.args[1] as JournalDestroyReceipt,\n );\n case \"getDestroyReceipt\":\n return store.getDestroyReceipt(request.args[0] as string);\n case \"maintain\":\n return store.maintain(request.args[0] as number | undefined);\n case \"getDiagnostics\":\n return store.getDiagnostics();\n case \"close\":\n return store.close();\n default:\n throw new Error(`Unknown journal worker method ${request.method}`);\n }\n}\n\nfunction normalizeAppend(value: unknown): JournalAppend {\n const batch = value as JournalAppend;\n return {\n ...batch,\n records: batch.records.map((record) => ({ ...record, bytes: Buffer.from(record.bytes) })),\n };\n}\n", "import { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { DatabaseSync } from \"node:sqlite\";\n\nimport {\n hardenPrivateDirectorySync,\n hardenSqliteSidecarsSync,\n} from \"../platform/shared/state-security.js\";\nimport type {\n AgentId,\n ContinuityEpoch,\n IncarnationId,\n ProjectorState,\n RawRpcRecord,\n} from \"../runtime/semantic-events.js\";\nimport {\n assertJournalAgentIdentity,\n assertJournalAppend,\n boundedSemanticEvents,\n sameJournalDestroyReceipt,\n} from \"./journal-store.js\";\nimport type {\n JournalAgent,\n JournalAppend,\n JournalCompact,\n JournalDestroyReceipt,\n JournalEpoch,\n JournalEventRange,\n JournalHighWater,\n JournalIncarnation,\n JournalMaintenanceResult,\n JournalOperation,\n JournalReceiveSnapshot,\n JournalSend,\n JournalStorageDiagnostics,\n JournalStore,\n StoredSemanticEvent,\n} from \"./journal-store.js\";\n\nexport const JOURNAL_SCHEMA_VERSION = 3;\nexport const JOURNAL_SCHEMA_CHECKSUM = \"003_uuid_journal_v3\";\nexport const LEGACY_JOURNAL_SCHEMA_CHECKSUMS = new Map([\n [1, \"001_initial_v1\"],\n [2, \"002_compact_v1\"],\n]);\n\nexport interface JournalMigrationRow {\n readonly version: number;\n readonly checksum: string;\n}\n\nexport type JournalMigrationState = \"fresh\" | \"legacy\" | \"current\";\n\nexport function classifyJournalMigrationRows(\n rows: readonly JournalMigrationRow[],\n): JournalMigrationState {\n if (rows.length === 0) return \"fresh\";\n for (const row of rows) {\n if (!Number.isSafeInteger(row.version) || typeof row.checksum !== \"string\") {\n throw new Error(\"pi-fleet database migration ledger is malformed\");\n }\n }\n if (rows.length === 1 && rows[0]?.version === JOURNAL_SCHEMA_VERSION) {\n if (rows[0].checksum !== JOURNAL_SCHEMA_CHECKSUM) {\n throw new Error(\n `pi-fleet database migration ${String(JOURNAL_SCHEMA_VERSION)} checksum mismatch`,\n );\n }\n return \"current\";\n }\n const legacyOne = rows.length === 1 && rows[0]?.version === 1;\n const legacyTwo = rows.length === 2 && rows[0]?.version === 1 && rows[1]?.version === 2;\n if (legacyOne || legacyTwo) {\n for (const row of rows) {\n if (LEGACY_JOURNAL_SCHEMA_CHECKSUMS.get(row.version) !== row.checksum) {\n throw new Error(`pi-fleet database migration ${String(row.version)} checksum mismatch`);\n }\n }\n return \"legacy\";\n }\n const newer = rows.find((row) => row.version > JOURNAL_SCHEMA_VERSION);\n if (newer !== undefined) {\n throw new Error(`pi-fleet database schema ${String(newer.version)} is newer than this runtime`);\n }\n throw new Error(\"pi-fleet database migration ledger sequence is invalid\");\n}\n\ninterface JsonRow {\n readonly data_json: string;\n}\n\nfunction* parseSemanticEventRows(rows: Iterable<JsonRow>): Iterable<StoredSemanticEvent> {\n for (const row of rows) yield JSON.parse(row.data_json) as StoredSemanticEvent;\n}\n\nexport interface SqliteJournalStoreOptions {\n readonly checkpointCommitInterval?: number;\n readonly reclaimPagesPerPass?: number;\n readonly now?: () => string;\n}\n\nconst idleMaintenance = (): JournalMaintenanceResult => ({\n state: \"idle\",\n lastCheckpointAt: null,\n busy: false,\n logFrames: 0,\n checkpointedFrames: 0,\n autoVacuumMode: \"none\",\n freelistPagesBefore: 0,\n freelistPagesAfter: 0,\n requestedReclaimPages: 0,\n});\n\nexport class SqliteJournalStore implements JournalStore {\n readonly #database: DatabaseSync;\n readonly #checkpointCommitInterval: number;\n readonly #reclaimPagesPerPass: number;\n readonly #now: () => string;\n #commitsSinceCheckpoint = 0;\n #lastAppendDurationMs: number | null = null;\n #storageFailureLatched = false;\n #maintenance = idleMaintenance();\n #closed = false;\n\n constructor(path: string, options: SqliteJournalStoreOptions = {}) {\n const directory = dirname(path);\n mkdirSync(directory, { recursive: true, mode: 0o700 });\n hardenPrivateDirectorySync(directory);\n hardenSqliteSidecarsSync(path);\n this.#checkpointCommitInterval = positiveInteger(\n options.checkpointCommitInterval ?? 128,\n \"Journal checkpoint commit interval\",\n );\n this.#reclaimPagesPerPass = positiveInteger(\n options.reclaimPagesPerPass ?? 32,\n \"Journal reclaim pages per pass\",\n );\n this.#now = options.now ?? (() => new Date().toISOString());\n this.#database = new DatabaseSync(path);\n this.#database.exec(\n \"PRAGMA auto_vacuum=INCREMENTAL; PRAGMA foreign_keys=ON; PRAGMA journal_mode=WAL; PRAGMA synchronous=FULL;\",\n );\n hardenSqliteSidecarsSync(path);\n try {\n const integrity = this.#database.prepare(\"PRAGMA quick_check\").get() as\n | { quick_check?: string }\n | undefined;\n if (integrity?.quick_check !== \"ok\") throw new Error(\"pi-fleet database quick_check failed\");\n this.#migrate();\n this.#database\n .prepare(\n \"UPDATE journal_runtime_health SET clean_shutdown = 0, started_at = ? WHERE singleton_key = 1\",\n )\n .run(new Date().toISOString());\n } catch (error: unknown) {\n this.#database.close();\n this.#closed = true;\n throw error;\n }\n }\n\n async createAgent(agent: JournalAgent): Promise<boolean> {\n this.#assertOpen();\n assertJournalAgentIdentity(agent);\n const result = this.#database\n .prepare(\"INSERT OR IGNORE INTO journal_agents(agent_id, name, data_json) VALUES(?, ?, ?)\")\n .run(agent.agentId, agent.name, JSON.stringify(agent));\n return result.changes === 1;\n }\n\n async createAgentWithOperation(\n agent: JournalAgent,\n operation: JournalOperation,\n ): Promise<boolean> {\n this.#assertOpen();\n assertJournalAgentIdentity(agent);\n if (operation.agentId !== agent.agentId || operation.targetName !== agent.name) {\n throw new Error(\"Create operation does not target the provisional agent\");\n }\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n const existing = await this.getOperation(operation.operationId);\n if (\n existing !== null &&\n (existing.method !== operation.method ||\n existing.fingerprint !== operation.fingerprint ||\n (existing.agentId !== null && existing.agentId !== agent.agentId))\n ) {\n throw new Error(\"Operation was already used with a different request\");\n }\n const created =\n this.#database\n .prepare(\n \"INSERT OR IGNORE INTO journal_agents(agent_id, name, data_json) VALUES(?, ?, ?)\",\n )\n .run(agent.agentId, agent.name, JSON.stringify(agent)).changes === 1;\n if (created) this.#putOperationSync(operation);\n this.#database.exec(\"COMMIT\");\n return created;\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n }\n\n async rollbackProvisionalCreate(\n agentId: AgentId,\n completedOperation: JournalOperation,\n ): Promise<JournalAgent | null> {\n this.#assertOpen();\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n const existing = await this.getAgentById(agentId);\n const pending = await this.getOperation(completedOperation.operationId);\n if (existing === null) {\n this.#database.exec(\"ROLLBACK\");\n return null;\n }\n if (\n pending === null ||\n pending.method !== \"create\" ||\n pending.state !== \"pending\" ||\n pending.agentId !== agentId ||\n pending.targetName !== existing.name ||\n completedOperation.method !== \"create\" ||\n completedOperation.state !== \"completed\" ||\n completedOperation.agentId !== null ||\n completedOperation.targetName !== existing.name ||\n completedOperation.fingerprint !== pending.fingerprint\n ) {\n throw new Error(\"Provisional create rollback does not match the pending operation\");\n }\n this.#database\n .prepare(\"DELETE FROM journal_operations WHERE agent_id = ? AND operation_id <> ?\")\n .run(agentId, completedOperation.operationId);\n this.#putOperationSync(completedOperation);\n this.#database.prepare(\"DELETE FROM journal_agents WHERE agent_id = ?\").run(agentId);\n this.#database.exec(\"COMMIT\");\n return existing;\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n }\n\n async getAgentByName(name: string): Promise<JournalAgent | null> {\n return this.#readJson<JournalAgent>(\n \"SELECT data_json FROM journal_agents WHERE name = ?\",\n name,\n );\n }\n\n async getAgentById(agentId: AgentId): Promise<JournalAgent | null> {\n return this.#readJson<JournalAgent>(\n \"SELECT data_json FROM journal_agents WHERE agent_id = ?\",\n agentId,\n );\n }\n\n async listAgents(): Promise<readonly JournalAgent[]> {\n return this.#readJsonRows<JournalAgent>(\"SELECT data_json FROM journal_agents ORDER BY name\");\n }\n\n async putAgent(agent: JournalAgent): Promise<void> {\n this.#assertOpen();\n assertJournalAgentIdentity(agent);\n this.#database\n .prepare(\n `INSERT INTO journal_agents(agent_id, name, data_json) VALUES(?, ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET name=excluded.name, data_json=excluded.data_json`,\n )\n .run(agent.agentId, agent.name, JSON.stringify(agent));\n }\n\n async putOperation(operation: JournalOperation): Promise<void> {\n this.#putOperationSync(operation);\n }\n\n async getOperation(operationId: string): Promise<JournalOperation | null> {\n return this.#readJson<JournalOperation>(\n \"SELECT data_json FROM journal_operations WHERE operation_id = ?\",\n operationId,\n );\n }\n\n async listPendingOperations(): Promise<readonly JournalOperation[]> {\n return this.#readJsonRows<JournalOperation>(\n \"SELECT data_json FROM journal_operations WHERE json_extract(data_json, '$.state') = 'pending' ORDER BY rowid\",\n );\n }\n\n async deleteOperation(operationId: string): Promise<void> {\n this.#assertOpen();\n this.#database\n .prepare(\"DELETE FROM journal_operations WHERE operation_id = ?\")\n .run(operationId);\n }\n\n async putSend(send: JournalSend): Promise<void> {\n this.#putOwned(\"journal_sends\", \"send_id\", send.sendId, send.agentId, send);\n }\n\n async getSend(sendId: string): Promise<JournalSend | null> {\n return this.#readJson<JournalSend>(\n \"SELECT data_json FROM journal_sends WHERE send_id = ?\",\n sendId,\n );\n }\n\n async nextSendOrdinal(agentId: AgentId): Promise<number> {\n const row = this.#database\n .prepare(\n `SELECT COALESCE(MAX(CAST(json_extract(data_json, '$.ordinal') AS INTEGER)), 0) + 1 AS ordinal\n FROM journal_sends WHERE agent_id = ?`,\n )\n .get(agentId) as { readonly ordinal: number };\n return row.ordinal;\n }\n\n async listNonterminalSends(): Promise<readonly JournalSend[]> {\n return this.#readJsonRows<JournalSend>(\n `SELECT data_json FROM journal_sends\n WHERE json_extract(data_json, '$.state') IN ('pending', 'dispatching')\n ORDER BY CAST(json_extract(data_json, '$.ordinal') AS INTEGER), rowid`,\n );\n }\n\n async putCompact(compact: JournalCompact): Promise<void> {\n this.#putOwned(\"journal_compacts\", \"compact_id\", compact.compactId, compact.agentId, compact);\n }\n\n async getCompact(compactId: string): Promise<JournalCompact | null> {\n return this.#readJson<JournalCompact>(\n \"SELECT data_json FROM journal_compacts WHERE compact_id = ?\",\n compactId,\n );\n }\n\n async listNonterminalCompacts(): Promise<readonly JournalCompact[]> {\n return this.#readJsonRows<JournalCompact>(\n `SELECT data_json FROM journal_compacts\n WHERE json_extract(data_json, '$.state') IN ('pending', 'dispatching') ORDER BY rowid`,\n );\n }\n\n async putIncarnation(incarnation: JournalIncarnation): Promise<void> {\n this.#putOwned(\n \"journal_incarnations\",\n \"incarnation_id\",\n incarnation.incarnationId,\n incarnation.agentId,\n incarnation,\n );\n }\n\n async listActiveIncarnations(): Promise<readonly JournalIncarnation[]> {\n return this.#readJsonRows<JournalIncarnation>(\n `SELECT data_json FROM journal_incarnations\n WHERE json_extract(data_json, '$.state') IN\n ('starting', 'live', 'stopping', 'cleanup_uncertain') ORDER BY rowid`,\n );\n }\n\n async putEpoch(epoch: JournalEpoch): Promise<void> {\n this.#assertOpen();\n this.#database\n .prepare(\n `INSERT INTO journal_epochs(agent_id, epoch, state, data_json) VALUES(?, ?, ?, ?)\n ON CONFLICT(agent_id, epoch) DO UPDATE SET\n state=excluded.state, data_json=excluded.data_json`,\n )\n .run(epoch.agentId, epoch.epoch, epoch.state, JSON.stringify(epoch));\n }\n\n async getEpochs(agentId: AgentId): Promise<readonly JournalEpoch[]> {\n return this.#readJsonRows<JournalEpoch>(\n \"SELECT data_json FROM journal_epochs WHERE agent_id = ? ORDER BY epoch\",\n agentId,\n );\n }\n\n async beginIncarnation(\n agentId: AgentId,\n incarnationId: IncarnationId,\n epoch: ContinuityEpoch,\n projectorState: ProjectorState,\n ): Promise<void> {\n this.#assertOpen();\n const incarnation = this.#database\n .prepare(\"SELECT 1 FROM journal_incarnations WHERE agent_id = ? AND incarnation_id = ?\")\n .get(agentId, incarnationId);\n const epochRow = this.#database\n .prepare(\"SELECT state FROM journal_epochs WHERE agent_id = ? AND epoch = ?\")\n .get(agentId, epoch) as { readonly state: string } | undefined;\n if (incarnation === undefined) {\n throw new Error(\"Projector binding references an unknown incarnation\");\n }\n if (epochRow?.state !== \"open\") {\n throw new Error(\"Projector binding requires an open continuity epoch\");\n }\n this.#database\n .prepare(\n `INSERT INTO journal_projector_state(\n agent_id, incarnation_id, epoch, data_json\n ) VALUES(?, ?, ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n incarnation_id=excluded.incarnation_id,\n epoch=excluded.epoch,\n data_json=excluded.data_json`,\n )\n .run(agentId, incarnationId, epoch, JSON.stringify(projectorState));\n }\n\n async append(batch: JournalAppend): Promise<void> {\n this.#assertOpen();\n const startedAt = performance.now();\n let transactionOpen = false;\n try {\n this.#database.exec(\"BEGIN IMMEDIATE\");\n transactionOpen = true;\n const current = this.#getHighWaterSync(batch.agentId) ?? {\n rawPosition: 0,\n eventPosition: 0,\n idleEventPosition: null,\n };\n const epochRow = this.#database\n .prepare(\"SELECT data_json FROM journal_epochs WHERE agent_id = ? AND epoch = ?\")\n .get(batch.agentId, batch.epoch) as JsonRow | undefined;\n assertJournalAppend(\n batch,\n current,\n epochRow === undefined ? null : (JSON.parse(epochRow.data_json) as JournalEpoch),\n );\n const projectorBinding = this.#database\n .prepare(\n `SELECT incarnation_id, epoch FROM journal_projector_state\n WHERE agent_id = ?`,\n )\n .get(batch.agentId) as\n | { readonly incarnation_id: string; readonly epoch: number }\n | undefined;\n if (\n projectorBinding?.incarnation_id !== batch.incarnationId ||\n projectorBinding.epoch !== batch.epoch\n ) {\n throw new Error(\"Journal append does not match the active projector incarnation\");\n }\n const putRecord = this.#database.prepare(\n `INSERT INTO journal_raw_records(\n agent_id, raw_position, incarnation_id, epoch, observed_at, record_bytes\n ) VALUES(?, ?, ?, ?, ?, ?)`,\n );\n for (const record of batch.records) {\n putRecord.run(\n record.agentId,\n record.position,\n record.incarnationId,\n batch.epoch,\n record.observedAt,\n record.bytes,\n );\n }\n const putEvent = this.#database.prepare(\n `INSERT INTO journal_semantic_events(\n agent_id, event_position, event_id, event_epoch, raw_position, event_type, data_json\n ) VALUES(?, ?, ?, ?, ?, ?, ?)`,\n );\n for (const stored of batch.events) {\n putEvent.run(\n stored.agentId,\n stored.position,\n stored.event.id,\n stored.event.epoch,\n stored.event.sourceRawPosition,\n stored.event.type,\n JSON.stringify(stored),\n );\n }\n this.#database\n .prepare(\n `UPDATE journal_projector_state SET data_json = ?\n WHERE agent_id = ? AND incarnation_id = ? AND epoch = ?`,\n )\n .run(JSON.stringify(batch.projectorState), batch.agentId, batch.incarnationId, batch.epoch);\n this.#database\n .prepare(\n `INSERT INTO journal_high_water(\n agent_id, raw_position, event_position, idle_event_position\n ) VALUES(?, ?, ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n raw_position=excluded.raw_position,\n event_position=excluded.event_position,\n idle_event_position=excluded.idle_event_position`,\n )\n .run(\n batch.agentId,\n batch.highWater.rawPosition,\n batch.highWater.eventPosition,\n batch.highWater.idleEventPosition,\n );\n this.#database\n .prepare(\n `UPDATE journal_runtime_health SET last_commit_at = ?\n WHERE singleton_key = 1`,\n )\n .run(new Date().toISOString());\n this.#database.exec(\"COMMIT\");\n transactionOpen = false;\n } catch (error: unknown) {\n if (transactionOpen) {\n try {\n this.#database.exec(\"ROLLBACK\");\n } catch {\n // The original durability failure remains authoritative when rollback also fails.\n }\n }\n this.#latchStorageFailure();\n throw error;\n } finally {\n this.#lastAppendDurationMs = Math.max(0, performance.now() - startedAt);\n }\n this.#commitsSinceCheckpoint += 1;\n if (this.#commitsSinceCheckpoint >= this.#checkpointCommitInterval) {\n await this.maintain(0);\n }\n }\n\n async openReceive(agentId: AgentId): Promise<JournalReceiveSnapshot | null> {\n this.#assertOpen();\n this.#database.exec(\"BEGIN\");\n try {\n const agent = this.#readJson<JournalAgent>(\n \"SELECT data_json FROM journal_agents WHERE agent_id = ?\",\n agentId,\n );\n if (agent === null) {\n this.#database.exec(\"COMMIT\");\n return null;\n }\n const snapshot = {\n agent,\n epochs: this.#readJsonRows<JournalEpoch>(\n \"SELECT data_json FROM journal_epochs WHERE agent_id = ? ORDER BY epoch\",\n agentId,\n ),\n highWater: this.#getHighWaterSync(agentId) ?? {\n rawPosition: 0,\n eventPosition: 0,\n idleEventPosition: null,\n },\n } satisfies JournalReceiveSnapshot;\n this.#database.exec(\"COMMIT\");\n return snapshot;\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n }\n\n async readEvents(range: JournalEventRange): Promise<readonly StoredSemanticEvent[]> {\n const rows = this.#database\n .prepare(\n `SELECT data_json FROM journal_semantic_events\n WHERE agent_id = ? AND event_epoch = ? AND event_position > ?\n ORDER BY event_position LIMIT ?`,\n )\n .iterate(range.agentId, range.epoch, range.afterPosition, range.limit) as Iterable<JsonRow>;\n return boundedSemanticEvents(parseSemanticEventRows(rows), range);\n }\n\n async getProjectorState(\n agentId: AgentId,\n incarnationId: IncarnationId,\n epoch: ContinuityEpoch,\n ): Promise<ProjectorState | null> {\n this.#assertOpen();\n const row = this.#database\n .prepare(\n `SELECT incarnation_id, epoch, data_json FROM journal_projector_state\n WHERE agent_id = ?`,\n )\n .get(agentId) as\n | { readonly incarnation_id: string; readonly epoch: number; readonly data_json: string }\n | undefined;\n if (row === undefined) return null;\n if (row.incarnation_id !== incarnationId || row.epoch !== epoch) {\n throw new Error(\"Projector state belongs to another incarnation or continuity epoch\");\n }\n return JSON.parse(row.data_json) as ProjectorState;\n }\n\n async getHighWater(agentId: AgentId): Promise<JournalHighWater | null> {\n return this.#getHighWaterSync(agentId);\n }\n\n async markIdle(agentId: AgentId, epoch: ContinuityEpoch): Promise<number> {\n this.#assertOpen();\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n const epochRow = this.#database\n .prepare(\"SELECT state FROM journal_epochs WHERE agent_id = ? AND epoch = ?\")\n .get(agentId, epoch) as { readonly state: string } | undefined;\n if (epochRow?.state !== \"open\") throw new Error(\"Idle marker requires an open epoch\");\n const current = this.#getHighWaterSync(agentId) ?? {\n rawPosition: 0,\n eventPosition: 0,\n idleEventPosition: null,\n };\n this.#database\n .prepare(\n `INSERT INTO journal_high_water(\n agent_id, raw_position, event_position, idle_event_position\n ) VALUES(?, ?, ?, ?)\n ON CONFLICT(agent_id) DO UPDATE SET\n idle_event_position=excluded.idle_event_position`,\n )\n .run(agentId, current.rawPosition, current.eventPosition, current.eventPosition);\n this.#database\n .prepare(\"UPDATE journal_runtime_health SET last_commit_at = ? WHERE singleton_key = 1\")\n .run(new Date().toISOString());\n this.#database.exec(\"COMMIT\");\n return current.eventPosition;\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n this.#latchStorageFailure();\n throw error;\n }\n }\n\n async getRawRecords(\n agentId: AgentId,\n afterPosition: number,\n limit: number,\n ): Promise<readonly RawRpcRecord[]> {\n this.#assertPositiveLimit(limit);\n const rows = this.#database\n .prepare(\n `SELECT raw_position, incarnation_id, observed_at, record_bytes\n FROM journal_raw_records WHERE agent_id = ? AND raw_position > ?\n ORDER BY raw_position LIMIT ?`,\n )\n .all(agentId, afterPosition, limit) as unknown as Array<{\n readonly raw_position: number;\n readonly incarnation_id: string;\n readonly observed_at: string;\n readonly record_bytes: Uint8Array;\n }>;\n return rows.map((row) => ({\n agentId,\n incarnationId: row.incarnation_id as RawRpcRecord[\"incarnationId\"],\n position: row.raw_position,\n observedAt: row.observed_at,\n bytes: Buffer.from(row.record_bytes),\n }));\n }\n\n async destroyAgent(\n agentId: AgentId,\n receipt: JournalDestroyReceipt,\n ): Promise<JournalAgent | null> {\n this.#assertOpen();\n if (receipt.agentId !== agentId) throw new Error(\"Destroy receipt targets another agent\");\n let destroyed: JournalAgent | null = null;\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n const priorReceipt = await this.getDestroyReceipt(receipt.operationId);\n if (priorReceipt !== null) {\n if (!sameJournalDestroyReceipt(priorReceipt, receipt)) {\n throw new Error(\"Destroy operation was already used\");\n }\n this.#database.exec(\"ROLLBACK\");\n return null;\n }\n const existing = await this.getAgentById(agentId);\n if (existing === null) {\n this.#database.exec(\"ROLLBACK\");\n return null;\n }\n this.#database.prepare(\"DELETE FROM journal_operations WHERE agent_id = ?\").run(agentId);\n this.#database.prepare(\"DELETE FROM journal_agents WHERE agent_id = ?\").run(agentId);\n this.#database\n .prepare(\n `INSERT INTO journal_destroy_receipts(\n operation_id, agent_id, agent_name, fingerprint, destroyed_at, status\n ) VALUES(?, ?, ?, ?, ?, ?)\n ON CONFLICT(operation_id) DO NOTHING`,\n )\n .run(\n receipt.operationId,\n receipt.agentId,\n receipt.agentName,\n receipt.fingerprint,\n receipt.destroyedAt,\n receipt.status,\n );\n this.#database.exec(\"COMMIT\");\n destroyed = existing;\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n await this.maintain(this.#reclaimPagesPerPass);\n return destroyed;\n }\n\n async getDestroyReceipt(operationId: string): Promise<JournalDestroyReceipt | null> {\n const row = this.#database\n .prepare(\n `SELECT operation_id, agent_id, agent_name, fingerprint, destroyed_at, status\n FROM journal_destroy_receipts WHERE operation_id = ?`,\n )\n .get(operationId) as\n | {\n readonly operation_id: string;\n readonly agent_id: string;\n readonly agent_name: string;\n readonly fingerprint: string;\n readonly destroyed_at: string;\n readonly status: \"destroyed\";\n }\n | undefined;\n return row === undefined\n ? null\n : {\n operationId: row.operation_id,\n agentId: row.agent_id as AgentId,\n agentName: row.agent_name,\n fingerprint: row.fingerprint,\n destroyedAt: row.destroyed_at,\n status: row.status,\n };\n }\n\n async maintain(reclaimPages = this.#reclaimPagesPerPass): Promise<JournalMaintenanceResult> {\n this.#assertOpen();\n if (!Number.isSafeInteger(reclaimPages) || reclaimPages < 0) {\n throw new Error(\"Journal reclaim page limit must be a non-negative integer\");\n }\n this.#maintenance = {\n ...this.#maintenance,\n state: \"running\",\n requestedReclaimPages: reclaimPages,\n };\n try {\n const checkpoint = this.#database.prepare(\"PRAGMA wal_checkpoint(PASSIVE)\").get() as {\n readonly busy: number;\n readonly log: number;\n readonly checkpointed: number;\n };\n const autoVacuumValue = pragmaInteger(this.#database, \"auto_vacuum\");\n const freelistPagesBefore = pragmaInteger(this.#database, \"freelist_count\");\n if (reclaimPages > 0 && autoVacuumValue === 2 && freelistPagesBefore > 0) {\n this.#database.exec(`PRAGMA incremental_vacuum(${String(reclaimPages)})`);\n }\n const result: JournalMaintenanceResult = {\n state: \"idle\",\n lastCheckpointAt: this.#now(),\n busy: checkpoint.busy !== 0,\n logFrames: checkpoint.log,\n checkpointedFrames: checkpoint.checkpointed,\n autoVacuumMode: autoVacuumMode(autoVacuumValue),\n freelistPagesBefore,\n freelistPagesAfter: pragmaInteger(this.#database, \"freelist_count\"),\n requestedReclaimPages: reclaimPages,\n };\n this.#maintenance = result;\n this.#commitsSinceCheckpoint = 0;\n return { ...result };\n } catch (error: unknown) {\n this.#maintenance = { ...this.#maintenance, state: \"failed\" };\n this.#latchStorageFailure();\n throw error;\n }\n }\n\n async getDiagnostics(): Promise<JournalStorageDiagnostics> {\n const retainedByAgent = this.#database\n .prepare(\n `SELECT a.agent_id,\n (SELECT COUNT(*) FROM journal_raw_records r\n WHERE r.agent_id = a.agent_id) AS raw_record_count,\n (SELECT COALESCE(SUM(length(r.record_bytes)), 0) FROM journal_raw_records r\n WHERE r.agent_id = a.agent_id) AS raw_bytes,\n (SELECT COUNT(*) FROM journal_semantic_events e\n WHERE e.agent_id = a.agent_id) AS semantic_event_count\n FROM journal_agents a ORDER BY a.agent_id`,\n )\n .all() as unknown as Array<{\n readonly agent_id: string;\n readonly raw_record_count: number;\n readonly raw_bytes: number;\n readonly semantic_event_count: number;\n }>;\n const row = this.#database\n .prepare(\n `SELECT\n (SELECT COUNT(*) FROM journal_raw_records) AS raw_record_count,\n (SELECT COALESCE(SUM(length(record_bytes)), 0) FROM journal_raw_records) AS raw_bytes,\n (SELECT COUNT(*) FROM journal_semantic_events) AS semantic_event_count,\n (SELECT COUNT(*) FROM journal_agents) AS agent_count,\n (SELECT COALESCE(SUM(json_array_length(data_json, '$.openActivities')), 0)\n FROM journal_projector_state) AS open_projector_activities,\n (SELECT COUNT(*) FROM journal_epochs\n WHERE state = 'closed'\n AND json_extract(data_json, '$.reason') = 'observation_uncertain')\n AS continuity_gap_count,\n (SELECT storage_state FROM journal_runtime_health WHERE singleton_key = 1) AS storage_state,\n (SELECT last_commit_at FROM journal_runtime_health WHERE singleton_key = 1) AS last_commit_at`,\n )\n .get() as {\n readonly raw_record_count: number;\n readonly raw_bytes: number;\n readonly semantic_event_count: number;\n readonly agent_count: number;\n readonly open_projector_activities: number;\n readonly continuity_gap_count: number;\n readonly storage_state: \"healthy\" | \"failed\";\n readonly last_commit_at: string | null;\n };\n return {\n rawRecordCount: row.raw_record_count,\n rawBytes: row.raw_bytes,\n semanticEventCount: row.semantic_event_count,\n agentCount: row.agent_count,\n retainedByAgent: retainedByAgent.map((agent) => ({\n agentId: agent.agent_id as AgentId,\n rawRecordCount: agent.raw_record_count,\n rawBytes: agent.raw_bytes,\n semanticEventCount: agent.semantic_event_count,\n })),\n openProjectorActivities: row.open_projector_activities,\n continuityGapCount: row.continuity_gap_count,\n storageState: this.#storageFailureLatched ? \"failed\" : row.storage_state,\n lastCommitAt: row.last_commit_at,\n lastAppendDurationMs: this.#lastAppendDurationMs,\n maintenance: { ...this.#maintenance },\n };\n }\n\n #latchStorageFailure(): void {\n this.#storageFailureLatched = true;\n try {\n this.#database\n .prepare(\n \"UPDATE journal_runtime_health SET storage_state = 'failed' WHERE singleton_key = 1\",\n )\n .run();\n } catch {\n // The in-memory latch remains authoritative until an explicit recovery design exists.\n }\n }\n\n async close(): Promise<void> {\n if (this.#closed) return;\n this.#database\n .prepare(\"UPDATE journal_runtime_health SET clean_shutdown = 1 WHERE singleton_key = 1\")\n .run();\n this.#database.close();\n this.#closed = true;\n }\n\n #migrate(): void {\n this.#database.exec(\"BEGIN IMMEDIATE\");\n try {\n this.#database.exec(\n `CREATE TABLE IF NOT EXISTS schema_migrations(\n version INTEGER PRIMARY KEY,\n checksum TEXT NOT NULL,\n applied_at TEXT NOT NULL\n )`,\n );\n const applied = this.#database\n .prepare(\"SELECT version, checksum FROM schema_migrations ORDER BY version\")\n .all() as unknown as JournalMigrationRow[];\n const migrationState = classifyJournalMigrationRows(applied);\n if (migrationState === \"current\") {\n this.#database.exec(\"COMMIT\");\n return;\n }\n this.#replaceLegacySchema();\n this.#database.prepare(\"DELETE FROM schema_migrations\").run();\n this.#database\n .prepare(\"INSERT INTO schema_migrations(version, checksum, applied_at) VALUES(?, ?, ?)\")\n .run(JOURNAL_SCHEMA_VERSION, JOURNAL_SCHEMA_CHECKSUM, new Date().toISOString());\n this.#database.exec(\"COMMIT\");\n } catch (error: unknown) {\n this.#database.exec(\"ROLLBACK\");\n throw error;\n }\n }\n\n #replaceLegacySchema(): void {\n this.#database.exec(`\n DROP TABLE IF EXISTS compact_records;\n DROP TABLE IF EXISTS send_records;\n DROP TABLE IF EXISTS incarnations;\n DROP TABLE IF EXISTS operations;\n DROP TABLE IF EXISTS agents;\n DROP TABLE IF EXISTS runtime_metadata;\n\n CREATE TABLE journal_agents(\n agent_id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE journal_operations(\n operation_id TEXT PRIMARY KEY,\n agent_id TEXT REFERENCES journal_agents(agent_id),\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE journal_sends(\n send_id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE journal_compacts(\n compact_id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n data_json TEXT NOT NULL CHECK(json_valid(data_json))\n );\n CREATE TABLE journal_incarnations(\n incarnation_id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n data_json TEXT NOT NULL CHECK(json_valid(data_json)),\n UNIQUE(agent_id, incarnation_id)\n );\n CREATE TABLE journal_epochs(\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n epoch INTEGER NOT NULL,\n state TEXT NOT NULL CHECK(state IN ('open', 'closed')),\n data_json TEXT NOT NULL CHECK(json_valid(data_json)),\n PRIMARY KEY(agent_id, epoch)\n );\n CREATE TABLE journal_raw_records(\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n raw_position INTEGER NOT NULL,\n incarnation_id TEXT NOT NULL,\n epoch INTEGER NOT NULL,\n observed_at TEXT NOT NULL,\n record_bytes BLOB NOT NULL,\n PRIMARY KEY(agent_id, raw_position),\n UNIQUE(agent_id, raw_position, epoch),\n FOREIGN KEY(agent_id, epoch) REFERENCES journal_epochs(agent_id, epoch),\n FOREIGN KEY(agent_id, incarnation_id)\n REFERENCES journal_incarnations(agent_id, incarnation_id)\n );\n CREATE TABLE journal_semantic_events(\n agent_id TEXT NOT NULL REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n event_position INTEGER NOT NULL,\n event_id TEXT NOT NULL UNIQUE,\n event_epoch INTEGER NOT NULL,\n raw_position INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n data_json TEXT NOT NULL CHECK(json_valid(data_json)),\n PRIMARY KEY(agent_id, event_position),\n FOREIGN KEY(agent_id, event_epoch) REFERENCES journal_epochs(agent_id, epoch),\n FOREIGN KEY(agent_id, raw_position, event_epoch)\n REFERENCES journal_raw_records(agent_id, raw_position, epoch)\n );\n CREATE TABLE journal_projector_state(\n agent_id TEXT PRIMARY KEY REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n incarnation_id TEXT NOT NULL,\n epoch INTEGER NOT NULL,\n data_json TEXT NOT NULL CHECK(json_valid(data_json)),\n FOREIGN KEY(agent_id, incarnation_id)\n REFERENCES journal_incarnations(agent_id, incarnation_id),\n FOREIGN KEY(agent_id, epoch) REFERENCES journal_epochs(agent_id, epoch)\n );\n CREATE TABLE journal_high_water(\n agent_id TEXT PRIMARY KEY REFERENCES journal_agents(agent_id) ON DELETE CASCADE,\n raw_position INTEGER NOT NULL,\n event_position INTEGER NOT NULL,\n idle_event_position INTEGER\n );\n CREATE TABLE journal_runtime_health(\n singleton_key INTEGER PRIMARY KEY CHECK(singleton_key = 1),\n storage_state TEXT NOT NULL CHECK(storage_state IN ('healthy', 'failed')),\n last_commit_at TEXT,\n clean_shutdown INTEGER NOT NULL CHECK(clean_shutdown IN (0, 1)),\n started_at TEXT\n );\n INSERT INTO journal_runtime_health(\n singleton_key, storage_state, last_commit_at, clean_shutdown, started_at\n ) VALUES(1, 'healthy', NULL, 1, NULL);\n CREATE TABLE journal_destroy_receipts(\n operation_id TEXT PRIMARY KEY,\n agent_id TEXT NOT NULL,\n agent_name TEXT NOT NULL,\n fingerprint TEXT NOT NULL,\n destroyed_at TEXT NOT NULL,\n status TEXT NOT NULL CHECK(status = 'destroyed')\n );\n CREATE INDEX journal_events_range\n ON journal_semantic_events(agent_id, event_position);\n CREATE INDEX journal_raw_range\n ON journal_raw_records(agent_id, raw_position);\n `);\n }\n\n #putOperationSync(operation: JournalOperation): void {\n this.#assertOpen();\n if (\n operation.agentId !== null &&\n this.#readJson<JournalAgent>(\n \"SELECT data_json FROM journal_agents WHERE agent_id = ?\",\n operation.agentId,\n ) === null\n ) {\n throw new Error(\"Operation targets an unknown agent generation\");\n }\n const existing = this.#database\n .prepare(\"SELECT agent_id, data_json FROM journal_operations WHERE operation_id = ?\")\n .get(operation.operationId) as\n | { readonly agent_id: string | null; readonly data_json: string }\n | undefined;\n if (existing !== undefined) {\n const prior = JSON.parse(existing.data_json) as JournalOperation;\n if (\n existing.agent_id !== null &&\n operation.agentId !== null &&\n existing.agent_id !== operation.agentId\n ) {\n throw new Error(\"Agent-owned record cannot change generations\");\n }\n if (prior.method !== operation.method || prior.fingerprint !== operation.fingerprint) {\n throw new Error(\"Operation was already used with a different request\");\n }\n }\n this.#database\n .prepare(\n `INSERT INTO journal_operations(operation_id, agent_id, data_json) VALUES(?, ?, ?)\n ON CONFLICT(operation_id) DO UPDATE SET\n agent_id=excluded.agent_id, data_json=excluded.data_json`,\n )\n .run(operation.operationId, operation.agentId, JSON.stringify(operation));\n }\n\n #putOwned(\n table: \"journal_sends\" | \"journal_compacts\" | \"journal_incarnations\",\n idColumn: \"operation_id\" | \"send_id\" | \"compact_id\" | \"incarnation_id\",\n id: string,\n agentId: AgentId,\n value: unknown,\n ): void {\n this.#assertOpen();\n const existing = this.#database\n .prepare(`SELECT agent_id FROM ${table} WHERE ${idColumn} = ?`)\n .get(id) as { readonly agent_id: string } | undefined;\n if (existing !== undefined && existing.agent_id !== agentId) {\n throw new Error(\"Agent-owned record cannot change generations\");\n }\n this.#database\n .prepare(\n `INSERT INTO ${table}(${idColumn}, agent_id, data_json) VALUES(?, ?, ?)\n ON CONFLICT(${idColumn}) DO UPDATE SET data_json=excluded.data_json`,\n )\n .run(id, agentId, JSON.stringify(value));\n }\n\n #readJson<T>(sql: string, value: string): T | null {\n this.#assertOpen();\n const row = this.#database.prepare(sql).get(value) as JsonRow | undefined;\n return row === undefined ? null : (JSON.parse(row.data_json) as T);\n }\n\n #readJsonRows<T>(sql: string, ...values: readonly string[]): readonly T[] {\n this.#assertOpen();\n const rows = this.#database.prepare(sql).all(...values) as unknown as JsonRow[];\n return rows.map((row) => JSON.parse(row.data_json) as T);\n }\n\n #getHighWaterSync(agentId: AgentId): JournalHighWater | null {\n this.#assertOpen();\n const row = this.#database\n .prepare(\n `SELECT raw_position, event_position, idle_event_position\n FROM journal_high_water WHERE agent_id = ?`,\n )\n .get(agentId) as\n | {\n readonly raw_position: number;\n readonly event_position: number;\n readonly idle_event_position: number | null;\n }\n | undefined;\n return row === undefined\n ? null\n : {\n rawPosition: row.raw_position,\n eventPosition: row.event_position,\n idleEventPosition: row.idle_event_position,\n };\n }\n\n #assertPositiveLimit(limit: number): void {\n if (!Number.isSafeInteger(limit) || limit <= 0)\n throw new Error(\"Journal range limit must be positive\");\n }\n\n #assertOpen(): void {\n if (this.#closed) throw new Error(\"pi-fleet journal store is closed\");\n }\n}\n\nfunction positiveInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`${label} must be a positive integer`);\n }\n return value;\n}\n\nfunction pragmaInteger(database: DatabaseSync, name: \"auto_vacuum\" | \"freelist_count\"): number {\n const row = database.prepare(`PRAGMA ${name}`).get() as Record<string, unknown> | undefined;\n const value = row?.[name];\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) {\n throw new Error(`SQLite PRAGMA ${name} returned an invalid value`);\n }\n return value;\n}\n\nfunction autoVacuumMode(value: number): JournalMaintenanceResult[\"autoVacuumMode\"] {\n if (value === 0) return \"none\";\n if (value === 1) return \"full\";\n if (value === 2) return \"incremental\";\n throw new Error(\"SQLite returned an unsupported auto_vacuum mode\");\n}\n", "import { chmodSync, constants, lstatSync } from \"node:fs\";\nimport { chmod, lstat, mkdir, open } from \"node:fs/promises\";\nimport { dirname, join, parse, resolve, sep } from \"node:path\";\n\nimport type { FleetPaths } from \"./paths.js\";\n\nconst PRIVATE_DIRECTORY_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst GROUP_OR_OTHER_WRITE = 0o022;\nconst STICKY_BIT = 0o1000;\nconst SAFE_ROOT_STICKY_DIRECTORIES = new Set([\"/tmp\", \"/var/tmp\"]);\n\n/** Prepare and verify paths that may retain sensitive pi-fleet state. */\nexport async function prepareFleetPathSecurity(paths: FleetPaths): Promise<void> {\n await preparePrivateDirectory(paths.runtimeRoot);\n if (paths.stateRoot !== paths.runtimeRoot) await preparePrivateDirectory(paths.stateRoot);\n await preparePrivateDatabase(paths.databasePath);\n}\n\nexport async function preparePrivateDirectory(path: string): Promise<void> {\n const absolutePath = resolve(path);\n await prepareDirectoryComponents(absolutePath);\n const stats = await lstat(absolutePath);\n assertCurrentUser(absolutePath, stats.uid);\n await chmod(absolutePath, PRIVATE_DIRECTORY_MODE);\n}\n\nexport async function preparePrivateDatabase(path: string): Promise<void> {\n const absolutePath = resolve(path);\n await preparePrivateDirectory(dirname(absolutePath));\n await assertPrivateRegularFileIfPresent(absolutePath);\n await assertPrivateRegularFileIfPresent(`${absolutePath}-wal`);\n await assertPrivateRegularFileIfPresent(`${absolutePath}-shm`);\n\n const handle = await open(\n absolutePath,\n constants.O_CREAT | constants.O_APPEND | constants.O_WRONLY | constants.O_NOFOLLOW,\n 0o600,\n );\n await handle.chmod(PRIVATE_FILE_MODE);\n await handle.close();\n}\n\nexport async function hardenSqliteSidecars(path: string): Promise<void> {\n await assertPrivateRegularFileIfPresent(path, true);\n await assertPrivateRegularFileIfPresent(`${path}-wal`, true);\n await assertPrivateRegularFileIfPresent(`${path}-shm`, true);\n}\n\nexport function hardenPrivateDirectorySync(path: string): void {\n assertTrustedDirectoryComponentsSync(resolve(path));\n const stats = lstatSync(path);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new Error(`Refusing unsafe pi-fleet directory ${path}`);\n }\n assertCurrentUser(path, stats.uid);\n chmodSync(path, PRIVATE_DIRECTORY_MODE);\n}\n\nexport function hardenSqliteSidecarsSync(path: string): void {\n for (const candidate of [path, `${path}-wal`, `${path}-shm`]) {\n let stats;\n try {\n stats = lstatSync(candidate);\n } catch (error: unknown) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw error;\n }\n if (stats.isSymbolicLink() || !stats.isFile()) {\n throw new Error(`Refusing unsafe pi-fleet state file ${candidate}`);\n }\n assertCurrentUser(candidate, stats.uid);\n chmodSync(candidate, PRIVATE_FILE_MODE);\n }\n}\n\nfunction assertTrustedDirectoryComponentsSync(absolutePath: string): void {\n const root = parse(absolutePath).root;\n let current = root;\n const rootStats = lstatSync(root);\n assertTrustedDirectoryAncestor(root, rootStats.uid, rootStats.mode);\n for (const component of absolutePath.slice(root.length).split(sep).filter(Boolean)) {\n current = join(current, component);\n const stats = lstatSync(current);\n if (stats.isSymbolicLink() || !stats.isDirectory()) {\n throw new Error(`Refusing unsafe pi-fleet directory ${current}`);\n }\n assertTrustedDirectoryAncestor(current, stats.uid, stats.mode);\n }\n}\n\nasync function prepareDirectoryComponents(absolutePath: string): Promise<void> {\n const root = parse(absolutePath).root;\n const rootStats = await lstat(root);\n assertTrustedDirectoryAncestor(root, rootStats.uid, rootStats.mode);\n const components = absolutePath.slice(root.length).split(sep).filter(Boolean);\n let current = root;\n for (const component of components) {\n current = join(current, component);\n let stats = await lstat(current).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (stats === null) {\n await mkdir(current, { mode: PRIVATE_DIRECTORY_MODE }).catch(\n (error: NodeJS.ErrnoException) => {\n if (error.code !== \"EEXIST\") throw error;\n },\n );\n stats = await lstat(current);\n }\n if (stats.isSymbolicLink()) {\n throw new Error(`Refusing unsafe pi-fleet directory symlink ${current}`);\n }\n if (!stats.isDirectory()) {\n throw new Error(`Refusing unsafe pi-fleet directory ${current}`);\n }\n assertTrustedDirectoryAncestor(current, stats.uid, stats.mode);\n }\n}\n\nexport function assertTrustedDirectoryAncestor(\n path: string,\n ownerUid: number,\n mode: number,\n currentUid = process.getuid?.(),\n): void {\n if (currentUid === undefined || ownerUid === currentUid) return;\n if (ownerUid === 0) {\n const writable = (mode & GROUP_OR_OTHER_WRITE) !== 0;\n if (!writable) return;\n if ((mode & STICKY_BIT) !== 0 && SAFE_ROOT_STICKY_DIRECTORIES.has(path)) return;\n }\n throw new Error(`Refusing untrusted pi-fleet directory ancestor: ${path}`);\n}\n\nasync function assertPrivateRegularFileIfPresent(path: string, harden = false): Promise<void> {\n const stats = await lstat(path).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\") return null;\n throw error;\n });\n if (stats === null) return;\n if (stats.isSymbolicLink() || !stats.isFile()) {\n throw new Error(`Refusing unsafe pi-fleet state file ${path}`);\n }\n assertCurrentUser(path, stats.uid);\n if (harden || (stats.mode & 0o077) !== 0) await chmod(path, PRIVATE_FILE_MODE);\n}\n\nfunction assertCurrentUser(path: string, ownerUid: number): void {\n const uid = process.getuid?.();\n if (uid !== undefined && ownerUid !== uid) {\n throw new Error(`Refusing pi-fleet path not owned by the current user: ${path}`);\n }\n}\n", "import type { AgentSummary } from \"../client/fleet-client.js\";\nimport type { AgentLaunchProfile } from \"../pi/launch-profile.js\";\nimport type {\n AgentId,\n ContinuityEpoch,\n IncarnationId,\n ProjectorState,\n RawRpcRecord,\n SemanticEvent,\n} from \"../runtime/semantic-events.js\";\n\nexport interface JournalAgent {\n readonly agentId: AgentId;\n readonly name: string;\n readonly summary: AgentSummary;\n readonly launch: AgentLaunchProfile;\n}\n\nexport interface JournalOperation {\n readonly operationId: string;\n readonly agentId: AgentId | null;\n readonly targetName: string;\n readonly method: \"create\" | \"send\" | \"destroy\" | \"compact\";\n readonly fingerprint: string;\n readonly state: \"pending\" | \"completed\";\n readonly result: unknown | null;\n /** Retained only while pending so proven-undispatched work can resume. */\n readonly request?: unknown;\n}\n\nexport interface JournalSend {\n readonly sendId: string;\n readonly agentId: AgentId;\n readonly ordinal: number;\n readonly message: string;\n readonly delivery: \"steer\" | \"followUp\";\n readonly state: \"pending\" | \"dispatching\" | \"acknowledged\" | \"failed\" | \"uncertain\";\n readonly acceptedAt: string;\n}\n\nexport interface JournalCompact {\n readonly compactId: string;\n readonly agentId: AgentId;\n readonly state: \"pending\" | \"dispatching\" | \"completed\" | \"failed\" | \"uncertain\";\n readonly requestedAt: string;\n readonly result?: {\n readonly tokensBefore: number;\n readonly estimatedTokensAfter?: number;\n };\n readonly error?: unknown;\n}\n\nexport interface JournalIncarnation {\n readonly incarnationId: IncarnationId;\n readonly agentId: AgentId;\n readonly pid: number | null;\n readonly state: \"starting\" | \"live\" | \"stopping\" | \"cleanup_uncertain\" | \"gone\";\n}\n\nexport interface JournalHighWater {\n readonly rawPosition: number;\n readonly eventPosition: number;\n readonly idleEventPosition: number | null;\n}\n\nexport interface JournalEpoch {\n readonly agentId: AgentId;\n readonly epoch: ContinuityEpoch;\n readonly state: \"open\" | \"closed\";\n readonly lastSafeEventPosition: number;\n readonly openedAt: string;\n readonly closedAt?: string;\n readonly reason?: \"observation_uncertain\";\n}\n\nexport interface StoredSemanticEvent {\n readonly agentId: AgentId;\n readonly position: number;\n readonly event: SemanticEvent;\n}\n\nexport interface JournalAppend {\n readonly agentId: AgentId;\n readonly incarnationId: IncarnationId;\n readonly epoch: ContinuityEpoch;\n readonly records: readonly RawRpcRecord[];\n readonly events: readonly StoredSemanticEvent[];\n readonly projectorState: ProjectorState;\n readonly highWater: JournalHighWater;\n}\n\nexport interface JournalEventRange {\n readonly agentId: AgentId;\n readonly epoch: ContinuityEpoch;\n readonly afterPosition: number;\n readonly limit: number;\n readonly maxBytes: number;\n readonly maxEventBytes: number;\n}\n\nexport interface JournalReceiveSnapshot {\n readonly agent: JournalAgent;\n readonly epochs: readonly JournalEpoch[];\n readonly highWater: JournalHighWater;\n}\n\nexport interface JournalDestroyReceipt {\n readonly operationId: string;\n readonly agentId: AgentId;\n readonly agentName: string;\n readonly fingerprint: string;\n readonly destroyedAt: string;\n readonly status: \"destroyed\";\n}\n\nexport interface JournalAgentStorageDiagnostics {\n readonly agentId: AgentId;\n readonly rawRecordCount: number;\n readonly rawBytes: number;\n readonly semanticEventCount: number;\n}\n\nexport interface JournalMaintenanceResult {\n readonly state: \"idle\" | \"running\" | \"failed\";\n readonly lastCheckpointAt: string | null;\n readonly busy: boolean;\n readonly logFrames: number;\n readonly checkpointedFrames: number;\n readonly autoVacuumMode: \"none\" | \"full\" | \"incremental\";\n readonly freelistPagesBefore: number;\n readonly freelistPagesAfter: number;\n readonly requestedReclaimPages: number;\n}\n\nexport interface JournalStorageDiagnostics {\n readonly rawRecordCount: number;\n readonly rawBytes: number;\n readonly semanticEventCount: number;\n readonly agentCount: number;\n readonly retainedByAgent: readonly JournalAgentStorageDiagnostics[];\n readonly openProjectorActivities: number;\n readonly continuityGapCount: number;\n readonly storageState: \"healthy\" | \"failed\";\n readonly lastCommitAt: string | null;\n readonly lastAppendDurationMs: number | null;\n readonly maintenance: JournalMaintenanceResult;\n}\n\nexport interface JournalStore {\n createAgent(agent: JournalAgent): Promise<boolean>;\n createAgentWithOperation(agent: JournalAgent, operation: JournalOperation): Promise<boolean>;\n rollbackProvisionalCreate(\n agentId: AgentId,\n completedOperation: JournalOperation,\n ): Promise<JournalAgent | null>;\n getAgentByName(name: string): Promise<JournalAgent | null>;\n getAgentById(agentId: AgentId): Promise<JournalAgent | null>;\n listAgents(): Promise<readonly JournalAgent[]>;\n putAgent(agent: JournalAgent): Promise<void>;\n\n putOperation(operation: JournalOperation): Promise<void>;\n getOperation(operationId: string): Promise<JournalOperation | null>;\n listPendingOperations(): Promise<readonly JournalOperation[]>;\n deleteOperation(operationId: string): Promise<void>;\n putSend(send: JournalSend): Promise<void>;\n getSend(sendId: string): Promise<JournalSend | null>;\n nextSendOrdinal(agentId: AgentId): Promise<number>;\n listNonterminalSends(): Promise<readonly JournalSend[]>;\n putCompact(compact: JournalCompact): Promise<void>;\n getCompact(compactId: string): Promise<JournalCompact | null>;\n listNonterminalCompacts(): Promise<readonly JournalCompact[]>;\n putIncarnation(incarnation: JournalIncarnation): Promise<void>;\n listActiveIncarnations(): Promise<readonly JournalIncarnation[]>;\n\n putEpoch(epoch: JournalEpoch): Promise<void>;\n beginIncarnation(\n agentId: AgentId,\n incarnationId: IncarnationId,\n epoch: ContinuityEpoch,\n projectorState: ProjectorState,\n ): Promise<void>;\n getEpochs(agentId: AgentId): Promise<readonly JournalEpoch[]>;\n append(batch: JournalAppend): Promise<void>;\n openReceive(agentId: AgentId): Promise<JournalReceiveSnapshot | null>;\n readEvents(range: JournalEventRange): Promise<readonly StoredSemanticEvent[]>;\n getProjectorState(\n agentId: AgentId,\n incarnationId: IncarnationId,\n epoch: ContinuityEpoch,\n ): Promise<ProjectorState | null>;\n getHighWater(agentId: AgentId): Promise<JournalHighWater | null>;\n markIdle(agentId: AgentId, epoch: ContinuityEpoch): Promise<number>;\n getRawRecords(\n agentId: AgentId,\n afterPosition: number,\n limit: number,\n ): Promise<readonly RawRpcRecord[]>;\n\n destroyAgent(agentId: AgentId, receipt: JournalDestroyReceipt): Promise<JournalAgent | null>;\n getDestroyReceipt(operationId: string): Promise<JournalDestroyReceipt | null>;\n maintain(reclaimPages?: number): Promise<JournalMaintenanceResult>;\n getDiagnostics(): Promise<JournalStorageDiagnostics>;\n close(): Promise<void>;\n}\n\nexport function boundedSemanticEvents(\n events: Iterable<StoredSemanticEvent>,\n range: JournalEventRange,\n): readonly StoredSemanticEvent[] {\n if (!Number.isSafeInteger(range.limit) || range.limit <= 0) {\n throw new Error(\"Journal event range limit must be positive\");\n }\n if (!Number.isSafeInteger(range.maxBytes) || range.maxBytes <= 0) {\n throw new Error(\"Journal event range byte limit must be positive\");\n }\n if (!Number.isSafeInteger(range.maxEventBytes) || range.maxEventBytes <= 0) {\n throw new Error(\"Journal semantic event limit must be positive\");\n }\n\n const selected: StoredSemanticEvent[] = [];\n let selectedBytes = 0;\n for (const stored of events) {\n if (stored.agentId !== range.agentId || stored.event.epoch !== range.epoch) continue;\n if (stored.position <= range.afterPosition) continue;\n const bytes = Buffer.byteLength(JSON.stringify(stored));\n if (bytes > range.maxEventBytes) throw new Error(\"Semantic event exceeds storage read limit\");\n if (selected.length > 0 && selectedBytes + bytes > range.maxBytes) break;\n selected.push(stored);\n selectedBytes += bytes;\n if (selected.length >= range.limit || selectedBytes >= range.maxBytes) break;\n }\n return selected;\n}\n\nexport function sameJournalDestroyReceipt(\n left: JournalDestroyReceipt,\n right: JournalDestroyReceipt,\n): boolean {\n return (\n left.operationId === right.operationId &&\n left.agentId === right.agentId &&\n left.agentName === right.agentName &&\n left.fingerprint === right.fingerprint &&\n left.destroyedAt === right.destroyedAt &&\n left.status === right.status\n );\n}\n\nexport function assertJournalAgentIdentity(agent: JournalAgent): void {\n if (agent.summary.id !== agent.agentId || agent.summary.name !== agent.name) {\n throw new Error(\"Journal agent identity does not match its summary\");\n }\n}\n\nexport function assertJournalAppend(\n batch: JournalAppend,\n current: JournalHighWater,\n epoch: JournalEpoch | null,\n): void {\n if (epoch === null) throw new Error(\"Journal append references an unknown continuity epoch\");\n if (epoch.state !== \"open\")\n throw new Error(\"Journal append references a closed continuity epoch\");\n let rawPosition = current.rawPosition;\n const appendedRawPositions = new Set<number>();\n for (const record of batch.records) {\n if (record.agentId !== batch.agentId) throw new Error(\"Raw record targets another agent\");\n if (record.incarnationId !== batch.incarnationId) {\n throw new Error(\"Raw record targets another incarnation\");\n }\n if (record.position !== ++rawPosition) throw new Error(\"Raw record position is not contiguous\");\n appendedRawPositions.add(record.position);\n }\n let eventPosition = current.eventPosition;\n for (const stored of batch.events) {\n if (stored.agentId !== batch.agentId || stored.event.agentId !== batch.agentId) {\n throw new Error(\"Semantic event targets another agent\");\n }\n if (stored.event.epoch !== batch.epoch) throw new Error(\"Semantic event epoch mismatch\");\n if (stored.position !== ++eventPosition) {\n throw new Error(\"Semantic event position is not contiguous\");\n }\n if (!appendedRawPositions.has(stored.event.sourceRawPosition)) {\n throw new Error(\"Semantic event must reference a raw record from the same append and epoch\");\n }\n }\n if (\n batch.highWater.rawPosition !== rawPosition ||\n batch.highWater.eventPosition !== eventPosition\n ) {\n throw new Error(\"Journal high-water position does not match the append\");\n }\n if (\n batch.highWater.idleEventPosition !== null &&\n batch.highWater.idleEventPosition > eventPosition\n ) {\n throw new Error(\"Idle high-water position exceeds committed events\");\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["store", "dirname", "options", "dirname"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PiRuntimeIdentity } from "../protocol/pi-identity.js";
|
|
2
|
+
export type ExternalPiResolutionErrorCode = "invalid_arguments" | "pi_not_found" | "pi_not_executable" | "pi_version_unavailable" | "pi_installation_changed";
|
|
3
|
+
export declare class ExternalPiResolutionError extends Error {
|
|
4
|
+
readonly code: ExternalPiResolutionErrorCode;
|
|
5
|
+
constructor(code: ExternalPiResolutionErrorCode, message: string);
|
|
6
|
+
}
|
|
7
|
+
export interface PiInstallation {
|
|
8
|
+
readonly selectedPath: string;
|
|
9
|
+
readonly realPath: string;
|
|
10
|
+
readonly version: string;
|
|
11
|
+
readonly nodePath: string;
|
|
12
|
+
readonly fingerprint: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function installationIdentity(installation: PiInstallation): PiRuntimeIdentity;
|
|
15
|
+
export interface ExternalPiResolverOptions {
|
|
16
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
17
|
+
readonly nodePath?: string;
|
|
18
|
+
readonly versionCommand?: (executable: string) => Promise<string>;
|
|
19
|
+
readonly versionTimeoutMs?: number;
|
|
20
|
+
readonly maxVersionOutputBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function resolveExternalPiInstallation(options?: ExternalPiResolverOptions): Promise<PiInstallation>;
|
|
23
|
+
export declare function externalPiExecutionEnvironment(env: NodeJS.ProcessEnv, selectedPath: string, nodePath: string): NodeJS.ProcessEnv;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PiInstallation } from "../../pi/external-installation.js";
|
|
2
|
+
import { type ControlSocketOwnership } from "../shared/runtime-ownership.js";
|
|
3
|
+
export declare function ensureRuntime(options: {
|
|
4
|
+
readonly socketPath: string;
|
|
5
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
6
|
+
readonly timeoutMs?: number;
|
|
7
|
+
readonly sourceRoot?: string;
|
|
8
|
+
readonly applicationRoot?: string;
|
|
9
|
+
readonly home?: string;
|
|
10
|
+
readonly piInstallation?: () => Promise<PiInstallation | null>;
|
|
11
|
+
readonly registeredRuntimeStarter?: (env: NodeJS.ProcessEnv) => Promise<boolean>;
|
|
12
|
+
readonly inspectOwnership?: (socketPath: string) => Promise<ControlSocketOwnership>;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
export declare function installedServiceStateRoot(contents: string, platform: "linux" | "darwin"): string | undefined;
|
|
15
|
+
export declare class PiServiceMismatchError extends Error {
|
|
16
|
+
readonly code = "pi_service_mismatch";
|
|
17
|
+
constructor(message: string);
|
|
18
|
+
}
|
|
19
|
+
export declare function assertRegisteredPiSelection(options: {
|
|
20
|
+
readonly selectedPath: string;
|
|
21
|
+
readonly nodePath: string;
|
|
22
|
+
readonly home?: string;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
export declare function installedServicePiExecutable(contents: string, platform: "linux" | "darwin"): string | undefined;
|
|
25
|
+
export declare function installedServicePiNode(contents: string, platform: "linux" | "darwin"): string | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function materializeRuntime(options: {
|
|
2
|
+
readonly sourceRoot: string;
|
|
3
|
+
readonly applicationRoot: string;
|
|
4
|
+
readonly hooks?: {
|
|
5
|
+
readonly afterDependencyCopy?: () => Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
}): Promise<string>;
|
|
8
|
+
export declare function verifyRuntime(root: string): Promise<void>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface FleetPaths {
|
|
2
|
+
readonly runtimeRoot: string;
|
|
3
|
+
readonly stateRoot: string;
|
|
4
|
+
readonly socketPath: string;
|
|
5
|
+
readonly databasePath: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveApplicationRoot(env?: NodeJS.ProcessEnv): string;
|
|
8
|
+
export declare function resolveFleetPaths(env?: NodeJS.ProcessEnv): FleetPaths;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ControlSocketOwnership = "absent" | "stale" | "responsive" | "uncertain";
|
|
2
|
+
export type ControlSocketProbe = (socketPath: string) => Promise<Exclude<ControlSocketOwnership, "absent">>;
|
|
3
|
+
export declare class RuntimeOwnershipBlockedError extends Error {
|
|
4
|
+
readonly code = "runtime_upgrade_deferred";
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function inspectControlSocketOwnership(socketPath: string, probe?: ControlSocketProbe): Promise<ControlSocketOwnership>;
|
|
8
|
+
export declare function preflightRuntimeStartup(options: {
|
|
9
|
+
readonly socketPath: string;
|
|
10
|
+
readonly destructive: boolean;
|
|
11
|
+
readonly assertOwnedProcessTreesAbsent?: () => Promise<void>;
|
|
12
|
+
readonly inspectOwnership?: typeof inspectControlSocketOwnership;
|
|
13
|
+
}): Promise<ControlSocketOwnership>;
|
|
14
|
+
export declare function probeControlSocket(socketPath: string): Promise<Exclude<ControlSocketOwnership, "absent">>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Socket } from "node:net";
|
|
2
|
+
export declare function readJsonLines(socket: Socket, onValue: (value: unknown) => void, onError: (error: Error) => void, maxFrameBytes?: number): () => void;
|
|
3
|
+
export declare function writeJsonLine(socket: Socket, value: unknown): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Static } from "@sinclair/typebox";
|
|
2
|
+
export declare const MANAGED_PI_ARTIFACT_ID = "@earendil-works/pi-coding-agent@0.80.10";
|
|
3
|
+
export declare const PiRuntimeIdentitySchema: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
4
|
+
mode: import("@sinclair/typebox").TLiteral<"managed">;
|
|
5
|
+
artifactId: import("@sinclair/typebox").TString;
|
|
6
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
7
|
+
mode: import("@sinclair/typebox").TLiteral<"external">;
|
|
8
|
+
selectedPath: import("@sinclair/typebox").TString;
|
|
9
|
+
nodePath: import("@sinclair/typebox").TString;
|
|
10
|
+
realPath: import("@sinclair/typebox").TString;
|
|
11
|
+
version: import("@sinclair/typebox").TString;
|
|
12
|
+
fingerprint: import("@sinclair/typebox").TString;
|
|
13
|
+
}>]>;
|
|
14
|
+
export type PiRuntimeIdentity = Static<typeof PiRuntimeIdentitySchema>;
|
|
15
|
+
export declare const MANAGED_PI_RUNTIME_IDENTITY: PiRuntimeIdentity;
|
|
16
|
+
export declare function samePiRuntimeIdentity(left: PiRuntimeIdentity, right: PiRuntimeIdentity): boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AgentEventId, ReceiveCursor, SemanticEvent } from "../runtime/semantic-events.js";
|
|
2
|
+
export interface SemanticSegmentFrame {
|
|
3
|
+
readonly type: "semantic.segment";
|
|
4
|
+
readonly eventId: AgentEventId;
|
|
5
|
+
readonly precedingCursor: ReceiveCursor;
|
|
6
|
+
readonly eventCursor: ReceiveCursor;
|
|
7
|
+
readonly index: number;
|
|
8
|
+
readonly count: number;
|
|
9
|
+
readonly data: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ReassembledSemanticEvent {
|
|
12
|
+
readonly event: SemanticEvent;
|
|
13
|
+
readonly precedingCursor: ReceiveCursor;
|
|
14
|
+
}
|
|
15
|
+
export declare function segmentSemanticEvent(event: SemanticEvent, precedingCursor: ReceiveCursor, maxFrameBytes: number, maxSegments?: number): readonly SemanticSegmentFrame[];
|
|
16
|
+
export declare class SemanticEventReassembler {
|
|
17
|
+
#private;
|
|
18
|
+
constructor(maxEventBytes: number, maxSegments?: number);
|
|
19
|
+
push(frame: SemanticSegmentFrame): ReassembledSemanticEvent | null;
|
|
20
|
+
reset(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function serializedFrameBytes(frame: SemanticSegmentFrame): number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ActivityId, AgentId, ContinuityEpoch, ReceiveCursor } from "../client/contracts.js";
|
|
2
|
+
export type { ActivityId, AgentEventId, AgentId, AssistantMessageFinishedEvent, AssistantMessageStartedEvent, AssistantThinkingFinishedEvent, AssistantThinkingStartedEvent, ContinuityEpoch, ReceiveCursor, SemanticEvent, SemanticEventBase, ToolExecutionFinishedEvent, ToolExecutionStartedEvent, } from "../client/contracts.js";
|
|
3
|
+
export type IncarnationId = string & {
|
|
4
|
+
readonly __brand: "IncarnationId";
|
|
5
|
+
};
|
|
6
|
+
export interface RawRpcRecord {
|
|
7
|
+
readonly agentId: AgentId;
|
|
8
|
+
readonly incarnationId: IncarnationId;
|
|
9
|
+
readonly position: number;
|
|
10
|
+
readonly observedAt: string;
|
|
11
|
+
/** Exact complete stdout bytes, including the terminating LF. */
|
|
12
|
+
readonly bytes: Buffer;
|
|
13
|
+
}
|
|
14
|
+
export interface ReceiveBoundary {
|
|
15
|
+
readonly agentId: AgentId;
|
|
16
|
+
readonly epoch: ContinuityEpoch;
|
|
17
|
+
readonly cursor: ReceiveCursor;
|
|
18
|
+
}
|
|
19
|
+
export interface ProjectorState {
|
|
20
|
+
readonly version: 1;
|
|
21
|
+
/** Monotonic assistant-envelope generation used to isolate repeated content indexes. */
|
|
22
|
+
readonly messageSequence: number;
|
|
23
|
+
/** Completed indexes in the current envelope, retained only until message_end. */
|
|
24
|
+
readonly finishedThinkingIndexes: readonly number[];
|
|
25
|
+
readonly openActivities: readonly ProjectorActivity[];
|
|
26
|
+
}
|
|
27
|
+
export type ProjectorActivity = {
|
|
28
|
+
readonly kind: "thinking";
|
|
29
|
+
readonly activityId: ActivityId;
|
|
30
|
+
readonly messageSequence: number;
|
|
31
|
+
readonly contentIndex: number;
|
|
32
|
+
readonly text: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: "message";
|
|
35
|
+
readonly activityId: ActivityId;
|
|
36
|
+
readonly messageSequence: number;
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: "tool";
|
|
39
|
+
readonly activityId: ActivityId;
|
|
40
|
+
readonly callId: string;
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly input: unknown;
|
|
43
|
+
};
|