@momentiq/dark-factory-cli 2.10.0 → 2.12.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.
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +3 -1
- package/dist/commands/prove.js.map +1 -1
- package/dist/cycle-doc-validator/validate_cycle_doc.py +224 -28
- package/dist/evidence/prove.d.ts.map +1 -1
- package/dist/evidence/prove.js +8 -1
- package/dist/evidence/prove.js.map +1 -1
- package/package.json +2 -2
- package/skills/verify/SKILL.md.tmpl +29 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAGD,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAChF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"AAeA,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAGD,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAChF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAqHD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,EAAE,OAAO,EACX,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CAuDjB"}
|
package/dist/commands/prove.js
CHANGED
|
@@ -87,7 +87,9 @@ const GLYPH = { proven: "✓", pending: "…", failed: "✗" };
|
|
|
87
87
|
function renderObjective(o) {
|
|
88
88
|
const lines = [];
|
|
89
89
|
const tag = o.enforced ? " [enforced]" : "";
|
|
90
|
-
|
|
90
|
+
// 2c: show source grounding when not the agent-asserted default.
|
|
91
|
+
const src = o.sourceVerification === "agent-asserted" ? "" : ` {${o.sourceVerification}}`;
|
|
92
|
+
lines.push(` ${GLYPH[o.status]} ${o.status.padEnd(7)} ${o.id}${tag}${src} ${o.text}`);
|
|
91
93
|
for (const b of o.bindings) {
|
|
92
94
|
const ptr = b.uploadId ? ` (cerebe:${b.uploadId})` : "";
|
|
93
95
|
lines.push(` ${b.kind}[${b.ref}] ${b.status} — ${b.detail}${ptr}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../../src/commands/prove.ts"],"names":[],"mappings":"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"}
|
|
@@ -94,11 +94,13 @@ from __future__ import annotations
|
|
|
94
94
|
|
|
95
95
|
import argparse
|
|
96
96
|
import base64
|
|
97
|
+
import hashlib
|
|
97
98
|
import json
|
|
98
99
|
import os
|
|
99
100
|
import re
|
|
100
101
|
import subprocess
|
|
101
102
|
import sys
|
|
103
|
+
import unicodedata
|
|
102
104
|
from dataclasses import dataclass, field
|
|
103
105
|
from pathlib import Path
|
|
104
106
|
from typing import Iterable
|
|
@@ -1068,19 +1070,114 @@ def _declared_refs(trailers: "Trailers") -> set[str]:
|
|
|
1068
1070
|
return refs
|
|
1069
1071
|
|
|
1070
1072
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
+
# Cycle 331.1 2c (#207) — source-criterion binding. These mirror the TS
|
|
1074
|
+
# contract in @momentiq/dark-factory-schemas (SOURCE_LOCATOR_RE +
|
|
1075
|
+
# canonicalizeCriterion); the canonicalization is pinned byte-for-byte by a
|
|
1076
|
+
# cross-impl fixture test so the Python (verify) and TS (author) sides can't drift.
|
|
1077
|
+
SOURCE_LOCATOR_RE = re.compile(r"^[a-z0-9_]+#[a-z0-9._-]+$", re.IGNORECASE)
|
|
1078
|
+
SHA256_HEX_RE = re.compile(r"^[0-9a-f]{64}$")
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
def canonicalize_criterion(text: str) -> str:
|
|
1082
|
+
"""Canonicalize a source criterion's text for hashing (mirror of the TS
|
|
1083
|
+
``canonicalizeCriterion``). Strips a list marker + criterion label + markdown
|
|
1084
|
+
emphasis and folds whitespace; preserves meaning-bearing text."""
|
|
1085
|
+
s = unicodedata.normalize("NFC", text)
|
|
1086
|
+
s = re.sub(r"^\s*(?:[-*+]|\d+[.)])\s+", "", s) # list marker
|
|
1087
|
+
s = re.sub(r"^\s*\*{0,2}[A-Za-z]+\d+[A-Za-z0-9]*\*{0,2}\s*[:.)–—-]\s+", "", s) # label
|
|
1088
|
+
s = re.sub(r"[*`]", "", s) # emphasis / code tokens
|
|
1089
|
+
s = re.sub(r"\s+", " ", s).strip() # whitespace
|
|
1090
|
+
return s
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def _slug_heading(h: str) -> str:
|
|
1094
|
+
return re.sub(r"[^a-z0-9]+", "_", h.strip().lower()).strip("_")
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
def _doc_body(path: Path) -> str:
|
|
1098
|
+
text = path.read_text(encoding="utf-8")
|
|
1099
|
+
m = re.match(r"^---\n.*?\n---\n", text, re.DOTALL)
|
|
1100
|
+
return text[m.end():] if m else text
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
def _h2_sections(body: str) -> dict[str, str]:
|
|
1104
|
+
sections: dict[str, list[str]] = {}
|
|
1105
|
+
slug: str | None = None
|
|
1106
|
+
for line in body.splitlines():
|
|
1107
|
+
m = re.match(r"^##\s+(.+)$", line) # h2 only (### has no space after ##)
|
|
1108
|
+
if m:
|
|
1109
|
+
slug = _slug_heading(m.group(1))
|
|
1110
|
+
sections.setdefault(slug, [])
|
|
1111
|
+
elif slug is not None:
|
|
1112
|
+
sections[slug].append(line)
|
|
1113
|
+
return {k: "\n".join(v).strip() for k, v in sections.items()}
|
|
1114
|
+
|
|
1073
1115
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
is a no-op — objectives are optional in v1.
|
|
1116
|
+
def _list_items(section_body: str) -> list[str]:
|
|
1117
|
+
return [ln for ln in section_body.splitlines() if re.match(r"^\s*(?:[-*+]|\d+[.)])\s+", ln)]
|
|
1077
1118
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1119
|
+
|
|
1120
|
+
def _find_criterion(section_body: str, crit_id: str) -> str | None:
|
|
1121
|
+
items = _list_items(section_body)
|
|
1122
|
+
label = re.compile(
|
|
1123
|
+
rf"^\s*(?:[-*+]|\d+[.)])\s*\*{{0,2}}{re.escape(crit_id)}\*{{0,2}}\s*[:.)–—-]",
|
|
1124
|
+
re.IGNORECASE,
|
|
1125
|
+
)
|
|
1126
|
+
for it in items: # 1) explicit label match (e.g. "- **EC1**: ...")
|
|
1127
|
+
if label.match(it):
|
|
1128
|
+
return it
|
|
1129
|
+
m = re.search(r"(\d+)$", crit_id) # 2) position fallback (ecN → Nth item)
|
|
1130
|
+
if m:
|
|
1131
|
+
idx = int(m.group(1)) - 1
|
|
1132
|
+
if 0 <= idx < len(items):
|
|
1133
|
+
return items[idx]
|
|
1134
|
+
return None
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
def _resolve_criterion(cycle_id: str, locator: str) -> tuple[str, str | None]:
|
|
1138
|
+
"""Resolve a text-hash locator against an IN-REPO cycle doc. Returns
|
|
1139
|
+
(status, text) where status is 'ok' | 'no-doc' | 'no-criterion'. 'no-doc'
|
|
1140
|
+
(source not resolvable locally) is the non-blocking path."""
|
|
1141
|
+
doc = find_cycle_doc(cycle_id)
|
|
1142
|
+
if doc is None:
|
|
1143
|
+
return ("no-doc", None)
|
|
1144
|
+
section_slug, _, crit_id = locator.partition("#")
|
|
1145
|
+
# SOURCE_LOCATOR_RE is case-insensitive but section slugs are lowercased
|
|
1146
|
+
# (_slug_heading), so normalize the lookup to avoid a false "not found".
|
|
1147
|
+
section = _h2_sections(_doc_body(doc.path)).get(section_slug.lower())
|
|
1148
|
+
if section is None:
|
|
1149
|
+
return ("no-criterion", None)
|
|
1150
|
+
text = _find_criterion(section, crit_id)
|
|
1151
|
+
return ("ok", text) if text is not None else ("no-criterion", None)
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
def validate_objectives(
|
|
1155
|
+
repo_root: Path, trailers: "Trailers", changed_files: Iterable[str]
|
|
1156
|
+
) -> list[str]:
|
|
1157
|
+
"""Validate .darkfactory/objectives.yaml against PR context. Empty list = ok.
|
|
1158
|
+
|
|
1159
|
+
**Validated ONLY when this PR authors/edits the manifest** (it appears in the
|
|
1160
|
+
PR's changed files). A committed manifest from an earlier PR must NOT be
|
|
1161
|
+
re-validated against an unrelated later PR's trailers — that was the
|
|
1162
|
+
stale-manifest gate-break (momentiq-ai/dark-factory#207). Combined with
|
|
1163
|
+
per-PR authoring (the agent drafts the manifest at PR-open), each PR's
|
|
1164
|
+
objectives are checked against that PR's own trailers and nothing else.
|
|
1165
|
+
|
|
1166
|
+
Structural checks mirror the TS ``parseObjectivesManifest`` contract (id
|
|
1167
|
+
format, id↔source consistency, non-empty text, ``enforced`` boolean, and the
|
|
1168
|
+
``attestedBy`` binding shapes) so the Python gate is not a looser subset that
|
|
1169
|
+
can silently drift from the TS parser. The PR-context checks (source linked
|
|
1170
|
+
by a trailer, ``route`` binding exists in config) are gate-only — they need
|
|
1171
|
+
PR state the pure parser doesn't have. NO coverage check (the ``enforced``
|
|
1172
|
+
flag is the future ratchet).
|
|
1173
|
+
|
|
1174
|
+
Uses a deferred ``import yaml`` so a missing pyyaml installation only errors
|
|
1175
|
+
when a repo actually ships the manifest (the skip/absent paths never import
|
|
1176
|
+
yaml), preserving the validator's dependency-light boot.
|
|
1083
1177
|
"""
|
|
1178
|
+
# Gate: only author-time validation. PRs that don't touch the manifest skip.
|
|
1179
|
+
if OBJECTIVES_MANIFEST_PATH not in set(changed_files):
|
|
1180
|
+
return []
|
|
1084
1181
|
manifest_path = repo_root / OBJECTIVES_MANIFEST_PATH
|
|
1085
1182
|
if not manifest_path.exists():
|
|
1086
1183
|
return []
|
|
@@ -1096,6 +1193,11 @@ def validate_objectives(repo_root: Path, trailers: "Trailers") -> list[str]:
|
|
|
1096
1193
|
return [f"{OBJECTIVES_MANIFEST_PATH}: invalid YAML — {exc}"]
|
|
1097
1194
|
if not isinstance(data, dict):
|
|
1098
1195
|
return [f"{OBJECTIVES_MANIFEST_PATH}: top-level must be a mapping"]
|
|
1196
|
+
if data.get("schemaVersion") != 1:
|
|
1197
|
+
return [
|
|
1198
|
+
f"{OBJECTIVES_MANIFEST_PATH}: schemaVersion must be 1, got "
|
|
1199
|
+
f"{data.get('schemaVersion')!r}"
|
|
1200
|
+
]
|
|
1099
1201
|
objectives = data.get("objectives")
|
|
1100
1202
|
if not isinstance(objectives, list):
|
|
1101
1203
|
return [f"{OBJECTIVES_MANIFEST_PATH}: 'objectives' must be a list"]
|
|
@@ -1113,31 +1215,124 @@ def validate_objectives(repo_root: Path, trailers: "Trailers") -> list[str]:
|
|
|
1113
1215
|
errors.append(
|
|
1114
1216
|
f"{loc}.id: expected 'cycle<N>#ec<k>' or 'issue<N>#ac<k>', got {oid!r}"
|
|
1115
1217
|
)
|
|
1218
|
+
text = obj.get("text")
|
|
1219
|
+
if not isinstance(text, str) or not text:
|
|
1220
|
+
errors.append(f"{loc}.text: expected a non-empty string")
|
|
1221
|
+
if not isinstance(obj.get("enforced"), bool):
|
|
1222
|
+
errors.append(f"{loc}.enforced: expected a boolean")
|
|
1116
1223
|
source = obj.get("source")
|
|
1117
1224
|
if not isinstance(source, dict):
|
|
1118
1225
|
errors.append(f"{loc}.source: expected a mapping, got {source!r}")
|
|
1119
1226
|
continue
|
|
1120
1227
|
kind, ref = source.get("kind"), source.get("ref")
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1228
|
+
if kind not in ("cycle", "issue"):
|
|
1229
|
+
errors.append(f"{loc}.source.kind: expected 'cycle' | 'issue', got {kind!r}")
|
|
1230
|
+
if not isinstance(ref, str) or not ref:
|
|
1231
|
+
errors.append(f"{loc}.source.ref: expected a non-empty string")
|
|
1232
|
+
# id↔source consistency (mirrors the TS parseObjective invariant): the id
|
|
1233
|
+
# must be namespaced by its source, e.g. cycle21#ec1 ↔ {cycle, "21"}.
|
|
1234
|
+
if isinstance(oid, str) and isinstance(kind, str) and isinstance(ref, str):
|
|
1235
|
+
ref_num = re.sub(r"^#", "", ref) if kind == "issue" else ref
|
|
1236
|
+
if not oid.startswith(f"{kind}{ref_num}#"):
|
|
1237
|
+
errors.append(
|
|
1238
|
+
f"{loc}.id: {oid!r} is inconsistent with source "
|
|
1239
|
+
f"{{kind: {kind}, ref: {ref!r}}}"
|
|
1240
|
+
)
|
|
1241
|
+
# PR-context: the source must be linked by one of this PR's trailers.
|
|
1242
|
+
# Only run when kind/ref are themselves valid — otherwise their own
|
|
1243
|
+
# errors above already fired, and a "not linked" message here would be
|
|
1244
|
+
# misleading noise the TS parser wouldn't surface. Normalize to match
|
|
1245
|
+
# _declared_refs (cycle via normalize_cycle_id; issue strips a leading "#").
|
|
1246
|
+
if kind in ("cycle", "issue") and isinstance(ref, str):
|
|
1247
|
+
normalized_ref = normalize_cycle_id(ref) if kind == "cycle" else re.sub(r'^#', '', ref)
|
|
1248
|
+
if f"{kind}:{normalized_ref}" not in declared:
|
|
1249
|
+
errors.append(
|
|
1250
|
+
f"{loc}.source: {kind} {ref!r} is not linked by any Cycle:/Closes #N trailer on this PR"
|
|
1251
|
+
)
|
|
1252
|
+
# attestedBy: structural validation of each binding (kind + required
|
|
1253
|
+
# field), plus route-existence (PR context) for route bindings.
|
|
1254
|
+
bindings = obj.get("attestedBy")
|
|
1255
|
+
if not isinstance(bindings, list):
|
|
1256
|
+
errors.append(f"{loc}.attestedBy: expected a list")
|
|
1257
|
+
continue
|
|
1258
|
+
for j, binding in enumerate(bindings):
|
|
1259
|
+
bloc = f"{loc}.attestedBy[{j}]"
|
|
1260
|
+
if not isinstance(binding, dict):
|
|
1261
|
+
errors.append(f"{bloc}: expected a mapping")
|
|
1262
|
+
continue
|
|
1263
|
+
bkind = binding.get("kind")
|
|
1264
|
+
if bkind == "route":
|
|
1136
1265
|
rid = binding.get("routeId")
|
|
1137
|
-
if rid not
|
|
1266
|
+
if not isinstance(rid, str) or not rid:
|
|
1267
|
+
errors.append(f"{bloc}.routeId: expected a non-empty string")
|
|
1268
|
+
elif rid not in route_ids:
|
|
1138
1269
|
errors.append(
|
|
1139
|
-
f"{
|
|
1270
|
+
f"{bloc}.routeId: {rid!r} is not a verificationRoute in .agent-review/config.json"
|
|
1140
1271
|
)
|
|
1272
|
+
elif bkind == "critic":
|
|
1273
|
+
cid = binding.get("criticId")
|
|
1274
|
+
if not isinstance(cid, str) or not cid:
|
|
1275
|
+
errors.append(f"{bloc}.criticId: expected a non-empty string")
|
|
1276
|
+
elif bkind == "test":
|
|
1277
|
+
tref = binding.get("ref")
|
|
1278
|
+
if not isinstance(tref, str) or not tref:
|
|
1279
|
+
errors.append(f"{bloc}.ref: expected a non-empty string")
|
|
1280
|
+
else:
|
|
1281
|
+
errors.append(
|
|
1282
|
+
f"{bloc}.kind: expected 'route' | 'critic' | 'test', got {bkind!r}"
|
|
1283
|
+
)
|
|
1284
|
+
# Cycle 331.1 2c (#207) — source-criterion binding. Verify a text-hash
|
|
1285
|
+
# against the IN-REPO cycle doc (blocking on mismatch / not-found);
|
|
1286
|
+
# human-reviewed is the escape; an unresolvable source (cross-repo cycle
|
|
1287
|
+
# doc, issue body) is a NON-BLOCKING note — no flaky network on the gate.
|
|
1288
|
+
sc = obj.get("sourceCriterion")
|
|
1289
|
+
if isinstance(sc, dict):
|
|
1290
|
+
sc_kind = sc.get("kind")
|
|
1291
|
+
if sc_kind == "human-reviewed":
|
|
1292
|
+
pass # accepted; surfaced by df prove as human-reviewed
|
|
1293
|
+
elif sc_kind == "text-hash":
|
|
1294
|
+
sloc, ssha = sc.get("locator"), sc.get("sha256")
|
|
1295
|
+
if not isinstance(sloc, str) or not SOURCE_LOCATOR_RE.match(sloc):
|
|
1296
|
+
errors.append(
|
|
1297
|
+
f"{loc}.sourceCriterion.locator: expected '<section-slug>#<criterion-id>', got {sloc!r}"
|
|
1298
|
+
)
|
|
1299
|
+
elif not isinstance(ssha, str) or not SHA256_HEX_RE.match(ssha):
|
|
1300
|
+
errors.append(
|
|
1301
|
+
f"{loc}.sourceCriterion.sha256: expected lowercase-hex SHA-256 (64 chars), got {ssha!r}"
|
|
1302
|
+
)
|
|
1303
|
+
elif kind == "cycle" and isinstance(ref, str):
|
|
1304
|
+
status, ctext = _resolve_criterion(normalize_cycle_id(ref) or ref, sloc)
|
|
1305
|
+
if status == "no-doc":
|
|
1306
|
+
print(
|
|
1307
|
+
f"[objectives] {loc}.sourceCriterion: cycle {ref!r} doc not in-repo — "
|
|
1308
|
+
"recorded, not verified (cross-repo verification deferred)",
|
|
1309
|
+
file=sys.stderr,
|
|
1310
|
+
)
|
|
1311
|
+
elif status == "no-criterion":
|
|
1312
|
+
errors.append(
|
|
1313
|
+
f"{loc}.sourceCriterion.locator: criterion {sloc!r} not found in the cycle doc"
|
|
1314
|
+
)
|
|
1315
|
+
elif ctext is not None:
|
|
1316
|
+
actual = hashlib.sha256(
|
|
1317
|
+
canonicalize_criterion(ctext).encode("utf-8")
|
|
1318
|
+
).hexdigest()
|
|
1319
|
+
if actual != ssha:
|
|
1320
|
+
errors.append(
|
|
1321
|
+
f"{loc}.sourceCriterion.sha256: does not match the source criterion "
|
|
1322
|
+
f"(recomputed {actual})"
|
|
1323
|
+
)
|
|
1324
|
+
else:
|
|
1325
|
+
print(
|
|
1326
|
+
f"[objectives] {loc}.sourceCriterion: {kind} source verification deferred "
|
|
1327
|
+
"(v1 verifies in-repo cycle docs) — recorded, not verified",
|
|
1328
|
+
file=sys.stderr,
|
|
1329
|
+
)
|
|
1330
|
+
else:
|
|
1331
|
+
errors.append(
|
|
1332
|
+
f"{loc}.sourceCriterion.kind: expected 'text-hash' | 'human-reviewed', got {sc_kind!r}"
|
|
1333
|
+
)
|
|
1334
|
+
elif sc is not None:
|
|
1335
|
+
errors.append(f"{loc}.sourceCriterion: expected a mapping")
|
|
1141
1336
|
return errors
|
|
1142
1337
|
|
|
1143
1338
|
|
|
@@ -1162,7 +1357,8 @@ def validate(
|
|
|
1162
1357
|
return errors
|
|
1163
1358
|
|
|
1164
1359
|
trailers = parse_trailers(body)
|
|
1165
|
-
|
|
1360
|
+
changed_files = list(changed_files)
|
|
1361
|
+
errors.extend(validate_objectives(REPO_ROOT, trailers, changed_files))
|
|
1166
1362
|
plan = is_plan_pr(title, labels_list, changed_files)
|
|
1167
1363
|
pr_type = "plan-pr" if plan else "code-pr"
|
|
1168
1364
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/evidence/prove.ts"],"names":[],"mappings":"AAsBA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAEjB,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../../src/evidence/prove.ts"],"names":[],"mappings":"AAsBA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAEjB,KAAK,SAAS,EAKd,KAAK,aAAa,EACnB,MAAM,gCAAgC,CAAC;AASxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IAEf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,SAAS,EAAE,CAAC;IAExB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAEhD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAEnD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAqED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,CA8B3F;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAQD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAiEtC"}
|
package/dist/evidence/prove.js
CHANGED
|
@@ -86,7 +86,14 @@ export function buildProofRecord(inputs, generatedAt) {
|
|
|
86
86
|
// An objective with no bindings is declared-but-unbound → pending, never
|
|
87
87
|
// silently proven. Otherwise it's the worst of its bindings.
|
|
88
88
|
const status = bindings.length === 0 ? "pending" : worstOf(bindings.map((b) => b.status));
|
|
89
|
-
|
|
89
|
+
// 2c: surface whether the objective is grounded in its source. df prove
|
|
90
|
+
// reports the binding kind; the cycle-doc-validation gate is the verifier.
|
|
91
|
+
const sourceVerification = o.sourceCriterion === undefined
|
|
92
|
+
? "agent-asserted"
|
|
93
|
+
: o.sourceCriterion.kind === "human-reviewed"
|
|
94
|
+
? "human-reviewed"
|
|
95
|
+
: "source-bound";
|
|
96
|
+
return { id: o.id, text: o.text, enforced: o.enforced, status, bindings, sourceVerification };
|
|
90
97
|
});
|
|
91
98
|
const summary = { proven: 0, pending: 0, failed: 0, total: objectives.length };
|
|
92
99
|
for (const o of objectives)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../../src/evidence/prove.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2EAA2E;AAC3E,gFAAgF;AAChF,kFAAkF;AAClF,4EAA4E;AAC5E,EAAE;AACF,qCAAqC;AACrC,iFAAiF;AACjF,8EAA8E;AAC9E,kFAAkF;AAClF,8BAA8B;AAC9B,EAAE;AACF,8EAA8E;AAC9E,kFAAkF;AAClF,mFAAmF;AACnF,sDAAsD;AAEtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EACL,uBAAuB,
|
|
1
|
+
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../../src/evidence/prove.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momentiq/dark-factory-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Dark Factory OSS CLI — multi-vendor adversarial critic orchestration (Cursor, Codex, Gemini, Grok) with min-complete-quorum aggregation and trusted-surface rebind",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://momentiq.ai/dark-factory",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"@google/genai": "^2.2.0",
|
|
99
99
|
"@iarna/toml": "2.2.5",
|
|
100
100
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
101
|
-
"@momentiq/dark-factory-schemas": "0.
|
|
101
|
+
"@momentiq/dark-factory-schemas": "0.12.0",
|
|
102
102
|
"@openai/codex-sdk": "^0.130.0",
|
|
103
103
|
"@yarnpkg/lockfile": "1.1.0",
|
|
104
104
|
"ajv": "^8.20.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verify
|
|
3
|
-
description: Use to PRODUCE evidence-gated validation-route evidence for a change before pushing — run the change-appropriate verification route(s) (terraform validate, helm lint+template, docker build, the touched service's targeted tests, the UI/Playwright route) and write per-SHA, diffHash-bound QualityGateEvidence the local pre-push gate (df gate-push / enforceVerificationRoutes) asserts. Use when asked to "verify a change", "produce route evidence", a routed push is blocked with verification_route_missing / verification_route_failed, or before pushing a commit that touches a routed surface (infra/terraform, deploy/helm, a Dockerfile, services/*/src, web/** or *.tsx).
|
|
3
|
+
description: Use to PRODUCE evidence-gated validation-route evidence for a change before pushing — run the change-appropriate verification route(s) (terraform validate, helm lint+template, docker build, the touched service's targeted tests, the UI/Playwright route) and write per-SHA, diffHash-bound QualityGateEvidence the local pre-push gate (df gate-push / enforceVerificationRoutes) asserts. Use when asked to "verify a change", "produce route evidence", a routed push is blocked with verification_route_missing / verification_route_failed, or before pushing a commit that touches a routed surface (infra/terraform, deploy/helm, a Dockerfile, services/*/src, web/** or *.tsx). ALSO use at CLOSEOUT — when a change declares objectives in .darkfactory/objectives.yaml, run `df prove` to bind that evidence to the objectives and "declare victory with proof" (a proven/pending/failed readout) instead of asserting "done".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /verify — evidence-gated validation routes
|
|
@@ -98,3 +98,31 @@ CLI. Copy the reference files from the `@momentiq/dark-factory-cli` package
|
|
|
98
98
|
(routes + required headings), wire an optional auth storage-state for protected
|
|
99
99
|
surfaces, and arm the `playwright` route's `command`. The full walkthrough is in
|
|
100
100
|
`docs/guides/ui-verification-route.md`.
|
|
101
|
+
|
|
102
|
+
## Closeout — declare victory with proof, not "done"
|
|
103
|
+
|
|
104
|
+
Producing evidence is half the loop; the other half is **proving the objectives
|
|
105
|
+
it attests**. When a change declares objectives in `.darkfactory/objectives.yaml`,
|
|
106
|
+
the closeout step is **`df prove`** — it joins each objective against the evidence
|
|
107
|
+
(`df verify` route exit codes + `df review` critic verdicts) and reports, per
|
|
108
|
+
objective, **proven / pending / failed**. An agent's final turn runs `df prove`
|
|
109
|
+
(or the `df_prove` MCP tool) and **cites that readout as the completion claim** —
|
|
110
|
+
proof derived from diffHash-bound artifacts — rather than asserting "done".
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
df prove # human readout: per-objective proven/pending/failed + bindings
|
|
114
|
+
df prove --json # the BoundProofRecord (for agents / the df_prove MCP tool)
|
|
115
|
+
df prove --strict # exit 1 if ANY objective is not proven (the gate form)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- **`pending` is honest, not a failure.** A `critic` binding is `pending` until the
|
|
119
|
+
fleet runs on HEAD (run `df review` or wait for CI); a `route` binding you can
|
|
120
|
+
satisfy now with `df verify`. Only `failed` (evidence is negative) is a problem.
|
|
121
|
+
- **Trust boundary.** This readout is *agent-attested, evidence-backed* — stronger
|
|
122
|
+
than free-text "done" (every status is derived, not asserted), but not yet
|
|
123
|
+
independent verification (that closes with runner-attested evidence + the
|
|
124
|
+
source-criterion ratchet).
|
|
125
|
+
- **The ratchet.** v1 is informational (`enforced: false` — `df prove` exits 0 and
|
|
126
|
+
surfaces pending/failed). Flip an objective to `enforced: true`, or run
|
|
127
|
+
`df prove --strict` (e.g. a `.husky/pre-push` step — see CONSUMER-ADOPTION §5),
|
|
128
|
+
to turn unproven objectives into a hard block with no code change.
|