@astrosheep/keiyaku 2.9.2 → 2.9.4

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 (238) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/agents/call-terms.js +13 -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 +25 -222
  6. package/build/agents/harness/index.js +3 -1
  7. package/build/agents/harness/outcome.js +47 -4
  8. package/build/agents/harness/projection.js +42 -59
  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 +50 -53
  21. package/build/agents/providers/codex-app-server/events.js +67 -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/registration.js +145 -0
  36. package/build/agents/providers/pi/session-schema.js +6 -0
  37. package/build/agents/providers/pi/terms.js +1 -0
  38. package/build/agents/providers/registration.js +7 -0
  39. package/build/agents/providers/registry.js +76 -0
  40. package/build/agents/selector.js +2 -29
  41. package/build/agents/types.js +8 -0
  42. package/build/artifact-directories.js +22 -0
  43. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  44. package/build/cli/commands/akuma/view/handler.js +5 -4
  45. package/build/cli/commands/akuma.js +6 -0
  46. package/build/cli/commands/contract/amend/handler.js +8 -2
  47. package/build/cli/commands/contract/arc/handler.js +7 -1
  48. package/build/cli/commands/contract/bind/handler.js +4 -3
  49. package/build/cli/commands/contract/bind/meta.js +34 -7
  50. package/build/cli/commands/contract/forfeit/handler.js +4 -4
  51. package/build/cli/commands/contract/log/handler.js +3 -3
  52. package/build/cli/commands/contract/petition/handler.js +4 -6
  53. package/build/cli/commands/contract/renew/handler.js +20 -6
  54. package/build/cli/commands/contract/renew/meta.js +5 -4
  55. package/build/cli/commands/metadata.js +58 -0
  56. package/build/cli/commands/projection/call/handler.js +6 -5
  57. package/build/cli/commands/projection/kill/handler.js +16 -32
  58. package/build/cli/commands/projection/shared.js +28 -0
  59. package/build/cli/commands/projection/status/handler.js +1 -1
  60. package/build/cli/commands/projection/tell/handler.js +14 -30
  61. package/build/cli/commands/projection/wait/handler.js +45 -22
  62. package/build/cli/commands/projection/wait/meta.js +7 -2
  63. package/build/cli/commands/registry.js +2 -54
  64. package/build/cli/commands/shared.js +10 -7
  65. package/build/cli/commands/skills/install/handler.js +2 -5
  66. package/build/cli/commands/skills/skills/handler.js +1 -1
  67. package/build/cli/commands/task/add/handler.js +5 -13
  68. package/build/cli/commands/task/catalog.js +2 -2
  69. package/build/cli/commands/task/done/handler.js +4 -8
  70. package/build/cli/commands/task/drop/handler.js +3 -6
  71. package/build/cli/commands/task/ls/handler.js +3 -5
  72. package/build/cli/commands/task/shared.js +14 -4
  73. package/build/cli/commands/task/{view → show}/handler.js +7 -8
  74. package/build/cli/commands/task/show/meta.js +8 -0
  75. package/build/cli/commands/task/start/handler.js +3 -6
  76. package/build/cli/commands/task/stop/handler.js +4 -8
  77. package/build/cli/commands/task/task/handler.js +1 -1
  78. package/build/cli/commands/task/update/handler.js +4 -8
  79. package/build/cli/completion.js +1 -1
  80. package/build/cli/flags.js +19 -3
  81. package/build/cli/help.js +4 -11
  82. package/build/cli/index.js +57 -83
  83. package/build/cli/missing-subcommand.js +7 -0
  84. package/build/cli/parse-flags.js +14 -5
  85. package/build/cli/parse-metadata.js +3 -3
  86. package/build/cli/parse-selectors.js +1 -1
  87. package/build/cli/parse.js +21 -0
  88. package/build/cli/projection-address.js +7 -12
  89. package/build/cli/render/address.js +41 -37
  90. package/build/cli/render/arc.js +24 -12
  91. package/build/cli/render/call.js +11 -5
  92. package/build/cli/render/errors.js +36 -1
  93. package/build/cli/render/format.js +4 -0
  94. package/build/cli/render/kanshi.js +6 -12
  95. package/build/cli/render/kill.js +9 -0
  96. package/build/cli/render/misc.js +55 -12
  97. package/build/cli/render/petition.js +20 -15
  98. package/build/cli/render/projection-activity.js +3 -0
  99. package/build/cli/render/shared.js +60 -21
  100. package/build/cli/render/skills.js +10 -0
  101. package/build/cli/render/status.js +37 -14
  102. package/build/cli/render/success-response.js +77 -0
  103. package/build/cli/render/task.js +54 -14
  104. package/build/cli/render/tell.js +5 -0
  105. package/build/cli/render/terminal-failure.js +58 -0
  106. package/build/cli/render/types.js +1 -0
  107. package/build/cli/render/wait.js +38 -36
  108. package/build/cli/types.js +1 -1
  109. package/build/config/akuma-loader.js +0 -5
  110. package/build/config/env-keys.js +1 -1
  111. package/build/config/provider-policy-ownership.js +3 -32
  112. package/build/config/settings/disease.js +8 -1
  113. package/build/config/settings/loader.js +11 -3
  114. package/build/config/settings/provider-instance-fields.js +51 -0
  115. package/build/config/settings/schema.js +6 -176
  116. package/build/core/addressing.js +66 -16
  117. package/build/core/amend.js +135 -18
  118. package/build/core/arc.js +19 -67
  119. package/build/core/bind.js +82 -35
  120. package/build/core/call/call.js +15 -9
  121. package/build/core/call/context.js +6 -51
  122. package/build/core/call/execution.js +21 -22
  123. package/build/core/call/prompt.js +14 -1
  124. package/build/core/command-markdown.js +45 -0
  125. package/build/core/context.js +13 -7
  126. package/build/core/contract-view.js +20 -3
  127. package/build/core/draft.js +123 -16
  128. package/build/core/forfeit.js +5 -2
  129. package/build/core/hints.js +1 -75
  130. package/build/core/identifier-slug.js +66 -0
  131. package/build/core/ids.js +25 -11
  132. package/build/core/ledger.js +20 -68
  133. package/build/core/markdown/parser.js +0 -68
  134. package/build/core/markdown/render.js +68 -0
  135. package/build/core/markdown/sections.js +2 -1
  136. package/build/core/outcome-base.js +4 -0
  137. package/build/core/projection/generation/database.js +2 -38
  138. package/build/core/projection/generation/model.js +42 -1
  139. package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
  140. package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
  141. package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
  142. package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
  143. package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
  144. package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
  145. package/build/core/projection/generation/store.js +2 -2
  146. package/build/core/projection/generation/transitions.js +1 -1
  147. package/build/core/projection/index.js +27 -0
  148. package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
  149. package/build/core/{projection-alias.js → projection/projection-alias.js} +14 -19
  150. package/build/core/projection/projection-coordinate.js +61 -0
  151. package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
  152. package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
  153. package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
  154. package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
  155. package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
  156. package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
  157. package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
  158. package/build/core/projection/projection-terminal-failure.js +104 -0
  159. package/build/core/projection/projection-wait.js +278 -0
  160. package/build/core/projection/projection-wake.js +203 -0
  161. package/build/core/provider-loader-ports.js +4 -0
  162. package/build/core/ref-log.js +65 -40
  163. package/build/core/registry.js +63 -10
  164. package/build/core/renew-session.js +128 -0
  165. package/build/core/renew.js +426 -99
  166. package/build/core/scope.js +143 -66
  167. package/build/core/seal.js +139 -35
  168. package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
  169. package/build/core/{claim.js → settlement/claim.js} +32 -8
  170. package/build/core/settlement/index.js +19 -0
  171. package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
  172. package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
  173. package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
  174. package/build/core/settlement/petition-io.js +1 -0
  175. package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
  176. package/build/core/{petition.js → settlement/petition.js} +12 -10
  177. package/build/core/settlement/queue-read-model.js +143 -0
  178. package/build/core/settlement/queue-seat-allocation.js +156 -0
  179. package/build/core/settlement/queue.js +6 -0
  180. package/build/core/settlement/settlement.js +295 -0
  181. package/build/core/{verdict.js → settlement/verdict.js} +9 -37
  182. package/build/core/status/board.js +24 -23
  183. package/build/core/status/ledger-batch.js +158 -0
  184. package/build/core/status/reconciliation.js +10 -4
  185. package/build/core/stored-agent-event.js +3 -0
  186. package/build/core/task/board.js +40 -4
  187. package/build/core/task/commands.js +30 -21
  188. package/build/core/task/index.js +12 -0
  189. package/build/core/task/settlement-git.js +157 -65
  190. package/build/core/task/settlement-policy.js +54 -24
  191. package/build/core/task/task-contract.js +370 -0
  192. package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
  193. package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
  194. package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
  195. package/build/core/{task-git-store.js → task/task-git-store.js} +92 -29
  196. package/build/core/task/task-repository.js +1 -0
  197. package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
  198. package/build/core/task/task-store.js +1 -0
  199. package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
  200. package/build/core/task/task.js +5 -0
  201. package/build/core/task/tree.js +37 -0
  202. package/build/core/task/validation.js +5 -2
  203. package/build/core/transcripts.js +15 -3
  204. package/build/core/worktree-path.js +43 -28
  205. package/build/flow-error.js +85 -39
  206. package/build/fs/durability.js +27 -0
  207. package/build/fs/path-coordinate.js +16 -0
  208. package/build/generated/version.js +3 -2
  209. package/build/git/branches.js +2 -1
  210. package/build/git/core.js +106 -2
  211. package/build/git/path-coordinate.js +17 -0
  212. package/build/git/refs.js +57 -0
  213. package/build/git/streaming-batch.js +301 -0
  214. package/build/git/worktree.js +65 -0
  215. package/build/index.js +3 -3
  216. package/build/keiyaku.js +2 -36
  217. package/package.json +4 -10
  218. package/skills/keiyaku/SKILL.md +3 -2
  219. package/skills/keiyaku-akuma/SKILL.md +10 -6
  220. package/skills/keiyaku-task/SKILL.md +1 -1
  221. package/skills/keiyaku-workflow/SKILL.md +25 -4
  222. package/build/agents/providers/codex-sdk.js +0 -329
  223. package/build/cli/commands/task/view/meta.js +0 -8
  224. package/build/core/command-io.js +0 -174
  225. package/build/core/path-coordinate.js +0 -27
  226. package/build/core/petition-claim.js +0 -117
  227. package/build/core/petition-run.js +0 -83
  228. package/build/core/projection-coordinate.js +0 -63
  229. package/build/core/projection-wait.js +0 -165
  230. package/build/core/projection-wake.js +0 -136
  231. package/build/core/queue.js +0 -343
  232. package/build/core/task-contract.js +0 -237
  233. package/build/core/task.js +0 -4
  234. /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
  235. /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
  236. /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
  237. /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
  238. /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
@@ -258,71 +258,3 @@ export function parseToAST(content, options = {}) {
258
258
  });
259
259
  return parser.parseDocument();
260
260
  }
261
- function renderListItemFirstLine(item) {
262
- const content = renderNodeContent(item);
263
- if (!content) {
264
- return `${" ".repeat(item.indent)}${item.marker}`;
265
- }
266
- const [firstLine, ...rest] = content.split("\n");
267
- const prefix = `${" ".repeat(item.indent)}${item.marker}${firstLine.length > 0 ? " " : ""}${firstLine}`;
268
- if (rest.length === 0) {
269
- return prefix;
270
- }
271
- return [prefix, ...rest].join("\n");
272
- }
273
- export function renderBlock(node) {
274
- switch (node.type) {
275
- case "section": {
276
- const header = `${"#".repeat(node.level)} ${node.title}`;
277
- const body = renderNodeContent(node);
278
- return body ? `${header}\n${body}` : header;
279
- }
280
- case "list":
281
- return node.items.map((item) => renderListItemFirstLine(item)).join("\n");
282
- case "code_block":
283
- return node.lines.join("\n");
284
- case "blockquote":
285
- return node.lines.map((line) => `${node.marker}${line}`).join("\n");
286
- case "text":
287
- return node.value;
288
- case "heading":
289
- return `${"#".repeat(node.level)} ${node.text}`;
290
- }
291
- }
292
- export function renderNodeContent(node) {
293
- switch (node.type) {
294
- case "document":
295
- return node.children.map((child) => renderBlock(child)).join("\n");
296
- case "section":
297
- return node.children.map((child) => renderBlock(child)).join("\n");
298
- case "list":
299
- return renderBlock(node);
300
- case "list_item":
301
- return node.children.map((child) => renderBlock(child)).join("\n");
302
- case "code_block":
303
- return node.lines.join("\n");
304
- case "blockquote":
305
- return node.lines.map((line) => `${node.marker}${line}`).join("\n");
306
- case "text":
307
- return node.value;
308
- case "heading":
309
- return `${"#".repeat(node.level)} ${node.text}`;
310
- }
311
- }
312
- export function renderSectionContent(sectionNode) {
313
- return sectionNode.children.map((child) => renderBlock(child)).join("\n");
314
- }
315
- export function extractListItems(sectionNode) {
316
- const items = [];
317
- for (const child of sectionNode.children) {
318
- if (child.type !== "list")
319
- continue;
320
- for (const item of child.items) {
321
- const rendered = renderNodeContent(item).trimEnd();
322
- if (rendered.trim().length > 0) {
323
- items.push(rendered);
324
- }
325
- }
326
- }
327
- return items;
328
- }
@@ -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
+ }
@@ -76,7 +76,7 @@ export function rollbackQuietly(database) {
76
76
  function validateSchemaShape(database) {
77
77
  const version = pragmaNumber(database, "user_version");
78
78
  if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
79
- throw new ProjectionGenerationStoreError(`projection generation schema version ${version} is not supported; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
79
+ throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
80
80
  }
81
81
  const objects = database.prepare(`
82
82
  SELECT name, type
@@ -138,7 +138,7 @@ function initializeOrValidateSchema(database) {
138
138
  database.exec(`PRAGMA user_version = ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
139
139
  }
140
140
  else if (version !== PROJECTION_GENERATION_SCHEMA_VERSION) {
141
- throw new ProjectionGenerationStoreError(`projection generation schema version ${version} is not supported; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
141
+ throw new ProjectionGenerationStoreError(`incompatible projection generation schema version ${version}; expected ${PROJECTION_GENERATION_SCHEMA_VERSION}`);
142
142
  }
143
143
  validateSchemaShape(database);
144
144
  database.exec("COMMIT");
@@ -268,39 +268,3 @@ export function closeDatabase(database) {
268
268
  closedDatabases.add(database);
269
269
  database.close();
270
270
  }
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,6 +1,16 @@
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";
6
16
  constructor(message, options) {
@@ -121,6 +131,37 @@ export function validateVerdictFacts(value, location) {
121
131
  if (typeof facts.state !== "string" || !VERDICTS.has(facts.state)) {
122
132
  throw new ProjectionGenerationStoreError(`${location}.state is not in the closed verdict vocabulary`);
123
133
  }
134
+ if (facts.state === "failed") {
135
+ const error = isPlainObject(facts.error) ? facts.error : undefined;
136
+ const version = error?.version;
137
+ if (!error || version !== OUTCOME_ERROR_VERSION) {
138
+ throw new ProjectionGenerationStoreError(`${location}.error has incompatible version ${version === undefined ? "missing" : String(version)}; expected ${OUTCOME_ERROR_VERSION}`);
139
+ }
140
+ if (Object.keys(error).some((key) => !OUTCOME_ERROR_KEYS.has(key))) {
141
+ throw new ProjectionGenerationStoreError(`${location}.error is not the current closed OutcomeError shape`);
142
+ }
143
+ if (typeof error.code !== "string" || !OUTCOME_ERROR_CODES.has(error.code)) {
144
+ throw new ProjectionGenerationStoreError(`${location}.error.code is not a recognized subagent failure code`);
145
+ }
146
+ if (typeof error.message !== "string") {
147
+ throw new ProjectionGenerationStoreError(`${location}.error.message must be a string`);
148
+ }
149
+ if (error.timeoutMs !== null && (typeof error.timeoutMs !== "number"
150
+ || !Number.isSafeInteger(error.timeoutMs)
151
+ || error.timeoutMs < 0)) {
152
+ throw new ProjectionGenerationStoreError(`${location}.error.timeoutMs must be null or a non-negative safe integer`);
153
+ }
154
+ if (error.exitCode !== null && (typeof error.exitCode !== "number"
155
+ || !Number.isSafeInteger(error.exitCode))) {
156
+ throw new ProjectionGenerationStoreError(`${location}.error.exitCode must be null or a safe integer`);
157
+ }
158
+ if (error.publicCause !== undefined) {
159
+ const cause = isPlainObject(error.publicCause) ? error.publicCause : undefined;
160
+ if (!cause || cause.kind !== "rate_limit_exhausted" || Object.keys(cause).length !== 1) {
161
+ throw new ProjectionGenerationStoreError(`${location}.error.publicCause is not a current closed cause`);
162
+ }
163
+ }
164
+ }
124
165
  return facts;
125
166
  }
126
167
  export function parseStoredRow(row) {
@@ -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 { demoteSubmittedTellsForReplay, readProjectionEvents, } from "../projection-core.js";
6
+ import { createProjectionExecutionObserver, } 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
  }
@@ -134,50 +135,27 @@ async function completionFacts(projectionDirectory, executionId, inputs, outcome
134
135
  * Construct the public Projection once and expose a provider-neutral execution
135
136
  * handle. Provider adapters and harness public types are unchanged.
136
137
  */
137
- export function executeProjectionGeneration(projectionDirectory, launch) {
138
+ export function executeProjectionGeneration(projectionDirectory, launch, providerLoaderPorts = {}) {
138
139
  const inputs = parseLaunchInputs(launch);
139
140
  initializeConfig(process.env, inputs.cwd);
140
141
  const executionId = launch.executionId;
141
- const tellFence = launch.facts.tellFence ?? [];
142
142
  demoteSubmittedTellsForReplay(projectionDirectory, executionId);
143
- const baseTerms = buildCallTerms(inputs.launchSnapshot, inputs.prompt, inputs.cwd, {
143
+ const terms = attachProviderLoaderPorts(buildCallTerms(inputs.launchSnapshot, inputs.prompt, inputs.cwd, {
144
144
  idleTimeoutMs: inputs.idleTimeoutMs,
145
145
  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;
146
+ }), providerLoaderPorts);
172
147
  const observerController = createProjectionExecutionObserver({
173
148
  projectionDirectory,
174
149
  executionId,
175
- ...(replayStartGate ? { replayStartGate } : {}),
176
150
  });
177
151
  let projection;
178
152
  try {
179
- projection = inputs.session && inputs.resumePath
180
- ? revive({ ...terms, session: inputs.session, resumePath: inputs.resumePath }, { observer: observerController.observer })
153
+ projection = inputs.session
154
+ ? revive({
155
+ ...terms,
156
+ session: inputs.session,
157
+ resumePath: inputs.resumePath ?? projectionDirectory,
158
+ }, { observer: observerController.observer })
181
159
  : call(terms, { observer: observerController.observer });
182
160
  }
183
161
  catch (error) {
@@ -186,14 +164,6 @@ export function executeProjectionGeneration(projectionDirectory, launch) {
186
164
  }
187
165
  const outcome = projection.outcome.then(async (result) => {
188
166
  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
167
  return {
198
168
  verdict: result.status === "completed"
199
169
  ? "completed"
@@ -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,5 +1,5 @@
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;
@@ -30,7 +30,7 @@ export async function startProjectionGeneration(projectionDirectory, executionId
30
30
  catch (error) {
31
31
  const detail = `runner spawn failed: ${errorDetail(error)}`;
32
32
  recordLaunchFailure(projectionDirectory, executionId, detail, "spawn");
33
- return { status: "failed", detail };
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)}`,
@@ -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.
@@ -315,6 +323,13 @@ export async function runProjectionGeneration(input) {
315
323
  facts: {
316
324
  failedAt: new Date(now()).toISOString(),
317
325
  detail: error instanceof Error ? error.message : String(error),
326
+ error: {
327
+ version: OUTCOME_ERROR_VERSION,
328
+ code: "SUBAGENT_EXEC_ERROR",
329
+ message: error instanceof Error ? error.message : String(error),
330
+ timeoutMs: null,
331
+ exitCode: null,
332
+ },
318
333
  },
319
334
  });
320
335
  }
@@ -1,7 +1,7 @@
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, };
4
+ export { PROJECTION_GENERATION_SCHEMA_VERSION, PROJECTION_GENERATION_STORE_FILE, };
5
5
  export { GENERATION_VERDICT_STATES, ProjectionGenerationStoreError, } from "./model.js";
6
6
  export class ProjectionGenerationStore {
7
7
  databasePath;
@@ -131,7 +131,6 @@ export function verdictIfOpen(database, readOnly, input) {
131
131
  if (input.verdict === "killed") {
132
132
  throw new ProjectionGenerationStoreError("verdict 'killed' is reserved to runnerKilledIfRequested and settleKillIfRunnerDead");
133
133
  }
134
- const facts = validateVerdictFacts({ ...(input.facts ?? {}), state: input.verdict }, "verdict facts");
135
134
  return writeTransition(database, readOnly, () => {
136
135
  const history = readValidatedHistory(database);
137
136
  const current = history.current;
@@ -150,6 +149,7 @@ export function verdictIfOpen(database, readOnly, input) {
150
149
  if (input.verdict === "launch-failed" && current.adoption) {
151
150
  return rejected("already-adopted", current);
152
151
  }
152
+ const facts = validateVerdictFacts({ ...(input.facts ?? {}), state: input.verdict }, "verdict facts");
153
153
  return committed([appendRecord(database, "verdict", executionId, facts, history.records.length + 1)]);
154
154
  });
155
155
  }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Public surface for the projection package.
3
+ * Only symbols required by current external consumers are re-exported.
4
+ * Package-internal modules must import each other directly, not through this file.
5
+ */
6
+ export { heartPath } from "./heart.js";
7
+ export { AGENT_ACTIVITY_WINDOW_SIZE, foldAgentActivity, } from "./projection-activity.js";
8
+ export { assertProjectionAlias, isProjectionAlias, moveProjectionAlias, projectionAliasRoot, readProjectionAlias, } from "./projection-alias.js";
9
+ export { resolveProjectionCoordinate } from "./projection-coordinate.js";
10
+ export { appendGenerationEvent, executionEventsPath, isProjectionId, isPublishedProjection, isoFromNowMs, projectionDir, projectionRoot, readProjectionEvents, } from "./projection-core.js";
11
+ export { readProjectionIdentity } from "./projection-identity.js";
12
+ export { killProjectionGeneration } from "./projection-kill.js";
13
+ export { observeProjectionLife } from "./projection-life-observer.js";
14
+ export { mintProjection, mintRepositoryProjection, ProjectionMintCollisionError, } from "./projection-mint.js";
15
+ export { acquireProjectionRunnerLock, initializeProjectionRunnerLockDatabase, isProjectionRunnerLockPlatformSupported, observeProjectionRunnerLock, projectionRunnerLockPath, } from "./projection-runner-lock.js";
16
+ export { hasStrandableProjectionGeneration, prioritizeProjectionStatusRows, readProjectionStatusBoard, } from "./projection-status.js";
17
+ export { projectTerminalFailure, } from "./projection-terminal-failure.js";
18
+ export { snapshotCommissionProjectionIds, waitForProjection, waitForProjectionSet, } from "./projection-wait.js";
19
+ export { assertTellEffortSupported, tellProjection, } from "./projection-wake.js";
20
+ export { openProjectionGenerationStore, openProjectionGenerationStoreReadOnly, ProjectionGenerationStore, } from "./generation/store.js";
21
+ export { createProjectionExecutionId } from "./generation/projection-generation-identity.js";
22
+ export { PROJECTION_ADOPTION_TIMEOUT_MS, startProjectionGeneration, } from "./generation/projection-generation-launcher.js";
23
+ export { projectionGenerationRunnerArgv, spawnProjectionGenerationRunner, } from "./generation/projection-generation-process.js";
24
+ export { runProjectionGeneration, } from "./generation/projection-generation-runner.js";
25
+ export { executeProjectionGeneration } from "./generation/projection-generation-execution.js";
26
+ export { runProjectionGenerationRuntime } from "./generation/projection-generation-runtime.js";
27
+ export { claimFencedTells, claimTellToInflight, demoteSubmittedTellsForReplay, listTellIds, markTellConsumed, markTellSubmitted, readProjectionTellCounts, readTellOriginal, readTellSubmitted, writeInboxTell, } from "./tell/store.js";
@@ -9,6 +9,9 @@ function duration(first, last) {
9
9
  return Math.max(0, last - first);
10
10
  }
11
11
  function warningIdentity(warning) {
12
+ if (warning.reason === "rate-limit") {
13
+ return JSON.stringify(warning);
14
+ }
12
15
  if (warning.reason === "retry") {
13
16
  return JSON.stringify({
14
17
  reason: warning.reason,
@@ -238,3 +241,12 @@ export function foldAgentActivity(events) {
238
241
  ...(failure ? { failure } : {}),
239
242
  };
240
243
  }
244
+ /**
245
+ * Public wait/status activity deliberately excludes provider-origin terminal
246
+ * prose. Diagnostic and fail-event text remains available to artifact/internal
247
+ * consumers through the full fold, but has no JSON or human projection path.
248
+ */
249
+ export function foldPublicProjectionActivity(events) {
250
+ const { diagnostic: _diagnostic, failure: _failure, ...activity } = foldAgentActivity(events);
251
+ return activity;
252
+ }
@@ -1,7 +1,8 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { isErrnoException } from "../errno.js";
4
- import { ProjectionStateError, randomHex8 } from "./atomic-publish.js";
3
+ import { isErrnoException } from "../../errno.js";
4
+ import { syncDirectorySync } from "../../fs/durability.js";
5
+ import { ProjectionStateError, randomHex8 } from "../atomic-publish.js";
5
6
  import { projectionCoordinateRoot } from "./projection-coordinate.js";
6
7
  import { isProjectionId } from "./projection-core.js";
7
8
  export const PROJECTION_ALIAS_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
@@ -15,12 +16,12 @@ export function assertProjectionAlias(value) {
15
16
  }
16
17
  return value;
17
18
  }
18
- export function projectionAliasRoot(cwd) {
19
- return path.join(projectionCoordinateRoot(cwd), ".keiyaku", "projection-alias");
19
+ export async function projectionAliasRoot(cwd) {
20
+ return path.join(await projectionCoordinateRoot(cwd), ".keiyaku", "projection-alias");
20
21
  }
21
- export function projectionAliasPath(cwd, alias) {
22
+ export async function projectionAliasPath(cwd, alias) {
22
23
  assertProjectionAlias(alias);
23
- return path.join(projectionAliasRoot(cwd), alias);
24
+ return path.join(await projectionAliasRoot(cwd), alias);
24
25
  }
25
26
  function invalidAliasRef(filePath) {
26
27
  return new ProjectionStateError(`invalid projection alias ref: ${filePath}`);
@@ -61,8 +62,8 @@ function readBoundedRegularAliasRef(filePath) {
61
62
  }
62
63
  }
63
64
  /** Undefined means no ref; malformed refs fail closed with their exact sidecar path. */
64
- export function readProjectionAlias(cwd, alias) {
65
- const filePath = projectionAliasPath(cwd, alias);
65
+ export async function readProjectionAlias(cwd, alias) {
66
+ const filePath = await projectionAliasPath(cwd, alias);
66
67
  const content = readBoundedRegularAliasRef(filePath);
67
68
  if (content === undefined)
68
69
  return undefined;
@@ -74,14 +75,14 @@ export function readProjectionAlias(cwd, alias) {
74
75
  return id;
75
76
  }
76
77
  /** Atomically replace one alias ref. Aliases intentionally have no multi-ref transaction. */
77
- export function moveProjectionAlias(cwd, alias, id) {
78
+ export async function moveProjectionAlias(cwd, alias, id) {
78
79
  assertProjectionAlias(alias);
79
80
  if (!isProjectionId(id))
80
81
  throw new ProjectionStateError(`invalid projection id: ${id}`);
81
- const previous = readProjectionAlias(cwd, alias);
82
- const root = projectionAliasRoot(cwd);
82
+ const previous = await readProjectionAlias(cwd, alias);
83
+ const root = await projectionAliasRoot(cwd);
83
84
  fs.mkdirSync(root, { recursive: true });
84
- const target = projectionAliasPath(cwd, alias);
85
+ const target = await projectionAliasPath(cwd, alias);
85
86
  let temp;
86
87
  try {
87
88
  for (let attempt = 0; attempt < 16; attempt += 1) {
@@ -107,13 +108,7 @@ export function moveProjectionAlias(cwd, alias, id) {
107
108
  if (!temp)
108
109
  throw new ProjectionStateError(`failed to create projection alias temp: ${target}`);
109
110
  fs.renameSync(temp, target);
110
- const directoryFd = fs.openSync(root, fs.constants.O_RDONLY);
111
- try {
112
- fs.fsyncSync(directoryFd);
113
- }
114
- finally {
115
- fs.closeSync(directoryFd);
116
- }
111
+ syncDirectorySync(root);
117
112
  }
118
113
  finally {
119
114
  if (temp)