devlyn-cli 3.2.1 → 3.3.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 +2 -2
- package/CLAUDE.md +2 -2
- package/README.md +12 -102
- package/bin/devlyn.js +13 -225
- package/bin/instruction-templates.json +8 -0
- package/config/skills/_shared/adapters/grok.md +1 -2
- package/config/skills/_shared/archive_run.py +15 -3
- package/config/skills/_shared/judge-role-evidence.py +21 -1
- package/config/skills/_shared/runtime-principles.md +1 -1
- package/config/skills/_shared/spec-verify-check.py +0 -653
- package/config/skills/_shared/state-phase-write.py +351 -25
- package/config/skills/_shared/task-complete.py +660 -150
- package/config/skills/_shared/terminal-claim-check.py +229 -4
- package/config/skills/_shared/verify-merge-findings.py +93 -2
- package/config/skills/devlyn:ideate/SKILL.md +3 -4
- package/config/skills/devlyn:ideate/references/elicitation.md +2 -35
- package/config/skills/devlyn:ideate/references/from-spec-mode.md +3 -18
- package/config/skills/devlyn:ideate/references/project-mode.md +1 -16
- package/config/skills/devlyn:ideate/references/spec-template.md +0 -2
- package/config/skills/devlyn:queue/SKILL.md +6 -4
- package/config/skills/devlyn:resolve/SKILL.md +16 -25
- package/config/skills/devlyn:resolve/references/free-form-mode.md +0 -14
- package/config/skills/devlyn:resolve/references/outer-loop.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/build-gate.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/cleanup.md +3 -3
- package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/probe-derive.md +1 -16
- package/config/skills/devlyn:resolve/references/phases/verify.md +4 -9
- package/config/skills/devlyn:resolve/references/state-schema.md +9 -7
- package/config/skills/devlyn:resolve/references/task-completion.md +47 -38
- package/{config/skills → optional-skills}/code-health-standards/SKILL.md +4 -13
- package/{config/skills → optional-skills}/code-review-standards/SKILL.md +4 -12
- package/{config/skills → optional-skills}/root-cause-analysis/SKILL.md +4 -12
- package/{config/skills → optional-skills}/ui-implementation-standards/SKILL.md +4 -14
- package/package.json +1 -57
- package/benchmark/auto-resolve/BENCHMARK-DESIGN.md +0 -289
- package/benchmark/auto-resolve/BENCHMARK-RESULTS.md +0 -341
- package/benchmark/auto-resolve/README.md +0 -696
- package/benchmark/auto-resolve/RUBRIC.md +0 -177
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/NOTES.md +0 -34
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/expected.json +0 -68
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/setup.sh +0 -4
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/spec.md +0 -44
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.ko.txt +0 -8
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.txt +0 -8
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/NOTES.md +0 -68
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/expected.json +0 -60
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/setup.sh +0 -17
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/spec.md +0 -51
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/invalid.js +0 -29
- package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/parallel.js +0 -50
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/NOTES.md +0 -75
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/expected.json +0 -52
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/setup.sh +0 -171
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/spec.md +0 -50
- package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/NOTES.md +0 -89
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/expected.json +0 -74
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/setup.sh +0 -251
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/spec.md +0 -57
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/task.txt +0 -13
- package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/verifiers/replay-malformed-body.js +0 -64
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/NOTES.md +0 -104
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/expected.json +0 -46
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/setup.sh +0 -336
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/spec.md +0 -51
- package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/NOTES.md +0 -38
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/expected.json +0 -64
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/setup.sh +0 -32
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/spec.md +0 -63
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/exact-success.js +0 -54
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/no-hardcoded-pricing.js +0 -47
- package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/stock-error.js +0 -45
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/NOTES.md +0 -57
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected-pair-plan-registry.json +0 -170
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected.json +0 -84
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/metadata.json +0 -21
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-fail.json +0 -214
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-pass.json +0 -223
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/setup.sh +0 -5
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/spec.md +0 -55
- package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/task.txt +0 -14
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/NOTES.md +0 -39
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/expected.json +0 -62
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/spec.md +0 -67
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/error-order.js +0 -55
- package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/priority-blocked.js +0 -48
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/NOTES.md +0 -35
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/expected.json +0 -56
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/spec.md +0 -64
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/conflicting-duplicate.js +0 -34
- package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/idempotent-close.js +0 -41
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/NOTES.md +0 -39
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/expected.json +0 -56
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/spec.md +0 -76
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/priority-rollback.js +0 -64
- package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/single-warehouse-fefo.js +0 -66
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/NOTES.md +0 -40
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/expected.json +0 -66
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/setup.sh +0 -36
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/spec.md +0 -71
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/catalog-source.js +0 -57
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/exact-success.js +0 -63
- package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/stock-error.js +0 -34
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/NOTES.md +0 -31
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/expected.json +0 -68
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/setup.sh +0 -17
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/spec.md +0 -68
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/conflicting-duplicate.js +0 -29
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/exact-payout.js +0 -58
- package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/rules-source.js +0 -56
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/NOTES.md +0 -35
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected-pair-plan-registry.json +0 -162
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected.json +0 -67
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/metadata.json +0 -19
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/setup.sh +0 -4
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/spec.md +0 -55
- package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/NOTES.md +0 -34
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/expected.json +0 -57
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/spec.md +0 -67
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/duplicate-event-error.js +0 -35
- package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/priority-transfer-rollback.js +0 -53
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/NOTES.md +0 -38
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/expected.json +0 -57
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/spec.md +0 -70
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/task.txt +0 -3
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/duplicate-renewal-error.js +0 -42
- package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/priority-credit-rollback.js +0 -70
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/NOTES.md +0 -47
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/expected.json +0 -57
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/setup.sh +0 -6
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/spec.md +0 -48
- package/benchmark/auto-resolve/fixtures/F4-web-browser-design/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/NOTES.md +0 -45
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/expected.json +0 -65
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/setup.sh +0 -55
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/spec.md +0 -48
- package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/NOTES.md +0 -43
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/expected.json +0 -77
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/setup.sh +0 -4
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/spec.md +0 -48
- package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/task.txt +0 -10
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/NOTES.md +0 -57
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/expected.json +0 -76
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/setup.sh +0 -36
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/spec.md +0 -45
- package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/NOTES.md +0 -53
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/expected.json +0 -63
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/setup.sh +0 -4
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/spec.md +0 -48
- package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/task.txt +0 -1
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/NOTES.md +0 -105
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/expected.json +0 -74
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/setup.sh +0 -28
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/spec.md +0 -59
- package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/task.txt +0 -5
- package/benchmark/auto-resolve/fixtures/SCHEMA.md +0 -188
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/NOTES.md +0 -37
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/RETIRED.md +0 -13
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/expected.json +0 -56
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/setup.sh +0 -18
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/spec.md +0 -69
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/task.txt +0 -7
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/exact-proration.js +0 -48
- package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/rules-source-and-conflict.js +0 -79
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/NOTES.md +0 -54
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/RETIRED.md +0 -7
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/expected.json +0 -67
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/spec.md +0 -67
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/task.txt +0 -5
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/policy-precedence.js +0 -72
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-and-immutability.js +0 -43
- package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-boundary.js +0 -116
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/NOTES.md +0 -35
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/RETIRED.md +0 -12
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/expected.json +0 -58
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/setup.sh +0 -2
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/spec.md +0 -73
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/task.txt +0 -17
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/mixed-idempotent-settlement.js +0 -53
- package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/rejection-boundaries.js +0 -74
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/NOTES.md +0 -28
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/RETIRED.md +0 -15
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/expected.json +0 -57
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/setup.sh +0 -50
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/spec.md +0 -59
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/ordered-settlement.js +0 -88
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/reject-invalid.js +0 -45
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/NOTES.md +0 -30
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/RETIRED.md +0 -16
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/expected.json +0 -64
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/setup.sh +0 -21
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/spec.md +0 -58
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/dup-op.js +0 -54
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/priority-apply.js +0 -82
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/rollback.js +0 -77
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/NOTES.md +0 -99
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/RETIRED.md +0 -18
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/expected.json +0 -64
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/setup.sh +0 -4
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/spec.md +0 -61
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/correctness-small.js +0 -135
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/scale.js +0 -100
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/validation.js +0 -75
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/NOTES.md +0 -93
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/RETIRED.md +0 -16
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/expected.json +0 -65
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/setup.sh +0 -18
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/spec.md +0 -66
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/task.txt +0 -9
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/correctness-small.js +0 -84
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/scale.js +0 -184
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/validation.js +0 -74
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/NOTES.md +0 -60
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/RETIRED.md +0 -29
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/expected.json +0 -73
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/metadata.json +0 -10
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/setup.sh +0 -28
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/spec.md +0 -58
- package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/task.txt +0 -5
- package/benchmark/auto-resolve/fixtures/test-repo/README.md +0 -12
- package/benchmark/auto-resolve/fixtures/test-repo/bin/cli.js +0 -63
- package/benchmark/auto-resolve/fixtures/test-repo/package-lock.json +0 -823
- package/benchmark/auto-resolve/fixtures/test-repo/package.json +0 -22
- package/benchmark/auto-resolve/fixtures/test-repo/playwright.config.js +0 -17
- package/benchmark/auto-resolve/fixtures/test-repo/server/index.js +0 -37
- package/benchmark/auto-resolve/fixtures/test-repo/tests/cli.test.js +0 -25
- package/benchmark/auto-resolve/fixtures/test-repo/tests/server.test.js +0 -58
- package/benchmark/auto-resolve/fixtures/test-repo/web/index.html +0 -37
- package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.json +0 -25
- package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.md +0 -10
- package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.json +0 -18
- package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.md +0 -9
- package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.json +0 -18
- package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.md +0 -9
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F16-cli-quote-tax-rules/l2_risk_probes/result.json +0 -28
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F23-cli-fulfillment-wave/l2_risk_probes/result.json +0 -28
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F25-cli-cart-promotion-rules/l2_risk_probes/result.json +0 -30
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.json +0 -82
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.md +0 -18
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.json +0 -46
- package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.md +0 -17
- package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/F21-cli-scheduler-priority/l2_risk_probes/result.json +0 -32
- package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.json +0 -44
- package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.md +0 -16
- package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.json +0 -18
- package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.md +0 -9
- package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.json +0 -28
- package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.md +0 -15
- package/benchmark/auto-resolve/run-real-benchmark.md +0 -303
- package/benchmark/auto-resolve/scripts/audit-headroom-rejections.py +0 -441
- package/benchmark/auto-resolve/scripts/audit-pair-evidence.py +0 -1256
- package/benchmark/auto-resolve/scripts/build-pair-eligible-manifest.py +0 -306
- package/benchmark/auto-resolve/scripts/check-f9-artifacts.py +0 -268
- package/benchmark/auto-resolve/scripts/collect-swebench-predictions.py +0 -108
- package/benchmark/auto-resolve/scripts/compile-report.py +0 -493
- package/benchmark/auto-resolve/scripts/fetch-swebench-instances.py +0 -129
- package/benchmark/auto-resolve/scripts/frozen-verify-gate.py +0 -434
- package/benchmark/auto-resolve/scripts/full-pipeline-pair-gate.py +0 -612
- package/benchmark/auto-resolve/scripts/headroom-gate.py +0 -378
- package/benchmark/auto-resolve/scripts/iter-0033c-compare.py +0 -683
- package/benchmark/auto-resolve/scripts/iter-0033c-l1-summary.py +0 -97
- package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +0 -542
- package/benchmark/auto-resolve/scripts/judge.sh +0 -565
- package/benchmark/auto-resolve/scripts/oracle-scope-tier-a.py +0 -256
- package/benchmark/auto-resolve/scripts/oracle-scope-tier-b.py +0 -287
- package/benchmark/auto-resolve/scripts/oracle-test-fidelity.py +0 -328
- package/benchmark/auto-resolve/scripts/pair-candidate-frontier.py +0 -469
- package/benchmark/auto-resolve/scripts/pair-plan-idgen.py +0 -401
- package/benchmark/auto-resolve/scripts/pair-plan-lint.py +0 -475
- package/benchmark/auto-resolve/scripts/pair-rejected-fixtures.sh +0 -103
- package/benchmark/auto-resolve/scripts/pair_evidence_contract.py +0 -270
- package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-case.py +0 -273
- package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-corpus.py +0 -148
- package/benchmark/auto-resolve/scripts/prepare-swebench-solver-worktree.py +0 -210
- package/benchmark/auto-resolve/scripts/recent-benchmark-summary.py +0 -232
- package/benchmark/auto-resolve/scripts/run-fixture.sh +0 -1024
- package/benchmark/auto-resolve/scripts/run-frozen-verify-pair.sh +0 -683
- package/benchmark/auto-resolve/scripts/run-full-pipeline-pair-candidate.sh +0 -458
- package/benchmark/auto-resolve/scripts/run-headroom-candidate.sh +0 -336
- package/benchmark/auto-resolve/scripts/run-iter-0033c.sh +0 -208
- package/benchmark/auto-resolve/scripts/run-suite.sh +0 -251
- package/benchmark/auto-resolve/scripts/run-swebench-frozen-corpus.sh +0 -310
- package/benchmark/auto-resolve/scripts/run-swebench-solver-batch.sh +0 -257
- package/benchmark/auto-resolve/scripts/ship-gate.py +0 -391
- package/benchmark/auto-resolve/scripts/solo-ceiling-avoidance.py +0 -53
- package/benchmark/auto-resolve/scripts/solo-headroom-hypothesis.py +0 -77
- package/benchmark/auto-resolve/scripts/swebench-frozen-matrix.py +0 -478
- package/benchmark/auto-resolve/scripts/test-audit-headroom-rejections.sh +0 -288
- package/benchmark/auto-resolve/scripts/test-audit-pair-evidence.sh +0 -1672
- package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +0 -1015
- package/benchmark/auto-resolve/scripts/test-build-pair-eligible-manifest.sh +0 -491
- package/benchmark/auto-resolve/scripts/test-check-f9-artifacts.sh +0 -91
- package/benchmark/auto-resolve/scripts/test-frozen-verify-gate.sh +0 -517
- package/benchmark/auto-resolve/scripts/test-full-pipeline-pair-gate.sh +0 -610
- package/benchmark/auto-resolve/scripts/test-headroom-gate.sh +0 -401
- package/benchmark/auto-resolve/scripts/test-iter-0033c-compare.sh +0 -525
- package/benchmark/auto-resolve/scripts/test-iter-0033c-l1-summary.sh +0 -254
- package/benchmark/auto-resolve/scripts/test-lint-fixtures.sh +0 -580
- package/benchmark/auto-resolve/scripts/test-pair-candidate-frontier.sh +0 -591
- package/benchmark/auto-resolve/scripts/test-run-full-pipeline-pair-candidate.sh +0 -497
- package/benchmark/auto-resolve/scripts/test-run-headroom-candidate.sh +0 -401
- package/benchmark/auto-resolve/scripts/test-run-swebench-solver-batch.sh +0 -111
- package/benchmark/auto-resolve/scripts/test-ship-gate.sh +0 -1189
- package/benchmark/auto-resolve/scripts/test-swebench-frozen-case.sh +0 -1221
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/NOTES.md +0 -28
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/expected.json +0 -63
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/spec.md +0 -47
- package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/NOTES.md +0 -34
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/expected.json +0 -53
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/spec.md +0 -50
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/duplicate-order-error.js +0 -27
- package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/priority-stock-reservation.js +0 -44
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/NOTES.md +0 -34
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/expected.json +0 -55
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/spec.md +0 -52
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/duplicate-ticket-error.js +0 -29
- package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/priority-agent-assignment.js +0 -48
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/NOTES.md +0 -34
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/expected.json +0 -55
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/spec.md +0 -55
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/duplicate-return-error.js +0 -43
- package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/priority-return-routing.js +0 -70
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/NOTES.md +0 -37
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/expected.json +0 -54
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/spec.md +0 -59
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/credit-ledger-priority.js +0 -98
- package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/duplicate-charge-error.js +0 -38
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/NOTES.md +0 -36
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/expected.json +0 -56
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/metadata.json +0 -10
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/setup.sh +0 -3
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/spec.md +0 -59
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/task.txt +0 -1
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/duplicate-refund-error.js +0 -41
- package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/priority-refund-ledger.js +0 -65
- package/config/skills/_shared/pair-plan-schema.md +0 -298
- package/scripts/lint-fixtures.sh +0 -352
- package/scripts/lint-shadow-fixtures.sh +0 -58
- package/scripts/lint-skills.sh +0 -4265
- package/scripts/test-owner-phases.py +0 -238
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Build the iter-0033c pair-eligible manifest (Codex R0/R0.5 + R0-infra/R0.5-infra).
|
|
3
|
-
|
|
4
|
-
Manifest captures the immutable Gate-3 input to iter-0033c-compare.py:
|
|
5
|
-
- which fixtures are pair-eligible (high-value ∪ L1≤L0 ∪ F9-if-iter-0033a-passed)
|
|
6
|
-
- what the Gate-3 threshold count is
|
|
7
|
-
- sha256 over the canonical document so any post-write tampering is detectable
|
|
8
|
-
|
|
9
|
-
Hashing pattern is the pre-stamp form lifted from
|
|
10
|
-
benchmark/auto-resolve/scripts/pair-plan-lint.py:81-91 — deep-copy the manifest,
|
|
11
|
-
zero out `manifest_sha256`, serialize with `sort_keys=True, separators=(",",":"),
|
|
12
|
-
ensure_ascii=False, allow_nan=False`, then sha256 the bytes.
|
|
13
|
-
|
|
14
|
-
Inputs (all required):
|
|
15
|
-
--c1-summary <path> iter-0033 (C1) summary.json (selection grounds; never a comparison baseline)
|
|
16
|
-
--f9-judge <path> iter-0033a F9 judge.json (F9 inclusion proof)
|
|
17
|
-
--l1-rerun-summary <path> L1 rerun summary archived for provenance, not selection
|
|
18
|
-
--output <path> destination .devlyn/manifests/iter-0033c-pair-eligible.json
|
|
19
|
-
|
|
20
|
-
Selection rule (frozen pre-registration, iter-0033c §"Pair-eligible fixture set"):
|
|
21
|
-
high_value = {F2, F3, F4, F6, F7}
|
|
22
|
-
promoted_by_l1_le_l0 = {f ∈ C1 summary | solo_claude.score ≤ bare.score}
|
|
23
|
-
conditional_excluded = {F1, F5} # promoted only if L1≤L0
|
|
24
|
-
reporting_only = {F8} # excluded from Gate 3
|
|
25
|
-
pair_eligible = high_value ∪ promoted_by_l1_le_l0 ∪ {F9 if iter-0033a passed}
|
|
26
|
-
− reporting_only
|
|
27
|
-
− conditional_excluded that did not get promoted
|
|
28
|
-
− current rejected/ceiling registry
|
|
29
|
-
"""
|
|
30
|
-
import argparse
|
|
31
|
-
import copy
|
|
32
|
-
import hashlib
|
|
33
|
-
import json
|
|
34
|
-
import re
|
|
35
|
-
import subprocess
|
|
36
|
-
import sys
|
|
37
|
-
from pathlib import Path
|
|
38
|
-
|
|
39
|
-
SCRIPT_DIR = Path(__file__).resolve().parent
|
|
40
|
-
if str(SCRIPT_DIR) not in sys.path:
|
|
41
|
-
sys.path.insert(0, str(SCRIPT_DIR))
|
|
42
|
-
|
|
43
|
-
from pair_evidence_contract import is_score, reject_json_constant
|
|
44
|
-
|
|
45
|
-
HIGH_VALUE = ["F2", "F3", "F4", "F6", "F7"]
|
|
46
|
-
CONDITIONAL = ["F1", "F5"]
|
|
47
|
-
REPORTING_ONLY = ["F8"]
|
|
48
|
-
REJECTED_REGISTRY = Path(__file__).with_name("pair-rejected-fixtures.sh")
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def exact_bool(value: object) -> bool | None:
|
|
52
|
-
return value if isinstance(value, bool) else None
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def disqualifier_flag(value: object, *, default: bool = False) -> bool:
|
|
56
|
-
if value is None:
|
|
57
|
-
return default
|
|
58
|
-
parsed = exact_bool(value)
|
|
59
|
-
return parsed if parsed is not None else True
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def file_sha256(path: Path) -> str:
|
|
63
|
-
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def canonical_manifest_sha256(manifest: dict) -> str:
|
|
67
|
-
"""Pre-stamp hash per pair-plan-lint.py:81-91 — zero out the stamp, then sha256."""
|
|
68
|
-
pre = copy.deepcopy(manifest)
|
|
69
|
-
pre["manifest_sha256"] = ""
|
|
70
|
-
s = json.dumps(
|
|
71
|
-
pre,
|
|
72
|
-
sort_keys=True,
|
|
73
|
-
separators=(",", ":"),
|
|
74
|
-
ensure_ascii=False,
|
|
75
|
-
allow_nan=False,
|
|
76
|
-
)
|
|
77
|
-
return hashlib.sha256(s.encode("utf-8")).hexdigest()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def fixture_short_id(full: str) -> str:
|
|
81
|
-
"""'F3-backend-contract-risk' -> 'F3'. Pure prefix; matches existing convention."""
|
|
82
|
-
return full.split("-", 1)[0] if "-" in full else full
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def load_rejected_fixture_reasons(path: Path) -> dict[str, str]:
|
|
86
|
-
if not path.is_file():
|
|
87
|
-
raise ValueError(f"rejected fixture registry not found: {path}")
|
|
88
|
-
rejected: dict[str, str] = {}
|
|
89
|
-
current: str | None = None
|
|
90
|
-
for line in path.read_text().splitlines():
|
|
91
|
-
match = re.match(r"\s*([FS]\d+)-\*\|([FS]\d+)\)", line)
|
|
92
|
-
if match and match.group(1) == match.group(2):
|
|
93
|
-
current = match.group(1)
|
|
94
|
-
continue
|
|
95
|
-
reason = re.match(r'\s*echo "([^"]+)"', line)
|
|
96
|
-
if current and reason:
|
|
97
|
-
rejected[current] = reason.group(1)
|
|
98
|
-
current = None
|
|
99
|
-
return dict(sorted(rejected.items(), key=lambda item: (item[0][0], int(item[0][1:]))))
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def load_rejected_short_ids(path: Path) -> list[str]:
|
|
103
|
-
return list(load_rejected_fixture_reasons(path))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def load_json_object(path: Path, label: str) -> dict:
|
|
107
|
-
try:
|
|
108
|
-
data = json.loads(path.read_text(), parse_constant=reject_json_constant)
|
|
109
|
-
except (ValueError, json.JSONDecodeError) as exc:
|
|
110
|
-
raise ValueError(f"{label} malformed: invalid JSON") from exc
|
|
111
|
-
if not isinstance(data, dict):
|
|
112
|
-
raise ValueError(f"{label} malformed: expected object")
|
|
113
|
-
return data
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def compute_promoted_l1_le_l0(c1_rows: list) -> list:
|
|
117
|
-
"""Return short fixture IDs (e.g. 'F3') where solo_claude.score ≤ bare.score in C1."""
|
|
118
|
-
promoted = []
|
|
119
|
-
for row in c1_rows:
|
|
120
|
-
if not isinstance(row, dict):
|
|
121
|
-
continue
|
|
122
|
-
raw_arms = row.get("arms")
|
|
123
|
-
arms = raw_arms if isinstance(raw_arms, dict) else {}
|
|
124
|
-
raw_solo = arms.get("solo_claude")
|
|
125
|
-
raw_bare = arms.get("bare")
|
|
126
|
-
solo_arm = raw_solo if isinstance(raw_solo, dict) else {}
|
|
127
|
-
bare_arm = raw_bare if isinstance(raw_bare, dict) else {}
|
|
128
|
-
if (
|
|
129
|
-
disqualifier_flag(solo_arm.get("disqualifier"))
|
|
130
|
-
or disqualifier_flag(bare_arm.get("disqualifier"))
|
|
131
|
-
):
|
|
132
|
-
continue
|
|
133
|
-
solo = solo_arm.get("score")
|
|
134
|
-
bare = bare_arm.get("score")
|
|
135
|
-
if not is_score(solo) or not is_score(bare):
|
|
136
|
-
continue
|
|
137
|
-
if solo <= bare:
|
|
138
|
-
fixture = row.get("fixture")
|
|
139
|
-
if isinstance(fixture, str):
|
|
140
|
-
promoted.append(fixture_short_id(fixture))
|
|
141
|
-
return promoted
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def mapped_score(judge: dict, arm: str) -> int | None:
|
|
145
|
-
mapping = judge.get("_blind_mapping")
|
|
146
|
-
if not isinstance(mapping, dict):
|
|
147
|
-
return None
|
|
148
|
-
letter = next((slot for slot, mapped in mapping.items() if mapped == arm), None)
|
|
149
|
-
if letter is None:
|
|
150
|
-
return None
|
|
151
|
-
raw_scores = judge.get("scores_by_arm")
|
|
152
|
-
scores = raw_scores if isinstance(raw_scores, dict) else {}
|
|
153
|
-
score = scores.get(arm)
|
|
154
|
-
if is_score(score):
|
|
155
|
-
return score
|
|
156
|
-
legacy = judge.get(f"{letter.lower()}_score")
|
|
157
|
-
return legacy if is_score(legacy) else None
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def mapped_disqualifier(judge: dict, arm: str) -> bool:
|
|
161
|
-
mapping = judge.get("_blind_mapping")
|
|
162
|
-
if not isinstance(mapping, dict):
|
|
163
|
-
return True
|
|
164
|
-
letter = next((slot for slot, mapped in mapping.items() if mapped == arm), None)
|
|
165
|
-
if letter is None:
|
|
166
|
-
return True
|
|
167
|
-
raw_by_arm = judge.get("disqualifiers_by_arm")
|
|
168
|
-
if raw_by_arm is not None and not isinstance(raw_by_arm, dict):
|
|
169
|
-
return True
|
|
170
|
-
by_arm = raw_by_arm if isinstance(raw_by_arm, dict) else {}
|
|
171
|
-
if arm in by_arm:
|
|
172
|
-
entry = by_arm.get(arm)
|
|
173
|
-
return disqualifier_flag(
|
|
174
|
-
entry.get("disqualifier") if isinstance(entry, dict) else entry
|
|
175
|
-
)
|
|
176
|
-
raw_legacy = judge.get("disqualifiers")
|
|
177
|
-
if raw_legacy is not None and not isinstance(raw_legacy, dict):
|
|
178
|
-
return True
|
|
179
|
-
legacy = raw_legacy if isinstance(raw_legacy, dict) else {}
|
|
180
|
-
return disqualifier_flag(legacy.get(letter))
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def f9_passed(f9_judge: dict) -> bool:
|
|
184
|
-
"""iter-0033a passed iff solo_claude beats bare and solo is not disqualified."""
|
|
185
|
-
solo = mapped_score(f9_judge, "solo_claude")
|
|
186
|
-
bare = mapped_score(f9_judge, "bare")
|
|
187
|
-
if solo is None or bare is None:
|
|
188
|
-
return False
|
|
189
|
-
return solo > bare and not mapped_disqualifier(f9_judge, "solo_claude")
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def head_sha() -> str:
|
|
193
|
-
try:
|
|
194
|
-
out = subprocess.check_output(
|
|
195
|
-
["git", "rev-parse", "HEAD"], stderr=subprocess.DEVNULL
|
|
196
|
-
)
|
|
197
|
-
return out.decode().strip()
|
|
198
|
-
except Exception:
|
|
199
|
-
return ""
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def main() -> int:
|
|
203
|
-
ap = argparse.ArgumentParser()
|
|
204
|
-
ap.add_argument("--c1-summary", required=True)
|
|
205
|
-
ap.add_argument("--f9-judge", required=True)
|
|
206
|
-
ap.add_argument("--l1-rerun-summary", required=True)
|
|
207
|
-
ap.add_argument("--output", required=True)
|
|
208
|
-
args = ap.parse_args()
|
|
209
|
-
|
|
210
|
-
c1_path = Path(args.c1_summary)
|
|
211
|
-
f9_path = Path(args.f9_judge)
|
|
212
|
-
l1_path = Path(args.l1_rerun_summary)
|
|
213
|
-
out_path = Path(args.output)
|
|
214
|
-
|
|
215
|
-
for p, label in [(c1_path, "c1-summary"), (f9_path, "f9-judge"), (l1_path, "l1-rerun-summary")]:
|
|
216
|
-
if not p.is_file():
|
|
217
|
-
print(f"error: {label} not found: {p}", file=sys.stderr)
|
|
218
|
-
return 2
|
|
219
|
-
|
|
220
|
-
try:
|
|
221
|
-
c1 = load_json_object(c1_path, "c1-summary")
|
|
222
|
-
f9 = load_json_object(f9_path, "f9-judge")
|
|
223
|
-
rejected_reasons = load_rejected_fixture_reasons(REJECTED_REGISTRY)
|
|
224
|
-
rejected_short_ids = list(rejected_reasons)
|
|
225
|
-
except ValueError as exc:
|
|
226
|
-
print(f"error: {exc}", file=sys.stderr)
|
|
227
|
-
return 2
|
|
228
|
-
|
|
229
|
-
c1_rows = c1.get("rows")
|
|
230
|
-
if not isinstance(c1_rows, list):
|
|
231
|
-
print("error: c1-summary malformed: rows must be an array", file=sys.stderr)
|
|
232
|
-
return 2
|
|
233
|
-
|
|
234
|
-
promoted = compute_promoted_l1_le_l0(c1_rows)
|
|
235
|
-
f9_in = f9_passed(f9)
|
|
236
|
-
|
|
237
|
-
pair_eligible = list(HIGH_VALUE) # frozen high-value list, ordered
|
|
238
|
-
for fx in promoted:
|
|
239
|
-
if fx not in pair_eligible and fx not in REPORTING_ONLY:
|
|
240
|
-
pair_eligible.append(fx)
|
|
241
|
-
if f9_in and "F9" not in pair_eligible:
|
|
242
|
-
pair_eligible.append("F9")
|
|
243
|
-
pair_eligible = [fx for fx in pair_eligible if fx not in REPORTING_ONLY]
|
|
244
|
-
rejected_excluded = sorted(
|
|
245
|
-
{fx for fx in pair_eligible if fx in rejected_short_ids},
|
|
246
|
-
key=lambda s: (s[0], int(s[1:])),
|
|
247
|
-
)
|
|
248
|
-
pair_eligible = [fx for fx in pair_eligible if fx not in rejected_short_ids]
|
|
249
|
-
|
|
250
|
-
conditional_promoted = [fx for fx in CONDITIONAL if fx in promoted]
|
|
251
|
-
conditional_excluded = [fx for fx in CONDITIONAL if fx not in promoted]
|
|
252
|
-
pair_eligible_sorted = sorted(pair_eligible, key=lambda s: (s[0], int(s[1:])))
|
|
253
|
-
if not pair_eligible_sorted:
|
|
254
|
-
rejected_text = ", ".join(rejected_excluded) if rejected_excluded else "none"
|
|
255
|
-
print(
|
|
256
|
-
"error: no pair-eligible fixtures remain after rejected-registry filtering "
|
|
257
|
-
f"(rejected_excluded={rejected_text})",
|
|
258
|
-
file=sys.stderr,
|
|
259
|
-
)
|
|
260
|
-
return 1
|
|
261
|
-
|
|
262
|
-
gate3_total = len(pair_eligible_sorted)
|
|
263
|
-
gate3_threshold = (gate3_total + 1) // 2 # ≥50% — ceil(gate3_total / 2)
|
|
264
|
-
|
|
265
|
-
manifest = {
|
|
266
|
-
"schema_version": "1.0",
|
|
267
|
-
"iter": "0033c",
|
|
268
|
-
"head": head_sha(),
|
|
269
|
-
"sources": {
|
|
270
|
-
"c1_summary": {"path": str(c1_path), "sha256": file_sha256(c1_path)},
|
|
271
|
-
"f9_judge": {"path": str(f9_path), "sha256": file_sha256(f9_path)},
|
|
272
|
-
"l1_rerun_summary": {"path": str(l1_path), "sha256": file_sha256(l1_path)},
|
|
273
|
-
},
|
|
274
|
-
"selection_rule": {
|
|
275
|
-
"high_value": HIGH_VALUE,
|
|
276
|
-
"promoted_by_l1_le_l0": sorted(set(promoted)),
|
|
277
|
-
"f9_included": f9_in,
|
|
278
|
-
"f9_passed_iter_0033a": f9_in,
|
|
279
|
-
"reporting_only": REPORTING_ONLY,
|
|
280
|
-
"conditional_excluded": conditional_excluded,
|
|
281
|
-
"conditional_promoted": conditional_promoted,
|
|
282
|
-
"rejected_registry": str(REJECTED_REGISTRY),
|
|
283
|
-
"rejected_excluded": rejected_excluded,
|
|
284
|
-
"rejected_excluded_reasons": {
|
|
285
|
-
fixture: rejected_reasons[fixture] for fixture in rejected_excluded
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
"fixtures_pair_eligible": pair_eligible_sorted,
|
|
289
|
-
"gate3_threshold_count": gate3_threshold,
|
|
290
|
-
"gate3_total": gate3_total,
|
|
291
|
-
"manifest_sha256": "",
|
|
292
|
-
}
|
|
293
|
-
manifest["manifest_sha256"] = canonical_manifest_sha256(manifest)
|
|
294
|
-
|
|
295
|
-
out_path.parent.mkdir(parents=True, exist_ok=True)
|
|
296
|
-
out_path.write_text(json.dumps(manifest, indent=2) + "\n")
|
|
297
|
-
|
|
298
|
-
print(f"[manifest] wrote {out_path}")
|
|
299
|
-
print(f"[manifest] pair-eligible: {pair_eligible_sorted} "
|
|
300
|
-
f"(gate3 ≥ {gate3_threshold} / {gate3_total})")
|
|
301
|
-
print(f"[manifest] sha256: {manifest['manifest_sha256']}")
|
|
302
|
-
return 0
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if __name__ == "__main__":
|
|
306
|
-
sys.exit(main())
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""F9 skill-driven arm artifact + transcript fingerprint check.
|
|
3
|
-
|
|
4
|
-
Out-of-band per Codex R0.5 §B (iter-0033a): expected.json.verification_commands
|
|
5
|
-
apply to ALL arms (run-fixture.sh:472), so a `docs/specs/**` check there would
|
|
6
|
-
punish bare. This script runs AFTER run-fixture.sh and asserts skill-driven
|
|
7
|
-
arms produced the artifacts the 2-skill ideate→resolve chain should emit.
|
|
8
|
-
|
|
9
|
-
Bare arm is exempt by construction.
|
|
10
|
-
|
|
11
|
-
Usage:
|
|
12
|
-
check-f9-artifacts.py --result-dir <results/<run_id>/F9-e2e-ideate-to-resolve/<arm>>
|
|
13
|
-
|
|
14
|
-
Exits:
|
|
15
|
-
0 — all checks pass (or bare arm — exempt).
|
|
16
|
-
1 — skill-driven arm but artifact contract violated.
|
|
17
|
-
2 — invalid invocation (missing args, missing dir).
|
|
18
|
-
|
|
19
|
-
Emits a small JSON report at <result-dir>/check-f9-artifacts.json.
|
|
20
|
-
"""
|
|
21
|
-
import argparse
|
|
22
|
-
import json
|
|
23
|
-
import os
|
|
24
|
-
import re
|
|
25
|
-
import sys
|
|
26
|
-
from pathlib import Path
|
|
27
|
-
|
|
28
|
-
from pair_evidence_contract import loads_strict_json_object
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
SKILL_DRIVEN_ARMS = {"variant", "solo_claude", "l2_gated", "l2_risk_probes", "l2_forced"}
|
|
32
|
-
EXEMPT_ARMS = {"bare"}
|
|
33
|
-
|
|
34
|
-
SPEC_DIR_GLOB = "docs/specs/*/spec.md"
|
|
35
|
-
SPEC_EXPECTED_GLOB = "docs/specs/*/spec.expected.json"
|
|
36
|
-
|
|
37
|
-
# Transcript fingerprint regexes (negative checks only — `claude -p`
|
|
38
|
-
# transcript captures only the agent's final reply, not intermediate
|
|
39
|
-
# tool calls; positive resolve invocation evidence lives in state).
|
|
40
|
-
RE_AUTO_RESOLVE = re.compile(r"/devlyn:auto-resolve\b")
|
|
41
|
-
RE_PREFLIGHT = re.compile(r"/devlyn:preflight\b")
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def _load_json_object(path: Path) -> tuple[dict | None, str | None]:
|
|
45
|
-
try:
|
|
46
|
-
data = loads_strict_json_object(path.read_text())
|
|
47
|
-
except json.JSONDecodeError as exc:
|
|
48
|
-
return None, f"{exc.__class__.__name__}: {exc}"
|
|
49
|
-
except ValueError as exc:
|
|
50
|
-
if str(exc) == "top-level JSON value must be an object":
|
|
51
|
-
return None, "expected JSON object"
|
|
52
|
-
return None, f"{exc.__class__.__name__}: {exc}"
|
|
53
|
-
return data, None
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def main() -> int:
|
|
57
|
-
p = argparse.ArgumentParser(description=__doc__.split("\n", 1)[0])
|
|
58
|
-
p.add_argument("--result-dir", required=True,
|
|
59
|
-
help="Path to results/<run_id>/<fixture>/<arm>/")
|
|
60
|
-
args = p.parse_args()
|
|
61
|
-
|
|
62
|
-
result_dir = Path(args.result_dir)
|
|
63
|
-
if not result_dir.is_dir():
|
|
64
|
-
print(f"error: result dir not found: {result_dir}", file=sys.stderr)
|
|
65
|
-
return 2
|
|
66
|
-
|
|
67
|
-
arm = result_dir.name
|
|
68
|
-
fixture = result_dir.parent.name
|
|
69
|
-
|
|
70
|
-
if fixture != "F9-e2e-ideate-to-resolve":
|
|
71
|
-
print(f"error: this script is F9-only (got fixture={fixture})", file=sys.stderr)
|
|
72
|
-
return 2
|
|
73
|
-
|
|
74
|
-
report = {
|
|
75
|
-
"fixture": fixture,
|
|
76
|
-
"arm": arm,
|
|
77
|
-
"checks": [],
|
|
78
|
-
"exempt": False,
|
|
79
|
-
"pass": True,
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if arm in EXEMPT_ARMS:
|
|
83
|
-
report["exempt"] = True
|
|
84
|
-
report["checks"].append({"name": "arm-is-bare-exempt", "pass": True})
|
|
85
|
-
_write_report(result_dir, report)
|
|
86
|
-
return 0
|
|
87
|
-
|
|
88
|
-
if arm not in SKILL_DRIVEN_ARMS:
|
|
89
|
-
print(f"error: unknown arm '{arm}' (expected one of {SKILL_DRIVEN_ARMS | EXEMPT_ARMS})",
|
|
90
|
-
file=sys.stderr)
|
|
91
|
-
return 2
|
|
92
|
-
|
|
93
|
-
# The fixture's work-dir is referenced from result_dir/timing.json. The
|
|
94
|
-
# arm produced files inside that work-dir; we glob from there.
|
|
95
|
-
timing_path = result_dir / "timing.json"
|
|
96
|
-
work_dir: Path
|
|
97
|
-
if timing_path.is_file():
|
|
98
|
-
timing, _timing_error = _load_json_object(timing_path)
|
|
99
|
-
if timing is not None:
|
|
100
|
-
work_dir = Path(timing.get("work_dir", ""))
|
|
101
|
-
else:
|
|
102
|
-
work_dir = Path("__invalid_timing_work_dir__")
|
|
103
|
-
else:
|
|
104
|
-
work_dir = Path("__missing_timing_work_dir__")
|
|
105
|
-
|
|
106
|
-
if not work_dir.is_dir():
|
|
107
|
-
report["checks"].append({
|
|
108
|
-
"name": "work-dir-resolvable",
|
|
109
|
-
"pass": False,
|
|
110
|
-
"reason": f"work_dir from timing.json not usable: {work_dir!r}",
|
|
111
|
-
})
|
|
112
|
-
report["pass"] = False
|
|
113
|
-
_write_report(result_dir, report)
|
|
114
|
-
return 1
|
|
115
|
-
|
|
116
|
-
# Check 1: docs/specs/<id>-<slug>/spec.md exists.
|
|
117
|
-
specs_root = work_dir / "docs" / "specs"
|
|
118
|
-
spec_md_files = list(specs_root.glob("*/spec.md")) if specs_root.is_dir() else []
|
|
119
|
-
spec_md_present = bool(spec_md_files)
|
|
120
|
-
report["checks"].append({
|
|
121
|
-
"name": "spec.md-exists-under-docs/specs",
|
|
122
|
-
"pass": spec_md_present,
|
|
123
|
-
"matched": [str(p.relative_to(work_dir)) for p in spec_md_files],
|
|
124
|
-
})
|
|
125
|
-
if not spec_md_present:
|
|
126
|
-
report["pass"] = False
|
|
127
|
-
|
|
128
|
-
# Check 2: spec.expected.json exists at the same dir.
|
|
129
|
-
spec_exp_files = list(specs_root.glob("*/spec.expected.json")) if specs_root.is_dir() else []
|
|
130
|
-
spec_exp_present = bool(spec_exp_files)
|
|
131
|
-
report["checks"].append({
|
|
132
|
-
"name": "spec.expected.json-exists-under-docs/specs",
|
|
133
|
-
"pass": spec_exp_present,
|
|
134
|
-
"matched": [str(p.relative_to(work_dir)) for p in spec_exp_files],
|
|
135
|
-
})
|
|
136
|
-
if not spec_exp_present:
|
|
137
|
-
report["pass"] = False
|
|
138
|
-
|
|
139
|
-
# Path-shape regression: the parent dir name should be `<id>-<slug>` shape.
|
|
140
|
-
# Both id and slug are kebab-case, so the dir must contain at least one
|
|
141
|
-
# hyphen. Bare `<id>/spec.md` (no hyphen) is the legacy shape we reject.
|
|
142
|
-
if spec_md_files:
|
|
143
|
-
bad_shapes = [p for p in spec_md_files if "-" not in p.parent.name]
|
|
144
|
-
report["checks"].append({
|
|
145
|
-
"name": "path-shape-id-slug",
|
|
146
|
-
"pass": not bad_shapes,
|
|
147
|
-
"non_conforming": [str(p.relative_to(work_dir)) for p in bad_shapes],
|
|
148
|
-
})
|
|
149
|
-
if bad_shapes:
|
|
150
|
-
report["pass"] = False
|
|
151
|
-
|
|
152
|
-
# Resolve invocation evidence — primary source is pipeline.state.json,
|
|
153
|
-
# NOT transcript.txt. `claude -p` only emits the agent's final reply to
|
|
154
|
-
# stdout; intermediate Skill / Agent / Bash tool calls do not appear in
|
|
155
|
-
# transcript.txt. Therefore "regex /devlyn:resolve --spec in transcript"
|
|
156
|
-
# is the wrong source. The authoritative evidence resolve actually ran
|
|
157
|
-
# in --spec mode is `state.mode == "spec"` plus `state.source.type ==
|
|
158
|
-
# "spec"` plus a populated `state.source.spec_path` pointing under
|
|
159
|
-
# `docs/specs/`. Per state-schema.md this is single-source-of-truth.
|
|
160
|
-
# Look for the archive first (preferred), then fall back to the live
|
|
161
|
-
# in-flight location. NEW resolve currently lands artifacts directly in
|
|
162
|
-
# `.devlyn/` and may skip the move-to-runs/ archive step (TODO: separate
|
|
163
|
-
# iter to fix archive); both locations carry the same authoritative
|
|
164
|
-
# state shape.
|
|
165
|
-
archived_paths = list(work_dir.glob(".devlyn/runs/*/pipeline.state.json"))
|
|
166
|
-
live_path = work_dir / ".devlyn" / "pipeline.state.json"
|
|
167
|
-
state_paths = archived_paths if archived_paths else (
|
|
168
|
-
[live_path] if live_path.is_file() else []
|
|
169
|
-
)
|
|
170
|
-
if not state_paths:
|
|
171
|
-
report["checks"].append({
|
|
172
|
-
"name": "pipeline.state.json-present",
|
|
173
|
-
"pass": False,
|
|
174
|
-
"reason": "neither .devlyn/runs/*/pipeline.state.json nor .devlyn/pipeline.state.json found in work_dir",
|
|
175
|
-
})
|
|
176
|
-
report["pass"] = False
|
|
177
|
-
else:
|
|
178
|
-
# Read the most recent run.
|
|
179
|
-
state_path = sorted(state_paths)[-1]
|
|
180
|
-
state, state_error = _load_json_object(state_path)
|
|
181
|
-
if state is None:
|
|
182
|
-
report["checks"].append({
|
|
183
|
-
"name": "pipeline.state.json-parses",
|
|
184
|
-
"pass": False,
|
|
185
|
-
"reason": state_error,
|
|
186
|
-
})
|
|
187
|
-
report["pass"] = False
|
|
188
|
-
|
|
189
|
-
if state is not None:
|
|
190
|
-
archived = "/runs/" in str(state_path)
|
|
191
|
-
report["checks"].append({
|
|
192
|
-
"name": "pipeline.state.json-present",
|
|
193
|
-
"pass": True,
|
|
194
|
-
"path": str(state_path.relative_to(work_dir)),
|
|
195
|
-
"archived_to_runs_dir": archived,
|
|
196
|
-
})
|
|
197
|
-
if not archived:
|
|
198
|
-
# Not a fail — note for harness developer that NEW resolve
|
|
199
|
-
# is skipping the archive step in this run.
|
|
200
|
-
report["checks"].append({
|
|
201
|
-
"name": "archive-step-completed",
|
|
202
|
-
"pass": True,
|
|
203
|
-
"warning": "NEW resolve left artifacts in .devlyn/ instead of .devlyn/runs/<id>/ — archive step skipped (separate iter for harness fix)",
|
|
204
|
-
})
|
|
205
|
-
mode = state.get("mode")
|
|
206
|
-
src_type = (state.get("source") or {}).get("type")
|
|
207
|
-
spec_path = (state.get("source") or {}).get("spec_path") or ""
|
|
208
|
-
spec_under_specs = spec_path.startswith("docs/specs/") and spec_path.endswith("spec.md")
|
|
209
|
-
mode_ok = mode == "spec"
|
|
210
|
-
src_ok = src_type == "spec"
|
|
211
|
-
report["checks"].append({
|
|
212
|
-
"name": "state.mode-and-source-spec",
|
|
213
|
-
"pass": mode_ok and src_ok and spec_under_specs,
|
|
214
|
-
"mode": mode,
|
|
215
|
-
"source.type": src_type,
|
|
216
|
-
"source.spec_path": spec_path,
|
|
217
|
-
})
|
|
218
|
-
if not (mode_ok and src_ok and spec_under_specs):
|
|
219
|
-
report["pass"] = False
|
|
220
|
-
|
|
221
|
-
# Transcript fingerprint — negative checks only. transcript.txt records
|
|
222
|
-
# the agent's final reply; if the agent (or any subagent) had invoked
|
|
223
|
-
# /devlyn:auto-resolve or /devlyn:preflight, the prompt-following gate
|
|
224
|
-
# should still surface the name in the summary. Positive resolve
|
|
225
|
-
# evidence lives in state above; here we just rule out the deprecated
|
|
226
|
-
# 3-skill chain names.
|
|
227
|
-
transcript_path = result_dir / "transcript.txt"
|
|
228
|
-
if not transcript_path.is_file():
|
|
229
|
-
report["checks"].append({
|
|
230
|
-
"name": "transcript-readable",
|
|
231
|
-
"pass": False,
|
|
232
|
-
"reason": f"transcript.txt missing at {transcript_path}",
|
|
233
|
-
})
|
|
234
|
-
report["pass"] = False
|
|
235
|
-
_write_report(result_dir, report)
|
|
236
|
-
return 1
|
|
237
|
-
|
|
238
|
-
transcript = transcript_path.read_text(errors="replace")
|
|
239
|
-
|
|
240
|
-
auto_resolve_hits = RE_AUTO_RESOLVE.findall(transcript)
|
|
241
|
-
report["checks"].append({
|
|
242
|
-
"name": "transcript-no-auto-resolve",
|
|
243
|
-
"pass": len(auto_resolve_hits) == 0,
|
|
244
|
-
"count": len(auto_resolve_hits),
|
|
245
|
-
})
|
|
246
|
-
if auto_resolve_hits:
|
|
247
|
-
report["pass"] = False
|
|
248
|
-
|
|
249
|
-
preflight_hits = RE_PREFLIGHT.findall(transcript)
|
|
250
|
-
report["checks"].append({
|
|
251
|
-
"name": "transcript-no-preflight",
|
|
252
|
-
"pass": len(preflight_hits) == 0,
|
|
253
|
-
"count": len(preflight_hits),
|
|
254
|
-
})
|
|
255
|
-
if preflight_hits:
|
|
256
|
-
report["pass"] = False
|
|
257
|
-
|
|
258
|
-
_write_report(result_dir, report)
|
|
259
|
-
return 0 if report["pass"] else 1
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
def _write_report(result_dir: Path, report: dict) -> None:
|
|
263
|
-
out_path = result_dir / "check-f9-artifacts.json"
|
|
264
|
-
out_path.write_text(json.dumps(report, indent=2) + "\n")
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if __name__ == "__main__":
|
|
268
|
-
sys.exit(main())
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Collect patch.diff files into SWE-bench prediction JSONL."""
|
|
3
|
-
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
|
-
import argparse
|
|
7
|
-
import json
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
from pair_evidence_contract import reject_json_constant
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def read_jsonl(path: Path) -> list[dict[str, Any]]:
|
|
15
|
-
rows: list[dict[str, Any]] = []
|
|
16
|
-
with path.open(encoding="utf8") as f:
|
|
17
|
-
for line_no, line in enumerate(f, start=1):
|
|
18
|
-
if not line.strip():
|
|
19
|
-
continue
|
|
20
|
-
value = json.loads(line, parse_constant=reject_json_constant)
|
|
21
|
-
if not isinstance(value, dict):
|
|
22
|
-
raise ValueError(f"{path}:{line_no}: expected JSON object")
|
|
23
|
-
rows.append(value)
|
|
24
|
-
return rows
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def instance_ids_from_jsonl(path: Path | None) -> set[str] | None:
|
|
28
|
-
if path is None:
|
|
29
|
-
return None
|
|
30
|
-
ids: set[str] = set()
|
|
31
|
-
for row in read_jsonl(path):
|
|
32
|
-
instance_id = row.get("instance_id")
|
|
33
|
-
if not isinstance(instance_id, str) or not instance_id:
|
|
34
|
-
raise ValueError(f"{path}: row missing non-empty instance_id")
|
|
35
|
-
ids.add(instance_id)
|
|
36
|
-
return ids
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def collect_from_root(root: Path, patch_name: str, keep: set[str] | None) -> list[tuple[str, Path]]:
|
|
40
|
-
patches: list[tuple[str, Path]] = []
|
|
41
|
-
seen: set[str] = set()
|
|
42
|
-
for patch_path in sorted(root.glob(f"*/{patch_name}")):
|
|
43
|
-
instance_id = patch_path.parent.name
|
|
44
|
-
if keep is not None and instance_id not in keep:
|
|
45
|
-
continue
|
|
46
|
-
seen.add(instance_id)
|
|
47
|
-
patches.append((instance_id, patch_path))
|
|
48
|
-
if keep is not None:
|
|
49
|
-
missing = sorted(keep - seen)
|
|
50
|
-
if missing:
|
|
51
|
-
raise ValueError(f"missing {patch_name} for instance ids: {', '.join(missing)}")
|
|
52
|
-
return patches
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def main() -> int:
|
|
56
|
-
parser = argparse.ArgumentParser()
|
|
57
|
-
parser.add_argument("--patch-root", required=True, type=Path)
|
|
58
|
-
parser.add_argument("--patch-name", default="patch.diff")
|
|
59
|
-
parser.add_argument("--instances-jsonl", type=Path, help="Optional filter/validation set.")
|
|
60
|
-
parser.add_argument("--model-name", required=True)
|
|
61
|
-
parser.add_argument("--out", required=True, type=Path)
|
|
62
|
-
parser.add_argument("--allow-empty", action="store_true")
|
|
63
|
-
args = parser.parse_args()
|
|
64
|
-
|
|
65
|
-
keep = instance_ids_from_jsonl(args.instances_jsonl)
|
|
66
|
-
patches = collect_from_root(args.patch_root, args.patch_name, keep)
|
|
67
|
-
if not patches:
|
|
68
|
-
raise ValueError(f"no {args.patch_name} files found under {args.patch_root}")
|
|
69
|
-
|
|
70
|
-
args.out.parent.mkdir(parents=True, exist_ok=True)
|
|
71
|
-
written = 0
|
|
72
|
-
skipped_empty: list[str] = []
|
|
73
|
-
with args.out.open("w", encoding="utf8") as f:
|
|
74
|
-
for instance_id, patch_path in patches:
|
|
75
|
-
patch = patch_path.read_text(encoding="utf8")
|
|
76
|
-
if not patch.strip():
|
|
77
|
-
if args.allow_empty:
|
|
78
|
-
skipped_empty.append(instance_id)
|
|
79
|
-
continue
|
|
80
|
-
raise ValueError(f"empty patch for {instance_id}: {patch_path}")
|
|
81
|
-
f.write(
|
|
82
|
-
json.dumps(
|
|
83
|
-
{
|
|
84
|
-
"instance_id": instance_id,
|
|
85
|
-
"model_name_or_path": args.model_name,
|
|
86
|
-
"model_patch": patch,
|
|
87
|
-
}
|
|
88
|
-
)
|
|
89
|
-
+ "\n"
|
|
90
|
-
)
|
|
91
|
-
written += 1
|
|
92
|
-
if written == 0:
|
|
93
|
-
raise ValueError("no non-empty patches collected")
|
|
94
|
-
|
|
95
|
-
report = {
|
|
96
|
-
"patch_root": str(args.patch_root),
|
|
97
|
-
"patch_name": args.patch_name,
|
|
98
|
-
"model_name_or_path": args.model_name,
|
|
99
|
-
"out": str(args.out),
|
|
100
|
-
"predictions_written": written,
|
|
101
|
-
"empty_skipped": skipped_empty,
|
|
102
|
-
}
|
|
103
|
-
print(json.dumps(report, indent=2))
|
|
104
|
-
return 0
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if __name__ == "__main__":
|
|
108
|
-
raise SystemExit(main())
|