devlyn-cli 2.9.3 → 2.10.1
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/AGENTS.md +3 -3
- package/CLAUDE.md +5 -5
- package/README.md +5 -5
- package/benchmark/auto-resolve/fixtures/SCHEMA.md +1 -1
- package/benchmark/auto-resolve/scripts/pair_evidence_contract.py +1 -0
- package/benchmark/auto-resolve/scripts/run-fixture.sh +11 -1
- package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +83 -1
- package/bin/devlyn.js +108 -15
- package/config/skills/_shared/adapters/README.md +2 -2
- package/config/skills/_shared/adapters/grok.md +99 -0
- package/config/skills/_shared/archive_run.py +35 -1
- package/config/skills/_shared/collect-codex-findings.py +231 -50
- package/config/skills/_shared/engine-doctor.sh +6 -3
- package/config/skills/_shared/engine-preflight.md +12 -5
- package/config/skills/_shared/expected.schema.json +7 -0
- package/config/skills/_shared/grok-anchor-guard.py +61 -0
- package/config/skills/_shared/phase-prompt-render.py +181 -0
- package/config/skills/_shared/resolve-bootstrap.py +630 -0
- package/config/skills/_shared/resolve-stop-hook.py +325 -0
- package/config/skills/_shared/spec-verify-check.py +308 -31
- package/config/skills/_shared/state-phase-write.py +2966 -27
- package/config/skills/_shared/terminal-claim-check.py +537 -0
- package/config/skills/_shared/verify-merge-findings.py +533 -16
- package/config/skills/devlyn:engines/SKILL.md +2 -2
- package/config/skills/devlyn:ideate/SKILL.md +1 -1
- package/config/skills/devlyn:queue/SKILL.md +12 -0
- package/config/skills/devlyn:resolve/SKILL.md +60 -78
- package/config/skills/devlyn:resolve/references/phases/build-gate.md +2 -2
- package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/plan.md +1 -5
- package/config/skills/devlyn:resolve/references/phases/probe-derive.md +4 -2
- package/config/skills/devlyn:resolve/references/phases/surface-close.md +34 -0
- package/config/skills/devlyn:resolve/references/phases/verify.md +70 -97
- package/config/skills/devlyn:resolve/references/state-schema.md +26 -19
- package/optional-skills/devlyn:reap/SKILL.md +1 -1
- package/optional-skills/devlyn:reap/scripts/reap.sh +25 -13
- package/optional-skills/devlyn:reap/scripts/scan.sh +15 -1
- package/package.json +1 -1
- package/scripts/lint-fixtures.sh +4 -1
- package/scripts/lint-skills.sh +269 -77
package/scripts/lint-skills.sh
CHANGED
|
@@ -60,17 +60,23 @@ _shared/spec-verify-check.py
|
|
|
60
60
|
_shared/collect-codex-findings.py
|
|
61
61
|
_shared/verify-merge-findings.py
|
|
62
62
|
_shared/state-phase-write.py
|
|
63
|
+
_shared/terminal-claim-check.py
|
|
64
|
+
_shared/resolve-stop-hook.py
|
|
65
|
+
_shared/resolve-bootstrap.py
|
|
63
66
|
devlyn:ideate/SKILL.md
|
|
64
67
|
devlyn:ideate/references/spec-template.md
|
|
65
68
|
devlyn:ideate/references/elicitation.md
|
|
66
69
|
devlyn:ideate/references/project-mode.md
|
|
67
70
|
devlyn:ideate/references/from-spec-mode.md
|
|
68
71
|
devlyn:resolve/SKILL.md
|
|
72
|
+
devlyn:queue/SKILL.md
|
|
73
|
+
devlyn:engines/SKILL.md
|
|
69
74
|
devlyn:resolve/references/state-schema.md
|
|
70
75
|
devlyn:resolve/references/free-form-mode.md
|
|
71
76
|
devlyn:resolve/references/phases/plan.md
|
|
72
77
|
devlyn:resolve/references/phases/probe-derive.md
|
|
73
78
|
devlyn:resolve/references/phases/implement.md
|
|
79
|
+
devlyn:resolve/references/phases/surface-close.md
|
|
74
80
|
devlyn:resolve/references/phases/build-gate.md
|
|
75
81
|
devlyn:resolve/references/phases/cleanup.md
|
|
76
82
|
devlyn:resolve/references/phases/verify.md
|
|
@@ -78,6 +84,7 @@ _shared/expected.schema.json
|
|
|
78
84
|
_shared/adapters/README.md
|
|
79
85
|
_shared/adapters/claude.md
|
|
80
86
|
_shared/adapters/codex.md
|
|
87
|
+
_shared/adapters/grok.md
|
|
81
88
|
_shared/adapters/omp.md
|
|
82
89
|
_shared/codex-config.md
|
|
83
90
|
_shared/codex-monitored.sh
|
|
@@ -146,6 +153,7 @@ offenders=$(git grep -Il -- 'mcp__codex-cli__' -- \
|
|
|
146
153
|
':!config/skills/preflight-workspace/**' \
|
|
147
154
|
':!benchmark/auto-resolve/external/**' \
|
|
148
155
|
':!benchmark/auto-resolve/results/**' \
|
|
156
|
+
':!benchmark/ceiling/results/**' \
|
|
149
157
|
':!benchmark/auto-resolve/PILOT-RESULTS*' \
|
|
150
158
|
2>/dev/null || true)
|
|
151
159
|
if [ -z "$offenders" ]; then
|
|
@@ -170,6 +178,7 @@ offenders=$(git grep -Il -- 'Requires Codex MCP\|Codex MCP server\|Codex MCP ava
|
|
|
170
178
|
':!config/skills/preflight-workspace/**' \
|
|
171
179
|
':!benchmark/auto-resolve/external/**' \
|
|
172
180
|
':!benchmark/auto-resolve/results/**' \
|
|
181
|
+
':!benchmark/ceiling/results/**' \
|
|
173
182
|
':!benchmark/auto-resolve/PILOT-RESULTS*' \
|
|
174
183
|
2>/dev/null || true)
|
|
175
184
|
if [ -z "$offenders" ]; then
|
|
@@ -198,16 +207,19 @@ else
|
|
|
198
207
|
fi
|
|
199
208
|
|
|
200
209
|
# ---------------------------------------------------------------------------
|
|
201
|
-
# 4. No model-pinned Claude references, any generation
|
|
202
|
-
#
|
|
210
|
+
# 4. No model-pinned Claude references, any generation, except the adjudicated
|
|
211
|
+
# SURFACE_CLOSE envelope whose requested id must equal CLI arg and modelUsage.
|
|
203
212
|
# ---------------------------------------------------------------------------
|
|
204
213
|
section "Check 4: No model-pinned Claude references"
|
|
205
|
-
offenders=$(grep -
|
|
214
|
+
offenders=$(grep -RInE 'Claude (Opus|Sonnet|Haiku|Fable)|claude-(opus|sonnet|haiku|fable)-[0-9]' \
|
|
206
215
|
config/skills 2>/dev/null \
|
|
207
216
|
| grep -v 'config/skills/roadmap-archival-workspace/' \
|
|
208
217
|
| grep -v 'config/skills/devlyn:auto-resolve-workspace/' \
|
|
209
218
|
| grep -v 'config/skills/devlyn:ideate-workspace/' \
|
|
210
219
|
| grep -v 'config/skills/preflight-workspace/' \
|
|
220
|
+
| grep -vE '^config/skills/devlyn:resolve/SKILL\.md:[0-9]+:Freeze .*--tools "Read,Grep,Glob,Edit,Write" --dangerously-skip-permissions --model claude-sonnet-5 --output-format json --strict-mcp-config --mcp-config '\''\{"mcpServers":\{\}\}'\''.*, recording the same model at SPW spawn\.' \
|
|
221
|
+
| cut -d: -f1 \
|
|
222
|
+
| sort -u \
|
|
211
223
|
|| true)
|
|
212
224
|
if [ -z "$offenders" ]; then
|
|
213
225
|
ok "no model-pinned Claude references"
|
|
@@ -257,6 +269,84 @@ else
|
|
|
257
269
|
bad "devlyn:design-ui must not be listed in OPTIONAL_ADDONS"
|
|
258
270
|
fi
|
|
259
271
|
|
|
272
|
+
# ---------------------------------------------------------------------------
|
|
273
|
+
# 5b. Every completed managed-skills install writes its own version marker.
|
|
274
|
+
# ---------------------------------------------------------------------------
|
|
275
|
+
section "Check 5b: Installed skill roots carry exact version markers"
|
|
276
|
+
if make_temp_dir tmp_install_marker /tmp/devlyn-install-marker.XXXXXX; then
|
|
277
|
+
marker_home="$tmp_install_marker/home"
|
|
278
|
+
marker_project="$tmp_install_marker/project"
|
|
279
|
+
installer="$PWD/bin/devlyn.js"
|
|
280
|
+
mkdir -p "$marker_home" "$marker_project"
|
|
281
|
+
|
|
282
|
+
if (cd "$marker_project" \
|
|
283
|
+
&& HOME="$marker_home" node "$installer" -y >"$tmp_install_marker/claude.log" 2>&1 \
|
|
284
|
+
&& HOME="$marker_home" node "$installer" agents all >"$tmp_install_marker/agents.log" 2>&1); then
|
|
285
|
+
if python3 - "$installer" "$marker_home" "$marker_project" <<'PY'
|
|
286
|
+
import json
|
|
287
|
+
import pathlib
|
|
288
|
+
import stat
|
|
289
|
+
import sys
|
|
290
|
+
|
|
291
|
+
installer = pathlib.Path(sys.argv[1])
|
|
292
|
+
home = pathlib.Path(sys.argv[2])
|
|
293
|
+
project = pathlib.Path(sys.argv[3])
|
|
294
|
+
package = json.loads((installer.parent.parent / "package.json").read_text())
|
|
295
|
+
expected = {"schemaVersion": 1, "package": package["name"], "version": package["version"]}
|
|
296
|
+
roots = [
|
|
297
|
+
project / ".claude" / "skills",
|
|
298
|
+
home / ".codex" / "skills",
|
|
299
|
+
home / ".agents" / "skills",
|
|
300
|
+
home / ".grok" / "skills",
|
|
301
|
+
]
|
|
302
|
+
for root in roots:
|
|
303
|
+
marker = root / ".devlyn-install.json"
|
|
304
|
+
actual = json.loads(marker.read_text())
|
|
305
|
+
if actual != expected:
|
|
306
|
+
raise SystemExit(f"{marker}: expected {expected}, got {actual}")
|
|
307
|
+
if stat.S_IMODE(marker.stat().st_mode) != 0o600:
|
|
308
|
+
raise SystemExit(f"{marker}: expected mode 0600")
|
|
309
|
+
if list(root.glob(".devlyn-install.json.*.tmp")):
|
|
310
|
+
raise SystemExit(f"{root}: stale marker temp file")
|
|
311
|
+
PY
|
|
312
|
+
then
|
|
313
|
+
if grep -Fxq '.claude/skills/.devlyn-install.json' "$marker_project/.gitignore"; then
|
|
314
|
+
ok "Claude, Codex, shared-agent, and Grok roots have exact 0600 markers; project marker is ignored"
|
|
315
|
+
else
|
|
316
|
+
bad "Claude project install must ignore its local marker"
|
|
317
|
+
fi
|
|
318
|
+
else
|
|
319
|
+
bad "completed installs must write the exact per-root marker"
|
|
320
|
+
fi
|
|
321
|
+
else
|
|
322
|
+
bad "isolated managed-skills install failed"
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
incomplete="$tmp_install_marker/incomplete"
|
|
326
|
+
mkdir -p "$incomplete/package" "$incomplete/home/.codex/skills" "$incomplete/claude/.claude/skills" "$incomplete/codex"
|
|
327
|
+
cp -R bin config package.json "$incomplete/package/"
|
|
328
|
+
rm -rf "$incomplete/package/config/skills/devlyn:queue"
|
|
329
|
+
printf '{"version":"stale"}\n' > "$incomplete/home/.codex/skills/.devlyn-install.json"
|
|
330
|
+
printf '{"version":"stale"}\n' > "$incomplete/claude/.claude/skills/.devlyn-install.json"
|
|
331
|
+
if ! (cd "$incomplete/claude" \
|
|
332
|
+
&& HOME="$incomplete/home" node "$incomplete/package/bin/devlyn.js" -y >"$incomplete/claude.log" 2>&1) \
|
|
333
|
+
&& ! (cd "$incomplete/codex" \
|
|
334
|
+
&& HOME="$incomplete/home" node "$incomplete/package/bin/devlyn.js" agents codex >"$incomplete/codex.log" 2>&1) \
|
|
335
|
+
&& grep -Fq 'Incomplete devlyn skill install; missing: devlyn:queue' "$incomplete/claude.log" \
|
|
336
|
+
&& grep -Fq 'Incomplete devlyn skill install; missing: devlyn:queue' "$incomplete/codex.log" \
|
|
337
|
+
&& [ -d "$incomplete/claude/.claude/skills/devlyn:resolve" ] \
|
|
338
|
+
&& [ -d "$incomplete/home/.codex/skills/devlyn:resolve" ] \
|
|
339
|
+
&& [ ! -e "$incomplete/claude/.claude/skills/.devlyn-install.json" ] \
|
|
340
|
+
&& [ ! -e "$incomplete/home/.codex/skills/.devlyn-install.json" ]; then
|
|
341
|
+
ok "incomplete Claude and Codex copies fail visibly without stale or replacement markers"
|
|
342
|
+
else
|
|
343
|
+
bad "incomplete Claude and Codex copies must fail visibly without an install marker"
|
|
344
|
+
fi
|
|
345
|
+
rm -rf "$tmp_install_marker"
|
|
346
|
+
else
|
|
347
|
+
bad "could not allocate install-marker smoke directory"
|
|
348
|
+
fi
|
|
349
|
+
|
|
260
350
|
# ---------------------------------------------------------------------------
|
|
261
351
|
# 6. Source ↔ installed mirror parity on critical path.
|
|
262
352
|
# Only runs if .claude/skills exists (i.e. installer has been run).
|
|
@@ -332,23 +422,23 @@ if ! grep -Fq 'def pair_trigger_skip_contract_violation' config/skills/_shared/v
|
|
|
332
422
|
|| ! grep -Fq 'verify-pair-trigger-skipped-reason-unsupported' config/skills/_shared/verify-merge-findings.py \
|
|
333
423
|
|| ! grep -Fq 'verify-pair-trigger-mechanical-blocker-unsupported' config/skills/_shared/verify-merge-findings.py \
|
|
334
424
|
|| ! grep -Fq 'verify-pair-trigger-primary-judge-blocker-unsupported' config/skills/_shared/verify-merge-findings.py \
|
|
335
|
-
|| ! grep -Fq '
|
|
336
|
-
|| ! grep -Fq 'Canonical
|
|
425
|
+
|| ! grep -Fq 'Missing, contradictory, incomplete, or unknown trigger state BLOCKs VERIFY' config/skills/devlyn:resolve/references/state-schema.md \
|
|
426
|
+
|| ! grep -Fq 'Canonical reasons are `pair.default`, `mode.verify-only`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
337
427
|
|| ! grep -Fq '`mode.pair-verify`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
338
|
-
|| ! grep -Fq 'Eligible
|
|
339
|
-
|| ! grep -Fq '
|
|
428
|
+
|| ! grep -Fq 'Eligible schema-v3 state must contain `pair.default` and every other applicable canonical' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
429
|
+
|| ! grep -Fq 'with `pair.default` plus every applicable outcome-independent canonical reason' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
340
430
|
|| ! grep -Fq '`mode.pair-verify`' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
341
431
|
|| ! grep -Fq '"pair_verify": false' config/skills/devlyn:resolve/references/state-schema.md \
|
|
342
|
-
|| ! grep -Fq '
|
|
343
|
-
|| ! grep -Fq '
|
|
344
|
-
|| ! grep -Fq '
|
|
432
|
+
|| ! grep -Fq 'Schema v3.0 eligible state requires `pair.default` plus every applicable telemetry reason' config/skills/devlyn:resolve/references/state-schema.md \
|
|
433
|
+
|| ! grep -Fq 'Ineligible new-run state has empty reasons and only' config/skills/devlyn:resolve/references/state-schema.md \
|
|
434
|
+
|| ! grep -Fq 'True only for `--pair-verify`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
345
435
|
|| ! grep -Fq 'pair_verify: true` only when `--pair-verify` was passed' config/skills/devlyn:resolve/SKILL.md \
|
|
346
|
-
|| ! grep -Fq '
|
|
436
|
+
|| ! grep -Fq 'persist `pair_trigger` before spawn with `pair.default` plus every applicable outcome-independent reason' config/skills/devlyn:resolve/SKILL.md \
|
|
347
437
|
|| ! grep -Fq '`--pair-verify` and `--no-pair` are mutually exclusive' config/skills/devlyn:resolve/SKILL.md \
|
|
348
438
|
|| ! grep -Fq 'mutually exclusive with `risk_profile.pair_default_enabled == false`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
349
439
|
|| ! grep -Fq 'if both are present, stop with `BLOCKED:invalid-flags`' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
350
|
-
|| ! grep -Fq '
|
|
351
|
-
|| ! grep -Fq '
|
|
440
|
+
|| ! grep -Fq 'Malformed risk or trigger state BLOCKs VERIFY' config/skills/devlyn:resolve/SKILL.md \
|
|
441
|
+
|| ! grep -Fq 'pair_default_enabled` is false only for explicit `--no-pair`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
352
442
|
|| ! grep -Fq 'def reject_json_constant' config/skills/_shared/verify-merge-findings.py \
|
|
353
443
|
|| ! grep -Fq 'loads_strict_json(raw)' config/skills/_shared/verify-merge-findings.py \
|
|
354
444
|
|| ! grep -Fq 'invalid JSON numeric constant: NaN' config/skills/_shared/verify-merge-findings.py; then
|
|
@@ -377,9 +467,17 @@ if python3 config/skills/_shared/collect-codex-findings.py --self-test >/dev/nul
|
|
|
377
467
|
else
|
|
378
468
|
bad "collect-codex-findings.py self-test failed"
|
|
379
469
|
fi
|
|
470
|
+
# iter-0082: the frozen collector contract — every negative through every ingress
|
|
471
|
+
# path, plus real judge captures replayed against hand-verified expectations.
|
|
472
|
+
# The self-test above is unit-shaped; this is the integration bar against real bytes.
|
|
473
|
+
if python3 benchmark/ceiling/probes/r-weld-0082/test-collector-contract.py >/dev/null 2>&1; then
|
|
474
|
+
ok "collector contract (iter-0082 negatives + real-capture corpus) passed"
|
|
475
|
+
else
|
|
476
|
+
bad "collector contract failed — run benchmark/ceiling/probes/r-weld-0082/test-collector-contract.py"
|
|
477
|
+
fi
|
|
380
478
|
if ! grep -Fq 'def reject_json_constant' config/skills/_shared/collect-codex-findings.py \
|
|
381
479
|
|| ! grep -Fq 'loads_strict_json(raw)' config/skills/_shared/collect-codex-findings.py \
|
|
382
|
-
|| ! grep -Fq 'NaN
|
|
480
|
+
|| ! grep -Fq 'NaN pair-JUDGE stdout finding' config/skills/_shared/collect-codex-findings.py; then
|
|
383
481
|
bad "collect-codex-findings.py must reject non-standard JSON constants in pair-JUDGE stdout"
|
|
384
482
|
fi
|
|
385
483
|
|
|
@@ -396,10 +494,56 @@ if ! grep -Fq 'SAFE_RUN_ID_RE' config/skills/_shared/archive_run.py \
|
|
|
396
494
|
|| ! grep -Fq 'invalid JSON numeric constant: NaN' config/skills/_shared/archive_run.py \
|
|
397
495
|
|| ! grep -Fq '"verify.pair.findings.jsonl"' config/skills/_shared/archive_run.py \
|
|
398
496
|
|| ! grep -Fq '"verify-merge.summary.json"' config/skills/_shared/archive_run.py \
|
|
497
|
+
|| ! grep -Fq '"surface-close.output.json"' config/skills/_shared/archive_run.py \
|
|
399
498
|
|| ! grep -Fq '"*-judge.*"' config/skills/_shared/archive_run.py; then
|
|
400
499
|
bad "archive_run.py must safely archive pair/risk-probe evidence and reject unsafe run ids"
|
|
401
500
|
fi
|
|
402
501
|
|
|
502
|
+
section "Check 6c2: SURFACE_CLOSE v6 dispatch is complete and mirrored"
|
|
503
|
+
surface_close_missing=0
|
|
504
|
+
if python3 config/skills/_shared/state-phase-write.py --self-test >/dev/null 2>&1; then
|
|
505
|
+
ok "SURFACE_CLOSE state/envelope/adjudication/audit/rollback self-test passed"
|
|
506
|
+
else
|
|
507
|
+
bad "state-phase-write.py SURFACE_CLOSE self-test failed"
|
|
508
|
+
fi
|
|
509
|
+
if ! grep -Fq 'rollback_surface_delta' config/skills/_shared/state-phase-write.py \
|
|
510
|
+
|| ! grep -Fq 'validate_surface_adjudication' config/skills/_shared/state-phase-write.py \
|
|
511
|
+
|| ! grep -Fq 'validate_surface_execution' config/skills/_shared/state-phase-write.py \
|
|
512
|
+
|| ! grep -Fq 'phases.surface_close spawn requires --engine claude' config/skills/_shared/state-phase-write.py \
|
|
513
|
+
|| ! grep -Fq 'phases.surface_close spawn requires --model' config/skills/_shared/state-phase-write.py \
|
|
514
|
+
|| ! grep -Fq 'BLOCKED:surface-close-input-mismatch' config/skills/_shared/state-phase-write.py \
|
|
515
|
+
|| ! grep -Fq 'surface-check' config/skills/_shared/state-phase-write.py \
|
|
516
|
+
|| ! grep -Fq 'surface-rollback' config/skills/_shared/state-phase-write.py; then
|
|
517
|
+
bad "state-phase-write.py must mechanically adjudicate, audit, guard, and roll back SURFACE_CLOSE"
|
|
518
|
+
fi
|
|
519
|
+
for tree in config/skills .claude/skills .agents/skills; do
|
|
520
|
+
skill="$tree/devlyn:resolve/SKILL.md"
|
|
521
|
+
phase="$tree/devlyn:resolve/references/phases/surface-close.md"
|
|
522
|
+
if ! grep -Fq '## PHASE 2.5: SURFACE_CLOSE' "$skill" \
|
|
523
|
+
|| ! grep -Fq '`state.source.type == "generated"` and complexity is trivial/medium' "$skill" \
|
|
524
|
+
|| ! grep -Fq 'Engine is Claude always' "$skill" \
|
|
525
|
+
|| ! grep -Fq 'executor flag/pin' "$skill" \
|
|
526
|
+
|| ! grep -Fq 'auto_surface_close_claude_unavailable' "$skill" \
|
|
527
|
+
|| ! grep -Fq 'canonical body VERBATIM' "$skill" \
|
|
528
|
+
|| ! grep -Fq 'run-bounded.py 600 -- claude -p' "$skill" \
|
|
529
|
+
|| ! grep -Fq -- '--tools "Read,Grep,Glob,Edit,Write" --dangerously-skip-permissions --model claude-sonnet-5 --output-format json --strict-mcp-config --mcp-config '\''{"mcpServers":{}}'\''' "$skill" \
|
|
530
|
+
|| ! grep -Fq '.devlyn/surface-close.output.json' "$skill" \
|
|
531
|
+
|| ! grep -Fq '**Common post-fix checkpoint (BUILD_GATE and VERIFY):**' "$skill" \
|
|
532
|
+
|| ! grep -Fq 'durability-enforce --round <n> --origin-phase <build_gate|verify>' "$skill" \
|
|
533
|
+
|| ! grep -Fq '`surface-rollback`' "$skill" \
|
|
534
|
+
|| grep -Fq 'Supplied digests' "$phase" \
|
|
535
|
+
|| grep -Fq 'Hash both artifacts first' "$phase" \
|
|
536
|
+
|| ! grep -Fq 'Never modify inputs or read state, PLAN, or IMPLEMENT transcript/reasoning.' "$phase" \
|
|
537
|
+
|| ! grep -Fq 'optionally followed by ` — <one-line evidence>`' "$phase" \
|
|
538
|
+
|| ! grep -Fq 'N/A <authorized-file>[:<line>] — <one-line evidence-based relationship judgment>' "$phase"; then
|
|
539
|
+
bad "$tree — SURFACE_CLOSE v6 dispatch/timeout/adjudication/rollback contract missing"
|
|
540
|
+
surface_close_missing=1
|
|
541
|
+
fi
|
|
542
|
+
done
|
|
543
|
+
if [ $surface_close_missing -eq 0 ]; then
|
|
544
|
+
ok "SURFACE_CLOSE v6 dispatch/timeout/adjudication/rollback contract is mirrored"
|
|
545
|
+
fi
|
|
546
|
+
|
|
403
547
|
section "Check 6d: Spec verification executes hidden-blind risk probes"
|
|
404
548
|
if python3 config/skills/_shared/spec-verify-check.py --self-test >/dev/null 2>&1; then
|
|
405
549
|
ok "spec-verify-check.py risk-probe and expected-contract self-test passed"
|
|
@@ -647,13 +791,16 @@ fi
|
|
|
647
791
|
if ! grep -Fq '"uses_visible_input_key_names"' config/skills/_shared/spec-verify-check.py \
|
|
648
792
|
|| ! grep -Fq '"asserts_visible_output_key_names"' config/skills/_shared/spec-verify-check.py \
|
|
649
793
|
|| ! grep -Fq '"asserts_no_unexpected_output_keys"' config/skills/_shared/spec-verify-check.py \
|
|
650
|
-
|| ! grep -Fq 'shape_contract
|
|
794
|
+
|| ! grep -Fq 'shape_contract claiming visible exact error object without' config/skills/_shared/spec-verify-check.py \
|
|
795
|
+
|| ! grep -Fq 'visible_text_names_exact_json_error_object' config/skills/_shared/spec-verify-check.py \
|
|
651
796
|
|| ! grep -Fq 'JSON error object shape_contract with exact object evidence was rejected' config/skills/_shared/spec-verify-check.py \
|
|
652
797
|
|| ! grep -Fq 'shape_contract without any evidence was accepted' config/skills/_shared/spec-verify-check.py \
|
|
653
798
|
|| ! grep -Fq 'shape_contract with exact key evidence was rejected' config/skills/_shared/spec-verify-check.py \
|
|
654
799
|
|| ! grep -Fq '`shape_contract` when the visible text names exact keys' config/skills/devlyn:resolve/references/phases/probe-derive.md \
|
|
655
|
-
|| ! grep -Fq '
|
|
656
|
-
|
|
800
|
+
|| ! grep -Fq 'visible_text_names_exact_json_error_object' config/skills/devlyn:resolve/references/phases/probe-derive.md \
|
|
801
|
+
|| ! grep -Fq '`shape_contract` must' config/skills/devlyn:resolve/SKILL.md \
|
|
802
|
+
|| ! grep -Fq 'visible_text_names_exact_json_error_object' config/skills/devlyn:resolve/SKILL.md; then
|
|
803
|
+
bad "risk-probe shape contracts must require exact visible input/output key evidence unconditionally, and asserts_exact_error_object when the probe claims the visible text names an exact JSON error object"
|
|
657
804
|
fi
|
|
658
805
|
if ! grep -Fq '"auth_signature_contract"' config/skills/_shared/spec-verify-check.py \
|
|
659
806
|
|| ! grep -Fq '"idempotency_replay"' config/skills/_shared/spec-verify-check.py \
|
|
@@ -960,7 +1107,7 @@ fi
|
|
|
960
1107
|
if ! grep -Fq 'per-feature Verification must include a solo-headroom' config/skills/devlyn:ideate/references/project-mode.md \
|
|
961
1108
|
|| ! grep -Fq 'per-feature Verification must include a solo-headroom' .claude/skills/devlyn:ideate/references/project-mode.md \
|
|
962
1109
|
|| ! grep -Fq 'per-feature Verification must include a solo-headroom' .agents/skills/devlyn:ideate/references/project-mode.md \
|
|
963
|
-
||
|
|
1110
|
+
|| grep -rq 'Context or Verification' config/skills/devlyn:ideate/references .claude/skills/devlyn:ideate/references .agents/skills/devlyn:ideate/references; then
|
|
964
1111
|
bad "ideate project mode must keep solo-headroom hypothesis inside each pair-candidate feature spec"
|
|
965
1112
|
else
|
|
966
1113
|
ok "ideate project mode keeps solo-headroom hypothesis inside each pair-candidate feature spec"
|
|
@@ -1078,38 +1225,39 @@ if ! grep -Fq 'If the spec includes a solo-headroom hypothesis, one of the two t
|
|
|
1078
1225
|
else
|
|
1079
1226
|
ok "resolve pair-JUDGE prompts prioritize solo-headroom hypothesis"
|
|
1080
1227
|
fi
|
|
1081
|
-
if ! grep -Fq '
|
|
1082
|
-
|| ! grep -Fq '
|
|
1083
|
-
|| ! grep -Fq '
|
|
1084
|
-
|| ! grep -Fq '
|
|
1085
|
-
|| ! grep -Fq '
|
|
1086
|
-
|| ! grep -Fq '
|
|
1087
|
-
|| ! grep -Fq '_shared/adapters
|
|
1088
|
-
|| ! grep -Fq '
|
|
1228
|
+
if ! grep -Fq 'The `--engine` flag does not disable default pairing' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1229
|
+
|| ! grep -Fq 'The `--engine` flag does not disable default pairing' .claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1230
|
+
|| ! grep -Fq 'The `--engine` flag does not disable default pairing' .agents/skills/devlyn:resolve/references/phases/verify.md \
|
|
1231
|
+
|| ! grep -Fq 'the second judge uses the OTHER engine by default when available' config/skills/devlyn:resolve/SKILL.md \
|
|
1232
|
+
|| ! grep -Fq 'the second judge uses the OTHER engine by default when available' .claude/skills/devlyn:resolve/SKILL.md \
|
|
1233
|
+
|| ! grep -Fq 'the second judge uses the OTHER engine by default when available' .agents/skills/devlyn:resolve/SKILL.md \
|
|
1234
|
+
|| ! grep -Fq '_shared/adapters/<name>.md' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1235
|
+
|| ! grep -Fq '`## Invocation`' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1236
|
+
|| ! grep -Fq '_shared/adapters/<name>.md` `## Invocation' config/skills/devlyn:resolve/SKILL.md \
|
|
1089
1237
|
|| ! grep -Fq '## Invocation' config/skills/_shared/adapters/claude.md \
|
|
1090
1238
|
|| ! grep -Fq '.devlyn/claude-judge.stdout' config/skills/_shared/adapters/claude.md; then
|
|
1091
1239
|
bad "engine-neutral pair-judge dual declaration (iter-0060) out of sync"
|
|
1092
1240
|
else
|
|
1093
1241
|
ok "engine-neutral pair-judge dual declaration (iter-0060) in sync"
|
|
1094
1242
|
fi
|
|
1095
|
-
if ! grep -Fq '
|
|
1096
|
-
|| ! grep -Fq '
|
|
1097
|
-
|| ! grep -Fq '
|
|
1098
|
-
|| ! grep -Fq '
|
|
1099
|
-
|| ! grep -Fq '
|
|
1100
|
-
|| ! grep -Fq '
|
|
1101
|
-
|| ! grep -Fq '
|
|
1102
|
-
|| ! grep -Fq '
|
|
1103
|
-
|| ! grep -Fq '
|
|
1104
|
-
|| ! grep -Fq '
|
|
1105
|
-
|| ! grep -Fq '
|
|
1106
|
-
|| ! grep -Fq '
|
|
1107
|
-
|| ! grep -Fq '
|
|
1108
|
-
|| ! grep -Fq '
|
|
1109
|
-
|| ! grep -Fq '
|
|
1110
|
-
|| ! grep -Fq '
|
|
1111
|
-
|| ! grep -Fq '
|
|
1112
|
-
|| ! grep -Fq '
|
|
1243
|
+
if ! grep -Fq '`complexity.high`, `complexity.large`' config/skills/devlyn:resolve/SKILL.md \
|
|
1244
|
+
|| ! grep -Fq '`complexity.high`, `complexity.large`' .claude/skills/devlyn:resolve/SKILL.md \
|
|
1245
|
+
|| ! grep -Fq '`complexity.high`, `complexity.large`' .agents/skills/devlyn:resolve/SKILL.md \
|
|
1246
|
+
|| ! grep -Fq '`spec.complexity.high`, `spec.complexity.large`' config/skills/devlyn:resolve/SKILL.md \
|
|
1247
|
+
|| ! grep -Fq '`spec.complexity.high`, `spec.complexity.large`' .claude/skills/devlyn:resolve/SKILL.md \
|
|
1248
|
+
|| ! grep -Fq '`spec.complexity.high`, `spec.complexity.large`' .agents/skills/devlyn:resolve/SKILL.md \
|
|
1249
|
+
|| ! grep -Fq 'Legacy complexity values remain accepted only for archived compatibility' config/skills/devlyn:resolve/references/state-schema.md \
|
|
1250
|
+
|| ! grep -Fq 'Legacy complexity values remain accepted only for archived compatibility' .claude/skills/devlyn:resolve/references/state-schema.md \
|
|
1251
|
+
|| ! grep -Fq 'Legacy complexity values remain accepted only for archived compatibility' .agents/skills/devlyn:resolve/references/state-schema.md \
|
|
1252
|
+
|| ! grep -Fq '`complexity.high`, `complexity.large`, `spec.complexity.high`, `spec.complexity.large`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
1253
|
+
|| ! grep -Fq '`complexity.high`, `complexity.large`, `spec.complexity.high`, `spec.complexity.large`' .claude/skills/devlyn:resolve/references/state-schema.md \
|
|
1254
|
+
|| ! grep -Fq '`complexity.high`, `complexity.large`, `spec.complexity.high`, `spec.complexity.large`' .agents/skills/devlyn:resolve/references/state-schema.md \
|
|
1255
|
+
|| ! grep -Fq '`complexity.large`, `spec.complexity.high`, `spec.complexity.large`,' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1256
|
+
|| ! grep -Fq '`complexity.large`, `spec.complexity.high`, `spec.complexity.large`,' .claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1257
|
+
|| ! grep -Fq '`complexity.large`, `spec.complexity.high`, `spec.complexity.large`,' .agents/skills/devlyn:resolve/references/phases/verify.md \
|
|
1258
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`, `risk.high`, `risk_probes.enabled`,' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1259
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`, `risk.high`, `risk_probes.enabled`,' .claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1260
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`, `risk.high`, `risk_probes.enabled`,' .agents/skills/devlyn:resolve/references/phases/verify.md; then
|
|
1113
1261
|
bad "resolve VERIFY docs must distinguish current large complexity, legacy high state, and legacy large spec compatibility"
|
|
1114
1262
|
else
|
|
1115
1263
|
ok "resolve VERIFY docs distinguish current large complexity, legacy high state, and legacy large spec compatibility"
|
|
@@ -1165,15 +1313,15 @@ if ! grep -Fq 'def spec_has_solo_headroom_hypothesis' config/skills/_shared/veri
|
|
|
1165
1313
|
|| ! grep -Fq 'spec_has_solo_headroom_hypothesis(' .agents/skills/_shared/verify-merge-findings.py \
|
|
1166
1314
|
|| ! grep -Fq ') is False' .agents/skills/_shared/verify-merge-findings.py \
|
|
1167
1315
|
|| ! grep -Fq ') is True' .agents/skills/_shared/verify-merge-findings.py \
|
|
1168
|
-
|| ! grep -Fq '
|
|
1316
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' \
|
|
1169
1317
|
config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1170
|
-
|| ! grep -Fq '
|
|
1318
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' \
|
|
1171
1319
|
.claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1172
|
-
|| ! grep -Fq '
|
|
1320
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' \
|
|
1173
1321
|
.agents/skills/devlyn:resolve/references/phases/verify.md \
|
|
1174
|
-
|| ! grep -Fq '
|
|
1175
|
-
|| ! grep -Fq '
|
|
1176
|
-
|| ! grep -Fq '
|
|
1322
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
1323
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' .claude/skills/devlyn:resolve/references/state-schema.md \
|
|
1324
|
+
|| ! grep -Fq '`spec.solo_headroom_hypothesis`' .agents/skills/devlyn:resolve/references/state-schema.md \
|
|
1177
1325
|
|| ! grep -Fq 'same actionable solo-headroom hypothesis is a VERIFY pair-trigger reason' config/skills/devlyn:resolve/SKILL.md \
|
|
1178
1326
|
|| ! grep -Fq 'same actionable solo-headroom hypothesis is a VERIFY pair-trigger reason' .claude/skills/devlyn:resolve/SKILL.md \
|
|
1179
1327
|
|| ! grep -Fq 'same actionable solo-headroom hypothesis is a VERIFY pair-trigger reason' .agents/skills/devlyn:resolve/SKILL.md; then
|
|
@@ -1199,9 +1347,9 @@ if ! grep -Fq 'pair_evidence_intent' config/skills/devlyn:resolve/references/fre
|
|
|
1199
1347
|
|| ! grep -Fq 'state.source.criteria_sha256` for generated free-form mode' config/skills/devlyn:resolve/references/phases/verify.md \
|
|
1200
1348
|
|| ! grep -Fq 'state.source.criteria_sha256` for generated free-form mode' .claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1201
1349
|
|| ! grep -Fq 'state.source.criteria_sha256` for generated free-form mode' .agents/skills/devlyn:resolve/references/phases/verify.md \
|
|
1202
|
-
|| ! grep -Fq 'Free-form
|
|
1203
|
-
|| ! grep -Fq 'Free-form
|
|
1204
|
-
|| ! grep -Fq 'Free-form
|
|
1350
|
+
|| ! grep -Fq 'Free-form sets `type: "generated"`' config/skills/devlyn:resolve/references/state-schema.md \
|
|
1351
|
+
|| ! grep -Fq 'Free-form sets `type: "generated"`' .claude/skills/devlyn:resolve/references/state-schema.md \
|
|
1352
|
+
|| ! grep -Fq 'Free-form sets `type: "generated"`' .agents/skills/devlyn:resolve/references/state-schema.md \
|
|
1205
1353
|
|| ! grep -Fq 'backticked observable command line that itself contains `miss`' config/skills/devlyn:resolve/references/free-form-mode.md \
|
|
1206
1354
|
|| ! grep -Fq 'backticked observable command line that itself contains `miss`' .claude/skills/devlyn:resolve/references/free-form-mode.md \
|
|
1207
1355
|
|| ! grep -Fq 'backticked observable command line that itself contains `miss`' .agents/skills/devlyn:resolve/references/free-form-mode.md \
|
|
@@ -1311,19 +1459,21 @@ if [ $verify_mech_missing -eq 0 ]; then
|
|
|
1311
1459
|
ok "spec-verify VERIFY output routes into verify-merge-findings.py"
|
|
1312
1460
|
fi
|
|
1313
1461
|
|
|
1314
|
-
section "Check 6j: VERIFY pair
|
|
1462
|
+
section "Check 6j: VERIFY default pair dispatches concurrently"
|
|
1315
1463
|
pair_trigger_order_missing=0
|
|
1316
1464
|
for file in \
|
|
1317
1465
|
config/skills/devlyn:resolve/SKILL.md \
|
|
1318
1466
|
.claude/skills/devlyn:resolve/SKILL.md \
|
|
1319
1467
|
.agents/skills/devlyn:resolve/SKILL.md
|
|
1320
1468
|
do
|
|
1321
|
-
if ! grep -Fq '
|
|
1322
|
-
|| ! grep -Fq '
|
|
1323
|
-
|| ! grep -Fq '
|
|
1324
|
-
|| ! grep -Fq '
|
|
1325
|
-
|| ! grep -Fq '
|
|
1326
|
-
|
|
1469
|
+
if ! grep -Fq 'Verify dual-judge is default-when-available' "$file" \
|
|
1470
|
+
|| ! grep -Fq 'persist `pair_trigger` before spawn with `pair.default`' "$file" \
|
|
1471
|
+
|| ! grep -Fq 'dispatch both judges concurrently against the same frozen diff' "$file" \
|
|
1472
|
+
|| ! grep -Fq 'A primary blocker never cancels the pair judge' "$file" \
|
|
1473
|
+
|| ! grep -Fq 'run the same two required judges sequentially' "$file" \
|
|
1474
|
+
|| ! grep -Fq 'Eligible schema-v3 state must include `pair.default`' "$file" \
|
|
1475
|
+
|| ! grep -Fq '`primary_judge_blocker` is parser-recognized only for archived v2.0 replay; new runs never write it' "$file"; then
|
|
1476
|
+
bad "$file — VERIFY default pair rule missing."
|
|
1327
1477
|
pair_trigger_order_missing=1
|
|
1328
1478
|
fi
|
|
1329
1479
|
done
|
|
@@ -1332,11 +1482,14 @@ for file in \
|
|
|
1332
1482
|
.claude/skills/devlyn:resolve/references/phases/verify.md \
|
|
1333
1483
|
.agents/skills/devlyn:resolve/references/phases/verify.md
|
|
1334
1484
|
do
|
|
1335
|
-
if ! grep -Fq 'Pair-mode
|
|
1336
|
-
|| ! grep -Fq '
|
|
1337
|
-
|| ! grep -Fq '
|
|
1338
|
-
|| ! grep -Fq '
|
|
1339
|
-
|
|
1485
|
+
if ! grep -Fq 'Pair-mode (default when OTHER engine is available)' "$file" \
|
|
1486
|
+
|| ! grep -Fq 'with `pair.default` plus every applicable' "$file" \
|
|
1487
|
+
|| ! grep -Fq 'dispatch the primary and pair JUDGEs concurrently against the same frozen' "$file" \
|
|
1488
|
+
|| ! grep -Fq 'A primary blocker does not cancel the pair-JUDGE' "$file" \
|
|
1489
|
+
|| ! grep -Fq 'runs the same two required judges' "$file" \
|
|
1490
|
+
|| ! grep -Fq 'Eligible schema-v3 state must contain `pair.default`' "$file" \
|
|
1491
|
+
|| ! grep -Fq 'New runs never' "$file"; then
|
|
1492
|
+
bad "$file — VERIFY default pair dispatch missing"
|
|
1340
1493
|
pair_trigger_order_missing=1
|
|
1341
1494
|
fi
|
|
1342
1495
|
done
|
|
@@ -1345,16 +1498,50 @@ for file in \
|
|
|
1345
1498
|
.claude/skills/devlyn:resolve/references/state-schema.md \
|
|
1346
1499
|
.agents/skills/devlyn:resolve/references/state-schema.md
|
|
1347
1500
|
do
|
|
1348
|
-
if ! grep -Fq '
|
|
1349
|
-
|| ! grep -Fq '
|
|
1350
|
-
|| ! grep -Fq '
|
|
1351
|
-
|| ! grep -Fq '
|
|
1352
|
-
|
|
1501
|
+
if ! grep -Fq '"version": "3.0"' "$file" \
|
|
1502
|
+
|| ! grep -Fq 'pair.default` dispatches both judges concurrently' "$file" \
|
|
1503
|
+
|| ! grep -Fq 'runs the same two required judges sequentially' "$file" \
|
|
1504
|
+
|| ! grep -Fq 'a primary blocker never skips the pair' "$file" \
|
|
1505
|
+
|| ! grep -Fq 'Schema v3.0 eligible state requires `pair.default`' "$file" \
|
|
1506
|
+
|| ! grep -Fq 'archived v2.0 replay' "$file" \
|
|
1507
|
+
|| ! grep -Fq 'Missing, contradictory, incomplete, or unknown trigger state BLOCKs VERIFY' "$file"; then
|
|
1508
|
+
bad "$file — schema-v3 default pair contract missing"
|
|
1353
1509
|
pair_trigger_order_missing=1
|
|
1354
1510
|
fi
|
|
1355
1511
|
done
|
|
1356
1512
|
if [ $pair_trigger_order_missing -eq 0 ]; then
|
|
1357
|
-
ok "VERIFY pair
|
|
1513
|
+
ok "VERIFY default pair dispatches concurrently"
|
|
1514
|
+
fi
|
|
1515
|
+
|
|
1516
|
+
section "Check 6k: PLAN route is orchestrator-fixed"
|
|
1517
|
+
plan_route_ok=1
|
|
1518
|
+
for plan_route_file in "config/skills/devlyn:resolve/SKILL.md" CLAUDE.md AGENTS.md \
|
|
1519
|
+
"config/skills/devlyn:engines/SKILL.md" ".agents/skills/devlyn:resolve/SKILL.md" \
|
|
1520
|
+
".agents/skills/devlyn:engines/SKILL.md"; do
|
|
1521
|
+
[ -f "$plan_route_file" ] || plan_route_ok=0
|
|
1522
|
+
done
|
|
1523
|
+
sed -n '/^<engine_routing>$/,/^<\/engine_routing>$/p' "config/skills/devlyn:resolve/SKILL.md" \
|
|
1524
|
+
| grep -Fq 'PLAN is orchestrator-fixed and never inherits `--engine`, an executor pin, or `state.engine`' || plan_route_ok=0
|
|
1525
|
+
sed -n '/^## PHASE 1: PLAN$/,/^## PHASE 1.5/p' "config/skills/devlyn:resolve/SKILL.md" \
|
|
1526
|
+
| grep -Fq 'PLAN is orchestrator-fixed and never inherits `--engine`, an executor pin, or `state.engine`' || plan_route_ok=0
|
|
1527
|
+
grep -Fq 'PLAN is orchestrator-fixed and never inherits `--engine` or an executor pin' CLAUDE.md || plan_route_ok=0
|
|
1528
|
+
grep -Fq 'PLAN is orchestrator-fixed and never inherits `--engine` or the executor pin' AGENTS.md || plan_route_ok=0
|
|
1529
|
+
grep -Fq 'PLAN is orchestrator-fixed and never follows the pin' config/skills/devlyn:engines/SKILL.md || plan_route_ok=0
|
|
1530
|
+
if grep -En '([Ee]xecutor|Default engine: Claude for)[^[:cntrl:]]{0,80}PLAN[[:space:]]*/[[:space:]]*IMPLEMENT([[:space:]]*/[[:space:]]*BUILD_GATE)?[[:space:]]*/[[:space:]]*CLEANUP' \
|
|
1531
|
+
config/skills/devlyn:resolve/SKILL.md \
|
|
1532
|
+
CLAUDE.md \
|
|
1533
|
+
AGENTS.md \
|
|
1534
|
+
README.md \
|
|
1535
|
+
config/skills/devlyn:engines/SKILL.md \
|
|
1536
|
+
.agents/skills/devlyn:resolve/SKILL.md \
|
|
1537
|
+
.agents/skills/devlyn:engines/SKILL.md \
|
|
1538
|
+
>/dev/null 2>&1; then
|
|
1539
|
+
plan_route_ok=0
|
|
1540
|
+
fi
|
|
1541
|
+
if [ $plan_route_ok -eq 1 ]; then
|
|
1542
|
+
ok "PLAN is orchestrator-fixed: exact declarations locked on all surfaces, no executor-role enumeration"
|
|
1543
|
+
else
|
|
1544
|
+
bad "PLAN route contract violated: a locked orchestrator-fixed declaration is missing or an executor-role enumeration re-teaches PLAN"
|
|
1358
1545
|
fi
|
|
1359
1546
|
|
|
1360
1547
|
section "Check 6h: No undocumented spec.expected.json.browser_flows field"
|
|
@@ -3444,8 +3631,9 @@ else
|
|
|
3444
3631
|
offenders="${offenders}"$'\n'"packaged pair evidence subset could not allocate temporary audit workspace"
|
|
3445
3632
|
fi
|
|
3446
3633
|
if make_temp_file pack_json /tmp/devlyn-lint-pack.XXXXXX.json \
|
|
3447
|
-
&&
|
|
3448
|
-
if
|
|
3634
|
+
&& make_temp_dir pack_cache /tmp/devlyn-lint-pack-cache.XXXXXX; then
|
|
3635
|
+
if npm_config_cache="$pack_cache" npm pack --dry-run --json > "$pack_json" 2>/dev/null; then
|
|
3636
|
+
if ! node - "$pack_json" <<'NODE'
|
|
3449
3637
|
const fs = require("fs");
|
|
3450
3638
|
const path = require("path");
|
|
3451
3639
|
const packPath = process.argv[2];
|
|
@@ -3531,13 +3719,17 @@ if (forbidden.length > 0) {
|
|
|
3531
3719
|
process.exit(2);
|
|
3532
3720
|
}
|
|
3533
3721
|
NODE
|
|
3534
|
-
|
|
3535
|
-
|
|
3722
|
+
then
|
|
3723
|
+
offenders="${offenders}"$'\n'"npm pack dry-run must include benchmark runner/gate regression tests, all shadow fixture files, retired fixture replay docs, and exclude pycache artifacts"
|
|
3724
|
+
fi
|
|
3725
|
+
else
|
|
3726
|
+
offenders="${offenders}"$'\n'"npm pack dry-run failed while checking benchmark runner/gate regression tests"
|
|
3536
3727
|
fi
|
|
3537
3728
|
else
|
|
3538
|
-
offenders="${offenders}"$'\n'"npm pack dry-run
|
|
3729
|
+
offenders="${offenders}"$'\n'"npm pack dry-run could not allocate temporary package workspace"
|
|
3539
3730
|
fi
|
|
3540
3731
|
[ -n "${pack_json:-}" ] && rm -f "$pack_json"
|
|
3732
|
+
[ -n "${pack_cache:-}" ] && rm -rf "$pack_cache"
|
|
3541
3733
|
non_executable_shell_scripts=$(find benchmark/auto-resolve/scripts -maxdepth 1 -name '*.sh' -type f ! -perm -111 -print | sort)
|
|
3542
3734
|
if [ -n "$non_executable_shell_scripts" ]; then
|
|
3543
3735
|
while IFS= read -r f; do
|
|
@@ -3694,7 +3886,7 @@ if ! grep -Fq 'high-risk fixture must include a resolve risk-trigger term' scrip
|
|
|
3694
3886
|
|| ! grep -Fq 'expected.json must be an object' scripts/lint-fixtures.sh \
|
|
3695
3887
|
|| ! grep -Fq 'schema_ok=0' scripts/lint-fixtures.sh \
|
|
3696
3888
|
|| ! grep -Fq 'DEVLYN_LINT_FIXTURES_NO_JSONSCHEMA' scripts/lint-fixtures.sh \
|
|
3697
|
-
|| ! grep -Fq 'conditional
|
|
3889
|
+
|| ! grep -Fq 'conditional risk-probe triggers' benchmark/auto-resolve/fixtures/SCHEMA.md; then
|
|
3698
3890
|
offenders="${offenders}"$'\n'"fixture lint must require high-risk fixtures to include resolve pair/risk trigger terms"
|
|
3699
3891
|
fi
|
|
3700
3892
|
unsafe_json_parser_refs=$(python3 - <<'PY'
|