Skip to content

feat(kanban): kinds 31001/31002/31003 + boards/cards CLI (Phase 1) - #4200

Open
AlexMooreProblems wants to merge 1 commit into
block:mainfrom
AlexMooreProblems:kanban-phase1
Open

feat(kanban): kinds 31001/31002/31003 + boards/cards CLI (Phase 1)#4200
AlexMooreProblems wants to merge 1 commit into
block:mainfrom
AlexMooreProblems:kanban-phase1

Conversation

@AlexMooreProblems

Copy link
Copy Markdown

What

Phase 1 of the native Kanban board. Adds the kind constants, a base-36 order-preserving rank codec, SDK builders, relay ingest scope, and the buzz boards / buzz cards CLI — agent-usable end-to-end.

Kinds (NIP-33 parameterized-replaceable, owner-authored, global-only)

  • 31001 KIND_KANBAN_BOARD — ordered columns live on the board event.
  • 31002 KIND_KANBAN_CARD — single column + rank; a move replaces the card event = last-write-wins.
  • 31003 KIND_KANBAN_CARD_MOVE — optional non-replaceable audit trail.

Highlights

  • buzz-core: kind constants + base-36 order-preserving fractional rank (strict betweenness, no trailing-0 invariant so string compare == numeric order; incl. 5,000-insert fuzz test).
  • buzz-sdk: build_kanban_board/build_kanban_card + move-audit builder, NIP-32 namespaced ["l", <label>, "kanban"] labels, h/invite share tags.
  • buzz-relay: 31001/31002/31003 → ingest UsersWrite scope + global-only, with unit tests.
  • buzz-cli: buzz boards (create/get/list/update/add-column/rename-column) + buzz cards (create/list/get/move/update); shared submit_lww_event maps a superseded NIP-33 write to CliError::Conflictexit 5 (mirrors buzz mem).

Verification

  • cargo test -p buzz-core -p buzz-sdk -p buzz-cli all green; relay ingest tests green.
  • e2e on the isolated test relay (Docker harness): board + cards, card move (LWW, same card id), column rename (stable colid), and an exit 5 conflict when two moves race.

Notes

  • due/rank are in the schema + CLI; due/sprint UI is deferred to a later phase. Sharing read/write enforcement (P3) is not in this change.

Implements Phase 1 of the Kanban board: adds kind constants and a
base-36 order-preserving rank codec in buzz-core, board/card/move
builders in buzz-sdk, the `buzz boards` / `buzz cards` CLI surface, and
relay ingest scope for all three kinds.

Kinds (NIP-33 parameterized-replaceable, owner-authored, global-only):
- 31001 KIND_KANBAN_BOARD: ordered columns live on the board event.
- 31002 KIND_KANBAN_CARD: single `column` + `rank`; a move replaces the
  card event, giving last-write-wins via NIP-33.
- 31003 KIND_KANBAN_CARD_MOVE: optional non-replaceable audit trail.

buzz-core
- kind.rs: add KIND_KANBAN_BOARD=31001, KIND_KANBAN_CARD=31002,
  KIND_KANBAN_CARD_MOVE=31003.
- kanban.rs: base-36 order-preserving fractional rank codec with
  strict betweenness (no trailing-0 invariant so string compare ==
  numeric order). Unit-tested incl. a 5,000-insert fuzz.

buzz-sdk
- builders.rs: BoardMeta/build_kanban_board, CardMeta/build_kanban_card,
  and a move-audit builder, with `h`/`invite` share tags and NIP-32
  namespaced `["l", <label>, "kanban"]` labels.

buzz-relay
- ingest.rs: register all three kinds in required_scope_for_kind
  (Scope::UsersWrite) and is_global_only_kind; add unit tests asserting
  the scope + global-only behaviour.

buzz-cli
- boards.rs / cards.rs: `boards create/get/list/update/add-column/
  rename-column` and `cards create/list/get/move/update`, wired into the
  clap command tree.
- Buffer via a shared submit_lww_event that surfaces a superseded NIP-33
  write ("duplicate:" response) as CliError::Conflict → exit code 5,
  mirroring `buzz mem`.
- Fix the column-tag parser to parse name/wip/order by key rather than
  fixed index: the 6-element no-wip form (["column",id,"name",<name>,
  "order",<n>]) was reading the trailing order value into wip and losing
  the order, corrupting boards with no-WIP columns on rename/add. Added
  regression tests.

Validation: cargo test -p buzz-core -p buzz-sdk -p buzz-cli (all pass),
relay ingest tests (all pass), and an e2e against the isolated test
relay proving card move LWW (same card id, new column) and the exit-5
conflict surfaced when two moves race (49/60 attempts produced a
conflict; single-winner races show exit 0 + exit 5).

Co-authored-by: Alex Moore <mooorealexandert@gmail.com>
Signed-off-by: Alex Moore <mooorealexandert@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant