nusy-kanban
Arrow-native kanban with a nautical soul — a high-performance, multi-agent work tracker built on Apache Arrow and Parquet. Tracks expeditions, voyages, and research with graph-native PRs, dual boards (dev + research), and NATS-powered coordination.
For AI developers building autonomous agents, nusy-kanban provides a structured
research workflow (HDD), SPARQL-queryable metadata, and a training queue — everything
a being needs to own its own development pipeline.
For AI Developers
This crate is designed for two audiences:
- Teams — developers who want a fast, self-hosted kanban with NATS multi-agent coordination, crash-safe persistence, and zero-copy columnar queries.
- Autonomous AI beings — agents who need a structured development workflow with hypothesis tracking, experiment queuing, and measurable targets.
If you are building a being that manages its own work, start with the Hypothesis-Driven Development (HDD) guide below.
Quick Start
# Initialize (creates .nusy-kanban/ locally)
# Create your first expedition
# or --server nats://your-host:4222 for multi-agent
# View and move work
Multi-Agent Setup
Point all agents at a shared NATS server for single-writer semantics:
No lock files, no ID collisions, no merge conflicts. The server serializes all writes.
Core Concepts
Arrow-Native Storage
Every write goes to an Apache Arrow RecordBatch backed by Parquet snapshots.
Queries are zero-copy columnar scans — no YAML globbing, no file I/O on reads.
Crash safety comes from a WAL + atomic rename pattern (via nusy-arrow-git).
Dual Boards
| Board | Types | Purpose |
|---|---|---|
| Development | Expedition, Chore, Voyage, Hazard, Signal | Feature work |
| Research | Paper, Hypothesis, Experiment, Measure, Idea, Literature | HDD research cycle |
The Nautical Theme
Development items follow a nautical lifecycle:
Harbor → Provisioning → Underway → Approaching Port → Arrived
(backlog) (ready) (in_progress) (review) (done)
Arrow Schema
┌─────────────────────────────────────────────────────────────────┐
│ items (KanbanStore) │
│ ─────────────────────────────────────────────────────────────── │
│ id, title, item_type, status, priority, assignee, │
│ tags, related, depends_on, body, created_at, updated_at, │
│ body_hash, resolution, closed_by │
└──────────────────────────┬────────────────────────────────────────┘
│ 1:many via id
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ runs │ │ item_comments │ │ relations │
│ ───────────── │ │ ───────────── │ │ ───────────── │
│ id, item_id, │ │ id, item_id, │ │ source_id, │
│ status, │ │ comment, │ │ target_id, │
│ updated_at, │ │ author, │ │ predicate, │
│ updated_by, │ │ created_at │ │ source_type, │
│ run_number │ │ │ │ target_type │
└───────────────┘ └───────────────┘ └───────────────┘
Persistence Flow
Write Request
│
▼
nusy-arrow-git::save_named_batches()
│
├─▶ Write to WAL (append-only log)
│
└─▶ Write to tmp Parquet files
│
▼
atomic rename() ← crash-safe
│
▼
Final Parquet files in .nusy-kanban/
HDD for Autonomous Beings
HDD (Hypothesis-Driven Development) is a research methodology that applies test-driven development rigor to scientific investigation. Where TDD writes a failing test first, HDD writes a falsifiable hypothesis before running an experiment.
The key rule: only validated enhancements ship. Negative results are documented, not hidden.
The 6 Research Types
All research items live on the research board and are created with nk commands:
| Type | ID | Purpose | Auto-links |
|---|---|---|---|
| Paper | PAPER-{N} |
Publication documenting validated hypotheses | Root of chain |
| Hypothesis | H{paper}.{seq} |
Falsifiable claim with quantitative target | kb:tests → Paper |
| Experiment | EXPR-{paper}.{seq} |
Reproducible protocol | kb:validates → Hypothesis |
| Measure | M-{N} |
Quantitative metric | kb:measures → Experiment |
| Idea | IDEA-{N} |
Raw observation or question | None |
| Literature | LIT-{N} |
Prior work survey | None |
The Cycle
IDEA → LITERATURE → HYPOTHESIS → EXPERIMENT → ANALYSIS → PAPER
↓
FAIL? → Refine → loop
Example: A Being Tracks Entity Recall
A being named Santiago notices entity queries are slow and runs an experiment:
# 1. Capture the observation
# → IDEA-042
# 2. Survey prior work
# → LIT-017
# 3. Formalize the hypothesis (quantitative target required)
# → H131.1 (auto-linked: H131.1 --tests--> PAPER-131)
# 4. Design the experiment
# → EXPR-131.1 (auto-linked: EXPR-131.1 --validates--> H131.1)
# 5. Define the measure
# → M-042
GPU Experiment Queue
Experiments requiring GPU compute go through a NATS KV training queue:
# Queue a GPU job
# On DGX:
Queue metadata is stored as RDF triples in the experiment's Arrow record, making it SPARQL-queryable:
HDD Diagnostics
CLI Reference (22 top-level + 17 subcommands)
Core (8): create, move, update, comment, show, list, board, boards
Query (6): query, stats, history, roadmap, blocked, next
Planning (3): roadmap, critical-path, worklist
Management (6): validate, rank, export, next-id, migrate, init
HDD Research (8): hdd paper, hdd hypothesis, hdd experiment, hdd measure,
hdd idea, hdd literature, hdd validate, hdd registry
Training Queue (5): training queue, training list, training claim,
training complete, training fail
Graph-Native PRs (11): pr create, pr list, pr view, pr diff, pr review,
pr merge, pr close, pr comment, pr checks, pr resolve, pr revise
See CLI-REFERENCE.md for full flag documentation.
NATS Integration
When --server nats://host:4222 is provided, all commands use a request-reply
pattern via NATS subjects:
| Subject pattern | Type | Purpose |
|---|---|---|
kanban.cmd.{command} |
Request-reply | All CLI commands (create, move, list, ...) |
kanban.event.> |
Pub-sub (JetStream) | All mutation events (created, moved, deleted) |
training_queue |
NATS KV | Distributed GPU job queue |
Event Payload Example
Every mutation emits a JetStream event:
Subscribe once to kanban.event.> to receive all board activity:
// Rust — via noesis-ship
bus.subscribe.await?;
# Python — via noesis-ship
await
SHACL Shape Validation
All 13 item types have machine-readable SHACL shapes in Turtle (.ttl) format,
shipped inside the binary. Shapes define required fields, status enums, ID patterns,
and body section templates.
ID Patterns
| Type | Pattern | Example |
|---|---|---|
| Expedition | ^EX-\d{4,}$ |
EX-3001 |
| Voyage | ^VY-\d{4,}$ |
VY-3001 |
| Hypothesis | ^H-\d{3,}$ |
H-131 |
| Experiment | ^EXPR-\d{3,} |
EXPR-131.1 |
| Measure | ^M-\d{3,}$ |
M-042 |
| Paper | ^PAPER-\d{3,}$ |
PAPER-131 |
Validate an Item (Python + rdflib)
=
# Load an item graph from your Arrow store or .ttl file
=
# Load the shapes
=
# Run SHACL validation (requires pyshacl)
, , =
All shapes live at ontology/shapes/ in the source tree. See
EX-3667-SHACL-SHAPES.md for the
full reference (600+ lines covering all 13 types, WIP constraints, SPARQL
validation examples, and status tables).
Ecosystem
| Crate | Role |
|---|---|
| nusy-arrow-core | Arrow schemas, graph store |
| nusy-arrow-git | Graph-native git primitives, WAL + atomic rename |
| nusy-kanban | Kanban engine + CLI (this crate) |
| nusy-kanban-server | NATS server for multi-agent coordination |
Feature Flags
| Flag | Enables | Default |
|---|---|---|
client |
NATS client (async-nats + tokio) | on |
pr |
Graph-native PR workflows | on |
ci |
CI runner integration | on |
build |
Cranelift build/test integration | on |
codegraph |
Code graph integration | on |
fastembed |
Fastembed embedding backend | on |
Troubleshooting
Build Errors
feature "client" references optional dependency "async-nats" but async-nats is not declared as optional
Ensure you have optional = true on both async-nats and tokio in [dependencies].
Missing Rust toolchain Requires Rust 1.75+ (edition 2021). Install via:
|
NATS Connection Failures
Connection refused when using --server nats://...
- Verify the NATS server is running:
nc -zv 192.168.8.110 4222 - Check server uptime on Mini:
ssh mini@192.168.8.110 uptime - Fall back to local mode (omit
--serverflag) — reads/writes.nusy-kanban/locally
Request timed out
Default timeout is 30s for commands. Check Mini's load and retry — transient overload.
Schema Migration
When upgrading, Parquet files are auto-normalized:
persist.rs:normalize_batch()appends null columns for new schema fields- No manual migration needed — the store handles it transparently
- To force a full reload: delete
.nusy-kanban/*.parquetand re-run commands
Local vs Server Mode
| Flag | Behavior |
|---|---|
--server nats://192.168.8.110:4222 |
Single-writer to NATS-backed Arrow store on Mini |
| (none) | Local mode — reads/writes .nusy-kanban/*.parquet in current directory |
Important: Do not run two local-mode processes on the same directory simultaneously — Parquet writes are not atomic across files.
Comparison
| Feature | nusy-kanban | Linear | GitHub Issues | Jira |
|---|---|---|---|---|
| Storage | Arrow/Parquet | Cloud DB | Cloud DB | Cloud DB |
| Offline-first | Yes | No | No | No |
| Multi-agent safe | NATS server | API | API | API |
| Query speed | Zero-copy columnar | API call | API call | API call |
| Research workflows | HDD board | No | No | No |
| Self-hosted | Yes (NATS) | No | GHES | Data Center |
| Crash safety | WAL + atomic rename | Managed | Managed | Managed |
License
MIT