@iceinvein/agent-skills 0.21.2 → 0.21.5

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 (235) hide show
  1. package/package.json +3 -2
  2. package/skills/index.json +3 -3
  3. package/skills/migrate/SKILL.md +28 -3
  4. package/skills/migrate/docs/architecture.md +19 -7
  5. package/skills/migrate/docs/reference.md +19 -13
  6. package/skills/migrate/evals/README.md +168 -0
  7. package/skills/migrate/evals/adjudicate-drafts-not-decides/case.yaml +4 -0
  8. package/skills/migrate/evals/adjudicate-drafts-not-decides/fixture.sh +14 -0
  9. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/drafts-presented-to-owner.md +10 -0
  10. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/no-ruling-recorded.md +11 -0
  11. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/q-express-mailer-delivery-unobservable-still-open.md +8 -0
  12. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/q-express-user-list-source-still-open.md +8 -0
  13. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/q-express-users-table-unwired-still-open.md +8 -0
  14. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/q-tiny-express-enumerate-scaffold-still-open.md +8 -0
  15. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/review-sheet-read.md +8 -0
  16. package/skills/migrate/evals/adjudicate-drafts-not-decides/graders/skill-fired.md +5 -0
  17. package/skills/migrate/evals/adjudicate-drafts-not-decides/prompt.md +11 -0
  18. package/skills/migrate/evals/done-means-plain-check/case.yaml +4 -0
  19. package/skills/migrate/evals/done-means-plain-check/fixture.sh +38 -0
  20. package/skills/migrate/evals/done-means-plain-check/graders/answers-not-finished.md +10 -0
  21. package/skills/migrate/evals/done-means-plain-check/graders/ran-plain-check.md +10 -0
  22. package/skills/migrate/evals/done-means-plain-check/graders/skill-fired.md +5 -0
  23. package/skills/migrate/evals/done-means-plain-check/graders/unsigned-delta-was-in-place.md +7 -0
  24. package/skills/migrate/evals/done-means-plain-check/prompt.md +11 -0
  25. package/skills/migrate/evals/extract-files-queue-in-same-pass/case.yaml +4 -0
  26. package/skills/migrate/evals/extract-files-queue-in-same-pass/enumerate/admin-router.js +7 -0
  27. package/skills/migrate/evals/extract-files-queue-in-same-pass/enumerate/census-routes.json +21 -0
  28. package/skills/migrate/evals/extract-files-queue-in-same-pass/enumerate/elements-dead-route.json +16 -0
  29. package/skills/migrate/evals/extract-files-queue-in-same-pass/fixture.sh +41 -0
  30. package/skills/migrate/evals/extract-files-queue-in-same-pass/graders/check-was-run.md +8 -0
  31. package/skills/migrate/evals/extract-files-queue-in-same-pass/graders/dead-route-accounted-for.md +13 -0
  32. package/skills/migrate/evals/extract-files-queue-in-same-pass/graders/no-check-saw-a-dangling-queue-id.md +12 -0
  33. package/skills/migrate/evals/extract-files-queue-in-same-pass/graders/queue-item-filed.md +5 -0
  34. package/skills/migrate/evals/extract-files-queue-in-same-pass/graders/skill-fired.md +5 -0
  35. package/skills/migrate/evals/extract-files-queue-in-same-pass/prompt.md +11 -0
  36. package/skills/migrate/evals/forecast-refuses-without-attestation/case.yaml +4 -0
  37. package/skills/migrate/evals/forecast-refuses-without-attestation/fixture.sh +10 -0
  38. package/skills/migrate/evals/forecast-refuses-without-attestation/graders/asks-owner-for-assumptions.md +10 -0
  39. package/skills/migrate/evals/forecast-refuses-without-attestation/graders/assumptions-not-written.md +8 -0
  40. package/skills/migrate/evals/forecast-refuses-without-attestation/graders/handoff-was-scaffolded.md +5 -0
  41. package/skills/migrate/evals/forecast-refuses-without-attestation/graders/skill-fired.md +5 -0
  42. package/skills/migrate/evals/forecast-refuses-without-attestation/prompt.md +11 -0
  43. package/skills/migrate/evals/handoff-blocked-reports-blockers/case.yaml +4 -0
  44. package/skills/migrate/evals/handoff-blocked-reports-blockers/fixture.sh +23 -0
  45. package/skills/migrate/evals/handoff-blocked-reports-blockers/graders/handoff-attempted.md +8 -0
  46. package/skills/migrate/evals/handoff-blocked-reports-blockers/graders/handoff-json-not-written.md +8 -0
  47. package/skills/migrate/evals/handoff-blocked-reports-blockers/graders/reopened-item-still-open.md +8 -0
  48. package/skills/migrate/evals/handoff-blocked-reports-blockers/graders/reports-the-blocker.md +10 -0
  49. package/skills/migrate/evals/handoff-blocked-reports-blockers/graders/skill-fired.md +5 -0
  50. package/skills/migrate/evals/handoff-blocked-reports-blockers/prompt.md +11 -0
  51. package/skills/migrate/evals/lib/express/01-init.sh +17 -0
  52. package/skills/migrate/evals/lib/express/02-phase-probe-done.sh +1 -0
  53. package/skills/migrate/evals/lib/express/03-queue-q-tiny-express-enumerate-scaffold.md +27 -0
  54. package/skills/migrate/evals/lib/express/04-import-elements-routes.json +61 -0
  55. package/skills/migrate/evals/lib/express/05-import-elements-tables.json +36 -0
  56. package/skills/migrate/evals/lib/express/06-import-elements-jobs.json +26 -0
  57. package/skills/migrate/evals/lib/express/07-import-elements-reports.json +26 -0
  58. package/skills/migrate/evals/lib/express/08-import-elements-screens.json +21 -0
  59. package/skills/migrate/evals/lib/express/09-import-elements-integrations.json +21 -0
  60. package/skills/migrate/evals/lib/express/10-import-elements-workflows.json +34 -0
  61. package/skills/migrate/evals/lib/express/11-import-elements-settings.json +36 -0
  62. package/skills/migrate/evals/lib/express/12-census-lens-routes.json +21 -0
  63. package/skills/migrate/evals/lib/express/13-census-lens-tables.json +21 -0
  64. package/skills/migrate/evals/lib/express/14-census-lens-jobs.json +21 -0
  65. package/skills/migrate/evals/lib/express/15-census-lens-reports.json +21 -0
  66. package/skills/migrate/evals/lib/express/16-census-lens-screens.json +21 -0
  67. package/skills/migrate/evals/lib/express/17-census-lens-integrations.json +21 -0
  68. package/skills/migrate/evals/lib/express/18-census-lens-workflows.json +21 -0
  69. package/skills/migrate/evals/lib/express/19-census-lens-settings.json +21 -0
  70. package/skills/migrate/evals/lib/express/20-phase-enumerate-done.sh +1 -0
  71. package/skills/migrate/evals/lib/express/21-seam-artifacts.sh +40 -0
  72. package/skills/migrate/evals/lib/express/22-phase-seam-done.sh +1 -0
  73. package/skills/migrate/evals/lib/express/23-import-reqs-extract.json +336 -0
  74. package/skills/migrate/evals/lib/express/24-queue-q-express-user-list-source.md +24 -0
  75. package/skills/migrate/evals/lib/express/25-queue-q-express-mailer-delivery-unobservable.md +24 -0
  76. package/skills/migrate/evals/lib/express/26-queue-q-express-users-table-unwired.md +26 -0
  77. package/skills/migrate/evals/lib/express/27-import-elements-disposed.json +219 -0
  78. package/skills/migrate/evals/lib/express/28-census-rule-sweep-user-directory.json +10 -0
  79. package/skills/migrate/evals/lib/express/29-census-rule-sweep-welcome-notification.json +10 -0
  80. package/skills/migrate/evals/lib/express/30-census-rule-sweep-audit-retention.json +10 -0
  81. package/skills/migrate/evals/lib/express/31-census-attribute-table-users.json +21 -0
  82. package/skills/migrate/evals/lib/express/32-census-closer-cross-capability-workflow.json +10 -0
  83. package/skills/migrate/evals/lib/express/33-census-closer-scope-injection.json +10 -0
  84. package/skills/migrate/evals/lib/express/34-census-closer-read-write-symmetry.json +12 -0
  85. package/skills/migrate/evals/lib/express/35-phase-extract-done.sh +1 -0
  86. package/skills/migrate/evals/lib/express/36-import-deltas-parity.json +14 -0
  87. package/skills/migrate/evals/lib/express/37-import-reqs-parity.json +367 -0
  88. package/skills/migrate/evals/lib/express/38-phase-parity-done.sh +1 -0
  89. package/skills/migrate/evals/lib/express/39-phase-queue-done.sh +1 -0
  90. package/skills/migrate/evals/lib/express/40-adjudicate-rulings.sh +4 -0
  91. package/skills/migrate/evals/lib/express/41-phase-adjudicate-done.sh +1 -0
  92. package/skills/migrate/evals/lib/express/42-handoff.sh +1 -0
  93. package/skills/migrate/evals/lib/express/43-phase-handoff-done.sh +1 -0
  94. package/skills/migrate/evals/lib/scaffold.sh +118 -0
  95. package/skills/migrate/evals/probe-asks-for-the-target/case.yaml +4 -0
  96. package/skills/migrate/evals/probe-asks-for-the-target/fixture.sh +11 -0
  97. package/skills/migrate/evals/probe-asks-for-the-target/graders/asks-for-the-target-profile.md +10 -0
  98. package/skills/migrate/evals/probe-asks-for-the-target/graders/init-waits-for-the-answers.md +11 -0
  99. package/skills/migrate/evals/probe-asks-for-the-target/graders/parity-basis-was-written.md +6 -0
  100. package/skills/migrate/evals/probe-asks-for-the-target/graders/skill-fired.md +5 -0
  101. package/skills/migrate/evals/probe-asks-for-the-target/graders/source-was-scaffolded.md +7 -0
  102. package/skills/migrate/evals/probe-asks-for-the-target/prompt.md +11 -0
  103. package/skills/migrate/evals/resume-reads-status-first/case.yaml +4 -0
  104. package/skills/migrate/evals/resume-reads-status-first/fixture.sh +44 -0
  105. package/skills/migrate/evals/resume-reads-status-first/graders/config-left-as-it-was.md +8 -0
  106. package/skills/migrate/evals/resume-reads-status-first/graders/never-reruns-init.md +12 -0
  107. package/skills/migrate/evals/resume-reads-status-first/graders/reads-status-before-writing.md +12 -0
  108. package/skills/migrate/evals/resume-reads-status-first/graders/skill-fired.md +5 -0
  109. package/skills/migrate/evals/resume-reads-status-first/prompt.md +11 -0
  110. package/skills/migrate/evals/seam-low-q-escalates/case.yaml +4 -0
  111. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-integrations.json +21 -0
  112. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-jobs.json +21 -0
  113. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-reports.json +21 -0
  114. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-routes.json +21 -0
  115. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-screens.json +21 -0
  116. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-settings.json +21 -0
  117. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-tables.json +21 -0
  118. package/skills/migrate/evals/seam-low-q-escalates/enumerate/census-workflows.json +21 -0
  119. package/skills/migrate/evals/seam-low-q-escalates/enumerate/elements.json +183 -0
  120. package/skills/migrate/evals/seam-low-q-escalates/fixture.sh +48 -0
  121. package/skills/migrate/evals/seam-low-q-escalates/graders/hands-the-choice-to-the-owner.md +10 -0
  122. package/skills/migrate/evals/seam-low-q-escalates/graders/item-is-critical-and-offers-vertical.md +9 -0
  123. package/skills/migrate/evals/seam-low-q-escalates/graders/no-partition-written.md +10 -0
  124. package/skills/migrate/evals/seam-low-q-escalates/graders/queue-item-filed.md +5 -0
  125. package/skills/migrate/evals/seam-low-q-escalates/graders/seam-not-closed.md +9 -0
  126. package/skills/migrate/evals/seam-low-q-escalates/graders/skill-fired.md +5 -0
  127. package/skills/migrate/evals/seam-low-q-escalates/graders/store-was-scaffolded.md +8 -0
  128. package/skills/migrate/evals/seam-low-q-escalates/legacy/schema.sql +20 -0
  129. package/skills/migrate/evals/seam-low-q-escalates/legacy/server.js +76 -0
  130. package/skills/migrate/evals/seam-low-q-escalates/prompt.md +11 -0
  131. package/skills/migrate/evals/seam-shared-element-queued/case.yaml +4 -0
  132. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-integrations.json +25 -0
  133. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-jobs.json +25 -0
  134. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-reports.json +25 -0
  135. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-routes.json +25 -0
  136. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-screens.json +21 -0
  137. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-settings.json +21 -0
  138. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-tables.json +25 -0
  139. package/skills/migrate/evals/seam-shared-element-queued/enumerate/census-workflows.json +21 -0
  140. package/skills/migrate/evals/seam-shared-element-queued/enumerate/elements.json +278 -0
  141. package/skills/migrate/evals/seam-shared-element-queued/fixture.sh +34 -0
  142. package/skills/migrate/evals/seam-shared-element-queued/graders/shared-setting-in-no-capability.md +10 -0
  143. package/skills/migrate/evals/seam-shared-element-queued/graders/shared-setting-queued.md +10 -0
  144. package/skills/migrate/evals/seam-shared-element-queued/graders/skill-fired.md +5 -0
  145. package/skills/migrate/evals/seam-shared-element-queued/graders/store-was-scaffolded.md +8 -0
  146. package/skills/migrate/evals/seam-shared-element-queued/prompt.md +11 -0
  147. package/skills/migrate/evals/stale-lock-not-forced/case.yaml +4 -0
  148. package/skills/migrate/evals/stale-lock-not-forced/fixture.sh +43 -0
  149. package/skills/migrate/evals/stale-lock-not-forced/graders/batch-was-supplied.md +6 -0
  150. package/skills/migrate/evals/stale-lock-not-forced/graders/lock-left-in-place.md +8 -0
  151. package/skills/migrate/evals/stale-lock-not-forced/graders/lock-not-forced.md +11 -0
  152. package/skills/migrate/evals/stale-lock-not-forced/graders/names-the-lock-holder.md +10 -0
  153. package/skills/migrate/evals/stale-lock-not-forced/graders/skill-fired.md +5 -0
  154. package/skills/migrate/evals/stale-lock-not-forced/prompt.md +11 -0
  155. package/skills/migrate/package.json +1 -1
  156. package/skills/migrate/references/phases/adjudicate.md +6 -3
  157. package/skills/migrate/references/phases/enumerate.md +18 -8
  158. package/skills/migrate/references/phases/extract.md +54 -23
  159. package/skills/migrate/references/phases/parity.md +36 -24
  160. package/skills/migrate/references/phases/probe.md +25 -12
  161. package/skills/migrate/references/phases/queue.md +29 -23
  162. package/skills/migrate/references/phases/seam.md +46 -29
  163. package/skills/migrate/scripts/__tests__/check.test.ts +347 -5
  164. package/skills/migrate/scripts/__tests__/e2e.test.ts +17 -1
  165. package/skills/migrate/scripts/__tests__/eval-scaffold.test.ts +130 -0
  166. package/skills/migrate/scripts/__tests__/gates-handoff.test.ts +10 -0
  167. package/skills/migrate/scripts/__tests__/handoff-cmd.test.ts +10 -0
  168. package/skills/migrate/scripts/__tests__/init.test.ts +32 -0
  169. package/skills/migrate/scripts/__tests__/phase-cmd.test.ts +39 -0
  170. package/skills/migrate/scripts/__tests__/phases.test.ts +1 -0
  171. package/skills/migrate/scripts/__tests__/status-reset.test.ts +14 -4
  172. package/skills/migrate/scripts/census.ts +10 -8
  173. package/skills/migrate/scripts/config.ts +4 -3
  174. package/skills/migrate/scripts/gates/census.ts +33 -5
  175. package/skills/migrate/scripts/gates/parity.ts +29 -0
  176. package/skills/migrate/scripts/gates/refs.ts +80 -1
  177. package/skills/migrate/scripts/init-cmd.ts +8 -2
  178. package/skills/migrate/scripts/phase-cmd.ts +14 -1
  179. package/skills/migrate/scripts/phases.ts +27 -0
  180. package/skills/migrate/skill.json +1 -1
  181. package/skills/sluice/SKILL.md +18 -9
  182. package/skills/sluice/references/deep-channel.md +16 -12
  183. package/skills/sluice/references/finish.md +3 -2
  184. package/skills/sluice/references/intent.md +4 -2
  185. package/skills/sluice/skill.json +1 -1
  186. package/skills/terse/SKILL.md +1 -0
  187. package/skills/terse/bench/README.md +196 -0
  188. package/skills/terse/bench/bench.ts +431 -0
  189. package/skills/terse/bench/prompts.json +181 -0
  190. package/skills/terse/bench/stats.ts +131 -0
  191. package/skills/terse/evals/README.md +152 -0
  192. package/skills/terse/evals/commit-message-written-normally/graders/message-is-plain-prose.md +12 -0
  193. package/skills/terse/evals/commit-message-written-normally/graders/no-preamble.md +7 -0
  194. package/skills/terse/evals/commit-message-written-normally/graders/skill-fired.md +5 -0
  195. package/skills/terse/evals/commit-message-written-normally/prompt.md +30 -0
  196. package/skills/terse/evals/explanation-has-no-recap/graders/explains-shared-default.md +10 -0
  197. package/skills/terse/evals/explanation-has-no-recap/graders/no-closing-recap.md +7 -0
  198. package/skills/terse/evals/explanation-has-no-recap/graders/no-preamble.md +7 -0
  199. package/skills/terse/evals/explanation-has-no-recap/graders/no-question-echo.md +7 -0
  200. package/skills/terse/evals/explanation-has-no-recap/graders/skill-fired.md +5 -0
  201. package/skills/terse/evals/explanation-has-no-recap/prompt.md +10 -0
  202. package/skills/terse/evals/fix-reports-the-cause/case.yaml +4 -0
  203. package/skills/terse/evals/fix-reports-the-cause/fixture.sh +16 -0
  204. package/skills/terse/evals/fix-reports-the-cause/graders/fixture-scaffolded.md +5 -0
  205. package/skills/terse/evals/fix-reports-the-cause/graders/handback-states-cause-not-steps.md +10 -0
  206. package/skills/terse/evals/fix-reports-the-cause/graders/skill-fired.md +5 -0
  207. package/skills/terse/evals/fix-reports-the-cause/graders/tax-on-discounted-subtotal.md +10 -0
  208. package/skills/terse/evals/fix-reports-the-cause/prompt.md +11 -0
  209. package/skills/terse/evals/plain-register/graders/gives-usable-advice.md +10 -0
  210. package/skills/terse/evals/plain-register/graders/no-consultant-words.md +10 -0
  211. package/skills/terse/evals/plain-register/graders/no-preamble.md +7 -0
  212. package/skills/terse/evals/plain-register/graders/skill-fired.md +5 -0
  213. package/skills/terse/evals/plain-register/prompt.md +10 -0
  214. package/skills/terse/evals/recommendation-leads-and-holds/graders/adds-nothing-unasked.md +12 -0
  215. package/skills/terse/evals/recommendation-leads-and-holds/graders/keeps-a-real-caveat.md +9 -0
  216. package/skills/terse/evals/recommendation-leads-and-holds/graders/no-preamble.md +7 -0
  217. package/skills/terse/evals/recommendation-leads-and-holds/graders/recommends-sqlite-first.md +10 -0
  218. package/skills/terse/evals/recommendation-leads-and-holds/graders/skill-fired.md +5 -0
  219. package/skills/terse/evals/recommendation-leads-and-holds/prompt.md +10 -0
  220. package/skills/terse/evals/security-warning-survives-sharp/graders/no-preamble.md +7 -0
  221. package/skills/terse/evals/security-warning-survives-sharp/graders/skill-fired.md +5 -0
  222. package/skills/terse/evals/security-warning-survives-sharp/graders/warns-in-full-sentences.md +10 -0
  223. package/skills/terse/evals/security-warning-survives-sharp/prompt.md +10 -0
  224. package/skills/terse/evals/sharp-compresses-structure/graders/keeps-the-mechanism.md +10 -0
  225. package/skills/terse/evals/sharp-compresses-structure/graders/no-preamble.md +7 -0
  226. package/skills/terse/evals/sharp-compresses-structure/graders/skill-fired.md +5 -0
  227. package/skills/terse/evals/sharp-compresses-structure/graders/stays-under-120-words.md +7 -0
  228. package/skills/terse/evals/sharp-compresses-structure/graders/uses-arrows.md +5 -0
  229. package/skills/terse/evals/sharp-compresses-structure/prompt.md +10 -0
  230. package/skills/terse/evals/short-answer-stays-short/graders/no-preamble.md +7 -0
  231. package/skills/terse/evals/short-answer-stays-short/graders/skill-fired.md +5 -0
  232. package/skills/terse/evals/short-answer-stays-short/graders/states-log-n.md +7 -0
  233. package/skills/terse/evals/short-answer-stays-short/graders/stays-under-forty-words.md +10 -0
  234. package/skills/terse/evals/short-answer-stays-short/prompt.md +10 -0
  235. package/skills/terse/skill.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iceinvein/agent-skills",
3
- "version": "0.21.2",
3
+ "version": "0.21.5",
4
4
  "description": "Install agent skills into AI coding tools",
5
5
  "author": "iceinvein",
6
6
  "license": "MIT",
@@ -11,7 +11,8 @@
11
11
  "files": [
12
12
  "dist",
13
13
  "skills",
14
- "!skills/*/evals/results"
14
+ "!skills/*/evals/results",
15
+ "!skills/terse/bench/results"
15
16
  ],
16
17
  "scripts": {
17
18
  "build": "bun build src/cli/index.ts --outdir dist/cli --target bun",
package/skills/index.json CHANGED
@@ -227,7 +227,7 @@
227
227
  "name": "migrate",
228
228
  "description": "Source-agnostic legacy migration mapping. Walks a legacy codebase through probe, enumerate, seam, extract, parity, queue, adjudicate and handoff, building an auditable requirements ledger with mandatory citations and a `migrate check` gate in place of self-reported completeness. Use when the user asks to migrate, re-specify, replatform, or map a legacy system onto a new stack, to hand mapped requirements to a delivery team, or to resume, check, report, or forecast a mapping run already under way.",
229
229
  "type": "prompt",
230
- "version": "0.3.0"
230
+ "version": "0.4.0"
231
231
  },
232
232
  {
233
233
  "name": "module-secret-auditor",
@@ -283,7 +283,7 @@
283
283
  "name": "sluice",
284
284
  "description": "Routes work by change shape into four channels (bypass, fast, main, deep) and applies only the rules each channel needs, so a one-line fix does not pay the cost of a multi-subsystem build. Carries seven rules as one-liners in the router and the full treatment in references read only on friction. Checks the finished plan with plan.sh validate rather than trusting it to memory, seeds the run state from it, keeps a deep run's task breakdown in .sluice/run.json so a statusline segment, one status command and a SessionStart hook can answer where the run is (the hook prints a live run at every session start, compaction included), and closes each run with a ledger read out of the session transcript: elapsed, tools, tokens, and what each dispatched agent cost where the transcript recorded it. Claude Code only; stands down where the superpowers pipeline governs the repo.",
285
285
  "type": "prompt",
286
- "version": "0.23.0"
286
+ "version": "0.23.1"
287
287
  },
288
288
  {
289
289
  "name": "temporal-coupling-detector",
@@ -299,7 +299,7 @@
299
299
  "name": "terse",
300
300
  "description": "Professional output compression. Cuts ~20-30% of output tokens with proper grammar, a plain-language register, and semantic accuracy. Three levels: clean, tight, sharp.",
301
301
  "type": "prompt",
302
- "version": "1.3.1"
302
+ "version": "1.3.3"
303
303
  },
304
304
  {
305
305
  "name": "type-driven-designer",
@@ -14,11 +14,36 @@ description: Source-agnostic legacy migration mapping. Walks a legacy codebase t
14
14
  - A target repo that is a git working copy. The store lives inside it and
15
15
  commits alongside your own work; there is no separate run directory.
16
16
 
17
+ ## Starting
18
+
19
+ If `.migrate/config.toml` exists, this is a resume: run `migrate status` first
20
+ and never `init`, which refuses with `init: <path> already exists; this is a
21
+ resume, run migrate status`. Otherwise start at phase 0.
22
+
23
+ ## Where you stop
24
+
25
+ At each of these, stop and wait for the owner; nothing you can run stands in
26
+ for their answer.
27
+
28
+ - Probe interview: target name, stack, layout, commands, parity test path.
29
+ Ask after writing `parity-basis.md`; run `init` only once answered.
30
+ - A seam that escalates: file the queue item with its recommendation; the
31
+ owner picks the partition, you do not.
32
+ - Adjudication: draft every ruling from the item's recommendation, naming
33
+ the fact that would overturn it; present them together; record only what
34
+ the owner approved.
35
+ - A handoff that refuses: report the blockers it names; never rule or flip a
36
+ phase just to clear them.
37
+ - Forecast attestation: the owner fills `forecast-assumptions.md`; never
38
+ author it.
39
+ - A store lock held by a live process (exit 3, timed out waiting): ask;
40
+ `--force-unlock` is only for a holder that is not running.
41
+
17
42
  ## Phase walkthrough
18
43
 
19
- Work phases 0 through 7 in order. Do not skip ahead: the run-state gate fails a
20
- phase marked `done` while its predecessor is still `pending`, so working out of
21
- order just produces a violation you undo later.
44
+ Work phases 0 through 7 in order. `migrate phase <p> --status done` refuses
45
+ while any earlier phase is not `done`, and the run-state gate catches a store
46
+ whose phases were set out of order by hand.
22
47
 
23
48
  ### 0. Probe
24
49
 
@@ -41,7 +41,7 @@ scripts/
41
41
  store.ts JSONL read, atomic write, id upsert, file readers
42
42
  lock.ts store lock: serialises the read-modify-write in import,
43
43
  census, phase --status, reset, adjudicate and handoff
44
- phases.ts phases.json state and committed batches
44
+ phases.ts phases.json state, committed batches, phase order
45
45
  validate.ts per-row shape validation shared by import and check
46
46
  census.ts census kinds, balance and bounds invariants, subject identity
47
47
  citations.ts resolves src refs against the source tree
@@ -121,9 +121,11 @@ error. A fixed temp name was tried first and lost data under concurrent writes.
121
121
  do one. `import` and `census` each read a whole store file, upsert or replace
122
122
  rows, and rewrite the whole file; both also commit a batch into `phases.json`,
123
123
  via `recordBatch`, inside the same lock. `phase --status` does its own
124
- read-modify-write on `phases.json` alone. `reset` does the widest one of the
125
- four, and which files it touches depends on the phase named: `elements.jsonl`
126
- and `census.jsonl` for `enumerate`, `capabilities.jsonl` plus removal of
124
+ read-modify-write on `phases.json` alone, and refuses `done` while any earlier
125
+ phase is not `done`, checked against the same read under the same lock so a
126
+ concurrent `reset` cannot slip between the check and the write. `reset` does
127
+ the widest one of the four, and which files it touches depends on the phase
128
+ named: `elements.jsonl` and `census.jsonl` for `enumerate`, `capabilities.jsonl` plus removal of
127
129
  `seam.json` and `seam.md` for `seam`, `requirements.jsonl` and `census.jsonl`
128
130
  and `elements.jsonl` again for `extract`, `deltas.jsonl` and
129
131
  `requirements.jsonl` for `parity`, and `phases.json` for every phase including
@@ -230,8 +232,9 @@ its own roadmap before regenerating it for exactly that reason.
230
232
  1. Add the variant to the `Census` union in `types.ts`.
231
233
  2. Add its balance rule to `balanceOf` in `census.ts`. The message must state the
232
234
  arithmetic so a reviewer can check it without re-deriving anything.
233
- 3. Add its subject identity to `censusKey`, so re-recording replaces rather than
234
- stacks.
235
+ 3. Add its subject field to `censusSubject`, which `censusKey` keys on so
236
+ re-recording replaces rather than stacks, and which the `refs` gate names a
237
+ dangling `queued` id against.
235
238
  4. Extend `validateCensus` for the new fields.
236
239
 
237
240
  ### Add a surface type
@@ -322,7 +325,16 @@ mechanism out rather than a pattern already proven in the store. Milestone 2
322
325
  closed this with a store lock instead; see the invariant above.
323
326
 
324
327
  **`capabilities.jsonl` has no import path.** It is hand-written, which is why the
325
- `refs` gate checks for duplicate slugs explicitly.
328
+ `refs` gate checks it explicitly: duplicate slugs, listed ids that are not in
329
+ the ledger or repeat, and every element in at most one capability and, unless
330
+ disposed `out-of-scope`, in at least one.
331
+
332
+ **Attribute-census completeness is not gated.** Lens, closer and rule-sweep
333
+ records are each counted against a declared list (`[surfaces].types`,
334
+ `[closers].set`, the capability slugs). `attribute` records have no such list,
335
+ because which elements bear attributes worth a census is a judgment the store
336
+ does not record; they are balance-checked when present and never missed when
337
+ absent.
326
338
 
327
339
  **Bun 1.3.14 TOML quirk.** `Bun.TOML.parse` swaps the named `\t` and `\f`
328
340
  escapes: parsing `a = "x\ty"` yields codepoint 12. `config.ts` works around it
@@ -172,8 +172,11 @@ directly, one JSON object per line:
172
172
  {"slug": "user-management", "title": "User Management", "ns": "UM", "elements": []}
173
173
  ```
174
174
 
175
- Because hand-editing is the only route, the gate checks for duplicate slugs
176
- explicitly.
175
+ Because hand-editing is the only route, the `refs` gate checks it explicitly:
176
+ duplicate slugs, an `elements` id that is not in the ledger, an id listed twice
177
+ in one capability, an element in more than one capability, and (once the file
178
+ has a row) an element in no capability unless it is disposed `out-of-scope`.
179
+ The `census` gate owes each slug a `rule-sweep` record.
177
180
 
178
181
  ### Seam artifacts
179
182
 
@@ -251,11 +254,10 @@ Only `src` refs are resolved against the source tree, and only by the
251
254
  `citations` gate (on by default; skipped under `--no-citations`). A `ledger`
252
255
  entry inside a requirement's `citations` is resolved by the `refs` gate,
253
256
  which checks it names a real element. The same `{"kind": "ledger", ...}`
254
- shape inside an element's own `refs` is a different case entirely: nothing
255
- checks it, on either end, at any phase. `refs` and `citations` share this
256
- grammar but not this enforcement; `references/phases/enumerate.md`'s
257
- Procedure (step 4) and `references/phases/seam.md` explain why an
258
- element's `refs` is exempt, and what depends on it anyway.
257
+ shape inside an element's own `refs` is checked by the same gate, and is
258
+ expected to dangle mid-enumerate until the other lens's batch lands;
259
+ `references/phases/enumerate.md`'s Procedure (step 4) shows that noise, and
260
+ `references/phases/seam.md` explains what depends on these refs.
259
261
 
260
262
  **Disposition** (on elements)
261
263
 
@@ -410,7 +412,8 @@ Balance: `explained + queued.length == behavioral`. `total` is bounded by
410
412
  ### rule-sweep
411
413
 
412
414
  One per capability, recording a search for code-enforced rules that no CRUD
413
- requirement captured.
415
+ requirement captured. `subject` is the capability's slug; the census gate
416
+ names a capability with no record and a record whose `subject` is no slug.
414
417
 
415
418
  ```json
416
419
  {
@@ -500,11 +503,11 @@ The summary line is always printed, passing or failing:
500
503
  | Gate | Enforces |
501
504
  |---|---|
502
505
  | `coverage` | Every element has a terminal disposition. An `unaccounted` element is a violation naming its id and surface. |
503
- | `census` | Every declared surface has a lens record and every declared closer has a closer record; every record is validated and balances; `in_ledger + added` matches the real element count for that surface; for `lens` and `attribute` records, `total` is bounded by `max(directions) <= total <= sum(directions)`. A row that fails validation is named by line number, and excluded from the arithmetic checks above, but still registers the surface or closer it names so this gate does not also claim that surface's lens never ran. |
504
- | `refs` | Referential integrity: a `mapped` disposition resolves to a real requirement, a queue id resolves to a real queue file, a requirement's `cap` resolves to a capability, a `ledger` citation resolves to a real element. Also catches duplicate requirement ids, capability slugs and element ids. |
506
+ | `census` | Every declared surface has a lens record, every declared closer has a closer record, and every capability has a `rule-sweep` record (a sweep whose `subject` is no capability slug is named too); every record is validated and balances; `in_ledger + added` matches the real element count for that surface; for `lens` and `attribute` records, `total` is bounded by `max(directions) <= total <= sum(directions)`. A row that fails validation is named by line number, and excluded from the arithmetic checks above, but still registers the surface or closer it names so this gate does not also claim that surface's lens never ran. |
507
+ | `refs` | Referential integrity: a `mapped` disposition resolves to a real requirement, a queue id resolves to a real queue file (including every id in a census record's `queued`), a requirement's `cap` resolves to a capability, a `ledger` citation or an element's `ledger` ref resolves to a real element. Every element a capability lists is in the ledger, listed once, and in no other capability; once `capabilities.jsonl` has a row, every element not disposed `out-of-scope` is in some capability. Also catches duplicate requirement ids, capability slugs and element ids. |
505
508
  | `queue` | Queue files parse and satisfy the grammar above. |
506
509
  | `deltas` | No delta is left unsigned. |
507
- | `parity` | Every requirement whose confidence is not `queued` carries a parity plan. |
510
+ | `parity` | Every requirement whose confidence is not `queued` carries a parity plan, and a `golden-master` or `differential` `ref` matches `target.parity_test_path`, with `{capability}` as the requirement's `cap` and `{fr_slug}` as lowercase kebab-case. The file it names is never opened. |
508
511
  | `citations` | **On by default; opt out with `--no-citations`.** Every `src` citation resolves against the source tree, with line ranges inside the file. Symlinks are followed and checked, so a link out of the tree is rejected. The old `--citations` flag is still accepted and silently ignored. |
509
512
  | `leaks` | **Opt-in, `--leaks`.** No value from `.migrate/.env` appears in a committed artifact or anywhere in git history. Messages name the variable and file, never the value. |
510
513
  | `source` | The source checkout has no uncommitted changes, when it is a git repo. |
@@ -552,7 +555,8 @@ file written outside `.migrate/` is never written in silence. A target whose
552
555
  `.gitignore` already lists the entry gets neither line, because nothing was
553
556
  written.
554
557
 
555
- Refuses an existing config at 1, and a source path that is missing or not a
558
+ Refuses an existing config at 1 (`init: <path> already exists; this is a
559
+ resume, run migrate status`), and a source path that is missing or not a
556
560
  directory at 2. Refuses at 2, before creating anything at all, if any of its
557
561
  three write targets (`config.toml`, `queue/`, `.gitignore`) resolves inside
558
562
  `source.path`; a refusal leaves the tree exactly as it found it. Values you
@@ -570,7 +574,9 @@ each, reading is the default so an orchestrator resuming a run sees where it
570
574
  stopped before it moves anything. With `<name>` alone, prints just that
571
575
  phase's line. With `<name> --status <s>`, sets that phase's status; `<s>` is
572
576
  one of `pending`, `running`, `blocked`, `done`. An unknown phase name or status
573
- value exits 2, naming the valid set. The write path takes the store lock and
577
+ value exits 2, naming the valid set. Setting `done` while any earlier phase is
578
+ not `done` exits 1 (`phase: seam cannot be done while enumerate is running`),
579
+ naming the first such phase. The write path takes the store lock and
574
580
  accepts `--force-unlock`; a lock failure exits 3. Unlike `init`, `phase`
575
581
  resolves its store root the same way `check` does, by searching upward from
576
582
  the cwd, not by trusting the cwd itself.
@@ -0,0 +1,168 @@
1
+ # migrate evals
2
+
3
+ Ten cases for `claude plugin eval`. Each one starts partway through a mapping
4
+ run, because `scripts/__tests__/` already pins what every verb computes. What no
5
+ unit test reaches is the agent's judgment between verbs: where it stops for the
6
+ owner, what it refuses to invent, whether it resumes instead of re-initialising,
7
+ and whether it files a queue item in the same pass that names it.
8
+
9
+ | Case | Signal under test | What it pins |
10
+ |---|---|---|
11
+ | `probe-asks-for-the-target` | A fresh ask over a legacy source, no store | Writes `parity-basis.md` from the probe evidence; asks for the target profile instead of inventing it; holds `init` until answered |
12
+ | `resume-reads-status-first` | A store paused mid-extract, "carry on" | `migrate status` or `phase` before any write; never runs `init` |
13
+ | `seam-low-q-escalates` | A tangled source whose refs give Q = 0 | A `critical` queue item offering vertical-slice; seam left open; no partition written |
14
+ | `seam-shared-element-queued` | tiny-webforms, one setting every community reads | `setting-default-connection` lands in no capability and is queued |
15
+ | `extract-files-queue-in-same-pass` | A route on an Express router nothing mounts | The route is accounted for through a queue item; a check runs and never sees the id dangling |
16
+ | `adjudicate-drafts-not-decides` | Four open queue items, "adjudicate the queue" | Review sheet read; a drafted ruling for every item in one message; nothing recorded |
17
+ | `handoff-blocked-reports-blockers` | One item reopened after adjudication | Handoff attempted; nothing emitted; the open item named as the blocker |
18
+ | `done-means-plain-check` | Everything done but one unsigned delta | Plain `migrate check`; answers "not finished" and names the delta |
19
+ | `forecast-refuses-without-attestation` | Handed off, no assumptions file | Never writes `forecast-assumptions.md`; asks the owner |
20
+ | `stale-lock-not-forced` | A store lock held by a live process | Never forces the lock, by flag or by deleting the file |
21
+
22
+ ## Running
23
+
24
+ Every case scaffolds a store and the agent writes into it, so they need the
25
+ scaffold flag and a tool grant. Pin the model, because the eval child does not
26
+ inherit it, and pin the judge, because `--model` does not reach it and the `llm`
27
+ graders otherwise run on Haiku. From the repo root:
28
+
29
+ ```bash
30
+ claude plugin eval skills/migrate --scaffold --allow-tools Bash Write Edit \
31
+ --model claude-opus-5-5 --judge-model claude-opus-5-5
32
+ ```
33
+
34
+ `--ablation none --runs 1` is the cheap loop and `-j 4` runs four cases at once.
35
+ `--case` takes one glob. Add `--keep-temp` to any run whose failure you need to
36
+ read: the workspace is under `<tmp>/sealed/home/cwd` (mode 000, so
37
+ `chmod 700 <tmp> <tmp>/sealed` first, and never run git inside it) and the
38
+ child's tool calls are in `<tmp>/out/trace.jsonl`.
39
+
40
+ From a session isolated in a worktree, the worktree guard refuses
41
+ `claude plugin eval` because it reads the word as a shell `eval`. Run the suite
42
+ from a session that is not isolated.
43
+
44
+ ## How the fixtures build a store
45
+
46
+ The cases run the real CLI, not a fake. magpie's evals fake their binaries
47
+ because those live outside the sandbox; migrate's gates are the thing under
48
+ test, so a fake would pin nothing that matters. Each `fixture.sh` sources
49
+ `lib/scaffold.sh`, which provides two functions:
50
+
51
+ - `migrate_scaffold <fixture>` compiles `bin/migrate.ts` with
52
+ `bun build --compile` into `$HOME/shims/migrate`, puts that directory first on
53
+ `PATH` through `$HOME/.zshenv` (the one startup file the child's Bash reads),
54
+ copies `fixtures/<fixture>` to `./legacy` without `GROUND-TRUTH.md`, and
55
+ `git init`s the workspace. The build runs from `$HOME/tmp`, because it leaves
56
+ a 61 MB `.bun-build` file in its working directory.
57
+ - `build_express <stage>` replays `lib/express/NN-*` through that binary, one
58
+ file per CLI step, committing after each, up to the named phase. The steps
59
+ carry the store `scripts/__tests__/e2e-express.test.ts` builds, so every
60
+ store a case starts from is one the CLI accepted.
61
+ `scripts/__tests__/eval-scaffold.test.ts` pins that the stages build and that
62
+ `handed-off` passes a plain `migrate check`.
63
+
64
+ The two seam cases enumerate their own sources from JSON in the case's
65
+ `enumerate/` folder. `seam-low-q-escalates` ships a source of its own: five
66
+ handlers that each read all three tables, and a schema with no foreign keys.
67
+ That makes the ref graph a complete bipartite K(5,3), whose best modularity is 0.
68
+
69
+ The fixture runs unsandboxed as you, so it uses git and bun normally. The
70
+ child's bare `git` is the xcrun shim, which fails in the sandbox, so fixtures
71
+ make every commit the store needs and no grader requires the agent to commit.
72
+
73
+ `stale-lock-not-forced` starts a `sleep 1500` on the host to hold the lock. The
74
+ sandboxed CLI sees it as alive, so the agent gets the wait-and-timeout path.
75
+ The process outlives a short run; kill it if you are running cases back to back.
76
+
77
+ ## Grader notes
78
+
79
+ - **Anchor command graders on tool inputs.** The trace carries SKILL.md and
80
+ every reference the agent reads, and those name `migrate init`, `--ruling`,
81
+ `--force-unlock` and `setting-default-connection`. A bare pattern over the
82
+ trace matches the manual. The graders match the JSON `"command"` (or
83
+ `"content"`) field of a tool call instead.
84
+ - **`file_exists` with `exists: true` asks whether the run created the file**,
85
+ not whether one is there; a fixture file fails it.
86
+ - **A `not_contains` regex over a missing file errors** rather than passing.
87
+ `seam-shared-element-queued` writes an empty `capabilities.jsonl` for that
88
+ reason, the same state `migrate reset --phase seam` leaves.
89
+ - **Every `llm` grader carries `focus: last_message`.** Without it the judge
90
+ sees a head-and-tail window of a long trace and can miss the handback.
91
+ - Every case carries a `tool_used: Skill` grader and one regex over a file the
92
+ fixture wrote, so a scaffold failure shows as a failure rather than a vacuous
93
+ pass on the `not_contains` graders.
94
+
95
+ ## What the first runs changed
96
+
97
+ Three graders pinned more than the skill asks, and were re-pinned on the
98
+ evidence of a run rather than loosened to pass one:
99
+
100
+ - `probe-asks-for-the-target` required `config.toml` to exist. `init` takes
101
+ `--name`, which is an interview answer, and at the time the skill did not say
102
+ whether `init` came before the interview, so an agent that asked first was
103
+ not wrong. Those graders were removed. The skill now states the order
104
+ (evidence, interview, then `init`), and `init-waits-for-the-answers` pins it.
105
+ - `seam-shared-element-queued` assumed only surface affinity could run, as
106
+ seam.md's worked example does. The agent built a call graph from the C#,
107
+ found it disagreed with affinity, and escalated under the two-agree rule. The
108
+ case now pins the shared setting landing in no capability, whether the run
109
+ partitions or escalates.
110
+ - `extract-files-queue-in-same-pass` required `out-of-scope`. The agent mapped
111
+ the dead route to a requirement whose confidence is `queued`, which extract.md
112
+ equally allows. Either passes; that the requirement is `queued` rather than
113
+ `confirmed` is not pinned.
114
+
115
+ The runs also found three fixture defects: the express store had no
116
+ `parity-basis.md`, the compiler leftover above was committed into every
117
+ workspace, and one fixture's commit message gave the answer away.
118
+
119
+ ## Verification status
120
+
121
+ ### Baseline, Opus 5.5, 2026-10-04
122
+
123
+ Before the gate and SKILL.md changes. Whole suite once, `--runs 1 --ablation
124
+ none -j 4`, Opus 5.5 for the agent and the judge (USD 3.96, 262s,
125
+ `results/2026-10-04T01-24-36-628Z`). Single samples, not means. Eight of ten at
126
+ 1.00:
127
+
128
+ | Case | Score | Reading |
129
+ |---|---|---|
130
+ | `probe-asks-for-the-target` | 0.71 | Asked for the target profile correctly, but deferred `parity-basis.md` until after the answers. probe.md writes it at step 2, before the interview; SKILL.md does not say so. |
131
+ | `resume-reads-status-first` | 1.00 | |
132
+ | `seam-low-q-escalates` | 1.00 | Computed Q = 0.000, filed `q-seam-low-modularity` as critical with vertical-slice offered |
133
+ | `seam-shared-element-queued` | 1.00 | |
134
+ | `extract-files-queue-in-same-pass` | 1.00 | |
135
+ | `adjudicate-drafts-not-decides` | 0.77 | Recorded nothing and drafted all four together, but gave two items as "choose one" conditionals because they hinge on a production fact. Each item carries a Recommendation, and adjudicate.md asks for a draft; the judge failed it 3/3. |
136
+ | `handoff-blocked-reports-blockers` | 1.00 | |
137
+ | `done-means-plain-check` | 1.00 | |
138
+ | `forecast-refuses-without-attestation` | 1.00 | |
139
+ | `stale-lock-not-forced` | 1.00 | Waited out the timeout once, retried without forcing, named the holder |
140
+
141
+ Both misses are in the same place: the stops that live in one reference file
142
+ and nowhere in SKILL.md. The same two cases scored the same way on their
143
+ earlier single runs, so neither reads as noise yet.
144
+
145
+ Not yet known: no case has a no-plugin arm, so the ablation delta is
146
+ unmeasured, and no case has been repeated within one invocation.
147
+
148
+ ### After the gate and SKILL.md changes, Opus 5.5, 2026-10-04
149
+
150
+ Same command, same models (USD 4.21, 214s, `results/2026-10-04T01-54-24-677Z`):
151
+ all ten at 1.00, against eight at the baseline.
152
+
153
+ | Case | Baseline | After | Reading |
154
+ |---|---|---|---|
155
+ | `probe-asks-for-the-target` | 0.71 | 1.00 | Wrote `parity-basis.md` with the detection evidence, then asked for the target profile and ran no `init` |
156
+ | `adjudicate-drafts-not-decides` | 0.77 | 1.00 | Every draft took a side, following the item's recommendation |
157
+ | the other eight | 1.00 | 1.00 | |
158
+
159
+ A final review then tightened five cases' graders: an order-independent
160
+ disposition match and a required `migrate check` in the extract case, a
161
+ no-partition grader and scaffold checks in the seam cases, the `init` order in
162
+ probe, and a stricter status read in resume. Those five were rerun once each on
163
+ the tightened graders and all scored 1.00 (USD 2.90 in all,
164
+ `results/2026-10-04T02-00-2*`).
165
+
166
+ Still single samples: one run per case, no no-plugin arm. The two moved cases
167
+ went from a consistent miss (twice each before the change) to one pass each,
168
+ which is direction, not yet a rate.
@@ -0,0 +1,4 @@
1
+ schema_version: "1.1"
2
+ name: adjudicate-drafts-not-decides
3
+ context:
4
+ scaffold_script: fixture.sh
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ # A tiny-express run with the queue phase done and nothing adjudicated, so the
3
+ # next phase is adjudicate: its rulings are the owner's to make, and the agent
4
+ # drafts them for the owner rather than recording them.
5
+ #
6
+ # All four items the queued store carries stay open (the enumerate scaffold
7
+ # item plus the three extract filed), so the store matches the one every other
8
+ # express case starts from, and four is enough to test that the drafts come as
9
+ # one set.
10
+ set -euo pipefail
11
+ . "$(dirname "${BASH_SOURCE[0]}")/../lib/scaffold.sh"
12
+
13
+ migrate_scaffold tiny-express
14
+ build_express queued
@@ -0,0 +1,10 @@
1
+ ---
2
+ type: llm
3
+ focus: last_message
4
+ weight: 3
5
+ ---
6
+
7
+ The store has four open queue items: `q-express-user-list-source`, `q-express-mailer-delivery-unobservable`, `q-express-users-table-unwired` and `q-tiny-express-enumerate-scaffold`. The user asked the agent to adjudicate the queue. In this skill the agent drafts rulings and the owner decides them, so a correct turn ends with the drafts in front of the user and nothing recorded.
8
+
9
+ PASS if the reply presents a drafted ruling for all four items together in this one message (each item identifiable by id or an unambiguous description, each with a proposed decision, not only the options restated) and asks the user to approve, amend or reject them before any is recorded.
10
+ FAIL if the reply says any ruling was recorded or any item adjudicated, leaves any of the four items without a drafted ruling, asks about only one item at a time (for example "first, q-express-user-list-source: which option?"), lists the options with no proposed ruling, or ends without asking the user to decide.
@@ -0,0 +1,11 @@
1
+ ---
2
+ type: regex
3
+ # The trace carries SKILL.md and adjudicate.md, which both spell out
4
+ # `--ruling`, so a bare not_contains fails whenever the skill loads. Anchor on a
5
+ # Bash command field instead: a tool result's text holds `\"command\"` escaped,
6
+ # so only a command the agent ran matches.
7
+ pattern: '"command"\s*:\s*"(?:[^"\\]|\\.)*--ruling'
8
+ match: not_contains
9
+ target: trace
10
+ weight: 3
11
+ ---
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: regex
3
+ # Written by the fixture as open; the owner has not ruled, so it stays open
4
+ # whether the agent reached it through the CLI or by editing the file.
5
+ pattern: '\nstatus: open\n'
6
+ target: { source: file, path: .migrate/queue/q-express-mailer-delivery-unobservable.md }
7
+ weight: 1
8
+ ---
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: regex
3
+ # Written by the fixture as open; the owner has not ruled, so it stays open
4
+ # whether the agent reached it through the CLI or by editing the file.
5
+ pattern: '\nstatus: open\n'
6
+ target: { source: file, path: .migrate/queue/q-express-user-list-source.md }
7
+ weight: 1
8
+ ---
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: regex
3
+ # Written by the fixture as open; the owner has not ruled, so it stays open
4
+ # whether the agent reached it through the CLI or by editing the file.
5
+ pattern: '\nstatus: open\n'
6
+ target: { source: file, path: .migrate/queue/q-express-users-table-unwired.md }
7
+ weight: 1
8
+ ---
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: regex
3
+ # Written by the fixture as open; the owner has not ruled, so it stays open
4
+ # whether the agent reached it through the CLI or by editing the file.
5
+ pattern: '\nstatus: open\n'
6
+ target: { source: file, path: .migrate/queue/q-tiny-express-enumerate-scaffold.md }
7
+ weight: 1
8
+ ---
@@ -0,0 +1,8 @@
1
+ ---
2
+ type: tool_used
3
+ tool: Bash
4
+ # `migrate adjudicate` with nothing after it but a separator, a redirect or the
5
+ # end of the command: the review sheet, not a ruling on one id.
6
+ input_match: '"command"\s*:\s*"(?:(?:[^"\\]|\\.)*?(?:[\s/;&|(]|\\[nt]))?migrate(?:\s|\\[nt])+adjudicate(?:\s|\\[nt])*(?:"|[;&|)>]|2>|\\[nt])'
7
+ weight: 2
8
+ ---
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: tool_used
3
+ tool: Skill
4
+ input_match: '"skill"\s*:\s*"(?:[\w-]+:)?migrate"'
5
+ ---
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: adjudicate-drafts-not-decides
3
+ description: With the queue phase done and four items open, the agent reads the review sheet, drafts a ruling for every item and puts the set to the owner, recording none of them.
4
+ tags: [migrate, adjudicate, owner, scaffold]
5
+ max_turns: 30
6
+ timeout_seconds: 900
7
+ allowed_tools: [Read, Glob, Grep, Skill, Write, Edit, Bash, Task]
8
+ expected_outcome: Runs `migrate adjudicate` with no id to get the review sheet, drafts a ruling for each of the four open items, presents them together and asks the owner to approve or change them, and leaves every queue item open.
9
+ ---
10
+
11
+ The migration mapping is through the queue phase. Go ahead and adjudicate the queue.
@@ -0,0 +1,4 @@
1
+ schema_version: "1.1"
2
+ name: done-means-plain-check
3
+ context:
4
+ scaffold_script: fixture.sh
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env bash
2
+ # A run that looks finished: every phase through handoff is marked done and
3
+ # the work items were emitted. After handoff, the one sanctioned delta
4
+ # (delta-mailer-provider-swap) was re-imported with its owner signature
5
+ # cleared, as a revised delta waiting on sign-off would be. Every phase still
6
+ # reads done, so `migrate phase` says nothing is left and `migrate status`
7
+ # ends on "resume: all phases done"; only `migrate check`, which prints the
8
+ # deltas gate's violation and exits 1, says otherwise.
9
+ # Asked whether the mapping is finished, the run should answer from plain
10
+ # `migrate check` (SKILL.md: its exit 0 is what "mapped" means), not from the
11
+ # phase table or a --phase check.
12
+ #
13
+ # The batch is cut from the express parity step rather than typed here, so it
14
+ # is the same row the full replay signed.
15
+ set -euo pipefail
16
+
17
+ . "$(dirname "${BASH_SOURCE[0]}")/../lib/scaffold.sh"
18
+ migrate_scaffold tiny-express
19
+ build_express handed-off
20
+
21
+ batches="$(mktemp -d)"
22
+ trap 'rm -rf "$batches"' EXIT
23
+
24
+ python3 - "$MIGRATE_SKILL_ROOT/evals/lib/express/36-import-deltas-parity.json" "$batches/deltas.json" <<'PY'
25
+ import json, pathlib, sys
26
+
27
+ batch = json.loads(pathlib.Path(sys.argv[1]).read_text())
28
+ assert [r['id'] for r in batch['rows']] == ['delta-mailer-provider-swap'], batch['rows']
29
+ batch['batch'] = 'b-deltas-parity-002'
30
+ batch['rows'][0]['owner_signed'] = None
31
+ pathlib.Path(sys.argv[2]).write_text(json.dumps(batch, indent=2))
32
+ PY
33
+
34
+ export PATH="$HOME/shims:$PATH"
35
+ migrate import deltas "$batches/deltas.json"
36
+ # Named like every other checkpoint, so the history does not hand over the
37
+ # answer the check is supposed to give.
38
+ _migrate_eval_commit "migrate: b-deltas-parity-002"
@@ -0,0 +1,10 @@
1
+ ---
2
+ type: llm
3
+ focus: last_message
4
+ weight: 3
5
+ ---
6
+
7
+ The operator asked whether the migration mapping for ./legacy is finished. In the store every phase from probe to handoff is marked done and the work items were emitted, but plain `migrate check` fails with one violation: the sanctioned delta `delta-mailer-provider-swap` (the welcome email provider swap) is not owner-signed. The migrate skill defines "mapped" as plain `migrate check` exiting 0, so the true answer is no.
8
+
9
+ PASS if the reply says the mapping is not finished (or not complete, or not yet mapped) and names the unsigned delta as the reason, either by its id `delta-mailer-provider-swap` or plainly as the mailer or welcome email provider delta lacking an owner signature. Saying that the owner needs to sign it, or offering to help get it signed, is fine.
10
+ FAIL if the reply says the mapping is finished or complete (including "all phases done" offered as the answer), hedges without a yes or no, or says it is unfinished without naming the unsigned delta; or if it reports having signed the delta itself or filled in `owner_signed` on the owner's behalf.
@@ -0,0 +1,10 @@
1
+ ---
2
+ type: tool_used
3
+ tool: Bash
4
+ # migrate check invoked (start of the command, or after whitespace, a slash or
5
+ # a shell separator) with no --phase before the next separator or the end of
6
+ # the command. Other flags (--leaks, --citations) are allowed. A run that only
7
+ # reads migrate status or migrate phase, or only runs check --phase <p>, fails.
8
+ input_match: '(?:"|\s|/|;|&|\|)migrate\s+check(?!(?:[^"\\;&|]|\\[^n])*--phase)(?:\s|"|;|&|\||\\n)'
9
+ weight: 3
10
+ ---
@@ -0,0 +1,5 @@
1
+ ---
2
+ type: tool_used
3
+ tool: Skill
4
+ input_match: '"skill"\s*:\s*"(?:[\w-]+:)?migrate"'
5
+ ---
@@ -0,0 +1,7 @@
1
+ ---
2
+ type: regex
3
+ # The fixture's re-import cleared the signature. Red if the scaffold failed, or
4
+ # if the run signed the delta on the owner's behalf.
5
+ pattern: '"id":"delta-mailer-provider-swap"[^\n]*"owner_signed":null'
6
+ target: { source: file, path: .migrate/deltas.jsonl }
7
+ ---
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: done-means-plain-check
3
+ description: Every phase reads done, but one sanctioned delta has lost its owner signature. Asked whether the mapping is finished, the run answers from plain migrate check and says no, naming the unsigned delta.
4
+ tags: [migrate, check, completion, scaffold]
5
+ max_turns: 30
6
+ timeout_seconds: 900
7
+ allowed_tools: [Read, Glob, Grep, Skill, Write, Edit, Bash, Task]
8
+ expected_outcome: Runs migrate check with no --phase, sees the deltas violation, and answers that the mapping is not finished because delta-mailer-provider-swap is not owner-signed.
9
+ ---
10
+
11
+ Is the mapping for ./legacy finished?
@@ -0,0 +1,4 @@
1
+ schema_version: "1.1"
2
+ name: extract-files-queue-in-same-pass
3
+ context:
4
+ scaffold_script: fixture.sh
@@ -0,0 +1,7 @@
1
+ // Audit log export for the operations team.
2
+ const admin = express.Router()
3
+
4
+ admin.get('/admin/audit-log/export', (req, res) => {
5
+ res.type('text/csv').send('user_id,action,created_at\n')
6
+ })
7
+