@bendyline/gilde 0.1.40 → 0.1.42

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 (150) hide show
  1. package/authoring/gstack/overlays/investigate.json +1 -0
  2. package/authoring/gstack/overlays/qa-only.json +1 -0
  3. package/authoring/gstack/wave.json +12 -2
  4. package/authoring/tactical/books/accessibility-retrofit.json +188 -0
  5. package/authoring/tactical/books/apply-review-findings.json +189 -0
  6. package/authoring/tactical/books/bug-fix-tdd.json +237 -0
  7. package/authoring/tactical/books/ci-pipeline.json +168 -0
  8. package/authoring/tactical/books/codemod-sweep.json +182 -0
  9. package/authoring/tactical/books/dependency-upgrade.json +196 -0
  10. package/authoring/tactical/books/flaky-test-fix.json +238 -0
  11. package/authoring/tactical/books/hotfix-flow.json +187 -0
  12. package/authoring/tactical/books/perf-optimization.json +219 -0
  13. package/authoring/tactical/books/refactor-module.json +217 -0
  14. package/authoring/tactical/books/schema-migration.json +192 -0
  15. package/authoring/tactical/books/test-suite-backfill.json +172 -0
  16. package/authoring/tactical/books/type-safety-pass.json +185 -0
  17. package/authoring/tactical/books/ux-update.json +178 -0
  18. package/authoring/tactical/evals/accessibility-retrofit.json +230 -0
  19. package/authoring/tactical/evals/apply-review-findings.json +290 -0
  20. package/authoring/tactical/evals/bug-fix-tdd.json +221 -0
  21. package/authoring/tactical/evals/ci-pipeline.json +227 -0
  22. package/authoring/tactical/evals/codemod-sweep.json +252 -0
  23. package/authoring/tactical/evals/dependency-upgrade.json +235 -0
  24. package/authoring/tactical/evals/flaky-test-fix.json +239 -0
  25. package/authoring/tactical/evals/hotfix-flow.json +220 -0
  26. package/authoring/tactical/evals/perf-optimization.json +235 -0
  27. package/authoring/tactical/evals/refactor-module.json +241 -0
  28. package/authoring/tactical/evals/schema-migration.json +225 -0
  29. package/authoring/tactical/evals/test-suite-backfill.json +197 -0
  30. package/authoring/tactical/evals/type-safety-pass.json +221 -0
  31. package/authoring/tactical/evals/ux-update.json +206 -0
  32. package/authoring/tactical/wave.json +89 -0
  33. package/data/chat-models/de/deepseek-r1-8b-q4/manifest.json +56 -1
  34. package/data/chat-models/gl/glm-5.2-754b-q2/manifest.json +56 -0
  35. package/data/chat-models/gp/gpt-oss-120b-q4/manifest.json +73 -1
  36. package/data/chat-models/gp/gpt-oss-20b-q4/manifest.json +77 -1
  37. package/data/chat-models/index.json +1 -1
  38. package/data/chat-models/ll/llama3.2-3b-q4/manifest.json +3 -1
  39. package/data/chat-models/mi/mistral-7b-q4/manifest.json +54 -3
  40. package/data/chat-models/mi/mistral-medium-3.5-128b-q4/manifest.json +76 -1
  41. package/data/craftbook-templates/ac/accessibility-retrofit/manifest.json +5 -4
  42. package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.0/craftbook.json +451 -0
  43. package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.0/test.json +231 -0
  44. package/data/craftbook-templates/al/alt-text-pass/manifest.json +5 -1
  45. package/data/craftbook-templates/ap/apply-review-findings/art.json +12 -0
  46. package/data/craftbook-templates/ap/apply-review-findings/logo.webp +0 -0
  47. package/data/craftbook-templates/ap/apply-review-findings/manifest.json +23 -0
  48. package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.0/craftbook.json +436 -0
  49. package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.0/test.json +291 -0
  50. package/data/craftbook-templates/br/browser-qa-audit/manifest.json +5 -1
  51. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.5/craftbook.json +438 -0
  52. package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.5/test.json +379 -0
  53. package/data/craftbook-templates/bu/bug-fix-tdd/manifest.json +3 -3
  54. package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.0/craftbook.json +545 -0
  55. package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.0/test.json +222 -0
  56. package/data/craftbook-templates/ch/changelog-cut/manifest.json +5 -1
  57. package/data/craftbook-templates/ch/changelog-writeup/manifest.json +5 -1
  58. package/data/craftbook-templates/ci/ci-pipeline/manifest.json +5 -3
  59. package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.0/craftbook.json +423 -0
  60. package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.0/test.json +228 -0
  61. package/data/craftbook-templates/co/codemod-sweep/art.json +12 -0
  62. package/data/craftbook-templates/co/codemod-sweep/logo.webp +0 -0
  63. package/data/craftbook-templates/co/codemod-sweep/manifest.json +23 -0
  64. package/data/craftbook-templates/co/codemod-sweep/versions/1.0.0/craftbook.json +441 -0
  65. package/data/craftbook-templates/co/codemod-sweep/versions/1.0.0/test.json +253 -0
  66. package/data/craftbook-templates/de/dependency-upgrade/art.json +12 -0
  67. package/data/craftbook-templates/de/dependency-upgrade/logo.webp +0 -0
  68. package/data/craftbook-templates/de/dependency-upgrade/manifest.json +23 -0
  69. package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.0/craftbook.json +459 -0
  70. package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.0/test.json +236 -0
  71. package/data/craftbook-templates/fe/feature-flag-release/manifest.json +5 -1
  72. package/data/craftbook-templates/fe/feature-flag-rollout/manifest.json +4 -1
  73. package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.0/craftbook.json +203 -0
  74. package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.0/test.json +165 -0
  75. package/data/craftbook-templates/fl/flaky-test-fix/art.json +12 -0
  76. package/data/craftbook-templates/fl/flaky-test-fix/logo.webp +0 -0
  77. package/data/craftbook-templates/fl/flaky-test-fix/manifest.json +24 -0
  78. package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.0/craftbook.json +534 -0
  79. package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.0/test.json +240 -0
  80. package/data/craftbook-templates/ho/hotfix-flow/manifest.json +5 -3
  81. package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.0/craftbook.json +442 -0
  82. package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.0/test.json +221 -0
  83. package/data/craftbook-templates/in/investigate/manifest.json +4 -1
  84. package/data/craftbook-templates/in/investigate-root-cause/manifest.json +5 -1
  85. package/data/craftbook-templates/index.json +1 -1
  86. package/data/craftbook-templates/li/live-browser-qa/manifest.json +5 -1
  87. package/data/craftbook-templates/ni/nightly-fix-sweep/art.json +12 -0
  88. package/data/craftbook-templates/ni/nightly-fix-sweep/logo.webp +0 -0
  89. package/data/craftbook-templates/ni/nightly-fix-sweep/manifest.json +23 -0
  90. package/data/craftbook-templates/ni/nightly-fix-sweep/versions/1.0.0/craftbook.json +145 -0
  91. package/data/craftbook-templates/ni/nightly-fix-sweep/versions/1.0.0/test.json +121 -0
  92. package/data/craftbook-templates/pe/perf-audit/versions/1.1.0/craftbook.json +195 -0
  93. package/data/craftbook-templates/pe/perf-audit/versions/1.1.0/test.json +165 -0
  94. package/data/craftbook-templates/pe/perf-optimization/manifest.json +3 -3
  95. package/data/craftbook-templates/pe/perf-optimization/versions/2.0.0/craftbook.json +511 -0
  96. package/data/craftbook-templates/pe/perf-optimization/versions/2.0.0/test.json +236 -0
  97. package/data/craftbook-templates/po/powerpoint-deck/versions/1.7.4/test.json +0 -1
  98. package/data/craftbook-templates/pu/pull-request-review/versions/1.8.0/craftbook.json +304 -0
  99. package/data/craftbook-templates/pu/pull-request-review/versions/1.8.0/test.json +144 -0
  100. package/data/craftbook-templates/qa/qa/manifest.json +3 -1
  101. package/data/craftbook-templates/re/refactor-module/manifest.json +2 -2
  102. package/data/craftbook-templates/re/refactor-module/versions/1.0.4/craftbook.json +150 -0
  103. package/data/craftbook-templates/re/refactor-module/versions/1.0.4/test.json +95 -0
  104. package/data/craftbook-templates/re/refactor-module/versions/2.0.0/craftbook.json +509 -0
  105. package/data/craftbook-templates/re/refactor-module/versions/2.0.0/test.json +242 -0
  106. package/data/craftbook-templates/re/release-notes/manifest.json +5 -1
  107. package/data/craftbook-templates/re/release-notes/versions/1.0.3/craftbook.json +220 -0
  108. package/data/craftbook-templates/re/release-notes/versions/1.0.3/test.json +114 -0
  109. package/data/craftbook-templates/re/release-pipeline-ci/manifest.json +5 -1
  110. package/data/craftbook-templates/re/release-readiness-review/versions/1.1.0/craftbook.json +192 -0
  111. package/data/craftbook-templates/re/release-readiness-review/versions/1.1.0/test.json +113 -0
  112. package/data/craftbook-templates/ro/root-cause-investigation/manifest.json +7 -1
  113. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.5/craftbook.json +433 -0
  114. package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.5/test.json +157 -0
  115. package/data/craftbook-templates/sc/schema-migration/manifest.json +4 -4
  116. package/data/craftbook-templates/sc/schema-migration/versions/2.0.0/craftbook.json +459 -0
  117. package/data/craftbook-templates/sc/schema-migration/versions/2.0.0/test.json +226 -0
  118. package/data/craftbook-templates/te/test-coverage-review/versions/1.2.0/craftbook.json +195 -0
  119. package/data/craftbook-templates/te/test-coverage-review/versions/1.2.0/test.json +116 -0
  120. package/data/craftbook-templates/te/test-suite-backfill/manifest.json +1 -2
  121. package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.0/craftbook.json +428 -0
  122. package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.0/test.json +198 -0
  123. package/data/craftbook-templates/ty/type-safety-pass/manifest.json +3 -3
  124. package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.0/craftbook.json +428 -0
  125. package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.0/test.json +222 -0
  126. package/data/craftbook-templates/ux/ux-update/art.json +12 -0
  127. package/data/craftbook-templates/ux/ux-update/logo.webp +0 -0
  128. package/data/craftbook-templates/ux/ux-update/manifest.json +22 -0
  129. package/data/craftbook-templates/ux/ux-update/versions/1.0.0/craftbook.json +439 -0
  130. package/data/craftbook-templates/ux/ux-update/versions/1.0.0/test.json +207 -0
  131. package/data/craftbook-templates/ve/version-bump/versions/1.1.0/craftbook.json +206 -0
  132. package/data/craftbook-templates/ve/version-bump/versions/1.1.0/test.json +95 -0
  133. package/data/gezel-templates/bo/boekwachter/versions/1.1.0/about.md +29 -0
  134. package/data/gezel-templates/bo/boekwachter/versions/1.1.0/manifest.json +16 -0
  135. package/data/gezel-templates/bu/builder/versions/1.5.0/about.md +34 -0
  136. package/data/gezel-templates/bu/builder/versions/1.5.0/manifest.json +16 -0
  137. package/data/gezel-templates/de/developer/versions/1.5.0/about.md +34 -0
  138. package/data/gezel-templates/de/developer/versions/1.5.0/manifest.json +21 -0
  139. package/data/gezel-templates/index.json +1 -1
  140. package/data/gezel-templates/re/reviewer/versions/1.4.0/about.md +49 -0
  141. package/data/gezel-templates/re/reviewer/versions/1.4.0/manifest.json +21 -0
  142. package/data/project-types/index.json +1 -1
  143. package/data/project-types/so/software-project/manifest.json +20 -0
  144. package/data/project-types/so/software-project/versions/1.0.0/about.md +3 -0
  145. package/data/project-types/so/software-project/versions/1.0.0/manifest.json +41 -0
  146. package/data/project-types/so/software-project/versions/1.0.0/mission.md +4 -0
  147. package/package.json +1 -1
  148. package/schemas/craftbook-doc.schema.json +248 -0
  149. package/schemas/craftbook-template-version.schema.json +248 -0
  150. package/schemas/craftbook-test.schema.json +200 -0
@@ -0,0 +1,236 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "title": "Measured near-linear fix for a quadratic hot path",
4
+ "objective": "The craftbook drives a measured optimization of a seeded O(n^2) duplicate finder: baseline numbers recorded with their method, one bottleneck fixed at the real site, the same measurement re-run to prove the gain, and an enforced review — verified mechanically via a deterministic instrumented op-count budget, reference-equal results, and a green-suite run.",
5
+ "tags": [
6
+ "code",
7
+ "performance",
8
+ "tactical-fleet"
9
+ ],
10
+ "prompt": "Use the Targeted Performance Fix craftbook for this: support says importing a 200-row sheet crawls, and profiling points at findDuplicates - a 200-item list burns about 40,000 comparisons. The brief is in source/perf-brief.md. Get findDuplicates near-linear without changing its results.",
11
+ "setup": {
12
+ "projectName": "Sheet Importer",
13
+ "about": "A tiny sheet-import module with an instrumented duplicate finder. Tests run with `npm run test` (node --test).",
14
+ "files": [
15
+ {
16
+ "path": "package.json",
17
+ "content": "{\n \"name\": \"sheet-importer\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"node --test\"\n }\n}\n"
18
+ },
19
+ {
20
+ "path": "src/instrument.js",
21
+ "content": "let comparisons = 0;\n\nexport function countComparison() {\n comparisons += 1;\n}\n\nexport function comparisonCount() {\n return comparisons;\n}\n\nexport function resetComparisons() {\n comparisons = 0;\n}\n"
22
+ },
23
+ {
24
+ "path": "src/find-duplicates.js",
25
+ "content": "import { countComparison } from './instrument.js';\n\nexport function findDuplicates(items) {\n const duplicates = [];\n for (let i = 0; i < items.length; i += 1) {\n let count = 0;\n for (let j = 0; j < items.length; j += 1) {\n countComparison();\n if (items[j] === items[i]) count += 1;\n }\n if (count > 1 && !duplicates.includes(items[i])) duplicates.push(items[i]);\n }\n return duplicates;\n}\n"
26
+ },
27
+ {
28
+ "path": "tests/duplicates.test.mjs",
29
+ "content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { findDuplicates } from '../src/find-duplicates.js';\n\ntest('reports each duplicate once, in first-appearance order', () => {\n assert.deepEqual(findDuplicates(['a', 'b', 'a', 'c', 'b']), ['a', 'b']);\n});\n\ntest('returns empty for unique lists', () => {\n assert.deepEqual(findDuplicates(['x', 'y', 'z']), []);\n});\n\ntest('order pins to first appearance, not second occurrence', () => {\n assert.deepEqual(findDuplicates(['a', 'b', 'b', 'a']), ['a', 'b']);\n});\n"
30
+ },
31
+ {
32
+ "path": "source/perf-brief.md",
33
+ "content": "# Performance brief\n\nSupport reports that importing a 200-row sheet crawls. Profiling points at `findDuplicates` in src/find-duplicates.js: for a 200-item list it performs about 40,000 instrumented comparisons (200 x 200 full rescans). The counter lives in src/instrument.js - `comparisonCount()` reads it, `resetComparisons()` clears it.\n\nTarget: get `findDuplicates` near-linear - well under 2,000 instrumented comparisons for a 200-item list - WITHOUT changing its results. Each duplicated value is reported once, in order of FIRST appearance.\n\nRules:\n\n- src/instrument.js is measurement infrastructure; leave it exactly as it is.\n- Keep the measurement honest: keep calling `countComparison()` for every equality comparison the new implementation still performs. Deleting instrumentation instead of deleting work is measurement theater.\n- Measure with a repeatable command: a small script that builds a 200-item list, calls `findDuplicates`, and prints `comparisonCount()`.\n"
34
+ },
35
+ {
36
+ "path": "tests/verify-perf.mjs",
37
+ "content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { findDuplicates } from '../src/find-duplicates.js';\nimport { comparisonCount, resetComparisons } from '../src/instrument.js';\n\n// Independent reference: each duplicated value once, first-appearance order.\nfunction referenceDuplicates(items) {\n const counts = new Map();\n for (const item of items) counts.set(item, (counts.get(item) ?? 0) + 1);\n const out = [];\n const added = new Set();\n for (const item of items) {\n if ((counts.get(item) ?? 0) > 1 && !added.has(item)) {\n added.add(item);\n out.push(item);\n }\n }\n return out;\n}\n\n// 1) Results identical to reference on small pinned cases.\nassert.deepEqual(findDuplicates(['a', 'b', 'a', 'c', 'b']), ['a', 'b']);\nassert.deepEqual(findDuplicates([]), []);\nassert.deepEqual(findDuplicates(['a', 'b', 'b', 'a']), ['a', 'b']);\n\n// 2) Deterministic 200-item workload: results equal reference AND the\n// instrumented op-count is under the stated budget (seeded code: 40000).\nconst items = [];\nfor (let i = 0; i < 200; i += 1) items.push('v' + ((i * 7) % 149));\nresetComparisons();\nconst result = findDuplicates(items);\nassert.deepEqual(result, referenceDuplicates(items), 'results changed - speed that changes answers is a bug');\nconsole.log('PERF_OPTIMIZATION_ORACLE results ok');\nconst ops = comparisonCount();\nassert.ok(\n ops <= 2000,\n 'findDuplicates on 200 items performed ' + ops + ' instrumented comparisons - the budget is 2000 and the seeded code did 40000',\n);\nconsole.log('PERF_OPTIMIZATION_ORACLE ops ' + ops + ' within budget');\n\n// 3) The whole suite is green on the optimized tree (real run).\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(process.cwd()), 0, 'the suite must be green on the optimized tree');\nconsole.log('PERF_OPTIMIZATION_ORACLE suite green');\nconsole.log('PERF_OPTIMIZATION_ORACLE done');\n",
38
+ "surface": "harness"
39
+ }
40
+ ],
41
+ "craftbookParams": {
42
+ "workPath": "tasks/eval",
43
+ "scope": "findDuplicates in src/find-duplicates.js does about 40,000 instrumented comparisons for a 200-item list; get it near-linear (well under 2,000 comparisons) without changing its results. See source/perf-brief.md."
44
+ }
45
+ },
46
+ "mocks": [],
47
+ "success": {
48
+ "summary": "The quadratic rescan is gone, the instrumented op-count for 200 items is under budget, results are identical to the reference on a deterministic workload, the suite is green on a real run, and every fleet artifact exists with honest numbers and citations.",
49
+ "deliverables": [
50
+ {
51
+ "path": "tasks/eval/baseline.md",
52
+ "kind": "markdown-notes",
53
+ "artifact": true,
54
+ "minBytes": 500,
55
+ "checks": [
56
+ {
57
+ "kind": "contains",
58
+ "file": "tasks/eval/baseline.md",
59
+ "pattern": "^##\\s+Current behavior[\\s\\S]*^##\\s+Measurements[\\s\\S]*^##\\s+Guardrail",
60
+ "flags": "im",
61
+ "label": "baseline sections in order"
62
+ },
63
+ {
64
+ "kind": "contains",
65
+ "file": "tasks/eval/baseline.md",
66
+ "pattern": "^##\\s+Measurements[\\s\\S]*\\d",
67
+ "flags": "im",
68
+ "label": "baseline numbers recorded"
69
+ },
70
+ {
71
+ "kind": "citationsResolve",
72
+ "file": "tasks/eval/baseline.md",
73
+ "minCitations": 2,
74
+ "artifact": true
75
+ }
76
+ ]
77
+ },
78
+ {
79
+ "path": "tasks/eval/plan.md",
80
+ "kind": "markdown-notes",
81
+ "artifact": true,
82
+ "minBytes": 500,
83
+ "checks": [
84
+ {
85
+ "kind": "contains",
86
+ "file": "tasks/eval/plan.md",
87
+ "pattern": "^##\\s+Target[\\s\\S]*^##\\s+Stages[\\s\\S]*^##\\s+Acceptance criteria",
88
+ "flags": "im",
89
+ "label": "plan sections in order"
90
+ },
91
+ {
92
+ "kind": "citationsResolve",
93
+ "file": "tasks/eval/plan.md",
94
+ "minCitations": 2,
95
+ "artifact": true
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ "path": "tasks/eval/change-notes.md",
101
+ "kind": "markdown-notes",
102
+ "artifact": true,
103
+ "minBytes": 600,
104
+ "checks": [
105
+ {
106
+ "kind": "contains",
107
+ "file": "tasks/eval/change-notes.md",
108
+ "pattern": "^##\\s+Stages executed[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Deviations from plan",
109
+ "flags": "im",
110
+ "label": "change-notes sections in order"
111
+ },
112
+ {
113
+ "kind": "citationsResolve",
114
+ "file": "tasks/eval/change-notes.md",
115
+ "minCitations": 2,
116
+ "artifact": true
117
+ }
118
+ ]
119
+ },
120
+ {
121
+ "path": "tasks/eval/verification.md",
122
+ "kind": "markdown-notes",
123
+ "artifact": true,
124
+ "minBytes": 400,
125
+ "checks": [
126
+ {
127
+ "kind": "contains",
128
+ "file": "tasks/eval/verification.md",
129
+ "pattern": "^##\\s+Before\\s*/\\s*after[\\s\\S]*^##\\s+Suite[\\s\\S]*^##\\s+Result",
130
+ "flags": "im",
131
+ "label": "verification sections in order"
132
+ },
133
+ {
134
+ "kind": "contains",
135
+ "file": "tasks/eval/verification.md",
136
+ "pattern": "^##\\s+Before\\s*/\\s*after[\\s\\S]*\\d",
137
+ "flags": "im",
138
+ "label": "both numbers quoted"
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ "path": "tasks/eval/review.md",
144
+ "kind": "markdown-report",
145
+ "artifact": true,
146
+ "minBytes": 400,
147
+ "checks": [
148
+ {
149
+ "kind": "contains",
150
+ "file": "tasks/eval/review.md",
151
+ "pattern": "Verdict:\\s*(?:PASS|REVISE)",
152
+ "flags": "i",
153
+ "label": "explicit reviewer verdict"
154
+ }
155
+ ]
156
+ }
157
+ ],
158
+ "checks": [
159
+ {
160
+ "kind": "notContains",
161
+ "file": "src/find-duplicates.js",
162
+ "pattern": "for\\s*\\(let j = 0; j < items\\.length",
163
+ "label": "the seeded inner full-list rescan is gone"
164
+ },
165
+ {
166
+ "kind": "sourceParses",
167
+ "file": "src/find-duplicates.js"
168
+ },
169
+ {
170
+ "kind": "nodeScriptPasses",
171
+ "script": "tests/verify-perf.mjs",
172
+ "timeoutMs": 60000,
173
+ "requiredOutput": [
174
+ {
175
+ "pattern": "PERF_OPTIMIZATION_ORACLE results ok",
176
+ "label": "results identical to the reference"
177
+ },
178
+ {
179
+ "pattern": "PERF_OPTIMIZATION_ORACLE ops \\d+ within budget",
180
+ "label": "instrumented op-count under the stated budget"
181
+ },
182
+ {
183
+ "pattern": "PERF_OPTIMIZATION_ORACLE suite green",
184
+ "label": "suite green on the optimized tree"
185
+ }
186
+ ]
187
+ }
188
+ ],
189
+ "taskNotes": {
190
+ "minBytes": 120,
191
+ "checks": [
192
+ {
193
+ "kind": "contains",
194
+ "file": "task-notes.md",
195
+ "pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
196
+ "flags": "i",
197
+ "label": "DONE note names the real test command"
198
+ }
199
+ ]
200
+ },
201
+ "taskGraph": {
202
+ "requireCraftbookTask": true,
203
+ "requireTerminalStep": true
204
+ },
205
+ "unchangedFixtures": [
206
+ "source/perf-brief.md",
207
+ "package.json",
208
+ "src/instrument.js"
209
+ ]
210
+ },
211
+ "rubric": {
212
+ "artifact": {
213
+ "path": "tasks/eval/verification.md",
214
+ "kind": "markdown"
215
+ },
216
+ "axes": [
217
+ {
218
+ "name": "Measurement honesty",
219
+ "description": "Baseline numbers were gathered by a stated, repeatable method before the change, and verification re-ran the identical method and quoted both figures side by side - no adjectives standing in for numbers, no swapped workload."
220
+ },
221
+ {
222
+ "name": "Bottleneck focus",
223
+ "description": "One bottleneck was named with its mechanism and fixed at the real site by that mechanism - not a synthetic proxy, a weakened measurement, or scattered micro-tweaks."
224
+ },
225
+ {
226
+ "name": "Correctness under speed",
227
+ "description": "Results stayed identical on the same inputs, the suite stayed green between stages with real receipts, and residual risk or unverified claims are labeled honestly."
228
+ }
229
+ ]
230
+ },
231
+ "qualityFocus": [
232
+ "numbers with their method",
233
+ "same-method re-measurement",
234
+ "enforced review loop"
235
+ ]
236
+ }
@@ -201,7 +201,6 @@
201
201
  {
202
202
  "service": "docblocks",
203
203
  "requiredTools": [
204
- "list_roots",
205
204
  "convert_document",
206
205
  "preview_document",
207
206
  "save_artifact"
@@ -0,0 +1,304 @@
1
+ {
2
+ "id": "pull-request-review",
3
+ "name": "Pull Request Review",
4
+ "description": "Review a GitHub pull request from a complete, launch-time local mirror rather than a context-sized API response. The runtime resolves the explicit PR number or current-branch PR, materializes an overview, a machine-readable changed-file manifest, one untruncated patch record per changed path, comments, and the full diff. The scope step publishes deterministic 25-file batches and the runtime fans them out to one child reviewer per batch, each in its own session with only its own records in context; a per-batch coverage gate holds every child to its exact slice and a merge gate holds the run to the whole corpus. Repository symbol search and GitHub check status ground cross-file and compile/CI claims before the final local verdict.",
5
+ "basedOn": {
6
+ "name": "Gezel Code Review",
7
+ "url": "https://github.com/bendyline/gezel"
8
+ },
9
+ "entryStepId": "scope",
10
+ "triggers": [
11
+ "review this pr",
12
+ "review the current pr",
13
+ "review this pull request",
14
+ "pr review",
15
+ "review the github pull request"
16
+ ],
17
+ "requirements": [
18
+ {
19
+ "kind": "github"
20
+ }
21
+ ],
22
+ "connectors": [
23
+ {
24
+ "typeId": "github-pulls",
25
+ "reason": "materialize the selected pull request as a complete, chunk-readable local corpus"
26
+ }
27
+ ],
28
+ "toolsets": [
29
+ {
30
+ "toolsetId": "github",
31
+ "optional": true,
32
+ "autoAllow": true,
33
+ "reason": "read CI/check status and perform targeted PR verification"
34
+ }
35
+ ],
36
+ "paramSchema": {
37
+ "type": "object",
38
+ "properties": {
39
+ "workPath": {
40
+ "type": "string",
41
+ "title": "Working folder",
42
+ "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.",
43
+ "default": "{{task.dir}}"
44
+ },
45
+ "number": {
46
+ "type": "number",
47
+ "title": "Pull request number",
48
+ "description": "Optional PR number. Leave blank to use the open PR whose head matches the project's checked-out branch."
49
+ },
50
+ "focus": {
51
+ "type": "string",
52
+ "title": "Review focus",
53
+ "default": "general correctness",
54
+ "description": "Optional area to emphasize, e.g. security, performance, or tests."
55
+ },
56
+ "intensity": {
57
+ "type": "string",
58
+ "title": "Intensity",
59
+ "enum": [
60
+ "low",
61
+ "medium",
62
+ "high"
63
+ ],
64
+ "default": "medium",
65
+ "squisq": {
66
+ "control": "segmented"
67
+ },
68
+ "description": "How deep to go on each changed-file batch. Coverage remains complete at every intensity."
69
+ }
70
+ }
71
+ },
72
+ "spawn": {
73
+ "overFile": "{{workPath}}/pr-review/batches.json",
74
+ "overArtifact": true,
75
+ "entryStepId": "review-batch",
76
+ "steps": [
77
+ {
78
+ "id": "review-batch",
79
+ "name": "Review batch {{batchNumber}} of PR #{{number}}",
80
+ "description": "Review one bounded slice of the pull-request corpus in a session that holds only that slice, then persist the batch's observations and its coverage shard.",
81
+ "prompt": "You are reviewing batch {{batchNumber}} of PR #{{number}} — records {{start}} through {{end}}. This batch is the whole of your assignment. Other reviewers hold the other batches; do not read, account for, or comment on files outside your slice.\n\nYour batch covers exactly these changed paths:\n\n{{paths}}\n\nRead exactly these artifact records — the runtime resolved their current filenames from the connector's identity sidecar, so no directory listing or ordinal reconstruction is needed:\n\n{{records}}\n\n1. Call `read_artifact` once for every exact record path in `{{records}}`. Each carries one complete changed-file patch and an authoritative `path` frontmatter. Binary/no-patch records still count toward coverage, but say so. Do not call `list_artifacts` on the pull-request corpus; that directory may contain more entries than one bounded listing can return.\n2. Review this batch for correctness, security, data loss, error handling, concurrency, compatibility, tests, and clarity, weighted by focus `{{focus}}` and intensity `{{intensity}}`. Cite exact `path:new-line` evidence from the diff hunks.\n3. Before claiming that a referenced API/type/module does not exist, call `find_symbol`, `search_code`, or `grep_files` against the checkout — its definition may live in a batch you were not given. Treat successful CI/typecheck evidence as rebuttable evidence that typed APIs resolve; never allege a missing typed API without a failed symbol/search verification. Use `github_pr_file` or paginated `github_pr_diff({ path, offset })` only for targeted live confirmation when the corpus record is ambiguous.\n4. Write the artifact `{{workPath}}/pr-review/observations-{{batchNumber}}.md` with `write_artifact`. Head it `## Batch {{batchNumber}} — files {{start}}–{{end}}`, then one short section per finding: severity (critical/major/minor/nit), `path:line`, what is wrong, and the fix. Add a `### Verified OK` list naming what you checked and found sound — the synthesizer needs to know what was examined, not only what failed. Number your findings `B{{batchNumber}}-1`, `B{{batchNumber}}-2`, … so they stay unique across batches.\n5. Write the artifact `{{workPath}}/pr-review/coverage-{{batchNumber}}.json` with `write_artifact` as `{ \"batchNumber\": {{batchNumber}}, \"reviewedFiles\": [...], \"reviewedRecords\": [...] }`, naming every exact `path` you reviewed and every exact artifact record path from `{{records}}`. Valid JSON, exact strings, this batch only. Then call `advance_task_step`.\n\nThe gate compares your shard against your batch's paths alone. Listing a path from another batch fails it just as surely as omitting one of yours.\n\nThese deliverables live in the project's artifacts drawer — write them with `write_artifact` and read them back with `read_artifact`; the shipped workspace stays untouched. A pull-request review never modifies project source.",
82
+ "suggestedRole": "reviewer",
83
+ "advanceWhen": {
84
+ "file": "{{workPath}}/pr-review/coverage-{{batchNumber}}.json",
85
+ "minBytes": 2,
86
+ "sniff": "json-valid",
87
+ "artifact": true
88
+ },
89
+ "gate": {
90
+ "at": "completion",
91
+ "checks": [
92
+ {
93
+ "kind": "corpusCoverage",
94
+ "file": "{{workPath}}/pr-review/coverage-{{batchNumber}}.json",
95
+ "corpusDir": "{{corpusScope}}",
96
+ "expectPaths": "{{paths}}",
97
+ "artifact": true
98
+ },
99
+ {
100
+ "kind": "minBytes",
101
+ "file": "{{workPath}}/pr-review/observations-{{batchNumber}}.md",
102
+ "bytes": 200,
103
+ "artifact": true
104
+ }
105
+ ],
106
+ "onReject": "review-batch",
107
+ "maxAttempts": 4
108
+ },
109
+ "terminal": true
110
+ }
111
+ ]
112
+ },
113
+ "steps": [
114
+ {
115
+ "id": "scope",
116
+ "name": "Map the pull request corpus",
117
+ "description": "Read the launch-time PR overview and manifest, capture CI/check evidence, and publish the deterministic review batches the runtime fans out over.",
118
+ "prompt": "**You are reviewing PR #{{number}}, not authoring it. Never modify project source in this craftbook.** The runtime already mirrored the selected PR into `{{corpusScope}}`; this corpus, not a single live diff call, is the authoritative review surface.\n\n**The fanout input is already published.** On entering this step the runtime published the manifest's complete batch array to `{{workPath}}/pr-review/batches.json` and enriched each batch with its exact current `records` paths. That file is done — do not write it, and do not \"fix\" it. Retyping 500+ exact paths through a tool call is what this step used to ask for, and it cannot survive a per-turn output cap.\n\nYour job is the evidence and the scope note.\n\n1. Call `list_artifacts({ path: \"{{corpusScope}}\", recursive: false })` and read the overview Markdown record it returns. Read the manifest directly at `{{corpusScope}}/attachments/001/pr-{{number}}-files.json`. Do not recursively list the corpus.\n2. Call `read_artifact({ path: \"{{workPath}}/pr-review/batches.json\" })` and note the batch count and ranges from what is actually on disk.\n3. Call `github_check_status` for the overview's head ref and record whether checks are success, failure, pending, or unknown. This is evidence, not a substitute for reviewing the diff.\n\nThen write ONE task note beginning `## Scope — PR #{{number}}`. Include title, URL, head → base, draft state, exact changed-file count, manifest path, batch count/ranges, CI/check status, existing-review themes, and 3–6 review themes weighted by focus `{{focus}}` and intensity `{{intensity}}`. Derive every path and count from the manifest and the published batches — never from memory. End by calling `advance_task_step`.\n\nThese deliverables live in the project's artifacts drawer — read them with `read_artifact`; the shipped workspace stays untouched.",
119
+ "suggestedRole": "reviewer",
120
+ "advanceWhen": {
121
+ "file": "{{workPath}}/pr-review/batches.json",
122
+ "minBytes": 2,
123
+ "sniff": "json-valid",
124
+ "artifact": true
125
+ },
126
+ "gate": {
127
+ "at": "completion",
128
+ "scripts": [
129
+ {
130
+ "name": "checkTaskNoteContains",
131
+ "scope": "standard",
132
+ "inputs": {
133
+ "pattern": "##\\s*Scope\\s*[—-]\\s*PR\\s*#{{number}}[\\s\\S]*(?:changed.file|files?)"
134
+ }
135
+ }
136
+ ],
137
+ "checks": [
138
+ {
139
+ "kind": "corpusBatches",
140
+ "file": "{{workPath}}/pr-review/batches.json",
141
+ "corpusDir": "{{corpusScope}}",
142
+ "artifact": true
143
+ }
144
+ ],
145
+ "onReject": "scope",
146
+ "maxAttempts": 3
147
+ },
148
+ "next": "scan",
149
+ "onEnter": [
150
+ {
151
+ "name": "publishCorpusBatches",
152
+ "scope": "standard",
153
+ "inputs": {
154
+ "corpusDir": "{{corpusScope}}",
155
+ "outFile": "{{workPath}}/pr-review/batches.json"
156
+ }
157
+ }
158
+ ]
159
+ },
160
+ {
161
+ "id": "scan",
162
+ "name": "Fan the batches out to the review crew",
163
+ "description": "Spawn one child reviewer per published batch. The runtime performs the fanout with no model turn; the crew is the work.",
164
+ "prompt": "The runtime spawns one child reviewer per entry in `{{workPath}}/pr-review/batches.json`, each in its own session holding only that batch's records. No turn is needed here.",
165
+ "suggestedRole": "reviewer",
166
+ "spawnFanout": true,
167
+ "advanceWhen": {
168
+ "file": "{{workPath}}/pr-review/fanout.md",
169
+ "minBytes": 1,
170
+ "sniff": "nonempty",
171
+ "artifact": true
172
+ },
173
+ "next": "collect"
174
+ },
175
+ {
176
+ "id": "collect",
177
+ "name": "Merge the batch ledgers",
178
+ "description": "Wait for the crew while the runtime deterministically rebuilds the run-wide ledger from exact per-batch coverage shards, then prove both corpus completeness and shard provenance.",
179
+ "prompt": "The runtime has rebuilt `{{workPath}}/pr-review-coverage.json` from every valid `coverage-N.json` shard currently on disk. Do not write or edit that ledger yourself — it is deliberately runtime-owned so a large pull request never has to pass hundreds of exact paths through one model tool call.\n\nCall `advance_task_step` now. The gate will compare the ledger against the complete connector corpus and independently prove that it is exactly the union of one valid shard per published batch. If reviewers are still working, it will reject and name the missing batches; on the fresh activation the runtime will rebuild the ledger again. Do not review files yourself or add paths to close the gap. A batch that remains stuck belongs in a task note, not a fabricated coverage claim.\n\nThe ledger and shards live in the project's artifacts drawer; the shipped workspace stays untouched.",
180
+ "suggestedRole": "reviewer",
181
+ "advanceWhen": {
182
+ "file": "{{workPath}}/pr-review-coverage.json",
183
+ "minBytes": 2,
184
+ "sniff": "json-valid",
185
+ "artifact": true
186
+ },
187
+ "gate": {
188
+ "at": "completion",
189
+ "checks": [
190
+ {
191
+ "kind": "corpusCoverage",
192
+ "file": "{{workPath}}/pr-review-coverage.json",
193
+ "corpusDir": "{{corpusScope}}",
194
+ "artifact": true
195
+ }
196
+ ],
197
+ "scripts": [
198
+ {
199
+ "name": "checkCorpusCoverageProvenance",
200
+ "scope": "standard",
201
+ "inputs": {
202
+ "batchesFile": "{{workPath}}/pr-review/batches.json",
203
+ "shardDir": "{{workPath}}/pr-review",
204
+ "ledgerFile": "{{workPath}}/pr-review-coverage.json",
205
+ "pullRequest": "{{number}}"
206
+ }
207
+ }
208
+ ],
209
+ "onReject": "collect",
210
+ "maxAttempts": 6
211
+ },
212
+ "onEnter": [
213
+ {
214
+ "name": "mergeCorpusCoverage",
215
+ "scope": "standard",
216
+ "inputs": {
217
+ "batchesFile": "{{workPath}}/pr-review/batches.json",
218
+ "shardDir": "{{workPath}}/pr-review",
219
+ "outFile": "{{workPath}}/pr-review-coverage.json",
220
+ "pullRequest": "{{number}}"
221
+ }
222
+ }
223
+ ],
224
+ "next": "report"
225
+ },
226
+ {
227
+ "id": "report",
228
+ "name": "Synthesize the review",
229
+ "description": "Synthesize every batch's observations into a cited report, re-verifying cross-file claims and keeping CI status distinct from code-review judgment.",
230
+ "prompt": "The coverage gate has proved that every changed path in PR #{{number}} was reviewed. Read the Scope note and the artifact `{{workPath}}/pr-review-coverage.json`, then call `list_artifacts({ path: \"{{workPath}}/pr-review\", recursive: true })` and read EVERY `observations-N.md` shard with `read_artifact`. There is one per batch and each holds findings the others do not — synthesizing from a subset silently drops whole batches of review.\n\nRe-check every critical or major candidate against the relevant workspace source with `find_symbol`, `search_code`, `grep_files`, `read_file`, or `read_files`; call `github_check_status` again if the earlier status was pending. Drop any candidate that is not supported. Reconcile duplicates: separate reviewers can raise the same defect from two batches — merge those into one row. Do not repeat an existing PR comment unless it still needs action and you explicitly say it was already raised.\n\nCite every finding as `path:line` using a changed path and a new-side diff line. Any critical or major finding requires `request-changes`; otherwise use `approve`. CI success is evidence that the checked revision compiled/tested as configured, but it does not erase logic findings. CI unknown/pending is not itself a code defect.\n\nWrite `{{workPath}}/pr-review.md` in ONE `write_artifact` call using exactly this skeleton:\n\n```\n# Pull Request Review — PR #{{number}}: <title>\n\n## Summary\n<2–6 sentences: what changes, overall risk, existing-comment coverage, and CI/check status. Say \"No findings.\" when there are none.>\n\nCoverage: <reviewed count>/<changed-file count> changed files across <batch count> batches.\n\n## Findings\n| # | Severity | File | Line | Finding | Recommendation |\n|---|----------|------|------|---------|----------------|\n<one row per finding; severities: critical, major, minor, nit. Keep the header when there are no findings.>\n\n## Verdict\nVerdict: approve\n<or> Verdict: request-changes\n<one sentence of rationale>\n```\n\nDo not modify source and do not call `github_pr_comment`; the report is local. If the gate rejects, repair the named gap and rewrite the whole report. Then call `advance_task_step`.\n\nThese deliverables live in the project's artifacts drawer — write them with `write_artifact` and read them back with `read_artifact`; the shipped workspace stays untouched. A pull-request review never modifies project source.",
231
+ "suggestedRole": "reviewer",
232
+ "advanceWhen": {
233
+ "file": "{{workPath}}/pr-review.md",
234
+ "minBytes": 500,
235
+ "artifact": true
236
+ },
237
+ "gate": {
238
+ "at": "completion",
239
+ "checks": [
240
+ {
241
+ "kind": "minBytes",
242
+ "file": "{{workPath}}/pr-review.md",
243
+ "bytes": 500,
244
+ "artifact": true
245
+ },
246
+ {
247
+ "kind": "contains",
248
+ "file": "{{workPath}}/pr-review.md",
249
+ "pattern": "#\\s+Pull Request Review\\s+[—-]\\s+PR\\s+#{{number}}",
250
+ "label": "PR-numbered title",
251
+ "artifact": true
252
+ },
253
+ {
254
+ "kind": "contains",
255
+ "file": "{{workPath}}/pr-review.md",
256
+ "pattern": "Coverage:\\s*\\d+\\s*/\\s*\\d+\\s+changed files",
257
+ "label": "coverage summary",
258
+ "artifact": true
259
+ },
260
+ {
261
+ "kind": "contains",
262
+ "file": "{{workPath}}/pr-review.md",
263
+ "pattern": "##\\s+Summary[\\s\\S]*##\\s+Findings[\\s\\S]*##\\s+Verdict",
264
+ "label": "required sections",
265
+ "artifact": true
266
+ },
267
+ {
268
+ "kind": "contains",
269
+ "file": "{{workPath}}/pr-review.md",
270
+ "pattern": "Verdict:\\s*(approve|request-changes)",
271
+ "label": "verdict line",
272
+ "artifact": true
273
+ },
274
+ {
275
+ "kind": "tableShape",
276
+ "file": "{{workPath}}/pr-review.md",
277
+ "requiredColumns": [
278
+ "Severity",
279
+ "File",
280
+ "Line",
281
+ "Finding",
282
+ "Recommendation"
283
+ ],
284
+ "artifact": true
285
+ }
286
+ ],
287
+ "onReject": "report",
288
+ "maxAttempts": 4
289
+ },
290
+ "next": "done"
291
+ },
292
+ {
293
+ "id": "done",
294
+ "name": "Deliver the verdict",
295
+ "description": "The complete-coverage report passed its gates. Summarize the verdict and point the user to the local evidence files.",
296
+ "prompt": "Read the artifacts `{{workPath}}/pr-review.md` and `{{workPath}}/pr-review-coverage.json` with `read_artifact`, then write one final task note with `write_task_note`: `PR #{{number}} — Verdict: <approve|request-changes> — N findings (a critical, b major, c minor, d nit) — coverage X/X` plus a one-paragraph summary. Tell the user the full local review is at `{{workPath}}/pr-review.md` in the project's artifacts drawer, the coverage ledger is beside it at `{{workPath}}/pr-review-coverage.json`, the per-batch observations are under `{{workPath}}/pr-review/`, and nothing was posted to GitHub. Then call `advance_task_step` to complete the task.",
297
+ "suggestedRole": "reviewer",
298
+ "terminal": true
299
+ }
300
+ ],
301
+ "minGezelVersion": "1.26237",
302
+ "version": "1.8.0",
303
+ "releasedAt": "2026-08-25T00:00:00Z"
304
+ }