@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/scope.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import * as fs from "node:fs/promises";
|
|
3
|
-
import * as os from "node:os";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import { createGit, wrapGitError } from "../git/core.js";
|
|
6
1
|
export class ScopePatternError extends Error {
|
|
7
2
|
code = "INVALID_SCOPE_PATTERN";
|
|
8
3
|
constructor(message) {
|
|
@@ -41,9 +36,9 @@ export function isBlankScopePatternLine(line) {
|
|
|
41
36
|
return canonicalizeScopePatternInput(line).length === 0;
|
|
42
37
|
}
|
|
43
38
|
/**
|
|
44
|
-
* Canonicalize a scope
|
|
39
|
+
* Canonicalize a scope Gitignore-like pattern for matching and persistence.
|
|
45
40
|
* Strips only a cosmetic leading `./` (including after `!`); preserves meaningful
|
|
46
|
-
* leading `/` anchoring,
|
|
41
|
+
* leading `/` anchoring, supported backslash escapes, and escaped trailing spaces.
|
|
47
42
|
*/
|
|
48
43
|
export function normalizeScopePattern(pattern) {
|
|
49
44
|
if (pattern.includes("\0") || pattern.includes("\n") || pattern.includes("\r")) {
|
|
@@ -78,75 +73,157 @@ export function normalizeScopePath(filePath) {
|
|
|
78
73
|
throw new ScopePatternError("scope path cannot contain NUL");
|
|
79
74
|
return normalized;
|
|
80
75
|
}
|
|
81
|
-
function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
76
|
+
function splitPatternComponents(pattern) {
|
|
77
|
+
const components = [];
|
|
78
|
+
let component = "";
|
|
79
|
+
let escaped = false;
|
|
80
|
+
for (const character of pattern) {
|
|
81
|
+
if (escaped) {
|
|
82
|
+
component += `\\${character}`;
|
|
83
|
+
escaped = false;
|
|
84
|
+
}
|
|
85
|
+
else if (character === "\\") {
|
|
86
|
+
escaped = true;
|
|
87
|
+
}
|
|
88
|
+
else if (character === "/") {
|
|
89
|
+
components.push(component);
|
|
90
|
+
component = "";
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
component += character;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (escaped)
|
|
97
|
+
component += "\\\\";
|
|
98
|
+
components.push(component);
|
|
99
|
+
return components;
|
|
100
|
+
}
|
|
101
|
+
function parseScopePattern(pattern) {
|
|
102
|
+
const normalized = normalizeScopePattern(pattern);
|
|
103
|
+
const escapedLeading = normalized.startsWith("\\!") || normalized.startsWith("\\#");
|
|
104
|
+
const negative = normalized.startsWith("!");
|
|
105
|
+
const body = negative ? normalized.slice(1) : normalized;
|
|
106
|
+
const comment = !escapedLeading && body.startsWith("#");
|
|
107
|
+
const anchored = body.startsWith("/");
|
|
108
|
+
const unanchored = anchored ? body.slice(1) : body;
|
|
109
|
+
const directory = unanchored.endsWith("/");
|
|
110
|
+
const source = directory ? unanchored.slice(0, -1) : unanchored;
|
|
111
|
+
const segments = splitPatternComponents(source);
|
|
112
|
+
return { negative, comment, directory, segments, componentOnly: !anchored && !source.includes("/") };
|
|
113
|
+
}
|
|
114
|
+
function componentMatches(pattern, value) {
|
|
115
|
+
let expression = "^";
|
|
116
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
117
|
+
const character = pattern[index];
|
|
118
|
+
if (character === "\\") {
|
|
119
|
+
index += 1;
|
|
120
|
+
expression += escapeRegex(pattern[index] ?? "\\");
|
|
121
|
+
}
|
|
122
|
+
else if (character === "*") {
|
|
123
|
+
if (pattern[index + 1] === "*") {
|
|
124
|
+
expression += ".*";
|
|
125
|
+
index += 1;
|
|
126
|
+
}
|
|
127
|
+
else
|
|
128
|
+
expression += "[^/]*";
|
|
129
|
+
}
|
|
130
|
+
else if (character === "?")
|
|
131
|
+
expression += "[^/]";
|
|
132
|
+
else if (character === "[") {
|
|
133
|
+
const close = pattern.indexOf("]", index + 1);
|
|
134
|
+
if (close === -1)
|
|
135
|
+
expression += "\\[";
|
|
136
|
+
else {
|
|
137
|
+
const rawClass = pattern.slice(index + 1, close);
|
|
138
|
+
const classBody = rawClass.startsWith("!") ? `^${rawClass.slice(1)}` : rawClass;
|
|
139
|
+
expression += `[${classBody.replace(/\\/g, "\\\\")}]`;
|
|
140
|
+
index = close;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else
|
|
144
|
+
expression += escapeRegex(character);
|
|
145
|
+
}
|
|
146
|
+
return new RegExp(`${expression}$`).test(value);
|
|
147
|
+
}
|
|
148
|
+
function escapeRegex(value) {
|
|
149
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
150
|
+
}
|
|
151
|
+
function patternMatchesPath(parsed, filePath) {
|
|
152
|
+
if (parsed.comment)
|
|
153
|
+
return false;
|
|
154
|
+
const pathSegments = filePath.split("/");
|
|
155
|
+
if (parsed.componentOnly) {
|
|
156
|
+
const lastMatchIndex = parsed.directory ? pathSegments.length - 1 : pathSegments.length;
|
|
157
|
+
return pathSegments.slice(0, lastMatchIndex).some((segment) => componentMatches(parsed.segments[0], segment));
|
|
158
|
+
}
|
|
159
|
+
const memo = new Map();
|
|
160
|
+
const matchesFrom = (patternIndex, pathIndex) => {
|
|
161
|
+
const key = `${patternIndex}:${pathIndex}`;
|
|
162
|
+
const cached = memo.get(key);
|
|
163
|
+
if (cached !== undefined)
|
|
164
|
+
return cached;
|
|
165
|
+
let matched;
|
|
166
|
+
if (patternIndex === parsed.segments.length) {
|
|
167
|
+
matched = parsed.directory ? pathIndex < pathSegments.length : pathIndex === pathSegments.length;
|
|
168
|
+
memo.set(key, matched);
|
|
169
|
+
return matched;
|
|
170
|
+
}
|
|
171
|
+
const segment = parsed.segments[patternIndex];
|
|
172
|
+
if (segment === "**") {
|
|
173
|
+
matched = false;
|
|
174
|
+
for (let nextPathIndex = pathIndex; nextPathIndex <= pathSegments.length; nextPathIndex += 1) {
|
|
175
|
+
if (matchesFrom(patternIndex + 1, nextPathIndex)) {
|
|
176
|
+
matched = true;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
116
179
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
matched = pathIndex < pathSegments.length
|
|
183
|
+
&& componentMatches(segment, pathSegments[pathIndex])
|
|
184
|
+
&& matchesFrom(patternIndex + 1, pathIndex + 1);
|
|
185
|
+
}
|
|
186
|
+
memo.set(key, matched);
|
|
187
|
+
return matched;
|
|
188
|
+
};
|
|
189
|
+
return matchesFrom(0, 0);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Evaluate the settled ordered Gitignore-like scope subset without invoking Git.
|
|
193
|
+
*/
|
|
194
|
+
export async function scopePathEvidence(_cwd, patterns, filePaths) {
|
|
195
|
+
const normalizedPatterns = patterns.map(normalizeScopePattern);
|
|
196
|
+
const normalizedPaths = filePaths.map(normalizeScopePath);
|
|
197
|
+
const parsedPatterns = normalizedPatterns.map(parseScopePattern);
|
|
198
|
+
return normalizedPaths.map((normalizedPath) => {
|
|
199
|
+
const pathDecisions = parsedPatterns.flatMap((parsed, index) => {
|
|
200
|
+
if (!patternMatchesPath(parsed, normalizedPath))
|
|
201
|
+
return [];
|
|
202
|
+
const effect = parsed.negative ? "exclude" : "include";
|
|
203
|
+
return [{ index, pattern: normalizedPatterns[index], effect, matchedAfter: effect === "include" }];
|
|
121
204
|
});
|
|
122
|
-
|
|
205
|
+
const decisivePattern = pathDecisions.at(-1);
|
|
206
|
+
const hasPositiveMatch = pathDecisions.some((decision) => decision.effect === "include");
|
|
207
|
+
const matched = decisivePattern?.matchedAfter ?? false;
|
|
208
|
+
return {
|
|
209
|
+
path: normalizedPath,
|
|
210
|
+
patterns: pathDecisions,
|
|
211
|
+
matched,
|
|
212
|
+
outcome: matched ? "matched" : hasPositiveMatch ? "excluded" : "no-positive-match",
|
|
213
|
+
...(decisivePattern ? { decisivePattern } : {}),
|
|
214
|
+
};
|
|
123
215
|
});
|
|
124
216
|
}
|
|
125
217
|
export async function pathsMatchingScope(cwd, patterns, filePaths) {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
if (normalizedPatterns.length === 0 || normalizedPaths.length === 0)
|
|
129
|
-
return new Set();
|
|
130
|
-
const temporaryRoot = await fs.mkdtemp(path.join(os.tmpdir(), "keiyaku-scope-"));
|
|
131
|
-
const gitDir = path.join(temporaryRoot, "scope.git");
|
|
132
|
-
const workTree = path.join(temporaryRoot, "worktree");
|
|
133
|
-
try {
|
|
134
|
-
await Promise.all([fs.mkdir(gitDir), fs.mkdir(workTree)]);
|
|
135
|
-
await createGit(gitDir).init(true);
|
|
136
|
-
await fs.writeFile(path.join(gitDir, "info", "exclude"), `${normalizedPatterns.join("\n")}\n`, "utf8");
|
|
137
|
-
return await runCheckIgnore(gitDir, workTree, cwd, normalizedPaths);
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
await fs.rm(temporaryRoot, { recursive: true, force: true });
|
|
141
|
-
}
|
|
218
|
+
const evidence = await scopePathEvidence(cwd, patterns, filePaths);
|
|
219
|
+
return new Set(evidence.filter((item) => item.matched).map((item) => item.path));
|
|
142
220
|
}
|
|
143
221
|
export function isNegativeScopePattern(pattern) {
|
|
144
222
|
return normalizeScopePattern(pattern).startsWith("!");
|
|
145
223
|
}
|
|
146
224
|
/**
|
|
147
|
-
* Parse only the subset whose path language can be proved statically:
|
|
148
|
-
* segments, `*` segments, and `**` segments.
|
|
149
|
-
* syntax is left to Git and produces no advisory warning.
|
|
225
|
+
* Parse only the positive subset whose path language can be proved statically:
|
|
226
|
+
* literal segments, `*` segments, and `**` segments.
|
|
150
227
|
*/
|
|
151
228
|
function staticScopeSegments(pattern) {
|
|
152
229
|
const positive = normalizeScopePattern(pattern);
|
package/build/core/seal.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as fs from "node:fs/promises";
|
|
2
|
-
import * as path from "node:path";
|
|
3
1
|
import { FlowError } from "../flow-error.js";
|
|
4
|
-
import { createGit, wrapGitError } from "../git/core.js";
|
|
2
|
+
import { createGit, parseRevListOutput, wrapGitError } from "../git/core.js";
|
|
5
3
|
import { KEIYAKU_FILE } from "../keiyaku.js";
|
|
4
|
+
import { formatLedgerEntryCommitMessage } from "./entry.js";
|
|
6
5
|
import { activeLedgerRef, appendWithRetry, readLedger } from "./ledger.js";
|
|
7
|
-
import {
|
|
8
|
-
import { normalizeScopePath,
|
|
6
|
+
import { refreshContractView } from "./contract-view.js";
|
|
7
|
+
import { normalizeScopePath, scopePathEvidence, } from "./scope.js";
|
|
9
8
|
import { deriveContractState, isTerminalState } from "./status/lifecycle.js";
|
|
9
|
+
import { casUpdateRefLog, createRefLogCommit } from "./ref-log.js";
|
|
10
10
|
function findBind(entries) {
|
|
11
11
|
const bind = entries.find((entry) => entry.kind === "bind");
|
|
12
12
|
if (!bind)
|
|
@@ -64,10 +64,7 @@ async function resolveCommit(cwd, revision) {
|
|
|
64
64
|
async function revList(cwd, from, to) {
|
|
65
65
|
const git = createGit(cwd);
|
|
66
66
|
try {
|
|
67
|
-
return (await git.raw(["rev-list", "--reverse", `${from}..${to}`]))
|
|
68
|
-
.split(/\r?\n/)
|
|
69
|
-
.map((line) => line.trim())
|
|
70
|
-
.filter(Boolean);
|
|
67
|
+
return parseRevListOutput(await git.raw(["rev-list", "--reverse", `${from}..${to}`]));
|
|
71
68
|
}
|
|
72
69
|
catch (error) {
|
|
73
70
|
throw wrapGitError(`rev-list ${from}..${to}`, error, cwd);
|
|
@@ -104,8 +101,37 @@ async function diffstat(cwd, from, to) {
|
|
|
104
101
|
}
|
|
105
102
|
async function scopeViolations(cwd, paths, scope) {
|
|
106
103
|
const auditedPaths = paths.filter((changedPath) => changedPath !== KEIYAKU_FILE);
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
return (await scopePathEvidence(cwd, scope, auditedPaths)).filter((evidence) => !evidence.matched);
|
|
105
|
+
}
|
|
106
|
+
async function auditScope(cwd, entries, paths, waivePaths) {
|
|
107
|
+
const scope = effectiveScope(entries);
|
|
108
|
+
const scopeViolationEvidence = await scopeViolations(cwd, paths, scope);
|
|
109
|
+
const waivedPaths = new Set(waivePaths.map(normalizeScopePath));
|
|
110
|
+
const unwaived = scopeViolationEvidence.filter((violation) => !waivedPaths.has(violation.path));
|
|
111
|
+
if (unwaived.length > 0) {
|
|
112
|
+
throw new ScopeAuditError(findBind(entries).contract, scope, unwaived);
|
|
113
|
+
}
|
|
114
|
+
const violations = scopeViolationEvidence.map((violation) => violation.path);
|
|
115
|
+
return {
|
|
116
|
+
scopeAudit: { violations, waived: violations.length > 0 },
|
|
117
|
+
scopeViolationEvidence,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export class ScopeAuditError extends FlowError {
|
|
121
|
+
scopeViolationEvidence;
|
|
122
|
+
constructor(_contractId, scope, evidence) {
|
|
123
|
+
const count = evidence.length;
|
|
124
|
+
const fileLabel = count === 1 ? "file" : "files";
|
|
125
|
+
super("SCOPE_VIOLATION", `scope violation — ${count} ${fileLabel} outside declared scope`, {
|
|
126
|
+
facts: {
|
|
127
|
+
kind: "scope_violation",
|
|
128
|
+
scope: [...scope],
|
|
129
|
+
violations: evidence,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
this.name = "ScopeAuditError";
|
|
133
|
+
this.scopeViolationEvidence = evidence;
|
|
134
|
+
}
|
|
109
135
|
}
|
|
110
136
|
function assertOperable(contractId, entries) {
|
|
111
137
|
const state = deriveContractState(entries);
|
|
@@ -127,11 +153,10 @@ export function currentSealArc(entries) {
|
|
|
127
153
|
}
|
|
128
154
|
/** Stable read-only coordinate naming the receipt source a petition would seal. */
|
|
129
155
|
export function petitionSealSource(entries) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
: `a${arc} · fence ${fence}▸HEAD`;
|
|
156
|
+
return {
|
|
157
|
+
arc: currentSealArc(entries),
|
|
158
|
+
fence: getFence(entries),
|
|
159
|
+
};
|
|
135
160
|
}
|
|
136
161
|
/** Shared read-only owner for the seal capture and its compact changed-path evidence. */
|
|
137
162
|
export async function previewSeal(cwd, entries, head = "HEAD", waivePaths = []) {
|
|
@@ -145,13 +170,7 @@ export async function previewSeal(cwd, entries, head = "HEAD", waivePaths = [])
|
|
|
145
170
|
changedPaths(cwd, oldFence, newFence),
|
|
146
171
|
diffstat(cwd, oldFence, newFence),
|
|
147
172
|
]);
|
|
148
|
-
const
|
|
149
|
-
const violations = await scopeViolations(cwd, paths, scope);
|
|
150
|
-
const waivedPaths = new Set(waivePaths.map(normalizeScopePath));
|
|
151
|
-
const unwaived = violations.filter((violation) => !waivedPaths.has(violation));
|
|
152
|
-
if (unwaived.length > 0) {
|
|
153
|
-
throw new FlowError("INTERNAL_STATE", `scope audit failed for contract ${findBind(entries).contract}: paths ${unwaived.join(", ")} outside ${scope.join(", ")}`);
|
|
154
|
-
}
|
|
173
|
+
const scopeAudit = await auditScope(cwd, entries, paths, waivePaths);
|
|
155
174
|
return {
|
|
156
175
|
capture: {
|
|
157
176
|
arc,
|
|
@@ -159,7 +178,7 @@ export async function previewSeal(cwd, entries, head = "HEAD", waivePaths = [])
|
|
|
159
178
|
newFence,
|
|
160
179
|
receipts,
|
|
161
180
|
diffstat: stat,
|
|
162
|
-
scopeAudit
|
|
181
|
+
...scopeAudit,
|
|
163
182
|
},
|
|
164
183
|
paths,
|
|
165
184
|
};
|
|
@@ -167,12 +186,30 @@ export async function previewSeal(cwd, entries, head = "HEAD", waivePaths = [])
|
|
|
167
186
|
export async function captureSeal(cwd, entries, head = "HEAD", waivePaths = []) {
|
|
168
187
|
return (await previewSeal(cwd, entries, head, waivePaths)).capture;
|
|
169
188
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
189
|
+
/** Preserve original receipt hashes while auditing the rebased delivery content. */
|
|
190
|
+
export async function captureRenewSeal(input) {
|
|
191
|
+
const arc = currentSealArc(input.entries);
|
|
192
|
+
if (arc === null)
|
|
193
|
+
return null;
|
|
194
|
+
const oldFence = getFence(input.entries);
|
|
195
|
+
const [receiptHead, contentBase, contentHead] = await Promise.all([
|
|
196
|
+
resolveCommit(input.cwd, input.receiptHead),
|
|
197
|
+
resolveCommit(input.cwd, input.contentBase),
|
|
198
|
+
resolveCommit(input.cwd, input.contentHead),
|
|
199
|
+
]);
|
|
200
|
+
const [receipts, paths, stat] = await Promise.all([
|
|
201
|
+
revList(input.cwd, oldFence, receiptHead),
|
|
202
|
+
changedPaths(input.cwd, contentBase, contentHead),
|
|
203
|
+
diffstat(input.cwd, contentBase, contentHead),
|
|
204
|
+
]);
|
|
205
|
+
return {
|
|
206
|
+
arc,
|
|
207
|
+
oldFence,
|
|
208
|
+
newFence: receiptHead,
|
|
209
|
+
receipts,
|
|
210
|
+
diffstat: stat,
|
|
211
|
+
...await auditScope(input.cwd, input.entries, paths, input.waivePaths ?? []),
|
|
212
|
+
};
|
|
176
213
|
}
|
|
177
214
|
export async function sealCurrentArc(input) {
|
|
178
215
|
const ledger = await readLedger(input.cwd, input.contractId);
|
|
@@ -196,25 +233,92 @@ export async function sealCurrentArc(input) {
|
|
|
196
233
|
if (currentArc !== capture.arc || getFence(entries) !== capture.oldFence) {
|
|
197
234
|
throw new FlowError("INTERNAL_STATE", `contract ${input.contractId} changed while sealing arc a${capture.arc}`);
|
|
198
235
|
}
|
|
236
|
+
const { scopeViolationEvidence: _scopeViolationEvidence, ...durableCapture } = capture;
|
|
199
237
|
return {
|
|
200
238
|
v: 1,
|
|
201
239
|
kind: "seal",
|
|
202
240
|
contract: input.contractId,
|
|
203
241
|
at,
|
|
204
242
|
actor: "engine",
|
|
205
|
-
data: { ...
|
|
243
|
+
data: { ...durableCapture, sealedBy: input.sealedBy },
|
|
206
244
|
};
|
|
207
245
|
});
|
|
208
246
|
if (!result.ok) {
|
|
209
247
|
throw new FlowError("INTERNAL_STATE", `failed to seal arc for ${input.contractId}: ${result.reason}`);
|
|
210
248
|
}
|
|
211
|
-
await
|
|
249
|
+
await refreshContractView({
|
|
250
|
+
ledgerCwd: input.cwd,
|
|
251
|
+
renderCwd: input.renderCwd,
|
|
252
|
+
contractId: input.contractId,
|
|
253
|
+
});
|
|
212
254
|
return {
|
|
213
255
|
...capture,
|
|
214
256
|
sealedBy: input.sealedBy,
|
|
215
257
|
ledgerHead: result.head,
|
|
216
|
-
incrementalDiff: capture.receipts.length === 0
|
|
217
|
-
? "nothing sealed"
|
|
218
|
-
: `${capture.receipts.length} receipt${capture.receipts.length === 1 ? "" : "s"} · +${capture.diffstat.insertions} −${capture.diffstat.deletions}`,
|
|
219
258
|
};
|
|
220
259
|
}
|
|
260
|
+
function splitLedgerMessage(entry) {
|
|
261
|
+
const message = formatLedgerEntryCommitMessage(entry);
|
|
262
|
+
const separator = message.indexOf("\n\n");
|
|
263
|
+
return { subject: message.slice(0, separator), body: message.slice(separator + 2).trimEnd() };
|
|
264
|
+
}
|
|
265
|
+
export async function appendRenewSettlement(input) {
|
|
266
|
+
const ledger = await readLedger(input.cwd, input.contractId);
|
|
267
|
+
if (!ledger || ledger.head !== input.expectedLedgerHead) {
|
|
268
|
+
throw new FlowError("CONCURRENT_MODIFICATION", `contract ${input.contractId} changed while renewing`);
|
|
269
|
+
}
|
|
270
|
+
assertOperable(input.contractId, ledger.entries);
|
|
271
|
+
if (input.capture && (currentSealArc(ledger.entries) !== input.capture.arc || getFence(ledger.entries) !== input.capture.oldFence)) {
|
|
272
|
+
throw new FlowError("CONCURRENT_MODIFICATION", `contract ${input.contractId} changed while renewing`);
|
|
273
|
+
}
|
|
274
|
+
const at = new Date(input.nowMs).toISOString();
|
|
275
|
+
let parentHead = ledger.head;
|
|
276
|
+
let sealHead;
|
|
277
|
+
if (input.capture) {
|
|
278
|
+
const { scopeViolationEvidence: _evidence, ...durableCapture } = input.capture;
|
|
279
|
+
const sealEntry = {
|
|
280
|
+
v: 1,
|
|
281
|
+
kind: "seal",
|
|
282
|
+
contract: input.contractId,
|
|
283
|
+
at,
|
|
284
|
+
actor: "engine",
|
|
285
|
+
data: { ...durableCapture, newFence: input.newHead, sealedBy: "renew" },
|
|
286
|
+
};
|
|
287
|
+
const message = splitLedgerMessage(sealEntry);
|
|
288
|
+
sealHead = await createRefLogCommit(input.cwd, {
|
|
289
|
+
...message,
|
|
290
|
+
parentHead,
|
|
291
|
+
errorLabel: `ledger seal ${input.contractId}`,
|
|
292
|
+
});
|
|
293
|
+
parentHead = sealHead;
|
|
294
|
+
}
|
|
295
|
+
const renewEntry = {
|
|
296
|
+
v: 1,
|
|
297
|
+
kind: "renew",
|
|
298
|
+
contract: input.contractId,
|
|
299
|
+
at,
|
|
300
|
+
actor: input.actor,
|
|
301
|
+
data: {
|
|
302
|
+
oldBase: input.oldBase,
|
|
303
|
+
newBase: input.newBase,
|
|
304
|
+
oldHead: input.oldHead,
|
|
305
|
+
newHead: input.newHead,
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
const message = splitLedgerMessage(renewEntry);
|
|
309
|
+
const renewHead = await createRefLogCommit(input.cwd, {
|
|
310
|
+
...message,
|
|
311
|
+
parentHead,
|
|
312
|
+
errorLabel: `ledger renew ${input.contractId}`,
|
|
313
|
+
});
|
|
314
|
+
if (!await casUpdateRefLog(input.cwd, activeLedgerRef(input.contractId), renewHead, ledger.head)) {
|
|
315
|
+
throw new FlowError("CONCURRENT_MODIFICATION", `contract ${input.contractId} changed while renewing`);
|
|
316
|
+
}
|
|
317
|
+
const sealed = input.capture ? {
|
|
318
|
+
...input.capture,
|
|
319
|
+
newFence: input.newHead,
|
|
320
|
+
sealedBy: "renew",
|
|
321
|
+
ledgerHead: sealHead,
|
|
322
|
+
} : null;
|
|
323
|
+
return { ledgerHead: renewHead, sealed };
|
|
324
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { FlowError } from "
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import { FlowError } from "../../flow-error.js";
|
|
4
|
+
import { syncDirectory } from "../../fs/durability.js";
|
|
5
|
+
import { createGit, errorContainsAnyPattern, MISSING_HEAD_PATTERNS, wrapGitError } from "../../git/core.js";
|
|
6
|
+
import { readLedger } from "../ledger.js";
|
|
7
|
+
import { shortCommitHash } from "../../git/commits.js";
|
|
8
|
+
import { commissionTarget, latestBase } from "../status/drift.js";
|
|
9
|
+
import { settleTaskBoardForLanding } from "../task/index.js";
|
|
10
|
+
import { stableRepoRoot } from "../worktree-path.js";
|
|
10
11
|
const CLAIM_RECEIPTS_FILE = "claim-receipts.jsonl";
|
|
11
12
|
async function appendClaimReceipt(cwd, receipt, restoreIfMissing = "") {
|
|
12
13
|
const receiptPath = path.join(await stableRepoRoot(cwd), ".keiyaku", CLAIM_RECEIPTS_FILE);
|
|
@@ -28,13 +29,7 @@ async function appendClaimReceipt(cwd, receipt, restoreIfMissing = "") {
|
|
|
28
29
|
finally {
|
|
29
30
|
await handle.close();
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
await directory.sync();
|
|
34
|
-
}
|
|
35
|
-
finally {
|
|
36
|
-
await directory.close();
|
|
37
|
-
}
|
|
32
|
+
await syncDirectory(path.dirname(receiptPath));
|
|
38
33
|
}
|
|
39
34
|
export async function resolveCommit(cwd, rev) {
|
|
40
35
|
const git = createGit(cwd);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { FlowError } from "
|
|
2
|
-
import {
|
|
1
|
+
import { FlowError } from "../../flow-error.js";
|
|
2
|
+
import { assertCleanTrackedWorkingTree } from "../../git/worktree.js";
|
|
3
|
+
import { activeLedgerRef, appendWithRetry, readLedger } from "../ledger.js";
|
|
3
4
|
import { assertClaimQueueHead, readQueueReadModel } from "./queue.js";
|
|
4
|
-
import { releaseScope } from "
|
|
5
|
-
import { deriveContractState } from "
|
|
6
|
-
import { commissionTarget, latestBase } from "
|
|
7
|
-
import { cleanupContractWorkspace, findContractWorktreePath, stableRepoRoot } from "
|
|
5
|
+
import { releaseScope } from "../registry.js";
|
|
6
|
+
import { deriveContractState } from "../status/lifecycle.js";
|
|
7
|
+
import { commissionTarget, latestBase } from "../status/drift.js";
|
|
8
|
+
import { cleanupContractWorkspace, findContractWorktreePath, stableRepoRoot } from "../worktree-path.js";
|
|
8
9
|
import { defaultMergeDelivery, relativeDisplayPath, resolveCommit, resolveCommitOrNull, } from "./claim-delivery.js";
|
|
9
10
|
async function cleanupClaim(cwd, contractId, actor, at) {
|
|
10
11
|
const stableRoot = await stableRepoRoot(cwd);
|
|
@@ -14,16 +15,37 @@ async function cleanupClaim(cwd, contractId, actor, at) {
|
|
|
14
15
|
function findClaim(entries) {
|
|
15
16
|
return entries.find((entry) => entry.kind === "claim");
|
|
16
17
|
}
|
|
18
|
+
/** Verdict belonging to the open petition window (after last petition, before claim). */
|
|
19
|
+
function latestCurrentPetitionVerdict(entries) {
|
|
20
|
+
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
21
|
+
const entry = entries[index];
|
|
22
|
+
if (entry.kind === "verdict")
|
|
23
|
+
return entry;
|
|
24
|
+
if (entry.kind === "petition")
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Delivery requires an approved verdict for the current petition.
|
|
31
|
+
* Already-claimed cleanup retry remains legal without re-proving judgment.
|
|
32
|
+
*/
|
|
17
33
|
function assertClaimableFromLedger(contractId, ledger) {
|
|
18
34
|
if (!ledger) {
|
|
19
35
|
throw new FlowError("INTERNAL_STATE", `contract ${contractId} not found`);
|
|
20
36
|
}
|
|
21
37
|
const state = deriveContractState(ledger.entries);
|
|
22
38
|
const claim = findClaim(ledger.entries);
|
|
23
|
-
if
|
|
24
|
-
return claim;
|
|
39
|
+
// Already-claimed cleanup retry: legal head even if a prior crash left debris.
|
|
25
40
|
if (claim && state.state === "claimed")
|
|
26
41
|
return claim;
|
|
42
|
+
if (state.state === "petitioned") {
|
|
43
|
+
const verdict = latestCurrentPetitionVerdict(ledger.entries);
|
|
44
|
+
if (verdict?.data.result !== "approved") {
|
|
45
|
+
throw new FlowError("INTERNAL_STATE", `contract ${contractId} cannot claim without approved verdict for current petition`);
|
|
46
|
+
}
|
|
47
|
+
return claim;
|
|
48
|
+
}
|
|
27
49
|
if (state.state === "forfeited") {
|
|
28
50
|
throw new FlowError("INTERNAL_STATE", `contract ${contractId} forfeited`);
|
|
29
51
|
}
|
|
@@ -95,6 +117,8 @@ export async function previewClaimContract(input) {
|
|
|
95
117
|
}
|
|
96
118
|
export async function claimContract(input) {
|
|
97
119
|
const at = new Date(input.nowMs).toISOString();
|
|
120
|
+
const deliveryWorktree = await findContractWorktreePath(input.cwd, input.contractId);
|
|
121
|
+
await assertCleanTrackedWorkingTree(deliveryWorktree ?? input.cwd);
|
|
98
122
|
const existing = await readLedger(input.cwd, input.contractId);
|
|
99
123
|
const existingClaim = assertClaimableFromLedger(input.contractId, existing);
|
|
100
124
|
const existingState = existing ? deriveContractState(existing.entries) : undefined;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the settlement package.
|
|
3
|
+
* Only symbols required by current external consumers are re-exported.
|
|
4
|
+
* Package-internal modules must import each other directly, not through this file.
|
|
5
|
+
*
|
|
6
|
+
* Orchestrator owns: gates → petition → pure verdict → claim delivery / reject publish.
|
|
7
|
+
* Foundations (queue, claim-delivery) may be depended on downward by stage modules.
|
|
8
|
+
* Stage modules (petition, verdict, claim) do not import one another.
|
|
9
|
+
*/
|
|
10
|
+
export { claimKeiyaku, petitionKeiyaku, } from "./settlement.js";
|
|
11
|
+
export { buildPetitionClaimInput, petitionContract, loadPetitionPreflightContext, assertPetitionFresh, assertPetitionArcReady, assertPetitionable, } from "./petition.js";
|
|
12
|
+
export { previewPetition, PETITION_PREVIEW_GATE_NAMES, } from "./petition-preview.js";
|
|
13
|
+
export { verdictContract, } from "./verdict.js";
|
|
14
|
+
export { claimContract, previewClaimContract, } from "./claim.js";
|
|
15
|
+
export { defaultMergeDelivery, relativeDisplayPath, resolveCommit, resolveCommitOrNull, } from "./claim-delivery.js";
|
|
16
|
+
export { allocateSettlementSeat, assertClaimQueueHead, deriveQueueReadModel, queueMembership, readQueueReadModel, seatAllocatorRef, } from "./queue.js";
|
|
17
|
+
export { buildClaimGatePipeline, createAgentReviewGate, createOathGate, } from "./petition-claim-gates.js";
|
|
18
|
+
export { assertHeadUnchanged } from "./petition-head-guard.js";
|
|
19
|
+
export { forfeitKeiyaku } from "./petition-forfeit.js";
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { getConfig } from "
|
|
3
|
-
import { assertSettingsKnobUsable } from "
|
|
4
|
-
import { resolveReviewerAgentName } from "
|
|
5
|
-
import { loadKeiyakuSettings } from "
|
|
6
|
-
import { loadAkumaCatalog } from "
|
|
7
|
-
import { formatAvailableAgentNames } from "
|
|
8
|
-
import { getDiffStats } from "
|
|
9
|
-
import { readDiff } from "
|
|
10
|
-
import { getCurrentBranch } from "
|
|
11
|
-
import { getLatestCommitHash } from "
|
|
12
|
-
import { DIFF_PREVIEW_TEXT_MAX_CHARS } from "
|
|
13
|
-
import { FlowError } from "
|
|
14
|
-
import { persistResponseHistory } from "
|
|
15
|
-
import { logInfo } from "
|
|
16
|
-
import { execSubagent } from "
|
|
17
|
-
import { readContractLog } from "
|
|
18
|
-
import { buildVerificationFailureHints } from "./hints.js";
|
|
2
|
+
import { getConfig } from "../../config/env.js";
|
|
3
|
+
import { assertSettingsKnobUsable } from "../../config/settings/disease.js";
|
|
4
|
+
import { resolveReviewerAgentName } from "../../config/settings/knobs.js";
|
|
5
|
+
import { loadKeiyakuSettings } from "../../config/settings/loader.js";
|
|
6
|
+
import { loadAkumaCatalog } from "../../config/akuma-loader.js";
|
|
7
|
+
import { formatAvailableAgentNames } from "../../agents/selector.js";
|
|
8
|
+
import { getDiffStats } from "../../git/diff/preview.js";
|
|
9
|
+
import { readDiff } from "../../git/diff/read.js";
|
|
10
|
+
import { getCurrentBranch } from "../../git/branches.js";
|
|
11
|
+
import { getLatestCommitHash } from "../../git/staging.js";
|
|
12
|
+
import { DIFF_PREVIEW_TEXT_MAX_CHARS } from "../../keiyaku.js";
|
|
13
|
+
import { FlowError } from "../../flow-error.js";
|
|
14
|
+
import { persistResponseHistory } from "../transcripts.js";
|
|
15
|
+
import { logInfo } from "../../telemetry/logger.js";
|
|
16
|
+
import { execSubagent } from "../call/call.js";
|
|
17
|
+
import { readContractLog } from "../log.js";
|
|
19
18
|
const CLAIM_VERIFICATION_OUTPUT_MAX_CHARS = 1200;
|
|
20
19
|
const REVIEW_PASS_TOKEN = "PASS";
|
|
21
20
|
const REVIEW_REJECTION_MESSAGE = "CLAIM rejected by independent reviewer.";
|
|
@@ -139,7 +138,12 @@ export function createCommandVerificationGate() {
|
|
|
139
138
|
pass: false,
|
|
140
139
|
code: "CLOSE_QUALITY_GATE_FAILED",
|
|
141
140
|
message: `CLAIM blocked: verification failed at '${verification.label}' (exit ${result.code}).`,
|
|
142
|
-
|
|
141
|
+
facts: {
|
|
142
|
+
kind: "verification_failure",
|
|
143
|
+
label: verification.label,
|
|
144
|
+
stdout: clipCommandOutput(result.stdout),
|
|
145
|
+
stderr: clipCommandOutput(result.stderr),
|
|
146
|
+
},
|
|
143
147
|
};
|
|
144
148
|
}
|
|
145
149
|
}
|