@riddledc/riddle-proof-packs 0.4.5 → 0.4.7
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 +53 -1
- package/bin/riddle-proof-durable-candidate-plan +4 -0
- package/dist/{chunk-XQ2N4EYF.js → chunk-SAE6HFAG.js} +4 -0
- package/dist/chunk-VFPSPQD7.js +219 -0
- package/dist/durableCandidatePlan-Dv2P33Wg.d.cts +77 -0
- package/dist/durableCandidatePlan-Dv2P33Wg.d.ts +77 -0
- package/dist/durableCandidatePlanCli.cjs +445 -0
- package/dist/durableCandidatePlanCli.d.cts +32 -0
- package/dist/durableCandidatePlanCli.d.ts +32 -0
- package/dist/durableCandidatePlanCli.js +177 -0
- package/dist/index.cjs +403 -2
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +192 -3
- package/dist/reviewPacketCli.cjs +4 -0
- package/dist/reviewPacketCli.js +1 -1
- package/package.json +3 -2
- package/packs/audio-mix/ratchet-method.md +12 -0
- package/packs/neon-step-sequencer/README.md +7 -0
- package/packs/neon-step-sequencer/case-study/findings.md +22 -0
- package/packs/neon-step-sequencer/case-study/ratchet-card.md +3 -1
- package/packs/neon-step-sequencer/case-study/ratchet-log.md +112 -0
- package/packs/neon-step-sequencer/examples/README.md +5 -1
- package/packs/neon-step-sequencer/examples/run-006-ratchet-loop-human-review-packet/human-review-packet.md +3 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/artifact-manifest.json +32 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/console.json +4 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/dom-summary.json +40 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/human-review-packet.json +801 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/human-review-packet.md +52 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/profile-result.json +11994 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/proof.json +11994 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/screenshots/lilarcade-neon-ratchet-loop-approved-candidate-desktop-neon-ratchet-loop-approved-candidate.png +0 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/screenshots/lilarcade-neon-ratchet-loop-approved-candidate-desktop.png +0 -0
- package/packs/neon-step-sequencer/examples/run-007-approved-candidate-applied/summary.md +32 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/artifact-manifest.json +32 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/console.json +4 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/dom-summary.json +40 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/durable-candidate-patch-plan.json +69 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/durable-candidate-patch-plan.md +29 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/human-review-packet.json +801 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/human-review-packet.md +52 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/profile-result.json +5078 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/proof.json +5078 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/screenshots/lilarcade-neon-fast-mix-health-desktop-neon-fast-mix-health.png +0 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/screenshots/lilarcade-neon-fast-mix-health-desktop.png +0 -0
- package/packs/neon-step-sequencer/examples/run-008-durable-mix-patch-handoff/summary.md +39 -0
- package/packs/neon-step-sequencer/profiles/ratchet-loop-approved-candidate.json +177 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/durableCandidatePlanCli.ts
|
|
31
|
+
var durableCandidatePlanCli_exports = {};
|
|
32
|
+
__export(durableCandidatePlanCli_exports, {
|
|
33
|
+
main: () => main,
|
|
34
|
+
parseDurableCandidatePlanCliArgs: () => parseDurableCandidatePlanCliArgs,
|
|
35
|
+
writeDurableCandidatePlanFiles: () => writeDurableCandidatePlanFiles
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(durableCandidatePlanCli_exports);
|
|
38
|
+
var import_node_fs = require("fs");
|
|
39
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
40
|
+
|
|
41
|
+
// src/humanReviewPacket.ts
|
|
42
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
43
|
+
function findHumanReviewPacket(value) {
|
|
44
|
+
if (!value || typeof value !== "object") return null;
|
|
45
|
+
if (isRecord(value) && value.kind === "human_review_packet") return value;
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
for (const entry of value) {
|
|
48
|
+
const packet = findHumanReviewPacket(entry);
|
|
49
|
+
if (packet) return packet;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
for (const entry of Object.values(value)) {
|
|
54
|
+
const packet = findHumanReviewPacket(entry);
|
|
55
|
+
if (packet) return packet;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function requireHumanReviewPacket(value) {
|
|
60
|
+
const packet = findHumanReviewPacket(value);
|
|
61
|
+
if (!packet) throw new Error("No human_review_packet found");
|
|
62
|
+
return packet;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/durableCandidatePlan.ts
|
|
66
|
+
var DEFAULT_APPROVAL_MODES = ["operator_approved", "mixing_canon_surrogate"];
|
|
67
|
+
var DEFAULT_ACTION_TYPES = ["set_mixer_level"];
|
|
68
|
+
var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
69
|
+
var asRecord = (value) => isRecord2(value) ? value : {};
|
|
70
|
+
var getPath = (value, path2) => {
|
|
71
|
+
let cursor = value;
|
|
72
|
+
for (const part of path2.split(".")) {
|
|
73
|
+
if (!isRecord2(cursor)) return void 0;
|
|
74
|
+
cursor = cursor[part];
|
|
75
|
+
}
|
|
76
|
+
return cursor;
|
|
77
|
+
};
|
|
78
|
+
var asFiniteNumber = (value) => {
|
|
79
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
80
|
+
if (typeof value !== "number" && typeof value !== "string") return null;
|
|
81
|
+
const numeric = Number(value);
|
|
82
|
+
return Number.isFinite(numeric) ? Number(numeric.toFixed(4)) : null;
|
|
83
|
+
};
|
|
84
|
+
var formatValue = (value) => {
|
|
85
|
+
if (value === null || value === void 0 || value === "") return "not captured";
|
|
86
|
+
if (typeof value === "number") return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(4)));
|
|
87
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
88
|
+
return String(value);
|
|
89
|
+
};
|
|
90
|
+
var formatCodeValue = (value) => `\`${formatValue(value)}\``;
|
|
91
|
+
var selectedTargetLabel = (packet) => {
|
|
92
|
+
const value = getPath(packet, "target.selectedSong.selectedSong") ?? getPath(packet, "target.routeState.selectedSong") ?? getPath(packet, "target.label");
|
|
93
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
94
|
+
};
|
|
95
|
+
var selectedRoute = (packet) => {
|
|
96
|
+
const value = getPath(packet, "target.routeState.route") ?? getPath(packet, "target.routeState.path") ?? getPath(packet, "target.route");
|
|
97
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
98
|
+
};
|
|
99
|
+
var selectedMixProfileId = (packet) => {
|
|
100
|
+
const value = getPath(packet, "recommendation.candidate.summary.mixProfile.id") ?? getPath(packet, "baseline.mixProfile.id") ?? getPath(packet, "target.mixProfile.id");
|
|
101
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
102
|
+
};
|
|
103
|
+
function createDurableCandidatePatchPlan(proofOrPacket, options = {}) {
|
|
104
|
+
const packet = requireHumanReviewPacket(proofOrPacket);
|
|
105
|
+
const recommendation = asRecord(packet.recommendation);
|
|
106
|
+
const candidate = asRecord(recommendation.candidate);
|
|
107
|
+
const action = asRecord(candidate.action);
|
|
108
|
+
const guardrails = asRecord(packet.guardrails);
|
|
109
|
+
const request = asRecord(packet.request);
|
|
110
|
+
const approval = asRecord(request.approval);
|
|
111
|
+
const ranking = asRecord(packet.ranking);
|
|
112
|
+
const proofBoundary = packet.proofBoundary;
|
|
113
|
+
const target = {
|
|
114
|
+
label: selectedTargetLabel(packet),
|
|
115
|
+
route: selectedRoute(packet),
|
|
116
|
+
mixProfileId: selectedMixProfileId(packet)
|
|
117
|
+
};
|
|
118
|
+
const actionType = action.type;
|
|
119
|
+
const actionTrack = action.track;
|
|
120
|
+
const from = asFiniteNumber(action.from);
|
|
121
|
+
const to = asFiniteNumber(action.to);
|
|
122
|
+
const numericDelta = asFiniteNumber(action.delta);
|
|
123
|
+
const delta = numericDelta ?? (from !== null && to !== null ? asFiniteNumber(to - from) : null);
|
|
124
|
+
const allowedApprovalModes = new Set(options.allowedApprovalModes ?? DEFAULT_APPROVAL_MODES);
|
|
125
|
+
const allowedActionTypes = new Set(options.allowedActionTypes ?? DEFAULT_ACTION_TYPES);
|
|
126
|
+
const errors = [];
|
|
127
|
+
if (packet.status !== "candidate_applied_for_listening_review") {
|
|
128
|
+
errors.push("packet status must be candidate_applied_for_listening_review");
|
|
129
|
+
}
|
|
130
|
+
if (recommendation.action !== "listen_to_applied_candidate") {
|
|
131
|
+
errors.push("recommendation action must be listen_to_applied_candidate");
|
|
132
|
+
}
|
|
133
|
+
if (guardrails.approvedCandidateApplied !== true) {
|
|
134
|
+
errors.push("approvedCandidateApplied guardrail must be true");
|
|
135
|
+
}
|
|
136
|
+
if (request.candidateActionsAreTransient !== false) {
|
|
137
|
+
errors.push("candidateActionsAreTransient must be false before a durable patch handoff");
|
|
138
|
+
}
|
|
139
|
+
if (!approval.mode) {
|
|
140
|
+
errors.push("approval mode is required");
|
|
141
|
+
} else if (!allowedApprovalModes.has(String(approval.mode))) {
|
|
142
|
+
errors.push(`approval mode ${formatValue(approval.mode)} is not allowed for durable patch handoff`);
|
|
143
|
+
}
|
|
144
|
+
if (ranking.role !== "review_order_only") {
|
|
145
|
+
errors.push("ranking role must remain review_order_only");
|
|
146
|
+
}
|
|
147
|
+
if (!String(proofBoundary ?? "").includes("musical taste still requires listening review")) {
|
|
148
|
+
errors.push("proof boundary must preserve the listening-review caveat");
|
|
149
|
+
}
|
|
150
|
+
if (!actionType || !allowedActionTypes.has(String(actionType))) {
|
|
151
|
+
errors.push(`action type ${formatValue(actionType)} is not allowed for durable patch handoff`);
|
|
152
|
+
}
|
|
153
|
+
if (typeof actionTrack !== "string" || !actionTrack.trim()) {
|
|
154
|
+
errors.push("candidate action track is required");
|
|
155
|
+
}
|
|
156
|
+
if (to === null) {
|
|
157
|
+
errors.push("candidate action target value is required");
|
|
158
|
+
}
|
|
159
|
+
if (String(actionType) === "set_mixer_level" && (to === null || to < 0 || to > 1.5)) {
|
|
160
|
+
errors.push("set_mixer_level target must be between 0 and 1.5");
|
|
161
|
+
}
|
|
162
|
+
if (options.requireTargetLabel !== false && !target.label) {
|
|
163
|
+
errors.push("target label is required for a scoped durable patch handoff");
|
|
164
|
+
}
|
|
165
|
+
if (options.requireMixProfileId === true && !target.mixProfileId) {
|
|
166
|
+
errors.push("mixProfileId is required for this durable patch handoff");
|
|
167
|
+
}
|
|
168
|
+
const actionShape = {
|
|
169
|
+
type: actionType ?? null,
|
|
170
|
+
track: actionTrack ?? null,
|
|
171
|
+
from,
|
|
172
|
+
to,
|
|
173
|
+
delta
|
|
174
|
+
};
|
|
175
|
+
const mixerLevels = !errors.length && String(actionType) === "set_mixer_level" && typeof actionTrack === "string" && to !== null ? { [actionTrack]: to } : null;
|
|
176
|
+
return {
|
|
177
|
+
version: "riddle-proof.durable-candidate-patch-plan.v1",
|
|
178
|
+
kind: "durable_candidate_patch_plan",
|
|
179
|
+
status: errors.length ? "not_ready_for_durable_patch" : "ready_for_durable_patch",
|
|
180
|
+
ok: errors.length === 0,
|
|
181
|
+
errors,
|
|
182
|
+
source: {
|
|
183
|
+
packetStatus: packet.status ?? null,
|
|
184
|
+
recommendationAction: recommendation.action ?? null,
|
|
185
|
+
rankingRole: ranking.role ?? null,
|
|
186
|
+
proofBoundary: proofBoundary ?? null
|
|
187
|
+
},
|
|
188
|
+
target,
|
|
189
|
+
candidate: {
|
|
190
|
+
label: candidate.label ?? null,
|
|
191
|
+
action: actionShape
|
|
192
|
+
},
|
|
193
|
+
approval: {
|
|
194
|
+
mode: approval.mode ?? null,
|
|
195
|
+
approvedBy: approval.approvedBy ?? null,
|
|
196
|
+
basis: approval.basis ?? null
|
|
197
|
+
},
|
|
198
|
+
durableEdit: errors.length ? null : {
|
|
199
|
+
sourceFile: options.sourceFile ?? null,
|
|
200
|
+
target,
|
|
201
|
+
action: actionShape,
|
|
202
|
+
mixerLevels,
|
|
203
|
+
provenance: {
|
|
204
|
+
humanReviewPacketStatus: packet.status ?? null,
|
|
205
|
+
recommendationLabel: candidate.label ?? null,
|
|
206
|
+
approvalMode: approval.mode ?? null,
|
|
207
|
+
approvedBy: approval.approvedBy ?? null,
|
|
208
|
+
basis: approval.basis ?? null
|
|
209
|
+
},
|
|
210
|
+
doesNotProve: [
|
|
211
|
+
"subjective mix quality",
|
|
212
|
+
"that the approval surrogate is a real listener preference",
|
|
213
|
+
"all possible candidate edits"
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
boundary: "This is a durable patch handoff for an approved listening-review candidate. It does not prove subjective mix quality.",
|
|
217
|
+
caveats: [
|
|
218
|
+
"A durable patch plan is not a taste verdict.",
|
|
219
|
+
"Ranking orders review only; it is not a universal mix-quality score.",
|
|
220
|
+
"Run a final current-target proof after the durable edit lands."
|
|
221
|
+
]
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function formatDurableCandidatePatchPlanMarkdown(plan, options = {}) {
|
|
225
|
+
if (plan.kind !== "durable_candidate_patch_plan") {
|
|
226
|
+
throw new Error("Expected a durable_candidate_patch_plan");
|
|
227
|
+
}
|
|
228
|
+
const lines = [
|
|
229
|
+
`# ${options.title ?? "Durable Candidate Patch Plan"}`,
|
|
230
|
+
"",
|
|
231
|
+
`- status: ${formatCodeValue(plan.status)}`,
|
|
232
|
+
`- ok: ${formatCodeValue(plan.ok)}`,
|
|
233
|
+
`- target_label: ${formatValue(plan.target.label)}`,
|
|
234
|
+
`- mix_profile_id: ${formatCodeValue(plan.target.mixProfileId)}`,
|
|
235
|
+
`- source_file: ${formatCodeValue(plan.durableEdit?.sourceFile)}`,
|
|
236
|
+
"",
|
|
237
|
+
"## Candidate",
|
|
238
|
+
"",
|
|
239
|
+
`- label: ${formatCodeValue(plan.candidate.label)}`,
|
|
240
|
+
`- action: ${formatCodeValue(`${formatValue(plan.candidate.action.type)} ${formatValue(plan.candidate.action.track)}: ${formatValue(plan.candidate.action.from)} -> ${formatValue(plan.candidate.action.to)} (${formatValue(plan.candidate.action.delta)})`)}`,
|
|
241
|
+
"",
|
|
242
|
+
"## Approval Boundary",
|
|
243
|
+
"",
|
|
244
|
+
`- approval_mode: ${formatCodeValue(plan.approval.mode)}`,
|
|
245
|
+
`- approved_by: ${formatCodeValue(plan.approval.approvedBy)}`,
|
|
246
|
+
`- basis: ${formatValue(plan.approval.basis)}`,
|
|
247
|
+
`- boundary: ${formatValue(plan.boundary)}`,
|
|
248
|
+
"",
|
|
249
|
+
"## Durable Edit",
|
|
250
|
+
"",
|
|
251
|
+
`- mixer_levels: ${formatCodeValue(JSON.stringify(plan.durableEdit?.mixerLevels ?? null))}`
|
|
252
|
+
];
|
|
253
|
+
if (plan.errors.length) {
|
|
254
|
+
lines.push("", "## Errors", "");
|
|
255
|
+
for (const error of plan.errors) lines.push(`- ${error}`);
|
|
256
|
+
}
|
|
257
|
+
lines.push("", "## Caveats", "");
|
|
258
|
+
for (const caveat of plan.caveats) lines.push(`- ${caveat}`);
|
|
259
|
+
return `${lines.join("\n")}
|
|
260
|
+
`;
|
|
261
|
+
}
|
|
262
|
+
function createDurableCandidatePatchPlanArtifacts(proofOrPacket, options = {}) {
|
|
263
|
+
const plan = createDurableCandidatePatchPlan(proofOrPacket, options);
|
|
264
|
+
const markdown = formatDurableCandidatePatchPlanMarkdown(plan, {
|
|
265
|
+
title: options.title
|
|
266
|
+
});
|
|
267
|
+
return {
|
|
268
|
+
plan,
|
|
269
|
+
json: `${JSON.stringify(plan, null, 2)}
|
|
270
|
+
`,
|
|
271
|
+
markdown
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// src/durableCandidatePlanCli.ts
|
|
276
|
+
var DEFAULT_JSON_NAME = "durable-candidate-patch-plan.json";
|
|
277
|
+
var DEFAULT_MARKDOWN_NAME = "durable-candidate-patch-plan.md";
|
|
278
|
+
var USAGE = `riddle-proof-durable-candidate-plan --proof <path|-> [options]
|
|
279
|
+
|
|
280
|
+
Validate an applied human_review_packet and write a durable candidate patch
|
|
281
|
+
plan. This is a handoff artifact, not proof of subjective quality.
|
|
282
|
+
|
|
283
|
+
Options:
|
|
284
|
+
--proof <path|-> Riddle Proof proof.json/profile-result.json, packet JSON, or '-' for stdin.
|
|
285
|
+
--output <dir> Output directory. Defaults to the proof file directory.
|
|
286
|
+
--json <path> JSON output path. Defaults to <output>/durable-candidate-patch-plan.json.
|
|
287
|
+
--markdown <path> Markdown output path. Defaults to <output>/durable-candidate-patch-plan.md.
|
|
288
|
+
--title <title> Markdown title. Defaults to "Durable Candidate Patch Plan".
|
|
289
|
+
--source-file <path> Optional source file where the durable edit should be applied.
|
|
290
|
+
--require-mix-profile Require a mixProfileId before reporting ready_for_durable_patch.
|
|
291
|
+
--stdout Also print the Markdown handoff to stdout.
|
|
292
|
+
--help Show this help.
|
|
293
|
+
`;
|
|
294
|
+
var readValue = (argv, index, name) => {
|
|
295
|
+
const value = argv[index + 1];
|
|
296
|
+
if (!value || value.startsWith("--")) throw new Error(`${name} requires a value.`);
|
|
297
|
+
return value;
|
|
298
|
+
};
|
|
299
|
+
function parseDurableCandidatePlanCliArgs(argv) {
|
|
300
|
+
const parsed = {
|
|
301
|
+
help: false,
|
|
302
|
+
proofPath: null,
|
|
303
|
+
outputDir: null,
|
|
304
|
+
jsonPath: null,
|
|
305
|
+
markdownPath: null,
|
|
306
|
+
title: null,
|
|
307
|
+
sourceFile: null,
|
|
308
|
+
requireMixProfileId: false,
|
|
309
|
+
stdout: false
|
|
310
|
+
};
|
|
311
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
312
|
+
const arg = argv[index];
|
|
313
|
+
if (arg === "--help" || arg === "-h") {
|
|
314
|
+
parsed.help = true;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (arg === "--proof" || arg === "--packet") {
|
|
318
|
+
parsed.proofPath = readValue(argv, index, arg);
|
|
319
|
+
index += 1;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (arg === "--output" || arg === "--output-dir") {
|
|
323
|
+
parsed.outputDir = readValue(argv, index, arg);
|
|
324
|
+
index += 1;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (arg === "--json") {
|
|
328
|
+
parsed.jsonPath = readValue(argv, index, arg);
|
|
329
|
+
index += 1;
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
if (arg === "--markdown" || arg === "--md") {
|
|
333
|
+
parsed.markdownPath = readValue(argv, index, arg);
|
|
334
|
+
index += 1;
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (arg === "--title") {
|
|
338
|
+
parsed.title = readValue(argv, index, arg);
|
|
339
|
+
index += 1;
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (arg === "--source-file") {
|
|
343
|
+
parsed.sourceFile = readValue(argv, index, arg);
|
|
344
|
+
index += 1;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (arg === "--require-mix-profile") {
|
|
348
|
+
parsed.requireMixProfileId = true;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (arg === "--stdout") {
|
|
352
|
+
parsed.stdout = true;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (!arg.startsWith("--") && !parsed.proofPath) {
|
|
356
|
+
parsed.proofPath = arg;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
throw new Error(`Unknown argument ${arg}.`);
|
|
360
|
+
}
|
|
361
|
+
return parsed;
|
|
362
|
+
}
|
|
363
|
+
var readProofArtifact = (proofPath) => {
|
|
364
|
+
if (proofPath === "-") return JSON.parse((0, import_node_fs.readFileSync)(0, "utf8"));
|
|
365
|
+
const absoluteProofPath = import_node_path.default.resolve(proofPath);
|
|
366
|
+
if (!(0, import_node_fs.existsSync)(absoluteProofPath)) {
|
|
367
|
+
throw new Error(`Proof artifact not found: ${absoluteProofPath}`);
|
|
368
|
+
}
|
|
369
|
+
return JSON.parse((0, import_node_fs.readFileSync)(absoluteProofPath, "utf8"));
|
|
370
|
+
};
|
|
371
|
+
var outputDirFor = (proofPath, outputDir) => {
|
|
372
|
+
if (outputDir) return import_node_path.default.resolve(outputDir);
|
|
373
|
+
if (proofPath === "-") return process.cwd();
|
|
374
|
+
return import_node_path.default.dirname(import_node_path.default.resolve(proofPath));
|
|
375
|
+
};
|
|
376
|
+
function writeDurableCandidatePlanFiles({
|
|
377
|
+
proofPath,
|
|
378
|
+
outputDir,
|
|
379
|
+
jsonPath,
|
|
380
|
+
markdownPath,
|
|
381
|
+
title,
|
|
382
|
+
sourceFile,
|
|
383
|
+
requireMixProfileId
|
|
384
|
+
}) {
|
|
385
|
+
const proof = readProofArtifact(proofPath);
|
|
386
|
+
const artifacts = createDurableCandidatePatchPlanArtifacts(proof, {
|
|
387
|
+
title: title ?? void 0,
|
|
388
|
+
sourceFile: sourceFile ?? void 0,
|
|
389
|
+
requireMixProfileId
|
|
390
|
+
});
|
|
391
|
+
const resolvedOutputDir = outputDirFor(proofPath, outputDir);
|
|
392
|
+
const resolvedJsonPath = import_node_path.default.resolve(jsonPath ?? import_node_path.default.join(resolvedOutputDir, DEFAULT_JSON_NAME));
|
|
393
|
+
const resolvedMarkdownPath = import_node_path.default.resolve(markdownPath ?? import_node_path.default.join(resolvedOutputDir, DEFAULT_MARKDOWN_NAME));
|
|
394
|
+
(0, import_node_fs.mkdirSync)(import_node_path.default.dirname(resolvedJsonPath), { recursive: true });
|
|
395
|
+
(0, import_node_fs.mkdirSync)(import_node_path.default.dirname(resolvedMarkdownPath), { recursive: true });
|
|
396
|
+
(0, import_node_fs.writeFileSync)(resolvedJsonPath, artifacts.json);
|
|
397
|
+
(0, import_node_fs.writeFileSync)(resolvedMarkdownPath, artifacts.markdown);
|
|
398
|
+
return {
|
|
399
|
+
...artifacts,
|
|
400
|
+
jsonPath: resolvedJsonPath,
|
|
401
|
+
markdownPath: resolvedMarkdownPath
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
async function main(argv = process.argv.slice(2)) {
|
|
405
|
+
const args = parseDurableCandidatePlanCliArgs(argv);
|
|
406
|
+
if (args.help) {
|
|
407
|
+
(0, import_node_fs.writeFileSync)(1, USAGE);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (!args.proofPath) throw new Error("--proof is required.");
|
|
411
|
+
const result = writeDurableCandidatePlanFiles({
|
|
412
|
+
proofPath: args.proofPath,
|
|
413
|
+
outputDir: args.outputDir,
|
|
414
|
+
jsonPath: args.jsonPath,
|
|
415
|
+
markdownPath: args.markdownPath,
|
|
416
|
+
title: args.title,
|
|
417
|
+
sourceFile: args.sourceFile,
|
|
418
|
+
requireMixProfileId: args.requireMixProfileId
|
|
419
|
+
});
|
|
420
|
+
if (args.stdout) {
|
|
421
|
+
(0, import_node_fs.writeFileSync)(1, result.markdown);
|
|
422
|
+
} else {
|
|
423
|
+
(0, import_node_fs.writeFileSync)(1, `${JSON.stringify({
|
|
424
|
+
ok: result.plan.ok,
|
|
425
|
+
status: result.plan.status,
|
|
426
|
+
json: result.jsonPath,
|
|
427
|
+
markdown: result.markdownPath,
|
|
428
|
+
sourceFile: result.plan.durableEdit?.sourceFile ?? null,
|
|
429
|
+
errors: result.plan.errors
|
|
430
|
+
}, null, 2)}
|
|
431
|
+
`);
|
|
432
|
+
}
|
|
433
|
+
if (!result.plan.ok) process.exitCode = 2;
|
|
434
|
+
}
|
|
435
|
+
main().catch((error) => {
|
|
436
|
+
(0, import_node_fs.writeFileSync)(2, `${error instanceof Error ? error.message : String(error)}
|
|
437
|
+
`);
|
|
438
|
+
process.exitCode = 1;
|
|
439
|
+
});
|
|
440
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
441
|
+
0 && (module.exports = {
|
|
442
|
+
main,
|
|
443
|
+
parseDurableCandidatePlanCliArgs,
|
|
444
|
+
writeDurableCandidatePlanFiles
|
|
445
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { D as DurableCandidatePatchPlan } from './durableCandidatePlan-Dv2P33Wg.cjs';
|
|
2
|
+
|
|
3
|
+
interface ParsedArgs {
|
|
4
|
+
help: boolean;
|
|
5
|
+
proofPath: string | null;
|
|
6
|
+
outputDir: string | null;
|
|
7
|
+
jsonPath: string | null;
|
|
8
|
+
markdownPath: string | null;
|
|
9
|
+
title: string | null;
|
|
10
|
+
sourceFile: string | null;
|
|
11
|
+
requireMixProfileId: boolean;
|
|
12
|
+
stdout: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare function parseDurableCandidatePlanCliArgs(argv: string[]): ParsedArgs;
|
|
15
|
+
declare function writeDurableCandidatePlanFiles({ proofPath, outputDir, jsonPath, markdownPath, title, sourceFile, requireMixProfileId, }: {
|
|
16
|
+
proofPath: string;
|
|
17
|
+
outputDir: string | null;
|
|
18
|
+
jsonPath: string | null;
|
|
19
|
+
markdownPath: string | null;
|
|
20
|
+
title: string | null;
|
|
21
|
+
sourceFile: string | null;
|
|
22
|
+
requireMixProfileId: boolean;
|
|
23
|
+
}): {
|
|
24
|
+
jsonPath: string;
|
|
25
|
+
markdownPath: string;
|
|
26
|
+
plan: DurableCandidatePatchPlan;
|
|
27
|
+
json: string;
|
|
28
|
+
markdown: string;
|
|
29
|
+
};
|
|
30
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
31
|
+
|
|
32
|
+
export { main, parseDurableCandidatePlanCliArgs, writeDurableCandidatePlanFiles };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { D as DurableCandidatePatchPlan } from './durableCandidatePlan-Dv2P33Wg.js';
|
|
2
|
+
|
|
3
|
+
interface ParsedArgs {
|
|
4
|
+
help: boolean;
|
|
5
|
+
proofPath: string | null;
|
|
6
|
+
outputDir: string | null;
|
|
7
|
+
jsonPath: string | null;
|
|
8
|
+
markdownPath: string | null;
|
|
9
|
+
title: string | null;
|
|
10
|
+
sourceFile: string | null;
|
|
11
|
+
requireMixProfileId: boolean;
|
|
12
|
+
stdout: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare function parseDurableCandidatePlanCliArgs(argv: string[]): ParsedArgs;
|
|
15
|
+
declare function writeDurableCandidatePlanFiles({ proofPath, outputDir, jsonPath, markdownPath, title, sourceFile, requireMixProfileId, }: {
|
|
16
|
+
proofPath: string;
|
|
17
|
+
outputDir: string | null;
|
|
18
|
+
jsonPath: string | null;
|
|
19
|
+
markdownPath: string | null;
|
|
20
|
+
title: string | null;
|
|
21
|
+
sourceFile: string | null;
|
|
22
|
+
requireMixProfileId: boolean;
|
|
23
|
+
}): {
|
|
24
|
+
jsonPath: string;
|
|
25
|
+
markdownPath: string;
|
|
26
|
+
plan: DurableCandidatePatchPlan;
|
|
27
|
+
json: string;
|
|
28
|
+
markdown: string;
|
|
29
|
+
};
|
|
30
|
+
declare function main(argv?: string[]): Promise<void>;
|
|
31
|
+
|
|
32
|
+
export { main, parseDurableCandidatePlanCliArgs, writeDurableCandidatePlanFiles };
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createDurableCandidatePatchPlanArtifacts
|
|
3
|
+
} from "./chunk-VFPSPQD7.js";
|
|
4
|
+
import "./chunk-SAE6HFAG.js";
|
|
5
|
+
|
|
6
|
+
// src/durableCandidatePlanCli.ts
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
var DEFAULT_JSON_NAME = "durable-candidate-patch-plan.json";
|
|
10
|
+
var DEFAULT_MARKDOWN_NAME = "durable-candidate-patch-plan.md";
|
|
11
|
+
var USAGE = `riddle-proof-durable-candidate-plan --proof <path|-> [options]
|
|
12
|
+
|
|
13
|
+
Validate an applied human_review_packet and write a durable candidate patch
|
|
14
|
+
plan. This is a handoff artifact, not proof of subjective quality.
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--proof <path|-> Riddle Proof proof.json/profile-result.json, packet JSON, or '-' for stdin.
|
|
18
|
+
--output <dir> Output directory. Defaults to the proof file directory.
|
|
19
|
+
--json <path> JSON output path. Defaults to <output>/durable-candidate-patch-plan.json.
|
|
20
|
+
--markdown <path> Markdown output path. Defaults to <output>/durable-candidate-patch-plan.md.
|
|
21
|
+
--title <title> Markdown title. Defaults to "Durable Candidate Patch Plan".
|
|
22
|
+
--source-file <path> Optional source file where the durable edit should be applied.
|
|
23
|
+
--require-mix-profile Require a mixProfileId before reporting ready_for_durable_patch.
|
|
24
|
+
--stdout Also print the Markdown handoff to stdout.
|
|
25
|
+
--help Show this help.
|
|
26
|
+
`;
|
|
27
|
+
var readValue = (argv, index, name) => {
|
|
28
|
+
const value = argv[index + 1];
|
|
29
|
+
if (!value || value.startsWith("--")) throw new Error(`${name} requires a value.`);
|
|
30
|
+
return value;
|
|
31
|
+
};
|
|
32
|
+
function parseDurableCandidatePlanCliArgs(argv) {
|
|
33
|
+
const parsed = {
|
|
34
|
+
help: false,
|
|
35
|
+
proofPath: null,
|
|
36
|
+
outputDir: null,
|
|
37
|
+
jsonPath: null,
|
|
38
|
+
markdownPath: null,
|
|
39
|
+
title: null,
|
|
40
|
+
sourceFile: null,
|
|
41
|
+
requireMixProfileId: false,
|
|
42
|
+
stdout: false
|
|
43
|
+
};
|
|
44
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
45
|
+
const arg = argv[index];
|
|
46
|
+
if (arg === "--help" || arg === "-h") {
|
|
47
|
+
parsed.help = true;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (arg === "--proof" || arg === "--packet") {
|
|
51
|
+
parsed.proofPath = readValue(argv, index, arg);
|
|
52
|
+
index += 1;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (arg === "--output" || arg === "--output-dir") {
|
|
56
|
+
parsed.outputDir = readValue(argv, index, arg);
|
|
57
|
+
index += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (arg === "--json") {
|
|
61
|
+
parsed.jsonPath = readValue(argv, index, arg);
|
|
62
|
+
index += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (arg === "--markdown" || arg === "--md") {
|
|
66
|
+
parsed.markdownPath = readValue(argv, index, arg);
|
|
67
|
+
index += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (arg === "--title") {
|
|
71
|
+
parsed.title = readValue(argv, index, arg);
|
|
72
|
+
index += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (arg === "--source-file") {
|
|
76
|
+
parsed.sourceFile = readValue(argv, index, arg);
|
|
77
|
+
index += 1;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (arg === "--require-mix-profile") {
|
|
81
|
+
parsed.requireMixProfileId = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (arg === "--stdout") {
|
|
85
|
+
parsed.stdout = true;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (!arg.startsWith("--") && !parsed.proofPath) {
|
|
89
|
+
parsed.proofPath = arg;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
throw new Error(`Unknown argument ${arg}.`);
|
|
93
|
+
}
|
|
94
|
+
return parsed;
|
|
95
|
+
}
|
|
96
|
+
var readProofArtifact = (proofPath) => {
|
|
97
|
+
if (proofPath === "-") return JSON.parse(readFileSync(0, "utf8"));
|
|
98
|
+
const absoluteProofPath = path.resolve(proofPath);
|
|
99
|
+
if (!existsSync(absoluteProofPath)) {
|
|
100
|
+
throw new Error(`Proof artifact not found: ${absoluteProofPath}`);
|
|
101
|
+
}
|
|
102
|
+
return JSON.parse(readFileSync(absoluteProofPath, "utf8"));
|
|
103
|
+
};
|
|
104
|
+
var outputDirFor = (proofPath, outputDir) => {
|
|
105
|
+
if (outputDir) return path.resolve(outputDir);
|
|
106
|
+
if (proofPath === "-") return process.cwd();
|
|
107
|
+
return path.dirname(path.resolve(proofPath));
|
|
108
|
+
};
|
|
109
|
+
function writeDurableCandidatePlanFiles({
|
|
110
|
+
proofPath,
|
|
111
|
+
outputDir,
|
|
112
|
+
jsonPath,
|
|
113
|
+
markdownPath,
|
|
114
|
+
title,
|
|
115
|
+
sourceFile,
|
|
116
|
+
requireMixProfileId
|
|
117
|
+
}) {
|
|
118
|
+
const proof = readProofArtifact(proofPath);
|
|
119
|
+
const artifacts = createDurableCandidatePatchPlanArtifacts(proof, {
|
|
120
|
+
title: title ?? void 0,
|
|
121
|
+
sourceFile: sourceFile ?? void 0,
|
|
122
|
+
requireMixProfileId
|
|
123
|
+
});
|
|
124
|
+
const resolvedOutputDir = outputDirFor(proofPath, outputDir);
|
|
125
|
+
const resolvedJsonPath = path.resolve(jsonPath ?? path.join(resolvedOutputDir, DEFAULT_JSON_NAME));
|
|
126
|
+
const resolvedMarkdownPath = path.resolve(markdownPath ?? path.join(resolvedOutputDir, DEFAULT_MARKDOWN_NAME));
|
|
127
|
+
mkdirSync(path.dirname(resolvedJsonPath), { recursive: true });
|
|
128
|
+
mkdirSync(path.dirname(resolvedMarkdownPath), { recursive: true });
|
|
129
|
+
writeFileSync(resolvedJsonPath, artifacts.json);
|
|
130
|
+
writeFileSync(resolvedMarkdownPath, artifacts.markdown);
|
|
131
|
+
return {
|
|
132
|
+
...artifacts,
|
|
133
|
+
jsonPath: resolvedJsonPath,
|
|
134
|
+
markdownPath: resolvedMarkdownPath
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
async function main(argv = process.argv.slice(2)) {
|
|
138
|
+
const args = parseDurableCandidatePlanCliArgs(argv);
|
|
139
|
+
if (args.help) {
|
|
140
|
+
writeFileSync(1, USAGE);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (!args.proofPath) throw new Error("--proof is required.");
|
|
144
|
+
const result = writeDurableCandidatePlanFiles({
|
|
145
|
+
proofPath: args.proofPath,
|
|
146
|
+
outputDir: args.outputDir,
|
|
147
|
+
jsonPath: args.jsonPath,
|
|
148
|
+
markdownPath: args.markdownPath,
|
|
149
|
+
title: args.title,
|
|
150
|
+
sourceFile: args.sourceFile,
|
|
151
|
+
requireMixProfileId: args.requireMixProfileId
|
|
152
|
+
});
|
|
153
|
+
if (args.stdout) {
|
|
154
|
+
writeFileSync(1, result.markdown);
|
|
155
|
+
} else {
|
|
156
|
+
writeFileSync(1, `${JSON.stringify({
|
|
157
|
+
ok: result.plan.ok,
|
|
158
|
+
status: result.plan.status,
|
|
159
|
+
json: result.jsonPath,
|
|
160
|
+
markdown: result.markdownPath,
|
|
161
|
+
sourceFile: result.plan.durableEdit?.sourceFile ?? null,
|
|
162
|
+
errors: result.plan.errors
|
|
163
|
+
}, null, 2)}
|
|
164
|
+
`);
|
|
165
|
+
}
|
|
166
|
+
if (!result.plan.ok) process.exitCode = 2;
|
|
167
|
+
}
|
|
168
|
+
main().catch((error) => {
|
|
169
|
+
writeFileSync(2, `${error instanceof Error ? error.message : String(error)}
|
|
170
|
+
`);
|
|
171
|
+
process.exitCode = 1;
|
|
172
|
+
});
|
|
173
|
+
export {
|
|
174
|
+
main,
|
|
175
|
+
parseDurableCandidatePlanCliArgs,
|
|
176
|
+
writeDurableCandidatePlanFiles
|
|
177
|
+
};
|