@astrosheep/keiyaku 2.9.8 → 2.9.10
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 +50 -182
- package/build/.tsbuildinfo +1 -1
- package/build/agents/harness/control-types.js +18 -1
- package/build/agents/harness/index.js +2 -0
- package/build/agents/harness/outcome-error.js +81 -0
- package/build/agents/harness/projection.js +10 -7
- package/build/agents/harness/router.js +5 -1
- package/build/agents/providers/claude-agent-sdk/adapter.js +18 -4
- package/build/agents/providers/claude-agent-sdk/registration.js +11 -1
- package/build/agents/providers/claude-agent-sdk/session.js +19 -5
- package/build/agents/providers/codex-app-server/adapter.js +11 -6
- package/build/agents/providers/codex-app-server/events.js +67 -6
- package/build/agents/providers/codex-app-server/registration.js +11 -1
- package/build/agents/providers/opencode-sdk/adapter.js +8 -1
- package/build/agents/providers/opencode-sdk/events.js +24 -2
- package/build/agents/providers/opencode-sdk/registration.js +11 -1
- package/build/agents/providers/pi/checkpoint.js +9 -1
- package/build/agents/providers/pi/events.js +2 -0
- package/build/agents/providers/pi/registration.js +14 -1
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/akuma/meta.js +3 -3
- package/build/cli/commands/akuma/catalog.js +2 -2
- package/build/cli/commands/akuma/{view → show}/handler.js +5 -5
- package/build/cli/commands/akuma/{view → show}/meta.js +3 -3
- package/build/cli/commands/akuma.js +1 -1
- package/build/cli/commands/contract/amend/handler.js +5 -4
- package/build/cli/commands/contract/arc/handler.js +5 -4
- package/build/cli/commands/contract/audit/handler.js +2 -2
- package/build/cli/commands/contract/bind/handler.js +12 -3
- package/build/cli/commands/contract/bind/meta.js +45 -15
- package/build/cli/commands/contract/forfeit/handler.js +9 -5
- package/build/cli/commands/contract/log/handler.js +2 -2
- package/build/cli/commands/contract/petition/handler.js +34 -7
- package/build/cli/commands/contract/renew/handler.js +7 -7
- package/build/cli/commands/contract/renew/meta.js +3 -3
- package/build/cli/commands/metadata.js +10 -6
- package/build/cli/commands/projection/call/meta.js +1 -1
- package/build/cli/commands/projection/catalog.js +2 -0
- package/build/cli/commands/projection/history/handler.js +21 -0
- package/build/cli/commands/projection/history/meta.js +9 -0
- package/build/cli/commands/projection/shared.js +3 -4
- package/build/cli/commands/projection/status/handler.js +3 -3
- package/build/cli/commands/projection/wait/handler.js +20 -11
- package/build/cli/commands/task/add/handler.js +14 -5
- package/build/cli/commands/task/add/meta.js +2 -2
- package/build/cli/commands/task/catalog.js +4 -0
- package/build/cli/commands/task/done/handler.js +1 -4
- package/build/cli/commands/task/done/meta.js +1 -1
- package/build/cli/commands/task/drop/meta.js +1 -1
- package/build/cli/commands/task/hold/handler.js +3 -0
- package/build/cli/commands/task/hold/meta.js +8 -0
- package/build/cli/commands/task/log/handler.js +1 -1
- package/build/cli/commands/task/log/meta.js +2 -2
- package/build/cli/commands/task/resume/handler.js +3 -0
- package/build/cli/commands/task/resume/meta.js +8 -0
- package/build/cli/commands/task/shared.js +39 -14
- package/build/cli/commands/task/show/handler.js +1 -1
- package/build/cli/commands/task/show/meta.js +1 -1
- package/build/cli/commands/task/start/meta.js +1 -1
- package/build/cli/commands/task/stop/handler.js +1 -4
- package/build/cli/commands/task/stop/meta.js +1 -1
- package/build/cli/commands/task/update/handler.js +11 -3
- package/build/cli/commands/task/update/meta.js +3 -3
- package/build/cli/completion.js +3 -2
- package/build/cli/flags.js +51 -14
- package/build/cli/help.js +4 -1
- package/build/cli/index.js +40 -25
- package/build/cli/parse-flags.js +40 -7
- package/build/cli/parse-metadata.js +5 -2
- package/build/cli/parse-selectors.js +2 -3
- package/build/cli/parse.js +40 -6
- package/build/cli/projection-address.js +12 -10
- package/build/cli/render/amendment-warning.js +8 -0
- package/build/cli/render/arc.js +6 -2
- package/build/cli/render/audit.js +400 -81
- package/build/cli/render/kanshi.js +242 -79
- package/build/cli/render/lifecycle.js +56 -0
- package/build/cli/render/misc.js +24 -28
- package/build/cli/render/petition.js +5 -0
- package/build/cli/render/projection-activity.js +65 -29
- package/build/cli/render/projection-history.js +64 -0
- package/build/cli/render/shared.js +23 -9
- package/build/cli/render/status.js +13 -35
- package/build/cli/render/task.js +51 -26
- package/build/cli/render/terminal-failure.js +3 -1
- package/build/cli/render/wait.js +45 -69
- package/build/cli/subagent-guard.js +1 -1
- package/build/cli/types.js +1 -1
- package/build/config/env-keys.js +3 -1
- package/build/config/env.js +24 -1
- package/build/config/settings/schema.js +3 -1
- package/build/core/address-carrier.js +89 -0
- package/build/core/addressing.js +255 -196
- package/build/core/amend.js +115 -38
- package/build/core/amendment-criteria.js +17 -0
- package/build/core/amendment-warning.js +10 -0
- package/build/core/arc.js +184 -83
- package/build/core/audit/candidate.js +110 -9
- package/build/core/audit/coordinates.js +120 -65
- package/build/core/audit/evidence.js +19 -23
- package/build/core/audit/facade.js +34 -11
- package/build/core/audit/report.js +5 -5
- package/build/core/bind-reconciliation.js +390 -0
- package/build/core/bind-workspace.js +12 -20
- package/build/core/bind.js +242 -273
- package/build/core/call/call.js +1 -0
- package/build/core/call/context.js +46 -71
- package/build/core/call/prompt.js +6 -3
- package/build/core/context.js +49 -35
- package/build/core/contract-carrier-runtime.js +408 -0
- package/build/core/contract-carrier.js +270 -0
- package/build/core/contract-view.js +33 -27
- package/build/core/contract.js +5 -1
- package/build/core/derived-replay.js +207 -0
- package/build/core/draft.js +125 -57
- package/build/core/forfeit.js +113 -56
- package/build/core/identifier-slug.js +63 -13
- package/build/core/ids.js +4 -4
- package/build/core/lifecycle-history.js +35 -0
- package/build/core/lifecycle-recovery.js +117 -0
- package/build/core/lifecycle-runner.js +377 -0
- package/build/core/log.js +37 -11
- package/build/core/outcome-base.js +181 -0
- package/build/core/process-group.js +139 -0
- package/build/core/projection/generation/database.js +82 -7
- package/build/core/projection/generation/model.js +9 -36
- package/build/core/projection/generation/projection-generation-continuation.js +10 -22
- package/build/core/projection/generation/projection-generation-execution.js +13 -6
- package/build/core/projection/index.js +5 -4
- package/build/core/projection/projection-activity.js +29 -8
- package/build/core/projection/projection-alias.js +23 -10
- package/build/core/projection/projection-core.js +21 -7
- package/build/core/projection/projection-execution-observer.js +91 -39
- package/build/core/projection/projection-history.js +474 -0
- package/build/core/projection/projection-runner-lock.js +12 -0
- package/build/core/projection/projection-status-observation.js +365 -0
- package/build/core/projection/projection-status.js +35 -337
- package/build/core/projection/projection-terminal-failure.js +13 -8
- package/build/core/projection/projection-wait.js +7 -2
- package/build/core/projection/tell/launch-store.js +244 -0
- package/build/core/projection/tell/model.js +3 -3
- package/build/core/projection/tell/store.js +70 -118
- package/build/core/registry.js +22 -87
- package/build/core/renew-build.js +424 -0
- package/build/core/renew-plan.js +239 -0
- package/build/core/renew-rewrite.js +77 -0
- package/build/core/renew.js +295 -520
- package/build/core/repository-ledger/accepted-fold-read.js +19 -0
- package/build/core/repository-ledger/accepted-tail.js +116 -0
- package/build/core/repository-ledger/admission.js +38 -0
- package/build/core/repository-ledger/authoritative-transaction.js +1 -0
- package/build/core/repository-ledger/claim-evidence.js +147 -0
- package/build/core/repository-ledger/codec.js +297 -0
- package/build/core/repository-ledger/current-state-store.js +853 -0
- package/build/core/repository-ledger/fold-repository.js +375 -0
- package/build/core/repository-ledger/fold.js +248 -0
- package/build/core/repository-ledger/git-object-store.js +243 -0
- package/build/core/repository-ledger/history-read.js +15 -0
- package/build/core/repository-ledger/incremental-read.js +153 -0
- package/build/core/repository-ledger/index.js +15 -0
- package/build/core/repository-ledger/inventory-plan.js +75 -0
- package/build/core/repository-ledger/inventory.js +310 -0
- package/build/core/repository-ledger/publication-admission.js +125 -0
- package/build/core/repository-ledger/publication.js +353 -0
- package/build/core/repository-ledger/read-model.js +469 -0
- package/build/core/repository-ledger/transaction-membership.js +78 -0
- package/build/core/repository-ledger/traversal.js +404 -0
- package/build/core/repository-ledger/write-transaction.js +339 -0
- package/build/core/seal.js +168 -161
- package/build/core/settlement/claim-delivery.js +42 -215
- package/build/core/settlement/claim.js +235 -153
- package/build/core/settlement/index.js +4 -4
- package/build/core/settlement/petition-claim-gates.js +52 -33
- package/build/core/settlement/petition-forfeit.js +12 -5
- package/build/core/settlement/petition-head-guard.js +8 -5
- package/build/core/settlement/petition-preview.js +68 -56
- package/build/core/settlement/petition-window.js +50 -0
- package/build/core/settlement/petition.js +252 -131
- package/build/core/settlement/queue-read-model.js +72 -95
- package/build/core/settlement/queue-seat-allocation.js +35 -126
- package/build/core/settlement/queue.js +1 -1
- package/build/core/settlement/settlement.js +172 -80
- package/build/core/settlement/verdict.js +112 -66
- package/build/core/settlement/verification-coordination.js +305 -0
- package/build/core/settlement/verification-supervisor.js +275 -0
- package/build/core/settlement/verification.js +398 -31
- package/build/core/status/board.js +125 -127
- package/build/core/status/lifecycle.js +7 -80
- package/build/core/structured-query.js +23 -0
- package/build/core/target-ref.js +1 -1
- package/build/core/task/board.js +59 -24
- package/build/core/task/commands.js +181 -33
- package/build/core/task/coordinate.js +56 -0
- package/build/core/task/document.js +25 -9
- package/build/core/task/index.js +7 -4
- package/build/core/task/query.js +17 -27
- package/build/core/task/settlement-git.js +164 -179
- package/build/core/task/settlement-policy.js +15 -11
- package/build/core/task/source-board.js +31 -13
- package/build/core/task/task-bind-preparation.js +193 -0
- package/build/core/task/task-contract.js +102 -193
- package/build/core/task/task-file-transaction.js +171 -0
- package/build/core/task/task-git-runtime.js +76 -14
- package/build/core/task/task-git-store.js +68 -169
- package/build/core/task/task-store-repository.js +13 -6
- package/build/core/task/task-worktree.js +6 -33
- package/build/core/task/task.js +1 -1
- package/build/core/task/tree.js +3 -3
- package/build/core/task/validation.js +4 -3
- package/build/core/transcripts.js +93 -1
- package/build/core/worktree-bootstrap.js +44 -36
- package/build/core/worktree-path.js +210 -77
- package/build/flow-error.js +7 -7
- package/build/generated/version.js +2 -2
- package/build/git/core.js +76 -13
- package/build/git/refs.js +168 -46
- package/build/git/streaming-batch.js +73 -13
- package/package.json +1 -1
- package/skills/keiyaku/SKILL.md +1 -1
- package/skills/keiyaku-akuma/SKILL.md +3 -3
- package/skills/keiyaku-task/SKILL.md +4 -2
- package/skills/keiyaku-workflow/SKILL.md +88 -203
- package/build/core/entry.js +0 -305
- package/build/core/ledger-batch.js +0 -194
- package/build/core/ledger.js +0 -84
- package/build/core/projection/leash.js +0 -87
- package/build/core/ref-log.js +0 -119
- package/build/core/renew-session.js +0 -128
- package/build/core/status/ledger-batch.js +0 -1
- package/build/core/status/reconciliation.js +0 -137
|
@@ -1,114 +1,433 @@
|
|
|
1
1
|
import { asMessage, FlowError } from "../../flow-error.js";
|
|
2
|
-
|
|
2
|
+
import { shortCommitHash } from "../../git/commits.js";
|
|
3
|
+
function shortRef(ref) {
|
|
4
|
+
return ref.replace(/^refs\/heads\//, "");
|
|
5
|
+
}
|
|
6
|
+
function formatDuration(ms) {
|
|
7
|
+
if (ms < 1000)
|
|
8
|
+
return `${ms}ms`;
|
|
9
|
+
const seconds = ms / 1000;
|
|
10
|
+
if (seconds < 60)
|
|
11
|
+
return `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`;
|
|
12
|
+
const minutes = Math.floor(seconds / 60);
|
|
13
|
+
const rem = Math.round(seconds % 60);
|
|
14
|
+
return `${minutes}m${rem.toString().padStart(2, "0")}s`;
|
|
15
|
+
}
|
|
16
|
+
function formatBytes(bytes) {
|
|
17
|
+
if (bytes < 1024)
|
|
18
|
+
return `${bytes} bytes`;
|
|
19
|
+
const kib = bytes / 1024;
|
|
20
|
+
if (kib < 1024)
|
|
21
|
+
return `${kib < 10 ? kib.toFixed(1) : Math.round(kib)} KiB`;
|
|
22
|
+
const mib = kib / 1024;
|
|
23
|
+
return `${mib < 10 ? mib.toFixed(1) : Math.round(mib)} MiB`;
|
|
24
|
+
}
|
|
25
|
+
function padLabel(label, width) {
|
|
26
|
+
return label.length >= width ? label : `${label}${" ".repeat(width - label.length)}`;
|
|
27
|
+
}
|
|
28
|
+
function scopeMatchLabel(file) {
|
|
29
|
+
if (file.matcher.decisivePattern) {
|
|
30
|
+
const effect = file.matcher.decisivePattern.effect === "exclude" ? "excluded by" : "matched";
|
|
31
|
+
return `${effect}: ${file.matcher.decisivePattern.pattern}`;
|
|
32
|
+
}
|
|
33
|
+
if (file.class === "downgraded")
|
|
34
|
+
return "no declared term · explained companions only";
|
|
35
|
+
return "no declared term";
|
|
36
|
+
}
|
|
37
|
+
function explanationLine(item) {
|
|
38
|
+
if (item.kind === "file-rename")
|
|
39
|
+
return `rename ${item.from} -> ${item.to} (${item.similarity}%)`;
|
|
40
|
+
if (item.kind === "symbol-rename") {
|
|
41
|
+
return `symbol rename ${item.from} -> ${item.to} · h${item.hunk} old:${item.oldLine ?? "-"} new:${item.newLine ?? "-"}`;
|
|
42
|
+
}
|
|
43
|
+
return `import · h${item.hunk} old:${item.oldLine ?? "-"} new:${item.newLine ?? "-"}`;
|
|
44
|
+
}
|
|
45
|
+
function residueSummary(file) {
|
|
46
|
+
if (file.class !== "violated" || file.residue.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
const hunks = [...new Set(file.residue.map((item) => item.hunk).filter((hunk) => hunk >= 0))].sort((a, b) => a - b);
|
|
49
|
+
if (file.residue.some((item) => item.kind === "binary")) {
|
|
50
|
+
return `unexplained: binary content changed`;
|
|
51
|
+
}
|
|
52
|
+
if (hunks.length === 0)
|
|
53
|
+
return `unexplained: ${file.residue.length} changes`;
|
|
54
|
+
return `unexplained: ${file.residue.length} lines across hunk ${hunks.join(", ")}`;
|
|
55
|
+
}
|
|
56
|
+
function indentBlock(text, prefix = " ") {
|
|
57
|
+
return text.split("\n").map((line) => `${prefix}${line}`);
|
|
58
|
+
}
|
|
59
|
+
function selectedFor(file, report) {
|
|
60
|
+
return report.presentation?.selected.filter((item) => item.path === file.path) ?? [];
|
|
61
|
+
}
|
|
62
|
+
function omissionsFor(file, report) {
|
|
63
|
+
return report.presentation?.omissions.filter((item) => item.path === file.path) ?? [];
|
|
64
|
+
}
|
|
65
|
+
function renderFileBlock(file, report) {
|
|
66
|
+
const rename = file.oldPath ? `${file.oldPath} -> ` : "";
|
|
67
|
+
const header = ` ${file.status} ${rename}${file.path}`.padEnd(62) + `+${file.stats.insertions} -${file.stats.deletions}`;
|
|
68
|
+
const lines = [header, ` ${scopeMatchLabel(file)}`];
|
|
69
|
+
for (const explanation of file.explanations)
|
|
70
|
+
lines.push(` ${explanationLine(explanation)}`);
|
|
71
|
+
const residue = residueSummary(file);
|
|
72
|
+
if (residue)
|
|
73
|
+
lines.push(` ${residue}`);
|
|
74
|
+
const selected = selectedFor(file, report);
|
|
75
|
+
const omissions = omissionsFor(file, report);
|
|
76
|
+
for (const item of selected) {
|
|
77
|
+
if (item.hunk === null)
|
|
78
|
+
continue;
|
|
79
|
+
lines.push("");
|
|
80
|
+
lines.push(...indentBlock(item.content));
|
|
81
|
+
}
|
|
82
|
+
if (omissions.length > 0) {
|
|
83
|
+
const omittedHunks = omissions.filter((item) => item.hunk !== null).length;
|
|
84
|
+
const omittedBytes = omissions.reduce((sum, item) => sum + item.bytes, 0);
|
|
85
|
+
const subject = omissions.every((item) => item.hunk === null)
|
|
86
|
+
? "file content omitted"
|
|
87
|
+
: `${omittedHunks} hunk${omittedHunks === 1 ? "" : "s"} omitted`;
|
|
88
|
+
lines.push("");
|
|
89
|
+
lines.push(` [${subject} · ${formatBytes(omittedBytes)}]`);
|
|
90
|
+
}
|
|
91
|
+
return lines;
|
|
92
|
+
}
|
|
93
|
+
function classRank(value) {
|
|
94
|
+
if (value === "violated")
|
|
95
|
+
return 0;
|
|
96
|
+
if (value === "downgraded")
|
|
97
|
+
return 1;
|
|
98
|
+
return 2;
|
|
99
|
+
}
|
|
100
|
+
function orderedFiles(report) {
|
|
101
|
+
return [...(report.files ?? [])].sort((left, right) => {
|
|
102
|
+
const rank = classRank(left.class) - classRank(right.class);
|
|
103
|
+
return rank || left.path.localeCompare(right.path);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function hasCoordinateRace(report) {
|
|
107
|
+
return report.findings.some((finding) => finding.code === "COORDINATE_RACE");
|
|
108
|
+
}
|
|
109
|
+
function isMatchedScope(file) {
|
|
110
|
+
return file.class === "in-scope" || file.matcher.matched;
|
|
111
|
+
}
|
|
112
|
+
function renderChanges(report) {
|
|
113
|
+
if (!report.diff || !report.presentation || !report.files) {
|
|
114
|
+
return [hasCoordinateRace(report) || report.rehearsal.status === "conflict" || report.rehearsal.status === "unknown" ? "—" : "not evaluated"];
|
|
115
|
+
}
|
|
116
|
+
const files = orderedFiles(report);
|
|
117
|
+
const outside = files.filter((file) => !isMatchedScope(file));
|
|
118
|
+
const declared = files.filter((file) => isMatchedScope(file));
|
|
119
|
+
const lines = [
|
|
120
|
+
`${report.diff.stat.filesChanged} files · +${report.diff.stat.insertions} -${report.diff.stat.deletions}`,
|
|
121
|
+
];
|
|
122
|
+
if (outside.length > 0) {
|
|
123
|
+
lines.push("", "Outside declared write set", "");
|
|
124
|
+
for (const file of outside) {
|
|
125
|
+
lines.push(...renderFileBlock(file, report), "");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (declared.length > 0) {
|
|
129
|
+
lines.push("", "Declared changes", "");
|
|
130
|
+
for (const file of declared) {
|
|
131
|
+
lines.push(...renderFileBlock(file, report), "");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const selectedCount = report.presentation.selected.filter((item) => item.hunk !== null).length;
|
|
135
|
+
const omittedCount = report.presentation.omissions.filter((item) => item.hunk !== null).length;
|
|
136
|
+
const totalHunks = selectedCount + omittedCount;
|
|
137
|
+
if (totalHunks > 0 || report.presentation.budget.limit === 0) {
|
|
138
|
+
lines.push(`Shown ${selectedCount} of ${totalHunks || selectedCount} hunks · ${formatBytes(report.presentation.budget.limit)} presentation limit`);
|
|
139
|
+
}
|
|
140
|
+
while (lines.at(-1) === "")
|
|
141
|
+
lines.pop();
|
|
142
|
+
return lines;
|
|
143
|
+
}
|
|
144
|
+
function shouldExpandResult(result) {
|
|
145
|
+
if (result.status === "runner_failed")
|
|
146
|
+
return true;
|
|
147
|
+
if (result.status === "executed" && result.exitCode !== 0)
|
|
148
|
+
return true;
|
|
149
|
+
return [result.stdout, result.stderr].some((stream) => stream.truncated || stream.tail.length > 0);
|
|
150
|
+
}
|
|
151
|
+
function streamDetail(name, result, forceEmpty) {
|
|
3
152
|
const stream = result[name];
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
153
|
+
if (!forceEmpty && !stream.truncated && stream.tail.length === 0)
|
|
154
|
+
return [];
|
|
155
|
+
const mark = stream.truncated ? `truncated · ${formatBytes(stream.omittedBytes)} omitted` : "complete";
|
|
156
|
+
return [` ${name} (${mark})`, ...indentBlock(stream.tail || "(empty)", " ")];
|
|
157
|
+
}
|
|
158
|
+
function verificationStatus(result) {
|
|
159
|
+
if (result.status === "runner_failed")
|
|
160
|
+
return "unknown";
|
|
161
|
+
return result.exitCode === 0 ? "passed" : "failed";
|
|
162
|
+
}
|
|
163
|
+
function sourceHeading(source) {
|
|
164
|
+
return source === "contract" ? "contract" : "repository gate";
|
|
165
|
+
}
|
|
166
|
+
function preparationReason(reason) {
|
|
167
|
+
if (reason === "verification_not_configured")
|
|
168
|
+
return "no verification plan";
|
|
169
|
+
if (reason === "verification_plan_unavailable")
|
|
170
|
+
return "verification plan unavailable";
|
|
171
|
+
if (reason === "coordinate_race")
|
|
172
|
+
return "coordinate change";
|
|
173
|
+
return "candidate unavailable";
|
|
174
|
+
}
|
|
175
|
+
function preparationResult(result) {
|
|
176
|
+
if (result.kind === "exit")
|
|
177
|
+
return `exit ${result.code}`;
|
|
178
|
+
if (result.kind === "signal")
|
|
179
|
+
return `signal ${result.signal}`;
|
|
180
|
+
if (result.kind === "timeout")
|
|
181
|
+
return "timeout";
|
|
182
|
+
return `spawn · ${result.message}`;
|
|
183
|
+
}
|
|
184
|
+
function preparationStreams(preparation) {
|
|
185
|
+
const lines = [];
|
|
186
|
+
for (const stream of ["stdout", "stderr"]) {
|
|
187
|
+
const tail = preparation[`${stream}Tail`];
|
|
188
|
+
const truncated = preparation[`${stream}Truncated`];
|
|
189
|
+
if (tail === undefined && !truncated)
|
|
190
|
+
continue;
|
|
191
|
+
lines.push(` ${stream} (${truncated ? "truncated" : "complete"})`);
|
|
192
|
+
lines.push(...indentBlock(tail || "(empty)", " "));
|
|
193
|
+
}
|
|
194
|
+
return lines;
|
|
195
|
+
}
|
|
196
|
+
function renderCandidatePreparation(report) {
|
|
197
|
+
const preparation = report.candidatePreparation;
|
|
198
|
+
if (preparation.status === "not-required")
|
|
199
|
+
return [` preparation not required · ${preparationReason(preparation.reason)}`];
|
|
200
|
+
if (preparation.status === "not-configured")
|
|
201
|
+
return [" preparation not configured · no bind bootstrap plan"];
|
|
202
|
+
const command = JSON.stringify(preparation.plan.command);
|
|
203
|
+
if (preparation.status === "succeeded") {
|
|
204
|
+
return [
|
|
205
|
+
` preparation passed ${padLabel(formatDuration(preparation.durationMs), 6)} ${command}`,
|
|
206
|
+
...preparationStreams(preparation),
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
const lines = [
|
|
210
|
+
` preparation failed ${padLabel(formatDuration(preparation.durationMs), 6)} ${preparationResult(preparation.result)}`,
|
|
211
|
+
` ${preparation.cause.code}: ${preparation.cause.message}`,
|
|
212
|
+
` argv ${command} · timeout ${preparation.plan.timeoutMs}ms`,
|
|
7
213
|
];
|
|
214
|
+
if (preparation.integrity) {
|
|
215
|
+
lines.push(` integrity head=${preparation.integrity.head ?? "unknown"} · tree=${preparation.integrity.tree ?? "unknown"} · tracked=${preparation.integrity.trackedChanges.length}`);
|
|
216
|
+
}
|
|
217
|
+
lines.push(...preparationStreams(preparation));
|
|
218
|
+
return lines;
|
|
8
219
|
}
|
|
9
|
-
function
|
|
220
|
+
function renderVerificationResults(report) {
|
|
10
221
|
if (report.verification.status === "not_configured")
|
|
11
222
|
return ["not configured"];
|
|
12
|
-
if (report.verification.status === "not_evaluated")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
223
|
+
if (report.verification.status === "not_evaluated") {
|
|
224
|
+
if (hasCoordinateRace(report) || report.verification.reason === "renew_conflict" || report.verification.reason === "renew_unknown") {
|
|
225
|
+
return ["—"];
|
|
226
|
+
}
|
|
227
|
+
return [`not evaluated · ${report.verification.reason.replaceAll("_", " ")}`];
|
|
228
|
+
}
|
|
229
|
+
if (report.verification.status === "unknown") {
|
|
230
|
+
return [`unknown · ${report.verification.cause.code}: ${report.verification.cause.message}`];
|
|
231
|
+
}
|
|
232
|
+
const labels = report.verification.results.map((result) => result.label);
|
|
233
|
+
const width = Math.max(8, ...labels.map((label) => label.length));
|
|
16
234
|
const lines = [];
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
235
|
+
const groups = ["contract", "repository-gate"];
|
|
236
|
+
for (const source of groups) {
|
|
237
|
+
const results = report.verification.results.filter((result) => result.source === source);
|
|
238
|
+
if (results.length === 0)
|
|
21
239
|
continue;
|
|
240
|
+
lines.push(` ${sourceHeading(source)}`);
|
|
241
|
+
for (const result of results) {
|
|
242
|
+
const status = padLabel(verificationStatus(result), 7);
|
|
243
|
+
const duration = formatDuration(result.durationMs);
|
|
244
|
+
lines.push(` ${padLabel(result.label, width)} ${status} ${padLabel(duration, 6)} ${result.declaration}`);
|
|
245
|
+
if (result.status === "runner_failed") {
|
|
246
|
+
lines.push(` ${result.cause.code}: ${result.cause.message}`);
|
|
247
|
+
}
|
|
248
|
+
if (shouldExpandResult(result)) {
|
|
249
|
+
const forceEmpty = result.status === "runner_failed" || (result.status === "executed" && result.exitCode !== 0);
|
|
250
|
+
lines.push(...streamDetail("stdout", result, forceEmpty), ...streamDetail("stderr", result, forceEmpty));
|
|
251
|
+
}
|
|
22
252
|
}
|
|
23
|
-
lines.push(`\`\`\`${result.executor}`, result.body, "\`\`\`", `exit ${result.exitCode} · duration ${result.durationMs}ms`, ...streamLines("stdout", result), ...streamLines("stderr", result), "");
|
|
24
253
|
}
|
|
25
254
|
return lines;
|
|
26
255
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
256
|
+
function renderVerification(report) {
|
|
257
|
+
const preparation = renderCandidatePreparation(report);
|
|
258
|
+
const results = renderVerificationResults(report);
|
|
259
|
+
return [...preparation, "", ...results];
|
|
260
|
+
}
|
|
261
|
+
function residueParts(readiness) {
|
|
262
|
+
const residue = readiness.deliveryResidue;
|
|
263
|
+
const parts = [];
|
|
264
|
+
if (residue.staged.length > 0)
|
|
265
|
+
parts.push(`${residue.staged.length} staged`);
|
|
266
|
+
if (residue.unstaged.length > 0)
|
|
267
|
+
parts.push(`${residue.unstaged.length} unstaged`);
|
|
268
|
+
if (residue.untracked.length > 0)
|
|
269
|
+
parts.push(`${residue.untracked.length} untracked`);
|
|
270
|
+
if (parts.length === 0 && residue.tracked.length > 0)
|
|
271
|
+
parts.push(`${residue.tracked.length} tracked dirty`);
|
|
272
|
+
return parts.join(" · ");
|
|
44
273
|
}
|
|
45
|
-
function
|
|
274
|
+
function renderDeliveryContext(report) {
|
|
275
|
+
const race = report.findings.find((finding) => finding.code === "COORDINATE_RACE");
|
|
276
|
+
if (race)
|
|
277
|
+
return renderCoordinateRace(race);
|
|
46
278
|
const readiness = report.readiness;
|
|
47
279
|
if (!readiness)
|
|
48
|
-
return ["not evaluated
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
280
|
+
return ["not evaluated"];
|
|
281
|
+
const lines = [];
|
|
282
|
+
const residue = residueParts(readiness);
|
|
283
|
+
lines.push(` worktree ${residue || "clean"}`);
|
|
284
|
+
const arcBits = [`max ${readiness.arc.max}`];
|
|
285
|
+
if (readiness.arc.open !== null)
|
|
286
|
+
arcBits.unshift(`open ${readiness.arc.open}`);
|
|
287
|
+
if (readiness.arc.fence)
|
|
288
|
+
arcBits.push(`fence ${shortCommitHash(readiness.arc.fence)}`);
|
|
289
|
+
if (readiness.arc.looseCommits.length > 0)
|
|
290
|
+
arcBits.push(`${readiness.arc.looseCommits.length} loose`);
|
|
291
|
+
lines.push(` arc ${arcBits.join(" · ")}`);
|
|
292
|
+
lines.push(` projection ${readiness.rewriteGuard.liveProjection ? "active" : "none"}`);
|
|
293
|
+
if (readiness.dependencies.length === 0) {
|
|
294
|
+
lines.push(" dependencies none");
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
const deps = readiness.dependencies
|
|
298
|
+
.map((item) => `${item.id} ${item.satisfied ? "settled" : item.state}`)
|
|
299
|
+
.join(" · ");
|
|
300
|
+
lines.push(` dependencies ${deps}`);
|
|
301
|
+
}
|
|
302
|
+
if (readiness.petition.queue) {
|
|
303
|
+
const position = readiness.petition.queue.position ?? "?";
|
|
304
|
+
lines.push(` petition ${readiness.petition.state} · queue ${position}/${readiness.petition.queue.length}`);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
lines.push(` petition ${readiness.petition.state}`);
|
|
308
|
+
}
|
|
309
|
+
return lines;
|
|
310
|
+
}
|
|
311
|
+
function formatRaceValue(value) {
|
|
312
|
+
if (typeof value === "string") {
|
|
313
|
+
return /^[0-9a-f]{40}$/i.test(value) ? shortCommitHash(value) : value;
|
|
314
|
+
}
|
|
315
|
+
if (value === null || value === undefined)
|
|
316
|
+
return String(value);
|
|
317
|
+
if (typeof value !== "object" || Array.isArray(value))
|
|
318
|
+
return JSON.stringify(value);
|
|
319
|
+
const record = value;
|
|
320
|
+
const preferred = ["cwd", "ref", "head", "tree", "residueFingerprint"];
|
|
321
|
+
const parts = [];
|
|
322
|
+
for (const key of preferred) {
|
|
323
|
+
if (!(key in record))
|
|
324
|
+
continue;
|
|
325
|
+
const raw = record[key];
|
|
326
|
+
if (raw === undefined)
|
|
327
|
+
continue;
|
|
328
|
+
if (key === "head" || key === "tree" || key === "residueFingerprint") {
|
|
329
|
+
parts.push(`${key}=${typeof raw === "string" ? (key === "residueFingerprint" ? raw.slice(0, 12) : formatRaceValue(raw)) : JSON.stringify(raw)}`);
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
if (key === "ref" && typeof raw === "string") {
|
|
333
|
+
parts.push(`${key}=${shortRef(raw)}`);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
parts.push(`${key}=${typeof raw === "string" ? raw : JSON.stringify(raw)}`);
|
|
337
|
+
}
|
|
338
|
+
if (parts.length === 0)
|
|
339
|
+
return JSON.stringify(value);
|
|
340
|
+
return parts.join(" · ");
|
|
57
341
|
}
|
|
58
|
-
function
|
|
59
|
-
const
|
|
60
|
-
|
|
342
|
+
function renderCoordinateRace(finding) {
|
|
343
|
+
const lines = [` coordinate change observed`, ` ${finding.detail}`];
|
|
344
|
+
const race = finding.race;
|
|
345
|
+
if (!race)
|
|
346
|
+
return lines;
|
|
347
|
+
lines.push(` which ${race.which}`);
|
|
348
|
+
lines.push(` pinned ${formatRaceValue(race.pinned)}`);
|
|
349
|
+
lines.push(` observed ${formatRaceValue(race.observed)}`);
|
|
350
|
+
return lines;
|
|
61
351
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
352
|
+
function renderRehearsal(report) {
|
|
353
|
+
const rehearsal = report.rehearsal;
|
|
354
|
+
if (rehearsal.status === "fresh")
|
|
355
|
+
return "fresh";
|
|
356
|
+
if (rehearsal.status === "clean") {
|
|
357
|
+
return `clean onto ${shortRef(report.coordinates.target.ref)}@${shortCommitHash(rehearsal.newBase)}`;
|
|
358
|
+
}
|
|
359
|
+
if (rehearsal.status === "conflict") {
|
|
360
|
+
const paths = rehearsal.paths.length > 0 ? rehearsal.paths.join(", ") : "paths unavailable";
|
|
361
|
+
return `conflict · ${paths}`;
|
|
362
|
+
}
|
|
363
|
+
return `unknown · ${rehearsal.cause.code}: ${rehearsal.cause.message}`;
|
|
364
|
+
}
|
|
365
|
+
function renderCandidate(report) {
|
|
366
|
+
const target = `${shortRef(report.coordinates.target.ref)}@${shortCommitHash(report.coordinates.target.head)}`;
|
|
367
|
+
const delivery = `${shortRef(report.coordinates.delivery.ref)}@${shortCommitHash(report.coordinates.delivery.head)}`;
|
|
368
|
+
const lines = [];
|
|
369
|
+
if (report.candidate) {
|
|
370
|
+
const candidateHead = shortCommitHash(report.candidate.head);
|
|
371
|
+
const candidateBase = shortCommitHash(report.candidate.base);
|
|
372
|
+
if (report.candidate.kind === "renew-rehearsal") {
|
|
373
|
+
lines.push(` ${candidateBase}..${candidateHead} · renew rehearsal`);
|
|
374
|
+
lines.push(` delivery ${delivery}`);
|
|
375
|
+
lines.push(` target ${target}`);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
lines.push(` ${target}..${candidateHead}`);
|
|
379
|
+
if (report.candidate.head !== report.coordinates.delivery.head) {
|
|
380
|
+
lines.push(` delivery ${delivery}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
lines.push(` ${target}..${delivery}`);
|
|
386
|
+
}
|
|
387
|
+
if (report.diff) {
|
|
388
|
+
lines.push(` ${report.diff.stat.filesChanged} files · +${report.diff.stat.insertions} -${report.diff.stat.deletions}`);
|
|
389
|
+
}
|
|
390
|
+
else if (report.findings.some((finding) => finding.code === "COORDINATE_RACE")) {
|
|
391
|
+
lines.push(" evidence not evaluated · coordinate change");
|
|
392
|
+
}
|
|
393
|
+
else if (report.rehearsal.status === "conflict") {
|
|
394
|
+
lines.push(" evidence not evaluated · renew conflict");
|
|
395
|
+
}
|
|
396
|
+
else if (report.rehearsal.status === "unknown") {
|
|
397
|
+
lines.push(" evidence not evaluated · renew unknown");
|
|
398
|
+
}
|
|
399
|
+
lines.push(` rehearsal: ${renderRehearsal(report)}`);
|
|
400
|
+
lines.push(` ledger ${shortCommitHash(report.coordinates.ledger.head)}`);
|
|
401
|
+
return lines;
|
|
402
|
+
}
|
|
403
|
+
function renderAcceptance(report) {
|
|
404
|
+
if (report.terms.criteria.length === 0)
|
|
405
|
+
return [" (none)"];
|
|
406
|
+
return report.terms.criteria.map((term, index) => ` ${index + 1}. ${term}`);
|
|
75
407
|
}
|
|
76
408
|
export function buildAuditResponse(report, json) {
|
|
77
409
|
const payload = report;
|
|
78
410
|
if (json)
|
|
79
411
|
return { text: JSON.stringify(report), payload };
|
|
80
|
-
const
|
|
412
|
+
const sections = [
|
|
81
413
|
`Audit ${report.contract}`,
|
|
82
414
|
"",
|
|
83
|
-
"
|
|
84
|
-
|
|
85
|
-
`delivery ${report.coordinates.delivery.ref} ${report.coordinates.delivery.head} tree ${report.coordinates.delivery.tree}`,
|
|
86
|
-
`target ${report.coordinates.target.ref} ${report.coordinates.target.head} tree ${report.coordinates.target.tree}`,
|
|
87
|
-
"",
|
|
88
|
-
"Criteria",
|
|
89
|
-
...report.terms.criteria.map((term) => `criterion ${term}`),
|
|
90
|
-
...report.terms.scope.map((term) => `scope ${term}`),
|
|
91
|
-
...report.terms.appendScope.map((term) => `append-scope ${term}`),
|
|
415
|
+
"Candidate",
|
|
416
|
+
...renderCandidate(report),
|
|
92
417
|
"",
|
|
93
|
-
"
|
|
94
|
-
|
|
418
|
+
"Acceptance",
|
|
419
|
+
...renderAcceptance(report),
|
|
95
420
|
"",
|
|
96
|
-
"
|
|
97
|
-
...
|
|
98
|
-
`counts files=${report.counts.files} selected=${report.counts.selected} omitted=${report.counts.omitted} in-scope=${report.counts.inScope} downgraded=${report.counts.downgraded} violated=${report.counts.violated} findings=${report.counts.findings}`,
|
|
99
|
-
"",
|
|
100
|
-
"Scope",
|
|
101
|
-
...renderScope(report),
|
|
421
|
+
"Changes",
|
|
422
|
+
...renderChanges(report),
|
|
102
423
|
"",
|
|
103
424
|
"Verification",
|
|
104
425
|
...renderVerification(report),
|
|
105
|
-
"Readiness",
|
|
106
|
-
...renderReadiness(report),
|
|
107
426
|
"",
|
|
108
|
-
"
|
|
109
|
-
...(report
|
|
110
|
-
]
|
|
111
|
-
return { text, payload };
|
|
427
|
+
"Delivery Context",
|
|
428
|
+
...renderDeliveryContext(report),
|
|
429
|
+
];
|
|
430
|
+
return { text: sections.join("\n"), payload };
|
|
112
431
|
}
|
|
113
432
|
export function buildAuditConstructionFailure(error, json) {
|
|
114
433
|
const cause = { code: error instanceof FlowError ? error.code : "INTERNAL_STATE", message: asMessage(error) };
|