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
5 changes: 2 additions & 3 deletions .agents/rules/consolebook.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Consolebook Workspace Rule

Read and follow the repository-root `AGENTS.md` before changing this
project. It and this rule contain no independent project policy;
`CONTRIBUTING.md` owns the contribution lifecycle and `docs/decisions/`
owns durable decisions.
project. It is the shared project contract and routes to additional context;
this rule adds no independent policy.
3 changes: 3 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ What problem does this solve, and what should be true after merge?
- [ ] All fixtures and examples are invented; no real agency data

```text
- web/: npm ci, npm run check, npm run build
- cargo fmt --check
- cargo clippy --workspace --all-targets -- -D warnings
- cargo test --workspace
- cargo build -p consolebook-server
- web/: npm run e2e (state the browser used)
```

## Review And Merge Notes
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,12 @@ jobs:
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
run: cargo test --workspace
# Playwright starts the binary itself, using invented scratch installations.
- name: Build browser-test binary
run: cargo build -p consolebook-server
- name: Install browser
run: npx playwright install --with-deps chromium
working-directory: web
- name: Browser tests
run: npm run e2e
working-directory: web
198 changes: 79 additions & 119 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,81 @@
# Repository Guidelines

## Start With The Smallest Useful Context

Consolebook is a small Rust workspace plus one web app: the server lives
in `crates/consolebook-server/` (library modules plus a thin CLI in
`main.rs`, integration tests in `tests/`, embedded migrations in
`migrations/`), and the embedded SvelteKit interface lives in `web/`
(built statically, embedded by the Rust build; Node.js is build-time
only).

Durable truth lives in a few files; read only what the task needs:

- `PRINCIPLES.md` — non-negotiable product constraints
- `docs/architecture.md` — system boundaries and design targets
- `docs/domain-model.md` — domain vocabulary and invariants
- `docs/records-integrity.md` — immutability, hashes, provenance
- `docs/roadmap.md` — milestone sequence and current position
- `docs/decisions/` — architecture decision records

## Build And Verification

- `cargo build -p consolebook-server` builds the server.
- `cargo test --workspace` runs the tests.
- `cargo fmt --check` and
`cargo clippy --workspace --all-targets -- -D warnings` are repository
gates; clippy pedantic is enabled workspace-wide.
- In `web/`: `npm ci`, `npm run check`, and `npm run build` are gates;
build `web/` before cargo when interface behavior matters (a bare cargo
build compiles but serves an honest "not embedded" notice).
- `npm run e2e` in `web/` drives the compiled binary through the shell in
a real browser (set `CONSOLEBOOK_E2E_CHROMIUM` to a Chromium path when
Playwright's own download is unavailable).
- The toolchain is pinned in `rust-toolchain.toml`; do not float it.

Verification means the reported command actually ran. Preserve exact failure
evidence and explain the causal leaf failure. A design document is not runtime
proof, and a passing unit test is not recovery proof.

## Issue, Branch, And Pull-Request Workflow

Follow `CONTRIBUTING.md`. Non-trivial implementation, bug, refactor,
documentation, operations, and maintenance work uses one primary GitHub
issue, an issue-linked branch, and a pull request; never push repository
changes directly to `main`. Search existing issues first. `Closes #...`
means the PR satisfies the issue's acceptance criteria; otherwise use
`Refs #...` and leave the issue open.

Security reports use private advisories per `SECURITY.md`, never public
issues.

## Product And Authority Contract

Consolebook is pre-alpha training-record software for emergency
communications centers. `PRINCIPLES.md` is the authority; the load-bearing
consequences for code:

- Finalized records are immutable while retained. Corrections are successor
versions or amendments; deletion is lawful disposition, a separate
authorized workflow. Never an in-place edit.
- Agency variation is versioned configuration, never agency-specific code
paths or hidden conditionals.
- Finalized records pin the exact configuration versions used to create
them; mutable reference data must not rewrite history.
- Operational dates carry agency-local meaning; duration and ordering use
UTC instants. Do not conflate them.
- One executable, one data directory, SQLite. No required external
services, telemetry, or cloud dependencies.

Engineer solutions, not band-aids. Heuristics, regexes, substring matching,
and silent defaults may aid diagnostics, discovery, or presentation; they
may not establish record integrity, authorization, retention, disposition,
or export behavior. Those are typed contracts with tests. A failure in a
typed check is a defect to engineer, not a class of input to route around.

## Defect And Maintainability Discipline

- Fix a defect, duplicated authority, or half-implementation found in
scope. File an exact-evidence issue when it belongs elsewhere; do not
silently route around it.
- Fix causes and prove the contract or property, not only the observed
input.
- Treat intermittent or unexplained failures as evidence of a defect, not
as a reason to retry until green.
- A slice adding behavior to a Rust source file over 1,000 lines must
include an ownership-based reorganization in the same issue or plan.
Thin dispatch, registration, and re-export wiring may remain in a large
hub.
- Before changing behavior in a Rust file over 1,500 lines, name the
ownership boundary being preserved or improved. Files over 2,500 lines
need a reviewed decomposition path before major feature work unless the
fix is urgent.
- Refactors name what moves, its new owner, persisted/public impact, and
the focused proof.
- Decisions that change durable system behavior get an ADR in
`docs/decisions/`; changes to `PRINCIPLES.md` require one.

## Rust And CLI Conventions

Use standard Rust formatting and naming, `thiserror` for library errors as
they emerge, and `anyhow` at application boundaries. `unsafe` is forbidden
workspace-wide. Keep modules focused on one domain capability. Use short
imperative Conventional Commit subjects such as
`storage(backup): validate snapshot before fsync`.

Structured `tracing` logs never contain record content, personal data, or
credentials. Startup verifies database connection invariants and fails
closed; `doctor` diagnoses read-only and never creates or migrates state
(ADR 0003).

## Documentation And Safety

`AGENTS.md` is the concise repo-wide contract; `CONTRIBUTING.md` owns the
full contribution lifecycle; ADRs own decisions. Tool entrypoints
(`CLAUDE.md`, `.agents/rules/`, `.github/copilot-instructions.md`) stay
thin and point back here.

All fixtures, examples, tests, and seed data use invented agencies, people,
incidents, narratives, and identifiers. Real training records, operational
material, credentials, or personal information never enter this repository
in any form — code, docs, tests, logs, or issue text.
Consolebook is pre-alpha training-record software for emergency communications
centers: one Rust executable, one SQLite data directory, and a static SvelteKit
UI. No required external services, telemetry, or production Node.js runtime.

## Find the relevant context

Start with `git status --short --branch` and the task's issue or PR, including
unresolved review feedback. Preserve unrelated work. Do not assume a previous
session's branch, milestone status, or verification still describes the head.

Read only the context needed for the task:

- Build, source ownership, or local development: `docs/development.md`.
- Next work and milestone status: `docs/roadmap.md`, then the linked GitHub issue.
- Product constraints: `PRINCIPLES.md`; boundaries: `docs/architecture.md`.
- Domain terms: `docs/domain-model.md`; record integrity: `docs/records-integrity.md`.
- Contribution lifecycle, verification, and refactor rules: `CONTRIBUTING.md`.
- Decisions and formats: the task index in `docs/development.md` links the
relevant ADRs and specifications. Do not load the entire corpus by default.
- Preview deployment: `docs/preview.md`. Host configuration and deployed
binaries are separate from this checkout.

The server is in `crates/consolebook-server/`: `src/` owns services and the thin
CLI, `migrations/` owns persisted constraints, and `tests/` owns integration
proof. `web/src/` owns the UI and typed API client; `web/e2e/` tests the binary
through a browser. `sessions.rs` means login sessions; `training_sessions.rs`
means training periods.

## Non-negotiable contracts

- Finalized records are immutable while retained. Corrections create successor
versions or amendments. Lawful disposition is a separate authorized workflow.
- Agency variation is versioned configuration. Finalized records pin configuration
and presentation snapshots; mutable reference data must not rewrite history.
- Operational dates are agency-local; duration and ordering use UTC instants.
- Capabilities and scope are enforced by domain services. HTTP and UI adapt
those decisions. Authorization, integrity, retention, disposition, and exports
require typed contracts and tests; heuristics cannot establish them.
- Startup verifies storage invariants and fails closed. `doctor` must diagnose
without creating, migrating, or changing state (ADR 0003).
- Use invented agencies, people, incidents, identifiers, and narratives. Real
records, operational material, personal data, and credentials never enter the
repository, tests, logs, or issues. Security reports follow `SECURITY.md` privately.

## Work and verification

Non-trivial work requires one primary issue, an issue-linked branch, and a PR.
Search existing issues first; never push directly to `main`. `Closes #...` means
all acceptance criteria are satisfied; otherwise use `Refs #...`.

Build `web/` before Rust when UI or embedding matters. The command sequence and
browser prerequisites are in `CONTRIBUTING.md`. Required checks: `npm ci`,
`npm run check`, `npm run build` in `web/`; `cargo fmt --check`,
`cargo clippy --workspace --all-targets -- -D warnings`, and
`cargo test --workspace`. Browser tests need the compiled debug binary.
Keep the pinned Rust toolchain in `rust-toolchain.toml`.

Report only verification actually run, with exact failures. Investigate
intermittent failures. Design documents are not runtime proof; unit tests are
not recovery drills. Fix causes and in-scope defects; file exact-evidence
issues for separate work.

Follow `CONTRIBUTING.md` before adding behavior to large Rust modules: over
1,000 lines requires an ownership-based reorganization, over 1,500 requires
naming the boundary first, and over 2,500 requires a reviewed decomposition
path before major feature work unless urgent. Refactors state the new owner,
persisted/public impact, and focused proof.

Durable behavior changes require an ADR; changes to `PRINCIPLES.md` require one.
Use forward migrations, standard Rust formatting, `thiserror` for library
errors as they emerge, `anyhow` at application boundaries, and no `unsafe`.
Use short imperative Conventional Commit subjects. Logs exclude sensitive
content; existing first-run setup-code output is the documented exception
(ADR 0004), not permission for additional secret logging.

This file owns the concise shared contract; `CONTRIBUTING.md` owns workflow,
`docs/development.md` owns the source map, and ADRs own decisions. Tool-specific
entrypoints (`CLAUDE.md`, `.agents/rules/`, `.github/copilot-instructions.md`)
only point here. Keep machine preferences and session handoffs out of this file.
103 changes: 67 additions & 36 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,67 +1,98 @@
# Contributing

Consolebook is pre-alpha. Design changes are welcome, but the domain and record-integrity constraints in [PRINCIPLES.md](PRINCIPLES.md) come first.

## Before contributing

- Read the principles and relevant architecture decision records.
- Discuss broad domain or architecture changes before writing a large patch.
- Add or update an ADR when a decision changes durable system behavior.
- Keep changes narrow enough to review and verify.
Consolebook is pre-alpha. Follow [AGENTS.md](AGENTS.md) and the product
constraints in [PRINCIPLES.md](PRINCIPLES.md). The task index and source map in
[docs/development.md](docs/development.md) route to additional context.

## Issue, branch, and pull-request workflow

Non-trivial implementation, bug, refactor, documentation, operations, and
maintenance work uses one primary GitHub issue, an issue-linked branch, and a
pull request. Never push repository changes directly to `main`.

- Inspect the checkout and existing PR reviews; preserve unrelated edits.
- Search open and closed issues before filing a new one.
- `Closes #...` in a pull request means it satisfies the issue's acceptance
criteria; use `Refs #...` when the issue must remain open across slices.
- The `pr-gate` workflow enforces the Rust checks below on every pull
request; run them locally first.
- Use short imperative Conventional Commit subjects such as
- Discuss broad domain or architecture changes before writing a large patch.
- `Closes #...` means the PR satisfies the issue's acceptance criteria; use
`Refs #...` for a slice that leaves the issue open.
- Use short imperative Conventional Commit subjects, such as
`storage(backup): validate snapshot before fsync`.
- Security reports use private advisories per [SECURITY.md](SECURITY.md),
never public issues.
- Security reports use private advisories per [SECURITY.md](SECURITY.md).

## Engineering discipline

Engineer solutions, not band-aids. Heuristics, regexes, substring matching,
and silent defaults may aid diagnostics, discovery, or presentation; they may
not establish record integrity, authorization, retention, disposition, or
export behavior. Fix a defect found in scope, or file an exact-evidence issue
when it belongs elsewhere; do not silently route around it.

## Privacy and fixtures
Fix causes and prove the contract, including in-scope defects and duplicated
authority. File exact-evidence issues for separate work. Heuristics may assist
discovery or presentation; authorization, integrity, retention, disposition,
and exports require typed contracts. Investigate intermittent failures rather
than retrying until green.

Never submit real training records or operational material.
Keep modules focused on a domain capability. For Rust source files:

Examples, screenshots, tests, and seed data must use invented:
- Adding behavior to a file over 1,000 lines requires an ownership-based
reorganization in the same issue or plan. Thin dispatch, registration, and
re-export wiring may remain in a large hub.
- Before changing behavior in a file over 1,500 lines, name the ownership
boundary being preserved or improved.
- Files over 2,500 lines require a reviewed decomposition path before major
feature work unless the fix is urgent.
- Refactors name what moves, its new owner, persisted/public impact, and the
focused proof. Avoid unrelated rewrites.

- agencies;
- people and identifiers;
- incidents and addresses;
- narratives;
- schedules; and
- program content.
Decisions changing durable behavior get an ADR in `docs/decisions/`; changes
to `PRINCIPLES.md` require one. Schema changes use forward migrations. Portable
format changes update the specification, producer, verifier, and fixtures
together, with versioning governed by that format's contract.

Remove credentials and personal information from logs and bug reports.
## Build and verification

## Rust checks
Use the Rust toolchain pinned in `rust-toolchain.toml` and npm's committed
lockfile. The Vite 7 dependency declares Node.js `^20.19.0 || >=22.12.0`;
use a compatible supported Node.js release. Node.js is build-time only.

Once implementation begins, changes should pass:
From the repository root, run in this order:

```sh
(cd web && npm ci && npm run check && npm run build)
cargo fmt --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo build -p consolebook-server
(cd web && npx playwright install chromium && npm run e2e)
```

## Documentation
The explicit build supplies `target/debug/consolebook-server` for the browser
tests. The shared fixture starts a scratch installation per test on an
OS-assigned loopback port and waits for shutdown before deleting its data.
`npm run check` checks both Svelte code and browser-test TypeScript.
If a system Chromium is available, skip the browser download and run:

```sh
(cd web && CONSOLEBOOK_E2E_CHROMIUM=/path/to/chromium npm run e2e)
```

Linux browser dependencies can be installed with
`npx playwright install --with-deps chromium` from `web/`.
The [pr-gate workflow](.github/workflows/pr-gate.yml) runs the web, Rust, and
browser checks on pull requests. Focused local tests help development but do
not replace required gates. Preserve exact failure evidence and report only
commands actually run; an unexplained failure is not a reason to retry.

## Documentation and fixtures

State what is implemented, what is proposed, and what was verified. Link to
the owning specification or decision instead of duplicating it. Update the
roadmap when milestone state changes and the development map when ownership
moves. Do not put session transcripts, transient branch inventories, or
verification claims without a named revision into agent entrypoints.

State what is implemented, what is proposed, and what has been verified. A design document is not runtime proof, and a passing unit test is not recovery proof.
All fixtures, screenshots, examples, and seed data use invented agencies,
people, incidents, identifiers, narratives, and schedules. Real operational
material and credentials never enter the repository or public issue text.
Remove sensitive values from diagnostic output before sharing it.

## Licensing contributions

Consolebook is licensed under AGPL-3.0-only. By submitting a contribution, you agree to license it under the same terms. The project does not require a separate contributor license agreement or a broad relicensing grant.
Consolebook is licensed under AGPL-3.0-only. Contributions use the same terms.
The project requires neither a separate contributor license agreement nor a
broad relicensing grant.
Loading