AGENTS.base.md is the versioned shared baseline for people working in the
pinto repository. It contains project rules that should stay consistent across
contributors and coding agents. See docs/DESIGN.md for
detailed design decisions.
Personal preferences and machine-specific instructions belong in a local overlay. They must not be added to this shared file or committed with the project.
Developers may derive a local AGENTS.md overlay from this baseline and then
append instructions for their own tools, editor, or environment:
cp AGENTS.base.md AGENTS.md
Keep the shared rules intact when adding local instructions. Root-level
AGENTS.md and CLAUDE.md, together with .claude/, are ignored by Git for
this purpose. Durable project rules belong in AGENTS.base.md or the linked
repository documentation so every contributor can use the same reference.
pinto is a Scrum backlog and Kanban board operated through the CLI and TUI. It manages Product Backlog items, Sprints, and Kanban boards without requiring users to leave the terminal.
These principles take precedence over all other decisions. When in doubt, choose the lighter and simpler option.
- Lightweight, fast, and simple — fast startup, few dependencies, and a low learning cost.
- Scrum-focused — keep the vocabulary limited to Product Backlog, Sprint, and Kanban concepts needed to execute Scrum.
- Plain text and Git-friendly — store data in human-readable files whose
changes can be reviewed with
git diff. - Local first — do not require a server, database service, or account.
- Heavy, full-stack feature growth like Jira or Asana.
- Features unrelated to Scrum or agile execution, such as Gantt charts, paid time tracking, CRM, or a document-management platform.
- A complex initialization flow that cannot work without configuration.
For every new feature, ask whether it is necessary for Scrum execution and whether it preserves the lightweight design.
- Toolchain management and task runner:
mise(mise.toml) - Language: Rust (2024 edition)
- CLI parser:
clap(derive API) - CLI completion and search:
clap_completegenerates shell completions;regexpowers regular-expression filters and validation. - Interactive Kanban TUI:
ratatuiwith its re-exportedcrosstermbackend; thekanbansubcommand is shipped and maintained. - Interactive shell:
rustylinefor line editing, history, and completion. - Serialization:
serde+serde_json+ TOML frontmatter (items) / TOML (configuration) - Markdown rendering:
termimadfor human-readable PBI and TUI details. - Dates and times:
chrono(DateTime<Utc>, RFC3339) - Errors:
thiserrorin library layers /anyhowin the binary - Localization:
fluent-bundleandunic-langidfor localized CLI/TUI text. - Concurrency: asynchronous I/O with [
tokio] / CPU parallelism with [rayon] - Storage and locking: asynchronous file operations with
tokio, advisory locks withfs4, secure editor buffers withtempfile, and optional SQLite support through bundledrusqlite. - Terminal layout:
terminal_sizefor terminal dimensions andunicode-widthfor display width. - Platform boundaries: Unix PTY tests use
libc; Windows-specific file identity support useswindows-sysonly on Windows. - Testing: standard tests +
assert_cmd/predicates/tempfilefor CLI integration tests
Keep dependencies to a minimum. Before adding a crate, check whether the standard library or an existing dependency is sufficient.
Use tokio for waiting on files and processes, rayon for CPU-bound
aggregation, fs4 for the board lock, and tempfile for the owner-private
editor buffer. ratatui supplies the TUI and its terminal backend, while
termimad supplies the shared Markdown rendering used by show and the
details popup. rusqlite is optional and only enables the SQLite backend; the
default file backend must remain usable without it.
Follow the rule “wait asynchronously, compute in parallel” (see
docs/DESIGN.md §3.4).
- I/O-bound work (waiting for files, networks, or databases) →
tokio. Usetokio::fsthroughout the persistence layer, parallelize multiple resources withJoinSet, and do not mix in synchronous blocking I/O. - CPU-bound work (analyzing or aggregating many PBIs) →
rayon. Split calculations across cores with parallel iterators. - At the boundary, “collect with async, solve with rayon.” For example,
listreads resources concurrently and parses them in parallel. - Do not add a sequential fallback based on item count. Keep I/O on the async path in anticipation of more remote I/O.
- Use a multi-threaded Tokio runtime and let Rayon's global pool handle CPU parallelism independently.
This project follows TDD. Keep the Red → Green → Refactor cycle:
- Red: write a failing test first.
- Green: write the smallest implementation that makes it pass.
- Refactor: improve structure and remove duplication while tests remain green.
- Do not write the implementation before the test.
- Test behavior in the single
pintocrate's domain modules (backlog,sprint, andrank), and verify CLI input and output with integration tests. - A commit should normally contain the test and the implementation that makes it pass.
Use mise for toolchain installation and project tasks. Start by running
mise install to install the tools declared in mise.toml.
mise install # Install the tools declared in mise.toml
mise run test # Run all tests, including all features
mise run lint # Run Clippy with warnings denied
mise run fmt # Format Rust sources
mise run book # Build the mdBook documentation
mise run check # test + lint + Rust/mdBook docs + fmt --check
mise run coverage # Measure the Cobertura line-coverage thresholdThe task definitions in mise.toml wrap locked all-feature tests, Clippy, Rust
documentation, mdbook build, formatting, and the coverage check. Direct
cargo commands are allowed, but prefer mise run to keep local and CI
behavior aligned. Public API examples and the CLI PTY tests can be run with:
cargo test --doc --locked
cargo test --test cli --lockedThe parser fuzz targets are under fuzz/. With nightly Rust and
cargo-fuzz installed, list and run them with:
cargo check --manifest-path fuzz/Cargo.toml --bins --locked
cargo fuzz list
cargo fuzz run automation_plan_parse -- -max_total_time=300
cargo fuzz run markdown_frontmatter_parse -- -max_total_time=300The scheduled CI fuzz job runs both targets and uploads failures from
fuzz/artifacts. See testing.md for the full
reproduction workflow.
Before committing, confirm that mise run check passes. It runs tests, lint,
Rust API documentation, mdBook documentation, and formatting checks.
pinto self-hosts its own backlog. The sole source of truth is .pinto/.
- Add, transition, rank, and remove items through pinto commands such as
add,move,edit, andrm. If manual recovery is necessary, edit.pinto/tasks/*.mddirectly. - The former repository-level backlog is not maintained; see
docs/migration.mdfor the migration procedure and historical background. - See
docs/DOGFOODING.mdfor the specific techniques used to validate changes with pinto and update.pinto/.
- Keep domain logic independent of the CLI and TUI so it remains easy to unit test.
- Avoid
unwrap()andexpect()on production code paths; propagate errors asResultvalues. - Add concise documentation comments to public APIs and non-obvious logic.
- Keep user-facing messages and help text concise. Errors should explain what to fix and how to fix it.
- Also read
CONTRIBUTING.md.