devlyn-cli 2.10.0 → 3.0.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.
Files changed (82) hide show
  1. package/AGENTS.md +4 -9
  2. package/CLAUDE.md +11 -15
  3. package/README.md +31 -7
  4. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.json +25 -0
  5. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.md +10 -0
  6. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.json +18 -0
  7. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.md +9 -0
  8. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.json +18 -0
  9. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.md +9 -0
  10. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F16-cli-quote-tax-rules/l2_risk_probes/result.json +28 -0
  11. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F23-cli-fulfillment-wave/l2_risk_probes/result.json +28 -0
  12. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F25-cli-cart-promotion-rules/l2_risk_probes/result.json +30 -0
  13. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.json +28 -0
  14. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.md +15 -0
  15. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.json +28 -0
  16. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.md +15 -0
  17. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/F21-cli-scheduler-priority/l2_risk_probes/result.json +32 -0
  18. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.json +44 -0
  19. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.md +16 -0
  20. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.json +18 -0
  21. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.md +9 -0
  22. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.json +28 -0
  23. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.md +15 -0
  24. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.json +28 -0
  25. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.md +15 -0
  26. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.json +28 -0
  27. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.md +15 -0
  28. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.json +28 -0
  29. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.md +15 -0
  30. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.json +28 -0
  31. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.md +15 -0
  32. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.json +28 -0
  33. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.md +15 -0
  34. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.json +28 -0
  35. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.md +15 -0
  36. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.json +28 -0
  37. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.md +15 -0
  38. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.json +28 -0
  39. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.md +15 -0
  40. package/benchmark/auto-resolve/scripts/run-fixture.sh +11 -1
  41. package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +83 -1
  42. package/bin/devlyn.js +59 -9
  43. package/config/skills/_shared/.ruff.toml +2 -0
  44. package/config/skills/_shared/adapters/claude.md +9 -1
  45. package/config/skills/_shared/adapters/codex.md +5 -0
  46. package/config/skills/_shared/adapters/grok.md +37 -13
  47. package/config/skills/_shared/archive_run.py +738 -56
  48. package/config/skills/_shared/codex-config.md +19 -4
  49. package/config/skills/_shared/codex-monitored.sh +81 -12
  50. package/config/skills/_shared/collect-codex-findings.py +419 -60
  51. package/config/skills/_shared/engine-preflight.md +8 -7
  52. package/config/skills/_shared/expected.schema.json +68 -0
  53. package/config/skills/_shared/finish-gate.py +12 -11
  54. package/config/skills/_shared/grok-anchor-guard.py +78 -0
  55. package/config/skills/_shared/invocation-receipt.py +1041 -0
  56. package/config/skills/_shared/judge-output-parser.py +200 -0
  57. package/config/skills/_shared/judge-role-evidence.py +273 -0
  58. package/config/skills/_shared/phase-prompt-render.py +181 -0
  59. package/config/skills/_shared/process-evidence.py +909 -0
  60. package/config/skills/_shared/resolve-bootstrap.py +776 -84
  61. package/config/skills/_shared/resolve-stop-hook.py +33 -1
  62. package/config/skills/_shared/role-config.py +552 -0
  63. package/config/skills/_shared/run-bounded.py +1 -1
  64. package/config/skills/_shared/spec-verify-check.py +1037 -192
  65. package/config/skills/_shared/state-phase-write.py +2551 -83
  66. package/config/skills/_shared/terminal-claim-check.py +15 -0
  67. package/config/skills/_shared/verify-merge-findings.py +1127 -50
  68. package/config/skills/devlyn:engines/SKILL.md +8 -16
  69. package/config/skills/devlyn:ideate/SKILL.md +1 -1
  70. package/config/skills/devlyn:ideate/references/spec-template.md +1 -0
  71. package/config/skills/devlyn:queue/SKILL.md +7 -4
  72. package/config/skills/devlyn:resolve/SKILL.md +94 -35
  73. package/config/skills/devlyn:resolve/references/outer-loop.md +15 -0
  74. package/config/skills/devlyn:resolve/references/phases/build-gate.md +33 -4
  75. package/config/skills/devlyn:resolve/references/phases/implement.md +4 -3
  76. package/config/skills/devlyn:resolve/references/phases/plan.md +1 -5
  77. package/config/skills/devlyn:resolve/references/phases/probe-derive.md +4 -2
  78. package/config/skills/devlyn:resolve/references/phases/verify.md +120 -80
  79. package/config/skills/devlyn:resolve/references/state-schema.md +23 -9
  80. package/package.json +5 -1
  81. package/scripts/lint-fixtures.sh +4 -1
  82. package/scripts/lint-skills.sh +447 -290
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260511-f3-http-error-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -37.0,
14
+ "min_bare_headroom": -37,
15
+ "avg_solo_headroom": -19.0,
16
+ "min_solo_headroom": -19,
17
+ "rows": [
18
+ {
19
+ "fixture": "F3-backend-contract-risk",
20
+ "status": "FAIL",
21
+ "bare_score": 97,
22
+ "solo_score": 99,
23
+ "bare_headroom": -37,
24
+ "solo_headroom": -19,
25
+ "reason": "bare score 97 > 60; solo_claude score 99 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260511-f3-http-error-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -37.0
9
+ Minimum bare headroom: -37
10
+ Average solo headroom: -19.0
11
+ Minimum solo headroom: -19
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F3-backend-contract-risk | 97 | -37 | 99 | -19 | FAIL | bare score 97 > 60; solo_claude score 99 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f2-medium-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -23.0,
14
+ "min_bare_headroom": -23,
15
+ "avg_solo_headroom": -15.0,
16
+ "min_solo_headroom": -15,
17
+ "rows": [
18
+ {
19
+ "fixture": "F2-cli-medium-subcommand",
20
+ "status": "FAIL",
21
+ "bare_score": 83,
22
+ "solo_score": 95,
23
+ "bare_headroom": -23,
24
+ "solo_headroom": -15,
25
+ "reason": "bare score 83 > 60; solo_claude score 95 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f2-medium-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -23.0
9
+ Minimum bare headroom: -23
10
+ Average solo headroom: -15.0
11
+ Minimum solo headroom: -15
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F2-cli-medium-subcommand | 83 | -23 | 95 | -15 | FAIL | bare score 83 > 60; solo_claude score 95 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f31-seat-rebalance-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": 27.0,
14
+ "min_bare_headroom": 27,
15
+ "avg_solo_headroom": -18.0,
16
+ "min_solo_headroom": -18,
17
+ "rows": [
18
+ {
19
+ "fixture": "F31-cli-seat-rebalance",
20
+ "status": "FAIL",
21
+ "bare_score": 33,
22
+ "solo_score": 98,
23
+ "bare_headroom": 27,
24
+ "solo_headroom": -18,
25
+ "reason": "solo_claude score 98 > 80; bare judge disqualifier; bare result disqualifier; bare verify disqualifier"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f31-seat-rebalance-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: 27.0
9
+ Minimum bare headroom: 27
10
+ Average solo headroom: -18.0
11
+ Minimum solo headroom: -18
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F31-cli-seat-rebalance | 33 | 27 | 98 | -18 | FAIL | solo_claude score 98 > 80; bare judge disqualifier; bare result disqualifier; bare verify disqualifier |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f32-subscription-renewal-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": 27.0,
14
+ "min_bare_headroom": 27,
15
+ "avg_solo_headroom": -18.0,
16
+ "min_solo_headroom": -18,
17
+ "rows": [
18
+ {
19
+ "fixture": "F32-cli-subscription-renewal",
20
+ "status": "FAIL",
21
+ "bare_score": 33,
22
+ "solo_score": 98,
23
+ "bare_headroom": 27,
24
+ "solo_headroom": -18,
25
+ "reason": "solo_claude score 98 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f32-subscription-renewal-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: 27.0
9
+ Minimum bare headroom: 27
10
+ Average solo headroom: -18.0
11
+ Minimum solo headroom: -18
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F32-cli-subscription-renewal | 33 | 27 | 98 | -18 | FAIL | solo_claude score 98 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f4-web-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -10.0,
14
+ "min_bare_headroom": -10,
15
+ "avg_solo_headroom": -12.0,
16
+ "min_solo_headroom": -12,
17
+ "rows": [
18
+ {
19
+ "fixture": "F4-web-browser-design",
20
+ "status": "FAIL",
21
+ "bare_score": 70,
22
+ "solo_score": 92,
23
+ "bare_headroom": -10,
24
+ "solo_headroom": -12,
25
+ "reason": "bare score 70 > 60; solo_claude score 92 > 80; bare judge disqualifier; bare result disqualifier; bare verify disqualifier"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f4-web-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -10.0
9
+ Minimum bare headroom: -10
10
+ Average solo headroom: -12.0
11
+ Minimum solo headroom: -12
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F4-web-browser-design | 70 | -10 | 92 | -12 | FAIL | bare score 70 > 60; solo_claude score 92 > 80; bare judge disqualifier; bare result disqualifier; bare verify disqualifier |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f5-fixloop-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -39.0,
14
+ "min_bare_headroom": -39,
15
+ "avg_solo_headroom": -19.0,
16
+ "min_solo_headroom": -19,
17
+ "rows": [
18
+ {
19
+ "fixture": "F5-fix-loop-red-green",
20
+ "status": "FAIL",
21
+ "bare_score": 99,
22
+ "solo_score": 99,
23
+ "bare_headroom": -39,
24
+ "solo_headroom": -19,
25
+ "reason": "bare score 99 > 60; solo_claude score 99 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f5-fixloop-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -39.0
9
+ Minimum bare headroom: -39
10
+ Average solo headroom: -19.0
11
+ Minimum solo headroom: -19
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F5-fix-loop-red-green | 99 | -39 | 99 | -19 | FAIL | bare score 99 > 60; solo_claude score 99 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f6-checksum-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -37.0,
14
+ "min_bare_headroom": -37,
15
+ "avg_solo_headroom": -16.0,
16
+ "min_solo_headroom": -16,
17
+ "rows": [
18
+ {
19
+ "fixture": "F6-dep-audit-native-module",
20
+ "status": "FAIL",
21
+ "bare_score": 97,
22
+ "solo_score": 96,
23
+ "bare_headroom": -37,
24
+ "solo_headroom": -16,
25
+ "reason": "bare score 97 > 60; solo_claude score 96 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f6-checksum-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -37.0
9
+ Minimum bare headroom: -37
10
+ Average solo headroom: -16.0
11
+ Minimum solo headroom: -16
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F6-dep-audit-native-module | 97 | -37 | 96 | -16 | FAIL | bare score 97 > 60; solo_claude score 96 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f7-scope-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": -39.0,
14
+ "min_bare_headroom": -39,
15
+ "avg_solo_headroom": -20.0,
16
+ "min_solo_headroom": -20,
17
+ "rows": [
18
+ {
19
+ "fixture": "F7-out-of-scope-trap",
20
+ "status": "FAIL",
21
+ "bare_score": 99,
22
+ "solo_score": 100,
23
+ "bare_headroom": -39,
24
+ "solo_headroom": -20,
25
+ "reason": "bare score 99 > 60; solo_claude score 100 > 80"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f7-scope-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: -39.0
9
+ Minimum bare headroom: -39
10
+ Average solo headroom: -20.0
11
+ Minimum solo headroom: -20
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F7-out-of-scope-trap | 99 | -39 | 100 | -20 | FAIL | bare score 99 > 60; solo_claude score 100 > 80 |
@@ -0,0 +1,28 @@
1
+ {
2
+ "run_id": "20260512-f9-e2e-headroom",
3
+ "rule": "at least 1 candidate fixtures; each must satisfy bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, with both baseline arms evidence-complete",
4
+ "verdict": "FAIL",
5
+ "fixtures_total": 1,
6
+ "fixtures_passed": 0,
7
+ "min_fixtures": 1,
8
+ "bare_max": 60,
9
+ "solo_max": 80,
10
+ "min_bare_headroom_required": 5,
11
+ "min_solo_headroom_required": 5,
12
+ "fixture_count_ok": true,
13
+ "avg_bare_headroom": 0.0,
14
+ "min_bare_headroom": 0,
15
+ "avg_solo_headroom": -10.0,
16
+ "min_solo_headroom": -10,
17
+ "rows": [
18
+ {
19
+ "fixture": "F9-e2e-ideate-to-resolve",
20
+ "status": "FAIL",
21
+ "bare_score": 60,
22
+ "solo_score": 90,
23
+ "bare_headroom": 0,
24
+ "solo_headroom": -10,
25
+ "reason": "bare headroom 0 < 5; solo_claude score 90 > 80; bare judge disqualifier"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,15 @@
1
+ # Headroom Gate — 20260512-f9-e2e-headroom
2
+
3
+ Verdict: **FAIL**
4
+
5
+ Fixtures passed: 0/1 (minimum required: 1)
6
+
7
+ Rule: at least 1 fixtures; bare <= 60 with headroom >= 5, solo_claude <= 80 with headroom >= 5, both baseline arms evidence-complete.
8
+ Average bare headroom: 0.0
9
+ Minimum bare headroom: 0
10
+ Average solo headroom: -10.0
11
+ Minimum solo headroom: -10
12
+
13
+ | Fixture | Bare | Bare headroom | Solo | Solo headroom | Status | Reason |
14
+ |---|---:|---:|---:|---:|---|---|
15
+ | F9-e2e-ideate-to-resolve | 60 | 0 | 90 | -10 | FAIL | bare headroom 0 < 5; solo_claude score 90 > 80; bare judge disqualifier |
@@ -744,8 +744,18 @@ verify = {"commands": [], "forbidden_pattern_hits": [], "deps_added": 0,
744
744
 
745
745
  for vc in expected.get("verification_commands", []):
746
746
  try:
747
+ timeout_sec = vc.get("timeout_sec", 60)
748
+ if (
749
+ isinstance(timeout_sec, bool)
750
+ or not isinstance(timeout_sec, int)
751
+ or not 1 <= timeout_sec <= 600
752
+ ):
753
+ raise ValueError(
754
+ "timeout_sec must be an integer from 1 to 600 (bool is not allowed)"
755
+ )
747
756
  proc = subprocess.run(vc["cmd"], cwd=work, shell=True, env=verify_env,
748
- capture_output=True, text=True, timeout=60)
757
+ capture_output=True, text=True,
758
+ timeout=timeout_sec)
749
759
  out = (proc.stdout or "") + (proc.stderr or "")
750
760
  ok_exit = proc.returncode == vc.get("exit_code", 0)
751
761
  ok_contains = all(s in out for s in vc.get("stdout_contains", []))
@@ -5,7 +5,7 @@ set -euo pipefail
5
5
  ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
6
6
  TMP="$(mktemp -d)"
7
7
  BENCH_ROOT="$ROOT/benchmark/auto-resolve"
8
- trap 'rm -rf "$TMP"; rm -rf "$BENCH_ROOT/results/arg-parse-command-test" "$BENCH_ROOT/results/arg-parse-discovery-test" "$BENCH_ROOT/results/arg-parse-shadow-suite-dry-run" "$BENCH_ROOT/results/arg-parse-shadow-cli-suite-dry-run" "$BENCH_ROOT/results/arg-parse-variant-path" "$BENCH_ROOT/results/arg-parse-headroom-cli-replay" "$BENCH_ROOT/results/arg-parse-pair-cli-replay" "$BENCH_ROOT/results/arg-parse-shadow-judge" "$BENCH_ROOT/results/arg-parse-opus-bad-mapping" "$BENCH_ROOT/results/arg-parse-opus-malformed-mapping" "$BENCH_ROOT/results/arg-parse-opus-malformed-score" "$BENCH_ROOT/results/arg-parse-opus-invalid-generated-score" "$BENCH_ROOT/results/arg-parse-opus-invalid-generated-dq" "$BENCH_ROOT/results/arg-parse-opus-summary-mapping" "$BENCH_ROOT/results/arg-parse-opus-summary-null-margin"; rm -rf /tmp/bench-arg-parse-variant-path-* /tmp/bench-arg-parse-headroom-cli-replay-*' EXIT
8
+ trap 'rm -rf "$TMP"; rm -rf "$BENCH_ROOT/results/arg-parse-command-test" "$BENCH_ROOT/results/arg-parse-discovery-test" "$BENCH_ROOT/results/arg-parse-shadow-suite-dry-run" "$BENCH_ROOT/results/arg-parse-shadow-cli-suite-dry-run" "$BENCH_ROOT/results/arg-parse-variant-path" "$BENCH_ROOT/results/arg-parse-timeout-budget" "$BENCH_ROOT/results/arg-parse-headroom-cli-replay" "$BENCH_ROOT/results/arg-parse-pair-cli-replay" "$BENCH_ROOT/results/arg-parse-shadow-judge" "$BENCH_ROOT/results/arg-parse-opus-bad-mapping" "$BENCH_ROOT/results/arg-parse-opus-malformed-mapping" "$BENCH_ROOT/results/arg-parse-opus-malformed-score" "$BENCH_ROOT/results/arg-parse-opus-invalid-generated-score" "$BENCH_ROOT/results/arg-parse-opus-invalid-generated-dq" "$BENCH_ROOT/results/arg-parse-opus-summary-mapping" "$BENCH_ROOT/results/arg-parse-opus-summary-null-margin" "$BENCH_ROOT/shadow-fixtures/arg-parse-timeout-budget"; rm -rf /tmp/bench-arg-parse-variant-path-* /tmp/bench-arg-parse-timeout-budget-* /tmp/bench-arg-parse-headroom-cli-replay-*' EXIT
9
9
 
10
10
  expect_fail_contains() {
11
11
  local name="$1"
@@ -849,6 +849,88 @@ if grep -Fq -- '--engine auto' \
849
849
  exit 1
850
850
  fi
851
851
  mkdir -p "$BENCH_ROOT/shadow-fixtures"
852
+ rm -rf "$BENCH_ROOT/shadow-fixtures/arg-parse-timeout-budget" \
853
+ "$BENCH_ROOT/results/arg-parse-timeout-budget"
854
+ cp -R "$BENCH_ROOT/fixtures/F1-cli-trivial-flag" \
855
+ "$BENCH_ROOT/shadow-fixtures/arg-parse-timeout-budget"
856
+ python3 - "$BENCH_ROOT/shadow-fixtures/arg-parse-timeout-budget/expected.json" <<'PY'
857
+ import json
858
+ import pathlib
859
+ import sys
860
+
861
+ path = pathlib.Path(sys.argv[1])
862
+ expected = json.loads(path.read_text())
863
+ expected["verification_commands"] = [
864
+ {"cmd": "true"},
865
+ {"cmd": "true", "timeout_sec": 1},
866
+ {"cmd": "true", "timeout_sec": 600},
867
+ {"cmd": "true", "timeout_sec": True},
868
+ {"cmd": "true", "timeout_sec": 601},
869
+ {
870
+ "cmd": "python3 -c \"import time; time.sleep(2)\"",
871
+ "timeout_sec": 1,
872
+ },
873
+ {
874
+ "cmd": "python3 -c \"import time; time.sleep(1)\"",
875
+ "timeout_sec": 5,
876
+ },
877
+ ]
878
+ path.write_text(json.dumps(expected, indent=2) + "\n")
879
+ PY
880
+ bash "$ROOT/benchmark/auto-resolve/scripts/run-fixture.sh" \
881
+ --fixture arg-parse-timeout-budget \
882
+ --arm bare \
883
+ --run-id arg-parse-timeout-budget \
884
+ --dry-run > "$TMP/timeout-budget-dry-run.out" 2>&1
885
+ python3 - "$BENCH_ROOT/results/arg-parse-timeout-budget/arg-parse-timeout-budget/bare/verify.json" <<'PY'
886
+ import json
887
+ import pathlib
888
+ import sys
889
+
890
+ commands = json.loads(pathlib.Path(sys.argv[1]).read_text())["commands"]
891
+ assert commands[0]["pass"] is True, commands
892
+ assert commands[1]["pass"] is True, commands
893
+ assert commands[2]["pass"] is True, commands
894
+ expected_error = (
895
+ "error:ValueError:timeout_sec must be an integer from 1 to 600 "
896
+ "(bool is not allowed)"
897
+ )
898
+ assert commands[3]["pass"] is False and commands[3]["reason"] == expected_error, commands
899
+ assert commands[4]["pass"] is False and commands[4]["reason"] == expected_error, commands
900
+ assert commands[5]["reason"] == "timeout", commands
901
+ assert commands[6]["pass"] is True, commands
902
+ PY
903
+
904
+ TIMEOUT_LINT_ROOT="$TMP/timeout-lint-fixtures"
905
+ mkdir -p "$TIMEOUT_LINT_ROOT"
906
+ cp -R "$BENCH_ROOT/fixtures/F1-cli-trivial-flag" \
907
+ "$TIMEOUT_LINT_ROOT/F1-cli-trivial-flag"
908
+ python3 - "$TIMEOUT_LINT_ROOT/F1-cli-trivial-flag/expected.json" <<'PY'
909
+ import json
910
+ import pathlib
911
+ import sys
912
+
913
+ path = pathlib.Path(sys.argv[1])
914
+ expected = json.loads(path.read_text())
915
+ expected["verification_commands"][0]["timeout_sec"] = 600
916
+ path.write_text(json.dumps(expected, indent=2) + "\n")
917
+ PY
918
+ DEVLYN_FIXTURES_DIR="$TIMEOUT_LINT_ROOT" DEVLYN_LINT_FIXTURES_NO_JSONSCHEMA=1 \
919
+ bash "$ROOT/scripts/lint-fixtures.sh" > "$TMP/timeout-lint-pass.out" 2>&1
920
+ python3 - "$TIMEOUT_LINT_ROOT/F1-cli-trivial-flag/expected.json" <<'PY'
921
+ import json
922
+ import pathlib
923
+ import sys
924
+
925
+ path = pathlib.Path(sys.argv[1])
926
+ expected = json.loads(path.read_text())
927
+ expected["verification_commands"][0]["timeout_sec"] = True
928
+ path.write_text(json.dumps(expected, indent=2) + "\n")
929
+ PY
930
+ expect_fail_contains timeout-lint-bool \
931
+ "timeout_sec must be an integer from 1 to 600" \
932
+ env DEVLYN_FIXTURES_DIR="$TIMEOUT_LINT_ROOT" DEVLYN_LINT_FIXTURES_NO_JSONSCHEMA=1 \
933
+ bash "$ROOT/scripts/lint-fixtures.sh"
852
934
  rm -rf "$BENCH_ROOT/shadow-fixtures/arg-parse-nan-metadata" \
853
935
  "$BENCH_ROOT/shadow-fixtures/arg-parse-nan-expected" \
854
936
  "$BENCH_ROOT/results/arg-parse-nan-metadata" \