@1aboveio/skills 0.19.2 → 0.20.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.
Files changed (203) hide show
  1. package/README.md +9 -4
  2. package/package.json +1 -1
  3. package/runtime/skills/distribution/generated/recipes.json +54 -48
  4. package/runtime/skills/distribution/scripts/bundles.mjs +113 -7
  5. package/runtime/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -6
  6. package/runtime/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +3 -36
  7. package/skills/cicd-pipeline/mergify/SKILL.md +1 -1
  8. package/skills/engineering/engineering-runtime/coherence/workflow.json +14 -83
  9. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +4 -6
  10. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +3 -36
  11. package/skills/engineering/smoke/SKILL.md +1 -1
  12. package/skills/payment/payment-analysis/SKILL.md +13 -7
  13. package/skills/payment/payment-analysis/references/chargebacks.md +43 -18
  14. package/skills/payment/payment-analysis/references/event-layers.md +4 -0
  15. package/skills/payment/payment-analysis/references/metrics.md +9 -7
  16. package/skills/payment/payment-analysis/references/report-template.md +3 -3
  17. package/skills/payment/payment-analysis/references/terminology.md +6 -1
  18. package/skills/payment/payment-analysis/references/visualization.md +1 -1
  19. package/skills/payment/tld-detection/SKILL.md +163 -0
  20. package/skills/payment/tld-detection/agents/openai.yaml +9 -0
  21. package/skills/payment/tld-detection/evals/evals.json +107 -0
  22. package/skills/payment/tld-detection/references/clean.md +51 -0
  23. package/skills/payment/tld-detection/references/clustering.md +219 -0
  24. package/skills/payment/tld-detection/references/decision.md +85 -0
  25. package/skills/payment/tld-detection/references/report-template.md +169 -0
  26. package/skills/payment/tld-detection/references/terminology.md +69 -0
  27. package/skills/payment/tld-detection/references/workflow.md +78 -0
  28. package/skills/payment/tld-detection/scripts/detect_ladders.py +390 -0
  29. package/skills/payment/tld-detection/tests/test_detect_ladders.py +132 -0
  30. package/skills/engineering/resolve-issues/SKILL.md +0 -168
  31. package/skills/engineering/resolve-issues/agents/openai.yaml +0 -9
  32. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +0 -499
  33. package/skills/engineering/resolve-issues/references/breaker.md +0 -82
  34. package/skills/engineering/resolve-issues/references/deliverables.md +0 -27
  35. package/skills/engineering/resolve-issues/references/delivery.md +0 -108
  36. package/skills/engineering/resolve-issues/references/evidence-lane.md +0 -21
  37. package/skills/engineering/resolve-issues/references/exact-head-ci.md +0 -287
  38. package/skills/engineering/resolve-issues/references/fan-out.md +0 -33
  39. package/skills/engineering/resolve-issues/references/finalization.md +0 -68
  40. package/skills/engineering/resolve-issues/references/guarantees.md +0 -10
  41. package/skills/engineering/resolve-issues/references/high-risk.md +0 -29
  42. package/skills/engineering/resolve-issues/references/incidents/848/README.md +0 -156
  43. package/skills/engineering/resolve-issues/references/intake.md +0 -86
  44. package/skills/engineering/resolve-issues/references/integration-gate.md +0 -53
  45. package/skills/engineering/resolve-issues/references/interference.md +0 -87
  46. package/skills/engineering/resolve-issues/references/loop.md +0 -134
  47. package/skills/engineering/resolve-issues/references/model-catalog.md +0 -9
  48. package/skills/engineering/resolve-issues/references/postmortem.md +0 -27
  49. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +0 -41
  50. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +0 -48
  51. package/skills/engineering/resolve-issues/references/pre-flight.md +0 -41
  52. package/skills/engineering/resolve-issues/references/regression-checklist.md +0 -26
  53. package/skills/engineering/resolve-issues/references/run-state.md +0 -288
  54. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +0 -48
  55. package/skills/engineering/resolve-issues/references/spawn-contract.md +0 -96
  56. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +0 -40
  57. package/skills/engineering/resolve-issues/references/why.md +0 -653
  58. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +0 -49
  59. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +0 -721
  60. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +0 -962
  61. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +0 -220
  62. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +0 -420
  63. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +0 -256
  64. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +0 -168
  65. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +0 -9
  66. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +0 -62
  67. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +0 -191
  68. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +0 -413
  69. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +0 -332
  70. package/skills/engineering/resolve-issues/scripts/finalize.mjs +0 -488
  71. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +0 -3307
  72. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +0 -16
  73. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +0 -51
  74. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +0 -17
  75. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +0 -166
  76. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +0 -92
  77. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +0 -73
  78. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +0 -159
  79. package/skills/engineering/resolve-issues/scripts/interference.mjs +0 -427
  80. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +0 -9
  81. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +0 -419
  82. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +0 -909
  83. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +0 -345
  84. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +0 -415
  85. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +0 -697
  86. package/skills/engineering/resolve-issues/scripts/report.mjs +0 -494
  87. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +0 -172
  88. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +0 -79
  89. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +0 -334
  90. package/skills/engineering/resolve-issues/scripts/run-state.mjs +0 -4792
  91. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +0 -395
  92. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +0 -290
  93. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +0 -170
  94. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +0 -293
  95. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +0 -197
  96. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +0 -127
  97. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +0 -893
  98. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +0 -829
  99. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +0 -290
  100. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +0 -80
  101. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +0 -102
  102. package/skills/engineering/resolve-release/LICENSE +0 -3
  103. package/skills/engineering/resolve-release/SKILL.md +0 -113
  104. package/skills/engineering/resolve-release/agents/openai.yaml +0 -9
  105. package/skills/engineering/resolve-release/references/assembly.md +0 -137
  106. package/skills/engineering/resolve-release/references/auto-when-green.md +0 -56
  107. package/skills/engineering/resolve-release/references/candidate.md +0 -167
  108. package/skills/engineering/resolve-release/references/exposure.md +0 -178
  109. package/skills/engineering/resolve-release/references/handoff.md +0 -24
  110. package/skills/engineering/resolve-release/references/postmortem.md +0 -230
  111. package/skills/engineering/resolve-release/references/preflight.md +0 -208
  112. package/skills/engineering/resolve-release/references/principles.md +0 -94
  113. package/skills/engineering/resolve-release/references/regression-checklist.md +0 -36
  114. package/skills/engineering/resolve-release/references/related-skills.md +0 -13
  115. package/skills/engineering/resolve-release/references/routing.md +0 -149
  116. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +0 -285
  117. package/skills/engineering/resolve-release/references/versioning.md +0 -202
  118. package/skills/engineering/resolve-release/references/why.md +0 -53
  119. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +0 -389
  120. package/skills/engineering/resolve-release/scripts/build-changes.mjs +0 -209
  121. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +0 -407
  122. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +0 -904
  123. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +0 -81
  124. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +0 -612
  125. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +0 -135
  126. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +0 -161
  127. package/skills/engineering/resolve-release/scripts/doctrine.mjs +0 -106
  128. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +0 -522
  129. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +0 -659
  130. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +0 -1014
  131. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +0 -526
  132. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +0 -169
  133. package/skills/engineering/resolve-release/scripts/green-gate.mjs +0 -599
  134. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +0 -752
  135. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +0 -56
  136. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +0 -1538
  137. package/skills/engineering/resolve-release/scripts/postmortem.mjs +0 -381
  138. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +0 -510
  139. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +0 -326
  140. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +0 -272
  141. package/skills/engineering/resolve-release/scripts/report.mjs +0 -417
  142. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +0 -114
  143. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +0 -238
  144. package/skills/engineering/resolve-release/scripts/review-packet.mjs +0 -503
  145. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +0 -263
  146. package/skills/engineering/resolve-release/scripts/version-assert.mjs +0 -339
  147. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +0 -485
  148. package/skills/engineering/resolve-release/scripts/version.mjs +0 -1199
  149. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +0 -449
  150. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +0 -21
  151. package/skills/engineering/resolve-release/vendor/README.md +0 -60
  152. package/skills/engineering/resolve-release/vendor/acorn.mjs +0 -6233
  153. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +0 -21
  154. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +0 -341
  155. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +0 -70
  156. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +0 -2
  157. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +0 -1
  158. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +0 -7
  159. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +0 -1
  160. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +0 -2033
  161. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +0 -2033
  162. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +0 -7
  163. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +0 -1
  164. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +0 -2
  165. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +0 -1
  166. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +0 -2
  167. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +0 -1
  168. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +0 -2
  169. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +0 -1
  170. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +0 -49
  171. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +0 -21
  172. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +0 -5
  173. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +0 -549
  174. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +0 -549
  175. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +0 -2
  176. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +0 -1
  177. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +0 -2
  178. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +0 -1
  179. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +0 -36
  180. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +0 -47
  181. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +0 -82
  182. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +0 -11
  183. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +0 -22
  184. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +0 -21
  185. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +0 -21
  186. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +0 -11
  187. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +0 -11
  188. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +0 -25
  189. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  190. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +0 -85
  191. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +0 -85
  192. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +0 -2
  193. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +0 -1
  194. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +0 -2
  195. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +0 -1
  196. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +0 -20
  197. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +0 -20
  198. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +0 -2
  199. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +0 -1
  200. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +0 -2
  201. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +0 -1
  202. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +0 -61
  203. /package/skills/{engineering/resolve-issues → payment/tld-detection}/LICENSE +0 -0
@@ -1,172 +0,0 @@
1
- import fs from 'node:fs'
2
- import { execFileSync } from 'node:child_process'
3
- import { parseMergifyYaml } from '../../engineering-runtime/scripts/mergify-yaml.mjs'
4
- import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
5
- import { validateRequiredCheckPlan } from '../../engineering-runtime/scripts/required-check-plan.mjs'
6
-
7
- const nonEmpty = (value) => typeof value === 'string' && value.trim().length > 0
8
- const unique = (values) => [...new Set(values.filter(nonEmpty))]
9
-
10
- function structuralConditionTree(value, label) {
11
- if (typeof value === 'string' && value.trim()) return { condition: value.trim() }
12
- if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} must be a condition string or and/or mapping`)
13
- const keys = Object.keys(value)
14
- if (keys.length !== 1 || !['and', 'or'].includes(keys[0])) throw new Error(`${label} has unsupported condition structure`)
15
- const children = value[keys[0]]
16
- if (!Array.isArray(children) || children.length === 0) throw new Error(`${label}.${keys[0]} must be a non-empty array`)
17
- return { [keys[0] === 'and' ? 'all' : 'any']: children.map((child, index) => structuralConditionTree(child, `${label}.${keys[0]}[${index}]`)) }
18
- }
19
-
20
- const MERGIFY_PHASES = {
21
- queue_conditions: { id: 'queue-entry', phase: 'pr-head', source: 'queue_conditions' },
22
- merge_conditions: { id: 'queue-merge', phase: 'queue-head', source: 'merge_conditions' },
23
- auto_merge_conditions: { id: 'auto-enqueue', phase: 'pr-head', source: 'auto_merge_conditions' },
24
- success_conditions: { id: 'merge-protection', phase: 'pr-head', source: 'success_conditions' },
25
- }
26
-
27
- export function mergifyDiscovery(yaml) {
28
- const document = parseMergifyYaml(yaml)
29
- const phases = []
30
- const phaseCounts = new Map()
31
- const collect = (value, label = 'root') => {
32
- if (!value || typeof value !== 'object') return
33
- if (Array.isArray(value)) return value.forEach((entry, index) => collect(entry, `${label}[${index}]`))
34
- for (const [key, child] of Object.entries(value)) {
35
- const at = `${label}.${key}`
36
- const shape = MERGIFY_PHASES[key]
37
- if (shape) {
38
- if (!Array.isArray(child) || child.length === 0) throw new Error(`${at} must be a non-empty condition array`)
39
- const trees = [{ all: child.map((entry, index) => structuralConditionTree(entry, `${at}[${index}]`)) }]
40
- const leaves = (tree) => tree.condition ? [tree.condition] : (tree.all || tree.any || []).flatMap(leaves)
41
- const count = (phaseCounts.get(shape.id) ?? 0) + 1
42
- phaseCounts.set(shape.id, count)
43
- phases.push({ ...shape, id: count === 1 ? shape.id : `${shape.id}:${count}`, source: `${shape.source}@${at}`, trees, conditions: unique(trees.flatMap(leaves)) })
44
- }
45
- collect(child, at)
46
- }
47
- }
48
- collect(document)
49
- if (!phases.length) throw new Error('Mergify YAML has no merge-admission condition sections')
50
- const leaves = (tree) => tree.condition ? [tree.condition] : (tree.all || tree.any || []).flatMap(leaves)
51
- const trees = phases.flatMap((phase) => phase.trees)
52
- return { phases, trees, conditions: unique(trees.flatMap(leaves)) }
53
- }
54
-
55
- export function mergifyConditions(yaml) { return mergifyDiscovery(yaml).conditions }
56
-
57
- function matchRefPattern(pattern, targetBranch, defaultBranch) {
58
- if (pattern === '~ALL') return true
59
- if (pattern === '~DEFAULT_BRANCH') {
60
- if (!nonEmpty(defaultBranch)) throw new Error('GitHub default branch is required to evaluate ~DEFAULT_BRANCH ruleset conditions')
61
- return targetBranch === defaultBranch
62
- }
63
- if (!nonEmpty(pattern)) throw new Error('ruleset ref_name include/exclude must contain non-empty strings')
64
- if (!/^[A-Za-z0-9._/*?/-]+$/.test(pattern)) throw new Error(`unsupported ruleset ref_name pattern ${JSON.stringify(pattern)}`)
65
- const expression = '^' + pattern.split('*').map((segment) => segment.split('?').map((part) => part.replace(/[.*+^${}()|[\]\\]/g, '\\$&')).join('[^/]')).join('.*') + '$'
66
- return new RegExp(expression).test(targetBranch)
67
- }
68
-
69
- function rulesetApplies(ruleset, { targetBranch, defaultBranch }) {
70
- if (ruleset?.enforcement && ruleset.enforcement !== 'active') return false
71
- if (ruleset?.target && ruleset.target !== 'branch') throw new Error(`unsupported ruleset target ${JSON.stringify(ruleset.target)}`)
72
- const conditions = ruleset?.conditions
73
- if (conditions == null) return true
74
- if (!conditions || typeof conditions !== 'object' || Array.isArray(conditions) || Object.keys(conditions).length !== 1 || !Object.hasOwn(conditions, 'ref_name')) throw new Error('unsupported or ambiguous GitHub ruleset condition structure')
75
- const ref = conditions.ref_name
76
- if (!ref || typeof ref !== 'object' || Array.isArray(ref) || Object.keys(ref).some((key) => !['include', 'exclude'].includes(key)) || !Array.isArray(ref.include) || !Array.isArray(ref.exclude)) throw new Error('unsupported or ambiguous GitHub ruleset ref_name condition shape')
77
- const included = ref.include.some((pattern) => matchRefPattern(pattern, targetBranch, defaultBranch))
78
- const excluded = ref.exclude.some((pattern) => matchRefPattern(pattern, targetBranch, defaultBranch))
79
- return included && !excluded
80
- }
81
-
82
- export function githubConditions(rulesets, { targetBranch, defaultBranch, withDiscovery = false } = {}) {
83
- const conditions = []
84
- const applicable = []
85
- for (const ruleset of Array.isArray(rulesets) ? rulesets : []) {
86
- if (!rulesetApplies(ruleset, { targetBranch, defaultBranch })) continue
87
- applicable.push({ id: ruleset?.id ?? null, target: ruleset?.target ?? 'branch', enforcement: ruleset?.enforcement ?? 'active', conditions: ruleset?.conditions ?? null })
88
- for (const rule of ruleset?.rules || []) {
89
- if (rule?.type !== 'required_status_checks') continue
90
- for (const check of rule.parameters?.required_status_checks || []) if (nonEmpty(check.context)) conditions.push('required_status_checks: ' + check.context)
91
- }
92
- }
93
- const result = { conditions: unique(conditions), rulesets: applicable }
94
- return withDiscovery ? result : result.conditions
95
- }
96
-
97
- const checksFrom = (conditions) => conditions.filter((condition) => /^required_status_checks:\s*|^check-success\s*=\s*/.test(condition)).map((condition) => condition.replace(/^required_status_checks:\s*|^check-success\s*=\s*/, '')).filter(nonEmpty)
98
-
99
- export function buildRequiredCheckPlan({ repository, targetBranch, defaultBranch, headSha, githubRulesets, mergifyYaml, mappings = {}, allowedSkippedJobs = [] }) {
100
- const githubResult = githubConditions(githubRulesets, { targetBranch, defaultBranch, withDiscovery: true })
101
- const github = githubResult.conditions
102
- const mergifyResult = mergifyDiscovery(mergifyYaml)
103
- const mergify = mergifyResult.conditions
104
- const requiredChecks = unique([...checksFrom(github), ...checksFrom(mergify)]).sort()
105
- const leaves = (tree) => tree.condition ? [tree.condition] : (tree.all || tree.any || []).flatMap(leaves)
106
- const checks = requiredChecks.map((name) => {
107
- const mapping = mappings[name]
108
- if (!mapping) throw new Error('live required check ' + name + ' has no classification/evidence mapping; classify it locally-reproduced or publish-only before freeze')
109
- const phases = unique([
110
- ...(github.includes('required_status_checks: ' + name) ? ['pr-head'] : []),
111
- ...mergifyResult.phases.filter((phase) => phase.trees.flatMap(leaves).includes('check-success = ' + name)).map((phase) => phase.phase),
112
- ])
113
- const sources = [...(github.includes('required_status_checks: ' + name) ? ['github-ruleset'] : []), ...mergifyResult.phases.filter((phase) => phase.trees.flatMap(leaves).includes('check-success = ' + name)).map((phase) => `mergify:${phase.id}`)]
114
- const queueEvidence = phases.includes('queue-head')
115
- ? mapping.queueEvidence ?? { provider: mapping.evidence?.provider ?? 'github', acquisition: 'github-check-runs' }
116
- : undefined
117
- return { name, admission: 'required', sources, phases, ...mapping, ...(queueEvidence ? { queueEvidence } : {}) }
118
- })
119
- const tree = (condition) => ({ condition })
120
- const plan = { version: 2, kind: 'required-check-plan', repository, targetBranch, headSha, discovery: { github: { conditions: github, trees: github.map(tree), rulesets: githubResult.rulesets }, mergify: { conditions: mergify, trees: mergifyResult.trees, phases: mergifyResult.phases }, requiredChecks }, checks, allowedSkippedJobs }
121
- const verdict = validateRequiredCheckPlan(plan, { expectedHeadSha: headSha })
122
- if (!verdict.ok) throw new Error('invalid discovered required-check plan: ' + verdict.errors.join('; '))
123
- return plan
124
- }
125
-
126
- function parseArgs(argv) {
127
- const options = {}
128
- for (let index = 0; index < argv.length; index += 1) {
129
- const arg = argv[index]
130
- if (arg === '--repository') options.repository = argv[++index]
131
- else if (arg === '--target') options.targetBranch = argv[++index]
132
- else if (arg === '--head') options.headSha = argv[++index]
133
- else if (arg === '--mappings') options.mappings = argv[++index]
134
- else if (arg === '--allowed-skipped-jobs') options.allowedSkippedJobs = argv[++index]
135
- else if (arg === '--out') options.out = argv[++index]
136
- else if (arg === '--help' || arg === '-h') options.help = true
137
- else throw new Error('unknown argument ' + arg)
138
- }
139
- return options
140
- }
141
-
142
- function ghJson(args) { return JSON.parse(execFileSync('gh', args, { encoding: 'utf8' })) }
143
-
144
- export function runCli(argv) {
145
- let options
146
- try { options = parseArgs(argv) } catch (error) { console.error('required-check-plan: ' + error.message); return 2 }
147
- if (options.help) {
148
- console.log('required-check-plan --repository owner/name --target main --head <40-sha> --mappings mappings.json [--allowed-skipped-jobs skips.json] --out required-check-plan.json')
149
- return 0
150
- }
151
- if (![options.repository, options.targetBranch, options.headSha, options.mappings, options.out].every(nonEmpty)) {
152
- console.error('required-check-plan requires --repository --target --head --mappings --out')
153
- return 2
154
- }
155
- try {
156
- const summary = ghJson(['api', 'repos/' + options.repository + '/rulesets'])
157
- const repository = ghJson(['api', 'repos/' + options.repository])
158
- const defaultBranch = repository.default_branch
159
- if (!nonEmpty(defaultBranch)) throw new Error('GitHub repository default_branch is unavailable; cannot evaluate ruleset conditions')
160
- const githubRulesets = summary.map((ruleset) => ghJson(['api', 'repos/' + options.repository + '/rulesets/' + ruleset.id]))
161
- const content = ghJson(['api', 'repos/' + options.repository + '/contents/.mergify.yml?ref=' + options.targetBranch])
162
- const mergifyYaml = Buffer.from(content.content.replace(/\s/g, ''), 'base64').toString('utf8')
163
- const mappings = JSON.parse(fs.readFileSync(options.mappings, 'utf8'))
164
- const allowedSkippedJobs = options.allowedSkippedJobs ? JSON.parse(fs.readFileSync(options.allowedSkippedJobs, 'utf8')) : []
165
- const plan = buildRequiredCheckPlan({ repository: options.repository, targetBranch: options.targetBranch, defaultBranch, headSha: options.headSha, githubRulesets, mergifyYaml, mappings, allowedSkippedJobs })
166
- fs.writeFileSync(options.out, JSON.stringify(plan, null, 2) + '\n')
167
- console.log('required-check-plan: discovered ' + plan.checks.length + ' live required checks at ' + plan.headSha)
168
- return 0
169
- } catch (error) { console.error('required-check-plan: ' + error.message); return 1 }
170
- }
171
-
172
- if (isMainModule(import.meta.url)) process.exit(runCli(process.argv.slice(2)))
@@ -1,79 +0,0 @@
1
- import { execFileSync } from 'node:child_process'
2
-
3
- export const CHANGED_SURFACES = [
4
- 'runtime',
5
- 'tests',
6
- 'verification-harness',
7
- 'evidence',
8
- 'docs',
9
- 'none',
10
- ]
11
-
12
- export const LEGACY_CHANGED_SURFACE = 'unknown'
13
-
14
- const SURFACE_ORDER = new Map(CHANGED_SURFACES.map((surface, index) => [surface, index]))
15
- const TEST_PATH = /(?:^|\/)(?:test|tests|__tests__|spec|specs)(?:\/|$)|\.(?:test|spec)\.[^/]+$/i
16
- const EVIDENCE_PATH = /(?:^|\/)(?:evidence|artifacts?|screenshots?|snapshots?|traces?)(?:\/|$)|(?:coverage-checklist|smoke-results|smoke-verdict|runtime-smoke)\.(?:json|md)$/i
17
- const DOC_PATH = /(?:^|\/)(?:docs?|documentation)(?:\/|$)|\.(?:md|mdx|rst|adoc|txt)$/i
18
- const HARNESS_PATH = /(?:^|\/)(?:e2e|harness|verification|validators?|sanitizers?|gates?|scripts)(?:\/|$)|(?:^|\/)(?:run-state|coverage-ledger|coverage-checklist|lint-tests|scan-diff)\.mjs$/i
19
-
20
- const normalizedPath = (value) => String(value).replaceAll('\\', '/').replace(/^\.\//, '')
21
-
22
- export function classifyChangedPath(file) {
23
- const value = normalizedPath(file)
24
- if (!value) return null
25
- if (TEST_PATH.test(value)) return 'tests'
26
- if (EVIDENCE_PATH.test(value)) return 'evidence'
27
- if (DOC_PATH.test(value)) return 'docs'
28
- if (HARNESS_PATH.test(value)) return 'verification-harness'
29
- return 'runtime'
30
- }
31
-
32
- export function normalizeChangedSurfaces(surfaces, { legacy = false } = {}) {
33
- const allowed = legacy ? [...CHANGED_SURFACES, LEGACY_CHANGED_SURFACE] : CHANGED_SURFACES
34
- if (!Array.isArray(surfaces) || !surfaces.length) {
35
- throw new Error(`changedSurfaces must be a non-empty array of ${allowed.join('|')}`)
36
- }
37
- const unique = [...new Set(surfaces)]
38
- const bad = unique.find((surface) => !allowed.includes(surface))
39
- if (bad) throw new Error(`changedSurfaces[] must each be one of ${allowed.join('|')} (got ${JSON.stringify(bad)})`)
40
- if (unique.includes('none') && unique.length !== 1) {
41
- throw new Error('changedSurfaces "none" is exclusive and cannot be combined with another surface')
42
- }
43
- if (unique.includes(LEGACY_CHANGED_SURFACE) && unique.length !== 1) {
44
- throw new Error('changedSurfaces "unknown" is a legacy-only exclusive classification')
45
- }
46
- return unique.sort((a, b) => (SURFACE_ORDER.get(a) ?? Number.MAX_SAFE_INTEGER) - (SURFACE_ORDER.get(b) ?? Number.MAX_SAFE_INTEGER))
47
- }
48
-
49
- export function classifyChangedPaths(paths) {
50
- const surfaces = [...new Set((Array.isArray(paths) ? paths : []).map(classifyChangedPath).filter(Boolean))]
51
- return normalizeChangedSurfaces(surfaces.length ? surfaces : ['none'])
52
- }
53
-
54
- export function deriveChangedSurfaces({ cwd = process.cwd(), fromRef, toRef = 'HEAD' } = {}) {
55
- if (typeof fromRef !== 'string' || !fromRef.trim()) throw new Error('fromRef is required to derive changedSurfaces')
56
- if (typeof toRef !== 'string' || !toRef.trim()) throw new Error('toRef is required to derive changedSurfaces')
57
- let output
58
- try {
59
- output = execFileSync(
60
- 'git',
61
- ['diff', '--name-only', '--no-renames', '-z', fromRef, toRef, '--'],
62
- { cwd, encoding: 'buffer', maxBuffer: 64 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'] },
63
- )
64
- } catch (error) {
65
- const detail = error.stderr?.toString().trim() || error.message
66
- throw new Error(`cannot derive changedSurfaces from ${fromRef}..${toRef}: ${detail}`)
67
- }
68
- const paths = output.toString('utf8').split('\0').filter(Boolean)
69
- return classifyChangedPaths(paths)
70
- }
71
-
72
- export function assertChangedSurfacesMatch(actual, expected) {
73
- const declared = normalizeChangedSurfaces(actual)
74
- const derived = normalizeChangedSurfaces(expected)
75
- if (JSON.stringify(declared) !== JSON.stringify(derived)) {
76
- throw new Error(`changedSurfaces override ${JSON.stringify(declared)} does not match diff-derived ${JSON.stringify(derived)}`)
77
- }
78
- return derived
79
- }
@@ -1,334 +0,0 @@
1
- // The sole round-7 source of truth for the contract-complete public matrix.
2
- // Keep the 42 case objects literal: the executor and durable evidence consume
3
- // these objects rather than maintaining a parallel declaration.
4
-
5
- export const MATRIX_THEME = {
6
- id: 'generic-writer-composability',
7
- kind: 'concurrency',
8
- contract: 'Generic writes preserve durable roster identity and dependency-bound history across every run-state state and task kind.',
9
- stateSpace: {
10
- states: [
11
- 'staged-manifest',
12
- 'new-versionless-unit',
13
- 'new-v2-unit',
14
- 'existing-versionless-unit',
15
- 'existing-v2-unit',
16
- 'existing-protected-unit',
17
- 'malformed-legacy-unit',
18
- ],
19
- taskKinds: ['set', 'merge', 'upsert-unit', 'validate', 'migrate-unit', 'round-transition'],
20
- },
21
- }
22
-
23
- const NOW = '2026-07-17T00:00:00.000Z'
24
- const unit = (id = '#809', extra = {}) => ({ id, status: 'in-progress', ...extra })
25
- const v2 = (id = '#809', extra = {}) => unit(id, { stateVersion: 2, ...extra })
26
- const protectedHistory = [
27
- { round: 1, verdict: 'PASS', themes: [] },
28
- ]
29
- const protectedUnit = (extra = {}) => v2('#protected', {
30
- status: 'in-progress',
31
- pr: '#334',
32
- branch: 'feat/809-contract-complete-fix-rounds',
33
- reviewHistory: structuredClone(protectedHistory),
34
- fixRounds: [],
35
- ...extra,
36
- })
37
- const malformedUnits = () => [unit('#malformed', { reviewHistory: { malformed: true }, fixRounds: ['malformed'] })]
38
-
39
- export function fixtureFor(arrange) {
40
- switch (arrange) {
41
- case 'staged-empty':
42
- return { models: { implementation: 'impl' } }
43
- case 'new-versionless-empty':
44
- return {}
45
- case 'new-versionless':
46
- return { units: [unit('#809')] }
47
- case 'new-v2-empty':
48
- return {}
49
- case 'new-v2':
50
- return { units: [v2('#809')] }
51
- case 'existing-versionless':
52
- return { units: [unit('#809')] }
53
- case 'existing-v2':
54
- return { units: [v2('#809')] }
55
- case 'existing-protected':
56
- return { units: [protectedUnit()] }
57
- case 'existing-protected-roster':
58
- return { units: [protectedUnit(), unit('#ordinary', { stateVersion: 2, status: 'queued' })] }
59
- case 'malformed-legacy':
60
- return { units: malformedUnits() }
61
- default:
62
- throw new Error(`unknown round-7 arrangement ${arrange}`)
63
- }
64
- }
65
-
66
- const json = (value) => JSON.stringify(value)
67
- const operation = (command, args, expectedExitStatus, stderrClass, mutation, assertion, expected = {}) => ({
68
- argv: [command, '<slug>', ...args, '--now', NOW],
69
- expectedExitStatus,
70
- stderrClass,
71
- mutation,
72
- assertion,
73
- expected,
74
- })
75
- const reject = (command, args, stderrClass, mutation = 'none/raw-byte-identical', assertion = 'rejection') => operation(command, args, 1, stderrClass, mutation, assertion)
76
- const accept = (command, args, mutation, assertion, expected = {}) => operation(command, args, 0, 'empty', mutation, assertion, expected)
77
- const readAccept = (args = []) => operation('validate', args, 0, 'validation-success', 'none/raw-byte-identical', 'read-only')
78
- const transition = (commands) => ({
79
- commands,
80
- expectedExitStatus: 0,
81
- stderrClass: 'empty',
82
- mutation: 'append-only-transition',
83
- assertion: 'transition',
84
- })
85
- const transitionCommand = (command, unitId, payload, expected) => ({ command, unitId, payload, expected })
86
- const transitionReject = (commands) => ({
87
- commands,
88
- expectedExitStatus: 1,
89
- stderrClass: 'transition-rejection',
90
- mutation: 'none/raw-byte-identical',
91
- assertion: 'rejection',
92
- })
93
- const markerRewrite = (command, args) => reject(command, args, 'generic-rejection', 'none/raw-byte-identical', 'rejection')
94
- const metadata = (command, args, expectedUnit) => accept(command, args, 'exact-delta', 'metadata', { unit: expectedUnit })
95
- export const MATRIX_CASES = [
96
- {
97
- caseId: 'staged-manifest--set', state: 'staged-manifest', taskKind: 'set', arrange: 'staged-empty',
98
- operation: accept('set', ['models.implementation', 'impl-next'], 'exact-delta', 'model-add', { models: { implementation: 'impl-next' } }),
99
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:97', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:199',
100
- },
101
- {
102
- caseId: 'staged-manifest--merge', state: 'staged-manifest', taskKind: 'merge', arrange: 'staged-empty',
103
- operation: accept('merge', [json({ models: { review: 'review' } })], 'exact-delta', 'model-add', { models: { review: 'review' } }),
104
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:102', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:237',
105
- },
106
- {
107
- caseId: 'staged-manifest--upsert-unit', state: 'staged-manifest', taskKind: 'upsert-unit', arrange: 'staged-empty',
108
- operation: accept('upsert-unit', [json(unit('#queued', { status: 'queued' }))], 'exact-delta', 'new-id', { unit: unit('#queued', { status: 'queued' }), order: ['#queued'] }),
109
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:107', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:274',
110
- },
111
- {
112
- caseId: 'staged-manifest--validate', state: 'staged-manifest', taskKind: 'validate', arrange: 'staged-empty',
113
- operation: reject('validate', [], 'validation-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:112', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:312',
114
- },
115
- {
116
- caseId: 'staged-manifest--migrate-unit', state: 'staged-manifest', taskKind: 'migrate-unit', arrange: 'staged-empty',
117
- operation: reject('migrate-unit', ['#missing', '--version', '1'], 'migration-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:116', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:347',
118
- },
119
- {
120
- caseId: 'staged-manifest--round-transition', state: 'staged-manifest', taskKind: 'round-transition', arrange: 'staged-empty',
121
- operation: transitionReject([
122
- transitionCommand('record-review-round', '#missing', { round: 1, verdict: 'PASS', findings: [] }, { type: 'reject' }),
123
- transitionCommand('record-fix-round', '#missing', { round: 1, reviewRound: 1, themeId: 'missing' }, { type: 'reject' }),
124
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:120', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:385',
125
- },
126
-
127
- {
128
- caseId: 'new-versionless-unit--set', state: 'new-versionless-unit', taskKind: 'set', arrange: 'new-versionless-empty',
129
- operation: accept('set', ['units', json([unit('#809', { status: 'queued' })])], 'exact-delta', 'create-v1', { unit: unit('#809', { status: 'queued' }), order: ['#809'] }),
130
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:128', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:434',
131
- },
132
- {
133
- caseId: 'new-versionless-unit--merge', state: 'new-versionless-unit', taskKind: 'merge', arrange: 'new-versionless-empty',
134
- operation: accept('merge', [json({ units: [unit('#809', { status: 'queued' })] })], 'exact-delta', 'create-v1', { unit: unit('#809', { status: 'queued' }), order: ['#809'] }),
135
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:133', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:472',
136
- },
137
- {
138
- caseId: 'new-versionless-unit--upsert-unit', state: 'new-versionless-unit', taskKind: 'upsert-unit', arrange: 'new-versionless-empty',
139
- operation: accept('upsert-unit', [json(unit('#809', { status: 'queued' }))], 'exact-delta', 'create-v1', { unit: unit('#809', { status: 'queued' }), order: ['#809'] }),
140
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:138', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:509',
141
- },
142
- {
143
- caseId: 'new-versionless-unit--validate', state: 'new-versionless-unit', taskKind: 'validate', arrange: 'new-versionless',
144
- operation: readAccept(), protectedState: [], testLocator: 'run-state-review6-cases.mjs:143', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:546',
145
- },
146
- {
147
- caseId: 'new-versionless-unit--migrate-unit', state: 'new-versionless-unit', taskKind: 'migrate-unit', arrange: 'new-versionless',
148
- operation: accept('migrate-unit', ['#809', '--version', '1'], 'migration', 'migration', { unit: v2('#809', { status: 'in-progress', reviewHistory: [] }) }),
149
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:147', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:581',
150
- },
151
- {
152
- caseId: 'new-versionless-unit--round-transition', state: 'new-versionless-unit', taskKind: 'round-transition', arrange: 'new-versionless',
153
- operation: transitionReject([
154
- transitionCommand('record-review-round', '#809', { round: 1, verdict: 'PASS', findings: [] }, { type: 'reject' }),
155
- transitionCommand('record-fix-round', '#809', { round: 1, reviewRound: 1, themeId: 'missing' }, { type: 'reject' }),
156
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:152', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:620',
157
- },
158
-
159
- {
160
- caseId: 'new-v2-unit--set', state: 'new-v2-unit', taskKind: 'set', arrange: 'new-v2-empty',
161
- operation: accept('set', ['units', json([v2('#809', { status: 'queued' })])], 'exact-delta', 'create-v2', { unit: v2('#809', { status: 'queued' }), order: ['#809'] }),
162
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:160', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:669',
163
- },
164
- {
165
- caseId: 'new-v2-unit--merge', state: 'new-v2-unit', taskKind: 'merge', arrange: 'new-v2-empty',
166
- operation: accept('merge', [json({ units: [v2('#809', { status: 'queued' })] })], 'exact-delta', 'create-v2', { unit: v2('#809', { status: 'queued' }), order: ['#809'] }),
167
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:165', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:707',
168
- },
169
- {
170
- caseId: 'new-v2-unit--upsert-unit', state: 'new-v2-unit', taskKind: 'upsert-unit', arrange: 'new-v2-empty',
171
- operation: accept('upsert-unit', [json(v2('#809', { status: 'queued' }))], 'exact-delta', 'create-v2', { unit: v2('#809', { status: 'queued' }), order: ['#809'] }),
172
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:170', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:744',
173
- },
174
- {
175
- caseId: 'new-v2-unit--validate', state: 'new-v2-unit', taskKind: 'validate', arrange: 'new-v2',
176
- operation: readAccept(), protectedState: [], testLocator: 'run-state-review6-cases.mjs:175', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:781',
177
- },
178
- {
179
- caseId: 'new-v2-unit--migrate-unit', state: 'new-v2-unit', taskKind: 'migrate-unit', arrange: 'new-v2',
180
- operation: reject('migrate-unit', ['#809', '--version', '1'], 'migration-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:179', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:816',
181
- },
182
- {
183
- caseId: 'new-v2-unit--round-transition', state: 'new-v2-unit', taskKind: 'round-transition', arrange: 'new-v2',
184
- operation: transition([
185
- transitionCommand('record-review-round', '#809', { round: 1, verdict: 'PASS', findings: [] }, {
186
- type: 'review-append',
187
- record: { round: 1, verdict: 'PASS', themes: [] },
188
- }),
189
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:183', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:854',
190
- },
191
-
192
- {
193
- caseId: 'existing-versionless-unit--set', state: 'existing-versionless-unit', taskKind: 'set', arrange: 'existing-versionless',
194
- operation: markerRewrite('set', ['units', json([unit('#809', { status: 'queued', stateVersion: 2 })])]),
195
- variants: [{ name: 'ordinary metadata is allowed', arrange: 'existing-versionless', operation: metadata('set', ['units', json([unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' })])], unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' })) }],
196
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:193', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:892',
197
- },
198
- {
199
- caseId: 'existing-versionless-unit--merge', state: 'existing-versionless-unit', taskKind: 'merge', arrange: 'existing-versionless',
200
- operation: markerRewrite('merge', [json({ units: [unit('#809', { status: 'queued', stateVersion: 2 })] })]),
201
- variants: [{ name: 'ordinary metadata is allowed', arrange: 'existing-versionless', operation: metadata('merge', [json({ units: [unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' })] })], unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' })) }],
202
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:199', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:961',
203
- },
204
- {
205
- caseId: 'existing-versionless-unit--upsert-unit', state: 'existing-versionless-unit', taskKind: 'upsert-unit', arrange: 'existing-versionless',
206
- operation: markerRewrite('upsert-unit', [json(v2('#809', { status: 'queued' }))]),
207
- variants: [{ name: 'ordinary metadata is allowed', arrange: 'existing-versionless', operation: metadata('upsert-unit', [json(unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' }))], unit('#809', { status: 'merge-ready', pr: '#809', lastVerdict: 'PASS' })) }],
208
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:205', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1028',
209
- },
210
- {
211
- caseId: 'existing-versionless-unit--validate', state: 'existing-versionless-unit', taskKind: 'validate', arrange: 'existing-versionless',
212
- operation: readAccept(), protectedState: [], testLocator: 'run-state-review6-cases.mjs:211', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1095',
213
- },
214
- {
215
- caseId: 'existing-versionless-unit--migrate-unit', state: 'existing-versionless-unit', taskKind: 'migrate-unit', arrange: 'existing-versionless',
216
- operation: accept('migrate-unit', ['#809', '--version', '1'], 'migration', 'migration', { unit: v2('#809', { status: 'in-progress', reviewHistory: [] }) }),
217
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:215', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1130',
218
- },
219
- {
220
- caseId: 'existing-versionless-unit--round-transition', state: 'existing-versionless-unit', taskKind: 'round-transition', arrange: 'existing-versionless',
221
- operation: transitionReject([
222
- transitionCommand('record-review-round', '#809', { round: 1, verdict: 'PASS', findings: [] }, { type: 'reject' }),
223
- transitionCommand('record-fix-round', '#809', { round: 1, reviewRound: 1, themeId: 'missing' }, { type: 'reject' }),
224
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:220', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1169',
225
- },
226
-
227
- {
228
- caseId: 'existing-v2-unit--set', state: 'existing-v2-unit', taskKind: 'set', arrange: 'existing-v2',
229
- operation: metadata('set', ['units', json([v2('#809', { status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })])], v2('#809', { status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
230
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:228', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1218',
231
- },
232
- {
233
- caseId: 'existing-v2-unit--merge', state: 'existing-v2-unit', taskKind: 'merge', arrange: 'existing-v2',
234
- operation: metadata('merge', [json({ units: [v2('#809', { status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })] })], v2('#809', { status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
235
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:233', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1257',
236
- },
237
- {
238
- caseId: 'existing-v2-unit--upsert-unit', state: 'existing-v2-unit', taskKind: 'upsert-unit', arrange: 'existing-v2',
239
- operation: metadata('upsert-unit', [json({ id: '#809', status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })], v2('#809', { status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
240
- protectedState: [], testLocator: 'run-state-review6-cases.mjs:238', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1295',
241
- },
242
- {
243
- caseId: 'existing-v2-unit--validate', state: 'existing-v2-unit', taskKind: 'validate', arrange: 'existing-v2',
244
- operation: readAccept(), protectedState: [], testLocator: 'run-state-review6-cases.mjs:243', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1333',
245
- },
246
- {
247
- caseId: 'existing-v2-unit--migrate-unit', state: 'existing-v2-unit', taskKind: 'migrate-unit', arrange: 'existing-v2',
248
- operation: reject('migrate-unit', ['#809', '--version', '1'], 'migration-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:247', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1368',
249
- },
250
- {
251
- caseId: 'existing-v2-unit--round-transition', state: 'existing-v2-unit', taskKind: 'round-transition', arrange: 'existing-v2',
252
- operation: transition([
253
- transitionCommand('record-review-round', '#809', { round: 1, verdict: 'PASS', findings: [] }, {
254
- type: 'review-append',
255
- record: { round: 1, verdict: 'PASS', themes: [] },
256
- }),
257
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:251', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1406',
258
- },
259
-
260
- {
261
- caseId: 'existing-protected-unit--set', state: 'existing-protected-unit', taskKind: 'set', arrange: 'existing-protected',
262
- operation: metadata('set', ['units', json([protectedUnit({ status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })])], protectedUnit({ status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
263
- variants: [
264
- { name: 'reorder complete protected roster', arrange: 'existing-protected-roster', operation: accept('set', ['units', json([unit('#ordinary', { stateVersion: 2, status: 'queued' }), protectedUnit()])], 'exact-delta', 'reorder', { order: ['#ordinary', '#protected'] }) },
265
- { name: 'add a new ID through set', arrange: 'existing-protected-roster', operation: accept('set', ['units', json([protectedUnit(), unit('#ordinary', { stateVersion: 2, status: 'queued' }), unit('#new', { status: 'queued' })])], 'exact-delta', 'new-id', { unit: unit('#new', { status: 'queued' }), order: ['#protected', '#ordinary', '#new'] }) },
266
- { name: 'protected history mutation rejects', arrange: 'existing-protected', operation: reject('set', ['units', json([protectedUnit({ reviewHistory: [...protectedHistory, { round: 2, verdict: 'PASS', themes: [] }] })])], 'generic-rejection') },
267
- ],
268
- protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:261', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1444',
269
- },
270
- {
271
- caseId: 'existing-protected-unit--merge', state: 'existing-protected-unit', taskKind: 'merge', arrange: 'existing-protected',
272
- operation: metadata('merge', [json({ units: [protectedUnit({ status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })] })], protectedUnit({ status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
273
- variants: [
274
- { name: 'add a new ID while retaining protected roster', arrange: 'existing-protected-roster', operation: accept('merge', [json({ units: [protectedUnit(), unit('#ordinary', { stateVersion: 2, status: 'queued' }), unit('#new', { status: 'queued' })] })], 'exact-delta', 'new-id', { unit: unit('#new', { status: 'queued' }), order: ['#protected', '#ordinary', '#new'] }) },
275
- { name: 'reorder complete roster through merge', arrange: 'existing-protected-roster', operation: accept('merge', [json({ units: [unit('#ordinary', { stateVersion: 2, status: 'queued' }), protectedUnit()] })], 'exact-delta', 'reorder', { order: ['#ordinary', '#protected'] }) },
276
- { name: 'protected history mutation rejects', arrange: 'existing-protected', operation: reject('merge', [json({ units: [protectedUnit({ fixRounds: [{ round: 1 }] })] })], 'generic-rejection') },
277
- ],
278
- protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:271', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1571',
279
- },
280
- {
281
- caseId: 'existing-protected-unit--upsert-unit', state: 'existing-protected-unit', taskKind: 'upsert-unit', arrange: 'existing-protected',
282
- operation: metadata('upsert-unit', [json({ id: '#protected', status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })], protectedUnit({ status: 'merge-ready', pr: '#334', branch: 'feat/809-contract-complete-fix-rounds', lastVerdict: 'PASS' })),
283
- variants: [
284
- { name: 'protected history mutation rejects', arrange: 'existing-protected', operation: reject('upsert-unit', [json({ id: '#protected', reviewHistory: [...protectedHistory, { round: 2, verdict: 'PASS', themes: [] }] })], 'generic-rejection') },
285
- { name: 'add a new ID through upsert-unit', arrange: 'existing-protected-roster', operation: accept('upsert-unit', [json(unit('#new', { status: 'queued' }))], 'exact-delta', 'new-id', { unit: unit('#new', { status: 'queued' }), order: ['#protected', '#ordinary', '#new'] }) },
286
- ],
287
- protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:281', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1694',
288
- },
289
- {
290
- caseId: 'existing-protected-unit--validate', state: 'existing-protected-unit', taskKind: 'validate', arrange: 'existing-protected',
291
- operation: readAccept(), protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:290', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1789',
292
- },
293
- {
294
- caseId: 'existing-protected-unit--migrate-unit', state: 'existing-protected-unit', taskKind: 'migrate-unit', arrange: 'existing-protected',
295
- operation: reject('migrate-unit', ['#protected', '--version', '1'], 'migration-rejection'), protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:294', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1824',
296
- },
297
- {
298
- caseId: 'existing-protected-unit--round-transition', state: 'existing-protected-unit', taskKind: 'round-transition', arrange: 'existing-protected',
299
- operation: transitionReject([
300
- // Pre-#888 deep history is readable, but appending without universal typed rounds
301
- // would keep writing the old schema. Reconstruct unknown classifications first.
302
- transitionCommand('record-review-round', '#protected', { round: 2, verdict: 'PASS', findings: [] }, { type: 'reject' }),
303
- ]), protectedState: ['#protected'], testLocator: 'run-state-review6-cases.mjs:298', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1862',
304
- },
305
- {
306
- caseId: 'malformed-legacy-unit--set', state: 'malformed-legacy-unit', taskKind: 'set', arrange: 'malformed-legacy',
307
- operation: reject('set', ['units', json([unit('#malformed', { status: 'merge-ready', reviewHistory: { malformed: true }, fixRounds: ['malformed'] })])], 'generic-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:306', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1899',
308
- },
309
- {
310
- caseId: 'malformed-legacy-unit--merge', state: 'malformed-legacy-unit', taskKind: 'merge', arrange: 'malformed-legacy',
311
- operation: reject('merge', [json({ units: [unit('#malformed', { status: 'merge-ready' })] })], 'generic-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:310', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1936',
312
- },
313
- {
314
- caseId: 'malformed-legacy-unit--upsert-unit', state: 'malformed-legacy-unit', taskKind: 'upsert-unit', arrange: 'malformed-legacy',
315
- operation: reject('upsert-unit', [json({ id: '#malformed', status: 'merge-ready' })], 'generic-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:314', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:1972',
316
- },
317
- {
318
- caseId: 'malformed-legacy-unit--validate', state: 'malformed-legacy-unit', taskKind: 'validate', arrange: 'malformed-legacy',
319
- operation: reject('validate', [], 'validation-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:318', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:2008',
320
- },
321
- {
322
- caseId: 'malformed-legacy-unit--migrate-unit', state: 'malformed-legacy-unit', taskKind: 'migrate-unit', arrange: 'malformed-legacy',
323
- operation: reject('migrate-unit', ['#malformed', '--version', '1'], 'migration-rejection'), protectedState: [], testLocator: 'run-state-review6-cases.mjs:322', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:2043',
324
- },
325
- {
326
- caseId: 'malformed-legacy-unit--round-transition', state: 'malformed-legacy-unit', taskKind: 'round-transition', arrange: 'malformed-legacy',
327
- operation: transitionReject([
328
- transitionCommand('record-review-round', '#malformed', { round: 1, verdict: 'PASS', findings: [] }, { type: 'reject' }),
329
- transitionCommand('record-fix-round', '#malformed', { round: 1, reviewRound: 1, themeId: 'missing' }, { type: 'reject' }),
330
- ]), protectedState: [], testLocator: 'run-state-review6-cases.mjs:326', evidenceLocator: 'docs/evidence/809-runtime-smoke.json:2081',
331
- },
332
- ]
333
-
334
- if (MATRIX_CASES.length !== 42) throw new Error(`round-6 matrix must contain exactly 42 literal cases; got ${MATRIX_CASES.length}`)