Spec Maintenance
The spec is both human-facing architecture documentation and agent-facing navigation. Keep it organized by ownership so a reader can start from the source package and follow links only when behavior crosses package boundaries.
Where New Docs Belong
| Change area | Documentation home |
|---|---|
| Single package behavior | spec/src/20-packages/<package>/ |
| Single plugin behavior | spec/src/20-packages/plugins/<plugin>/ |
| Package-local current functionality | packages/<package>/spec.md or packages/plugins/<plugin>/spec.md |
| Shared runtime contracts | spec/src/30-cross-package-contracts/ |
| System shape, boot flow, host targets | spec/src/10-architecture/ |
| Public site legal or policy pages | packages/lapis.md/src/pages/ plus the lapis.md package spec |
| Test strategy and workflows | spec/src/40-testing/ |
| Release readiness and milestone scope | spec/src/50-roadmap/ |
| Accepted architectural decisions | spec/src/90-decisions/ |
| Durable unimplemented tasks | owning package, contract, roadmap, or ADR page |
| Temporary implementation plans | spec/working/active-plans/ |
If a change touches multiple packages, document each package-owned responsibility on the package page and put the shared rule in a cross-package contract. Avoid duplicating the same contract in several package pages.
Package-local spec.md files are concise current-functionality mirrors for people and agents working inside a package directory. Keep them aligned with the rendered package page, but keep detailed cross-package contracts and ADR context in spec/src/.
Required Navigation Updates
Every rendered spec page must be linked from SUMMARY.md. When adding, moving, or deleting pages, update that file in the same change and run mdbook build spec when practical.
Markdown Linting
Run make spec-lint from the repo root, or make lint from inside spec/, after every update under spec/. Use make spec-lint-fix from the root, or make lint-fix from inside spec/, to apply markdownlint fixes automatically, then rerun the lint target.
markdownlint-cli2 reads the root .markdownlint-cli2.jsonc file. That config lints spec/**/*.md and packages/**/spec.md, excludes the generated mdBook output, and excludes temporary active-plan markdown files under spec/working/active-plans/.
Durable State Versus Temporary State
Durable implementation truth belongs in spec/src/. Temporary checklists, blockers, handoff notes, and in-progress implementation state belong in spec/working/active-plans/ and should be deleted when the task is complete.
Durable Follow-Up Tracking
When a spec page mentions behavior that is planned, pending, missing, or not implemented, keep the detailed context in the package, contract, ADR, roadmap, or parity page that owns the behavior. Use stable task IDs only when they still help connect related pages.
Use spec/working/active-plans/ only for short-lived execution state while a task is active. When the implementation lands, update the owning spec page and remove the temporary active plan.
ADRs
Use an ADR when the codebase accepts a direction that changes package boundaries, host strategy, data ownership, plugin contracts, persistence shape, or long-term testing expectations. Keep implementation pages accurate about current code and link to ADRs for accepted future direction.