---
id: PRD-0001
title: "M0 — Project Scaffolding & Hygiene"
status: done
owner: "Aaron Roney"
created: 2026-07-01
updated: 2026-07-01

principles:
- "Quality is the substrate: lints, tests, CI, and docs land before any feature code."
- "Single package: conclavelib (lib) + thin conclave (bin); modules mirror DESIGN §13."
- "Pinned nightly + edition 2024; house conventions copied from kord/razel/ratrod (DESIGN §22)."
- "cargo-make is the only entry point for dev commands; the canonical gate is ci = [fmt-check, clippy, test]."

references:
- name: "Conclave design doc (DESIGN.md §22 conventions, §13 components)"
  url: "docs/DESIGN.md"
- name: "ratrod (closest structural template — lib+thin-bin tokio service)"
  url: "https://github.com/twitchax/ratrod"
- name: "razel (test SOC, cargo-make ci gate, CI sharding)"
  url: "https://github.com/twitchax/razel"

acceptance_tests:
- id: uat-001
  name: "cargo make ci passes on the scaffold (fmt-check + clippy -D warnings + nextest)"
  command: cargo make ci
  uat_status: verified
- id: uat-002
  name: "conclave --help lists the subcommand skeleton (serve, bridge, register, machine, join, perm, key)"
  command: cargo run -- --help
  uat_status: verified
- id: uat-003
  name: "coverage builds and emits an lcov file"
  command: cargo make codecov
  uat_status: verified
- id: uat-004
  name: "the e2e harness spawns the built binary in a TempDir (placeholder e2e test passes)"
  command: cargo nextest run -E 'test(/e2e_/)'
  uat_status: verified

tasks:
- id: T-001
  title: "Cargo package: single package, lib conclavelib + bin conclave, edition 2024, resolver 2"
  priority: 1
  status: done
  notes: "[[package]] name=conclave-cli; [lib] name=conclavelib; [[bin]] name=conclave. rust-toolchain.toml pinned to a specific nightly date + components rustfmt,clippy. Baseline framework deps only (tokio, clap derive, tracing, tracing-subscriber, anyhow, thiserror); feature-specific deps (serde/bincode/ed25519/secrecy/surrealdb/axum/tungstenite/rustls) are added by the milestone that needs them."
- id: T-002
  title: "Cargo [lints] table + release/dev-release/profiling profiles"
  priority: 1
  status: done
  notes: "[lints] deny(unused, clippy::unwrap_used, clippy::correctness, clippy::complexity, clippy::pedantic) with narrow allows for macro-codegen noise only. Profiles per DESIGN §22 (release: opt-level=3,lto,codegen-units=1,strip; dev-release: fast-iter; profiling: debug=2,no-lto)."
- id: T-003
  title: "rustfmt.toml (canonical kord/ratrod settings)"
  priority: 2
  status: done
  notes: "max_width=200, struct_lit_width=40, reorder_impl_items=true, format_macro_bodies=false, format_code_in_doc_comments=true."
- id: T-004
  title: "Makefile.toml (cargo-make) with the full task graph + ci gate"
  priority: 1
  status: done
  notes: "fmt, fmt-check, clippy (--all-targets --all-features -- -D warnings), build/build-release/build-profiling, test (nextest)/test-cargo fallback, codecov/codecov-html (llvm-cov nextest --lcov), install-* via cargo binstall --no-confirm --locked, tools aggregate, ci=[fmt-check,clippy,test]. Every task workspace=false + explicit cwd."
- id: T-005
  title: "Module SOC stubs + type aliases + thin bin"
  priority: 1
  status: done
  notes: "conclavelib modules: base (Constant struct, Err/Res/Void aliases, domain types: paths, PermissionLevel, Visibility), protocol, identity, server, bridge (stubs with //! docs). bin: clap derive with the subcommand skeleton, tracing-subscriber init, dispatch. Compiles + clippy-clean with unimplemented!() bodies where needed."
- id: T-006
  title: ".config/nextest.toml (retries + serialized network-heavy group)"
  priority: 2
  status: done
  notes: "retries=2; [test-groups] network-heavy = { max-threads = 1 }; a slow-timeout default. Overrides added as network/e2e tests land."
- id: T-007
  title: "Test harness skeleton (unit/integration/e2e SOC)"
  priority: 2
  status: done
  notes: "tests/e2e.rs with a placeholder test that spawns env!(\"CARGO_BIN_EXE_conclave\") --help in a tempfile::TempDir; a pub mod tests helper factory in conclavelib for duplex/key fixtures; tests/fixtures/ dir. pretty_assertions dev-dep."
- id: T-008
  title: "CI workflows: build.yml + copilot-setup-steps.yml"
  priority: 1
  status: done
  notes: "build.yml jobs: lint (fmt-check + clippy), test (cargo make test), codecov (llvm-cov -> codecov-action@v5), platform builds gated to main (linux native; windows via cross; macos native). Preamble: checkout -> dtolnay/rust-toolchain (from toolchain file) -> Swatinem/rust-cache@v2 cache-all-crates -> cargo-bins/cargo-binstall@main -> cargo binstall cargo-make. copilot-setup-steps.yml bootstraps the agent env (one binstall line + cargo fetch)."
- id: T-009
  title: "Docs & release scaffolding"
  priority: 2
  status: done
  notes: "README.md (badge row + skeleton sections: Usage/Install/Protocol(mermaid placeholders)/Development/Architecture/License), CHANGELOG.md (Keep a Changelog) + cliff.toml (git-cliff), DEVELOPMENT.md, CLAUDE.md (conclave-specifics + defer to global constitution), MIT LICENSE."
- id: T-010
  title: ".gitignore + green pipeline verification"
  priority: 3
  status: done
  notes: "/target, coverage artifacts, /.surreal data dir, editor cruft. Then run cargo make ci locally and confirm all four UATs pass before closing M0."
---

# Summary

Stand up the `conclave` repository skeleton with every engineering convention (lints, formatting,
profiles, task runner, CI, test SOC, docs) already in place, so all subsequent feature milestones
(M1–M5) are built on a green, well-linted, well-tested substrate rather than retrofitting quality
later.

# Problem

Conclave is a from-scratch Rust project. If scaffolding and hygiene are deferred, feature code
accretes without lint discipline, a test harness, or CI, and retrofitting them later is expensive
and lossy. The design (DESIGN §22) already fixes the exact conventions to adopt from the sibling
repos; M0 materializes them once.

# Goals

1. A compiling single-package `conclavelib` + `conclave` skeleton with the DESIGN §13 module SOC.
2. Lints, `rustfmt`, profiles, and a `cargo-make` `ci` gate that fail the build on any warning.
3. A three-tier test harness (unit / integration / e2e-spawns-binary) wired to `nextest` + coverage.
4. CI (lint/test/codecov/platform) + the `copilot-setup-steps.yml` agent bootstrap.
5. Docs/release scaffolding (README, CHANGELOG+git-cliff, DEVELOPMENT, CLAUDE.md, MIT LICENSE).

# Technical Approach

Follow DESIGN §22 verbatim. Single Cargo package: crate `conclave-cli` publishing a library
(`conclavelib`) and a thin binary (`conclave`, `[[bin]] name = "conclave"`). Pinned nightly via
`rust-toolchain.toml`, edition 2024. Lints via the Cargo `[lints]` table (DRY across lib + bin).
`Makefile.toml` is the sole command surface; `ci = [fmt-check, clippy, test]` is the canonical
gate reused in CI. Module stubs (`base`, `protocol`, `identity`, `server`, `bridge`) carry `//!`
docs and the `Err`/`Res`/`Void` aliases + `Constant` struct so later milestones drop into a
known shape. The e2e harness spawns the real binary via `env!("CARGO_BIN_EXE_conclave")` in a
`TempDir`, and `.config/nextest.toml` pre-declares the `network-heavy` serialized group + retries
that the socket-based e2e tests in later milestones will need.

# Assumptions

- `cargo-binstall`, `cargo-make`, `cargo-nextest`, `cargo-llvm-cov` are available locally/in CI.
- A Codecov token exists for the `codecov` job (can be deferred; job is non-blocking until then).
- The chosen pinned nightly supports edition 2024 and `#[coverage(off)]`.

# Constraints

- No feature logic in M0 — stubs may use `unimplemented!()`, but the crate must compile and pass
  `cargo make ci` (clippy included) with only the narrow, justified `allow`s.
- Keep dependencies minimal; add feature-specific crates in the milestone that first needs them.

# References to Code

- `docs/DESIGN.md` §13 (components/module SOC), §22 (conventions), §21 (stack).
- Sibling repos for copyable patterns: `ratrod` (module layout, aliases, e2e harness),
  `razel` (`ci` gate, `.config/nextest.toml`, profiles), `kord` (`copilot-setup-steps.yml`, badges).

# Non-Goals (MVP)

- Any wire protocol, identity, server, or bridge logic (M1+).
- Publishing to crates.io / release automation beyond `cargo-release --no-publish` config.
- Multi-crate workspace split (single package for v1).

# History
(Entries appended during implementation go below this line.)

## 2026-07-01 — M0 executed (T-001…T-010)

Scaffold landed in a single focused pass, conventions copied from ratrod (module SOC, `Err`/`Res`/
`Void` aliases, `Constant`, e2e-spawns-binary harness, rustfmt), razel (`[lints]` set, profiles,
`.config/nextest.toml`, `cargo-make` `ci` gate, CI structure), and kord (`copilot-setup-steps.yml`,
README badge row). Toolchain pinned to `nightly-2025-12-22` (matches razel/kord), edition 2024.

All four UATs pass locally:

- **uat-001** `cargo make ci` — green (fmt-check + clippy `-D warnings` + nextest, 12 tests).
- **uat-002** `cargo run -- --help` — lists the full subcommand skeleton (serve, bridge, register,
  machine, join, perm, key, channel, acl, invite, who, kick, ban, user).
- **uat-003** `cargo make codecov` — emits `coverage.lcov`.
- **uat-004** `cargo nextest run -E 'test(/e2e_/)'` — the placeholder e2e spawns the built binary
  in a `TempDir`.

Notes / small deviations, none of which change the design:

- `codecov` / `codecov-html` cargo-make tasks carry `clear = true` to override cargo-make's
  predefined `codecov` task (the legacy bash uploader) — the same reason razel does.
- The always-compiled shared-fixture module is `conclavelib::tests`; its own unit tests live in an
  inner `self_tests` module (avoids `clippy::module_inception` with the file-level `tests` name).
- `thiserror` is present as a baseline dep per T-001; the typed boundary enums (`ProtocolError`,
  `AuthError`, `AclError`) it backs land with the wire/identity work in M1, so the non-`base`
  modules ship as `//!`-documented stubs for now.
- Logs go to stderr (conventional for a CLI; keeps stdout clean for data and makes the e2e
  unimplemented-command assertion robust).
