@astrosheep/keiyaku 4.0.0 → 4.0.2

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 (308) hide show
  1. package/README.md +133 -8
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +13 -5
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -32
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +134 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +262 -46
  12. package/build/src/akuma/abort.d.ts +2 -0
  13. package/build/src/akuma/abort.js +50 -0
  14. package/build/src/akuma/akuma.d.ts +50 -33
  15. package/build/src/akuma/akuma.js +175 -127
  16. package/build/src/akuma/archetype.d.ts +14 -5
  17. package/build/src/akuma/archetype.js +85 -39
  18. package/build/src/akuma/body.d.ts +3 -5
  19. package/build/src/akuma/body.js +490 -183
  20. package/build/src/akuma/coordinate.d.ts +9 -0
  21. package/build/src/akuma/coordinate.js +22 -0
  22. package/build/src/akuma/heart/facts.d.ts +88 -45
  23. package/build/src/akuma/heart/facts.js +19 -8
  24. package/build/src/akuma/heart/index.d.ts +64 -55
  25. package/build/src/akuma/heart/index.js +172 -252
  26. package/build/src/akuma/heart/rows.d.ts +38 -83
  27. package/build/src/akuma/heart/rows.js +117 -155
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +61 -22
  30. package/build/src/akuma/heart/soul.d.ts +8 -0
  31. package/build/src/akuma/heart/soul.js +136 -0
  32. package/build/src/akuma/heart/storage.d.ts +47 -0
  33. package/build/src/akuma/heart/storage.js +224 -0
  34. package/build/src/akuma/heart/tells.d.ts +12 -0
  35. package/build/src/akuma/heart/tells.js +79 -0
  36. package/build/src/akuma/heart/timeline.d.ts +15 -0
  37. package/build/src/akuma/heart/timeline.js +86 -0
  38. package/build/src/akuma/identity.d.ts +2 -2
  39. package/build/src/akuma/identity.js +9 -9
  40. package/build/src/akuma/index.d.ts +10 -3
  41. package/build/src/akuma/index.js +7 -1
  42. package/build/src/akuma/projection.d.ts +176 -0
  43. package/build/src/akuma/projection.js +256 -0
  44. package/build/src/akuma/provider-recipe.d.ts +24 -0
  45. package/build/src/akuma/provider-recipe.js +100 -0
  46. package/build/src/akuma/provider.d.ts +67 -13
  47. package/build/src/akuma/provider.js +172 -105
  48. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  49. package/build/src/akuma/providers/acp/core.js +159 -0
  50. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  51. package/build/src/akuma/providers/acp/events.js +73 -0
  52. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  53. package/build/src/akuma/providers/acp/index.js +94 -0
  54. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  55. package/build/src/akuma/providers/claude/events.js +238 -0
  56. package/build/src/akuma/providers/claude/index.d.ts +47 -0
  57. package/build/src/akuma/providers/claude/index.js +279 -0
  58. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  59. package/build/src/akuma/providers/claude/input.js +109 -0
  60. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  61. package/build/src/akuma/providers/codex-app-server/events.js +15 -12
  62. package/build/src/akuma/providers/codex-app-server/index.d.ts +15 -13
  63. package/build/src/akuma/providers/codex-app-server/index.js +77 -33
  64. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  65. package/build/src/akuma/providers/grok-build/index.js +70 -0
  66. package/build/src/akuma/providers/index.d.ts +5 -3
  67. package/build/src/akuma/providers/index.js +35 -56
  68. package/build/src/akuma/providers/opencode-sdk/events.d.ts +54 -0
  69. package/build/src/akuma/providers/opencode-sdk/events.js +235 -0
  70. package/build/src/akuma/providers/opencode-sdk/index.d.ts +33 -0
  71. package/build/src/akuma/providers/opencode-sdk/index.js +308 -0
  72. package/build/src/akuma/providers/opencode-sdk/session.d.ts +26 -0
  73. package/build/src/akuma/providers/opencode-sdk/session.js +63 -0
  74. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  75. package/build/src/akuma/providers/pi/events.js +166 -0
  76. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  77. package/build/src/akuma/providers/pi/index.js +191 -0
  78. package/build/src/akuma/publication.d.ts +3 -3
  79. package/build/src/akuma/publication.js +28 -40
  80. package/build/src/akuma/requests.d.ts +9 -6
  81. package/build/src/akuma/requests.js +95 -65
  82. package/build/src/alias/index.d.ts +4 -3
  83. package/build/src/alias/index.js +12 -13
  84. package/build/src/body/decode.js +7 -1
  85. package/build/src/body/region.d.ts +2 -0
  86. package/build/src/body/region.js +77 -7
  87. package/build/src/body/render.js +2 -1
  88. package/build/src/body/shape.js +7 -1
  89. package/build/src/body/verification.js +19 -4
  90. package/build/src/cli/accepted.d.ts +18 -12
  91. package/build/src/cli/accepted.js +73 -34
  92. package/build/src/cli/actor.js +3 -3
  93. package/build/src/cli/commands/akuma-invoke.d.ts +44 -19
  94. package/build/src/cli/commands/akuma-invoke.js +101 -52
  95. package/build/src/cli/commands/akuma.d.ts +27 -9
  96. package/build/src/cli/commands/akuma.js +151 -80
  97. package/build/src/cli/commands/contract.d.ts +155 -0
  98. package/build/src/cli/commands/contract.js +20 -0
  99. package/build/src/cli/commands/install.js +2 -0
  100. package/build/src/cli/commands/task-invoke.d.ts +19 -4
  101. package/build/src/cli/commands/task-invoke.js +65 -17
  102. package/build/src/cli/commands/task-query.d.ts +5 -0
  103. package/build/src/cli/commands/task-query.js +247 -0
  104. package/build/src/cli/commands/task.d.ts +3 -1
  105. package/build/src/cli/commands/task.js +52 -14
  106. package/build/src/cli/coordinates.d.ts +18 -0
  107. package/build/src/cli/coordinates.js +120 -0
  108. package/build/src/cli/draft.d.ts +8 -0
  109. package/build/src/cli/draft.js +96 -0
  110. package/build/src/cli/invoke.d.ts +9 -3
  111. package/build/src/cli/invoke.js +287 -108
  112. package/build/src/cli/main.js +54 -7
  113. package/build/src/cli/parse.d.ts +21 -117
  114. package/build/src/cli/parse.js +79 -84
  115. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  116. package/build/src/cli/render/akuma-tool-command.js +144 -0
  117. package/build/src/cli/render/akuma-tool.d.ts +4 -2
  118. package/build/src/cli/render/akuma-tool.js +35 -5
  119. package/build/src/cli/render/akuma.d.ts +3 -1
  120. package/build/src/cli/render/akuma.js +247 -212
  121. package/build/src/cli/render/audit.d.ts +3 -0
  122. package/build/src/cli/render/audit.js +104 -0
  123. package/build/src/cli/render/catalog.d.ts +2 -0
  124. package/build/src/cli/render/catalog.js +16 -0
  125. package/build/src/cli/render/contract.d.ts +3 -3
  126. package/build/src/cli/render/contract.js +200 -54
  127. package/build/src/cli/render/kanshi.js +272 -129
  128. package/build/src/cli/render/receipt.d.ts +19 -0
  129. package/build/src/cli/render/receipt.js +106 -0
  130. package/build/src/cli/render/refusal.d.ts +16 -2
  131. package/build/src/cli/render/refusal.js +88 -3
  132. package/build/src/cli/render/region.d.ts +2 -0
  133. package/build/src/cli/render/region.js +17 -0
  134. package/build/src/cli/render/task.d.ts +2 -1
  135. package/build/src/cli/render/task.js +223 -60
  136. package/build/src/cli/render/terminal.d.ts +20 -0
  137. package/build/src/cli/render/terminal.js +121 -0
  138. package/build/src/cli/render/text.js +11 -3
  139. package/build/src/cli/result.d.ts +126 -19
  140. package/build/src/cli/usage.d.ts +1 -0
  141. package/build/src/cli/usage.js +3 -0
  142. package/build/src/contract-worktree.d.ts +44 -0
  143. package/build/src/contract-worktree.js +251 -0
  144. package/build/src/coordination/durable-file.d.ts +5 -1
  145. package/build/src/coordination/durable-file.js +57 -10
  146. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  147. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  148. package/build/src/core/facts/codec.js +23 -4
  149. package/build/src/core/facts/eligibility.d.ts +1 -10
  150. package/build/src/core/facts/eligibility.js +0 -49
  151. package/build/src/core/facts/fold.js +1 -6
  152. package/build/src/core/facts/gate.d.ts +1 -0
  153. package/build/src/core/facts/gate.js +1 -0
  154. package/build/src/core/facts/observation.d.ts +3 -0
  155. package/build/src/core/facts/observation.js +12 -0
  156. package/build/src/core/facts/types.d.ts +10 -3
  157. package/build/src/core/subject.js +2 -2
  158. package/build/src/core/verbs/amend.d.ts +1 -1
  159. package/build/src/core/verbs/amend.js +3 -18
  160. package/build/src/core/verbs/bind.js +2 -16
  161. package/build/src/core/verbs/deliver.d.ts +1 -1
  162. package/build/src/core/verbs/deliver.js +14 -4
  163. package/build/src/core/verbs/placement.d.ts +1 -1
  164. package/build/src/core/verbs/placement.js +7 -9
  165. package/build/src/dispatch/index.d.ts +5 -3
  166. package/build/src/dispatch/index.js +30 -21
  167. package/build/src/duration.d.ts +10 -0
  168. package/build/src/duration.js +22 -0
  169. package/build/src/git/admission.d.ts +2 -2
  170. package/build/src/git/admission.js +33 -23
  171. package/build/src/git/hooks.d.ts +15 -0
  172. package/build/src/git/hooks.js +70 -18
  173. package/build/src/git/identity.d.ts +5 -1
  174. package/build/src/git/identity.js +23 -4
  175. package/build/src/git/integration.d.ts +48 -0
  176. package/build/src/git/integration.js +250 -0
  177. package/build/src/git/observe.d.ts +29 -15
  178. package/build/src/git/observe.js +185 -76
  179. package/build/src/git/read-observation.d.ts +41 -0
  180. package/build/src/git/read-observation.js +361 -0
  181. package/build/src/git/reconcile.d.ts +17 -5
  182. package/build/src/git/reconcile.js +305 -109
  183. package/build/src/git/repository.d.ts +41 -18
  184. package/build/src/git/repository.js +220 -114
  185. package/build/src/git/scratch.d.ts +17 -0
  186. package/build/src/git/scratch.js +73 -0
  187. package/build/src/git/target-placement.d.ts +92 -0
  188. package/build/src/git/target-placement.js +375 -0
  189. package/build/src/git/tender.d.ts +49 -0
  190. package/build/src/git/tender.js +63 -0
  191. package/build/src/git/terminal-seal.d.ts +24 -0
  192. package/build/src/git/terminal-seal.js +89 -0
  193. package/build/src/git/tree.d.ts +2 -2
  194. package/build/src/git/tree.js +4 -0
  195. package/build/src/git/workspace.d.ts +53 -0
  196. package/build/src/git/workspace.js +139 -0
  197. package/build/src/identity/selector.d.ts +6 -0
  198. package/build/src/identity/selector.js +19 -0
  199. package/build/src/index.d.ts +4 -2
  200. package/build/src/index.js +2 -1
  201. package/build/src/kanshi/index.d.ts +2 -2
  202. package/build/src/kanshi/index.js +1 -1
  203. package/build/src/kanshi/read.d.ts +7 -3
  204. package/build/src/kanshi/read.js +245 -45
  205. package/build/src/kanshi/report.d.ts +81 -6
  206. package/build/src/kanshi/select.d.ts +5 -0
  207. package/build/src/kanshi/select.js +33 -1
  208. package/build/src/library/address.d.ts +57 -0
  209. package/build/src/library/address.js +165 -0
  210. package/build/src/library/akuma-creation.d.ts +16 -7
  211. package/build/src/library/akuma-creation.js +96 -22
  212. package/build/src/library/audit.d.ts +18 -0
  213. package/build/src/library/audit.js +44 -0
  214. package/build/src/library/bind.d.ts +21 -0
  215. package/build/src/library/bind.js +56 -0
  216. package/build/src/library/catalog.d.ts +58 -0
  217. package/build/src/library/catalog.js +69 -0
  218. package/build/src/library/configuration.d.ts +6 -15
  219. package/build/src/library/configuration.js +14 -17
  220. package/build/src/library/contract.d.ts +23 -49
  221. package/build/src/library/contract.js +171 -185
  222. package/build/src/library/delivery.d.ts +24 -0
  223. package/build/src/library/delivery.js +21 -0
  224. package/build/src/library/fleet.d.ts +65 -0
  225. package/build/src/library/fleet.js +153 -0
  226. package/build/src/library/input.d.ts +3 -0
  227. package/build/src/library/input.js +19 -0
  228. package/build/src/library/keiyaku.d.ts +18 -3
  229. package/build/src/library/keiyaku.js +12 -1
  230. package/build/src/library/mutation.d.ts +39 -0
  231. package/build/src/library/mutation.js +37 -0
  232. package/build/src/library/reconcile.d.ts +29 -0
  233. package/build/src/library/reconcile.js +179 -0
  234. package/build/src/library/refusal.d.ts +21 -0
  235. package/build/src/library/refusal.js +29 -0
  236. package/build/src/library/region.d.ts +14 -1
  237. package/build/src/library/region.js +18 -4
  238. package/build/src/library/repo.d.ts +4 -13
  239. package/build/src/library/repo.js +14 -24
  240. package/build/src/protocol/attempt.d.ts +16 -3
  241. package/build/src/protocol/attempt.js +41 -10
  242. package/build/src/protocol/bind.d.ts +9 -2
  243. package/build/src/protocol/bind.js +48 -40
  244. package/build/src/protocol/intent.d.ts +57 -20
  245. package/build/src/protocol/intent.js +55 -79
  246. package/build/src/protocol/operations.d.ts +152 -43
  247. package/build/src/protocol/operations.js +482 -166
  248. package/build/src/protocol/outcome.d.ts +14 -3
  249. package/build/src/protocol/outcome.js +11 -3
  250. package/build/src/protocol/placement.d.ts +41 -0
  251. package/build/src/protocol/placement.js +147 -0
  252. package/build/src/protocol/read/documents.d.ts +2 -2
  253. package/build/src/protocol/read/documents.js +4 -4
  254. package/build/src/protocol/read/status.d.ts +18 -5
  255. package/build/src/protocol/read/status.js +73 -13
  256. package/build/src/protocol/run.d.ts +49 -7
  257. package/build/src/protocol/run.js +53 -25
  258. package/build/src/runtime/proc/line-rpc.d.ts +4 -8
  259. package/build/src/runtime/proc/line-rpc.js +22 -28
  260. package/build/src/runtime/proc/run.d.ts +23 -21
  261. package/build/src/runtime/proc/run.js +123 -89
  262. package/build/src/runtime/proc/stdio.d.ts +18 -0
  263. package/build/src/runtime/proc/stdio.js +58 -0
  264. package/build/src/settings.d.ts +7 -1
  265. package/build/src/settings.js +32 -17
  266. package/build/src/settlement/fence.d.ts +5 -0
  267. package/build/src/settlement/fence.js +14 -0
  268. package/build/src/settlement/holder.d.ts +35 -4
  269. package/build/src/settlement/holder.js +127 -28
  270. package/build/src/settlement/settle.d.ts +9 -1
  271. package/build/src/settlement/settle.js +74 -37
  272. package/build/src/task/board.d.ts +23 -5
  273. package/build/src/task/board.js +17 -10
  274. package/build/src/task/compose.d.ts +2 -2
  275. package/build/src/task/compose.js +18 -10
  276. package/build/src/task/context.d.ts +3 -3
  277. package/build/src/task/context.js +15 -20
  278. package/build/src/task/document.d.ts +2 -1
  279. package/build/src/task/document.js +15 -5
  280. package/build/src/task/index.d.ts +27 -15
  281. package/build/src/task/index.js +57 -35
  282. package/build/src/task/operations.d.ts +38 -13
  283. package/build/src/task/operations.js +80 -46
  284. package/build/src/task/query.d.ts +67 -0
  285. package/build/src/task/query.js +279 -0
  286. package/build/src/task/store.d.ts +5 -7
  287. package/build/src/task/store.js +43 -28
  288. package/build/src/verification/declaration.d.ts +1 -0
  289. package/build/src/verification/execution.d.ts +51 -0
  290. package/build/src/verification/execution.js +108 -0
  291. package/build/src/workspace-place.d.ts +41 -0
  292. package/build/src/workspace-place.js +386 -0
  293. package/build/src/world.d.ts +24 -0
  294. package/build/src/world.js +136 -0
  295. package/package.json +8 -4
  296. package/build/src/akuma/activity.d.ts +0 -66
  297. package/build/src/akuma/activity.js +0 -139
  298. package/build/src/akuma/providers/claude.js +0 -305
  299. package/build/src/context-root.d.ts +0 -4
  300. package/build/src/context-root.js +0 -15
  301. package/build/src/git/delivery.d.ts +0 -20
  302. package/build/src/git/delivery.js +0 -109
  303. package/build/src/git/verification.d.ts +0 -14
  304. package/build/src/git/verification.js +0 -56
  305. package/build/src/protocol/read/audit.d.ts +0 -25
  306. package/build/src/protocol/read/audit.js +0 -39
  307. package/build/src/verification/producer.d.ts +0 -23
  308. package/build/src/verification/producer.js +0 -54
@@ -1,38 +1,52 @@
1
1
  import { type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
2
2
  import type { ContractsObservation } from "../core/facts/observation.js";
3
3
  import { type GitSnapshot, type GitOid, type GitRepository } from "./repository.js";
4
+ import { type GitDecodeChannel, type GitReadObservation, type GitTreeSelection } from "./read-observation.js";
5
+ export type TargetObservation = Readonly<{
6
+ head: SnapshotId | null;
7
+ drift: boolean;
8
+ }>;
9
+ export declare function observeDeliveryTargetAt(observation: GitReadObservation, state: ContractState): Promise<TargetObservation | null>;
4
10
  type GitJournalRecord = Readonly<{
5
11
  entries: readonly JournalEntry[];
6
12
  state: ContractState | null;
7
13
  }>;
8
- type GitObservation = Readonly<{
14
+ export type ContractWorldObservation = Readonly<{
15
+ snapshot: SnapshotId | null;
9
16
  contracts: ReadonlyMap<ContractId, GitJournalRecord>;
10
17
  }>;
18
+ export type ActiveContractWorldObservation = ContractWorldObservation & Readonly<{
19
+ eligibility: ContractsObservation;
20
+ }>;
11
21
  export type GitAdmissionSnapshot = Readonly<{
12
22
  snapshot: GitSnapshot;
13
23
  frozenJournalBytes: ReadonlyMap<GitOid, Buffer>;
24
+ treeDirectories: ReadonlyMap<string, ReadonlyMap<string, import("./tree.js").TreeEntry>>;
14
25
  }>;
15
26
  export type GitDecisionObservation = Readonly<{
16
27
  admission: GitAdmissionSnapshot;
17
28
  decision: ContractsObservation;
18
29
  journals: ReadonlyMap<ContractId, GitJournalRecord>;
19
30
  }>;
20
- type BindCoordinatesObservation = Readonly<{
31
+ export type BindCoordinatesObservation = Readonly<{
21
32
  start: SnapshotId;
22
33
  target?: string;
34
+ branch: string | null;
23
35
  }>;
24
- export declare function normalizeTargetBranch(repository: GitRepository, input: string): string | null;
25
- /** Read the effective worktree's attached branch, or null for detached HEAD. */
26
- export declare function currentBranch(repository: GitRepository): string | null;
36
+ export declare function normalizeTargetBranch(repository: GitRepository, input: string): Promise<string | null>;
37
+ /** Read one worktree's attached branch, or null for detached HEAD. */
38
+ export declare function currentBranch(repository: GitRepository, path?: string): Promise<string | null>;
27
39
  /** Observe bind's tender start and optional reward target without creating persistent state. */
28
- export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): BindCoordinatesObservation | null;
29
- /** Read one immutable Git snapshot, enumerate its journals, and include requested absence. */
30
- export declare function observeGit(repository: GitRepository, requested?: readonly ContractId[]): GitObservation;
31
- /** Read one Git tree and fold all requested contracts from that immutable snapshot. */
32
- export declare function observeContracts(repository: GitRepository, ids: readonly ContractId[]): GitObservation;
33
- export declare function observeContractsForAdmission(repository: GitRepository, ids: readonly ContractId[]): GitDecisionObservation;
34
- /** Extend one admission observation with contracts from its already-pinned tree. */
35
- export declare function extendContractsForAdmission(repository: GitRepository, observation: GitDecisionObservation, ids: readonly ContractId[]): GitDecisionObservation;
36
- export declare function observeGitForAdmission(repository: GitRepository, ids: readonly ContractId[]): GitDecisionObservation;
37
- export declare function observeContract(repository: GitRepository, id: ContractId): GitJournalRecord;
40
+ export declare function observeBindCoordinates(repository: GitRepository, requestedTarget?: string): Promise<BindCoordinatesObservation | null>;
41
+ export declare function observeActiveContractWorld(observation: GitReadObservation): Promise<ActiveContractWorldObservation>;
42
+ export declare function observeContractWorld(observation: GitReadObservation, requested?: readonly ContractId[]): Promise<ContractWorldObservation>;
43
+ export declare function observeContractsForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
44
+ /** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
45
+ export declare function observeGitForAdmissionAt(repository: GitRepository, channel: GitDecodeChannel, ids: readonly ContractId[], selection?: GitTreeSelection): Promise<GitDecisionObservation>;
46
+ export declare function withContractReadObservationAt<Value>(repository: GitRepository, channel: GitDecodeChannel, id: ContractId, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
47
+ /** Observe targeted Contract journals within an already frozen Git epoch. */
48
+ export declare function observeContractsForAdmissionInObservationAt(observation: GitReadObservation, ids: readonly ContractId[]): Promise<GitDecisionObservation>;
49
+ export declare function observeContractAt(repository: GitRepository, channel: GitDecodeChannel, id: ContractId): Promise<GitJournalRecord>;
50
+ export declare function extendContractsForAdmissionAt(channel: GitDecodeChannel, observation: GitDecisionObservation, ids: readonly ContractId[]): Promise<GitDecisionObservation>;
51
+ export declare function extendAdmissionPathsAt(channel: GitDecodeChannel, observation: GitDecisionObservation, paths: readonly string[]): Promise<GitDecisionObservation>;
38
52
  export {};
@@ -1,10 +1,25 @@
1
1
  import { decodeJournal } from "../core/facts/codec.js";
2
2
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
3
3
  import { foldJournal } from "../core/facts/fold.js";
4
- import { contractJournalPath, mintContractHead, mintSnapshotId } from "./identity.js";
5
- import { GitPlumbingError, isKeiyakuOwnedRef, extendGitPaths, readBlobs, readGit, readGitPaths, runGit, } from "./repository.js";
4
+ import { contractJournalPath, contractJournalPaths, mintContractHead, mintSnapshotId, } from "./identity.js";
5
+ import { GitPlumbingError, isKeiyakuOwnedRef, runGit, } from "./repository.js";
6
+ import { readGitTreeSelection, withGitTargetedReadObservation, } from "./read-observation.js";
7
+ export async function observeDeliveryTargetAt(observation, state) {
8
+ const target = state.coordinates.target;
9
+ if (target === undefined)
10
+ return null;
11
+ const value = await observation.resolveRef(target);
12
+ const head = value === null ? null : mintSnapshotId(value);
13
+ const delivery = state.delivery?.data;
14
+ if (delivery === undefined)
15
+ return { head, drift: false };
16
+ const expected = state.terminal?.kind === "claimed"
17
+ ? delivery.integration.snapshot
18
+ : delivery.integration.predecessor;
19
+ return { head, drift: head !== expected };
20
+ }
6
21
  const TARGET_COORDINATES_FORMAT = "%(refname)%00%(objectname)%00";
7
- export function normalizeTargetBranch(repository, input) {
22
+ export async function normalizeTargetBranch(repository, input) {
8
23
  if (input.includes("\0"))
9
24
  return null;
10
25
  const prefix = "refs/heads/";
@@ -15,7 +30,7 @@ export function normalizeTargetBranch(repository, input) {
15
30
  if (branch.length === 0 || branch.startsWith("-") || isKeiyakuOwnedRef(target))
16
31
  return null;
17
32
  try {
18
- const checked = runGit(repository, ["check-ref-format", "--branch", branch]).toString("utf8").trim();
33
+ const checked = (await runGit(repository, ["check-ref-format", "--branch", branch])).toString("utf8").trim();
19
34
  return checked === branch ? target : null;
20
35
  }
21
36
  catch (error) {
@@ -24,10 +39,15 @@ export function normalizeTargetBranch(repository, input) {
24
39
  throw error;
25
40
  }
26
41
  }
27
- /** Read the effective worktree's attached branch, or null for detached HEAD. */
28
- export function currentBranch(repository) {
42
+ /** Read one worktree's attached branch, or null for detached HEAD. */
43
+ export async function currentBranch(repository, path) {
29
44
  try {
30
- const ref = runGit(repository, ["symbolic-ref", "--quiet", "HEAD"]).toString("utf8").trim();
45
+ const ref = (await runGit(repository, [
46
+ ...(path === undefined ? [] : ["-C", path]),
47
+ "symbolic-ref",
48
+ "--quiet",
49
+ "HEAD",
50
+ ])).toString("utf8").trim();
31
51
  return ref.startsWith("refs/heads/") ? ref : null;
32
52
  }
33
53
  catch (error) {
@@ -46,10 +66,13 @@ function structuredFields(output, fieldCount) {
46
66
  return fields.slice(0, -1);
47
67
  }
48
68
  /** Observe bind's tender start and optional reward target without creating persistent state. */
49
- export function observeBindCoordinates(repository, requestedTarget) {
69
+ export async function observeBindCoordinates(repository, requestedTarget) {
50
70
  if (requestedTarget === undefined) {
51
71
  try {
52
- return { start: mintSnapshotId(runGit(repository, ["rev-parse", "--verify", "HEAD"]).toString("utf8").trim()) };
72
+ return {
73
+ start: mintSnapshotId((await runGit(repository, ["rev-parse", "--verify", "HEAD"])).toString("utf8").trim()),
74
+ branch: await currentBranch(repository),
75
+ };
53
76
  }
54
77
  catch {
55
78
  malformedBindCoordinatesOutput();
@@ -58,7 +81,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
58
81
  if (isKeiyakuOwnedRef(requestedTarget)) {
59
82
  throw new Error(`bind target names a Keiyaku-owned ref: ${requestedTarget}`);
60
83
  }
61
- const output = runGit(repository, [
84
+ const output = await runGit(repository, [
62
85
  "for-each-ref",
63
86
  `--format=${TARGET_COORDINATES_FORMAT}`,
64
87
  "--",
@@ -70,7 +93,7 @@ export function observeBindCoordinates(repository, requestedTarget) {
70
93
  if (target !== requestedTarget || start === undefined)
71
94
  malformedBindCoordinatesOutput();
72
95
  try {
73
- return { target, start: mintSnapshotId(start) };
96
+ return { target, start: mintSnapshotId(start), branch: await currentBranch(repository) };
74
97
  }
75
98
  catch {
76
99
  malformedBindCoordinatesOutput();
@@ -93,35 +116,47 @@ function decodeGitJournal(path, git, bytes, expectedId) {
93
116
  throw new AuthorityCorruptionError(`journal content does not canonically identify ${path}`);
94
117
  }
95
118
  const id = first.contract;
96
- if (contractJournalPath(id) !== path) {
119
+ if (!contractJournalPaths(id).includes(path)) {
97
120
  throw new AuthorityCorruptionError(`journal path does not match canonical contract identity: ${path}`);
98
121
  }
99
122
  return { id, entries, oid: journal.oid };
100
123
  }
101
- function observeDecodedJournal(id, decoded) {
124
+ function journalClass(state) {
125
+ return state.terminal === null ? "active" : "terminal";
126
+ }
127
+ function observeDecodedJournal(id, decoded, path) {
128
+ const state = foldJournal(id, decoded.entries, mintContractHead(decoded.oid));
129
+ if (path !== undefined && contractJournalPath(id, journalClass(state)) !== path) {
130
+ throw new AuthorityCorruptionError(`journal path class does not match folded state: ${path}`);
131
+ }
102
132
  return {
103
133
  entries: decoded.entries,
104
- state: foldJournal(id, decoded.entries, mintContractHead(decoded.oid)),
134
+ state,
105
135
  };
106
136
  }
107
137
  function observeFromGit(git, id, blobs) {
108
- const path = contractJournalPath(id);
109
- const journal = git.paths.get(path);
110
- if (journal === undefined)
138
+ const matches = contractJournalPaths(id)
139
+ .flatMap((path) => git.paths.has(path) ? [path] : []);
140
+ if (matches.length > 1)
141
+ throw new AuthorityCorruptionError(`duplicate contract journal identity: ${id}`);
142
+ const path = matches[0];
143
+ if (path === undefined)
111
144
  return { entries: [], state: null };
145
+ const journal = git.paths.get(path);
112
146
  if (journal.type !== "blob")
113
147
  throw new AuthorityCorruptionError(`journal path is not a blob: ${path}`);
114
148
  const bytes = blobs.get(journal.oid);
115
149
  if (bytes === undefined)
116
150
  throw new Error(`missing batched journal bytes: ${path}`);
117
151
  const decoded = decodeGitJournal(path, git, bytes, id);
118
- return observeDecodedJournal(id, decoded);
152
+ return observeDecodedJournal(id, decoded, path);
119
153
  }
120
- function enumerateContractObservations(git, blobs) {
154
+ function enumerateContractObservations(git, blobs, journalClass) {
121
155
  const observations = new Map();
122
156
  const seen = new Set();
123
157
  for (const [path, journal] of git.paths) {
124
- if (!path.startsWith("contracts/") || !path.endsWith(".jsonl"))
158
+ const match = /^contracts\/(active|terminal)\/[0-9a-f]{2}\/[0-9a-f]{2}\/[0-9a-f]{60}\.jsonl$/u.exec(path);
159
+ if (match === null || (journalClass !== undefined && match[1] !== journalClass))
125
160
  continue;
126
161
  if (journal.type !== "blob")
127
162
  throw new AuthorityCorruptionError(`journal path is not a blob: ${path}`);
@@ -133,95 +168,169 @@ function enumerateContractObservations(git, blobs) {
133
168
  if (seen.has(id))
134
169
  throw new AuthorityCorruptionError(`duplicate contract journal identity: ${id}`);
135
170
  seen.add(id);
136
- observations.set(id, observeDecodedJournal(id, decoded));
171
+ observations.set(id, observeDecodedJournal(id, decoded, path));
137
172
  }
138
173
  return observations;
139
174
  }
140
- /** Read one immutable Git snapshot, enumerate its journals, and include requested absence. */
141
- export function observeGit(repository, requested = []) {
142
- const git = readGit(repository);
143
- const observed = observeFrozenGitSnapshot(repository, git, requested);
144
- return { contracts: observed.contracts };
175
+ export async function observeActiveContractWorld(observation) {
176
+ const git = observation.snapshot;
177
+ const journals = [...git.paths]
178
+ .filter(([path, entry]) => path.startsWith("contracts/active/") && path.endsWith(".jsonl") && entry.type === "blob");
179
+ const results = await observation.readBlobs(journals.map(([, entry]) => entry.oid));
180
+ const blobs = new Map();
181
+ for (const [path, entry] of journals) {
182
+ const result = results.get(entry.oid);
183
+ if (result?.kind !== "present")
184
+ throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
185
+ blobs.set(entry.oid, result.bytes);
186
+ }
187
+ const contracts = new Map(enumerateContractObservations(git, blobs, "active"));
188
+ const prerequisites = [...new Set([...contracts.values()].flatMap((record) => record.state?.terms.after ?? []))];
189
+ const dependencyRecords = await observeTargetedContractsAt(observation, prerequisites);
190
+ return {
191
+ snapshot: git.commit === null ? null : mintSnapshotId(git.commit),
192
+ contracts,
193
+ eligibility: decisionProjection({
194
+ contracts: new Map([...contracts, ...dependencyRecords.contracts]),
195
+ }),
196
+ };
145
197
  }
146
- function observeFrozenGitSnapshot(repository, git, requested) {
147
- const blobs = readBlobs(repository, [...git.paths]
148
- .filter(([path, entry]) => path.startsWith("contracts/") && path.endsWith(".jsonl") && entry.type === "blob")
149
- .map(([, entry]) => entry.oid));
198
+ export async function observeContractWorld(observation, requested = []) {
199
+ const git = observation.snapshot;
200
+ const journals = [...git.paths]
201
+ .filter(([path, entry]) => /^contracts\/(?:active|terminal)\//u.test(path) && path.endsWith(".jsonl") && entry.type === "blob");
202
+ const results = await observation.readBlobs(journals.map(([, entry]) => entry.oid));
203
+ const blobs = new Map();
204
+ for (const [path, entry] of journals) {
205
+ const result = results.get(entry.oid);
206
+ if (result?.kind !== "present")
207
+ throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
208
+ blobs.set(entry.oid, result.bytes);
209
+ }
150
210
  const contracts = new Map(enumerateContractObservations(git, blobs));
151
211
  for (const id of requested) {
152
212
  if (!contracts.has(id))
153
213
  contracts.set(id, observeFromGit(git, id, blobs));
154
214
  }
155
215
  return {
216
+ snapshot: git.commit === null ? null : mintSnapshotId(git.commit),
156
217
  contracts,
157
- frozenJournalBytes: blobs,
158
218
  };
159
219
  }
160
- /** Read one Git tree and fold all requested contracts from that immutable snapshot. */
161
- export function observeContracts(repository, ids) {
162
- const git = readGitPaths(repository, ids.map((id) => contractJournalPath(id)));
163
- const observed = observeFrozenContractsSnapshot(repository, git, ids);
164
- return { contracts: observed.contracts };
220
+ async function observeTargetedContractsAt(observation, ids) {
221
+ return await observeTargetedContractsFromSnapshotAt(observation.snapshot, observation.readBlobs, ids);
165
222
  }
166
- function observeFrozenContractsSnapshot(repository, git, ids) {
167
- const contracts = new Map();
168
- const paths = ids.map((id) => contractJournalPath(id));
169
- const blobs = readBlobs(repository, paths.flatMap((path) => {
170
- const journal = git.paths.get(path);
171
- return journal?.type === "blob" ? [journal.oid] : [];
172
- }));
173
- for (const id of ids) {
174
- if (!contracts.has(id))
175
- contracts.set(id, observeFromGit(git, id, blobs));
223
+ async function observeTargetedContractsFromSnapshotAt(snapshot, readBlobsAt, ids) {
224
+ const paths = ids.flatMap(contractJournalPaths);
225
+ const entries = paths.flatMap((path) => {
226
+ const journal = snapshot.paths.get(path);
227
+ return journal?.type === "blob" ? [[path, journal]] : [];
228
+ });
229
+ const results = await readBlobsAt(entries.map(([, entry]) => entry.oid));
230
+ const blobs = new Map();
231
+ for (const [path, entry] of entries) {
232
+ const result = results.get(entry.oid);
233
+ if (result?.kind !== "present")
234
+ throw new AuthorityCorruptionError(`missing Git journal object: ${path}`);
235
+ blobs.set(entry.oid, result.bytes);
176
236
  }
177
- return {
178
- contracts,
179
- frozenJournalBytes: blobs,
180
- };
237
+ const contracts = new Map();
238
+ for (const id of ids)
239
+ contracts.set(id, observeFromGit(snapshot, id, blobs));
240
+ return { contracts, frozenJournalBytes: blobs };
181
241
  }
182
- function decisionProjection(observation) {
183
- return new Map([...observation.contracts].map(([id, record]) => [id, record.state]));
242
+ export async function observeContractsForAdmissionAt(repository, channel, ids, selection = {}) {
243
+ return withGitTargetedReadObservation(repository, channel, {
244
+ paths: [...ids.flatMap(contractJournalPaths), ...(selection.paths ?? [])],
245
+ ...(selection.subtrees === undefined ? {} : { subtrees: selection.subtrees }),
246
+ }, async (observation) => await observeContractsForAdmissionInObservationAt(observation, ids));
247
+ }
248
+ /** Observe selected Contract journals and their current direct prerequisites in one Git epoch. */
249
+ export async function observeGitForAdmissionAt(repository, channel, ids, selection = {}) {
250
+ const observation = await observeContractsForAdmissionAt(repository, channel, ids, selection);
251
+ const prerequisites = [...new Set(ids.flatMap((id) => observation.decision.get(id)?.terms.after ?? []))];
252
+ return await extendContractsForAdmissionAt(channel, observation, prerequisites);
253
+ }
254
+ export function withContractReadObservationAt(repository, channel, id, consume) {
255
+ return withGitTargetedReadObservation(repository, channel, {
256
+ paths: contractJournalPaths(id),
257
+ }, consume);
184
258
  }
185
- export function observeContractsForAdmission(repository, ids) {
186
- const git = readGitPaths(repository, ids.map((id) => contractJournalPath(id)));
187
- const contracts = observeFrozenContractsSnapshot(repository, git, ids);
259
+ /** Observe targeted Contract journals within an already frozen Git epoch. */
260
+ export async function observeContractsForAdmissionInObservationAt(observation, ids) {
261
+ const contracts = await observeTargetedContractsAt(observation, ids);
188
262
  return {
189
- admission: { snapshot: git, frozenJournalBytes: contracts.frozenJournalBytes },
263
+ admission: {
264
+ snapshot: observation.snapshot,
265
+ frozenJournalBytes: contracts.frozenJournalBytes,
266
+ treeDirectories: observation.treeDirectories,
267
+ },
190
268
  decision: decisionProjection(contracts),
191
269
  journals: contracts.contracts,
192
270
  };
193
271
  }
194
- /** Extend one admission observation with contracts from its already-pinned tree. */
195
- export function extendContractsForAdmission(repository, observation, ids) {
272
+ export async function observeContractAt(repository, channel, id) {
273
+ const observation = await observeContractsForAdmissionAt(repository, channel, [id]);
274
+ const record = observation.journals.get(id);
275
+ if (record === undefined)
276
+ throw new Error(`missing requested contract observation: ${id}`);
277
+ return record;
278
+ }
279
+ export async function extendContractsForAdmissionAt(channel, observation, ids) {
196
280
  const missing = ids.filter((id) => !observation.decision.has(id));
197
281
  if (missing.length === 0)
198
282
  return observation;
199
- const snapshot = extendGitPaths(repository, observation.admission.snapshot, missing.map((id) => contractJournalPath(id)));
200
- const added = observeFrozenContractsSnapshot(repository, snapshot, missing);
283
+ const readBlobsAt = async (oids) => {
284
+ const objects = await channel.readObjects(oids);
285
+ const blobs = new Map();
286
+ for (const [oid, object] of objects) {
287
+ if (object.kind === "missing")
288
+ blobs.set(oid, object);
289
+ else {
290
+ if (object.type !== "blob")
291
+ throw new AuthorityCorruptionError(`Git object is not a blob: ${oid}`);
292
+ blobs.set(oid, { kind: "present", bytes: object.bytes });
293
+ }
294
+ }
295
+ return blobs;
296
+ };
297
+ const snapshot = observation.admission.snapshot;
298
+ if (snapshot.tree === null)
299
+ return observation;
300
+ const selected = await readGitTreeSelection(channel, snapshot.tree, {
301
+ paths: missing.flatMap(contractJournalPaths),
302
+ });
303
+ const extendedSnapshot = {
304
+ ...snapshot,
305
+ paths: new Map([...snapshot.paths, ...selected.paths]),
306
+ };
307
+ const added = await observeTargetedContractsFromSnapshotAt(extendedSnapshot, readBlobsAt, missing);
201
308
  return {
202
309
  admission: {
203
- snapshot,
204
- frozenJournalBytes: new Map([
205
- ...observation.admission.frozenJournalBytes,
206
- ...added.frozenJournalBytes,
207
- ]),
310
+ snapshot: extendedSnapshot,
311
+ frozenJournalBytes: new Map([...observation.admission.frozenJournalBytes, ...added.frozenJournalBytes]),
312
+ treeDirectories: new Map([...observation.admission.treeDirectories, ...selected.directories]),
208
313
  },
209
314
  decision: new Map([...observation.decision, ...decisionProjection(added)]),
210
315
  journals: new Map([...observation.journals, ...added.contracts]),
211
316
  };
212
317
  }
213
- export function observeGitForAdmission(repository, ids) {
214
- const git = readGit(repository);
215
- const contracts = observeFrozenGitSnapshot(repository, git, ids);
318
+ export async function extendAdmissionPathsAt(channel, observation, paths) {
319
+ if (paths.length === 0 || observation.admission.snapshot.tree === null)
320
+ return observation;
321
+ const selected = await readGitTreeSelection(channel, observation.admission.snapshot.tree, { paths });
216
322
  return {
217
- admission: { snapshot: git, frozenJournalBytes: contracts.frozenJournalBytes },
218
- decision: decisionProjection(contracts),
219
- journals: contracts.contracts,
323
+ ...observation,
324
+ admission: {
325
+ ...observation.admission,
326
+ snapshot: {
327
+ ...observation.admission.snapshot,
328
+ paths: new Map([...observation.admission.snapshot.paths, ...selected.paths]),
329
+ },
330
+ treeDirectories: new Map([...observation.admission.treeDirectories, ...selected.directories]),
331
+ },
220
332
  };
221
333
  }
222
- export function observeContract(repository, id) {
223
- const observation = observeContracts(repository, [id]).contracts.get(id);
224
- if (observation === undefined)
225
- throw new Error(`missing requested contract observation: ${id}`);
226
- return observation;
334
+ function decisionProjection(observation) {
335
+ return new Map([...observation.contracts].map(([id, record]) => [id, record.state]));
227
336
  }
@@ -0,0 +1,41 @@
1
+ import { type TreeEntry } from "./tree.js";
2
+ import { type GitOid, type GitRepository, type GitSnapshot } from "./repository.js";
3
+ declare const gitReadObservationBrand: unique symbol;
4
+ declare const gitDecodeChannelBrand: unique symbol;
5
+ export type GitBlobResult = Readonly<{
6
+ kind: "present";
7
+ bytes: Buffer;
8
+ }> | Readonly<{
9
+ kind: "missing";
10
+ }>;
11
+ export type GitReadObservation = Readonly<{
12
+ readonly [gitReadObservationBrand]: true;
13
+ repository: GitRepository;
14
+ snapshot: GitSnapshot;
15
+ treeDirectories: ReadonlyMap<string, ReadonlyMap<string, TreeEntry>>;
16
+ readBlobs(oids: readonly GitOid[]): Promise<ReadonlyMap<GitOid, GitBlobResult>>;
17
+ resolveRef(ref: string): Promise<GitOid | null>;
18
+ }>;
19
+ export type GitObjectResult = Readonly<{
20
+ kind: "present";
21
+ type: string;
22
+ bytes: Buffer;
23
+ }> | Readonly<{
24
+ kind: "missing";
25
+ }>;
26
+ export type GitDecodeChannel = Readonly<{
27
+ readonly [gitDecodeChannelBrand]: true;
28
+ readObjects(oids: readonly GitOid[]): Promise<ReadonlyMap<GitOid, GitObjectResult>>;
29
+ }>;
30
+ export type GitTreeSelection = Readonly<{
31
+ paths?: readonly string[];
32
+ subtrees?: readonly string[];
33
+ }>;
34
+ export declare function readGitTreeSelection(channel: GitDecodeChannel, root: GitOid, selection: GitTreeSelection): Promise<Readonly<{
35
+ paths: ReadonlyMap<string, TreeEntry>;
36
+ directories: ReadonlyMap<string, ReadonlyMap<string, TreeEntry>>;
37
+ }>>;
38
+ export declare function withGitDecodeChannel<Value>(repository: GitRepository, consume: (channel: GitDecodeChannel) => Value | PromiseLike<Value>): Promise<Value>;
39
+ export declare function withGitReadObservation<Value>(repository: GitRepository, channel: GitDecodeChannel, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
40
+ export declare function withGitTargetedReadObservation<Value>(repository: GitRepository, channel: GitDecodeChannel, selection: GitTreeSelection, consume: (observation: GitReadObservation) => Value | PromiseLike<Value>): Promise<Value>;
41
+ export {};