@astrosheep/keiyaku 4.0.1 → 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.
- package/README.md +137 -5
- 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 +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +23 -14
- package/build/src/akuma/akuma.js +120 -104
- package/build/src/akuma/archetype.d.ts +7 -6
- package/build/src/akuma/archetype.js +68 -41
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +408 -213
- package/build/src/akuma/heart/facts.d.ts +25 -34
- package/build/src/akuma/heart/facts.js +18 -7
- package/build/src/akuma/heart/index.d.ts +39 -42
- package/build/src/akuma/heart/index.js +134 -93
- package/build/src/akuma/heart/rows.d.ts +9 -31
- package/build/src/akuma/heart/rows.js +26 -44
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +7 -15
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +28 -14
- package/build/src/akuma/heart/storage.js +86 -26
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +6 -1
- package/build/src/akuma/index.js +6 -0
- package/build/src/akuma/projection.d.ts +117 -38
- package/build/src/akuma/projection.js +208 -97
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +12 -4
- package/build/src/akuma/provider.js +117 -70
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/claude/events.js +66 -13
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +35 -21
- package/build/src/akuma/providers/codex-app-server/events.js +4 -1
- package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
- package/build/src/akuma/providers/codex-app-server/index.js +24 -31
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +24 -59
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
- package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
- package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
- package/build/src/akuma/providers/pi/events.js +49 -11
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +50 -21
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -7
- package/build/src/akuma/requests.js +92 -65
- package/build/src/alias/index.d.ts +2 -2
- package/build/src/alias/index.js +10 -10
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/cli/accepted.d.ts +17 -13
- package/build/src/cli/accepted.js +72 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
- package/build/src/cli/commands/akuma-invoke.js +14 -9
- package/build/src/cli/commands/akuma.d.ts +13 -3
- package/build/src/cli/commands/akuma.js +67 -34
- package/build/src/cli/commands/contract.d.ts +18 -5
- package/build/src/cli/commands/contract.js +9 -3
- package/build/src/cli/commands/task-invoke.d.ts +17 -4
- package/build/src/cli/commands/task-invoke.js +43 -20
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +51 -13
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +4 -3
- package/build/src/cli/invoke.js +160 -179
- package/build/src/cli/main.js +34 -6
- package/build/src/cli/parse.d.ts +9 -2
- package/build/src/cli/parse.js +29 -7
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +2 -2
- package/build/src/cli/render/akuma-tool.js +30 -4
- package/build/src/cli/render/akuma.d.ts +1 -0
- package/build/src/cli/render/akuma.js +211 -116
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +192 -79
- package/build/src/cli/render/kanshi.js +263 -168
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -20
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +7 -0
- package/build/src/cli/render/terminal.js +46 -0
- package/build/src/cli/render/text.js +6 -3
- package/build/src/cli/result.d.ts +115 -20
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +6 -5
- package/build/src/contract-worktree.js +95 -57
- package/build/src/coordination/durable-file.d.ts +4 -3
- package/build/src/coordination/durable-file.js +29 -25
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +0 -11
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +1 -7
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +4 -1
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +17 -17
- package/build/src/git/admission.d.ts +1 -1
- package/build/src/git/admission.js +11 -11
- package/build/src/git/hooks.js +13 -13
- package/build/src/git/integration.d.ts +14 -15
- package/build/src/git/integration.js +80 -44
- package/build/src/git/observe.d.ts +5 -3
- package/build/src/git/observe.js +18 -12
- package/build/src/git/read-observation.js +9 -9
- package/build/src/git/reconcile.d.ts +2 -0
- package/build/src/git/reconcile.js +138 -95
- package/build/src/git/repository.d.ts +27 -19
- package/build/src/git/repository.js +155 -83
- package/build/src/git/scratch.d.ts +7 -3
- package/build/src/git/scratch.js +44 -37
- package/build/src/git/target-placement.d.ts +40 -4
- package/build/src/git/target-placement.js +221 -101
- package/build/src/git/tender.d.ts +6 -5
- package/build/src/git/tender.js +24 -43
- package/build/src/git/terminal-seal.d.ts +1 -1
- package/build/src/git/terminal-seal.js +7 -5
- package/build/src/git/workspace.d.ts +36 -4
- package/build/src/git/workspace.js +53 -18
- package/build/src/identity/selector.js +1 -1
- package/build/src/index.d.ts +3 -3
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +2 -1
- package/build/src/kanshi/read.js +118 -27
- package/build/src/kanshi/report.d.ts +50 -0
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +32 -0
- package/build/src/library/address.d.ts +12 -3
- package/build/src/library/address.js +77 -46
- package/build/src/library/akuma-creation.d.ts +6 -1
- package/build/src/library/akuma-creation.js +86 -13
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -1
- package/build/src/library/catalog.js +5 -8
- package/build/src/library/contract.d.ts +5 -6
- package/build/src/library/contract.js +11 -35
- package/build/src/library/delivery.d.ts +2 -1
- package/build/src/library/fleet.d.ts +2 -2
- package/build/src/library/fleet.js +35 -71
- package/build/src/library/keiyaku.d.ts +3 -2
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +7 -6
- package/build/src/library/mutation.js +23 -25
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/region.d.ts +12 -0
- package/build/src/library/region.js +15 -1
- package/build/src/library/repo.d.ts +4 -16
- package/build/src/library/repo.js +13 -38
- package/build/src/protocol/attempt.js +6 -6
- package/build/src/protocol/bind.js +4 -4
- package/build/src/protocol/intent.d.ts +15 -2
- package/build/src/protocol/intent.js +21 -6
- package/build/src/protocol/operations.d.ts +73 -22
- package/build/src/protocol/operations.js +292 -88
- package/build/src/protocol/outcome.d.ts +9 -3
- package/build/src/protocol/outcome.js +3 -1
- package/build/src/protocol/placement.d.ts +15 -4
- package/build/src/protocol/placement.js +58 -25
- package/build/src/protocol/read/status.d.ts +8 -1
- package/build/src/protocol/read/status.js +61 -14
- package/build/src/runtime/proc/line-rpc.d.ts +3 -8
- package/build/src/runtime/proc/line-rpc.js +16 -43
- package/build/src/runtime/proc/run.d.ts +15 -29
- package/build/src/runtime/proc/run.js +113 -105
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +2 -2
- package/build/src/settings.js +8 -8
- package/build/src/settlement/fence.d.ts +0 -4
- package/build/src/settlement/fence.js +0 -9
- package/build/src/settlement/holder.d.ts +11 -1
- package/build/src/settlement/holder.js +25 -0
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +52 -89
- package/build/src/task/board.d.ts +3 -3
- package/build/src/task/board.js +6 -9
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +14 -14
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +19 -7
- package/build/src/task/index.js +42 -23
- package/build/src/task/operations.d.ts +15 -9
- package/build/src/task/operations.js +78 -48
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +2 -2
- package/build/src/task/store.js +40 -25
- package/build/src/verification/execution.d.ts +4 -2
- package/build/src/verification/execution.js +9 -5
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +13 -2
- package/build/src/world.js +81 -48
- package/package.json +3 -2
- package/build/src/protocol/read/audit.d.ts +0 -31
- package/build/src/protocol/read/audit.js +0 -55
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { readAliases } from "../alias/index.js";
|
|
2
2
|
import { Akuma } from "../akuma/akuma.js";
|
|
3
|
+
import { probeBornAkuma } from "../akuma/index.js";
|
|
3
4
|
import { parseAkuId } from "../akuma/identity.js";
|
|
4
5
|
import { contractId } from "../core/facts/types.js";
|
|
5
6
|
import { readDispatches } from "../dispatch/index.js";
|
|
6
7
|
import { matchesAkumaGlob, parseAkumaAlias, parseAkumaGlob, } from "../identity/selector.js";
|
|
7
8
|
import { requireInput } from "./input.js";
|
|
8
9
|
import { scopeForRepo } from "./repo.js";
|
|
10
|
+
export class AkumaWorldScopeError extends TypeError {
|
|
11
|
+
refusal;
|
|
12
|
+
constructor(refusal) {
|
|
13
|
+
super(`akuma-not-in-world ${refusal.world} ${refusal.ids.join(" ")}`);
|
|
14
|
+
this.name = "AkumaWorldScopeError";
|
|
15
|
+
this.refusal = refusal;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
9
18
|
function nonblank(value, label) {
|
|
10
19
|
if (typeof value !== "string" || value.trim().length === 0)
|
|
11
20
|
throw new TypeError(`${label} must be a nonblank string`);
|
|
@@ -22,17 +31,17 @@ function settingsOption(value) {
|
|
|
22
31
|
function world(path, settings) {
|
|
23
32
|
return Akuma.of(path, settings);
|
|
24
33
|
}
|
|
25
|
-
function directId(path, selector) {
|
|
34
|
+
async function directId(path, selector) {
|
|
26
35
|
if (selector.startsWith("@")) {
|
|
27
36
|
const alias = parseAkumaAlias(selector);
|
|
28
|
-
const resolved = readAliases(path).find((binding) => binding.alias === alias)?.akuId ?? null;
|
|
37
|
+
const resolved = (await readAliases(path)).find((binding) => binding.alias === alias)?.akuId ?? null;
|
|
29
38
|
if (resolved === null)
|
|
30
39
|
throw new TypeError(`unknown Akuma alias: ${alias}`);
|
|
31
40
|
return resolved;
|
|
32
41
|
}
|
|
33
42
|
return parseAkuId(selector).id;
|
|
34
43
|
}
|
|
35
|
-
export function resolveNamedAddress(input) {
|
|
44
|
+
export async function resolveNamedAddress(input) {
|
|
36
45
|
const selector = nonblank(input.selector, "selector");
|
|
37
46
|
if (selector.startsWith("kei/"))
|
|
38
47
|
return { kind: "contract", id: contractId(selector) };
|
|
@@ -44,7 +53,7 @@ export function resolveNamedAddress(input) {
|
|
|
44
53
|
&& `@${row.id.slice("kei/".length)}` === alias);
|
|
45
54
|
const aliasId = input.path === null
|
|
46
55
|
? null
|
|
47
|
-
: readAliases(input.path).find((binding) => binding.alias === alias)?.akuId ?? null;
|
|
56
|
+
: (await readAliases(input.path)).find((binding) => binding.alias === alias)?.akuId ?? null;
|
|
48
57
|
if (contractMatches.length > 0 && aliasId !== null)
|
|
49
58
|
throw new TypeError(`ambiguous selector matches Contract and Akuma: ${selector}`);
|
|
50
59
|
if (contractMatches.length === 1)
|
|
@@ -55,7 +64,7 @@ export function resolveNamedAddress(input) {
|
|
|
55
64
|
return { kind: "akuma", id: aliasId };
|
|
56
65
|
throw new TypeError(`unknown selector: ${selector}`);
|
|
57
66
|
}
|
|
58
|
-
export function addressAkuma(input) {
|
|
67
|
+
export async function addressAkuma(input) {
|
|
59
68
|
const values = requireInput(input, "Akuma address input");
|
|
60
69
|
for (const key of Object.keys(values)) {
|
|
61
70
|
if (!["path", "akuma", "settings", "repo"].includes(key))
|
|
@@ -65,11 +74,61 @@ export function addressAkuma(input) {
|
|
|
65
74
|
scopeForRepo(values.repo);
|
|
66
75
|
const path = nonblank(values.path, "path");
|
|
67
76
|
const settings = settingsOption(values.settings);
|
|
68
|
-
return { path, id: directId(path, nonblank(values.akuma, "akuma")), ...(settings === undefined ? {} : { settings }) };
|
|
77
|
+
return { path, id: await directId(path, nonblank(values.akuma, "akuma")), ...(settings === undefined ? {} : { settings }) };
|
|
69
78
|
}
|
|
70
79
|
function idsFromFleet(fleet) {
|
|
71
80
|
return fleet.rows.map((row) => row.id);
|
|
72
81
|
}
|
|
82
|
+
function parseSetSelector(raw) {
|
|
83
|
+
const selector = nonblank(raw, "akuma selector");
|
|
84
|
+
if (selector.startsWith("kei/"))
|
|
85
|
+
return { kind: "contract", value: contractId(selector) };
|
|
86
|
+
if (selector.includes("*"))
|
|
87
|
+
return { kind: "glob", value: parseAkumaGlob(selector) };
|
|
88
|
+
if (selector.startsWith("@"))
|
|
89
|
+
return { kind: "alias", value: parseAkumaAlias(selector) };
|
|
90
|
+
return { kind: "direct", value: parseAkuId(selector).id };
|
|
91
|
+
}
|
|
92
|
+
function hasSelectorKind(selectors, kind) {
|
|
93
|
+
return selectors.some((selector) => selector.kind === kind);
|
|
94
|
+
}
|
|
95
|
+
function addSelectorIds(selector, sources, selected, contractMembers) {
|
|
96
|
+
if (selector.kind === "contract") {
|
|
97
|
+
for (const dispatch of sources.dispatches) {
|
|
98
|
+
if (dispatch.contractId !== selector.value)
|
|
99
|
+
continue;
|
|
100
|
+
selected.add(dispatch.akuId);
|
|
101
|
+
contractMembers.add(dispatch.akuId);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (selector.kind === "glob") {
|
|
106
|
+
for (const id of sources.fleetIds)
|
|
107
|
+
if (matchesAkumaGlob(selector.value, id))
|
|
108
|
+
selected.add(id);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (selector.kind === "alias") {
|
|
112
|
+
const id = sources.aliases.get(selector.value);
|
|
113
|
+
if (id === undefined)
|
|
114
|
+
throw new TypeError(`unknown Akuma alias: ${selector.value}`);
|
|
115
|
+
selected.add(id);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
selected.add(selector.value);
|
|
119
|
+
}
|
|
120
|
+
async function contractMemberInWorld(path, id) {
|
|
121
|
+
return await probeBornAkuma(path, id);
|
|
122
|
+
}
|
|
123
|
+
async function refuseForeignContractMembers(path, ids, contractMembers) {
|
|
124
|
+
const foreign = [];
|
|
125
|
+
for (const id of ids) {
|
|
126
|
+
if (contractMembers.has(id) && !await contractMemberInWorld(path, id))
|
|
127
|
+
foreign.push(id);
|
|
128
|
+
}
|
|
129
|
+
if (foreign.length > 0)
|
|
130
|
+
throw new AkumaWorldScopeError({ kind: "akuma-not-in-world", ids: foreign, world: path });
|
|
131
|
+
}
|
|
73
132
|
export async function addressAkumaSet(input) {
|
|
74
133
|
const values = requireInput(input, "Akuma set address input");
|
|
75
134
|
for (const key of Object.keys(values)) {
|
|
@@ -80,55 +139,27 @@ export async function addressAkumaSet(input) {
|
|
|
80
139
|
throw new TypeError("akuma must be a nonempty selector array");
|
|
81
140
|
const path = nonblank(values.path, "path");
|
|
82
141
|
const settings = settingsOption(values.settings);
|
|
83
|
-
const selectors = values.akuma.map(
|
|
84
|
-
|
|
85
|
-
if (selector.startsWith("kei/"))
|
|
86
|
-
return { kind: "contract", value: contractId(selector) };
|
|
87
|
-
if (selector.includes("*"))
|
|
88
|
-
return { kind: "glob", value: parseAkumaGlob(selector) };
|
|
89
|
-
if (selector.startsWith("@"))
|
|
90
|
-
return { kind: "alias", value: parseAkumaAlias(selector) };
|
|
91
|
-
return { kind: "direct", value: parseAkuId(selector).id };
|
|
92
|
-
});
|
|
93
|
-
if (selectors.some((selector) => selector.kind === "contract") && values.repo === undefined) {
|
|
142
|
+
const selectors = values.akuma.map(parseSetSelector);
|
|
143
|
+
if (hasSelectorKind(selectors, "contract") && values.repo === undefined) {
|
|
94
144
|
throw new TypeError("Contract Akuma selector requires repo");
|
|
95
145
|
}
|
|
96
|
-
const fleetIds = selectors
|
|
97
|
-
? idsFromFleet(world(path, settings).list())
|
|
146
|
+
const fleetIds = hasSelectorKind(selectors, "glob")
|
|
147
|
+
? idsFromFleet(await world(path, settings).list())
|
|
98
148
|
: [];
|
|
99
|
-
const aliases = selectors
|
|
100
|
-
? new Map(readAliases(path).map((binding) => [binding.alias, binding.akuId]))
|
|
149
|
+
const aliases = hasSelectorKind(selectors, "alias")
|
|
150
|
+
? new Map((await readAliases(path)).map((binding) => [binding.alias, binding.akuId]))
|
|
101
151
|
: new Map();
|
|
102
|
-
const dispatches = selectors
|
|
152
|
+
const dispatches = hasSelectorKind(selectors, "contract")
|
|
103
153
|
? await readDispatches(scopeForRepo(values.repo))
|
|
104
154
|
: [];
|
|
105
155
|
const selected = new Set();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.map((dispatch) => dispatch.akuId);
|
|
111
|
-
for (const id of members)
|
|
112
|
-
selected.add(id);
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
if (selector.kind === "glob") {
|
|
116
|
-
for (const id of fleetIds)
|
|
117
|
-
if (matchesAkumaGlob(selector.value, id))
|
|
118
|
-
selected.add(id);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (selector.kind === "alias") {
|
|
122
|
-
const id = aliases.get(selector.value);
|
|
123
|
-
if (id === undefined)
|
|
124
|
-
throw new TypeError(`unknown Akuma alias: ${selector.value}`);
|
|
125
|
-
selected.add(id);
|
|
126
|
-
}
|
|
127
|
-
else
|
|
128
|
-
selected.add(selector.value);
|
|
129
|
-
}
|
|
156
|
+
const contractMembers = new Set();
|
|
157
|
+
const sources = { fleetIds, aliases, dispatches };
|
|
158
|
+
for (const selector of selectors)
|
|
159
|
+
addSelectorIds(selector, sources, selected, contractMembers);
|
|
130
160
|
const ids = [...selected].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
|
|
131
161
|
if (ids.length === 0)
|
|
132
162
|
throw new TypeError("Akuma selector snapshot is empty");
|
|
163
|
+
await refuseForeignContractMembers(path, ids, contractMembers);
|
|
133
164
|
return { path, ids, ...(settings === undefined ? {} : { settings }) };
|
|
134
165
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AliasBinding } from "../alias/index.js";
|
|
2
|
-
import { type AkumaStatus, type ForkReceipt } from "../akuma/akuma.js";
|
|
2
|
+
import { type AkumaStatus, type ForkReceipt, type ReadonlyRestraint } from "../akuma/akuma.js";
|
|
3
3
|
import type { AkuId } from "../akuma/identity.js";
|
|
4
4
|
import { type Dispatch, type DispatchFailure } from "../dispatch/index.js";
|
|
5
5
|
import { type AkumaAlias } from "../identity/selector.js";
|
|
@@ -57,6 +57,11 @@ export type CallObservation = Readonly<{
|
|
|
57
57
|
export type CallResult = Readonly<{
|
|
58
58
|
kind: "called";
|
|
59
59
|
akuma: AkuId;
|
|
60
|
+
readonly?: ReadonlyRestraint;
|
|
61
|
+
execution: Readonly<{
|
|
62
|
+
cwd: string;
|
|
63
|
+
source: "input" | "world" | "contract-worktree";
|
|
64
|
+
}>;
|
|
60
65
|
dispatch: DispatchStage;
|
|
61
66
|
alias: AliasStage;
|
|
62
67
|
observation: CallObservation;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { realpath, stat } from "node:fs/promises";
|
|
1
2
|
import { moveAlias } from "../alias/index.js";
|
|
2
|
-
import { Akuma } from "../akuma/akuma.js";
|
|
3
|
+
import { Akuma, } from "../akuma/akuma.js";
|
|
3
4
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
4
5
|
import { publishDispatch, readDispatch, } from "../dispatch/index.js";
|
|
5
6
|
import { parseAkumaAlias } from "../identity/selector.js";
|
|
7
|
+
import { readManagedWorktreeAppointment } from "../workspace-place.js";
|
|
6
8
|
import { requireInput } from "./input.js";
|
|
7
9
|
import { addressAkuma } from "./address.js";
|
|
8
|
-
import { seatForKeiyaku } from "./contract.js";
|
|
10
|
+
import { KeiyakuRefused, seatForKeiyaku } from "./contract.js";
|
|
9
11
|
import { scopeForRepo } from "./repo.js";
|
|
10
12
|
function nonblank(value, label) {
|
|
11
13
|
if (typeof value !== "string" || value.trim().length === 0) {
|
|
@@ -67,9 +69,9 @@ async function observeCall(handle, mode, timeoutMs) {
|
|
|
67
69
|
return { kind: "failed", failure: integrationFailure(error) };
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
function dispatchStage(input) {
|
|
72
|
+
async function dispatchStage(input) {
|
|
71
73
|
try {
|
|
72
|
-
const published = publishDispatch(input);
|
|
74
|
+
const published = await publishDispatch(input);
|
|
73
75
|
return published.kind === "dispatched"
|
|
74
76
|
? { kind: "dispatched", dispatch: published.dispatch }
|
|
75
77
|
: { kind: "failed", failure: published.failure };
|
|
@@ -78,17 +80,74 @@ function dispatchStage(input) {
|
|
|
78
80
|
return { kind: "failed", failure: integrationFailure(error) };
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
|
-
function forkDispatchStage(input) {
|
|
83
|
+
async function forkDispatchStage(input) {
|
|
82
84
|
try {
|
|
83
|
-
const parent = readDispatch(input.repository, input.parent);
|
|
85
|
+
const parent = await readDispatch(input.repository, input.parent);
|
|
84
86
|
return parent === null
|
|
85
87
|
? { kind: "none" }
|
|
86
|
-
: dispatchStage({ repository: input.repository, akuId: input.child, contractId: parent.contractId });
|
|
88
|
+
: await dispatchStage({ repository: input.repository, akuId: input.child, contractId: parent.contractId });
|
|
87
89
|
}
|
|
88
90
|
catch (error) {
|
|
89
91
|
return { kind: "failed", failure: integrationFailure(error) };
|
|
90
92
|
}
|
|
91
93
|
}
|
|
94
|
+
async function canonicalizeExistingDirectory(path, diagnostic) {
|
|
95
|
+
try {
|
|
96
|
+
const real = await realpath(path);
|
|
97
|
+
if (!(await stat(real)).isDirectory())
|
|
98
|
+
throw new Error(diagnostic);
|
|
99
|
+
return real;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (error instanceof Error && error.message === diagnostic)
|
|
103
|
+
throw error;
|
|
104
|
+
throw new Error(diagnostic);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function unavailableWorkspace(contractId, detail) {
|
|
108
|
+
return new Error(`Contract workspace is unavailable: ${contractId} ${detail}`);
|
|
109
|
+
}
|
|
110
|
+
async function currentManagedContract(contract, contractId) {
|
|
111
|
+
let state;
|
|
112
|
+
try {
|
|
113
|
+
state = await contract.state();
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
if (error instanceof Error && error.message === `contract does not exist: ${contractId}`) {
|
|
117
|
+
throw new KeiyakuRefused({ kind: "contract-missing", contractId });
|
|
118
|
+
}
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
if (state.terminal !== null)
|
|
122
|
+
throw new KeiyakuRefused({ kind: "terminal", contractId: state.id });
|
|
123
|
+
if (state.coordinates.workspace !== "worktree") {
|
|
124
|
+
throw unavailableWorkspace(state.id, "is here");
|
|
125
|
+
}
|
|
126
|
+
return state;
|
|
127
|
+
}
|
|
128
|
+
async function resolveCallExecution(input) {
|
|
129
|
+
if (input.cwd !== undefined) {
|
|
130
|
+
return {
|
|
131
|
+
cwd: await canonicalizeExistingDirectory(input.cwd, `cwd is not an existing directory: ${input.cwd}`),
|
|
132
|
+
source: "input",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (input.contract === undefined)
|
|
136
|
+
return { cwd: input.path, source: "world" };
|
|
137
|
+
const seat = seatForKeiyaku(input.contract);
|
|
138
|
+
const state = await currentManagedContract(input.contract, seat.id);
|
|
139
|
+
const appointment = await readManagedWorktreeAppointment(seat.scope, state.id);
|
|
140
|
+
if (appointment.kind === "unappointed") {
|
|
141
|
+
throw unavailableWorkspace(state.id, "is unappointed; use reconcile");
|
|
142
|
+
}
|
|
143
|
+
if (appointment.kind === "failed") {
|
|
144
|
+
throw new Error(`${appointment.diagnostic}; use reconcile`);
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
cwd: await canonicalizeExistingDirectory(appointment.path, `Contract workspace is unavailable: ${appointment.path}`),
|
|
148
|
+
source: "contract-worktree",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
92
151
|
export async function callKeiyaku(input) {
|
|
93
152
|
const values = requireInput(input, "Keiyaku.call input");
|
|
94
153
|
onlyKeys(values, ["path", "archetype", "body", "cwd", "mode", "timeoutMs", "settings", "contract", "alias"], "Keiyaku.call input");
|
|
@@ -103,14 +162,20 @@ export async function callKeiyaku(input) {
|
|
|
103
162
|
? undefined
|
|
104
163
|
: parseAkumaAlias(nonblank(values.alias, "alias"));
|
|
105
164
|
const seat = values.contract === undefined ? undefined : seatForKeiyaku(values.contract);
|
|
165
|
+
const execution = await resolveCallExecution({
|
|
166
|
+
path,
|
|
167
|
+
...(cwd === undefined ? {} : { cwd }),
|
|
168
|
+
...(seat === undefined ? {} : { contract: values.contract }),
|
|
169
|
+
});
|
|
106
170
|
const handle = await Akuma.of(path, settings).call({
|
|
107
171
|
archetype,
|
|
108
172
|
body,
|
|
109
|
-
|
|
173
|
+
cwd: execution.cwd,
|
|
110
174
|
});
|
|
175
|
+
const readonly = (await handle.status()).readonly;
|
|
111
176
|
const dispatch = seat === undefined
|
|
112
177
|
? { kind: "none" }
|
|
113
|
-
: dispatchStage({ repository: seat.scope, akuId: handle.id, contractId: seat.id });
|
|
178
|
+
: await dispatchStage({ repository: seat.scope, akuId: handle.id, contractId: seat.id });
|
|
114
179
|
let aliasStage = { kind: "none" };
|
|
115
180
|
if (alias !== undefined) {
|
|
116
181
|
if (dispatch.kind === "failed")
|
|
@@ -126,7 +191,15 @@ export async function callKeiyaku(input) {
|
|
|
126
191
|
}
|
|
127
192
|
}
|
|
128
193
|
const observation = await observeCall(handle, mode, timeoutMs);
|
|
129
|
-
return {
|
|
194
|
+
return {
|
|
195
|
+
kind: "called",
|
|
196
|
+
akuma: handle.id,
|
|
197
|
+
...(readonly === undefined ? {} : { readonly }),
|
|
198
|
+
execution,
|
|
199
|
+
dispatch,
|
|
200
|
+
alias: aliasStage,
|
|
201
|
+
observation,
|
|
202
|
+
};
|
|
130
203
|
}
|
|
131
204
|
export async function forkKeiyaku(input) {
|
|
132
205
|
const values = requireInput(input, "Keiyaku.fork input");
|
|
@@ -134,11 +207,11 @@ export async function forkKeiyaku(input) {
|
|
|
134
207
|
const path = nonblank(values.path, "path");
|
|
135
208
|
const at = nonblank(values.at, "at");
|
|
136
209
|
const settings = settingsOption(values.settings);
|
|
137
|
-
const akuma = addressAkuma({
|
|
210
|
+
const akuma = (await addressAkuma({
|
|
138
211
|
path,
|
|
139
212
|
akuma: nonblank(values.akuma, "akuma"),
|
|
140
213
|
...(settings === undefined ? {} : { settings }),
|
|
141
|
-
}).id;
|
|
214
|
+
})).id;
|
|
142
215
|
const repository = values.repo === undefined ? undefined : scopeForRepo(values.repo);
|
|
143
216
|
const receipt = await Akuma.of(path, settings)
|
|
144
217
|
.of({ id: akuma })
|
|
@@ -147,6 +220,6 @@ export async function forkKeiyaku(input) {
|
|
|
147
220
|
return { ...receipt, parent: akuma };
|
|
148
221
|
const dispatch = repository === undefined
|
|
149
222
|
? { kind: "none" }
|
|
150
|
-
: forkDispatchStage({ repository, parent: akuma, child: receipt.child });
|
|
223
|
+
: await forkDispatchStage({ repository, parent: akuma, child: receipt.child });
|
|
151
224
|
return { kind: "forked", parent: akuma, child: receipt.child, dispatch };
|
|
152
225
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ContractId } from "../core/facts/types.js";
|
|
2
|
+
import { type AuditReport, type RepositoryScope } from "../protocol/operations.js";
|
|
3
|
+
import { type WorktreeHooks } from "./configuration.js";
|
|
4
|
+
import { type MutationResult } from "./mutation.js";
|
|
5
|
+
export type AuditInput = Readonly<{
|
|
6
|
+
actor?: string;
|
|
7
|
+
hooks?: WorktreeHooks;
|
|
8
|
+
includeDirty?: boolean;
|
|
9
|
+
showDiff?: boolean;
|
|
10
|
+
requireBranchesToBeUpToDate?: boolean;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}>;
|
|
13
|
+
/** Normalize public audit input and project the protocol audit operation. */
|
|
14
|
+
export declare function auditContract(input: Readonly<{
|
|
15
|
+
scope: RepositoryScope;
|
|
16
|
+
contractId: ContractId;
|
|
17
|
+
input?: AuditInput;
|
|
18
|
+
}>): Promise<MutationResult<AuditReport>>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { decodeContractDocument } from "../body/decode.js";
|
|
2
|
+
import { withGitDecodeChannel } from "../git/read-observation.js";
|
|
3
|
+
import { auditOperation, } from "../protocol/operations.js";
|
|
4
|
+
import { worktreeHooksOption } from "./configuration.js";
|
|
5
|
+
import { actorOption, documentDerivation, optionalBoolean, optionalSignal, requireInput, } from "./input.js";
|
|
6
|
+
import { completeMutation } from "./mutation.js";
|
|
7
|
+
import { requireAccepted } from "./refusal.js";
|
|
8
|
+
function normalizeAuditInput(input) {
|
|
9
|
+
const values = input === undefined ? undefined : requireInput(input, "audit input");
|
|
10
|
+
const signal = optionalSignal(values?.signal);
|
|
11
|
+
return {
|
|
12
|
+
hooks: worktreeHooksOption(values?.hooks),
|
|
13
|
+
...actorOption(values?.actor),
|
|
14
|
+
includeDirty: optionalBoolean(values?.includeDirty, "includeDirty") ?? false,
|
|
15
|
+
showDiff: optionalBoolean(values?.showDiff, "showDiff") ?? false,
|
|
16
|
+
requireBranchesToBeUpToDate: optionalBoolean(values?.requireBranchesToBeUpToDate, "requireBranchesToBeUpToDate") ?? false,
|
|
17
|
+
...(signal === undefined ? {} : { signal }),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Normalize public audit input and project the protocol audit operation. */
|
|
21
|
+
export async function auditContract(input) {
|
|
22
|
+
const normalized = normalizeAuditInput(input.input);
|
|
23
|
+
return withGitDecodeChannel(input.scope, async (channel) => {
|
|
24
|
+
const accepted = requireAccepted(await auditOperation({
|
|
25
|
+
scope: input.scope,
|
|
26
|
+
channel,
|
|
27
|
+
contractId: input.contractId,
|
|
28
|
+
deriveDocument: (state) => documentDerivation(decodeContractDocument(state.terms.document.bytes), state.terms.gates, state.id),
|
|
29
|
+
includeDirty: normalized.includeDirty,
|
|
30
|
+
showDiff: normalized.showDiff,
|
|
31
|
+
requireBranchesToBeUpToDate: normalized.requireBranchesToBeUpToDate,
|
|
32
|
+
...(normalized.signal === undefined ? {} : { signal: normalized.signal }),
|
|
33
|
+
...(normalized.actor === undefined ? {} : { actor: normalized.actor }),
|
|
34
|
+
}));
|
|
35
|
+
return completeMutation({
|
|
36
|
+
scope: input.scope,
|
|
37
|
+
channel,
|
|
38
|
+
contractId: input.contractId,
|
|
39
|
+
accepted,
|
|
40
|
+
value: (report) => report,
|
|
41
|
+
hooks: normalized.hooks,
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -30,7 +30,7 @@ async function attemptCandidates(input) {
|
|
|
30
30
|
const id = candidateId(input.title, collision);
|
|
31
31
|
let reserved = false;
|
|
32
32
|
if (input.workspace === "here") {
|
|
33
|
-
const reservation = reserveContractWorktree(input.scope, id);
|
|
33
|
+
const reservation = await reserveContractWorktree(input.scope, id);
|
|
34
34
|
if (reservation.kind !== "reserved") {
|
|
35
35
|
return { kind: "refused", refusal: {
|
|
36
36
|
kind: "here-worktree-appointed",
|
|
@@ -44,13 +44,13 @@ async function attemptCandidates(input) {
|
|
|
44
44
|
if (result.kind === "accepted")
|
|
45
45
|
return result;
|
|
46
46
|
if (reserved)
|
|
47
|
-
releaseContractWorktree(input.scope, id);
|
|
47
|
+
await releaseContractWorktree(input.scope, id);
|
|
48
48
|
if (result.kind !== "refused" || result.refusal.kind !== "contract-exists")
|
|
49
49
|
return result;
|
|
50
50
|
}
|
|
51
51
|
throw new Error("contract identity collision attempts exhausted");
|
|
52
52
|
}
|
|
53
|
-
export function admitBindWithAppointment(input) {
|
|
53
|
+
export async function admitBindWithAppointment(input) {
|
|
54
54
|
const action = () => attemptCandidates(input);
|
|
55
|
-
return input.workspace === "here" ? withContractWorktreeAppointment(input.scope, action) : action();
|
|
55
|
+
return input.workspace === "here" ? await withContractWorktreeAppointment(input.scope, action) : action();
|
|
56
56
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AkumaList } from "../akuma/akuma.js";
|
|
2
2
|
import { type ArchetypeCatalogRow } from "../akuma/archetype.js";
|
|
3
3
|
import type { Settings } from "../settings.js";
|
|
4
|
-
import {
|
|
4
|
+
import type { TaskRow } from "../task/index.js";
|
|
5
5
|
import { type ContractBoard } from "./contract.js";
|
|
6
6
|
import { Repo } from "./repo.js";
|
|
7
7
|
import type { WorldRoot } from "../world.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Akuma } from "../akuma/akuma.js";
|
|
2
2
|
import { listArchetypeDefinitions } from "../akuma/archetype.js";
|
|
3
|
-
import {
|
|
3
|
+
import { observeTaskCatalogRows } from "../task/operations.js";
|
|
4
4
|
import { listKeiyaku } from "./contract.js";
|
|
5
5
|
import { requireInput } from "./input.js";
|
|
6
6
|
import { Repo } from "./repo.js";
|
|
@@ -32,7 +32,7 @@ function queryValue(value) {
|
|
|
32
32
|
if (query.kind !== "akuma")
|
|
33
33
|
return { kind: query.kind };
|
|
34
34
|
if (query.archetype !== undefined && typeof query.archetype !== "string") {
|
|
35
|
-
throw new TypeError("Keiyaku.ls Akuma
|
|
35
|
+
throw new TypeError("Keiyaku.ls Akuma name must be a string");
|
|
36
36
|
}
|
|
37
37
|
return { kind: "akuma", ...(query.archetype === undefined ? {} : { archetype: query.archetype }) };
|
|
38
38
|
}
|
|
@@ -52,16 +52,13 @@ export async function listCatalog(input) {
|
|
|
52
52
|
return { kind: "contracts", root: board.root, state: board.state, rows: board.rows };
|
|
53
53
|
}
|
|
54
54
|
if (query.kind === "archetypes") {
|
|
55
|
-
return { kind: "archetypes", rows: listArchetypeDefinitions({ settings: settingsValue(values.settings) }) };
|
|
55
|
+
return { kind: "archetypes", rows: await listArchetypeDefinitions({ settings: settingsValue(values.settings) }) };
|
|
56
56
|
}
|
|
57
57
|
const path = worldRoot(values.path);
|
|
58
58
|
if (query.kind === "tasks") {
|
|
59
|
-
|
|
60
|
-
if (result.kind !== "accepted")
|
|
61
|
-
throw new Error(`Task catalog ${result.kind}: ${JSON.stringify(result)}`);
|
|
62
|
-
return { kind: "tasks", root: path, rows: result.value };
|
|
59
|
+
return { kind: "tasks", root: path, rows: await observeTaskCatalogRows(path) };
|
|
63
60
|
}
|
|
64
|
-
const listed = Akuma.of(path).list(query.archetype === undefined ? undefined : { archetype: query.archetype });
|
|
61
|
+
const listed = await Akuma.of(path).list(query.archetype === undefined ? undefined : { archetype: query.archetype });
|
|
65
62
|
return {
|
|
66
63
|
kind: "akuma",
|
|
67
64
|
root: path,
|
|
@@ -3,23 +3,24 @@ import { type RegionObservation, type RegionOverlap } from "./region.js";
|
|
|
3
3
|
import { type Gate, type WorktreeHooks } from "./configuration.js";
|
|
4
4
|
import { type ChangeId, type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
|
|
5
5
|
export { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
6
|
-
import { type AuditReport, type ContractBoard, type ContractDisposition, type ContractGateCurrent, type ContractGateReport, type ContractObservation, type ContractPhase, type ContractRow, type FactKind, type PlacementStop, type ReconcileReport as ProtocolReconcileReport, type RepositoryScope, type ReviewValue, type
|
|
6
|
+
import { type AuditReport, type ContractBoard, type ContractDisposition, type ContractGateCurrent, type ContractGateReport, type ContractObservation, type ContractPhase, type ContractRow, type FactKind, type PlacementStop, type ReconcileReport as ProtocolReconcileReport, type RepositoryScope, type ReviewValue, type VerificationReuse, type VerificationStop, type DeliveryPreparationRefusal } from "../protocol/operations.js";
|
|
7
7
|
import { type SettlementReport } from "../settlement/settle.js";
|
|
8
8
|
import { type TaskId } from "../task/identity.js";
|
|
9
9
|
import { Repo, type ReconcileInput } from "./repo.js";
|
|
10
|
+
import { type AuditInput } from "./audit.js";
|
|
10
11
|
import { Delivery } from "./delivery.js";
|
|
11
12
|
import { type MutationResult } from "./mutation.js";
|
|
12
13
|
export { KeiyakuRefused, KeiyakuRetry, type ContractAppointmentRefusal, type KeiyakuRefusal, type KeiyakuRetryReason, } from "./refusal.js";
|
|
13
14
|
export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError } from "./configuration.js";
|
|
14
15
|
export type { Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, WorktreeHooks } from "./configuration.js";
|
|
15
|
-
export type { AuditReport, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow, FactKind, SnapshotId,
|
|
16
|
+
export type { AuditReport, DeliveryPreparationRefusal, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow, FactKind, SnapshotId, };
|
|
16
17
|
export type { TaskId };
|
|
17
18
|
export type { RegionOverlap };
|
|
18
19
|
export type Fact = JournalEntry;
|
|
19
20
|
export type ActorId = string;
|
|
20
21
|
export type AttestationVerdict = "satisfied" | "unsatisfied";
|
|
21
22
|
export type Review = ReviewValue;
|
|
22
|
-
export type { PlacementStop, VerificationStop };
|
|
23
|
+
export type { PlacementStop, VerificationReuse, VerificationStop };
|
|
23
24
|
export type TopologyEffect = ProtocolReconcileReport["effects"][number] | ContractFileEffect;
|
|
24
25
|
export type Lag = ProtocolReconcileReport["lag"][number] | ContractFileLag;
|
|
25
26
|
export type { MutationResult };
|
|
@@ -89,9 +90,7 @@ export type DeliverInput = ActorOptions & Readonly<{
|
|
|
89
90
|
includeDirty?: boolean;
|
|
90
91
|
signal?: AbortSignal;
|
|
91
92
|
}>;
|
|
92
|
-
export type AuditInput
|
|
93
|
-
signal?: AbortSignal;
|
|
94
|
-
}>;
|
|
93
|
+
export type { AuditInput };
|
|
95
94
|
export declare class KeiyakuHandle {
|
|
96
95
|
private readonly id;
|
|
97
96
|
private readonly scope;
|
|
@@ -2,20 +2,21 @@ import { documentDiff } from "../markdown/diff.js";
|
|
|
2
2
|
import { applyAmendDocument } from "../body/amend.js";
|
|
3
3
|
import { decodeArcDocument } from "../body/arc.js";
|
|
4
4
|
import { decodeContractDocument } from "../body/decode.js";
|
|
5
|
-
import {
|
|
5
|
+
import { renderContractGuidance, } from "../contract-worktree.js";
|
|
6
6
|
import { actorOption, contractTerms, documentDerivation, normalizedGates, normalizedList, optionalBoolean, optionalNonblank, optionalSignal, requireInput, requireMarkdown, } from "./input.js";
|
|
7
7
|
import { observeRegion } from "./region.js";
|
|
8
8
|
import { worktreeHooksOption } from "./configuration.js";
|
|
9
9
|
import { contractId, } from "../core/facts/types.js";
|
|
10
10
|
export { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
11
|
-
import { abandonOperation, amendOperation, arcOperation,
|
|
11
|
+
import { abandonOperation, amendOperation, arcOperation, contractObservationOperation, contractsOperation, deliveryDiffOperation, deliverOperation, deliveryOperation, reviewOperation, stateOperation, } from "../protocol/operations.js";
|
|
12
12
|
import { withGitDecodeChannel } from "../git/read-observation.js";
|
|
13
|
-
import { settle } from "../settlement/settle.js";
|
|
14
13
|
import { claimTaskHolderWithFence, releaseTaskHolder, releaseTaskHolderWithFence, taskHolderObservationSelection, } from "../settlement/holder.js";
|
|
15
14
|
import { parseTaskId } from "../task/identity.js";
|
|
16
15
|
import { reconcileInput, scopeForRepo } from "./repo.js";
|
|
16
|
+
import { auditContract } from "./audit.js";
|
|
17
17
|
import { Delivery, deliveryHandle } from "./delivery.js";
|
|
18
18
|
import { completeHolderMutation, completeMutation, } from "./mutation.js";
|
|
19
|
+
import { completeReconcile } from "./reconcile.js";
|
|
19
20
|
import { admitBindWithAppointment } from "./bind.js";
|
|
20
21
|
import { KeiyakuRefused, requireAccepted } from "./refusal.js";
|
|
21
22
|
export { KeiyakuRefused, KeiyakuRetry, } from "./refusal.js";
|
|
@@ -197,42 +198,17 @@ export class KeiyakuHandle {
|
|
|
197
198
|
});
|
|
198
199
|
}
|
|
199
200
|
async audit(input) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return withGitDecodeChannel(this.scope, async (channel) => {
|
|
205
|
-
const accepted = requireAccepted(await auditOperation({
|
|
206
|
-
scope: this.scope,
|
|
207
|
-
channel,
|
|
208
|
-
contractId: this.id,
|
|
209
|
-
deriveDocument: (state) => documentDerivation(decodeContractDocument(state.terms.document.bytes), state.terms.gates, state.id),
|
|
210
|
-
...(signal === undefined ? {} : { signal }),
|
|
211
|
-
...actor,
|
|
212
|
-
}));
|
|
213
|
-
return completeMutation({
|
|
214
|
-
...completion(this.scope, channel, this.id, (report) => report, hooks),
|
|
215
|
-
accepted,
|
|
216
|
-
});
|
|
201
|
+
return auditContract({
|
|
202
|
+
scope: this.scope,
|
|
203
|
+
contractId: this.id,
|
|
204
|
+
...(input === undefined ? {} : { input }),
|
|
217
205
|
});
|
|
218
206
|
}
|
|
219
207
|
async reconcile(input) {
|
|
220
208
|
const options = reconcileInput(input);
|
|
221
|
-
return withGitDecodeChannel(this.scope,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const settlement = await settle({ repository: this.scope, channel, state: retained.state, effects: retained.report.effects });
|
|
225
|
-
const deferRemoval = retained.state !== null && retained.state.terminal !== null
|
|
226
|
-
&& retained.state.coordinates.workspace === "worktree";
|
|
227
|
-
const cleanup = deferRemoval
|
|
228
|
-
? await reconcileOperation({ scope: this.scope, channel, contractId: this.id, ...options })
|
|
229
|
-
: null;
|
|
230
|
-
return {
|
|
231
|
-
effects: [...retained.report.effects, ...projection.effects, ...(cleanup?.report.effects ?? [])],
|
|
232
|
-
lag: [...retained.report.lag, ...projection.lag, ...(cleanup?.report.lag ?? [])],
|
|
233
|
-
settlement,
|
|
234
|
-
};
|
|
235
|
-
});
|
|
209
|
+
return withGitDecodeChannel(this.scope, (channel) => completeReconcile({
|
|
210
|
+
scope: this.scope, channel, contractId: this.id, ...options,
|
|
211
|
+
}));
|
|
236
212
|
}
|
|
237
213
|
deliveryHandle(delivery) {
|
|
238
214
|
return deliveryHandle(delivery, () => deliveryDiffOperation({
|
|
@@ -3,6 +3,7 @@ import type { DeliverValue } from "../protocol/operations.js";
|
|
|
3
3
|
declare class DeliveryHandle {
|
|
4
4
|
private readonly readDiff;
|
|
5
5
|
readonly verification?: DeliverValue["verification"];
|
|
6
|
+
readonly verificationReuse?: DeliverValue["verificationReuse"];
|
|
6
7
|
readonly placement?: DeliverValue["placement"];
|
|
7
8
|
readonly cleanup?: DeliverValue["cleanup"];
|
|
8
9
|
readonly leak?: DeliverValue["leak"];
|
|
@@ -10,7 +11,7 @@ declare class DeliveryHandle {
|
|
|
10
11
|
readonly integration: DeliverValue["integration"];
|
|
11
12
|
readonly method: DeliverValue["method"];
|
|
12
13
|
readonly policy: DeliverValue["policy"];
|
|
13
|
-
constructor(identity: Pick<DeliverValue, "tenderSnapshot" | "integration" | "method" | "policy">, readDiff: () => Promise<string | null>, outcomes?: Partial<Pick<DeliverValue, "verification" | "placement" | "cleanup" | "leak">>);
|
|
14
|
+
constructor(identity: Pick<DeliverValue, "tenderSnapshot" | "integration" | "method" | "policy">, readDiff: () => Promise<string | null>, outcomes?: Partial<Pick<DeliverValue, "verification" | "verificationReuse" | "placement" | "cleanup" | "leak">>);
|
|
14
15
|
diff(): Promise<string | null>;
|
|
15
16
|
}
|
|
16
17
|
export type Delivery = DeliveryHandle;
|