Developer Guide¶
5-Spot is built ADR-first. Architecture is decided, recorded and visualized before code is written, and the decision record is a first-class deliverable — equal in importance to the code and the tests. If you are about to change anything architecturally significant, start here rather than in an editor.
Architecture Driven Development¶
The order is fixed. Each step has an artifact and a gate:
| Step | Produces | Lives in | Gate |
|---|---|---|---|
| 1 · ADR | The decision, with the alternatives you rejected | docs/adr/NNNN-title.md |
Status / Context / Decision / Consequences, and a row in the ADR index |
| 2 · CALM | Nodes, relationships, interfaces, flows | docs/architecture/calm/architecture.json |
make calm-validate, then make calm-diagrams renders into System and Flows |
| 3 · TDD | A failing test that defines the behaviour | src/foo_tests.rs beside src/foo.rs |
The test fails for the right reason before any implementation exists |
| 4 · Implement | The minimum code that passes | src/ |
cargo fmt, clippy and the full test suite, all clean |
| 5 · Docs | Changelog entry, affected guides, roadmap status | .claude/CHANGELOG.md, docs/src/, ROADMAPS.md |
Docs match the code; a roadmap row reflects reality, not intent |
| 6 · Threat model | A full pass over every section, and a bumped stamp | docs/src/security/threat-model.md |
The Covers ADR range names this ADR. "No change" is a conclusion, not a skip — the stamp still moves |
An ADR is not done until the threat-model pass has run — it is the last step, not an afterthought. A change that is not reflected in CALM is not designed yet. A CRD shape change
starts in src/crd.rs — the source of truth — and regenerates with make crds
then make crddoc; the YAML under deploy/crds/ is generated and never
hand-edited.
When does it apply?¶
Full ADR + CALM — new CRDs or CRD fields that change a contract; new controllers, reconcilers or binaries; changes to the CAPI interaction (Machine, bootstrap or infrastructure contract, allowed API groups); deploy, admission or GitOps topology; and cross-cutting concerns such as security boundaries, RBAC posture, failure domains or scheduling semantics.
ADR only, no CALM — process and policy decisions that change no system topology: methodology, CI policy, repository conventions. Say so explicitly in the ADR's Consequences.
Neither — typos, comment tweaks, formatting, isolated bug fixes with no architectural impact, and mechanical refactors that preserve behaviour. These still follow TDD.
When you are unsure whether a change is architectural, write the ADR. A short, slightly redundant ADR costs little. An undocumented architectural decision costs the next person a re-derivation.
The decision log¶
ADRs are never rewritten. A decision that no longer holds is marked
Superseded and links forward to the one that replaced it, so the log reads as
a history rather than a snapshot — check the Status line before you rely on
one. The canonical index is
docs/adr/README.md;
the table below is a convenience copy.
| ADR | Decision | Status |
|---|---|---|
| 0001 | Adopt Architecture Driven Development | Accepted |
| 0002 | Kata config delivery via spec.kata, resolved in the workload cluster |
Accepted |
| 0003 | In-pod host k0s-service restart via nsenter |
Accepted |
| 0004 | Agent pod-security exception boundary, deny-by-default | Accepted |
| 0005 | Remove spec.kata.destPath; fix the host path |
Accepted |
| 0006 | Pluggable spot-schedule provider contract | Accepted |
| 0007 | CRD multi-version support, additive-only evolution | Accepted |
| 0008 | Auto-VEX signed off before submission, enforced in CI | Accepted |
| 0009 | Unify activation under spec.schedule as a provider reference |
Accepted |
| 0010 | Base-image digests pinned on the FROM line |
Accepted |
| 0011 | Schedule-gated capacity in its own controller, scaling rather than creating | Accepted |
| 0012 | The kata-config agent validates its own Node annotation; the restart argv terminates options | Accepted |
| 0013 | The kata-config-ref Node annotation is controller-writable only, enforced at admission |
Accepted |
| 0014 | Drive capacity to zero on a host-governance conflict | Accepted |
| 0015 | Internalize a dependency when its used surface is 500 lines or less | Accepted |
Start with 0001 for the methodology, 0006 and 0009 for how activation works, 0007 before touching a CRD, and 0004 before deploying into a cluster with a pod-security baseline.
Where to go next¶
- Development Setup — toolchain,
cross, a local cluster - Building — binaries, images, the pinned base images
- Testing — the TDD file pattern and how to run the suite
- Contributing — sign-off, commit conventions, review
- Threat Model — what is defended, from whom, and with which control in which file. Read it before changing RBAC, admission policy or anything the node-side agents touch.