Contributing to kanbanr
Thanks for your interest! kanbanr is a personal open-source project — maintained best-effort, friendly to contributors, no SLA. Small fixes and focused features are very welcome; please open an issue before large changes so we can agree on the approach.
What kanbanr is (so contributions fit the design)
One binary. kanbanr is the only writer — the CLI edits a git-backed data/ folder directly
(driven by a Claude skill). kanbanr serve runs a read-only view daemon (localhost, no auth, no
accounts) over the same folder. Sharing is delegated to git remotes. Keep this split intact:
- All writes go through
kanbanr-core(the engine: store ·dispatchrouter · git · activity). The CLI and the daemon both call core; don’t add a second write path. - The web UI and the
servedaemon never mutate data. They read and stream. New “actions” in the UI should be read-only (e.g. export). - Data is human-readable YAML/markdown; no database.
See Architecture overview for the full architecture.
Prerequisites
- Rust stable (
rustup), withrustfmtandclippy. - Node 22+ and npm (for the web SPA).
- A C toolchain for the vendored libgit2 + OpenSSL build:
cmake,make,perl, and a C compiler (gcc/clang). On Debian/Ubuntu:sudo apt-get install -y cmake make perl gcc. On macOS:brew install cmake(perl ships with macOS). On Windows: cmake + Strawberry Perl onPATH.The first build compiles vendored C from source and is slow (a few minutes); it’s cached afterward. This is expected, not a hang.
Build, test, lint
From the repo root (the Makefile wraps the common flows):
make build # cargo build --release (api/) + web build
make test # cargo test --workspace (unit + Docker-less integration)
make itest # packaging smoke: build the image + testcontainers test (needs Docker)
Run the same checks CI runs before opening a PR — all of them, in one command:
make ci
It copies the tracked tree to a clean folder (~/.cache/kanbanr-ci/tree, with its own build
cache) and runs every CI check that can run off GitHub, reading each step’s script from the
workflow file itself, plus actionlint and a check that every action the workflows use exists. It
ends by listing what only GitHub can verify: the macOS and Windows legs, uploads and publishing.
It needs Docker (for actionlint and PowerShell), an authenticated gh, shellcheck, and the
mdbook / mdbook-mermaid versions pinned in docs.yml, and cargo-deny + cargo-audit
(cargo install cargo-deny cargo-audit --locked). The individual checks, if you want one:
cd api && cargo fmt --all --check # formatting
cd api && cargo clippy --workspace -- -D warnings # lints (warnings are errors)
cd api && cargo test --workspace
cd web && npm ci && npm run build # web type-check + build
Run the app locally to try your change:
make serve # builds the SPA + serves the read-only monitor on http://localhost:8080
Coding conventions
- Rust:
cargo fmt+clippyclean (no warnings). Match the surrounding style; comments explain why, not what, at the density of the file you’re editing. - TypeScript/React: the UI is read-only and plain (
fetch+EventSource); no state libraries. Keep components small and typed. - Prefer a single
kanbanr batch/dispatchroute over bespoke one-off code paths. - Update tests for behavior changes;
kanbanr-coreis where the engine tests live. - Update the relevant docs (the Using kanbanr and Architecture chapters, the skill) when you change a contract.
The bar: say why, and show it works
kanbanr asks the same thing of a contribution that it asks of its own maintainer, because this project’s board is the demonstration that the method works — a change that skipped it would break the demonstration. The bar is one sentence long:
State why the change exists, and prove each requirement with a test that actually passed.
In practice, the PR template has a Definition block. Fill it in:
- A statement — what the change gives whom, and why. One sentence.
- The six dimensions — what / how / where / when / who / why, a line each.
- Requirements in EARS form (
WHEN … THE SYSTEM SHALL …), each with the test that proves it, named exactly as your test runner prints it. - Leave what you don’t know blank. A blank is reported and can be filled; an invented answer reads like rigour and is worse than nothing. If something is genuinely ambiguous, ask in the issue rather than guessing.
You do not need the board to do this. kanbanr check --file definition.yaml validates a
definition on its own, which is what CI runs on your PR — no board access required.
Reading the project’s board
The board itself is public: https://github.com/startr-trade/kanbanr-board. Clone it beside
this repository — the committed .kanbanr points at ../kanbanr-board — and the whole method is
there to read:
git clone https://github.com/startr-trade/kanbanr-board ../kanbanr-board
kanbanr board # what is planned, in progress and done
kanbanr ready # what can be picked up now
kanbanr feature show FEAT-128 # why an item exists, and how it was verified
kanbanr why api/crates/kanbanr-cli/src/main.rs:120 # the item and requirement behind a line
kanbanr serve # the live monitor
Before you change something, kanbanr why on the lines you are touching names the requirement they
serve; your definition should say whether you keep it, change it, or add one beside it. Only the
maintainer writes to the board: a contribution’s definition travels in its pull request, and the
maintainer records it on the board when the pull request is merged.
A worked example
A real change from this project’s own history, end to end. The defect: ticking an item’s last task auto-completed it without recording the status change, so cycle time was blind to the normal way items finish.
statement: "A recorded transition for every status change, however it happened, so that flow numbers
describe the items that finished normally rather than only the ones moved by hand"
goals: [G-2]
zachman:
what: "The history entry an auto-completion did not write"
how: "The auto-complete branch appends the same Transition a manual move does"
where: "kanbanr-core/src/store.rs, set_task_state_on"
when: "Whenever the last open task of an item is completed"
who: "Anyone reading cycle time, which was blind to the normal path"
why: "Auto-completion is how most items reach a terminal status, so the measurement was missing
precisely where it mattered"
requirements:
- kind: functional
text: "WHEN completing a task auto-completes its item, THE SYSTEM SHALL append the same
transition a manual move records."
tests:
- name: tests::auto_completion_records_the_move_like_any_other
kind: unit
state: green
- kind: functional
text: "WHEN a status is renamed, THE SYSTEM SHALL leave the items' histories unchanged."
tests:
- name: tests::auto_completion_records_the_move_like_any_other
kind: unit
state: green
The commit that followed carried Refs: kanbanr:FEAT-061/R-1 in its trailer, and the test named
above is the one that ran. That is the whole shape: a reason, a requirement, a test, a reference.
A note on this project’s own board. Items created before the method was adopted have no definition, and
kanbanr doctordeliberately does not report them. The board reads as adopted, not abandoned — everything from that point on meets the bar above.
Commits & pull requests
- Fork, branch off
main(feature/short-nameorfix/short-name). - Keep commits focused; write clear messages (imperative mood: “Add …”, “Fix …”).
- Reference what the change serves in the commit trailer:
Refs: kanbanr:FEAT-046/R-2if you know the item, or describe it in the PR if you don’t have the board. - Optionally sign off your commits (
git commit -s) to certify the Developer Certificate of Origin. - Make sure
make ciis green, and that every requirement in your definition has a green test. - Open a PR; fill in the template, definition included; link any issue.
Licensing of contributions
kanbanr is dual-licensed MIT OR Apache-2.0 (see LICENSE-MIT and LICENSE-APACHE). Unless you state otherwise, any contribution you intentionally submit for inclusion is licensed under those same terms, per section 5 of the Apache-2.0 license, with no additional terms or conditions.
Reporting bugs / requesting features
Use the GitHub issue templates. For anything security-sensitive, do not open a public issue — follow SECURITY.md.