From 2dd808cdd39351418708f2ec69f66f1d5738812c Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Wed, 11 Mar 2026 10:15:48 -0700 Subject: [PATCH] chore: migrate task tracking from nbd to beans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace all .nbd/ ticket stores with .beans/ directories across the mono-repo (root, edu, nbd, quotesdb). Field mappings: status todo→todo, in_progress→in-progress, done→completed, closed→scrapped, archived→completed, backlog→draft; priority numeric→label; type project→epic. All dependency relationships preserved via --blocked-by. Add scripts/migrate-nbd-to-beans.sh for reproducible future migrations. Update CLAUDE.md task-tracking sections (root, edu, nbd, quotesdb) to reference beans commands instead of nbd commands. Counts: root 2, edu 48, nbd 38, quotesdb 121 beans created; 0 failures. Co-Authored-By: Claude Sonnet 4.6 --- .beans.yml | 6 + ...es-for-all-projects-with-lint-check-bui.md | 19 +- ...ontact-footer-to-all-service-front-ends.md | 19 +- .claude/settings.json | 8 + CLAUDE.md | 51 ++--- edu/.beans.yml | 6 + ...exercise-simulating-a-random-walk-rust.md} | 19 +- ...g-atoms-integers-booleans-strings-symb.md} | 16 +- ...--markov-lesson-what-is-a-markov-chain.md} | 19 +- ...rcise-5-retrieval-augmented-generation.md} | 19 +- ...esson-applications-and-further-reading.md} | 19 +- .../edu-3sww--11-checking-special-forms.md} | 16 +- ...ov-exercise-n-gram-generalization-rust.md} | 19 +- .../edu-4kkb--12-the-c-runtime-preamble.md} | 16 +- ...du-write-chapter-on-shader-programming.md} | 19 +- ...-13-generating-c-atoms-and-expressions.md} | 16 +- ...ov-exercise-bigram-text-generator-rust.md} | 19 +- ...p2--markov-exercise-weather-model-rust.md} | 19 +- .../edu-91j2--vector-db.md} | 32 ++- ...son-text-generation-with-markov-chains.md} | 19 +- ...n-transition-probabilities-and-matrice.md} | 19 +- ...apter-on-co-op-worker-owned-business-s.md} | 19 +- ...zf5--2-minilisp-language-specification.md} | 16 +- ...e-writing-a-lisp-to-c-compiler-in-rust.md} | 35 ++- ...-c98s--9-generating-embeddings-in-rust.md} | 19 +- ...achine-learning-chapter-self-play-game.md} | 19 +- ...l--11-exercise-4-recommendation-engine.md} | 19 +- .../edu-g1r5--5-setting-up-the-project.md} | 16 +- ...10-exercise-3-semantic-document-search.md} | 19 +- .../edu-h3yx--10-symbol-tables-and-scope.md} | 16 +- .../edu-hvic--2-embeddings.md} | 19 +- .../edu-hvmi--4-what-is-a-vector-database.md} | 19 +- ...du-ic66--6-setting-up-turso-sqlite-vec.md} | 19 +- ...introduction-to-nom-parser-combinators.md} | 16 +- .../edu-mlut--1-what-is-a-vector.md} | 19 +- .../edu-mmbr--8-parsing-atoms-with-nom.md} | 16 +- .../edu-n7zb--7-the-abstract-syntax-tree.md} | 16 +- ...--3-compiler-architecture-the-pipeline.md} | 16 +- .../edu-nc61--16-the-compilation-pipeline.md} | 16 +- ...8-exercise-2-k-nearest-neighbor-search.md} | 19 +- ...rcise-1-storing-and-retrieving-vectors.md} | 19 +- ...generating-c-definitions-and-functions.md} | 16 +- .../fb7f74.md => .beans/edu-svom--markov.md} | 30 ++- .../edu-twtl--3-vector-similarity.md} | 19 +- ...dbook-to-cloudflare-pages-at-vibebooks.md} | 19 +- ...arsing-s-expressions-and-special-forms.md} | 16 +- ...apter-on-creating-and-training-a-simpl.md} | 19 +- ...nerating-c-control-flow-and-sequencing.md} | 16 +- ...markov-lesson-stationary-distributions.md} | 19 +- ...-uz3e--5-under-the-hood-ann-algorithms.md} | 19 +- .../edu-v0ud--17-testing-the-compiler.md} | 16 +- ...ts-next-extensions-and-further-reading.md} | 16 +- ...lb8--1-introduction-what-were-building.md} | 16 +- ...--markov-lesson-states-and-transitions.md} | 19 +- edu/.nbd/.gitignore | 1 - edu/CLAUDE.md | 4 +- flake.nix | 3 + nbd/.beans.yml | 6 + .../nbd-08jg--add-nbd-next-subcommand.md} | 21 +- ...dp--ascii-graph-rendering-in-displayrs.md} | 21 +- .../nbd-2i1e--nbd-claude-md-command.md} | 19 +- ...-done-tickets-from-nbd-list-by-default.md} | 21 +- .../nbd-56ho--tests-for-nbd-graph-command.md} | 21 +- ...s-in-markdown-format-instead-of-key-va.md} | 19 +- ...bd-7cab--add-backlog-status-to-tickets.md} | 19 +- ...onvenience-sub-commands-open-start-com.md} | 19 +- .../nbd-95l6--nbd-init-command.md} | 19 +- ...tus-sub-commands-list-todo-list-backlo.md} | 19 +- ...nbdconfigtoml-for-per-project-defaults.md} | 19 +- ...dd-graph-computation-module-srcgraphrs.md} | 19 +- ...nbd-d9dh--add-nbd-graph-cli-subcommand.md} | 22 +- .../nbd-fgwx--nbd-update-diff-output.md} | 19 +- ...e-md-snippet-to-show-json-on-all-comma.md} | 19 +- .../nbd-i0fc--nbd-ready-command.md} | 19 +- ...hiveclosed-archivedone-closedcancelled.md} | 19 +- ...xt-and-nbd-ready-by-dependency-subtree.md} | 19 +- ...ientation-show-goals-at-root-prerequis.md} | 19 +- ...h-id-show-ancestry-path-through-ticket.md} | 21 +- ...--nbd-init-add-cachedb-to-nbdgitignore.md} | 19 +- ...ut-format-that-wraps-each-ticket-secti.md} | 19 +- ...user-configurable-type-and-status-stri.md} | 19 +- ...add-version-flag-with-xyzgitsha-format.md} | 19 +- ...-remove-id-field-from-ticket-json-body.md} | 19 +- ...oziy--turso-cache-for-list-performance.md} | 19 +- ...flag-into-list-ready-and-migrate-comma.md} | 21 +- ...-nbd-archive-command-and-closed-status.md} | 19 +- .../nbd-q2d1--nbd-migrate-command.md} | 21 +- ...pe-filtered-sub-commands-next-bug-next.md} | 19 +- .../nbd-rulc--partial-id-matching.md} | 19 +- ...iple-file-format-support-md-toml-jsonb.md} | 19 +- ...filtering-tickets-by-project-stream-of.md} | 19 +- .../nbd-wbf7--nix-flake-for-nbd.md} | 19 +- ...-compile-into-binary-via-include-str-a.md} | 19 +- ...hange-graph-cycle-marker-from-cycle-to.md} | 19 +- ...status-new-default-for-tickets-lacking.md} | 19 +- ...ticketfilter-module-with-glob-matching.md} | 19 +- nbd/.nbd/.gitignore | 1 - nbd/.nbd/tickets/b05b5a.json | 8 - nbd/.nbd/tickets/e6b9df.json | 8 - nbd/CLAUDE.md | 52 ++--- quotesdb/.beans.yml | 6 + ...db-layer-add-submissions-locked-update.md} | 19 +- ...rowse-page-browse-paginated-quote-list.md} | 24 +- ...author-optional-default-anonymous-clar.md} | 19 +- ...memd-uidocsplanningmd-uidocsarchitectu.md} | 22 +- ...d-crate-wasm-compatibility-with-worker.md} | 16 +- ...-250z--quotesdbui-admin-page-component.md} | 21 +- ...ote-detail-page-quotesid-view-edit-for.md} | 23 +- ...-single-crate-with-api-and-ui-binaries.md} | 18 +- ...get-apiquotesid-200-with-quote-404-not.md} | 19 +- .../quotesdb-32yd--quotesdb.md} | 21 +- ...flare-pages-build-strategy-pages-ci-bu.md} | 16 +- ...flare-d1-database-resource-and-documen.md} | 19 +- ...-turnstile-captcha-on-quote-submission.md} | 19 +- ...dmemd-apidocsplanningmd-apidocsarchite.md} | 18 +- ...t-apiquotes-paginated-list-with-author.md} | 20 +- ...et-apiquotes-pagination-page1-pagen-ou.md} | 19 +- ...cmainrs-cloudflare-workers-entry-point.md} | 18 +- ...grations-in-opentofu-null-resource-loc.md} | 16 +- ...f--bootstrap-quotesdb-project-skeleton.md} | 18 +- ...rd-passphrase-crate-selection-for-wasm.md} | 16 +- ...convert-apiopenapiyaml-to-json-at-comp.md} | 16 +- ...th-code-session-storage-utility-module.md} | 16 +- ...rets-management-cloudflare-api-token-a.md} | 18 +- ...gination-component-prevnext-buttons-cu.md} | 19 +- ...nerate-id-in-srclibrs-uuid-v4-for-wasm.md} | 16 +- ...tabase-connection-module-and-sqlx-migr.md} | 20 +- ...ent-get-api-serve-openapi-spec-as-json.md} | 19 +- ...flare-worker-routedomain-workerdev-sub.md} | 18 +- ...eport-button-with-modal-reason-field-c.md} | 21 +- ...ect-cloudflare-workers-script-resource.md} | 16 +- ...code-storage-strategy-localstorage-per.md} | 16 +- ...schema-migration-workflow-how-to-apply.md} | 19 +- ...-abstraction-quoterepository-trait-cfg.md} | 18 +- ...esdbui-submit-page-locked-state-banner.md} | 21 +- ...tyling-approach-for-wasm-plain-css-cdn.md} | 16 +- ...t-apiquotes-create-quote-generate-uuid.md} | 22 +- ...harness-how-to-import-and-start-quotes.md} | 16 +- ...orkflowsdeploy-apiyml-gitea-actions-wo.md} | 19 +- ...orker-gzipped-binary-size-is-within-cf.md} | 18 +- ...cargotoml-with-integration-test-depend.md} | 19 +- ...mpiler-warnings-in-api-and-ui-binaries.md} | 19 +- ...st-apiquotesid-partial-update-verify-x.md} | 20 +- ...inding-chicken-and-egg-d1-id-not-known.md} | 16 +- ...date-field-should-use-typedate-for-cal.md} | 19 +- ...-quotesdbui-admin-api-client-functions.md} | 19 +- ...i-client-module-typed-fetch-wrappers-f.md} | 20 +- .../quotesdb-eh4l--write-testsreadmemd.md} | 18 +- ...ofu-state-backend-local-file-gitignore.md} | 16 +- ...ror-handling-consistent-error-envelope.md} | 19 +- ...s-spa-fallback-create-file-and-include.md} | 16 +- ...ersion-selection-and-yew-router-compat.md} | 19 +- ...otoml-with-all-crate-dependencies-axum.md} | 18 +- ...st-server-harness-spawn-quotesdb-api-w.md} | 20 +- ...router-ordering-verify-apiquotesrandom.md} | 19 +- ...get-apiquotesrandom-200-with-quote-404.md} | 19 +- ...eadmemd-setup-apply-destroy-instructio.md} | 22 +- ...schemasql-idempotent-d1-schema-for-quo.md} | 19 +- ...in-auth-code-cloudflare-secret-for-admi.md | 10 + ...cal-devmd-local-dev-quickstart-cargo-r.md} | 20 +- ...reports-table-and-post-apiquotesidrepo.md} | 19 +- ...ow-friendly-empty-state-when-no-quotes.md} | 19 +- ...bmit-page-submit-quote-creation-form-d.md} | 21 +- ...oxy-config-to-trunktoml-forward-api-to.md} | 20 +- ...thor-page-authorname-paginated-list-of.md} | 24 +- ...ration-test-isolation-strategy-per-tes.md} | 16 +- ...ror-display-component-consistent-error.md} | 19 +- ...nt-d1repository-for-cloudflare-workers.md} | 19 +- ...gotoml-with-yewwasm-dependencies-yew-y.md} | 21 +- ...g-filter-component-tag-inputselect-for.md} | 19 +- ...ests-in-apisrctestsrs-covering-all-han.md} | 24 +- ...-auth-code-delete-any-quote-regardless.md} | 19 +- ...stom-domain-quoteselijahrun-cloudflare.md} | 18 +- ...t-apiquotesrandom-random-row-query-mus.md} | 20 +- ...me-page-fetch-and-display-random-quote.md} | 22 +- ...otesdbui-add-footer-with-contact-email.md} | 19 +- .../quotesdb-ndjj--quotesdbui.md} | 22 +- ...post-apiadminlock-and-apiadminunlock-e.md} | 21 +- ...t-apiquotesid-fetch-by-nanoid-return-4.md} | 20 +- ...lete-apiquotesid-verify-x-auth-code-ca.md} | 19 +- ...admin-moderation-endpoints-list-report.md} | 22 +- ...workers-rs-cloudflare-d1-compatibility.md} | 16 +- ...ared-quotecard-component-displays-text.md} | 19 +- .../quotesdb-pqdw--quotesdbapi.md} | 21 +- ...ample-documenting-database-url-and-all.md} | 20 +- ...ollapsible-filter-panel-on-browse-page.md} | 16 +- ...g-join-logic-fetch-tags-per-quote-inse.md} | 18 +- ...th-code-modalprompt-component-dialog-r.md} | 20 +- ...flare-pages-project-resource-build-con.md} | 19 +- ...dmin-page-auth-first-flow-and-remove-f.md} | 19 +- ...idden-toggle-on-quote-pages-auth-requi.md} | 21 +- ...enforce-submission-lock-on-put-apiquot.md} | 21 +- .../quotesdb-ryhx--quotesdbqa.md} | 32 ++- ...flare-workers-wasm-size-limit-free-tie.md} | 16 +- ...a-cloudflare-rate-limiting-waf-rules-o.md} | 19 +- ...pi-spec-serving-strategy-embed-yaml-at.md} | 16 +- ...-dev-config-turso-file-sqlite-vs-d1-bi.md} | 18 +- ...s-by-date-range-beforeafter-with-yearm.md} | 19 +- ...get-api-openapi-spec-returned-as-valid.md} | 19 +- ...admin-moderation-tab-paginated-reports.md} | 22 +- ...flare-pages-spa-routing-404-fallback-c.md} | 16 +- ...tesdbapi-get-apistatus-public-endpoint.md} | 21 +- ...elete-apiquotesid-valid-auth-204-no-bo.md} | 19 +- ...flare-workers-script-resource-wasm-art.md} | 21 +- ...ost-apiquotesid-valid-auth-200-wrong-a.md} | 19 +- ...rs-rs-compatibility-with-native-rust-t.md} | 16 +- ...nuistylecss-full-stylesheet-for-all-ui.md} | 18 +- ...word-passphrase-auth-code-generator-mu.md} | 19 +- ...nktoml-and-uiindexhtml-build-configura.md} | 21 +- ...remove-submit-another-link-from-succes.md} | 19 +- ...-post-apiadminreset-auth-code-endpoint.md} | 21 +- ...-dev-cors-and-trunk-api-proxy-config-t.md} | 18 +- .../quotesdb-xi3i--quotesdbinfra.md} | 18 +- ...isrcmainrs-yew-app-shell-browserrouter.md} | 20 +- ...kers-rs-wasm-entry-point-to-api-binary.md} | 19 +- ...orkflowsdeploy-uiyml-gitea-actions-wor.md} | 19 +- ...hidden-flag-for-quotes-schema-migratio.md} | 19 +- ...ag-operations-create-with-tags-list-by.md} | 19 +- ...client-selection-for-integration-tests.md} | 16 +- ...ut-apiquotes-create-auto-auth-code-cus.md} | 19 +- ...base-migration-strategy-for-cloudflare.md} | 16 +- ...-opentofu-project-providerstf-terrafor.md} | 18 +- quotesdb/.nbd/.gitignore | 1 - quotesdb/.nbd/tickets/d4a624.md | 7 - quotesdb/CLAUDE.md | 34 +-- scripts/migrate-nbd-to-beans.sh | 206 ++++++++++++++++++ 226 files changed, 2714 insertions(+), 1666 deletions(-) create mode 100644 .beans.yml rename .nbd/tickets/82df74.md => .beans/vibed-0fcp--add-justfiles-for-all-projects-with-lint-check-bui.md (89%) rename .nbd/tickets/09cda0.md => .beans/vibed-wqsu--add-contact-footer-to-all-service-front-ends.md (89%) create mode 100644 edu/.beans.yml rename edu/{.nbd/tickets/64826a.md => .beans/edu-0w1v--markov-exercise-simulating-a-random-walk-rust.md} (75%) rename edu/{.nbd/tickets/685f5e.md => .beans/edu-16fy--6-recognizing-atoms-integers-booleans-strings-symb.md} (96%) rename edu/{.nbd/tickets/fbf323.md => .beans/edu-18qe--markov-lesson-what-is-a-markov-chain.md} (68%) rename edu/{.nbd/tickets/5ed295.md => .beans/edu-1oh8--12-exercise-5-retrieval-augmented-generation.md} (93%) rename edu/{.nbd/tickets/5994a6.md => .beans/edu-34co--markov-lesson-applications-and-further-reading.md} (78%) rename edu/{.nbd/tickets/6d40a7.md => .beans/edu-3sww--11-checking-special-forms.md} (96%) rename edu/{.nbd/tickets/1f995a.md => .beans/edu-4gok--markov-exercise-n-gram-generalization-rust.md} (78%) rename edu/{.nbd/tickets/3e1250.md => .beans/edu-4kkb--12-the-c-runtime-preamble.md} (96%) rename edu/{.nbd/tickets/0fbe1a.md => .beans/edu-4u7w--edu-write-chapter-on-shader-programming.md} (87%) rename edu/{.nbd/tickets/1eb794.md => .beans/edu-63ze--13-generating-c-atoms-and-expressions.md} (96%) rename edu/{.nbd/tickets/74be50.md => .beans/edu-6r70--markov-exercise-bigram-text-generator-rust.md} (77%) rename edu/{.nbd/tickets/257a2a.md => .beans/edu-7cp2--markov-exercise-weather-model-rust.md} (79%) rename edu/{.nbd/tickets/b7c95f.md => .beans/edu-91j2--vector-db.md} (85%) rename edu/{.nbd/tickets/92a829.md => .beans/edu-9kuk--markov-lesson-text-generation-with-markov-chains.md} (71%) rename edu/{.nbd/tickets/44ebe7.md => .beans/edu-a1al--markov-lesson-transition-probabilities-and-matrice.md} (72%) rename edu/{.nbd/tickets/8618e4.md => .beans/edu-al3r--edu-write-chapter-on-co-op-worker-owned-business-s.md} (86%) rename edu/{.nbd/tickets/a93829.md => .beans/edu-azf5--2-minilisp-language-specification.md} (96%) rename edu/{.nbd/tickets/67e284.md => .beans/edu-b73b--course-writing-a-lisp-to-c-compiler-in-rust.md} (80%) rename edu/{.nbd/tickets/4c961f.md => .beans/edu-c98s--9-generating-embeddings-in-rust.md} (94%) rename edu/{.nbd/tickets/8f14c6.md => .beans/edu-coqp--edu-write-machine-learning-chapter-self-play-game.md} (88%) rename edu/{.nbd/tickets/e8be9a.md => .beans/edu-dgfl--11-exercise-4-recommendation-engine.md} (92%) rename edu/{.nbd/tickets/3dc36b.md => .beans/edu-g1r5--5-setting-up-the-project.md} (94%) rename edu/{.nbd/tickets/1ef9f4.md => .beans/edu-ga52--10-exercise-3-semantic-document-search.md} (95%) rename edu/{.nbd/tickets/d0b9f8.md => .beans/edu-h3yx--10-symbol-tables-and-scope.md} (97%) rename edu/{.nbd/tickets/584e0c.md => .beans/edu-hvic--2-embeddings.md} (93%) rename edu/{.nbd/tickets/d9f850.md => .beans/edu-hvmi--4-what-is-a-vector-database.md} (92%) rename edu/{.nbd/tickets/37cdd5.md => .beans/edu-ic66--6-setting-up-turso-sqlite-vec.md} (81%) rename edu/{.nbd/tickets/5835e9.md => .beans/edu-jzvr--4-introduction-to-nom-parser-combinators.md} (97%) rename edu/{.nbd/tickets/21d9be.md => .beans/edu-mlut--1-what-is-a-vector.md} (79%) rename edu/{.nbd/tickets/b6c9ad.md => .beans/edu-mmbr--8-parsing-atoms-with-nom.md} (96%) rename edu/{.nbd/tickets/a1a827.md => .beans/edu-n7zb--7-the-abstract-syntax-tree.md} (97%) rename edu/{.nbd/tickets/3aeb62.md => .beans/edu-n9ap--3-compiler-architecture-the-pipeline.md} (95%) rename edu/{.nbd/tickets/58b37a.md => .beans/edu-nc61--16-the-compilation-pipeline.md} (96%) rename edu/{.nbd/tickets/5674ce.md => .beans/edu-paqf--8-exercise-2-k-nearest-neighbor-search.md} (91%) rename edu/{.nbd/tickets/081a55.md => .beans/edu-pdeo--7-exercise-1-storing-and-retrieving-vectors.md} (91%) rename edu/{.nbd/tickets/cbc6e3.md => .beans/edu-pyue--14-generating-c-definitions-and-functions.md} (96%) rename edu/{.nbd/tickets/fb7f74.md => .beans/edu-svom--markov.md} (64%) rename edu/{.nbd/tickets/99e1d9.md => .beans/edu-twtl--3-vector-similarity.md} (93%) rename edu/{.nbd/tickets/59c122.md => .beans/edu-tx54--deploy-edu-mdbook-to-cloudflare-pages-at-vibebooks.md} (93%) rename edu/{.nbd/tickets/a4c9f8.md => .beans/edu-tzzh--9-parsing-s-expressions-and-special-forms.md} (97%) rename edu/{.nbd/tickets/389d8d.md => .beans/edu-u2w7--edu-write-chapter-on-creating-and-training-a-simpl.md} (89%) rename edu/{.nbd/tickets/de82f1.md => .beans/edu-unus--15-generating-c-control-flow-and-sequencing.md} (96%) rename edu/{.nbd/tickets/68ee16.md => .beans/edu-urpp--markov-lesson-stationary-distributions.md} (72%) rename edu/{.nbd/tickets/6ec5ff.md => .beans/edu-uz3e--5-under-the-hood-ann-algorithms.md} (93%) rename edu/{.nbd/tickets/8fa47a.md => .beans/edu-v0ud--17-testing-the-compiler.md} (96%) rename edu/{.nbd/tickets/1d16da.md => .beans/edu-y4e6--18-whats-next-extensions-and-further-reading.md} (96%) rename edu/{.nbd/tickets/e8da8b.md => .beans/edu-ylb8--1-introduction-what-were-building.md} (95%) rename edu/{.nbd/tickets/738be2.md => .beans/edu-zjy1--markov-lesson-states-and-transitions.md} (74%) delete mode 100644 edu/.nbd/.gitignore create mode 100644 nbd/.beans.yml rename nbd/{.nbd/tickets/fc6df4.md => .beans/nbd-08jg--add-nbd-next-subcommand.md} (96%) rename nbd/{.nbd/tickets/e14172.md => .beans/nbd-17dp--ascii-graph-rendering-in-displayrs.md} (91%) rename nbd/{.nbd/tickets/fc444f.md => .beans/nbd-2i1e--nbd-claude-md-command.md} (93%) rename nbd/{.nbd/tickets/92e45b.md => .beans/nbd-4w8z--exclude-done-tickets-from-nbd-list-by-default.md} (94%) rename nbd/{.nbd/tickets/9c1f2c.md => .beans/nbd-56ho--tests-for-nbd-graph-command.md} (91%) rename nbd/{.nbd/tickets/4036aa.md => .beans/nbd-6j0q--print-tickets-in-markdown-format-instead-of-key-va.md} (92%) rename nbd/{.nbd/tickets/c12091.md => .beans/nbd-7cab--add-backlog-status-to-tickets.md} (93%) rename nbd/{.nbd/tickets/d9713b.md => .beans/nbd-8yn8--add-status-convenience-sub-commands-open-start-com.md} (84%) rename nbd/{.nbd/tickets/4d2359.md => .beans/nbd-95l6--nbd-init-command.md} (86%) rename nbd/{.nbd/tickets/53fdbe.md => .beans/nbd-9mxu--add-list-status-sub-commands-list-todo-list-backlo.md} (85%) rename nbd/{.nbd/tickets/3ba7f9.md => .beans/nbd-9vrn--add-nbdconfigtoml-for-per-project-defaults.md} (90%) rename nbd/{.nbd/tickets/9c9ebe.md => .beans/nbd-csdh--add-graph-computation-module-srcgraphrs.md} (93%) rename nbd/{.nbd/tickets/9ad11f.md => .beans/nbd-d9dh--add-nbd-graph-cli-subcommand.md} (91%) rename nbd/{.nbd/tickets/5f1495.md => .beans/nbd-fgwx--nbd-update-diff-output.md} (88%) rename nbd/{.nbd/tickets/9344a5.md => .beans/nbd-flbj--update-claude-md-snippet-to-show-json-on-all-comma.md} (86%) rename nbd/{.nbd/tickets/e1968f.md => .beans/nbd-i0fc--nbd-ready-command.md} (87%) rename nbd/{.nbd/tickets/feb901.md => .beans/nbd-jc1v--split-archiveclosed-archivedone-closedcancelled.md} (93%) rename nbd/{.nbd/tickets/818598.md => .beans/nbd-kq6o--scope-nbd-next-and-nbd-ready-by-dependency-subtree.md} (94%) rename nbd/{.nbd/tickets/668150.md => .beans/nbd-l38k--fix-graph-orientation-show-goals-at-root-prerequis.md} (86%) rename nbd/{.nbd/tickets/06ca62.md => .beans/nbd-lins--fix-nbd-graph-id-show-ancestry-path-through-ticket.md} (88%) rename nbd/{.nbd/tickets/4aceeb.md => .beans/nbd-m9q2--nbd-init-add-cachedb-to-nbdgitignore.md} (83%) rename nbd/{.nbd/tickets/39b2cf.md => .beans/nbd-mkkm--add-xml-output-format-that-wraps-each-ticket-secti.md} (92%) rename nbd/{.nbd/tickets/0f577a.md => .beans/nbd-n2xz--investigate-user-configurable-type-and-status-stri.md} (89%) rename nbd/{.nbd/tickets/c24ee8.md => .beans/nbd-no88--add-version-flag-with-xyzgitsha-format.md} (95%) rename nbd/{.nbd/tickets/d1634a.md => .beans/nbd-o3k8--remove-id-field-from-ticket-json-body.md} (94%) rename nbd/{.nbd/tickets/833807.md => .beans/nbd-oziy--turso-cache-for-list-performance.md} (93%) rename nbd/{.nbd/tickets/887344.md => .beans/nbd-p9na--wire-filter-flag-into-list-ready-and-migrate-comma.md} (94%) rename nbd/{.nbd/tickets/1939a7.md => .beans/nbd-pq2x--nbd-archive-command-and-closed-status.md} (88%) rename nbd/{.nbd/tickets/0f51af.md => .beans/nbd-q2d1--nbd-migrate-command.md} (95%) rename nbd/{.nbd/tickets/1c686c.md => .beans/nbd-ql0c--add-next-type-filtered-sub-commands-next-bug-next.md} (81%) rename nbd/{.nbd/tickets/c9d551.md => .beans/nbd-rulc--partial-id-matching.md} (88%) rename nbd/{.nbd/tickets/460caf.md => .beans/nbd-s16w--multiple-file-format-support-md-toml-jsonb.md} (92%) rename nbd/{.nbd/tickets/67209c.md => .beans/nbd-urlz--investigate-filtering-tickets-by-project-stream-of.md} (85%) rename nbd/{.nbd/tickets/6e4239.md => .beans/nbd-wbf7--nix-flake-for-nbd.md} (87%) rename nbd/{.nbd/tickets/1c5783.md => .beans/nbd-wi74--version-file-compile-into-binary-via-include-str-a.md} (91%) rename nbd/{.nbd/tickets/8b4041.md => .beans/nbd-y4nv--change-graph-cycle-marker-from-cycle-to.md} (87%) rename nbd/{.nbd/tickets/e222cd.md => .beans/nbd-yh0v--add-triage-status-new-default-for-tickets-lacking.md} (91%) rename nbd/{.nbd/tickets/c2a024.md => .beans/nbd-zz62--implement-ticketfilter-module-with-glob-matching.md} (96%) delete mode 100644 nbd/.nbd/.gitignore delete mode 100644 nbd/.nbd/tickets/b05b5a.json delete mode 100644 nbd/.nbd/tickets/e6b9df.json create mode 100644 quotesdb/.beans.yml rename quotesdb/{.nbd/tickets/69a2c5.md => .beans/quotesdb-04cw--quotesdbapi-db-layer-add-submissions-locked-update.md} (86%) rename quotesdb/{.nbd/tickets/5cdbd9.md => .beans/quotesdb-0flf--implement-browse-page-browse-paginated-quote-list.md} (77%) rename quotesdb/{.nbd/tickets/5b3475.md => .beans/quotesdb-0wpo--submit-form-author-optional-default-anonymous-clar.md} (91%) rename quotesdb/{.nbd/tickets/372790.md => .beans/quotesdb-0x53--write-uireadmemd-uidocsplanningmd-uidocsarchitectu.md} (76%) rename quotesdb/{.nbd/tickets/6f2e18.md => .beans/quotesdb-1o8u--triage-nanoid-crate-wasm-compatibility-with-worker.md} (91%) rename quotesdb/{.nbd/tickets/c3c8c6.md => .beans/quotesdb-250z--quotesdbui-admin-page-component.md} (93%) rename quotesdb/{.nbd/tickets/5f1112.md => .beans/quotesdb-297v--implement-quote-detail-page-quotesid-view-edit-for.md} (78%) rename quotesdb/{.nbd/tickets/b38032.md => .beans/quotesdb-29nd--refactor-to-single-crate-with-api-and-ui-binaries.md} (97%) rename quotesdb/{.nbd/tickets/f9f448.md => .beans/quotesdb-2nlt--test-suite-get-apiquotesid-200-with-quote-404-not.md} (80%) rename quotesdb/{.nbd/tickets/ec118c.md => .beans/quotesdb-32yd--quotesdb.md} (97%) rename quotesdb/{.nbd/tickets/fc9bfd.md => .beans/quotesdb-3951--triage-cloudflare-pages-build-strategy-pages-ci-bu.md} (91%) rename quotesdb/{.nbd/tickets/d0da0b.md => .beans/quotesdb-3euj--define-cloudflare-d1-database-resource-and-documen.md} (87%) rename quotesdb/{.nbd/tickets/a57e7e.md => .beans/quotesdb-3mk8--cloudflare-turnstile-captcha-on-quote-submission.md} (95%) rename quotesdb/{.nbd/tickets/08af7a.md => .beans/quotesdb-45sn--write-apireadmemd-apidocsplanningmd-apidocsarchite.md} (85%) rename quotesdb/{.nbd/tickets/886bfd.md => .beans/quotesdb-4gqi--implement-get-apiquotes-paginated-list-with-author.md} (86%) rename quotesdb/{.nbd/tickets/93f1b6.md => .beans/quotesdb-4pxt--test-suite-get-apiquotes-pagination-page1-pagen-ou.md} (81%) rename quotesdb/{.nbd/tickets/6e829e.md => .beans/quotesdb-4t5j--set-up-apisrcmainrs-cloudflare-workers-entry-point.md} (86%) rename quotesdb/{.nbd/tickets/5c0c64.md => .beans/quotesdb-4tec--triage-d1-migrations-in-opentofu-null-resource-loc.md} (91%) rename quotesdb/{.nbd/tickets/d6ba23.md => .beans/quotesdb-58hf--bootstrap-quotesdb-project-skeleton.md} (51%) rename quotesdb/{.nbd/tickets/6ed325.md => .beans/quotesdb-58hh--triage-4-word-passphrase-crate-selection-for-wasm.md} (93%) rename quotesdb/{.nbd/tickets/8892d5.md => .beans/quotesdb-5aow--add-buildrs-convert-apiopenapiyaml-to-json-at-comp.md} (93%) rename quotesdb/{.nbd/tickets/5379eb.md => .beans/quotesdb-5dda--implement-auth-code-session-storage-utility-module.md} (94%) rename quotesdb/{.nbd/tickets/71b1d4.md => .beans/quotesdb-625z--document-secrets-management-cloudflare-api-token-a.md} (77%) rename quotesdb/{.nbd/tickets/2c5a57.md => .beans/quotesdb-6huz--implement-pagination-component-prevnext-buttons-cu.md} (78%) rename quotesdb/{.nbd/tickets/7a0d9f.md => .beans/quotesdb-6lh5--implement-generate-id-in-srclibrs-uuid-v4-for-wasm.md} (94%) rename quotesdb/{.nbd/tickets/a5049d.md => .beans/quotesdb-6ng5--implement-database-connection-module-and-sqlx-migr.md} (90%) rename quotesdb/{.nbd/tickets/28e7d9.md => .beans/quotesdb-753n--implement-get-api-serve-openapi-spec-as-json.md} (90%) rename quotesdb/{.nbd/tickets/ae6a82.md => .beans/quotesdb-76hx--define-cloudflare-worker-routedomain-workerdev-sub.md} (81%) rename quotesdb/{.nbd/tickets/354276.md => .beans/quotesdb-792p--quotesdbui-report-button-with-modal-reason-field-c.md} (83%) rename quotesdb/{.nbd/tickets/efee79.md => .beans/quotesdb-8zm9--triage-correct-cloudflare-workers-script-resource.md} (87%) rename quotesdb/{.nbd/tickets/0bc655.md => .beans/quotesdb-9e3j--triage-auth-code-storage-strategy-localstorage-per.md} (91%) rename quotesdb/{.nbd/tickets/75489a.md => .beans/quotesdb-9fpn--document-d1-schema-migration-workflow-how-to-apply.md} (86%) rename quotesdb/{.nbd/tickets/00aff0.md => .beans/quotesdb-9ghn--implement-db-abstraction-quoterepository-trait-cfg.md} (98%) rename quotesdb/{.nbd/tickets/14570c.md => .beans/quotesdb-9jsk--quotesdbui-submit-page-locked-state-banner.md} (90%) rename quotesdb/{.nbd/tickets/5e3e37.md => .beans/quotesdb-9lxc--triage-cssstyling-approach-for-wasm-plain-css-cdn.md} (90%) rename quotesdb/{.nbd/tickets/05f8ae.md => .beans/quotesdb-a0q1--implement-put-apiquotes-create-quote-generate-uuid.md} (84%) rename quotesdb/{.nbd/tickets/2ab7a8.md => .beans/quotesdb-aa9s--triage-test-harness-how-to-import-and-start-quotes.md} (88%) rename quotesdb/{.nbd/tickets/57fe5e.md => .beans/quotesdb-ah5w--write-giteaworkflowsdeploy-apiyml-gitea-actions-wo.md} (93%) rename quotesdb/{.nbd/tickets/3781c9.md => .beans/quotesdb-ap4c--verify-api-worker-gzipped-binary-size-is-within-cf.md} (91%) rename quotesdb/{.nbd/tickets/5f5ba0.md => .beans/quotesdb-bl2g--set-up-testscargotoml-with-integration-test-depend.md} (82%) rename quotesdb/{.nbd/tickets/b01bad.md => .beans/quotesdb-bysu--fix-compiler-warnings-in-api-and-ui-binaries.md} (88%) rename quotesdb/{.nbd/tickets/5d9f5a.md => .beans/quotesdb-bz2v--implement-post-apiquotesid-partial-update-verify-x.md} (86%) rename quotesdb/{.nbd/tickets/07cafb.md => .beans/quotesdb-cc35--triage-d1-binding-chicken-and-egg-d1-id-not-known.md} (92%) rename quotesdb/{.nbd/tickets/dfd185.md => .beans/quotesdb-csvt--submit-form-date-field-should-use-typedate-for-cal.md} (86%) rename quotesdb/{.nbd/tickets/161f32.md => .beans/quotesdb-d09v--quotesdbui-admin-api-client-functions.md} (94%) rename quotesdb/{.nbd/tickets/1e6a09.md => .beans/quotesdb-dgwi--implement-api-client-module-typed-fetch-wrappers-f.md} (88%) rename quotesdb/{.nbd/tickets/75e3f0.md => .beans/quotesdb-eh4l--write-testsreadmemd.md} (77%) rename quotesdb/{.nbd/tickets/07feaa.md => .beans/quotesdb-esnq--triage-opentofu-state-backend-local-file-gitignore.md} (88%) rename quotesdb/{.nbd/tickets/d792e2.md => .beans/quotesdb-fagr--implement-error-handling-consistent-error-envelope.md} (85%) rename quotesdb/{.nbd/tickets/9ef703.md => .beans/quotesdb-fg44--add-redirects-spa-fallback-create-file-and-include.md} (90%) rename quotesdb/{.nbd/tickets/166996.md => .beans/quotesdb-fhhk--triage-yew-version-selection-and-yew-router-compat.md} (80%) rename quotesdb/{.nbd/tickets/1f5bb5.md => .beans/quotesdb-ghzc--set-up-cargotoml-with-all-crate-dependencies-axum.md} (91%) rename quotesdb/{.nbd/tickets/9b581f.md => .beans/quotesdb-gu9j--implement-test-server-harness-spawn-quotesdb-api-w.md} (92%) rename quotesdb/{.nbd/tickets/e8f5cf.md => .beans/quotesdb-h07r--test-suite-router-ordering-verify-apiquotesrandom.md} (82%) rename quotesdb/{.nbd/tickets/aa0eab.md => .beans/quotesdb-hag9--test-suite-get-apiquotesrandom-200-with-quote-404.md} (78%) rename quotesdb/{.nbd/tickets/d5839a.md => .beans/quotesdb-hfhl--write-infrareadmemd-setup-apply-destroy-instructio.md} (69%) rename quotesdb/{.nbd/tickets/bb1514.md => .beans/quotesdb-hmbh--create-infraschemasql-idempotent-d1-schema-for-quo.md} (95%) create mode 100644 quotesdb/.beans/quotesdb-hna0--support-admin-auth-code-cloudflare-secret-for-admi.md rename quotesdb/{.nbd/tickets/af56a7.md => .beans/quotesdb-hord--write-docslocal-devmd-local-dev-quickstart-cargo-r.md} (90%) rename quotesdb/{.nbd/tickets/77237f.md => .beans/quotesdb-i37j--quotesdbapi-reports-table-and-post-apiquotesidrepo.md} (83%) rename quotesdb/{.nbd/tickets/9d756a.md => .beans/quotesdb-iar0--home-page-show-friendly-empty-state-when-no-quotes.md} (84%) rename quotesdb/{.nbd/tickets/1ba523.md => .beans/quotesdb-ivwr--implement-submit-page-submit-quote-creation-form-d.md} (80%) rename quotesdb/{.nbd/tickets/00d6d7.md => .beans/quotesdb-jhmw--add-trunk-proxy-config-to-trunktoml-forward-api-to.md} (92%) rename quotesdb/{.nbd/tickets/b3ef98.md => .beans/quotesdb-jlef--implement-author-page-authorname-paginated-list-of.md} (73%) rename quotesdb/{.nbd/tickets/fba598.md => .beans/quotesdb-jpu5--triage-integration-test-isolation-strategy-per-tes.md} (93%) rename quotesdb/{.nbd/tickets/fc2f51.md => .beans/quotesdb-k258--implement-error-display-component-consistent-error.md} (77%) rename quotesdb/{.nbd/tickets/bacb16.md => .beans/quotesdb-k5rx--implement-d1repository-for-cloudflare-workers.md} (93%) rename quotesdb/{.nbd/tickets/93515e.md => .beans/quotesdb-kaat--set-up-uicargotoml-with-yewwasm-dependencies-yew-y.md} (86%) rename quotesdb/{.nbd/tickets/d3d502.md => .beans/quotesdb-kg2l--implement-tag-filter-component-tag-inputselect-for.md} (78%) rename quotesdb/{.nbd/tickets/a6bce1.md => .beans/quotesdb-kh9l--write-unit-tests-in-apisrctestsrs-covering-all-han.md} (80%) rename quotesdb/{.nbd/tickets/809cba.md => .beans/quotesdb-ky1o--admin-super-auth-code-delete-any-quote-regardless.md} (95%) rename quotesdb/{.nbd/tickets/657836.md => .beans/quotesdb-l09d--configure-custom-domain-quoteselijahrun-cloudflare.md} (80%) rename quotesdb/{.nbd/tickets/2ce22e.md => .beans/quotesdb-l4e9--implement-get-apiquotesrandom-random-row-query-mus.md} (83%) rename quotesdb/{.nbd/tickets/1a274d.md => .beans/quotesdb-m9vb--implement-home-page-fetch-and-display-random-quote.md} (78%) rename quotesdb/{.nbd/tickets/b2af7f.md => .beans/quotesdb-mhal--quotesdbui-add-footer-with-contact-email.md} (75%) rename quotesdb/{.nbd/tickets/c3503b.md => .beans/quotesdb-ndjj--quotesdbui.md} (74%) rename quotesdb/{.nbd/tickets/0c73cd.md => .beans/quotesdb-njv2--quotesdbapi-post-apiadminlock-and-apiadminunlock-e.md} (91%) rename quotesdb/{.nbd/tickets/5dbb7d.md => .beans/quotesdb-nrue--implement-get-apiquotesid-fetch-by-nanoid-return-4.md} (81%) rename quotesdb/{.nbd/tickets/b20b5a.md => .beans/quotesdb-ode0--implement-delete-apiquotesid-verify-x-auth-code-ca.md} (84%) rename quotesdb/{.nbd/tickets/6c5904.md => .beans/quotesdb-ooyx--quotesdbapi-admin-moderation-endpoints-list-report.md} (82%) rename quotesdb/{.nbd/tickets/e8a330.md => .beans/quotesdb-osmv--triage-sqlx-workers-rs-cloudflare-d1-compatibility.md} (91%) rename quotesdb/{.nbd/tickets/0d987f.md => .beans/quotesdb-oukj--implement-shared-quotecard-component-displays-text.md} (80%) rename quotesdb/{.nbd/tickets/f3dc74.md => .beans/quotesdb-pqdw--quotesdbapi.md} (75%) rename quotesdb/{.nbd/tickets/9c9546.md => .beans/quotesdb-q8u2--create-envexample-documenting-database-url-and-all.md} (89%) rename quotesdb/{.nbd/tickets/a6e8ba.md => .beans/quotesdb-qbpg--quotesdbui-collapsible-filter-panel-on-browse-page.md} (88%) rename quotesdb/{.nbd/tickets/175382.md => .beans/quotesdb-qf7x--implement-tag-join-logic-fetch-tags-per-quote-inse.md} (86%) rename quotesdb/{.nbd/tickets/f850c6.md => .beans/quotesdb-qqdf--implement-auth-code-modalprompt-component-dialog-r.md} (84%) rename quotesdb/{.nbd/tickets/ae886f.md => .beans/quotesdb-qt7m--define-cloudflare-pages-project-resource-build-con.md} (89%) rename quotesdb/{.nbd/tickets/cb8de0.md => .beans/quotesdb-r3eq--quotesdbui-admin-page-auth-first-flow-and-remove-f.md} (87%) rename quotesdb/{.nbd/tickets/f4930e.md => .beans/quotesdb-r51f--quotesdbui-hidden-toggle-on-quote-pages-auth-requi.md} (80%) rename quotesdb/{.nbd/tickets/a57b95.md => .beans/quotesdb-r72e--quotesdbapi-enforce-submission-lock-on-put-apiquot.md} (87%) rename quotesdb/{.nbd/tickets/ce1e4f.md => .beans/quotesdb-ryhx--quotesdbqa.md} (61%) rename quotesdb/{.nbd/tickets/182210.md => .beans/quotesdb-shfq--triage-cloudflare-workers-wasm-size-limit-free-tie.md} (88%) rename quotesdb/{.nbd/tickets/06d304.md => .beans/quotesdb-sqho--quotesdbinfra-cloudflare-rate-limiting-waf-rules-o.md} (88%) rename quotesdb/{.nbd/tickets/2ec8b1.md => .beans/quotesdb-t0r8--triage-openapi-spec-serving-strategy-embed-yaml-at.md} (91%) rename quotesdb/{.nbd/tickets/33ed29.md => .beans/quotesdb-td4l--triage-local-dev-config-turso-file-sqlite-vs-d1-bi.md} (91%) rename quotesdb/{.nbd/tickets/03fa32.md => .beans/quotesdb-teha--filter-quotes-by-date-range-beforeafter-with-yearm.md} (95%) rename quotesdb/{.nbd/tickets/789d0f.md => .beans/quotesdb-tl2d--test-suite-get-api-openapi-spec-returned-as-valid.md} (79%) rename quotesdb/{.nbd/tickets/3f22f2.md => .beans/quotesdb-twgb--quotesdbui-admin-moderation-tab-paginated-reports.md} (82%) rename quotesdb/{.nbd/tickets/e2bd9b.md => .beans/quotesdb-tzvj--triage-cloudflare-pages-spa-routing-404-fallback-c.md} (90%) rename quotesdb/{.nbd/tickets/35685a.md => .beans/quotesdb-um1y--quotesdbapi-get-apistatus-public-endpoint.md} (92%) rename quotesdb/{.nbd/tickets/8c87db.md => .beans/quotesdb-v3dw--test-suite-delete-apiquotesid-valid-auth-204-no-bo.md} (78%) rename quotesdb/{.nbd/tickets/a23489.md => .beans/quotesdb-vsgd--define-cloudflare-workers-script-resource-wasm-art.md} (87%) rename quotesdb/{.nbd/tickets/fae330.md => .beans/quotesdb-vxrj--test-suite-post-apiquotesid-valid-auth-200-wrong-a.md} (78%) rename quotesdb/{.nbd/tickets/a91260.md => .beans/quotesdb-wizu--triage-workers-rs-compatibility-with-native-rust-t.md} (88%) rename quotesdb/{.nbd/tickets/0fbdd5.md => .beans/quotesdb-wlpv--write-srcbinuistylecss-full-stylesheet-for-all-ui.md} (92%) rename quotesdb/{.nbd/tickets/03bb91.md => .beans/quotesdb-wmvy--implement-4-word-passphrase-auth-code-generator-mu.md} (95%) rename quotesdb/{.nbd/tickets/dc3d2b.md => .beans/quotesdb-wvb8--set-up-uitrunktoml-and-uiindexhtml-build-configura.md} (90%) rename quotesdb/{.nbd/tickets/6a4c61.md => .beans/quotesdb-x2kf--submit-form-remove-submit-another-link-from-succes.md} (87%) rename quotesdb/{.nbd/tickets/68fd11.md => .beans/quotesdb-xa7q--quotesdbapi-post-apiadminreset-auth-code-endpoint.md} (93%) rename quotesdb/{.nbd/tickets/a9534d.md => .beans/quotesdb-xg67--triage-local-dev-cors-and-trunk-api-proxy-config-t.md} (87%) rename quotesdb/{.nbd/tickets/25c413.md => .beans/quotesdb-xi3i--quotesdbinfra.md} (80%) rename quotesdb/{.nbd/tickets/04f865.md => .beans/quotesdb-xqh3--implement-uisrcmainrs-yew-app-shell-browserrouter.md} (80%) rename quotesdb/{.nbd/tickets/65e220.md => .beans/quotesdb-yjpy--add-workers-rs-wasm-entry-point-to-api-binary.md} (90%) rename quotesdb/{.nbd/tickets/5137d7.md => .beans/quotesdb-yo7x--write-giteaworkflowsdeploy-uiyml-gitea-actions-wor.md} (93%) rename quotesdb/{.nbd/tickets/8a7fba.md => .beans/quotesdb-ysah--quotesdbapi-hidden-flag-for-quotes-schema-migratio.md} (84%) rename quotesdb/{.nbd/tickets/893eba.md => .beans/quotesdb-yxaa--test-suite-tag-operations-create-with-tags-list-by.md} (78%) rename quotesdb/{.nbd/tickets/0d84fa.md => .beans/quotesdb-z43c--triage-http-client-selection-for-integration-tests.md} (88%) rename quotesdb/{.nbd/tickets/4a4c26.md => .beans/quotesdb-zc1j--test-suite-put-apiquotes-create-auto-auth-code-cus.md} (82%) rename quotesdb/{.nbd/tickets/580e66.md => .beans/quotesdb-zlfi--triage-database-migration-strategy-for-cloudflare.md} (90%) rename quotesdb/{.nbd/tickets/2d1371.md => .beans/quotesdb-zzm3--set-up-infra-opentofu-project-providerstf-terrafor.md} (86%) delete mode 100644 quotesdb/.nbd/.gitignore delete mode 100644 quotesdb/.nbd/tickets/d4a624.md create mode 100755 scripts/migrate-nbd-to-beans.sh diff --git a/.beans.yml b/.beans.yml new file mode 100644 index 0000000..5d6e6cc --- /dev/null +++ b/.beans.yml @@ -0,0 +1,6 @@ +beans: + path: .beans + prefix: vibed- + id_length: 4 + default_status: todo + default_type: task diff --git a/.nbd/tickets/82df74.md b/.beans/vibed-0fcp--add-justfiles-for-all-projects-with-lint-check-bui.md similarity index 89% rename from .nbd/tickets/82df74.md rename to .beans/vibed-0fcp--add-justfiles-for-all-projects-with-lint-check-bui.md index d6c574e..0ad7171 100644 --- a/.nbd/tickets/82df74.md +++ b/.beans/vibed-0fcp--add-justfiles-for-all-projects-with-lint-check-bui.md @@ -1,10 +1,13 @@ -+++ -title = "Add justfiles for all projects with lint, check, build, build-release, and release recipes" -priority = 5 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# vibed-0fcp +title: Add justfiles for all projects with lint, check, build, build-release, and release recipes +status: todo +type: task +priority: normal +created_at: 2026-03-10T23:29:17Z +updated_at: 2026-03-10T23:29:17Z +--- + ## Background The root `TODO.md` calls for each project in the mono-repo to have a `justfile` with standard recipe names so that any contributor can run the same commands regardless of project type. `just` is a command runner similar to Make but with cleaner syntax. @@ -63,4 +66,4 @@ Not every project needs every recipe; stub missing ones with an error or a no-op - Recipe names must be consistent across all projects (`lint`, `check`, `build`, `build-release`, `release`). - Commands are run from the directory containing the `justfile`, so paths are relative to the project directory. - Add a comment above each recipe explaining what it does. -- Check whether the `just` package is already in each project's Nix dev shell (`flake.nix`); add it if missing. \ No newline at end of file +- Check whether the `just` package is already in each project's Nix dev shell (`flake.nix`); add it if missing. diff --git a/.nbd/tickets/09cda0.md b/.beans/vibed-wqsu--add-contact-footer-to-all-service-front-ends.md similarity index 89% rename from .nbd/tickets/09cda0.md rename to .beans/vibed-wqsu--add-contact-footer-to-all-service-front-ends.md index f286c80..d3790fe 100644 --- a/.nbd/tickets/09cda0.md +++ b/.beans/vibed-wqsu--add-contact-footer-to-all-service-front-ends.md @@ -1,10 +1,13 @@ -+++ -title = "Add contact footer to all service front-ends" -priority = 3 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# vibed-wqsu +title: Add contact footer to all service front-ends +status: todo +type: task +priority: low +created_at: 2026-03-10T23:29:17Z +updated_at: 2026-03-10T23:29:17Z +--- + ## Background The root `TODO.md` calls for a footer on every service front-end with contact info: @@ -61,4 +64,4 @@ Simplest option: add `footer.html` fragment via `[output.html] additional-js` ha - `edu/theme/index.hbs` (new — copy from mdbook default, add footer) - `edu/book.toml` (may need `[output.html] theme = "theme"` entry) -- `quotesdb/ui/src/components/footer.rs` (new) or similar \ No newline at end of file +- `quotesdb/ui/src/components/footer.rs` (new) or similar diff --git a/.claude/settings.json b/.claude/settings.json index e373568..a2152d4 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -3,5 +3,13 @@ "superpowers@claude-plugins-official": true, "plugin-dev@claude-plugins-official": true, "rust-analyzer-lsp@claude-plugins-official": true + }, + "hooks": { + "SessionStart": [ + { "hooks": [{ "type": "command", "command": "beans prime" }] } + ], + "PreCompact": [ + { "hooks": [{ "type": "command", "command": "beans prime" }] } + ] } } diff --git a/CLAUDE.md b/CLAUDE.md index fff02e4..184a91f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -327,59 +327,60 @@ Covers: -## Task Tracking with nbd +**IMPORTANT**: before you do anything else, run the `beans prime` command and heed its output. -`nbd` is a CLI tool for managing work tickets, designed for agent workflows. +## Task Tracking with beans + +`beans` is a CLI tool for managing work tickets (called "beans"), designed for agent workflows. ### Initialisation ```sh -nbd init +beans init ``` -Run once in the project root. Creates `.nbd/tickets/`. Safe to run multiple times. +Run once in the project root. Creates `.beans/`. Safe to run multiple times. ### Core commands ```sh -# Create a new ticket (use --ftype md for a human-readable body) -nbd create --title "Add OAuth login" --type feature --priority 7 --ftype md --json +# Create a new bean +beans create --json "Add OAuth login" --type feature --priority high --status todo -# List all open tickets (sorted by priority) -nbd list --json +# List all beans +beans list --json -# Read a specific ticket -nbd read --json +# Show a specific bean +beans show --json -# Update a ticket -nbd update --status in_progress --json -nbd update --status done --json +# Update a bean +beans update --json --status in-progress +beans update --json --status completed ``` ### Finding what to work on ```sh -# All tickets that are unblocked and ready to start -nbd ready --json +# All beans that are unblocked and ready to start +beans list --json --ready -# The single highest-priority unblocked ticket -nbd next --json +# Filter by type or status +beans list --json --type bug --status todo ``` ### Workflow -1. **Before starting** — create a ticket: `nbd create --title "..." --ftype md --json` -2. **When starting** — mark it in progress: `nbd update --status in_progress --json` -3. **When done** — mark it complete: `nbd update --status done --json` +1. **Before starting** — create a bean: `beans create --json "..." --type task --status todo` +2. **When starting** — mark it in progress: `beans update --json --status in-progress` +3. **When done** — mark it complete: `beans update --json --status completed` ### Guidelines - **Always pass `--json`** to every command for structured, unambiguous output. -- **Always pass `--ftype md`** when creating tickets — markdown format keeps the body human-readable. - Use `jq` to parse and transform JSON output when needed. -- Priority scale 0–10: use **7–9** for bugs, **5** for normal tasks, **3** for nice-to-haves. -- `--type` choices: `project`, `feature`, `task`, `bug`. -- Use `--deps id1,id2` to express blockers — tickets that must be done first. -- Create tickets *before* starting non-trivial tasks, not after. +- `--priority` choices: `critical`, `high`, `normal`, `low`, `deferred`. +- `--type` choices: `milestone`, `epic`, `feature`, `task`, `bug`. +- Use `--blocked-by ` to express blockers — beans that must be done first. +- Create beans *before* starting non-trivial tasks, not after. diff --git a/edu/.beans.yml b/edu/.beans.yml new file mode 100644 index 0000000..aecb97c --- /dev/null +++ b/edu/.beans.yml @@ -0,0 +1,6 @@ +beans: + path: .beans + prefix: edu- + id_length: 4 + default_status: todo + default_type: task diff --git a/edu/.nbd/tickets/64826a.md b/edu/.beans/edu-0w1v--markov-exercise-simulating-a-random-walk-rust.md similarity index 75% rename from edu/.nbd/tickets/64826a.md rename to edu/.beans/edu-0w1v--markov-exercise-simulating-a-random-walk-rust.md index 820b354..55f9a47 100644 --- a/edu/.nbd/tickets/64826a.md +++ b/edu/.beans/edu-0w1v--markov-exercise-simulating-a-random-walk-rust.md @@ -1,8 +1,11 @@ -+++ -title = "Markov exercise: Simulating a Random Walk (Rust)" -priority = 7 -status = "archived" -ticket_type = "task" -dependencies = [] -+++ -Write Section 5 of edu/markov.md: Exercise 2 — Simulating a Random Walk\n\nLearning objectives:\n- Model a countably-finite state space (bounded integers) in Rust\n- Implement reflecting boundary conditions\n- Aggregate results from many trials into a histogram\n\nContent to produce:\n- Setup instructions (reuse or extend Exercise 1 project)\n- Step-by-step hints:\n 1. Define RandomWalk with min, max, prob_right fields\n 2. Implement step with boundary reflection (clamp or reverse)\n 3. Implement histogram by running simulate() many times\n 4. Print histogram as ASCII bar chart\n 5. Observe convergence toward uniform (symmetric walk) or skewed (asymmetric)\n- Full reference solution\n\nTarget: replace the stub in edu/markov.md §5 \ No newline at end of file +--- +# edu-0w1v +title: 'Markov exercise: Simulating a Random Walk (Rust)' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 5 of edu/markov.md: Exercise 2 — Simulating a Random Walk\n\nLearning objectives:\n- Model a countably-finite state space (bounded integers) in Rust\n- Implement reflecting boundary conditions\n- Aggregate results from many trials into a histogram\n\nContent to produce:\n- Setup instructions (reuse or extend Exercise 1 project)\n- Step-by-step hints:\n 1. Define RandomWalk with min, max, prob_right fields\n 2. Implement step with boundary reflection (clamp or reverse)\n 3. Implement histogram by running simulate() many times\n 4. Print histogram as ASCII bar chart\n 5. Observe convergence toward uniform (symmetric walk) or skewed (asymmetric)\n- Full reference solution\n\nTarget: replace the stub in edu/markov.md §5 diff --git a/edu/.nbd/tickets/685f5e.md b/edu/.beans/edu-16fy--6-recognizing-atoms-integers-booleans-strings-symb.md similarity index 96% rename from edu/.nbd/tickets/685f5e.md rename to edu/.beans/edu-16fy--6-recognizing-atoms-integers-booleans-strings-symb.md index 4a2b463..ca36db7 100644 --- a/edu/.nbd/tickets/685f5e.md +++ b/edu/.beans/edu-16fy--6-recognizing-atoms-integers-booleans-strings-symb.md @@ -1,10 +1,12 @@ -+++ -title = "§6 Recognizing Atoms: Integers, Booleans, Strings, Symbols" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-16fy +title: '§6 Recognizing Atoms: Integers, Booleans, Strings, Symbols' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- ## §6 Recognizing Atoms: Integers, Booleans, Strings, Symbols — Stub to fill diff --git a/edu/.nbd/tickets/fbf323.md b/edu/.beans/edu-18qe--markov-lesson-what-is-a-markov-chain.md similarity index 68% rename from edu/.nbd/tickets/fbf323.md rename to edu/.beans/edu-18qe--markov-lesson-what-is-a-markov-chain.md index c71f796..9717c41 100644 --- a/edu/.nbd/tickets/fbf323.md +++ b/edu/.beans/edu-18qe--markov-lesson-what-is-a-markov-chain.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: What Is a Markov Chain?" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 1 of edu/markov.md: 'What Is a Markov Chain?'\n\nLearning objectives:\n- Define the Markov property (memorylessness)\n- Give 3–4 concrete real-world examples (weather, board games, web surfing, genetics)\n- Explain why the Markov property is a useful modelling assumption\n- Introduce the notation P(Xₙ₊₁ = s | X₀, …, Xₙ) = P(Xₙ₊₁ = s | Xₙ)\n\nContent to produce:\n- 3–5 paragraphs of prose\n- At least one illustrative example worked through informally\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §1 \ No newline at end of file +--- +# edu-18qe +title: 'Markov lesson: What Is a Markov Chain?' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- + +Write Section 1 of edu/markov.md: 'What Is a Markov Chain?'\n\nLearning objectives:\n- Define the Markov property (memorylessness)\n- Give 3–4 concrete real-world examples (weather, board games, web surfing, genetics)\n- Explain why the Markov property is a useful modelling assumption\n- Introduce the notation P(Xₙ₊₁ = s | X₀, …, Xₙ) = P(Xₙ₊₁ = s | Xₙ)\n\nContent to produce:\n- 3–5 paragraphs of prose\n- At least one illustrative example worked through informally\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §1 diff --git a/edu/.nbd/tickets/5ed295.md b/edu/.beans/edu-1oh8--12-exercise-5-retrieval-augmented-generation.md similarity index 93% rename from edu/.nbd/tickets/5ed295.md rename to edu/.beans/edu-1oh8--12-exercise-5-retrieval-augmented-generation.md index 949c155..6aec3ae 100644 --- a/edu/.nbd/tickets/5ed295.md +++ b/edu/.beans/edu-1oh8--12-exercise-5-retrieval-augmented-generation.md @@ -1,10 +1,13 @@ -+++ -title = "§12 Exercise 5: Retrieval-Augmented Generation" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-1oh8 +title: '§12 Exercise 5: Retrieval-Augmented Generation' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## §12 Exercise 5 — Retrieval-Augmented Generation — Stub to fill File: `edu/src/vector-db.md`, section `### 12. Exercise 5 — Retrieval-Augmented Generation` @@ -87,4 +90,4 @@ Print the retrieved passages first (so the reader can see what context was used) ## Reference solution -Full `main.rs` inside `
`. Keep `retrieve`, `build_prompt`, and `call_llm` as clearly named separate functions. The `main` function should be a thin orchestrator. \ No newline at end of file +Full `main.rs` inside `
`. Keep `retrieve`, `build_prompt`, and `call_llm` as clearly named separate functions. The `main` function should be a thin orchestrator. diff --git a/edu/.nbd/tickets/5994a6.md b/edu/.beans/edu-34co--markov-lesson-applications-and-further-reading.md similarity index 78% rename from edu/.nbd/tickets/5994a6.md rename to edu/.beans/edu-34co--markov-lesson-applications-and-further-reading.md index c722890..40104c0 100644 --- a/edu/.nbd/tickets/5994a6.md +++ b/edu/.beans/edu-34co--markov-lesson-applications-and-further-reading.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: Applications and Further Reading" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 10 of edu/markov.md: 'Applications and Further Reading'\n\nLearning objectives:\n- Survey real-world applications: PageRank, MCMC, HMMs, RL, bioinformatics\n- Give a 2–3 sentence description of each application and how Markov chains appear\n- Point to concrete next steps for learners who want to go deeper\n\nContent to produce:\n- Application survey (5–7 topics, each 2–3 sentences)\n- Annotated reading list:\n * 'Introduction to Probability' (Blitzstein & Hwang) — free PDF\n * 'Markov Chains' (Norris) — rigorous treatment\n * Sutton & Barto 'Reinforcement Learning' — RL connection\n * The Metropolis-Hastings algorithm article on Wikipedia\n- Rust ecosystem pointers (crates for probabilistic modelling)\n\nTarget: replace the stub in edu/markov.md §10 \ No newline at end of file +--- +# edu-34co +title: 'Markov lesson: Applications and Further Reading' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 10 of edu/markov.md: 'Applications and Further Reading'\n\nLearning objectives:\n- Survey real-world applications: PageRank, MCMC, HMMs, RL, bioinformatics\n- Give a 2–3 sentence description of each application and how Markov chains appear\n- Point to concrete next steps for learners who want to go deeper\n\nContent to produce:\n- Application survey (5–7 topics, each 2–3 sentences)\n- Annotated reading list:\n * 'Introduction to Probability' (Blitzstein & Hwang) — free PDF\n * 'Markov Chains' (Norris) — rigorous treatment\n * Sutton & Barto 'Reinforcement Learning' — RL connection\n * The Metropolis-Hastings algorithm article on Wikipedia\n- Rust ecosystem pointers (crates for probabilistic modelling)\n\nTarget: replace the stub in edu/markov.md §10 diff --git a/edu/.nbd/tickets/6d40a7.md b/edu/.beans/edu-3sww--11-checking-special-forms.md similarity index 96% rename from edu/.nbd/tickets/6d40a7.md rename to edu/.beans/edu-3sww--11-checking-special-forms.md index 9927029..7d7b41c 100644 --- a/edu/.nbd/tickets/6d40a7.md +++ b/edu/.beans/edu-3sww--11-checking-special-forms.md @@ -1,10 +1,12 @@ -+++ -title = "§11 Checking Special Forms" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-3sww +title: §11 Checking Special Forms +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- ## §11 Checking Special Forms — Stub to fill diff --git a/edu/.nbd/tickets/1f995a.md b/edu/.beans/edu-4gok--markov-exercise-n-gram-generalization-rust.md similarity index 78% rename from edu/.nbd/tickets/1f995a.md rename to edu/.beans/edu-4gok--markov-exercise-n-gram-generalization-rust.md index ed85370..a7359d4 100644 --- a/edu/.nbd/tickets/1f995a.md +++ b/edu/.beans/edu-4gok--markov-exercise-n-gram-generalization-rust.md @@ -1,8 +1,11 @@ -+++ -title = "Markov exercise: N-gram Generalization (Rust)" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 8 of edu/markov.md: Exercise 4 — N-gram Generalization\n\nLearning objectives:\n- Generalize from bigrams to arbitrary-order n-gram chains\n- Use Vec as a HashMap key (or a joined string)\n- Empirically compare output quality for n = 1, 2, 3, 4\n\nContent to produce:\n- Setup instructions (extend Exercise 3 project)\n- Step-by-step hints:\n 1. Modify train to use a sliding window of n words as the key\n 2. Modify generate to maintain a deque/window of the last n words\n 3. Run on the same corpus with n = 1, 2, 3, 4 and print 50 words each\n 4. Discuss observations: when does it start memorising the corpus?\n- Full reference solution\n- Stretch goal: implement character-level n-grams instead of word-level\n\nTarget: replace the stub in edu/markov.md §8 \ No newline at end of file +--- +# edu-4gok +title: 'Markov exercise: N-gram Generalization (Rust)' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + +Write Section 8 of edu/markov.md: Exercise 4 — N-gram Generalization\n\nLearning objectives:\n- Generalize from bigrams to arbitrary-order n-gram chains\n- Use Vec as a HashMap key (or a joined string)\n- Empirically compare output quality for n = 1, 2, 3, 4\n\nContent to produce:\n- Setup instructions (extend Exercise 3 project)\n- Step-by-step hints:\n 1. Modify train to use a sliding window of n words as the key\n 2. Modify generate to maintain a deque/window of the last n words\n 3. Run on the same corpus with n = 1, 2, 3, 4 and print 50 words each\n 4. Discuss observations: when does it start memorising the corpus?\n- Full reference solution\n- Stretch goal: implement character-level n-grams instead of word-level\n\nTarget: replace the stub in edu/markov.md §8 diff --git a/edu/.nbd/tickets/3e1250.md b/edu/.beans/edu-4kkb--12-the-c-runtime-preamble.md similarity index 96% rename from edu/.nbd/tickets/3e1250.md rename to edu/.beans/edu-4kkb--12-the-c-runtime-preamble.md index 1108965..042a714 100644 --- a/edu/.nbd/tickets/3e1250.md +++ b/edu/.beans/edu-4kkb--12-the-c-runtime-preamble.md @@ -1,10 +1,12 @@ -+++ -title = "§12 The C Runtime Preamble" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-4kkb +title: §12 The C Runtime Preamble +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §12 The C Runtime Preamble — Stub to fill diff --git a/edu/.nbd/tickets/0fbe1a.md b/edu/.beans/edu-4u7w--edu-write-chapter-on-shader-programming.md similarity index 87% rename from edu/.nbd/tickets/0fbe1a.md rename to edu/.beans/edu-4u7w--edu-write-chapter-on-shader-programming.md index 54cba5e..379f7de 100644 --- a/edu/.nbd/tickets/0fbe1a.md +++ b/edu/.beans/edu-4u7w--edu-write-chapter-on-shader-programming.md @@ -1,10 +1,13 @@ -+++ -title = "edu: write chapter on shader programming" -priority = 3 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-4u7w +title: 'edu: write chapter on shader programming' +status: todo +type: task +priority: low +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## Background From `edu/TODO.md`: Hands-on: Shader programming. @@ -46,4 +49,4 @@ A practical introduction to GPU shaders, written with Rust as the host language. ## File to create - `edu/src/shaders.md` -- Add to `edu/src/SUMMARY.md` under a `# Graphics` section \ No newline at end of file +- Add to `edu/src/SUMMARY.md` under a `# Graphics` section diff --git a/edu/.nbd/tickets/1eb794.md b/edu/.beans/edu-63ze--13-generating-c-atoms-and-expressions.md similarity index 96% rename from edu/.nbd/tickets/1eb794.md rename to edu/.beans/edu-63ze--13-generating-c-atoms-and-expressions.md index 70cb711..495b6a4 100644 --- a/edu/.nbd/tickets/1eb794.md +++ b/edu/.beans/edu-63ze--13-generating-c-atoms-and-expressions.md @@ -1,10 +1,12 @@ -+++ -title = "§13 Generating C: Atoms and Expressions" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-63ze +title: '§13 Generating C: Atoms and Expressions' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §13 Generating C: Atoms and Expressions — Stub to fill diff --git a/edu/.nbd/tickets/74be50.md b/edu/.beans/edu-6r70--markov-exercise-bigram-text-generator-rust.md similarity index 77% rename from edu/.nbd/tickets/74be50.md rename to edu/.beans/edu-6r70--markov-exercise-bigram-text-generator-rust.md index baecd36..d7a6d62 100644 --- a/edu/.nbd/tickets/74be50.md +++ b/edu/.beans/edu-6r70--markov-exercise-bigram-text-generator-rust.md @@ -1,8 +1,11 @@ -+++ -title = "Markov exercise: Bigram Text Generator (Rust)" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 7 of edu/markov.md: Exercise 3 — Bigram Text Generator\n\nLearning objectives:\n- Build a HashMap-based transition table from a text corpus\n- Implement weighted random sampling over successor words\n- Generate and print novel word sequences from a seed\n\nContent to produce:\n- Setup instructions (new Cargo project or extend previous, add rand crate)\n- Step-by-step hints:\n 1. Tokenize corpus into words (split_whitespace)\n 2. Build BigramModel::train by iterating consecutive word pairs\n 3. Implement weighted sampling in generate (accumulate weights, compare to rng draw)\n 4. Handle end-of-chain gracefully (seed word not in model)\n 5. Try with a public-domain text (e.g., Project Gutenberg excerpt)\n- Full reference solution\n\nTarget: replace the stub in edu/markov.md §7 \ No newline at end of file +--- +# edu-6r70 +title: 'Markov exercise: Bigram Text Generator (Rust)' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 7 of edu/markov.md: Exercise 3 — Bigram Text Generator\n\nLearning objectives:\n- Build a HashMap-based transition table from a text corpus\n- Implement weighted random sampling over successor words\n- Generate and print novel word sequences from a seed\n\nContent to produce:\n- Setup instructions (new Cargo project or extend previous, add rand crate)\n- Step-by-step hints:\n 1. Tokenize corpus into words (split_whitespace)\n 2. Build BigramModel::train by iterating consecutive word pairs\n 3. Implement weighted sampling in generate (accumulate weights, compare to rng draw)\n 4. Handle end-of-chain gracefully (seed word not in model)\n 5. Try with a public-domain text (e.g., Project Gutenberg excerpt)\n- Full reference solution\n\nTarget: replace the stub in edu/markov.md §7 diff --git a/edu/.nbd/tickets/257a2a.md b/edu/.beans/edu-7cp2--markov-exercise-weather-model-rust.md similarity index 79% rename from edu/.nbd/tickets/257a2a.md rename to edu/.beans/edu-7cp2--markov-exercise-weather-model-rust.md index 3e73730..d6933b0 100644 --- a/edu/.nbd/tickets/257a2a.md +++ b/edu/.beans/edu-7cp2--markov-exercise-weather-model-rust.md @@ -1,8 +1,11 @@ -+++ -title = "Markov exercise: Weather Model (Rust)" -priority = 7 -status = "archived" -ticket_type = "task" -dependencies = [] -+++ -Write Section 4 of edu/markov.md: Exercise 1 — Weather Model\n\nLearning objectives:\n- Translate a transition matrix into a Rust struct\n- Use a weighted random draw to implement a single Markov step\n- Run a simulation and print or collect the resulting sequence\n\nContent to produce:\n- Setup instructions (new Cargo project, add rand crate)\n- Step-by-step hints:\n 1. Define the Weather enum and index conversion\n 2. Implement WeatherChain::step using rand::Rng::gen::()\n 3. Implement WeatherChain::simulate as a loop collecting states\n 4. Run with transition matrix [[0.8, 0.2], [0.4, 0.6]] from Sunny\n 5. Count sunny vs rainy days and compare to stationary distribution\n- Full reference solution (collapsed or at end)\n\nTarget: replace the stub in edu/markov.md §4 \ No newline at end of file +--- +# edu-7cp2 +title: 'Markov exercise: Weather Model (Rust)' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + +Write Section 4 of edu/markov.md: Exercise 1 — Weather Model\n\nLearning objectives:\n- Translate a transition matrix into a Rust struct\n- Use a weighted random draw to implement a single Markov step\n- Run a simulation and print or collect the resulting sequence\n\nContent to produce:\n- Setup instructions (new Cargo project, add rand crate)\n- Step-by-step hints:\n 1. Define the Weather enum and index conversion\n 2. Implement WeatherChain::step using rand::Rng::gen::()\n 3. Implement WeatherChain::simulate as a loop collecting states\n 4. Run with transition matrix [[0.8, 0.2], [0.4, 0.6]] from Sunny\n 5. Count sunny vs rainy days and compare to stationary distribution\n- Full reference solution (collapsed or at end)\n\nTarget: replace the stub in edu/markov.md §4 diff --git a/edu/.nbd/tickets/b7c95f.md b/edu/.beans/edu-91j2--vector-db.md similarity index 85% rename from edu/.nbd/tickets/b7c95f.md rename to edu/.beans/edu-91j2--vector-db.md index de6237d..8876898 100644 --- a/edu/.nbd/tickets/b7c95f.md +++ b/edu/.beans/edu-91j2--vector-db.md @@ -1,10 +1,26 @@ -+++ -title = "vector-db" -priority = 5 -status = "done" -ticket_type = "project" -dependencies = ["21d9be", "584e0c", "99e1d9", "d9f850", "6ec5ff", "37cdd5", "081a55", "5674ce", "4c961f", "1ef9f4", "e8be9a", "5ed295"] -+++ +--- +# edu-91j2 +title: vector-db +status: completed +type: epic +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:04Z +blocked_by: + - edu-mlut + - edu-hvic + - edu-twtl + - edu-hvmi + - edu-uz3e + - edu-ic66 + - edu-pdeo + - edu-paqf + - edu-c98s + - edu-ga52 + - edu-dgfl + - edu-1oh8 +--- + ## Project: Vector Database Self-Guided Course This is the top-level project ticket for `edu/src/vector-db.md` — a self-guided mdbook course on vector databases in the **Vibed Learning** site (`edu/`). @@ -47,4 +63,4 @@ The course is modelled on `edu/src/markov.md`. It teaches vector databases throu - **KNN query:** `vector_top_k('table', vector('[...]'), k)` table-valued function - **Distance function:** `vector_distance_cos(a, b)` — 0 = identical, 2 = opposite -This project ticket closes when all 12 section tickets are done and `mdbook build` passes. \ No newline at end of file +This project ticket closes when all 12 section tickets are done and `mdbook build` passes. diff --git a/edu/.nbd/tickets/92a829.md b/edu/.beans/edu-9kuk--markov-lesson-text-generation-with-markov-chains.md similarity index 71% rename from edu/.nbd/tickets/92a829.md rename to edu/.beans/edu-9kuk--markov-lesson-text-generation-with-markov-chains.md index b99f8f5..aa7daa0 100644 --- a/edu/.nbd/tickets/92a829.md +++ b/edu/.beans/edu-9kuk--markov-lesson-text-generation-with-markov-chains.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: Text Generation with Markov Chains" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 6 of edu/markov.md: 'Text Generation with Markov Chains'\n\nLearning objectives:\n- Explain how words (or characters) become states in a text Markov chain\n- Define bigrams and how they form a transition table from a corpus\n- Discuss why generated text sounds locally plausible but globally incoherent\n- Introduce the concept of order-n chains and the tradeoff between coherence and novelty\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A short worked bigram example from a 2-sentence sample text (show the table)\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §6 \ No newline at end of file +--- +# edu-9kuk +title: 'Markov lesson: Text Generation with Markov Chains' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 6 of edu/markov.md: 'Text Generation with Markov Chains'\n\nLearning objectives:\n- Explain how words (or characters) become states in a text Markov chain\n- Define bigrams and how they form a transition table from a corpus\n- Discuss why generated text sounds locally plausible but globally incoherent\n- Introduce the concept of order-n chains and the tradeoff between coherence and novelty\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A short worked bigram example from a 2-sentence sample text (show the table)\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §6 diff --git a/edu/.nbd/tickets/44ebe7.md b/edu/.beans/edu-a1al--markov-lesson-transition-probabilities-and-matrice.md similarity index 72% rename from edu/.nbd/tickets/44ebe7.md rename to edu/.beans/edu-a1al--markov-lesson-transition-probabilities-and-matrice.md index 23e330b..10d4cc3 100644 --- a/edu/.nbd/tickets/44ebe7.md +++ b/edu/.beans/edu-a1al--markov-lesson-transition-probabilities-and-matrice.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: Transition Probabilities and Matrices" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 3 of edu/markov.md: 'Transition Probabilities and Matrices'\n\nLearning objectives:\n- Formally define the transition matrix P where P[i][j] = P(next=j | current=i)\n- Explain the stochastic matrix constraint: all rows sum to 1, all entries ≥ 0\n- Show how to compute the distribution after k steps: π₀ Pᵏ\n- Work through a 2×2 weather-model example by hand\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A worked numeric example (2-state weather chain)\n- LaTeX-style or plain-text matrix notation\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §3 \ No newline at end of file +--- +# edu-a1al +title: 'Markov lesson: Transition Probabilities and Matrices' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + +Write Section 3 of edu/markov.md: 'Transition Probabilities and Matrices'\n\nLearning objectives:\n- Formally define the transition matrix P where P[i][j] = P(next=j | current=i)\n- Explain the stochastic matrix constraint: all rows sum to 1, all entries ≥ 0\n- Show how to compute the distribution after k steps: π₀ Pᵏ\n- Work through a 2×2 weather-model example by hand\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A worked numeric example (2-state weather chain)\n- LaTeX-style or plain-text matrix notation\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §3 diff --git a/edu/.nbd/tickets/8618e4.md b/edu/.beans/edu-al3r--edu-write-chapter-on-co-op-worker-owned-business-s.md similarity index 86% rename from edu/.nbd/tickets/8618e4.md rename to edu/.beans/edu-al3r--edu-write-chapter-on-co-op-worker-owned-business-s.md index b574604..a067171 100644 --- a/edu/.nbd/tickets/8618e4.md +++ b/edu/.beans/edu-al3r--edu-write-chapter-on-co-op-worker-owned-business-s.md @@ -1,10 +1,13 @@ -+++ -title = "edu: write chapter on co-op worker-owned business structure" -priority = 3 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-al3r +title: 'edu: write chapter on co-op worker-owned business structure' +status: todo +type: task +priority: low +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## Background From `edu/TODO.md`: write a chapter about how to structure a co-op profit-sharing worker-owned business. @@ -28,4 +31,4 @@ This is a conceptual/informational chapter, not a Rust hands-on. It fits natural ## Notes -This chapter is explicitly not intended to be authoritative legal or financial advice — add the standard AI-generated disclaimer. \ No newline at end of file +This chapter is explicitly not intended to be authoritative legal or financial advice — add the standard AI-generated disclaimer. diff --git a/edu/.nbd/tickets/a93829.md b/edu/.beans/edu-azf5--2-minilisp-language-specification.md similarity index 96% rename from edu/.nbd/tickets/a93829.md rename to edu/.beans/edu-azf5--2-minilisp-language-specification.md index 3095a8f..53ee465 100644 --- a/edu/.nbd/tickets/a93829.md +++ b/edu/.beans/edu-azf5--2-minilisp-language-specification.md @@ -1,10 +1,12 @@ -+++ -title = "§2 MiniLisp Language Specification" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-azf5 +title: §2 MiniLisp Language Specification +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §2 MiniLisp Language Specification — Stub to fill diff --git a/edu/.nbd/tickets/67e284.md b/edu/.beans/edu-b73b--course-writing-a-lisp-to-c-compiler-in-rust.md similarity index 80% rename from edu/.nbd/tickets/67e284.md rename to edu/.beans/edu-b73b--course-writing-a-lisp-to-c-compiler-in-rust.md index 5bc7338..465216c 100644 --- a/edu/.nbd/tickets/67e284.md +++ b/edu/.beans/edu-b73b--course-writing-a-lisp-to-c-compiler-in-rust.md @@ -1,10 +1,31 @@ -+++ -title = "Course: Writing a Lisp-to-C Compiler in Rust" -priority = 5 -status = "done" -ticket_type = "project" -dependencies = ["e8da8b", "a93829", "3aeb62", "5835e9", "3dc36b", "685f5e", "a1a827", "b6c9ad", "a4c9f8", "d0b9f8", "6d40a7", "3e1250", "1eb794", "cbc6e3", "de82f1", "58b37a", "8fa47a", "1d16da"] -+++ +--- +# edu-b73b +title: 'Course: Writing a Lisp-to-C Compiler in Rust' +status: completed +type: epic +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:03Z +blocked_by: + - edu-ylb8 + - edu-azf5 + - edu-n9ap + - edu-jzvr + - edu-g1r5 + - edu-16fy + - edu-n7zb + - edu-mmbr + - edu-tzzh + - edu-h3yx + - edu-3sww + - edu-4kkb + - edu-63ze + - edu-pyue + - edu-unus + - edu-nc61 + - edu-v0ud + - edu-y4e6 +--- ## Course: Writing a Lisp-to-C Compiler in Rust diff --git a/edu/.nbd/tickets/4c961f.md b/edu/.beans/edu-c98s--9-generating-embeddings-in-rust.md similarity index 94% rename from edu/.nbd/tickets/4c961f.md rename to edu/.beans/edu-c98s--9-generating-embeddings-in-rust.md index 2ca7dfa..038d8cf 100644 --- a/edu/.nbd/tickets/4c961f.md +++ b/edu/.beans/edu-c98s--9-generating-embeddings-in-rust.md @@ -1,10 +1,13 @@ -+++ -title = "§9 Generating Embeddings in Rust" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-c98s +title: §9 Generating Embeddings in Rust +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## §9 Generating Embeddings in Rust — Stub to fill File: `edu/src/vector-db.md`, section `### 9. Generating Embeddings in Rust` @@ -60,4 +63,4 @@ Show a minimal async function that POSTs to the embeddings endpoint and returns **Choosing between them.** Recommend fastembed for §10–§12 because: no API key, no network dependency, deterministic results (important for exercises), sub-100ms per batch on CPU. Use the HTTP approach when you need a specific production-grade model or have one already deployed. -**Dimensionality note.** The `F32_BLOB(d)` column type must match the model's output dimension exactly — you cannot mix dimensions. Change the DDL from the toy `F32_BLOB(3)` used in §6–§8 to `F32_BLOB(384)` for BGE-Small, `F32_BLOB(768)` for all-MiniLM-L6-v2, or `F32_BLOB(1536)` for OpenAI text-embedding-3-small. The index must also be dropped and recreated if you change the dimension. \ No newline at end of file +**Dimensionality note.** The `F32_BLOB(d)` column type must match the model's output dimension exactly — you cannot mix dimensions. Change the DDL from the toy `F32_BLOB(3)` used in §6–§8 to `F32_BLOB(384)` for BGE-Small, `F32_BLOB(768)` for all-MiniLM-L6-v2, or `F32_BLOB(1536)` for OpenAI text-embedding-3-small. The index must also be dropped and recreated if you change the dimension. diff --git a/edu/.nbd/tickets/8f14c6.md b/edu/.beans/edu-coqp--edu-write-machine-learning-chapter-self-play-game.md similarity index 88% rename from edu/.nbd/tickets/8f14c6.md rename to edu/.beans/edu-coqp--edu-write-machine-learning-chapter-self-play-game.md index 064b727..3428708 100644 --- a/edu/.nbd/tickets/8f14c6.md +++ b/edu/.beans/edu-coqp--edu-write-machine-learning-chapter-self-play-game.md @@ -1,10 +1,13 @@ -+++ -title = "edu: write Machine Learning chapter (self-play game AI, Alpha Go Zero style)" -priority = 3 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-coqp +title: 'edu: write Machine Learning chapter (self-play game AI, Alpha Go Zero style)' +status: todo +type: task +priority: low +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## Background From `edu/TODO.md`: Hands-on: Machine Learning; training a computer to play a game by playing against itself (a-la Alpha Go Zero). @@ -40,4 +43,4 @@ A self-play reinforcement learning course. The practical focus is implementing a ## File to create - `edu/src/ml-self-play.md` -- Add to `edu/src/SUMMARY.md` under a `# Machine Learning` section \ No newline at end of file +- Add to `edu/src/SUMMARY.md` under a `# Machine Learning` section diff --git a/edu/.nbd/tickets/e8be9a.md b/edu/.beans/edu-dgfl--11-exercise-4-recommendation-engine.md similarity index 92% rename from edu/.nbd/tickets/e8be9a.md rename to edu/.beans/edu-dgfl--11-exercise-4-recommendation-engine.md index 935d3fe..9a69623 100644 --- a/edu/.nbd/tickets/e8be9a.md +++ b/edu/.beans/edu-dgfl--11-exercise-4-recommendation-engine.md @@ -1,10 +1,13 @@ -+++ -title = "§11 Exercise 4: Recommendation Engine" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-dgfl +title: '§11 Exercise 4: Recommendation Engine' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- + ## §11 Exercise 4 — Recommendation Engine — Stub to fill File: `edu/src/vector-db.md`, section `### 11. Exercise 4 — Recommendation Engine` @@ -68,4 +71,4 @@ Output format: `"Customers who liked Laptop also liked: Mechanical Keyboard (0.0 ## Reference solution -Full `main.rs` inside `
`. The `recommend` function should be clearly separated from the setup boilerplate. The recommendation query pattern (SELECT embedding → feed as query to vector_top_k) is the key technique to highlight. \ No newline at end of file +Full `main.rs` inside `
`. The `recommend` function should be clearly separated from the setup boilerplate. The recommendation query pattern (SELECT embedding → feed as query to vector_top_k) is the key technique to highlight. diff --git a/edu/.nbd/tickets/3dc36b.md b/edu/.beans/edu-g1r5--5-setting-up-the-project.md similarity index 94% rename from edu/.nbd/tickets/3dc36b.md rename to edu/.beans/edu-g1r5--5-setting-up-the-project.md index a8af53a..1d02633 100644 --- a/edu/.nbd/tickets/3dc36b.md +++ b/edu/.beans/edu-g1r5--5-setting-up-the-project.md @@ -1,10 +1,12 @@ -+++ -title = "§5 Setting Up the Project" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-g1r5 +title: §5 Setting Up the Project +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §5 Setting Up the Project — Stub to fill diff --git a/edu/.nbd/tickets/1ef9f4.md b/edu/.beans/edu-ga52--10-exercise-3-semantic-document-search.md similarity index 95% rename from edu/.nbd/tickets/1ef9f4.md rename to edu/.beans/edu-ga52--10-exercise-3-semantic-document-search.md index 94152ff..b9e4094 100644 --- a/edu/.nbd/tickets/1ef9f4.md +++ b/edu/.beans/edu-ga52--10-exercise-3-semantic-document-search.md @@ -1,10 +1,13 @@ -+++ -title = "§10 Exercise 3: Semantic Document Search" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-ga52 +title: '§10 Exercise 3: Semantic Document Search' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## §10 Exercise 3 — Semantic Document Search — Stub to fill File: `edu/src/vector-db.md`, section `### 10. Exercise 3 — Semantic Document Search` @@ -77,4 +80,4 @@ Print results ranked by distance with the passage text. ## Reference solution -Full self-contained `main.rs` inside `
`: creates table, embeds and inserts all 15 passages, runs three queries, prints results. \ No newline at end of file +Full self-contained `main.rs` inside `
`: creates table, embeds and inserts all 15 passages, runs three queries, prints results. diff --git a/edu/.nbd/tickets/d0b9f8.md b/edu/.beans/edu-h3yx--10-symbol-tables-and-scope.md similarity index 97% rename from edu/.nbd/tickets/d0b9f8.md rename to edu/.beans/edu-h3yx--10-symbol-tables-and-scope.md index dc7ae3e..c211f12 100644 --- a/edu/.nbd/tickets/d0b9f8.md +++ b/edu/.beans/edu-h3yx--10-symbol-tables-and-scope.md @@ -1,10 +1,12 @@ -+++ -title = "§10 Symbol Tables and Scope" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-h3yx +title: §10 Symbol Tables and Scope +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §10 Symbol Tables and Scope — Stub to fill diff --git a/edu/.nbd/tickets/584e0c.md b/edu/.beans/edu-hvic--2-embeddings.md similarity index 93% rename from edu/.nbd/tickets/584e0c.md rename to edu/.beans/edu-hvic--2-embeddings.md index 42245eb..9c42f20 100644 --- a/edu/.nbd/tickets/584e0c.md +++ b/edu/.beans/edu-hvic--2-embeddings.md @@ -1,10 +1,13 @@ -+++ -title = "§2 Embeddings" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-hvic +title: §2 Embeddings +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## §2 Embeddings — Stub to fill File: `edu/src/vector-db.md`, section `### 2. Embeddings` @@ -34,4 +37,4 @@ This is a **reading lesson** — no Rust code. Target 400–700 words. Follow th **Practical dimensionalities.** 384 (MiniLM, fast, ~130MB), 768 (BERT-base, sentence-transformers default), 1536 (OpenAI text-embedding-3-small), 3072 (text-embedding-3-large). Larger is not always better — depends on task and dataset. -**Embeddings for non-text data.** Brief mention: CLIP produces image embeddings comparable to text embeddings in the same space (enabling text-to-image search). Product embeddings can be learned from purchase co-occurrence. The vector database stores float arrays regardless of modality. \ No newline at end of file +**Embeddings for non-text data.** Brief mention: CLIP produces image embeddings comparable to text embeddings in the same space (enabling text-to-image search). Product embeddings can be learned from purchase co-occurrence. The vector database stores float arrays regardless of modality. diff --git a/edu/.nbd/tickets/d9f850.md b/edu/.beans/edu-hvmi--4-what-is-a-vector-database.md similarity index 92% rename from edu/.nbd/tickets/d9f850.md rename to edu/.beans/edu-hvmi--4-what-is-a-vector-database.md index 58a3d4a..75f5735 100644 --- a/edu/.nbd/tickets/d9f850.md +++ b/edu/.beans/edu-hvmi--4-what-is-a-vector-database.md @@ -1,10 +1,13 @@ -+++ -title = "§4 What Is a Vector Database?" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-hvmi +title: §4 What Is a Vector Database? +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- + ## §4 What Is a Vector Database? — Stub to fill File: `edu/src/vector-db.md`, section `### 4. What Is a Vector Database?` @@ -43,4 +46,4 @@ This is a **reading lesson** — no Rust code. Target 500–700 words. Bold lead - Index build time: one-time cost paid before serving queries. - Memory footprint: HNSW stores graph edges in RAM; this limits how large the index can grow on a single machine. -**Where sqlite-vec / Turso fits.** sqlite-vec is appropriate for embedded applications, local development, and small-to-medium corpora (up to a few million vectors). Dedicated cloud vector databases (Pinecone, Qdrant, Weaviate) handle larger scale and add features like multi-tenancy, filtering, and distributed search. \ No newline at end of file +**Where sqlite-vec / Turso fits.** sqlite-vec is appropriate for embedded applications, local development, and small-to-medium corpora (up to a few million vectors). Dedicated cloud vector databases (Pinecone, Qdrant, Weaviate) handle larger scale and add features like multi-tenancy, filtering, and distributed search. diff --git a/edu/.nbd/tickets/37cdd5.md b/edu/.beans/edu-ic66--6-setting-up-turso-sqlite-vec.md similarity index 81% rename from edu/.nbd/tickets/37cdd5.md rename to edu/.beans/edu-ic66--6-setting-up-turso-sqlite-vec.md index b14bcd8..937bb56 100644 --- a/edu/.nbd/tickets/37cdd5.md +++ b/edu/.beans/edu-ic66--6-setting-up-turso-sqlite-vec.md @@ -1,10 +1,13 @@ -+++ -title = "§6 Setting Up Turso + sqlite-vec" -priority = 5 -status = "closed" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-ic66 +title: §6 Setting Up Turso + sqlite-vec +status: scrapped +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## §6 Setting Up Turso + sqlite-vec — ALREADY COMPLETE This section is fully written in `edu/src/vector-db.md` under `### 6. Setting Up`. No further content work is needed. Mark this ticket done. @@ -18,4 +21,4 @@ This section is fully written in `edu/src/vector-db.md` under `### 6. Setting Up - Reference table of all sqlite-vec constructs used in later exercises: `F32_BLOB(d)`, `vector()`, `vector_extract()`, `vector_distance_cos()`, `libsql_vector_idx`, `vector_top_k()` - Creating a `F32_BLOB(3)` vector table - Creating an HNSW index with `USING libsql_vector_idx(embedding)` -- Complete working `main.rs` listing — produces "SQLite version: x.y.z" and "Database ready." \ No newline at end of file +- Complete working `main.rs` listing — produces "SQLite version: x.y.z" and "Database ready." diff --git a/edu/.nbd/tickets/5835e9.md b/edu/.beans/edu-jzvr--4-introduction-to-nom-parser-combinators.md similarity index 97% rename from edu/.nbd/tickets/5835e9.md rename to edu/.beans/edu-jzvr--4-introduction-to-nom-parser-combinators.md index e45f814..861f763 100644 --- a/edu/.nbd/tickets/5835e9.md +++ b/edu/.beans/edu-jzvr--4-introduction-to-nom-parser-combinators.md @@ -1,10 +1,12 @@ -+++ -title = "§4 Introduction to nom: Parser Combinators" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-jzvr +title: '§4 Introduction to nom: Parser Combinators' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §4 Introduction to nom: Parser Combinators — Stub to fill diff --git a/edu/.nbd/tickets/21d9be.md b/edu/.beans/edu-mlut--1-what-is-a-vector.md similarity index 79% rename from edu/.nbd/tickets/21d9be.md rename to edu/.beans/edu-mlut--1-what-is-a-vector.md index bf47ec5..33bb190 100644 --- a/edu/.nbd/tickets/21d9be.md +++ b/edu/.beans/edu-mlut--1-what-is-a-vector.md @@ -1,10 +1,13 @@ -+++ -title = "§1 What Is a Vector?" -priority = 5 -status = "closed" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-mlut +title: §1 What Is a Vector? +status: scrapped +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## §1 What Is a Vector? — ALREADY COMPLETE This section is fully written in `edu/src/vector-db.md` under `### 1. What Is a Vector?`. No further content work is needed. Mark this ticket done. @@ -15,4 +18,4 @@ This section is fully written in `edu/src/vector-db.md` under `### 1. What Is a - Geometric intuition in 2D and 3D: magnitude (`‖v‖ = √(Σ vᵢ²)`), direction, orthogonality via dot product - High-dimensional spaces: the curse of dimensionality, normalisation onto the unit hypersphere, dimensions are not individually interpretable features - Vectors as representations: the key insight that similarity in meaning corresponds to proximity in vector space — the basis of everything that follows -- Notation used throughout the course: **v**, `v[i]`, `‖v‖`, *d* for dimension, *n* for number of stored vectors \ No newline at end of file +- Notation used throughout the course: **v**, `v[i]`, `‖v‖`, *d* for dimension, *n* for number of stored vectors diff --git a/edu/.nbd/tickets/b6c9ad.md b/edu/.beans/edu-mmbr--8-parsing-atoms-with-nom.md similarity index 96% rename from edu/.nbd/tickets/b6c9ad.md rename to edu/.beans/edu-mmbr--8-parsing-atoms-with-nom.md index 5705f82..c8a9764 100644 --- a/edu/.nbd/tickets/b6c9ad.md +++ b/edu/.beans/edu-mmbr--8-parsing-atoms-with-nom.md @@ -1,10 +1,12 @@ -+++ -title = "§8 Parsing Atoms with nom" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-mmbr +title: §8 Parsing Atoms with nom +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §8 Parsing Atoms with nom — Stub to fill diff --git a/edu/.nbd/tickets/a1a827.md b/edu/.beans/edu-n7zb--7-the-abstract-syntax-tree.md similarity index 97% rename from edu/.nbd/tickets/a1a827.md rename to edu/.beans/edu-n7zb--7-the-abstract-syntax-tree.md index b718748..9519423 100644 --- a/edu/.nbd/tickets/a1a827.md +++ b/edu/.beans/edu-n7zb--7-the-abstract-syntax-tree.md @@ -1,10 +1,12 @@ -+++ -title = "§7 The Abstract Syntax Tree" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-n7zb +title: §7 The Abstract Syntax Tree +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §7 The Abstract Syntax Tree — Stub to fill diff --git a/edu/.nbd/tickets/3aeb62.md b/edu/.beans/edu-n9ap--3-compiler-architecture-the-pipeline.md similarity index 95% rename from edu/.nbd/tickets/3aeb62.md rename to edu/.beans/edu-n9ap--3-compiler-architecture-the-pipeline.md index c1ba441..6dbc099 100644 --- a/edu/.nbd/tickets/3aeb62.md +++ b/edu/.beans/edu-n9ap--3-compiler-architecture-the-pipeline.md @@ -1,10 +1,12 @@ -+++ -title = "§3 Compiler Architecture: The Pipeline" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-n9ap +title: '§3 Compiler Architecture: The Pipeline' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §3 Compiler Architecture: The Pipeline — Stub to fill diff --git a/edu/.nbd/tickets/58b37a.md b/edu/.beans/edu-nc61--16-the-compilation-pipeline.md similarity index 96% rename from edu/.nbd/tickets/58b37a.md rename to edu/.beans/edu-nc61--16-the-compilation-pipeline.md index 8e801dc..4d7568d 100644 --- a/edu/.nbd/tickets/58b37a.md +++ b/edu/.beans/edu-nc61--16-the-compilation-pipeline.md @@ -1,10 +1,12 @@ -+++ -title = "§16 The Compilation Pipeline" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-nc61 +title: §16 The Compilation Pipeline +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- ## §16 The Compilation Pipeline — Stub to fill diff --git a/edu/.nbd/tickets/5674ce.md b/edu/.beans/edu-paqf--8-exercise-2-k-nearest-neighbor-search.md similarity index 91% rename from edu/.nbd/tickets/5674ce.md rename to edu/.beans/edu-paqf--8-exercise-2-k-nearest-neighbor-search.md index 5678c0d..700845f 100644 --- a/edu/.nbd/tickets/5674ce.md +++ b/edu/.beans/edu-paqf--8-exercise-2-k-nearest-neighbor-search.md @@ -1,10 +1,13 @@ -+++ -title = "§8 Exercise 2: K-Nearest Neighbor Search" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-paqf +title: '§8 Exercise 2: K-Nearest Neighbor Search' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## §8 Exercise 2 — K-Nearest Neighbor Search — Stub to fill File: `edu/src/vector-db.md`, section `### 8. Exercise 2 — K-Nearest Neighbor Search` @@ -62,4 +65,4 @@ Query: [0.85, 0.15, 0.25] ## Reference solution -Full `main.rs` inside `
Show full solution`. The solution should re-run setup from §7 (create table, insert data) then run the three KNN queries. \ No newline at end of file +Full `main.rs` inside `
Show full solution`. The solution should re-run setup from §7 (create table, insert data) then run the three KNN queries. diff --git a/edu/.nbd/tickets/081a55.md b/edu/.beans/edu-pdeo--7-exercise-1-storing-and-retrieving-vectors.md similarity index 91% rename from edu/.nbd/tickets/081a55.md rename to edu/.beans/edu-pdeo--7-exercise-1-storing-and-retrieving-vectors.md index 294a63f..d7e37b0 100644 --- a/edu/.nbd/tickets/081a55.md +++ b/edu/.beans/edu-pdeo--7-exercise-1-storing-and-retrieving-vectors.md @@ -1,10 +1,13 @@ -+++ -title = "§7 Exercise 1: Storing and Retrieving Vectors" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-pdeo +title: '§7 Exercise 1: Storing and Retrieving Vectors' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:29:59Z +updated_at: 2026-03-10T23:29:59Z +--- + ## §7 Exercise 1 — Storing and Retrieving Vectors — Stub to fill File: `edu/src/vector-db.md`, section `### 7. Exercise 1 — Storing and Retrieving Vectors` @@ -71,4 +74,4 @@ SELECT id, label, vector_extract(embedding) FROM items ORDER BY id ## Cargo.toml additions -Add `serde_json = "1"` for JSON array parsing. \ No newline at end of file +Add `serde_json = "1"` for JSON array parsing. diff --git a/edu/.nbd/tickets/cbc6e3.md b/edu/.beans/edu-pyue--14-generating-c-definitions-and-functions.md similarity index 96% rename from edu/.nbd/tickets/cbc6e3.md rename to edu/.beans/edu-pyue--14-generating-c-definitions-and-functions.md index 7aa6793..550500b 100644 --- a/edu/.nbd/tickets/cbc6e3.md +++ b/edu/.beans/edu-pyue--14-generating-c-definitions-and-functions.md @@ -1,10 +1,12 @@ -+++ -title = "§14 Generating C: Definitions and Functions" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-pyue +title: '§14 Generating C: Definitions and Functions' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §14 Generating C: Definitions and Functions — Stub to fill diff --git a/edu/.nbd/tickets/fb7f74.md b/edu/.beans/edu-svom--markov.md similarity index 64% rename from edu/.nbd/tickets/fb7f74.md rename to edu/.beans/edu-svom--markov.md index a5fc795..9293b2f 100644 --- a/edu/.nbd/tickets/fb7f74.md +++ b/edu/.beans/edu-svom--markov.md @@ -1,8 +1,22 @@ -+++ -title = "markov" -priority = 7 -status = "done" -ticket_type = "project" -dependencies = ["fbf323", "738be2", "44ebe7", "257a2a", "64826a", "92a829", "74be50", "1f995a", "68ee16", "5994a6"] -+++ -Self-guided Markov chain course in edu/markov.md.\n\nThe course outline lives in edu/markov.md. Each of the 10 section tickets must be completed to flesh out all stubs before this project is done.\n\nSections:\n1. fbf323 — What Is a Markov Chain?\n2. 738be2 — States and Transitions\n3. 44ebe7 — Transition Probabilities and Matrices\n4. 257a2a — Exercise 1: Weather Model (Rust)\n5. 64826a — Exercise 2: Random Walk (Rust)\n6. 92a829 — Text Generation with Markov Chains\n7. 74be50 — Exercise 3: Bigram Text Generator (Rust)\n8. 1f995a — Exercise 4: N-gram Generalization (Rust)\n9. 68ee16 — Stationary Distributions\n10. 5994a6 — Applications and Further Reading \ No newline at end of file +--- +# edu-svom +title: markov +status: completed +type: epic +priority: high +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:04Z +blocked_by: + - edu-18qe + - edu-zjy1 + - edu-a1al + - edu-7cp2 + - edu-0w1v + - edu-9kuk + - edu-6r70 + - edu-4gok + - edu-urpp + - edu-34co +--- + +Self-guided Markov chain course in edu/markov.md.\n\nThe course outline lives in edu/markov.md. Each of the 10 section tickets must be completed to flesh out all stubs before this project is done.\n\nSections:\n1. fbf323 — What Is a Markov Chain?\n2. 738be2 — States and Transitions\n3. 44ebe7 — Transition Probabilities and Matrices\n4. 257a2a — Exercise 1: Weather Model (Rust)\n5. 64826a — Exercise 2: Random Walk (Rust)\n6. 92a829 — Text Generation with Markov Chains\n7. 74be50 — Exercise 3: Bigram Text Generator (Rust)\n8. 1f995a — Exercise 4: N-gram Generalization (Rust)\n9. 68ee16 — Stationary Distributions\n10. 5994a6 — Applications and Further Reading diff --git a/edu/.nbd/tickets/99e1d9.md b/edu/.beans/edu-twtl--3-vector-similarity.md similarity index 93% rename from edu/.nbd/tickets/99e1d9.md rename to edu/.beans/edu-twtl--3-vector-similarity.md index 5102913..5cc9488 100644 --- a/edu/.nbd/tickets/99e1d9.md +++ b/edu/.beans/edu-twtl--3-vector-similarity.md @@ -1,10 +1,13 @@ -+++ -title = "§3 Vector Similarity" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-twtl +title: §3 Vector Similarity +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## §3 Vector Similarity — Stub to fill File: `edu/src/vector-db.md`, section `### 3. Vector Similarity` @@ -34,4 +37,4 @@ This is a **reading lesson with inline math** — no Rust code. Target 400–600 **When to use each.** Text and sentence embeddings: cosine (or dot product if model outputs unit vectors, which many do). Follow the model card's recommendation when specified. Low-dimensional geometric features: L2. -**Worked example.** Use vectors a = [1, 0, 1] and b = [1, 1, 0]. Compute all three by hand and show the arithmetic step by step. Cosine similarity = 0.5, L2 distance ≈ 1.414, dot product = 1. This concretises the formulas before the reader sees them in SQL queries. \ No newline at end of file +**Worked example.** Use vectors a = [1, 0, 1] and b = [1, 1, 0]. Compute all three by hand and show the arithmetic step by step. Cosine similarity = 0.5, L2 distance ≈ 1.414, dot product = 1. This concretises the formulas before the reader sees them in SQL queries. diff --git a/edu/.nbd/tickets/59c122.md b/edu/.beans/edu-tx54--deploy-edu-mdbook-to-cloudflare-pages-at-vibebooks.md similarity index 93% rename from edu/.nbd/tickets/59c122.md rename to edu/.beans/edu-tx54--deploy-edu-mdbook-to-cloudflare-pages-at-vibebooks.md index e36bf7e..4c99517 100644 --- a/edu/.nbd/tickets/59c122.md +++ b/edu/.beans/edu-tx54--deploy-edu-mdbook-to-cloudflare-pages-at-vibebooks.md @@ -1,10 +1,13 @@ -+++ -title = "Deploy edu mdbook to Cloudflare Pages at vibebooks.elijah.run" -priority = 5 -status = "done" -ticket_type = "project" -dependencies = [] -+++ +--- +# edu-tx54 +title: Deploy edu mdbook to Cloudflare Pages at vibebooks.elijah.run +status: completed +type: epic +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## Background From `edu/TODO.md`: @@ -71,4 +74,4 @@ Add a `release` recipe to `edu/justfile` (see justfiles ticket) that triggers th - `tofu validate && tofu plan` from `edu/infra/` - `mdbook build` from `edu/` — builds without errors -- After deploy: `curl -I https://vibebooks.elijah.run` returns 200 \ No newline at end of file +- After deploy: `curl -I https://vibebooks.elijah.run` returns 200 diff --git a/edu/.nbd/tickets/a4c9f8.md b/edu/.beans/edu-tzzh--9-parsing-s-expressions-and-special-forms.md similarity index 97% rename from edu/.nbd/tickets/a4c9f8.md rename to edu/.beans/edu-tzzh--9-parsing-s-expressions-and-special-forms.md index 3bed190..9405178 100644 --- a/edu/.nbd/tickets/a4c9f8.md +++ b/edu/.beans/edu-tzzh--9-parsing-s-expressions-and-special-forms.md @@ -1,10 +1,12 @@ -+++ -title = "§9 Parsing S-Expressions and Special Forms" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-tzzh +title: §9 Parsing S-Expressions and Special Forms +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §9 Parsing S-Expressions and Special Forms — Stub to fill diff --git a/edu/.nbd/tickets/389d8d.md b/edu/.beans/edu-u2w7--edu-write-chapter-on-creating-and-training-a-simpl.md similarity index 89% rename from edu/.nbd/tickets/389d8d.md rename to edu/.beans/edu-u2w7--edu-write-chapter-on-creating-and-training-a-simpl.md index f804a10..3d90c9e 100644 --- a/edu/.nbd/tickets/389d8d.md +++ b/edu/.beans/edu-u2w7--edu-write-chapter-on-creating-and-training-a-simpl.md @@ -1,10 +1,13 @@ -+++ -title = "edu: write chapter on creating and training a simple LLM" -priority = 3 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-u2w7 +title: 'edu: write chapter on creating and training a simple LLM' +status: todo +type: task +priority: low +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- + ## Background From `edu/TODO.md`: Hands-on: Creating and training a simple LLM. @@ -44,4 +47,4 @@ A practical course on building a small language model from scratch in Rust, cove ## File to create - `edu/src/llm-from-scratch.md` -- Add to `edu/src/SUMMARY.md` under the `# Machine Learning` section \ No newline at end of file +- Add to `edu/src/SUMMARY.md` under the `# Machine Learning` section diff --git a/edu/.nbd/tickets/de82f1.md b/edu/.beans/edu-unus--15-generating-c-control-flow-and-sequencing.md similarity index 96% rename from edu/.nbd/tickets/de82f1.md rename to edu/.beans/edu-unus--15-generating-c-control-flow-and-sequencing.md index 20c3953..ec6f58e 100644 --- a/edu/.nbd/tickets/de82f1.md +++ b/edu/.beans/edu-unus--15-generating-c-control-flow-and-sequencing.md @@ -1,10 +1,12 @@ -+++ -title = "§15 Generating C: Control Flow and Sequencing" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-unus +title: '§15 Generating C: Control Flow and Sequencing' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §15 Generating C: Control Flow and Sequencing — Stub to fill diff --git a/edu/.nbd/tickets/68ee16.md b/edu/.beans/edu-urpp--markov-lesson-stationary-distributions.md similarity index 72% rename from edu/.nbd/tickets/68ee16.md rename to edu/.beans/edu-urpp--markov-lesson-stationary-distributions.md index f9e0421..a5bd953 100644 --- a/edu/.nbd/tickets/68ee16.md +++ b/edu/.beans/edu-urpp--markov-lesson-stationary-distributions.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: Stationary Distributions" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 9 of edu/markov.md: 'Stationary Distributions'\n\nLearning objectives:\n- Define stationary distribution π: πP = π, Σπᵢ = 1\n- Explain existence and uniqueness conditions: irreducibility and aperiodicity\n- Show how to compute π analytically for a 2-state chain\n- Introduce power iteration as a numerical method\n- Connect to the long-run frequency interpretation from the simulation in Exercise 1\n\nContent to produce:\n- 4–6 paragraphs of prose\n- Worked 2×2 example: solve πP = π by hand\n- Power iteration pseudocode or brief Rust sketch\n\nTarget: replace the stub in edu/markov.md §9 \ No newline at end of file +--- +# edu-urpp +title: 'Markov lesson: Stationary Distributions' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 9 of edu/markov.md: 'Stationary Distributions'\n\nLearning objectives:\n- Define stationary distribution π: πP = π, Σπᵢ = 1\n- Explain existence and uniqueness conditions: irreducibility and aperiodicity\n- Show how to compute π analytically for a 2-state chain\n- Introduce power iteration as a numerical method\n- Connect to the long-run frequency interpretation from the simulation in Exercise 1\n\nContent to produce:\n- 4–6 paragraphs of prose\n- Worked 2×2 example: solve πP = π by hand\n- Power iteration pseudocode or brief Rust sketch\n\nTarget: replace the stub in edu/markov.md §9 diff --git a/edu/.nbd/tickets/6ec5ff.md b/edu/.beans/edu-uz3e--5-under-the-hood-ann-algorithms.md similarity index 93% rename from edu/.nbd/tickets/6ec5ff.md rename to edu/.beans/edu-uz3e--5-under-the-hood-ann-algorithms.md index e2482eb..d08682a 100644 --- a/edu/.nbd/tickets/6ec5ff.md +++ b/edu/.beans/edu-uz3e--5-under-the-hood-ann-algorithms.md @@ -1,10 +1,13 @@ -+++ -title = "§5 Under the Hood: ANN Algorithms" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-uz3e +title: '§5 Under the Hood: ANN Algorithms' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + ## §5 Under the Hood: ANN Algorithms — Stub to fill File: `edu/src/vector-db.md`, section `### 5. Under the Hood: ANN Algorithms` @@ -58,4 +61,4 @@ IVFFlat requires a training step before data can be inserted. Incremental insert | Insert | Incremental | Batch (requires training) | | Memory | Higher (graph edges) | Lower | | Recall@10 at defaults | ~0.95+ | ~0.90+ (depends on nprobe) | -| Used by | sqlite-vec, Qdrant, Weaviate | pgvector, Faiss | \ No newline at end of file +| Used by | sqlite-vec, Qdrant, Weaviate | pgvector, Faiss | diff --git a/edu/.nbd/tickets/8fa47a.md b/edu/.beans/edu-v0ud--17-testing-the-compiler.md similarity index 96% rename from edu/.nbd/tickets/8fa47a.md rename to edu/.beans/edu-v0ud--17-testing-the-compiler.md index 9460072..e54f39c 100644 --- a/edu/.nbd/tickets/8fa47a.md +++ b/edu/.beans/edu-v0ud--17-testing-the-compiler.md @@ -1,10 +1,12 @@ -+++ -title = "§17 Testing the Compiler" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-v0ud +title: §17 Testing the Compiler +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- ## §17 Testing the Compiler — Stub to fill diff --git a/edu/.nbd/tickets/1d16da.md b/edu/.beans/edu-y4e6--18-whats-next-extensions-and-further-reading.md similarity index 96% rename from edu/.nbd/tickets/1d16da.md rename to edu/.beans/edu-y4e6--18-whats-next-extensions-and-further-reading.md index 1bbc4a6..a48cee1 100644 --- a/edu/.nbd/tickets/1d16da.md +++ b/edu/.beans/edu-y4e6--18-whats-next-extensions-and-further-reading.md @@ -1,10 +1,12 @@ -+++ -title = "§18 What's Next: Extensions and Further Reading" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-y4e6 +title: '§18 What''s Next: Extensions and Further Reading' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:00Z +updated_at: 2026-03-10T23:30:00Z +--- ## §18 What's Next: Extensions and Further Reading — Stub to fill diff --git a/edu/.nbd/tickets/e8da8b.md b/edu/.beans/edu-ylb8--1-introduction-what-were-building.md similarity index 95% rename from edu/.nbd/tickets/e8da8b.md rename to edu/.beans/edu-ylb8--1-introduction-what-were-building.md index c9e5a6f..1cec998 100644 --- a/edu/.nbd/tickets/e8da8b.md +++ b/edu/.beans/edu-ylb8--1-introduction-what-were-building.md @@ -1,10 +1,12 @@ -+++ -title = "§1 Introduction: What We're Building" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# edu-ylb8 +title: '§1 Introduction: What We''re Building' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:02Z +updated_at: 2026-03-10T23:30:02Z +--- ## §1 Introduction: What We're Building — Stub to fill diff --git a/edu/.nbd/tickets/738be2.md b/edu/.beans/edu-zjy1--markov-lesson-states-and-transitions.md similarity index 74% rename from edu/.nbd/tickets/738be2.md rename to edu/.beans/edu-zjy1--markov-lesson-states-and-transitions.md index 625beee..cc9073c 100644 --- a/edu/.nbd/tickets/738be2.md +++ b/edu/.beans/edu-zjy1--markov-lesson-states-and-transitions.md @@ -1,8 +1,11 @@ -+++ -title = "Markov lesson: States and Transitions" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ -Write Section 2 of edu/markov.md: 'States and Transitions'\n\nLearning objectives:\n- Define state space (finite vs countably infinite)\n- Define a transition as a directed edge between states with an associated probability\n- Introduce state-transition diagrams and how to draw them\n- Distinguish absorbing states, transient states, and recurrent states at an intuitive level\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A hand-drawn-style ASCII or described state-transition diagram for the weather example\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §2 \ No newline at end of file +--- +# edu-zjy1 +title: 'Markov lesson: States and Transitions' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:30:01Z +updated_at: 2026-03-10T23:30:01Z +--- + +Write Section 2 of edu/markov.md: 'States and Transitions'\n\nLearning objectives:\n- Define state space (finite vs countably infinite)\n- Define a transition as a directed edge between states with an associated probability\n- Introduce state-transition diagrams and how to draw them\n- Distinguish absorbing states, transient states, and recurrent states at an intuitive level\n\nContent to produce:\n- 3–5 paragraphs of prose\n- A hand-drawn-style ASCII or described state-transition diagram for the weather example\n- No code in this section\n\nTarget: replace the stub in edu/markov.md §2 diff --git a/edu/.nbd/.gitignore b/edu/.nbd/.gitignore deleted file mode 100644 index be8efad..0000000 --- a/edu/.nbd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cache.db diff --git a/edu/CLAUDE.md b/edu/CLAUDE.md index 8165289..523c4c0 100644 --- a/edu/CLAUDE.md +++ b/edu/CLAUDE.md @@ -25,7 +25,7 @@ mdbook build # Serve locally with live reload (default: http://localhost:3000) mdbook serve -# Enter the Nix dev shell (provides mdbook + nbd) +# Enter the Nix dev shell (provides mdbook + beans) nix develop # or automatically via direnv: cd into the directory ``` @@ -52,6 +52,6 @@ Scope for commit messages: `edu` (e.g., `docs(edu): write §3 transition matrice Ticket IDs appear in commit messages in `[]` format. -Stub sections in content are marked with 🚧 and reference an nbd ticket — fill in content and close the ticket when complete. +Stub sections in content are marked with 🚧 and reference a beans ticket — fill in content and close the ticket when complete. diff --git a/flake.nix b/flake.nix index ee69d78..c7eb520 100644 --- a/flake.nix +++ b/flake.nix @@ -55,6 +55,9 @@ # NBD task management nbd.packages.${system}.nbd + # Task management + pkgs.beans + # MCP servers pkgs.nodejs diff --git a/nbd/.beans.yml b/nbd/.beans.yml new file mode 100644 index 0000000..146c095 --- /dev/null +++ b/nbd/.beans.yml @@ -0,0 +1,6 @@ +beans: + path: .beans + prefix: nbd- + id_length: 4 + default_status: todo + default_type: task diff --git a/nbd/.nbd/tickets/fc6df4.md b/nbd/.beans/nbd-08jg--add-nbd-next-subcommand.md similarity index 96% rename from nbd/.nbd/tickets/fc6df4.md rename to nbd/.beans/nbd-08jg--add-nbd-next-subcommand.md index 8c4828d..385f146 100644 --- a/nbd/.nbd/tickets/fc6df4.md +++ b/nbd/.beans/nbd-08jg--add-nbd-next-subcommand.md @@ -1,10 +1,15 @@ -+++ -title = "Add nbd next subcommand" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = ["887344"] -+++ +--- +# nbd-08jg +title: Add nbd next subcommand +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-p9na +--- + ## Summary Add `nbd next` subcommand that selects the single highest-priority ticket that is @@ -176,4 +181,4 @@ cargo run -- next --json (Create bug priority 8, task priority 9: with filter, should return the bug.) - `nbd next --json` returns a JSON object with a `"next"` key containing all ticket fields including `"id"`. -- `nbd next --filter priority=99 --json` returns `{"next": null}` (no ticket has priority 99). \ No newline at end of file +- `nbd next --filter priority=99 --json` returns `{"next": null}` (no ticket has priority 99). diff --git a/nbd/.nbd/tickets/e14172.md b/nbd/.beans/nbd-17dp--ascii-graph-rendering-in-displayrs.md similarity index 91% rename from nbd/.nbd/tickets/e14172.md rename to nbd/.beans/nbd-17dp--ascii-graph-rendering-in-displayrs.md index a8843a4..0951dbd 100644 --- a/nbd/.nbd/tickets/e14172.md +++ b/nbd/.beans/nbd-17dp--ascii-graph-rendering-in-displayrs.md @@ -1,10 +1,15 @@ -+++ -title = "ASCII graph rendering in display.rs" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["9c9ebe"] -+++ +--- +# nbd-17dp +title: ASCII graph rendering in display.rs +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-csdh +--- + Add `format_graph` and `print_graph` to `src/display.rs` to render a ticket dependency DAG as an ASCII tree. ## Motivation @@ -65,4 +70,4 @@ pub fn print_subtree(graph: &TicketGraph, root_id: &str) - `format_graph` on a two-ticket chain shows the child indented with `└──`. - `format_graph` with a branching parent shows `├──` for all but the last child and `└──` for the last. - `format_subtree` only shows the specified root's subtree. -- A cycle in the graph does not cause infinite recursion; the repeated node is labelled `[cycle]`. \ No newline at end of file +- A cycle in the graph does not cause infinite recursion; the repeated node is labelled `[cycle]`. diff --git a/nbd/.nbd/tickets/fc444f.md b/nbd/.beans/nbd-2i1e--nbd-claude-md-command.md similarity index 93% rename from nbd/.nbd/tickets/fc444f.md rename to nbd/.beans/nbd-2i1e--nbd-claude-md-command.md index 405e591..088ce9c 100644 --- a/nbd/.nbd/tickets/fc444f.md +++ b/nbd/.beans/nbd-2i1e--nbd-claude-md-command.md @@ -1,10 +1,13 @@ -+++ -title = "nbd claude-md command" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-2i1e +title: nbd claude-md command +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + Add `nbd claude-md` subcommand that prints a ready-to-paste CLAUDE.md snippet for adopting `nbd` in any project. The snippet content is maintained as a source file and baked into the binary at compile time via `include_str!`. ## Motivation @@ -65,4 +68,4 @@ Integration tests (`tests/integration.rs`): - `src/claude_md_snippet.md` — new file; the canonical snippet content - `src/main.rs` — `include_str!` constant, `ClaudeMd` command variant and handler - `tests/integration.rs` — integration tests -- `README.md` — mention `nbd claude-md` in the Usage section \ No newline at end of file +- `README.md` — mention `nbd claude-md` in the Usage section diff --git a/nbd/.nbd/tickets/92e45b.md b/nbd/.beans/nbd-4w8z--exclude-done-tickets-from-nbd-list-by-default.md similarity index 94% rename from nbd/.nbd/tickets/92e45b.md rename to nbd/.beans/nbd-4w8z--exclude-done-tickets-from-nbd-list-by-default.md index 2c8337a..723c5e2 100644 --- a/nbd/.nbd/tickets/92e45b.md +++ b/nbd/.beans/nbd-4w8z--exclude-done-tickets-from-nbd-list-by-default.md @@ -1,10 +1,15 @@ -+++ -title = "Exclude done tickets from nbd list by default" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = ["887344"] -+++ +--- +# nbd-4w8z +title: Exclude done tickets from nbd list by default +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-p9na +--- + ## Summary Change `nbd list` to hide `done` tickets by default. Users must explicitly opt in @@ -130,4 +135,4 @@ nbd list --json - `src/filter.rs` — `matches_status`, `matches_except_status` methods - `src/tests.rs` — unit tests for new filter methods - `tests/integration.rs` — new tests, update any affected existing tests -- `README.md` — updated usage section \ No newline at end of file +- `README.md` — updated usage section diff --git a/nbd/.nbd/tickets/9c1f2c.md b/nbd/.beans/nbd-56ho--tests-for-nbd-graph-command.md similarity index 91% rename from nbd/.nbd/tickets/9c1f2c.md rename to nbd/.beans/nbd-56ho--tests-for-nbd-graph-command.md index bc1c9e7..c1d169f 100644 --- a/nbd/.nbd/tickets/9c1f2c.md +++ b/nbd/.beans/nbd-56ho--tests-for-nbd-graph-command.md @@ -1,10 +1,15 @@ -+++ -title = "Tests for nbd graph command" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9ad11f"] -+++ +--- +# nbd-56ho +title: Tests for nbd graph command +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-d9dh +--- + Add comprehensive unit and integration tests for the `nbd graph` command introduced across tickets `9c9ebe`, `e14172`, and `9ad11f`. ## Unit tests (src/tests.rs) @@ -87,4 +92,4 @@ test_graph_partial_id ## Files touched - `src/tests.rs` — unit tests for `TicketGraph` and `format_graph` / `format_subtree` -- `tests/integration.rs` — CLI-level integration tests \ No newline at end of file +- `tests/integration.rs` — CLI-level integration tests diff --git a/nbd/.nbd/tickets/4036aa.md b/nbd/.beans/nbd-6j0q--print-tickets-in-markdown-format-instead-of-key-va.md similarity index 92% rename from nbd/.nbd/tickets/4036aa.md rename to nbd/.beans/nbd-6j0q--print-tickets-in-markdown-format-instead-of-key-va.md index 91d2f80..dafca50 100644 --- a/nbd/.nbd/tickets/4036aa.md +++ b/nbd/.beans/nbd-6j0q--print-tickets-in-markdown-format-instead-of-key-va.md @@ -1,10 +1,13 @@ -+++ -title = "Print tickets in markdown format instead of key-value table" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-6j0q +title: Print tickets in markdown format instead of key-value table +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Goal When a ticket is printed to stdout (e.g. by `nbd read`, `nbd create`, `nbd archive`, `nbd next`, `nbd update` without `--json`), it should be rendered as markdown with TOML frontmatter — the same format used by `--ftype md` files on disk — rather than the current key-value table. @@ -94,4 +97,4 @@ cargo run -- create --title "Test ticket" --body "Some body text" --priority 7 - # dependencies = [] # +++ # Some body text -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/c12091.md b/nbd/.beans/nbd-7cab--add-backlog-status-to-tickets.md similarity index 93% rename from nbd/.nbd/tickets/c12091.md rename to nbd/.beans/nbd-7cab--add-backlog-status-to-tickets.md index f785429..1caaf41 100644 --- a/nbd/.nbd/tickets/c12091.md +++ b/nbd/.beans/nbd-7cab--add-backlog-status-to-tickets.md @@ -1,10 +1,13 @@ -+++ -title = "Add backlog status to tickets" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-7cab +title: Add backlog status to tickets +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Goal Add a `backlog` status variant so tickets can be created without immediately surfacing in the active work queue. Tickets in `backlog` are created but intentionally deferred; they should not appear in `nbd list`, `nbd ready`, or `nbd next` by default. @@ -77,4 +80,4 @@ cargo run -- create --title "Backlog item" --status backlog --json cargo run -- list --json # should NOT appear cargo run -- list --all --json # should appear cargo run -- ready --json # should NOT appear -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/d9713b.md b/nbd/.beans/nbd-8yn8--add-status-convenience-sub-commands-open-start-com.md similarity index 84% rename from nbd/.nbd/tickets/d9713b.md rename to nbd/.beans/nbd-8yn8--add-status-convenience-sub-commands-open-start-com.md index 4ee4d6f..8c0d8fa 100644 --- a/nbd/.nbd/tickets/d9713b.md +++ b/nbd/.beans/nbd-8yn8--add-status-convenience-sub-commands-open-start-com.md @@ -1,10 +1,13 @@ -+++ -title = "Add status convenience sub-commands (open, start, complete, close)" -priority = 5 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-8yn8 +title: Add status convenience sub-commands (open, start, complete, close) +status: todo +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Problem `nbd update --status ` is verbose for the most common lifecycle transitions. `nbd archive` already exists as a top-level convenience — the same pattern should apply to all transitions. @@ -45,4 +48,4 @@ Wire up in `dispatch()` following the same pattern as `Commands::Archive`. **`tests/integration.rs`** -Add integration tests for each command analogous to the existing archive test. \ No newline at end of file +Add integration tests for each command analogous to the existing archive test. diff --git a/nbd/.nbd/tickets/4d2359.md b/nbd/.beans/nbd-95l6--nbd-init-command.md similarity index 86% rename from nbd/.nbd/tickets/4d2359.md rename to nbd/.beans/nbd-95l6--nbd-init-command.md index 85dbfa7..3dc904e 100644 --- a/nbd/.nbd/tickets/4d2359.md +++ b/nbd/.beans/nbd-95l6--nbd-init-command.md @@ -1,10 +1,13 @@ -+++ -title = "nbd init command" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-95l6 +title: nbd init command +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + Add an explicit `nbd init` subcommand that creates `.nbd/tickets/` in the current working directory, analogous to `git init`. ## Motivation @@ -30,4 +33,4 @@ Currently users must run `mkdir -p .nbd/tickets` manually before first use. This ## Files touched - `src/main.rs` — new `Init` variant and `cmd_init` handler - `tests/integration.rs` — new integration tests -- `README.md` — update Initialise section \ No newline at end of file +- `README.md` — update Initialise section diff --git a/nbd/.nbd/tickets/53fdbe.md b/nbd/.beans/nbd-9mxu--add-list-status-sub-commands-list-todo-list-backlo.md similarity index 85% rename from nbd/.nbd/tickets/53fdbe.md rename to nbd/.beans/nbd-9mxu--add-list-status-sub-commands-list-todo-list-backlo.md index e81ff07..1dfb076 100644 --- a/nbd/.nbd/tickets/53fdbe.md +++ b/nbd/.beans/nbd-9mxu--add-list-status-sub-commands-list-todo-list-backlo.md @@ -1,10 +1,13 @@ -+++ -title = "Add list status sub-commands (list todo, list backlog, etc.)" -priority = 4 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-9mxu +title: Add list status sub-commands (list todo, list backlog, etc.) +status: todo +type: feature +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem Filtering by status requires the verbose `--filter status=X`. Common patterns like listing only backlog or only completed tickets should have ergonomic shortcuts. @@ -46,4 +49,4 @@ If both `status` and `--filter status=...` are given, merge them (OR behaviour w **`tests/integration.rs`** -Add tests for each status shorthand. \ No newline at end of file +Add tests for each status shorthand. diff --git a/nbd/.nbd/tickets/3ba7f9.md b/nbd/.beans/nbd-9vrn--add-nbdconfigtoml-for-per-project-defaults.md similarity index 90% rename from nbd/.nbd/tickets/3ba7f9.md rename to nbd/.beans/nbd-9vrn--add-nbdconfigtoml-for-per-project-defaults.md index 26a41b5..5da448e 100644 --- a/nbd/.nbd/tickets/3ba7f9.md +++ b/nbd/.beans/nbd-9vrn--add-nbdconfigtoml-for-per-project-defaults.md @@ -1,10 +1,13 @@ -+++ -title = "Add .nbd/config.toml for per-project defaults" -priority = 5 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-9vrn +title: Add .nbd/config.toml for per-project defaults +status: todo +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem All defaults (output format, file type, default status) are hard-coded in the CLI. Users in a project that always uses `--json` or always creates `md`-format tickets must pass these flags repeatedly. A per-project config file would let them set these once. @@ -70,4 +73,4 @@ After creating the tickets directory, write `.nbd/config.toml` with default valu ## Dependencies -None. Can be implemented independently of other tickets. \ No newline at end of file +None. Can be implemented independently of other tickets. diff --git a/nbd/.nbd/tickets/9c9ebe.md b/nbd/.beans/nbd-csdh--add-graph-computation-module-srcgraphrs.md similarity index 93% rename from nbd/.nbd/tickets/9c9ebe.md rename to nbd/.beans/nbd-csdh--add-graph-computation-module-srcgraphrs.md index 85a2093..2c35d57 100644 --- a/nbd/.nbd/tickets/9c9ebe.md +++ b/nbd/.beans/nbd-csdh--add-graph-computation-module-srcgraphrs.md @@ -1,10 +1,13 @@ -+++ -title = "Add graph computation module (src/graph.rs)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-csdh +title: Add graph computation module (src/graph.rs) +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + Implement `src/graph.rs` — a module that builds a directed dependency graph from a flat list of tickets and provides the data structures needed by the ASCII renderer and JSON output. ## Motivation @@ -73,4 +76,4 @@ No new crates needed. If `IndexMap` insertion-order is useful, `indexmap` can be - `roots` returns only tickets with no in-graph dependencies. - `subtree` returns the correct set of IDs for a linear chain. - `subtree` does not infinite-loop when the data contains a cycle. -- `to_json_value` contains all expected IDs in `nodes` and all edges in `edges`. \ No newline at end of file +- `to_json_value` contains all expected IDs in `nodes` and all edges in `edges`. diff --git a/nbd/.nbd/tickets/9ad11f.md b/nbd/.beans/nbd-d9dh--add-nbd-graph-cli-subcommand.md similarity index 91% rename from nbd/.nbd/tickets/9ad11f.md rename to nbd/.beans/nbd-d9dh--add-nbd-graph-cli-subcommand.md index 629761b..98e2d98 100644 --- a/nbd/.nbd/tickets/9ad11f.md +++ b/nbd/.beans/nbd-d9dh--add-nbd-graph-cli-subcommand.md @@ -1,10 +1,16 @@ -+++ -title = "Add 'nbd graph' CLI subcommand" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["9c9ebe", "e14172"] -+++ +--- +# nbd-d9dh +title: Add 'nbd graph' CLI subcommand +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-csdh + - nbd-17dp +--- + Wire up the `graph` subcommand in `src/main.rs` to expose the ASCII dependency graph and JSON output. ## Motivation @@ -87,4 +93,4 @@ Same shape as full graph but only including nodes and edges reachable from ` ## Depends on - `9c9ebe` — graph computation module -- `e14172` — ASCII rendering functions \ No newline at end of file +- `e14172` — ASCII rendering functions diff --git a/nbd/.nbd/tickets/5f1495.md b/nbd/.beans/nbd-fgwx--nbd-update-diff-output.md similarity index 88% rename from nbd/.nbd/tickets/5f1495.md rename to nbd/.beans/nbd-fgwx--nbd-update-diff-output.md index af2fcab..9d7c579 100644 --- a/nbd/.nbd/tickets/5f1495.md +++ b/nbd/.beans/nbd-fgwx--nbd-update-diff-output.md @@ -1,10 +1,13 @@ -+++ -title = "nbd update diff output" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-fgwx +title: nbd update diff output +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + Show a git-diff-style +/- summary of what changed when `nbd update` is run without `--json`. ## Motivation @@ -50,4 +53,4 @@ Integration test: - `src/display.rs` — `format_diff`, `print_diff` - `src/main.rs` — `cmd_update` uses `print_diff` - `src/tests.rs` — unit tests for `format_diff` -- `tests/integration.rs` — integration tests \ No newline at end of file +- `tests/integration.rs` — integration tests diff --git a/nbd/.nbd/tickets/9344a5.md b/nbd/.beans/nbd-flbj--update-claude-md-snippet-to-show-json-on-all-comma.md similarity index 86% rename from nbd/.nbd/tickets/9344a5.md rename to nbd/.beans/nbd-flbj--update-claude-md-snippet-to-show-json-on-all-comma.md index d485dec..64fae38 100644 --- a/nbd/.nbd/tickets/9344a5.md +++ b/nbd/.beans/nbd-flbj--update-claude-md-snippet-to-show-json-on-all-comma.md @@ -1,10 +1,13 @@ -+++ -title = "Update claude-md snippet to show --json on all commands" -priority = 4 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-flbj +title: Update claude-md snippet to show --json on all commands +status: completed +type: task +priority: low +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Goal The `nbd claude-md` command emits `src/claude_md_snippet.md` verbatim. The current snippet shows core commands without `--json`, contradicting the guideline at the bottom that says to always pass it. @@ -48,4 +51,4 @@ The `nbd ready` and `nbd next` sections should also include `--json`. cargo run -- claude-md | grep -c '\-\-json' ``` -The count should go up after the change. All existing tests should still pass. \ No newline at end of file +The count should go up after the change. All existing tests should still pass. diff --git a/nbd/.nbd/tickets/e1968f.md b/nbd/.beans/nbd-i0fc--nbd-ready-command.md similarity index 87% rename from nbd/.nbd/tickets/e1968f.md rename to nbd/.beans/nbd-i0fc--nbd-ready-command.md index 3076b90..5a871f8 100644 --- a/nbd/.nbd/tickets/e1968f.md +++ b/nbd/.beans/nbd-i0fc--nbd-ready-command.md @@ -1,10 +1,13 @@ -+++ -title = "nbd ready command" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-i0fc +title: nbd ready command +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + Add `nbd ready` subcommand that lists tickets which are actionable right now: not yet done and with all dependencies completed. ## Motivation @@ -38,4 +41,4 @@ Unit-style integration tests: ## Files touched - `src/main.rs` — new `Ready` variant and `cmd_ready` handler -- `tests/integration.rs` — new integration tests \ No newline at end of file +- `tests/integration.rs` — new integration tests diff --git a/nbd/.nbd/tickets/feb901.md b/nbd/.beans/nbd-jc1v--split-archiveclosed-archivedone-closedcancelled.md similarity index 93% rename from nbd/.nbd/tickets/feb901.md rename to nbd/.beans/nbd-jc1v--split-archiveclosed-archivedone-closedcancelled.md index ed1702f..d9e8453 100644 --- a/nbd/.nbd/tickets/feb901.md +++ b/nbd/.beans/nbd-jc1v--split-archiveclosed-archivedone-closedcancelled.md @@ -1,10 +1,13 @@ -+++ -title = "Split archive/closed: archive=done, closed=cancelled" -priority = 6 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# nbd-jc1v +title: 'Split archive/closed: archive=done, closed=cancelled' +status: completed +type: bug +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Problem Currently `nbd archive` sets a ticket's status to `closed`. This conflates two distinct intents: @@ -85,4 +88,4 @@ cargo run -- create --title "Test archive" --json | jq -r '.id' | xargs -I{} car # → status should be "archived" cargo run -- create --title "Cancelled ticket" --json | jq -r '.id' | xargs -I{} cargo run -- update {} --status closed --json # → status should be "closed" -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/818598.md b/nbd/.beans/nbd-kq6o--scope-nbd-next-and-nbd-ready-by-dependency-subtree.md similarity index 94% rename from nbd/.nbd/tickets/818598.md rename to nbd/.beans/nbd-kq6o--scope-nbd-next-and-nbd-ready-by-dependency-subtree.md index b1a9e83..d57b329 100644 --- a/nbd/.nbd/tickets/818598.md +++ b/nbd/.beans/nbd-kq6o--scope-nbd-next-and-nbd-ready-by-dependency-subtree.md @@ -1,10 +1,13 @@ -+++ -title = "Scope nbd next and nbd ready by dependency subtree" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-kq6o +title: Scope nbd next and nbd ready by dependency subtree +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Summary Add an optional positional `` argument to `nbd next` and `nbd ready` that scopes @@ -99,4 +102,4 @@ Add integration tests (using `tempdir`): ```sh cargo fmt && cargo check && cargo clippy && cargo test -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/668150.md b/nbd/.beans/nbd-l38k--fix-graph-orientation-show-goals-at-root-prerequis.md similarity index 86% rename from nbd/.nbd/tickets/668150.md rename to nbd/.beans/nbd-l38k--fix-graph-orientation-show-goals-at-root-prerequis.md index 84dc51e..ae026ff 100644 --- a/nbd/.nbd/tickets/668150.md +++ b/nbd/.beans/nbd-l38k--fix-graph-orientation-show-goals-at-root-prerequis.md @@ -1,10 +1,13 @@ -+++ -title = "Fix graph orientation: show goals at root, prerequisites as leaves" -priority = 7 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# nbd-l38k +title: 'Fix graph orientation: show goals at root, prerequisites as leaves' +status: completed +type: bug +priority: high +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem The dependency graph is inverted. Currently: @@ -42,4 +45,4 @@ The edge semantics paragraph should be updated: "A is a dependency of B" means A ### Tests -Update any graph-related tests in `src/tests.rs` and `tests/integration.rs` that assert the current (inverted) traversal order. \ No newline at end of file +Update any graph-related tests in `src/tests.rs` and `tests/integration.rs` that assert the current (inverted) traversal order. diff --git a/nbd/.nbd/tickets/06ca62.md b/nbd/.beans/nbd-lins--fix-nbd-graph-id-show-ancestry-path-through-ticket.md similarity index 88% rename from nbd/.nbd/tickets/06ca62.md rename to nbd/.beans/nbd-lins--fix-nbd-graph-id-show-ancestry-path-through-ticket.md index abf52f0..22d304a 100644 --- a/nbd/.nbd/tickets/06ca62.md +++ b/nbd/.beans/nbd-lins--fix-nbd-graph-id-show-ancestry-path-through-ticket.md @@ -1,10 +1,15 @@ -+++ -title = "Fix nbd graph : show ancestry path through ticket, not just subtree" -priority = 6 -status = "todo" -ticket_type = "bug" -dependencies = ["668150"] -+++ +--- +# nbd-lins +title: 'Fix nbd graph : show ancestry path through ticket, not just subtree' +status: todo +type: bug +priority: normal +created_at: 2026-03-10T23:30:29Z +updated_at: 2026-03-10T23:30:31Z +blocked_by: + - nbd-l38k +--- + ## Problem Currently `nbd graph ` renders the subtree **below** the given ticket via dependent edges (tickets blocked by it). After the graph orientation fix (see ticket 668150), `nbd graph ` will render the dependency subtree **below** the given ticket. @@ -54,4 +59,4 @@ In `src/main.rs`: Add integration tests in `tests/integration.rs`: - Create tickets A, B, C, D, E with A depending on B/C/D, and B depending on E -- Assert `nbd graph B` output contains A and E but not C and D \ No newline at end of file +- Assert `nbd graph B` output contains A and E but not C and D diff --git a/nbd/.nbd/tickets/4aceeb.md b/nbd/.beans/nbd-m9q2--nbd-init-add-cachedb-to-nbdgitignore.md similarity index 83% rename from nbd/.nbd/tickets/4aceeb.md rename to nbd/.beans/nbd-m9q2--nbd-init-add-cachedb-to-nbdgitignore.md index b10ff36..ae31620 100644 --- a/nbd/.nbd/tickets/4aceeb.md +++ b/nbd/.beans/nbd-m9q2--nbd-init-add-cachedb-to-nbdgitignore.md @@ -1,10 +1,13 @@ -+++ -title = "nbd init: add cache.db to .nbd/.gitignore" -priority = 5 -status = "todo" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-m9q2 +title: 'nbd init: add cache.db to .nbd/.gitignore' +status: todo +type: task +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem `.nbd/cache.db` is a Turso/libsql SQLite cache file created automatically by `list_tickets_cached`. It should never be committed to git. Currently `nbd init` does not create a `.gitignore` to exclude it. @@ -30,4 +33,4 @@ The JSON output for `--json` should include a `gitignore` key indicating the pat **`tests/integration.rs`** -Add a test that runs `nbd init` and asserts `.nbd/.gitignore` contains `cache.db`. Run `nbd init` a second time and assert the file is unchanged (idempotent). \ No newline at end of file +Add a test that runs `nbd init` and asserts `.nbd/.gitignore` contains `cache.db`. Run `nbd init` a second time and assert the file is unchanged (idempotent). diff --git a/nbd/.nbd/tickets/39b2cf.md b/nbd/.beans/nbd-mkkm--add-xml-output-format-that-wraps-each-ticket-secti.md similarity index 92% rename from nbd/.nbd/tickets/39b2cf.md rename to nbd/.beans/nbd-mkkm--add-xml-output-format-that-wraps-each-ticket-secti.md index 71a77d3..b48e563 100644 --- a/nbd/.nbd/tickets/39b2cf.md +++ b/nbd/.beans/nbd-mkkm--add-xml-output-format-that-wraps-each-ticket-secti.md @@ -1,10 +1,13 @@ -+++ -title = "Add --xml output format that wraps each ticket section in XML tags" -priority = 4 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-mkkm +title: Add --xml output format that wraps each ticket section in XML tags +status: todo +type: feature +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Background From `nbd/TODO.md`: @@ -101,4 +104,4 @@ All commands that support `--json` should also support `--xml`: - `nbd migrate` - `nbd graph` (the JSON graph format has a defined structure; XML should mirror it) - `nbd claude-md` (wrap snippet in `` tag) -- `nbd init` (wrap root path in ``) \ No newline at end of file +- `nbd init` (wrap root path in ``) diff --git a/nbd/.nbd/tickets/0f577a.md b/nbd/.beans/nbd-n2xz--investigate-user-configurable-type-and-status-stri.md similarity index 89% rename from nbd/.nbd/tickets/0f577a.md rename to nbd/.beans/nbd-n2xz--investigate-user-configurable-type-and-status-stri.md index 96c7a1f..5d679e2 100644 --- a/nbd/.nbd/tickets/0f577a.md +++ b/nbd/.beans/nbd-n2xz--investigate-user-configurable-type-and-status-stri.md @@ -1,10 +1,13 @@ -+++ -title = "Investigate: user-configurable type and status strings with lifecycle phases" -priority = 3 -status = "backlog" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-n2xz +title: 'Investigate: user-configurable type and status strings with lifecycle phases' +status: draft +type: task +priority: low +created_at: 2026-03-10T23:30:29Z +updated_at: 2026-03-10T23:30:29Z +--- + ## Problem `type` and `status` are currently hard-coded Rust enums. Users cannot add custom values (e.g., `status = "review"` or `type = "spike"`) without modifying the codebase. But certain status values (`done`, `archived`, `closed`) have special semantics (excluded from `list`/`ready`/`next`; counted as resolved for deps). Making these extensible requires a design that lets users declare which values are "pre-work", "in-work", and "post-work". @@ -45,4 +48,4 @@ Allow `type` to be any string. Keep built-in types (`project`, `feature`, `task` ## Expected output -Create one or more follow-up tickets with a concrete implementation plan and migration strategy. \ No newline at end of file +Create one or more follow-up tickets with a concrete implementation plan and migration strategy. diff --git a/nbd/.nbd/tickets/c24ee8.md b/nbd/.beans/nbd-no88--add-version-flag-with-xyzgitsha-format.md similarity index 95% rename from nbd/.nbd/tickets/c24ee8.md rename to nbd/.beans/nbd-no88--add-version-flag-with-xyzgitsha-format.md index 8af79f4..fbc4145 100644 --- a/nbd/.nbd/tickets/c24ee8.md +++ b/nbd/.beans/nbd-no88--add-version-flag-with-xyzgitsha-format.md @@ -1,10 +1,13 @@ -+++ -title = "Add --version flag with X.Y.Z+GitSha format" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-no88 +title: Add --version flag with X.Y.Z+GitSha format +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Goal Add a `--version` / `-V` flag to `nbd` that prints the version in the format: @@ -123,4 +126,4 @@ fn version_flag_exits_zero_with_semver() { cargo fmt && cargo check && cargo clippy && cargo test cargo run -- --version # Expected output: nbd 0.1.0+ -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/d1634a.md b/nbd/.beans/nbd-o3k8--remove-id-field-from-ticket-json-body.md similarity index 94% rename from nbd/.nbd/tickets/d1634a.md rename to nbd/.beans/nbd-o3k8--remove-id-field-from-ticket-json-body.md index 1b2d9f1..52101c1 100644 --- a/nbd/.nbd/tickets/d1634a.md +++ b/nbd/.beans/nbd-o3k8--remove-id-field-from-ticket-json-body.md @@ -1,10 +1,13 @@ -+++ -title = "Remove id field from ticket JSON body" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-o3k8 +title: Remove id field from ticket JSON body +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + The ticket ID is already encoded in the filename (`a3f9c2.json`). Storing it redundantly inside the JSON body creates a potential consistency hazard (the two could disagree) and wastes space. The filename should be the sole source of truth for the ID. ## Motivation @@ -77,4 +80,4 @@ Integration tests (`tests/integration.rs`): - `src/ticket.rs` — add `#[serde(skip)]` to `id` - `src/store.rs` — `read_ticket` and `list_tickets` inject id from filename - `src/tests.rs` — update and add unit tests -- `tests/integration.rs` — add assertion that written files lack `"id"` key \ No newline at end of file +- `tests/integration.rs` — add assertion that written files lack `"id"` key diff --git a/nbd/.nbd/tickets/833807.md b/nbd/.beans/nbd-oziy--turso-cache-for-list-performance.md similarity index 93% rename from nbd/.nbd/tickets/833807.md rename to nbd/.beans/nbd-oziy--turso-cache-for-list-performance.md index bff67a5..c0937d4 100644 --- a/nbd/.nbd/tickets/833807.md +++ b/nbd/.beans/nbd-oziy--turso-cache-for-list-performance.md @@ -1,10 +1,13 @@ -+++ -title = "Turso cache for list performance" -priority = 3 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-oziy +title: Turso cache for list performance +status: completed +type: feature +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + Add a Turso (libsql) cache in `.nbd/cache.db` to accelerate `nbd list` and `nbd ready` for large ticket stores. ## Motivation @@ -64,4 +67,4 @@ Fall back to `list_tickets` on any cache error. cargo fmt && cargo check && cargo clippy && cargo test cargo run -- list # should create .nbd/cache.db on first run cargo run -- list # second run uses cache -``` \ No newline at end of file +``` diff --git a/nbd/.nbd/tickets/887344.md b/nbd/.beans/nbd-p9na--wire-filter-flag-into-list-ready-and-migrate-comma.md similarity index 94% rename from nbd/.nbd/tickets/887344.md rename to nbd/.beans/nbd-p9na--wire-filter-flag-into-list-ready-and-migrate-comma.md index 6f36efd..e019885 100644 --- a/nbd/.nbd/tickets/887344.md +++ b/nbd/.beans/nbd-p9na--wire-filter-flag-into-list-ready-and-migrate-comma.md @@ -1,10 +1,15 @@ -+++ -title = "Wire --filter flag into list, ready, and migrate commands" -priority = 8 -status = "done" -ticket_type = "feature" -dependencies = ["c2a024"] -+++ +--- +# nbd-p9na +title: Wire --filter flag into list, ready, and migrate commands +status: completed +type: feature +priority: critical +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:32Z +blocked_by: + - nbd-zz62 +--- + ## Summary Add `--filter KEY=VALUE` (repeatable) to the `list`, `ready`, and `migrate` CLI commands. @@ -147,4 +152,4 @@ JSON format: add `"skipped": N` key to the existing object. **error cases:** - `--filter` with unknown key exits non-zero. -- `--filter` with no `=` exits non-zero. \ No newline at end of file +- `--filter` with no `=` exits non-zero. diff --git a/nbd/.nbd/tickets/1939a7.md b/nbd/.beans/nbd-pq2x--nbd-archive-command-and-closed-status.md similarity index 88% rename from nbd/.nbd/tickets/1939a7.md rename to nbd/.beans/nbd-pq2x--nbd-archive-command-and-closed-status.md index 6a22ee0..b362a52 100644 --- a/nbd/.nbd/tickets/1939a7.md +++ b/nbd/.beans/nbd-pq2x--nbd-archive-command-and-closed-status.md @@ -1,10 +1,13 @@ -+++ -title = "nbd archive command and Closed status" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-pq2x +title: nbd archive command and Closed status +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:29Z +updated_at: 2026-03-10T23:30:29Z +--- + Add `Status::Closed` (serialised as `"closed"`) and a convenience `nbd archive ` command that sets it. ## Motivation @@ -47,4 +50,4 @@ Add `Status::Closed` (serialised as `"closed"`) and a convenience `nbd archive < - `src/display.rs` — `status_str` update - `src/tests.rs` — unit tests - `tests/integration.rs` — integration tests -- `README.md` — document archive and --all \ No newline at end of file +- `README.md` — document archive and --all diff --git a/nbd/.nbd/tickets/0f51af.md b/nbd/.beans/nbd-q2d1--nbd-migrate-command.md similarity index 95% rename from nbd/.nbd/tickets/0f51af.md rename to nbd/.beans/nbd-q2d1--nbd-migrate-command.md index 4bc3cf1..92e8a73 100644 --- a/nbd/.nbd/tickets/0f51af.md +++ b/nbd/.beans/nbd-q2d1--nbd-migrate-command.md @@ -1,10 +1,15 @@ -+++ -title = "nbd migrate command" -priority = 9 -status = "done" -ticket_type = "feature" -dependencies = ["d1634a"] -+++ +--- +# nbd-q2d1 +title: nbd migrate command +status: completed +type: feature +priority: critical +created_at: 2026-03-10T23:30:29Z +updated_at: 2026-03-10T23:30:31Z +blocked_by: + - nbd-o3k8 +--- + Add `nbd migrate` to bring all ticket files on disk into conformance with the current schema. This is the standard mechanism for handling any schema change — field removals, field additions, renames, or type changes. ## Motivation @@ -108,4 +113,4 @@ Integration tests (`tests/integration.rs`): - `src/display.rs` — `print_migrate_report` - `src/tests.rs` — unit tests - `tests/integration.rs` — integration tests -- `README.md` — document `nbd migrate` \ No newline at end of file +- `README.md` — document `nbd migrate` diff --git a/nbd/.nbd/tickets/1c686c.md b/nbd/.beans/nbd-ql0c--add-next-type-filtered-sub-commands-next-bug-next.md similarity index 81% rename from nbd/.nbd/tickets/1c686c.md rename to nbd/.beans/nbd-ql0c--add-next-type-filtered-sub-commands-next-bug-next.md index 10b3914..74a801c 100644 --- a/nbd/.nbd/tickets/1c686c.md +++ b/nbd/.beans/nbd-ql0c--add-next-type-filtered-sub-commands-next-bug-next.md @@ -1,10 +1,13 @@ -+++ -title = "Add next filtered sub-commands (next bug, next feature, next task)" -priority = 4 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-ql0c +title: Add next filtered sub-commands (next bug, next feature, next task) +status: todo +type: feature +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem `nbd next --filter type=bug` is verbose. When an engineer wants the highest-priority ready bug, they should be able to say `nbd next bug`. @@ -41,4 +44,4 @@ Explicit `--filter type=...` values are ORed with the positional shorthand, cons **`tests/integration.rs`** -Add tests verifying that `next bug` returns only bug-type ready tickets and that `next` with no argument still works as before. \ No newline at end of file +Add tests verifying that `next bug` returns only bug-type ready tickets and that `next` with no argument still works as before. diff --git a/nbd/.nbd/tickets/c9d551.md b/nbd/.beans/nbd-rulc--partial-id-matching.md similarity index 88% rename from nbd/.nbd/tickets/c9d551.md rename to nbd/.beans/nbd-rulc--partial-id-matching.md index 4087712..7c7e859 100644 --- a/nbd/.nbd/tickets/c9d551.md +++ b/nbd/.beans/nbd-rulc--partial-id-matching.md @@ -1,10 +1,13 @@ -+++ -title = "Partial ID matching" -priority = 8 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-rulc +title: Partial ID matching +status: completed +type: feature +priority: critical +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + Allow `nbd read`, `nbd update`, and dependency resolution to accept a prefix of a ticket ID (e.g. `nbd read a3f` resolves to `a3f9c2`). ## Motivation @@ -40,4 +43,4 @@ Integration tests in `tests/integration.rs`: - `src/store.rs` — new `resolve_id` function - `src/main.rs` — `cmd_read`, `cmd_update`, `validate_deps` use `resolve_id` - `src/tests.rs` — unit tests -- `tests/integration.rs` — integration tests \ No newline at end of file +- `tests/integration.rs` — integration tests diff --git a/nbd/.nbd/tickets/460caf.md b/nbd/.beans/nbd-s16w--multiple-file-format-support-md-toml-jsonb.md similarity index 92% rename from nbd/.nbd/tickets/460caf.md rename to nbd/.beans/nbd-s16w--multiple-file-format-support-md-toml-jsonb.md index fcf9e44..46cb657 100644 --- a/nbd/.nbd/tickets/460caf.md +++ b/nbd/.beans/nbd-s16w--multiple-file-format-support-md-toml-jsonb.md @@ -1,10 +1,13 @@ -+++ -title = "Multiple file format support (md, toml, jsonb)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-s16w +title: Multiple file format support (md, toml, jsonb) +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + Add `--ftype` flag to `create` and `update` to write tickets in markdown, TOML, or binary JSON (CBOR) in addition to the existing JSON format. Format is detected from file extension on read. ## Motivation @@ -81,4 +84,4 @@ Long-form body text goes here. Supports full markdown. - `src/tests.rs` — format roundtrip tests - `tests/integration.rs` — format integration tests - `README.md` — document `--ftype` -- `docs/ARCHITECTURE.md` — update storage layout section \ No newline at end of file +- `docs/ARCHITECTURE.md` — update storage layout section diff --git a/nbd/.nbd/tickets/67209c.md b/nbd/.beans/nbd-urlz--investigate-filtering-tickets-by-project-stream-of.md similarity index 85% rename from nbd/.nbd/tickets/67209c.md rename to nbd/.beans/nbd-urlz--investigate-filtering-tickets-by-project-stream-of.md index f2d1009..63cf1b1 100644 --- a/nbd/.nbd/tickets/67209c.md +++ b/nbd/.beans/nbd-urlz--investigate-filtering-tickets-by-project-stream-of.md @@ -1,10 +1,13 @@ -+++ -title = "Investigate: filtering tickets by project / stream of work" -priority = 3 -status = "backlog" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-urlz +title: 'Investigate: filtering tickets by project / stream of work' +status: draft +type: task +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem When multiple streams of work coexist (e.g., refactoring vs. new feature), there is no way to select tickets for one stream only. `nbd next` and `nbd list` operate across all tickets. @@ -28,4 +31,4 @@ Investigate by: ## Expected output -Create one or more follow-up tickets with a concrete implementation plan, or close this ticket with a rationale if the existing tools are sufficient. \ No newline at end of file +Create one or more follow-up tickets with a concrete implementation plan, or close this ticket with a rationale if the existing tools are sufficient. diff --git a/nbd/.nbd/tickets/6e4239.md b/nbd/.beans/nbd-wbf7--nix-flake-for-nbd.md similarity index 87% rename from nbd/.nbd/tickets/6e4239.md rename to nbd/.beans/nbd-wbf7--nix-flake-for-nbd.md index 56def80..7db092b 100644 --- a/nbd/.nbd/tickets/6e4239.md +++ b/nbd/.beans/nbd-wbf7--nix-flake-for-nbd.md @@ -1,10 +1,13 @@ -+++ -title = "Nix flake for nbd" -priority = 4 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-wbf7 +title: Nix flake for nbd +status: completed +type: task +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + Add `nbd/flake.nix` so that `nbd` can be consumed as a Nix package and used as a CLI tool in other projects in the mono-repo. ## Motivation @@ -35,4 +38,4 @@ The `buildRustPackage` derivation requires a `cargoHash` (or `cargoSha256`). Use ## Files touched - `nbd/flake.nix` — new file -- `README.md` — add `nix run` usage section \ No newline at end of file +- `README.md` — add `nix run` usage section diff --git a/nbd/.nbd/tickets/1c5783.md b/nbd/.beans/nbd-wi74--version-file-compile-into-binary-via-include-str-a.md similarity index 91% rename from nbd/.nbd/tickets/1c5783.md rename to nbd/.beans/nbd-wi74--version-file-compile-into-binary-via-include-str-a.md index 4cc414b..339e568 100644 --- a/nbd/.nbd/tickets/1c5783.md +++ b/nbd/.beans/nbd-wi74--version-file-compile-into-binary-via-include-str-a.md @@ -1,10 +1,13 @@ -+++ -title = 'VERSION file: compile into binary via include_str\! and add nbd version subcommand' -priority = 5 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-wi74 +title: '''VERSION file: compile into binary via include_str\! and add nbd version subcommand''' +status: todo +type: feature +priority: normal +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Problem The current version string is assembled in `main.rs` from `CARGO_PKG_VERSION` (Cargo.toml) and `GIT_SHORT_SHA` (build.rs). There is no `nbd version` subcommand — only `--version`. And the `/work` skill does not bump any version on completion. @@ -73,4 +76,4 @@ The skill should read `VERSION`, parse the semver, increment the appropriate com - `nbd/build.rs` (update: emit `NBD_VERSION`) - `nbd/src/main.rs` (update: use `NBD_VERSION`, add `Version` subcommand) - `nbd/Cargo.toml` (keep version in sync with `VERSION` file) -- `.claude/skills/work/SKILL.md` (update: add version-bump step) \ No newline at end of file +- `.claude/skills/work/SKILL.md` (update: add version-bump step) diff --git a/nbd/.nbd/tickets/8b4041.md b/nbd/.beans/nbd-y4nv--change-graph-cycle-marker-from-cycle-to.md similarity index 87% rename from nbd/.nbd/tickets/8b4041.md rename to nbd/.beans/nbd-y4nv--change-graph-cycle-marker-from-cycle-to.md index 334330a..973b420 100644 --- a/nbd/.nbd/tickets/8b4041.md +++ b/nbd/.beans/nbd-y4nv--change-graph-cycle-marker-from-cycle-to.md @@ -1,10 +1,13 @@ -+++ -title = "Change graph cycle marker from [cycle] to *" -priority = 3 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# nbd-y4nv +title: Change graph cycle marker from [cycle] to * +status: completed +type: task +priority: low +created_at: 2026-03-10T23:30:30Z +updated_at: 2026-03-10T23:30:30Z +--- + ## Goal When `nbd graph` renders a node that has already been visited (a node appearing in multiple branches of the tree), it currently labels the repeat occurrence as `[cycle]`. This label is misleading — the node isn't truly in a cycle, it's simply appearing twice in the tree because it's depended on from multiple places. Change the marker to `*` to indicate "this ticket appears elsewhere in the tree". @@ -55,4 +58,4 @@ cargo fmt && cargo check && cargo clippy && cargo test cargo run -- graph ``` -Any test that checks for `[cycle]` in graph output needs updating to expect `*` instead. \ No newline at end of file +Any test that checks for `[cycle]` in graph output needs updating to expect `*` instead. diff --git a/nbd/.nbd/tickets/e222cd.md b/nbd/.beans/nbd-yh0v--add-triage-status-new-default-for-tickets-lacking.md similarity index 91% rename from nbd/.nbd/tickets/e222cd.md rename to nbd/.beans/nbd-yh0v--add-triage-status-new-default-for-tickets-lacking.md index dc04418..e6e489a 100644 --- a/nbd/.nbd/tickets/e222cd.md +++ b/nbd/.beans/nbd-yh0v--add-triage-status-new-default-for-tickets-lacking.md @@ -1,10 +1,13 @@ -+++ -title = "Add triage status: new default for tickets lacking implementation detail" -priority = 6 -status = "todo" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-yh0v +title: 'Add triage status: new default for tickets lacking implementation detail' +status: todo +type: feature +priority: normal +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Problem New tickets are created with `status=todo`, implying they are ready to work on. But many tickets need further research or implementation details before work can begin. The TODO describes a `triage` status for exactly this case — tickets that need an LLM or human to fill in details before they become `todo`. @@ -79,4 +82,4 @@ Add unit tests: - `nbd next` does not include `triage` tickets. - `nbd list` does not include `triage` tickets by default. - `nbd list --filter status=triage` shows only triage tickets. -- `nbd list --all` includes `triage` tickets. \ No newline at end of file +- `nbd list --all` includes `triage` tickets. diff --git a/nbd/.nbd/tickets/c2a024.md b/nbd/.beans/nbd-zz62--implement-ticketfilter-module-with-glob-matching.md similarity index 96% rename from nbd/.nbd/tickets/c2a024.md rename to nbd/.beans/nbd-zz62--implement-ticketfilter-module-with-glob-matching.md index 4adf4df..22a1395 100644 --- a/nbd/.nbd/tickets/c2a024.md +++ b/nbd/.beans/nbd-zz62--implement-ticketfilter-module-with-glob-matching.md @@ -1,10 +1,13 @@ -+++ -title = "Implement TicketFilter module with glob matching" -priority = 8 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# nbd-zz62 +title: Implement TicketFilter module with glob matching +status: completed +type: feature +priority: critical +created_at: 2026-03-10T23:30:31Z +updated_at: 2026-03-10T23:30:31Z +--- + ## Summary Add a `src/filter.rs` module implementing `TicketFilter`, which parses and applies @@ -129,4 +132,4 @@ The module is `pub(crate)`. - `TicketFilter::matches` — same key OR correctly (either matches). - `TicketFilter::matches` — empty filter matches everything. - `TicketFilter::is_empty` — true when no filters, false when any filter set. -- `TicketFilter::has_status_filter` — true iff status vec is non-empty. \ No newline at end of file +- `TicketFilter::has_status_filter` — true iff status vec is non-empty. diff --git a/nbd/.nbd/.gitignore b/nbd/.nbd/.gitignore deleted file mode 100644 index be8efad..0000000 --- a/nbd/.nbd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cache.db diff --git a/nbd/.nbd/tickets/b05b5a.json b/nbd/.nbd/tickets/b05b5a.json deleted file mode 100644 index 081995c..0000000 --- a/nbd/.nbd/tickets/b05b5a.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "title": "Test archive", - "body": "", - "priority": 5, - "status": "archived", - "dependencies": [], - "ticket_type": "task" -} \ No newline at end of file diff --git a/nbd/.nbd/tickets/e6b9df.json b/nbd/.nbd/tickets/e6b9df.json deleted file mode 100644 index eef5fcf..0000000 --- a/nbd/.nbd/tickets/e6b9df.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "title": "Test ticket", - "body": "Some body text", - "priority": 7, - "status": "done", - "dependencies": [], - "ticket_type": "bug" -} \ No newline at end of file diff --git a/nbd/CLAUDE.md b/nbd/CLAUDE.md index 58c1d29..558a9dd 100644 --- a/nbd/CLAUDE.md +++ b/nbd/CLAUDE.md @@ -114,77 +114,61 @@ nbd graph [] [--filter KEY=VALUE ...] [--json] -## Task Tracking with nbd +## Task Tracking with beans -Use `nbd` to track tasks for work on this project. Since the binary is not -installed, always invoke via `cargo run` from the `nbd/` directory: +Use `beans` to track tasks for work on this project. ```sh -cargo run -- [flags] -``` - -The `.nbd/` directory at the project root is the ticket store. If it does not -exist yet, initialise it first: - -```sh -cargo run -- init +beans init # run once; creates .beans/ ``` ### Workflow -Always pass `--json` to every command. -Use `jq` to parse and transform the JSON output if necessary. +Always pass `--json` to every command. Use `jq` to parse output when needed. -**Before starting work:** Create a ticket for the task. Use `--ftype md` so the body is stored as human-readable markdown. +**Before starting work:** Create a bean. ```sh -cargo run -- create --title "Add partial ID matching" --type feature --priority 7 --ftype md --json +beans create --json "Add partial ID matching" --type feature --priority high --status todo ``` **When starting a task:** Update its status. ```sh -cargo run -- update --status in_progress --json +beans update --json --status in-progress ``` **When done:** Mark it complete. ```sh -cargo run -- update --status done --json -``` - -**To get the single best ticket to work on next:** - -```sh -cargo run -- next --json +beans update --json --status completed ``` -**To see all tickets that are unblocked and ready to start:** +**To see all beans ready to start:** ```sh -cargo run -- ready --json +beans list --json --ready ``` -**To see all tickets:** +**To see all beans:** ```sh -cargo run -- list --json +beans list --json ``` -**To read a specific ticket:** +**To view a specific bean:** ```sh -cargo run -- read --json +beans show --json ``` ### Guidelines - **Always use `--json`.** It gives structured, unambiguous output on every command. -- **Always use `--ftype md`** when creating tickets. Markdown format keeps the body human-readable in the file browser. -- Create tickets *before* starting non-trivial tasks, not after. -- Use `--deps id1,id2` to express blockers — tickets that must be done first. -- `--priority` follows 0–10: use 7–9 for bugs, 5 for normal tasks, 3 for nice-to-haves. -- `--type` choices: `project`, `feature`, `task`, `bug`. +- Create beans *before* starting non-trivial tasks, not after. +- Use `--blocked-by ` to express blockers — beans that must be done first. +- `--priority` choices: `critical`, `high`, `normal`, `low`, `deferred`. +- `--type` choices: `milestone`, `epic`, `feature`, `task`, `bug`. diff --git a/quotesdb/.beans.yml b/quotesdb/.beans.yml new file mode 100644 index 0000000..b53de64 --- /dev/null +++ b/quotesdb/.beans.yml @@ -0,0 +1,6 @@ +beans: + path: .beans + prefix: quotesdb- + id_length: 4 + default_status: todo + default_type: task diff --git a/quotesdb/.nbd/tickets/69a2c5.md b/quotesdb/.beans/quotesdb-04cw--quotesdbapi-db-layer-add-submissions-locked-update.md similarity index 86% rename from quotesdb/.nbd/tickets/69a2c5.md rename to quotesdb/.beans/quotesdb-04cw--quotesdbapi-db-layer-add-submissions-locked-update.md index ac1ce2a..cb8890d 100644 --- a/quotesdb/.nbd/tickets/69a2c5.md +++ b/quotesdb/.beans/quotesdb-04cw--quotesdbapi-db-layer-add-submissions-locked-update.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/api: DB layer — add submissions_locked + update_admin_auth_code" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-04cw +title: 'quotesdb/api: DB layer — add submissions_locked + update_admin_auth_code' +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- + ## Goal Extend the DB abstraction layer with three new trait methods and seed on startup. @@ -61,4 +64,4 @@ cargo fmt && cargo check && cargo clippy && cargo test `feat(quotesdb): ...` ## Design reference -`docs/plans/2026-03-04-admin-features-design.md` \ No newline at end of file +`docs/plans/2026-03-04-admin-features-design.md` diff --git a/quotesdb/.nbd/tickets/5cdbd9.md b/quotesdb/.beans/quotesdb-0flf--implement-browse-page-browse-paginated-quote-list.md similarity index 77% rename from quotesdb/.nbd/tickets/5cdbd9.md rename to quotesdb/.beans/quotesdb-0flf--implement-browse-page-browse-paginated-quote-list.md index a60bb6c..e4f41fc 100644 --- a/quotesdb/.nbd/tickets/5cdbd9.md +++ b/quotesdb/.beans/quotesdb-0flf--implement-browse-page-browse-paginated-quote-list.md @@ -1,10 +1,20 @@ -+++ -title = "Implement Browse page (/browse) — paginated quote list with author/tag filter controls" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["04f865", "1e6a09", "0d987f", "2c5a57", "d3d502", "fc2f51", "0fbdd5"] -+++ +--- +# quotesdb-0flf +title: Implement Browse page (/browse) — paginated quote list with author/tag filter controls +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-xqh3 + - quotesdb-dgwi + - quotesdb-oukj + - quotesdb-6huz + - quotesdb-kg2l + - quotesdb-k258 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/5b3475.md b/quotesdb/.beans/quotesdb-0wpo--submit-form-author-optional-default-anonymous-clar.md similarity index 91% rename from quotesdb/.nbd/tickets/5b3475.md rename to quotesdb/.beans/quotesdb-0wpo--submit-form-author-optional-default-anonymous-clar.md index d242ca8..aea6896 100644 --- a/quotesdb/.nbd/tickets/5b3475.md +++ b/quotesdb/.beans/quotesdb-0wpo--submit-form-author-optional-default-anonymous-clar.md @@ -1,10 +1,13 @@ -+++ -title = "Submit form: author optional (default Anonymous), clarify auth code auto-generation" -priority = 5 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# quotesdb-0wpo +title: 'Submit form: author optional (default Anonymous), clarify auth code auto-generation' +status: completed +type: bug +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- + ## Bug Two related UX issues on the submit form (`src/bin/ui/pages/submit.rs`): @@ -80,4 +83,4 @@ Manually test: submit a quote with author left blank — it should succeed and d ## Commit scope -`fix(quotesdb): submit form author optional and auth code label` \ No newline at end of file +`fix(quotesdb): submit form author optional and auth code label` diff --git a/quotesdb/.nbd/tickets/372790.md b/quotesdb/.beans/quotesdb-0x53--write-uireadmemd-uidocsplanningmd-uidocsarchitectu.md similarity index 76% rename from quotesdb/.nbd/tickets/372790.md rename to quotesdb/.beans/quotesdb-0x53--write-uireadmemd-uidocsplanningmd-uidocsarchitectu.md index 61b93af..5262b35 100644 --- a/quotesdb/.nbd/tickets/372790.md +++ b/quotesdb/.beans/quotesdb-0x53--write-uireadmemd-uidocsplanningmd-uidocsarchitectu.md @@ -1,10 +1,18 @@ -+++ -title = "Write ui/README.md, ui/docs/PLANNING.md, ui/docs/ARCHITECTURE.md" -priority = 3 -status = "done" -ticket_type = "task" -dependencies = ["1a274d", "1ba523", "5f1112", "b3ef98", "5cdbd9"] -+++ +--- +# quotesdb-0x53 +title: Write ui/README.md, ui/docs/PLANNING.md, ui/docs/ARCHITECTURE.md +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-m9vb + - quotesdb-ivwr + - quotesdb-297v + - quotesdb-jlef + - quotesdb-0flf +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/6f2e18.md b/quotesdb/.beans/quotesdb-1o8u--triage-nanoid-crate-wasm-compatibility-with-worker.md similarity index 91% rename from quotesdb/.nbd/tickets/6f2e18.md rename to quotesdb/.beans/quotesdb-1o8u--triage-nanoid-crate-wasm-compatibility-with-worker.md index 5cdf6ed..86618fa 100644 --- a/quotesdb/.nbd/tickets/6f2e18.md +++ b/quotesdb/.beans/quotesdb-1o8u--triage-nanoid-crate-wasm-compatibility-with-worker.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] NanoID crate WASM compatibility with workers-rs target" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-1o8u +title: '[TRIAGE] NanoID crate WASM compatibility with workers-rs target' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/c3c8c6.md b/quotesdb/.beans/quotesdb-250z--quotesdbui-admin-page-component.md similarity index 93% rename from quotesdb/.nbd/tickets/c3c8c6.md rename to quotesdb/.beans/quotesdb-250z--quotesdbui-admin-page-component.md index 8a0ce38..61d2407 100644 --- a/quotesdb/.nbd/tickets/c3c8c6.md +++ b/quotesdb/.beans/quotesdb-250z--quotesdbui-admin-page-component.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/ui: /admin page component" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["161f32"] -+++ +--- +# quotesdb-250z +title: 'quotesdb/ui: /admin page component' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:18Z +blocked_by: + - quotesdb-d09v +--- + ## /admin page component (UI) Create the /admin route and page component. The page provides a persistent admin auth code input, an auth code reset section, and a submissions lock/unlock section. @@ -100,4 +105,4 @@ cargo fmt && cargo check --target wasm32-unknown-unknown --bin ui ``` feat(quotesdb): /admin page component -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/5f1112.md b/quotesdb/.beans/quotesdb-297v--implement-quote-detail-page-quotesid-view-edit-for.md similarity index 78% rename from quotesdb/.nbd/tickets/5f1112.md rename to quotesdb/.beans/quotesdb-297v--implement-quote-detail-page-quotesid-view-edit-for.md index ec981bc..a288fab 100644 --- a/quotesdb/.nbd/tickets/5f1112.md +++ b/quotesdb/.beans/quotesdb-297v--implement-quote-detail-page-quotesid-view-edit-for.md @@ -1,10 +1,19 @@ -+++ -title = "Implement Quote detail page (/quotes/:id) — view, edit form with auth prompt, delete with auth prompt" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["04f865", "1e6a09", "0d987f", "f850c6", "fc2f51", "0fbdd5"] -+++ +--- +# quotesdb-297v +title: Implement Quote detail page (/quotes/:id) — view, edit form with auth prompt, delete with auth prompt +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-xqh3 + - quotesdb-dgwi + - quotesdb-oukj + - quotesdb-qqdf + - quotesdb-k258 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/b38032.md b/quotesdb/.beans/quotesdb-29nd--refactor-to-single-crate-with-api-and-ui-binaries.md similarity index 97% rename from quotesdb/.nbd/tickets/b38032.md rename to quotesdb/.beans/quotesdb-29nd--refactor-to-single-crate-with-api-and-ui-binaries.md index 6b47306..747df28 100644 --- a/quotesdb/.nbd/tickets/b38032.md +++ b/quotesdb/.beans/quotesdb-29nd--refactor-to-single-crate-with-api-and-ui-binaries.md @@ -1,10 +1,14 @@ -+++ -title = "Refactor to single-crate with api and ui binaries" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["ec118c"] -+++ +--- +# quotesdb-29nd +title: Refactor to single-crate with api and ui binaries +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-32yd +--- Collapse the three separate sub-crates (`api/`, `ui/`, `tests/`) into a single Cargo crate rooted at `quotesdb/`. This simplifies the project structure, enables direct code sharing between the api and ui via `src/lib.rs`, and makes `cargo test` run all tests (unit + integration) in a single invocation. diff --git a/quotesdb/.nbd/tickets/f9f448.md b/quotesdb/.beans/quotesdb-2nlt--test-suite-get-apiquotesid-200-with-quote-404-not.md similarity index 80% rename from quotesdb/.nbd/tickets/f9f448.md rename to quotesdb/.beans/quotesdb-2nlt--test-suite-get-apiquotesid-200-with-quote-404-not.md index ad9bbf2..4e7bc98 100644 --- a/quotesdb/.nbd/tickets/f9f448.md +++ b/quotesdb/.beans/quotesdb-2nlt--test-suite-get-apiquotesid-200-with-quote-404-not.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: GET /api/quotes/:id — 200 with quote, 404 not found, schema validation" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "5dbb7d"] -+++ +--- +# quotesdb-2nlt +title: 'Test suite: GET /api/quotes/:id — 200 with quote, 404 not found, schema validation' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-gu9j + - quotesdb-nrue +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/ec118c.md b/quotesdb/.beans/quotesdb-32yd--quotesdb.md similarity index 97% rename from quotesdb/.nbd/tickets/ec118c.md rename to quotesdb/.beans/quotesdb-32yd--quotesdb.md index 5e78c33..3fbd159 100644 --- a/quotesdb/.nbd/tickets/ec118c.md +++ b/quotesdb/.beans/quotesdb-32yd--quotesdb.md @@ -1,10 +1,17 @@ -+++ -title = "quotesdb" -priority = 8 -status = "todo" -ticket_type = "project" -dependencies = ["ce1e4f", "f3dc74", "c3503b", "25c413"] -+++ +--- +# quotesdb-32yd +title: quotesdb +status: todo +type: epic +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-ryhx + - quotesdb-pqdw + - quotesdb-ndjj + - quotesdb-xi3i +--- REQUIRED: Use `superpowers:executing-plans` to implement this plan task-by-task. diff --git a/quotesdb/.nbd/tickets/fc9bfd.md b/quotesdb/.beans/quotesdb-3951--triage-cloudflare-pages-build-strategy-pages-ci-bu.md similarity index 91% rename from quotesdb/.nbd/tickets/fc9bfd.md rename to quotesdb/.beans/quotesdb-3951--triage-cloudflare-pages-build-strategy-pages-ci-bu.md index 1a686d7..04a86cf 100644 --- a/quotesdb/.nbd/tickets/fc9bfd.md +++ b/quotesdb/.beans/quotesdb-3951--triage-cloudflare-pages-build-strategy-pages-ci-bu.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Cloudflare Pages build strategy — Pages CI build vs pre-built trunk artifact upload" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-3951 +title: '[TRIAGE] Cloudflare Pages build strategy — Pages CI build vs pre-built trunk artifact upload' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:12Z +updated_at: 2026-03-10T23:32:12Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/d0da0b.md b/quotesdb/.beans/quotesdb-3euj--define-cloudflare-d1-database-resource-and-documen.md similarity index 87% rename from quotesdb/.nbd/tickets/d0da0b.md rename to quotesdb/.beans/quotesdb-3euj--define-cloudflare-d1-database-resource-and-documen.md index 314559e..3ad86ed 100644 --- a/quotesdb/.nbd/tickets/d0da0b.md +++ b/quotesdb/.beans/quotesdb-3euj--define-cloudflare-d1-database-resource-and-documen.md @@ -1,10 +1,15 @@ -+++ -title = "Define Cloudflare D1 database resource and document binding name for the Worker" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["2d1371", "5c0c64"] -+++ +--- +# quotesdb-3euj +title: Define Cloudflare D1 database resource and document binding name for the Worker +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-zzm3 + - quotesdb-4tec +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. The D1 database must be provisioned before the Worker can bind to it — OpenTofu handles this automatically via the attribute reference in the Worker resource (see triage 07cafb). diff --git a/quotesdb/.nbd/tickets/a57e7e.md b/quotesdb/.beans/quotesdb-3mk8--cloudflare-turnstile-captcha-on-quote-submission.md similarity index 95% rename from quotesdb/.nbd/tickets/a57e7e.md rename to quotesdb/.beans/quotesdb-3mk8--cloudflare-turnstile-captcha-on-quote-submission.md index 37ecee0..96e1de0 100644 --- a/quotesdb/.nbd/tickets/a57e7e.md +++ b/quotesdb/.beans/quotesdb-3mk8--cloudflare-turnstile-captcha-on-quote-submission.md @@ -1,10 +1,13 @@ -+++ -title = "Cloudflare Turnstile CAPTCHA on quote submission" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-3mk8 +title: Cloudflare Turnstile CAPTCHA on quote submission +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- + ## Feature Add Cloudflare Turnstile CAPTCHA to protect the `PUT /api/quotes` endpoint (and the submit form in the UI) from bots and spam. This is a three-part change: infra, API, and UI. @@ -141,4 +144,4 @@ Manually verify: the submit form shows the Turnstile widget and submission is bl ## Commit scope -`feat(quotesdb): Cloudflare Turnstile CAPTCHA on submit` \ No newline at end of file +`feat(quotesdb): Cloudflare Turnstile CAPTCHA on submit` diff --git a/quotesdb/.nbd/tickets/08af7a.md b/quotesdb/.beans/quotesdb-45sn--write-apireadmemd-apidocsplanningmd-apidocsarchite.md similarity index 85% rename from quotesdb/.nbd/tickets/08af7a.md rename to quotesdb/.beans/quotesdb-45sn--write-apireadmemd-apidocsplanningmd-apidocsarchite.md index 94d2a6a..b04e4fd 100644 --- a/quotesdb/.nbd/tickets/08af7a.md +++ b/quotesdb/.beans/quotesdb-45sn--write-apireadmemd-apidocsplanningmd-apidocsarchite.md @@ -1,10 +1,14 @@ -+++ -title = "Write api/README.md, api/docs/PLANNING.md, api/docs/ARCHITECTURE.md" -priority = 3 -status = "done" -ticket_type = "task" -dependencies = ["a6bce1"] -+++ +--- +# quotesdb-45sn +title: Write api/README.md, api/docs/PLANNING.md, api/docs/ARCHITECTURE.md +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-kh9l +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/886bfd.md b/quotesdb/.beans/quotesdb-4gqi--implement-get-apiquotes-paginated-list-with-author.md similarity index 86% rename from quotesdb/.nbd/tickets/886bfd.md rename to quotesdb/.beans/quotesdb-4gqi--implement-get-apiquotes-paginated-list-with-author.md index 5b36e99..b63ad93 100644 --- a/quotesdb/.nbd/tickets/886bfd.md +++ b/quotesdb/.beans/quotesdb-4gqi--implement-get-apiquotes-paginated-list-with-author.md @@ -1,10 +1,16 @@ -+++ -title = "Implement GET /api/quotes — paginated list with author filter (case-insensitive) and tag filter" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2", "175382"] -+++ +--- +# quotesdb-4gqi +title: Implement GET /api/quotes — paginated list with author filter (case-insensitive) and tag filter +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr + - quotesdb-qf7x +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/93f1b6.md b/quotesdb/.beans/quotesdb-4pxt--test-suite-get-apiquotes-pagination-page1-pagen-ou.md similarity index 81% rename from quotesdb/.nbd/tickets/93f1b6.md rename to quotesdb/.beans/quotesdb-4pxt--test-suite-get-apiquotes-pagination-page1-pagen-ou.md index ed6e3fd..f44f94f 100644 --- a/quotesdb/.nbd/tickets/93f1b6.md +++ b/quotesdb/.beans/quotesdb-4pxt--test-suite-get-apiquotes-pagination-page1-pagen-ou.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: GET /api/quotes — pagination (page=1, page=N, out-of-range), author filter, tag filter, no results" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "886bfd"] -+++ +--- +# quotesdb-4pxt +title: 'Test suite: GET /api/quotes — pagination (page=1, page=N, out-of-range), author filter, tag filter, no results' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-gu9j + - quotesdb-4gqi +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/6e829e.md b/quotesdb/.beans/quotesdb-4t5j--set-up-apisrcmainrs-cloudflare-workers-entry-point.md similarity index 86% rename from quotesdb/.nbd/tickets/6e829e.md rename to quotesdb/.beans/quotesdb-4t5j--set-up-apisrcmainrs-cloudflare-workers-entry-point.md index edbb4a9..33988c8 100644 --- a/quotesdb/.nbd/tickets/6e829e.md +++ b/quotesdb/.beans/quotesdb-4t5j--set-up-apisrcmainrs-cloudflare-workers-entry-point.md @@ -1,10 +1,14 @@ -+++ -title = "Set up api/src/main.rs — Cloudflare Workers entry point and Axum router wiring" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5"] -+++ +--- +# quotesdb-4t5j +title: Set up api/src/main.rs — Cloudflare Workers entry point and Axum router wiring +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-ghzc +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/5c0c64.md b/quotesdb/.beans/quotesdb-4tec--triage-d1-migrations-in-opentofu-null-resource-loc.md similarity index 91% rename from quotesdb/.nbd/tickets/5c0c64.md rename to quotesdb/.beans/quotesdb-4tec--triage-d1-migrations-in-opentofu-null-resource-loc.md index c714484..b76db63 100644 --- a/quotesdb/.nbd/tickets/5c0c64.md +++ b/quotesdb/.beans/quotesdb-4tec--triage-d1-migrations-in-opentofu-null-resource-loc.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] D1 migrations in OpenTofu — null_resource local-exec vs separate wrangler step vs manual" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-4tec +title: '[TRIAGE] D1 migrations in OpenTofu — null_resource local-exec vs separate wrangler step vs manual' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/d6ba23.md b/quotesdb/.beans/quotesdb-58hf--bootstrap-quotesdb-project-skeleton.md similarity index 51% rename from quotesdb/.nbd/tickets/d6ba23.md rename to quotesdb/.beans/quotesdb-58hf--bootstrap-quotesdb-project-skeleton.md index 3e7cf3d..8cac50d 100644 --- a/quotesdb/.nbd/tickets/d6ba23.md +++ b/quotesdb/.beans/quotesdb-58hf--bootstrap-quotesdb-project-skeleton.md @@ -1,10 +1,14 @@ -+++ -title = "Bootstrap quotesdb project skeleton" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["ec118c"] -+++ +--- +# quotesdb-58hf +title: Bootstrap quotesdb project skeleton +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-32yd +--- This was the initial bootstrap task for the quotesdb project. It has been completed. diff --git a/quotesdb/.nbd/tickets/6ed325.md b/quotesdb/.beans/quotesdb-58hh--triage-4-word-passphrase-crate-selection-for-wasm.md similarity index 93% rename from quotesdb/.nbd/tickets/6ed325.md rename to quotesdb/.beans/quotesdb-58hh--triage-4-word-passphrase-crate-selection-for-wasm.md index 5e6715f..1e52c9a 100644 --- a/quotesdb/.nbd/tickets/6ed325.md +++ b/quotesdb/.beans/quotesdb-58hh--triage-4-word-passphrase-crate-selection-for-wasm.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] 4-word passphrase crate selection for WASM target (no_std/wasm32 constraints)" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-58hh +title: '[TRIAGE] 4-word passphrase crate selection for WASM target (no_std/wasm32 constraints)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/8892d5.md b/quotesdb/.beans/quotesdb-5aow--add-buildrs-convert-apiopenapiyaml-to-json-at-comp.md similarity index 93% rename from quotesdb/.nbd/tickets/8892d5.md rename to quotesdb/.beans/quotesdb-5aow--add-buildrs-convert-apiopenapiyaml-to-json-at-comp.md index bfc2c0b..82f0643 100644 --- a/quotesdb/.nbd/tickets/8892d5.md +++ b/quotesdb/.beans/quotesdb-5aow--add-buildrs-convert-apiopenapiyaml-to-json-at-comp.md @@ -1,10 +1,12 @@ -+++ -title = "Add build.rs — convert api/openapi.yaml to JSON at compile time for Workers embed" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-5aow +title: Add build.rs — convert api/openapi.yaml to JSON at compile time for Workers embed +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- Resolved from TRIAGE ticket 2ec8b1. The `GET /api/` endpoint must serve the OpenAPI spec as JSON. diff --git a/quotesdb/.nbd/tickets/5379eb.md b/quotesdb/.beans/quotesdb-5dda--implement-auth-code-session-storage-utility-module.md similarity index 94% rename from quotesdb/.nbd/tickets/5379eb.md rename to quotesdb/.beans/quotesdb-5dda--implement-auth-code-session-storage-utility-module.md index 1018ba7..f6df934 100644 --- a/quotesdb/.nbd/tickets/5379eb.md +++ b/quotesdb/.beans/quotesdb-5dda--implement-auth-code-session-storage-utility-module.md @@ -1,10 +1,12 @@ -+++ -title = "Implement auth code session storage — utility module and AuthModal pre-fill integration" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-5dda +title: Implement auth code session storage — utility module and AuthModal pre-fill integration +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- Resolved from TRIAGE ticket 0bc655. The auth code (4-word passphrase) that authorises edit and diff --git a/quotesdb/.nbd/tickets/71b1d4.md b/quotesdb/.beans/quotesdb-625z--document-secrets-management-cloudflare-api-token-a.md similarity index 77% rename from quotesdb/.nbd/tickets/71b1d4.md rename to quotesdb/.beans/quotesdb-625z--document-secrets-management-cloudflare-api-token-a.md index acac51c..e6bda4d 100644 --- a/quotesdb/.nbd/tickets/71b1d4.md +++ b/quotesdb/.beans/quotesdb-625z--document-secrets-management-cloudflare-api-token-a.md @@ -1,10 +1,14 @@ -+++ -title = "Document secrets management — Cloudflare API token, account ID, how to supply to OpenTofu and local dev" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["2d1371"] -+++ +--- +# quotesdb-625z +title: Document secrets management — Cloudflare API token, account ID, how to supply to OpenTofu and local dev +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-zzm3 +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/2c5a57.md b/quotesdb/.beans/quotesdb-6huz--implement-pagination-component-prevnext-buttons-cu.md similarity index 78% rename from quotesdb/.nbd/tickets/2c5a57.md rename to quotesdb/.beans/quotesdb-6huz--implement-pagination-component-prevnext-buttons-cu.md index 2e16709..6f62dc4 100644 --- a/quotesdb/.nbd/tickets/2c5a57.md +++ b/quotesdb/.beans/quotesdb-6huz--implement-pagination-component-prevnext-buttons-cu.md @@ -1,10 +1,15 @@ -+++ -title = "Implement pagination component — prev/next buttons, current page indicator, total pages" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "0fbdd5"] -+++ +--- +# quotesdb-6huz +title: Implement pagination component — prev/next buttons, current page indicator, total pages +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-kaat + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/7a0d9f.md b/quotesdb/.beans/quotesdb-6lh5--implement-generate-id-in-srclibrs-uuid-v4-for-wasm.md similarity index 94% rename from quotesdb/.nbd/tickets/7a0d9f.md rename to quotesdb/.beans/quotesdb-6lh5--implement-generate-id-in-srclibrs-uuid-v4-for-wasm.md index e6e4c33..a2c36e7 100644 --- a/quotesdb/.nbd/tickets/7a0d9f.md +++ b/quotesdb/.beans/quotesdb-6lh5--implement-generate-id-in-srclibrs-uuid-v4-for-wasm.md @@ -1,10 +1,12 @@ -+++ -title = "Implement generate_id() in src/lib.rs — UUID v4 for WASM-compatible quote IDs" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-6lh5 +title: Implement generate_id() in src/lib.rs — UUID v4 for WASM-compatible quote IDs +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- Resolved from TRIAGE ticket 6f2e18. The `nanoid` crate is not suitable for wasm32-unknown-unknown diff --git a/quotesdb/.nbd/tickets/a5049d.md b/quotesdb/.beans/quotesdb-6ng5--implement-database-connection-module-and-sqlx-migr.md similarity index 90% rename from quotesdb/.nbd/tickets/a5049d.md rename to quotesdb/.beans/quotesdb-6ng5--implement-database-connection-module-and-sqlx-migr.md index 098225c..d572980 100644 --- a/quotesdb/.nbd/tickets/a5049d.md +++ b/quotesdb/.beans/quotesdb-6ng5--implement-database-connection-module-and-sqlx-migr.md @@ -1,10 +1,16 @@ -+++ -title = "Implement database connection module and SQLx migrations (quotes + quote_tags schema)" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5", "580e66", "33ed29"] -+++ +--- +# quotesdb-6ng5 +title: Implement database connection module and SQLx migrations (quotes + quote_tags schema) +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-ghzc + - quotesdb-zlfi + - quotesdb-td4l +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/28e7d9.md b/quotesdb/.beans/quotesdb-753n--implement-get-api-serve-openapi-spec-as-json.md similarity index 90% rename from quotesdb/.nbd/tickets/28e7d9.md rename to quotesdb/.beans/quotesdb-753n--implement-get-api-serve-openapi-spec-as-json.md index ac6d303..30aa2b4 100644 --- a/quotesdb/.nbd/tickets/28e7d9.md +++ b/quotesdb/.beans/quotesdb-753n--implement-get-api-serve-openapi-spec-as-json.md @@ -1,10 +1,15 @@ -+++ -title = "Implement GET /api/ — serve OpenAPI spec as JSON" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5", "8892d5"] -+++ +--- +# quotesdb-753n +title: Implement GET /api/ — serve OpenAPI spec as JSON +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-ghzc + - quotesdb-5aow +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/ae6a82.md b/quotesdb/.beans/quotesdb-76hx--define-cloudflare-worker-routedomain-workerdev-sub.md similarity index 81% rename from quotesdb/.nbd/tickets/ae6a82.md rename to quotesdb/.beans/quotesdb-76hx--define-cloudflare-worker-routedomain-workerdev-sub.md index 4aecec5..2bfd9d4 100644 --- a/quotesdb/.nbd/tickets/ae6a82.md +++ b/quotesdb/.beans/quotesdb-76hx--define-cloudflare-worker-routedomain-workerdev-sub.md @@ -1,10 +1,14 @@ -+++ -title = "Define Cloudflare Worker route/domain — worker.dev subdomain or custom route for API" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["a23489"] -+++ +--- +# quotesdb-76hx +title: Define Cloudflare Worker route/domain — worker.dev subdomain or custom route for API +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-vsgd +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/354276.md b/quotesdb/.beans/quotesdb-792p--quotesdbui-report-button-with-modal-reason-field-c.md similarity index 83% rename from quotesdb/.nbd/tickets/354276.md rename to quotesdb/.beans/quotesdb-792p--quotesdbui-report-button-with-modal-reason-field-c.md index 3f48b90..5e8ef8a 100644 --- a/quotesdb/.nbd/tickets/354276.md +++ b/quotesdb/.beans/quotesdb-792p--quotesdbui-report-button-with-modal-reason-field-c.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/ui: report button with modal (reason field + captcha)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["77237f"] -+++ +--- +# quotesdb-792p +title: 'quotesdb/ui: report button with modal (reason field + captcha)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-i37j +--- + ## Summary Add a Report button to quote detail pages that opens a modal with an optional reason field and a CAPTCHA to prevent abuse. @@ -40,4 +45,4 @@ Use Cloudflare Turnstile (free, privacy-friendly). Site key stored as an environ ```sh cargo fmt && cargo check && cargo clippy trunk build -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/efee79.md b/quotesdb/.beans/quotesdb-8zm9--triage-correct-cloudflare-workers-script-resource.md similarity index 87% rename from quotesdb/.nbd/tickets/efee79.md rename to quotesdb/.beans/quotesdb-8zm9--triage-correct-cloudflare-workers-script-resource.md index 0fe57cc..c3407bf 100644 --- a/quotesdb/.nbd/tickets/efee79.md +++ b/quotesdb/.beans/quotesdb-8zm9--triage-correct-cloudflare-workers-script-resource.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Correct cloudflare_workers_script resource name in current Cloudflare provider version" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-8zm9 +title: '[TRIAGE] Correct cloudflare_workers_script resource name in current Cloudflare provider version' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:11Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/0bc655.md b/quotesdb/.beans/quotesdb-9e3j--triage-auth-code-storage-strategy-localstorage-per.md similarity index 91% rename from quotesdb/.nbd/tickets/0bc655.md rename to quotesdb/.beans/quotesdb-9e3j--triage-auth-code-storage-strategy-localstorage-per.md index 8a9ce3c..b725588 100644 --- a/quotesdb/.nbd/tickets/0bc655.md +++ b/quotesdb/.beans/quotesdb-9e3j--triage-auth-code-storage-strategy-localstorage-per.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Auth code storage strategy — localStorage persistence vs component-only state?" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-9e3j +title: '[TRIAGE] Auth code storage strategy — localStorage persistence vs component-only state?' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/75489a.md b/quotesdb/.beans/quotesdb-9fpn--document-d1-schema-migration-workflow-how-to-apply.md similarity index 86% rename from quotesdb/.nbd/tickets/75489a.md rename to quotesdb/.beans/quotesdb-9fpn--document-d1-schema-migration-workflow-how-to-apply.md index 2815c9f..2387ac2 100644 --- a/quotesdb/.nbd/tickets/75489a.md +++ b/quotesdb/.beans/quotesdb-9fpn--document-d1-schema-migration-workflow-how-to-apply.md @@ -1,10 +1,15 @@ -+++ -title = "Document D1 schema migration workflow — how to apply SQL schema changes to D1 in CI/CD" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["d0da0b", "bb1514"] -+++ +--- +# quotesdb-9fpn +title: Document D1 schema migration workflow — how to apply SQL schema changes to D1 in CI/CD +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-3euj + - quotesdb-hmbh +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/00aff0.md b/quotesdb/.beans/quotesdb-9ghn--implement-db-abstraction-quoterepository-trait-cfg.md similarity index 98% rename from quotesdb/.nbd/tickets/00aff0.md rename to quotesdb/.beans/quotesdb-9ghn--implement-db-abstraction-quoterepository-trait-cfg.md index 1701c09..343fa2f 100644 --- a/quotesdb/.nbd/tickets/00aff0.md +++ b/quotesdb/.beans/quotesdb-9ghn--implement-db-abstraction-quoterepository-trait-cfg.md @@ -1,10 +1,12 @@ -+++ -title = "Implement DB abstraction: QuoteRepository trait + cfg-split D1/rusqlite impls" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-9ghn +title: 'Implement DB abstraction: QuoteRepository trait + cfg-split D1/rusqlite impls' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:04Z +updated_at: 2026-03-10T23:32:04Z +--- Resolution of TRIAGE ticket e8a330: **SQLx is NOT compatible with Cloudflare Workers/D1.** @@ -340,4 +342,4 @@ cargo check --target wasm32-unknown-unknown `feat(quotesdb): implement QuoteRepository trait and cfg-split D1/rusqlite DB abstraction` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/14570c.md b/quotesdb/.beans/quotesdb-9jsk--quotesdbui-submit-page-locked-state-banner.md similarity index 90% rename from quotesdb/.nbd/tickets/14570c.md rename to quotesdb/.beans/quotesdb-9jsk--quotesdbui-submit-page-locked-state-banner.md index 6b379a3..cca1dcd 100644 --- a/quotesdb/.nbd/tickets/14570c.md +++ b/quotesdb/.beans/quotesdb-9jsk--quotesdbui-submit-page-locked-state-banner.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/ui: /submit page locked-state banner" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["161f32"] -+++ +--- +# quotesdb-9jsk +title: 'quotesdb/ui: /submit page locked-state banner' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-d09v +--- + ## /submit page locked-state banner (UI) Modify the existing /submit page to check the submission lock on mount. When the lock is active, hide the submission form entirely and show a closed-submissions banner in its place. @@ -97,4 +102,4 @@ cargo fmt && cargo check --target wasm32-unknown-unknown --bin ui ``` feat(quotesdb): show locked banner on /submit when submissions are closed -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/5e3e37.md b/quotesdb/.beans/quotesdb-9lxc--triage-cssstyling-approach-for-wasm-plain-css-cdn.md similarity index 90% rename from quotesdb/.nbd/tickets/5e3e37.md rename to quotesdb/.beans/quotesdb-9lxc--triage-cssstyling-approach-for-wasm-plain-css-cdn.md index d134c87..ceed86d 100644 --- a/quotesdb/.nbd/tickets/5e3e37.md +++ b/quotesdb/.beans/quotesdb-9lxc--triage-cssstyling-approach-for-wasm-plain-css-cdn.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] CSS/styling approach for Wasm — plain CSS, CDN Tailwind, or Wasm-compatible crate?" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-9lxc +title: '[TRIAGE] CSS/styling approach for Wasm — plain CSS, CDN Tailwind, or Wasm-compatible crate?' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/05f8ae.md b/quotesdb/.beans/quotesdb-a0q1--implement-put-apiquotes-create-quote-generate-uuid.md similarity index 84% rename from quotesdb/.nbd/tickets/05f8ae.md rename to quotesdb/.beans/quotesdb-a0q1--implement-put-apiquotes-create-quote-generate-uuid.md index 2ca8ae8..8db2336 100644 --- a/quotesdb/.nbd/tickets/05f8ae.md +++ b/quotesdb/.beans/quotesdb-a0q1--implement-put-apiquotes-create-quote-generate-uuid.md @@ -1,10 +1,18 @@ -+++ -title = "Implement PUT /api/quotes — create quote, generate UUID v4 ID, generate auth_code if not provided, return 201 with auth_code" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2", "03bb91", "175382", "7a0d9f"] -+++ +--- +# quotesdb-a0q1 +title: Implement PUT /api/quotes — create quote, generate UUID v4 ID, generate auth_code if not provided, return 201 with auth_code +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr + - quotesdb-wmvy + - quotesdb-qf7x + - quotesdb-6lh5 +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/2ab7a8.md b/quotesdb/.beans/quotesdb-aa9s--triage-test-harness-how-to-import-and-start-quotes.md similarity index 88% rename from quotesdb/.nbd/tickets/2ab7a8.md rename to quotesdb/.beans/quotesdb-aa9s--triage-test-harness-how-to-import-and-start-quotes.md index df89959..0a03a9d 100644 --- a/quotesdb/.nbd/tickets/2ab7a8.md +++ b/quotesdb/.beans/quotesdb-aa9s--triage-test-harness-how-to-import-and-start-quotes.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Test harness: how to import and start quotesdb-api in tests (workers-rs vs native build target)" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-aa9s +title: '[TRIAGE] Test harness: how to import and start quotesdb-api in tests (workers-rs vs native build target)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:06Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/57fe5e.md b/quotesdb/.beans/quotesdb-ah5w--write-giteaworkflowsdeploy-apiyml-gitea-actions-wo.md similarity index 93% rename from quotesdb/.nbd/tickets/57fe5e.md rename to quotesdb/.beans/quotesdb-ah5w--write-giteaworkflowsdeploy-apiyml-gitea-actions-wo.md index c0bdeab..35acdd2 100644 --- a/quotesdb/.nbd/tickets/57fe5e.md +++ b/quotesdb/.beans/quotesdb-ah5w--write-giteaworkflowsdeploy-apiyml-gitea-actions-wo.md @@ -1,10 +1,15 @@ -+++ -title = "Write .gitea/workflows/deploy-api.yml — Gitea Actions workflow to build and deploy API Worker via OpenTofu" -priority = 4 -status = "done" -ticket_type = "task" -dependencies = ["a23489", "2d1371"] -+++ +--- +# quotesdb-ah5w +title: Write .gitea/workflows/deploy-api.yml — Gitea Actions workflow to build and deploy API Worker via OpenTofu +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-vsgd + - quotesdb-zzm3 +--- The API Worker is a workers-rs Wasm binary deployed to Cloudflare Workers. The OpenTofu resource (`infra/worker.tf`) reads the compiled Wasm via `filebase64("../target/wasm32-unknown-unknown/release/api.wasm")` and uploads it on `tofu apply`. This means the CI workflow must compile the Wasm before running `tofu apply`. diff --git a/quotesdb/.nbd/tickets/3781c9.md b/quotesdb/.beans/quotesdb-ap4c--verify-api-worker-gzipped-binary-size-is-within-cf.md similarity index 91% rename from quotesdb/.nbd/tickets/3781c9.md rename to quotesdb/.beans/quotesdb-ap4c--verify-api-worker-gzipped-binary-size-is-within-cf.md index 0f73990..3e924c7 100644 --- a/quotesdb/.nbd/tickets/3781c9.md +++ b/quotesdb/.beans/quotesdb-ap4c--verify-api-worker-gzipped-binary-size-is-within-cf.md @@ -1,10 +1,14 @@ -+++ -title = "Verify API worker gzipped binary size is within CF Workers free tier (3 MB limit)" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5"] -+++ +--- +# quotesdb-ap4c +title: Verify API worker gzipped binary size is within CF Workers free tier (3 MB limit) +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-ghzc +--- Resolved from TRIAGE ticket 182210. The original concern (1 MB Workers free tier limit) was based on diff --git a/quotesdb/.nbd/tickets/5f5ba0.md b/quotesdb/.beans/quotesdb-bl2g--set-up-testscargotoml-with-integration-test-depend.md similarity index 82% rename from quotesdb/.nbd/tickets/5f5ba0.md rename to quotesdb/.beans/quotesdb-bl2g--set-up-testscargotoml-with-integration-test-depend.md index 95d209e..7fbf966 100644 --- a/quotesdb/.nbd/tickets/5f5ba0.md +++ b/quotesdb/.beans/quotesdb-bl2g--set-up-testscargotoml-with-integration-test-depend.md @@ -1,10 +1,15 @@ -+++ -title = "Set up tests/Cargo.toml with integration test dependencies (reqwest/hyper, tokio, serde_json)" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["0d84fa", "fba598"] -+++ +--- +# quotesdb-bl2g +title: Set up tests/Cargo.toml with integration test dependencies (reqwest/hyper, tokio, serde_json) +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-z43c + - quotesdb-jpu5 +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. diff --git a/quotesdb/.nbd/tickets/b01bad.md b/quotesdb/.beans/quotesdb-bysu--fix-compiler-warnings-in-api-and-ui-binaries.md similarity index 88% rename from quotesdb/.nbd/tickets/b01bad.md rename to quotesdb/.beans/quotesdb-bysu--fix-compiler-warnings-in-api-and-ui-binaries.md index 0668e36..ee5fe1c 100644 --- a/quotesdb/.nbd/tickets/b01bad.md +++ b/quotesdb/.beans/quotesdb-bysu--fix-compiler-warnings-in-api-and-ui-binaries.md @@ -1,10 +1,13 @@ -+++ -title = "Fix compiler warnings in api and ui binaries" -priority = 7 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# quotesdb-bysu +title: Fix compiler warnings in api and ui binaries +status: completed +type: bug +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:10Z +--- + ## Bug Running `cargo build --target wasm32-unknown-unknown` (and `trunk build`) produces compiler warnings in both the `api` and `ui` binaries. All warnings should be resolved so the build is clean. @@ -59,4 +62,4 @@ Also run `trunk build` and confirm no warnings are emitted for the `quotesdb` cr ## Commit scope -`fix(quotesdb): resolve compiler warnings in api and ui` \ No newline at end of file +`fix(quotesdb): resolve compiler warnings in api and ui` diff --git a/quotesdb/.nbd/tickets/5d9f5a.md b/quotesdb/.beans/quotesdb-bz2v--implement-post-apiquotesid-partial-update-verify-x.md similarity index 86% rename from quotesdb/.nbd/tickets/5d9f5a.md rename to quotesdb/.beans/quotesdb-bz2v--implement-post-apiquotesid-partial-update-verify-x.md index a60933e..aed9b7f 100644 --- a/quotesdb/.nbd/tickets/5d9f5a.md +++ b/quotesdb/.beans/quotesdb-bz2v--implement-post-apiquotesid-partial-update-verify-x.md @@ -1,10 +1,16 @@ -+++ -title = "Implement POST /api/quotes/:id — partial update, verify X-Auth-Code header, update updated_at" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2", "175382"] -+++ +--- +# quotesdb-bz2v +title: Implement POST /api/quotes/:id — partial update, verify X-Auth-Code header, update updated_at +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr + - quotesdb-qf7x +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/07cafb.md b/quotesdb/.beans/quotesdb-cc35--triage-d1-binding-chicken-and-egg-d1-id-not-known.md similarity index 92% rename from quotesdb/.nbd/tickets/07cafb.md rename to quotesdb/.beans/quotesdb-cc35--triage-d1-binding-chicken-and-egg-d1-id-not-known.md index e20b86f..64a7bdb 100644 --- a/quotesdb/.nbd/tickets/07cafb.md +++ b/quotesdb/.beans/quotesdb-cc35--triage-d1-binding-chicken-and-egg-d1-id-not-known.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] D1 binding chicken-and-egg — D1 ID not known until after apply, but Worker needs it at plan time" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-cc35 +title: '[TRIAGE] D1 binding chicken-and-egg — D1 ID not known until after apply, but Worker needs it at plan time' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/dfd185.md b/quotesdb/.beans/quotesdb-csvt--submit-form-date-field-should-use-typedate-for-cal.md similarity index 86% rename from quotesdb/.nbd/tickets/dfd185.md rename to quotesdb/.beans/quotesdb-csvt--submit-form-date-field-should-use-typedate-for-cal.md index 64672bb..5f8fbb6 100644 --- a/quotesdb/.nbd/tickets/dfd185.md +++ b/quotesdb/.beans/quotesdb-csvt--submit-form-date-field-should-use-typedate-for-cal.md @@ -1,10 +1,13 @@ -+++ -title = "Submit form: date field should use type=date for calendar picker" -priority = 5 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# quotesdb-csvt +title: 'Submit form: date field should use type=date for calendar picker' +status: completed +type: bug +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:11Z +--- + ## Bug The date field on the submit form (`src/bin/ui/pages/submit.rs`, around line 200–215) uses `type="text"` with a placeholder hinting at YYYY-MM-DD format. This means: @@ -46,4 +49,4 @@ Manually verify the date field shows a calendar picker in the browser. ## Commit scope -`fix(quotesdb): submit form date input type` \ No newline at end of file +`fix(quotesdb): submit form date input type` diff --git a/quotesdb/.nbd/tickets/161f32.md b/quotesdb/.beans/quotesdb-d09v--quotesdbui-admin-api-client-functions.md similarity index 94% rename from quotesdb/.nbd/tickets/161f32.md rename to quotesdb/.beans/quotesdb-d09v--quotesdbui-admin-api-client-functions.md index 337c3ec..fe2cc79 100644 --- a/quotesdb/.nbd/tickets/161f32.md +++ b/quotesdb/.beans/quotesdb-d09v--quotesdbui-admin-api-client-functions.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/ui: admin API client functions" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-d09v +title: 'quotesdb/ui: admin API client functions' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- + ## Admin API client functions (UI) Add four async functions to the UI API client module that cover every admin and status endpoint introduced by the API tickets. These functions are consumed by the /admin page and the /submit page. @@ -119,4 +122,4 @@ cargo fmt && cargo check --target wasm32-unknown-unknown --bin ui ``` feat(quotesdb): admin API client functions in UI -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/1e6a09.md b/quotesdb/.beans/quotesdb-dgwi--implement-api-client-module-typed-fetch-wrappers-f.md similarity index 88% rename from quotesdb/.nbd/tickets/1e6a09.md rename to quotesdb/.beans/quotesdb-dgwi--implement-api-client-module-typed-fetch-wrappers-f.md index 59e4d7e..86a243c 100644 --- a/quotesdb/.nbd/tickets/1e6a09.md +++ b/quotesdb/.beans/quotesdb-dgwi--implement-api-client-module-typed-fetch-wrappers-f.md @@ -1,10 +1,14 @@ -+++ -title = "Implement API client module — typed fetch wrappers for all quotesdb-api endpoints" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["93515e"] -+++ +--- +# quotesdb-dgwi +title: Implement API client module — typed fetch wrappers for all quotesdb-api endpoints +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-kaat +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. @@ -51,4 +55,4 @@ trunk build `feat(quotesdb): implement typed API client module for all quotesdb-api endpoints` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/75e3f0.md b/quotesdb/.beans/quotesdb-eh4l--write-testsreadmemd.md similarity index 77% rename from quotesdb/.nbd/tickets/75e3f0.md rename to quotesdb/.beans/quotesdb-eh4l--write-testsreadmemd.md index e1f257f..c9846c7 100644 --- a/quotesdb/.nbd/tickets/75e3f0.md +++ b/quotesdb/.beans/quotesdb-eh4l--write-testsreadmemd.md @@ -1,10 +1,14 @@ -+++ -title = "Write tests/README.md" -priority = 3 -status = "done" -ticket_type = "task" -dependencies = ["9b581f"] -+++ +--- +# quotesdb-eh4l +title: Write tests/README.md +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-gu9j +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/07feaa.md b/quotesdb/.beans/quotesdb-esnq--triage-opentofu-state-backend-local-file-gitignore.md similarity index 88% rename from quotesdb/.nbd/tickets/07feaa.md rename to quotesdb/.beans/quotesdb-esnq--triage-opentofu-state-backend-local-file-gitignore.md index 8dc9d00..31d2b51 100644 --- a/quotesdb/.nbd/tickets/07feaa.md +++ b/quotesdb/.beans/quotesdb-esnq--triage-opentofu-state-backend-local-file-gitignore.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] OpenTofu state backend — local file (gitignored) vs Terraform Cloud vs Cloudflare R2?" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-esnq +title: '[TRIAGE] OpenTofu state backend — local file (gitignored) vs Terraform Cloud vs Cloudflare R2?' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/d792e2.md b/quotesdb/.beans/quotesdb-fagr--implement-error-handling-consistent-error-envelope.md similarity index 85% rename from quotesdb/.nbd/tickets/d792e2.md rename to quotesdb/.beans/quotesdb-fagr--implement-error-handling-consistent-error-envelope.md index b60ef85..b6dfa7d 100644 --- a/quotesdb/.nbd/tickets/d792e2.md +++ b/quotesdb/.beans/quotesdb-fagr--implement-error-handling-consistent-error-envelope.md @@ -1,10 +1,15 @@ -+++ -title = 'Implement error handling — consistent {"error": "..."} envelope for 400/403/404/422/500' -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5", "6e829e"] -+++ +--- +# quotesdb-fagr +title: '''Implement error handling — consistent {"error": "..."} envelope for 400/403/404/422/500''' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-ghzc + - quotesdb-4t5j +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/9ef703.md b/quotesdb/.beans/quotesdb-fg44--add-redirects-spa-fallback-create-file-and-include.md similarity index 90% rename from quotesdb/.nbd/tickets/9ef703.md rename to quotesdb/.beans/quotesdb-fg44--add-redirects-spa-fallback-create-file-and-include.md index 415eeca..4d87bad 100644 --- a/quotesdb/.nbd/tickets/9ef703.md +++ b/quotesdb/.beans/quotesdb-fg44--add-redirects-spa-fallback-create-file-and-include.md @@ -1,10 +1,12 @@ -+++ -title = "Add `_redirects` SPA fallback — create file and include in Trunk build via copy-file" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-fg44 +title: Add `_redirects` SPA fallback — create file and include in Trunk build via copy-file +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- Resolved from TRIAGE ticket e2bd9b. Yew uses client-side routing (BrowserRouter), so a direct diff --git a/quotesdb/.nbd/tickets/166996.md b/quotesdb/.beans/quotesdb-fhhk--triage-yew-version-selection-and-yew-router-compat.md similarity index 80% rename from quotesdb/.nbd/tickets/166996.md rename to quotesdb/.beans/quotesdb-fhhk--triage-yew-version-selection-and-yew-router-compat.md index 7ea2ed2..aa977f2 100644 --- a/quotesdb/.nbd/tickets/166996.md +++ b/quotesdb/.beans/quotesdb-fhhk--triage-yew-version-selection-and-yew-router-compat.md @@ -1,10 +1,13 @@ -+++ -title = "[TRIAGE] Yew version selection and yew-router compatibility (0.21+?)" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-fhhk +title: '[TRIAGE] Yew version selection and yew-router compatibility (0.21+?)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- + This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. @@ -29,4 +32,4 @@ Actions taken: `chore(quotesdb): resolve triage — yew-version-selection-and-yewrouter-compatibility-021` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/1f5bb5.md b/quotesdb/.beans/quotesdb-ghzc--set-up-cargotoml-with-all-crate-dependencies-axum.md similarity index 91% rename from quotesdb/.nbd/tickets/1f5bb5.md rename to quotesdb/.beans/quotesdb-ghzc--set-up-cargotoml-with-all-crate-dependencies-axum.md index 9404054..615c784 100644 --- a/quotesdb/.nbd/tickets/1f5bb5.md +++ b/quotesdb/.beans/quotesdb-ghzc--set-up-cargotoml-with-all-crate-dependencies-axum.md @@ -1,10 +1,14 @@ -+++ -title = "Set up Cargo.toml with all crate dependencies (axum, tokio, workers-rs, rusqlite, serde, uuid, etc.)" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["7a0d9f"] -+++ +--- +# quotesdb-ghzc +title: Set up Cargo.toml with all crate dependencies (axum, tokio, workers-rs, rusqlite, serde, uuid, etc.) +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-6lh5 +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/9b581f.md b/quotesdb/.beans/quotesdb-gu9j--implement-test-server-harness-spawn-quotesdb-api-w.md similarity index 92% rename from quotesdb/.nbd/tickets/9b581f.md rename to quotesdb/.beans/quotesdb-gu9j--implement-test-server-harness-spawn-quotesdb-api-w.md index 525dbc9..f6f8681 100644 --- a/quotesdb/.nbd/tickets/9b581f.md +++ b/quotesdb/.beans/quotesdb-gu9j--implement-test-server-harness-spawn-quotesdb-api-w.md @@ -1,10 +1,16 @@ -+++ -title = "Implement test server harness — spawn quotesdb-api with temp SQLite DB, return base URL" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["5f5ba0", "2ab7a8", "fba598"] -+++ +--- +# quotesdb-gu9j +title: Implement test server harness — spawn quotesdb-api with temp SQLite DB, return base URL +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-bl2g + - quotesdb-aa9s + - quotesdb-jpu5 +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. diff --git a/quotesdb/.nbd/tickets/e8f5cf.md b/quotesdb/.beans/quotesdb-h07r--test-suite-router-ordering-verify-apiquotesrandom.md similarity index 82% rename from quotesdb/.nbd/tickets/e8f5cf.md rename to quotesdb/.beans/quotesdb-h07r--test-suite-router-ordering-verify-apiquotesrandom.md index 9af958a..56c6686 100644 --- a/quotesdb/.nbd/tickets/e8f5cf.md +++ b/quotesdb/.beans/quotesdb-h07r--test-suite-router-ordering-verify-apiquotesrandom.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: router ordering — verify /api/quotes/random is not matched as :id parameter" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "6e829e"] -+++ +--- +# quotesdb-h07r +title: 'Test suite: router ordering — verify /api/quotes/random is not matched as :id parameter' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-gu9j + - quotesdb-4t5j +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/aa0eab.md b/quotesdb/.beans/quotesdb-hag9--test-suite-get-apiquotesrandom-200-with-quote-404.md similarity index 78% rename from quotesdb/.nbd/tickets/aa0eab.md rename to quotesdb/.beans/quotesdb-hag9--test-suite-get-apiquotesrandom-200-with-quote-404.md index c5e4be9..dfc99d5 100644 --- a/quotesdb/.nbd/tickets/aa0eab.md +++ b/quotesdb/.beans/quotesdb-hag9--test-suite-get-apiquotesrandom-200-with-quote-404.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: GET /api/quotes/random — 200 with quote, 404 when database is empty" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "2ce22e"] -+++ +--- +# quotesdb-hag9 +title: 'Test suite: GET /api/quotes/random — 200 with quote, 404 when database is empty' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-gu9j + - quotesdb-l4e9 +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/d5839a.md b/quotesdb/.beans/quotesdb-hfhl--write-infrareadmemd-setup-apply-destroy-instructio.md similarity index 69% rename from quotesdb/.nbd/tickets/d5839a.md rename to quotesdb/.beans/quotesdb-hfhl--write-infrareadmemd-setup-apply-destroy-instructio.md index 56cac5f..69e364e 100644 --- a/quotesdb/.nbd/tickets/d5839a.md +++ b/quotesdb/.beans/quotesdb-hfhl--write-infrareadmemd-setup-apply-destroy-instructio.md @@ -1,10 +1,18 @@ -+++ -title = "Write infra/README.md — setup, apply, destroy instructions and required credentials" -priority = 3 -status = "done" -ticket_type = "task" -dependencies = ["2d1371", "d0da0b", "a23489", "ae886f", "ae6a82"] -+++ +--- +# quotesdb-hfhl +title: Write infra/README.md — setup, apply, destroy instructions and required credentials +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-zzm3 + - quotesdb-3euj + - quotesdb-vsgd + - quotesdb-qt7m + - quotesdb-76hx +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/bb1514.md b/quotesdb/.beans/quotesdb-hmbh--create-infraschemasql-idempotent-d1-schema-for-quo.md similarity index 95% rename from quotesdb/.nbd/tickets/bb1514.md rename to quotesdb/.beans/quotesdb-hmbh--create-infraschemasql-idempotent-d1-schema-for-quo.md index 18f1d78..660f7f4 100644 --- a/quotesdb/.nbd/tickets/bb1514.md +++ b/quotesdb/.beans/quotesdb-hmbh--create-infraschemasql-idempotent-d1-schema-for-quo.md @@ -1,10 +1,15 @@ -+++ -title = "Create infra/schema.sql — idempotent D1 schema for quotes and quote_tags" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["d0da0b", "5c0c64"] -+++ +--- +# quotesdb-hmbh +title: Create infra/schema.sql — idempotent D1 schema for quotes and quote_tags +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:18Z +blocked_by: + - quotesdb-3euj + - quotesdb-4tec +--- TRIAGE 5c0c64 resolved: the chosen D1 migration strategy is a **separate wrangler step**. diff --git a/quotesdb/.beans/quotesdb-hna0--support-admin-auth-code-cloudflare-secret-for-admi.md b/quotesdb/.beans/quotesdb-hna0--support-admin-auth-code-cloudflare-secret-for-admi.md new file mode 100644 index 0000000..3449f40 --- /dev/null +++ b/quotesdb/.beans/quotesdb-hna0--support-admin-auth-code-cloudflare-secret-for-admi.md @@ -0,0 +1,10 @@ +--- +# quotesdb-hna0 +title: Support ADMIN_AUTH_CODE Cloudflare secret for admin auth +status: completed +type: feature +priority: critical +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:10Z +--- + diff --git a/quotesdb/.nbd/tickets/af56a7.md b/quotesdb/.beans/quotesdb-hord--write-docslocal-devmd-local-dev-quickstart-cargo-r.md similarity index 90% rename from quotesdb/.nbd/tickets/af56a7.md rename to quotesdb/.beans/quotesdb-hord--write-docslocal-devmd-local-dev-quickstart-cargo-r.md index 4f2a0f0..e7b821d 100644 --- a/quotesdb/.nbd/tickets/af56a7.md +++ b/quotesdb/.beans/quotesdb-hord--write-docslocal-devmd-local-dev-quickstart-cargo-r.md @@ -1,10 +1,14 @@ -+++ -title = "Write docs/LOCAL_DEV.md — local dev quickstart (cargo run + trunk serve, rusqlite, DATABASE_URL)" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["33ed29"] -+++ +--- +# quotesdb-hord +title: Write docs/LOCAL_DEV.md — local dev quickstart (cargo run + trunk serve, rusqlite, DATABASE_URL) +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-td4l +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file (development). @@ -66,4 +70,4 @@ Write `docs/LOCAL_DEV.md` explaining how to set up and run the quotesdb project `docs(quotesdb): write LOCAL_DEV.md — local dev quickstart for api and ui` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/77237f.md b/quotesdb/.beans/quotesdb-i37j--quotesdbapi-reports-table-and-post-apiquotesidrepo.md similarity index 83% rename from quotesdb/.nbd/tickets/77237f.md rename to quotesdb/.beans/quotesdb-i37j--quotesdbapi-reports-table-and-post-apiquotesidrepo.md index d2bfaaf..2080e13 100644 --- a/quotesdb/.nbd/tickets/77237f.md +++ b/quotesdb/.beans/quotesdb-i37j--quotesdbapi-reports-table-and-post-apiquotesidrepo.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/api: reports table and POST /api/quotes/:id/report endpoint" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-i37j +title: 'quotesdb/api: reports table and POST /api/quotes/:id/report endpoint' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- + ## Summary Create a reports table and a public endpoint for reporting quotes for moderation review. @@ -39,4 +42,4 @@ Rate limiting will be handled separately at the Cloudflare layer (see infra tick ## Validation ```sh cargo fmt && cargo check && cargo clippy && cargo test -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/9d756a.md b/quotesdb/.beans/quotesdb-iar0--home-page-show-friendly-empty-state-when-no-quotes.md similarity index 84% rename from quotesdb/.nbd/tickets/9d756a.md rename to quotesdb/.beans/quotesdb-iar0--home-page-show-friendly-empty-state-when-no-quotes.md index 47ebcfe..5b26dd1 100644 --- a/quotesdb/.nbd/tickets/9d756a.md +++ b/quotesdb/.beans/quotesdb-iar0--home-page-show-friendly-empty-state-when-no-quotes.md @@ -1,10 +1,13 @@ -+++ -title = "Home page: show friendly empty state when no quotes in database" -priority = 7 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# quotesdb-iar0 +title: 'Home page: show friendly empty state when no quotes in database' +status: completed +type: bug +priority: high +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- + ## Bug When the database is empty, `GET /api/quotes/random` returns a 404 response. The home page (`src/bin/ui/pages/home.rs`) currently treats all errors (including 404) the same way — it sets the `error` state and displays it via ``, which results in something like a raw JSON error message being shown to the user. @@ -43,4 +46,4 @@ cargo run & ## Commit scope -`fix(quotesdb): home page empty state` \ No newline at end of file +`fix(quotesdb): home page empty state` diff --git a/quotesdb/.nbd/tickets/1ba523.md b/quotesdb/.beans/quotesdb-ivwr--implement-submit-page-submit-quote-creation-form-d.md similarity index 80% rename from quotesdb/.nbd/tickets/1ba523.md rename to quotesdb/.beans/quotesdb-ivwr--implement-submit-page-submit-quote-creation-form-d.md index 46c5e53..58bbd12 100644 --- a/quotesdb/.nbd/tickets/1ba523.md +++ b/quotesdb/.beans/quotesdb-ivwr--implement-submit-page-submit-quote-creation-form-d.md @@ -1,10 +1,17 @@ -+++ -title = "Implement Submit page (/submit) — quote creation form, display returned auth_code on success" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["04f865", "1e6a09", "fc2f51", "0fbdd5"] -+++ +--- +# quotesdb-ivwr +title: Implement Submit page (/submit) — quote creation form, display returned auth_code on success +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-xqh3 + - quotesdb-dgwi + - quotesdb-k258 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/00d6d7.md b/quotesdb/.beans/quotesdb-jhmw--add-trunk-proxy-config-to-trunktoml-forward-api-to.md similarity index 92% rename from quotesdb/.nbd/tickets/00d6d7.md rename to quotesdb/.beans/quotesdb-jhmw--add-trunk-proxy-config-to-trunktoml-forward-api-to.md index 08deb62..36d1129 100644 --- a/quotesdb/.nbd/tickets/00d6d7.md +++ b/quotesdb/.beans/quotesdb-jhmw--add-trunk-proxy-config-to-trunktoml-forward-api-to.md @@ -1,10 +1,14 @@ -+++ -title = "Add Trunk proxy config to Trunk.toml: forward /api/* to local API server" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["a9534d"] -+++ +--- +# quotesdb-jhmw +title: 'Add Trunk proxy config to Trunk.toml: forward /api/* to local API server' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:04Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-xg67 +--- The `quotesdb` project uses Trunk to build and serve the Yew (Wasm) frontend. During `trunk serve`, the UI @@ -92,4 +96,4 @@ trunk build `chore(quotesdb): add Trunk proxy config to forward /api/* to local API server` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/b3ef98.md b/quotesdb/.beans/quotesdb-jlef--implement-author-page-authorname-paginated-list-of.md similarity index 73% rename from quotesdb/.nbd/tickets/b3ef98.md rename to quotesdb/.beans/quotesdb-jlef--implement-author-page-authorname-paginated-list-of.md index 24fcd7c..2083b6f 100644 --- a/quotesdb/.nbd/tickets/b3ef98.md +++ b/quotesdb/.beans/quotesdb-jlef--implement-author-page-authorname-paginated-list-of.md @@ -1,10 +1,20 @@ -+++ -title = "Implement Author page (/author/:name) — paginated list of quotes by a single author" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["04f865", "1e6a09", "0d987f", "2c5a57", "d3d502", "fc2f51", "0fbdd5"] -+++ +--- +# quotesdb-jlef +title: Implement Author page (/author/:name) — paginated list of quotes by a single author +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-xqh3 + - quotesdb-dgwi + - quotesdb-oukj + - quotesdb-6huz + - quotesdb-kg2l + - quotesdb-k258 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/fba598.md b/quotesdb/.beans/quotesdb-jpu5--triage-integration-test-isolation-strategy-per-tes.md similarity index 93% rename from quotesdb/.nbd/tickets/fba598.md rename to quotesdb/.beans/quotesdb-jpu5--triage-integration-test-isolation-strategy-per-tes.md index ee69d1d..f1e6773 100644 --- a/quotesdb/.nbd/tickets/fba598.md +++ b/quotesdb/.beans/quotesdb-jpu5--triage-integration-test-isolation-strategy-per-tes.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Integration test isolation strategy — per-test temp DB vs shared DB with transaction rollback?" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-jpu5 +title: '[TRIAGE] Integration test isolation strategy — per-test temp DB vs shared DB with transaction rollback?' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:11Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/fc2f51.md b/quotesdb/.beans/quotesdb-k258--implement-error-display-component-consistent-error.md similarity index 77% rename from quotesdb/.nbd/tickets/fc2f51.md rename to quotesdb/.beans/quotesdb-k258--implement-error-display-component-consistent-error.md index c55b05d..4c74b6c 100644 --- a/quotesdb/.nbd/tickets/fc2f51.md +++ b/quotesdb/.beans/quotesdb-k258--implement-error-display-component-consistent-error.md @@ -1,10 +1,15 @@ -+++ -title = "Implement error display component — consistent error state UI across all pages" -priority = 4 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "0fbdd5"] -+++ +--- +# quotesdb-k258 +title: Implement error display component — consistent error state UI across all pages +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-kaat + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/bacb16.md b/quotesdb/.beans/quotesdb-k5rx--implement-d1repository-for-cloudflare-workers.md similarity index 93% rename from quotesdb/.nbd/tickets/bacb16.md rename to quotesdb/.beans/quotesdb-k5rx--implement-d1repository-for-cloudflare-workers.md index 8d87853..eba31b2 100644 --- a/quotesdb/.nbd/tickets/bacb16.md +++ b/quotesdb/.beans/quotesdb-k5rx--implement-d1repository-for-cloudflare-workers.md @@ -1,10 +1,13 @@ -+++ -title = "Implement D1Repository for Cloudflare Workers" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-k5rx +title: Implement D1Repository for Cloudflare Workers +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:10Z +--- + ## Goal Implement all 7 stub methods in `src/bin/api/db/d1.rs` so the API works against Cloudflare D1 in production. @@ -65,4 +68,4 @@ These are required so `D1Repository` satisfies the `Arc The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. @@ -48,4 +53,4 @@ trunk build `chore(quotesdb): set up ui Cargo dependencies for Yew/Wasm` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/d3d502.md b/quotesdb/.beans/quotesdb-kg2l--implement-tag-filter-component-tag-inputselect-for.md similarity index 78% rename from quotesdb/.nbd/tickets/d3d502.md rename to quotesdb/.beans/quotesdb-kg2l--implement-tag-filter-component-tag-inputselect-for.md index d5fffb0..44c51d9 100644 --- a/quotesdb/.nbd/tickets/d3d502.md +++ b/quotesdb/.beans/quotesdb-kg2l--implement-tag-filter-component-tag-inputselect-for.md @@ -1,10 +1,15 @@ -+++ -title = "Implement tag filter component — tag input/select for browse and author pages" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "0fbdd5"] -+++ +--- +# quotesdb-kg2l +title: Implement tag filter component — tag input/select for browse and author pages +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-kaat + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/a6bce1.md b/quotesdb/.beans/quotesdb-kh9l--write-unit-tests-in-apisrctestsrs-covering-all-han.md similarity index 80% rename from quotesdb/.nbd/tickets/a6bce1.md rename to quotesdb/.beans/quotesdb-kh9l--write-unit-tests-in-apisrctestsrs-covering-all-han.md index 46e1e74..154aa96 100644 --- a/quotesdb/.nbd/tickets/a6bce1.md +++ b/quotesdb/.beans/quotesdb-kh9l--write-unit-tests-in-apisrctestsrs-covering-all-han.md @@ -1,10 +1,20 @@ -+++ -title = "Write unit tests in api/src/tests.rs covering all handlers, auth logic, and pagination" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["2ce22e", "5dbb7d", "886bfd", "05f8ae", "5d9f5a", "b20b5a", "28e7d9"] -+++ +--- +# quotesdb-kh9l +title: Write unit tests in api/src/tests.rs covering all handlers, auth logic, and pagination +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-l4e9 + - quotesdb-nrue + - quotesdb-4gqi + - quotesdb-a0q1 + - quotesdb-bz2v + - quotesdb-ode0 + - quotesdb-753n +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/809cba.md b/quotesdb/.beans/quotesdb-ky1o--admin-super-auth-code-delete-any-quote-regardless.md similarity index 95% rename from quotesdb/.nbd/tickets/809cba.md rename to quotesdb/.beans/quotesdb-ky1o--admin-super-auth-code-delete-any-quote-regardless.md index 0565132..4c7c745 100644 --- a/quotesdb/.nbd/tickets/809cba.md +++ b/quotesdb/.beans/quotesdb-ky1o--admin-super-auth-code-delete-any-quote-regardless.md @@ -1,10 +1,13 @@ -+++ -title = "Admin super auth code: delete any quote regardless of per-quote auth" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-ky1o +title: 'Admin super auth code: delete any quote regardless of per-quote auth' +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- + ## Feature Add an **admin super auth code** — a single global passphrase that can delete (and update) any quote, bypassing the per-quote `auth_code` check. This allows the operator to moderate content without needing the original submitter's code. @@ -165,4 +168,4 @@ Manual test: ## Commit scope -`feat(quotesdb): admin super auth code for quote moderation` \ No newline at end of file +`feat(quotesdb): admin super auth code for quote moderation` diff --git a/quotesdb/.nbd/tickets/657836.md b/quotesdb/.beans/quotesdb-l09d--configure-custom-domain-quoteselijahrun-cloudflare.md similarity index 80% rename from quotesdb/.nbd/tickets/657836.md rename to quotesdb/.beans/quotesdb-l09d--configure-custom-domain-quoteselijahrun-cloudflare.md index 324ef2a..88ef0b0 100644 --- a/quotesdb/.nbd/tickets/657836.md +++ b/quotesdb/.beans/quotesdb-l09d--configure-custom-domain-quoteselijahrun-cloudflare.md @@ -1,10 +1,14 @@ -+++ -title = "Configure custom domain quotes.elijah.run → Cloudflare Pages (DNS record + Pages domain binding)" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["ae886f"] -+++ +--- +# quotesdb-l09d +title: Configure custom domain quotes.elijah.run → Cloudflare Pages (DNS record + Pages domain binding) +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-qt7m +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/2ce22e.md b/quotesdb/.beans/quotesdb-l4e9--implement-get-apiquotesrandom-random-row-query-mus.md similarity index 83% rename from quotesdb/.nbd/tickets/2ce22e.md rename to quotesdb/.beans/quotesdb-l4e9--implement-get-apiquotesrandom-random-row-query-mus.md index 5b7ef2f..723d495 100644 --- a/quotesdb/.nbd/tickets/2ce22e.md +++ b/quotesdb/.beans/quotesdb-l4e9--implement-get-apiquotesrandom-random-row-query-mus.md @@ -1,10 +1,16 @@ -+++ -title = "Implement GET /api/quotes/random — random row query (must be registered before /:id route)" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2", "175382"] -+++ +--- +# quotesdb-l4e9 +title: Implement GET /api/quotes/random — random row query (must be registered before /:id route) +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr + - quotesdb-qf7x +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/1a274d.md b/quotesdb/.beans/quotesdb-m9vb--implement-home-page-fetch-and-display-random-quote.md similarity index 78% rename from quotesdb/.nbd/tickets/1a274d.md rename to quotesdb/.beans/quotesdb-m9vb--implement-home-page-fetch-and-display-random-quote.md index 645f832..d3dab55 100644 --- a/quotesdb/.nbd/tickets/1a274d.md +++ b/quotesdb/.beans/quotesdb-m9vb--implement-home-page-fetch-and-display-random-quote.md @@ -1,10 +1,18 @@ -+++ -title = "Implement Home page (/) — fetch and display random quote, 'Browse all' link" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["04f865", "1e6a09", "0d987f", "fc2f51", "0fbdd5"] -+++ +--- +# quotesdb-m9vb +title: Implement Home page (/) — fetch and display random quote, 'Browse all' link +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-xqh3 + - quotesdb-dgwi + - quotesdb-oukj + - quotesdb-k258 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/b2af7f.md b/quotesdb/.beans/quotesdb-mhal--quotesdbui-add-footer-with-contact-email.md similarity index 75% rename from quotesdb/.nbd/tickets/b2af7f.md rename to quotesdb/.beans/quotesdb-mhal--quotesdbui-add-footer-with-contact-email.md index 18759a1..5df8308 100644 --- a/quotesdb/.nbd/tickets/b2af7f.md +++ b/quotesdb/.beans/quotesdb-mhal--quotesdbui-add-footer-with-contact-email.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/ui: add footer with contact email" -priority = 3 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-mhal +title: 'quotesdb/ui: add footer with contact email' +status: completed +type: feature +priority: low +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:10Z +--- + ## Summary Add a footer to every page in the quotesdb UI displaying a contact email address. @@ -24,4 +27,4 @@ Run from quotesdb/ root: ```sh cargo fmt && cargo check && cargo clippy trunk build -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/c3503b.md b/quotesdb/.beans/quotesdb-ndjj--quotesdbui.md similarity index 74% rename from quotesdb/.nbd/tickets/c3503b.md rename to quotesdb/.beans/quotesdb-ndjj--quotesdbui.md index ce687e7..f7b062a 100644 --- a/quotesdb/.nbd/tickets/c3503b.md +++ b/quotesdb/.beans/quotesdb-ndjj--quotesdbui.md @@ -1,10 +1,18 @@ -+++ -title = "quotesdb/ui" -priority = 7 -status = "todo" -ticket_type = "project" -dependencies = ["b2af7f", "f4930e", "354276", "3f22f2", "cb8de0"] -+++ +--- +# quotesdb-ndjj +title: quotesdb/ui +status: todo +type: epic +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:18Z +blocked_by: + - quotesdb-mhal + - quotesdb-r51f + - quotesdb-792p + - quotesdb-twgb + - quotesdb-r3eq +--- This is the sub-project tracking ticket for `quotesdb/ui`. All UI implementation tasks depend on this ticket. The UI domain covers: Cargo/Trunk setup, Yew app shell, page components, API client, auth modal, pagination, and documentation. diff --git a/quotesdb/.nbd/tickets/0c73cd.md b/quotesdb/.beans/quotesdb-njv2--quotesdbapi-post-apiadminlock-and-apiadminunlock-e.md similarity index 91% rename from quotesdb/.nbd/tickets/0c73cd.md rename to quotesdb/.beans/quotesdb-njv2--quotesdbapi-post-apiadminlock-and-apiadminunlock-e.md index fe18bb7..95ee0a1 100644 --- a/quotesdb/.nbd/tickets/0c73cd.md +++ b/quotesdb/.beans/quotesdb-njv2--quotesdbapi-post-apiadminlock-and-apiadminunlock-e.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/api: POST /api/admin/lock and /api/admin/unlock endpoints" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = ["69a2c5"] -+++ +--- +# quotesdb-njv2 +title: 'quotesdb/api: POST /api/admin/lock and /api/admin/unlock endpoints' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-04cw +--- + ## POST /api/admin/lock and /api/admin/unlock endpoints Add the two admin-protected endpoints that toggle the global submissions lock. Both require `X-Admin-Code` and return the current lock state after the operation. @@ -86,4 +91,4 @@ cargo fmt && cargo check && cargo clippy && cargo test ``` feat(quotesdb): POST /api/admin/lock and /api/admin/unlock endpoints -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/5dbb7d.md b/quotesdb/.beans/quotesdb-nrue--implement-get-apiquotesid-fetch-by-nanoid-return-4.md similarity index 81% rename from quotesdb/.nbd/tickets/5dbb7d.md rename to quotesdb/.beans/quotesdb-nrue--implement-get-apiquotesid-fetch-by-nanoid-return-4.md index 53720a3..e3095a8 100644 --- a/quotesdb/.nbd/tickets/5dbb7d.md +++ b/quotesdb/.beans/quotesdb-nrue--implement-get-apiquotesid-fetch-by-nanoid-return-4.md @@ -1,10 +1,16 @@ -+++ -title = "Implement GET /api/quotes/:id — fetch by NanoID, return 404 if not found" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2", "175382"] -+++ +--- +# quotesdb-nrue +title: Implement GET /api/quotes/:id — fetch by NanoID, return 404 if not found +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr + - quotesdb-qf7x +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/b20b5a.md b/quotesdb/.beans/quotesdb-ode0--implement-delete-apiquotesid-verify-x-auth-code-ca.md similarity index 84% rename from quotesdb/.nbd/tickets/b20b5a.md rename to quotesdb/.beans/quotesdb-ode0--implement-delete-apiquotesid-verify-x-auth-code-ca.md index 65c6317..10983e9 100644 --- a/quotesdb/.nbd/tickets/b20b5a.md +++ b/quotesdb/.beans/quotesdb-ode0--implement-delete-apiquotesid-verify-x-auth-code-ca.md @@ -1,10 +1,15 @@ -+++ -title = "Implement DELETE /api/quotes/:id — verify X-Auth-Code, cascade delete quote and tags, return 204" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d", "d792e2"] -+++ +--- +# quotesdb-ode0 +title: Implement DELETE /api/quotes/:id — verify X-Auth-Code, cascade delete quote and tags, return 204 +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-6ng5 + - quotesdb-fagr +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/6c5904.md b/quotesdb/.beans/quotesdb-ooyx--quotesdbapi-admin-moderation-endpoints-list-report.md similarity index 82% rename from quotesdb/.nbd/tickets/6c5904.md rename to quotesdb/.beans/quotesdb-ooyx--quotesdbapi-admin-moderation-endpoints-list-report.md index 05ca862..05e3bbb 100644 --- a/quotesdb/.nbd/tickets/6c5904.md +++ b/quotesdb/.beans/quotesdb-ooyx--quotesdbapi-admin-moderation-endpoints-list-report.md @@ -1,10 +1,16 @@ -+++ -title = "quotesdb/api: admin moderation endpoints (list reports, delete/hide from report)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["8a7fba", "77237f"] -+++ +--- +# quotesdb-ooyx +title: 'quotesdb/api: admin moderation endpoints (list reports, delete/hide from report)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-ysah + - quotesdb-i37j +--- + ## Summary Add admin endpoints for viewing and acting on reported quotes. @@ -45,4 +51,4 @@ DELETE /api/admin/reports/:quote_id/reports ## Validation ```sh cargo fmt && cargo check && cargo clippy && cargo test -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/e8a330.md b/quotesdb/.beans/quotesdb-osmv--triage-sqlx-workers-rs-cloudflare-d1-compatibility.md similarity index 91% rename from quotesdb/.nbd/tickets/e8a330.md rename to quotesdb/.beans/quotesdb-osmv--triage-sqlx-workers-rs-cloudflare-d1-compatibility.md index d59a4df..aaf9148 100644 --- a/quotesdb/.nbd/tickets/e8a330.md +++ b/quotesdb/.beans/quotesdb-osmv--triage-sqlx-workers-rs-cloudflare-d1-compatibility.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] SQLx + workers-rs + Cloudflare D1 compatibility (known issues?)" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-osmv +title: '[TRIAGE] SQLx + workers-rs + Cloudflare D1 compatibility (known issues?)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:11Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/0d987f.md b/quotesdb/.beans/quotesdb-oukj--implement-shared-quotecard-component-displays-text.md similarity index 80% rename from quotesdb/.nbd/tickets/0d987f.md rename to quotesdb/.beans/quotesdb-oukj--implement-shared-quotecard-component-displays-text.md index 42d086b..063a0b1 100644 --- a/quotesdb/.nbd/tickets/0d987f.md +++ b/quotesdb/.beans/quotesdb-oukj--implement-shared-quotecard-component-displays-text.md @@ -1,10 +1,15 @@ -+++ -title = "Implement shared QuoteCard component — displays text, author, source, date, tags" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "0fbdd5"] -+++ +--- +# quotesdb-oukj +title: Implement shared QuoteCard component — displays text, author, source, date, tags +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-kaat + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/f3dc74.md b/quotesdb/.beans/quotesdb-pqdw--quotesdbapi.md similarity index 75% rename from quotesdb/.nbd/tickets/f3dc74.md rename to quotesdb/.beans/quotesdb-pqdw--quotesdbapi.md index 40bf851..9b71fe8 100644 --- a/quotesdb/.nbd/tickets/f3dc74.md +++ b/quotesdb/.beans/quotesdb-pqdw--quotesdbapi.md @@ -1,10 +1,17 @@ -+++ -title = "quotesdb/api" -priority = 7 -status = "todo" -ticket_type = "project" -dependencies = ["8a7fba", "77237f", "6c5904", "d4a624"] -+++ +--- +# quotesdb-pqdw +title: quotesdb/api +status: todo +type: epic +priority: high +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-ysah + - quotesdb-i37j + - quotesdb-ooyx + - quotesdb-hna0 +--- This is the sub-project tracking ticket for `quotesdb/api`. All API implementation tasks depend on this ticket. The API domain covers: Cargo setup, database layer, HTTP handlers, auth, OpenAPI spec, unit tests, and documentation. diff --git a/quotesdb/.nbd/tickets/9c9546.md b/quotesdb/.beans/quotesdb-q8u2--create-envexample-documenting-database-url-and-all.md similarity index 89% rename from quotesdb/.nbd/tickets/9c9546.md rename to quotesdb/.beans/quotesdb-q8u2--create-envexample-documenting-database-url-and-all.md index 3ed5ac3..39152b6 100644 --- a/quotesdb/.nbd/tickets/9c9546.md +++ b/quotesdb/.beans/quotesdb-q8u2--create-envexample-documenting-database-url-and-all.md @@ -1,10 +1,14 @@ -+++ -title = "Create .env.example documenting DATABASE_URL and all local dev environment variables" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["33ed29"] -+++ +--- +# quotesdb-q8u2 +title: Create .env.example documenting DATABASE_URL and all local dev environment variables +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-td4l +--- TRIAGE 33ed29 resolved the local dev database strategy: rusqlite with a local SQLite file. @@ -63,4 +67,4 @@ rm .env `chore(quotesdb): add .env.example documenting DATABASE_URL for local dev` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/a6e8ba.md b/quotesdb/.beans/quotesdb-qbpg--quotesdbui-collapsible-filter-panel-on-browse-page.md similarity index 88% rename from quotesdb/.nbd/tickets/a6e8ba.md rename to quotesdb/.beans/quotesdb-qbpg--quotesdbui-collapsible-filter-panel-on-browse-page.md index acc1fc9..1278211 100644 --- a/quotesdb/.nbd/tickets/a6e8ba.md +++ b/quotesdb/.beans/quotesdb-qbpg--quotesdbui-collapsible-filter-panel-on-browse-page.md @@ -1,10 +1,12 @@ -+++ -title = "quotesdb/ui: collapsible filter panel on browse page" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-qbpg +title: 'quotesdb/ui: collapsible filter panel on browse page' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- ## Summary diff --git a/quotesdb/.nbd/tickets/175382.md b/quotesdb/.beans/quotesdb-qf7x--implement-tag-join-logic-fetch-tags-per-quote-inse.md similarity index 86% rename from quotesdb/.nbd/tickets/175382.md rename to quotesdb/.beans/quotesdb-qf7x--implement-tag-join-logic-fetch-tags-per-quote-inse.md index 07bcbe8..c338dea 100644 --- a/quotesdb/.nbd/tickets/175382.md +++ b/quotesdb/.beans/quotesdb-qf7x--implement-tag-join-logic-fetch-tags-per-quote-inse.md @@ -1,10 +1,14 @@ -+++ -title = "Implement tag join logic — fetch tags per quote, insert/replace tags on create/update" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["a5049d"] -+++ +--- +# quotesdb-qf7x +title: Implement tag join logic — fetch tags per quote, insert/replace tags on create/update +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-6ng5 +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/f850c6.md b/quotesdb/.beans/quotesdb-qqdf--implement-auth-code-modalprompt-component-dialog-r.md similarity index 84% rename from quotesdb/.nbd/tickets/f850c6.md rename to quotesdb/.beans/quotesdb-qqdf--implement-auth-code-modalprompt-component-dialog-r.md index ef3125a..fe18ca4 100644 --- a/quotesdb/.nbd/tickets/f850c6.md +++ b/quotesdb/.beans/quotesdb-qqdf--implement-auth-code-modalprompt-component-dialog-r.md @@ -1,10 +1,16 @@ -+++ -title = "Implement auth code modal/prompt component — dialog requesting X-Auth-Code before edit or delete" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "5379eb", "0fbdd5"] -+++ +--- +# quotesdb-qqdf +title: Implement auth code modal/prompt component — dialog requesting X-Auth-Code before edit or delete +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-kaat + - quotesdb-5dda + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/ae886f.md b/quotesdb/.beans/quotesdb-qt7m--define-cloudflare-pages-project-resource-build-con.md similarity index 89% rename from quotesdb/.nbd/tickets/ae886f.md rename to quotesdb/.beans/quotesdb-qt7m--define-cloudflare-pages-project-resource-build-con.md index f420fcc..77d870c 100644 --- a/quotesdb/.nbd/tickets/ae886f.md +++ b/quotesdb/.beans/quotesdb-qt7m--define-cloudflare-pages-project-resource-build-con.md @@ -1,10 +1,15 @@ -+++ -title = "Define Cloudflare Pages project resource — build config, output dir, git repo connection or artifact upload" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["2d1371", "fc9bfd"] -+++ +--- +# quotesdb-qt7m +title: Define Cloudflare Pages project resource — build config, output dir, git repo connection or artifact upload +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:17Z +blocked_by: + - quotesdb-zzm3 + - quotesdb-3951 +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/tickets/cb8de0.md b/quotesdb/.beans/quotesdb-r3eq--quotesdbui-admin-page-auth-first-flow-and-remove-f.md similarity index 87% rename from quotesdb/.nbd/tickets/cb8de0.md rename to quotesdb/.beans/quotesdb-r3eq--quotesdbui-admin-page-auth-first-flow-and-remove-f.md index dafabab..e31e531 100644 --- a/quotesdb/.nbd/tickets/cb8de0.md +++ b/quotesdb/.beans/quotesdb-r3eq--quotesdbui-admin-page-auth-first-flow-and-remove-f.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/ui: admin page auth-first flow and remove from default nav" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-r3eq +title: 'quotesdb/ui: admin page auth-first flow and remove from default nav' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:10Z +--- + ## Summary Two related admin UX improvements: 1. Remove the admin link from all default navigation/page footers — admins access /admin directly via URL. @@ -37,4 +40,4 @@ Currently the /admin page may show controls before authenticating. Change the fl ```sh cargo fmt && cargo check && cargo clippy trunk build -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/f4930e.md b/quotesdb/.beans/quotesdb-r51f--quotesdbui-hidden-toggle-on-quote-pages-auth-requi.md similarity index 80% rename from quotesdb/.nbd/tickets/f4930e.md rename to quotesdb/.beans/quotesdb-r51f--quotesdbui-hidden-toggle-on-quote-pages-auth-requi.md index c3a1f27..a0e3df0 100644 --- a/quotesdb/.nbd/tickets/f4930e.md +++ b/quotesdb/.beans/quotesdb-r51f--quotesdbui-hidden-toggle-on-quote-pages-auth-requi.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/ui: hidden toggle on quote pages (auth required to unhide)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["8a7fba"] -+++ +--- +# quotesdb-r51f +title: 'quotesdb/ui: hidden toggle on quote pages (auth required to unhide)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-ysah +--- + ## Summary Add UI for toggling the hidden state of a quote on the quote detail page. Requires the quote's auth code to change hidden state. @@ -33,4 +38,4 @@ On the /quotes/:id page: ```sh cargo fmt && cargo check && cargo clippy trunk build -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/a57b95.md b/quotesdb/.beans/quotesdb-r72e--quotesdbapi-enforce-submission-lock-on-put-apiquot.md similarity index 87% rename from quotesdb/.nbd/tickets/a57b95.md rename to quotesdb/.beans/quotesdb-r72e--quotesdbapi-enforce-submission-lock-on-put-apiquot.md index 3d81357..57437e7 100644 --- a/quotesdb/.nbd/tickets/a57b95.md +++ b/quotesdb/.beans/quotesdb-r72e--quotesdbapi-enforce-submission-lock-on-put-apiquot.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/api: enforce submission lock on PUT /api/quotes" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = ["69a2c5"] -+++ +--- +# quotesdb-r72e +title: 'quotesdb/api: enforce submission lock on PUT /api/quotes' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-04cw +--- + ## Enforce submission lock on PUT /api/quotes Modify the quote-creation handler to check the submissions lock before accepting a new quote. If locked, return `423 Locked` with a JSON error body. @@ -65,4 +70,4 @@ cargo fmt && cargo check && cargo clippy && cargo test ``` feat(quotesdb): enforce submission lock on PUT /api/quotes -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/ce1e4f.md b/quotesdb/.beans/quotesdb-ryhx--quotesdbqa.md similarity index 61% rename from quotesdb/.nbd/tickets/ce1e4f.md rename to quotesdb/.beans/quotesdb-ryhx--quotesdbqa.md index 3514cf4..fd5028e 100644 --- a/quotesdb/.nbd/tickets/ce1e4f.md +++ b/quotesdb/.beans/quotesdb-ryhx--quotesdbqa.md @@ -1,10 +1,28 @@ -+++ -title = "quotesdb/qa" -priority = 7 -status = "done" -ticket_type = "project" -dependencies = ["2ab7a8", "fba598", "0d84fa", "5f5ba0", "9b581f", "e8f5cf", "789d0f", "4a4c26", "aa0eab", "93f1b6", "f9f448", "fae330", "8c87db", "893eba", "75e3f0"] -+++ +--- +# quotesdb-ryhx +title: quotesdb/qa +status: completed +type: epic +priority: high +created_at: 2026-03-10T23:32:10Z +updated_at: 2026-03-10T23:32:18Z +blocked_by: + - quotesdb-aa9s + - quotesdb-jpu5 + - quotesdb-z43c + - quotesdb-bl2g + - quotesdb-gu9j + - quotesdb-h07r + - quotesdb-tl2d + - quotesdb-zc1j + - quotesdb-hag9 + - quotesdb-4pxt + - quotesdb-2nlt + - quotesdb-vxrj + - quotesdb-v3dw + - quotesdb-yxaa + - quotesdb-eh4l +--- This is the sub-project tracking ticket for `quotesdb/qa`. All integration test tasks depend on this ticket. The QA domain covers: test Cargo setup, test server harness, and a test suite per API endpoint. diff --git a/quotesdb/.nbd/tickets/182210.md b/quotesdb/.beans/quotesdb-shfq--triage-cloudflare-workers-wasm-size-limit-free-tie.md similarity index 88% rename from quotesdb/.nbd/tickets/182210.md rename to quotesdb/.beans/quotesdb-shfq--triage-cloudflare-workers-wasm-size-limit-free-tie.md index e0d1910..897bfeb 100644 --- a/quotesdb/.nbd/tickets/182210.md +++ b/quotesdb/.beans/quotesdb-shfq--triage-cloudflare-workers-wasm-size-limit-free-tie.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Cloudflare Workers WASM size limit — free tier 1MB limit may require paid plan for Rust binary" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-shfq +title: '[TRIAGE] Cloudflare Workers WASM size limit — free tier 1MB limit may require paid plan for Rust binary' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/06d304.md b/quotesdb/.beans/quotesdb-sqho--quotesdbinfra-cloudflare-rate-limiting-waf-rules-o.md similarity index 88% rename from quotesdb/.nbd/tickets/06d304.md rename to quotesdb/.beans/quotesdb-sqho--quotesdbinfra-cloudflare-rate-limiting-waf-rules-o.md index b714122..ee20a37 100644 --- a/quotesdb/.nbd/tickets/06d304.md +++ b/quotesdb/.beans/quotesdb-sqho--quotesdbinfra-cloudflare-rate-limiting-waf-rules-o.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/infra: Cloudflare rate limiting (WAF rules or Workers rate limiting per IP)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-sqho +title: 'quotesdb/infra: Cloudflare rate limiting (WAF rules or Workers rate limiting per IP)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- + ## Summary Investigate and implement rate limiting for the quotesdb API and frontend using Cloudflare's native tooling. @@ -49,4 +52,4 @@ Investigate and implement rate limiting for the quotesdb API and frontend using # from infra/ tofu validate tofu plan -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/2ec8b1.md b/quotesdb/.beans/quotesdb-t0r8--triage-openapi-spec-serving-strategy-embed-yaml-at.md similarity index 91% rename from quotesdb/.nbd/tickets/2ec8b1.md rename to quotesdb/.beans/quotesdb-t0r8--triage-openapi-spec-serving-strategy-embed-yaml-at.md index 84f3cff..935d5a9 100644 --- a/quotesdb/.nbd/tickets/2ec8b1.md +++ b/quotesdb/.beans/quotesdb-t0r8--triage-openapi-spec-serving-strategy-embed-yaml-at.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] OpenAPI spec serving strategy — embed YAML at compile time vs load at runtime" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-t0r8 +title: '[TRIAGE] OpenAPI spec serving strategy — embed YAML at compile time vs load at runtime' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:06Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/33ed29.md b/quotesdb/.beans/quotesdb-td4l--triage-local-dev-config-turso-file-sqlite-vs-d1-bi.md similarity index 91% rename from quotesdb/.nbd/tickets/33ed29.md rename to quotesdb/.beans/quotesdb-td4l--triage-local-dev-config-turso-file-sqlite-vs-d1-bi.md index c09a0c6..fc298bf 100644 --- a/quotesdb/.nbd/tickets/33ed29.md +++ b/quotesdb/.beans/quotesdb-td4l--triage-local-dev-config-turso-file-sqlite-vs-d1-bi.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Local dev config: Turso (file SQLite) vs D1 binding selection strategy" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-td4l +title: '[TRIAGE] Local dev config: Turso (file SQLite) vs D1 binding selection strategy' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:06Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. @@ -53,4 +55,4 @@ Updated: `chore(quotesdb): resolve triage — local-dev-config-turso-file-sqlite-vs-d1-binding-selection-s` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/03fa32.md b/quotesdb/.beans/quotesdb-teha--filter-quotes-by-date-range-beforeafter-with-yearm.md similarity index 95% rename from quotesdb/.nbd/tickets/03fa32.md rename to quotesdb/.beans/quotesdb-teha--filter-quotes-by-date-range-beforeafter-with-yearm.md index 29eb97b..14474c4 100644 --- a/quotesdb/.nbd/tickets/03fa32.md +++ b/quotesdb/.beans/quotesdb-teha--filter-quotes-by-date-range-beforeafter-with-yearm.md @@ -1,10 +1,13 @@ -+++ -title = "Filter quotes by date range (before/after with year/month/day granularity)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-teha +title: Filter quotes by date range (before/after with year/month/day granularity) +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- + ## Feature Extend `GET /api/quotes` with date range filtering. Users can specify a "before" and/or "after" bound, with year/month/day granularity for each. Quotes without a date (`date IS NULL`) are excluded when a date filter is active. @@ -159,4 +162,4 @@ Test manually: ## Commit scope -`feat(quotesdb): date range filter for quotes list` \ No newline at end of file +`feat(quotesdb): date range filter for quotes list` diff --git a/quotesdb/.nbd/tickets/789d0f.md b/quotesdb/.beans/quotesdb-tl2d--test-suite-get-api-openapi-spec-returned-as-valid.md similarity index 79% rename from quotesdb/.nbd/tickets/789d0f.md rename to quotesdb/.beans/quotesdb-tl2d--test-suite-get-api-openapi-spec-returned-as-valid.md index 46ea67f..77e0d77 100644 --- a/quotesdb/.nbd/tickets/789d0f.md +++ b/quotesdb/.beans/quotesdb-tl2d--test-suite-get-api-openapi-spec-returned-as-valid.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: GET /api/ — OpenAPI spec returned as valid JSON with expected structure" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "28e7d9"] -+++ +--- +# quotesdb-tl2d +title: 'Test suite: GET /api/ — OpenAPI spec returned as valid JSON with expected structure' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-gu9j + - quotesdb-753n +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/3f22f2.md b/quotesdb/.beans/quotesdb-twgb--quotesdbui-admin-moderation-tab-paginated-reports.md similarity index 82% rename from quotesdb/.nbd/tickets/3f22f2.md rename to quotesdb/.beans/quotesdb-twgb--quotesdbui-admin-moderation-tab-paginated-reports.md index 928ba1d..686bf91 100644 --- a/quotesdb/.nbd/tickets/3f22f2.md +++ b/quotesdb/.beans/quotesdb-twgb--quotesdbui-admin-moderation-tab-paginated-reports.md @@ -1,10 +1,16 @@ -+++ -title = "quotesdb/ui: admin moderation tab (paginated reports, per-quote modal with delete/hide)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = ["6c5904", "cb8de0"] -+++ +--- +# quotesdb-twgb +title: 'quotesdb/ui: admin moderation tab (paginated reports, per-quote modal with delete/hide)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-ooyx + - quotesdb-r3eq +--- + ## Summary Add a Moderation tab to the admin page showing a paginated list of reported quotes. Clicking a report opens a detail modal with the quote and all reports, plus action buttons. @@ -38,4 +44,4 @@ Add a Moderation tab to the admin page showing a paginated list of reported quot ```sh cargo fmt && cargo check && cargo clippy trunk build -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/e2bd9b.md b/quotesdb/.beans/quotesdb-tzvj--triage-cloudflare-pages-spa-routing-404-fallback-c.md similarity index 90% rename from quotesdb/.nbd/tickets/e2bd9b.md rename to quotesdb/.beans/quotesdb-tzvj--triage-cloudflare-pages-spa-routing-404-fallback-c.md index 061de17..ed6b2e6 100644 --- a/quotesdb/.nbd/tickets/e2bd9b.md +++ b/quotesdb/.beans/quotesdb-tzvj--triage-cloudflare-pages-spa-routing-404-fallback-c.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Cloudflare Pages SPA routing — 404 fallback config for client-side Yew router" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-tzvj +title: '[TRIAGE] Cloudflare Pages SPA routing — 404 fallback config for client-side Yew router' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:11Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/35685a.md b/quotesdb/.beans/quotesdb-um1y--quotesdbapi-get-apistatus-public-endpoint.md similarity index 92% rename from quotesdb/.nbd/tickets/35685a.md rename to quotesdb/.beans/quotesdb-um1y--quotesdbapi-get-apistatus-public-endpoint.md index a62da2c..d87c112 100644 --- a/quotesdb/.nbd/tickets/35685a.md +++ b/quotesdb/.beans/quotesdb-um1y--quotesdbapi-get-apistatus-public-endpoint.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/api: GET /api/status public endpoint" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = ["69a2c5"] -+++ +--- +# quotesdb-um1y +title: 'quotesdb/api: GET /api/status public endpoint' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-04cw +--- + ## GET /api/status public endpoint Add a public status endpoint that exposes whether submissions are currently locked. The UI calls this on mount for both the /submit and /admin pages. @@ -97,4 +102,4 @@ cargo fmt && cargo check && cargo clippy && cargo test ``` feat(quotesdb): GET /api/status public endpoint -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/8c87db.md b/quotesdb/.beans/quotesdb-v3dw--test-suite-delete-apiquotesid-valid-auth-204-no-bo.md similarity index 78% rename from quotesdb/.nbd/tickets/8c87db.md rename to quotesdb/.beans/quotesdb-v3dw--test-suite-delete-apiquotesid-valid-auth-204-no-bo.md index b66c7d9..95cf45b 100644 --- a/quotesdb/.nbd/tickets/8c87db.md +++ b/quotesdb/.beans/quotesdb-v3dw--test-suite-delete-apiquotesid-valid-auth-204-no-bo.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: DELETE /api/quotes/:id — valid auth 204 no body, wrong auth 403, not found 404, cascade deletes tags" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "b20b5a"] -+++ +--- +# quotesdb-v3dw +title: 'Test suite: DELETE /api/quotes/:id — valid auth 204 no body, wrong auth 403, not found 404, cascade deletes tags' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-gu9j + - quotesdb-ode0 +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/a23489.md b/quotesdb/.beans/quotesdb-vsgd--define-cloudflare-workers-script-resource-wasm-art.md similarity index 87% rename from quotesdb/.nbd/tickets/a23489.md rename to quotesdb/.beans/quotesdb-vsgd--define-cloudflare-workers-script-resource-wasm-art.md index ce72a5e..81192b2 100644 --- a/quotesdb/.nbd/tickets/a23489.md +++ b/quotesdb/.beans/quotesdb-vsgd--define-cloudflare-workers-script-resource-wasm-art.md @@ -1,10 +1,17 @@ -+++ -title = "Define Cloudflare Workers script resource — WASM artifact, D1 binding, environment variables" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["2d1371", "d0da0b", "07cafb", "efee79"] -+++ +--- +# quotesdb-vsgd +title: Define Cloudflare Workers script resource — WASM artifact, D1 binding, environment variables +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-zzm3 + - quotesdb-3euj + - quotesdb-cc35 + - quotesdb-8zm9 +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. diff --git a/quotesdb/.nbd/tickets/fae330.md b/quotesdb/.beans/quotesdb-vxrj--test-suite-post-apiquotesid-valid-auth-200-wrong-a.md similarity index 78% rename from quotesdb/.nbd/tickets/fae330.md rename to quotesdb/.beans/quotesdb-vxrj--test-suite-post-apiquotesid-valid-auth-200-wrong-a.md index 752598e..0457512 100644 --- a/quotesdb/.nbd/tickets/fae330.md +++ b/quotesdb/.beans/quotesdb-vxrj--test-suite-post-apiquotesid-valid-auth-200-wrong-a.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: POST /api/quotes/:id — valid auth 200, wrong auth 403, not found 404, partial update, null to clear optional fields" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "5d9f5a"] -+++ +--- +# quotesdb-vxrj +title: 'Test suite: POST /api/quotes/:id — valid auth 200, wrong auth 403, not found 404, partial update, null to clear optional fields' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:20Z +blocked_by: + - quotesdb-gu9j + - quotesdb-bz2v +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/a91260.md b/quotesdb/.beans/quotesdb-wizu--triage-workers-rs-compatibility-with-native-rust-t.md similarity index 88% rename from quotesdb/.nbd/tickets/a91260.md rename to quotesdb/.beans/quotesdb-wizu--triage-workers-rs-compatibility-with-native-rust-t.md index 8c3d8cf..a73e37d 100644 --- a/quotesdb/.nbd/tickets/a91260.md +++ b/quotesdb/.beans/quotesdb-wizu--triage-workers-rs-compatibility-with-native-rust-t.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] workers-rs compatibility with native Rust test binaries (may need separate native feature flag)" -priority = 9 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-wizu +title: '[TRIAGE] workers-rs compatibility with native Rust test binaries (may need separate native feature flag)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/0fbdd5.md b/quotesdb/.beans/quotesdb-wlpv--write-srcbinuistylecss-full-stylesheet-for-all-ui.md similarity index 92% rename from quotesdb/.nbd/tickets/0fbdd5.md rename to quotesdb/.beans/quotesdb-wlpv--write-srcbinuistylecss-full-stylesheet-for-all-ui.md index db58420..3c2ac9d 100644 --- a/quotesdb/.nbd/tickets/0fbdd5.md +++ b/quotesdb/.beans/quotesdb-wlpv--write-srcbinuistylecss-full-stylesheet-for-all-ui.md @@ -1,10 +1,14 @@ -+++ -title = "Write src/bin/ui/style.css — full stylesheet for all UI pages and components" -priority = 6 -status = "done" -ticket_type = "task" -dependencies = ["dc3d2b"] -+++ +--- +# quotesdb-wlpv +title: Write src/bin/ui/style.css — full stylesheet for all UI pages and components +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-wvb8 +--- CSS approach resolved in triage 5e3e37: **plain CSS** — a single `src/bin/ui/style.css` file linked from `index.html` via ``. diff --git a/quotesdb/.nbd/tickets/03bb91.md b/quotesdb/.beans/quotesdb-wmvy--implement-4-word-passphrase-auth-code-generator-mu.md similarity index 95% rename from quotesdb/.nbd/tickets/03bb91.md rename to quotesdb/.beans/quotesdb-wmvy--implement-4-word-passphrase-auth-code-generator-mu.md index 1e99f76..08179d1 100644 --- a/quotesdb/.nbd/tickets/03bb91.md +++ b/quotesdb/.beans/quotesdb-wmvy--implement-4-word-passphrase-auth-code-generator-mu.md @@ -1,10 +1,15 @@ -+++ -title = "Implement 4-word passphrase auth_code generator (must work in WASM/workers-rs)" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = ["1f5bb5", "6ed325"] -+++ +--- +# quotesdb-wmvy +title: Implement 4-word passphrase auth_code generator (must work in WASM/workers-rs) +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:04Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-ghzc + - quotesdb-58hh +--- The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`. diff --git a/quotesdb/.nbd/tickets/dc3d2b.md b/quotesdb/.beans/quotesdb-wvb8--set-up-uitrunktoml-and-uiindexhtml-build-configura.md similarity index 90% rename from quotesdb/.nbd/tickets/dc3d2b.md rename to quotesdb/.beans/quotesdb-wvb8--set-up-uitrunktoml-and-uiindexhtml-build-configura.md index 13dd915..9d9db58 100644 --- a/quotesdb/.nbd/tickets/dc3d2b.md +++ b/quotesdb/.beans/quotesdb-wvb8--set-up-uitrunktoml-and-uiindexhtml-build-configura.md @@ -1,10 +1,15 @@ -+++ -title = "Set up ui/Trunk.toml and ui/index.html — build configuration and Wasm entry point" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["a9534d", "9ef703"] -+++ +--- +# quotesdb-wvb8 +title: Set up ui/Trunk.toml and ui/index.html — build configuration and Wasm entry point +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:11Z +updated_at: 2026-03-10T23:32:19Z +blocked_by: + - quotesdb-xg67 + - quotesdb-fg44 +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. @@ -71,4 +76,4 @@ trunk build `chore(quotesdb): set up Trunk.toml and index.html for UI build` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/6a4c61.md b/quotesdb/.beans/quotesdb-x2kf--submit-form-remove-submit-another-link-from-succes.md similarity index 87% rename from quotesdb/.nbd/tickets/6a4c61.md rename to quotesdb/.beans/quotesdb-x2kf--submit-form-remove-submit-another-link-from-succes.md index f74d367..cf2aa6f 100644 --- a/quotesdb/.nbd/tickets/6a4c61.md +++ b/quotesdb/.beans/quotesdb-x2kf--submit-form-remove-submit-another-link-from-succes.md @@ -1,10 +1,13 @@ -+++ -title = "Submit form: remove 'Submit another' link from success screen" -priority = 5 -status = "done" -ticket_type = "bug" -dependencies = [] -+++ +--- +# quotesdb-x2kf +title: 'Submit form: remove ''Submit another'' link from success screen' +status: completed +type: bug +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- + ## Bug After successfully submitting a quote, the success screen (`src/bin/ui/pages/submit.rs`, lines 111–133) offers two actions: @@ -72,4 +75,4 @@ Manually verify: after submitting a quote, the success screen shows "View your q ## Commit scope -`fix(quotesdb): remove submit-another link from success screen` \ No newline at end of file +`fix(quotesdb): remove submit-another link from success screen` diff --git a/quotesdb/.nbd/tickets/68fd11.md b/quotesdb/.beans/quotesdb-xa7q--quotesdbapi-post-apiadminreset-auth-code-endpoint.md similarity index 93% rename from quotesdb/.nbd/tickets/68fd11.md rename to quotesdb/.beans/quotesdb-xa7q--quotesdbapi-post-apiadminreset-auth-code-endpoint.md index e95b1ac..ce8468b 100644 --- a/quotesdb/.nbd/tickets/68fd11.md +++ b/quotesdb/.beans/quotesdb-xa7q--quotesdbapi-post-apiadminreset-auth-code-endpoint.md @@ -1,10 +1,15 @@ -+++ -title = "quotesdb/api: POST /api/admin/reset-auth-code endpoint" -priority = 6 -status = "done" -ticket_type = "feature" -dependencies = ["69a2c5"] -+++ +--- +# quotesdb-xa7q +title: 'quotesdb/api: POST /api/admin/reset-auth-code endpoint' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:15Z +blocked_by: + - quotesdb-04cw +--- + ## POST /api/admin/reset-auth-code endpoint Add the admin-protected endpoint that replaces the stored admin auth code. The caller must supply the current code via `X-Admin-Code`. A new code may be provided in the request body; if omitted, the server generates a fresh 4-word passphrase. @@ -118,4 +123,4 @@ cargo fmt && cargo check && cargo clippy && cargo test ``` feat(quotesdb): POST /api/admin/reset-auth-code endpoint -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/a9534d.md b/quotesdb/.beans/quotesdb-xg67--triage-local-dev-cors-and-trunk-api-proxy-config-t.md similarity index 87% rename from quotesdb/.nbd/tickets/a9534d.md rename to quotesdb/.beans/quotesdb-xg67--triage-local-dev-cors-and-trunk-api-proxy-config-t.md index 4fee687..220d2c6 100644 --- a/quotesdb/.nbd/tickets/a9534d.md +++ b/quotesdb/.beans/quotesdb-xg67--triage-local-dev-cors-and-trunk-api-proxy-config-t.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Local dev CORS and Trunk API proxy config (trunk serve proxying to api on different port)" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-xg67 +title: '[TRIAGE] Local dev CORS and Trunk API proxy config (trunk serve proxying to api on different port)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:09Z +updated_at: 2026-03-10T23:32:09Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. @@ -39,4 +41,4 @@ Created ticket: 00d6d7 (dedicated implementation task for the proxy config). `chore(quotesdb): resolve triage — local-dev-cors-and-trunk-api-proxy-config-trunk-serve-proxyi` - \ No newline at end of file + diff --git a/quotesdb/.nbd/tickets/25c413.md b/quotesdb/.beans/quotesdb-xi3i--quotesdbinfra.md similarity index 80% rename from quotesdb/.nbd/tickets/25c413.md rename to quotesdb/.beans/quotesdb-xi3i--quotesdbinfra.md index c74f4d0..6996a7f 100644 --- a/quotesdb/.nbd/tickets/25c413.md +++ b/quotesdb/.beans/quotesdb-xi3i--quotesdbinfra.md @@ -1,10 +1,14 @@ -+++ -title = "quotesdb/infra" -priority = 7 -status = "todo" -ticket_type = "project" -dependencies = ["06d304"] -+++ +--- +# quotesdb-xi3i +title: quotesdb/infra +status: todo +type: epic +priority: high +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-sqho +--- This is the sub-project tracking ticket for `quotesdb/infra`. All infrastructure tasks depend on this ticket. The infra domain covers: OpenTofu project setup, Cloudflare Worker, D1 database, Pages project, custom domain, and documentation. diff --git a/quotesdb/.nbd/tickets/04f865.md b/quotesdb/.beans/quotesdb-xqh3--implement-uisrcmainrs-yew-app-shell-browserrouter.md similarity index 80% rename from quotesdb/.nbd/tickets/04f865.md rename to quotesdb/.beans/quotesdb-xqh3--implement-uisrcmainrs-yew-app-shell-browserrouter.md index 6938965..1faff71 100644 --- a/quotesdb/.nbd/tickets/04f865.md +++ b/quotesdb/.beans/quotesdb-xqh3--implement-uisrcmainrs-yew-app-shell-browserrouter.md @@ -1,10 +1,16 @@ -+++ -title = "Implement ui/src/main.rs — Yew app shell, BrowserRouter, route definitions for all 5 pages" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["93515e", "dc3d2b", "0fbdd5"] -+++ +--- +# quotesdb-xqh3 +title: Implement ui/src/main.rs — Yew app shell, BrowserRouter, route definitions for all 5 pages +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:12Z +blocked_by: + - quotesdb-kaat + - quotesdb-wvb8 + - quotesdb-wlpv +--- The `quotesdb` UI is a Yew (Rust → Wasm) single-page app compiled by Trunk and hosted on Cloudflare Pages. It communicates with the backend API via `fetch` calls. Source lives in `src/bin/ui/`. Run with `trunk serve` for local development. diff --git a/quotesdb/.nbd/tickets/65e220.md b/quotesdb/.beans/quotesdb-yjpy--add-workers-rs-wasm-entry-point-to-api-binary.md similarity index 90% rename from quotesdb/.nbd/tickets/65e220.md rename to quotesdb/.beans/quotesdb-yjpy--add-workers-rs-wasm-entry-point-to-api-binary.md index bb34246..dd8b3f1 100644 --- a/quotesdb/.nbd/tickets/65e220.md +++ b/quotesdb/.beans/quotesdb-yjpy--add-workers-rs-wasm-entry-point-to-api-binary.md @@ -1,10 +1,13 @@ -+++ -title = "Add workers-rs WASM entry point to api binary" -priority = 7 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-yjpy +title: Add workers-rs WASM entry point to api binary +status: completed +type: feature +priority: high +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- + ## Goal Enable `cargo build --release --bin api --target wasm32-unknown-unknown` so the api binary deploys as a Cloudflare Worker (see `infra/worker.tf`). @@ -42,4 +45,4 @@ All axum types used in handlers (Router, Path, Query, State, Json, etc.) are ava cargo build --release --bin api --target wasm32-unknown-unknown cargo build --release --bin api # native must still work cargo fmt && cargo check && cargo clippy && cargo test -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/5137d7.md b/quotesdb/.beans/quotesdb-yo7x--write-giteaworkflowsdeploy-uiyml-gitea-actions-wor.md similarity index 93% rename from quotesdb/.nbd/tickets/5137d7.md rename to quotesdb/.beans/quotesdb-yo7x--write-giteaworkflowsdeploy-uiyml-gitea-actions-wor.md index bb0f7df..2d80e78 100644 --- a/quotesdb/.nbd/tickets/5137d7.md +++ b/quotesdb/.beans/quotesdb-yo7x--write-giteaworkflowsdeploy-uiyml-gitea-actions-wor.md @@ -1,10 +1,15 @@ -+++ -title = "Write .gitea/workflows/deploy-ui.yml — Gitea Actions workflow to build and deploy UI to Cloudflare Pages" -priority = 4 -status = "done" -ticket_type = "task" -dependencies = ["ae886f", "dc3d2b"] -+++ +--- +# quotesdb-yo7x +title: Write .gitea/workflows/deploy-ui.yml — Gitea Actions workflow to build and deploy UI to Cloudflare Pages +status: completed +type: task +priority: low +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-qt7m + - quotesdb-wvb8 +--- Build strategy resolved in triage fc9bfd: pre-built artifact + Gitea Actions + `wrangler pages deploy`. diff --git a/quotesdb/.nbd/tickets/8a7fba.md b/quotesdb/.beans/quotesdb-ysah--quotesdbapi-hidden-flag-for-quotes-schema-migratio.md similarity index 84% rename from quotesdb/.nbd/tickets/8a7fba.md rename to quotesdb/.beans/quotesdb-ysah--quotesdbapi-hidden-flag-for-quotes-schema-migratio.md index 3316735..7fd3b0d 100644 --- a/quotesdb/.nbd/tickets/8a7fba.md +++ b/quotesdb/.beans/quotesdb-ysah--quotesdbapi-hidden-flag-for-quotes-schema-migratio.md @@ -1,10 +1,13 @@ -+++ -title = "quotesdb/api: hidden flag for quotes (schema migration + endpoints)" -priority = 5 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ +--- +# quotesdb-ysah +title: 'quotesdb/api: hidden flag for quotes (schema migration + endpoints)' +status: completed +type: feature +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:08Z +--- + ## Summary Add a boolean hidden flag to quotes. Hidden quotes are excluded from listing endpoints and require direct URL access. Changing a quote from hidden to public requires the auth code. @@ -34,4 +37,4 @@ ALTER TABLE quotes ADD COLUMN hidden INTEGER NOT NULL DEFAULT 0; ## Validation ```sh cargo fmt && cargo check && cargo clippy && cargo test -``` \ No newline at end of file +``` diff --git a/quotesdb/.nbd/tickets/893eba.md b/quotesdb/.beans/quotesdb-yxaa--test-suite-tag-operations-create-with-tags-list-by.md similarity index 78% rename from quotesdb/.nbd/tickets/893eba.md rename to quotesdb/.beans/quotesdb-yxaa--test-suite-tag-operations-create-with-tags-list-by.md index d2ed254..f77c774 100644 --- a/quotesdb/.nbd/tickets/893eba.md +++ b/quotesdb/.beans/quotesdb-yxaa--test-suite-tag-operations-create-with-tags-list-by.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: tag operations — create with tags, list by tag filter, update replaces all tags" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "175382"] -+++ +--- +# quotesdb-yxaa +title: 'Test suite: tag operations — create with tags, list by tag filter, update replaces all tags' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:08Z +updated_at: 2026-03-10T23:32:16Z +blocked_by: + - quotesdb-gu9j + - quotesdb-qf7x +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/0d84fa.md b/quotesdb/.beans/quotesdb-z43c--triage-http-client-selection-for-integration-tests.md similarity index 88% rename from quotesdb/.nbd/tickets/0d84fa.md rename to quotesdb/.beans/quotesdb-z43c--triage-http-client-selection-for-integration-tests.md index 0b80486..6679cbb 100644 --- a/quotesdb/.nbd/tickets/0d84fa.md +++ b/quotesdb/.beans/quotesdb-z43c--triage-http-client-selection-for-integration-tests.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] HTTP client selection for integration tests — reqwest vs hyper vs ureq (tokio vs blocking)" -priority = 7 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-z43c +title: '[TRIAGE] HTTP client selection for integration tests — reqwest vs hyper vs ureq (tokio vs blocking)' +status: completed +type: task +priority: high +created_at: 2026-03-10T23:32:05Z +updated_at: 2026-03-10T23:32:05Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/4a4c26.md b/quotesdb/.beans/quotesdb-zc1j--test-suite-put-apiquotes-create-auto-auth-code-cus.md similarity index 82% rename from quotesdb/.nbd/tickets/4a4c26.md rename to quotesdb/.beans/quotesdb-zc1j--test-suite-put-apiquotes-create-auto-auth-code-cus.md index 6754633..6a595ae 100644 --- a/quotesdb/.nbd/tickets/4a4c26.md +++ b/quotesdb/.beans/quotesdb-zc1j--test-suite-put-apiquotes-create-auto-auth-code-cus.md @@ -1,10 +1,15 @@ -+++ -title = "Test suite: PUT /api/quotes — create (auto auth_code, custom auth_code, missing fields 422)" -priority = 5 -status = "done" -ticket_type = "task" -dependencies = ["9b581f", "05f8ae"] -+++ +--- +# quotesdb-zc1j +title: 'Test suite: PUT /api/quotes — create (auto auth_code, custom auth_code, missing fields 422)' +status: completed +type: task +priority: normal +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:14Z +blocked_by: + - quotesdb-gu9j + - quotesdb-a0q1 +--- Integration tests live in `tests/` and exercise the API binary against a temporary SQLite database. They run with `cargo test` and must not require a running Cloudflare environment. The test harness spawns the API server on a random port and returns the base URL. diff --git a/quotesdb/.nbd/tickets/580e66.md b/quotesdb/.beans/quotesdb-zlfi--triage-database-migration-strategy-for-cloudflare.md similarity index 90% rename from quotesdb/.nbd/tickets/580e66.md rename to quotesdb/.beans/quotesdb-zlfi--triage-database-migration-strategy-for-cloudflare.md index 98276e4..9e7e418 100644 --- a/quotesdb/.nbd/tickets/580e66.md +++ b/quotesdb/.beans/quotesdb-zlfi--triage-database-migration-strategy-for-cloudflare.md @@ -1,10 +1,12 @@ -+++ -title = "[TRIAGE] Database migration strategy for Cloudflare Workers (startup vs wrangler d1 execute)" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = [] -+++ +--- +# quotesdb-zlfi +title: '[TRIAGE] Database migration strategy for Cloudflare Workers (startup vs wrangler d1 execute)' +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:07Z +updated_at: 2026-03-10T23:32:07Z +--- This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. diff --git a/quotesdb/.nbd/tickets/2d1371.md b/quotesdb/.beans/quotesdb-zzm3--set-up-infra-opentofu-project-providerstf-terrafor.md similarity index 86% rename from quotesdb/.nbd/tickets/2d1371.md rename to quotesdb/.beans/quotesdb-zzm3--set-up-infra-opentofu-project-providerstf-terrafor.md index 00efba3..afb57e3 100644 --- a/quotesdb/.nbd/tickets/2d1371.md +++ b/quotesdb/.beans/quotesdb-zzm3--set-up-infra-opentofu-project-providerstf-terrafor.md @@ -1,10 +1,14 @@ -+++ -title = "Set up infra/ OpenTofu project — providers.tf, terraform.tf, .gitignore for state" -priority = 8 -status = "done" -ticket_type = "task" -dependencies = ["07feaa"] -+++ +--- +# quotesdb-zzm3 +title: Set up infra/ OpenTofu project — providers.tf, terraform.tf, .gitignore for state +status: completed +type: task +priority: critical +created_at: 2026-03-10T23:32:06Z +updated_at: 2026-03-10T23:32:13Z +blocked_by: + - quotesdb-esnq +--- Infrastructure is managed with OpenTofu using the Cloudflare provider. Configuration lives in `infra/`. Resources include a Cloudflare Worker (API), Cloudflare D1 database (bound to the worker), and a Cloudflare Pages project (UI frontend). diff --git a/quotesdb/.nbd/.gitignore b/quotesdb/.nbd/.gitignore deleted file mode 100644 index be8efad..0000000 --- a/quotesdb/.nbd/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cache.db diff --git a/quotesdb/.nbd/tickets/d4a624.md b/quotesdb/.nbd/tickets/d4a624.md deleted file mode 100644 index f4f77ab..0000000 --- a/quotesdb/.nbd/tickets/d4a624.md +++ /dev/null @@ -1,7 +0,0 @@ -+++ -title = "Support ADMIN_AUTH_CODE Cloudflare secret for admin auth" -priority = 8 -status = "done" -ticket_type = "feature" -dependencies = [] -+++ diff --git a/quotesdb/CLAUDE.md b/quotesdb/CLAUDE.md index daac4d1..8e4ee17 100644 --- a/quotesdb/CLAUDE.md +++ b/quotesdb/CLAUDE.md @@ -37,26 +37,26 @@ Design reference: `docs/plans/2026-02-27-quotesdb-design.md` -## nbd Ticket Tracking +## beans Ticket Tracking -**Always run `nbd` commands from the `quotesdb/` directory.** Tickets are scoped to the directory where `nbd init` was run. Running `nbd` from a parent directory will not find these tickets. +**Always run `beans` commands from the `quotesdb/` directory.** Beans are scoped to the directory where `beans init` was run. Running `beans` from a parent directory will not find these beans. ```sh # Correct — from quotesdb/ -nbd list --json -nbd read b38032 --json -nbd update b38032 --status done --json +beans list --json +beans show --json +beans update --json --status completed -# Wrong — from qdb/ or vibed/ -cd quotesdb && nbd list --json # must be in quotesdb/ +# Wrong — from vibed/ +cd quotesdb && beans list --json # must be in quotesdb/ ``` -### Ticket Hierarchy +### Bean Hierarchy ``` -quotesdb (root project ticket, ec118c) -├── quotesdb/api (sub-project ticket) -│ ├── quotesdb/api/ (task/feature/bug tickets) +quotesdb (root epic bean) +├── quotesdb/api (sub-epic bean) +│ ├── quotesdb/api/ (task/feature/bug beans) │ └── ... ├── quotesdb/ui │ └── ... @@ -67,11 +67,11 @@ quotesdb (root project ticket, ec118c) ``` Rules: -- Create a ticket **before** starting any non-trivial work. -- Work tickets are **dependencies of** their sub-project ticket — add them with `nbd update --deps "...existing...,"`. Work tickets do **not** list the sub-project in their own `--deps`. -- Sub-project tickets are **dependencies of** the root project ticket (`ec118c`) — they do **not** list `ec118c` in their own `--deps`. -- The dependency flows upward: `work → sub-project → root`. Each level can only close after all tickets below it are done. -- **Only close a ticket after its work has been validated** (all `cargo fmt/check/clippy/test` pass, or equivalent for infra). +- Create a bean **before** starting any non-trivial work. +- Work beans block their sub-epic bean — wire with `beans update --blocked-by `. +- Sub-epic beans block the root epic bean. +- The dependency flows upward: `work → sub-epic → root`. Each level can only close after all beans below it are done. +- **Only close a bean after its work has been validated** (all `cargo fmt/check/clippy/test` pass, or equivalent for infra). @@ -134,7 +134,7 @@ Dispatch all implementation work to a domain expert sub-agent. Match the domain Each sub-agent should receive: 1. The relevant section of `docs/plans/2026-02-27-quotesdb-design.md` -2. The specific nbd ticket body +2. The specific bean body (`beans show --json `) 3. The validation commands to run before closing the ticket 4. The conventional commit scope to use (e.g., `feat(quotesdb): ...`) diff --git a/scripts/migrate-nbd-to-beans.sh b/scripts/migrate-nbd-to-beans.sh new file mode 100755 index 0000000..5d4dc88 --- /dev/null +++ b/scripts/migrate-nbd-to-beans.sh @@ -0,0 +1,206 @@ +#!/usr/bin/env bash +# migrate-nbd-to-beans.sh — Migrate nbd tickets to beans +# +# Usage: bash scripts/migrate-nbd-to-beans.sh [project-dir] +# Defaults to current directory if no arg given. +# +# Requirements: beans, jq + +set -euo pipefail + +PROJECT_DIR="${1:-.}" +PROJECT_DIR="$(cd "$PROJECT_DIR" && pwd)" +NBD_DIR="$PROJECT_DIR/.nbd/tickets" +MAP_FILE="/tmp/nbd_id_map_$(echo "$PROJECT_DIR" | tr '/' '_').tsv" + +# ── Preflight ──────────────────────────────────────────────────────────────── + +if [[ ! -d "$NBD_DIR" ]]; then + echo "ERROR: No .nbd/tickets directory found in $PROJECT_DIR" >&2 + exit 1 +fi + +command -v beans >/dev/null 2>&1 || { echo "ERROR: beans not found in PATH" >&2; exit 1; } +command -v jq >/dev/null 2>&1 || { echo "ERROR: jq not found in PATH" >&2; exit 1; } + +# ── Field mappers ───────────────────────────────────────────────────────────── + +map_priority() { + local p="${1:-5}" + if [[ "$p" -ge 8 ]]; then echo "critical" + elif [[ "$p" -eq 7 ]]; then echo "high" + elif [[ "$p" -ge 5 ]]; then echo "normal" + elif [[ "$p" -ge 3 ]]; then echo "low" + else echo "deferred" + fi +} + +map_status() { + case "$1" in + todo) echo "todo" ;; + in_progress) echo "in-progress" ;; + done) echo "completed" ;; + closed) echo "scrapped" ;; + archived) echo "completed" ;; + backlog) echo "draft" ;; + *) echo "todo" ;; + esac +} + +map_type() { + case "$1" in + project) echo "epic" ;; + feature) echo "feature" ;; + task) echo "task" ;; + bug) echo "bug" ;; + *) echo "task" ;; + esac +} + +# ── Parse TOML frontmatter field (string value, strips surrounding quotes) ─── + +parse_field() { + local field="$1" + local file="$2" + awk -v field="$field" ' + /^\+\+\+$/ { fm_count++; if (fm_count == 2) exit; next } + fm_count == 1 && $0 ~ "^" field " = " { + line = $0 + sub("^" field " = \"?", "", line) + sub("\"?$", "", line) + print line + exit + } + ' "$file" +} + +# ── Extract body (everything after second +++) ──────────────────────────────── + +extract_body() { + local file="$1" + awk '/^\+\+\+$/ { count++; if (count == 2) { body=1; next } } body { print }' "$file" +} + +# ── Extract dep IDs from a TOML array string ───────────────────────────────── +# Input: dependencies = ["abc123", "def456"] +# Output: abc123\ndef456 (one per line) + +extract_dep_ids() { + echo "$1" | grep -oE '[0-9a-f]{6}' || true +} + +# ── Init ────────────────────────────────────────────────────────────────────── + +echo "==> Initializing beans in $PROJECT_DIR" +(cd "$PROJECT_DIR" && beans init) + +# Clear map file: columns are old_id new_id deps_raw +> "$MAP_FILE" + +tickets_created=0 +tickets_failed=0 +deps_wired=0 +warnings=() + +# ── Pass 1: Create beans ────────────────────────────────────────────────────── + +echo "" +echo "==> Pass 1: Creating beans from nbd tickets" + +body_tmp="$(mktemp)" +trap 'rm -f "$body_tmp"' EXIT + +for ticket_file in "$NBD_DIR"/*.md; do + [[ -f "$ticket_file" ]] || continue + old_id="$(basename "$ticket_file" .md)" + + # Parse frontmatter fields + title="$(parse_field title "$ticket_file")" + priority_num="$(parse_field priority "$ticket_file")" + status_raw="$(parse_field status "$ticket_file")" + type_raw="$(parse_field ticket_type "$ticket_file")" + deps_line="$(awk '/^\+\+\+$/ { fm_count++; if (fm_count == 2) exit; next } fm_count == 1 && /^dependencies = / { print; exit }' "$ticket_file")" + + # Map to beans values + beans_priority="$(map_priority "${priority_num:-5}")" + beans_status="$(map_status "${status_raw:-todo}")" + beans_type="$(map_type "${type_raw:-task}")" + + # Write body to temp file to avoid quoting issues + extract_body "$ticket_file" > "$body_tmp" + + # Create the bean + result="$(cd "$PROJECT_DIR" && beans create \ + --json \ + --type "$beans_type" \ + --status "$beans_status" \ + --priority "$beans_priority" \ + --body-file "$body_tmp" \ + "$title" 2>&1)" || true + + if new_id="$(echo "$result" | jq -r '.bean.id // .id' 2>/dev/null)" && [[ -n "$new_id" && "$new_id" != "null" ]]; then + printf '%s\t%s\t%s\n' "$old_id" "$new_id" "$deps_line" >> "$MAP_FILE" + (( tickets_created++ )) || true + echo " ✓ $old_id -> $new_id [$beans_status/$beans_priority/$beans_type] $title" + else + (( tickets_failed++ )) || true + warnings+=("WARN: failed to create ticket for nbd/$old_id: $title") + echo " ✗ $old_id FAILED: $title" + echo " Response: $result" + fi +done + +# ── Pass 2: Wire dependencies ───────────────────────────────────────────────── + +echo "" +echo "==> Pass 2: Wiring dependencies" + +while IFS=$'\t' read -r old_id new_id deps_line; do + dep_ids="$(extract_dep_ids "$deps_line")" + [[ -z "$dep_ids" ]] && continue + + while IFS= read -r dep_old_id; do + [[ -z "$dep_old_id" ]] && continue + + # Look up the new beans ID for this dependency + dep_new_id="$(awk -F'\t' -v id="$dep_old_id" '$1 == id { print $2 }' "$MAP_FILE")" + + if [[ -z "$dep_new_id" ]]; then + warnings+=("WARN: dep $dep_old_id (for $old_id -> $new_id) not found in map — skipped") + echo " ! dep $dep_old_id not found in map (for $new_id)" + continue + fi + + result="$(cd "$PROJECT_DIR" && beans update "$new_id" --blocked-by "$dep_new_id" --json 2>&1)" || true + if echo "$result" | jq -e '.bean.id // .id' > /dev/null 2>&1; then + (( deps_wired++ )) || true + echo " ✓ $new_id blocked-by $dep_new_id (was $old_id blocked-by $dep_old_id)" + else + warnings+=("WARN: failed to wire dep $dep_new_id -> $new_id: $result") + echo " ✗ failed to wire $dep_new_id -> $new_id" + fi + done <<< "$dep_ids" +done < "$MAP_FILE" + +# ── Cleanup ─────────────────────────────────────────────────────────────────── + +echo "" +echo "==> Removing .nbd directory" +rm -rf "$PROJECT_DIR/.nbd" +echo " Removed $PROJECT_DIR/.nbd" + +# ── Summary ─────────────────────────────────────────────────────────────────── + +echo "" +echo "==========================================" +echo " Migration complete for: $PROJECT_DIR" +echo " Tickets created : $tickets_created" +echo " Tickets failed : $tickets_failed" +echo " Deps wired : $deps_wired" +if [[ ${#warnings[@]} -gt 0 ]]; then + echo " Warnings:" + for w in "${warnings[@]}"; do + echo " - $w" + done +fi +echo "=========================================="