@astrosheep/keiyaku 2.9.11 → 2.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -85
- package/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +1 -0
- package/build/agents/providers/claude-agent-sdk/adapter.js +17 -4
- package/build/cli/commands/akuma/akuma/handler.js +2 -1
- package/build/cli/commands/akuma/akuma/meta.js +4 -3
- package/build/cli/commands/akuma/catalog.js +2 -0
- package/build/cli/commands/akuma/list/handler.js +1 -1
- package/build/cli/commands/akuma/list/meta-list.js +12 -0
- package/build/cli/commands/akuma/list/meta-ls.js +2 -2
- package/build/cli/commands/akuma.js +5 -0
- package/build/cli/commands/contract/amend/meta.js +4 -3
- package/build/cli/commands/contract/arc/meta.js +2 -0
- package/build/cli/commands/contract/audit/handler.js +28 -2
- package/build/cli/commands/contract/audit/meta.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +4 -4
- package/build/cli/commands/contract/petition/handler.js +2 -1
- package/build/cli/commands/contract/petition/meta.js +2 -2
- package/build/cli/commands/contract/renew/handler.js +44 -3
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +14 -10
- package/build/cli/commands/projection/call/handler.js +1 -1
- package/build/cli/commands/projection/call/meta.js +1 -1
- package/build/cli/commands/projection/catalog.js +2 -2
- package/build/cli/commands/projection/{revive → fork}/handler.js +10 -5
- package/build/cli/commands/projection/fork/meta.js +12 -0
- package/build/cli/commands/projection/history/handler.js +46 -2
- package/build/cli/commands/projection/history/meta.js +3 -3
- package/build/cli/commands/projection/kill/handler.js +4 -5
- package/build/cli/commands/projection/kill/meta.js +2 -2
- package/build/cli/commands/projection/status/handler.js +29 -13
- package/build/cli/commands/projection/status/meta.js +14 -3
- package/build/cli/commands/projection/tell/handler.js +8 -4
- package/build/cli/commands/projection/tell/meta.js +1 -1
- package/build/cli/commands/projection/wait/handler.js +45 -20
- package/build/cli/commands/projection/wait/meta.js +1 -1
- package/build/cli/commands/shared.js +2 -2
- package/build/cli/commands/system/catalog.js +2 -0
- package/build/cli/commands/task/add/handler.js +28 -12
- package/build/cli/commands/task/add/meta.js +18 -6
- package/build/cli/commands/task/catalog.js +4 -0
- package/build/cli/commands/task/compose/handler.js +18 -0
- package/build/cli/commands/task/compose/meta.js +10 -0
- package/build/cli/commands/task/doctor/handler.js +2 -3
- package/build/cli/commands/task/doctor/meta.js +2 -2
- package/build/cli/commands/task/done/meta.js +2 -2
- package/build/cli/commands/task/drop/handler.js +7 -2
- package/build/cli/commands/task/drop/meta.js +6 -3
- package/build/cli/commands/task/hold/meta.js +2 -2
- package/build/cli/commands/task/log/meta.js +2 -2
- package/build/cli/commands/task/ls/meta.js +2 -2
- package/build/cli/commands/task/note/handler.js +6 -0
- package/build/cli/commands/task/note/meta.js +11 -0
- package/build/cli/commands/task/resume/meta.js +2 -2
- package/build/cli/commands/task/shared.js +29 -15
- package/build/cli/commands/task/show/meta.js +2 -2
- package/build/cli/commands/task/start/meta.js +2 -2
- package/build/cli/commands/task/stop/meta.js +2 -2
- package/build/cli/commands/task/update/meta.js +3 -2
- package/build/cli/commands/verification/handler.js +43 -0
- package/build/cli/commands/verification/meta.js +13 -0
- package/build/cli/completion.js +16 -13
- package/build/cli/flags.js +48 -12
- package/build/cli/help.js +29 -30
- package/build/cli/index.js +14 -8
- package/build/cli/parse-flags.js +60 -21
- package/build/cli/parse-metadata.js +10 -4
- package/build/cli/parse-selectors.js +22 -4
- package/build/cli/parse.js +43 -30
- package/build/cli/projection-address.js +7 -7
- package/build/cli/render/arc.js +12 -3
- package/build/cli/render/audit.js +2 -2
- package/build/cli/render/call.js +4 -4
- package/build/cli/render/kanshi.js +122 -85
- package/build/cli/render/misc.js +2 -2
- package/build/cli/render/petition.js +16 -1
- package/build/cli/render/projection-history.js +17 -4
- package/build/cli/render/shared.js +5 -5
- package/build/cli/render/status-indicator.js +47 -0
- package/build/cli/render/status.js +106 -76
- package/build/cli/render/success-response.js +20 -5
- package/build/cli/render/task.js +33 -5
- package/build/cli/render/tell.js +10 -4
- package/build/cli/render/tool-command-normalization.js +137 -0
- package/build/cli/render/tool-presentation.js +2 -1
- package/build/cli/render/verification.js +23 -0
- package/build/cli/render/wait.js +101 -33
- package/build/cli/types.js +2 -1
- package/build/config/akuma-loader.js +21 -1
- package/build/config/settings/knobs.js +7 -1
- package/build/config/settings/schema.js +10 -5
- package/build/core/addressing.js +3 -3
- package/build/core/amend.js +102 -17
- package/build/core/arc.js +4 -4
- package/build/core/audit/candidate.js +10 -18
- package/build/core/audit/coordinates.js +12 -17
- package/build/core/audit/evidence.js +6 -4
- package/build/core/audit/facade.js +3 -3
- package/build/core/audit/report.js +1 -1
- package/build/core/bind-reconciliation.js +42 -23
- package/build/core/bind.js +182 -81
- package/build/core/call/call.js +6 -7
- package/build/core/call/context.js +46 -33
- package/build/core/call/execution.js +21 -6
- package/build/core/call/prompt.js +11 -42
- package/build/core/contract-carrier-runtime.js +209 -105
- package/build/core/contract-carrier.js +156 -73
- package/build/core/contract-view.js +43 -6
- package/build/core/contract.js +2 -1
- package/build/core/derived-replay.js +168 -35
- package/build/core/draft.js +60 -27
- package/build/core/forfeit.js +1 -1
- package/build/core/lifecycle-history.js +13 -0
- package/build/core/lifecycle-recovery.js +32 -27
- package/build/core/lifecycle-runner.js +14 -14
- package/build/core/log.js +1 -1
- package/build/core/outcome-base.js +2 -2
- package/build/core/projection/akuma-name.js +43 -0
- package/build/core/projection/generation/database.js +141 -79
- package/build/core/projection/generation/ledger.js +91 -0
- package/build/core/projection/generation/model.js +19 -14
- package/build/core/projection/generation/projection-generation-continuation.js +1 -1
- package/build/core/projection/generation/projection-generation-doorbell.js +88 -0
- package/build/core/projection/generation/projection-generation-execution.js +24 -0
- package/build/core/projection/generation/projection-generation-identity.js +4 -0
- package/build/core/projection/generation/projection-generation-launcher.js +72 -138
- package/build/core/projection/generation/projection-generation-process.js +16 -15
- package/build/core/projection/generation/projection-generation-runner.js +132 -76
- package/build/core/projection/generation/projection-generation-runtime.js +10 -61
- package/build/core/projection/generation/protocol.js +68 -0
- package/build/core/projection/generation/store.js +17 -7
- package/build/core/projection/generation/transitions.js +24 -14
- package/build/core/projection/index.js +5 -5
- package/build/core/projection/projection-core.js +6 -2
- package/build/core/projection/projection-execution-observer.js +1 -1
- package/build/core/projection/projection-history.js +8 -8
- package/build/core/projection/projection-kill.js +20 -10
- package/build/core/projection/projection-life-observer.js +8 -8
- package/build/core/projection/projection-mint.js +6 -8
- package/build/core/projection/projection-status-observation.js +77 -8
- package/build/core/projection/projection-status.js +151 -4
- package/build/core/projection/projection-wait.js +48 -29
- package/build/core/projection/projection-wake.js +28 -88
- package/build/core/projection/tell/launch-store.js +1 -1
- package/build/core/projection/tell/store.js +1 -1
- package/build/core/renew-build.js +204 -74
- package/build/core/renew-plan.js +34 -9
- package/build/core/renew-rewrite.js +56 -15
- package/build/core/renew.js +39 -35
- package/build/core/repository-ledger/accepted-fold-read.js +6 -3
- package/build/core/repository-ledger/claim-evidence.js +1 -1
- package/build/core/repository-ledger/codec.js +11 -5
- package/build/core/repository-ledger/current-state-store.js +464 -349
- package/build/core/repository-ledger/fold-repository.js +5 -6
- package/build/core/repository-ledger/identity.js +60 -0
- package/build/core/repository-ledger/inventory.js +3 -3
- package/build/core/repository-ledger/read-model.js +57 -9
- package/build/core/repository-ledger/write-transaction.js +24 -17
- package/build/core/run-control/connection-bound-close.js +41 -0
- package/build/core/run-control/detached-lease-bootstrap.js +208 -0
- package/build/core/run-control/detached-process.js +14 -0
- package/build/core/run-control/index.js +6 -0
- package/build/core/{process-group.js → run-control/process-tree.js} +1 -1
- package/build/core/run-control/runner-lease.js +172 -0
- package/build/core/run-control/sqlite-process-lifetime-lock.js +174 -0
- package/build/core/seal.js +44 -32
- package/build/core/settlement/claim-delivery.js +22 -9
- package/build/core/settlement/claim.js +8 -6
- package/build/core/settlement/petition-claim-gates.js +9 -8
- package/build/core/settlement/petition-head-guard.js +5 -6
- package/build/core/settlement/petition-preview.js +21 -5
- package/build/core/settlement/petition.js +51 -17
- package/build/core/settlement/settlement.js +20 -15
- package/build/core/settlement/verdict.js +2 -2
- package/build/core/settlement/verification.js +492 -364
- package/build/core/status/board.js +184 -75
- package/build/core/status/drift.js +8 -10
- package/build/core/task/board.js +1 -0
- package/build/core/task/commands.js +25 -0
- package/build/core/task/compose.js +328 -0
- package/build/core/task/document.js +102 -39
- package/build/core/task/index.js +4 -3
- package/build/core/task/settlement-git.js +70 -30
- package/build/core/task/settlement-policy.js +27 -14
- package/build/core/task/source-board.js +1 -0
- package/build/core/task/task-bind-preparation.js +59 -9
- package/build/core/task/task-contract.js +2 -2
- package/build/core/task/task-git-store.js +1 -0
- package/build/core/task/task-store-repository.js +2 -0
- package/build/core/task/task.js +2 -2
- package/build/core/transcripts.js +4 -4
- package/build/core/verification-declaration.js +95 -0
- package/build/core/worktree-bootstrap.js +1 -1
- package/build/core/worktree-path.js +7 -11
- package/build/flow-error.js +15 -2
- package/build/generated/version.js +2 -2
- package/build/git/branches.js +41 -70
- package/build/git/commits.js +92 -21
- package/build/git/core.js +9 -161
- package/build/git/diff/preview.js +4 -4
- package/build/git/diff/read.js +4 -4
- package/build/git/diff/structured.js +5 -5
- package/build/git/process.js +229 -0
- package/build/git/refs.js +30 -5
- package/build/git/staging.js +39 -115
- package/build/git/streaming-batch.js +9 -16
- package/build/git/worktree.js +104 -91
- package/build/index.js +7 -0
- package/package.json +2 -2
- package/skills/keiyaku-akuma/SKILL.md +27 -21
- package/skills/keiyaku-task/SKILL.md +61 -5
- package/skills/keiyaku-workflow/SKILL.md +81 -26
- package/build/cli/commands/projection/revive/meta.js +0 -12
- package/build/core/projection/projection-life-protocol.js +0 -115
- package/build/core/projection/projection-runner-lock.js +0 -382
- package/build/core/projection/tell/database.js +0 -127
- package/build/core/settlement/verification-coordination.js +0 -305
- package/build/core/settlement/verification-supervisor.js +0 -275
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { createOathGate } from "./petition-claim-gates.js";
|
|
2
|
-
import { assertFoldedPetitionable, } from "./petition.js";
|
|
2
|
+
import { assertFoldedPetitionable, precedingRenewSealResult, } from "./petition.js";
|
|
3
3
|
import { captureFoldedSeal } from "../seal.js";
|
|
4
4
|
import { withContractCarrierSession } from "../contract-carrier.js";
|
|
5
5
|
import { FlowError } from "../../flow-error.js";
|
|
6
|
+
import { normalizeScopePattern } from "../scope.js";
|
|
6
7
|
export const PETITION_PREVIEW_GATE_NAMES = [
|
|
7
8
|
"contract",
|
|
8
9
|
"freshness",
|
|
@@ -44,6 +45,7 @@ export async function previewPetition(input) {
|
|
|
44
45
|
const base = session.lifecycle.pins.base;
|
|
45
46
|
const target = { ref: session.lifecycle.pins.target.ref, branch: session.lifecycle.pins.target.ref.slice("refs/heads/".length) };
|
|
46
47
|
const context = { lifecycle: session.lifecycle, deliveryCwd: session.target.root, base, target };
|
|
48
|
+
const appendScope = (input.appendScope ?? []).map(normalizeScopePattern);
|
|
47
49
|
const gates = [{ name: "contract", result: "pass" }];
|
|
48
50
|
const freshness = await gate("freshness", async () => {
|
|
49
51
|
if (!session.pins.target.head || context.base !== session.pins.target.head) {
|
|
@@ -58,15 +60,28 @@ export async function previewPetition(input) {
|
|
|
58
60
|
})
|
|
59
61
|
: notEvaluated("arc");
|
|
60
62
|
gates.push(arc);
|
|
61
|
-
const state = await gate("state", () => {
|
|
62
|
-
assertFoldedPetitionable(input.contractId, context.lifecycle);
|
|
63
|
+
const state = await gate("state", async () => {
|
|
64
|
+
await assertFoldedPetitionable(input.contractId, context.lifecycle, session.repository, session.stableRoot);
|
|
63
65
|
});
|
|
64
66
|
gates.push(state);
|
|
65
67
|
let seal;
|
|
68
|
+
let scopeWarning = null;
|
|
66
69
|
if (freshness.result === "pass" && arc.result === "pass" && state.result === "pass") {
|
|
67
70
|
try {
|
|
68
|
-
const
|
|
69
|
-
|
|
71
|
+
const precedingRenewSeal = appendScope.length === 0
|
|
72
|
+
? await precedingRenewSealResult(context.deliveryCwd, context.lifecycle)
|
|
73
|
+
: null;
|
|
74
|
+
const capture = precedingRenewSeal
|
|
75
|
+
? null
|
|
76
|
+
: await captureFoldedSeal(context.deliveryCwd, context.lifecycle, "HEAD", appendScope, "warn");
|
|
77
|
+
const scope = precedingRenewSeal ?? capture;
|
|
78
|
+
if (scope?.scopeAudit.violations.length) {
|
|
79
|
+
scopeWarning = {
|
|
80
|
+
violations: [...scope.scopeAudit.violations],
|
|
81
|
+
evidence: [...scope.scopeViolationEvidence],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
seal = { name: "seal", result: "pass", detail: sealFileDetail(scope?.diffstat.files ?? 0) };
|
|
70
85
|
}
|
|
71
86
|
catch (error) {
|
|
72
87
|
seal = { name: "seal", result: "failed", detail: failureDetail(error) };
|
|
@@ -102,6 +117,7 @@ export async function previewPetition(input) {
|
|
|
102
117
|
contract: input.contractId,
|
|
103
118
|
target: context.target.ref,
|
|
104
119
|
arc: { source: { arc: context.lifecycle.phase === "active" ? context.lifecycle.intent.arc : null, fence: context.lifecycle.pins.delivery } },
|
|
120
|
+
scopeWarning,
|
|
105
121
|
gates,
|
|
106
122
|
verdict: gates.some((item) => item.result === "failed") ? "would_fail" : "would_succeed",
|
|
107
123
|
};
|
|
@@ -3,14 +3,44 @@ import { parseCommandMarkdown } from "../command-markdown.js";
|
|
|
3
3
|
import { runLifecycle } from "../lifecycle-runner.js";
|
|
4
4
|
import { queueMembership, readQueueReadModel } from "./queue.js";
|
|
5
5
|
import { captureFoldedSeal } from "../seal.js";
|
|
6
|
-
import { currentLifecycleState } from "../repository-ledger/read-model.js";
|
|
6
|
+
import { currentLifecycleState, lookupCurrentContract } from "../repository-ledger/read-model.js";
|
|
7
7
|
import { assertCleanTrackedWorkingTree } from "../../git/worktree.js";
|
|
8
|
-
import { normalizeScopePattern } from "../scope.js";
|
|
9
|
-
|
|
8
|
+
import { normalizeScopePattern, scopePathEvidence } from "../scope.js";
|
|
9
|
+
import { readRemainingTaskNeedsForSettlement } from "../task/settlement-policy.js";
|
|
10
|
+
export async function assertFoldedPetitionable(contractId, model, repository, stableRoot) {
|
|
10
11
|
const state = currentLifecycleState(model);
|
|
11
12
|
if (state.state !== "active" && state.state !== "bound") {
|
|
12
13
|
throw new FlowError("INTERNAL_STATE", `contract ${contractId} cannot petition from state ${state.state}`);
|
|
13
14
|
}
|
|
15
|
+
const unavailable = model.causal.after.filter((dependency) => {
|
|
16
|
+
const prerequisite = lookupCurrentContract(repository, dependency);
|
|
17
|
+
return prerequisite.status !== "healthy" ||
|
|
18
|
+
(prerequisite.model.phase !== "claimed" && prerequisite.model.phase !== "forfeited");
|
|
19
|
+
});
|
|
20
|
+
if (unavailable.length > 0) {
|
|
21
|
+
throw new FlowError("INTERNAL_STATE", `contract ${contractId} cannot petition before after dependencies settle: ${unavailable.join(", ")}`);
|
|
22
|
+
}
|
|
23
|
+
const pendingNeeds = (await readRemainingTaskNeedsForSettlement(stableRoot, model.causal.needs))
|
|
24
|
+
.filter((need) => !need.satisfied);
|
|
25
|
+
if (pendingNeeds.length > 0) {
|
|
26
|
+
throw new FlowError("INTERNAL_STATE", `contract ${contractId} cannot petition before task needs settle: ${pendingNeeds.map((need) => need.id).join(", ")}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Rehydrate the seal consumed by an immediately preceding renew without auditing a new segment. */
|
|
30
|
+
export async function precedingRenewSealResult(cwd, lifecycle, renewIndex = lifecycle.history.length - 1) {
|
|
31
|
+
const renew = lifecycle.history[renewIndex]?.entry;
|
|
32
|
+
const seal = lifecycle.history[renewIndex - 1];
|
|
33
|
+
if (renew?.kind !== "renew" || seal?.entry.kind !== "seal" || seal.entry.data.sealedBy !== "renew")
|
|
34
|
+
return null;
|
|
35
|
+
return {
|
|
36
|
+
...seal.entry.data,
|
|
37
|
+
receipts: [...seal.entry.data.receipts],
|
|
38
|
+
diffstat: { ...seal.entry.data.diffstat },
|
|
39
|
+
scopeAudit: { violations: [...seal.entry.data.scopeAudit.violations] },
|
|
40
|
+
scopeViolationEvidence: await scopePathEvidence(cwd, lifecycle.effectiveScope, seal.entry.data.scopeAudit.violations),
|
|
41
|
+
sealedBy: "renew",
|
|
42
|
+
ledgerHead: seal.objectId,
|
|
43
|
+
};
|
|
14
44
|
}
|
|
15
45
|
function nextSettlementSeat(read, target) {
|
|
16
46
|
let floor = 0;
|
|
@@ -68,7 +98,7 @@ export async function petitionContract(input) {
|
|
|
68
98
|
const branch = target.slice("refs/heads/".length);
|
|
69
99
|
throw new FlowError("INTERNAL_STATE", `contract ${input.contractId} must renew onto ${branch} before petition`, { facts: { kind: "needs_renew", contractId: input.contractId } });
|
|
70
100
|
}
|
|
71
|
-
assertFoldedPetitionable(input.contractId, session.lifecycle);
|
|
101
|
+
await assertFoldedPetitionable(input.contractId, session.lifecycle, session.repository, session.stableRoot);
|
|
72
102
|
return { lifecycle: session.lifecycle, deliveryCwd };
|
|
73
103
|
},
|
|
74
104
|
prepare: async (admission) => {
|
|
@@ -88,7 +118,7 @@ export async function petitionContract(input) {
|
|
|
88
118
|
receipts: [...acceptedSeal.data.receipts],
|
|
89
119
|
diffstat: { ...acceptedSeal.data.diffstat },
|
|
90
120
|
scopeAudit: { violations: [...acceptedSeal.data.scopeAudit.violations] },
|
|
91
|
-
scopeViolationEvidence:
|
|
121
|
+
scopeViolationEvidence: await scopePathEvidence(input.cwd, admission.business.lifecycle.effectiveScope, acceptedSeal.data.scopeAudit.violations),
|
|
92
122
|
};
|
|
93
123
|
prefixIndex -= 1;
|
|
94
124
|
}
|
|
@@ -101,13 +131,14 @@ export async function petitionContract(input) {
|
|
|
101
131
|
return {
|
|
102
132
|
additions: [],
|
|
103
133
|
capture,
|
|
134
|
+
precedingRenewSeal: await precedingRenewSealResult(input.cwd, admission.business.lifecycle, admission.business.lifecycle.history.findIndex(({ objectId }) => objectId === transaction.entryObjectIds.at(-1)) - 1),
|
|
104
135
|
seat: accepted.data.seat,
|
|
105
136
|
targetHead: accepted.data.intent === "claim" ? accepted.data.targetHead : admission.pins.target.head ?? "",
|
|
106
137
|
existing: { transactionObjectId: transaction.transactionObjectId },
|
|
107
138
|
};
|
|
108
139
|
}
|
|
109
140
|
const scopeEntry = patterns.length === 0 ? null : {
|
|
110
|
-
v:
|
|
141
|
+
v: 2,
|
|
111
142
|
kind: "amend",
|
|
112
143
|
contract: input.contractId,
|
|
113
144
|
at,
|
|
@@ -118,12 +149,12 @@ export async function petitionContract(input) {
|
|
|
118
149
|
if (!deliveryCwd)
|
|
119
150
|
throw new FlowError("INTERNAL_STATE", `petition ${input.contractId} is missing its delivery worktree`);
|
|
120
151
|
const lifecycle = admission.business.lifecycle;
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const capture =
|
|
152
|
+
const precedingRenewSeal = patterns.length === 0
|
|
153
|
+
? await precedingRenewSealResult(input.cwd, lifecycle)
|
|
154
|
+
: null;
|
|
155
|
+
const capture = precedingRenewSeal
|
|
125
156
|
? null
|
|
126
|
-
: await captureFoldedSeal(deliveryCwd, lifecycle, "HEAD", patterns);
|
|
157
|
+
: await captureFoldedSeal(deliveryCwd, lifecycle, "HEAD", patterns, "warn");
|
|
127
158
|
let sealEntry = null;
|
|
128
159
|
if (capture) {
|
|
129
160
|
const { scopeViolationEvidence: _evidence, ...durableCapture } = capture;
|
|
@@ -145,6 +176,7 @@ export async function petitionContract(input) {
|
|
|
145
176
|
return {
|
|
146
177
|
additions,
|
|
147
178
|
capture,
|
|
179
|
+
precedingRenewSeal,
|
|
148
180
|
seat: nextSettlementSeat(admission.repository, admission.pins.target.ref),
|
|
149
181
|
targetHead,
|
|
150
182
|
};
|
|
@@ -169,7 +201,7 @@ export async function petitionContract(input) {
|
|
|
169
201
|
const base = session.lifecycle.pins.base;
|
|
170
202
|
if (base !== session.pins.target.head)
|
|
171
203
|
return { code: "PETITION_TARGET_CHANGED", message: "petition target/base facts changed during preparation" };
|
|
172
|
-
assertFoldedPetitionable(input.contractId, session.lifecycle);
|
|
204
|
+
await assertFoldedPetitionable(input.contractId, session.lifecycle, session.repository, session.stableRoot);
|
|
173
205
|
return undefined;
|
|
174
206
|
},
|
|
175
207
|
effect: async ({ context, prepared }) => {
|
|
@@ -208,15 +240,15 @@ export async function petitionContract(input) {
|
|
|
208
240
|
? await context.replayCommitted({ transactionObjectId: prepared.existing.transactionObjectId })
|
|
209
241
|
: await context.publishAuthoritative({
|
|
210
242
|
verb: "petition",
|
|
211
|
-
admittedLedgerHead: context.session.
|
|
212
|
-
acceptedLifecycleTail: context.session.lifecycle.
|
|
243
|
+
admittedLedgerHead: context.session.pins.repositoryLedgerHead,
|
|
244
|
+
acceptedLifecycleTail: context.session.lifecycle.contractHead,
|
|
213
245
|
entries: additions,
|
|
214
246
|
});
|
|
215
247
|
if (result.status === "indeterminate") {
|
|
216
|
-
return { kind: "precommit-effects-only", authoritativeHead: result.currentHead ?? context.session.
|
|
248
|
+
return { kind: "precommit-effects-only", authoritativeHead: result.currentHead ?? context.session.pins.repositoryLedgerHead };
|
|
217
249
|
}
|
|
218
250
|
if (result.status !== "committed") {
|
|
219
|
-
const authoritativeHead = result.currentHead ?? context.session.
|
|
251
|
+
const authoritativeHead = result.currentHead ?? context.session.pins.repositoryLedgerHead;
|
|
220
252
|
return { kind: "refused-before-effects", authoritativeHead, refusal: { code: "LEDGER_CAS_CONFLICT", message: `contract ${input.contractId} changed during petition` } };
|
|
221
253
|
}
|
|
222
254
|
if (input.reviewPersistence) {
|
|
@@ -254,7 +286,9 @@ export async function petitionContract(input) {
|
|
|
254
286
|
position,
|
|
255
287
|
seat: prepared.seat,
|
|
256
288
|
reviewHistoryPath,
|
|
257
|
-
sealed: prepared.capture
|
|
289
|
+
sealed: prepared.capture
|
|
290
|
+
? { ...prepared.capture, sealedBy: "petition", ledgerHead: result.transaction.entryObjectIds[result.transaction.entries.findIndex((entry) => entry.kind === "seal")] }
|
|
291
|
+
: prepared.precedingRenewSeal ?? undefined,
|
|
258
292
|
},
|
|
259
293
|
};
|
|
260
294
|
},
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { FlowError } from "../../flow-error.js";
|
|
2
2
|
import { readCurrentContractContext } from "../context.js";
|
|
3
3
|
import { convergeContractCarrier, withContractCarrierSession } from "../contract-carrier.js";
|
|
4
|
-
import {
|
|
4
|
+
import { requireCommitCoordinate } from "../../git/commits.js";
|
|
5
5
|
import { getCurrentBranch, requireGitRepository } from "../../git/branches.js";
|
|
6
|
-
import { getLatestCommitHash } from "../../git/staging.js";
|
|
7
6
|
import { readContractLog } from "../log.js";
|
|
8
7
|
import { scopePathEvidence } from "../scope.js";
|
|
9
8
|
import { nextReviewResponseNumber } from "../transcripts.js";
|
|
@@ -45,15 +44,17 @@ async function pinnedCloseCandidate(cwd, contractId, signal) {
|
|
|
45
44
|
if (session.target.status !== "available" || !session.pins.delivery.head) {
|
|
46
45
|
throw new FlowError("INTERNAL_STATE", session.target.status === "available" ? `contract ${contractId} delivery ref does not resolve` : session.target.reason);
|
|
47
46
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
git.raw(["rev-parse", "--verify", "HEAD^{commit}"]),
|
|
51
|
-
git.raw(["rev-parse", "--verify", "HEAD^{tree}"]),
|
|
52
|
-
]);
|
|
53
|
-
if (head.trim() !== session.pins.delivery.head) {
|
|
47
|
+
const coordinate = await requireCommitCoordinate(session.target.root, "HEAD");
|
|
48
|
+
if (coordinate.commit !== session.pins.delivery.head) {
|
|
54
49
|
throw new FlowError("INTERNAL_STATE", `contract ${contractId} delivery head changed while petition was being prepared`);
|
|
55
50
|
}
|
|
56
|
-
|
|
51
|
+
const bind = session.lifecycle.history.find(({ entry }) => entry.kind === "bind")?.entry;
|
|
52
|
+
return {
|
|
53
|
+
deliveryCwd: session.target.root,
|
|
54
|
+
candidate: { head: coordinate.commit, tree: coordinate.tree },
|
|
55
|
+
contractVerification: contractVerificationDeclarations(session.lifecycle),
|
|
56
|
+
preparation: bind?.kind === "bind" && bind.data.workspace === "worktree" ? bind.data.bootstrap ?? null : null,
|
|
57
|
+
};
|
|
57
58
|
});
|
|
58
59
|
}
|
|
59
60
|
async function loadCloseContext(cwd, requestedContractId, signal) {
|
|
@@ -66,6 +67,7 @@ async function loadCloseContext(cwd, requestedContractId, signal) {
|
|
|
66
67
|
deliveryCwd: pinned.deliveryCwd,
|
|
67
68
|
verificationCandidate: pinned.candidate,
|
|
68
69
|
contractVerification: pinned.contractVerification,
|
|
70
|
+
verificationPreparation: pinned.preparation,
|
|
69
71
|
keiyakuBranch: `keiyaku/${requestedContractId}`,
|
|
70
72
|
baseBranch: lifecycle.pins.target.ref.slice("refs/heads/".length),
|
|
71
73
|
contractId: requestedContractId,
|
|
@@ -88,6 +90,7 @@ async function loadCloseContext(cwd, requestedContractId, signal) {
|
|
|
88
90
|
deliveryCwd: pinned.deliveryCwd,
|
|
89
91
|
verificationCandidate: pinned.candidate,
|
|
90
92
|
contractVerification: pinned.contractVerification,
|
|
93
|
+
verificationPreparation: pinned.preparation,
|
|
91
94
|
keiyakuBranch,
|
|
92
95
|
baseBranch: contractContext.baseBranch,
|
|
93
96
|
contractId: contractContext.contractId,
|
|
@@ -107,14 +110,15 @@ async function throwClaimGateFailure(failure, _input, context, _dependencies) {
|
|
|
107
110
|
}
|
|
108
111
|
async function runClaimGatePipelineOrThrow(input, context, dependencies) {
|
|
109
112
|
const deliveryCwd = context.deliveryCwd ?? context.cwd;
|
|
110
|
-
const verificationCandidate = context.verificationCandidate ?? {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
113
|
+
const verificationCandidate = context.verificationCandidate ?? await (async () => {
|
|
114
|
+
const coordinate = await requireCommitCoordinate(deliveryCwd, "HEAD");
|
|
115
|
+
return { head: coordinate.commit, tree: coordinate.tree };
|
|
116
|
+
})();
|
|
117
|
+
const verificationPreparation = context.verificationPreparation ?? null;
|
|
114
118
|
const gateConfig = await dependencies.resolveClaimGateConfig(context.cwd);
|
|
115
119
|
const repositoryGates = gateConfig.repositoryGates ?? gateConfig.verificationCommands ?? [];
|
|
116
120
|
const verificationPlan = composeVerificationPlan({ contract: context.contractVerification ?? [], repositoryGates, timeoutMs: gateConfig.verificationTimeoutMs });
|
|
117
|
-
const
|
|
121
|
+
const repositoryRoot = await stableRepoRoot(context.cwd);
|
|
118
122
|
let review;
|
|
119
123
|
let reviewHeadBeforeWrite;
|
|
120
124
|
let reviewerActor;
|
|
@@ -123,11 +127,12 @@ async function runClaimGatePipelineOrThrow(input, context, dependencies) {
|
|
|
123
127
|
for (const gate of buildClaimGatePipeline()) {
|
|
124
128
|
const result = await gate.evaluate({
|
|
125
129
|
cwd: deliveryCwd,
|
|
126
|
-
|
|
130
|
+
repositoryRoot,
|
|
127
131
|
contractId: context.contractId,
|
|
128
132
|
input,
|
|
129
133
|
verificationPlan,
|
|
130
134
|
verificationCandidate,
|
|
135
|
+
verificationPreparation,
|
|
131
136
|
baseBranch: dependencies.baseBranch,
|
|
132
137
|
reviewNumber: dependencies.reviewNumber,
|
|
133
138
|
});
|
|
@@ -103,12 +103,12 @@ export async function verdictContract(input) {
|
|
|
103
103
|
value: { result: admission.business.existing.result, summary: admission.business.existing.summary },
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
const committed = await context.publishAuthoritative({ verb: "verdict", admittedLedgerHead: admission.ledgerHead, acceptedLifecycleTail: context.session.lifecycle.
|
|
106
|
+
const committed = await context.publishAuthoritative({ verb: "verdict", admittedLedgerHead: admission.ledgerHead, acceptedLifecycleTail: context.session.lifecycle.contractHead, entries: [prepared.entry] });
|
|
107
107
|
if (committed.status === "indeterminate") {
|
|
108
108
|
return { kind: "precommit-effects-only", authoritativeHead: committed.currentHead ?? admission.ledgerHead };
|
|
109
109
|
}
|
|
110
110
|
if (committed.status !== "committed") {
|
|
111
|
-
return { kind: "refused-before-effects", authoritativeHead: committed.currentHead ?? context.session.
|
|
111
|
+
return { kind: "refused-before-effects", authoritativeHead: committed.currentHead ?? context.session.pins.repositoryLedgerHead, refusal: { code: "LEDGER_CAS_CONFLICT", message: `contract ${input.contractId} changed during verdict` } };
|
|
112
112
|
}
|
|
113
113
|
return {
|
|
114
114
|
kind: "committed",
|