@momentiq/dark-factory-cli 2.13.2 → 2.15.0

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.
@@ -0,0 +1,594 @@
1
+ // `df objectives` — Objectives authoring commands for verifiable-objectives
2
+ // (momentiq-ai/dark-factory#207, objectives Phase 1).
3
+ //
4
+ // Subcommands:
5
+ // hash — print the canonical sha256 of a criterion text (for manifest authoring)
6
+ // derive — generate a .darkfactory/objectives.yaml from cycle-doc exit criteria (Task 5)
7
+ // check — verify text-hash bindings in an existing manifest (Task 6)
8
+ //
9
+ // Exit codes: 0 success / 1 semantic failure / 2 usage error.
10
+ import { createHash } from "node:crypto";
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
12
+ import { dirname, join, resolve } from "node:path";
13
+ import { canonicalizeCriterion, parseObjectivesManifest, SOURCE_LOCATOR_RE, } from "@momentiq/dark-factory-schemas";
14
+ import { parse as yamlParse, stringify as yamlStringify } from "yaml";
15
+ import { readCycleDoc } from "../mcp/cycle-doc/parser.js";
16
+ export function parseObjectivesArgs(rest) {
17
+ const sub = rest[0];
18
+ const subRest = rest.slice(1);
19
+ if (sub === undefined || sub === "") {
20
+ return { subcommand: undefined };
21
+ }
22
+ if (sub === "hash") {
23
+ return parseHashArgs(subRest);
24
+ }
25
+ if (sub === "derive") {
26
+ return parseDeriveArgs(subRest);
27
+ }
28
+ if (sub === "check") {
29
+ return parseCheckArgs(subRest);
30
+ }
31
+ return { error: `unknown subcommand: ${sub}` };
32
+ }
33
+ function parseHashArgs(rest) {
34
+ let text;
35
+ for (let i = 0; i < rest.length; i++) {
36
+ const a = rest[i] ?? "";
37
+ if (a === "--text") {
38
+ const next = rest[i + 1];
39
+ if (next === undefined || next.startsWith("--")) {
40
+ return { error: "--text requires a value." };
41
+ }
42
+ text = next;
43
+ i++;
44
+ continue;
45
+ }
46
+ if (a.startsWith("--text=")) {
47
+ text = a.slice("--text=".length);
48
+ continue;
49
+ }
50
+ // Flags that are not yet implemented
51
+ if (a === "--locator" || a === "--cycle") {
52
+ return {
53
+ error: `${a} is not yet implemented — use --text "<criterion>" to hash a criterion directly.`,
54
+ };
55
+ }
56
+ if (a.startsWith("--locator=") || a.startsWith("--cycle=")) {
57
+ const flag = a.startsWith("--locator=") ? "--locator" : "--cycle";
58
+ return {
59
+ error: `${flag} is not yet implemented — use --text "<criterion>" to hash a criterion directly.`,
60
+ };
61
+ }
62
+ return { error: `unknown flag or positional arg: ${a}` };
63
+ }
64
+ if (text === undefined) {
65
+ return { error: "--text is required (e.g. --text \"- **EC1**: Criterion text\")." };
66
+ }
67
+ return { subcommand: "hash", text };
68
+ }
69
+ function parseDeriveArgs(rest) {
70
+ let cycle;
71
+ let apply = false;
72
+ let json = false;
73
+ let cwd = process.cwd();
74
+ for (let i = 0; i < rest.length; i++) {
75
+ const a = rest[i] ?? "";
76
+ if (a === "--cycle") {
77
+ const next = rest[i + 1];
78
+ if (next === undefined || next.startsWith("--")) {
79
+ return { error: "--cycle requires a value (e.g. --cycle 23)." };
80
+ }
81
+ cycle = next;
82
+ i++;
83
+ continue;
84
+ }
85
+ if (a.startsWith("--cycle=")) {
86
+ cycle = a.slice("--cycle=".length);
87
+ continue;
88
+ }
89
+ if (a === "--cwd") {
90
+ const next = rest[i + 1];
91
+ if (next === undefined || next.startsWith("--")) {
92
+ return { error: "--cwd requires a value." };
93
+ }
94
+ cwd = next;
95
+ i++;
96
+ continue;
97
+ }
98
+ if (a.startsWith("--cwd=")) {
99
+ cwd = a.slice("--cwd=".length);
100
+ continue;
101
+ }
102
+ if (a === "--apply") {
103
+ apply = true;
104
+ continue;
105
+ }
106
+ if (a === "--json") {
107
+ json = true;
108
+ continue;
109
+ }
110
+ return { error: `unknown flag or positional arg: ${a}` };
111
+ }
112
+ if (cycle === undefined || cycle === "") {
113
+ return { error: "--cycle is required (e.g. --cycle 23)." };
114
+ }
115
+ // Normalize a `cycle23` / `cycle 23` style value down to the bare number the
116
+ // id + source.ref use (`cycle<N>#ec<k>`, `{kind:"cycle", ref:"<N>"}`). The
117
+ // cycle-doc parser keys on the `cycle<N>` id form, so we rebuild that below.
118
+ const ref = cycle.replace(/^cycle/i, "").trim();
119
+ if (ref === "" || !/^\d+(?:\.\d+)*$/.test(ref)) {
120
+ return { error: `--cycle must be a cycle number (e.g. 23 or cycle23), got ${JSON.stringify(cycle)}.` };
121
+ }
122
+ return { subcommand: "derive", cycle: ref, apply, json, cwd };
123
+ }
124
+ function parseCheckArgs(rest) {
125
+ let json = false;
126
+ let cwd = process.cwd();
127
+ for (let i = 0; i < rest.length; i++) {
128
+ const a = rest[i] ?? "";
129
+ if (a === "--cwd") {
130
+ const next = rest[i + 1];
131
+ if (next === undefined || next.startsWith("--")) {
132
+ return { error: "--cwd requires a value." };
133
+ }
134
+ cwd = next;
135
+ i++;
136
+ continue;
137
+ }
138
+ if (a.startsWith("--cwd=")) {
139
+ cwd = a.slice("--cwd=".length);
140
+ continue;
141
+ }
142
+ if (a === "--json") {
143
+ json = true;
144
+ continue;
145
+ }
146
+ return { error: `unknown flag or positional arg: ${a}` };
147
+ }
148
+ return { subcommand: "check", json, cwd };
149
+ }
150
+ // ---------------------------------------------------------------------------
151
+ // Exit-criteria extraction — the hash-consistency core.
152
+ //
153
+ // This MUST enumerate list items and assign criterion ids IDENTICALLY to the
154
+ // Python gate validator's resolver (`validate_cycle_doc.py` `_list_items` +
155
+ // `_find_criterion`), or a derived manifest's text-hash sha256 will not match
156
+ // what the validator recomputes and every objective fails the gate.
157
+ //
158
+ // - Item enumeration mirrors `_list_items`: a line is an item iff it matches
159
+ // `^\s*(?:[-*+]|\d+[.)])\s+` (dash/star/plus or `N.`/`N)` markers).
160
+ // - Id assignment mirrors `_find_criterion`'s resolution, inverted: the
161
+ // validator resolves `ec<k>` by (1) an explicit `EC<k>` label match, else
162
+ // (2) positional (`ec<N>` → Nth item). So we read each item's OWN `EC<k>`
163
+ // label (the validator's label regex, constrained to the `EC<digits>`
164
+ // exit-criterion convention so every id stays valid per OBJECTIVE_ID_RE);
165
+ // when no `EC<k>` label is present we fall back to positional `ec<index>`.
166
+ // Round-tripping is verified: `_find_criterion(section, <our id>)` returns
167
+ // the exact line we hashed, across in-order / out-of-order / mixed / plain
168
+ // / numbered docs (see the unit tests).
169
+ //
170
+ // The sha256 we emit is `sha256(canonicalizeCriterion(<raw item line>))` — the
171
+ // FULL raw line, exactly the `ctext` the validator feeds to
172
+ // `canonicalize_criterion`. `canonicalizeCriterion` (the shared schema mirror)
173
+ // strips the marker + label + emphasis itself, so feeding the raw line is what
174
+ // keeps the two sides byte-identical.
175
+ // ---------------------------------------------------------------------------
176
+ // Mirror of the validator's `_list_items` item-detection regex.
177
+ const ITEM_RE = /^\s*(?:[-*+]|\d+[.)])\s+/;
178
+ // Mirror of the validator's `_find_criterion` label regex, constrained to the
179
+ // `EC<digits>` exit-criterion convention and capturing the number. Requires a
180
+ // trailing separator `[:.)–—-]` exactly like the validator (so a bare
181
+ // "`EC1` foo" with no separator correctly falls through to positional, matching
182
+ // the validator's resolution).
183
+ const EC_LABEL_RE = /^\s*(?:[-*+]|\d+[.)])\s*\*{0,2}EC(\d+)\*{0,2}\s*[:.)–—-]/i;
184
+ // Display-text derivation: strip the list marker, then a leading `EC<k>` token
185
+ // (bold/backtick-wrapped, with or without a separator), then residual emphasis,
186
+ // and fold whitespace. This is the human-facing `text` field only — it is NOT
187
+ // the hash input (the hash uses `canonicalizeCriterion(<raw line>)`), so its
188
+ // exact shape carries no cross-impl contract; it just reads cleanly.
189
+ function criterionDisplayText(rawLine) {
190
+ let s = rawLine.normalize("NFC");
191
+ s = s.replace(/^\s*(?:[-*+]|\d+[.)])\s+/, ""); // list marker
192
+ s = s.replace(/^\s*[`*]{0,2}EC\d+[`*]{0,2}\s*(?:[:.)–—-]\s+)?/i, ""); // EC<k> label token
193
+ s = s.replace(/[*`]/g, ""); // residual emphasis / code ticks
194
+ s = s.replace(/\s+/g, " ").trim();
195
+ return s;
196
+ }
197
+ /**
198
+ * Enumerate a `## Exit criteria` section body's items and assign each a
199
+ * validator-compatible criterion id. See the block comment above for the
200
+ * cross-impl-consistency contract this upholds.
201
+ *
202
+ * Each item also carries the non-marker continuation lines that follow it (up
203
+ * to the next blank line / list item), so callers can detect multi-line
204
+ * criteria — see `continuationLines`.
205
+ */
206
+ export function extractExitCriteria(sectionBody) {
207
+ const out = [];
208
+ const lines = sectionBody.split(/\r?\n/);
209
+ let itemIndex = 0;
210
+ for (let i = 0; i < lines.length; i++) {
211
+ const line = lines[i] ?? "";
212
+ if (!ITEM_RE.test(line))
213
+ continue;
214
+ const raw = line;
215
+ const labelMatch = EC_LABEL_RE.exec(raw);
216
+ const id = labelMatch ? `ec${parseInt(labelMatch[1] ?? "", 10)}` : `ec${itemIndex + 1}`;
217
+ itemIndex++;
218
+ // Collect continuation lines: subsequent lines until a blank line or the
219
+ // next list item. A blank line terminates the item; a marker line is the
220
+ // next item (so it is NOT a continuation and stays available to the outer
221
+ // loop). Only non-marker, non-blank lines are continuations.
222
+ const continuationLines = [];
223
+ for (let j = i + 1; j < lines.length; j++) {
224
+ const next = lines[j] ?? "";
225
+ if (next.trim() === "")
226
+ break; // blank line terminates the item
227
+ if (ITEM_RE.test(next))
228
+ break; // next list item (incl. nested sub-bullets)
229
+ continuationLines.push(next);
230
+ }
231
+ out.push({ id, text: criterionDisplayText(raw), raw, continuationLines });
232
+ }
233
+ return out;
234
+ }
235
+ function sha256Hex(s) {
236
+ return createHash("sha256").update(s, "utf8").digest("hex");
237
+ }
238
+ const MANIFEST_RELATIVE_PATH = join(".darkfactory", "objectives.yaml");
239
+ const HELP = [
240
+ "df objectives — objectives authoring commands for verifiable-objectives.",
241
+ "",
242
+ "Usage:",
243
+ " df objectives <subcommand> [flags]",
244
+ "",
245
+ "Subcommands:",
246
+ " hash Print the canonical sha256 of a criterion text.",
247
+ " derive Generate .darkfactory/objectives.yaml from cycle-doc exit criteria.",
248
+ " check Verify text-hash bindings in an existing manifest.",
249
+ "",
250
+ "Flags (hash):",
251
+ " --text <criterion> Criterion text to hash (required).",
252
+ "",
253
+ "Flags (derive):",
254
+ " --cycle <N> Cycle number whose Exit criteria to derive from (required).",
255
+ " --apply Write .darkfactory/objectives.yaml (default: print to stdout).",
256
+ " --cwd <path> Repository root to operate in (default: process cwd).",
257
+ " --json Emit the manifest object as JSON instead of YAML.",
258
+ "",
259
+ "Flags (check):",
260
+ " --cwd <path> Repository root containing .darkfactory/objectives.yaml (default: process cwd).",
261
+ " --json Emit a structured JSON result.",
262
+ "",
263
+ " --help, -h Show this message.",
264
+ "",
265
+ "Exit codes:",
266
+ " 0 success",
267
+ " 1 semantic failure",
268
+ " 2 usage / flag error",
269
+ "",
270
+ ].join("\n");
271
+ export async function cmdObjectives(rest, io, deps = {}) {
272
+ if (rest.includes("--help") || rest.includes("-h")) {
273
+ io.stdout(`${HELP}`);
274
+ return 0;
275
+ }
276
+ const parsed = parseObjectivesArgs(rest);
277
+ if ("error" in parsed) {
278
+ io.stderr(`df objectives: ${parsed.error}\nRun \`df objectives --help\` for usage.\n`);
279
+ return 2;
280
+ }
281
+ if (parsed.subcommand === undefined) {
282
+ io.stdout(`${HELP}`);
283
+ return 2;
284
+ }
285
+ if (parsed.subcommand === "hash") {
286
+ const digest = createHash("sha256").update(canonicalizeCriterion(parsed.text), "utf8").digest("hex");
287
+ io.stdout(digest + "\n");
288
+ return 0;
289
+ }
290
+ if (parsed.subcommand === "derive") {
291
+ return cmdDerive(parsed, io, deps);
292
+ }
293
+ if (parsed.subcommand === "check") {
294
+ return cmdCheck(parsed, io, deps);
295
+ }
296
+ // Should not reach here since parseObjectivesArgs handles unknown subcommands
297
+ io.stdout(`${HELP}`);
298
+ return 2;
299
+ }
300
+ async function cmdDerive(opts, io, deps) {
301
+ const read = deps.readCycleDoc ?? readCycleDoc;
302
+ const cycleDocId = `cycle${opts.cycle}`;
303
+ const doc = await read(opts.cwd, cycleDocId);
304
+ if (doc === null) {
305
+ io.stderr(`df objectives derive: cycle doc ${cycleDocId} not found under ` +
306
+ `${join(opts.cwd, "docs/roadmap/cycles")} — nothing to derive.\n`);
307
+ return 1;
308
+ }
309
+ const section = doc.sections["exit_criteria"];
310
+ if (section === undefined || section.trim() === "") {
311
+ io.stderr(`df objectives derive: cycle doc ${cycleDocId} has no '## Exit criteria' section ` +
312
+ "(or it is empty) — nothing to derive.\n");
313
+ return 1;
314
+ }
315
+ const criteria = extractExitCriteria(section);
316
+ if (criteria.length === 0) {
317
+ io.stderr(`df objectives derive: cycle doc ${cycleDocId} '## Exit criteria' section has no ` +
318
+ "list items — nothing to derive.\n");
319
+ return 1;
320
+ }
321
+ // Multi-line-criterion guard (fail-loud). The hash unit is the single `raw`
322
+ // item line, so any continuation line is content SILENTLY excluded from the
323
+ // source binding: editing it would not change the sha256, yet `df objectives
324
+ // check` and the dashboard `source-bound` rung would still pass — an unsound
325
+ // binding. The design intends SINGLE-LINE atomic exit criteria (spec §4.3),
326
+ // so REFUSE to mis-bind rather than dropping the continuation silently. The
327
+ // author must make the criterion a single line (or split it into multiple
328
+ // single-line criteria). This catches only NON-marker continuations; a
329
+ // marker-led nested sub-bullet is enumerated as its own item (the distinct
330
+ // phantom-objective case, tracked at dark-factory#248).
331
+ const multiLine = criteria.filter((c) => c.continuationLines.length > 0);
332
+ if (multiLine.length > 0) {
333
+ const detail = multiLine
334
+ .map((c) => ` - ${cycleDocId}#${c.id}: ${JSON.stringify(c.raw.trim())} ` +
335
+ `has ${c.continuationLines.length} continuation line` +
336
+ `${c.continuationLines.length === 1 ? "" : "s"} (first: ` +
337
+ `${JSON.stringify((c.continuationLines[0] ?? "").trim())})`)
338
+ .join("\n");
339
+ io.stderr(`df objectives derive: ${cycleDocId} '## Exit criteria' has multi-line ` +
340
+ `criterion/criteria — refusing to mis-bind.\n${detail}\n` +
341
+ `Each exit criterion must be a SINGLE line: only that line is hashed into ` +
342
+ `the source binding, so a continuation line would be silently excluded ` +
343
+ `(editing it would not change the binding). Rewrite each offending ` +
344
+ `criterion as one line (or split it into multiple single-line criteria), ` +
345
+ `then re-run. See the derive-from-source design §4.3 (single-line atomic ` +
346
+ `criteria).\n`);
347
+ return 1;
348
+ }
349
+ // Duplicate-id guard: a cycle doc with two identically-labeled EC items
350
+ // (e.g. two `**EC1**` entries) produces criteria with the same id. That is an
351
+ // authoring error in the cycle doc — duplicate objective ids make proof/evidence
352
+ // binding ambiguous and are REJECTED by `parseObjectivesManifest`. Fail here
353
+ // with a clear, actionable message rather than letting the self-validation
354
+ // round-trip below throw an opaque "internal error".
355
+ const seenIds = new Set();
356
+ const duplicateIds = new Set();
357
+ for (const c of criteria) {
358
+ const fullId = `${cycleDocId}#${c.id}`;
359
+ if (seenIds.has(fullId))
360
+ duplicateIds.add(fullId);
361
+ seenIds.add(fullId);
362
+ }
363
+ if (duplicateIds.size > 0) {
364
+ io.stderr(`df objectives derive: ${cycleDocId} exit criteria has duplicate criterion ` +
365
+ `id(s): ${[...duplicateIds].join(", ")}. Criterion labels (e.g. \`EC1\`) must be ` +
366
+ `unique — fix the cycle doc to use distinct labels, then re-run.\n`);
367
+ return 1;
368
+ }
369
+ // Idempotence: preserve hand-edited `attestedBy` bindings from an existing
370
+ // manifest by objective id. Re-running refreshes text/hash + reconciles
371
+ // added/removed criteria, but never clobbers bindings the agent authored.
372
+ const manifestPath = resolve(opts.cwd, MANIFEST_RELATIVE_PATH);
373
+ const preservedBindings = loadPreservedBindings(manifestPath, io);
374
+ const objectives = criteria.map((c) => {
375
+ const id = `${cycleDocId}#${c.id}`;
376
+ const locator = `exit_criteria#${c.id}`;
377
+ // Defensive: the locator is built from `exit_criteria` + an `ec<k>` id, both
378
+ // of which satisfy SOURCE_LOCATOR_RE by construction — assert it so a future
379
+ // id-scheme change can't silently emit an unparseable locator.
380
+ if (!SOURCE_LOCATOR_RE.test(locator)) {
381
+ throw new Error(`internal: derived locator ${JSON.stringify(locator)} is malformed`);
382
+ }
383
+ const sha256 = sha256Hex(canonicalizeCriterion(c.raw));
384
+ return {
385
+ id,
386
+ source: { kind: "cycle", ref: opts.cycle },
387
+ text: c.text,
388
+ attestedBy: preservedBindings.get(id) ?? [],
389
+ enforced: false,
390
+ sourceCriterion: { kind: "text-hash", locator, sha256 },
391
+ };
392
+ });
393
+ const manifest = { schemaVersion: 1, objectives };
394
+ // Validate our own output against the schema parser — a derived manifest that
395
+ // can't round-trip is a bug, surfaced loudly here rather than at gate time.
396
+ try {
397
+ parseObjectivesManifest(manifest);
398
+ }
399
+ catch (err) {
400
+ io.stderr(`df objectives derive: internal error — derived manifest failed schema validation: ${err instanceof Error ? err.message : String(err)}\n`);
401
+ return 1;
402
+ }
403
+ if (opts.json) {
404
+ io.stdout(`${JSON.stringify(manifest, null, 2)}\n`);
405
+ }
406
+ const yaml = yamlStringify(manifest);
407
+ if (opts.apply) {
408
+ mkdirSync(dirname(manifestPath), { recursive: true });
409
+ writeFileSync(manifestPath, yaml, "utf8");
410
+ if (!opts.json) {
411
+ io.stdout(`Wrote ${objectives.length} objective${objectives.length === 1 ? "" : "s"} to ` +
412
+ `${MANIFEST_RELATIVE_PATH}\n`);
413
+ }
414
+ return 0;
415
+ }
416
+ if (!opts.json) {
417
+ io.stdout(yaml);
418
+ }
419
+ return 0;
420
+ }
421
+ async function cmdCheck(opts, io, deps) {
422
+ const read = deps.readCycleDoc ?? readCycleDoc;
423
+ const manifestPath = resolve(opts.cwd, MANIFEST_RELATIVE_PATH);
424
+ if (!existsSync(manifestPath)) {
425
+ const msg = `No ${MANIFEST_RELATIVE_PATH} found under ${opts.cwd} — nothing to check.`;
426
+ if (opts.json) {
427
+ io.stdout(JSON.stringify({ ok: true, note: msg, results: [] }, null, 2) + "\n");
428
+ }
429
+ else {
430
+ io.stdout(`note: ${msg}\n`);
431
+ }
432
+ return 0;
433
+ }
434
+ let manifest;
435
+ try {
436
+ const raw = readFileSync(manifestPath, "utf8");
437
+ manifest = parseObjectivesManifest(yamlParse(raw));
438
+ }
439
+ catch (err) {
440
+ io.stderr(`df objectives check: ${MANIFEST_RELATIVE_PATH} could not be parsed: ${err instanceof Error ? err.message : String(err)}\n`);
441
+ return 1;
442
+ }
443
+ const results = [];
444
+ let anyFail = false;
445
+ for (const obj of manifest.objectives) {
446
+ const sc = obj.sourceCriterion;
447
+ if (sc === undefined) {
448
+ results.push({ id: obj.id, status: "note", message: "no sourceCriterion binding — skipped." });
449
+ continue;
450
+ }
451
+ if (sc.kind === "human-reviewed") {
452
+ results.push({ id: obj.id, status: "note", message: "human-reviewed — skipped." });
453
+ continue;
454
+ }
455
+ if (sc.kind === "inferred") {
456
+ results.push({
457
+ id: obj.id,
458
+ status: "note",
459
+ message: "inferred (awaiting ratification) — skipped.",
460
+ });
461
+ continue;
462
+ }
463
+ // sc.kind === "text-hash"
464
+ // Parse the locator: `<section>#<criterion-id>`
465
+ const hashMatch = /^([^#]+)#(.+)$/.exec(sc.locator);
466
+ if (!hashMatch) {
467
+ results.push({ id: obj.id, status: "fail", message: `malformed locator: ${sc.locator}` });
468
+ anyFail = true;
469
+ continue;
470
+ }
471
+ const sectionSlug = hashMatch[1];
472
+ const criterionId = hashMatch[2];
473
+ // Only `exit_criteria` is currently resolvable.
474
+ if (sectionSlug !== "exit_criteria") {
475
+ results.push({
476
+ id: obj.id,
477
+ status: "fail",
478
+ message: `unsupported section in locator: ${sectionSlug} (only exit_criteria is supported).`,
479
+ });
480
+ anyFail = true;
481
+ continue;
482
+ }
483
+ // Derive cycle id from the objective id (`cycle<N>#ec<k>` → `cycle<N>`).
484
+ const cycleIdMatch = /^(cycle[^#]+)#/.exec(obj.id);
485
+ if (!cycleIdMatch || !obj.source || obj.source.kind !== "cycle") {
486
+ results.push({
487
+ id: obj.id,
488
+ status: "fail",
489
+ message: `cannot derive cycle doc id from objective id: ${obj.id}`,
490
+ });
491
+ anyFail = true;
492
+ continue;
493
+ }
494
+ const cycleDocId = `cycle${obj.source.ref}`;
495
+ const doc = await read(opts.cwd, cycleDocId);
496
+ if (doc === null) {
497
+ results.push({
498
+ id: obj.id,
499
+ status: "fail",
500
+ message: `cycle doc ${cycleDocId} not found under ${join(opts.cwd, "docs/roadmap/cycles")}.`,
501
+ });
502
+ anyFail = true;
503
+ continue;
504
+ }
505
+ const section = doc.sections[sectionSlug];
506
+ if (section === undefined || section.trim() === "") {
507
+ results.push({
508
+ id: obj.id,
509
+ status: "fail",
510
+ message: `cycle doc ${cycleDocId} has no '${sectionSlug}' section.`,
511
+ });
512
+ anyFail = true;
513
+ continue;
514
+ }
515
+ const criteria = extractExitCriteria(section);
516
+ const criterion = criteria.find((c) => c.id === criterionId);
517
+ if (criterion === undefined) {
518
+ results.push({
519
+ id: obj.id,
520
+ status: "fail",
521
+ message: `criterion ${criterionId} not found in ${cycleDocId} '${sectionSlug}' (${criteria.length} items found).`,
522
+ });
523
+ anyFail = true;
524
+ continue;
525
+ }
526
+ const actualSha256 = sha256Hex(canonicalizeCriterion(criterion.raw));
527
+ if (actualSha256 !== sc.sha256) {
528
+ results.push({
529
+ id: obj.id,
530
+ status: "fail",
531
+ message: `text-hash mismatch for ${criterionId} in ${cycleDocId}: ` +
532
+ `declared ${sc.sha256.slice(0, 12)}… ≠ actual ${actualSha256.slice(0, 12)}… ` +
533
+ `(criterion text may have changed — re-run \`df objectives derive\` to refresh).`,
534
+ });
535
+ anyFail = true;
536
+ continue;
537
+ }
538
+ results.push({ id: obj.id, status: "ok", message: `text-hash verified (${sc.sha256.slice(0, 12)}…).` });
539
+ }
540
+ if (opts.json) {
541
+ io.stdout(JSON.stringify({ ok: !anyFail, results: results.map((r) => ({ id: r.id, status: r.status, message: r.message })) }, null, 2) + "\n");
542
+ }
543
+ else {
544
+ for (const r of results) {
545
+ if (r.status === "ok") {
546
+ io.stdout(`ok ${r.id}: ${r.message}\n`);
547
+ }
548
+ else if (r.status === "fail") {
549
+ io.stdout(`FAIL ${r.id}: ${r.message}\n`);
550
+ }
551
+ else {
552
+ io.stdout(`note ${r.id}: ${r.message}\n`);
553
+ }
554
+ }
555
+ if (!anyFail && results.length > 0) {
556
+ io.stdout(`\nAll ${results.length} objective${results.length === 1 ? "" : "s"} ok.\n`);
557
+ }
558
+ else if (!anyFail && results.length === 0) {
559
+ io.stdout("No objectives to check.\n");
560
+ }
561
+ }
562
+ return anyFail ? 1 : 0;
563
+ }
564
+ /**
565
+ * Read an existing manifest (if any) and return a map of objective id →
566
+ * `attestedBy` bindings to preserve across a re-derive. A malformed/unreadable
567
+ * existing manifest is non-fatal (we warn and derive fresh) — the worst case is
568
+ * losing hand-edits the operator can re-add, which is strictly safer than
569
+ * refusing to derive.
570
+ */
571
+ function loadPreservedBindings(manifestPath, io) {
572
+ const preserved = new Map();
573
+ if (!existsSync(manifestPath)) {
574
+ return preserved;
575
+ }
576
+ let parsed;
577
+ try {
578
+ const existing = readFileSync(manifestPath, "utf8");
579
+ parsed = parseObjectivesManifest(yamlParse(existing));
580
+ }
581
+ catch (err) {
582
+ io.stderr(`df objectives derive: warning — existing ${MANIFEST_RELATIVE_PATH} could not be ` +
583
+ `parsed (${err instanceof Error ? err.message : String(err)}); deriving fresh, ` +
584
+ "hand-edited attestedBy bindings are NOT preserved.\n");
585
+ return preserved;
586
+ }
587
+ for (const obj of parsed.objectives) {
588
+ if (obj.attestedBy.length > 0) {
589
+ preserved.set(obj.id, obj.attestedBy);
590
+ }
591
+ }
592
+ return preserved;
593
+ }
594
+ //# sourceMappingURL=objectives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objectives.js","sourceRoot":"","sources":["../../src/commands/objectives.ts"],"names":[],"mappings":"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"}