@astrosheep/keiyaku 4.0.0 → 4.0.1
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 +2 -9
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +11 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +9 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +94 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +162 -45
- package/build/src/akuma/akuma.d.ts +33 -25
- package/build/src/akuma/akuma.js +93 -61
- package/build/src/akuma/archetype.d.ts +8 -0
- package/build/src/akuma/archetype.js +28 -9
- package/build/src/akuma/body.js +196 -84
- package/build/src/akuma/coordinate.d.ts +9 -0
- package/build/src/akuma/coordinate.js +22 -0
- package/build/src/akuma/heart/facts.d.ts +67 -15
- package/build/src/akuma/heart/facts.js +3 -3
- package/build/src/akuma/heart/index.d.ts +41 -29
- package/build/src/akuma/heart/index.js +72 -193
- package/build/src/akuma/heart/rows.d.ts +30 -53
- package/build/src/akuma/heart/rows.js +91 -111
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +55 -8
- package/build/src/akuma/heart/storage.d.ts +33 -0
- package/build/src/akuma/heart/storage.js +164 -0
- package/build/src/akuma/heart/tells.d.ts +12 -0
- package/build/src/akuma/heart/tells.js +79 -0
- package/build/src/akuma/heart/timeline.d.ts +15 -0
- package/build/src/akuma/heart/timeline.js +86 -0
- package/build/src/akuma/index.d.ts +4 -2
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection.d.ts +97 -0
- package/build/src/akuma/projection.js +145 -0
- package/build/src/akuma/provider.d.ts +57 -11
- package/build/src/akuma/provider.js +57 -37
- package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
- package/build/src/akuma/providers/claude/events.js +185 -0
- package/build/src/akuma/providers/claude/index.d.ts +46 -0
- package/build/src/akuma/providers/claude/index.js +265 -0
- package/build/src/akuma/providers/claude/input.d.ts +13 -0
- package/build/src/akuma/providers/claude/input.js +109 -0
- package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
- package/build/src/akuma/providers/codex-app-server/events.js +12 -12
- package/build/src/akuma/providers/codex-app-server/index.d.ts +13 -11
- package/build/src/akuma/providers/codex-app-server/index.js +73 -22
- package/build/src/akuma/providers/index.js +22 -8
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +48 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +116 -0
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +32 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +203 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +41 -0
- package/build/src/akuma/providers/opencode-sdk/session.js +62 -0
- package/build/src/akuma/providers/pi/events.d.ts +33 -0
- package/build/src/akuma/providers/pi/events.js +128 -0
- package/build/src/akuma/providers/pi/index.d.ts +11 -0
- package/build/src/akuma/providers/pi/index.js +162 -0
- package/build/src/akuma/requests.d.ts +1 -0
- package/build/src/akuma/requests.js +5 -2
- package/build/src/alias/index.d.ts +4 -3
- package/build/src/alias/index.js +2 -3
- package/build/src/body/render.js +2 -1
- package/build/src/body/shape.js +7 -1
- package/build/src/body/verification.js +19 -4
- package/build/src/cli/accepted.d.ts +2 -0
- package/build/src/cli/accepted.js +2 -1
- package/build/src/cli/commands/akuma-invoke.d.ts +42 -18
- package/build/src/cli/commands/akuma-invoke.js +94 -50
- package/build/src/cli/commands/akuma.d.ts +15 -7
- package/build/src/cli/commands/akuma.js +94 -56
- package/build/src/cli/commands/contract.d.ts +142 -0
- package/build/src/cli/commands/contract.js +14 -0
- package/build/src/cli/commands/install.js +2 -0
- package/build/src/cli/commands/task-invoke.d.ts +3 -1
- package/build/src/cli/commands/task-invoke.js +27 -2
- package/build/src/cli/commands/task.js +2 -2
- package/build/src/cli/invoke.d.ts +6 -1
- package/build/src/cli/invoke.js +241 -43
- package/build/src/cli/main.js +20 -1
- package/build/src/cli/parse.d.ts +13 -116
- package/build/src/cli/parse.js +51 -78
- package/build/src/cli/render/akuma-tool.d.ts +2 -0
- package/build/src/cli/render/akuma-tool.js +6 -2
- package/build/src/cli/render/akuma.d.ts +2 -1
- package/build/src/cli/render/akuma.js +157 -217
- package/build/src/cli/render/catalog.d.ts +2 -0
- package/build/src/cli/render/catalog.js +16 -0
- package/build/src/cli/render/contract.d.ts +1 -1
- package/build/src/cli/render/contract.js +38 -5
- package/build/src/cli/render/kanshi.js +53 -5
- package/build/src/cli/render/refusal.js +17 -0
- package/build/src/cli/render/terminal.d.ts +13 -0
- package/build/src/cli/render/terminal.js +75 -0
- package/build/src/cli/render/text.js +5 -0
- package/build/src/cli/result.d.ts +15 -3
- package/build/src/contract-worktree.d.ts +43 -0
- package/build/src/contract-worktree.js +213 -0
- package/build/src/coordination/durable-file.d.ts +3 -0
- package/build/src/coordination/durable-file.js +44 -1
- package/build/src/core/facts/codec.js +23 -4
- package/build/src/core/facts/eligibility.d.ts +1 -10
- package/build/src/core/facts/eligibility.js +0 -49
- package/build/src/core/facts/observation.d.ts +3 -0
- package/build/src/core/facts/observation.js +12 -0
- package/build/src/core/facts/types.d.ts +10 -3
- package/build/src/core/subject.js +2 -2
- package/build/src/core/verbs/amend.js +12 -16
- package/build/src/core/verbs/bind.js +2 -16
- package/build/src/core/verbs/deliver.js +20 -4
- package/build/src/core/verbs/placement.js +3 -8
- package/build/src/dispatch/index.d.ts +3 -1
- package/build/src/dispatch/index.js +14 -5
- package/build/src/duration.d.ts +10 -0
- package/build/src/duration.js +22 -0
- package/build/src/git/admission.d.ts +2 -2
- package/build/src/git/admission.js +26 -16
- package/build/src/git/hooks.d.ts +15 -0
- package/build/src/git/hooks.js +57 -5
- package/build/src/git/identity.d.ts +5 -1
- package/build/src/git/identity.js +23 -4
- package/build/src/git/integration.d.ts +49 -0
- package/build/src/git/integration.js +214 -0
- package/build/src/git/observe.d.ts +25 -13
- package/build/src/git/observe.js +175 -72
- package/build/src/git/read-observation.d.ts +41 -0
- package/build/src/git/read-observation.js +361 -0
- package/build/src/git/reconcile.d.ts +15 -5
- package/build/src/git/reconcile.js +238 -85
- package/build/src/git/repository.d.ts +19 -4
- package/build/src/git/repository.js +77 -43
- package/build/src/git/scratch.d.ts +13 -0
- package/build/src/git/scratch.js +66 -0
- package/build/src/git/target-placement.d.ts +56 -0
- package/build/src/git/target-placement.js +255 -0
- package/build/src/git/tender.d.ts +48 -0
- package/build/src/git/tender.js +82 -0
- package/build/src/git/terminal-seal.d.ts +24 -0
- package/build/src/git/terminal-seal.js +87 -0
- package/build/src/git/tree.d.ts +2 -2
- package/build/src/git/tree.js +4 -0
- package/build/src/git/workspace.d.ts +21 -0
- package/build/src/git/workspace.js +104 -0
- package/build/src/identity/selector.d.ts +6 -0
- package/build/src/identity/selector.js +19 -0
- package/build/src/index.d.ts +4 -2
- package/build/src/index.js +2 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.d.ts +5 -2
- package/build/src/kanshi/read.js +154 -45
- package/build/src/kanshi/report.d.ts +31 -6
- package/build/src/kanshi/select.js +1 -1
- package/build/src/library/address.d.ts +48 -0
- package/build/src/library/address.js +134 -0
- package/build/src/library/akuma-creation.d.ts +10 -6
- package/build/src/library/akuma-creation.js +12 -11
- package/build/src/library/bind.d.ts +21 -0
- package/build/src/library/bind.js +56 -0
- package/build/src/library/catalog.d.ts +58 -0
- package/build/src/library/catalog.js +72 -0
- package/build/src/library/configuration.d.ts +6 -15
- package/build/src/library/configuration.js +14 -17
- package/build/src/library/contract.d.ts +21 -46
- package/build/src/library/contract.js +193 -183
- package/build/src/library/delivery.d.ts +23 -0
- package/build/src/library/delivery.js +21 -0
- package/build/src/library/fleet.d.ts +65 -0
- package/build/src/library/fleet.js +189 -0
- package/build/src/library/input.d.ts +3 -0
- package/build/src/library/input.js +19 -0
- package/build/src/library/keiyaku.d.ts +16 -2
- package/build/src/library/keiyaku.js +11 -1
- package/build/src/library/mutation.d.ts +38 -0
- package/build/src/library/mutation.js +39 -0
- package/build/src/library/refusal.d.ts +21 -0
- package/build/src/library/refusal.js +29 -0
- package/build/src/library/region.d.ts +2 -1
- package/build/src/library/region.js +3 -3
- package/build/src/library/repo.d.ts +4 -1
- package/build/src/library/repo.js +31 -16
- package/build/src/protocol/attempt.d.ts +16 -3
- package/build/src/protocol/attempt.js +39 -8
- package/build/src/protocol/bind.d.ts +9 -2
- package/build/src/protocol/bind.js +47 -39
- package/build/src/protocol/intent.d.ts +42 -18
- package/build/src/protocol/intent.js +36 -75
- package/build/src/protocol/operations.d.ts +93 -35
- package/build/src/protocol/operations.js +235 -123
- package/build/src/protocol/outcome.d.ts +7 -2
- package/build/src/protocol/outcome.js +9 -3
- package/build/src/protocol/placement.d.ts +30 -0
- package/build/src/protocol/placement.js +114 -0
- package/build/src/protocol/read/audit.d.ts +9 -3
- package/build/src/protocol/read/audit.js +25 -9
- package/build/src/protocol/read/documents.d.ts +2 -2
- package/build/src/protocol/read/documents.js +4 -4
- package/build/src/protocol/read/status.d.ts +11 -5
- package/build/src/protocol/read/status.js +28 -15
- package/build/src/protocol/run.d.ts +49 -7
- package/build/src/protocol/run.js +53 -25
- package/build/src/runtime/proc/line-rpc.d.ts +1 -0
- package/build/src/runtime/proc/line-rpc.js +21 -0
- package/build/src/runtime/proc/run.d.ts +18 -2
- package/build/src/runtime/proc/run.js +34 -8
- package/build/src/settings.d.ts +6 -0
- package/build/src/settings.js +29 -14
- package/build/src/settlement/fence.d.ts +9 -0
- package/build/src/settlement/fence.js +23 -0
- package/build/src/settlement/holder.d.ts +25 -4
- package/build/src/settlement/holder.js +102 -28
- package/build/src/settlement/settle.d.ts +8 -0
- package/build/src/settlement/settle.js +102 -28
- package/build/src/task/board.d.ts +20 -2
- package/build/src/task/board.js +11 -1
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +2 -2
- package/build/src/task/context.js +2 -7
- package/build/src/task/index.d.ts +9 -9
- package/build/src/task/index.js +15 -12
- package/build/src/task/operations.d.ts +31 -12
- package/build/src/task/operations.js +8 -4
- package/build/src/task/store.d.ts +4 -6
- package/build/src/task/store.js +3 -3
- package/build/src/verification/declaration.d.ts +1 -0
- package/build/src/verification/execution.d.ts +49 -0
- package/build/src/verification/execution.js +104 -0
- package/build/src/world.d.ts +13 -0
- package/build/src/world.js +103 -0
- package/package.json +7 -4
- package/build/src/akuma/activity.d.ts +0 -66
- package/build/src/akuma/activity.js +0 -139
- package/build/src/akuma/providers/claude.js +0 -305
- package/build/src/context-root.d.ts +0 -4
- package/build/src/context-root.js +0 -15
- package/build/src/git/delivery.d.ts +0 -20
- package/build/src/git/delivery.js +0 -109
- package/build/src/git/verification.d.ts +0 -14
- package/build/src/git/verification.js +0 -56
- package/build/src/verification/producer.d.ts +0 -23
- package/build/src/verification/producer.js +0 -54
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { materializeIntegrationSnapshot, planIntegration, prepareReviewIntegration, readDeliveryDiff, } from "../git/integration.js";
|
|
2
|
+
import { captureTender, dirtyTenderDelta, dirtyTenderRefusal, materializeTenderSnapshot, } from "../git/tender.js";
|
|
3
|
+
import { currentBranch, extendContractsForAdmissionAt, observeContractAt, observeContractWorld, observeContractsForAdmissionAt, } from "../git/observe.js";
|
|
4
|
+
import { reconcile, reconcileBatch, reconcileObservationFailure, } from "../git/reconcile.js";
|
|
4
5
|
import { NoGitWorldError, repositoryAt } from "../git/repository.js";
|
|
5
|
-
import {
|
|
6
|
+
import { withGitReadObservation } from "../git/read-observation.js";
|
|
6
7
|
import { dependencyKeySet } from "../core/subject.js";
|
|
7
8
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
8
9
|
import { contractState, documentIsCurrent } from "../core/facts/observation.js";
|
|
@@ -12,102 +13,190 @@ import { decideAmend } from "../core/verbs/amend.js";
|
|
|
12
13
|
import { decideArc } from "../core/verbs/arc.js";
|
|
13
14
|
import { decideDeliver } from "../core/verbs/deliver.js";
|
|
14
15
|
import { decideAttestation } from "../core/verbs/attestation.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { auditReport,
|
|
16
|
+
import { admitIntent, verifyDelivery, } from "./intent.js";
|
|
17
|
+
import { admitPlacement } from "./placement.js";
|
|
18
|
+
import { auditReport, readAuditAt } from "./read/audit.js";
|
|
18
19
|
import { readDocuments } from "./read/documents.js";
|
|
19
|
-
import { readContractBoard,
|
|
20
|
-
import { admitDecidedOffer } from "./attempt.js";
|
|
20
|
+
import { readContractBoard, readContractObservationAt, } from "./read/status.js";
|
|
21
|
+
import { admitDecidedOffer, mintAttempts } from "./attempt.js";
|
|
21
22
|
export { bindOperation } from "./bind.js";
|
|
22
|
-
import { accepted, admitted, complete } from "./outcome.js";
|
|
23
|
+
import { accepted, admitted, complete, } from "./outcome.js";
|
|
23
24
|
const REVIEWED = gate("reviewed");
|
|
24
25
|
function timestamp() { return new Date().toISOString(); }
|
|
25
26
|
function mergeAdmissions(current, next) {
|
|
26
|
-
|
|
27
|
+
const effects = [...(current.physical?.effects ?? []), ...(next.physical?.effects ?? [])];
|
|
28
|
+
const lag = [...(current.physical?.lag ?? []), ...(next.physical?.lag ?? [])];
|
|
29
|
+
return {
|
|
30
|
+
...next,
|
|
31
|
+
facts: [...current.facts, ...next.facts],
|
|
32
|
+
...(effects.length === 0 && lag.length === 0 ? {} : { physical: { effects, lag } }),
|
|
33
|
+
};
|
|
27
34
|
}
|
|
28
35
|
function stepStop(result) {
|
|
29
36
|
if (result.kind === "accepted")
|
|
30
37
|
return undefined;
|
|
31
38
|
return result.kind === "refused" ? { refusal: result.refusal } : { retry: result };
|
|
32
39
|
}
|
|
40
|
+
function verificationStop(step) {
|
|
41
|
+
return "failure" in step ? step : stepStop(step);
|
|
42
|
+
}
|
|
43
|
+
function placementStop(result) {
|
|
44
|
+
if (result.kind === "accepted")
|
|
45
|
+
return undefined;
|
|
46
|
+
if (result.kind === "placement-failed") {
|
|
47
|
+
return { failure: "target-placement-failed", diagnostic: result.diagnostic };
|
|
48
|
+
}
|
|
49
|
+
if (result.kind === "target-moved") {
|
|
50
|
+
const { contractId, target, expected, observed } = result;
|
|
51
|
+
return { failure: "target-moved", contractId, target, expected, observed };
|
|
52
|
+
}
|
|
53
|
+
return result.kind === "refused" ? { refusal: result.refusal } : { retry: result };
|
|
54
|
+
}
|
|
33
55
|
export { NoGitWorldError };
|
|
34
56
|
export function scopeOperation(input) { return repositoryAt(input.coordinate); }
|
|
35
57
|
export function currentBranchOperation(input) {
|
|
36
58
|
return currentBranch(input.scope);
|
|
37
59
|
}
|
|
38
|
-
export function contractsOperation(input) {
|
|
60
|
+
export async function contractsOperation(input) {
|
|
61
|
+
return withGitReadObservation(input.scope, input.channel, readContractBoard);
|
|
62
|
+
}
|
|
39
63
|
export function contractObservationOperation(input) {
|
|
40
|
-
return
|
|
64
|
+
return readContractObservationAt(input.scope, input.channel, input.contractId);
|
|
41
65
|
}
|
|
42
|
-
export function
|
|
43
|
-
|
|
44
|
-
|
|
66
|
+
export async function documentsOperationAt(scope, channel) {
|
|
67
|
+
return withGitReadObservation(scope, channel, readDocuments);
|
|
68
|
+
}
|
|
69
|
+
export async function stateOperation(input) {
|
|
70
|
+
const state = (await observeContractAt(input.scope, input.channel, input.contractId)).state;
|
|
45
71
|
if (state === null)
|
|
46
72
|
throw new Error(`contract does not exist: ${input.contractId}`);
|
|
47
73
|
return state;
|
|
48
74
|
}
|
|
49
|
-
export function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (state === null || state.delivery === null)
|
|
53
|
-
return null;
|
|
54
|
-
return {
|
|
55
|
-
snapshotId: state.delivery.data.candidate,
|
|
56
|
-
changeId: state.delivery.data.deliveryPatchId,
|
|
57
|
-
expectedPredecessor: state.delivery.data.expectedPredecessor,
|
|
58
|
-
};
|
|
75
|
+
export async function deliveryOperation(input) {
|
|
76
|
+
const state = (await observeContractAt(input.scope, input.channel, input.contractId)).state;
|
|
77
|
+
return state?.delivery?.data ?? null;
|
|
59
78
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
export async function deliveryDiffOperation(input) { return readDeliveryDiff(input.scope, input.integrationPredecessor, input.integrationSnapshot); }
|
|
80
|
+
export async function amendOperation(input) {
|
|
81
|
+
const attempts = mintAttempts({ entryCount: 1 });
|
|
82
|
+
let source = input.source;
|
|
83
|
+
for (let index = 0; index < attempts.length; index += 1) {
|
|
84
|
+
let observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
85
|
+
const state = contractState(observation.decision, input.contractId);
|
|
86
|
+
if (source === undefined && state !== null)
|
|
87
|
+
source = state.terms;
|
|
88
|
+
const amendment = source === undefined || input.deriveAmendment === undefined
|
|
89
|
+
? undefined
|
|
90
|
+
: { source, ...input.deriveAmendment(source) };
|
|
91
|
+
if (amendment !== undefined) {
|
|
92
|
+
observation = await extendContractsForAdmissionAt(input.channel, observation, [...new Set([...(state?.terms.after ?? []), ...amendment.terms.after])]);
|
|
93
|
+
}
|
|
94
|
+
const preparation = amendment === undefined
|
|
95
|
+
? undefined
|
|
96
|
+
: amendment.verification.kind === "prepared"
|
|
97
|
+
? { kind: "prepared", data: amendment.terms }
|
|
98
|
+
: { kind: "refused", refusal: amendment.verification.refusal };
|
|
99
|
+
const decision = decideAmend({
|
|
100
|
+
input: {
|
|
101
|
+
contractId: input.contractId,
|
|
102
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
103
|
+
at: timestamp(),
|
|
104
|
+
...(amendment === undefined ? {} : { source: amendment.source }),
|
|
105
|
+
...(preparation === undefined ? {} : { preparation }),
|
|
106
|
+
},
|
|
107
|
+
attempt: attempts[index],
|
|
108
|
+
observation: observation.decision,
|
|
109
|
+
});
|
|
110
|
+
if (decision.kind === "refused")
|
|
111
|
+
return decision;
|
|
112
|
+
const admission = await admitDecidedOffer({
|
|
113
|
+
channel: input.channel,
|
|
114
|
+
repository: input.scope,
|
|
115
|
+
decisionObservation: observation,
|
|
116
|
+
attempt: attempts[index],
|
|
117
|
+
offer: decision.offer,
|
|
118
|
+
primaryContract: input.contractId,
|
|
119
|
+
});
|
|
120
|
+
if (admission.kind === "accepted") {
|
|
121
|
+
if (amendment === undefined)
|
|
122
|
+
throw new Error("accepted amendment is missing its document derivation");
|
|
123
|
+
return admitted(admission, amendment);
|
|
73
124
|
}
|
|
74
|
-
|
|
75
|
-
|
|
125
|
+
if (admission.kind === "publication-failed")
|
|
126
|
+
return { kind: "retry", reason: admission };
|
|
127
|
+
if (admission.kind === "collision" && index + 1 === attempts.length)
|
|
128
|
+
return { kind: "retry", reason: admission };
|
|
76
129
|
}
|
|
77
|
-
return
|
|
130
|
+
return { kind: "retry", reason: { kind: "exhausted" } };
|
|
78
131
|
}
|
|
79
|
-
export
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
132
|
+
export function prepareDelivery(repository, stage, input) {
|
|
133
|
+
const { contractId, coordinates } = stage;
|
|
134
|
+
if (coordinates.workspace === "here" && coordinates.target !== undefined) {
|
|
135
|
+
const branch = currentBranch(repository);
|
|
136
|
+
if (branch !== coordinates.target) {
|
|
137
|
+
return { kind: "refused", refusal: { kind: "workspace-not-on-target", contractId, target: coordinates.target, branch } };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const tender = captureTender(repository, stage);
|
|
141
|
+
if (tender.kind === "refused")
|
|
142
|
+
return tender;
|
|
143
|
+
if ((tender.data.dirty && input.includeDirty !== true) || tender.data.changes.submodules.length > 0) {
|
|
144
|
+
return { kind: "refused", refusal: dirtyTenderRefusal(repository, contractId, tender.data) };
|
|
145
|
+
}
|
|
146
|
+
const tenderSnapshot = materializeTenderSnapshot(repository, tender.data, {
|
|
147
|
+
contractId,
|
|
148
|
+
title: input.title,
|
|
149
|
+
...(input.message === undefined ? {} : { message: input.message }),
|
|
150
|
+
});
|
|
151
|
+
const requireBranchesToBeUpToDate = input.requireBranchesToBeUpToDate ?? false;
|
|
152
|
+
const integration = planIntegration(repository, stage, { ...tender.data, head: tenderSnapshot }, requireBranchesToBeUpToDate);
|
|
153
|
+
if (integration.kind === "refused")
|
|
154
|
+
return integration;
|
|
155
|
+
const integrationSnapshot = coordinates.target === undefined
|
|
156
|
+
? tenderSnapshot
|
|
157
|
+
: materializeIntegrationSnapshot(repository, integration.data.tree, integration.data.predecessor, {
|
|
158
|
+
contractId,
|
|
159
|
+
title: input.title,
|
|
160
|
+
...(input.message === undefined ? {} : { message: input.message }),
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
kind: "prepared",
|
|
164
|
+
data: {
|
|
165
|
+
tenderSnapshot,
|
|
166
|
+
integration: { predecessor: integration.data.predecessor, snapshot: integrationSnapshot, changeId: integration.data.changeId },
|
|
167
|
+
method: "squash",
|
|
168
|
+
policy: { requireBranchesToBeUpToDate },
|
|
169
|
+
},
|
|
93
170
|
};
|
|
94
|
-
return complete(admitIntent(input.scope, decisionInput, decideAmend, {
|
|
95
|
-
observedContracts: [input.contractId, ...(amendment?.terms.after ?? [])],
|
|
96
|
-
observe: observePrerequisiteClosure,
|
|
97
|
-
}), undefined);
|
|
98
171
|
}
|
|
99
|
-
function
|
|
100
|
-
const
|
|
172
|
+
export function prepareReview(repository, stage) {
|
|
173
|
+
const tender = captureTender(repository, stage);
|
|
174
|
+
if (tender.kind === "refused")
|
|
175
|
+
return tender;
|
|
176
|
+
if (tender.data.changes.submodules.length > 0) {
|
|
177
|
+
return { kind: "refused", refusal: dirtyTenderRefusal(repository, stage.contractId, tender.data) };
|
|
178
|
+
}
|
|
179
|
+
const workspace = dirtyTenderDelta(repository, tender.data);
|
|
180
|
+
return prepareReviewIntegration(repository, stage, tender.data, workspace);
|
|
181
|
+
}
|
|
182
|
+
async function deliverAttempt(input, attempt) {
|
|
183
|
+
let decisionObservation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
101
184
|
const state = contractState(decisionObservation.decision, input.contractId);
|
|
185
|
+
if (state !== null) {
|
|
186
|
+
decisionObservation = await extendContractsForAdmissionAt(input.channel, decisionObservation, state.terms.after);
|
|
187
|
+
}
|
|
188
|
+
const derivation = state === null || input.deriveDocument === undefined
|
|
189
|
+
? undefined
|
|
190
|
+
: input.deriveDocument(state);
|
|
102
191
|
let preparation;
|
|
103
|
-
if (state === null ||
|
|
192
|
+
if (state === null || derivation === undefined) {
|
|
104
193
|
preparation = { kind: "unavailable" };
|
|
105
194
|
}
|
|
106
|
-
else if (
|
|
195
|
+
else if (derivation.verification.kind === "refused") {
|
|
107
196
|
preparation = {
|
|
108
197
|
kind: "refused",
|
|
109
|
-
document:
|
|
110
|
-
refusal:
|
|
198
|
+
document: derivation.document,
|
|
199
|
+
refusal: derivation.verification.refusal,
|
|
111
200
|
};
|
|
112
201
|
}
|
|
113
202
|
else {
|
|
@@ -115,12 +204,14 @@ function deliverAttempt(input, attempt) {
|
|
|
115
204
|
contractId: state.id,
|
|
116
205
|
coordinates: state.coordinates,
|
|
117
206
|
}, {
|
|
118
|
-
title:
|
|
207
|
+
title: derivation.title,
|
|
119
208
|
...(input.message === undefined ? {} : { message: input.message }),
|
|
209
|
+
requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate,
|
|
210
|
+
includeDirty: input.includeDirty,
|
|
120
211
|
});
|
|
121
212
|
preparation = prepared.kind === "refused"
|
|
122
|
-
? { kind: "refused", document:
|
|
123
|
-
: { kind: "prepared", document:
|
|
213
|
+
? { kind: "refused", document: derivation.document, refusal: prepared.refusal }
|
|
214
|
+
: { kind: "prepared", document: derivation.document, data: prepared.data };
|
|
124
215
|
}
|
|
125
216
|
const decisionInput = {
|
|
126
217
|
contractId: input.contractId,
|
|
@@ -134,61 +225,64 @@ function deliverAttempt(input, attempt) {
|
|
|
134
225
|
if (preparation.kind !== "prepared") {
|
|
135
226
|
throw new Error("offered delivery is missing its mechanical preparation");
|
|
136
227
|
}
|
|
137
|
-
const admitted = admitDecidedOffer(
|
|
228
|
+
const admitted = await admitDecidedOffer({
|
|
229
|
+
channel: input.channel,
|
|
230
|
+
repository: input.scope,
|
|
231
|
+
decisionObservation,
|
|
232
|
+
attempt,
|
|
233
|
+
offer: decision.offer,
|
|
234
|
+
primaryContract: input.contractId,
|
|
235
|
+
});
|
|
138
236
|
if (admitted.kind === "accepted") {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
expectedPredecessor: preparation.data.expectedPredecessor,
|
|
143
|
-
} };
|
|
237
|
+
if (derivation === undefined)
|
|
238
|
+
throw new Error("accepted delivery is missing its document derivation");
|
|
239
|
+
return { ...admitted, value: { delivery: preparation.data, derivation } };
|
|
144
240
|
}
|
|
145
241
|
return admitted;
|
|
146
242
|
}
|
|
147
243
|
async function completeDelivery(input, first) {
|
|
148
|
-
|
|
149
|
-
throw new Error("accepted delivery is missing its document derivation");
|
|
150
|
-
}
|
|
151
|
-
const derivation = input.derivation;
|
|
244
|
+
const derivation = first.value.derivation;
|
|
152
245
|
if (derivation.verification.kind !== "prepared") {
|
|
153
246
|
throw new Error("accepted delivery is missing its Verification preparation");
|
|
154
247
|
}
|
|
155
248
|
let admission = first;
|
|
156
249
|
let verificationValue;
|
|
250
|
+
let cleanup;
|
|
157
251
|
let leak;
|
|
158
252
|
const verification = await verifyDelivery({
|
|
253
|
+
channel: input.channel,
|
|
159
254
|
repository: input.scope,
|
|
160
255
|
contractId: input.contractId,
|
|
161
256
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
162
257
|
at: timestamp(),
|
|
163
258
|
state: first.state,
|
|
164
259
|
environment: process.env,
|
|
165
|
-
|
|
260
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
166
261
|
...(derivation.verification.data === null
|
|
167
262
|
? {}
|
|
168
263
|
: { verification: derivation.verification.data }),
|
|
169
264
|
});
|
|
170
265
|
if (verification !== null) {
|
|
266
|
+
cleanup = verification.cleanup;
|
|
171
267
|
leak = verification.leak;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
verificationValue = stepStop(verification.step);
|
|
176
|
-
if (verification.step.kind === "accepted")
|
|
177
|
-
admission = mergeAdmissions(admission, verification.step);
|
|
268
|
+
verificationValue = verificationStop(verification.step);
|
|
269
|
+
if (!("failure" in verification.step) && verification.step.kind === "accepted") {
|
|
270
|
+
admission = mergeAdmissions(admission, verification.step);
|
|
178
271
|
}
|
|
179
272
|
}
|
|
180
|
-
const placement = admitPlacement(input.scope, {
|
|
273
|
+
const placement = await admitPlacement(input.channel, input.scope, first.state.coordinates.target, {
|
|
181
274
|
contractId: input.contractId,
|
|
182
275
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
183
276
|
at: timestamp(),
|
|
184
277
|
});
|
|
185
|
-
const placementValue =
|
|
278
|
+
const placementValue = placementStop(placement);
|
|
186
279
|
if (placement.kind === "accepted")
|
|
187
280
|
admission = mergeAdmissions(admission, placement);
|
|
188
281
|
return admitted(admission, {
|
|
189
|
-
...first.value,
|
|
282
|
+
...first.value.delivery,
|
|
190
283
|
...(verificationValue === undefined ? {} : { verification: verificationValue }),
|
|
191
284
|
...(placementValue === undefined ? {} : { placement: placementValue }),
|
|
285
|
+
...(cleanup === undefined ? {} : { cleanup }),
|
|
192
286
|
...(leak === undefined ? {} : { leak }),
|
|
193
287
|
});
|
|
194
288
|
}
|
|
@@ -196,7 +290,7 @@ export async function deliverOperation(input) {
|
|
|
196
290
|
const attempts = mintAttempts({ entryCount: 2 });
|
|
197
291
|
let first = null;
|
|
198
292
|
for (let index = 0; index < attempts.length; index += 1) {
|
|
199
|
-
const result = deliverAttempt(input, attempts[index]);
|
|
293
|
+
const result = await deliverAttempt(input, attempts[index]);
|
|
200
294
|
if (result.kind === "accepted") {
|
|
201
295
|
first = result;
|
|
202
296
|
break;
|
|
@@ -214,16 +308,19 @@ export async function deliverOperation(input) {
|
|
|
214
308
|
return { kind: "retry", reason: { kind: "exhausted" } };
|
|
215
309
|
return completeDelivery(input, first);
|
|
216
310
|
}
|
|
217
|
-
export function abandonOperation(input) {
|
|
218
|
-
return complete(admitIntent(input.scope, {
|
|
311
|
+
export async function abandonOperation(input) {
|
|
312
|
+
return complete(await admitIntent(input.channel, input.scope, {
|
|
219
313
|
contractId: input.contractId,
|
|
220
314
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
221
315
|
at: timestamp(),
|
|
222
316
|
...(input.note === undefined ? {} : { note: input.note }),
|
|
223
|
-
}, decideAbandon,
|
|
317
|
+
}, decideAbandon, {
|
|
318
|
+
...(input.decorateOffer === undefined ? {} : { decorateOffer: input.decorateOffer }),
|
|
319
|
+
...(input.observationSelection === undefined ? {} : { observationSelection: input.observationSelection }),
|
|
320
|
+
}), undefined);
|
|
224
321
|
}
|
|
225
|
-
export function arcOperation(input) {
|
|
226
|
-
return complete(admitIntent(input.scope, {
|
|
322
|
+
export async function arcOperation(input) {
|
|
323
|
+
return complete(await admitIntent(input.channel, input.scope, {
|
|
227
324
|
contractId: input.contractId,
|
|
228
325
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
229
326
|
at: timestamp(),
|
|
@@ -231,9 +328,13 @@ export function arcOperation(input) {
|
|
|
231
328
|
}, decideArc), undefined);
|
|
232
329
|
}
|
|
233
330
|
function reviewAttempt(input, attempt) {
|
|
234
|
-
|
|
331
|
+
return reviewAttemptObserved(input, attempt);
|
|
332
|
+
}
|
|
333
|
+
async function reviewAttemptObserved(input, attempt) {
|
|
334
|
+
const decisionObservation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
235
335
|
const state = contractState(decisionObservation.decision, input.contractId);
|
|
236
336
|
let preparation;
|
|
337
|
+
let workspace;
|
|
237
338
|
if (state !== null) {
|
|
238
339
|
const prepared = prepareReview(input.scope, { contractId: state.id, coordinates: state.coordinates });
|
|
239
340
|
preparation = prepared.kind === "refused"
|
|
@@ -244,12 +345,14 @@ function reviewAttempt(input, attempt) {
|
|
|
244
345
|
gate: REVIEWED,
|
|
245
346
|
subject: dependencyKeySet([
|
|
246
347
|
{ kind: "document", value: state.terms.document.key },
|
|
247
|
-
{ kind: "change", value: prepared.data },
|
|
348
|
+
{ kind: "change", value: prepared.data.changeId },
|
|
248
349
|
]),
|
|
249
350
|
verdict: input.verdict,
|
|
250
351
|
...(input.summary === undefined ? {} : { summary: input.summary }),
|
|
251
352
|
},
|
|
252
353
|
};
|
|
354
|
+
if (prepared.kind === "prepared")
|
|
355
|
+
workspace = prepared.data.workspace;
|
|
253
356
|
}
|
|
254
357
|
const decisionInput = {
|
|
255
358
|
contractId: input.contractId,
|
|
@@ -260,17 +363,27 @@ function reviewAttempt(input, attempt) {
|
|
|
260
363
|
const decision = decideAttestation({ input: decisionInput, attempt, observation: decisionObservation.decision });
|
|
261
364
|
if (decision.kind === "refused")
|
|
262
365
|
return { kind: "refused", refusal: decision.refusal };
|
|
263
|
-
const admitted = admitDecidedOffer(
|
|
366
|
+
const admitted = await admitDecidedOffer({
|
|
367
|
+
channel: input.channel,
|
|
368
|
+
repository: input.scope,
|
|
369
|
+
decisionObservation,
|
|
370
|
+
attempt,
|
|
371
|
+
offer: decision.offer,
|
|
372
|
+
primaryContract: input.contractId,
|
|
373
|
+
});
|
|
264
374
|
if (admitted.kind === "accepted")
|
|
265
|
-
return {
|
|
375
|
+
return {
|
|
376
|
+
...admitted,
|
|
377
|
+
value: workspace === undefined ? {} : { workspace },
|
|
378
|
+
};
|
|
266
379
|
return admitted;
|
|
267
380
|
}
|
|
268
|
-
export function reviewOperation(input) {
|
|
381
|
+
export async function reviewOperation(input) {
|
|
269
382
|
const git = input.scope;
|
|
270
|
-
const attempts = mintAttempts({ entryCount:
|
|
383
|
+
const attempts = mintAttempts({ entryCount: 1 });
|
|
271
384
|
let review = null;
|
|
272
385
|
for (let index = 0; index < attempts.length; index += 1) {
|
|
273
|
-
const result = reviewAttempt(input, attempts[index]);
|
|
386
|
+
const result = await reviewAttempt(input, attempts[index]);
|
|
274
387
|
if (result.kind === "accepted" || result.kind === "refused") {
|
|
275
388
|
review = result;
|
|
276
389
|
break;
|
|
@@ -285,26 +398,23 @@ export function reviewOperation(input) {
|
|
|
285
398
|
if (review.kind !== "accepted")
|
|
286
399
|
return review;
|
|
287
400
|
if (input.verdict !== "satisfied")
|
|
288
|
-
return admitted(review,
|
|
289
|
-
const placement = admitPlacement(git, {
|
|
401
|
+
return admitted(review, review.value);
|
|
402
|
+
const placement = await admitPlacement(input.channel, git, review.state.coordinates.target, {
|
|
290
403
|
contractId: input.contractId,
|
|
291
404
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
292
405
|
at: timestamp(),
|
|
293
406
|
});
|
|
294
|
-
const
|
|
407
|
+
const stopped = placementStop(placement);
|
|
295
408
|
const admission = placement.kind === "accepted" ? mergeAdmissions(review, placement) : review;
|
|
296
|
-
return admitted(admission,
|
|
409
|
+
return admitted(admission, { ...review.value, ...(stopped === undefined ? {} : { placement: stopped }) });
|
|
297
410
|
}
|
|
298
411
|
export async function auditOperation(input) {
|
|
299
412
|
const git = input.scope;
|
|
300
|
-
const initial =
|
|
413
|
+
const initial = await readAuditAt(git, input.channel, input.contractId, REVIEWED);
|
|
301
414
|
if (initial.state === null)
|
|
302
415
|
return { kind: "refused", refusal: { kind: "contract-missing", contractId: input.contractId } };
|
|
303
|
-
const derivation = input.
|
|
304
|
-
if (derivation === undefined) {
|
|
305
|
-
return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
|
|
306
|
-
}
|
|
307
|
-
if (!documentIsCurrent(initial.state, derivation.document)) {
|
|
416
|
+
const derivation = input.deriveDocument?.(initial.state);
|
|
417
|
+
if (derivation === undefined || !documentIsCurrent(initial.state, derivation.document)) {
|
|
308
418
|
return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
|
|
309
419
|
}
|
|
310
420
|
if (derivation.verification.kind === "refused") {
|
|
@@ -314,31 +424,27 @@ export async function auditOperation(input) {
|
|
|
314
424
|
return accepted(initial.state, [], initial.report);
|
|
315
425
|
}
|
|
316
426
|
const verification = await verifyDelivery({
|
|
427
|
+
channel: input.channel,
|
|
317
428
|
repository: git,
|
|
318
429
|
contractId: input.contractId,
|
|
319
430
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
320
431
|
at: timestamp(),
|
|
321
432
|
state: initial.state,
|
|
322
433
|
environment: process.env,
|
|
323
|
-
|
|
434
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
324
435
|
verification: derivation.verification.data,
|
|
325
436
|
});
|
|
326
437
|
if (verification === null) {
|
|
327
438
|
throw new Error("audit verification preparation unexpectedly produced no attempt");
|
|
328
439
|
}
|
|
329
|
-
const attempt =
|
|
330
|
-
? verification.step
|
|
331
|
-
: verification.step.kind === "accepted"
|
|
332
|
-
? undefined
|
|
333
|
-
: verification.step.kind === "refused"
|
|
334
|
-
? { refusal: verification.step.refusal }
|
|
335
|
-
: { retry: verification.step };
|
|
440
|
+
const attempt = verificationStop(verification.step);
|
|
336
441
|
const report = !("failure" in verification.step) && verification.step.kind === "accepted"
|
|
337
|
-
? auditReport(verification.step.journal, REVIEWED)
|
|
442
|
+
? auditReport(verification.step.journal, REVIEWED, initial.state, initial.report.targetObservation)
|
|
338
443
|
: initial.report;
|
|
339
444
|
const value = {
|
|
340
445
|
...report,
|
|
341
446
|
...(attempt === undefined ? {} : { attempt }),
|
|
447
|
+
...(verification.cleanup === undefined ? {} : { cleanup: verification.cleanup }),
|
|
342
448
|
...(verification.leak === undefined ? {} : { leak: verification.leak }),
|
|
343
449
|
};
|
|
344
450
|
return !("failure" in verification.step) && verification.step.kind === "accepted"
|
|
@@ -349,9 +455,11 @@ export async function reconcileOperation(input) {
|
|
|
349
455
|
try {
|
|
350
456
|
const observation = await reconcile({
|
|
351
457
|
repository: input.scope,
|
|
458
|
+
channel: input.channel,
|
|
352
459
|
contractId: input.contractId,
|
|
353
460
|
hooks: input.hooks,
|
|
354
461
|
retryHooks: input.retryHooks,
|
|
462
|
+
...(input.retainTerminalWorktree === undefined ? {} : { retainTerminalWorktree: input.retainTerminalWorktree }),
|
|
355
463
|
});
|
|
356
464
|
return { state: observation.state, report: observation.result };
|
|
357
465
|
}
|
|
@@ -363,8 +471,12 @@ export async function reconcileOperation(input) {
|
|
|
363
471
|
}
|
|
364
472
|
export async function reconcileAllOperation(input) {
|
|
365
473
|
const git = input.scope;
|
|
366
|
-
const observation =
|
|
367
|
-
const contracts = (await reconcileBatch(git, observation.contracts.keys(),
|
|
474
|
+
const observation = await withGitReadObservation(input.scope, input.channel, (read) => observeContractWorld(read));
|
|
475
|
+
const contracts = (await reconcileBatch(git, input.channel, observation.contracts.keys(), {
|
|
476
|
+
hooks: input.hooks,
|
|
477
|
+
retryHooks: input.retryHooks,
|
|
478
|
+
retainTerminalWorktree: input.retainTerminalWorktree ?? false,
|
|
479
|
+
})).map((item) => ({
|
|
368
480
|
contractId: item.contract,
|
|
369
481
|
state: item.state,
|
|
370
482
|
report: item.result,
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { ContractHead, ContractState, JournalEntry } from "../core/facts/types.js";
|
|
2
2
|
import type { AcceptedAdmission } from "./attempt.js";
|
|
3
3
|
import type { ProtocolResult, ProtocolTerminal } from "./run.js";
|
|
4
|
+
import type { ReconcileResult } from "../git/reconcile.js";
|
|
5
|
+
export type AcceptedProtocolStep = AcceptedAdmission & Readonly<{
|
|
6
|
+
physical?: ReconcileResult;
|
|
7
|
+
}>;
|
|
4
8
|
export type IntentOutcome<Value, Refusal = never> = Readonly<{
|
|
5
9
|
kind: "accepted";
|
|
6
10
|
facts: readonly JournalEntry[];
|
|
7
11
|
head: ContractHead;
|
|
8
12
|
value: Value;
|
|
13
|
+
physical?: ReconcileResult;
|
|
9
14
|
}> | Readonly<{
|
|
10
15
|
kind: "refused";
|
|
11
16
|
refusal: Refusal;
|
|
@@ -13,6 +18,6 @@ export type IntentOutcome<Value, Refusal = never> = Readonly<{
|
|
|
13
18
|
kind: "retry";
|
|
14
19
|
reason: ProtocolTerminal;
|
|
15
20
|
}>;
|
|
16
|
-
export declare function accepted<Value, Refusal = never>(state: ContractState, facts: readonly JournalEntry[], value: Value): IntentOutcome<Value, Refusal>;
|
|
17
|
-
export declare function admitted<Value, Refusal = never>(admission:
|
|
21
|
+
export declare function accepted<Value, Refusal = never>(state: ContractState, facts: readonly JournalEntry[], value: Value, physical?: ReconcileResult): IntentOutcome<Value, Refusal>;
|
|
22
|
+
export declare function admitted<Value, Refusal = never>(admission: AcceptedProtocolStep, value: Value): IntentOutcome<Value, Refusal>;
|
|
18
23
|
export declare function complete<Value, Refusal>(result: ProtocolResult<Refusal>, value: Value): IntentOutcome<Value, Refusal>;
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
export function accepted(state, facts, value) {
|
|
1
|
+
export function accepted(state, facts, value, physical) {
|
|
2
2
|
if (state.head === null)
|
|
3
3
|
throw new Error("accepted contract is missing its journal head");
|
|
4
|
-
return {
|
|
4
|
+
return {
|
|
5
|
+
kind: "accepted",
|
|
6
|
+
facts,
|
|
7
|
+
head: state.head,
|
|
8
|
+
value,
|
|
9
|
+
...(physical === undefined ? {} : { physical }),
|
|
10
|
+
};
|
|
5
11
|
}
|
|
6
12
|
export function admitted(admission, value) {
|
|
7
|
-
return accepted(admission.state, admission.facts, value);
|
|
13
|
+
return accepted(admission.state, admission.facts, value, admission.physical);
|
|
8
14
|
}
|
|
9
15
|
export function complete(result, value) {
|
|
10
16
|
if (result.kind === "refused")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ActorId, ContractId, SnapshotId } from "../core/facts/types.js";
|
|
2
|
+
import { type PlacementRefusal } from "../core/verbs/placement.js";
|
|
3
|
+
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
4
|
+
import { type ReconcileResult } from "../git/reconcile.js";
|
|
5
|
+
import { type GitRepository } from "../git/repository.js";
|
|
6
|
+
import { type TargetPlacementRefusal } from "../git/target-placement.js";
|
|
7
|
+
import { type AcceptedAdmission } from "./attempt.js";
|
|
8
|
+
import { type ProtocolResult } from "./run.js";
|
|
9
|
+
export type PlacementExecutionFailure = Readonly<{
|
|
10
|
+
kind: "placement-failed";
|
|
11
|
+
diagnostic: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type TargetMovedStop = Readonly<{
|
|
14
|
+
kind: "target-moved";
|
|
15
|
+
contractId: ContractId;
|
|
16
|
+
target: string;
|
|
17
|
+
expected: SnapshotId;
|
|
18
|
+
observed: SnapshotId | null;
|
|
19
|
+
}>;
|
|
20
|
+
export type PlacementProtocolResult = (AcceptedAdmission & Readonly<{
|
|
21
|
+
physical?: ReconcileResult;
|
|
22
|
+
}>) | Exclude<ProtocolResult<PlacementRefusal | TargetPlacementRefusal>, AcceptedAdmission> | TargetMovedStop | PlacementExecutionFailure;
|
|
23
|
+
type PlacementProtocolInput = Readonly<{
|
|
24
|
+
contractId: ContractId;
|
|
25
|
+
actor?: ActorId;
|
|
26
|
+
at: string;
|
|
27
|
+
}>;
|
|
28
|
+
/** Run the sole placement adjudicator inside the target's physical fence. */
|
|
29
|
+
export declare function admitPlacement(channel: GitDecodeChannel, repository: GitRepository, target: string | undefined, input: PlacementProtocolInput): Promise<PlacementProtocolResult>;
|
|
30
|
+
export {};
|