@astrosheep/keiyaku 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
- package/build/src/akuma/akuma.d.ts +34 -12
- package/build/src/akuma/akuma.js +118 -63
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +33 -0
- package/build/src/akuma/archetype.d.ts +7 -4
- package/build/src/akuma/archetype.js +15 -16
- package/build/src/akuma/body.d.ts +6 -1
- package/build/src/akuma/body.js +36 -27
- package/build/src/akuma/heart/facts.d.ts +82 -14
- package/build/src/akuma/heart/index.d.ts +5 -18
- package/build/src/akuma/heart/index.js +14 -84
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -26
- package/build/src/akuma/heart/rows.js +0 -50
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +22 -10
- package/build/src/akuma/heart/soul.js +2 -36
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +15 -0
- package/build/src/akuma/heart/timeline.d.ts +1 -5
- package/build/src/akuma/heart/timeline.js +8 -17
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/projection.d.ts +17 -3
- package/build/src/akuma/projection.js +40 -3
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +2 -7
- package/build/src/akuma/provider.js +2 -1
- package/build/src/akuma/providers/acp/core.d.ts +3 -1
- package/build/src/akuma/providers/acp/core.js +10 -6
- package/build/src/akuma/providers/acp/events.d.ts +11 -3
- package/build/src/akuma/providers/acp/events.js +78 -4
- package/build/src/akuma/providers/acp/index.js +0 -1
- package/build/src/akuma/providers/claude/events.js +62 -3
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +7 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +0 -2
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -3
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/events.js +17 -3
- package/build/src/akuma/providers/pi/index.js +11 -4
- package/build/src/akuma/providers/unified-patch.d.ts +4 -0
- package/build/src/akuma/providers/unified-patch.js +14 -0
- package/build/src/akuma/publication.d.ts +1 -1
- package/build/src/akuma/publication.js +1 -1
- package/build/src/akuma/request-serve.d.ts +87 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +124 -0
- package/build/src/akuma/request-wire.js +380 -0
- package/build/src/akuma/requests.d.ts +41 -41
- package/build/src/akuma/requests.js +75 -374
- package/build/src/akuma-body.d.ts +8 -0
- package/build/src/akuma-body.js +84 -0
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +39 -9
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
- package/build/src/cli/commands/akuma-invoke.js +18 -10
- package/build/src/cli/commands/akuma.d.ts +11 -2
- package/build/src/cli/commands/akuma.js +67 -28
- package/build/src/cli/commands/amend.d.ts +1 -1
- package/build/src/cli/commands/amend.js +1 -1
- package/build/src/cli/commands/contract.d.ts +8 -8
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/install.js +2 -2
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/commands/task-query.d.ts +1 -1
- package/build/src/cli/commands/task-query.js +11 -5
- package/build/src/cli/coordinates.d.ts +2 -0
- package/build/src/cli/coordinates.js +12 -5
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +116 -75
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +3 -2
- package/build/src/cli/parse.js +25 -8
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +138 -24
- package/build/src/cli/render/audit.js +18 -8
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +243 -36
- package/build/src/cli/render/kanshi.js +64 -29
- package/build/src/cli/render/receipt.d.ts +2 -1
- package/build/src/cli/render/receipt.js +37 -2
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +52 -9
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +7 -9
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +7 -8
- package/build/src/git/integration.js +62 -9
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +26 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +8 -2
- package/build/src/git/reconcile.js +63 -14
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +4 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +1 -1
- package/build/src/git/target-placement.js +9 -7
- package/build/src/git/tender.d.ts +20 -5
- package/build/src/git/tender.js +45 -13
- package/build/src/git/terminal-seal.d.ts +16 -2
- package/build/src/git/terminal-seal.js +15 -5
- package/build/src/git/workspace.d.ts +2 -1
- package/build/src/git/workspace.js +13 -5
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +9 -1
- package/build/src/kanshi/read.js +91 -37
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/address.d.ts +5 -14
- package/build/src/library/address.js +27 -23
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/audit.d.ts +2 -1
- package/build/src/library/audit.js +1 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +5 -1
- package/build/src/library/configuration.js +71 -18
- package/build/src/library/contract.d.ts +70 -3
- package/build/src/library/contract.js +213 -27
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +70 -12
- package/build/src/library/fleet.js +236 -56
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +1 -5
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/library/mutation.d.ts +2 -1
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +3 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +3 -1
- package/build/src/library/repo.js +8 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +140 -0
- package/build/src/protocol/bind.d.ts +2 -3
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/completion.d.ts +32 -0
- package/build/src/protocol/completion.js +130 -0
- package/build/src/protocol/deliver.d.ts +37 -0
- package/build/src/protocol/deliver.js +160 -0
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -1
- package/build/src/protocol/operations.d.ts +65 -198
- package/build/src/protocol/operations.js +21 -634
- package/build/src/protocol/placement.d.ts +4 -13
- package/build/src/protocol/placement.js +3 -15
- package/build/src/protocol/read/status.d.ts +4 -2
- package/build/src/protocol/read/status.js +27 -15
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +33 -0
- package/build/src/protocol/review.js +148 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +2 -1
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -4
- package/build/src/task/board.js +73 -29
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +4 -4
- package/build/src/task/index.js +8 -131
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +39 -0
- package/build/src/task/mutation.js +85 -0
- package/build/src/task/operations.d.ts +4 -19
- package/build/src/task/operations.js +64 -18
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +2 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +5 -3
|
@@ -193,7 +193,56 @@ function endpointFact(id, observed) {
|
|
|
193
193
|
return `-> ${id} (unavailable)`;
|
|
194
194
|
return `-> ${id}`;
|
|
195
195
|
}
|
|
196
|
-
function
|
|
196
|
+
function renderNamespaceTasks(row, context) {
|
|
197
|
+
if (row.namespaceTasks.kind === "absent")
|
|
198
|
+
return plumbFacts(["namespace tasks absent"], context.columns);
|
|
199
|
+
if (row.namespaceTasks.kind === "failed") {
|
|
200
|
+
return plumbFacts([`namespace tasks failed ${row.namespaceTasks.failure.message}`], context.columns);
|
|
201
|
+
}
|
|
202
|
+
const lines = [...plumbFacts([`namespace tasks ${row.namespaceTasks.value.length}`], context.columns)];
|
|
203
|
+
for (const task of row.namespaceTasks.value) {
|
|
204
|
+
const scan = `${taskMark(task)} ${task.id} · P${task.priority} ${task.disposition}`;
|
|
205
|
+
const title = safeText(task.title);
|
|
206
|
+
const inline = `${scan} — ${title}`;
|
|
207
|
+
if (displayColumns(inline) <= context.columns - displayColumns(PLUMB)) {
|
|
208
|
+
lines.push(...plumbFacts([inline], context.columns));
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
lines.push(...plumbFacts([`${scan} —`], context.columns));
|
|
212
|
+
lines.push(...plumbBlock(title, context.columns));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return lines;
|
|
216
|
+
}
|
|
217
|
+
function renderContractRow(row, report, context, selection) {
|
|
218
|
+
const hot = contractHot(row);
|
|
219
|
+
const compact = !hot && selection !== "contract";
|
|
220
|
+
const title = row.title ?? "title unavailable";
|
|
221
|
+
const phase = `${row.phase} · ${formatAge(row.phaseAt, report.observedAt)}`;
|
|
222
|
+
const lines = [identityLine(contractMark(row), row.id)];
|
|
223
|
+
lines.push(...plumbFacts(compact ? [title, phase, ...targetFacts(row)] : [title], context.columns));
|
|
224
|
+
if (!compact)
|
|
225
|
+
lines.push(...plumbFacts([phase, ...targetFacts(row)], context.columns));
|
|
226
|
+
lines.push(...plumbFacts([workspaceState(row)], context.columns));
|
|
227
|
+
if (showWorkspacePath(row, hot || selection === "contract")
|
|
228
|
+
&& row.workspaceObservation.kind !== "unappointed"
|
|
229
|
+
&& row.workspaceObservation.location.kind === "worktree") {
|
|
230
|
+
lines.push(plumbPath(row.workspaceObservation.location.path));
|
|
231
|
+
}
|
|
232
|
+
lines.push(...renderGates(row.gates.reports, report.observedAt, context.columns, selection === "contract"));
|
|
233
|
+
if (row.holder.kind === "held")
|
|
234
|
+
lines.push(...plumbFacts([`task ${row.holder.taskId}`], context.columns));
|
|
235
|
+
if (row.holder.kind === "unavailable")
|
|
236
|
+
lines.push(...plumbFacts(["holder unavailable"], context.columns));
|
|
237
|
+
for (const attached of row.fleet) {
|
|
238
|
+
const aliases = attached.aliases.length === 0 ? "" : ` (${attached.aliases.join(" ")})`;
|
|
239
|
+
lines.push(...plumbFacts([`akuma ${attached.id}${aliases}`], context.columns));
|
|
240
|
+
}
|
|
241
|
+
if (selection === "contract")
|
|
242
|
+
lines.push(...renderNamespaceTasks(row, context));
|
|
243
|
+
return lines;
|
|
244
|
+
}
|
|
245
|
+
function renderContracts(report, context) {
|
|
197
246
|
const section = report.contracts;
|
|
198
247
|
if (section.kind === "absent")
|
|
199
248
|
return sectionAbsent("KEIYAKU", context.columns);
|
|
@@ -204,37 +253,21 @@ function renderContracts(report, context, selection) {
|
|
|
204
253
|
...section.value.rows.filter((row) => !contractHot(row)),
|
|
205
254
|
];
|
|
206
255
|
const lines = [aperture("KEIYAKU", context.columns)];
|
|
207
|
-
for (const row of rows)
|
|
208
|
-
|
|
209
|
-
const compact = !hot && selection !== "contract";
|
|
210
|
-
const title = row.title ?? "title unavailable";
|
|
211
|
-
const phase = `${row.phase} · ${formatAge(row.phaseAt, report.observedAt)}`;
|
|
212
|
-
lines.push(identityLine(contractMark(row), row.id));
|
|
213
|
-
lines.push(...plumbFacts(compact
|
|
214
|
-
? [title, phase, ...targetFacts(row)]
|
|
215
|
-
: [title], context.columns));
|
|
216
|
-
if (!compact)
|
|
217
|
-
lines.push(...plumbFacts([phase, ...targetFacts(row)], context.columns));
|
|
218
|
-
lines.push(...plumbFacts([workspaceState(row)], context.columns));
|
|
219
|
-
if (showWorkspacePath(row, hot || selection === "contract")
|
|
220
|
-
&& row.workspaceObservation.kind !== "unappointed"
|
|
221
|
-
&& row.workspaceObservation.location.kind === "worktree") {
|
|
222
|
-
lines.push(plumbPath(row.workspaceObservation.location.path));
|
|
223
|
-
}
|
|
224
|
-
lines.push(...renderGates(row.gates.reports, report.observedAt, context.columns, selection === "contract"));
|
|
225
|
-
if (row.holder.kind === "held")
|
|
226
|
-
lines.push(...plumbFacts([`task ${row.holder.taskId}`], context.columns));
|
|
227
|
-
if (row.holder.kind === "unavailable")
|
|
228
|
-
lines.push(...plumbFacts(["holder unavailable"], context.columns));
|
|
229
|
-
for (const attached of row.fleet) {
|
|
230
|
-
const aliases = attached.aliases.length === 0 ? "" : ` (${attached.aliases.join(" ")})`;
|
|
231
|
-
lines.push(...plumbFacts([`akuma ${attached.id}${aliases}`], context.columns));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
256
|
+
for (const row of rows)
|
|
257
|
+
lines.push(...renderContractRow(row, report, context, "world"));
|
|
234
258
|
const attention = rows.filter(contractHot).length;
|
|
235
259
|
lines.push(aperture(`${rows.length} keiyaku · ${attention} attention`, context.columns));
|
|
236
260
|
return lines;
|
|
237
261
|
}
|
|
262
|
+
function renderSelectedContract(report, context) {
|
|
263
|
+
const section = report.contracts;
|
|
264
|
+
if (section.kind === "absent")
|
|
265
|
+
return [`${PLUMB}keiyaku absent`];
|
|
266
|
+
if (section.kind === "failed")
|
|
267
|
+
return [tone(`! ${safeText(section.failure.message)}`, "alert", context.color)];
|
|
268
|
+
const row = section.value.rows[0];
|
|
269
|
+
return row === undefined ? [`${PLUMB}keiyaku absent`] : renderContractRow(row, report, context, "contract");
|
|
270
|
+
}
|
|
238
271
|
function renderTasks(report, context) {
|
|
239
272
|
const section = report.tasks;
|
|
240
273
|
if (section.kind === "absent")
|
|
@@ -335,10 +368,12 @@ function splitHorizon(report, columns) {
|
|
|
335
368
|
return [`kanshi ${HORIZON}${RULE.repeat(left)} ${aggregate} ${HORIZON}${RULE.repeat(right)} ${world}`];
|
|
336
369
|
}
|
|
337
370
|
export function renderKanshiText(report, context = { columns: 80, color: false }, selection = "world") {
|
|
371
|
+
if (selection === "contract")
|
|
372
|
+
return renderSelectedContract(report, context).join("\n");
|
|
338
373
|
return [
|
|
339
374
|
...splitHorizon(report, context.columns),
|
|
340
375
|
"",
|
|
341
|
-
...renderContracts(report, context
|
|
376
|
+
...renderContracts(report, context),
|
|
342
377
|
"",
|
|
343
378
|
...renderTasks(report, context),
|
|
344
379
|
"",
|
|
@@ -10,10 +10,11 @@ type HookFailure = Extract<Lag, {
|
|
|
10
10
|
export declare function receiptRow(lines: string[], mark: string, label: string, segments: readonly ReceiptSegment[], columns: number): void;
|
|
11
11
|
export declare function receiptPayload(lines: string[], label: string, payload: string): void;
|
|
12
12
|
export declare function outcomeLines(mark: "✓" | "!" | "?", verb: string, word: "accepted" | "refused" | "retry", contract: string | undefined, columns?: number): string[];
|
|
13
|
+
export declare function titleLines(mark: string, title: string, contract: string, columns?: number): string[];
|
|
13
14
|
export declare function hookFailureSummary(failure: HookFailure): string;
|
|
14
15
|
export declare function appendHookPayload(lines: string[], failure: HookFailure): void;
|
|
15
16
|
export declare function reuseLines(reuse: VerificationReuse | undefined, columns: number): readonly string[];
|
|
16
|
-
export declare function stopLines(label: "verification" | "
|
|
17
|
+
export declare function stopLines(label: "verification" | "completion", stop: VerificationStop | PlacementStop, columns: number, addressed: string): readonly string[];
|
|
17
18
|
export declare function cleanupLines(cleanup: NonNullable<AcceptedDeliverResult["cleanup"]>, columns: number): readonly string[];
|
|
18
19
|
export declare function leakLines(leak: NonNullable<AcceptedDeliverResult["leak"]>, columns: number): readonly string[];
|
|
19
20
|
export {};
|
|
@@ -30,6 +30,13 @@ export function outcomeLines(mark, verb, word, contract, columns = 80) {
|
|
|
30
30
|
return [inline];
|
|
31
31
|
return [`${base} —`, ` ${safeText(contract)}`];
|
|
32
32
|
}
|
|
33
|
+
export function titleLines(mark, title, contract, columns = 80) {
|
|
34
|
+
const base = `${mark} ${title}`;
|
|
35
|
+
const inline = `${base} — ${contract}`;
|
|
36
|
+
if (displayColumns(inline) <= columns)
|
|
37
|
+
return [inline];
|
|
38
|
+
return [`${base} —`, ` ${safeText(contract)}`];
|
|
39
|
+
}
|
|
33
40
|
export function hookFailureSummary(failure) {
|
|
34
41
|
if (failure.kind === "timeout" || failure.kind === "unknown-exit")
|
|
35
42
|
return failure.kind;
|
|
@@ -52,6 +59,32 @@ export function reuseLines(reuse, columns) {
|
|
|
52
59
|
return [];
|
|
53
60
|
return renderOpaqueBlock(`reuse verification ${reuse.entry} ${reuse.verdict}`, " ", columns);
|
|
54
61
|
}
|
|
62
|
+
function prerequisiteRows(stop, columns) {
|
|
63
|
+
if (!("refusal" in stop) || stop.refusal?.kind !== "prerequisites-unsatisfied")
|
|
64
|
+
return [];
|
|
65
|
+
const lines = [];
|
|
66
|
+
for (const prerequisite of stop.refusal.unmet) {
|
|
67
|
+
receiptRow(lines, " ", "prerequisite", [
|
|
68
|
+
{ text: prerequisite.contractId, opaque: true },
|
|
69
|
+
{ text: "·" },
|
|
70
|
+
{ text: prerequisite.state },
|
|
71
|
+
], columns);
|
|
72
|
+
}
|
|
73
|
+
return lines;
|
|
74
|
+
}
|
|
75
|
+
function targetMovedDetail(stop) {
|
|
76
|
+
if ("integratedAt" in stop) {
|
|
77
|
+
return [
|
|
78
|
+
{ text: stop.target, opaque: true },
|
|
79
|
+
{ text: `${stop.integratedAt} -> ${stop.observed}`, opaque: true },
|
|
80
|
+
{ text: `attempts=${stop.attempts}` },
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
return [
|
|
84
|
+
{ text: stop.target, opaque: true },
|
|
85
|
+
{ text: `${stop.expected} -> ${stop.observed}`, opaque: true },
|
|
86
|
+
];
|
|
87
|
+
}
|
|
55
88
|
export function stopLines(label, stop, columns, addressed) {
|
|
56
89
|
const detail = [];
|
|
57
90
|
if ("refusal" in stop && stop.refusal !== undefined) {
|
|
@@ -69,11 +102,13 @@ export function stopLines(label, stop, columns, addressed) {
|
|
|
69
102
|
detail.push({ text: `command=${stop.command}` }, { text: hookFailureSummary(stop.detail), opaque: true });
|
|
70
103
|
}
|
|
71
104
|
else if (stop.failure === "target-moved") {
|
|
72
|
-
detail.push(
|
|
105
|
+
detail.push(...targetMovedDetail(stop));
|
|
73
106
|
}
|
|
74
107
|
}
|
|
75
108
|
const lines = [];
|
|
76
|
-
|
|
109
|
+
const state = label === "verification" ? "failed" : "blocked";
|
|
110
|
+
receiptRow(lines, "!", label, [{ text: state }, { text: "·" }, ...detail], columns);
|
|
111
|
+
lines.push(...prerequisiteRows(stop, columns));
|
|
77
112
|
if ("failure" in stop && stop.failure === "environment-failure" && "command" in stop) {
|
|
78
113
|
appendHookPayload(lines, stop.detail);
|
|
79
114
|
}
|
|
@@ -23,8 +23,6 @@ export declare function renderBoundedTextBlock(value: string, input: Readonly<{
|
|
|
23
23
|
truncated?: boolean;
|
|
24
24
|
}>): readonly string[];
|
|
25
25
|
export declare function safeText(value: string): string;
|
|
26
|
-
export declare function renderFacts(primary: string, facts: readonly string[], columns: number): readonly string[];
|
|
27
26
|
export declare function renderTextBlock(value: string, indent: string, columns: number): readonly string[];
|
|
28
27
|
export declare function renderOpaqueBlock(value: string, indent: string, columns: number): readonly string[];
|
|
29
|
-
export declare function renderVoiceRuler(left: string, right: string, columns: number): string;
|
|
30
28
|
export declare function tone(value: string, kind: "dim" | "alert", color: boolean): string;
|
|
@@ -110,28 +110,6 @@ export function renderBoundedTextBlock(value, input) {
|
|
|
110
110
|
export function safeText(value) {
|
|
111
111
|
return value.replaceAll(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, (character) => /\s/u.test(character) ? " " : "�");
|
|
112
112
|
}
|
|
113
|
-
export function renderFacts(primary, facts, columns) {
|
|
114
|
-
const head = safeText(primary);
|
|
115
|
-
const clean = facts.map(safeText);
|
|
116
|
-
if (clean.length === 0)
|
|
117
|
-
return [head];
|
|
118
|
-
const inline = `${head} ${clean.join(" · ")}`;
|
|
119
|
-
if (displayColumns(inline) <= columns)
|
|
120
|
-
return [inline];
|
|
121
|
-
const lines = [head];
|
|
122
|
-
let current = " ";
|
|
123
|
-
for (const fact of clean) {
|
|
124
|
-
const candidate = current === " " ? `${current}${fact}` : `${current} · ${fact}`;
|
|
125
|
-
if (current !== " " && displayColumns(candidate) > columns) {
|
|
126
|
-
lines.push(current);
|
|
127
|
-
current = ` ${fact}`;
|
|
128
|
-
}
|
|
129
|
-
else
|
|
130
|
-
current = candidate;
|
|
131
|
-
}
|
|
132
|
-
lines.push(current);
|
|
133
|
-
return lines;
|
|
134
|
-
}
|
|
135
113
|
export function renderTextBlock(value, indent, columns) {
|
|
136
114
|
const words = safeText(value).trim().split(/\s+/u).filter((word) => word.length > 0);
|
|
137
115
|
if (words.length === 0)
|
|
@@ -183,13 +161,6 @@ export function renderOpaqueBlock(value, indent, columns) {
|
|
|
183
161
|
}
|
|
184
162
|
return lines;
|
|
185
163
|
}
|
|
186
|
-
export function renderVoiceRuler(left, right, columns) {
|
|
187
|
-
const width = Math.max(20, Math.min(80, columns));
|
|
188
|
-
const occupied = displayColumns(left) + displayColumns(right) + 2;
|
|
189
|
-
if (occupied >= width)
|
|
190
|
-
return `${left}\n${"─".repeat(Math.max(1, width - displayColumns(right) - 1))} ${right}`;
|
|
191
|
-
return `${left} ${"─".repeat(width - occupied)} ${right}`;
|
|
192
|
-
}
|
|
193
164
|
export function tone(value, kind, color) {
|
|
194
165
|
if (!color)
|
|
195
166
|
return value;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { renderObservation } from "./board.js";
|
|
2
|
-
import { renderAccepted, renderRetry } from "./contract.js";
|
|
2
|
+
import { renderAccepted, renderContractHistory, renderRetry } from "./contract.js";
|
|
3
3
|
import { renderKanshiText } from "./kanshi.js";
|
|
4
4
|
import { renderRefusal } from "./refusal.js";
|
|
5
5
|
import { renderCatalogText } from "./catalog.js";
|
|
@@ -11,6 +11,8 @@ export function renderText(result, context) {
|
|
|
11
11
|
return renderKanshiText(result.report, context, result.selection);
|
|
12
12
|
if (result.kind === "catalog")
|
|
13
13
|
return renderCatalogText(result.catalog);
|
|
14
|
+
if (result.kind === "contract-history")
|
|
15
|
+
return renderContractHistory(result.history);
|
|
14
16
|
if (result.kind === "region")
|
|
15
17
|
return renderRegionText(result.region);
|
|
16
18
|
if (result.kind === "accepted")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuditReport, ContractId, Fact, MutationResult, PlacementStop, ReconcileReport, Review, VerificationReuse, VerificationStop } from "../index.js";
|
|
1
|
+
import type { AuditReport, ContractHistory, ContractId, Fact, MutationResult, PlacementStop, ReconcileReport, Review, VerificationReuse, VerificationStop } from "../index.js";
|
|
2
2
|
import type { KanshiReport } from "../kanshi/index.js";
|
|
3
3
|
import type { RegionRead, Section } from "../kanshi/index.js";
|
|
4
4
|
import type { Catalog } from "../index.js";
|
|
@@ -11,11 +11,19 @@ export type BindDraftReceipt = Readonly<{
|
|
|
11
11
|
warning: string;
|
|
12
12
|
}>;
|
|
13
13
|
export type Effect = ReconcileReport["effects"][number];
|
|
14
|
-
|
|
14
|
+
type AcceptedFactEnvelope = Readonly<{
|
|
15
15
|
contract: ContractId;
|
|
16
16
|
entry: string;
|
|
17
|
-
kind: Fact["kind"];
|
|
18
17
|
}>;
|
|
18
|
+
export type AcceptedFact = (AcceptedFactEnvelope & Readonly<{
|
|
19
|
+
kind: Exclude<Fact["kind"], "reintegrated">;
|
|
20
|
+
data?: never;
|
|
21
|
+
}>) | (AcceptedFactEnvelope & Readonly<{
|
|
22
|
+
kind: "reintegrated";
|
|
23
|
+
data: Extract<Fact, {
|
|
24
|
+
kind: "reintegrated";
|
|
25
|
+
}>["data"];
|
|
26
|
+
}>);
|
|
19
27
|
export type Lag = ReconcileReport["lag"][number];
|
|
20
28
|
type MutationEnvelope = Pick<MutationResult<unknown>, "head" | "effects" | "settlement">;
|
|
21
29
|
export type AcceptedEnvelope = Readonly<{
|
|
@@ -29,6 +37,7 @@ export type AcceptedEnvelope = Readonly<{
|
|
|
29
37
|
}>;
|
|
30
38
|
export type AcceptedBindResult = AcceptedEnvelope & Readonly<{
|
|
31
39
|
verb: "bind";
|
|
40
|
+
workspace: "worktree" | "here";
|
|
32
41
|
target: string | null;
|
|
33
42
|
verification?: never;
|
|
34
43
|
verificationReuse?: never;
|
|
@@ -36,8 +45,11 @@ export type AcceptedBindResult = AcceptedEnvelope & Readonly<{
|
|
|
36
45
|
cleanup?: never;
|
|
37
46
|
leak?: never;
|
|
38
47
|
report?: never;
|
|
39
|
-
workspace?: never;
|
|
40
48
|
diff?: never;
|
|
49
|
+
verificationVerdict?: never;
|
|
50
|
+
verdict?: never;
|
|
51
|
+
chapter?: never;
|
|
52
|
+
note?: never;
|
|
41
53
|
}> & RegionObservation;
|
|
42
54
|
export type AcceptedAmendResult = AcceptedEnvelope & Readonly<{
|
|
43
55
|
verb: "amend";
|
|
@@ -50,9 +62,14 @@ export type AcceptedAmendResult = AcceptedEnvelope & Readonly<{
|
|
|
50
62
|
leak?: never;
|
|
51
63
|
report?: never;
|
|
52
64
|
workspace?: never;
|
|
65
|
+
verificationVerdict?: never;
|
|
66
|
+
verdict?: never;
|
|
67
|
+
chapter?: never;
|
|
68
|
+
note?: never;
|
|
53
69
|
}> & RegionObservation;
|
|
54
70
|
export type AcceptedDeliverResult = AcceptedEnvelope & Readonly<{
|
|
55
71
|
verb: "deliver";
|
|
72
|
+
verificationVerdict?: "satisfied" | "unsatisfied";
|
|
56
73
|
verification?: VerificationStop;
|
|
57
74
|
verificationReuse?: VerificationReuse;
|
|
58
75
|
placement?: PlacementStop;
|
|
@@ -64,23 +81,34 @@ export type AcceptedDeliverResult = AcceptedEnvelope & Readonly<{
|
|
|
64
81
|
report?: never;
|
|
65
82
|
workspace?: never;
|
|
66
83
|
diff?: never;
|
|
84
|
+
verdict?: never;
|
|
85
|
+
chapter?: never;
|
|
86
|
+
note?: never;
|
|
67
87
|
}>;
|
|
68
88
|
export type AcceptedReviewResult = AcceptedEnvelope & Readonly<{
|
|
69
89
|
verb: "review";
|
|
90
|
+
verdict: "satisfied" | "unsatisfied";
|
|
91
|
+
verificationVerdict?: "satisfied" | "unsatisfied";
|
|
92
|
+
verification?: VerificationStop;
|
|
93
|
+
verificationReuse?: VerificationReuse;
|
|
70
94
|
placement?: PlacementStop;
|
|
71
95
|
workspace?: Review["workspace"];
|
|
96
|
+
cleanup?: MutationResult<unknown>["cleanup"];
|
|
97
|
+
leak?: MutationResult<unknown>["leak"];
|
|
72
98
|
target?: never;
|
|
73
|
-
verification?: never;
|
|
74
|
-
verificationReuse?: never;
|
|
75
|
-
cleanup?: never;
|
|
76
|
-
leak?: never;
|
|
77
99
|
overlaps?: never;
|
|
78
100
|
overlapFailure?: never;
|
|
79
101
|
report?: never;
|
|
80
102
|
diff?: never;
|
|
103
|
+
chapter?: never;
|
|
104
|
+
note?: never;
|
|
81
105
|
}>;
|
|
82
106
|
export type AcceptedArcResult = AcceptedEnvelope & Readonly<{
|
|
83
107
|
verb: "arc";
|
|
108
|
+
chapter: Readonly<{
|
|
109
|
+
seq: number;
|
|
110
|
+
title: string;
|
|
111
|
+
}>;
|
|
84
112
|
target?: never;
|
|
85
113
|
verification?: never;
|
|
86
114
|
verificationReuse?: never;
|
|
@@ -92,9 +120,13 @@ export type AcceptedArcResult = AcceptedEnvelope & Readonly<{
|
|
|
92
120
|
report?: never;
|
|
93
121
|
workspace?: never;
|
|
94
122
|
diff?: never;
|
|
123
|
+
verificationVerdict?: never;
|
|
124
|
+
verdict?: never;
|
|
125
|
+
note?: never;
|
|
95
126
|
}>;
|
|
96
127
|
export type AcceptedAbandonResult = AcceptedEnvelope & Readonly<{
|
|
97
128
|
verb: "abandon";
|
|
129
|
+
note?: string;
|
|
98
130
|
target?: never;
|
|
99
131
|
verification?: never;
|
|
100
132
|
verificationReuse?: never;
|
|
@@ -106,6 +138,9 @@ export type AcceptedAbandonResult = AcceptedEnvelope & Readonly<{
|
|
|
106
138
|
report?: never;
|
|
107
139
|
workspace?: never;
|
|
108
140
|
diff?: never;
|
|
141
|
+
verificationVerdict?: never;
|
|
142
|
+
verdict?: never;
|
|
143
|
+
chapter?: never;
|
|
109
144
|
}>;
|
|
110
145
|
export type AcceptedAuditResult = AcceptedEnvelope & Readonly<{
|
|
111
146
|
verb: "audit";
|
|
@@ -120,6 +155,10 @@ export type AcceptedAuditResult = AcceptedEnvelope & Readonly<{
|
|
|
120
155
|
overlapFailure?: never;
|
|
121
156
|
workspace?: never;
|
|
122
157
|
diff?: never;
|
|
158
|
+
verificationVerdict?: never;
|
|
159
|
+
verdict?: never;
|
|
160
|
+
chapter?: never;
|
|
161
|
+
note?: never;
|
|
123
162
|
}>;
|
|
124
163
|
export type AcceptedResult = AcceptedBindResult | AcceptedAmendResult | AcceptedDeliverResult | AcceptedReviewResult | AcceptedArcResult | AcceptedAbandonResult | AcceptedAuditResult;
|
|
125
164
|
export type RefusedResult = Readonly<{
|
|
@@ -158,5 +197,9 @@ export type CatalogResult = Readonly<{
|
|
|
158
197
|
kind: "catalog";
|
|
159
198
|
catalog: Catalog;
|
|
160
199
|
}>;
|
|
161
|
-
export type
|
|
200
|
+
export type ContractHistoryResult = Readonly<{
|
|
201
|
+
kind: "contract-history";
|
|
202
|
+
history: ContractHistory;
|
|
203
|
+
}>;
|
|
204
|
+
export type InvocationResult = AcceptedResult | RefusedResult | RetryResult | ObservationResult | GuidanceResult | StatusResult | RegionResult | CatalogResult | ContractHistoryResult;
|
|
162
205
|
export {};
|
|
@@ -6,4 +6,5 @@ export type SelectedContract = Readonly<{
|
|
|
6
6
|
}>;
|
|
7
7
|
export declare function contractFromInput(repo: Repo, value: string): SelectedContract;
|
|
8
8
|
export declare function resolveContextualContract(board: ContractBoard, selector: string | undefined, scope: string): ContractId;
|
|
9
|
+
export declare function canonicalContractSelector(selector: string): ContractId;
|
|
9
10
|
export declare function resolveKanshiContract(report: KanshiReport, selector: string): string;
|
|
@@ -50,12 +50,7 @@ export function resolveContextualContract(board, selector, scope) {
|
|
|
50
50
|
return resolveShortContract(board.rows, selector);
|
|
51
51
|
return selectorError(`contract selector must be kei/<contract-segment> or @<contract-segment>: ${selector}`);
|
|
52
52
|
}
|
|
53
|
-
export function
|
|
54
|
-
if (report.contracts.kind !== "present") {
|
|
55
|
-
return selectorError(`cannot select a contract while the Contract world is ${report.contracts.kind}`);
|
|
56
|
-
}
|
|
57
|
-
if (selector.startsWith("@"))
|
|
58
|
-
return resolveShortContract(report.contracts.value.rows, selector);
|
|
53
|
+
export function canonicalContractSelector(selector) {
|
|
59
54
|
try {
|
|
60
55
|
identitySegments({ family: "kei", value: selector });
|
|
61
56
|
}
|
|
@@ -64,3 +59,11 @@ export function resolveKanshiContract(report, selector) {
|
|
|
64
59
|
}
|
|
65
60
|
return selector;
|
|
66
61
|
}
|
|
62
|
+
export function resolveKanshiContract(report, selector) {
|
|
63
|
+
if (report.contracts.kind !== "present") {
|
|
64
|
+
return selectorError(`cannot select a contract while the Contract world is ${report.contracts.kind}`);
|
|
65
|
+
}
|
|
66
|
+
if (selector.startsWith("@"))
|
|
67
|
+
return resolveShortContract(report.contracts.value.rows, selector);
|
|
68
|
+
return canonicalContractSelector(selector);
|
|
69
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DerivedFileAction } from "./coordination/durable-file.js";
|
|
2
2
|
import { type ContractId, type ContractState } from "./core/facts/types.js";
|
|
3
|
-
import { type GitRepository } from "./git/
|
|
3
|
+
import { type GitRepository } from "./git/process.js";
|
|
4
4
|
import { type PlaceRegister } from "./workspace-place.js";
|
|
5
5
|
export declare function renderContractGuidance(state: ContractState): string;
|
|
6
6
|
export type ContractFileEffect = Readonly<{
|
|
@@ -40,5 +40,4 @@ export type ContractReservation = Readonly<{
|
|
|
40
40
|
export declare function reserveContractWorktree(repository: GitRepository, contract: ContractId): Promise<ContractReservation>;
|
|
41
41
|
export declare function withContractWorktreeAppointment<T>(repository: GitRepository, action: () => T | Promise<T>): Promise<T>;
|
|
42
42
|
export declare function releaseContractWorktree(repository: GitRepository, contract: ContractId): Promise<void>;
|
|
43
|
-
export declare function removeContractWorktreeAppointment(repository: GitRepository, contract: ContractId): Promise<void>;
|
|
44
43
|
export declare function projectContractWorktree(repository: GitRepository, state: ContractState | null, register?: PlaceRegister): Promise<ContractWorktreeResult>;
|
|
@@ -3,9 +3,10 @@ import { join } from "node:path";
|
|
|
3
3
|
import { acquireSqliteTransactionLock } from "./coordination/sqlite-transaction-lock.js";
|
|
4
4
|
import { createFileDurablyExclusive, repairDerivedFile, } from "./coordination/durable-file.js";
|
|
5
5
|
import { contractId } from "./core/facts/types.js";
|
|
6
|
-
import {
|
|
6
|
+
import { worktreeGitDirectory, worktreeRoot, } from "./git/repository.js";
|
|
7
|
+
import { GitPlumbingError, runGit } from "./git/process.js";
|
|
7
8
|
import { worktreePath } from "./git/workspace.js";
|
|
8
|
-
import { appointmentFor, placeRegisterPath,
|
|
9
|
+
import { appointmentFor, placeRegisterPath, } from "./workspace-place.js";
|
|
9
10
|
const IGNORE_BYTES = ".gitignore\nKEIYAKU.md\n";
|
|
10
11
|
const APPOINTMENT_DESCRIPTION = "This is a read-only projection. Do not edit manually.";
|
|
11
12
|
function appointmentBytes(contract) {
|
|
@@ -48,6 +49,9 @@ const FULFILLMENT = [
|
|
|
48
49
|
"### Deliverer", "",
|
|
49
50
|
"Implement and verify the Objective under the Design, Region, and Criteria in this Contract.",
|
|
50
51
|
"When an Arc is active, stay within that current chapter.",
|
|
52
|
+
"For work requiring three or more steps, prefer `keiyaku task -C <worktree>` "
|
|
53
|
+
+ "to organize and manage Tasks.",
|
|
54
|
+
"Promptly update progress for Tasks already present in the current worktree.",
|
|
51
55
|
"Leave lifecycle decisions to the caller; report the candidate, verification performed, and any unmet term.", "",
|
|
52
56
|
"### Reviewer", "",
|
|
53
57
|
"Review this Contract worktree against the complete Contract.",
|
|
@@ -129,12 +133,6 @@ export async function releaseContractWorktree(repository, contract) {
|
|
|
129
133
|
}
|
|
130
134
|
catch { /* reservation cleanup is best effort */ }
|
|
131
135
|
}
|
|
132
|
-
export async function removeContractWorktreeAppointment(repository, contract) {
|
|
133
|
-
const appointment = await readContractAppointment(repository);
|
|
134
|
-
if (appointment.kind !== "appointed" || appointment.contract !== contract)
|
|
135
|
-
return;
|
|
136
|
-
await unlink(appointment.path);
|
|
137
|
-
}
|
|
138
136
|
async function repair(repository, worktree, relativePath, bytes) {
|
|
139
137
|
const path = join(worktree, relativePath);
|
|
140
138
|
if (await isTracked(repository, relativePath))
|
|
@@ -235,7 +233,7 @@ export async function projectContractWorktree(repository, state, register) {
|
|
|
235
233
|
if (state.coordinates.workspace === "here") {
|
|
236
234
|
return await here(repository, state, renderContractGuidance(state));
|
|
237
235
|
}
|
|
238
|
-
const appointed =
|
|
236
|
+
const appointed = register === undefined ? undefined : appointmentFor(register, state.id);
|
|
239
237
|
if (appointed === undefined) {
|
|
240
238
|
return {
|
|
241
239
|
effects: [],
|
|
@@ -6,6 +6,7 @@ const VERSION_BY_KIND = {
|
|
|
6
6
|
amend: 1,
|
|
7
7
|
bound: 1,
|
|
8
8
|
deliver: 1,
|
|
9
|
+
reintegrated: 1,
|
|
9
10
|
attestation: 1,
|
|
10
11
|
claimed: 1,
|
|
11
12
|
arc: 1,
|
|
@@ -182,6 +183,14 @@ function validateData(kind, value) {
|
|
|
182
183
|
},
|
|
183
184
|
};
|
|
184
185
|
}
|
|
186
|
+
case "reintegrated": {
|
|
187
|
+
const object = requireRecord(value, path);
|
|
188
|
+
requireKeys(object, ["predecessor", "snapshot"], path);
|
|
189
|
+
return {
|
|
190
|
+
predecessor: brandedValue(object.predecessor, `${path}.predecessor`, snapshotId),
|
|
191
|
+
snapshot: brandedValue(object.snapshot, `${path}.snapshot`, snapshotId),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
185
194
|
case "attestation":
|
|
186
195
|
return validateAttestation(value, path);
|
|
187
196
|
case "claimed": {
|
|
@@ -24,6 +24,7 @@ function stateFromBind(id, head, bind, attestations) {
|
|
|
24
24
|
terms: cloneTerms(bind.data.terms),
|
|
25
25
|
bound: null,
|
|
26
26
|
delivery: null,
|
|
27
|
+
currentIntegration: null,
|
|
27
28
|
attestations,
|
|
28
29
|
terminal: null,
|
|
29
30
|
};
|
|
@@ -55,7 +56,18 @@ function foldEntry(state, entry, attestations) {
|
|
|
55
56
|
case "deliver":
|
|
56
57
|
if (state.bound === null)
|
|
57
58
|
foldError("deliver requires bound");
|
|
58
|
-
return { ...state, delivery: entry };
|
|
59
|
+
return { ...state, delivery: entry, currentIntegration: { ...entry.data.integration } };
|
|
60
|
+
case "reintegrated":
|
|
61
|
+
if (state.delivery === null)
|
|
62
|
+
foldError("reintegrated requires a deliver");
|
|
63
|
+
return {
|
|
64
|
+
...state,
|
|
65
|
+
currentIntegration: {
|
|
66
|
+
predecessor: entry.data.predecessor,
|
|
67
|
+
snapshot: entry.data.snapshot,
|
|
68
|
+
changeId: state.delivery.data.integration.changeId,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
59
71
|
case "attestation":
|
|
60
72
|
attestations.push(entry);
|
|
61
73
|
return { ...state, attestations };
|
|
@@ -85,6 +85,11 @@ export type DeliverData = Readonly<{
|
|
|
85
85
|
requireBranchesToBeUpToDate: boolean;
|
|
86
86
|
}>;
|
|
87
87
|
}>;
|
|
88
|
+
export type CurrentIntegration = DeliverData["integration"];
|
|
89
|
+
export type ReintegratedData = Readonly<{
|
|
90
|
+
predecessor: SnapshotId;
|
|
91
|
+
snapshot: SnapshotId;
|
|
92
|
+
}>;
|
|
88
93
|
export type AttestationData = Readonly<{
|
|
89
94
|
gate: Gate;
|
|
90
95
|
subject: DependencyKeySet;
|
|
@@ -116,11 +121,12 @@ export type BindEntry = JournalEnvelope<"bind", BindData>;
|
|
|
116
121
|
type AmendEntry = JournalEnvelope<"amend", AmendData>;
|
|
117
122
|
type BoundEntry = JournalEnvelope<"bound", BoundData>;
|
|
118
123
|
type DeliverEntry = JournalEnvelope<"deliver", DeliverData>;
|
|
124
|
+
export type ReintegratedEntry = JournalEnvelope<"reintegrated", ReintegratedData>;
|
|
119
125
|
export type AttestationEntry = JournalEnvelope<"attestation", AttestationData>;
|
|
120
126
|
type ClaimedEntry = JournalEnvelope<"claimed", ClaimedData>;
|
|
121
127
|
export type ArcEntry = JournalEnvelope<"arc", ArcData>;
|
|
122
128
|
type AbandonedEntry = JournalEnvelope<"abandoned", AbandonedData>;
|
|
123
|
-
export type JournalEntry = BindEntry | AmendEntry | BoundEntry | DeliverEntry | AttestationEntry | ClaimedEntry | ArcEntry | AbandonedEntry;
|
|
129
|
+
export type JournalEntry = BindEntry | AmendEntry | BoundEntry | DeliverEntry | ReintegratedEntry | AttestationEntry | ClaimedEntry | ArcEntry | AbandonedEntry;
|
|
124
130
|
export type FactKind = JournalEntry["kind"];
|
|
125
131
|
type ContractTerminal = ClaimedEntry | AbandonedEntry;
|
|
126
132
|
export type ContractState = Readonly<{
|
|
@@ -130,6 +136,7 @@ export type ContractState = Readonly<{
|
|
|
130
136
|
terms: ContractTerms;
|
|
131
137
|
bound: BoundEntry | null;
|
|
132
138
|
delivery: DeliverEntry | null;
|
|
139
|
+
currentIntegration: CurrentIntegration | null;
|
|
133
140
|
attestations: readonly AttestationEntry[];
|
|
134
141
|
currentArc?: ArcEntry;
|
|
135
142
|
terminal: ContractTerminal | null;
|
|
@@ -65,12 +65,13 @@ export function parseDependencyKeySet(value) {
|
|
|
65
65
|
return decodeDependencyKeySet(value).canonical;
|
|
66
66
|
}
|
|
67
67
|
function currentKeys(state) {
|
|
68
|
+
const integration = state.currentIntegration ?? state.delivery?.data.integration;
|
|
68
69
|
return new Set([
|
|
69
70
|
encodeKey({ kind: "document", value: state.terms.document.key }),
|
|
70
71
|
...state.terms.segments.map((value) => encodeKey({ kind: "segment", value })),
|
|
71
|
-
...(
|
|
72
|
-
encodeKey({ kind: "snapshot", value:
|
|
73
|
-
encodeKey({ kind: "change", value:
|
|
72
|
+
...(integration === undefined ? [] : [
|
|
73
|
+
encodeKey({ kind: "snapshot", value: integration.snapshot }),
|
|
74
|
+
encodeKey({ kind: "change", value: integration.changeId }),
|
|
74
75
|
]),
|
|
75
76
|
]);
|
|
76
77
|
}
|
|
@@ -5,9 +5,17 @@ type PlacementInput = Readonly<{
|
|
|
5
5
|
actor?: ActorId;
|
|
6
6
|
at: string;
|
|
7
7
|
}>;
|
|
8
|
+
export type UnmetPrerequisite = Readonly<{
|
|
9
|
+
contractId: ContractId;
|
|
10
|
+
state: "missing" | "active" | "abandoned";
|
|
11
|
+
}>;
|
|
8
12
|
export type PlacementRefusal = Readonly<{
|
|
9
|
-
kind: "contract-missing" | "delivery-missing" | "terminal" | "
|
|
13
|
+
kind: "contract-missing" | "delivery-missing" | "terminal" | "gates-unsatisfied";
|
|
14
|
+
contractId: ContractId;
|
|
15
|
+
}> | Readonly<{
|
|
16
|
+
kind: "prerequisites-unsatisfied";
|
|
10
17
|
contractId: ContractId;
|
|
18
|
+
unmet: readonly UnmetPrerequisite[];
|
|
11
19
|
}>;
|
|
12
20
|
export declare function decidePlacement({ input, attempt, observation }: DecideInput<PlacementInput>): OfferDecision<PlacementRefusal>;
|
|
13
21
|
export {};
|