@astrosheep/keiyaku 2.9.2 → 2.9.4
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/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +13 -94
- package/build/agents/harness/activity-values.js +16 -0
- package/build/agents/harness/event-persistence.js +218 -0
- package/build/agents/harness/execution-handle.js +25 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +47 -4
- package/build/agents/harness/projection.js +42 -59
- package/build/agents/harness/provider-adapter.js +58 -0
- package/build/agents/harness/router.js +11 -187
- package/build/agents/harness/runtime.js +17 -4
- package/build/agents/harness/session.js +15 -0
- package/build/agents/launch-snapshot/model.js +15 -236
- package/build/agents/launch-snapshot/parse-helpers.js +114 -0
- package/build/agents/launch-snapshot/resolve.js +17 -43
- package/build/agents/opencode-sdk.js +45 -12
- package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
- package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
- package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
- package/build/agents/providers/codex-app-server/adapter.js +50 -53
- package/build/agents/providers/codex-app-server/events.js +67 -11
- package/build/agents/providers/codex-app-server/identity.js +1 -0
- package/build/agents/providers/codex-app-server/policy.js +29 -0
- package/build/agents/providers/codex-app-server/registration.js +248 -0
- package/build/agents/providers/codex-app-server/session-schema.js +6 -0
- package/build/agents/providers/codex-app-server/session.js +23 -17
- package/build/agents/providers/codex-app-server/terms.js +1 -0
- package/build/agents/providers/opencode-sdk/adapter.js +94 -50
- package/build/agents/providers/opencode-sdk/events.js +8 -4
- package/build/agents/providers/opencode-sdk/registration.js +135 -0
- package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
- package/build/agents/providers/opencode-sdk/session.js +21 -14
- package/build/agents/providers/opencode-sdk/terms.js +1 -0
- package/build/agents/providers/pi/adapter.js +36 -30
- package/build/agents/providers/pi/registration.js +145 -0
- package/build/agents/providers/pi/session-schema.js +6 -0
- package/build/agents/providers/pi/terms.js +1 -0
- package/build/agents/providers/registration.js +7 -0
- package/build/agents/providers/registry.js +76 -0
- package/build/agents/selector.js +2 -29
- package/build/agents/types.js +8 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/arc/handler.js +7 -1
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +34 -7
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/petition/handler.js +4 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +58 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +7 -2
- package/build/cli/commands/registry.js +2 -54
- package/build/cli/commands/shared.js +10 -7
- package/build/cli/commands/skills/install/handler.js +2 -5
- package/build/cli/commands/skills/skills/handler.js +1 -1
- package/build/cli/commands/task/add/handler.js +5 -13
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/ls/handler.js +3 -5
- package/build/cli/commands/task/shared.js +14 -4
- package/build/cli/commands/task/{view → show}/handler.js +7 -8
- package/build/cli/commands/task/show/meta.js +8 -0
- package/build/cli/commands/task/start/handler.js +3 -6
- package/build/cli/commands/task/stop/handler.js +4 -8
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/update/handler.js +4 -8
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +19 -3
- package/build/cli/help.js +4 -11
- package/build/cli/index.js +57 -83
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/parse-flags.js +14 -5
- package/build/cli/parse-metadata.js +3 -3
- package/build/cli/parse-selectors.js +1 -1
- package/build/cli/parse.js +21 -0
- package/build/cli/projection-address.js +7 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- package/build/cli/render/call.js +11 -5
- package/build/cli/render/errors.js +36 -1
- package/build/cli/render/format.js +4 -0
- package/build/cli/render/kanshi.js +6 -12
- package/build/cli/render/kill.js +9 -0
- package/build/cli/render/misc.js +55 -12
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +3 -0
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +37 -14
- package/build/cli/render/success-response.js +77 -0
- package/build/cli/render/task.js +54 -14
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +58 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +38 -36
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +1 -1
- package/build/config/provider-policy-ownership.js +3 -32
- package/build/config/settings/disease.js +8 -1
- package/build/config/settings/loader.js +11 -3
- package/build/config/settings/provider-instance-fields.js +51 -0
- package/build/config/settings/schema.js +6 -176
- package/build/core/addressing.js +66 -16
- package/build/core/amend.js +135 -18
- package/build/core/arc.js +19 -67
- package/build/core/bind.js +82 -35
- package/build/core/call/call.js +15 -9
- package/build/core/call/context.js +6 -51
- package/build/core/call/execution.js +21 -22
- package/build/core/call/prompt.js +14 -1
- package/build/core/command-markdown.js +45 -0
- package/build/core/context.js +13 -7
- package/build/core/contract-view.js +20 -3
- package/build/core/draft.js +123 -16
- package/build/core/forfeit.js +5 -2
- package/build/core/hints.js +1 -75
- package/build/core/identifier-slug.js +66 -0
- package/build/core/ids.js +25 -11
- package/build/core/ledger.js +20 -68
- package/build/core/markdown/parser.js +0 -68
- package/build/core/markdown/render.js +68 -0
- package/build/core/markdown/sections.js +2 -1
- package/build/core/outcome-base.js +4 -0
- package/build/core/projection/generation/database.js +2 -38
- package/build/core/projection/generation/model.js +42 -1
- package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
- package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
- package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
- package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
- package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
- package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
- package/build/core/projection/generation/store.js +2 -2
- package/build/core/projection/generation/transitions.js +1 -1
- package/build/core/projection/index.js +27 -0
- package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
- package/build/core/{projection-alias.js → projection/projection-alias.js} +14 -19
- package/build/core/projection/projection-coordinate.js +61 -0
- package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
- package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
- package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
- package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
- package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
- package/build/core/projection/projection-terminal-failure.js +104 -0
- package/build/core/projection/projection-wait.js +278 -0
- package/build/core/projection/projection-wake.js +203 -0
- package/build/core/provider-loader-ports.js +4 -0
- package/build/core/ref-log.js +65 -40
- package/build/core/registry.js +63 -10
- package/build/core/renew-session.js +128 -0
- package/build/core/renew.js +426 -99
- package/build/core/scope.js +143 -66
- package/build/core/seal.js +139 -35
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
- package/build/core/{claim.js → settlement/claim.js} +32 -8
- package/build/core/settlement/index.js +19 -0
- package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
- package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
- package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
- package/build/core/settlement/petition-io.js +1 -0
- package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
- package/build/core/{petition.js → settlement/petition.js} +12 -10
- package/build/core/settlement/queue-read-model.js +143 -0
- package/build/core/settlement/queue-seat-allocation.js +156 -0
- package/build/core/settlement/queue.js +6 -0
- package/build/core/settlement/settlement.js +295 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/status/board.js +24 -23
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +3 -0
- package/build/core/task/board.js +40 -4
- package/build/core/task/commands.js +30 -21
- package/build/core/task/index.js +12 -0
- package/build/core/task/settlement-git.js +157 -65
- package/build/core/task/settlement-policy.js +54 -24
- package/build/core/task/task-contract.js +370 -0
- package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
- package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
- package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
- package/build/core/{task-git-store.js → task/task-git-store.js} +92 -29
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
- package/build/core/task/task-store.js +1 -0
- package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
- package/build/core/task/task.js +5 -0
- package/build/core/task/tree.js +37 -0
- package/build/core/task/validation.js +5 -2
- package/build/core/transcripts.js +15 -3
- package/build/core/worktree-path.js +43 -28
- package/build/flow-error.js +85 -39
- package/build/fs/durability.js +27 -0
- package/build/fs/path-coordinate.js +16 -0
- package/build/generated/version.js +3 -2
- package/build/git/branches.js +2 -1
- package/build/git/core.js +106 -2
- package/build/git/path-coordinate.js +17 -0
- package/build/git/refs.js +57 -0
- package/build/git/streaming-batch.js +301 -0
- package/build/git/worktree.js +65 -0
- package/build/index.js +3 -3
- package/build/keiyaku.js +2 -36
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +3 -2
- package/skills/keiyaku-akuma/SKILL.md +10 -6
- package/skills/keiyaku-task/SKILL.md +1 -1
- package/skills/keiyaku-workflow/SKILL.md +25 -4
- package/build/agents/providers/codex-sdk.js +0 -329
- package/build/cli/commands/task/view/meta.js +0 -8
- package/build/core/command-io.js +0 -174
- package/build/core/path-coordinate.js +0 -27
- package/build/core/petition-claim.js +0 -117
- package/build/core/petition-run.js +0 -83
- package/build/core/projection-coordinate.js +0 -63
- package/build/core/projection-wait.js +0 -165
- package/build/core/projection-wake.js +0 -136
- package/build/core/queue.js +0 -343
- package/build/core/task-contract.js +0 -237
- package/build/core/task.js +0 -4
- /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
- /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
- /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
- /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
- /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
package/build/core/renew.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { readProjectionStatusBoard } from "./projection-status.js";
|
|
8
|
-
import { renderContractView } from "./contract-view.js";
|
|
9
|
-
import { captureSeal, findOpenArc, getMaxArc, receiptsAfterFence, sealCurrentArc } from "./seal.js";
|
|
1
|
+
import { asMessage, FlowError } from "../flow-error.js";
|
|
2
|
+
import { createGit, errorContainsAnyPattern, MISSING_HEAD_PATTERNS, parseRevListOutput, runGitProcess, wrapGitError } from "../git/core.js";
|
|
3
|
+
import { readLedger } from "./ledger.js";
|
|
4
|
+
import { hasStrandableProjectionGeneration } from "./projection/index.js";
|
|
5
|
+
import { refreshContractView } from "./contract-view.js";
|
|
6
|
+
import { appendRenewSettlement, captureRenewSeal, captureSeal, findOpenArc, getFence, getMaxArc, receiptsAfterFence } from "./seal.js";
|
|
10
7
|
import { deriveContractState, isTerminalState } from "./status/lifecycle.js";
|
|
11
8
|
import { commissionTarget, latestBase } from "./status/drift.js";
|
|
12
|
-
import { findContractWorktreePath } from "./worktree-path.js";
|
|
9
|
+
import { findContractWorktreePath, findRegisteredContractWorktreePath, stableRepoRoot } from "./worktree-path.js";
|
|
13
10
|
import { getCurrentBranch, requireGitRepository } from "../git/branches.js";
|
|
11
|
+
import { assertCleanTrackedWorkingTree, getUnmergedPaths, hasActiveRebase } from "../git/worktree.js";
|
|
12
|
+
import { createRecoveryRef, deleteRecoveryRef } from "../git/refs.js";
|
|
14
13
|
import { resolveContractAddress, withResolvedAddress } from "./addressing.js";
|
|
15
14
|
import { ACTOR_IDENTITY } from "../keiyaku.js";
|
|
16
15
|
import { persistResponseHistory } from "./transcripts.js";
|
|
16
|
+
import { convergeRenewRecoverySession, readRenewRecoverySession, removeRenewRecoverySession, writeRenewRecoverySession, } from "./renew-session.js";
|
|
17
17
|
function assertOperable(contractId, entries) {
|
|
18
18
|
const state = deriveContractState(entries);
|
|
19
19
|
if (state.state === "corrupt") {
|
|
@@ -43,15 +43,14 @@ async function resolveCommitOrNull(cwd, rev) {
|
|
|
43
43
|
throw wrapGitError(`rev-parse ${rev}`, error, cwd);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
throw new FlowError("INTERNAL_STATE", `contract ${contractId} active ledger disappeared before render`);
|
|
50
|
-
}
|
|
51
|
-
await fs.writeFile(path.join(renderCwd, KEIYAKU_FILE), renderContractView({ id: contractId, entries: ledger.entries }), "utf8");
|
|
46
|
+
const RENEW_RECOVERY_REF_PREFIX = "refs/keiyaku/recovery/renew";
|
|
47
|
+
function renewRecoveryRef(contractId, oldHead) {
|
|
48
|
+
return `${RENEW_RECOVERY_REF_PREFIX}/${contractId}/${oldHead}`;
|
|
52
49
|
}
|
|
53
|
-
async function rewriteBranch(
|
|
50
|
+
async function rewriteBranch(input) {
|
|
51
|
+
const { cwd, contractId, oldHead, recoveryRef, newBase, oldBase, branch, preserveConflict } = input;
|
|
54
52
|
const git = createGit(cwd);
|
|
53
|
+
const originalBranch = branch ? await getCurrentBranch(cwd) : undefined;
|
|
55
54
|
const args = branch
|
|
56
55
|
? ["rebase", "--onto", newBase, oldBase, branch]
|
|
57
56
|
: ["rebase", "--onto", newBase, oldBase];
|
|
@@ -59,31 +58,155 @@ async function rewriteBranch(cwd, newBase, oldBase, branch) {
|
|
|
59
58
|
await git.raw(args);
|
|
60
59
|
}
|
|
61
60
|
catch (error) {
|
|
61
|
+
const isConflict = errorContainsAnyPattern(error, ["CONFLICT", "could not apply", "Resolve all conflicts manually"]);
|
|
62
|
+
let conflictPaths = [];
|
|
63
|
+
let conflictPathDiagnostic;
|
|
64
|
+
if (isConflict) {
|
|
65
|
+
try {
|
|
66
|
+
conflictPaths = await getUnmergedPaths(cwd);
|
|
67
|
+
}
|
|
68
|
+
catch (captureError) {
|
|
69
|
+
conflictPathDiagnostic = asMessage(captureError);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (isConflict && preserveConflict) {
|
|
73
|
+
throw new FlowError("RENEW_SESSION_OPEN", `renew recovery session is open for ${contractId}`, {
|
|
74
|
+
cause: error,
|
|
75
|
+
facts: { kind: "renew_session", commission: contractId, nextAction: "resolve-conflicts" },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
62
78
|
try {
|
|
63
79
|
await git.raw(["rebase", "--abort"]);
|
|
64
80
|
}
|
|
65
|
-
catch {
|
|
66
|
-
|
|
81
|
+
catch (abortError) {
|
|
82
|
+
throw wrapGitError("rebase --abort", abortError, cwd);
|
|
67
83
|
}
|
|
68
|
-
if (
|
|
69
|
-
|
|
84
|
+
if (originalBranch && originalBranch !== branch) {
|
|
85
|
+
try {
|
|
86
|
+
await git.raw(["switch", originalBranch]);
|
|
87
|
+
}
|
|
88
|
+
catch (switchError) {
|
|
89
|
+
throw wrapGitError(`switch ${originalBranch}`, switchError, cwd);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (isConflict) {
|
|
93
|
+
const restoredHead = await resolveCommit(cwd, `keiyaku/${contractId}`);
|
|
94
|
+
if (restoredHead !== oldHead) {
|
|
95
|
+
throw new FlowError("INTERNAL_STATE", `renew abort did not restore keiyaku/${contractId}: expected ${oldHead}, found ${restoredHead}`);
|
|
96
|
+
}
|
|
97
|
+
await assertCleanTrackedWorkingTree(cwd);
|
|
98
|
+
throw new FlowError("CLOSE_MERGE_CONFLICT", "renew conflict", {
|
|
99
|
+
cause: error,
|
|
100
|
+
facts: {
|
|
101
|
+
kind: "renew_conflict",
|
|
102
|
+
contractId,
|
|
103
|
+
oldHead,
|
|
104
|
+
recoveryRef,
|
|
105
|
+
conflictPaths,
|
|
106
|
+
conflictPathCapture: conflictPathDiagnostic
|
|
107
|
+
? { status: "failed", diagnostic: conflictPathDiagnostic }
|
|
108
|
+
: { status: "captured" },
|
|
109
|
+
workspaceRestored: true,
|
|
110
|
+
ledgerWrites: false,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
70
113
|
}
|
|
71
114
|
throw wrapGitError(`renew ${branch ?? "current branch"}`, error, cwd);
|
|
72
115
|
}
|
|
73
116
|
}
|
|
74
|
-
function assertNoInFlightProjection(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
117
|
+
async function assertNoInFlightProjection(repositoryRoot, contractId, deliveryWorktree, nowMs) {
|
|
118
|
+
if (!await hasStrandableProjectionGeneration({
|
|
119
|
+
cwd: repositoryRoot,
|
|
120
|
+
commissionId: contractId,
|
|
121
|
+
deliveryWorktree,
|
|
122
|
+
nowMs,
|
|
123
|
+
}))
|
|
78
124
|
return;
|
|
79
|
-
throw new FlowError("INTERNAL_STATE", `akuma still out on ${contractId}'s worktree; rewriting under it would strand its work`, {
|
|
125
|
+
throw new FlowError("INTERNAL_STATE", `akuma still out on ${contractId}'s worktree; rewriting under it would strand its work`, { facts: { kind: "projection_in_flight", contractId } });
|
|
80
126
|
}
|
|
81
127
|
function looseCommitError(contractId, receipts) {
|
|
82
|
-
return new FlowError("NO_OPEN_ARC", `${receipts.length} commits after fence have no arc to receipt them`, {
|
|
83
|
-
|
|
128
|
+
return new FlowError("NO_OPEN_ARC", `${receipts.length} commits after fence have no arc to receipt them`, { facts: { kind: "loose_commits", contractId, nextVerb: "renew" } });
|
|
129
|
+
}
|
|
130
|
+
async function mergeBase(cwd, left, right) {
|
|
131
|
+
const git = createGit(cwd);
|
|
132
|
+
try {
|
|
133
|
+
return (await git.raw(["merge-base", left, right])).trim();
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw wrapGitError(`merge-base ${left} ${right}`, error, cwd);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function assertRenewCoordinates(input) {
|
|
140
|
+
const fence = getFence(input.entries);
|
|
141
|
+
let branchBase;
|
|
142
|
+
let fenceBase;
|
|
143
|
+
try {
|
|
144
|
+
[branchBase, fenceBase] = await Promise.all([
|
|
145
|
+
mergeBase(input.cwd, input.oldHead, input.targetHead),
|
|
146
|
+
mergeBase(input.cwd, fence, input.oldHead),
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
throw new FlowError("RENEW_COORDINATE_DRIFT", `renew coordinates for ${input.contractId} are detached from the ledger`, {
|
|
151
|
+
cause: error,
|
|
152
|
+
facts: { kind: "renew_coordinate_drift", commission: input.contractId, oldBase: input.oldBase, oldHead: input.oldHead, fence, targetHead: input.targetHead },
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (branchBase === input.oldBase && fenceBase === fence)
|
|
156
|
+
return;
|
|
157
|
+
throw new FlowError("RENEW_COORDINATE_DRIFT", `renew coordinates for ${input.contractId} drifted from the ledger before scope audit`, {
|
|
158
|
+
facts: { kind: "renew_coordinate_drift", commission: input.contractId, oldBase: input.oldBase, oldHead: input.oldHead, fence, targetHead: input.targetHead },
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async function finishRenew(input) {
|
|
162
|
+
const capture = input.capture === undefined
|
|
163
|
+
? await captureSeal(input.repositoryRoot, input.entries, input.oldHead, input.waivePaths)
|
|
164
|
+
: input.capture;
|
|
165
|
+
const settlement = await appendRenewSettlement({
|
|
166
|
+
cwd: input.repositoryRoot,
|
|
167
|
+
contractId: input.contractId,
|
|
168
|
+
expectedLedgerHead: input.ledgerHead,
|
|
169
|
+
capture,
|
|
170
|
+
oldBase: input.oldBase,
|
|
171
|
+
newBase: input.newBase,
|
|
172
|
+
oldHead: input.oldHead,
|
|
173
|
+
newHead: input.newHead,
|
|
174
|
+
actor: input.actor,
|
|
175
|
+
nowMs: input.nowMs,
|
|
176
|
+
});
|
|
177
|
+
await input.afterLedgerCas?.();
|
|
178
|
+
await refreshContractView({
|
|
179
|
+
ledgerCwd: input.repositoryRoot,
|
|
180
|
+
renderCwd: input.rewriteCwd,
|
|
181
|
+
contractId: input.contractId,
|
|
84
182
|
});
|
|
183
|
+
const recoveryCleanup = await deleteRecoveryRef(input.repositoryRoot, input.recoveryRef, input.oldHead);
|
|
184
|
+
await removeRenewRecoverySession(input.repositoryRoot, input.contractId);
|
|
185
|
+
return {
|
|
186
|
+
contractId: input.contractId,
|
|
187
|
+
oldBase: input.oldBase,
|
|
188
|
+
newBase: input.newBase,
|
|
189
|
+
oldHead: input.oldHead,
|
|
190
|
+
newHead: input.newHead,
|
|
191
|
+
ledgerHead: settlement.ledgerHead,
|
|
192
|
+
alreadyFresh: false,
|
|
193
|
+
sealed: settlement.sealed,
|
|
194
|
+
recoveryCleanup,
|
|
195
|
+
};
|
|
85
196
|
}
|
|
86
197
|
export async function renewContract(input) {
|
|
198
|
+
const repositoryRoot = await stableRepoRoot(input.cwd);
|
|
199
|
+
const worktreePath = await findContractWorktreePath(repositoryRoot, input.contractId);
|
|
200
|
+
const rewriteCwd = worktreePath ?? input.cwd;
|
|
201
|
+
if (await readRenewRecoverySession(repositoryRoot, input.contractId)) {
|
|
202
|
+
throw new FlowError("RENEW_SESSION_OPEN", `renew recovery session is open for ${input.contractId}`, {
|
|
203
|
+
facts: { kind: "renew_session", commission: input.contractId, nextAction: "continue-or-abort" },
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (input.resolveConflicts && !worktreePath) {
|
|
207
|
+
throw new FlowError("INTERNAL_STATE", `renew --resolve requires ${input.contractId}'s registered contract worktree`);
|
|
208
|
+
}
|
|
209
|
+
await assertCleanTrackedWorkingTree(rewriteCwd);
|
|
87
210
|
const ledger = await readLedger(input.cwd, input.contractId);
|
|
88
211
|
if (!ledger) {
|
|
89
212
|
throw new FlowError("INTERNAL_STATE", `contract ${input.contractId} not found or not active`);
|
|
@@ -102,6 +225,14 @@ export async function renewContract(input) {
|
|
|
102
225
|
throw new FlowError("INTERNAL_STATE", "ledger must contain bind entry");
|
|
103
226
|
const branch = `keiyaku/${input.contractId}`;
|
|
104
227
|
const oldHead = await resolveCommit(input.cwd, branch);
|
|
228
|
+
await assertRenewCoordinates({
|
|
229
|
+
cwd: repositoryRoot,
|
|
230
|
+
contractId: input.contractId,
|
|
231
|
+
oldBase,
|
|
232
|
+
oldHead,
|
|
233
|
+
targetHead,
|
|
234
|
+
entries: ledger.entries,
|
|
235
|
+
});
|
|
105
236
|
const capture = await captureSeal(input.cwd, ledger.entries, oldHead, input.waivePaths);
|
|
106
237
|
if (getMaxArc(ledger.entries) > 0 && !findOpenArc(ledger.entries)) {
|
|
107
238
|
const loose = await receiptsAfterFence(input.cwd, ledger.entries, oldHead);
|
|
@@ -118,51 +249,216 @@ export async function renewContract(input) {
|
|
|
118
249
|
ledgerHead: ledger.head,
|
|
119
250
|
alreadyFresh: true,
|
|
120
251
|
sealed: null,
|
|
252
|
+
recoveryCleanup: null,
|
|
121
253
|
};
|
|
122
254
|
}
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
await
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
255
|
+
const deliveryWorktree = worktreePath ?? repositoryRoot;
|
|
256
|
+
await assertNoInFlightProjection(repositoryRoot, input.contractId, deliveryWorktree, input.nowMs);
|
|
257
|
+
const recoveryRef = renewRecoveryRef(input.contractId, oldHead);
|
|
258
|
+
await createRecoveryRef(input.cwd, recoveryRef, oldHead);
|
|
259
|
+
if (input.resolveConflicts) {
|
|
260
|
+
await writeRenewRecoverySession(repositoryRoot, {
|
|
261
|
+
commission: input.contractId,
|
|
262
|
+
oldBase,
|
|
263
|
+
oldHead,
|
|
264
|
+
newBase: targetHead,
|
|
265
|
+
recoveryRef,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
await rewriteBranch({
|
|
270
|
+
cwd: rewriteCwd,
|
|
271
|
+
contractId: input.contractId,
|
|
272
|
+
oldHead,
|
|
273
|
+
recoveryRef,
|
|
274
|
+
newBase: targetHead,
|
|
275
|
+
oldBase,
|
|
276
|
+
branch: worktreePath ? undefined : branch,
|
|
277
|
+
preserveConflict: input.resolveConflicts,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
if (input.resolveConflicts && !(error instanceof FlowError && error.code === "RENEW_SESSION_OPEN")) {
|
|
282
|
+
await removeRenewRecoverySession(repositoryRoot, input.contractId);
|
|
141
283
|
}
|
|
142
|
-
|
|
143
|
-
v: 1,
|
|
144
|
-
kind: "renew",
|
|
145
|
-
contract: input.contractId,
|
|
146
|
-
at,
|
|
147
|
-
actor: input.actor,
|
|
148
|
-
data: { oldBase, newBase: targetHead, oldHead, newHead },
|
|
149
|
-
};
|
|
150
|
-
});
|
|
151
|
-
if (!result.ok) {
|
|
152
|
-
throw new FlowError("INTERNAL_STATE", `failed to append renew for ${input.contractId}: ${result.reason}`);
|
|
284
|
+
throw error;
|
|
153
285
|
}
|
|
154
|
-
await
|
|
155
|
-
return {
|
|
286
|
+
const newHead = await resolveCommit(input.cwd, branch);
|
|
287
|
+
return await finishRenew({
|
|
288
|
+
repositoryRoot,
|
|
289
|
+
rewriteCwd,
|
|
290
|
+
ledgerHead: ledger.head,
|
|
291
|
+
entries: ledger.entries,
|
|
156
292
|
contractId: input.contractId,
|
|
157
293
|
oldBase,
|
|
158
|
-
newBase: targetHead,
|
|
159
294
|
oldHead,
|
|
295
|
+
newBase: targetHead,
|
|
160
296
|
newHead,
|
|
161
|
-
|
|
297
|
+
recoveryRef,
|
|
298
|
+
actor: input.actor,
|
|
299
|
+
nowMs: input.nowMs,
|
|
300
|
+
capture,
|
|
301
|
+
afterLedgerCas: input.afterLedgerCas,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
async function revListRange(cwd, range) {
|
|
305
|
+
const git = createGit(cwd);
|
|
306
|
+
try {
|
|
307
|
+
return parseRevListOutput(await git.raw(["rev-list", "--reverse", range]));
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
throw wrapGitError(`rev-list ${range}`, error, cwd);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async function assertRecoveryFacts(repositoryRoot, contractId, session) {
|
|
314
|
+
if (session.commission !== contractId) {
|
|
315
|
+
throw new FlowError("INTERNAL_STATE", `renew recovery session belongs to ${session.commission}, not ${contractId}`);
|
|
316
|
+
}
|
|
317
|
+
const rewriteCwd = await findRegisteredContractWorktreePath(repositoryRoot, contractId);
|
|
318
|
+
if (!rewriteCwd)
|
|
319
|
+
throw new FlowError("INTERNAL_STATE", `registered contract worktree disappeared for ${contractId}`);
|
|
320
|
+
const ledger = await readLedger(repositoryRoot, contractId);
|
|
321
|
+
if (!ledger)
|
|
322
|
+
throw new FlowError("INTERNAL_STATE", `contract ${contractId} not found or not active`);
|
|
323
|
+
const savedHead = await resolveCommit(repositoryRoot, session.recoveryRef);
|
|
324
|
+
if (savedHead !== session.oldHead || latestBase(ledger.entries) !== session.oldBase) {
|
|
325
|
+
throw new FlowError("RENEW_SESSION_OPEN", `renew recovery session facts no longer match the owned rewrite for ${contractId}`, {
|
|
326
|
+
facts: { kind: "renew_session", commission: contractId, nextAction: "abort" },
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
return { ledger, rewriteCwd };
|
|
330
|
+
}
|
|
331
|
+
async function resultFromSpentSession(repositoryRoot, spent) {
|
|
332
|
+
const seal = spent.seal;
|
|
333
|
+
const sealed = seal ? {
|
|
334
|
+
...seal.data,
|
|
335
|
+
scopeViolationEvidence: [],
|
|
336
|
+
ledgerHead: await resolveCommit(repositoryRoot, `${spent.ledger.head}^`),
|
|
337
|
+
} : null;
|
|
338
|
+
return {
|
|
339
|
+
contractId: spent.session.commission,
|
|
340
|
+
...spent.renew.data,
|
|
341
|
+
ledgerHead: spent.ledger.head,
|
|
162
342
|
alreadyFresh: false,
|
|
163
343
|
sealed,
|
|
344
|
+
recoveryCleanup: spent.recoveryCleanup,
|
|
164
345
|
};
|
|
165
346
|
}
|
|
347
|
+
export async function continueRenewContract(input) {
|
|
348
|
+
const repositoryRoot = await stableRepoRoot(input.cwd);
|
|
349
|
+
const sessionState = await convergeRenewRecoverySession(repositoryRoot, input.contractId);
|
|
350
|
+
if (sessionState.state === "spent")
|
|
351
|
+
return await resultFromSpentSession(repositoryRoot, sessionState);
|
|
352
|
+
if (sessionState.state === "none") {
|
|
353
|
+
throw new FlowError("RENEW_SESSION_NOT_FOUND", `no renew recovery session is open for ${input.contractId}`);
|
|
354
|
+
}
|
|
355
|
+
const session = sessionState.session;
|
|
356
|
+
const { ledger, rewriteCwd } = await assertRecoveryFacts(repositoryRoot, input.contractId, session);
|
|
357
|
+
const delivery = await revListRange(repositoryRoot, `${session.oldBase}..${session.oldHead}`);
|
|
358
|
+
if (await hasActiveRebase(rewriteCwd)) {
|
|
359
|
+
const stoppedAt = await resolveCommitOrNull(rewriteCwd, "REBASE_HEAD");
|
|
360
|
+
if (!stoppedAt) {
|
|
361
|
+
throw new FlowError("RENEW_SESSION_OPEN", `owned rebase state has no stopped receipt for ${input.contractId}`, {
|
|
362
|
+
facts: { kind: "renew_session", commission: input.contractId, nextAction: "abort" },
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
const stoppedIndex = delivery.indexOf(stoppedAt);
|
|
366
|
+
const rewrittenPrefix = await revListRange(rewriteCwd, `${session.newBase}..HEAD`);
|
|
367
|
+
if (stoppedIndex < 0 || rewrittenPrefix.length !== stoppedIndex) {
|
|
368
|
+
throw new FlowError("RENEW_SESSION_OPEN", `loose commits do not belong to the owned renew rebase for ${input.contractId}`, {
|
|
369
|
+
facts: { kind: "renew_session", commission: input.contractId, nextAction: "continue-or-abort" },
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
const continued = await runGitProcess(rewriteCwd, ["rebase", "--continue"], {
|
|
373
|
+
env: { GIT_EDITOR: "true" },
|
|
374
|
+
});
|
|
375
|
+
if (continued.status !== 0) {
|
|
376
|
+
const error = continued.error ?? { message: "git rebase --continue failed", stderr: continued.stderr, stdout: continued.stdout };
|
|
377
|
+
if (errorContainsAnyPattern(error, ["CONFLICT", "could not apply", "Resolve all conflicts manually"])) {
|
|
378
|
+
throw new FlowError("RENEW_SESSION_OPEN", `renew recovery session is open for ${input.contractId}`, {
|
|
379
|
+
cause: error,
|
|
380
|
+
facts: { kind: "renew_session", commission: input.contractId, nextAction: "resolve-conflicts" },
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
throw wrapGitError("rebase --continue", error, rewriteCwd);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
const newHead = await resolveCommit(repositoryRoot, `keiyaku/${input.contractId}`);
|
|
387
|
+
const rewritten = await revListRange(repositoryRoot, `${session.newBase}..${newHead}`);
|
|
388
|
+
if (await mergeBase(repositoryRoot, session.newBase, newHead) !== session.newBase || rewritten.length !== delivery.length) {
|
|
389
|
+
throw new FlowError("RENEW_SESSION_OPEN", `rewritten delivery no longer corresponds to the saved renew receipts for ${input.contractId}`, {
|
|
390
|
+
facts: { kind: "renew_session", commission: input.contractId, nextAction: "abort" },
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
const capture = await captureRenewSeal({
|
|
394
|
+
cwd: repositoryRoot,
|
|
395
|
+
entries: ledger.entries,
|
|
396
|
+
receiptHead: session.oldHead,
|
|
397
|
+
contentBase: session.newBase,
|
|
398
|
+
contentHead: newHead,
|
|
399
|
+
waivePaths: input.waivePaths,
|
|
400
|
+
});
|
|
401
|
+
return await finishRenew({
|
|
402
|
+
repositoryRoot,
|
|
403
|
+
rewriteCwd,
|
|
404
|
+
ledgerHead: ledger.head,
|
|
405
|
+
entries: ledger.entries,
|
|
406
|
+
contractId: input.contractId,
|
|
407
|
+
oldBase: session.oldBase,
|
|
408
|
+
oldHead: session.oldHead,
|
|
409
|
+
newBase: session.newBase,
|
|
410
|
+
newHead,
|
|
411
|
+
recoveryRef: session.recoveryRef,
|
|
412
|
+
actor: input.actor,
|
|
413
|
+
nowMs: input.nowMs,
|
|
414
|
+
capture,
|
|
415
|
+
afterLedgerCas: input.afterLedgerCas,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
export async function abortRenewContract(input) {
|
|
419
|
+
const repositoryRoot = await stableRepoRoot(input.cwd);
|
|
420
|
+
const sessionState = await convergeRenewRecoverySession(repositoryRoot, input.contractId);
|
|
421
|
+
if (sessionState.state !== "live") {
|
|
422
|
+
throw new FlowError("RENEW_SESSION_NOT_FOUND", `no renew recovery session is open for ${input.contractId}`);
|
|
423
|
+
}
|
|
424
|
+
const session = sessionState.session;
|
|
425
|
+
const { rewriteCwd } = await assertRecoveryFacts(repositoryRoot, input.contractId, session);
|
|
426
|
+
const git = createGit(rewriteCwd);
|
|
427
|
+
if (await hasActiveRebase(rewriteCwd)) {
|
|
428
|
+
try {
|
|
429
|
+
await git.raw(["rebase", "--abort"]);
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
throw wrapGitError("rebase --abort", error, rewriteCwd);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
let branch;
|
|
436
|
+
try {
|
|
437
|
+
branch = (await git.raw(["symbolic-ref", "--quiet", "--short", "HEAD"])).trim();
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
branch = undefined;
|
|
441
|
+
}
|
|
442
|
+
const expectedBranch = `keiyaku/${input.contractId}`;
|
|
443
|
+
if (branch !== expectedBranch) {
|
|
444
|
+
try {
|
|
445
|
+
await git.raw(["switch", expectedBranch]);
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
throw wrapGitError(`switch ${expectedBranch}`, error, rewriteCwd);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
try {
|
|
452
|
+
await git.raw(["reset", "--hard", session.oldHead]);
|
|
453
|
+
}
|
|
454
|
+
catch (error) {
|
|
455
|
+
throw wrapGitError(`reset --hard ${session.recoveryRef}`, error, rewriteCwd);
|
|
456
|
+
}
|
|
457
|
+
await assertCleanTrackedWorkingTree(rewriteCwd);
|
|
458
|
+
await removeRenewRecoverySession(repositoryRoot, input.contractId);
|
|
459
|
+
const recoveryCleanup = await deleteRecoveryRef(repositoryRoot, session.recoveryRef, session.oldHead);
|
|
460
|
+
return { contractId: input.contractId, oldHead: session.oldHead, recoveryCleanup };
|
|
461
|
+
}
|
|
166
462
|
export async function renewKeiyaku(input) {
|
|
167
463
|
await requireGitRepository(input.cwd, "renew");
|
|
168
464
|
const address = input.address ?? await resolveContractAddress(input.cwd, input.contractId, input.contractAddressSource);
|
|
@@ -174,47 +470,78 @@ export async function renewKeiyaku(input) {
|
|
|
174
470
|
actor: ACTOR_IDENTITY,
|
|
175
471
|
nowMs: Date.now(),
|
|
176
472
|
waivePaths: input.waivePaths,
|
|
473
|
+
resolveConflicts: input.resolveConflicts,
|
|
177
474
|
});
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
475
|
+
return await buildRenewOutcome(input.cwd, address, renewed);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
async function buildRenewOutcome(cwd, address, renewed) {
|
|
479
|
+
const contractId = address.binding.commissionId;
|
|
480
|
+
const currentBranch = await getCurrentBranch(cwd);
|
|
481
|
+
const baseBranch = address.target.branch.slice("refs/heads/".length);
|
|
482
|
+
const summary = renewed.alreadyFresh
|
|
483
|
+
? `Contract ${contractId} is already fresh; nothing touched.`
|
|
484
|
+
: `Contract ${contractId} renewed onto ${renewed.newBase}.`;
|
|
485
|
+
const cleanupWarnings = renewed.recoveryCleanup?.status === "retained"
|
|
486
|
+
? [`Renew succeeded, but recovery ref ${renewed.recoveryCleanup.ref} was retained: ${renewed.recoveryCleanup.diagnostic}`]
|
|
487
|
+
: [];
|
|
488
|
+
let responsePath;
|
|
489
|
+
let artifactId;
|
|
490
|
+
try {
|
|
491
|
+
const persisted = await persistResponseHistory({
|
|
492
|
+
cwd,
|
|
493
|
+
tool: "renew",
|
|
494
|
+
provenance: { authority: { kind: "repository" }, binding: address.binding, evidenceCwd: cwd },
|
|
495
|
+
title: contractId,
|
|
496
|
+
oldBase: renewed.oldBase,
|
|
497
|
+
newBase: renewed.newBase,
|
|
498
|
+
oldHead: renewed.oldHead,
|
|
499
|
+
newHead: renewed.newHead,
|
|
500
|
+
ledgerCommit: renewed.ledgerHead,
|
|
501
|
+
summary,
|
|
502
|
+
emptyDiffLabel: "nothing sealed",
|
|
503
|
+
...(renewed.sealed ? { sealed: renewed.sealed } : {}),
|
|
504
|
+
});
|
|
505
|
+
responsePath = persisted.responsePath;
|
|
506
|
+
artifactId = persisted.artifactId;
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
responsePath = undefined;
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
status: "success",
|
|
513
|
+
...renewed,
|
|
514
|
+
currentBranch,
|
|
515
|
+
baseBranch,
|
|
516
|
+
// CLI/render synthesizes public face bytes from sealed typed facts.
|
|
517
|
+
diff: "",
|
|
518
|
+
sealed: renewed.sealed ?? undefined,
|
|
519
|
+
summary,
|
|
520
|
+
...(cleanupWarnings.length > 0 ? { meta: { warnings: cleanupWarnings } } : {}),
|
|
521
|
+
responsePath,
|
|
522
|
+
artifactId,
|
|
523
|
+
address,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
export async function continueRenewKeiyaku(input) {
|
|
527
|
+
await requireGitRepository(input.cwd, "renew --continue");
|
|
528
|
+
return await withResolvedAddress(input.address, async () => buildRenewOutcome(input.cwd, input.address, await continueRenewContract({
|
|
529
|
+
cwd: input.cwd,
|
|
530
|
+
contractId: input.address.binding.commissionId,
|
|
531
|
+
actor: ACTOR_IDENTITY,
|
|
532
|
+
nowMs: Date.now(),
|
|
533
|
+
waivePaths: input.waivePaths,
|
|
534
|
+
})));
|
|
535
|
+
}
|
|
536
|
+
export async function abortRenewKeiyaku(input) {
|
|
537
|
+
await requireGitRepository(input.cwd, "renew --abort");
|
|
538
|
+
return await withResolvedAddress(input.address, async () => {
|
|
539
|
+
const result = await abortRenewContract({ cwd: input.cwd, contractId: input.address.binding.commissionId });
|
|
207
540
|
return {
|
|
208
541
|
status: "success",
|
|
209
|
-
...
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
diff,
|
|
213
|
-
sealed: renewed.sealed ?? undefined,
|
|
214
|
-
summary,
|
|
215
|
-
responsePath,
|
|
216
|
-
artifactId,
|
|
217
|
-
address,
|
|
542
|
+
...result,
|
|
543
|
+
address: input.address,
|
|
544
|
+
summary: `Renew recovery for ${result.contractId} aborted; delivery restored to ${result.oldHead}.`,
|
|
218
545
|
};
|
|
219
546
|
});
|
|
220
547
|
}
|