@astrosheep/keiyaku 4.0.4 → 4.0.6
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 +15 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
- package/build/src/akuma/akuma.d.ts +2 -1
- package/build/src/akuma/akuma.js +27 -9
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +3 -10
- package/build/src/akuma/archetype.d.ts +3 -1
- package/build/src/akuma/archetype.js +11 -6
- package/build/src/akuma/body-turn.d.ts +64 -0
- package/build/src/akuma/body-turn.js +449 -0
- package/build/src/akuma/body.d.ts +4 -5
- package/build/src/akuma/body.js +9 -414
- package/build/src/akuma/heart/facts.d.ts +37 -9
- package/build/src/akuma/heart/facts.js +3 -1
- package/build/src/akuma/heart/index.d.ts +4 -13
- package/build/src/akuma/heart/index.js +14 -135
- 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 -28
- package/build/src/akuma/heart/rows.js +4 -138
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +11 -3
- package/build/src/akuma/heart/soul.js +0 -36
- package/build/src/akuma/heart/timeline.d.ts +1 -0
- package/build/src/akuma/heart/timeline.js +19 -0
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/nuke.d.ts +2 -0
- package/build/src/akuma/nuke.js +152 -0
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +4 -7
- package/build/src/akuma/providers/acp/config.d.ts +8 -0
- package/build/src/akuma/providers/acp/config.js +37 -0
- package/build/src/akuma/providers/acp/core.js +12 -2
- package/build/src/akuma/providers/acp/index.d.ts +1 -8
- package/build/src/akuma/providers/acp/index.js +2 -38
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +12 -3
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +5 -2
- package/build/src/akuma/providers/grok-build/index.js +1 -2
- package/build/src/akuma/providers/index.d.ts +3 -2
- package/build/src/akuma/providers/index.js +36 -36
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +29 -6
- package/build/src/akuma/request-serve.d.ts +88 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +125 -0
- package/build/src/akuma/request-wire.js +383 -0
- package/build/src/akuma/requests.d.ts +28 -94
- package/build/src/akuma/requests.js +52 -562
- package/build/src/akuma-body.d.ts +7 -0
- package/build/src/akuma-body.js +69 -2
- package/build/src/alias/index.d.ts +1 -0
- package/build/src/alias/index.js +34 -1
- 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.js +21 -9
- package/build/src/cli/commands/akuma-invoke.js +1 -0
- package/build/src/cli/commands/akuma.d.ts +1 -0
- package/build/src/cli/commands/akuma.js +13 -10
- package/build/src/cli/commands/contract.d.ts +28 -17
- package/build/src/cli/commands/contract.js +23 -17
- package/build/src/cli/commands/install.d.ts +2 -2
- package/build/src/cli/commands/install.js +6 -6
- package/build/src/cli/commands/nuke.d.ts +10 -0
- package/build/src/cli/commands/nuke.js +20 -0
- package/build/src/cli/commands/task-invoke.d.ts +15 -0
- package/build/src/cli/commands/task-invoke.js +144 -24
- package/build/src/cli/commands/task-query.d.ts +2 -2
- package/build/src/cli/commands/task-query.js +1 -2
- package/build/src/cli/commands/task.js +22 -22
- package/build/src/cli/coordinates.d.ts +6 -2
- package/build/src/cli/coordinates.js +12 -56
- package/build/src/cli/invoke.d.ts +5 -4
- package/build/src/cli/invoke.js +112 -58
- package/build/src/cli/main.d.ts +0 -2
- package/build/src/cli/main.js +4 -140
- package/build/src/cli/parse.d.ts +17 -4
- package/build/src/cli/parse.js +93 -15
- package/build/src/cli/render/akuma.js +111 -53
- package/build/src/cli/render/audit.js +2 -6
- package/build/src/cli/render/contract.js +61 -20
- package/build/src/cli/render/kanshi.js +15 -5
- package/build/src/cli/render/nuke.d.ts +3 -0
- package/build/src/cli/render/nuke.js +8 -0
- package/build/src/cli/render/receipt.js +28 -1
- package/build/src/cli/render/refusal.d.ts +2 -1
- package/build/src/cli/render/refusal.js +31 -0
- 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 +6 -1
- package/build/src/cli/result.d.ts +36 -9
- package/build/src/cli/runtime.d.ts +2 -0
- package/build/src/cli/runtime.js +140 -0
- package/build/src/cli/usage.d.ts +0 -2
- package/build/src/cli/usage.js +0 -4
- package/build/src/contract-worktree.d.ts +29 -14
- package/build/src/contract-worktree.js +131 -70
- 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/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +2 -0
- package/build/src/git/hooks.js +34 -1
- package/build/src/git/integration.d.ts +9 -2
- package/build/src/git/integration.js +92 -1
- package/build/src/git/nuke.d.ts +2 -0
- package/build/src/git/nuke.js +97 -0
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +28 -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 +4 -1
- package/build/src/git/reconcile.js +42 -8
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +7 -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 +3 -2
- package/build/src/git/target-placement.js +15 -14
- package/build/src/git/tender.d.ts +2 -1
- package/build/src/git/tender.js +4 -3
- package/build/src/git/terminal-seal.d.ts +2 -2
- package/build/src/git/terminal-seal.js +3 -6
- package/build/src/git/workspace.d.ts +4 -1
- package/build/src/git/workspace.js +1 -1
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/read.js +5 -1
- package/build/src/library/address.js +7 -1
- package/build/src/library/akuma-creation.d.ts +1 -0
- package/build/src/library/akuma-creation.js +8 -1
- package/build/src/library/audit.d.ts +3 -1
- package/build/src/library/audit.js +2 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +1 -1
- package/build/src/library/configuration.d.ts +1 -1
- package/build/src/library/configuration.js +52 -18
- package/build/src/library/contract.d.ts +59 -4
- package/build/src/library/contract.js +195 -34
- package/build/src/library/delivery.d.ts +4 -2
- package/build/src/library/fleet.d.ts +27 -7
- package/build/src/library/fleet.js +79 -39
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +0 -5
- package/build/src/library/keiyaku.d.ts +6 -2
- package/build/src/library/keiyaku.js +2 -0
- package/build/src/library/mutation.d.ts +3 -1
- package/build/src/library/mutation.js +3 -0
- package/build/src/library/nuke.d.ts +14 -0
- package/build/src/library/nuke.js +54 -0
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +8 -3
- package/build/src/library/refusal.d.ts +10 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +4 -1
- package/build/src/library/repo.js +10 -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 +147 -0
- package/build/src/protocol/bind.d.ts +1 -1
- package/build/src/protocol/completion.d.ts +42 -0
- package/build/src/protocol/completion.js +183 -0
- package/build/src/protocol/deliver.d.ts +49 -0
- package/build/src/protocol/deliver.js +261 -0
- package/build/src/protocol/intent.d.ts +2 -1
- package/build/src/protocol/intent.js +8 -2
- package/build/src/protocol/operations.d.ts +93 -202
- package/build/src/protocol/operations.js +23 -642
- package/build/src/protocol/placement.d.ts +12 -13
- package/build/src/protocol/placement.js +8 -19
- package/build/src/protocol/read/status.d.ts +17 -5
- package/build/src/protocol/read/status.js +57 -13
- 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 +34 -0
- package/build/src/protocol/review.js +156 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.js +9 -5
- package/build/src/settlement/fence.d.ts +3 -1
- package/build/src/settlement/fence.js +24 -0
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +1 -2
- package/build/src/task/board.d.ts +0 -1
- package/build/src/task/board.js +0 -3
- package/build/src/task/compose.d.ts +2 -2
- package/build/src/task/compose.js +13 -11
- package/build/src/task/context.d.ts +14 -2
- package/build/src/task/context.js +30 -7
- package/build/src/task/index.d.ts +7 -6
- package/build/src/task/index.js +17 -145
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +44 -0
- package/build/src/task/mutation.js +93 -0
- package/build/src/task/operations.d.ts +14 -6
- package/build/src/task/operations.js +57 -57
- package/build/src/task/store.d.ts +1 -0
- package/build/src/task/store.js +91 -3
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/workspace-place.d.ts +3 -4
- package/build/src/workspace-place.js +26 -15
- package/package.json +3 -3
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ArcData } from "../core/facts/types.js";
|
|
2
|
+
import { type ArcRefusal } from "../core/verbs/arc.js";
|
|
3
|
+
import type { IntentOutcome, MutationOperationInput } from "./operations.js";
|
|
4
|
+
export declare function arcOperation(input: MutationOperationInput & Readonly<{
|
|
5
|
+
chapter: Omit<ArcData, "seq">;
|
|
6
|
+
}>): Promise<IntentOutcome<void, ArcRefusal>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { decideArc } from "../core/verbs/arc.js";
|
|
2
|
+
import { admitIntent } from "./intent.js";
|
|
3
|
+
import { complete } from "./outcome.js";
|
|
4
|
+
import { timestamp } from "./operations.js";
|
|
5
|
+
export async function arcOperation(input) {
|
|
6
|
+
return complete(await admitIntent(input.channel, input.scope, {
|
|
7
|
+
contractId: input.contractId,
|
|
8
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
9
|
+
at: timestamp(),
|
|
10
|
+
data: input.chapter,
|
|
11
|
+
}, decideArc), undefined);
|
|
12
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type PublicationFailed } from "../git/admission.js";
|
|
2
2
|
import { type GitDecisionObservation } from "../git/observe.js";
|
|
3
3
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
4
|
-
import { type GitRefAssertion
|
|
4
|
+
import { type GitRefAssertion } from "../git/repository.js";
|
|
5
|
+
import type { GitRepository } from "../git/process.js";
|
|
5
6
|
import type { AttemptContext } from "../core/decide.js";
|
|
6
7
|
import type { Offer } from "../core/facts/offer.js";
|
|
7
8
|
import { type ContractId, type ContractState, type EntryUlid, type JournalEntry } from "../core/facts/types.js";
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type DeliveryDiffScope } from "../git/integration.js";
|
|
2
|
+
import type { ChangeId, ContractState, DeliverData } from "../core/facts/types.js";
|
|
3
|
+
import { type AuditTargetAnswer } from "../git/target-placement.js";
|
|
4
|
+
import type { DeliveryPreparationRefusal, DocumentDerivation, IntentOutcome, MutationOperationInput, VerificationStop } from "./operations.js";
|
|
5
|
+
type AuditWorkspace = Readonly<{
|
|
6
|
+
kind: "worktree" | "here";
|
|
7
|
+
path: string;
|
|
8
|
+
}>;
|
|
9
|
+
type DiffScope = DeliveryDiffScope;
|
|
10
|
+
export type AuditReport = Readonly<{
|
|
11
|
+
candidate: Readonly<{
|
|
12
|
+
kind: "blocked";
|
|
13
|
+
refusal: DeliveryPreparationRefusal;
|
|
14
|
+
}> | Readonly<{
|
|
15
|
+
kind: "ready";
|
|
16
|
+
workspace: AuditWorkspace;
|
|
17
|
+
identity: DeliverData;
|
|
18
|
+
scope: DiffScope;
|
|
19
|
+
diff?: string;
|
|
20
|
+
}>;
|
|
21
|
+
verification: Readonly<{
|
|
22
|
+
kind: "not-run";
|
|
23
|
+
}> | Readonly<{
|
|
24
|
+
kind: "satisfied";
|
|
25
|
+
passed: number;
|
|
26
|
+
total: number;
|
|
27
|
+
summary?: string;
|
|
28
|
+
}> | Readonly<{
|
|
29
|
+
kind: "unsatisfied";
|
|
30
|
+
passed: number;
|
|
31
|
+
total: number;
|
|
32
|
+
summary?: string;
|
|
33
|
+
}> | Readonly<{
|
|
34
|
+
kind: "stopped";
|
|
35
|
+
stop: VerificationStop;
|
|
36
|
+
}>;
|
|
37
|
+
target: Readonly<{
|
|
38
|
+
kind: "not-observed";
|
|
39
|
+
}> | AuditTargetAnswer;
|
|
40
|
+
delivery?: Readonly<{
|
|
41
|
+
changeId: ChangeId;
|
|
42
|
+
relation: "identical" | "differs";
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
type AuditOperationInput = MutationOperationInput & Readonly<{
|
|
46
|
+
deriveDocument?: (state: ContractState) => DocumentDerivation;
|
|
47
|
+
requireBranchesToBeUpToDate?: boolean;
|
|
48
|
+
includeDirty?: boolean;
|
|
49
|
+
showDiff?: boolean;
|
|
50
|
+
signal?: AbortSignal;
|
|
51
|
+
}>;
|
|
52
|
+
export declare function auditOperation(input: AuditOperationInput): Promise<IntentOutcome<AuditReport>>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { readDeliveryDiff, readDeliveryScope } from "../git/integration.js";
|
|
2
|
+
import { observeContractsForAdmissionAt } from "../git/observe.js";
|
|
3
|
+
import { activeContract, documentIsCurrent } from "../core/facts/observation.js";
|
|
4
|
+
import { adjudicateAuditTarget } from "../git/target-placement.js";
|
|
5
|
+
import { readManagedWorktreeAppointment } from "../workspace-place.js";
|
|
6
|
+
import { verifyDelivery } from "./intent.js";
|
|
7
|
+
import { accepted, admitted } from "./outcome.js";
|
|
8
|
+
import { prepareDelivery } from "./deliver.js";
|
|
9
|
+
import { timestamp, unpackVerificationOutcome } from "./operations.js";
|
|
10
|
+
async function auditWorkspace(repository, state, resolveHereWorkspace) {
|
|
11
|
+
if (state.coordinates.workspace === "here") {
|
|
12
|
+
const path = resolveHereWorkspace === undefined
|
|
13
|
+
? repository.effectiveCwd
|
|
14
|
+
: await resolveHereWorkspace(state.id);
|
|
15
|
+
return path === undefined
|
|
16
|
+
? { kind: "unappointed" }
|
|
17
|
+
: { kind: "ready", answer: { kind: "here", path } };
|
|
18
|
+
}
|
|
19
|
+
const appointed = await readManagedWorktreeAppointment(repository, state.id);
|
|
20
|
+
if (appointed.kind === "failed")
|
|
21
|
+
throw new Error(appointed.diagnostic);
|
|
22
|
+
if (appointed.kind === "unappointed")
|
|
23
|
+
return appointed;
|
|
24
|
+
return { kind: "ready", answer: { kind: "worktree", path: appointed.path }, appointment: appointed };
|
|
25
|
+
}
|
|
26
|
+
function auditDeliveryRelation(state, candidate) {
|
|
27
|
+
const recorded = state.delivery?.data.integration.changeId;
|
|
28
|
+
if (recorded === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
return { changeId: recorded, relation: recorded === candidate.integration.changeId ? "identical" : "differs" };
|
|
31
|
+
}
|
|
32
|
+
async function auditCandidateVerification(input, state, snapshot, definition) {
|
|
33
|
+
const verification = await verifyDelivery({
|
|
34
|
+
channel: input.channel,
|
|
35
|
+
repository: input.scope,
|
|
36
|
+
contractId: input.contractId,
|
|
37
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
38
|
+
at: timestamp(),
|
|
39
|
+
state,
|
|
40
|
+
snapshot,
|
|
41
|
+
environment: process.env,
|
|
42
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
43
|
+
verification: definition,
|
|
44
|
+
});
|
|
45
|
+
if (verification === null)
|
|
46
|
+
throw new Error("audit verification preparation unexpectedly produced no attempt");
|
|
47
|
+
return unpackVerificationOutcome(verification);
|
|
48
|
+
}
|
|
49
|
+
function auditVerificationAnswer(verified) {
|
|
50
|
+
if (verified === undefined)
|
|
51
|
+
return { kind: "not-run" };
|
|
52
|
+
if (verified.stop !== undefined)
|
|
53
|
+
return { kind: "stopped", stop: verified.stop };
|
|
54
|
+
if (verified.counts === undefined)
|
|
55
|
+
throw new Error("terminal Verification is missing producer counts");
|
|
56
|
+
return {
|
|
57
|
+
kind: verified.counts.verdict,
|
|
58
|
+
passed: verified.counts.passed,
|
|
59
|
+
total: verified.counts.total,
|
|
60
|
+
...(verified.counts.summary === undefined ? {} : { summary: verified.counts.summary }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function readyAuditCandidate(repository, candidate, workspace, showDiff) {
|
|
64
|
+
const predecessor = candidate.integration.predecessor;
|
|
65
|
+
const snapshot = candidate.integration.snapshot;
|
|
66
|
+
const scope = await readDeliveryScope(repository, predecessor, snapshot, showDiff);
|
|
67
|
+
const diff = showDiff ? await readDeliveryDiff(repository, predecessor, snapshot) : undefined;
|
|
68
|
+
return {
|
|
69
|
+
kind: "ready",
|
|
70
|
+
workspace,
|
|
71
|
+
identity: candidate,
|
|
72
|
+
scope,
|
|
73
|
+
...(diff === undefined || diff === null ? {} : { diff }),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function auditTargetAnswer(repository, state, candidate, workspacePath) {
|
|
77
|
+
const target = state.coordinates.target;
|
|
78
|
+
if (target === undefined)
|
|
79
|
+
return { kind: "not-observed" };
|
|
80
|
+
return await adjudicateAuditTarget(repository, {
|
|
81
|
+
contractId: state.id,
|
|
82
|
+
coordinates: { ...state.coordinates, target },
|
|
83
|
+
predecessor: candidate.integration.predecessor,
|
|
84
|
+
candidate: candidate.integration.snapshot,
|
|
85
|
+
...(workspacePath === undefined ? {} : { hereWorkspacePath: workspacePath }),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function blockedAudit(refusal) {
|
|
89
|
+
return {
|
|
90
|
+
candidate: { kind: "blocked", refusal },
|
|
91
|
+
verification: { kind: "not-run" },
|
|
92
|
+
target: { kind: "not-observed" },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function completedAudit(state, verified, value) {
|
|
96
|
+
const obligations = {
|
|
97
|
+
...(verified?.cleanup === undefined ? {} : { cleanup: verified.cleanup }),
|
|
98
|
+
...(verified?.leak === undefined ? {} : { leak: verified.leak }),
|
|
99
|
+
};
|
|
100
|
+
return verified?.admission === undefined
|
|
101
|
+
? accepted(state, [], value, undefined, obligations)
|
|
102
|
+
: { ...admitted(verified.admission, value), ...obligations };
|
|
103
|
+
}
|
|
104
|
+
export async function auditOperation(input) {
|
|
105
|
+
const observed = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
106
|
+
const state = activeContract(observed.decision, input.contractId);
|
|
107
|
+
if ("kind" in state)
|
|
108
|
+
return { kind: "refused", refusal: state };
|
|
109
|
+
const derivation = input.deriveDocument?.(state);
|
|
110
|
+
if (derivation === undefined || !documentIsCurrent(state, derivation.document)) {
|
|
111
|
+
return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
|
|
112
|
+
}
|
|
113
|
+
if (derivation.verification.kind === "refused")
|
|
114
|
+
return { kind: "refused", refusal: derivation.verification.refusal };
|
|
115
|
+
const workspace = await auditWorkspace(input.scope, state, input.resolveHereWorkspace);
|
|
116
|
+
if (workspace.kind === "unappointed") {
|
|
117
|
+
return accepted(state, [], blockedAudit({ kind: "worktree-missing", contractId: state.id }));
|
|
118
|
+
}
|
|
119
|
+
const prepared = await prepareDelivery(input.scope, {
|
|
120
|
+
contractId: state.id,
|
|
121
|
+
coordinates: state.coordinates,
|
|
122
|
+
...(workspace.appointment === undefined ? {} : { appointment: workspace.appointment }),
|
|
123
|
+
...(workspace.answer.kind === "here" ? { workspacePath: workspace.answer.path } : {}),
|
|
124
|
+
}, {
|
|
125
|
+
title: derivation.title,
|
|
126
|
+
document: derivation.bytes,
|
|
127
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
128
|
+
requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate ?? false,
|
|
129
|
+
includeDirty: input.includeDirty ?? false,
|
|
130
|
+
});
|
|
131
|
+
if (prepared.kind === "refused")
|
|
132
|
+
return accepted(state, [], blockedAudit(prepared.refusal));
|
|
133
|
+
const verified = derivation.verification.data === null
|
|
134
|
+
? undefined
|
|
135
|
+
: await auditCandidateVerification(input, state, prepared.data.integration.snapshot, derivation.verification.data);
|
|
136
|
+
const verification = auditVerificationAnswer(verified);
|
|
137
|
+
const delivery = auditDeliveryRelation(state, prepared.data);
|
|
138
|
+
const value = {
|
|
139
|
+
candidate: await readyAuditCandidate(input.scope, prepared.data, workspace.answer, input.showDiff === true),
|
|
140
|
+
verification,
|
|
141
|
+
target: verification.kind === "stopped"
|
|
142
|
+
? { kind: "not-observed" }
|
|
143
|
+
: await auditTargetAnswer(input.scope, state, prepared.data, workspace.answer.kind === "here" ? workspace.answer.path : undefined),
|
|
144
|
+
...(delivery === undefined ? {} : { delivery }),
|
|
145
|
+
};
|
|
146
|
+
return completedAudit(state, verified, value);
|
|
147
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GitRepository } from "../git/
|
|
1
|
+
import type { GitRepository } from "../git/process.js";
|
|
2
2
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
3
|
import type { BindData, ActorId, ContractId } from "../core/facts/types.js";
|
|
4
4
|
import { type BindRefusal } from "../core/verbs/bind.js";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ActorId, ContractId, SnapshotId } from "../core/facts/types.js";
|
|
2
|
+
import type { WorktreeLeak } from "../git/scratch.js";
|
|
3
|
+
import type { GitRepository } from "../git/process.js";
|
|
4
|
+
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
5
|
+
import type { VerificationDeclarationPreparation } from "../verification/declaration.js";
|
|
6
|
+
import { type CurrentVerifiedAttestation, type VerificationCleanupFailure } from "./intent.js";
|
|
7
|
+
import type { AcceptedProtocolStep } from "./outcome.js";
|
|
8
|
+
import type { PlacementStop, VerificationStop } from "./operations.js";
|
|
9
|
+
export type CandidateCompletion = Readonly<{
|
|
10
|
+
integration: SnapshotId;
|
|
11
|
+
verification?: Readonly<{
|
|
12
|
+
mode: "ran" | "reused";
|
|
13
|
+
verdict: "satisfied" | "unsatisfied";
|
|
14
|
+
}>;
|
|
15
|
+
}>;
|
|
16
|
+
export type CompletionEvidence = Readonly<{
|
|
17
|
+
completion?: CandidateCompletion;
|
|
18
|
+
verification?: VerificationStop;
|
|
19
|
+
verificationReuse?: CurrentVerifiedAttestation;
|
|
20
|
+
verificationSummary?: string;
|
|
21
|
+
placement?: PlacementStop;
|
|
22
|
+
cleanup?: VerificationCleanupFailure;
|
|
23
|
+
leak?: WorktreeLeak;
|
|
24
|
+
}>;
|
|
25
|
+
type CompletionInput = Readonly<{
|
|
26
|
+
channel: GitDecodeChannel;
|
|
27
|
+
repository: GitRepository;
|
|
28
|
+
contractId: ContractId;
|
|
29
|
+
target?: string;
|
|
30
|
+
actor?: ActorId;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
verification: VerificationDeclarationPreparation;
|
|
33
|
+
initial: AcceptedProtocolStep;
|
|
34
|
+
verifyInitial: boolean;
|
|
35
|
+
hereWorkspacePath?: string;
|
|
36
|
+
}>;
|
|
37
|
+
export type CompletionResult = Readonly<{
|
|
38
|
+
admission: AcceptedProtocolStep;
|
|
39
|
+
evidence: CompletionEvidence;
|
|
40
|
+
}>;
|
|
41
|
+
export declare function completeCandidate(input: CompletionInput): Promise<CompletionResult>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { currentVerifiedAttestation, verifyDelivery } from "./intent.js";
|
|
2
|
+
import { admitPlacement } from "./placement.js";
|
|
3
|
+
import { reintegrateOperation } from "./reintegrate.js";
|
|
4
|
+
import { mergeAdmissions, placementStop, timestamp, unpackVerificationOutcome } from "./operations.js";
|
|
5
|
+
const MAX_REINTEGRATION_CYCLES = 3;
|
|
6
|
+
function reintegrationStop(result) {
|
|
7
|
+
if (result.kind === "placement-failed") {
|
|
8
|
+
return { failure: "target-placement-failed", diagnostic: result.diagnostic };
|
|
9
|
+
}
|
|
10
|
+
if (result.kind === "refused")
|
|
11
|
+
return { refusal: result.refusal };
|
|
12
|
+
return { retry: result.reason };
|
|
13
|
+
}
|
|
14
|
+
async function verificationFor(input, admission, snapshot) {
|
|
15
|
+
const current = currentVerifiedAttestation(admission.state);
|
|
16
|
+
if (current !== undefined) {
|
|
17
|
+
return {
|
|
18
|
+
admission,
|
|
19
|
+
evidence: { verificationReuse: current },
|
|
20
|
+
completionVerification: {
|
|
21
|
+
mode: "reused",
|
|
22
|
+
verdict: current.verdict,
|
|
23
|
+
...(current.summary === undefined ? {} : { summary: current.summary }),
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (input.verification.kind === "refused") {
|
|
28
|
+
return { admission, evidence: { verification: { refusal: input.verification.refusal } } };
|
|
29
|
+
}
|
|
30
|
+
const result = await verifyDelivery({
|
|
31
|
+
channel: input.channel,
|
|
32
|
+
repository: input.repository,
|
|
33
|
+
contractId: input.contractId,
|
|
34
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
35
|
+
at: timestamp(),
|
|
36
|
+
state: admission.state,
|
|
37
|
+
snapshot,
|
|
38
|
+
environment: process.env,
|
|
39
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
40
|
+
...(input.verification.data === null ? {} : { verification: input.verification.data }),
|
|
41
|
+
});
|
|
42
|
+
if (result === null)
|
|
43
|
+
return { admission, evidence: {} };
|
|
44
|
+
const unpacked = unpackVerificationOutcome(result);
|
|
45
|
+
return {
|
|
46
|
+
admission: unpacked.admission === undefined ? admission : mergeAdmissions(admission, unpacked.admission),
|
|
47
|
+
evidence: {
|
|
48
|
+
...(unpacked.stop === undefined ? {} : { verification: unpacked.stop }),
|
|
49
|
+
...(unpacked.counts?.verdict !== "unsatisfied" || unpacked.counts.summary === undefined
|
|
50
|
+
? {}
|
|
51
|
+
: { verificationSummary: unpacked.counts.summary }),
|
|
52
|
+
...(unpacked.cleanup === undefined ? {} : { cleanup: unpacked.cleanup }),
|
|
53
|
+
...(unpacked.leak === undefined ? {} : { leak: unpacked.leak }),
|
|
54
|
+
},
|
|
55
|
+
...(unpacked.counts === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: {
|
|
58
|
+
completionVerification: {
|
|
59
|
+
mode: "ran",
|
|
60
|
+
verdict: unpacked.counts.verdict,
|
|
61
|
+
...(unpacked.counts.summary === undefined ? {} : { summary: unpacked.counts.summary }),
|
|
62
|
+
},
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function mergeEvidence(current, next) {
|
|
67
|
+
const merged = { ...current, ...next };
|
|
68
|
+
if (next.verification !== undefined) {
|
|
69
|
+
const { verificationReuse: _ignored, ...withoutReuse } = merged;
|
|
70
|
+
return withoutReuse;
|
|
71
|
+
}
|
|
72
|
+
if (next.verificationReuse !== undefined) {
|
|
73
|
+
const { verification: _ignored, ...withoutVerification } = merged;
|
|
74
|
+
return withoutVerification;
|
|
75
|
+
}
|
|
76
|
+
return merged;
|
|
77
|
+
}
|
|
78
|
+
function replaceVerificationEvidence(current, next) {
|
|
79
|
+
const { verification: _verification, verificationReuse: _verificationReuse, verificationSummary: _verificationSummary, ...withoutVerification } = current;
|
|
80
|
+
return mergeEvidence(withoutVerification, next);
|
|
81
|
+
}
|
|
82
|
+
function requiredPlacementStop(result) {
|
|
83
|
+
const stop = placementStop(result);
|
|
84
|
+
if (stop === undefined)
|
|
85
|
+
throw new Error("non-accepted placement is missing its stop");
|
|
86
|
+
return stop;
|
|
87
|
+
}
|
|
88
|
+
function acceptedCompletion(admission, completionVerification) {
|
|
89
|
+
const integration = admission.state.currentIntegration?.snapshot;
|
|
90
|
+
if (integration === undefined)
|
|
91
|
+
throw new Error("accepted placement is missing its final integration");
|
|
92
|
+
const current = completionVerification ?? currentVerifiedAttestation(admission.state);
|
|
93
|
+
const verification = current === undefined
|
|
94
|
+
? undefined
|
|
95
|
+
: { mode: completionVerification?.mode ?? "reused", verdict: current.verdict };
|
|
96
|
+
const summary = current?.summary;
|
|
97
|
+
return {
|
|
98
|
+
completion: {
|
|
99
|
+
integration,
|
|
100
|
+
...(verification === undefined ? {} : { verification }),
|
|
101
|
+
},
|
|
102
|
+
...(verification?.verdict !== "unsatisfied" || summary === undefined ? {} : { verificationSummary: summary }),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async function admitCurrentPlacement(input) {
|
|
106
|
+
return await admitPlacement({
|
|
107
|
+
channel: input.channel,
|
|
108
|
+
repository: input.repository,
|
|
109
|
+
target: input.target,
|
|
110
|
+
placement: {
|
|
111
|
+
contractId: input.contractId,
|
|
112
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
113
|
+
at: timestamp(),
|
|
114
|
+
},
|
|
115
|
+
...(input.hereWorkspacePath === undefined ? {} : { hereWorkspacePath: input.hereWorkspacePath }),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
export async function completeCandidate(input) {
|
|
119
|
+
let admission = input.initial;
|
|
120
|
+
let evidence = {};
|
|
121
|
+
let completionVerification;
|
|
122
|
+
if (input.verifyInitial) {
|
|
123
|
+
const snapshot = admission.state.currentIntegration?.snapshot;
|
|
124
|
+
if (snapshot === undefined)
|
|
125
|
+
throw new Error("accepted delivery is missing its current integration");
|
|
126
|
+
const verified = await verificationFor(input, admission, snapshot);
|
|
127
|
+
admission = verified.admission;
|
|
128
|
+
evidence = mergeEvidence(evidence, verified.evidence);
|
|
129
|
+
completionVerification = verified.completionVerification;
|
|
130
|
+
}
|
|
131
|
+
let placement = await admitCurrentPlacement(input);
|
|
132
|
+
if (placement.kind === "accepted") {
|
|
133
|
+
admission = mergeAdmissions(admission, placement);
|
|
134
|
+
return { admission, evidence: mergeEvidence(evidence, acceptedCompletion(admission, completionVerification)) };
|
|
135
|
+
}
|
|
136
|
+
if (placement.kind !== "target-moved" || input.target === undefined) {
|
|
137
|
+
return { admission, evidence: mergeEvidence(evidence, { placement: requiredPlacementStop(placement) }) };
|
|
138
|
+
}
|
|
139
|
+
let integratedAt;
|
|
140
|
+
for (let attempts = 1; attempts <= MAX_REINTEGRATION_CYCLES; attempts += 1) {
|
|
141
|
+
const reintegrated = await reintegrateOperation({
|
|
142
|
+
channel: input.channel,
|
|
143
|
+
repository: input.repository,
|
|
144
|
+
contractId: input.contractId,
|
|
145
|
+
target: input.target,
|
|
146
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
147
|
+
...(input.hereWorkspacePath === undefined ? {} : { hereWorkspacePath: input.hereWorkspacePath }),
|
|
148
|
+
});
|
|
149
|
+
if (reintegrated.kind !== "accepted") {
|
|
150
|
+
return { admission, evidence: mergeEvidence(evidence, { placement: reintegrationStop(reintegrated) }) };
|
|
151
|
+
}
|
|
152
|
+
admission = mergeAdmissions(admission, reintegrated);
|
|
153
|
+
integratedAt = reintegrated.value.snapshot;
|
|
154
|
+
const verified = await verificationFor(input, admission, reintegrated.value.snapshot);
|
|
155
|
+
admission = verified.admission;
|
|
156
|
+
evidence = replaceVerificationEvidence(evidence, verified.evidence);
|
|
157
|
+
completionVerification = verified.completionVerification;
|
|
158
|
+
placement = await admitCurrentPlacement(input);
|
|
159
|
+
if (placement.kind === "accepted") {
|
|
160
|
+
admission = mergeAdmissions(admission, placement);
|
|
161
|
+
return { admission, evidence: mergeEvidence(evidence, acceptedCompletion(admission, completionVerification)) };
|
|
162
|
+
}
|
|
163
|
+
if (placement.kind !== "target-moved") {
|
|
164
|
+
return { admission, evidence: mergeEvidence(evidence, { placement: requiredPlacementStop(placement) }) };
|
|
165
|
+
}
|
|
166
|
+
if (attempts === MAX_REINTEGRATION_CYCLES) {
|
|
167
|
+
return {
|
|
168
|
+
admission,
|
|
169
|
+
evidence: mergeEvidence(evidence, {
|
|
170
|
+
placement: {
|
|
171
|
+
failure: "target-moved",
|
|
172
|
+
contractId: input.contractId,
|
|
173
|
+
target: input.target,
|
|
174
|
+
integratedAt: integratedAt,
|
|
175
|
+
observed: placement.observed,
|
|
176
|
+
attempts,
|
|
177
|
+
},
|
|
178
|
+
}),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
throw new Error("reintegration cycle bound was not enforced");
|
|
183
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ActorId, ContractId, ContractState, DeliverData, SnapshotId } from "../core/facts/types.js";
|
|
2
|
+
import type { CurrentVerifiedAttestation } from "./intent.js";
|
|
3
|
+
import { type CompletionEvidence } from "./completion.js";
|
|
4
|
+
import { type ManagedWorktreeAppointment } from "../workspace-place.js";
|
|
5
|
+
import type { DeliveryPreparationRefusal, DocumentDerivation, IntentOutcome, MutationOperationInput } from "./operations.js";
|
|
6
|
+
type DeliveryIdentity = DeliverData;
|
|
7
|
+
export type VerificationReuse = CurrentVerifiedAttestation;
|
|
8
|
+
export type DeliverValue = DeliveryIdentity & CompletionEvidence;
|
|
9
|
+
export type AppointedWorkspace = Readonly<{
|
|
10
|
+
kind: "here" | "worktree";
|
|
11
|
+
path: string;
|
|
12
|
+
}>;
|
|
13
|
+
export type IntegrationConflictMaterialized = Readonly<{
|
|
14
|
+
kind: "integration-conflict-materialized";
|
|
15
|
+
targetHead: SnapshotId;
|
|
16
|
+
conflictPaths: readonly string[];
|
|
17
|
+
workspace: AppointedWorkspace;
|
|
18
|
+
}>;
|
|
19
|
+
type DeliverOperationInput = MutationOperationInput & Readonly<{
|
|
20
|
+
deriveDocument: (state: ContractState) => DocumentDerivation;
|
|
21
|
+
message?: string;
|
|
22
|
+
requireBranchesToBeUpToDate: boolean;
|
|
23
|
+
includeDirty: boolean;
|
|
24
|
+
materializeConflict: boolean;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function prepareDelivery(repository: import("../git/process.js").GitRepository, stage: Readonly<{
|
|
28
|
+
contractId: ContractId;
|
|
29
|
+
coordinates: ContractState["coordinates"];
|
|
30
|
+
appointment?: Extract<ManagedWorktreeAppointment, {
|
|
31
|
+
kind: "appointed";
|
|
32
|
+
}>;
|
|
33
|
+
workspacePath?: string;
|
|
34
|
+
}>, input: Readonly<{
|
|
35
|
+
title: string;
|
|
36
|
+
document: string;
|
|
37
|
+
actor?: ActorId;
|
|
38
|
+
message?: string;
|
|
39
|
+
requireBranchesToBeUpToDate?: boolean;
|
|
40
|
+
includeDirty?: boolean;
|
|
41
|
+
}>): Promise<{
|
|
42
|
+
kind: "prepared";
|
|
43
|
+
data: DeliverData;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "refused";
|
|
46
|
+
refusal: DeliveryPreparationRefusal;
|
|
47
|
+
}>;
|
|
48
|
+
export declare function deliverOperation(input: DeliverOperationInput): Promise<IntentOutcome<DeliverValue> | IntegrationConflictMaterialized>;
|
|
49
|
+
export {};
|