@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,241 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Behavior-preserving extraction of duplicated logic",
|
|
4
|
+
"objective": "The craftbook drives a disciplined refactor of copy-pasted name-normalization logic: a green baseline recorded before anything moves, reversible stages with the suite green throughout, a re-measured duplication target, and an enforced review — verified mechanically via a reference matrix across both call sites, a duplication count across src/, and a green-suite run.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"refactor",
|
|
8
|
+
"tactical-fleet"
|
|
9
|
+
],
|
|
10
|
+
"prompt": "Use the Behavior-Preserving Refactor craftbook for this: the same name-normalization logic is copy-pasted in src/format-name.js and src/report.js, and the copies have drifted once already. The brief is in source/refactor-brief.md. Extract the shared logic into a new src/normalize-name.js used by both files, without changing behavior.",
|
|
11
|
+
"setup": {
|
|
12
|
+
"projectName": "Crewlog",
|
|
13
|
+
"about": "A tiny crew-hours logging module. Tests run with `npm run test` (node --test).",
|
|
14
|
+
"files": [
|
|
15
|
+
{
|
|
16
|
+
"path": "package.json",
|
|
17
|
+
"content": "{\n \"name\": \"crewlog\",\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/format-name.js",
|
|
21
|
+
"content": "export function formatName(raw) {\n const words = String(raw).trim().split(/\\s+/);\n const fixed = [];\n for (const word of words) {\n fixed.push(word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\n }\n return fixed.join(' ');\n}\n"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "src/report.js",
|
|
25
|
+
"content": "function titleCaseName(raw) {\n const words = String(raw).trim().split(/\\s+/);\n const fixed = [];\n for (const word of words) {\n fixed.push(word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());\n }\n return fixed.join(' ');\n}\n\nexport function reportLine(entry) {\n return titleCaseName(entry.name) + ': ' + entry.hours + 'h';\n}\n\nexport function reportSummary(entries) {\n return entries.map((entry) => reportLine(entry)).join('\\n');\n}\n"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": "tests/format.test.mjs",
|
|
29
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { formatName } from '../src/format-name.js';\n\ntest('formats a messy name', () => {\n assert.equal(formatName(' ada lovelace '), 'Ada Lovelace');\n});\n"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"path": "tests/report.test.mjs",
|
|
33
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { reportLine } from '../src/report.js';\n\ntest('report line normalizes the name', () => {\n assert.equal(reportLine({ name: 'grace hopper', hours: 2 }), 'Grace Hopper: 2h');\n});\n"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"path": "source/refactor-brief.md",
|
|
37
|
+
"content": "# Refactor brief\n\nThe same name-normalization logic (trim, collapse inner whitespace, title-case each word) is copy-pasted in two places:\n\n- src/format-name.js - `formatName`, used by the profile screens\n- src/report.js - a private `titleCaseName` helper feeding `reportLine`\n\nThe copies drifted once before and had to be manually re-synced. Extract the shared logic into a NEW `src/normalize-name.js` module used by both files, WITHOUT changing behavior. Every output must stay byte-for-byte identical, including edge cases: extra inner spaces, ALL-CAPS input, single letters, and the empty string. Public exports must survive unchanged: `formatName`, `reportLine`, and `reportSummary` keep their names and signatures.\n"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"path": "tests/verify-refactor.mjs",
|
|
41
|
+
"surface": "harness",
|
|
42
|
+
"content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { formatName } from '../src/format-name.js';\nimport { reportLine, reportSummary } from '../src/report.js';\n\n// 1) Behavior: a reference matrix across BOTH call sites, quirks included.\nconst matrix = [\n [' ada lovelace ', 'Ada Lovelace'],\n ['GRACE HOPPER', 'Grace Hopper'],\n ['katherine g. johnson', 'Katherine G. Johnson'],\n ['a', 'A'],\n ['', ''],\n];\nfor (const [input, expected] of matrix) {\n assert.equal(formatName(input), expected, 'formatName(' + JSON.stringify(input) + ')');\n}\nassert.equal(reportLine({ name: ' grace HOPPER ', hours: 4 }), 'Grace Hopper: 4h');\nassert.equal(reportLine({ name: 'ada lovelace', hours: 2 }), 'Ada Lovelace: 2h');\nassert.equal(\n reportSummary([\n { name: 'ADA LOVELACE', hours: 1 },\n { name: ' mary jackson ', hours: 3 },\n ]),\n 'Ada Lovelace: 1h\\nMary Jackson: 3h',\n);\nconsole.log('REFACTOR_MODULE_ORACLE behavior ok');\n\n// 2) Deduplication: the title-case implementation exists at most once\n// across src/ - two surviving copies mean the extraction did not happen.\nconst root = process.cwd();\nfunction countMarker(relDir) {\n let count = 0;\n for (const entry of readdirSync(join(root, relDir), { withFileTypes: true })) {\n const relPath = relDir + '/' + entry.name;\n if (entry.isDirectory()) {\n count += countMarker(relPath);\n } else if (/\\.(js|mjs|cjs|ts)$/.test(entry.name)) {\n const text = readFileSync(join(root, relPath), 'utf8');\n count += (text.match(/toUpperCase/g) ?? []).length;\n }\n }\n return count;\n}\nconst occurrences = countMarker('src');\nassert.ok(\n occurrences <= 1,\n 'the title-case implementation appears ' + occurrences + ' times across src/ - the duplication was not extracted to one shared place',\n);\nconsole.log('REFACTOR_MODULE_ORACLE dedupe ok');\n\n// 3) The whole suite is green on the refactored tree (real run).\nfunction runSuite(cwd) {\n try {\n execFileSync(process.execPath, ['--test'], { cwd, stdio: 'pipe', timeout: 30000 });\n return 0;\n } catch (err) {\n return typeof err.status === 'number' ? err.status : 1;\n }\n}\nassert.equal(runSuite(root), 0, 'the suite must be green on the refactored tree');\nconsole.log('REFACTOR_MODULE_ORACLE suite green');\nconsole.log('REFACTOR_MODULE_ORACLE done');\n"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"craftbookParams": {
|
|
46
|
+
"workPath": "tasks/eval",
|
|
47
|
+
"scope": "Extract the duplicated name normalization in src/format-name.js and src/report.js into a shared src/normalize-name.js used by both, without changing behavior; see source/refactor-brief.md."
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"success": {
|
|
51
|
+
"summary": "The duplicated normalization lives in exactly one place, both call sites behave byte-for-byte as before (reference matrix), the suite is green on a real run, and every fleet artifact exists with honest citations.",
|
|
52
|
+
"deliverables": [
|
|
53
|
+
{
|
|
54
|
+
"path": "tasks/eval/baseline.md",
|
|
55
|
+
"kind": "markdown-notes",
|
|
56
|
+
"artifact": true,
|
|
57
|
+
"minBytes": 500,
|
|
58
|
+
"checks": [
|
|
59
|
+
{
|
|
60
|
+
"kind": "contains",
|
|
61
|
+
"file": "tasks/eval/baseline.md",
|
|
62
|
+
"pattern": "^##\\s+Current behavior[\\s\\S]*^##\\s+Measurements[\\s\\S]*^##\\s+Guardrail",
|
|
63
|
+
"flags": "im",
|
|
64
|
+
"label": "baseline sections in order"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"kind": "citationsResolve",
|
|
68
|
+
"file": "tasks/eval/baseline.md",
|
|
69
|
+
"minCitations": 2,
|
|
70
|
+
"artifact": true
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"path": "tasks/eval/plan.md",
|
|
76
|
+
"kind": "markdown-notes",
|
|
77
|
+
"artifact": true,
|
|
78
|
+
"minBytes": 500,
|
|
79
|
+
"checks": [
|
|
80
|
+
{
|
|
81
|
+
"kind": "contains",
|
|
82
|
+
"file": "tasks/eval/plan.md",
|
|
83
|
+
"pattern": "^##\\s+Target[\\s\\S]*^##\\s+Stages[\\s\\S]*^##\\s+Acceptance criteria",
|
|
84
|
+
"flags": "im",
|
|
85
|
+
"label": "plan sections in order"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"kind": "citationsResolve",
|
|
89
|
+
"file": "tasks/eval/plan.md",
|
|
90
|
+
"minCitations": 2,
|
|
91
|
+
"artifact": true
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"path": "tasks/eval/change-notes.md",
|
|
97
|
+
"kind": "markdown-notes",
|
|
98
|
+
"artifact": true,
|
|
99
|
+
"minBytes": 600,
|
|
100
|
+
"checks": [
|
|
101
|
+
{
|
|
102
|
+
"kind": "contains",
|
|
103
|
+
"file": "tasks/eval/change-notes.md",
|
|
104
|
+
"pattern": "^##\\s+Stages executed[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Deviations from plan",
|
|
105
|
+
"flags": "im",
|
|
106
|
+
"label": "change-notes sections in order"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"kind": "citationsResolve",
|
|
110
|
+
"file": "tasks/eval/change-notes.md",
|
|
111
|
+
"minCitations": 2,
|
|
112
|
+
"artifact": true
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": "tasks/eval/verification.md",
|
|
118
|
+
"kind": "markdown-notes",
|
|
119
|
+
"artifact": true,
|
|
120
|
+
"minBytes": 400,
|
|
121
|
+
"checks": [
|
|
122
|
+
{
|
|
123
|
+
"kind": "contains",
|
|
124
|
+
"file": "tasks/eval/verification.md",
|
|
125
|
+
"pattern": "^##\\s+Before\\s*/\\s*after[\\s\\S]*^##\\s+Suite[\\s\\S]*^##\\s+Result",
|
|
126
|
+
"flags": "im",
|
|
127
|
+
"label": "verification sections in order"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"kind": "contains",
|
|
131
|
+
"file": "tasks/eval/verification.md",
|
|
132
|
+
"pattern": "^##\\s+Before\\s*/\\s*after[\\s\\S]*\\d",
|
|
133
|
+
"flags": "im",
|
|
134
|
+
"label": "before/after figures quoted"
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"path": "tasks/eval/review.md",
|
|
140
|
+
"kind": "markdown-report",
|
|
141
|
+
"artifact": true,
|
|
142
|
+
"minBytes": 400,
|
|
143
|
+
"checks": [
|
|
144
|
+
{
|
|
145
|
+
"kind": "contains",
|
|
146
|
+
"file": "tasks/eval/review.md",
|
|
147
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
148
|
+
"flags": "i",
|
|
149
|
+
"label": "explicit reviewer verdict"
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"checks": [
|
|
155
|
+
{
|
|
156
|
+
"kind": "notContains",
|
|
157
|
+
"file": "src/format-name.js",
|
|
158
|
+
"pattern": "toUpperCase",
|
|
159
|
+
"label": "format-name.js no longer carries its own title-case copy"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"kind": "notContains",
|
|
163
|
+
"file": "src/report.js",
|
|
164
|
+
"pattern": "toUpperCase",
|
|
165
|
+
"label": "report.js no longer carries its own title-case copy"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"kind": "sourceParses",
|
|
169
|
+
"file": "src/format-name.js"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"kind": "sourceParses",
|
|
173
|
+
"file": "src/report.js"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"kind": "nodeScriptPasses",
|
|
177
|
+
"script": "tests/verify-refactor.mjs",
|
|
178
|
+
"timeoutMs": 60000,
|
|
179
|
+
"requiredOutput": [
|
|
180
|
+
{
|
|
181
|
+
"pattern": "REFACTOR_MODULE_ORACLE behavior ok",
|
|
182
|
+
"label": "both call sites match the reference matrix"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"pattern": "REFACTOR_MODULE_ORACLE dedupe ok",
|
|
186
|
+
"label": "the implementation exists at most once across src/"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"pattern": "REFACTOR_MODULE_ORACLE suite green",
|
|
190
|
+
"label": "suite green on the refactored tree"
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
"taskNotes": {
|
|
196
|
+
"minBytes": 120,
|
|
197
|
+
"checks": [
|
|
198
|
+
{
|
|
199
|
+
"kind": "contains",
|
|
200
|
+
"file": "task-notes.md",
|
|
201
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
|
|
202
|
+
"flags": "i",
|
|
203
|
+
"label": "DONE note names the real test command"
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
"taskGraph": {
|
|
208
|
+
"requireCraftbookTask": true,
|
|
209
|
+
"requireTerminalStep": true
|
|
210
|
+
},
|
|
211
|
+
"unchangedFixtures": [
|
|
212
|
+
"source/refactor-brief.md",
|
|
213
|
+
"package.json"
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
"rubric": {
|
|
217
|
+
"artifact": {
|
|
218
|
+
"path": "tasks/eval/change-notes.md",
|
|
219
|
+
"kind": "markdown"
|
|
220
|
+
},
|
|
221
|
+
"axes": [
|
|
222
|
+
{
|
|
223
|
+
"name": "Guardrail-first discipline",
|
|
224
|
+
"description": "The suite was genuinely run and recorded green before any restructuring, characterization coverage was considered honestly, and the baseline counted the duplication with a stated method."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "Reversible-stage execution",
|
|
228
|
+
"description": "The restructure happened in small planned stages at the real sites, with the suite kept green between stages and deviations recorded honestly rather than papered over."
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"name": "Genuine deduplication",
|
|
232
|
+
"description": "One shared implementation remains, both call sites use it, public exports survived unchanged, and no behavior change was smuggled in under cover of the refactor."
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
"qualityFocus": [
|
|
237
|
+
"green-before/green-after receipts",
|
|
238
|
+
"same-method re-measurement",
|
|
239
|
+
"enforced review loop"
|
|
240
|
+
]
|
|
241
|
+
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"title": "Expand/contract data migration with no record stranded",
|
|
4
|
+
"objective": "The craftbook drives an expand/contract migration of a JSON user store from a flat name field to a nested profile shape: a plan grounded in the real files, accessors changed at their real sites with the suite green between stages, the data transformed with every value surviving exactly, and the old shape fully retired - verified mechanically, including a pure-nested-record probe proving the dual-read did not linger.",
|
|
5
|
+
"tags": [
|
|
6
|
+
"code",
|
|
7
|
+
"schema-migration",
|
|
8
|
+
"expand-contract",
|
|
9
|
+
"tactical-fleet"
|
|
10
|
+
],
|
|
11
|
+
"prompt": "Use the Schema / Type Migration craftbook for this: migrate our user records from the flat name field to the nested profile shape described in source/migration-brief.md. No record may be lost, the accessors in src/users.js must keep working at every stage, and when it is done nothing may read the flat field any more.",
|
|
12
|
+
"setup": {
|
|
13
|
+
"projectName": "Crew Roster",
|
|
14
|
+
"about": "A tiny user-roster module backed by a JSON data file. Tests run with `npm run test` (node --test).",
|
|
15
|
+
"files": [
|
|
16
|
+
{
|
|
17
|
+
"path": "package.json",
|
|
18
|
+
"content": "{\n \"name\": \"crew-roster\",\n \"private\": true,\n \"version\": \"1.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"node --test\"\n }\n}\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "data/users.json",
|
|
22
|
+
"content": "[\n { \"id\": 1, \"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\" },\n { \"id\": 2, \"name\": \"Grace Hopper\", \"email\": \"grace@example.com\" },\n { \"id\": 3, \"name\": \"Annie Easley\", \"email\": \"annie@example.com\" }\n]\n"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "src/users.js",
|
|
26
|
+
"content": "import { readFileSync } from 'node:fs';\n\nconst DB_URL = new URL('../data/users.json', import.meta.url);\n\nexport function loadUsers() {\n return JSON.parse(readFileSync(DB_URL, 'utf8'));\n}\n\nexport function fullName(user) {\n return user.name;\n}\n\nexport function byFullName(users, wanted) {\n return users.find((user) => user.name === wanted);\n}\n"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"path": "tests/users.test.mjs",
|
|
30
|
+
"content": "import assert from 'node:assert/strict';\nimport { test } from 'node:test';\nimport { byFullName, fullName, loadUsers } from '../src/users.js';\n\ntest('loads every user record', () => {\n assert.equal(loadUsers().length, 3);\n});\n\ntest('fullName renders the display name', () => {\n assert.deepEqual(loadUsers().map(fullName), [\n 'Ada Lovelace',\n 'Grace Hopper',\n 'Annie Easley',\n ]);\n});\n\ntest('byFullName finds a user by display name', () => {\n assert.equal(byFullName(loadUsers(), 'Grace Hopper').email, 'grace@example.com');\n});\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "source/migration-brief.md",
|
|
34
|
+
"content": "# Migration brief: nested profile shape\n\nWe sort and filter by last name now, so the flat `name` field has to go.\n\nCurrent record shape in `data/users.json`:\n\n { \"id\": 1, \"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\" }\n\nTarget record shape:\n\n { \"id\": 1, \"profile\": { \"first\": \"Ada\", \"last\": \"Lovelace\" }, \"email\": \"ada@example.com\" }\n\nRules:\n\n- Every existing record must survive the migration exactly - same people, same\n emails, names split on the single space between first and last name.\n- The accessors in `src/users.js` must keep working for their callers at every\n stage: `fullName` and `byFullName` keep returning the same display names as\n today.\n- When the migration is done, nothing reads the flat `name` field any more.\n"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"path": "tests/verify-migration.mjs",
|
|
38
|
+
"surface": "harness",
|
|
39
|
+
"content": "import assert from 'node:assert/strict';\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nconst root = process.cwd();\n\n// 1) The data moved to the target shape with no record stranded.\nconst records = JSON.parse(readFileSync(join(root, 'data/users.json'), 'utf8'));\nassert.ok(Array.isArray(records), 'data/users.json must stay a JSON array');\nassert.equal(records.length, 3, 'all three records must survive the migration');\nconst expected = new Map([\n ['ada@example.com', ['Ada', 'Lovelace']],\n ['grace@example.com', ['Grace', 'Hopper']],\n ['annie@example.com', ['Annie', 'Easley']],\n]);\nfor (const record of records) {\n assert.ok(record && typeof record === 'object', 'each record must stay an object');\n assert.ok(!('name' in record), `record ${record.id} still carries the flat name field`);\n const want = expected.get(record.email);\n assert.ok(want, `record ${record.id} lost or changed its email`);\n assert.equal(record.profile?.first, want[0], `record ${record.id} must keep its first name exactly`);\n assert.equal(record.profile?.last, want[1], `record ${record.id} must keep its last name exactly`);\n}\nconsole.log('SCHEMAMIG_ORACLE data intact');\n\n// 2) The accessors read the new shape - a pure nested record, no flat fallback.\nconst users = await import(pathToFileURL(join(root, 'src/users.js')).href);\nassert.equal(\n users.fullName({ profile: { first: 'Test', last: 'User' } }),\n 'Test User',\n 'fullName must read profile.first and profile.last',\n);\nassert.equal(\n users.byFullName([{ profile: { first: 'Grace', last: 'Hopper' }, email: 'x' }], 'Grace Hopper')?.email,\n 'x',\n 'byFullName must match display names on the new shape',\n);\nconsole.log('SCHEMAMIG_ORACLE accessors migrated');\n\n// 3) Contract landed: no flat-shape read remains in the accessor module.\nconst accessorSource = readFileSync(join(root, 'src/users.js'), 'utf8');\nassert.ok(\n !/\\.name\\b|\\[[\"']name[\"']\\]/.test(accessorSource),\n 'src/users.js still reads the flat name field',\n);\nconsole.log('SCHEMAMIG_ORACLE contract complete');\n\n// 4) The suite is green on the migrated tree, and the seeded test file survives.\nreadFileSync(join(root, 'tests/users.test.mjs'));\nfunction runSuite(cwd) {\n try {\n execFileSync(process.execPath, ['--test'], { cwd, stdio: 'pipe', timeout: 30000 });\n return 0;\n } catch (err) {\n return typeof err.status === 'number' ? err.status : 1;\n }\n}\nassert.equal(runSuite(root), 0, 'the suite must be green after the migration');\nconsole.log('SCHEMAMIG_ORACLE suite green');\nconsole.log('SCHEMAMIG_ORACLE done');\n"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"craftbookParams": {
|
|
43
|
+
"workPath": "tasks/eval",
|
|
44
|
+
"scope": "Migrate data/users.json and src/users.js from the flat name field to profile.first/profile.last per source/migration-brief.md, with no record loss and reads working at every stage."
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"success": {
|
|
48
|
+
"summary": "Every record reaches the nested profile shape with its values intact, the accessors read the new shape with the dual-read retired, the flat field is gone from data and code, the suite is green, and every fleet artifact exists with honest receipts.",
|
|
49
|
+
"deliverables": [
|
|
50
|
+
{
|
|
51
|
+
"path": "tasks/eval/migration-plan.md",
|
|
52
|
+
"kind": "markdown-notes",
|
|
53
|
+
"artifact": true,
|
|
54
|
+
"minBytes": 700,
|
|
55
|
+
"checks": [
|
|
56
|
+
{
|
|
57
|
+
"kind": "contains",
|
|
58
|
+
"file": "tasks/eval/migration-plan.md",
|
|
59
|
+
"pattern": "^##\\s+Current shape[\\s\\S]*^##\\s+Target shape[\\s\\S]*^##\\s+Stages[\\s\\S]*^##\\s+Data safety[\\s\\S]*^##\\s+Rollback per stage",
|
|
60
|
+
"flags": "im",
|
|
61
|
+
"label": "plan sections in order"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"kind": "contains",
|
|
65
|
+
"file": "tasks/eval/migration-plan.md",
|
|
66
|
+
"pattern": "data/users\\.json",
|
|
67
|
+
"label": "names the real data file"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"kind": "citationsResolve",
|
|
71
|
+
"file": "tasks/eval/migration-plan.md",
|
|
72
|
+
"minCitations": 2,
|
|
73
|
+
"artifact": true
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"path": "tasks/eval/change-notes.md",
|
|
79
|
+
"kind": "markdown-notes",
|
|
80
|
+
"artifact": true,
|
|
81
|
+
"minBytes": 700,
|
|
82
|
+
"checks": [
|
|
83
|
+
{
|
|
84
|
+
"kind": "contains",
|
|
85
|
+
"file": "tasks/eval/change-notes.md",
|
|
86
|
+
"pattern": "^##\\s+Stages executed[\\s\\S]*^##\\s+Files touched[\\s\\S]*^##\\s+Data transformed[\\s\\S]*^##\\s+Deviations",
|
|
87
|
+
"flags": "im",
|
|
88
|
+
"label": "change-notes sections in order"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"kind": "citationsResolve",
|
|
92
|
+
"file": "tasks/eval/change-notes.md",
|
|
93
|
+
"minCitations": 2,
|
|
94
|
+
"artifact": true
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "tasks/eval/verification.md",
|
|
100
|
+
"kind": "markdown-notes",
|
|
101
|
+
"artifact": true,
|
|
102
|
+
"minBytes": 500,
|
|
103
|
+
"checks": [
|
|
104
|
+
{
|
|
105
|
+
"kind": "contains",
|
|
106
|
+
"file": "tasks/eval/verification.md",
|
|
107
|
+
"pattern": "^##\\s+Old shape check[\\s\\S]*^##\\s+Data integrity[\\s\\S]*^##\\s+Suite[\\s\\S]*^##\\s+Result",
|
|
108
|
+
"flags": "im",
|
|
109
|
+
"label": "verification sections in order"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"path": "tasks/eval/review.md",
|
|
115
|
+
"kind": "markdown-report",
|
|
116
|
+
"artifact": true,
|
|
117
|
+
"minBytes": 400,
|
|
118
|
+
"checks": [
|
|
119
|
+
{
|
|
120
|
+
"kind": "contains",
|
|
121
|
+
"file": "tasks/eval/review.md",
|
|
122
|
+
"pattern": "Verdict:\\s*(?:PASS|REVISE)",
|
|
123
|
+
"flags": "i",
|
|
124
|
+
"label": "explicit reviewer verdict"
|
|
125
|
+
}
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"checks": [
|
|
130
|
+
{
|
|
131
|
+
"kind": "notContains",
|
|
132
|
+
"file": "data/users.json",
|
|
133
|
+
"pattern": "\"name\"\\s*:",
|
|
134
|
+
"label": "the flat name field is gone from the data"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"kind": "notContains",
|
|
138
|
+
"file": "src/users.js",
|
|
139
|
+
"pattern": "\\.name\\b|\\[[\"']name[\"']\\]",
|
|
140
|
+
"label": "no flat-shape read remains in the accessors"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"kind": "sourceParses",
|
|
144
|
+
"file": "src/users.js"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"kind": "sniff",
|
|
148
|
+
"file": "data/users.json",
|
|
149
|
+
"sniff": "json-valid"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"kind": "nodeRuns",
|
|
153
|
+
"file": "tests/users.test.mjs"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"kind": "nodeScriptPasses",
|
|
157
|
+
"script": "tests/verify-migration.mjs",
|
|
158
|
+
"timeoutMs": 60000,
|
|
159
|
+
"requiredOutput": [
|
|
160
|
+
{
|
|
161
|
+
"pattern": "SCHEMAMIG_ORACLE data intact",
|
|
162
|
+
"label": "every record migrated with values intact"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"pattern": "SCHEMAMIG_ORACLE accessors migrated",
|
|
166
|
+
"label": "accessors read the new shape"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"pattern": "SCHEMAMIG_ORACLE contract complete",
|
|
170
|
+
"label": "the dual-read retired with the old shape"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"pattern": "SCHEMAMIG_ORACLE suite green",
|
|
174
|
+
"label": "suite green on the migrated tree"
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
],
|
|
179
|
+
"taskNotes": {
|
|
180
|
+
"minBytes": 120,
|
|
181
|
+
"checks": [
|
|
182
|
+
{
|
|
183
|
+
"kind": "contains",
|
|
184
|
+
"file": "task-notes.md",
|
|
185
|
+
"pattern": "\\bDONE\\b[\\s\\S]*(npm\\s+run\\s+test|node\\s+--test)",
|
|
186
|
+
"flags": "i",
|
|
187
|
+
"label": "DONE note names the real test command"
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"taskGraph": {
|
|
192
|
+
"requireCraftbookTask": true,
|
|
193
|
+
"requireTerminalStep": true
|
|
194
|
+
},
|
|
195
|
+
"unchangedFixtures": [
|
|
196
|
+
"source/migration-brief.md",
|
|
197
|
+
"package.json"
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
"rubric": {
|
|
201
|
+
"artifact": {
|
|
202
|
+
"path": "tasks/eval/change-notes.md",
|
|
203
|
+
"kind": "markdown"
|
|
204
|
+
},
|
|
205
|
+
"axes": [
|
|
206
|
+
{
|
|
207
|
+
"name": "Expand/contract discipline",
|
|
208
|
+
"description": "The stages genuinely followed expand, migrate, contract in order - readers accepted both shapes while the data moved, and the old shape was dropped only after the transform completed with a green suite."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"name": "Data preservation",
|
|
212
|
+
"description": "The transform is real and lossless: every record reached the target shape with names and emails surviving exactly, proven by counts and spot-checks rather than asserted."
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "Honest verification",
|
|
216
|
+
"description": "Verification searched for leftover old-shape reads, quoted what it found, ran the real suite, and labeled anything unrun as unverified instead of claiming it."
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
"qualityFocus": [
|
|
221
|
+
"expand/contract data safety",
|
|
222
|
+
"no record stranded",
|
|
223
|
+
"real-site accessor changes"
|
|
224
|
+
]
|
|
225
|
+
}
|