@1aboveio/skills 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +90 -0
  3. package/bin/1aboveio-skills.mjs +18 -0
  4. package/package.json +28 -0
  5. package/runtime/skills/distribution/generated/recipes.json +1189 -0
  6. package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
  7. package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  8. package/skills/backend/airflow-dag-develop/LICENSE +3 -0
  9. package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
  10. package/skills/backend/app-debug/LICENSE +3 -0
  11. package/skills/backend/app-debug/SKILL.md +109 -0
  12. package/skills/backend/app-debug/references/common-errors.md +128 -0
  13. package/skills/backend/python-backend/LICENSE +3 -0
  14. package/skills/backend/python-backend/SKILL.md +326 -0
  15. package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
  16. package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
  17. package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
  18. package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
  19. package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
  20. package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
  21. package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
  22. package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
  23. package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
  24. package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
  25. package/skills/cicd-pipeline/docker/LICENSE +3 -0
  26. package/skills/cicd-pipeline/docker/SKILL.md +126 -0
  27. package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
  28. package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
  29. package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
  30. package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
  31. package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
  32. package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
  33. package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
  34. package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
  35. package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
  36. package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
  37. package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
  38. package/skills/cicd-pipeline/mergify/LICENSE +3 -0
  39. package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
  40. package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
  41. package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
  42. package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
  43. package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
  44. package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
  45. package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
  46. package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
  47. package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
  48. package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
  49. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
  50. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
  51. package/skills/cicd-pipeline/podman/LICENSE +3 -0
  52. package/skills/cicd-pipeline/podman/SKILL.md +70 -0
  53. package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
  54. package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  55. package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
  56. package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
  57. package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
  58. package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
  59. package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
  60. package/skills/engineering/e2e-test/LICENSE +3 -0
  61. package/skills/engineering/e2e-test/SKILL.md +156 -0
  62. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
  63. package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
  64. package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
  65. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  66. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
  67. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
  68. package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
  69. package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
  70. package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
  71. package/skills/engineering/e2e-test/references/debugging.md +36 -0
  72. package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
  73. package/skills/engineering/e2e-test/references/reviewing.md +39 -0
  74. package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
  75. package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
  76. package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
  77. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  78. package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
  79. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  80. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  81. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  82. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  83. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
  84. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  85. package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
  86. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
  87. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  88. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  89. package/skills/engineering/engineering-runtime/SKILL.md +10 -0
  90. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  91. package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
  92. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  93. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  94. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  95. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  96. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  97. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  98. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  99. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
  100. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
  101. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  102. package/skills/engineering/ensure-coverage/SKILL.md +136 -0
  103. package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
  104. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
  105. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
  106. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  107. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  108. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  109. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
  110. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  111. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
  112. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
  113. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
  114. package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
  115. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
  116. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
  117. package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
  118. package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
  119. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
  120. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  121. package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
  122. package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
  123. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
  124. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
  125. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
  126. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
  127. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
  128. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
  129. package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
  130. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
  131. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  132. package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
  133. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
  134. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  135. package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
  136. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  137. package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
  138. package/skills/engineering/harness-runtime/LICENSE +3 -0
  139. package/skills/engineering/harness-runtime/SKILL.md +18 -0
  140. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  141. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  142. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  143. package/skills/engineering/harness-runtime/contracts.md +15 -0
  144. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  145. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  146. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  147. package/skills/engineering/harness-runtime/index.mjs +767 -0
  148. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  149. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  150. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
  151. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  152. package/skills/engineering/implement-and-pr/LICENSE +3 -0
  153. package/skills/engineering/implement-and-pr/SKILL.md +176 -0
  154. package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
  155. package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
  156. package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
  157. package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
  158. package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
  159. package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
  160. package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
  161. package/skills/engineering/resolve-issues/LICENSE +3 -0
  162. package/skills/engineering/resolve-issues/SKILL.md +167 -0
  163. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
  164. package/skills/engineering/resolve-issues/references/breaker.md +82 -0
  165. package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
  166. package/skills/engineering/resolve-issues/references/delivery.md +108 -0
  167. package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
  168. package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
  169. package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
  170. package/skills/engineering/resolve-issues/references/finalization.md +68 -0
  171. package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
  172. package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
  173. package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
  174. package/skills/engineering/resolve-issues/references/intake.md +86 -0
  175. package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
  176. package/skills/engineering/resolve-issues/references/interference.md +87 -0
  177. package/skills/engineering/resolve-issues/references/loop.md +134 -0
  178. package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
  179. package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
  180. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
  181. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
  182. package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
  183. package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
  184. package/skills/engineering/resolve-issues/references/run-state.md +288 -0
  185. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
  186. package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
  187. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
  188. package/skills/engineering/resolve-issues/references/why.md +653 -0
  189. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
  190. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
  191. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
  192. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
  193. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
  194. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
  195. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
  196. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  197. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
  198. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
  199. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
  200. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
  201. package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
  202. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
  203. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
  204. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
  205. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
  206. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
  207. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
  208. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
  209. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
  210. package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
  211. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  212. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
  213. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
  214. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
  215. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
  216. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
  217. package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
  218. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
  219. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
  220. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
  221. package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
  222. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
  223. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
  224. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
  225. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
  226. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
  227. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
  228. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
  229. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
  230. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
  231. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
  232. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
  233. package/skills/engineering/resolve-release/LICENSE +3 -0
  234. package/skills/engineering/resolve-release/SKILL.md +112 -0
  235. package/skills/engineering/resolve-release/references/assembly.md +137 -0
  236. package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
  237. package/skills/engineering/resolve-release/references/candidate.md +167 -0
  238. package/skills/engineering/resolve-release/references/exposure.md +178 -0
  239. package/skills/engineering/resolve-release/references/handoff.md +24 -0
  240. package/skills/engineering/resolve-release/references/postmortem.md +230 -0
  241. package/skills/engineering/resolve-release/references/preflight.md +207 -0
  242. package/skills/engineering/resolve-release/references/principles.md +94 -0
  243. package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
  244. package/skills/engineering/resolve-release/references/related-skills.md +12 -0
  245. package/skills/engineering/resolve-release/references/routing.md +149 -0
  246. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
  247. package/skills/engineering/resolve-release/references/versioning.md +202 -0
  248. package/skills/engineering/resolve-release/references/why.md +53 -0
  249. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
  250. package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
  251. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
  252. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
  253. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
  254. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
  255. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
  256. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
  257. package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
  258. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
  259. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
  260. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
  261. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
  262. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
  263. package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
  264. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
  265. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
  266. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
  267. package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
  268. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
  269. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
  270. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
  271. package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
  272. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
  273. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
  274. package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
  275. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
  276. package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
  277. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
  278. package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
  279. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
  280. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
  281. package/skills/engineering/resolve-release/vendor/README.md +60 -0
  282. package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
  283. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
  284. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
  285. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
  286. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
  287. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
  288. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
  289. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
  290. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
  291. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
  292. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
  293. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
  294. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
  295. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
  296. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
  297. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
  298. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
  299. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
  300. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
  301. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
  302. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
  303. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
  304. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
  305. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
  306. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
  307. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
  308. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
  309. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
  310. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
  311. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
  312. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
  313. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
  314. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
  315. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
  316. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
  317. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
  318. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
  319. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  320. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
  321. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
  322. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
  323. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
  324. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
  325. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
  326. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
  327. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
  328. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
  329. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
  330. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
  331. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
  332. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
  333. package/skills/engineering/review-pr/LICENSE +3 -0
  334. package/skills/engineering/review-pr/SKILL.md +123 -0
  335. package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
  336. package/skills/engineering/review-pr/references/code-correctness.md +5 -0
  337. package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
  338. package/skills/engineering/review-pr/references/coordination.md +18 -0
  339. package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
  340. package/skills/engineering/review-pr/references/finding-themes.md +7 -0
  341. package/skills/engineering/review-pr/references/github-posting.md +98 -0
  342. package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
  343. package/skills/engineering/review-pr/references/incremental-output.md +16 -0
  344. package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
  345. package/skills/engineering/review-pr/references/output-format.md +99 -0
  346. package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
  347. package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
  348. package/skills/engineering/review-pr/references/re-review.md +18 -0
  349. package/skills/engineering/review-pr/references/review-method.md +199 -0
  350. package/skills/engineering/review-pr/references/review-mode.md +30 -0
  351. package/skills/engineering/review-pr/references/review-posture.md +53 -0
  352. package/skills/engineering/review-pr/references/round1-depth.md +62 -0
  353. package/skills/engineering/review-pr/references/scripts.md +17 -0
  354. package/skills/engineering/review-pr/references/workflow.md +16 -0
  355. package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
  356. package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
  357. package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
  358. package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
  359. package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
  360. package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
  361. package/skills/engineering/smoke/LICENSE +3 -0
  362. package/skills/engineering/smoke/SKILL.md +131 -0
  363. package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
  364. package/skills/engineering/smoke/references/manifest.md +192 -0
  365. package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
  366. package/skills/fullstack/better-auth/LICENSE +3 -0
  367. package/skills/fullstack/better-auth/SKILL.md +601 -0
  368. package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
  369. package/skills/fullstack/monorepo/LICENSE +3 -0
  370. package/skills/fullstack/monorepo/SKILL.md +465 -0
  371. package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
  372. package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
  373. package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
  374. package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
  375. package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
  376. package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
  377. package/skills/fullstack/prisma-setup/LICENSE +3 -0
  378. package/skills/fullstack/prisma-setup/SKILL.md +180 -0
  379. package/skills/fullstack/prisma-setup/nextjs.md +258 -0
  380. package/skills/fullstack/prisma-setup/turborepo.md +301 -0
  381. package/skills/fullstack/shadcn/LICENSE +3 -0
  382. package/skills/fullstack/shadcn/SKILL.md +119 -0
  383. package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
  384. package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
  385. package/skills/fullstack/shadcn/cli.md +411 -0
  386. package/skills/fullstack/shadcn/customization.md +224 -0
  387. package/skills/fullstack/shadcn/evals/evals.json +90 -0
  388. package/skills/fullstack/shadcn/mcp.md +101 -0
  389. package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
  390. package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
  391. package/skills/fullstack/shadcn/rules/composition.md +195 -0
  392. package/skills/fullstack/shadcn/rules/data-table.md +201 -0
  393. package/skills/fullstack/shadcn/rules/forms.md +255 -0
  394. package/skills/fullstack/shadcn/rules/icons.md +103 -0
  395. package/skills/fullstack/shadcn/rules/styling.md +167 -0
  396. package/skills/fullstack/zod-v4/LICENSE +3 -0
  397. package/skills/fullstack/zod-v4/SKILL.md +287 -0
@@ -0,0 +1,85 @@
1
+ # Hook Contract (in-loop gate enforcement)
2
+
3
+ The [CI Contract](ci-contract.md) wires the gates at **merge time** — the latest,
4
+ slowest place to discover a problem. This contract adds the *earliest* place: the
5
+ agent's own **edit/stop loop**, run as Claude Code hooks so a violation is caught at
6
+ the keystroke or at the moment the agent tries to finish, not after a CI round-trip.
7
+
8
+ The point is a **shift left, not a new gate**. Hooks invoke the existing
9
+ `lint-tests.mjs` and `coverage-ledger.mjs`; they add no rules and own no doctrine.
10
+ They convert two `resolve-issues` principles from prose into mechanics the agent
11
+ *cannot* bypass:
12
+
13
+ - **Principle 1 — never skip/disable/weaken a test.** A `PreToolUse` hook denies an
14
+ edit that *adds* a banned pattern (`test.skip`/`.only`/`xfail`/`xit`,
15
+ `waitForTimeout`/numeric `cy.wait`/`time.sleep`) to a test file.
16
+ - **Principle 5 — the loop exits on a fresh green gate, never on a claim.** A `Stop`
17
+ hook blocks the agent from declaring done while a gate is red against the current
18
+ HEAD.
19
+
20
+ The runnable hooks are provided by the **adopting repo** in its own `hooks/` dir
21
+ (`gate-pretooluse.mjs`, `gate-stop.mjs`) — this skill ships the **doctrine**, not the
22
+ scripts. This file specifies which gate belongs at which lifecycle event, and why.
23
+
24
+ ## The enforcement tiers
25
+
26
+ A gate runs at the **earliest point it can run cheaply and decisively**. Three tiers,
27
+ widening in cost and scope:
28
+
29
+ | Tier | Lifecycle event | Gate | Why here (and not earlier/later) |
30
+ |---|---|---|---|
31
+ | **Edit-time** | `PreToolUse` (Edit/Write/MultiEdit on a test file) | `lint-tests` skip/timeout, on the *proposed addition* only | Syntactically decidable, ~zero false positives, sub-second. Safe to block at the keystroke. Catching it here saves the agent from building on a test it will have to un-break. |
32
+ | **Stop-time** | `Stop` | `lint-tests --diff` over the net change + `coverage-ledger validate` | Needs the whole `base...HEAD` diff and the surface inventory — not available mid-edit, but cheap enough to run once when the agent tries to finish. This is the mechanical form of "don't stop on a claim." |
33
+ | **CI** | the [CI Contract](ci-contract.md) gates | inventory freshness, accounting, **presentation sweep**, functional/journey suite, `coverage-checklist validate` | Needs a browser, a seeded env, a specific Review-Contract checklist target, or minutes of runtime. Belongs in the PR lane, never the inner loop. |
34
+
35
+ The dividing line is **decidability and cost**, the same line `lint-tests` draws
36
+ between GATE and LEAD: a check blocks at edit-time only if a legitimate edit could
37
+ never trip it. A heuristic ("is this assertion meaningful?", over-mocking) stays a
38
+ review LEAD — never a blocking hook, because a noisy blocking hook gets turned off,
39
+ taking the real enforcement with it.
40
+
41
+ ### Why these specific placements
42
+
43
+ - **Skip/timeout lint at edit-time, not just CI** — the one check both fully
44
+ decidable and instantaneous, guarding the principle most prone to shortcut under
45
+ pressure ("just skip it to get green").
46
+ - **`coverage-ledger validate` at stop-time, not edit-time** — it reconciles the
47
+ *whole* changed surface against the inventory; a partial mid-edit tree would
48
+ produce false failures. Stop is the first coherent point.
49
+ - **`coverage-checklist validate` stays in CI** — it validates a *specific*
50
+ Review-Contract checklist path a generic stop hook can't know. Runs at the
51
+ `implement-and-pr` gate step and in CI.
52
+ - **Presentation sweep / full suite stay in CI** — a browser and a seeded env are
53
+ not inner-loop costs.
54
+
55
+ ## Degradation contract (never trap the agent)
56
+
57
+ A hook that can't run its gate **must allow**, never block — blocking on a check you
58
+ can't perform is indistinguishable from a false positive, and the first spurious
59
+ fire gets the whole layer disabled:
60
+
61
+ - **Scripts unresolved** (`ensure-coverage` not vendored / `ENSURE_COVERAGE_SCRIPTS`
62
+ unset and not at the default path) → allow.
63
+ - **`lint-tests --diff` can't compute a diff** (not a git repo, bad base) → the
64
+ runner treats unparseable output as `degraded`, not a violation.
65
+ - **`coverage-ledger validate` exits 2** (no surface inventory — gate not wired
66
+ here) → `degraded`, allow. Only exit **1** (a real reconciliation failure) blocks.
67
+
68
+ So a repo wiring only part of the pipeline still gets the edit-time skip lint and
69
+ suffers no spurious stop-blocks.
70
+
71
+ ## Escape hatch
72
+
73
+ `TEST_GATE_OFF=1` disables both hooks for the session — for the legitimate cases (a
74
+ deliberately half-written test mid-edit, or an *inherited* failure the agent is
75
+ fixing), paired with a duty to surface the block to a human. The invariant:
76
+ **disable the gate, never the test.** Using `TEST_GATE_OFF` to land a real
77
+ `test.skip` is the same failure one level up, and it leaves a reviewable trace (the
78
+ env flip) where a silent `test.skip` is what the gate hunts for.
79
+
80
+ ## Relationship to the other enforcement surfaces
81
+
82
+ Hooks are the **first** line, CI the **last**, review the **judgment** layer
83
+ between — redundant on purpose: the hook catches the skip at the keystroke, CI
84
+ catches it if the hook was off, `review-pr` catches the *semantic* failures neither
85
+ can decide. Doctrine stays here in `ensure-coverage`; the hooks **consume** it.
@@ -0,0 +1,109 @@
1
+ # Coverage Ledger: Worked Example
2
+
3
+ A concrete shape for the breadth-axis Coverage Ledger specced in [../breadth/coverage-ledger.md](../breadth/coverage-ledger.md). Paths and command names are illustrative — adapt to the repo. The pattern is what matters: a **generated inventory** from code, a **curated layer authored one file per requirement**, and a **generated aggregation** that dedups by surface and computes status.
4
+
5
+ ## Why it exists
6
+
7
+ A test-outward audit (mock census → mocked files → gaps) cannot find a surface with no tests — absence produces no signal. The ledger flips direction: enumerate obligations from requirements *and* code, reconcile, let mismatches surface the gaps. The motivating case: a `/settings/models` page with accepted ADRs and a live route, whose only "tests" used Playwright `route.fulfill` to fake the response — proxy wiring counted as coverage. The ledger forces the surface to be owned and discovered; the depth axis then grades it `Over-mocked`.
8
+
9
+ ## Layout
10
+
11
+ ```
12
+ docs/tests/adr/0008-org-model-allowlist.criteria.md # ACs for the ADR
13
+ docs/tests/adr/0008-org-model-allowlist.coverage.yml # this ADR's owned surfaces
14
+ docs/tests/prd/<slug>.coverage.yml
15
+ docs/tests/_generated/surface-inventory.json # discovered from code
16
+ docs/tests/_generated/coverage-index.json # computed aggregation
17
+ ```
18
+
19
+ ## Layer 1 — generated inventory (never hand-edited)
20
+
21
+ Regenerated from routers/migrations/event registry, one entry per surface. The adapter emits `class` (mechanical) and `reachability`; the baseline floor is computed from `(kind, class)` **before any curated file exists**.
22
+
23
+ ```json
24
+ // docs/tests/_generated/surface-inventory.json
25
+ { "surfaces": [
26
+ { "id": "/settings/models", "kind": "route", "class": "mutation", "reachability": "reachable" },
27
+ { "id": "/internal/debug-panel", "kind": "route", "class": "read", "reachability": "guarded" },
28
+ { "id": "/api/settings/model-allowlist", "kind": "api", "class": "mutation" },
29
+ { "id": "model_allowlist", "kind": "table" }
30
+ ] }
31
+ ```
32
+
33
+ ## Layer 2 — curated coverage, one file per requirement (hand-maintained)
34
+
35
+ Each file declares only the surfaces that requirement **owns**, their required level, and the criteria link. **No status field** — so multiple owners of a surface can never disagree.
36
+
37
+ ```yaml
38
+ # docs/tests/adr/0008-org-model-allowlist.coverage.yml
39
+ criteria: docs/tests/adr/0008-org-model-allowlist.criteria.md
40
+ surfaces:
41
+ "/settings/models":
42
+ requiredLevels: [pg-api, browser-journey, no-secret-assertion]
43
+ "/api/settings/model-allowlist":
44
+ requiredLevels: [pg-api]
45
+ ```
46
+
47
+ A second requirement (`0030-model-dispatch.coverage.yml`) can own `/settings/models` too; `aggregate` unions their `requirementRefs` and takes the strictest level.
48
+
49
+ ## Evidence — declared by tests, not hand-listed
50
+
51
+ Tests say what they prove with a `@covers` annotation (plus optional `@level`), so curated files never carry rot-prone paths. A test that fakes its own endpoint is detected as first-party interception → `Over-mocked`:
52
+
53
+ ```ts
54
+ // apps/web/e2e/models.spec.ts
55
+ // @covers /settings/models
56
+ // @level browser-journey
57
+ test('models page', async ({ page }) => {
58
+ await page.route('**/api/**', (r) => r.fulfill({ body: '{}' })) // -> Over-mocked
59
+ })
60
+ ```
61
+
62
+ ## Layer 3 — generated aggregation (never hand-edited)
63
+
64
+ Merges every curated file by surface, unions `requirementRefs`, takes the strictest level, diffs against the inventory, maps `@covers` → surface, and **computes** status.
65
+
66
+ ```jsonc
67
+ // docs/tests/_generated/coverage-index.json
68
+ {
69
+ "/settings/models": {
70
+ "requirementRefs": ["adr:0008", "adr:0030"],
71
+ // every route also auto-carries the presentation floor (render-health + spatial + perceivability + reachability + temporal)
72
+ "requiredLevels": ["pg-api", "browser-journey", "no-secret-assertion", "presentation:render-health", "presentation:spatial", "presentation:perceivability", "presentation:reachability", "presentation:temporal"],
73
+ "alignment": "Aligned",
74
+ "depthStatus": "Over-mocked" // computed: only route.fulfill tests exist
75
+ },
76
+ "/internal/debug-panel": {
77
+ "requirementRefs": [],
78
+ "requiredLevels": ["browser-journey", "presentation:render-health", "presentation:spatial", "presentation:perceivability", "presentation:reachability", "presentation:temporal"],
79
+ "alignment": "Orphan surface", // warn: owned by no curated file
80
+ "depthStatus": "Missing" // error: baseline floor unmet
81
+ }
82
+ }
83
+ ```
84
+
85
+ `/internal/debug-panel` shows the decoupling: `Orphan surface` is only a **warn** (nobody owns it), but its baseline floor is still graded — `Missing` is the failing finding. To exclude it a curated file adds `exclude: { category: internal, reason: "..." }` — honored because it is a `read` route, but **rejected** if it were a `reachable` `mutation`.
86
+
87
+ ## Alignment statuses (computed)
88
+
89
+ - `Aligned` — requirement ↔ surface present; grade depth next.
90
+ - `Orphan surface` — surface in inventory, owned by no curated file (`inventory − union(curated)`). A **warn**; the baseline floor is still enforced via depth status.
91
+ - `Excluded` — human-declared out of scope (category + reason), permitted by the reachability/class gate; printed in the census.
92
+ - `Unrealized requirement` — a curated surface absent from the inventory.
93
+ - `Stale link` — a curated surface or criteria link points at something gone.
94
+
95
+ Rows carrying a baseline floor (Aligned or Orphan) are graded by the depth classifications ([../depth/grading.md](../depth/grading.md)). Internal surfaces (`table`/`event`/`job`) instead resolve to `Reached` or `Dead`. `Covered` requires reviewer attestation (`verified: true`); `Unverified` blocks the gate by default.
96
+
97
+ ## How this caught `/settings/models`
98
+
99
+ 1. The inventory adapter lists the route and its APIs/tables.
100
+ 2. ADR-0008 and ADR-0030 each own it; `aggregate` merges them into one row, strictest level `pg-api + browser-journey` (plus the auto-applied presentation floor).
101
+ 3. `validate` resolves status from tests: only a `route.fulfill` test exists → `Over-mocked`; required `pg-api`/`browser-journey` evidence is `Missing`.
102
+
103
+ And **even with no ADR at all**: the adapter tags `class: mutation`, the Surface Baseline Contract auto-applies a `browser-journey` floor, and the same `route.fulfill`-only test resolves to `Over-mocked` → the gate fails. The organically-added, un-ADR'd route closes by default.
104
+
105
+ ## Presentation & visual (worked shapes)
106
+
107
+ Every `kind: route` auto-carries the presentation floor on top of `browser-journey`; a real-browser spec tags each level it proves (`// @level presentation:spatial`, etc.) and calls the corresponding assertion (`assertNoHorizontalOverflow`, `assertContrast`, `assertTargetSizes`/`assertFocusVisible`, `assertNoFirstPartyShift`). A DOM-only test tagged with a presentation level grades `Over-mocked`; a `browser-journey` with no such checks leaves the level `Wrong Level`. Full instrument list and failure modes: [../presentation/axis.md](../presentation/axis.md).
108
+
109
+ `presentation:visual` is **not** auto-floored — a surface earns a committed pixel baseline only by declaring it in its curated file (with gated, reasoned `mask:` regions), because every intended UI change re-baselines. It grades `Missing` with no committed baseline, and a diff counts as coverage only when tied to a declared intended UI change. Mechanics: [../presentation/runner-contract.md](../presentation/runner-contract.md), [../enforcement/ci-contract.md](../enforcement/ci-contract.md).
@@ -0,0 +1,33 @@
1
+ # Refund Flow Test Criteria Example
2
+
3
+ A minimal worked criteria doc for a money-movement feature — shows ACs and a risk-classified test matrix. (Template: [../process/output-template.md](../process/output-template.md).)
4
+
5
+ ## Example PRD
6
+
7
+ Merchant can request a refund for a settled payment. System validates eligibility, creates a refund record, calls the provider, updates payment/refund status, and emits refund events.
8
+
9
+ ## Acceptance Criteria
10
+
11
+ - AC1: Merchant can refund a settled payment for an amount ≤ remaining refundable amount.
12
+ - AC2: Refund rejected if payment is not settled.
13
+ - AC3: Refund rejected if amount exceeds remaining refundable amount.
14
+ - AC4: Duplicate request with the same idempotency key returns the original refund, creates no second refund.
15
+ - AC5: Provider accepts → status `PROCESSING`, `refund.created` emitted.
16
+ - AC6: Provider rejects → status `FAILED`, normalized provider error stored.
17
+ - AC7: Remaining refundable amount updates only after successful creation.
18
+ - AC8: Unauthorized merchant cannot refund another merchant's payment.
19
+ - AC9: System recovers safely if the provider call succeeds but event publish fails.
20
+ - AC10: Refund APIs return stable error codes, not raw provider/internal errors.
21
+
22
+ ## Test Matrix (representative rows)
23
+
24
+ | Scenario | ACs | Test Level | Setup/Input | Assertions | Evidence |
25
+ |---|---|---|---|---|---|
26
+ | Valid partial refund | AC1, AC5, AC7 | Integration/API | Settled payment, amount < remaining | Refund row created, `PROCESSING`, provider called once, event emitted, remaining updated | CI integration test |
27
+ | Duplicate request | AC4 | Integration | Same merchant/payment/idempotency key twice | One refund row, one provider call, same response | CI integration test |
28
+ | Unauthorized merchant | AC8 | API/security | Merchant B refunds Merchant A's payment | `403`/`404`, no provider call, no refund row | CI API/security test |
29
+ | Provider hard decline | AC6, AC10 | Integration + fake provider | Provider returns decline | `FAILED`, normalized error stored, no success event | CI integration test |
30
+ | Event publish failure | AC5, AC9 | Integration/recovery | DB commit succeeds, publish fails | Outbox retry emits event, no duplicate refund/provider call | CI recovery test |
31
+ | Concurrent refunds | AC3, AC4, AC7 | Integration/concurrency | Two requests race the same remaining amount | Valid total only, no over-refund | CI concurrency test |
32
+
33
+ Money/security ACs (AC1, AC4, AC7, AC8) are **never mock-only**, even with approval — they require integration/API/journey evidence against real state ([../process/test-strategy.md](../process/test-strategy.md)). The provider is the one external faked with a fake adapter; the DB, idempotency, concurrency, and outbox run for real.
@@ -0,0 +1,78 @@
1
+ # Presentation Floor (browser routes)
2
+
3
+ > Read when: working any `presentation:*` invariant. Sibling: [runner-contract.md](runner-contract.md) (the interface the `e2e-test` sweep must satisfy to *run* these). This skill *grades* the axis; the `e2e-test` sweep *runs* it.
4
+
5
+ The **Presentation** axis (third axis) rides the [Surface Baseline Contract](../breadth/surface-baseline.md) machinery as a per-route floor. Every live browser route auto-carries a presentation obligation *on top of* its `browser-journey` floor, checked at the viewport floor `[375, 1280]` (default theme, seeded data).
6
+
7
+ > **This skill grades the axis; it does not run it.** The tokens below are *graded* by the Coverage Ledger (does a qualifying real-render test exist, is it non-intercepting, is it attested). The *instruments* that open a browser and observe these invariants live in the **`e2e-test` skill's presentation sweep**. ensure-coverage owns the **contract** — [runner-contract.md](runner-contract.md) (the interface a repo's sweep must satisfy and the per-`(route, level)` result shape the ledger consumes) — not the runner. This mirrors how breadth delegates surface discovery to an inventory adapter ([../breadth/inventory-contract.md](../breadth/inventory-contract.md)).
8
+
9
+ Invariants, **spine first**:
10
+
11
+ - **`presentation:render-health`** *(spine)* — the page renders without a **`pageerror` (uncaught exception), a `console.error`, a rendered error boundary, or an HTTP `>= 500`** on the document or any first-party request it issues. The cheapest, most foundational check — an uncaught `TypeError` on mount fails here before any layout question is asked — so every other presentation level sits on it. A green functional journey sails past it when the route's only test intercepts its own API. **Continuous, not load-only**: it must also hold *through* the interactions the other instruments drive — a `presentation:temporal` trigger, a `presentation:perceivability` post-delete mutation, a mutation-form journey's submit — so an error / `console.error` / first-party 5xx fired *during a write* fails too. (This is "mutate-health": render-health composed with the trigger/mutation pattern, not a separate axis — compose with those checks rather than re-driving the form.)
12
+ - **`presentation:spatial`** — laid out without collision: no unintended horizontal overflow **and** no unintended element overlap (bounding-box intersection) at the floor viewports. Intentional z-stacks (carousels, badges, sticky headers) are suppressed only via a **gated allowlist** (`category` + `reason`, surfaced in a census); an overlap occluding a **reachable interactive element can never be allowlisted**.
13
+ - **`presentation:perceivability`** — controls are visible/distinguishable (WCAG contrast), and things that must be *absent* are gone (negative form: a role-gated control not visible to the wrong role; a deleted item does not linger).
14
+ - **`presentation:reachability`** — a user can get to the page and tell its controls are actionable: every manifest route is reachable by crawling the rendered nav (no **navigational orphan**), interactive controls show a visible focus indicator and meet the ≥44px target floor. Negative form: a modal traps focus (no click-through / focus escape); a privilege-gated route is not navigationally reachable for the wrong role.
15
+ - **`presentation:temporal`** — the layout holds still as things inject. **Split by who renders the shift** — *first-party* (lazy images, async data, our dynamic fields) is a **hermetic gate** (real render, no network; before/after geometry gated on a stable condition, never a fixed sleep, or a `PerformanceObserver` CLS score). *Third-party* (Stripe/Adyen payfields) runs against the provider **sandbox iframe** in a **non-blocking PR lane**: a failure posts a visible annotation and the surface stays `Unverified` until a reviewer attests. Top-page CLS is **structurally blind to cross-origin iframes** (WICG excludes descendant frames), so this is a before/after geometry assertion gated on a provider-ready signal, not CLS. The mobile **dynamic-viewport (`dvh`/`100vh`) cell** is gated via Playwright emulation with a tuned tolerance (staging fallback if flake is unmanageable).
16
+
17
+ "Graded" means the ledger marks a route's floor `Missing` / `Over-mocked` / `Unverified` / `Covered` from the tests that exist — it cannot itself detect a runtime crash, which is why the sweep is a **separate, mandatory CI job** ([../enforcement/ci-contract.md](../enforcement/ci-contract.md)), not a side effect of the functional E2E suite.
18
+
19
+ The floor runs at the screen viewport floor (`[375, 1280]`). The **`media=print` cell is warn-only by default** — a broken print stylesheet is logged in the census, not a blocking gate (lower-frequency, harder to assert deterministically). A surface may escalate it to a gate when print output is a real product surface (e.g. an invoice).
20
+
21
+ ## Feature-derived escalation (the condition matrix grows itself)
22
+
23
+ The floor above is the fixed minimum; the adapter then *raises* it from deterministic code **signals**, adding cell-qualified obligations (e.g. `presentation:perceivability@dark`) so two agents on the same code compute the same set:
24
+
25
+ | signal (adapter-derived) | adds |
26
+ |---|---|
27
+ | a dark-mode/theme toggle | `presentation:perceivability@dark` (contrast must also hold in dark theme) |
28
+ | an i18n library | `presentation:spatial@long-locale`, `presentation:spatial@rtl` (layout must survive long locales + RTL) |
29
+
30
+ A cell-qualified level grades exactly like its base (real render, exact-match, DOM-only → `Over-mocked`). **Adding cells is free; a check can never be made weaker; a cell may be removed only through the gated `excludeCells` path** (`category` + `reason`, surfaced in the census); the base mechanical floor (unqualified levels) can never be removed. This mirrors the Surface Baseline Contract's raise-only + gated-exclusion rule.
31
+
32
+ > **Navigational vs guard-chain reachability.** `presentation:reachability` is **navigational** ("can a user *click* here from an entry point") — *not* the guard-chain [Route Discovery & Reachability Protocol](../breadth/surface-discovery.md) ("can the URL load past middleware/auth"). A route can be guard-reachable yet navigation-orphaned. Both matter; different checks.
33
+
34
+ > **Affordance ↔ `impeccable` boundary.** The *deterministic* affordance checks live here (focus-indicator **presence**, target size, nav-orphan). The *aesthetic/holistic* judgment (is the focus style good, is a11y resilient under zoom/AT) stays in `impeccable` (`reference/harden.md`). This axis proves the cue **exists**; impeccable judges whether it's good.
35
+
36
+ ## Proven only against a real rendered page
37
+
38
+ A presentation level is **exact-match** and proven only against a **real rendered page**:
39
+
40
+ - A functional `browser-journey` does **not** satisfy a presentation level — a journey clicks the DOM; it never asserts no-overflow or perceivability. Each is required separately; one presentation level does not satisfy another.
41
+ - A DOM-only / JSDOM assertion of a presentation level grades **`Over-mocked`** — the axis's proxy-wiring (it can't see what a human sees). The proving test must drive a real browser.
42
+ - Like any obligation, a statically-satisfied presentation level lands at blocking `Unverified` until reviewer-attested.
43
+
44
+ **State-aware, abstain-on-doubt.** A check is deterministic only where element state is unambiguous; where it cannot decide it **abstains → blocking `Unverified`**, never a silent pass. Disabled controls are *intended* low-contrast (WCAG exempts them), so the perceivability check derives state (`aria-disabled`/`[disabled]`) and skips them. axe-core's contrast rule **abstains** ("incomplete") on text over a background-image/gradient — the invisible-control case — and that abstain blocks until reviewer attestation (`verified: true`, after manual check) **or** escalation to a stronger instrument. **AI-vision is triage-only**: it may flag for human attestation but never promotes an obligation to `Covered` (run-to-run non-determinism).
45
+
46
+ Non-browser surfaces (`api`/`table`/`event`/`job`) carry **no** presentation floor.
47
+
48
+ ## `presentation:visual` — opt-in pixel-baseline regression
49
+
50
+ The floor invariants above are *structural* and auto-applied: they prove a page renders, doesn't overflow, and is perceivable, but not that it *looks* right. `presentation:visual` is the **opt-in** level that pins the rendered appearance against a committed pixel baseline and fails on drift — catching the restyle/wrong-content/visually-broken-but-not-erroring class the other levels miss.
51
+
52
+ It is **not** part of the auto-floor. A surface earns it only by declaring `presentation:visual` in its curated `*.coverage.yml` (the raise-only path of the [Surface Baseline Contract](../breadth/surface-baseline.md)) — a baseline is a maintenance liability, so which routes deserve it is a per-surface breadth decision. Once declared it grades like its siblings: **exact-match, real-render** (a DOM/JSDOM snapshot can't see pixels → `Over-mocked`), statically-satisfied lands at blocking `Unverified` until attested. Distinctive grading hooks:
53
+
54
+ - The proving evidence is the **committed baseline PNG(s)** at the floor viewports — a cell with no committed baseline is `Missing`.
55
+ - A **baseline diff** grades as coverage only when tied to a *declared* intended UI change (`review-pr` blocks a silent `--update-snapshots` to green — the visual analogue of no-skip-to-green).
56
+ - It is **CI-only**, in a pinned container; run mechanics, determinism rules (mask/freeze/threshold), and the two CI jobs live in [runner-contract.md](runner-contract.md) and [../enforcement/ci-contract.md](../enforcement/ci-contract.md). AI-vision stays triage-only — a pixel baseline is the deterministic instrument; vision can flag, never promote.
57
+
58
+ ## `presentation:fidelity` — does it match the design source it came from?
59
+
60
+ Every level above is **self-referential**. render-health asks whether the page renders, perceivability whether a human can act on it, and `presentation:visual` whether it drifted from *its own* committed baseline. None of them asks the question a unit built from a prototype, mockup or design doc actually owes: **does this match the thing it was supposed to be derived from?**
61
+
62
+ That gap is not theoretical. A baseline captured from a wrong implementation is green forever — in the incident below it would have locked in a card plane the design did not have and a flattened type scale, and reported success. Drift detection cannot substitute for fidelity, because it takes the implementation as its own authority.
63
+
64
+ **When it is owed.** A unit whose source cites a design artifact — a prototype branch/path, a mockup, a design doc that fixes layout — carries `presentation:fidelity` on the surfaces that artifact covers. A unit with no cited design source does not; this is not an auto-floor and inventing one for a CRUD tweak is ceremony.
65
+
66
+ **The rule that makes it fidelity.** Every expected value is read off the **source**, with it rendered, and cites the source line it came from. A value copied off the page you built is a baseline wearing a fidelity label.
67
+
68
+ **Why it is not a differ.** The obvious instrument diffs source against implementation, and it only works when both are the same stack. An HTML prototype, a v0 export or a Figma frame against a React deliverable defeats it immediately. So the work splits where it actually divides: **comparing across technologies is judgment; checking against an extracted spec is mechanical.** A human reads both, rendered, once, and writes the load-bearing properties down in units that survive a stack change — computed pixels, not `sm:text-3xl`. That parity manifest is the interchange format and the only step needing eyes. Everything after it mechanizes:
69
+
70
+ - `scripts/design-parity.mjs scaffold` emits the manifest skeleton from a **doctrine-fixed catalog** — page measure, container plane (three properties: a card returns through whichever one you left unpinned), primary/secondary type scale **per floor viewport**, box padding, coupled-element rhythm, and one relational row (`primary.font-size > secondary.font-size`) that survives both a stack change and a token change. The catalog is the anti-omission device: the rows you would have forgotten are already in the file, and a row may be **rejected with a written reason but never silently omitted**.
71
+ - `design-parity.mjs probe <manifest> --viewport <px>` emits the JS that measures the built page; its output is the results file. `e2e-test` or `agent-browser` drives it — this skill owns what must be proven, not the runner.
72
+ - `design-parity.mjs validate <manifest> --observed <results.json>` is the gate. Without `--observed` it announces itself as the **reduced form**: it checks the manifest is complete and its citations resolve, never that the page conforms.
73
+
74
+ **No rewriting the target to match the page.** The cheapest way to green this gate is to stop fixing the page and edit `expected` instead — the same move as a bare `--update-snapshots`, except easier, because it is one character of YAML rather than a regenerated PNG and leaves no image in the diff to notice. It is also mechanically detectable, thanks to the property that makes this fidelity: **the source is pinned and therefore immutable**. If `source.sha` has not moved and the row's `from:` line has not moved, the value read off that line cannot have changed. So `design-parity.mjs validate --diff <base>` blocks a changed `expected` under an unmoved source, and a genuine mis-read clears it by saying so — `rebase: <reason>` on the row, the same declared-intended-change shape the visual baseline already uses. When the source itself is re-pinned, expectations are *supposed* to move: that warns rather than blocks. `review-pr` treats an undeclared rewrite as a blocker, exactly as it does a silent re-baseline.
75
+
76
+ **The render is not optional.** A property list catches what someone thought to list. Before the terminal review, render source and deliverable at the floor viewports `[375, 1280]` and put them **side by side** in the PR. This is the check that fails when the manifest itself is incomplete, and it is the cheapest one here.
77
+
78
+ **Named incident (fmm-express #521, 2026-08-06).** A settled prototype was cited by exact branch and path in the issue, summarized **once** into four prose bullets, and every downstream artifact — issue, criteria doc, tests, code — descended from the summary rather than the source. What the summary dropped (page measure, card plane, the primary input's responsive type steps, the secondary field's scale) was then unfindable: nothing re-read the source and nothing rendered it — one image in a 3,040-message session, pasted by the user. The criteria doc listed "visual screenshot baselines" under **Non-goals** on a unit whose entire content was visual, so a fully green suite shipped a page that took four rounds of user correction. Hence two hard rules: a presentation-only unit **may not** list visual/parity evidence as a non-goal, and a cited design source is **consumed, not summarized**.
@@ -0,0 +1,74 @@
1
+ # Presentation Runner Contract
2
+
3
+ The presentation axis is **graded** by the Coverage Ledger but **run** by a real browser the ledger never launches. This file is the interface between the two: what a repo's presentation sweep must do, and the per-`(route, level)` result shape the ledger consumes. It is the presentation-axis sibling of [../breadth/inventory-contract.md](../breadth/inventory-contract.md) (which is the breadth-axis discovery contract).
4
+
5
+ The reference implementation of this contract ships in the **`e2e-test` skill** (`scripts/presentation-render-health.mjs`, `presentation-checks.mjs`, `presentation-sweep.mjs`, …). ensure-coverage owns the contract; `e2e-test` owns the runner. A repo may use the reference runner as-is or supply its own as long as it satisfies this contract.
6
+
7
+ ## Why a runner is needed at all
8
+
9
+ `coverage-ledger.mjs` is a static analyzer: it proves *a qualifying test was authored* (real-browser, non-intercepting, `@covers <route>` at `@level presentation:*`, attested) and can mark a route's floor `Missing` / `Over-mocked` / `Unverified` / `Covered`. It **cannot** observe a `pageerror`, an overflow, or a layout shift — only a browser opening the real page can. So the gate has two halves: **accounting** (`coverage-ledger.mjs validate` — is the obligation owned and proven by a clean test?) and **rendering** (this sweep — does the page pass the invariant when opened for real?). A repo that wires only accounting ships crashing routes with a green board.
10
+
11
+ ## What the sweep must do
12
+
13
+ Given the generated route manifest (the same `kind: "route"` surfaces emitted per [../breadth/inventory-contract.md](../breadth/inventory-contract.md)):
14
+
15
+ 1. **Open every manifest route in a real browser** (Chromium) at the viewport floor `[375, 1280]` — `PRESENTATION_VIEWPORT_FLOOR`, the ledger constant. Do **not** sample or top-N silently; if you bound coverage, `log` what was dropped.
16
+ 2. **Drive the real render path — no first-party interception.** `page.route('**/api/**')`, `route.fulfill`, MSW for owned paths, or first-party fixtures **disqualify** the run for that route (a sweep faking its own backend proves proxy wiring). Externals (Stripe, third-party APIs) may be faked. Mirrors the ledger's `INTERCEPT_RE` rule — a route proven only behind an interception is `Over-mocked`.
17
+ 3. **Assert the floor invariants, spine first**, recording a result per `(route, level, viewport)`:
18
+ - `presentation:render-health` *(spine)* — no `pageerror`, no `console.error`, no rendered error boundary / framework overlay, no HTTP `>= 500` on the document or any first-party request. **Continuous, not load-only**: the sweep asserts it at load, and authored journeys keep the watcher attached *through* their interactions (the `temporal` trigger, the `perceivability` post-delete mutation, the mutation-form submit) so an error fired *during a write* fails too ("mutate-health"). The sweep itself proves only the load path — write paths are destructive and need authored journeys.
19
+ - `presentation:spatial` — no unintended horizontal overflow, no unintended element overlap.
20
+ - `presentation:perceivability` — contrast / no invisible-but-present controls (+ negative forms).
21
+ - `presentation:reachability` — navigational reachability + affordance cues (focus indicator present, ≥44px target).
22
+ - `presentation:temporal` — first-party shift is a hermetic gate; third-party shift runs against the provider sandbox in a non-blocking lane.
23
+ 4. **Abstain, never silently pass.** Where state is ambiguous (contrast over a gradient/image, a route unreachable because seeding failed), emit `unverified` — it blocks until attested or escalated. Where the environment cannot render at all (no `DATABASE_URL`, auth unavailable), emit `blocked`, **not** `pass`. "Could not check" is never "checked and fine."
24
+
25
+ ## Visual regression — the opt-in `presentation:visual` level
26
+
27
+ The floor invariants are auto-applied and assert *structural* facts; none catches a surface that renders cleanly, passes contrast, and is laid out without collision yet *looks wrong* (wrong content, a restyled component). `presentation:visual` closes that gap: it captures the rendered page and **fails when it drifts from a committed reference image**.
28
+
29
+ Unlike the floor levels, **`presentation:visual` is opt-in, never auto-floored** — a surface carries it only when its curated `*.coverage.yml` declares it (the raise-the-level path of the [Surface Baseline Contract](../breadth/surface-baseline.md)). A pixel baseline is a maintenance liability (every intended UI change re-baselines), so which routes deserve it is a per-surface breadth decision. The reference runner uses **Playwright's built-in `toHaveScreenshot()`** — baselines, 3-up diff, `mask:` regions, and the `maxDiffPixelRatio` threshold are all native.
30
+
31
+ **CI-only, in a pinned container — non-negotiable.** A baseline generated on one OS and gated on another fails on every glyph's anti-aliasing, and a visual gate that reds on every PR gets disabled. So **both** baseline generation and the gate run only in CI inside a pinned Playwright image (`mcr.microsoft.com/playwright:vX.Y`). Two CI jobs realize this ([../enforcement/ci-contract.md](../enforcement/ci-contract.md)): a blocking **`visual-gate`** and an on-demand **`visual-baseline-regen`** (label/dispatch-triggered `--update-snapshots`, commits the PNGs back). The in-loop hooks never run it ([../enforcement/hooks.md](../enforcement/hooks.md)).
32
+
33
+ **Determinism is the surface's obligation.** Before the snapshot: animations/transitions disabled, clock frozen, data seeded, and every known-dynamic region (timestamps, avatars, live counts) covered by a `mask:` locator — a *gated concession* declared with a `reason`, surfaced in the census, so masking can't silently grow to hide a regression. The threshold is a **tight** `maxDiffPixelRatio` for sub-pixel AA noise, never loose enough to swallow a real change.
34
+
35
+ **A baseline change is reviewable evidence.** The committed PNGs are the durable record; a diff to them must be tied to a *declared* intended UI change in the Review Contract, never a silent `--update-snapshots` to green (`review-pr` enforces this). After regen, the durable baseline link (at the SHA) plus the ephemeral diff-preview URL are posted back to the work item and **returned as a value** (`--evidence-out`, plus stdout) for the `resolve-issues` orchestrator to record on the unit — the evidence-posting step in [../enforcement/ci-contract.md](../enforcement/ci-contract.md). The regen job does **not** write the run manifest itself; the orchestrator is its only writer (ADR 0001 decision 5 (`docs/adr/0001-interference-is-the-scheduling-primitive.md`)).
36
+
37
+ ## Fixtures the sweep needs (repo-supplied)
38
+
39
+ These are repo-specific, like inventory discovery. The reference runner parameterizes them:
40
+
41
+ - **Auth** — a deterministic bypass/seeded session so guarded routes render as a real user (e.g. an `E2E_AUTH_BYPASS` cookie). A login wall is not a render pass.
42
+ - **Seed** — deterministic data so `read`/`detail` routes render real content and `mutation` routes have something to act on. An empty-state-only render does not prove the populated page.
43
+ - **Param substitution** — dynamic segments (`/tasks/[id]`) need a concrete seeded id per route. A route whose param cannot be resolved is `blocked`, not skipped.
44
+ - **Allowlist** — intentional overlap/z-stack suppression is a *gated* allowlist (`category` + `reason`, surfaced in a census); an overlap occluding a reachable interactive control can never be allowlisted.
45
+
46
+ ## Result shape the ledger consumes
47
+
48
+ Emit JSON to `docs/tests/_generated/presentation-results.json`:
49
+
50
+ ```json
51
+ {
52
+ "viewportFloor": [375, 1280],
53
+ "results": [
54
+ { "route": "/tasks", "level": "presentation:render-health", "status": "fail",
55
+ "evidence": "pageerror: Cannot read properties of undefined (reading 'id') at TasksToolbar" },
56
+ { "route": "/tasks", "level": "presentation:spatial", "status": "blocked",
57
+ "evidence": "render-health failed; layout not assessable" },
58
+ { "route": "/dashboard", "level": "presentation:render-health", "status": "pass" },
59
+ { "route": "/dashboard", "level": "presentation:visual", "status": "fail", "viewport": 1280,
60
+ "evidence": "12.4% pixels differ from baseline (maxDiffPixelRatio 0.001)",
61
+ "baseline": "e2e/dashboard.spec.ts-snapshots/dashboard-1280-chromium-linux.png",
62
+ "diffArtifact": "https://…/artifacts/visual-diff (expires 2026-09-13)" }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ - `status` — `pass | fail | unverified | blocked`. `fail` and `blocked` exit the sweep non-zero (gate fails). `unverified` blocks the ledger until attested.
68
+ - `evidence` — the concrete observation (the actual `pageerror` text, offending selector + overflow px, the unreachable param, the percent-pixels-differ for `presentation:visual`). Name the failure, not "presentation partial."
69
+ - For `presentation:visual` only: `viewport` (which floor viewport this cell covers — visual is captured per viewport), `baseline` (the committed reference PNG the gate compared against — the durable evidence), and `diffArtifact` (the ephemeral 3-up diff URL on failure, with its expiry). These flow into the evidence-posting step.
70
+ - The ledger reconciles these against each route's required presentation levels: a `fail`/`blocked`/missing result on a required level is a finding; a `pass` is a *lead* that still needs a clean authored test + attestation to reach `Covered` (a sweep run is execution evidence, not authored coverage).
71
+
72
+ ## Relationship to the functional E2E suite
73
+
74
+ The sweep is a **separate gate** from the functional/journey E2E suite, though both use Playwright: the functional suite clicks the DOM and may legitimately intercept externals; the sweep opens the real render path and asserts perceivability. A green functional suite satisfies **no** presentation level ([axis.md](axis.md)). CI placement: [../enforcement/ci-contract.md](../enforcement/ci-contract.md).
@@ -0,0 +1,33 @@
1
+ # Audit Mode (process)
2
+
3
+ > Read when: auditing whether existing code/tests cover a requirement, PR, issue, feature, or bugfix. Audit current sufficiency against the behavior-first criteria; do not only generate ideal future criteria. Coverage classifications used here are defined in [../depth/grading.md](../depth/grading.md).
4
+
5
+ Audit steps:
6
+
7
+ 1. Derive ACs from the source before inspecting implementation details.
8
+ 2. Identify public interfaces, workflows, state transitions, side effects, code paths, and existing tests.
9
+ 3. For E2E audit, run the [Route Discovery & Reachability Protocol](../breadth/surface-discovery.md) before judging coverage.
10
+ 4. Identify critical journeys with actor/role, start state, trigger, major steps, expected end state, route reachability, and observable side effects.
11
+ 5. Map each AC and journey to existing tests only after inspecting the actual test files/cases/assertions; prior docs, PR summaries, or agent reports are leads, not proof.
12
+ 6. Reject coverage that only validates private functions, implementation structure, or shallow route render-health checks for business journeys.
13
+ 7. Create follow-up items for every gap with required test level, setup/input, assertions, mock/fake policy, and evidence.
14
+ 8. Reach a production-readiness verdict — an explicit ship / no-ship call, the specific scenarios a real user would hit in the first week, and the evidence that would raise confidence — and **put it at the TOP of the deliverable** (the reader's first question is "what's the call?"; the census and detail justify it below). Do not let mapped ACs alone earn a ship call. Separate **blocking decisions** (product/scope choices that change the verdict and need a human answer) from **follow-up actions** (work to schedule) — see the output template; don't dump both into one vague "open questions" list.
15
+ 9. Audit the **enforcement wiring** against [../enforcement/ci-contract.md](../enforcement/ci-contract.md), not just the tests: does the repo run the accounting gate *and* a separate render sweep over the manifest? A repo can have clean doctrine and still ship a crashing route because the sweep gate is absent, in warn-only/phase-in mode, or the route is missing from the inventory. Run the meta-gate — `scripts/ci-audit.mjs --files <ci configs>` — which reports each required gate as present / warn-only / absent; a missing or weakened render-sweep gate is itself a finding, independent of any single test.
16
+ 10. **Run the over-mock scan WHOLE-TREE as part of the depth audit** — it mechanically finds `Over-mocked` (a test that fakes the first-party seam it claims to exercise), **zero-tolerance** ([../depth/mock-policy.md](../depth/mock-policy.md)). Run it **from this skill against the target repo** (the scripts live here, not in the audited repo — their absence there is expected, not a reason to skip):
17
+ ```
18
+ node <path-to-this-skill>/scripts/lint-tests.mjs --rules mock-internal-seam # whole-tree: every test file, not just the diff
19
+ ```
20
+ - **Always run it, even with no `coverage.config.json`** — default-on, config-independent (config only declares topology); a missing config means "run on defaults" (conventional `@/`/`~/`-aliased repo), not "not applicable." Whole-tree (no `--diff`): inherited mocks aren't grandfathered.
21
+ - **Each hit is an `Over-mocked` census row and an automatic no-ship contributor.** **Quantify the count in the verdict** — never compress to "advisory mock debt." Resolution: replace with a real-boundary test, fake only the external, or **delete** (over-mock is worse than no test); no `@mock-ok` waiver. Deleting reverts the route to its honest breadth status (`Missing`/`Excluded`).
22
+ - A **non-conventional topology** (e.g. a monorepo `@acme/` scope, generated dirs) earns a "declare topology in `coverage.config.json`" follow-up — never "gate not available," never a reason to downgrade the finding.
23
+ 11. If code/tests or route discovery cannot be inspected/run, mark assessment `BLOCKED` and state the missing access, files, or command failure. ("The lint script isn't in the audited repo" is *not* BLOCKED — the script is part of this skill; run it from here.)
24
+
25
+ The coverage classifications (`Covered` / `Partial` / `Missing` / `Wrong Level` / `Over-mocked` / `Unverified` / `Excluded` / `BLOCKED`) are defined in [../depth/grading.md](../depth/grading.md). Use that vocabulary, not a vague "covered."
26
+
27
+ ## Completeness: enumerate every surface, not just the salient gaps
28
+
29
+ **Gap-finding must be exhaustive, not a highlight reel.** An audit that lists "the top 3 problems" silently leaves the long tail uncovered — where the un-ACed orphan hides. Completeness comes from **closed-world enumeration**:
30
+
31
+ 1. **Start from the full surface inventory** (every route, API, write form, table, event, job — from [surface discovery](../breadth/surface-discovery.md) / the generated inventory), not the list of things you happened to notice.
32
+ 2. **Emit a complete surface census**: one row per inventoried surface with its status. `gaps = inventory − {surfaces at Covered}`, so every surface is accounted for *by construction*. The census is the deliverable's backbone (the **Surface Census** table in [output-template.md](output-template.md)); the prose highlights the worst rows, but the table proves nothing was skipped.
33
+ 3. **Every non-`Covered`/non-`Excluded` row is a gap** with its own follow-up item. If the inventory cannot be fully enumerated (no adapter, partial access), say so and mark the unenumerated portion `BLOCKED`; do not silently scope to what was easy to see.
@@ -0,0 +1,139 @@
1
+ # Output Template, Writing Rules & Validation (process)
2
+
3
+ > Read when: producing the criteria/audit document (create mode), or running the final self-check before saving.
4
+
5
+ ## Lead with the verdict
6
+
7
+ An **audit deliverable opens with the verdict**, not buries it under tables. Put a one-line `## Verdict: Ship / No-ship` (with the one-sentence reason) as the **first section**, before the Surface Census and the detailed assessment, which then *justify* it below. (Create-mode criteria docs lead with Source/Scope — there's no verdict yet.)
8
+
9
+ **Quantify the debt that drives the verdict — a no-ship is a number, not a vibe.** A `No-ship` carries the **magnitudes** that make it no-ship, in the verdict itself: counts of uncovered surfaces, orphan surfaces, ledger warnings, skipped tests, and **over-mock findings** (the `mock-internal-seam` count is a zero-tolerance, automatic no-ship contributor — [../depth/mock-policy.md](../depth/mock-policy.md)). "Coverage is still partial" drops the evidence the reader needs to size the work. **If a finding has a count, the count goes in the summary** — "it doesn't block CI yet" is never a license to omit it.
10
+
11
+ ## Writing Rules
12
+
13
+ - Make each AC independently testable.
14
+ - Prefer observable outcomes over internal implementation details.
15
+ - Include negative cases and misuse paths, not only happy paths.
16
+ - For async/pub-sub/orchestrator systems, require correlation IDs and final durable state assertions.
17
+ - For idempotent APIs, require duplicate request tests and concurrent request tests when money/state transitions are involved.
18
+ - For security-sensitive flows, require authorization tests for cross-tenant/cross-merchant access.
19
+ - For provider integrations, use fake adapters in integration tests and real providers only in staging smoke tests.
20
+ - Avoid vague criteria like “works correctly,” “fast,” or “secure”; replace them with measurable expectations.
21
+
22
+ ## Output Template
23
+
24
+ Use this structure unless the user asks for another format:
25
+
26
+ ```markdown
27
+ # Test Criteria: <feature/task name>
28
+
29
+ ## Source
30
+ - Input: <PRD/design document/spec/bug brief/GitHub issue/code audit source name or link>
31
+ - Version/date: <if available>
32
+ - Author/owner: <if available>
33
+
34
+ ## Scope
35
+ - In scope: <behaviors covered>
36
+ - Out of scope: <behaviors intentionally excluded>
37
+ - Assumptions: <behavior inferred from issue/context/sibling flows because source is incomplete>
38
+ - Blockers: <product/access/env decisions that prevent precise criteria>
39
+ - Design source: <the prototype ref:path / mockup / layout-fixing doc this unit is built from, pinned at a commit — or `none`>
40
+
41
+ > **"Out of scope" cannot exclude the axis the unit is about.** Scope excludes *behaviors*; it is not a place to retire an axis of proof. The named incident (fmm-express #521) is one line in this section: a charge-screen unit whose entire content was visual listed *"Non-goals: visual screenshot baselines"*, and a fully green suite then shipped a page that took four rounds of user correction. If the unit cites a **Design source** above, its criteria owe `presentation:fidelity` — a parity manifest and the side-by-side render ([../presentation/axis.md](../presentation/axis.md)) — and writing that evidence off here is declaring the point of the work out of scope. The reverse is fine and common: a unit with no design source simply says `none`.
42
+
43
+ ## Acceptance Criteria
44
+ - AC1: <actor/system does ... under condition ... with expected observable result>
45
+ - AC2: <...>
46
+
47
+ ## Critical User/System Journeys
48
+ - J1: <actor/role starts from ... does ... and reaches ... with expected side effects>
49
+ - J2: <...>
50
+
51
+ ## Test Matrix
52
+ | Scenario | AC/Journey | Test Level | Mock/Fake Policy | Setup/Input | Assertions | Required Evidence |
53
+ |---|---|---|---|---|---|---|
54
+ | Happy path | AC1 / J1 | Integration/API | Real DB + fake external provider | ... | ... | CI test name/log |
55
+ | Invalid input | AC2 | Unit + API | Mock provider only to assert it is not called | ... | ... | CI test name/log |
56
+
57
+ ## Mock And Integration Policy
58
+ - Mock acceptable: <pure decision logic, provider failures, asserting side effect is not called>
59
+ - Integration required: <DB transactions, idempotency, concurrency, event/outbox, auth/tenant isolation, schema compatibility>
60
+ - External dependency strategy: <fake provider adapter, emulator, test container, staging smoke test>
61
+ - Mock-only exceptions: <AC/scenario + explicit justification + reviewer approval — applies ONLY to the non-seam mock-only judgment; mocking a first-party internal seam is gate 5 (`mock-internal-seam`), zero-tolerance, NOT an approvable exception — see [../depth/mock-policy.md](../depth/mock-policy.md)>
62
+
63
+ ## Required Automated Tests
64
+ - Unit: <specific logic and edge cases>
65
+ - Integration: <DB/broker/provider fakes/state transitions>
66
+ - Contract/API: <request/response/schema guarantees>
67
+ - API E2E: <endpoint behavior with state/side-effect assertions, if needed>
68
+ - UI E2E: <page route render-health/functional browser behavior, if needed>
69
+ - Journey E2E: <cross-page/core business flow with real APIs where practical, if needed>
70
+
71
+ ## Coverage Mapping
72
+ | Requirement/Journey | ACs | Test Case/File | Status |
73
+ |---|---|---|---|
74
+ | <REQ-1 / J1> | AC1, AC2 | <path::test_name> | Required |
75
+
76
+ ## Surface Census (Audit Mode Only — every surface, not just the gaps)
77
+ One row per inventoried surface so completeness is provable by construction: gaps = every row not `Covered`/`Excluded`. If the inventory can't be fully enumerated, say so and mark the rest `BLOCKED` — do not quietly scope to what was easy to see.
78
+ | Surface | kind/class | Required level | Status | Proving test (or — ) |
79
+ |---|---|---|---|---|
80
+ | /settings/team | route/mutation | browser-journey + presentation | Over-mocked | e2e/team.spec.ts (intercepts own API) |
81
+ | /settings/team/members | route/mutation | browser-journey + presentation | Missing | — (orphan, no test) |
82
+ | /api/team/invite | api/mutation | api + integration | Partial | tests/api/invite.test.ts |
83
+ | ... (every remaining surface) | ... | ... | ... | ... |
84
+
85
+ ## Existing Coverage Assessment (Audit Mode Only)
86
+ - Production-readiness verdict: <Ship / No-ship>, with the specific user scenarios likely to generate bug reports in the first week and the evidence that would raise confidence. **State the driving counts** (uncovered/orphan surfaces, ledger warnings, skips, over-mock findings) — a no-ship names its numbers, including advisory-scan counts; it does not hide them behind "partial."
87
+ - Current coverage status: <Covered / Partial / Missing / Wrong Level / Over-mocked / Unverified / BLOCKED>
88
+ - Existing tests reviewed: <actual paths/test names/cases/assertions inspected; do not list docs-only claims as reviewed tests>
89
+ - Code paths reviewed: <paths/modules>
90
+ - Route/endpoint discovery: <method/command/source used, discovered count, manifest count, missing/stale/uncovered entries>
91
+ - Route reachability: <Reachable / Redirected / Guarded / Blocked / Unknown per relevant route, with layout/middleware/guard evidence>
92
+ - E2E journeys identified: <journey list or Not applicable>
93
+ - E2E journey coverage: <journey -> API/UI/Journey E2E evidence/status>
94
+ - Prior coverage docs/reports checked: <None or list; state which claims were verified against test code>
95
+ - Coverage gaps: <missing scenarios, weak assertions, over-mocking, wrong level, uncovered journeys, unverified claims, or None>
96
+ - Follow-up test criteria items: <specific tests to add/update, with AC/journey mapping>
97
+
98
+ ## Test Skipping
99
+ - Skipped tests: <None or list with allowed category, evidence/blocker link, and replacement verification>
100
+
101
+ ## Behavior-First Validation
102
+ - ACs describe externally observable behavior, not private functions.
103
+ - Test matrix scenarios validate outcomes, durable state, contracts, side effects, permissions, and failure behavior.
104
+ - Unit tests are scoped to public behavior, pure decision logic, or stable public contracts.
105
+ - Mock-only coverage does not bypass the core behavior under test.
106
+ - Existing coverage claims were verified against actual test code, not trusted from prior docs/reports.
107
+ - Route discovery and reachability analysis were performed before E2E audit, if applicable.
108
+ - Production-readiness verdict is stated as an explicit ship/no-ship call with named first-week bug-report scenarios, not a vibe.
109
+ - Status: PASS / FAIL / BLOCKED
110
+ - Required revisions before approval: <None or list>
111
+
112
+ ## Reviewer Checklist
113
+ - Obligation impact stated: which obligations/surfaces this change touches, their `requirementRefs`, and the evidence that proves each.
114
+ - No `Orphan surface` introduced: every changed/new surface is referenced by at least one requirement and has a Coverage Ledger row.
115
+ - Every changed/new page with a write form has a mutation-form journey test that fills the real UI and asserts the backend accepts the submission; split-contract forms (fields and validator from different sources) are not signed off on seam tests alone.
116
+ - Every AC maps to an automated test or approved exception.
117
+ - Tests assert behavior/state, not implementation details only.
118
+ - No tests skipped/weakened to make CI pass; every (inherited) skip has an allowed category, evidence/blocker link, and replacement verification.
119
+ - Substitutes appear only at external trust boundaries; no internal seam (DB, service layer, internal endpoint, event bus) is mocked. Fakes/stubs keep failure-path/edge cases fast and deterministic and never call a live third party in CI; mocks/fakes don't bypass the core behavior.
120
+ - Mock-only coverage is rejected for stateful workflow, money movement, auth, idempotency, concurrency, event/outbox, or orchestrator recovery unless explicitly approved; money movement, auth, and idempotency can never be mock-only even with approval. (This approval path is the broader mock-only *judgment* only — mocking a first-party internal seam is the zero-tolerance `mock-internal-seam` gate 5, never approvable — resolve it by making the test real, faking only the external, or deleting it; see [the mock policy](../depth/mock-policy.md).)
121
+ - Failure, retry, duplicate, permission, and concurrency cases are covered where relevant.
122
+ - Test evidence is attached: CI link, command output, logs, screenshots, or traces.
123
+
124
+ ## Blocking Decisions (need a human answer to finalize the criteria)
125
+ Each entry is a product/scope decision you could NOT make yourself — phrase it so the reader knows exactly what to decide and why it matters. These are distinct from follow-up actions (which are just work to schedule); a blocking decision changes the criteria/verdict depending on the answer.
126
+ - Decision: <the choice to make> · Why it blocks: <which AC/scope/verdict is undetermined until this is answered> · If A → <consequence for the criteria/tests> · If B → <consequence>. Default if no answer: <the assumption you'll proceed on, marked `Assumption`>.
127
+ ```
128
+
129
+ ## Behavior-First Validation (the gate before saving)
130
+
131
+ After drafting, validate and revise before saving. Mark `BLOCKED` only when the source lacks enough information/access to define observable behavior. Reject criteria or audit claims that rely on:
132
+
133
+ - ACs phrased as calls to specific internal functions, or test matrices organized around implementation modules instead of user/system scenarios.
134
+ - Mock-heavy plans that never exercise state changes, API contracts, permissions, events, or side effects; or substitutes standing in for internal seams (DB, service layer, internal endpoints, event bus) instead of external trust boundaries.
135
+ - Requirement coverage mapped only to private-method/unit tests when integration, contract, or E2E is required.
136
+ - Coverage classified `Covered` from prior docs/PR summaries/audit reports/issue comments/CI/agent claims without inspecting actual test code/assertions.
137
+ - E2E audits that skipped deterministic route/endpoint discovery or reachability analysis.
138
+ - Audits driven only test-outward (mock census, existing-test mapping) without requirement-inward reconciliation, so `Orphan surface` gaps stay invisible.
139
+ - Reachable pages with write forms treated as covered by route/API/validator tests, without a mutation-form journey that fills the rendered UI and asserts the backend accepts the submission (split-contract form gap).