Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,35 @@ Exempt artifact types (no trailer required): `chore`, `style`, `ci`, `docs`, `bu
To skip traceability for a commit, add: `Trace: skip`
<!-- END rivet-managed -->

## Before You Push (Rust)

`Format` and `Clippy` are the two most common first-push CI failures, and
neither has a fast guard in the default agent workflow unless you have run
`./scripts/install-hooks.sh` (which installs a git `pre-commit` that runs
`cargo fmt --all -- --check` on staged `.rs` files). Even with the hook,
clippy is not checked per-commit (too slow). So before every push that
touches Rust, run the **exact CI gates** by hand:

```sh
cargo fmt --all -- --check # CI "Format" gate (ci.yml)
cargo clippy --all-targets -- -D warnings # CI "Clippy" gate — note --all-targets and -D warnings
```

Pitfalls (verified against CI):
- `cargo clippy ... | grep '^error'` is **deceptive** — CI uses `-D warnings`,
so a *warning* (e.g. `doc_lazy_continuation`) fails CI while that grep reports
clean. Always run the full `-D warnings` form, no grep.
- `cargo clippy -p <crate>` skips test code; CI runs `--all-targets`, which
lints tests too. Test-only lints pass locally but fail CI without
`--all-targets`.
- The commit-msg hook rejects body lines shaped like `Word:` as malformed
trailers — phrase verification prose as "Confirmed with …", and keep real
trailers (`Implements`/`Verifies`/`Refs`) in the final block.

A one-shot `pre-commit install --install-hooks` also activates the
`.pre-commit-config.yaml` `cargo-fmt` + `cargo-clippy` hooks if you prefer the
pre-commit framework. See `docs/pre-commit.md`.

## Parallel-PR friction (avoiding merge conflicts)

When several PRs are in flight at once (the dogfooding loop is the heaviest
Expand Down
52 changes: 52 additions & 0 deletions artifacts/requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6183,3 +6183,55 @@ artifacts:
links:
- type: traces-to
target: REQ-007
- id: REQ-202
type: requirement
title: "rivet-cli must support a minimal `--no-default-features` build (validate/list/commit-msg-check) that excludes the serve+MCP+LSP stack"
status: draft
description: |
Finding (issue #456, AI-agent dogfooding, verified against
rivet-cli/Cargo.toml). `rivet validate` is the hook-critical and
CI-critical hot path, yet rivet-cli has NO way to build a minimal binary:
`[features]` is `default = []` (only `wasm` is non-trivial), and `axum`,
`tower-http`, `notify` (serve), `lsp-server`/`lsp-types` (LSP), and `rmcp`
(full streamable-HTTP MCP server) are UNCONDITIONAL dependencies. So every
from-source build — `cargo install rivet`, CI's compile step, and a local
build to test a one-line validate change — compiles the entire web/MCP/LSP
tree even though validate/list/commit-msg-check never use it. rivet-core
already gates its heavy deps (`wasm`, `reqwest`, `spar-*` are
`optional = true`); the coupling is specific to rivet-cli.

Fix (additive, preserves published behavior): introduce cargo features and
KEEP them in `default`, so the released binary is byte-for-byte unchanged:
default = ["serve", "mcp", "lsp"]
serve = ["dep:axum", "dep:tower-http", "dep:notify"]
mcp = ["dep:rmcp", "dep:tokio"]
lsp = ["dep:lsp-server", "dep:lsp-types"]
…with `#[cfg(feature = ...)]` gating the corresponding command handlers and
`mod serve`/`mod mcp`/`mod lsp` declarations in main.rs. The code-side
gating across the serve/mcp/lsp command dispatch is the bulk of the work
and needs care so `--no-default-features` still compiles cleanly. The
default-feature set is a maintainer call (filed as draft).

Acceptance:
- `rivet-cli/Cargo.toml` declares `serve`/`mcp`/`lsp` features, all in
`default`, with the corresponding deps marked `optional = true`
(`dep:` syntax).
- `cargo build -p rivet-cli --no-default-features` succeeds and the
resulting binary runs `validate`, `list`, and `commit-msg-check`.
- `cargo build -p rivet-cli --no-default-features` does NOT compile
`axum`, `rmcp`, or `lsp-server` (verify via
`cargo tree -p rivet-cli --no-default-features` absence).
- Default build (`cargo build -p rivet-cli`) is unchanged: serve, mcp,
and lsp subcommands all present.
- `rivet validate` on the rivet repo still PASS.
tags: [cli, build, cargo-features, minimal-build, friction, dogfooding]
fields:
priority: should
category: functional
links:
- type: traces-to
target: REQ-007
provenance:
created-by: ai-assisted
model: claude-opus-4-8
timestamp: 2026-06-05T09:23:14Z
Loading