@bendyline/gilde 0.1.55 → 0.1.57

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 (191) hide show
  1. package/authoring/chat-models/glm-5.3-flash-320b-q2.json +129 -0
  2. package/authoring/chat-models/qwen3.8-flash-next-iq3.json +198 -0
  3. package/authoring/chat-models/qwen3.8-flash-next-iq4.json +198 -0
  4. package/authoring/gstack/wave.json +2 -2
  5. package/data/chat-models/gl/glm-5.3-flash-320b-q2/manifest.json +137 -0
  6. package/data/chat-models/gl/glm-5.3-flash-320b-q2/versions/1.0.0/manifest.json +23 -0
  7. package/data/chat-models/index.json +1 -1
  8. package/data/chat-models/qw/qwen3.8-flash-next-iq3/manifest.json +221 -0
  9. package/data/chat-models/qw/qwen3.8-flash-next-iq3/versions/1.0.0/manifest.json +36 -0
  10. package/data/chat-models/qw/qwen3.8-flash-next-iq4/manifest.json +221 -0
  11. package/data/chat-models/qw/qwen3.8-flash-next-iq4/versions/1.0.0/manifest.json +36 -0
  12. package/data/craftbook-templates/a1/a11y-audit/versions/1.1.3/test.json +16 -8
  13. package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.2/craftbook.json +618 -0
  14. package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.2/test.json +228 -0
  15. package/data/craftbook-templates/al/album-curate/versions/1.0.3/test.json +6 -3
  16. package/data/craftbook-templates/al/alert-rules/versions/1.0.3/test.json +8 -8
  17. package/data/craftbook-templates/an/anniversary-cut/versions/1.0.5/test.json +10 -5
  18. package/data/craftbook-templates/an/annual-document-review/versions/1.0.3/test.json +16 -8
  19. package/data/craftbook-templates/an/anomaly-scan/versions/1.0.3/test.json +12 -6
  20. package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.2/craftbook.json +602 -0
  21. package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.2/test.json +290 -0
  22. package/data/craftbook-templates/ar/artifact-integrity-review/versions/1.0.3/test.json +18 -9
  23. package/data/craftbook-templates/au/audiobook-master-pack/versions/1.0.5/test.json +10 -5
  24. package/data/craftbook-templates/au/auth-flow/versions/1.0.3/test.json +12 -6
  25. package/data/craftbook-templates/au/auth-flow/versions/1.0.4/craftbook.json +282 -0
  26. package/data/craftbook-templates/au/auth-flow/versions/1.0.4/test.json +143 -0
  27. package/data/craftbook-templates/au/automation-recipe/versions/1.0.3/test.json +12 -6
  28. package/data/craftbook-templates/ba/backup-routine/versions/1.0.4/craftbook.json +282 -0
  29. package/data/craftbook-templates/ba/backup-routine/versions/1.0.4/test.json +108 -0
  30. package/data/craftbook-templates/bl/blog-post/versions/1.0.3/test.json +8 -8
  31. package/data/craftbook-templates/br/branding-website/versions/1.1.3/craftbook.json +335 -0
  32. package/data/craftbook-templates/br/branding-website/versions/1.1.3/test.json +164 -0
  33. package/data/craftbook-templates/br/broadcast-announcement/versions/1.0.3/test.json +8 -8
  34. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.8/craftbook.json +621 -0
  35. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.8/test.json +376 -0
  36. package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.2/craftbook.json +730 -0
  37. package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.2/test.json +221 -0
  38. package/data/craftbook-templates/bu/build-loop/versions/1.1.1/test.json +8 -8
  39. package/data/craftbook-templates/ca/case-study/versions/1.0.3/test.json +8 -8
  40. package/data/craftbook-templates/ch/chapter-narration-run/versions/1.0.4/test.json +10 -5
  41. package/data/craftbook-templates/ch/character-turnaround/versions/1.0.3/test.json +25 -11
  42. package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.2/craftbook.json +587 -0
  43. package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.2/test.json +225 -0
  44. package/data/craftbook-templates/ci/citation-audit/versions/1.0.3/test.json +28 -14
  45. package/data/craftbook-templates/cl/cli-tool/versions/1.1.3/test.json +8 -8
  46. package/data/craftbook-templates/co/codebase-refactoring-review/versions/1.0.3/test.json +16 -8
  47. package/data/craftbook-templates/co/codebase-ux-review/versions/1.0.3/test.json +18 -9
  48. package/data/craftbook-templates/co/codemod-sweep/versions/1.0.2/craftbook.json +605 -0
  49. package/data/craftbook-templates/co/codemod-sweep/versions/1.0.2/test.json +252 -0
  50. package/data/craftbook-templates/co/cohort-analysis/versions/1.0.3/test.json +18 -9
  51. package/data/craftbook-templates/co/competitive-analysis/versions/1.0.3/test.json +23 -15
  52. package/data/craftbook-templates/co/content-accuracy-review/versions/1.0.3/test.json +28 -14
  53. package/data/craftbook-templates/co/content-deck/versions/1.2.3/craftbook.json +4 -4
  54. package/data/craftbook-templates/co/content-deck/versions/1.2.3/test.json +3 -0
  55. package/data/craftbook-templates/co/content-deck/versions/1.2.4/craftbook.json +341 -0
  56. package/data/craftbook-templates/co/content-deck/versions/1.2.4/test.json +169 -0
  57. package/data/craftbook-templates/co/copy-review/versions/1.0.3/test.json +14 -7
  58. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.3/craftbook.json +4 -4
  59. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.3/test.json +3 -0
  60. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.4/craftbook.json +345 -0
  61. package/data/craftbook-templates/co/corpus-email-digest/versions/1.2.4/test.json +187 -0
  62. package/data/craftbook-templates/co/corpus-synthesis/versions/1.0.3/test.json +26 -13
  63. package/data/craftbook-templates/co/cover-letter/versions/1.0.3/test.json +8 -8
  64. package/data/craftbook-templates/cs/csv-transformer/versions/1.2.4/test.json +7 -7
  65. package/data/craftbook-templates/da/dashboard-spec/versions/1.0.3/test.json +7 -7
  66. package/data/craftbook-templates/da/data-export-migrate/versions/1.0.4/craftbook.json +285 -0
  67. package/data/craftbook-templates/da/data-export-migrate/versions/1.0.4/test.json +104 -0
  68. package/data/craftbook-templates/da/data-pipeline-etl/versions/1.0.5/craftbook.json +284 -0
  69. package/data/craftbook-templates/da/data-pipeline-etl/versions/1.0.5/test.json +162 -0
  70. package/data/craftbook-templates/da/data-quality-audit/versions/1.0.3/test.json +38 -19
  71. package/data/craftbook-templates/da/data-to-report/versions/1.0.3/test.json +12 -6
  72. package/data/craftbook-templates/db/db-index-tuning/versions/1.0.4/craftbook.json +286 -0
  73. package/data/craftbook-templates/db/db-index-tuning/versions/1.0.4/test.json +104 -0
  74. package/data/craftbook-templates/de/dependency-audit/versions/1.1.3/test.json +14 -7
  75. package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.2/craftbook.json +621 -0
  76. package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.2/test.json +235 -0
  77. package/data/craftbook-templates/de/design-review/versions/1.0.3/test.json +16 -8
  78. package/data/craftbook-templates/de/design-system-consultation/versions/2.0.8/craftbook.json +616 -0
  79. package/data/craftbook-templates/de/design-system-consultation/versions/2.0.8/test.json +201 -0
  80. package/data/craftbook-templates/do/doc-intake-pipeline/versions/1.0.4/craftbook.json +285 -0
  81. package/data/craftbook-templates/do/doc-intake-pipeline/versions/1.0.4/test.json +104 -0
  82. package/data/craftbook-templates/do/doc-rewrite/versions/1.0.3/test.json +119 -55
  83. package/data/craftbook-templates/do/dockerize-app/versions/1.0.4/craftbook.json +285 -0
  84. package/data/craftbook-templates/do/dockerize-app/versions/1.0.4/test.json +92 -0
  85. package/data/craftbook-templates/do/documentation-drift-review/versions/1.0.3/test.json +18 -9
  86. package/data/craftbook-templates/dr/draft-social-post/versions/1.0.2/craftbook.json +324 -0
  87. package/data/craftbook-templates/dr/draft-social-post/versions/1.0.2/test.json +161 -0
  88. package/data/craftbook-templates/ed/edit-notes/versions/1.0.3/test.json +11 -4
  89. package/data/craftbook-templates/en/engineering-retrospective/versions/2.0.8/craftbook.json +566 -0
  90. package/data/craftbook-templates/en/engineering-retrospective/versions/2.0.8/test.json +191 -0
  91. package/data/craftbook-templates/ep/episode-plan/versions/1.0.3/test.json +10 -5
  92. package/data/craftbook-templates/ex/executive-level-review/versions/2.0.7/test.json +7 -10
  93. package/data/craftbook-templates/ex/executive-level-review/versions/2.0.8/craftbook.json +595 -0
  94. package/data/craftbook-templates/ex/executive-level-review/versions/2.0.8/test.json +139 -0
  95. package/data/craftbook-templates/ex/expense-categorize/versions/1.0.4/craftbook.json +277 -0
  96. package/data/craftbook-templates/ex/expense-categorize/versions/1.0.4/test.json +104 -0
  97. package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.2/craftbook.json +327 -0
  98. package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.2/test.json +162 -0
  99. package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.2/craftbook.json +718 -0
  100. package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.2/test.json +239 -0
  101. package/data/craftbook-templates/fo/form-fill-batch/versions/1.0.4/craftbook.json +285 -0
  102. package/data/craftbook-templates/fo/form-fill-batch/versions/1.0.4/test.json +162 -0
  103. package/data/craftbook-templates/fo/form-wizard/versions/1.0.3/test.json +8 -8
  104. package/data/craftbook-templates/ho/holiday-card-run/versions/1.0.3/test.json +11 -4
  105. package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.2/craftbook.json +610 -0
  106. package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.2/test.json +220 -0
  107. package/data/craftbook-templates/ht/html-arcade-game/versions/1.2.3/craftbook.json +343 -0
  108. package/data/craftbook-templates/ht/html-arcade-game/versions/1.2.3/test.json +176 -0
  109. package/data/craftbook-templates/id/idea-office-hours/versions/2.0.8/craftbook.json +566 -0
  110. package/data/craftbook-templates/id/idea-office-hours/versions/2.0.8/test.json +141 -0
  111. package/data/craftbook-templates/im/image-set-index/versions/1.2.3/craftbook.json +298 -0
  112. package/data/craftbook-templates/im/image-set-index/versions/1.2.3/test.json +180 -0
  113. package/data/craftbook-templates/in/insurance-inventory/versions/1.0.3/test.json +11 -4
  114. package/data/craftbook-templates/in/interactive-quiz/versions/1.0.3/test.json +48 -23
  115. package/data/craftbook-templates/in/invitation-design/versions/1.0.3/test.json +1 -1
  116. package/data/craftbook-templates/index.json +1 -1
  117. package/data/craftbook-templates/it/item-intake/versions/1.0.3/test.json +11 -4
  118. package/data/craftbook-templates/le/lead-enrichment/versions/1.0.4/craftbook.json +277 -0
  119. package/data/craftbook-templates/le/lead-enrichment/versions/1.0.4/test.json +104 -0
  120. package/data/craftbook-templates/me/meeting-prep-brief/versions/1.0.3/test.json +16 -8
  121. package/data/craftbook-templates/me/memory-prompt-session/versions/1.0.3/test.json +3 -0
  122. package/data/craftbook-templates/mo/morning-report/versions/1.0.3/test.json +21 -9
  123. package/data/craftbook-templates/of/office-hours/versions/1.1.1/test.json +8 -8
  124. package/data/craftbook-templates/pe/perf-optimization/versions/2.0.2/craftbook.json +697 -0
  125. package/data/craftbook-templates/pe/perf-optimization/versions/2.0.2/test.json +235 -0
  126. package/data/craftbook-templates/pe/pest-diagnosis/versions/1.0.3/test.json +19 -8
  127. package/data/craftbook-templates/pl/plan/versions/1.0.2/test.json +8 -8
  128. package/data/craftbook-templates/pl/playtest-report/versions/1.0.3/test.json +17 -7
  129. package/data/craftbook-templates/pr/practice-exam/versions/1.0.3/test.json +7 -2
  130. package/data/craftbook-templates/pr/practice-session/versions/1.0.3/test.json +11 -4
  131. package/data/craftbook-templates/pu/pull-request-review/versions/1.9.2/craftbook.json +435 -0
  132. package/data/craftbook-templates/pu/pull-request-review/versions/1.9.2/test.json +141 -0
  133. package/data/craftbook-templates/qu/quarterly-summary/versions/1.0.3/test.json +16 -8
  134. package/data/craftbook-templates/re/receipt-intake/versions/1.0.3/test.json +11 -4
  135. package/data/craftbook-templates/re/receipt-ocr-ledger/versions/1.0.4/craftbook.json +277 -0
  136. package/data/craftbook-templates/re/receipt-ocr-ledger/versions/1.0.4/test.json +104 -0
  137. package/data/craftbook-templates/re/recipe-capture/versions/1.0.3/test.json +13 -5
  138. package/data/craftbook-templates/re/record-a-relative/versions/1.0.3/test.json +3 -0
  139. package/data/craftbook-templates/re/recurring-invoice-run/versions/1.0.4/craftbook.json +285 -0
  140. package/data/craftbook-templates/re/recurring-invoice-run/versions/1.0.4/test.json +104 -0
  141. package/data/craftbook-templates/re/refactor-module/versions/2.0.2/craftbook.json +695 -0
  142. package/data/craftbook-templates/re/refactor-module/versions/2.0.2/test.json +241 -0
  143. package/data/craftbook-templates/re/release-artifact-sanity-check/versions/1.0.4/craftbook.json +361 -0
  144. package/data/craftbook-templates/re/release-artifact-sanity-check/versions/1.0.4/test.json +138 -0
  145. package/data/craftbook-templates/re/release-notes/versions/1.0.4/test.json +8 -8
  146. package/data/craftbook-templates/re/release-notes/versions/1.0.5/craftbook.json +339 -0
  147. package/data/craftbook-templates/re/release-notes/versions/1.0.5/test.json +111 -0
  148. package/data/craftbook-templates/re/reliability-review/versions/1.0.3/test.json +16 -8
  149. package/data/craftbook-templates/re/research-report/versions/1.0.3/test.json +16 -8
  150. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.8/craftbook.json +596 -0
  151. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.8/test.json +157 -0
  152. package/data/craftbook-templates/ro/rough-cut-assembly/versions/1.0.4/test.json +13 -5
  153. package/data/craftbook-templates/sc/schema-migration/versions/2.0.2/craftbook.json +624 -0
  154. package/data/craftbook-templates/sc/schema-migration/versions/2.0.2/test.json +225 -0
  155. package/data/craftbook-templates/sc/script-automation/versions/1.0.4/craftbook.json +284 -0
  156. package/data/craftbook-templates/sc/script-automation/versions/1.0.4/test.json +162 -0
  157. package/data/craftbook-templates/se/security-architecture-review/versions/2.0.7/test.json +10 -13
  158. package/data/craftbook-templates/se/security-architecture-review/versions/2.0.8/craftbook.json +597 -0
  159. package/data/craftbook-templates/se/security-architecture-review/versions/2.0.8/test.json +157 -0
  160. package/data/craftbook-templates/so/social-digest/versions/1.0.3/craftbook.json +239 -0
  161. package/data/craftbook-templates/so/social-digest/versions/1.0.3/test.json +168 -0
  162. package/data/craftbook-templates/so/source-quality-audit/versions/1.0.3/test.json +25 -11
  163. package/data/craftbook-templates/sp/spec-authoring/versions/2.0.8/craftbook.json +599 -0
  164. package/data/craftbook-templates/sp/spec-authoring/versions/2.0.8/test.json +162 -0
  165. package/data/craftbook-templates/te/technical-documentation/versions/2.0.8/craftbook.json +577 -0
  166. package/data/craftbook-templates/te/technical-documentation/versions/2.0.8/test.json +174 -0
  167. package/data/craftbook-templates/te/test-coverage-review/versions/1.2.1/test.json +16 -8
  168. package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.2/craftbook.json +592 -0
  169. package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.2/test.json +195 -0
  170. package/data/craftbook-templates/th/thank-you-batch/versions/1.0.3/test.json +6 -3
  171. package/data/craftbook-templates/th/thank-you-sweep/versions/1.0.3/test.json +11 -4
  172. package/data/craftbook-templates/ti/tileset-batch/versions/1.0.3/test.json +9 -3
  173. package/data/craftbook-templates/tr/transcribe-and-shownotes/versions/1.0.3/test.json +10 -5
  174. package/data/craftbook-templates/tr/transcribe-index/versions/1.0.3/test.json +6 -3
  175. package/data/craftbook-templates/tr/translate-content/versions/1.1.3/craftbook.json +140 -0
  176. package/data/craftbook-templates/tr/translate-content/versions/1.1.3/test.json +141 -0
  177. package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.2/craftbook.json +594 -0
  178. package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.2/test.json +221 -0
  179. package/data/craftbook-templates/ux/ux-update/versions/1.0.2/craftbook.json +606 -0
  180. package/data/craftbook-templates/ux/ux-update/versions/1.0.2/test.json +206 -0
  181. package/data/craftbook-templates/we/weak-spot-drill/versions/1.0.3/test.json +11 -4
  182. package/data/craftbook-templates/we/weekly-walkthrough/versions/1.0.3/test.json +21 -9
  183. package/data/craftbook-templates/wh/whitepaper/versions/1.0.3/test.json +16 -8
  184. package/data/craftbook-templates/ye/year-in-review/versions/1.0.3/test.json +8 -4
  185. package/data/project-types/index.json +1 -1
  186. package/data/project-types/ju/just-chat/manifest.json +1 -1
  187. package/data/project-types/ju/just-chat/versions/1.0.1/about.md +5 -0
  188. package/data/project-types/ju/just-chat/versions/1.0.1/manifest.json +19 -0
  189. package/package.json +1 -1
  190. package/schemas/chat-model-identity.schema.json +27 -0
  191. package/schemas/chat-model-version.schema.json +22 -0
@@ -0,0 +1,225 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "title": "Expand/contract data migration with no record stranded",
4
+ "objective": "The craftbook drives an expand/contract migration of a JSON user store from a flat name field to a nested profile shape: a plan grounded in the real files, accessors changed at their real sites with the suite green between stages, the data transformed with every value surviving exactly, and the old shape fully retired - verified mechanically, including a pure-nested-record probe proving the dual-read did not linger.",
5
+ "tags": [
6
+ "code",
7
+ "schema-migration",
8
+ "expand-contract",
9
+ "tactical-fleet"
10
+ ],
11
+ "prompt": "Use the Schema / Type Migration craftbook for this: migrate our user records from the flat name field to the nested profile shape described in source/migration-brief.md. No record may be lost, the accessors in src/users.js must keep working at every stage, and when it is done nothing may read the flat field any more.",
12
+ "setup": {
13
+ "projectName": "Crew Roster",
14
+ "about": "A tiny user-roster module backed by a JSON data file. Tests run with `npm run test` (node --test).",
15
+ "files": [
16
+ {
17
+ "path": "package.json",
18
+ "content": "{\n \"name\": \"crew-roster\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"node --test\"\n }\n}\n"
19
+ },
20
+ {
21
+ "path": "data/users.json",
22
+ "content": "[\n { \"id\": 1, \"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\" },\n { \"id\": 2, \"name\": \"Grace Hopper\", \"email\": \"grace@example.com\" },\n { \"id\": 3, \"name\": \"Annie Easley\", \"email\": \"annie@example.com\" }\n]\n"
23
+ },
24
+ {
25
+ "path": "src/users.js",
26
+ "content": "import { readFileSync } from 'node:fs';\n\nconst DB_URL = new URL('../data/users.json', import.meta.url);\n\nexport function loadUsers() {\n return JSON.parse(readFileSync(DB_URL, 'utf8'));\n}\n\nexport function fullName(user) {\n return user.name;\n}\n\nexport function byFullName(users, wanted) {\n return users.find((user) => user.name === wanted);\n}\n"
27
+ },
28
+ {
29
+ "path": "tests/users.test.mjs",
30
+ "content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { byFullName, fullName, loadUsers } from '../src/users.js';\n\ntest('loads every user record', () => {\n assert.equal(loadUsers().length, 3);\n});\n\ntest('fullName renders the display name', () => {\n assert.deepEqual(loadUsers().map(fullName), [\n 'Ada Lovelace',\n 'Grace Hopper',\n 'Annie Easley',\n ]);\n});\n\ntest('byFullName finds a user by display name', () => {\n assert.equal(byFullName(loadUsers(), 'Grace Hopper').email, 'grace@example.com');\n});\n"
31
+ },
32
+ {
33
+ "path": "source/migration-brief.md",
34
+ "content": "# Migration brief: nested profile shape\n\nWe sort and filter by last name now, so the flat `name` field has to go.\n\nCurrent record shape in `data/users.json`:\n\n { \"id\": 1, \"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\" }\n\nTarget record shape:\n\n { \"id\": 1, \"profile\": { \"first\": \"Ada\", \"last\": \"Lovelace\" }, \"email\": \"ada@example.com\" }\n\nRules:\n\n- Every existing record must survive the migration exactly - same people, same\n emails, names split on the single space between first and last name.\n- The accessors in `src/users.js` must keep working for their callers at every\n stage: `fullName` and `byFullName` keep returning the same display names as\n today.\n- When the migration is done, nothing reads the flat `name` field any more.\n"
35
+ },
36
+ {
37
+ "path": "tests/verify-migration.mjs",
38
+ "content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nconst root = process.cwd();\n\n// 1) The data moved to the target shape with no record stranded.\nconst records = JSON.parse(readFileSync(join(root, 'data/users.json'), 'utf8'));\nassert.ok(Array.isArray(records), 'data/users.json must stay a JSON array');\nassert.equal(records.length, 3, 'all three records must survive the migration');\nconst expected = new Map([\n ['ada@example.com', ['Ada', 'Lovelace']],\n ['grace@example.com', ['Grace', 'Hopper']],\n ['annie@example.com', ['Annie', 'Easley']],\n]);\nfor (const record of records) {\n assert.ok(record && typeof record === 'object', 'each record must stay an object');\n assert.ok(!('name' in record), `record ${record.id} still carries the flat name field`);\n const want = expected.get(record.email);\n assert.ok(want, `record ${record.id} lost or changed its email`);\n assert.equal(record.profile?.first, want[0], `record ${record.id} must keep its first name exactly`);\n assert.equal(record.profile?.last, want[1], `record ${record.id} must keep its last name exactly`);\n}\nconsole.log('SCHEMAMIG_ORACLE data intact');\n\n// 2) The accessors read the new shape - a pure nested record, no flat fallback.\nconst users = await import(pathToFileURL(join(root, 'src/users.js')).href);\nassert.equal(\n users.fullName({ profile: { first: 'Test', last: 'User' } }),\n 'Test User',\n 'fullName must read profile.first and profile.last',\n);\nassert.equal(\n users.byFullName([{ profile: { first: 'Grace', last: 'Hopper' }, email: 'x' }], 'Grace Hopper')?.email,\n 'x',\n 'byFullName must match display names on the new shape',\n);\nconsole.log('SCHEMAMIG_ORACLE accessors migrated');\n\n// 3) Contract landed: no flat-shape read remains in the accessor module.\nconst accessorSource = readFileSync(join(root, 'src/users.js'), 'utf8');\nassert.ok(\n !/\\.name\\b|\\[[\"']name[\"']\\]/.test(accessorSource),\n 'src/users.js still reads the flat name field',\n);\nconsole.log('SCHEMAMIG_ORACLE contract complete');\n\n// 4) The suite is green on the migrated tree, and the seeded test file survives.\nreadFileSync(join(root, 'tests/users.test.mjs'));\nfunction runSuite(cwd) {\n try {\n execFileSync(process.execPath, ['--test'], { cwd, stdio: 'pipe', timeout: 30000 });\n return 0;\n } catch (err) {\n return typeof err.status === 'number' ? err.status : 1;\n }\n}\nassert.equal(runSuite(root), 0, 'the suite must be green after the migration');\nconsole.log('SCHEMAMIG_ORACLE suite green');\nconsole.log('SCHEMAMIG_ORACLE done');\n",
39
+ "surface": "harness"
40
+ }
41
+ ],
42
+ "craftbookParams": {
43
+ "scope": "Migrate data/users.json and src/users.js from the flat name field to profile.first/profile.last per source/migration-brief.md, with no record loss and reads working at every stage."
44
+ }
45
+ },
46
+ "mocks": [],
47
+ "success": {
48
+ "summary": "Every record reaches the nested profile shape with its values intact, the accessors read the new shape with the dual-read retired, the flat field is gone from data and code, the suite is green, and every fleet artifact exists with honest receipts.",
49
+ "deliverables": [
50
+ {
51
+ "path": "{{task.dir}}/migration-plan.md",
52
+ "kind": "markdown-notes",
53
+ "artifact": true,
54
+ "minBytes": 700,
55
+ "checks": [
56
+ {
57
+ "kind": "contains",
58
+ "file": "{{task.dir}}/migration-plan.md",
59
+ "pattern": "^##\\s+Current shape[\\s\\S]*^##\\s+Target shape[\\s\\S]*^##\\s+Stages[\\s\\S]*^##\\s+Data safety[\\s\\S]*^##\\s+Rollback per stage",
60
+ "flags": "im",
61
+ "label": "plan sections in order"
62
+ },
63
+ {
64
+ "kind": "contains",
65
+ "file": "{{task.dir}}/migration-plan.md",
66
+ "pattern": "data/users\\.json",
67
+ "label": "names the real data file"
68
+ },
69
+ {
70
+ "kind": "citationsResolve",
71
+ "file": "{{task.dir}}/migration-plan.md",
72
+ "minCitations": 2,
73
+ "artifact": true
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "path": "{{task.dir}}/change-notes.md",
79
+ "kind": "markdown-notes",
80
+ "artifact": true,
81
+ "minBytes": 700,
82
+ "checks": [
83
+ {
84
+ "kind": "contains",
85
+ "file": "{{task.dir}}/change-notes.md",
86
+ "pattern": "^##\\s+Stages executed[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Data transformed[\\s\\S]*^##\\s+Deviations",
87
+ "flags": "im",
88
+ "label": "change-notes sections in order"
89
+ },
90
+ {
91
+ "kind": "citationsResolve",
92
+ "file": "{{task.dir}}/change-notes.md",
93
+ "minCitations": 2,
94
+ "artifact": true
95
+ }
96
+ ]
97
+ },
98
+ {
99
+ "path": "{{task.dir}}/verification.md",
100
+ "kind": "markdown-notes",
101
+ "artifact": true,
102
+ "minBytes": 500,
103
+ "checks": [
104
+ {
105
+ "kind": "contains",
106
+ "file": "{{task.dir}}/verification.md",
107
+ "pattern": "^##\\s+Old shape check[\\s\\S]*^##\\s+Data integrity[\\s\\S]*^##\\s+Suite[\\s\\S]*^##\\s+Result",
108
+ "flags": "im",
109
+ "label": "verification sections in order"
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ "path": "{{task.dir}}/review.md",
115
+ "kind": "markdown-report",
116
+ "artifact": true,
117
+ "minBytes": 400,
118
+ "checks": [
119
+ {
120
+ "kind": "contains",
121
+ "file": "{{task.dir}}/review.md",
122
+ "pattern": "Verdict:\\s*(?:PASS|REVISE)",
123
+ "flags": "i",
124
+ "label": "explicit reviewer verdict"
125
+ }
126
+ ]
127
+ }
128
+ ],
129
+ "checks": [
130
+ {
131
+ "kind": "notContains",
132
+ "file": "data/users.json",
133
+ "pattern": "\"name\"\\s*:",
134
+ "label": "the flat name field is gone from the data"
135
+ },
136
+ {
137
+ "kind": "notContains",
138
+ "file": "src/users.js",
139
+ "pattern": "\\.name\\b|\\[[\"']name[\"']\\]",
140
+ "label": "no flat-shape read remains in the accessors"
141
+ },
142
+ {
143
+ "kind": "sourceParses",
144
+ "file": "src/users.js"
145
+ },
146
+ {
147
+ "kind": "sniff",
148
+ "file": "data/users.json",
149
+ "sniff": "json-valid"
150
+ },
151
+ {
152
+ "kind": "nodeRuns",
153
+ "file": "tests/users.test.mjs"
154
+ },
155
+ {
156
+ "kind": "nodeScriptPasses",
157
+ "script": "tests/verify-migration.mjs",
158
+ "timeoutMs": 60000,
159
+ "requiredOutput": [
160
+ {
161
+ "pattern": "SCHEMAMIG_ORACLE data intact",
162
+ "label": "every record migrated with values intact"
163
+ },
164
+ {
165
+ "pattern": "SCHEMAMIG_ORACLE accessors migrated",
166
+ "label": "accessors read the new shape"
167
+ },
168
+ {
169
+ "pattern": "SCHEMAMIG_ORACLE contract complete",
170
+ "label": "the dual-read retired with the old shape"
171
+ },
172
+ {
173
+ "pattern": "SCHEMAMIG_ORACLE suite green",
174
+ "label": "suite green on the migrated tree"
175
+ }
176
+ ]
177
+ }
178
+ ],
179
+ "taskNotes": {
180
+ "minBytes": 120,
181
+ "checks": [
182
+ {
183
+ "kind": "contains",
184
+ "file": "task-notes.md",
185
+ "pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
186
+ "flags": "i",
187
+ "label": "DONE note names the real test command"
188
+ }
189
+ ]
190
+ },
191
+ "taskGraph": {
192
+ "requireCraftbookTask": true,
193
+ "requireTerminalStep": true
194
+ },
195
+ "unchangedFixtures": [
196
+ "source/migration-brief.md",
197
+ "package.json"
198
+ ]
199
+ },
200
+ "rubric": {
201
+ "artifact": {
202
+ "path": "{{task.dir}}/change-notes.md",
203
+ "kind": "markdown"
204
+ },
205
+ "axes": [
206
+ {
207
+ "name": "Expand/contract discipline",
208
+ "description": "The stages genuinely followed expand, migrate, contract in order - readers accepted both shapes while the data moved, and the old shape was dropped only after the transform completed with a green suite."
209
+ },
210
+ {
211
+ "name": "Data preservation",
212
+ "description": "The transform is real and lossless: every record reached the target shape with names and emails surviving exactly, proven by counts and spot-checks rather than asserted."
213
+ },
214
+ {
215
+ "name": "Honest verification",
216
+ "description": "Verification searched for leftover old-shape reads, quoted what it found, ran the real suite, and labeled anything unrun as unverified instead of claiming it."
217
+ }
218
+ ]
219
+ },
220
+ "qualityFocus": [
221
+ "expand/contract data safety",
222
+ "no record stranded",
223
+ "real-site accessor changes"
224
+ ]
225
+ }
@@ -0,0 +1,284 @@
1
+ {
2
+ "id": "script-automation",
3
+ "name": "One-Off Automation Script",
4
+ "description": "Write a one-off automation script that reliably does a repetitive task — process files, call an API, transform data — with arguments, a dry-run, idempotency, and clear logging so it is safe to run. Scopes the task FIRST — inputs/outputs, side-effects, the dry-run, idempotency, and failure handling — then implements the runnable script with args and a dry-run mode, then a reviewer confirms it does the job, is safe to re-run, and fails loudly. Covers argument handling, dry-run/preview mode, idempotent side-effects, progress logging, error handling, and safe-to-rerun automation.\n\nA gallery craftbook generated from an archetype spec. It runs\n`phase → (per-phase gate) → … → evaluate → (loop) → finish`. Each build\nphase that produces a checkable artifact is followed by a **runtime\ngate-checkpoint** — the runtime verifies the artifact and routes with no\nmodel turn, looping back to redo the phase on a miss. The final `evaluate`\nstep holds a static deliverable gate plus a reviewer QA pass. What it adds\nover the generic `build-loop`: a specialist role per phase, a\ndomain-correct ordering, and a concrete per-phase quality bar.\n\nDeliverables marked \"artifact\" land in the project's artifacts drawer (`write_artifact` / `read_artifact`), not the shipped workspace — review output is not product source.\n\nPhases:\n\n1. Scope the task (planner) — lock inputs/outputs, side-effects, dry-run, safety → gated on artifact `{{workPath}}/scope.md` (markdown-notes)\n2. Build the script (developer) — implement the runnable script with dry-run → gated on `src/script.js` (code-module)\n3. Verify the script (reviewer) — confirm it works, is rerun-safe, fails loudly → gated on artifact `{{workPath}}/verify.md` (markdown-notes)\n\nThe gates never advance with an unmet criterion, and loop back to the\nowning phase to fix named gaps.\n",
5
+ "entryStepId": "scope",
6
+ "triggers": [
7
+ "write an automation script",
8
+ "automate a task",
9
+ "one-off script",
10
+ "script to process files",
11
+ "batch automation"
12
+ ],
13
+ "paramSchema": {
14
+ "type": "object",
15
+ "properties": {
16
+ "workPath": {
17
+ "type": "string",
18
+ "title": "Working folder",
19
+ "description": "Per-task working folder in the artifacts drawer. Defaults to this task's own folder so runs never collide; override with a stable name when you deliberately want runs to share files.",
20
+ "default": "{{task.dir}}"
21
+ }
22
+ }
23
+ },
24
+ "steps": [
25
+ {
26
+ "id": "scope",
27
+ "name": "Scope the task",
28
+ "description": "lock inputs/outputs, side-effects, dry-run, safety",
29
+ "prompt": "Scope the automation before coding — a script with side-effects deserves a plan. Step 1: State exactly what the script does, its INPUTS (args, files, env) and its OUTPUTS/side-effects (files written, API calls, records changed). Step 2: Decide the safety affordances: a DRY-RUN/preview mode that shows what would happen without doing it, and how the real run is confirmed. Step 3: Decide idempotency — re-running must not double-apply (skip already-done work) — and failure handling (stop vs skip-and-log, exit code). Step 4: Decide the logging: what progress and summary it prints. Step 5: Write a numbered acceptance-criteria checklist of 5-9 items (e.g. 'a dry-run makes no changes and previews the plan', 'a real run performs the task', 're-running is a safe no-op on already-done items', 'errors are logged and exit non-zero'). `write_task_note` the scope + checklist and write the same to the produces path.\n\nThe deliverable `{{workPath}}/scope.md` lands in the project's artifacts drawer — write it with `write_artifact` and read it back with `read_artifact`; the shipped workspace stays untouched.",
30
+ "suggestedRole": "planner",
31
+ "toolPolicy": {
32
+ "disallowBuiltinToolsets": [
33
+ "ai-apps",
34
+ "archives",
35
+ "audio",
36
+ "browser-automation",
37
+ "code-execution",
38
+ "craftbooks",
39
+ "data-tables",
40
+ "entity-intel",
41
+ "git",
42
+ "image-intel",
43
+ "images",
44
+ "role-delegation",
45
+ "role-delegation-escalation",
46
+ "security-intel",
47
+ "team-management",
48
+ "videos",
49
+ "web",
50
+ "workspace-fs-write"
51
+ ],
52
+ "outputMedium": "artifact",
53
+ "additionalOutputMedia": [
54
+ "task-note"
55
+ ]
56
+ },
57
+ "advanceWhen": {
58
+ "file": "{{workPath}}/scope.md",
59
+ "minBytes": 1,
60
+ "sniff": "nonempty",
61
+ "artifact": true
62
+ },
63
+ "gate": {
64
+ "at": "completion",
65
+ "checks": [
66
+ {
67
+ "kind": "minBytes",
68
+ "file": "{{workPath}}/scope.md",
69
+ "bytes": 120,
70
+ "artifact": true
71
+ },
72
+ {
73
+ "kind": "sniff",
74
+ "file": "{{workPath}}/scope.md",
75
+ "sniff": "nonempty",
76
+ "artifact": true
77
+ }
78
+ ],
79
+ "onReject": "scope",
80
+ "maxAttempts": 3
81
+ },
82
+ "next": "build"
83
+ },
84
+ {
85
+ "id": "build",
86
+ "name": "Build the script",
87
+ "description": "implement the runnable script with dry-run",
88
+ "prompt": "Implement the script to the scope as a single runnable file. Step 1: Parse the arguments (including a `--dry-run` flag) and validate inputs up front, failing fast with a clear message on bad args. Step 2: Implement the core task; in dry-run mode, LOG what each action WOULD do and make zero side-effects, while the real run performs them. Step 3: Make side-effects idempotent — check before writing/calling so a re-run skips already-done items. Step 4: Log progress per item and a final summary (done/skipped/failed counts); on error, log it clearly and exit non-zero. Write the script to the produces path. On a loop-back, fix only the named gap. `write_task_note` the file path and which criteria now pass.",
89
+ "suggestedRole": "developer",
90
+ "toolPolicy": {
91
+ "disallowBuiltinToolsets": [
92
+ "ai-apps",
93
+ "archives",
94
+ "artifacts",
95
+ "audio",
96
+ "browser-automation",
97
+ "craftbooks",
98
+ "data-tables",
99
+ "entity-intel",
100
+ "git",
101
+ "image-intel",
102
+ "images",
103
+ "role-delegation",
104
+ "role-delegation-escalation",
105
+ "security-intel",
106
+ "team-management",
107
+ "videos",
108
+ "web"
109
+ ],
110
+ "outputMedium": "workspace",
111
+ "additionalOutputMedia": [
112
+ "task-note"
113
+ ]
114
+ },
115
+ "advanceWhen": {
116
+ "file": "src/script.js",
117
+ "minBytes": 1,
118
+ "sniff": "nonempty"
119
+ },
120
+ "gate": {
121
+ "at": "completion",
122
+ "checks": [
123
+ {
124
+ "kind": "minBytes",
125
+ "file": "src/script.js",
126
+ "bytes": 200
127
+ },
128
+ {
129
+ "kind": "sniff",
130
+ "file": "src/script.js",
131
+ "sniff": "nonempty"
132
+ },
133
+ {
134
+ "kind": "esmImports",
135
+ "file": "src/script.js"
136
+ },
137
+ {
138
+ "kind": "sourceParses",
139
+ "file": "src/script.js"
140
+ }
141
+ ],
142
+ "onReject": "build",
143
+ "maxAttempts": 3
144
+ },
145
+ "next": "verify"
146
+ },
147
+ {
148
+ "id": "verify",
149
+ "name": "Verify the script",
150
+ "description": "confirm it works, is rerun-safe, fails loudly",
151
+ "prompt": "Verify the automation is correct and safe. Step 1: Run it with `--dry-run` and confirm it previews actions and makes NO changes. Step 2: Run it for real on sample input and confirm it performs the task and prints a sensible summary. Step 3: Run it AGAIN and confirm the second run is a safe no-op on already-done items (idempotent). Step 4: Feed bad input/args and confirm it fails loudly with a clear message and a non-zero exit. Write a verification note covering the dry-run, real run, re-run, and error handling to the produces path.\n\nThe deliverable `{{workPath}}/verify.md` lands in the project's artifacts drawer — write it with `write_artifact` and read it back with `read_artifact`; the shipped workspace stays untouched.",
152
+ "suggestedRole": "reviewer",
153
+ "toolPolicy": {
154
+ "disallowBuiltinToolsets": [
155
+ "ai-apps",
156
+ "archives",
157
+ "audio",
158
+ "browser-automation",
159
+ "code-execution",
160
+ "craftbooks",
161
+ "data-tables",
162
+ "entity-intel",
163
+ "git",
164
+ "image-intel",
165
+ "images",
166
+ "role-delegation",
167
+ "role-delegation-escalation",
168
+ "security-intel",
169
+ "team-management",
170
+ "videos",
171
+ "web",
172
+ "workspace-fs-write"
173
+ ],
174
+ "outputMedium": "artifact",
175
+ "additionalOutputMedia": [
176
+ "task-note"
177
+ ]
178
+ },
179
+ "advanceWhen": {
180
+ "file": "{{workPath}}/verify.md",
181
+ "minBytes": 1,
182
+ "sniff": "nonempty",
183
+ "artifact": true
184
+ },
185
+ "gate": {
186
+ "at": "completion",
187
+ "checks": [
188
+ {
189
+ "kind": "minBytes",
190
+ "file": "src/script.js",
191
+ "bytes": 200
192
+ },
193
+ {
194
+ "kind": "sniff",
195
+ "file": "src/script.js",
196
+ "sniff": "nonempty"
197
+ },
198
+ {
199
+ "kind": "esmImports",
200
+ "file": "src/script.js"
201
+ },
202
+ {
203
+ "kind": "sourceParses",
204
+ "file": "src/script.js"
205
+ }
206
+ ],
207
+ "onReject": "verify",
208
+ "maxAttempts": 4
209
+ },
210
+ "next": "evaluate"
211
+ },
212
+ {
213
+ "id": "evaluate",
214
+ "name": "Evaluate",
215
+ "description": "Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.",
216
+ "prompt": "Run the script in dry-run, real, re-run, and error modes. For EACH acceptance criterion: confirm dry-run makes no changes and previews the plan, confirm a real run performs the task with a summary, confirm a re-run is a safe no-op on done items, and confirm bad input fails loudly with a non-zero exit. Write PASS/FAIL per criterion; a dry-run that mutates state or a non-idempotent re-run is a FAIL.\n\nThen route — this is the whole point of the loop:\n\n- **Every criterion PASSES →** call `advance_task_step({ ref, stepId: \"evaluate\", next: \"finish\" })`.\n- **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: \"evaluate\", next: \"build\" })` to loop back. The builder fixes exactly those gaps.\n\nNever route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in.",
217
+ "suggestedRole": "reviewer",
218
+ "toolPolicy": {
219
+ "disallowBuiltinToolsets": [
220
+ "ai-apps",
221
+ "archives",
222
+ "artifacts",
223
+ "audio",
224
+ "browser-automation",
225
+ "craftbooks",
226
+ "data-tables",
227
+ "entity-intel",
228
+ "git",
229
+ "image-intel",
230
+ "images",
231
+ "role-delegation",
232
+ "role-delegation-escalation",
233
+ "security-intel",
234
+ "team-management",
235
+ "videos",
236
+ "web",
237
+ "workspace-fs-write"
238
+ ],
239
+ "outputMedium": "task-note"
240
+ },
241
+ "consumes": [
242
+ {
243
+ "file": "src/script.js"
244
+ }
245
+ ],
246
+ "next": "build"
247
+ },
248
+ {
249
+ "id": "finish",
250
+ "name": "Finish",
251
+ "description": "All acceptance criteria met. Stamp a short summary and report DONE.",
252
+ "prompt": "Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.",
253
+ "suggestedRole": "developer",
254
+ "toolPolicy": {
255
+ "disallowBuiltinToolsets": [
256
+ "ai-apps",
257
+ "archives",
258
+ "artifacts",
259
+ "audio",
260
+ "browser-automation",
261
+ "code-execution",
262
+ "craftbooks",
263
+ "data-tables",
264
+ "entity-intel",
265
+ "git",
266
+ "image-intel",
267
+ "images",
268
+ "role-delegation",
269
+ "role-delegation-escalation",
270
+ "security-intel",
271
+ "team-management",
272
+ "videos",
273
+ "web",
274
+ "workspace-fs-write"
275
+ ],
276
+ "outputMedium": "task-note"
277
+ },
278
+ "terminal": true
279
+ }
280
+ ],
281
+ "version": "1.0.4",
282
+ "releasedAt": "2026-09-05T03:30:00Z",
283
+ "minGezelVersion": "1.26233"
284
+ }