@astrosheep/keiyaku 4.6.11 → 4.6.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/build/plugins/claude/skills/keiyaku/SKILL.md +3 -1
  2. package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
  3. package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +3 -2
  4. package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +9 -8
  5. package/build/plugins/codex/skills/keiyaku/SKILL.md +3 -1
  6. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
  7. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +3 -2
  8. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +9 -8
  9. package/build/plugins/opencode/skills/keiyaku/SKILL.md +3 -1
  10. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
  11. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +3 -2
  12. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +9 -8
  13. package/build/skills/keiyaku/SKILL.md +3 -1
  14. package/build/skills/keiyaku-babysit/SKILL.md +1 -1
  15. package/build/skills/keiyaku-bind/SKILL.md +3 -2
  16. package/build/skills/keiyaku-workflow/SKILL.md +9 -8
  17. package/build/src/akuma/akuma-errors.d.ts +5 -0
  18. package/build/src/akuma/akuma-errors.js +9 -0
  19. package/build/src/akuma/akuma-owner.d.ts +14 -19
  20. package/build/src/akuma/akuma-owner.js +56 -54
  21. package/build/src/akuma/akuma-selection-execution.d.ts +5 -4
  22. package/build/src/akuma/akuma-selection-execution.js +59 -17
  23. package/build/src/akuma/akuma.d.ts +1 -2
  24. package/build/src/akuma/allowed.d.ts +2 -3
  25. package/build/src/akuma/allowed.js +1 -3
  26. package/build/src/akuma/body.js +17 -7
  27. package/build/src/akuma/call-initial-tell.d.ts +18 -0
  28. package/build/src/akuma/call-initial-tell.js +18 -0
  29. package/build/src/akuma/call-request.d.ts +20 -4
  30. package/build/src/akuma/heart/facts.d.ts +13 -0
  31. package/build/src/akuma/heart/facts.js +6 -0
  32. package/build/src/akuma/heart/index.d.ts +29 -14
  33. package/build/src/akuma/heart/index.js +75 -29
  34. package/build/src/akuma/heart/rows.d.ts +9 -2
  35. package/build/src/akuma/heart/rows.js +72 -11
  36. package/build/src/akuma/heart/storage.d.ts +2 -8
  37. package/build/src/akuma/heart/storage.js +13 -13
  38. package/build/src/akuma/heart/tells.d.ts +3 -1
  39. package/build/src/akuma/heart/tells.js +18 -2
  40. package/build/src/akuma/provider.d.ts +2 -4
  41. package/build/src/akuma/provider.js +29 -6
  42. package/build/src/akuma/providers/acp/core.js +23 -21
  43. package/build/src/akuma/providers/claude/index.js +0 -8
  44. package/build/src/akuma/providers/codex-app-server/index.js +9 -8
  45. package/build/src/akuma/providers/execution-environment.d.ts +1 -1
  46. package/build/src/akuma/providers/execution-environment.js +1 -0
  47. package/build/src/akuma/providers/opencode-sdk/events.js +111 -81
  48. package/build/src/akuma/providers/opencode-sdk/index.js +179 -150
  49. package/build/src/akuma/providers/opencode-sdk/native-http.js +7 -3
  50. package/build/src/akuma/providers/opencode-sdk/session.d.ts +5 -3
  51. package/build/src/akuma/providers/opencode-sdk/session.js +32 -27
  52. package/build/src/akuma/providers/paseo/index.js +0 -2
  53. package/build/src/akuma/providers/pi/index.js +23 -20
  54. package/build/src/akuma/selection-observation.d.ts +78 -9
  55. package/build/src/akuma/selection-owner-port.d.ts +2 -1
  56. package/build/src/akuma/selection-owner-port.js +6 -1
  57. package/build/src/akuma/selection-request.d.ts +1 -1
  58. package/build/src/akuma/selection-request.js +8 -3
  59. package/build/src/akuma/turn-drive.js +79 -48
  60. package/build/src/akuma-body.js +5 -3
  61. package/build/src/cli/commands/akuma-grammar.js +2 -2
  62. package/build/src/cli/commands/akuma.js +24 -16
  63. package/build/src/cli/commands/contract-grammar.d.ts +3 -7
  64. package/build/src/cli/commands/contract-grammar.js +12 -10
  65. package/build/src/cli/commands/contract-help.d.ts +3 -13
  66. package/build/src/cli/commands/contract-help.js +7 -16
  67. package/build/src/cli/commands/contract.js +19 -35
  68. package/build/src/cli/commands/debt.js +30 -29
  69. package/build/src/cli/parse.js +0 -1
  70. package/build/src/cli/render/akuma-activity.d.ts +36 -9
  71. package/build/src/cli/render/akuma-activity.js +142 -65
  72. package/build/src/cli/render/akuma.d.ts +6 -0
  73. package/build/src/cli/render/akuma.js +67 -24
  74. package/build/src/cli/render/catalog.js +0 -1
  75. package/build/src/cli/render/contract-observation.d.ts +16 -3
  76. package/build/src/cli/render/contract-observation.js +3 -0
  77. package/build/src/cli/render/contract.d.ts +2 -2
  78. package/build/src/cli/render/contract.js +4 -4
  79. package/build/src/cli/render/delivery-preview.d.ts +7 -0
  80. package/build/src/cli/render/{audit.js → delivery-preview.js} +29 -27
  81. package/build/src/cli/render/kanshi-akuma.d.ts +3 -1
  82. package/build/src/cli/render/kanshi-akuma.js +23 -8
  83. package/build/src/cli/render/kanshi.js +4 -1
  84. package/build/src/cli/render/receipt.js +3 -3
  85. package/build/src/cli/render/refusal.js +2 -2
  86. package/build/src/cli/render/terminal.d.ts +0 -1
  87. package/build/src/cli/render/terminal.js +1 -1
  88. package/build/src/cli/square-identity.d.ts +15 -0
  89. package/build/src/cli/square-identity.js +180 -0
  90. package/build/src/contract-worktree.js +1 -1
  91. package/build/src/core/verbs/placement.d.ts +2 -1
  92. package/build/src/core/verbs/placement.js +1 -1
  93. package/build/src/debt/context.d.ts +0 -5
  94. package/build/src/debt/context.js +32 -44
  95. package/build/src/git/process.d.ts +1 -0
  96. package/build/src/git/process.js +18 -1
  97. package/build/src/git/read-observation.js +2 -1
  98. package/build/src/git/scratch.d.ts +5 -1
  99. package/build/src/git/scratch.js +41 -12
  100. package/build/src/git/target-placement.d.ts +22 -4
  101. package/build/src/git/target-placement.js +44 -20
  102. package/build/src/index.d.ts +2 -2
  103. package/build/src/kanshi/read.js +187 -105
  104. package/build/src/kanshi/report.d.ts +5 -0
  105. package/build/src/library/address.d.ts +18 -4
  106. package/build/src/library/address.js +27 -6
  107. package/build/src/library/contract-address.d.ts +6 -0
  108. package/build/src/library/contract-address.js +12 -1
  109. package/build/src/library/contract-execution.d.ts +2 -2
  110. package/build/src/library/contract-execution.js +13 -17
  111. package/build/src/library/contract-operations.d.ts +59 -94
  112. package/build/src/library/contract-operations.js +23 -19
  113. package/build/src/library/contract-outcomes.d.ts +3 -3
  114. package/build/src/library/contract-settings.d.ts +1 -0
  115. package/build/src/library/contract-settings.js +1 -1
  116. package/build/src/library/invocation.d.ts +2 -2
  117. package/build/src/library/invocation.js +1 -1
  118. package/build/src/library/keiyaku.d.ts +2 -2
  119. package/build/src/library/keiyaku.js +2 -2
  120. package/build/src/library/outcome.d.ts +148 -268
  121. package/build/src/library/outcome.js +4 -8
  122. package/build/src/library/refusal.d.ts +2 -2
  123. package/build/src/library/refusal.js +2 -2
  124. package/build/src/plugin/runtime.js +15 -19
  125. package/build/src/protocol/{audit.d.ts → delivery-preview.d.ts} +62 -97
  126. package/build/src/protocol/delivery-preview.js +167 -0
  127. package/build/src/protocol/progress.d.ts +1 -1
  128. package/build/src/runtime/proc/run.js +22 -4
  129. package/build/src/runtime/proc/windows-launch.exe +0 -0
  130. package/build/src/verification/execution.d.ts +1 -1
  131. package/build/src/verification/execution.js +5 -3
  132. package/package.json +5 -2
  133. package/skills/keiyaku/SKILL.md +3 -1
  134. package/skills/keiyaku-babysit/SKILL.md +1 -1
  135. package/skills/keiyaku-bind/SKILL.md +3 -2
  136. package/skills/keiyaku-workflow/SKILL.md +9 -8
  137. package/build/src/cli/render/audit.d.ts +0 -7
  138. package/build/src/protocol/audit.js +0 -203
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
- import type { ContractState, SnapshotId } from "../core/facts/types.js";
2
+ import type { ContractState } from "../core/facts/types.js";
3
3
  import type { DocumentDerivation, IntentOutcome, MutationOperationInput } from "./operations.js";
4
- export declare const auditReportSchema: z.ZodObject<{
4
+ export declare const deliveryPreviewReportSchema: z.ZodObject<{
5
5
  candidate: z.ZodUnion<readonly [z.ZodObject<{
6
6
  kind: z.ZodLiteral<"blocked">;
7
7
  refusal: z.ZodUnion<readonly [z.ZodObject<{
@@ -34,20 +34,20 @@ export declare const auditReportSchema: z.ZodObject<{
34
34
  "unrelated-histories": "unrelated-histories";
35
35
  conflict: "conflict";
36
36
  }>;
37
- targetHead: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
37
+ targetHead: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
38
38
  conflictPaths: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
39
39
  }, z.core.$strict>, z.ZodTransform<{
40
40
  kind: "integration-failed";
41
41
  contractId: import("../core/facts/types.js").ContractId;
42
42
  reason: "not-based-on-target" | "unrelated-histories" | "conflict";
43
- targetHead: SnapshotId;
43
+ targetHead: import("../core/facts/types.js").SnapshotId;
44
44
  } & {
45
45
  conflictPaths?: readonly string[];
46
46
  }, {
47
47
  kind: "integration-failed";
48
48
  contractId: import("../core/facts/types.js").ContractId;
49
49
  reason: "not-based-on-target" | "unrelated-histories" | "conflict";
50
- targetHead: SnapshotId;
50
+ targetHead: import("../core/facts/types.js").SnapshotId;
51
51
  conflictPaths?: readonly string[] | undefined;
52
52
  }>>, z.ZodObject<{
53
53
  kind: z.ZodLiteral<"integration-unsupported">;
@@ -76,10 +76,10 @@ export declare const auditReportSchema: z.ZodObject<{
76
76
  }, z.core.$strict>;
77
77
  identity: z.ZodObject<{
78
78
  note: z.ZodOptional<z.ZodString>;
79
- tenderSnapshot: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
79
+ tenderSnapshot: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
80
80
  integration: z.ZodObject<{
81
- predecessor: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
82
- snapshot: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
81
+ predecessor: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
82
+ snapshot: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
83
83
  changeId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ChangeId, string>>;
84
84
  }, z.core.$strict>;
85
85
  method: z.ZodLiteral<"squash">;
@@ -94,92 +94,49 @@ export declare const auditReportSchema: z.ZodObject<{
94
94
  paths: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
95
95
  }, z.core.$strict>;
96
96
  diff: z.ZodOptional<z.ZodString>;
97
+ requirements: z.ZodObject<{
98
+ gates: z.ZodReadonly<z.ZodArray<z.ZodObject<{
99
+ gate: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").Gate, string>>;
100
+ current: z.ZodUnion<readonly [z.ZodObject<{
101
+ kind: z.ZodLiteral<"missing">;
102
+ }, z.core.$strict>, z.ZodObject<{
103
+ kind: z.ZodLiteral<"attested">;
104
+ verdict: z.ZodEnum<{
105
+ satisfied: "satisfied";
106
+ unsatisfied: "unsatisfied";
107
+ }>;
108
+ at: z.ZodString;
109
+ summary: z.ZodOptional<z.ZodString>;
110
+ }, z.core.$strict>, z.ZodObject<{
111
+ kind: z.ZodLiteral<"stale">;
112
+ priorVerdict: z.ZodEnum<{
113
+ satisfied: "satisfied";
114
+ unsatisfied: "unsatisfied";
115
+ }>;
116
+ reason: z.ZodOptional<z.ZodObject<{
117
+ kind: z.ZodLiteral<"candidate-content-changed">;
118
+ target: z.ZodOptional<z.ZodString>;
119
+ previousChange: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ChangeId, string>>;
120
+ currentChange: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ChangeId, string>>;
121
+ }, z.core.$strict>>;
122
+ }, z.core.$strict>]>;
123
+ }, z.core.$strict>>>;
124
+ unmetPrerequisites: z.ZodReadonly<z.ZodArray<z.ZodObject<{
125
+ contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>;
126
+ state: z.ZodEnum<{
127
+ abandoned: "abandoned";
128
+ missing: "missing";
129
+ active: "active";
130
+ }>;
131
+ }, z.core.$strict>>>;
132
+ }, z.core.$strict>;
97
133
  }, z.core.$strict>]>;
98
134
  verification: z.ZodUnion<readonly [z.ZodObject<{
99
135
  kind: z.ZodLiteral<"not-run">;
100
136
  }, z.core.$strict>, z.ZodObject<{
101
137
  kind: z.ZodLiteral<"undeclared">;
102
138
  }, z.core.$strict>, z.ZodObject<{
103
- kind: z.ZodLiteral<"stopped">;
104
- stop: z.ZodUnion<readonly [z.ZodObject<{
105
- refusal: z.ZodUnion<readonly [z.ZodObject<{
106
- kind: z.ZodEnum<{
107
- terminal: "terminal";
108
- "contract-missing": "contract-missing";
109
- }>;
110
- contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>;
111
- }, z.core.$strict>, z.ZodObject<{
112
- kind: z.ZodLiteral<"verification-declaration-invalid">;
113
- contractId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>>;
114
- }, z.core.$strict>]>;
115
- }, z.core.$strict>, z.ZodObject<{
116
- retry: z.ZodUnion<readonly [z.ZodObject<{
117
- kind: z.ZodEnum<{
118
- exhausted: "exhausted";
119
- collision: "collision";
120
- }>;
121
- }, z.core.$strict>, z.ZodObject<{
122
- kind: z.ZodLiteral<"publication-failed">;
123
- diagnostic: z.ZodString;
124
- }, z.core.$strict>]>;
125
- }, z.core.$strict>, z.ZodUnion<readonly [z.ZodObject<{
126
- stdout: z.ZodOptional<z.ZodString>;
127
- stderr: z.ZodOptional<z.ZodString>;
128
- truncated: z.ZodOptional<z.ZodLiteral<true>>;
129
- failure: z.ZodEnum<{
130
- cancelled: "cancelled";
131
- "unknown-exit": "unknown-exit";
132
- }>;
133
- }, z.core.$strict>, z.ZodObject<{
134
- stdout: z.ZodOptional<z.ZodString>;
135
- stderr: z.ZodOptional<z.ZodString>;
136
- truncated: z.ZodOptional<z.ZodLiteral<true>>;
137
- failure: z.ZodEnum<{
138
- "spawn-error": "spawn-error";
139
- "candidate-unavailable": "candidate-unavailable";
140
- }>;
141
- diagnostic: z.ZodString;
142
- }, z.core.$strict>, z.ZodObject<{
143
- stdout: z.ZodOptional<z.ZodString>;
144
- stderr: z.ZodOptional<z.ZodString>;
145
- truncated: z.ZodOptional<z.ZodLiteral<true>>;
146
- failure: z.ZodLiteral<"environment-failure">;
147
- diagnostic: z.ZodString;
148
- }, z.core.$strict>, z.ZodObject<{
149
- stdout: z.ZodOptional<z.ZodString>;
150
- stderr: z.ZodOptional<z.ZodString>;
151
- truncated: z.ZodOptional<z.ZodLiteral<true>>;
152
- failure: z.ZodLiteral<"environment-failure">;
153
- name: z.ZodString;
154
- detail: z.ZodUnion<readonly [z.ZodObject<{
155
- kind: z.ZodLiteral<"exit">;
156
- code: z.ZodNumber;
157
- stdout: z.ZodString;
158
- stderr: z.ZodString;
159
- truncated: z.ZodBoolean;
160
- }, z.core.$strict>, z.ZodObject<{
161
- stdout: z.ZodOptional<z.ZodString>;
162
- stderr: z.ZodOptional<z.ZodString>;
163
- truncated: z.ZodOptional<z.ZodBoolean>;
164
- kind: z.ZodLiteral<"timeout">;
165
- }, z.core.$strict>, z.ZodObject<{
166
- stdout: z.ZodOptional<z.ZodString>;
167
- stderr: z.ZodOptional<z.ZodString>;
168
- truncated: z.ZodOptional<z.ZodBoolean>;
169
- kind: z.ZodLiteral<"unknown-exit">;
170
- }, z.core.$strict>, z.ZodObject<{
171
- kind: z.ZodLiteral<"spawn-error">;
172
- diagnostic: z.ZodString;
173
- }, z.core.$strict>]>;
174
- }, z.core.$strict>]>]>;
175
- }, z.core.$strict>, z.ZodObject<{
176
- kind: z.ZodEnum<{
177
- satisfied: "satisfied";
178
- unsatisfied: "unsatisfied";
179
- }>;
180
- passed: z.ZodNumber;
181
- total: z.ZodNumber;
182
- summary: z.ZodOptional<z.ZodString>;
139
+ kind: z.ZodLiteral<"required">;
183
140
  }, z.core.$strict>, z.ZodObject<{
184
141
  entry: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").EntryUlid, string>>;
185
142
  verdict: z.ZodEnum<{
@@ -187,19 +144,27 @@ export declare const auditReportSchema: z.ZodObject<{
187
144
  unsatisfied: "unsatisfied";
188
145
  }>;
189
146
  summary: z.ZodOptional<z.ZodString>;
190
- kind: z.ZodLiteral<"reused">;
147
+ kind: z.ZodLiteral<"recorded">;
191
148
  }, z.core.$strict>]>;
192
149
  target: z.ZodUnion<readonly [z.ZodObject<{
193
150
  kind: z.ZodLiteral<"not-observed">;
194
151
  }, z.core.$strict>, z.ZodUnion<readonly [z.ZodObject<{
195
152
  kind: z.ZodLiteral<"placeable">;
196
153
  ref: z.ZodString;
197
- head: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
154
+ head: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
155
+ checkouts: z.ZodReadonly<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
156
+ kind: z.ZodLiteral<"followable">;
157
+ path: z.ZodString;
158
+ }, z.core.$strict>, z.ZodObject<{
159
+ kind: z.ZodLiteral<"not-followable">;
160
+ path: z.ZodString;
161
+ diagnostic: z.ZodString;
162
+ }, z.core.$strict>]>>>;
198
163
  }, z.core.$strict>, z.ZodObject<{
199
164
  kind: z.ZodLiteral<"moved">;
200
165
  ref: z.ZodString;
201
- expected: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
202
- observed: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>>;
166
+ expected: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
167
+ observed: z.ZodNullable<z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>>;
203
168
  }, z.core.$strict>, z.ZodObject<{
204
169
  kind: z.ZodLiteral<"refused">;
205
170
  refusal: z.ZodObject<{
@@ -251,14 +216,14 @@ export declare const auditReportSchema: z.ZodObject<{
251
216
  }, z.core.$strict>]>;
252
217
  }, z.core.$strict>>;
253
218
  }, z.core.$strict>;
254
- export type AuditReport = z.infer<typeof auditReportSchema>;
255
- type AuditOperationInput = MutationOperationInput & Readonly<{
256
- deriveDocument?: (state: ContractState) => DocumentDerivation;
219
+ export type DeliveryPreviewReport = z.infer<typeof deliveryPreviewReportSchema>;
220
+ type DeliveryPreviewOperationInput = MutationOperationInput & Readonly<{
221
+ deriveDocument: (state: ContractState) => DocumentDerivation;
257
222
  requireBranchesToBeUpToDate?: boolean;
258
223
  includeDirty?: boolean;
259
224
  showDiff?: boolean;
260
225
  signal?: AbortSignal;
261
226
  }>;
262
- type AuditRefusal = import("../core/verbs/deliver.js").DeliverRefusal | import("../verification/declaration.js").VerificationDeclarationRefusal;
263
- export declare function auditOperation(input: AuditOperationInput): Promise<IntentOutcome<AuditReport, AuditRefusal>>;
227
+ type PreviewRefusal = import("../core/verbs/deliver.js").DeliverRefusal | import("../verification/declaration.js").VerificationDeclarationRefusal;
228
+ export declare function previewDeliveryOperation(input: DeliveryPreviewOperationInput): Promise<IntentOutcome<DeliveryPreviewReport, PreviewRefusal>>;
264
229
  export {};
@@ -0,0 +1,167 @@
1
+ import { z } from "zod";
2
+ import { deliverDataSchema, deliveryPreparationRefusalSchema, changeIdSchema, verdictSchema, entryUlidSchema, contractIdSchema, gateReportSchema, recordedIntegrationSnapshots, } from "./operations.js";
3
+ import { previewTargetAnswerSchema, adjudicatePreviewTarget } from "../git/target-placement.js";
4
+ import { verificationReuseSchema, currentVerifiedAttestation } from "./intent.js";
5
+ import { deliveryDiffScopeSchema, readDeliveryDiff, readDeliveryScope } from "../git/integration.js";
6
+ import { observeGitForAdmissionAt } from "../git/observe.js";
7
+ import { activeContract, documentIsCurrent } from "../core/facts/observation.js";
8
+ import { gateReports } from "../core/facts/gate.js";
9
+ import { unmetPrerequisites } from "../core/verbs/placement.js";
10
+ import { observeTargetLag, contractTargetLagSchema, worktreeWorkspaceSchema } from "../git/workspace.js";
11
+ import { readManagedWorktreeAppointment } from "../workspace-place.js";
12
+ import { accepted } from "./outcome.js";
13
+ import { prepareDelivery } from "./deliver.js";
14
+ export const deliveryPreviewReportSchema = z
15
+ .object({
16
+ candidate: z.union([
17
+ z.object({ kind: z.literal("blocked"), refusal: deliveryPreparationRefusalSchema }).strict(),
18
+ z
19
+ .object({
20
+ kind: z.literal("ready"),
21
+ workspace: worktreeWorkspaceSchema,
22
+ identity: deliverDataSchema,
23
+ scope: deliveryDiffScopeSchema,
24
+ diff: z.string().optional(),
25
+ requirements: z
26
+ .object({
27
+ gates: z.array(gateReportSchema).readonly(),
28
+ unmetPrerequisites: z
29
+ .array(z
30
+ .object({
31
+ contractId: contractIdSchema,
32
+ state: z.enum(["missing", "active", "abandoned"]),
33
+ })
34
+ .strict())
35
+ .readonly(),
36
+ })
37
+ .strict(),
38
+ })
39
+ .strict(),
40
+ ]),
41
+ verification: z.union([
42
+ z.object({ kind: z.literal("not-run") }).strict(),
43
+ z.object({ kind: z.literal("undeclared") }).strict(),
44
+ z.object({ kind: z.literal("required") }).strict(),
45
+ verificationReuseSchema.extend({ kind: z.literal("recorded") }).strict(),
46
+ ]),
47
+ target: z.union([z.object({ kind: z.literal("not-observed") }).strict(), previewTargetAnswerSchema]),
48
+ targetLag: contractTargetLagSchema.optional(),
49
+ delivery: z
50
+ .object({
51
+ changeId: changeIdSchema,
52
+ relation: z.enum(["identical", "differs"]),
53
+ verification: z.union([
54
+ z.object({ kind: z.enum(["undeclared", "unrecorded"]) }).strict(),
55
+ z.object({ kind: z.literal("recorded"), verdict: verdictSchema, fact: entryUlidSchema }).strict(),
56
+ ]),
57
+ })
58
+ .strict()
59
+ .optional(),
60
+ })
61
+ .strict();
62
+ function deliveryRelation(state, candidate, declaration) {
63
+ const recorded = state.delivery?.data.integration.changeId;
64
+ if (recorded === undefined)
65
+ return undefined;
66
+ const verification = declaration === null ? undefined : currentVerifiedAttestation(state);
67
+ return {
68
+ changeId: recorded,
69
+ relation: recorded === candidate.integration.changeId ? "identical" : "differs",
70
+ verification: declaration === null
71
+ ? { kind: "undeclared" }
72
+ : verification === undefined
73
+ ? { kind: "unrecorded" }
74
+ : { kind: "recorded", verdict: verification.verdict, fact: verification.entry },
75
+ };
76
+ }
77
+ function verificationAnswer(prospective, declaration) {
78
+ if (declaration === null)
79
+ return { kind: "undeclared" };
80
+ const evidence = currentVerifiedAttestation(prospective);
81
+ return evidence === undefined ? { kind: "required" } : { kind: "recorded", ...evidence };
82
+ }
83
+ async function readyCandidate(repository, candidate, workspace, requirements, showDiff) {
84
+ const { predecessor, snapshot } = candidate.integration;
85
+ const scope = await readDeliveryScope(repository, predecessor, snapshot, showDiff);
86
+ const diff = showDiff ? await readDeliveryDiff(repository, predecessor, snapshot) : undefined;
87
+ return {
88
+ kind: "ready",
89
+ workspace,
90
+ identity: candidate,
91
+ scope,
92
+ requirements,
93
+ ...(diff === undefined || diff === null ? {} : { diff }),
94
+ };
95
+ }
96
+ async function targetAnswer(repository, state, candidate) {
97
+ const target = state.coordinates.target;
98
+ if (target === undefined)
99
+ return { kind: "not-observed" };
100
+ return await adjudicatePreviewTarget(repository, {
101
+ contractId: state.id,
102
+ coordinates: { ...state.coordinates, target },
103
+ predecessor: candidate.integration.predecessor,
104
+ candidate: candidate.integration.snapshot,
105
+ });
106
+ }
107
+ function blockedPreview(refusal) {
108
+ return {
109
+ candidate: { kind: "blocked", refusal },
110
+ verification: { kind: "not-run" },
111
+ target: { kind: "not-observed" },
112
+ };
113
+ }
114
+ export async function previewDeliveryOperation(input) {
115
+ input.signal?.throwIfAborted();
116
+ const observed = await observeGitForAdmissionAt(input.scope, input.channel, [input.contractId]);
117
+ const state = activeContract(observed.decision, input.contractId);
118
+ if ("kind" in state)
119
+ return { kind: "refused", refusal: state };
120
+ const derivation = input.deriveDocument(state);
121
+ if (!documentIsCurrent(state, derivation.document)) {
122
+ return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
123
+ }
124
+ if (derivation.verification.kind === "refused")
125
+ return { kind: "refused", refusal: derivation.verification.refusal };
126
+ const appointment = await readManagedWorktreeAppointment(input.scope, state.id);
127
+ if (appointment.kind === "failed")
128
+ throw new Error(appointment.diagnostic);
129
+ if (appointment.kind === "unappointed") {
130
+ return accepted(state, [], blockedPreview({ kind: "worktree-missing", contractId: state.id }));
131
+ }
132
+ const prepared = await prepareDelivery(input.scope, {
133
+ contractId: state.id,
134
+ coordinates: state.coordinates,
135
+ recordedIntegrations: recordedIntegrationSnapshots(observed.journals.get(state.id)?.entries ?? []),
136
+ appointment,
137
+ }, {
138
+ title: derivation.title,
139
+ document: derivation.bytes,
140
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
141
+ requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate ?? false,
142
+ includeDirty: input.includeDirty ?? false,
143
+ });
144
+ if (prepared.kind === "refused")
145
+ return accepted(state, [], blockedPreview(prepared.refusal));
146
+ // Supply prospective keys to the generic currentness owner, never a fabricated delivery fact.
147
+ const prospective = { ...state, currentIntegration: prepared.data.integration };
148
+ const candidate = await readyCandidate(input.scope, prepared.data, { kind: "worktree", path: appointment.path }, {
149
+ gates: gateReports(prospective).reports,
150
+ unmetPrerequisites: unmetPrerequisites(state.terms.after, observed.decision),
151
+ }, input.showDiff === true);
152
+ input.progress?.recordDeliveryPreview(state.id, { candidate });
153
+ const verification = verificationAnswer(prospective, derivation.verification.data);
154
+ const delivery = deliveryRelation(state, prepared.data, derivation.verification.data);
155
+ input.progress?.recordDeliveryPreview(state.id, { verification, ...(delivery === undefined ? {} : { delivery }) });
156
+ const target = await targetAnswer(input.scope, state, prepared.data);
157
+ input.progress?.recordDeliveryPreview(state.id, { target });
158
+ const targetLag = target.kind === "placeable" ? await observeTargetLag(input.scope, appointment.path, target.head) : undefined;
159
+ const value = {
160
+ candidate,
161
+ verification,
162
+ target,
163
+ ...(targetLag === undefined ? {} : { targetLag }),
164
+ ...(delivery === undefined ? {} : { delivery }),
165
+ };
166
+ return accepted(state, [], value);
167
+ }
@@ -118,7 +118,7 @@ export interface ProtocolProgress {
118
118
  recordPlacementPhysical(contractId: ContractId, report: ReconcileResult): void;
119
119
  recordVerification(contractId: ContractId, snapshot: SnapshotId | undefined, result: VerificationResidue): void;
120
120
  recordStop(stop: ExecutionStop): void;
121
- recordAudit(contractId: ContractId, report: Partial<import("./audit.js").AuditReport>): void;
121
+ recordDeliveryPreview(contractId: ContractId, report: Partial<import("./delivery-preview.js").DeliveryPreviewReport>): void;
122
122
  /** Current candidate conclusions, retained before the next await can fail. */
123
123
  recordCandidate(contractId: ContractId, evidence: CompletionEvidence): void;
124
124
  /** The candidate's completion base, retained before an optional scope read can fail. */
@@ -197,12 +197,18 @@ async function executeProcess(input, timeoutMs, consumeStdout, spawnProcess = sp
197
197
  const terminationFailure = new Promise((resolve) => {
198
198
  reportTerminationFailure = (error) => resolve({ kind: "termination-error", error });
199
199
  });
200
+ const terminate = () => {
201
+ if (termination === undefined) {
202
+ termination = terminateOwnedProcess(child);
203
+ void termination.catch(reportTerminationFailure);
204
+ }
205
+ return termination;
206
+ };
200
207
  const requestStop = (reason) => {
201
208
  if (stop !== undefined)
202
209
  return;
203
210
  stop = reason;
204
- termination = terminateOwnedProcess(child);
205
- void termination.catch(reportTerminationFailure);
211
+ void terminate();
206
212
  };
207
213
  const failStream = (error) => {
208
214
  if (streamError !== undefined)
@@ -235,16 +241,28 @@ async function executeProcess(input, timeoutMs, consumeStdout, spawnProcess = sp
235
241
  const cancel = () => requestStop("cancelled");
236
242
  input.signal?.addEventListener("abort", cancel, { once: true });
237
243
  const timeout = timeoutMs === undefined ? undefined : setTimeout(() => requestStop("timeout"), timeoutMs);
244
+ const retire = () => {
245
+ if (timeout !== undefined)
246
+ clearTimeout(timeout);
247
+ input.signal?.removeEventListener("abort", cancel);
248
+ void terminate();
249
+ };
250
+ // Descendants can retain the output pipes after leader exit, so cleanup must
251
+ // start at exit rather than waiting for close. Close still drains the output.
252
+ child.once("exit", retire);
238
253
  const terminal = await waitForProcessEnd(child, terminationFailure);
239
254
  if (timeout !== undefined)
240
255
  clearTimeout(timeout);
241
256
  input.signal?.removeEventListener("abort", cancel);
257
+ child.removeListener("exit", retire);
242
258
  if (terminal.kind === "termination-error")
243
259
  throw terminal.error;
244
- await termination;
260
+ await terminate();
245
261
  output.finish();
246
- const pid = child.pid ?? null;
247
262
  const capture = capturedOutput(stdout.result(), stderr.result(), consumeStdout !== undefined);
263
+ return processConsumption(terminal, capture, child.pid ?? null, streamError, stop);
264
+ }
265
+ function processConsumption(terminal, capture, pid, streamError, stop) {
248
266
  if (terminal.kind === "spawn-error") {
249
267
  return { outcome: { kind: "spawn-error", diagnostic: terminal.error.message, ...capture }, pid };
250
268
  }
@@ -1,6 +1,6 @@
1
1
  import type { ContractId, SnapshotId } from "../core/facts/types.js";
2
2
  import { type HookFailure } from "../git/hooks.js";
3
- import type { MaterializedScratchCandidate, WorktreeLeak } from "../git/scratch.js";
3
+ import { type MaterializedScratchCandidate, type WorktreeLeak } from "../git/scratch.js";
4
4
  import type { GitRepository } from "../git/process.js";
5
5
  import type { Settings } from "../settings.js";
6
6
  import type { VerificationObservation } from "./observation.js";
@@ -1,4 +1,5 @@
1
1
  import { runHookCommands, worktreeHooksFrom } from "../git/hooks.js";
2
+ import { ScratchMaterializationError } from "../git/scratch.js";
2
3
  import { runProcess } from "../runtime/proc/run.js";
3
4
  const SUMMARY_BYTES = 32 * 1024;
4
5
  export function capturedOutput(value) {
@@ -129,10 +130,11 @@ async function materializeScratch(input) {
129
130
  state: "finished",
130
131
  outcome: input.signal?.aborted ? "cancelled" : "failed",
131
132
  });
132
- if (input.signal?.aborted)
133
- return { outcome: { kind: "cancelled" } };
134
133
  return {
135
- outcome: { kind: "candidate-unavailable", diagnostic: error instanceof Error ? error.message : String(error) },
134
+ outcome: input.signal?.aborted
135
+ ? { kind: "cancelled" }
136
+ : { kind: "candidate-unavailable", diagnostic: error instanceof Error ? error.message : String(error) },
137
+ ...(error instanceof ScratchMaterializationError ? { leak: error.leak } : {}),
136
138
  };
137
139
  }
138
140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/keiyaku",
3
- "version": "4.6.11",
3
+ "version": "4.6.13",
4
4
  "workspaces": [
5
5
  "plugins/square",
6
6
  "plugins/paseo/forwarder"
@@ -64,14 +64,16 @@
64
64
  "@earendil-works/pi-coding-agent": "*"
65
65
  },
66
66
  "devDependencies": {
67
- "@earendil-works/pi-coding-agent": "^1.0.0",
67
+ "@earendil-works/pi-coding-agent": "^1.4.0",
68
68
  "@getpaseo/plugin": "0.11.2",
69
+ "@getpaseo/server": "0.11.2",
69
70
  "@types/cross-spawn": "^6.0.6",
70
71
  "@types/node": "^25.0.0",
71
72
  "@types/ws": "^8.18.2",
72
73
  "@typescript-eslint/parser": "^8.66.0",
73
74
  "eslint": "^9.39.5",
74
75
  "knip": "^6.31.0",
76
+ "pino": "^10.4.0",
75
77
  "prettier": "3.6.2",
76
78
  "tsx": "^4.20.0",
77
79
  "typescript": "^5.9.0"
@@ -84,6 +86,7 @@
84
86
  "@getpaseo/client": "0.11.2",
85
87
  "@getpaseo/protocol": "0.11.2",
86
88
  "@opencode/client": "2.0.20",
89
+ "@opencode/schema": "2.0.20",
87
90
  "cross-spawn": "^7.0.6",
88
91
  "diff": "^8.0.4",
89
92
  "undici": "8.10.2",
@@ -36,7 +36,9 @@ selects the Contract repository; it never retargets that World. `call
36
36
  cwd). Without it, the call uses the invocation cwd; `--contract` associates a
37
37
  Contract without selecting an execution directory.
38
38
 
39
- `deliver`, `review`, and `audit` may take time after their leading admission.
39
+ `deliver` and `review` may take time after their leading admission.
40
+ `deliver --dry-run` only observes the prospective candidate, standing evidence,
41
+ and target followability; it never runs Verification or hooks or admits work.
40
42
  Their witnessed progress is ephemeral stderr output; stdout remains one final
41
43
  text or JSON result. Ctrl-C asks the owned operation to stop and waits for its
42
44
  truthful final receipt, so it is not evidence that an already admitted action
@@ -54,7 +54,7 @@ does not move without you.
54
54
  | Silent wedge: initial answer empty and worktree clean | Inspect status and history, then send one steering `tell`. If the worker remains unresponsive, `kill` and call a new Akuma; an empty answer alone is not proof the Contract failed. |
55
55
  | Verdict record refused with `not-allowed` | Read the worker's analysis in history. Record the verdict yourself if you did not deliver the candidate, or call a new Reviewer with the grant from `keiyaku-workflow` and have it inspect current work and record a fresh verdict. The refused request wrote no Contract testimony. |
56
56
  | Review stale after changed candidate tender | Normal content-currentness result. Give the same Reviewer the changed diff and current terms with `tell`; have it re-examine and record current testimony. A target move alone does not stale review. |
57
- | Target moved under the appointed worktree | Have the Deliverer inspect target movement and merge the target branch (main when selected) in that worktree when required; resolve conflicts there, then audit again. Do not resolve against a stale integration preview. |
57
+ | Target moved under the appointed worktree | Have the Deliverer inspect target movement and merge the target branch (main when selected) in that worktree when required; resolve conflicts there, then run `deliver --dry-run` again. Do not resolve against a stale integration preview. |
58
58
  | Typed refusal names its rule | Fix the named input or physical condition, then retry from a fresh observation. Do not repeat the same request blindly. |
59
59
 
60
60
  ## What Babysitting Never Owns
@@ -157,8 +157,9 @@ commands; `5m` is the normal baseline.
157
157
  Verification runs only when the Contract selects the `verified` gate, against
158
158
  the exact integration snapshot in a clean disposable worktree for that attempt.
159
159
  `deliver` reuses current satisfied evidence or runs the declarations; unsatisfied
160
- results and runtime stops prevent placement. `audit` runs declarations for a
161
- prospective candidate. Without `verified`, no verb runs Verification and the
160
+ results and runtime stops prevent placement. `deliver --dry-run` only observes
161
+ standing evidence for a prospective candidate; it never executes declarations.
162
+ Without `verified`, no verb runs Verification and the
162
163
  section is inert document text. `reviewed` independently requires review
163
164
  evidence. Selected gates are checked at placement.
164
165
 
@@ -69,12 +69,13 @@ Each act changes a different part of the world:
69
69
  `reconcile` retries workspace realization.
70
70
  - **Work:** Changes and commits belong in the appointed worktree. Another
71
71
  lane's claim can move the target beneath it. Check target movement before
72
- audit; when it matters, merge the target branch (main when selected) in the
73
- worktree and resolve conflicts there before auditing.
74
- - **Audit:** Previews the candidate and target without tendering or claiming.
75
- With `verified` selected, Verification runs for the captured subject and can
76
- record an attestation. Without that gate, the section is inert text and no
77
- verb runs Verification. A stopped run records no new verdict.
72
+ delivery preview; when it matters, merge the target branch (main when selected)
73
+ in the worktree and resolve conflicts there before previewing again.
74
+ - **Delivery preview:** Use `deliver --dry-run` to observe the candidate, existing
75
+ Verification evidence and target followability without tendering or claiming.
76
+ It never runs Verification or hooks, admits testimony, or reconciles. Missing
77
+ or stale evidence means Verification is still required; an existing failure
78
+ remains unsatisfied. Preparation is not a promise of successful delivery.
78
79
  - **Deliver:** Captures a tender and integration against the observed target;
79
80
  journal gains a delivered candidate. Ready prerequisites and gates trigger
80
81
  placement and claim in this invocation; otherwise the candidate waits.
@@ -88,7 +89,7 @@ Each act changes a different part of the world:
88
89
  and abandoned Contracts cannot be reopened.
89
90
 
90
91
  Placement judges declared gates, not the producer's identity. Review does not
91
- replace Verification; audit never requests placement. Read the final receipt
92
+ replace Verification; delivery preview never requests placement. Read the final receipt
92
93
  for stops and reconciliation lag after an admitted act.
93
94
 
94
95
  ## 5. Handing A Role To An Akuma
@@ -101,7 +102,7 @@ authority.
101
102
  | Role | Grant at birth | Return |
102
103
  | --- | --- | --- |
103
104
  | Holder | The actions the delegated loop will perform; include `contract.review` when this holder will review. Commission with the `kei`, current Arc when one exists, appointed worktree, and holder duties. | Acceptance or abandonment, with receipts. |
104
- | Deliverer | The ordinary baseline: every Debt mutation, Contract audit and delivery, and Akuma management. `keiyaku -C <repo> call worker --alias @deliverer --contract <kei/...> --workdir <appointed-path> -` | The delivery receipt. |
105
+ | Deliverer | The ordinary baseline: every Debt mutation, Contract delivery, and Akuma management. Preview is unkeyed. `keiyaku -C <repo> call worker --alias @deliverer --contract <kei/...> --workdir <appointed-path> -` | The delivery receipt. |
105
106
  | Reviewer | `--allowed contract.review`: `keiyaku -C <repo> call review-akuma --alias @reviewer --contract <kei/...> --workdir <appointed-path> --allowed contract.review -` | The verdict receipt. Without the grant, `not-allowed` refuses and no verdict is recorded. |
106
107
 
107
108
  An Archetype's explicit allowed set replaces the ordinary baseline; check
@@ -1,7 +0,0 @@
1
- import type { AuditOutcome } from "../../index.js";
2
- import { type TextRenderContext } from "./terminal.js";
3
- type AcceptedAudit = Extract<AuditOutcome, {
4
- kind: "accepted";
5
- }>;
6
- export declare function renderAcceptedAudit(result: AcceptedAudit, context?: TextRenderContext): string;
7
- export {};