@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.
- package/authoring/gstack/overlays/investigate.json +1 -0
- package/authoring/gstack/overlays/qa-only.json +1 -0
- package/authoring/gstack/wave.json +12 -2
- package/authoring/tactical/books/accessibility-retrofit.json +188 -0
- package/authoring/tactical/books/apply-review-findings.json +189 -0
- package/authoring/tactical/books/bug-fix-tdd.json +237 -0
- package/authoring/tactical/books/ci-pipeline.json +168 -0
- package/authoring/tactical/books/codemod-sweep.json +182 -0
- package/authoring/tactical/books/dependency-upgrade.json +196 -0
- package/authoring/tactical/books/flaky-test-fix.json +238 -0
- package/authoring/tactical/books/hotfix-flow.json +187 -0
- package/authoring/tactical/books/perf-optimization.json +219 -0
- package/authoring/tactical/books/refactor-module.json +217 -0
- package/authoring/tactical/books/schema-migration.json +192 -0
- package/authoring/tactical/books/test-suite-backfill.json +172 -0
- package/authoring/tactical/books/type-safety-pass.json +185 -0
- package/authoring/tactical/books/ux-update.json +178 -0
- package/authoring/tactical/evals/accessibility-retrofit.json +230 -0
- package/authoring/tactical/evals/apply-review-findings.json +290 -0
- package/authoring/tactical/evals/bug-fix-tdd.json +221 -0
- package/authoring/tactical/evals/ci-pipeline.json +227 -0
- package/authoring/tactical/evals/codemod-sweep.json +252 -0
- package/authoring/tactical/evals/dependency-upgrade.json +235 -0
- package/authoring/tactical/evals/flaky-test-fix.json +239 -0
- package/authoring/tactical/evals/hotfix-flow.json +220 -0
- package/authoring/tactical/evals/perf-optimization.json +235 -0
- package/authoring/tactical/evals/refactor-module.json +241 -0
- package/authoring/tactical/evals/schema-migration.json +225 -0
- package/authoring/tactical/evals/test-suite-backfill.json +197 -0
- package/authoring/tactical/evals/type-safety-pass.json +221 -0
- package/authoring/tactical/evals/ux-update.json +206 -0
- package/authoring/tactical/wave.json +89 -0
- package/data/chat-models/de/deepseek-r1-8b-q4/manifest.json +56 -1
- package/data/chat-models/gl/glm-5.2-754b-q2/manifest.json +56 -0
- package/data/chat-models/gp/gpt-oss-120b-q4/manifest.json +73 -1
- package/data/chat-models/gp/gpt-oss-20b-q4/manifest.json +77 -1
- package/data/chat-models/index.json +1 -1
- package/data/chat-models/ll/llama3.2-3b-q4/manifest.json +3 -1
- package/data/chat-models/mi/mistral-7b-q4/manifest.json +54 -3
- package/data/chat-models/mi/mistral-medium-3.5-128b-q4/manifest.json +76 -1
- package/data/craftbook-templates/ac/accessibility-retrofit/manifest.json +5 -4
- package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.0/craftbook.json +451 -0
- package/data/craftbook-templates/ac/accessibility-retrofit/versions/2.0.0/test.json +231 -0
- package/data/craftbook-templates/al/alt-text-pass/manifest.json +5 -1
- package/data/craftbook-templates/ap/apply-review-findings/art.json +12 -0
- package/data/craftbook-templates/ap/apply-review-findings/logo.webp +0 -0
- package/data/craftbook-templates/ap/apply-review-findings/manifest.json +23 -0
- package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.0/craftbook.json +436 -0
- package/data/craftbook-templates/ap/apply-review-findings/versions/1.0.0/test.json +291 -0
- package/data/craftbook-templates/br/browser-qa-audit/manifest.json +5 -1
- package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.5/craftbook.json +438 -0
- package/data/craftbook-templates/br/browser-qa-audit/versions/2.0.5/test.json +379 -0
- package/data/craftbook-templates/bu/bug-fix-tdd/manifest.json +3 -3
- package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.0/craftbook.json +545 -0
- package/data/craftbook-templates/bu/bug-fix-tdd/versions/2.0.0/test.json +222 -0
- package/data/craftbook-templates/ch/changelog-cut/manifest.json +5 -1
- package/data/craftbook-templates/ch/changelog-writeup/manifest.json +5 -1
- package/data/craftbook-templates/ci/ci-pipeline/manifest.json +5 -3
- package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.0/craftbook.json +423 -0
- package/data/craftbook-templates/ci/ci-pipeline/versions/2.0.0/test.json +228 -0
- package/data/craftbook-templates/co/codemod-sweep/art.json +12 -0
- package/data/craftbook-templates/co/codemod-sweep/logo.webp +0 -0
- package/data/craftbook-templates/co/codemod-sweep/manifest.json +23 -0
- package/data/craftbook-templates/co/codemod-sweep/versions/1.0.0/craftbook.json +441 -0
- package/data/craftbook-templates/co/codemod-sweep/versions/1.0.0/test.json +253 -0
- package/data/craftbook-templates/de/dependency-upgrade/art.json +12 -0
- package/data/craftbook-templates/de/dependency-upgrade/logo.webp +0 -0
- package/data/craftbook-templates/de/dependency-upgrade/manifest.json +23 -0
- package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.0/craftbook.json +459 -0
- package/data/craftbook-templates/de/dependency-upgrade/versions/1.0.0/test.json +236 -0
- package/data/craftbook-templates/fe/feature-flag-release/manifest.json +5 -1
- package/data/craftbook-templates/fe/feature-flag-rollout/manifest.json +4 -1
- package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.0/craftbook.json +203 -0
- package/data/craftbook-templates/fe/feature-flag-rollout/versions/1.1.0/test.json +165 -0
- package/data/craftbook-templates/fl/flaky-test-fix/art.json +12 -0
- package/data/craftbook-templates/fl/flaky-test-fix/logo.webp +0 -0
- package/data/craftbook-templates/fl/flaky-test-fix/manifest.json +24 -0
- package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.0/craftbook.json +534 -0
- package/data/craftbook-templates/fl/flaky-test-fix/versions/1.0.0/test.json +240 -0
- package/data/craftbook-templates/ho/hotfix-flow/manifest.json +5 -3
- package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.0/craftbook.json +442 -0
- package/data/craftbook-templates/ho/hotfix-flow/versions/2.0.0/test.json +221 -0
- package/data/craftbook-templates/in/investigate/manifest.json +4 -1
- package/data/craftbook-templates/in/investigate-root-cause/manifest.json +5 -1
- package/data/craftbook-templates/index.json +1 -1
- package/data/craftbook-templates/li/live-browser-qa/manifest.json +5 -1
- package/data/craftbook-templates/ni/nightly-fix-sweep/art.json +12 -0
- package/data/craftbook-templates/ni/nightly-fix-sweep/logo.webp +0 -0
- package/data/craftbook-templates/ni/nightly-fix-sweep/manifest.json +23 -0
- package/data/craftbook-templates/ni/nightly-fix-sweep/versions/1.0.0/craftbook.json +145 -0
- package/data/craftbook-templates/ni/nightly-fix-sweep/versions/1.0.0/test.json +121 -0
- package/data/craftbook-templates/pe/perf-audit/versions/1.1.0/craftbook.json +195 -0
- package/data/craftbook-templates/pe/perf-audit/versions/1.1.0/test.json +165 -0
- package/data/craftbook-templates/pe/perf-optimization/manifest.json +3 -3
- package/data/craftbook-templates/pe/perf-optimization/versions/2.0.0/craftbook.json +511 -0
- package/data/craftbook-templates/pe/perf-optimization/versions/2.0.0/test.json +236 -0
- package/data/craftbook-templates/po/powerpoint-deck/versions/1.7.4/test.json +0 -1
- package/data/craftbook-templates/pu/pull-request-review/versions/1.8.0/craftbook.json +304 -0
- package/data/craftbook-templates/pu/pull-request-review/versions/1.8.0/test.json +144 -0
- package/data/craftbook-templates/qa/qa/manifest.json +3 -1
- package/data/craftbook-templates/re/refactor-module/manifest.json +2 -2
- package/data/craftbook-templates/re/refactor-module/versions/1.0.4/craftbook.json +150 -0
- package/data/craftbook-templates/re/refactor-module/versions/1.0.4/test.json +95 -0
- package/data/craftbook-templates/re/refactor-module/versions/2.0.0/craftbook.json +509 -0
- package/data/craftbook-templates/re/refactor-module/versions/2.0.0/test.json +242 -0
- package/data/craftbook-templates/re/release-notes/manifest.json +5 -1
- package/data/craftbook-templates/re/release-notes/versions/1.0.3/craftbook.json +220 -0
- package/data/craftbook-templates/re/release-notes/versions/1.0.3/test.json +114 -0
- package/data/craftbook-templates/re/release-pipeline-ci/manifest.json +5 -1
- package/data/craftbook-templates/re/release-readiness-review/versions/1.1.0/craftbook.json +192 -0
- package/data/craftbook-templates/re/release-readiness-review/versions/1.1.0/test.json +113 -0
- package/data/craftbook-templates/ro/root-cause-investigation/manifest.json +7 -1
- package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.5/craftbook.json +433 -0
- package/data/craftbook-templates/ro/root-cause-investigation/versions/2.0.5/test.json +157 -0
- package/data/craftbook-templates/sc/schema-migration/manifest.json +4 -4
- package/data/craftbook-templates/sc/schema-migration/versions/2.0.0/craftbook.json +459 -0
- package/data/craftbook-templates/sc/schema-migration/versions/2.0.0/test.json +226 -0
- package/data/craftbook-templates/te/test-coverage-review/versions/1.2.0/craftbook.json +195 -0
- package/data/craftbook-templates/te/test-coverage-review/versions/1.2.0/test.json +116 -0
- package/data/craftbook-templates/te/test-suite-backfill/manifest.json +1 -2
- package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.0/craftbook.json +428 -0
- package/data/craftbook-templates/te/test-suite-backfill/versions/2.0.0/test.json +198 -0
- package/data/craftbook-templates/ty/type-safety-pass/manifest.json +3 -3
- package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.0/craftbook.json +428 -0
- package/data/craftbook-templates/ty/type-safety-pass/versions/2.0.0/test.json +222 -0
- package/data/craftbook-templates/ux/ux-update/art.json +12 -0
- package/data/craftbook-templates/ux/ux-update/logo.webp +0 -0
- package/data/craftbook-templates/ux/ux-update/manifest.json +22 -0
- package/data/craftbook-templates/ux/ux-update/versions/1.0.0/craftbook.json +439 -0
- package/data/craftbook-templates/ux/ux-update/versions/1.0.0/test.json +207 -0
- package/data/craftbook-templates/ve/version-bump/versions/1.1.0/craftbook.json +206 -0
- package/data/craftbook-templates/ve/version-bump/versions/1.1.0/test.json +95 -0
- package/data/gezel-templates/bo/boekwachter/versions/1.1.0/about.md +29 -0
- package/data/gezel-templates/bo/boekwachter/versions/1.1.0/manifest.json +16 -0
- package/data/gezel-templates/bu/builder/versions/1.5.0/about.md +34 -0
- package/data/gezel-templates/bu/builder/versions/1.5.0/manifest.json +16 -0
- package/data/gezel-templates/de/developer/versions/1.5.0/about.md +34 -0
- package/data/gezel-templates/de/developer/versions/1.5.0/manifest.json +21 -0
- package/data/gezel-templates/index.json +1 -1
- package/data/gezel-templates/re/reviewer/versions/1.4.0/about.md +49 -0
- package/data/gezel-templates/re/reviewer/versions/1.4.0/manifest.json +21 -0
- package/data/project-types/index.json +1 -1
- package/data/project-types/so/software-project/manifest.json +20 -0
- package/data/project-types/so/software-project/versions/1.0.0/about.md +3 -0
- package/data/project-types/so/software-project/versions/1.0.0/manifest.json +41 -0
- package/data/project-types/so/software-project/versions/1.0.0/mission.md +4 -0
- package/package.json +1 -1
- package/schemas/craftbook-doc.schema.json +248 -0
- package/schemas/craftbook-template-version.schema.json +248 -0
- package/schemas/craftbook-test.schema.json +200 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Accessibility retrofit on a seeded page",
|
|
4
|
+
"objective": "The craftbook drives a real accessibility retrofit of a page seeded with five concrete violations: missing alt text on two meaningful images, a placeholder-as-label email input, a div-as-button control with no keyboard path, a heading jump from h1 to h4, and a decorative divider whose empty alt must survive untouched. Every repair is verified mechanically by string-parsing the fixed markup.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"accessibility",
|
|
8
|
+
"a11y",
|
|
9
|
+
"tactical-fleet"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Use the Accessibility Retrofit craftbook on this site: readers using screen readers and keyboards report the Field Notes page is unusable — images carry no descriptions, the signup field has no label, and the Join the list control cannot be reached or activated with the keyboard. Audit index.html, fix every violation at its real site in the markup, and verify the result.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Acme Field Notes",
|
|
14
|
+
"about": "A small static newsletter site: index.html plus styles.css and a few inline SVG images. No build step and no test suite.",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "package.json",
|
|
18
|
+
"content": "{\n \"name\": \"field-notes\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\"\n}\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "index.html",
|
|
22
|
+
"content": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Acme Field Notes</title>\n<link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n<div class=\"masthead\">\n <h1>Acme Field Notes</h1>\n <img src=\"images/divider.svg\" class=\"divider\" alt=\"\">\n</div>\n<div class=\"content\">\n <h4>Latest dispatch</h4>\n <img src=\"images/harvest-crew.svg\" class=\"feature\">\n <p>The harvest crew finished the north field on Tuesday, two days ahead of schedule, and moved on to the orchard rows.</p>\n <h4>Sign up for dispatches</h4>\n <p>Get the weekly note by email.</p>\n <input type=\"email\" placeholder=\"Your email address\">\n <div class=\"button\" onclick=\"joinList()\">Join the list</div>\n <p id=\"joined-note\" hidden>You are on the list.</p>\n <h4>From the archive</h4>\n <img src=\"images/seed-chart.svg\" class=\"feature\">\n <p>Germination rates for the last five seasons, charted by seed lot and sowing week.</p>\n</div>\n<script>\nfunction joinList() {\n document.getElementById('joined-note').hidden = false;\n}\n</script>\n</body>\n</html>\n"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "styles.css",
|
|
26
|
+
"content": "body { margin: 0; font-family: Georgia, serif; color: #222; background: #faf8f4; }\n.masthead { padding: 2rem 1.5rem 0; }\n.divider { width: 100%; height: 12px; }\n.content { max-width: 40rem; padding: 1rem 1.5rem 3rem; }\n.feature { max-width: 100%; }\n.button { display: inline-block; padding: 0.5rem 1rem; background: #2e5d3b; color: #fff; cursor: pointer; }\n.button:hover { background: #234a2e; }\ninput[type=\"email\"] { padding: 0.5rem; width: 16rem; }\n"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"path": "images/harvest-crew.svg",
|
|
30
|
+
"content": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 180\"><rect width=\"320\" height=\"180\" fill=\"#dce8d8\"/><text x=\"16\" y=\"95\" font-size=\"16\">Harvest crew walking the north field at dawn</text></svg>\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "images/seed-chart.svg",
|
|
34
|
+
"content": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 180\"><rect width=\"320\" height=\"180\" fill=\"#e8e2d4\"/><text x=\"16\" y=\"95\" font-size=\"16\">Germination rate by season, 2021 to 2025</text></svg>\n"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"path": "images/divider.svg",
|
|
38
|
+
"content": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 12\"><line x1=\"0\" y1=\"6\" x2=\"320\" y2=\"6\" stroke=\"#b8b0a0\" stroke-width=\"2\"/></svg>\n"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"path": "tests/verify-retrofit.mjs",
|
|
42
|
+
"surface": "harness",
|
|
43
|
+
"content": "import assert from 'node:assert/strict';\nimport { readFileSync } from 'node:fs';\n\nconst html = readFileSync('index.html', 'utf8');\n\nfunction imgTag(src) {\n const tags = [...html.matchAll(/<img\\b[^>]*>/gi)].map((m) => m[0]);\n const tag = tags.find((t) => t.includes(src));\n assert.ok(tag, `an img referencing ${src} still exists`);\n return tag;\n}\nfunction altOf(tag, src) {\n const alt = tag.match(/\\balt\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/i);\n assert.ok(alt, `image ${src} carries an alt attribute`);\n return alt[2] ?? alt[3] ?? '';\n}\n\n// 1) Meaningful images: specific, non-empty alt text.\nfor (const src of ['harvest-crew', 'seed-chart']) {\n const alt = altOf(imgTag(src), src).trim();\n assert.ok(alt.length >= 10, `alt for ${src} must be specific, got \"${alt}\"`);\n assert.ok(!/^(image|photo|picture|graphic|img)$/i.test(alt), `alt for ${src} must not be filler`);\n assert.ok(!/^(an? )?(image|photo|picture) of/i.test(alt), `alt for ${src} must not open with \"image of\"`);\n}\nconsole.log('A11YRETRO_ORACLE alts ok');\n\n// 2) The decorative divider keeps an EMPTY alt - no sprayed description.\nassert.equal(altOf(imgTag('divider'), 'divider').trim(), '', 'decorative divider keeps alt=\"\"');\nconsole.log('A11YRETRO_ORACLE decorative ok');\n\n// 3) The email input is labeled by a real label whose for resolves to its id.\nconst labels = [...html.matchAll(/<label\\b[^>]*\\bfor\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi)];\nassert.ok(labels.length >= 1, 'a label element with a for attribute exists');\nconst paired = labels.filter((m) => new RegExp(`<input\\\\b[^>]*\\\\bid\\\\s*=\\\\s*[\"']${m[1]}[\"']`, 'i').test(html));\nassert.ok(paired.length >= 1, \"a label's for attribute resolves to a real input id\");\nconsole.log('A11YRETRO_ORACLE label ok');\n\n// 4) The join control is a real button, or carries complete ARIA button semantics.\nconst join = html.match(/<([a-z0-9]+)\\b([^>]*)>\\s*Join the list/i);\nassert.ok(join, 'the \"Join the list\" control still exists');\nconst [, joinTag, joinAttrs] = join;\nif (joinTag.toLowerCase() !== 'button') {\n assert.ok(/\\brole\\s*=\\s*[\"']button[\"']/i.test(joinAttrs), 'non-button control carries role=\"button\"');\n assert.ok(/\\btabindex\\s*=\\s*[\"']0[\"']/i.test(joinAttrs), 'non-button control is focusable via tabindex=\"0\"');\n const keyWired = /\\bonkey(?:down|up|press)\\s*=/i.test(joinAttrs) || /addEventListener\\s*\\(\\s*[\"']key(?:down|up|press)[\"']/i.test(html);\n assert.ok(keyWired, 'non-button control has keyboard activation wired');\n}\nconsole.log('A11YRETRO_ORACLE control ok');\n\n// 5) Heading order is monotonic from a single h1.\nconst levels = [...html.matchAll(/<h([1-6])\\b[^>]*>/gi)].map((m) => Number(m[1]));\nassert.ok(levels.length >= 3, 'the page keeps its headings');\nassert.equal(levels[0], 1, 'the page starts at h1');\nfor (let i = 1; i < levels.length; i++) {\n assert.ok(levels[i] <= levels[i - 1] + 1, `heading level jumps from h${levels[i - 1]} to h${levels[i]}`);\n}\nconsole.log('A11YRETRO_ORACLE headings ok');\n\n// 6) The join behavior target survives the retrofit.\nassert.ok(/joined-note/.test(html), 'the joined-note behavior target survives');\nconsole.log('A11YRETRO_ORACLE done');\n"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"craftbookParams": {
|
|
47
|
+
"workPath": "tasks/eval"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"success": {
|
|
51
|
+
"summary": "All five seeded violations are repaired at their real sites in index.html — specific alts on the meaningful images, an empty alt preserved on the decorative divider, a paired label, a keyboard-operable join control, monotonic headings — and every fleet artifact exists with honest citations.",
|
|
52
|
+
"deliverables": [
|
|
53
|
+
{
|
|
54
|
+
"path": "tasks/eval/audit.md",
|
|
55
|
+
"kind": "markdown-notes",
|
|
56
|
+
"artifact": true,
|
|
57
|
+
"minBytes": 600,
|
|
58
|
+
"checks": [
|
|
59
|
+
{
|
|
60
|
+
"kind": "contains",
|
|
61
|
+
"file": "tasks/eval/audit.md",
|
|
62
|
+
"pattern": "^##\\s+Scope[\\s\\S]*^##\\s+Violations[\\s\\S]*^##\\s+Priorities",
|
|
63
|
+
"flags": "im",
|
|
64
|
+
"label": "audit sections in order"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"kind": "tableShape",
|
|
68
|
+
"file": "tasks/eval/audit.md",
|
|
69
|
+
"requiredColumns": [
|
|
70
|
+
"File",
|
|
71
|
+
"Issue",
|
|
72
|
+
"Priority"
|
|
73
|
+
],
|
|
74
|
+
"minRows": 3,
|
|
75
|
+
"artifact": true
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"kind": "citationsResolve",
|
|
79
|
+
"file": "tasks/eval/audit.md",
|
|
80
|
+
"minCitations": 2,
|
|
81
|
+
"artifact": true
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"kind": "contains",
|
|
85
|
+
"file": "tasks/eval/audit.md",
|
|
86
|
+
"pattern": "index\\.html",
|
|
87
|
+
"label": "the audit names the real page"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"path": "tasks/eval/fix-notes.md",
|
|
93
|
+
"kind": "markdown-notes",
|
|
94
|
+
"artifact": true,
|
|
95
|
+
"minBytes": 700,
|
|
96
|
+
"checks": [
|
|
97
|
+
{
|
|
98
|
+
"kind": "contains",
|
|
99
|
+
"file": "tasks/eval/fix-notes.md",
|
|
100
|
+
"pattern": "^##\\s+Problem[\\s\\S]*^##\\s+Change[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Per-violation disposition[\\s\\S]*^##\\s+Risk[\\s\\S]*^##\\s+How to verify",
|
|
101
|
+
"flags": "im",
|
|
102
|
+
"label": "fix-notes sections in order"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"kind": "citationsResolve",
|
|
106
|
+
"file": "tasks/eval/fix-notes.md",
|
|
107
|
+
"minCitations": 2,
|
|
108
|
+
"artifact": true
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"path": "tasks/eval/validation.md",
|
|
114
|
+
"kind": "markdown-notes",
|
|
115
|
+
"artifact": true,
|
|
116
|
+
"minBytes": 500,
|
|
117
|
+
"checks": [
|
|
118
|
+
{
|
|
119
|
+
"kind": "contains",
|
|
120
|
+
"file": "tasks/eval/validation.md",
|
|
121
|
+
"pattern": "^##\\s+Per-item verification[\\s\\S]*^##\\s+Keyboard walk[\\s\\S]*^##\\s+Result",
|
|
122
|
+
"flags": "im",
|
|
123
|
+
"label": "validation sections in order"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"path": "tasks/eval/review.md",
|
|
129
|
+
"kind": "markdown-report",
|
|
130
|
+
"artifact": true,
|
|
131
|
+
"minBytes": 400,
|
|
132
|
+
"checks": [
|
|
133
|
+
{
|
|
134
|
+
"kind": "contains",
|
|
135
|
+
"file": "tasks/eval/review.md",
|
|
136
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
137
|
+
"flags": "i",
|
|
138
|
+
"label": "explicit reviewer verdict"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"checks": [
|
|
144
|
+
{
|
|
145
|
+
"kind": "notContains",
|
|
146
|
+
"file": "index.html",
|
|
147
|
+
"pattern": "<img\\b(?![^>]*\\balt\\s*=)[^>]*>",
|
|
148
|
+
"label": "no image is missing its alt attribute"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"kind": "htmlLint",
|
|
152
|
+
"file": "index.html"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"kind": "nodeScriptPasses",
|
|
156
|
+
"script": "tests/verify-retrofit.mjs",
|
|
157
|
+
"timeoutMs": 60000,
|
|
158
|
+
"requiredOutput": [
|
|
159
|
+
{
|
|
160
|
+
"pattern": "A11YRETRO_ORACLE alts ok",
|
|
161
|
+
"label": "meaningful images carry specific alt text"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"pattern": "A11YRETRO_ORACLE decorative ok",
|
|
165
|
+
"label": "the decorative divider keeps its empty alt"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"pattern": "A11YRETRO_ORACLE label ok",
|
|
169
|
+
"label": "the label's for pairs with a real input id"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"pattern": "A11YRETRO_ORACLE control ok",
|
|
173
|
+
"label": "the join control is keyboard-operable"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"pattern": "A11YRETRO_ORACLE headings ok",
|
|
177
|
+
"label": "heading order is monotonic"
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
],
|
|
182
|
+
"taskNotes": {
|
|
183
|
+
"minBytes": 120,
|
|
184
|
+
"checks": [
|
|
185
|
+
{
|
|
186
|
+
"kind": "contains",
|
|
187
|
+
"file": "task-notes.md",
|
|
188
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(validation\\.md|fix-notes\\.md|audit\\.md)",
|
|
189
|
+
"flags": "i",
|
|
190
|
+
"label": "DONE note names the deliverables"
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
"taskGraph": {
|
|
195
|
+
"requireCraftbookTask": true,
|
|
196
|
+
"requireTerminalStep": true
|
|
197
|
+
},
|
|
198
|
+
"unchangedFixtures": [
|
|
199
|
+
"package.json",
|
|
200
|
+
"images/harvest-crew.svg",
|
|
201
|
+
"images/seed-chart.svg",
|
|
202
|
+
"images/divider.svg"
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
"rubric": {
|
|
206
|
+
"artifact": {
|
|
207
|
+
"path": "tasks/eval/fix-notes.md",
|
|
208
|
+
"kind": "markdown"
|
|
209
|
+
},
|
|
210
|
+
"axes": [
|
|
211
|
+
{
|
|
212
|
+
"name": "Real-site repair",
|
|
213
|
+
"description": "Violations were fixed in the actual markup with semantic elements preferred over ARIA bolt-ons — a real button and a real label rather than aria-label sprayed on divs."
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "Classification judgment",
|
|
217
|
+
"description": "Meaningful versus decorative images were classified correctly: specific purposeful alt text for the content images, an empty alt preserved on the divider, and the decorative call stated in the notes."
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "Honest verification trail",
|
|
221
|
+
"description": "Audit, fix-notes, and validation reconcile item for item, and validation separates what was inspected in the code from what was actually exercised."
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
"qualityFocus": [
|
|
226
|
+
"real-site fixes over ARIA theater",
|
|
227
|
+
"content vs decorative image judgment",
|
|
228
|
+
"enforced review loop"
|
|
229
|
+
]
|
|
230
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Apply review findings with a reconciled ledger",
|
|
4
|
+
"objective": "The craftbook drives a real findings pass: three seeded review findings (unvalidated numeric input, a swallowed error, a misleading error message) read from an artifacts-drawer findings file, triaged against the current code, fixed at their actual sites, and verified per finding - with behavior probes proving each one genuinely closed and the neighborhood suite still green.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"review-findings",
|
|
8
|
+
"bug-fix",
|
|
9
|
+
"tactical-fleet"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Use the Apply Review Findings craftbook: last week's code review left three findings in the artifacts drawer at reviews/findings.json. Triage them against the current code, fix what is real at the real sites, and account for every finding.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Order Intake",
|
|
14
|
+
"about": "A tiny order-intake library (quantity parsing, config loading, discounts). Tests run with `npm run test` (node --test).",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "package.json",
|
|
18
|
+
"content": "{\n \"name\": \"intake\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"node --test\"\n }\n}\n",
|
|
19
|
+
"modelInput": false
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "src/quantity.js",
|
|
23
|
+
"content": "export function parseQuantity(raw) {\n return parseInt(raw, 10);\n}\n\nexport function clampQuantity(qty, max) {\n return Math.min(qty, max);\n}\n"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "src/config.js",
|
|
27
|
+
"content": "import { readFileSync } from 'node:fs';\n\nexport function loadConfig(path) {\n try {\n return JSON.parse(readFileSync(path, 'utf8'));\n } catch (err) {\n return {};\n }\n}\n"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "src/discount.js",
|
|
31
|
+
"content": "export function applyDiscount(total, percent) {\n if (percent < 0 || percent > 100) {\n throw new Error('quantity out of range');\n }\n return Math.round(total * (1 - percent / 100) * 100) / 100;\n}\n"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"path": "tests/intake.test.mjs",
|
|
35
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { parseQuantity } from '../src/quantity.js';\nimport { applyDiscount } from '../src/discount.js';\nimport { loadConfig } from '../src/config.js';\n\ntest('parseQuantity reads plain integers', () => {\n assert.equal(parseQuantity('3'), 3);\n assert.equal(parseQuantity('12'), 12);\n});\n\ntest('applyDiscount takes a percentage off', () => {\n assert.equal(applyDiscount(100, 10), 90);\n assert.equal(applyDiscount(80, 0), 80);\n});\n\ntest('loadConfig falls back to defaults for a missing file', () => {\n assert.deepEqual(loadConfig('no-such-config.json'), {});\n});\n",
|
|
36
|
+
"modelInput": false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "reviews/findings.json",
|
|
40
|
+
"surface": "artifact",
|
|
41
|
+
"content": "[\n {\n \"id\": \"RV-1\",\n \"file\": \"src/quantity.js\",\n \"severity\": \"major\",\n \"title\": \"parseQuantity accepts invalid numeric input\",\n \"detail\": \"parseInt returns NaN for non-numeric input, and negative or zero values pass through unchecked, so downstream order math silently corrupts. parseQuantity must return only positive integers and throw a RangeError naming the rejected value for anything else.\",\n \"verify\": \"parseQuantity('abc'), parseQuantity('-2'), and parseQuantity('0') must throw; parseQuantity('3') must still return 3.\"\n },\n {\n \"id\": \"RV-2\",\n \"file\": \"src/config.js\",\n \"severity\": \"major\",\n \"title\": \"loadConfig swallows JSON syntax errors\",\n \"detail\": \"The catch returns {} for every failure, so a corrupt config file silently behaves like an empty one and a bad deploy ships. Only a missing file may fall back to {}; a parse failure must propagate to the caller.\",\n \"verify\": \"loadConfig on a file containing invalid JSON must throw; loadConfig on a missing path must still return {}.\"\n },\n {\n \"id\": \"RV-3\",\n \"file\": \"src/discount.js\",\n \"severity\": \"minor\",\n \"title\": \"applyDiscount raises a misleading error message\",\n \"detail\": \"An out-of-range percent raises 'quantity out of range', so support keeps chasing phantom quantity bugs. The message must describe the discount percent that was rejected.\",\n \"verify\": \"applyDiscount(100, 150) must throw with a message that mentions the discount or percent, not quantity.\"\n }\n]\n"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"path": "tests/verify-findings.mjs",
|
|
45
|
+
"surface": "harness",
|
|
46
|
+
"content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parseQuantity } from '../src/quantity.js';\nimport { loadConfig } from '../src/config.js';\nimport { applyDiscount } from '../src/discount.js';\n\nconst root = process.cwd();\n\n// RV-1: parseQuantity accepts only positive integers, and still parses them.\nassert.equal(parseQuantity('3'), 3, \"parseQuantity('3') must still return 3\");\nassert.equal(parseQuantity('12'), 12, \"parseQuantity('12') must still return 12\");\nassert.throws(() => parseQuantity('abc'), \"parseQuantity('abc') must throw\");\nassert.throws(() => parseQuantity('-2'), \"parseQuantity('-2') must throw\");\nassert.throws(() => parseQuantity('0'), \"parseQuantity('0') must throw\");\nconsole.log('FINDINGS_ORACLE rv1 closed');\n\n// RV-2: a corrupt config raises; a missing config still falls back to {}.\nconst corruptPath = join(root, '.oracle-corrupt-config.json');\nwriteFileSync(corruptPath, '{ not json');\nassert.throws(() => loadConfig(corruptPath), 'a corrupt config must raise, not vanish into defaults');\nrmSync(corruptPath, { force: true });\nassert.deepEqual(loadConfig(join(root, 'no-such-config.json')), {}, 'a missing config must still fall back to {}');\nconsole.log('FINDINGS_ORACLE rv2 closed');\n\n// RV-3: the out-of-range message describes the discount, not the quantity.\nlet threw = false;\nlet message = '';\ntry {\n applyDiscount(100, 150);\n} catch (err) {\n threw = true;\n message = String((err && err.message) || err);\n}\nassert.ok(threw, 'applyDiscount(100, 150) must throw');\nassert.match(message, /discount|percent/i, 'the error must describe the discount percent');\nassert.ok(!/quantity/i.test(message), 'the error must not blame quantity');\nassert.equal(applyDiscount(100, 10), 90, 'valid discounts must still work');\nassert.equal(applyDiscount(80, 0), 80, 'a zero discount must still be allowed');\nconsole.log('FINDINGS_ORACLE rv3 closed');\n\n// The neighborhood suite stays green after the findings pass.\nexecFileSync(process.execPath, ['--test'], { cwd: root, stdio: 'pipe', timeout: 30000 });\nconsole.log('FINDINGS_ORACLE suite green');\nconsole.log('FINDINGS_ORACLE done');\n"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"craftbookParams": {
|
|
50
|
+
"workPath": "tasks/eval",
|
|
51
|
+
"findingsPath": "reviews/findings.json"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"success": {
|
|
55
|
+
"summary": "All three seeded findings are genuinely closed at their real sites (validated quantity input, propagating config parse errors, an honest discount message), the neighborhood tests stay green, and the finding ids reconcile across triage, fix notes, and verification.",
|
|
56
|
+
"deliverables": [
|
|
57
|
+
{
|
|
58
|
+
"path": "tasks/eval/triage.md",
|
|
59
|
+
"kind": "markdown-notes",
|
|
60
|
+
"artifact": true,
|
|
61
|
+
"minBytes": 600,
|
|
62
|
+
"checks": [
|
|
63
|
+
{
|
|
64
|
+
"kind": "contains",
|
|
65
|
+
"file": "tasks/eval/triage.md",
|
|
66
|
+
"pattern": "^##\\s+Findings read[\\s\\S]*^##\\s+Will fix[\\s\\S]*^##\\s+Deferred[\\s\\S]*^##\\s+Clusters",
|
|
67
|
+
"flags": "im",
|
|
68
|
+
"label": "triage sections in order"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"kind": "contains",
|
|
72
|
+
"file": "tasks/eval/triage.md",
|
|
73
|
+
"pattern": "\\bRV-1\\b",
|
|
74
|
+
"label": "finding RV-1 triaged"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"kind": "contains",
|
|
78
|
+
"file": "tasks/eval/triage.md",
|
|
79
|
+
"pattern": "\\bRV-2\\b",
|
|
80
|
+
"label": "finding RV-2 triaged"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"kind": "contains",
|
|
84
|
+
"file": "tasks/eval/triage.md",
|
|
85
|
+
"pattern": "\\bRV-3\\b",
|
|
86
|
+
"label": "finding RV-3 triaged"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"kind": "citationsResolve",
|
|
90
|
+
"file": "tasks/eval/triage.md",
|
|
91
|
+
"minCitations": 2,
|
|
92
|
+
"artifact": true
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"path": "tasks/eval/fix-notes.md",
|
|
98
|
+
"kind": "markdown-notes",
|
|
99
|
+
"artifact": true,
|
|
100
|
+
"minBytes": 700,
|
|
101
|
+
"checks": [
|
|
102
|
+
{
|
|
103
|
+
"kind": "contains",
|
|
104
|
+
"file": "tasks/eval/fix-notes.md",
|
|
105
|
+
"pattern": "^##\\s+Problem[\\s\\S]*^##\\s+Change[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Per-finding disposition[\\s\\S]*^##\\s+Risk[\\s\\S]*^##\\s+How to verify",
|
|
106
|
+
"flags": "im",
|
|
107
|
+
"label": "fix-notes sections in order"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"kind": "contains",
|
|
111
|
+
"file": "tasks/eval/fix-notes.md",
|
|
112
|
+
"pattern": "\\bRV-1\\b",
|
|
113
|
+
"label": "disposition for RV-1"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"kind": "contains",
|
|
117
|
+
"file": "tasks/eval/fix-notes.md",
|
|
118
|
+
"pattern": "\\bRV-2\\b",
|
|
119
|
+
"label": "disposition for RV-2"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"kind": "contains",
|
|
123
|
+
"file": "tasks/eval/fix-notes.md",
|
|
124
|
+
"pattern": "\\bRV-3\\b",
|
|
125
|
+
"label": "disposition for RV-3"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"kind": "citationsResolve",
|
|
129
|
+
"file": "tasks/eval/fix-notes.md",
|
|
130
|
+
"minCitations": 2,
|
|
131
|
+
"artifact": true
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"path": "tasks/eval/validation.md",
|
|
137
|
+
"kind": "markdown-notes",
|
|
138
|
+
"artifact": true,
|
|
139
|
+
"minBytes": 450,
|
|
140
|
+
"checks": [
|
|
141
|
+
{
|
|
142
|
+
"kind": "contains",
|
|
143
|
+
"file": "tasks/eval/validation.md",
|
|
144
|
+
"pattern": "^##\\s+Per-finding verification[\\s\\S]*^##\\s+Result",
|
|
145
|
+
"flags": "im",
|
|
146
|
+
"label": "validation sections in order"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"kind": "contains",
|
|
150
|
+
"file": "tasks/eval/validation.md",
|
|
151
|
+
"pattern": "\\bRV-1\\b",
|
|
152
|
+
"label": "verification for RV-1"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"kind": "contains",
|
|
156
|
+
"file": "tasks/eval/validation.md",
|
|
157
|
+
"pattern": "\\bRV-2\\b",
|
|
158
|
+
"label": "verification for RV-2"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"kind": "contains",
|
|
162
|
+
"file": "tasks/eval/validation.md",
|
|
163
|
+
"pattern": "\\bRV-3\\b",
|
|
164
|
+
"label": "verification for RV-3"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"kind": "citationsResolve",
|
|
168
|
+
"file": "tasks/eval/validation.md",
|
|
169
|
+
"minCitations": 2,
|
|
170
|
+
"artifact": true
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"path": "tasks/eval/review.md",
|
|
176
|
+
"kind": "markdown-report",
|
|
177
|
+
"artifact": true,
|
|
178
|
+
"minBytes": 400,
|
|
179
|
+
"checks": [
|
|
180
|
+
{
|
|
181
|
+
"kind": "contains",
|
|
182
|
+
"file": "tasks/eval/review.md",
|
|
183
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
184
|
+
"flags": "i",
|
|
185
|
+
"label": "explicit reviewer verdict"
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"checks": [
|
|
191
|
+
{
|
|
192
|
+
"kind": "notContains",
|
|
193
|
+
"file": "src/discount.js",
|
|
194
|
+
"pattern": "quantity out of range",
|
|
195
|
+
"label": "the misleading discount message is gone (RV-3)"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"kind": "notContains",
|
|
199
|
+
"file": "src/config.js",
|
|
200
|
+
"pattern": "catch\\s*(?:\\([^)]*\\))?\\s*\\{\\s*return\\s*\\{\\s*\\}",
|
|
201
|
+
"label": "the blanket error swallow is gone (RV-2)"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"kind": "sourceParses",
|
|
205
|
+
"file": "src/quantity.js"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"kind": "sourceParses",
|
|
209
|
+
"file": "src/config.js"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"kind": "sourceParses",
|
|
213
|
+
"file": "src/discount.js"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"kind": "nodeRuns",
|
|
217
|
+
"file": "tests/intake.test.mjs",
|
|
218
|
+
"timeoutMs": 30000
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"kind": "nodeScriptPasses",
|
|
222
|
+
"script": "tests/verify-findings.mjs",
|
|
223
|
+
"timeoutMs": 60000,
|
|
224
|
+
"requiredOutput": [
|
|
225
|
+
{
|
|
226
|
+
"pattern": "FINDINGS_ORACLE rv1 closed",
|
|
227
|
+
"label": "invalid quantities are rejected (RV-1)"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"pattern": "FINDINGS_ORACLE rv2 closed",
|
|
231
|
+
"label": "corrupt configs raise, missing configs default (RV-2)"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"pattern": "FINDINGS_ORACLE rv3 closed",
|
|
235
|
+
"label": "the discount error names the discount (RV-3)"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"pattern": "FINDINGS_ORACLE suite green",
|
|
239
|
+
"label": "the neighborhood suite stays green"
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
"taskNotes": {
|
|
245
|
+
"minBytes": 120,
|
|
246
|
+
"checks": [
|
|
247
|
+
{
|
|
248
|
+
"kind": "contains",
|
|
249
|
+
"file": "task-notes.md",
|
|
250
|
+
"pattern": "\\bDONE\\b[\\s\\S]*validation\\.md",
|
|
251
|
+
"flags": "i",
|
|
252
|
+
"label": "DONE note names the validation deliverable"
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
"taskGraph": {
|
|
257
|
+
"requireCraftbookTask": true,
|
|
258
|
+
"requireTerminalStep": true
|
|
259
|
+
},
|
|
260
|
+
"unchangedFixtures": [
|
|
261
|
+
"package.json",
|
|
262
|
+
"tests/intake.test.mjs"
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
"rubric": {
|
|
266
|
+
"artifact": {
|
|
267
|
+
"path": "tasks/eval/fix-notes.md",
|
|
268
|
+
"kind": "markdown"
|
|
269
|
+
},
|
|
270
|
+
"axes": [
|
|
271
|
+
{
|
|
272
|
+
"name": "Triage honesty",
|
|
273
|
+
"description": "Every finding is judged against the code as it stands, with a defensible category and no invented or dropped findings."
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "Real closure",
|
|
277
|
+
"description": "Each fix lands at the actual cited site and genuinely resolves what the finding describes - validation added, errors propagated, messages made truthful - with the smallest correct change."
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "Ledger discipline",
|
|
281
|
+
"description": "The same finding ids flow through triage, fix notes, and verification with consistent outcomes, and verification honestly separates what was run from what was only read."
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
"qualityFocus": [
|
|
286
|
+
"per-finding accountability",
|
|
287
|
+
"smallest correct change",
|
|
288
|
+
"honest verification"
|
|
289
|
+
]
|
|
290
|
+
}
|