@astrosheep/keiyaku 2.9.3 → 2.9.5

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.
Files changed (282) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/agents/call-terms.js +14 -94
  3. package/build/agents/harness/activity-values.js +16 -0
  4. package/build/agents/harness/event-persistence.js +218 -0
  5. package/build/agents/harness/execution-handle.js +26 -222
  6. package/build/agents/harness/index.js +3 -1
  7. package/build/agents/harness/outcome.js +68 -5
  8. package/build/agents/harness/projection.js +179 -124
  9. package/build/agents/harness/provider-adapter.js +58 -0
  10. package/build/agents/harness/router.js +11 -187
  11. package/build/agents/harness/runtime.js +17 -4
  12. package/build/agents/harness/session.js +15 -0
  13. package/build/agents/launch-snapshot/model.js +15 -236
  14. package/build/agents/launch-snapshot/parse-helpers.js +114 -0
  15. package/build/agents/launch-snapshot/resolve.js +17 -43
  16. package/build/agents/opencode-sdk.js +45 -12
  17. package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
  18. package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
  19. package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
  20. package/build/agents/providers/codex-app-server/adapter.js +82 -53
  21. package/build/agents/providers/codex-app-server/events.js +90 -11
  22. package/build/agents/providers/codex-app-server/identity.js +1 -0
  23. package/build/agents/providers/codex-app-server/policy.js +29 -0
  24. package/build/agents/providers/codex-app-server/registration.js +248 -0
  25. package/build/agents/providers/codex-app-server/session-schema.js +6 -0
  26. package/build/agents/providers/codex-app-server/session.js +23 -17
  27. package/build/agents/providers/codex-app-server/terms.js +1 -0
  28. package/build/agents/providers/opencode-sdk/adapter.js +94 -50
  29. package/build/agents/providers/opencode-sdk/events.js +8 -4
  30. package/build/agents/providers/opencode-sdk/registration.js +135 -0
  31. package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
  32. package/build/agents/providers/opencode-sdk/session.js +21 -14
  33. package/build/agents/providers/opencode-sdk/terms.js +1 -0
  34. package/build/agents/providers/pi/adapter.js +36 -30
  35. package/build/agents/providers/pi/events.js +4 -3
  36. package/build/agents/providers/pi/registration.js +145 -0
  37. package/build/agents/providers/pi/session-schema.js +6 -0
  38. package/build/agents/providers/pi/terms.js +1 -0
  39. package/build/agents/providers/registration.js +7 -0
  40. package/build/agents/providers/registry.js +76 -0
  41. package/build/agents/selector.js +2 -29
  42. package/build/agents/types.js +10 -0
  43. package/build/artifact-directories.js +22 -0
  44. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  45. package/build/cli/commands/akuma/akuma/meta.js +1 -1
  46. package/build/cli/commands/akuma/list/meta-ls.js +1 -1
  47. package/build/cli/commands/akuma/view/handler.js +5 -4
  48. package/build/cli/commands/akuma/view/meta.js +1 -1
  49. package/build/cli/commands/akuma.js +6 -0
  50. package/build/cli/commands/contract/amend/handler.js +8 -2
  51. package/build/cli/commands/contract/amend/meta.js +4 -4
  52. package/build/cli/commands/contract/arc/handler.js +8 -2
  53. package/build/cli/commands/contract/arc/meta.js +4 -4
  54. package/build/cli/commands/contract/audit/handler.js +16 -0
  55. package/build/cli/commands/contract/audit/meta.js +16 -0
  56. package/build/cli/commands/contract/bind/handler.js +4 -3
  57. package/build/cli/commands/contract/bind/meta.js +44 -8
  58. package/build/cli/commands/contract/catalog.js +2 -0
  59. package/build/cli/commands/contract/forfeit/handler.js +4 -4
  60. package/build/cli/commands/contract/forfeit/meta.js +1 -1
  61. package/build/cli/commands/contract/log/handler.js +3 -3
  62. package/build/cli/commands/contract/log/meta.js +1 -1
  63. package/build/cli/commands/contract/petition/handler.js +5 -8
  64. package/build/cli/commands/contract/petition/meta.js +6 -6
  65. package/build/cli/commands/contract/renew/handler.js +20 -6
  66. package/build/cli/commands/contract/renew/meta.js +6 -5
  67. package/build/cli/commands/metadata.js +59 -0
  68. package/build/cli/commands/projection/call/handler.js +6 -5
  69. package/build/cli/commands/projection/call/meta.js +4 -1
  70. package/build/cli/commands/projection/kill/handler.js +16 -32
  71. package/build/cli/commands/projection/kill/meta.js +1 -1
  72. package/build/cli/commands/projection/revive/meta.js +4 -1
  73. package/build/cli/commands/projection/shared.js +28 -0
  74. package/build/cli/commands/projection/status/handler.js +1 -1
  75. package/build/cli/commands/projection/status/meta.js +1 -1
  76. package/build/cli/commands/projection/tell/handler.js +14 -30
  77. package/build/cli/commands/projection/tell/meta.js +4 -1
  78. package/build/cli/commands/projection/wait/handler.js +45 -22
  79. package/build/cli/commands/projection/wait/meta.js +8 -3
  80. package/build/cli/commands/registry.js +2 -54
  81. package/build/cli/commands/shared.js +10 -7
  82. package/build/cli/commands/skills/install/handler.js +2 -5
  83. package/build/cli/commands/skills/install/meta.js +1 -1
  84. package/build/cli/commands/skills/skills/handler.js +1 -1
  85. package/build/cli/commands/skills/skills/meta.js +1 -1
  86. package/build/cli/commands/system/completion/meta.js +1 -1
  87. package/build/cli/commands/system/dump-env/meta.js +1 -1
  88. package/build/cli/commands/system/guide/meta.js +1 -1
  89. package/build/cli/commands/task/add/handler.js +7 -15
  90. package/build/cli/commands/task/add/meta.js +4 -1
  91. package/build/cli/commands/task/catalog.js +2 -2
  92. package/build/cli/commands/task/doctor/meta.js +1 -1
  93. package/build/cli/commands/task/done/handler.js +4 -8
  94. package/build/cli/commands/task/done/meta.js +1 -1
  95. package/build/cli/commands/task/drop/handler.js +3 -6
  96. package/build/cli/commands/task/drop/meta.js +1 -1
  97. package/build/cli/commands/task/ls/handler.js +12 -8
  98. package/build/cli/commands/task/ls/meta.js +3 -3
  99. package/build/cli/commands/task/shared.js +14 -4
  100. package/build/cli/commands/task/{view → show}/handler.js +7 -8
  101. package/build/cli/commands/task/show/meta.js +8 -0
  102. package/build/cli/commands/task/start/handler.js +3 -6
  103. package/build/cli/commands/task/start/meta.js +1 -1
  104. package/build/cli/commands/task/stop/handler.js +4 -8
  105. package/build/cli/commands/task/stop/meta.js +1 -1
  106. package/build/cli/commands/task/task/handler.js +1 -1
  107. package/build/cli/commands/task/task/meta.js +1 -1
  108. package/build/cli/commands/task/update/handler.js +6 -11
  109. package/build/cli/commands/task/update/meta.js +4 -1
  110. package/build/cli/completion.js +1 -1
  111. package/build/cli/flags.js +37 -6
  112. package/build/cli/help.js +7 -14
  113. package/build/cli/index.js +112 -154
  114. package/build/cli/missing-subcommand.js +7 -0
  115. package/build/cli/output-stream-error-policy.js +19 -5
  116. package/build/cli/parse-flags.js +33 -7
  117. package/build/cli/parse-metadata.js +3 -9
  118. package/build/cli/parse-selectors.js +2 -1
  119. package/build/cli/parse.js +35 -5
  120. package/build/cli/projection-address.js +12 -12
  121. package/build/cli/render/address.js +41 -37
  122. package/build/cli/render/arc.js +24 -12
  123. package/build/cli/render/audit.js +121 -0
  124. package/build/cli/render/call.js +11 -5
  125. package/build/cli/render/errors.js +36 -1
  126. package/build/cli/render/format.js +4 -0
  127. package/build/cli/render/kanshi.js +6 -12
  128. package/build/cli/render/kill.js +9 -0
  129. package/build/cli/render/misc.js +58 -13
  130. package/build/cli/render/petition.js +20 -15
  131. package/build/cli/render/projection-activity.js +15 -6
  132. package/build/cli/render/shared.js +60 -21
  133. package/build/cli/render/skills.js +10 -0
  134. package/build/cli/render/status.js +56 -23
  135. package/build/cli/render/success-response.js +78 -0
  136. package/build/cli/render/task.js +66 -57
  137. package/build/cli/render/tell.js +5 -0
  138. package/build/cli/render/terminal-failure.js +63 -0
  139. package/build/cli/render/types.js +1 -0
  140. package/build/cli/render/wait.js +68 -38
  141. package/build/cli/types.js +1 -1
  142. package/build/config/akuma-loader.js +0 -5
  143. package/build/config/env-keys.js +3 -1
  144. package/build/config/env.js +3 -0
  145. package/build/config/provider-policy-ownership.js +3 -32
  146. package/build/config/settings/disease.js +8 -1
  147. package/build/config/settings/loader.js +11 -3
  148. package/build/config/settings/provider-instance-fields.js +51 -0
  149. package/build/config/settings/schema.js +6 -176
  150. package/build/core/addressing.js +66 -16
  151. package/build/core/amend.js +61 -18
  152. package/build/core/arc.js +33 -73
  153. package/build/core/audit.js +650 -0
  154. package/build/core/bind.js +82 -35
  155. package/build/core/call/call.js +15 -9
  156. package/build/core/call/context.js +6 -51
  157. package/build/core/call/execution.js +22 -22
  158. package/build/core/call/prompt.js +14 -1
  159. package/build/core/command-markdown.js +45 -0
  160. package/build/core/context.js +13 -7
  161. package/build/core/contract-view.js +22 -6
  162. package/build/core/draft.js +139 -19
  163. package/build/core/entry.js +3 -4
  164. package/build/core/forfeit.js +5 -2
  165. package/build/core/hints.js +1 -75
  166. package/build/core/identifier-slug.js +66 -0
  167. package/build/core/ids.js +25 -11
  168. package/build/core/ledger.js +20 -68
  169. package/build/core/markdown/lex.js +2 -1
  170. package/build/core/markdown/parser.js +0 -68
  171. package/build/core/markdown/render.js +68 -0
  172. package/build/core/markdown/sections.js +2 -1
  173. package/build/core/outcome-base.js +4 -0
  174. package/build/core/projection/generation/database.js +41 -52
  175. package/build/core/projection/generation/model.js +63 -2
  176. package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
  177. package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +36 -53
  178. package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
  179. package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +9 -7
  180. package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
  181. package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +19 -3
  182. package/build/core/projection/generation/store.js +3 -3
  183. package/build/core/projection/generation/transitions.js +19 -3
  184. package/build/core/projection/index.js +27 -0
  185. package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
  186. package/build/core/{projection-alias.js → projection/projection-alias.js} +13 -13
  187. package/build/core/projection/projection-coordinate.js +61 -0
  188. package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
  189. package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +37 -78
  190. package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
  191. package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
  192. package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +16 -2
  193. package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
  194. package/build/core/{projection-status.js → projection/projection-status.js} +163 -45
  195. package/build/core/projection/projection-terminal-failure.js +106 -0
  196. package/build/core/projection/projection-wait.js +275 -0
  197. package/build/core/projection/projection-wake.js +227 -0
  198. package/build/core/provider-loader-ports.js +4 -0
  199. package/build/core/ref-log.js +65 -40
  200. package/build/core/registry.js +63 -10
  201. package/build/core/renew-session.js +128 -0
  202. package/build/core/renew.js +448 -102
  203. package/build/core/scope.js +272 -68
  204. package/build/core/seal.js +165 -40
  205. package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +8 -8
  206. package/build/core/{claim.js → settlement/claim.js} +32 -8
  207. package/build/core/settlement/index.js +19 -0
  208. package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +24 -49
  209. package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
  210. package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
  211. package/build/core/settlement/petition-io.js +1 -0
  212. package/build/core/{petition-preview.js → settlement/petition-preview.js} +2 -2
  213. package/build/core/{petition.js → settlement/petition.js} +21 -12
  214. package/build/core/settlement/queue-read-model.js +143 -0
  215. package/build/core/settlement/queue-seat-allocation.js +156 -0
  216. package/build/core/settlement/queue.js +6 -0
  217. package/build/core/settlement/settlement.js +288 -0
  218. package/build/core/{verdict.js → settlement/verdict.js} +9 -37
  219. package/build/core/settlement/verification.js +59 -0
  220. package/build/core/status/board.js +62 -41
  221. package/build/core/status/ledger-batch.js +158 -0
  222. package/build/core/status/reconciliation.js +10 -4
  223. package/build/core/stored-agent-event.js +6 -2
  224. package/build/core/task/board.js +41 -4
  225. package/build/core/task/commands.js +45 -28
  226. package/build/core/task/document.js +5 -0
  227. package/build/core/task/index.js +12 -0
  228. package/build/core/task/model.js +8 -1
  229. package/build/core/task/query.js +172 -0
  230. package/build/core/task/settlement-git.js +265 -74
  231. package/build/core/task/settlement-policy.js +67 -29
  232. package/build/core/task/source-board.js +1 -0
  233. package/build/core/task/task-contract.js +444 -0
  234. package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
  235. package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
  236. package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
  237. package/build/core/{task-git-store.js → task/task-git-store.js} +90 -19
  238. package/build/core/task/task-repository.js +1 -0
  239. package/build/core/{task-store-repository.js → task/task-store-repository.js} +6 -4
  240. package/build/core/task/task-store.js +1 -0
  241. package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
  242. package/build/core/task/task.js +7 -0
  243. package/build/core/task/tree.js +37 -0
  244. package/build/core/task/validation.js +5 -2
  245. package/build/core/transcripts.js +15 -3
  246. package/build/core/worktree-path.js +43 -28
  247. package/build/flow-error.js +83 -39
  248. package/build/fs/path-coordinate.js +16 -0
  249. package/build/generated/version.js +3 -2
  250. package/build/git/branches.js +2 -1
  251. package/build/git/core.js +106 -2
  252. package/build/git/diff/parsers.js +23 -13
  253. package/build/git/diff/structured.js +127 -0
  254. package/build/git/path-coordinate.js +17 -0
  255. package/build/git/refs.js +57 -0
  256. package/build/git/streaming-batch.js +301 -0
  257. package/build/git/worktree.js +65 -0
  258. package/build/index.js +9 -9
  259. package/build/keiyaku.js +2 -36
  260. package/build/telemetry/logger.js +4 -2
  261. package/package.json +4 -10
  262. package/skills/keiyaku/SKILL.md +5 -4
  263. package/skills/keiyaku-akuma/SKILL.md +25 -11
  264. package/skills/keiyaku-task/SKILL.md +17 -8
  265. package/skills/keiyaku-workflow/SKILL.md +58 -9
  266. package/build/agents/providers/codex-sdk.js +0 -329
  267. package/build/cli/commands/task/view/meta.js +0 -8
  268. package/build/core/command-io.js +0 -174
  269. package/build/core/path-coordinate.js +0 -27
  270. package/build/core/petition-claim.js +0 -117
  271. package/build/core/petition-run.js +0 -83
  272. package/build/core/projection-coordinate.js +0 -63
  273. package/build/core/projection-wait.js +0 -165
  274. package/build/core/projection-wake.js +0 -136
  275. package/build/core/queue.js +0 -343
  276. package/build/core/task-contract.js +0 -237
  277. package/build/core/task.js +0 -4
  278. /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
  279. /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
  280. /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
  281. /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
  282. /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
@@ -0,0 +1,68 @@
1
+ function renderListItemFirstLine(item) {
2
+ const content = renderNodeContent(item);
3
+ if (!content) {
4
+ return `${" ".repeat(item.indent)}${item.marker}`;
5
+ }
6
+ const [firstLine, ...rest] = content.split("\n");
7
+ const prefix = `${" ".repeat(item.indent)}${item.marker}${firstLine.length > 0 ? " " : ""}${firstLine}`;
8
+ if (rest.length === 0) {
9
+ return prefix;
10
+ }
11
+ return [prefix, ...rest].join("\n");
12
+ }
13
+ export function renderBlock(node) {
14
+ switch (node.type) {
15
+ case "section": {
16
+ const header = `${"#".repeat(node.level)} ${node.title}`;
17
+ const body = renderNodeContent(node);
18
+ return body ? `${header}\n${body}` : header;
19
+ }
20
+ case "list":
21
+ return node.items.map((item) => renderListItemFirstLine(item)).join("\n");
22
+ case "code_block":
23
+ return node.lines.join("\n");
24
+ case "blockquote":
25
+ return node.lines.map((line) => `${node.marker}${line}`).join("\n");
26
+ case "text":
27
+ return node.value;
28
+ case "heading":
29
+ return `${"#".repeat(node.level)} ${node.text}`;
30
+ }
31
+ }
32
+ export function renderNodeContent(node) {
33
+ switch (node.type) {
34
+ case "document":
35
+ return node.children.map((child) => renderBlock(child)).join("\n");
36
+ case "section":
37
+ return node.children.map((child) => renderBlock(child)).join("\n");
38
+ case "list":
39
+ return renderBlock(node);
40
+ case "list_item":
41
+ return node.children.map((child) => renderBlock(child)).join("\n");
42
+ case "code_block":
43
+ return node.lines.join("\n");
44
+ case "blockquote":
45
+ return node.lines.map((line) => `${node.marker}${line}`).join("\n");
46
+ case "text":
47
+ return node.value;
48
+ case "heading":
49
+ return `${"#".repeat(node.level)} ${node.text}`;
50
+ }
51
+ }
52
+ export function renderSectionContent(sectionNode) {
53
+ return sectionNode.children.map((child) => renderBlock(child)).join("\n");
54
+ }
55
+ export function extractListItems(sectionNode) {
56
+ const items = [];
57
+ for (const child of sectionNode.children) {
58
+ if (child.type !== "list")
59
+ continue;
60
+ for (const item of child.items) {
61
+ const rendered = renderNodeContent(item).trimEnd();
62
+ if (rendered.trim().length > 0) {
63
+ items.push(rendered);
64
+ }
65
+ }
66
+ }
67
+ return items;
68
+ }
@@ -1,4 +1,5 @@
1
- import { extractListItems, parseToAST, renderBlock, renderSectionContent } from "./parser.js";
1
+ import { parseToAST } from "./parser.js";
2
+ import { extractListItems, renderBlock, renderSectionContent } from "./render.js";
2
3
  import { KeiyakuParseError } from "./types.js";
3
4
  import { normalizeSectionTitle } from "./titles.js";
4
5
  function splitByHeadingBlocks(sectionNode) {
@@ -0,0 +1,4 @@
1
+ import { ACTOR_IDENTITY } from "../keiyaku.js";
2
+ export function defaultActorClock(nowMs = Date.now()) {
3
+ return { actor: ACTOR_IDENTITY, nowMs };
4
+ }
@@ -57,11 +57,40 @@ const TELL_TABLE_SQL = `
57
57
  ) STRICT
58
58
  `;
59
59
  const closedDatabases = new WeakSet();
60
+ /** Classify only proved missing schema evidence as historical incompatibility. */
61
+ export function projectionGenerationStoreInspectionError(databasePath, error) {
62
+ if (error instanceof ProjectionGenerationStoreError)
63
+ return error;
64
+ const code = error && typeof error === "object" && "code" in error
65
+ ? error.code
66
+ : undefined;
67
+ if (code === "ENOENT") {
68
+ return new ProjectionGenerationStoreError(`projection generation store does not exist at ${databasePath}`, {
69
+ cause: error,
70
+ observation: "incompatible",
71
+ });
72
+ }
73
+ return new ProjectionGenerationStoreError(`projection generation store could not be inspected at ${databasePath}`, {
74
+ cause: error,
75
+ });
76
+ }
77
+ function projectionGenerationStoreReadError(databasePath, error) {
78
+ if (error instanceof ProjectionGenerationStoreError)
79
+ return error;
80
+ const sqliteCode = error && typeof error === "object" && "errcode" in error
81
+ ? error.errcode
82
+ : undefined;
83
+ const incompatible = sqliteCode === 11 || sqliteCode === 26;
84
+ return new ProjectionGenerationStoreError(`cannot read projection generation store at ${databasePath}`, {
85
+ cause: error,
86
+ ...(incompatible ? { observation: "incompatible" } : {}),
87
+ });
88
+ }
60
89
  function pragmaNumber(database, pragma) {
61
90
  const row = database.prepare(`PRAGMA ${pragma}`).get();
62
91
  const value = row ? Object.values(row)[0] : undefined;
63
92
  if (typeof value !== "number" && typeof value !== "bigint") {
64
- throw new ProjectionGenerationStoreError(`PRAGMA ${pragma} returned an invalid value`);
93
+ throw new ProjectionGenerationStoreError(`PRAGMA ${pragma} returned an invalid value`, { observation: "incompatible" });
65
94
  }
66
95
  return Number(value);
67
96
  }
@@ -76,7 +105,7 @@ export function rollbackQuietly(database) {
76
105
  function validateSchemaShape(database) {
77
106
  const version = pragmaNumber(database, "user_version");
78
107
  if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
79
- throw new ProjectionGenerationStoreError(`projection generation schema version ${version} is not supported; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
108
+ throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`, { observation: "incompatible" });
80
109
  }
81
110
  const objects = database.prepare(`
82
111
  SELECT name, type
@@ -86,36 +115,36 @@ function validateSchemaShape(database) {
86
115
  `).all();
87
116
  const signature = objects.map((object) => `${object.type}:${object.name}`).join(",");
88
117
  if (signature !== "table:generation_records,table:generation_schema,table:projection_identity,table:projection_tells") {
89
- throw new ProjectionGenerationStoreError(`projection generation schema contains unexpected objects: ${signature || "none"}`);
118
+ throw new ProjectionGenerationStoreError(`projection generation schema contains unexpected objects: ${signature || "none"}`, { observation: "incompatible" });
90
119
  }
91
120
  const metadata = database.prepare("SELECT singleton, version FROM generation_schema").all();
92
121
  if (metadata.length !== 1 || Number(metadata[0].singleton) !== 1 || Number(metadata[0].version) !== PROJECTION_GENERATION_SCHEMA_VERSION) {
93
- throw new ProjectionGenerationStoreError("projection generation schema metadata is malformed");
122
+ throw new ProjectionGenerationStoreError("projection generation schema metadata is malformed", { observation: "incompatible" });
94
123
  }
95
124
  const recordColumns = database.prepare("PRAGMA table_info(generation_records)").all();
96
125
  const columnSignature = recordColumns
97
126
  .map((column) => `${column.name}:${column.type}:${Number(column.notnull)}:${Number(column.pk)}`)
98
127
  .join(",");
99
128
  if (columnSignature !== "seq:INTEGER:0:1,kind:TEXT:1:0,execution_id:TEXT:1:0,facts_json:TEXT:1:0") {
100
- throw new ProjectionGenerationStoreError("projection generation record schema is malformed");
129
+ throw new ProjectionGenerationStoreError("projection generation record schema is malformed", { observation: "incompatible" });
101
130
  }
102
131
  const identityColumns = database.prepare("PRAGMA table_info(projection_identity)").all();
103
132
  const identitySignature = identityColumns
104
133
  .map((column) => `${column.name}:${column.type}:${Number(column.notnull)}:${Number(column.pk)}`)
105
134
  .join(",");
106
135
  if (identitySignature !== "singleton:INTEGER:0:1,version:INTEGER:1:0,pid:INTEGER:1:0,akuma:TEXT:1:0,provider:TEXT:1:0,authority_json:TEXT:1:0,binding_json:TEXT:1:0,minted_at:TEXT:1:0,workspace_root:TEXT:1:0,effective_policy_json:TEXT:0:0") {
107
- throw new ProjectionGenerationStoreError("projection identity schema is malformed");
136
+ throw new ProjectionGenerationStoreError("projection identity schema is malformed", { observation: "incompatible" });
108
137
  }
109
138
  const tellColumns = database.prepare("PRAGMA table_info(projection_tells)").all();
110
139
  const tellSignature = tellColumns
111
140
  .map((column) => `${column.name}:${column.type}:${Number(column.notnull)}:${Number(column.pk)}`)
112
141
  .join(",");
113
142
  if (tellSignature !== "tell_id:TEXT:1:1,text:TEXT:1:0,created_at:TEXT:1:0,effort:TEXT:0:0,state:TEXT:1:0,execution_id:TEXT:0:0,fence_json:TEXT:0:0,replayed_from_json:TEXT:0:0,delivered_at:TEXT:0:0") {
114
- throw new ProjectionGenerationStoreError("projection tell schema is malformed");
143
+ throw new ProjectionGenerationStoreError("projection tell schema is malformed", { observation: "incompatible" });
115
144
  }
116
145
  const quickCheck = database.prepare("PRAGMA quick_check").get();
117
146
  if (!quickCheck || Object.values(quickCheck)[0] !== "ok") {
118
- throw new ProjectionGenerationStoreError("projection generation database failed quick_check");
147
+ throw new ProjectionGenerationStoreError("projection generation database failed quick_check", { observation: "incompatible" });
119
148
  }
120
149
  }
121
150
  function initializeOrValidateSchema(database) {
@@ -138,7 +167,7 @@ function initializeOrValidateSchema(database) {
138
167
  database.exec(`PRAGMA user_version = ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
139
168
  }
140
169
  else if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
141
- throw new ProjectionGenerationStoreError(`projection generation schema version ${version} is not supported; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
170
+ throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`, { observation: "incompatible" });
142
171
  }
143
172
  validateSchemaShape(database);
144
173
  database.exec("COMMIT");
@@ -195,13 +224,11 @@ export function openReadOnlyDatabase(projectionDirectory) {
195
224
  const databasePath = path.join(projectionDirectory, PROJECTION_GENERATION_STORE_FILE);
196
225
  try {
197
226
  if (!fs.lstatSync(databasePath).isFile()) {
198
- throw new ProjectionGenerationStoreError("projection generation store must be a regular file");
227
+ throw new ProjectionGenerationStoreError("projection generation store must be a regular file", { observation: "incompatible" });
199
228
  }
200
229
  }
201
230
  catch (error) {
202
- if (error instanceof ProjectionGenerationStoreError)
203
- throw error;
204
- throw new ProjectionGenerationStoreError(`projection generation store does not exist at ${databasePath}`, { cause: error });
231
+ throw projectionGenerationStoreInspectionError(databasePath, error);
205
232
  }
206
233
  let database;
207
234
  try {
@@ -220,9 +247,7 @@ export function openReadOnlyDatabase(projectionDirectory) {
220
247
  database?.close();
221
248
  }
222
249
  catch { /* preserve the read/open failure */ }
223
- if (error instanceof ProjectionGenerationStoreError)
224
- throw error;
225
- throw new ProjectionGenerationStoreError(`cannot read projection generation store at ${databasePath}`, { cause: error });
250
+ throw projectionGenerationStoreReadError(databasePath, error);
226
251
  }
227
252
  }
228
253
  export function assertDatabaseOpen(database) {
@@ -268,39 +293,3 @@ export function closeDatabase(database) {
268
293
  closedDatabases.add(database);
269
294
  database.close();
270
295
  }
271
- /**
272
- * Discovery-only predicate: a readable regular heart whose PRAGMA user_version
273
- * is exactly 1 is recognized historical residue. Never opens through the store
274
- * class, never mutates, and any observation failure returns false so callers
275
- * proceed into the strict current-schema reader.
276
- */
277
- export function isProjectionGenerationSchemaV1Residue(projectionDirectory) {
278
- const databasePath = path.join(projectionDirectory, PROJECTION_GENERATION_STORE_FILE);
279
- let database;
280
- let residue = false;
281
- try {
282
- if (!fs.lstatSync(databasePath).isFile())
283
- return false;
284
- database = new DatabaseSync(databasePath, {
285
- readOnly: true,
286
- enableDoubleQuotedStringLiterals: false,
287
- allowExtension: false,
288
- });
289
- configureHeartBusyTimeout(database);
290
- residue = pragmaNumber(database, "user_version") === 1;
291
- }
292
- catch {
293
- return false;
294
- }
295
- finally {
296
- if (database) {
297
- try {
298
- database.close();
299
- }
300
- catch {
301
- residue = false;
302
- }
303
- }
304
- }
305
- return residue;
306
- }
@@ -1,13 +1,30 @@
1
- import { GENERATION_VERDICT_STATES, } from "../../projection-life-protocol.js";
1
+ import { GENERATION_VERDICT_STATES, } from "../projection-life-protocol.js";
2
+ import { OUTCOME_ERROR_VERSION, SUBAGENT_FAILURE_CODES } from "../../../agents/types.js";
2
3
  export { GENERATION_VERDICT_STATES };
3
4
  export const VERDICTS = new Set(GENERATION_VERDICT_STATES);
5
+ const OUTCOME_ERROR_CODES = new Set(SUBAGENT_FAILURE_CODES);
6
+ const OUTCOME_ERROR_KEYS = new Set([
7
+ "version",
8
+ "code",
9
+ "message",
10
+ "timeoutMs",
11
+ "exitCode",
12
+ "publicCause",
13
+ ]);
4
14
  export class ProjectionGenerationStoreError extends Error {
5
15
  code = "PROJECTION_GENERATION_STORE_ERROR";
16
+ /** Historical schemas/outcomes are not a current lifecycle observation. */
17
+ observation;
6
18
  constructor(message, options) {
7
19
  super(message, options);
8
20
  this.name = "ProjectionGenerationStoreError";
21
+ this.observation = options?.observation ?? "unknown";
9
22
  }
10
23
  }
24
+ export function isIncompatibleProjectionGenerationStoreError(error) {
25
+ return error instanceof ProjectionGenerationStoreError
26
+ && error.observation === "incompatible";
27
+ }
11
28
  export function isPlainObject(value) {
12
29
  if (value === null || typeof value !== "object" || Array.isArray(value))
13
30
  return false;
@@ -121,6 +138,40 @@ export function validateVerdictFacts(value, location) {
121
138
  if (typeof facts.state !== "string" || !VERDICTS.has(facts.state)) {
122
139
  throw new ProjectionGenerationStoreError(`${location}.state is not in the closed verdict vocabulary`);
123
140
  }
141
+ if (facts.terminalAt !== undefined) {
142
+ facts.terminalAt = assertIsoTimestamp(facts.terminalAt, `${location}.terminalAt`);
143
+ }
144
+ if (facts.state === "failed") {
145
+ const error = isPlainObject(facts.error) ? facts.error : undefined;
146
+ const version = error?.version;
147
+ if (!error || version !== OUTCOME_ERROR_VERSION) {
148
+ throw new ProjectionGenerationStoreError(`${location}.error has incompatible version ${version === undefined ? "missing" : String(version)}; expected ${OUTCOME_ERROR_VERSION}`, { observation: "incompatible" });
149
+ }
150
+ if (Object.keys(error).some((key) => !OUTCOME_ERROR_KEYS.has(key))) {
151
+ throw new ProjectionGenerationStoreError(`${location}.error is not the current closed OutcomeError shape`);
152
+ }
153
+ if (typeof error.code !== "string" || !OUTCOME_ERROR_CODES.has(error.code)) {
154
+ throw new ProjectionGenerationStoreError(`${location}.error.code is not a recognized subagent failure code`);
155
+ }
156
+ if (typeof error.message !== "string") {
157
+ throw new ProjectionGenerationStoreError(`${location}.error.message must be a string`);
158
+ }
159
+ if (error.timeoutMs !== null && (typeof error.timeoutMs !== "number"
160
+ || !Number.isSafeInteger(error.timeoutMs)
161
+ || error.timeoutMs < 0)) {
162
+ throw new ProjectionGenerationStoreError(`${location}.error.timeoutMs must be null or a non-negative safe integer`);
163
+ }
164
+ if (error.exitCode !== null && (typeof error.exitCode !== "number"
165
+ || !Number.isSafeInteger(error.exitCode))) {
166
+ throw new ProjectionGenerationStoreError(`${location}.error.exitCode must be null or a safe integer`);
167
+ }
168
+ if (error.publicCause !== undefined) {
169
+ const cause = isPlainObject(error.publicCause) ? error.publicCause : undefined;
170
+ if (!cause || cause.kind !== "rate_limit_exhausted" || Object.keys(cause).length !== 1) {
171
+ throw new ProjectionGenerationStoreError(`${location}.error.publicCause is not a current closed cause`);
172
+ }
173
+ }
174
+ }
124
175
  return facts;
125
176
  }
126
177
  export function parseStoredRow(row) {
@@ -140,7 +191,7 @@ export function parseStoredRow(row) {
140
191
  decoded = JSON.parse(row.facts_json);
141
192
  }
142
193
  catch (error) {
143
- throw new ProjectionGenerationStoreError(`generation row ${seq} contains malformed facts JSON`, { cause: error });
194
+ throw new ProjectionGenerationStoreError(`generation row ${seq} contains malformed facts JSON`, { cause: error, observation: "incompatible" });
144
195
  }
145
196
  const location = `generation row ${seq} facts`;
146
197
  const facts = row.kind === "launch"
@@ -199,3 +250,13 @@ export function validateHistory(records) {
199
250
  }
200
251
  return current;
201
252
  }
253
+ export function extractTerminalTimestamp(facts) {
254
+ if (!facts)
255
+ return undefined;
256
+ for (const key of ["completedAt", "failedAt", "dismissedAt", "killedAt", "terminalAt"]) {
257
+ const value = facts[key];
258
+ if (typeof value === "string" && Number.isFinite(Date.parse(value)))
259
+ return value;
260
+ }
261
+ return undefined;
262
+ }
@@ -1,6 +1,6 @@
1
- import { ProjectionStateError } from "./atomic-publish.js";
2
- import { applySnapshotEffort, parseResolvedAkumaLaunchSnapshot, } from "../agents/launch-snapshot/model.js";
3
- import { listTellIds, readTellOriginal, readTellSubmitted, } from "./projection-core.js";
1
+ import { ProjectionStateError } from "../../atomic-publish.js";
2
+ import { applySnapshotEffort, parseResolvedAkumaLaunchSnapshot, } from "../../../agents/launch-snapshot/model.js";
3
+ import { listTellIds, readTellOriginal, readTellSubmitted, } from "../projection-core.js";
4
4
  export function snapshotPendingTells(projectionDirectory) {
5
5
  const pending = ["inbox", "inflight", "submitted"]
6
6
  .flatMap((layer) => listTellIds(projectionDirectory, layer)
@@ -1,12 +1,13 @@
1
- import { initializeConfig } from "../config/env.js";
2
- import { buildCallTerms } from "../agents/call-terms.js";
3
- import { parseResolvedAkumaLaunchSnapshot, } from "../agents/launch-snapshot/model.js";
4
- import { revive, call, } from "../agents/harness/index.js";
5
- import { demoteSubmittedTellsForReplay, readProjectionEvents, } from "./projection-core.js";
6
- import { createProjectionExecutionObserver, createReplayRunStartGate, markReplayCompleted, snapshotReplayPrompt, } from "./projection-execution-observer.js";
7
- import { readProjectionIdentity } from "./projection-identity.js";
8
- import { selectValidStoredAgentEvents } from "./stored-agent-event.js";
9
- import { persistResponseHistory } from "./transcripts.js";
1
+ import { initializeConfig } from "../../../config/env.js";
2
+ import { buildCallTerms } from "../../../agents/call-terms.js";
3
+ import { parseResolvedAkumaLaunchSnapshot } from "../../../agents/launch-snapshot/model.js";
4
+ import { revive, call, } from "../../../agents/harness/index.js";
5
+ import { claimFencedTells, demoteSubmittedTellsForReplay, readTellOriginal, readProjectionEvents, } from "../projection-core.js";
6
+ import { createProjectionExecutionObserver, renderProjectionTellFrame, } from "../projection-execution-observer.js";
7
+ import { readProjectionIdentity } from "../projection-identity.js";
8
+ import { selectValidStoredAgentEvents } from "../../stored-agent-event.js";
9
+ import { persistResponseHistory } from "../../transcripts.js";
10
+ import { attachProviderLoaderPorts, } from "../../provider-loader-ports.js";
10
11
  function isObject(value) {
11
12
  return value !== null && typeof value === "object" && !Array.isArray(value);
12
13
  }
@@ -57,6 +58,7 @@ function parseLaunchInputs(launch) {
57
58
  ...(context ? { context } : {}),
58
59
  launchSnapshot,
59
60
  idleTimeoutMs: requirePositiveSafeInteger(raw.idleTimeoutMs, "idleTimeoutMs"),
61
+ executionTimeoutMs: requirePositiveSafeInteger(raw.executionTimeoutMs, "executionTimeoutMs"),
60
62
  persistProjectionResponse: raw.persistProjectionResponse,
61
63
  ...(raw.session ? { session: raw.session } : {}),
62
64
  ...(resumePath ? { resumePath } : {}),
@@ -134,66 +136,47 @@ async function completionFacts(projectionDirectory, executionId, inputs, outcome
134
136
  * Construct the public Projection once and expose a provider-neutral execution
135
137
  * handle. Provider adapters and harness public types are unchanged.
136
138
  */
137
- export function executeProjectionGeneration(projectionDirectory, launch) {
139
+ export function executeProjectionGeneration(projectionDirectory, launch, providerLoaderPorts = {}) {
138
140
  const inputs = parseLaunchInputs(launch);
139
141
  initializeConfig(process.env, inputs.cwd);
140
142
  const executionId = launch.executionId;
141
- const tellFence = launch.facts.tellFence ?? [];
142
143
  demoteSubmittedTellsForReplay(projectionDirectory, executionId);
143
- const baseTerms = buildCallTerms(inputs.launchSnapshot, inputs.prompt, inputs.cwd, {
144
+ const initialTellIds = claimFencedTells(projectionDirectory, launch.facts.tellFence ?? [], executionId);
145
+ const tellPrompt = initialTellIds.map((tellId) => {
146
+ const tell = readTellOriginal(projectionDirectory, "inflight", tellId);
147
+ return renderProjectionTellFrame(tellId, tell.text);
148
+ }).join("\n\n");
149
+ const prompt = tellPrompt === ""
150
+ ? inputs.prompt
151
+ : inputs.session
152
+ ? tellPrompt
153
+ : `${inputs.prompt}\n\n${tellPrompt}`;
154
+ const terms = attachProviderLoaderPorts(buildCallTerms(inputs.launchSnapshot, prompt, inputs.cwd, {
144
155
  idleTimeoutMs: inputs.idleTimeoutMs,
156
+ executionTimeoutMs: inputs.executionTimeoutMs,
145
157
  initialTurn: maximumValidEnvelopeTurn(projectionDirectory),
146
- });
147
- const launchSnapshot = baseTerms.provider === "codex-sdk"
148
- ? snapshotReplayPrompt(projectionDirectory, baseTerms.prompt, tellFence, executionId, {
149
- sessionContinuationPromptPrefix: inputs.session && inputs.resumePath
150
- ? baseTerms.sessionContinuationPromptPrefix
151
- : undefined,
152
- })
153
- : undefined;
154
- const terms = launchSnapshot
155
- ? baseTerms.provider === "codex-sdk" && launchSnapshot.effort
156
- ? {
157
- ...baseTerms,
158
- prompt: launchSnapshot.prompt,
159
- threadOptions: {
160
- ...baseTerms.threadOptions,
161
- modelReasoningEffort: launchSnapshot.effort,
162
- },
163
- }
164
- : { ...baseTerms, prompt: launchSnapshot.prompt }
165
- : baseTerms;
166
- // A constructed driver is not an SDK run acknowledgement. Tier-2 has no
167
- // live steer surface, so the first provider event is the earliest harness
168
- // observable start; a successful no-event completion is the only fallback.
169
- const replayStartGate = launchSnapshot
170
- ? createReplayRunStartGate(projectionDirectory, executionId, launchSnapshot.tellIds)
171
- : undefined;
158
+ }), providerLoaderPorts);
172
159
  const observerController = createProjectionExecutionObserver({
173
160
  projectionDirectory,
174
161
  executionId,
175
- ...(replayStartGate ? { replayStartGate } : {}),
162
+ initialTellIds,
176
163
  });
177
164
  let projection;
178
165
  try {
179
- projection = inputs.session && inputs.resumePath
180
- ? revive({ ...terms, session: inputs.session, resumePath: inputs.resumePath }, { observer: observerController.observer })
166
+ projection = inputs.session
167
+ ? revive({
168
+ ...terms,
169
+ session: inputs.session,
170
+ resumePath: inputs.resumePath ?? projectionDirectory,
171
+ }, { observer: observerController.observer })
181
172
  : call(terms, { observer: observerController.observer });
182
173
  }
183
174
  catch (error) {
184
- observerController.close();
175
+ void observerController.close();
185
176
  throw error;
186
177
  }
187
178
  const outcome = projection.outcome.then(async (result) => {
188
179
  try {
189
- if (result.status === "completed") {
190
- // A provider may complete successfully without emitting any observable
191
- // events. Its successful completion is still a real run start.
192
- replayStartGate?.observeSuccessfulCompletion();
193
- if (launchSnapshot) {
194
- markReplayCompleted(projectionDirectory, executionId);
195
- }
196
- }
197
180
  return {
198
181
  verdict: result.status === "completed"
199
182
  ? "completed"
@@ -204,10 +187,10 @@ export function executeProjectionGeneration(projectionDirectory, launch) {
204
187
  };
205
188
  }
206
189
  finally {
207
- observerController.close();
190
+ await observerController.close();
208
191
  }
209
- }, (error) => {
210
- observerController.close();
192
+ }, async (error) => {
193
+ await observerController.close();
211
194
  throw error;
212
195
  });
213
196
  return {
@@ -1,7 +1,7 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import * as path from "node:path";
3
- import { ProjectionStateError } from "./atomic-publish.js";
4
- import { createUlid } from "./ids.js";
3
+ import { ProjectionStateError } from "../../atomic-publish.js";
4
+ import { createUlid } from "../../ids.js";
5
5
  const EXECUTION_ID_PATTERN = /^[0-9A-HJKMNP-TV-Z]{26}$/;
6
6
  export function createProjectionExecutionId(nowMs = Date.now()) {
7
7
  return createUlid(nowMs, [...randomBytes(10)]);
@@ -1,18 +1,18 @@
1
1
  import { setTimeout as delay } from "node:timers/promises";
2
- import { openProjectionGenerationStore } from "./projection/generation/store.js";
2
+ import { openProjectionGenerationStore } from "./store.js";
3
3
  import { spawnProjectionGenerationRunner, } from "./projection-generation-process.js";
4
4
  export const PROJECTION_ADOPTION_TIMEOUT_MS = 4_000;
5
5
  export const PROJECTION_ADOPTION_POLL_MS = 20;
6
6
  function errorDetail(error) {
7
7
  return error instanceof Error ? error.message : String(error);
8
8
  }
9
- function recordLaunchFailure(projectionDirectory, executionId, detail, stage) {
9
+ function recordLaunchFailure(projectionDirectory, executionId, detail, stage, terminalAt) {
10
10
  const store = openProjectionGenerationStore(projectionDirectory);
11
11
  try {
12
12
  return store.verdictIfOpen({
13
13
  executionId,
14
14
  verdict: "launch-failed",
15
- facts: { stage, detail },
15
+ facts: { stage, detail, ...(terminalAt ? { terminalAt } : {}) },
16
16
  }).status === "committed";
17
17
  }
18
18
  finally {
@@ -29,8 +29,8 @@ export async function startProjectionGeneration(projectionDirectory, executionId
29
29
  }
30
30
  catch (error) {
31
31
  const detail = `runner spawn failed: ${errorDetail(error)}`;
32
- recordLaunchFailure(projectionDirectory, executionId, detail, "spawn");
33
- return { status: "failed", detail };
32
+ recordLaunchFailure(projectionDirectory, executionId, detail, "spawn", new Date(now()).toISOString());
33
+ return { status: "failed", cause: "spawn", detail };
34
34
  }
35
35
  const deadline = now() + PROJECTION_ADOPTION_TIMEOUT_MS;
36
36
  for (;;) {
@@ -41,6 +41,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
41
41
  if (current?.launch.executionId !== executionId) {
42
42
  return {
43
43
  status: "failed",
44
+ cause: "adoption",
44
45
  detail: "launch stopped being current before adoption",
45
46
  };
46
47
  }
@@ -49,6 +50,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
49
50
  if (current.verdict) {
50
51
  return {
51
52
  status: "failed",
53
+ cause: "adoption",
52
54
  detail: typeof current.verdict.facts.detail === "string"
53
55
  ? current.verdict.facts.detail
54
56
  : `launch ended as ${String(current.verdict.facts.state)}`,
@@ -73,7 +75,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
73
75
  store.close();
74
76
  }
75
77
  const detail = "runner did not commit adoption before startup timeout";
76
- if (!recordLaunchFailure(projectionDirectory, executionId, detail, "adoption")) {
78
+ if (!recordLaunchFailure(projectionDirectory, executionId, detail, "adoption", new Date(now()).toISOString())) {
77
79
  const raced = openProjectionGenerationStore(projectionDirectory);
78
80
  try {
79
81
  const current = raced.readCurrentGeneration();
@@ -86,5 +88,5 @@ export async function startProjectionGeneration(projectionDirectory, executionId
86
88
  }
87
89
  }
88
90
  child.kill("SIGTERM");
89
- return { status: "failed", detail };
91
+ return { status: "failed", cause: "adoption", detail };
90
92
  }
@@ -4,7 +4,8 @@ import { spawn as nodeSpawn } from "node:child_process";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { executionStdioLogPath } from "./projection-generation-identity.js";
6
6
  const MODULE_FILE = fileURLToPath(import.meta.url);
7
- const PACKAGE_ROOT = path.resolve(path.dirname(MODULE_FILE), "..", "..");
7
+ // Lives at src/core/projection/generation/ — four levels up is the package root.
8
+ const PACKAGE_ROOT = path.resolve(path.dirname(MODULE_FILE), "..", "..", "..", "..");
8
9
  const RUNNER_ENTRY = MODULE_FILE.endsWith(".ts")
9
10
  ? [process.execPath, "--import", "tsx", path.join(PACKAGE_ROOT, "src", "index.ts")]
10
11
  : [process.execPath, path.join(PACKAGE_ROOT, "build", "index.js")];
@@ -1,8 +1,9 @@
1
- import { openProjectionGenerationStore, } from "./projection/generation/store.js";
2
- import { acquireProjectionRunnerLock, observeProjectionRunnerLock, } from "./projection-runner-lock.js";
1
+ import { openProjectionGenerationStore, } from "./store.js";
2
+ import { acquireProjectionRunnerLock, observeProjectionRunnerLock, } from "../projection-runner-lock.js";
3
3
  import { createProjectionExecutionId } from "./projection-generation-identity.js";
4
4
  import { applyContinuationEffort, } from "./projection-generation-continuation.js";
5
- import { openProjectionTellObserver } from "./projection/tell/database.js";
5
+ import { openProjectionTellObserver } from "../tell/database.js";
6
+ import { OUTCOME_ERROR_VERSION } from "../../../agents/types.js";
6
7
  /** Private runner-side kill grace. Not a setting, env, parameter, or export. */
7
8
  const KILL_GRACE_MS = 5000;
8
9
  function successorLaunchFacts(launch, completionFacts, effort, now) {
@@ -228,6 +229,13 @@ export async function runProjectionGeneration(input) {
228
229
  diagnostic: "escalation-failed",
229
230
  detail: errorDetail(error),
230
231
  failedAt: new Date(now()).toISOString(),
232
+ error: {
233
+ version: OUTCOME_ERROR_VERSION,
234
+ code: "SUBAGENT_EXEC_ERROR",
235
+ message: errorDetail(error),
236
+ timeoutMs: null,
237
+ exitCode: null,
238
+ },
231
239
  },
232
240
  });
233
241
  // Durably completed after the failed verdict; outer catch must not overwrite.
@@ -278,6 +286,7 @@ export async function runProjectionGeneration(input) {
278
286
  facts: {
279
287
  stage: "spawn",
280
288
  detail: `successor runner spawn failed: ${errorDetail(error)}`,
289
+ terminalAt: new Date(now()).toISOString(),
281
290
  },
282
291
  });
283
292
  }
@@ -315,6 +324,13 @@ export async function runProjectionGeneration(input) {
315
324
  facts: {
316
325
  failedAt: new Date(now()).toISOString(),
317
326
  detail: error instanceof Error ? error.message : String(error),
327
+ error: {
328
+ version: OUTCOME_ERROR_VERSION,
329
+ code: "SUBAGENT_EXEC_ERROR",
330
+ message: error instanceof Error ? error.message : String(error),
331
+ timeoutMs: null,
332
+ exitCode: null,
333
+ },
318
334
  },
319
335
  });
320
336
  }
@@ -1,8 +1,8 @@
1
- import { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, assertDatabaseOpen, closeDatabase, isProjectionGenerationSchemaV1Residue, openMutableDatabase, openReadOnlyDatabase, readValidatedHistory, } from "./database.js";
1
+ import { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, assertDatabaseOpen, closeDatabase, openMutableDatabase, openReadOnlyDatabase, readValidatedHistory, } from "./database.js";
2
2
  import { initializeIdentity as initializeProjectionIdentity, readIdentity as readProjectionIdentity, } from "./identity.js";
3
3
  import * as transitions from "./transitions.js";
4
- export { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, isProjectionGenerationSchemaV1Residue, };
5
- export { GENERATION_VERDICT_STATES, ProjectionGenerationStoreError, } from "./model.js";
4
+ export { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, };
5
+ export { GENERATION_VERDICT_STATES, isIncompatibleProjectionGenerationStoreError, ProjectionGenerationStoreError, } from "./model.js";
6
6
  export class ProjectionGenerationStore {
7
7
  databasePath;
8
8
  readOnly;