# Contributing to Constellate
Thanks for helping shape Constellate. This guide explains how to set up your workspace, the guard rails we enforce in the CLI/template stack, and how to document changes in the sample portal.
## Local Environment
- Install Rust 1.76+ with `cargo`. Nix users can enter the curated shell via `nix-shell nix/shell.nix`.
- Clone the repository and run `cargo fetch` once to prime dependencies so `constellate build`/`serve` start instantly.
- Optional: install the Codex helper (`.codex/skills/constellate`) to streamline task/document scaffolding.
## Development Workflow
```bash
nix-shell nix/shell.nix # optional reproducible toolchain
cargo fmt # format every change set
cargo clippy --all-targets --all-features # lint with the same flags CI uses
cargo test # unit helpers live in src/main.rs
constellate init --workspace workspace # scaffold a sample workspace if needed
constellate build --input workspace --output workspace/dist
constellate serve --input workspace --output workspace/dist --port 8080
constellate new --workspace workspace adr "Switch templating"
constellate status task TASK-001 done "Ready for QA" --workspace workspace
```
## Template Guard Rails
- Default HTML lives under `templates/default/` and is embedded via `include_str!`; never paste raw HTML into `.rs`/`.toml` sources (tests are exempt). Run `rg '<[^>]*>' src --glob '!**/tests/**'` before sending a patch.
- Use `constellate theme export [subset]` to copy templates into `workspace/templates/` while iterating. Keep overrides synchronized with the embedded tree so downstream workspaces can cherry-pick file-level overrides.
- Runtime-only markup goes in `templates/default/partials/...`; test fixtures belong under `templates/internal/` so they can be `include_str!`-ed without violating the "no inline HTML" rule.
- Renderer migration efforts (TASK-039/040/041) track document, navigation/overview, and manifest/icon workâkeep contributions scoped accordingly.
## Portal Feature Invariants
- Metadata pipelines must continue to render `<type> / <id>` beneath the document chip, keep status/owner data in the rail, and list all remaining attributes in the footer.
- Navigation options (`tabs`, `sidebar`, `collections`, pager settings) must respect `[theme.navigation.*]`.
- Search overlay behavior (Ctrl+K shortcut, `assets/search-index.json` fetch, SearchEntry serialization, keyboard navigation) should not regress.
- The serve watcher must reload configs, retry on transient IO errors, and rebuild with fresh settings after every save.
## Documentation & Workspace Updates
- Workspace markdown under `workspace/pages/**` doubles as user documentation. Every change should be reflected via `constellate new --workspace workspace task "<title>"` (or `adr`/`doc` as appropriate) rather than hand-writing files.
- Populate task metadata (`created`, `done`, `status`, `links`) using `date +%Y-%m-%d` for timestamps and cross-link relevant requirements/ADRs.
- After editing documents, run `constellate build --input workspace --output workspace/dist` so the sample portal stays current.
## Testing & Review Checklist
- Always run `cargo fmt` and `cargo clippy --all-targets --all-features` before opening a PR. Add targeted unit tests under `src/main.rs` adjacent to the helpers being touched.
- When touching config parsing or path normalization logic, extend the watcher/unit tests at the bottom of `src/main.rs`.
- If you introduce new template context data, update `SearchEntry`, `write_search_index`, and any JS consumers plus `templates/default/partials/...` that render the values.
- Keep diffs scoped: add new helper functions rather than duplicating logic, and include a brief doc comment for each function explaining intent per the repository guidelines.
## Additional References
- `workspace/pages/docs/templates/` documents template context contracts; update those pages whenever the frontend data model changes.