@bendyline/gilde 0.1.39 → 0.1.41
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/chat-models/muse-glimmer-30b-q4.json +3 -3
- package/authoring/chat-models/ornith-9b-q4.json +1 -1
- package/authoring/chat-models/ornith1.5-9b-q4.json +149 -0
- package/authoring/chat-models/qwen3.8-27b-iq1-s.json +190 -0
- package/authoring/chat-models/qwen3.8-27b-q2.json +189 -0
- 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/chat-models/mu/muse-glimmer-30b-q4/manifest.json +4 -3
- package/data/chat-models/mu/muse-glimmer-30b-q4/versions/1.0.2/manifest.json +20 -0
- package/data/chat-models/or/ornith-9b-q4/manifest.json +1 -1
- package/data/chat-models/or/ornith1.5-9b-q4/manifest.json +187 -0
- package/data/chat-models/or/ornith1.5-9b-q4/versions/1.0.0/manifest.json +53 -0
- package/data/chat-models/qw/qwen3.8-27b-iq1-s/manifest.json +195 -0
- package/data/chat-models/qw/qwen3.8-27b-iq1-s/versions/1.0.0/manifest.json +19 -0
- package/data/chat-models/qw/qwen3.8-27b-q2/manifest.json +194 -0
- package/data/chat-models/qw/qwen3.8-27b-q2/versions/1.0.0/manifest.json +19 -0
- package/data/craftbook-templates/a1/a11y-audit/manifest.json +1 -0
- package/data/craftbook-templates/ab/ab-test-readout/manifest.json +1 -0
- package/data/craftbook-templates/ac/accessibility-retrofit/manifest.json +6 -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/ad/ad-variations/manifest.json +1 -0
- package/data/craftbook-templates/al/album-curate/manifest.json +1 -0
- package/data/craftbook-templates/al/alert-rules/manifest.json +1 -0
- package/data/craftbook-templates/al/alt-text-pass/manifest.json +6 -1
- package/data/craftbook-templates/an/anniversary-cut/manifest.json +1 -0
- package/data/craftbook-templates/an/annotated-bibliography/manifest.json +1 -0
- package/data/craftbook-templates/an/annual-document-review/manifest.json +1 -0
- package/data/craftbook-templates/an/anomaly-scan/manifest.json +1 -0
- package/data/craftbook-templates/ap/api-contract-review/manifest.json +1 -0
- 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/ar/artifact-integrity-review/manifest.json +1 -0
- package/data/craftbook-templates/au/audio-ad-spot/manifest.json +1 -0
- package/data/craftbook-templates/au/audio-highlight-reel/manifest.json +1 -0
- package/data/craftbook-templates/au/audiobook-master-pack/manifest.json +1 -0
- package/data/craftbook-templates/au/auth-flow/manifest.json +1 -0
- package/data/craftbook-templates/au/automation-recipe/manifest.json +1 -0
- package/data/craftbook-templates/ba/backup-routine/manifest.json +1 -0
- package/data/craftbook-templates/bl/blog-post/manifest.json +1 -0
- package/data/craftbook-templates/bo/board-deck/manifest.json +1 -0
- package/data/craftbook-templates/bo/board-game-web/manifest.json +1 -0
- package/data/craftbook-templates/bo/booking-automation/manifest.json +1 -0
- package/data/craftbook-templates/br/branding-website/manifest.json +1 -0
- package/data/craftbook-templates/br/broadcast-announcement/manifest.json +1 -0
- package/data/craftbook-templates/br/browser-qa-audit/manifest.json +6 -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 +4 -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/bu/build-loop/manifest.json +1 -0
- package/data/craftbook-templates/ca/calendar-brief/manifest.json +1 -0
- package/data/craftbook-templates/ca/canvas-generative-art/manifest.json +1 -0
- package/data/craftbook-templates/ca/careful-mode/manifest.json +1 -0
- package/data/craftbook-templates/ca/case-study/manifest.json +1 -0
- package/data/craftbook-templates/ca/case-study-writeup/manifest.json +1 -0
- package/data/craftbook-templates/ch/changelog-cut/manifest.json +6 -1
- package/data/craftbook-templates/ch/changelog-writeup/manifest.json +6 -1
- package/data/craftbook-templates/ch/chapter-narration-run/manifest.json +1 -0
- package/data/craftbook-templates/ch/chapter-weave/manifest.json +1 -0
- package/data/craftbook-templates/ch/character-sheet/manifest.json +1 -0
- package/data/craftbook-templates/ch/character-turnaround/manifest.json +1 -0
- package/data/craftbook-templates/ch/chart-pack/manifest.json +1 -0
- package/data/craftbook-templates/ch/chrome-extension/manifest.json +1 -0
- package/data/craftbook-templates/ci/ci-pipeline/manifest.json +6 -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/ci/citation-audit/manifest.json +1 -0
- package/data/craftbook-templates/cl/cli-tool/manifest.json +1 -0
- package/data/craftbook-templates/co/code-review/manifest.json +1 -0
- package/data/craftbook-templates/co/codebase-refactoring-review/manifest.json +1 -0
- package/data/craftbook-templates/co/codebase-ux-review/manifest.json +1 -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/co/cohort-analysis/manifest.json +1 -0
- package/data/craftbook-templates/co/company-research-brief/manifest.json +1 -0
- package/data/craftbook-templates/co/comparison-matrix/manifest.json +1 -0
- package/data/craftbook-templates/co/compat-check/manifest.json +1 -0
- package/data/craftbook-templates/co/competitive-analysis/manifest.json +1 -0
- package/data/craftbook-templates/co/comprehensive-codebase-review/art.json +12 -0
- package/data/craftbook-templates/co/comprehensive-codebase-review/logo.webp +0 -0
- package/data/craftbook-templates/co/comprehensive-codebase-review/manifest.json +27 -0
- package/data/craftbook-templates/co/comprehensive-codebase-review/versions/1.0.0/craftbook.json +337 -0
- package/data/craftbook-templates/co/comprehensive-codebase-review/versions/1.0.0/test.json +160 -0
- package/data/craftbook-templates/co/config-scaffold/manifest.json +1 -0
- package/data/craftbook-templates/co/content-accuracy-review/manifest.json +1 -0
- package/data/craftbook-templates/co/content-deck/manifest.json +1 -0
- package/data/craftbook-templates/co/contract-template/manifest.json +1 -0
- package/data/craftbook-templates/co/cookbook-layout/manifest.json +1 -0
- package/data/craftbook-templates/co/copy-review/manifest.json +1 -0
- package/data/craftbook-templates/co/corpus-email-digest/manifest.json +1 -0
- package/data/craftbook-templates/co/corpus-synthesis/manifest.json +1 -0
- package/data/craftbook-templates/co/cover-letter/manifest.json +1 -0
- package/data/craftbook-templates/cr/crm-update-batch/manifest.json +1 -0
- package/data/craftbook-templates/cr/cron-job/manifest.json +1 -0
- package/data/craftbook-templates/cr/crossword-forge/manifest.json +1 -0
- package/data/craftbook-templates/cs/csv-transformer/manifest.json +1 -0
- package/data/craftbook-templates/da/dashboard-spec/manifest.json +1 -0
- package/data/craftbook-templates/da/data-dictionary/manifest.json +1 -0
- package/data/craftbook-templates/da/data-export-migrate/manifest.json +1 -0
- package/data/craftbook-templates/da/data-join-merge/manifest.json +1 -0
- package/data/craftbook-templates/da/data-pipeline-etl/manifest.json +1 -0
- package/data/craftbook-templates/da/data-quality-audit/manifest.json +1 -0
- package/data/craftbook-templates/da/data-to-report/manifest.json +1 -0
- package/data/craftbook-templates/da/data-viz-page/manifest.json +1 -0
- package/data/craftbook-templates/da/dataset-clean/manifest.json +1 -0
- package/data/craftbook-templates/db/db-index-tuning/manifest.json +1 -0
- package/data/craftbook-templates/de/deep-security-review/manifest.json +1 -0
- package/data/craftbook-templates/de/dependency-audit/manifest.json +1 -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/de/deploy-checklist/manifest.json +1 -0
- package/data/craftbook-templates/de/design-review/manifest.json +1 -0
- package/data/craftbook-templates/de/design-system-consultation/manifest.json +1 -0
- package/data/craftbook-templates/di/diagram-from-text/manifest.json +1 -0
- package/data/craftbook-templates/di/digest-from-feeds/manifest.json +1 -0
- package/data/craftbook-templates/do/doc-intake-pipeline/manifest.json +1 -0
- package/data/craftbook-templates/do/doc-rewrite/manifest.json +1 -0
- package/data/craftbook-templates/do/dockerize-app/manifest.json +1 -0
- package/data/craftbook-templates/do/docs-site/manifest.json +1 -0
- package/data/craftbook-templates/do/documentation-drift-review/manifest.json +1 -0
- package/data/craftbook-templates/dr/draft-social-post/manifest.json +1 -0
- package/data/craftbook-templates/dr/drive-wrap-up/manifest.json +1 -0
- package/data/craftbook-templates/du/due-diligence-brief/manifest.json +1 -0
- package/data/craftbook-templates/eb/ebook-compile/manifest.json +1 -0
- package/data/craftbook-templates/ed/edit-notes/manifest.json +1 -0
- package/data/craftbook-templates/em/email-sequence/manifest.json +1 -0
- package/data/craftbook-templates/em/email-template/manifest.json +1 -0
- package/data/craftbook-templates/en/engineering-retrospective/manifest.json +1 -0
- package/data/craftbook-templates/ep/episode-plan/manifest.json +1 -0
- package/data/craftbook-templates/es/escalation-playbook/manifest.json +1 -0
- package/data/craftbook-templates/ev/evidence-brief/manifest.json +1 -0
- package/data/craftbook-templates/ex/executive-level-review/manifest.json +1 -0
- package/data/craftbook-templates/ex/expense-categorize/manifest.json +1 -0
- package/data/craftbook-templates/fa/fact-check/manifest.json +1 -0
- package/data/craftbook-templates/fa/family-story-chapter/manifest.json +1 -0
- package/data/craftbook-templates/fa/faq-from-docs/manifest.json +1 -0
- package/data/craftbook-templates/fa/favicon-set/manifest.json +1 -0
- package/data/craftbook-templates/fe/feature-flag-release/manifest.json +6 -1
- package/data/craftbook-templates/fe/feature-flag-rollout/manifest.json +5 -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/fe/feedback-widget/manifest.json +1 -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/fo/folder-to-audio/manifest.json +1 -0
- package/data/craftbook-templates/fo/forecast-model/manifest.json +1 -0
- package/data/craftbook-templates/fo/form-fill-batch/manifest.json +1 -0
- package/data/craftbook-templates/fo/form-wizard/manifest.json +1 -0
- package/data/craftbook-templates/fr/freeze-scope/manifest.json +1 -0
- package/data/craftbook-templates/ga/game-with-screens/manifest.json +1 -0
- package/data/craftbook-templates/gl/glossary-build/manifest.json +1 -0
- package/data/craftbook-templates/gr/graphql-api/manifest.json +1 -0
- package/data/craftbook-templates/gr/grpc-service/manifest.json +1 -0
- package/data/craftbook-templates/ha/handbook-section/manifest.json +1 -0
- package/data/craftbook-templates/he/hero-image/manifest.json +1 -0
- package/data/craftbook-templates/ho/holiday-card-run/manifest.json +1 -0
- package/data/craftbook-templates/ho/hotfix-flow/manifest.json +6 -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/ht/html-arcade-game/manifest.json +1 -0
- package/data/craftbook-templates/ht/html-puzzle-game/manifest.json +1 -0
- package/data/craftbook-templates/ic/icon-pack/manifest.json +1 -0
- package/data/craftbook-templates/id/idea-office-hours/manifest.json +1 -0
- package/data/craftbook-templates/id/idle-clicker-game/manifest.json +1 -0
- package/data/craftbook-templates/im/image-batch-edit/manifest.json +1 -0
- package/data/craftbook-templates/im/image-dedup-cluster/manifest.json +1 -0
- package/data/craftbook-templates/im/image-palette-extract/manifest.json +1 -0
- package/data/craftbook-templates/im/image-seo-rename/manifest.json +1 -0
- package/data/craftbook-templates/im/image-set-index/manifest.json +1 -0
- package/data/craftbook-templates/in/inbox-triage/manifest.json +1 -0
- package/data/craftbook-templates/in/incident-comms-templates/manifest.json +1 -0
- package/data/craftbook-templates/in/incident-postmortem/manifest.json +1 -0
- package/data/craftbook-templates/in/insurance-inventory/manifest.json +1 -0
- package/data/craftbook-templates/in/interactive-quiz/manifest.json +1 -0
- package/data/craftbook-templates/in/investigate/manifest.json +5 -1
- package/data/craftbook-templates/in/investigate-root-cause/manifest.json +6 -1
- package/data/craftbook-templates/in/invitation-design/manifest.json +1 -0
- package/data/craftbook-templates/in/invoice-generator/manifest.json +1 -0
- package/data/craftbook-templates/in/invoice-run/manifest.json +1 -0
- package/data/craftbook-templates/index.json +1 -1
- package/data/craftbook-templates/it/item-intake/manifest.json +1 -0
- package/data/craftbook-templates/ju/juice-pass/manifest.json +1 -0
- package/data/craftbook-templates/kn/knowledge-base-article/manifest.json +1 -0
- package/data/craftbook-templates/kp/kpi-scorecard/manifest.json +1 -0
- package/data/craftbook-templates/la/landing-copy/manifest.json +1 -0
- package/data/craftbook-templates/la/landing-page/manifest.json +1 -0
- package/data/craftbook-templates/le/lead-enrichment/manifest.json +1 -0
- package/data/craftbook-templates/li/library-package/manifest.json +1 -0
- package/data/craftbook-templates/li/literature-review/manifest.json +1 -0
- package/data/craftbook-templates/li/live-browser-qa/manifest.json +6 -1
- package/data/craftbook-templates/lo/localize-content/manifest.json +1 -0
- package/data/craftbook-templates/lo/logo-set/manifest.json +1 -0
- package/data/craftbook-templates/ma/market-scan/manifest.json +1 -0
- package/data/craftbook-templates/me/meeting-minutes/manifest.json +1 -0
- package/data/craftbook-templates/me/meeting-notes-to-actions/manifest.json +1 -0
- package/data/craftbook-templates/me/meeting-prep-brief/manifest.json +1 -0
- package/data/craftbook-templates/me/meeting-summary-audio/manifest.json +1 -0
- package/data/craftbook-templates/me/memory-prompt-session/manifest.json +1 -0
- package/data/craftbook-templates/me/message-queue-consumer/manifest.json +1 -0
- package/data/craftbook-templates/mi/micro-game-jam/manifest.json +1 -0
- package/data/craftbook-templates/mo/mock-interview/manifest.json +1 -0
- package/data/craftbook-templates/mo/mod-scaffold/manifest.json +1 -0
- package/data/craftbook-templates/mo/monitor-and-alert/manifest.json +1 -0
- package/data/craftbook-templates/mo/month-close/manifest.json +1 -0
- package/data/craftbook-templates/mo/monthly-recording-review/manifest.json +1 -0
- package/data/craftbook-templates/mo/moodboard/manifest.json +1 -0
- package/data/craftbook-templates/mo/morning-brief/manifest.json +1 -0
- package/data/craftbook-templates/mo/morning-report/manifest.json +1 -0
- package/data/craftbook-templates/mu/music-metadata-tag/manifest.json +1 -0
- package/data/craftbook-templates/na/narrated-slideshow/manifest.json +1 -0
- package/data/craftbook-templates/ne/newsletter-issue/manifest.json +1 -0
- 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/no/notification-router/manifest.json +1 -0
- package/data/craftbook-templates/oc/ocr-extract/manifest.json +1 -0
- package/data/craftbook-templates/of/offer-compare/manifest.json +1 -0
- package/data/craftbook-templates/of/office-hours/manifest.json +1 -0
- package/data/craftbook-templates/on/onboarding-checklist/manifest.json +1 -0
- package/data/craftbook-templates/on/onboarding-flow/manifest.json +1 -0
- package/data/craftbook-templates/on/oncall-handoff/manifest.json +1 -0
- package/data/craftbook-templates/on/one-pager/manifest.json +1 -0
- package/data/craftbook-templates/op/ops-runbook/manifest.json +1 -0
- package/data/craftbook-templates/pa/page-spread/manifest.json +1 -0
- package/data/craftbook-templates/pa/parser-grammar/manifest.json +1 -0
- package/data/craftbook-templates/pe/perf-audit/manifest.json +1 -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 +4 -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/pe/pest-diagnosis/manifest.json +1 -0
- package/data/craftbook-templates/ph/photo-cull/manifest.json +1 -0
- package/data/craftbook-templates/ph/physics-toy/manifest.json +1 -0
- package/data/craftbook-templates/pi/pitch-deck/manifest.json +1 -0
- package/data/craftbook-templates/pl/plan/manifest.json +1 -0
- package/data/craftbook-templates/pl/playtest-report/manifest.json +1 -0
- package/data/craftbook-templates/po/podcast-chaptering/manifest.json +1 -0
- package/data/craftbook-templates/po/portfolio-site/manifest.json +1 -0
- package/data/craftbook-templates/po/powerpoint-deck/manifest.json +1 -0
- package/data/craftbook-templates/pr/pr-security-review/manifest.json +1 -0
- package/data/craftbook-templates/pr/practice-exam/manifest.json +1 -0
- package/data/craftbook-templates/pr/practice-session/manifest.json +1 -0
- package/data/craftbook-templates/pr/pre-departure-countdown/manifest.json +1 -0
- package/data/craftbook-templates/pr/press-release/manifest.json +1 -0
- package/data/craftbook-templates/pr/price-tracker/manifest.json +1 -0
- package/data/craftbook-templates/pr/pricing-page/manifest.json +1 -0
- package/data/craftbook-templates/pr/product-descriptions/manifest.json +1 -0
- package/data/craftbook-templates/pr/proposal-sow/manifest.json +1 -0
- package/data/craftbook-templates/pu/pull-request-review/manifest.json +1 -0
- package/data/craftbook-templates/pu/puzzle-pack-layout/manifest.json +1 -0
- package/data/craftbook-templates/pw/pwa-offline/manifest.json +1 -0
- package/data/craftbook-templates/qa/qa/manifest.json +4 -1
- package/data/craftbook-templates/qu/quarterly-summary/manifest.json +1 -0
- package/data/craftbook-templates/re/reading-list/manifest.json +1 -0
- package/data/craftbook-templates/re/receipt-intake/manifest.json +1 -0
- package/data/craftbook-templates/re/receipt-ocr-ledger/manifest.json +1 -0
- package/data/craftbook-templates/re/reception-report/manifest.json +1 -0
- package/data/craftbook-templates/re/recipe-capture/manifest.json +1 -0
- package/data/craftbook-templates/re/record-a-relative/manifest.json +1 -0
- package/data/craftbook-templates/re/recurring-invoice-run/manifest.json +1 -0
- package/data/craftbook-templates/re/refactor-module/manifest.json +3 -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/regex-builder/manifest.json +1 -0
- package/data/craftbook-templates/re/release-announcement/manifest.json +1 -0
- package/data/craftbook-templates/re/release-artifact-sanity-check/manifest.json +1 -0
- package/data/craftbook-templates/re/release-notes/manifest.json +6 -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 +6 -1
- package/data/craftbook-templates/re/release-readiness-review/manifest.json +1 -0
- 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/re/reliability-review/manifest.json +1 -0
- package/data/craftbook-templates/re/report-pdf/manifest.json +1 -0
- package/data/craftbook-templates/re/research-report/manifest.json +1 -0
- package/data/craftbook-templates/re/research-to-document/manifest.json +1 -0
- package/data/craftbook-templates/re/rest-api/manifest.json +1 -0
- package/data/craftbook-templates/re/resume-cv/manifest.json +1 -0
- package/data/craftbook-templates/re/reviewer-loop/manifest.json +1 -0
- package/data/craftbook-templates/ro/rollback-plan/manifest.json +1 -0
- package/data/craftbook-templates/ro/root-cause-investigation/manifest.json +8 -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/ro/rough-cut-assembly/manifest.json +1 -0
- package/data/craftbook-templates/ru/runbook/manifest.json +1 -0
- package/data/craftbook-templates/sc/schema-migration/manifest.json +5 -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/sc/scrape-to-structured/manifest.json +1 -0
- package/data/craftbook-templates/sc/script-automation/manifest.json +1 -0
- package/data/craftbook-templates/sd/sdk-wrapper/manifest.json +1 -0
- package/data/craftbook-templates/se/seasonal-maintenance-sweep/manifest.json +1 -0
- package/data/craftbook-templates/se/security-architecture-review/manifest.json +1 -0
- package/data/craftbook-templates/se/seo-meta-pack/manifest.json +1 -0
- package/data/craftbook-templates/sh/ship/manifest.json +1 -0
- package/data/craftbook-templates/so/social-digest/manifest.json +1 -0
- package/data/craftbook-templates/so/social-thread/manifest.json +1 -0
- package/data/craftbook-templates/so/source-quality-audit/manifest.json +1 -0
- package/data/craftbook-templates/sp/spa-dashboard/manifest.json +1 -0
- package/data/craftbook-templates/sp/spec-authoring/manifest.json +1 -0
- package/data/craftbook-templates/sp/spec-doc/manifest.json +1 -0
- package/data/craftbook-templates/sp/spreadsheet-model/manifest.json +1 -0
- package/data/craftbook-templates/sp/sprite-sheet/manifest.json +1 -0
- package/data/craftbook-templates/sq/sql-analysis/manifest.json +1 -0
- package/data/craftbook-templates/st/standup-summary/manifest.json +1 -0
- package/data/craftbook-templates/st/state-machine/manifest.json +1 -0
- package/data/craftbook-templates/st/status-report/manifest.json +1 -0
- package/data/craftbook-templates/su/subscription-audit/manifest.json +1 -0
- package/data/craftbook-templates/su/subtitle-generator/manifest.json +1 -0
- package/data/craftbook-templates/su/summarize-long/manifest.json +1 -0
- package/data/craftbook-templates/su/survey-analysis/manifest.json +1 -0
- package/data/craftbook-templates/sv/svg-animation/manifest.json +1 -0
- package/data/craftbook-templates/ta/tailor-resume/manifest.json +1 -0
- package/data/craftbook-templates/te/technical-documentation/manifest.json +1 -0
- package/data/craftbook-templates/te/test-coverage-review/manifest.json +1 -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 +2 -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/th/thank-you-batch/manifest.json +1 -0
- package/data/craftbook-templates/th/thank-you-sweep/manifest.json +1 -0
- package/data/craftbook-templates/th/threat-model/manifest.json +1 -0
- package/data/craftbook-templates/th/thumbnail-generator/manifest.json +1 -0
- package/data/craftbook-templates/ti/tileset-batch/manifest.json +1 -0
- package/data/craftbook-templates/to/tone-rewrite/manifest.json +1 -0
- package/data/craftbook-templates/to/topic-explainer/manifest.json +1 -0
- package/data/craftbook-templates/tr/transcribe-and-shownotes/manifest.json +1 -0
- package/data/craftbook-templates/tr/transcribe-audio/manifest.json +1 -0
- package/data/craftbook-templates/tr/transcribe-index/manifest.json +1 -0
- package/data/craftbook-templates/tr/translate-content/manifest.json +1 -0
- package/data/craftbook-templates/ty/type-safety-pass/manifest.json +4 -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/manifest.json +1 -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/craftbook-templates/vi/video-storyboard/manifest.json +1 -0
- package/data/craftbook-templates/vi/visit-prep/manifest.json +1 -0
- package/data/craftbook-templates/vo/voiceover-script/manifest.json +1 -0
- package/data/craftbook-templates/we/weak-spot-drill/manifest.json +1 -0
- package/data/craftbook-templates/we/web-app-crud/manifest.json +1 -0
- package/data/craftbook-templates/we/web-component/manifest.json +1 -0
- package/data/craftbook-templates/we/webhook-handler/manifest.json +1 -0
- package/data/craftbook-templates/we/week-plan/manifest.json +1 -0
- package/data/craftbook-templates/we/weekly-menu-plan/manifest.json +1 -0
- package/data/craftbook-templates/we/weekly-pipeline-review/manifest.json +1 -0
- package/data/craftbook-templates/we/weekly-review/manifest.json +1 -0
- package/data/craftbook-templates/we/weekly-walkthrough/manifest.json +1 -0
- package/data/craftbook-templates/wh/whitepaper/manifest.json +1 -0
- package/data/craftbook-templates/ye/year-in-review/manifest.json +1 -0
- package/data/craftbook-templates/yo/youtube-chapters-seo/manifest.json +1 -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-identity.schema.json +21 -0
- package/schemas/craftbook-template-version.schema.json +248 -0
- package/schemas/craftbook-test.schema.json +210 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Test backfill proven by mutants",
|
|
4
|
+
"objective": "The craftbook drives a risk-ranked backfill of an untested date-range module. The oracle proves the new tests bite: three seeded mutations (an exclusive boundary, a duration off-by-one, overlap collapsed to containment) are applied in copies and the model's suite must fail at least two of them while staying green on the real tree — with the module under test byte-identical to the fixture.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"tests",
|
|
8
|
+
"coverage",
|
|
9
|
+
"tactical-fleet"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Use the Test Suite Backfill craftbook: src/date-range.js schedules bookings across the product and has no tests at all — tests/ only covers the formatter. Backfill a meaningful suite for the date-range module in the existing test layout, highest-risk behavior first: its bounds are inclusive on both ends and an inverted range must throw.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Booking Ranges",
|
|
14
|
+
"about": "A tiny scheduling library. Tests run with `npm run test` (node --test). src/date-range.js is untested; src/format.js has an existing test that shows the layout and style.",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "package.json",
|
|
18
|
+
"content": "{\n \"name\": \"booking-ranges\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"node --test\"\n }\n}\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "src/date-range.js",
|
|
22
|
+
"content": "// Inclusive [start, end] day ranges. Days are ISO strings like '2026-03-14'.\nconst DAY_MS = 86400000;\n\nfunction dayValue(day) {\n if (typeof day !== 'string' || !/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) {\n throw new Error(`invalid day: ${day}`);\n }\n const value = Date.parse(`${day}T00:00:00Z`);\n if (Number.isNaN(value)) throw new Error(`invalid day: ${day}`);\n return value;\n}\n\nfunction assertRange(range) {\n const start = dayValue(range.start);\n const end = dayValue(range.end);\n if (start > end) {\n throw new Error(`invalid range: ${range.start} is after ${range.end}`);\n }\n return { start, end };\n}\n\nexport function overlaps(a, b) {\n const ra = assertRange(a);\n const rb = assertRange(b);\n return ra.start <= rb.end && rb.start <= ra.end;\n}\n\nexport function containsDay(range, day) {\n const r = assertRange(range);\n const d = dayValue(day);\n return d >= r.start && d <= r.end;\n}\n\nexport function durationDays(range) {\n const r = assertRange(range);\n return Math.round((r.end - r.start) / DAY_MS) + 1;\n}\n"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "src/format.js",
|
|
26
|
+
"content": "export function slugify(text) {\n return String(text)\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"path": "tests/format.test.mjs",
|
|
30
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { slugify } from '../src/format.js';\n\ntest('slugify collapses spaces and punctuation', () => {\n assert.equal(slugify('Walnut writing desk!'), 'walnut-writing-desk');\n});\n\ntest('slugify trims stray dashes', () => {\n assert.equal(slugify(' --Oak shelf-- '), 'oak-shelf');\n});\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "tests/verify-backfill.mjs",
|
|
34
|
+
"surface": "harness",
|
|
35
|
+
"content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { cpSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst root = process.cwd();\nconst ORACLE = 'verify-backfill.mjs';\n\n// Bare `node --test` discovery: finds tests/**/*.test.* from cwd and skips\n// dot-directories, so the .oracle-* mutant copies never leak into a run.\n// (A literal `--test tests/` directory argument no longer resolves on\n// modern Node - it is treated as a module path.)\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}\n\n// 1) New tests exist in the real layout and target the date-range module.\nconst testFiles = readdirSync(join(root, 'tests'), { recursive: true })\n .map(String)\n .filter((f) => /\\.test\\.(mjs|js|cjs)$/.test(f) && !f.endsWith('format.test.mjs'));\nassert.ok(testFiles.length >= 1, 'no new test file found in tests/');\nconst newTestText = testFiles.map((f) => readFileSync(join(root, 'tests', f), 'utf8')).join('\\n');\nassert.ok(/date-range/.test(newTestText), 'the new tests never reference the date-range module');\nconsole.log('BACKFILL_ORACLE new tests found');\n\n// 2) The suite is green on the real tree.\nassert.equal(runSuite(root), 0, 'the suite must pass on the real tree');\nconsole.log('BACKFILL_ORACLE suite green');\n\n// 3) Seeded defects in copies must make the new suite fail - proof the tests bite.\nconst source = readFileSync(join(root, 'src', 'date-range.js'), 'utf8');\nfunction mutantCaught(name, mutate) {\n const mroot = join(root, `.oracle-${name}`);\n rmSync(mroot, { recursive: true, force: true });\n mkdirSync(mroot, { recursive: true });\n cpSync(join(root, 'src'), join(mroot, 'src'), { recursive: true });\n cpSync(join(root, 'tests'), join(mroot, 'tests'), { recursive: true });\n rmSync(join(mroot, 'tests', ORACLE), { force: true });\n cpSync(join(root, 'package.json'), join(mroot, 'package.json'));\n const mutated = mutate(source);\n assert.notEqual(mutated, source, `mutation ${name} failed to apply - src/date-range.js was altered`);\n writeFileSync(join(mroot, 'src', 'date-range.js'), mutated);\n const caught = runSuite(mroot) !== 0;\n console.log(`BACKFILL_ORACLE mutant ${name} ${caught ? 'caught' : 'MISSED'}`);\n return caught;\n}\n\nconst caught = [\n mutantCaught('boundary', (s) => s.replace('rb.start <= ra.end', 'rb.start < ra.end')),\n mutantCaught('duration', (s) => s.replace('/ DAY_MS) + 1', '/ DAY_MS)')),\n mutantCaught('containment', (s) => s.replace('ra.start <= rb.end && rb.start <= ra.end', 'ra.start <= rb.start && rb.end <= ra.end')),\n].filter(Boolean).length;\nassert.ok(caught >= 2, `the new tests caught only ${caught}/3 seeded defects - they do not pin real behavior`);\nconsole.log(`BACKFILL_ORACLE mutants ${caught}/3`);\nconsole.log('BACKFILL_ORACLE done');\n"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"craftbookParams": {
|
|
39
|
+
"workPath": "tasks/eval"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"success": {
|
|
43
|
+
"summary": "New tests for the date-range module live in the real layout, the whole suite is green on the untouched tree, and the tests catch at least two of three seeded mutations — with every fleet artifact present and honestly cited.",
|
|
44
|
+
"deliverables": [
|
|
45
|
+
{
|
|
46
|
+
"path": "tasks/eval/risk-map.md",
|
|
47
|
+
"kind": "markdown-notes",
|
|
48
|
+
"artifact": true,
|
|
49
|
+
"minBytes": 500,
|
|
50
|
+
"checks": [
|
|
51
|
+
{
|
|
52
|
+
"kind": "contains",
|
|
53
|
+
"file": "tasks/eval/risk-map.md",
|
|
54
|
+
"pattern": "^##\\s+Modules[\\s\\S]*^##\\s+Risks ranked[\\s\\S]*^##\\s+Chosen targets",
|
|
55
|
+
"flags": "im",
|
|
56
|
+
"label": "risk-map sections in order"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"kind": "contains",
|
|
60
|
+
"file": "tasks/eval/risk-map.md",
|
|
61
|
+
"pattern": "src/date-range\\.js",
|
|
62
|
+
"label": "names the real target module"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"kind": "citationsResolve",
|
|
66
|
+
"file": "tasks/eval/risk-map.md",
|
|
67
|
+
"minCitations": 2,
|
|
68
|
+
"artifact": true
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"path": "tasks/eval/test-notes.md",
|
|
74
|
+
"kind": "markdown-notes",
|
|
75
|
+
"artifact": true,
|
|
76
|
+
"minBytes": 600,
|
|
77
|
+
"checks": [
|
|
78
|
+
{
|
|
79
|
+
"kind": "contains",
|
|
80
|
+
"file": "tasks/eval/test-notes.md",
|
|
81
|
+
"pattern": "^##\\s+Tests added[\\s\\S]*^##\\s+Behaviors pinned[\\s\\S]*^##\\s+How each test would catch a realistic break",
|
|
82
|
+
"flags": "im",
|
|
83
|
+
"label": "test-notes sections in order"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"kind": "citationsResolve",
|
|
87
|
+
"file": "tasks/eval/test-notes.md",
|
|
88
|
+
"minCitations": 2,
|
|
89
|
+
"artifact": true
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"path": "tasks/eval/verification.md",
|
|
95
|
+
"kind": "markdown-notes",
|
|
96
|
+
"artifact": true,
|
|
97
|
+
"minBytes": 400,
|
|
98
|
+
"checks": [
|
|
99
|
+
{
|
|
100
|
+
"kind": "contains",
|
|
101
|
+
"file": "tasks/eval/verification.md",
|
|
102
|
+
"pattern": "^##\\s+Suite[\\s\\S]*^##\\s+Coverage summary[\\s\\S]*^##\\s+Result",
|
|
103
|
+
"flags": "im",
|
|
104
|
+
"label": "verification sections in order"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"path": "tasks/eval/review.md",
|
|
110
|
+
"kind": "markdown-report",
|
|
111
|
+
"artifact": true,
|
|
112
|
+
"minBytes": 400,
|
|
113
|
+
"checks": [
|
|
114
|
+
{
|
|
115
|
+
"kind": "contains",
|
|
116
|
+
"file": "tasks/eval/review.md",
|
|
117
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
118
|
+
"flags": "i",
|
|
119
|
+
"label": "explicit reviewer verdict"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"checks": [
|
|
125
|
+
{
|
|
126
|
+
"kind": "nodeRuns",
|
|
127
|
+
"file": "tests/format.test.mjs"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"kind": "nodeScriptPasses",
|
|
131
|
+
"script": "tests/verify-backfill.mjs",
|
|
132
|
+
"timeoutMs": 120000,
|
|
133
|
+
"requiredOutput": [
|
|
134
|
+
{
|
|
135
|
+
"pattern": "BACKFILL_ORACLE new tests found",
|
|
136
|
+
"label": "new tests exist in the real layout"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"pattern": "BACKFILL_ORACLE suite green",
|
|
140
|
+
"label": "the whole suite passes on the real tree"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"pattern": "BACKFILL_ORACLE mutants [23]/3",
|
|
144
|
+
"label": "the new tests catch seeded defects"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"taskNotes": {
|
|
150
|
+
"minBytes": 120,
|
|
151
|
+
"checks": [
|
|
152
|
+
{
|
|
153
|
+
"kind": "contains",
|
|
154
|
+
"file": "task-notes.md",
|
|
155
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
|
|
156
|
+
"flags": "i",
|
|
157
|
+
"label": "DONE note names the real test command"
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
"taskGraph": {
|
|
162
|
+
"requireCraftbookTask": true,
|
|
163
|
+
"requireTerminalStep": true
|
|
164
|
+
},
|
|
165
|
+
"unchangedFixtures": [
|
|
166
|
+
"package.json",
|
|
167
|
+
"src/date-range.js",
|
|
168
|
+
"src/format.js",
|
|
169
|
+
"tests/format.test.mjs"
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"rubric": {
|
|
173
|
+
"artifact": {
|
|
174
|
+
"path": "tasks/eval/test-notes.md",
|
|
175
|
+
"kind": "markdown"
|
|
176
|
+
},
|
|
177
|
+
"axes": [
|
|
178
|
+
{
|
|
179
|
+
"name": "Risk-driven targeting",
|
|
180
|
+
"description": "The tests pin the behaviors whose silent breakage costs most — inclusive bounds, duration arithmetic, the invalid-range throw — following the risk map rather than the easiest paths."
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "Tests that bite",
|
|
184
|
+
"description": "Each test asserts real values, errors, and edge cases a wrong implementation would fail; no tautologies, and seeded mutations to the module are actually caught."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "Layout fidelity and honesty",
|
|
188
|
+
"description": "Tests follow the existing layout and style, the suite result comes from real runs, the module under test is untouched, and uncovered targets are deferred honestly."
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
"qualityFocus": [
|
|
193
|
+
"mutation-proof regression guards",
|
|
194
|
+
"risk-ranked coverage",
|
|
195
|
+
"enforced review of assertions"
|
|
196
|
+
]
|
|
197
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Counted tightening of seeded unsafe patterns",
|
|
4
|
+
"objective": "The craftbook drives a counted type-safety pass over a module with three seeded unsafe patterns and their real consequences: a loose-equality guard that lets 0 through, an implicit string-number concat corrupting a total, and a swallowed catch hiding data loss. Verified mechanically: the patterns are structurally gone, the three behavioral consequences are fixed by probes, the suite is green, and the fleet artifacts quote honest before/after counts.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"type-safety",
|
|
8
|
+
"tactical-fleet"
|
|
9
|
+
],
|
|
10
|
+
"prompt": "Use the Type-Safety Pass craftbook for this: src/expenses.js has unsafe patterns with real consequences - splitting across zero people returns Infinity, string amounts silently corrupt the running total, and corrupt imports vanish without a trace. The brief is in source/cleanup-brief.md. Tighten the module and fix those three consequences without breaking the pinned happy-path behavior.",
|
|
11
|
+
"setup": {
|
|
12
|
+
"projectName": "Expense Tracker",
|
|
13
|
+
"about": "A tiny expense-tracking module. Tests run with `npm run test` (node --test).",
|
|
14
|
+
"files": [
|
|
15
|
+
{
|
|
16
|
+
"path": "package.json",
|
|
17
|
+
"content": "{\n \"name\": \"expense-tracker\",\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/expenses.js",
|
|
21
|
+
"content": "const DEFAULT_CATEGORY = 'general';\n\nexport function splitEvenly(total, people) {\n if (people == null) throw new Error('people required');\n return Math.round((total / people) * 100) / 100;\n}\n\nexport function addExpense(report, entry) {\n report.total = report.total + entry.amount;\n report.entries.push({\n label: entry.label,\n amount: entry.amount,\n category: entry.category || DEFAULT_CATEGORY,\n });\n return report;\n}\n\nexport function importEntry(report, json) {\n try {\n const entry = JSON.parse(json);\n return addExpense(report, entry);\n } catch (err) {\n return report;\n }\n}\n"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "tests/expenses.test.mjs",
|
|
25
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { addExpense, importEntry, splitEvenly } from '../src/expenses.js';\n\ntest('splits evenly with rounding', () => {\n assert.equal(splitEvenly(100, 4), 25);\n assert.equal(splitEvenly(100, 3), 33.33);\n});\n\ntest('adds numeric expenses', () => {\n const report = { total: 0, entries: [] };\n addExpense(report, { label: 'lunch', amount: 12 });\n assert.equal(report.total, 12);\n assert.equal(report.entries.length, 1);\n});\n\ntest('imports a valid entry', () => {\n const report = { total: 0, entries: [] };\n importEntry(report, '{\"label\":\"bus\",\"amount\":3}');\n assert.equal(report.entries.length, 1);\n});\n"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": "source/cleanup-brief.md",
|
|
29
|
+
"content": "# Cleanup brief\n\nsrc/expenses.js has unsafe patterns with three consequences we can reproduce:\n\n1. `splitEvenly(100, 0)` returns `Infinity` - the loose `== null` guard lets `0` through. Splitting across zero people must throw, exactly like a missing count.\n2. Legacy JSON entries sometimes carry `amount` as a numeric string like `\"12.50\"`. `addExpense` then concatenates instead of adding and the running total silently becomes a string like `\"1012.50\"`. A string amount must be treated as the number it spells, and a total must always stay a number.\n3. `importEntry` swallows every parse error, so a corrupt import vanishes without a trace - we lost a day of expenses to this once. A corrupt import must throw, not return as if nothing happened.\n\nTighten the module: strict checks instead of loose equality, validate or normalize values at the boundary they cross, surface errors instead of swallowing them. Happy-path behavior pinned by the tests must not change. Do not silence anything to make a count fall.\n"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"path": "tests/verify-expenses.mjs",
|
|
33
|
+
"surface": "harness",
|
|
34
|
+
"content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { addExpense, importEntry, splitEvenly } from '../src/expenses.js';\n\n// 1) Structural: the seeded unsafe patterns are gone from the module.\nconst source = readFileSync(join(process.cwd(), 'src', 'expenses.js'), 'utf8');\nassert.ok(\n !/(^|[^=!<>])==[^=]|!=[^=]/.test(source),\n 'loose equality is still present in src/expenses.js',\n);\nassert.ok(\n !/catch[^{]*\\{\\s*\\}/.test(source),\n 'an empty catch still swallows errors in src/expenses.js',\n);\nassert.ok(\n !/@ts-ignore|@ts-expect-error|eslint-disable/.test(source),\n 'a suppression comment was introduced to move a count',\n);\nconsole.log('TYPE_SAFETY_PASS_ORACLE patterns gone');\n\n// 2) Behavior: the three declared consequences are fixed, happy path preserved.\nassert.equal(splitEvenly(100, 4), 25);\nassert.equal(splitEvenly(100, 3), 33.33);\nassert.throws(() => splitEvenly(100, 0), undefined, 'zero people must be rejected, not Infinity');\nassert.throws(() => splitEvenly(100, null));\nassert.throws(() => splitEvenly(100, undefined));\n\nconst stringAmounts = { total: 10, entries: [] };\naddExpense(stringAmounts, { label: 'taxi', amount: '12.50' });\nassert.equal(stringAmounts.total, 22.5, 'a string amount must be treated as the number it spells');\nassert.equal(typeof stringAmounts.total, 'number', 'the running total must stay a number');\n\nconst numeric = { total: 0, entries: [] };\naddExpense(numeric, { label: 'lunch', amount: 12 });\nassert.equal(numeric.total, 12);\n\nconst report = { total: 0, entries: [] };\nassert.throws(() => importEntry(report, 'not json {'), undefined, 'a corrupt import must throw, not vanish');\nimportEntry(report, '{\"label\":\"bus\",\"amount\":\"3.25\"}');\nassert.equal(report.total, 3.25);\nassert.equal(report.entries.length, 1);\nconsole.log('TYPE_SAFETY_PASS_ORACLE behavior ok');\n\n// 3) The whole suite is green after the pass (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 after the pass');\nconsole.log('TYPE_SAFETY_PASS_ORACLE suite green');\nconsole.log('TYPE_SAFETY_PASS_ORACLE done');\n"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"craftbookParams": {
|
|
38
|
+
"workPath": "tasks/eval",
|
|
39
|
+
"scope": "Tighten src/expenses.js: fix the loose-equality zero bug in splitEvenly, the string-amount concat bug in addExpense, and the swallowed catch in importEntry, per source/cleanup-brief.md."
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"success": {
|
|
43
|
+
"summary": "The seeded unsafe patterns are structurally gone, the three declared behavioral consequences are fixed (probes), the suite is green on a real run, and the fleet artifacts quote honest before/after counts gathered by the same method.",
|
|
44
|
+
"deliverables": [
|
|
45
|
+
{
|
|
46
|
+
"path": "tasks/eval/audit.md",
|
|
47
|
+
"kind": "markdown-notes",
|
|
48
|
+
"artifact": true,
|
|
49
|
+
"minBytes": 600,
|
|
50
|
+
"checks": [
|
|
51
|
+
{
|
|
52
|
+
"kind": "contains",
|
|
53
|
+
"file": "tasks/eval/audit.md",
|
|
54
|
+
"pattern": "^##\\s+Inventory[\\s\\S]*^##\\s+Targets[\\s\\S]*^##\\s+Guardrail",
|
|
55
|
+
"flags": "im",
|
|
56
|
+
"label": "audit sections in order"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"kind": "contains",
|
|
60
|
+
"file": "tasks/eval/audit.md",
|
|
61
|
+
"pattern": "^##\\s+Inventory[\\s\\S]*\\d",
|
|
62
|
+
"flags": "im",
|
|
63
|
+
"label": "inventory carries counts"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"kind": "citationsResolve",
|
|
67
|
+
"file": "tasks/eval/audit.md",
|
|
68
|
+
"minCitations": 2,
|
|
69
|
+
"artifact": true
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"path": "tasks/eval/change-notes.md",
|
|
75
|
+
"kind": "markdown-notes",
|
|
76
|
+
"artifact": true,
|
|
77
|
+
"minBytes": 600,
|
|
78
|
+
"checks": [
|
|
79
|
+
{
|
|
80
|
+
"kind": "contains",
|
|
81
|
+
"file": "tasks/eval/change-notes.md",
|
|
82
|
+
"pattern": "^##\\s+Patterns addressed[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Deviations",
|
|
83
|
+
"flags": "im",
|
|
84
|
+
"label": "change-notes sections in order"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"kind": "citationsResolve",
|
|
88
|
+
"file": "tasks/eval/change-notes.md",
|
|
89
|
+
"minCitations": 2,
|
|
90
|
+
"artifact": true
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "tasks/eval/verification.md",
|
|
96
|
+
"kind": "markdown-notes",
|
|
97
|
+
"artifact": true,
|
|
98
|
+
"minBytes": 400,
|
|
99
|
+
"checks": [
|
|
100
|
+
{
|
|
101
|
+
"kind": "contains",
|
|
102
|
+
"file": "tasks/eval/verification.md",
|
|
103
|
+
"pattern": "^##\\s+Before\\s*/\\s*after counts[\\s\\S]*^##\\s+Suite[\\s\\S]*^##\\s+Result",
|
|
104
|
+
"flags": "im",
|
|
105
|
+
"label": "verification sections in order"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"kind": "contains",
|
|
109
|
+
"file": "tasks/eval/verification.md",
|
|
110
|
+
"pattern": "^##\\s+Before\\s*/\\s*after counts[\\s\\S]*\\d",
|
|
111
|
+
"flags": "im",
|
|
112
|
+
"label": "before/after counts quoted"
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": "tasks/eval/review.md",
|
|
118
|
+
"kind": "markdown-report",
|
|
119
|
+
"artifact": true,
|
|
120
|
+
"minBytes": 400,
|
|
121
|
+
"checks": [
|
|
122
|
+
{
|
|
123
|
+
"kind": "contains",
|
|
124
|
+
"file": "tasks/eval/review.md",
|
|
125
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
126
|
+
"flags": "i",
|
|
127
|
+
"label": "explicit reviewer verdict"
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
"checks": [
|
|
133
|
+
{
|
|
134
|
+
"kind": "notContains",
|
|
135
|
+
"file": "src/expenses.js",
|
|
136
|
+
"pattern": "(^|[^=!<>])==[^=]|!=[^=]",
|
|
137
|
+
"label": "loose equality is gone from the module"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"kind": "notContains",
|
|
141
|
+
"file": "src/expenses.js",
|
|
142
|
+
"pattern": "catch[^{]*\\{\\s*\\}",
|
|
143
|
+
"label": "no empty catch swallows errors"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"kind": "notContains",
|
|
147
|
+
"file": "src/expenses.js",
|
|
148
|
+
"pattern": "@ts-ignore|@ts-expect-error|eslint-disable",
|
|
149
|
+
"label": "no suppression comment bought the improvement"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"kind": "sourceParses",
|
|
153
|
+
"file": "src/expenses.js"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"kind": "nodeScriptPasses",
|
|
157
|
+
"script": "tests/verify-expenses.mjs",
|
|
158
|
+
"timeoutMs": 60000,
|
|
159
|
+
"requiredOutput": [
|
|
160
|
+
{
|
|
161
|
+
"pattern": "TYPE_SAFETY_PASS_ORACLE patterns gone",
|
|
162
|
+
"label": "seeded unsafe patterns structurally gone"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"pattern": "TYPE_SAFETY_PASS_ORACLE behavior ok",
|
|
166
|
+
"label": "the three declared consequences are fixed"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"pattern": "TYPE_SAFETY_PASS_ORACLE suite green",
|
|
170
|
+
"label": "suite green after the pass"
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"taskNotes": {
|
|
176
|
+
"minBytes": 120,
|
|
177
|
+
"checks": [
|
|
178
|
+
{
|
|
179
|
+
"kind": "contains",
|
|
180
|
+
"file": "task-notes.md",
|
|
181
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
|
|
182
|
+
"flags": "i",
|
|
183
|
+
"label": "DONE note names the real test command"
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
"taskGraph": {
|
|
188
|
+
"requireCraftbookTask": true,
|
|
189
|
+
"requireTerminalStep": true
|
|
190
|
+
},
|
|
191
|
+
"unchangedFixtures": [
|
|
192
|
+
"source/cleanup-brief.md",
|
|
193
|
+
"package.json"
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
"rubric": {
|
|
197
|
+
"artifact": {
|
|
198
|
+
"path": "tasks/eval/verification.md",
|
|
199
|
+
"kind": "markdown"
|
|
200
|
+
},
|
|
201
|
+
"axes": [
|
|
202
|
+
{
|
|
203
|
+
"name": "Honest counting",
|
|
204
|
+
"description": "The audit counted real patterns with a stated, repeatable method, and verification re-counted with exactly that method, quoting before and after per pattern - no method swap, no adjectives standing in for counts."
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"name": "No suppression",
|
|
208
|
+
"description": "Every count fell because the code got stronger: strict checks, boundary validation, surfaced errors - never a deleted assertion, silenced error path, cast, or ignore-comment."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"name": "Consequence-fix discipline",
|
|
212
|
+
"description": "The three declared consequences were fixed and named in the notes, happy-path behavior stayed pinned and green with real receipts, and anything unverified is labeled honestly."
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
"qualityFocus": [
|
|
217
|
+
"counts with their method",
|
|
218
|
+
"no suppression-by-cast",
|
|
219
|
+
"enforced review loop"
|
|
220
|
+
]
|
|
221
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "UX change with before/after proof",
|
|
4
|
+
"objective": "The craftbook drives a described UX change on a small orders page: move the bottom-of-page search into the header next to the title with an exact requested placeholder, while the / keyboard shortcut and the list-filter handler keep working. Placement, placeholder, and surviving wiring are verified mechanically against the fixed markup.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"ux",
|
|
8
|
+
"frontend",
|
|
9
|
+
"tactical-fleet"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Use the Implement a UX Change craftbook: nobody finds the search on the Orderboard page because it sits at the very bottom. Move the search into the header next to the title, set its placeholder to 'Search orders…', and keep the / keyboard shortcut working. The full request is in source/change-request.md.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Orderboard",
|
|
14
|
+
"about": "A single-page order list for a small furniture shop: index.html with an inline script, plus styles.css. No build step and no test suite.",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "package.json",
|
|
18
|
+
"content": "{\n \"name\": \"orderboard\",\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>Orderboard</title>\n<link rel=\"stylesheet\" href=\"styles.css\">\n</head>\n<body>\n<header class=\"topbar\">\n <h1>Orderboard</h1>\n</header>\n<main>\n <ul id=\"orders\">\n <li>#1042 Walnut writing desk</li>\n <li>#1043 Oak bookshelf</li>\n <li>#1044 Cherry side table</li>\n <li>#1045 Maple bench</li>\n <li>#1046 Walnut picture frame</li>\n </ul>\n</main>\n<section class=\"search-row\">\n <input id=\"search\" type=\"search\" placeholder=\"Filter orders\">\n</section>\n<script>\nconst search = document.getElementById('search');\nsearch.addEventListener('input', () => {\n const q = search.value.toLowerCase();\n for (const item of document.querySelectorAll('#orders li')) {\n item.hidden = q !== '' && !item.textContent.toLowerCase().includes(q);\n }\n});\ndocument.addEventListener('keydown', (event) => {\n if (event.key === '/' && document.activeElement !== search) {\n event.preventDefault();\n search.focus();\n }\n});\n</script>\n</body>\n</html>\n"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "styles.css",
|
|
26
|
+
"content": "body { margin: 0; font-family: system-ui, sans-serif; color: #1c2430; background: #f5f6f8; }\n.topbar { display: flex; align-items: center; gap: 1rem; padding: 0.75rem 1.25rem; background: #223047; color: #fff; }\n.topbar h1 { margin: 0; font-size: 1.2rem; }\nmain { max-width: 40rem; padding: 1rem 1.25rem; }\n#orders { list-style: none; padding: 0; }\n#orders li { padding: 0.5rem 0.25rem; border-bottom: 1px solid #dde1e8; }\n.search-row { padding: 1rem 1.25rem; }\n#search { padding: 0.4rem 0.6rem; width: 16rem; }\n"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"path": "source/change-request.md",
|
|
30
|
+
"content": "# Change request\n\nFrom the product owner: \"Nobody finds the search — it sits at the very bottom of the page. Move the search into the header, next to the Orderboard title. Set its placeholder to 'Search orders…'. The / keyboard shortcut people already use must keep working, and typing in the box must still filter the list.\"\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "tests/verify-ux-update.mjs",
|
|
34
|
+
"surface": "harness",
|
|
35
|
+
"content": "import assert from 'node:assert/strict';\nimport { readFileSync } from 'node:fs';\n\nconst html = readFileSync('index.html', 'utf8');\nlet code = html;\nfor (const m of html.matchAll(/<script\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"']/gi)) {\n try { code += readFileSync(m[1], 'utf8'); } catch {}\n}\n\n// 1) Exactly one search input, and it lives inside the header, next to the title.\nconst inputs = [...html.matchAll(/<input\\b[^>]*>/gi)].map((m) => m[0]).filter((t) => /\\bid\\s*=\\s*[\"']search[\"']/i.test(t));\nassert.equal(inputs.length, 1, 'exactly one #search input exists');\nconst header = html.match(/<header\\b[^>]*>([\\s\\S]*?)<\\/header>/i);\nassert.ok(header, 'the header still exists');\nassert.ok(/\\bid\\s*=\\s*[\"']search[\"']/i.test(header[1]), 'the search input lives inside the header');\nassert.ok(/<h1\\b[^>]*>[^<]*Orderboard/i.test(header[1]), 'the Orderboard title is still in the header');\nconsole.log('UXUPDATE_ORACLE placement ok');\n\n// 2) The placeholder is exactly as requested.\nconst ph = inputs[0].match(/\\bplaceholder\\s*=\\s*[\"']([^\"']*)[\"']/i);\nassert.ok(ph, 'the search input has a placeholder');\nassert.equal(ph[1], 'Search orders…', 'placeholder is exactly \"Search orders…\"');\nconsole.log('UXUPDATE_ORACLE placeholder ok');\n\n// 3) The / shortcut still targets and focuses the search input.\nassert.ok(/['\"]\\/['\"]/.test(code), 'the / key hook survives');\nassert.ok(/getElementById\\(\\s*['\"]search['\"]\\s*\\)|querySelector\\(\\s*['\"]#search['\"]\\s*\\)/.test(code), 'the script still targets #search');\nassert.ok(/\\.focus\\s*\\(\\s*\\)/.test(code), 'the shortcut still focuses the search input');\nconsole.log('UXUPDATE_ORACLE shortcut ok');\n\n// 4) The list-filter behavior is still wired.\nassert.ok(/addEventListener\\s*\\(\\s*['\"]input['\"]/.test(code) || /\\boninput\\s*=/i.test(html), 'the input filter handler is still wired');\nassert.ok(/#orders/.test(code), 'the filter still targets the order list');\nconsole.log('UXUPDATE_ORACLE filter ok');\nconsole.log('UXUPDATE_ORACLE done');\n"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"craftbookParams": {
|
|
39
|
+
"workPath": "tasks/eval",
|
|
40
|
+
"scope": "Move the search into the header next to the Orderboard title, set its placeholder to 'Search orders…', and keep the / keyboard shortcut and the list filtering working; see source/change-request.md."
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"success": {
|
|
44
|
+
"summary": "The search input sits inside the header next to the title with the exact requested placeholder, the old bottom-of-page placement is gone, and the / shortcut plus the filter handler still work — with every fleet artifact present and honestly cited.",
|
|
45
|
+
"deliverables": [
|
|
46
|
+
{
|
|
47
|
+
"path": "tasks/eval/before.md",
|
|
48
|
+
"kind": "markdown-notes",
|
|
49
|
+
"artifact": true,
|
|
50
|
+
"minBytes": 500,
|
|
51
|
+
"checks": [
|
|
52
|
+
{
|
|
53
|
+
"kind": "contains",
|
|
54
|
+
"file": "tasks/eval/before.md",
|
|
55
|
+
"pattern": "^##\\s+Request[\\s\\S]*^##\\s+Current behavior[\\s\\S]*^##\\s+Surfaces involved",
|
|
56
|
+
"flags": "im",
|
|
57
|
+
"label": "before sections in order"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"kind": "citationsResolve",
|
|
61
|
+
"file": "tasks/eval/before.md",
|
|
62
|
+
"minCitations": 2,
|
|
63
|
+
"artifact": true
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"kind": "contains",
|
|
67
|
+
"file": "tasks/eval/before.md",
|
|
68
|
+
"pattern": "index\\.html",
|
|
69
|
+
"label": "names the real page"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"path": "tasks/eval/fix-notes.md",
|
|
75
|
+
"kind": "markdown-notes",
|
|
76
|
+
"artifact": true,
|
|
77
|
+
"minBytes": 700,
|
|
78
|
+
"checks": [
|
|
79
|
+
{
|
|
80
|
+
"kind": "contains",
|
|
81
|
+
"file": "tasks/eval/fix-notes.md",
|
|
82
|
+
"pattern": "^##\\s+Problem[\\s\\S]*^##\\s+Change[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Consistency notes[\\s\\S]*^##\\s+Risk[\\s\\S]*^##\\s+How to verify",
|
|
83
|
+
"flags": "im",
|
|
84
|
+
"label": "fix-notes sections in order"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"kind": "citationsResolve",
|
|
88
|
+
"file": "tasks/eval/fix-notes.md",
|
|
89
|
+
"minCitations": 2,
|
|
90
|
+
"artifact": true
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "tasks/eval/validation.md",
|
|
96
|
+
"kind": "markdown-notes",
|
|
97
|
+
"artifact": true,
|
|
98
|
+
"minBytes": 500,
|
|
99
|
+
"checks": [
|
|
100
|
+
{
|
|
101
|
+
"kind": "contains",
|
|
102
|
+
"file": "tasks/eval/validation.md",
|
|
103
|
+
"pattern": "^##\\s+Before\\s*/\\s*after[\\s\\S]*^##\\s+What was exercised[\\s\\S]*^##\\s+Result",
|
|
104
|
+
"flags": "im",
|
|
105
|
+
"label": "validation sections in order"
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"path": "tasks/eval/review.md",
|
|
111
|
+
"kind": "markdown-report",
|
|
112
|
+
"artifact": true,
|
|
113
|
+
"minBytes": 400,
|
|
114
|
+
"checks": [
|
|
115
|
+
{
|
|
116
|
+
"kind": "contains",
|
|
117
|
+
"file": "tasks/eval/review.md",
|
|
118
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
119
|
+
"flags": "i",
|
|
120
|
+
"label": "explicit reviewer verdict"
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
"checks": [
|
|
126
|
+
{
|
|
127
|
+
"kind": "notContains",
|
|
128
|
+
"file": "index.html",
|
|
129
|
+
"pattern": "placeholder=[\"']Filter orders[\"']",
|
|
130
|
+
"label": "the old bottom-of-page search placeholder is gone"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"kind": "htmlLint",
|
|
134
|
+
"file": "index.html"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"kind": "nodeScriptPasses",
|
|
138
|
+
"script": "tests/verify-ux-update.mjs",
|
|
139
|
+
"timeoutMs": 60000,
|
|
140
|
+
"requiredOutput": [
|
|
141
|
+
{
|
|
142
|
+
"pattern": "UXUPDATE_ORACLE placement ok",
|
|
143
|
+
"label": "search moved into the header next to the title"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"pattern": "UXUPDATE_ORACLE placeholder ok",
|
|
147
|
+
"label": "placeholder is exactly as requested"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"pattern": "UXUPDATE_ORACLE shortcut ok",
|
|
151
|
+
"label": "the / shortcut still focuses the search"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"pattern": "UXUPDATE_ORACLE filter ok",
|
|
155
|
+
"label": "the list filter is still wired"
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"taskNotes": {
|
|
161
|
+
"minBytes": 120,
|
|
162
|
+
"checks": [
|
|
163
|
+
{
|
|
164
|
+
"kind": "contains",
|
|
165
|
+
"file": "task-notes.md",
|
|
166
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(validation\\.md|fix-notes\\.md|before\\.md)",
|
|
167
|
+
"flags": "i",
|
|
168
|
+
"label": "DONE note names the deliverables"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"taskGraph": {
|
|
173
|
+
"requireCraftbookTask": true,
|
|
174
|
+
"requireTerminalStep": true
|
|
175
|
+
},
|
|
176
|
+
"unchangedFixtures": [
|
|
177
|
+
"package.json",
|
|
178
|
+
"source/change-request.md"
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"rubric": {
|
|
182
|
+
"artifact": {
|
|
183
|
+
"path": "tasks/eval/fix-notes.md",
|
|
184
|
+
"kind": "markdown"
|
|
185
|
+
},
|
|
186
|
+
"axes": [
|
|
187
|
+
{
|
|
188
|
+
"name": "Request fidelity",
|
|
189
|
+
"description": "The delivered change is what was asked, judged as a user would: search in the header next to the title, the exact placeholder, nothing extra smuggled in."
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "Convention respect",
|
|
193
|
+
"description": "The edit reuses the page's existing structure, naming, and style patterns — the topbar's own layout — rather than inventing a new one-off style."
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "Behavior preservation with honest verification",
|
|
197
|
+
"description": "The / shortcut and the input filter still work after the move, and validation separates what was inspected in the code from what was actually exercised."
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
"qualityFocus": [
|
|
202
|
+
"before/after grounded in real markup",
|
|
203
|
+
"existing behaviors preserved",
|
|
204
|
+
"enforced review loop"
|
|
205
|
+
]
|
|
206
|
+
}
|