The code-level engineering canon. Markdown only, no scripts – consulted, not invoked. Workflow skills cite it; agents and humans read it. Larger scopes live in the sibling skills architectural-design-principles (system-level) and ui-ux-design-principles (experience-level).
Architectural concerns mapping (mandatory before promote/merge)
Fill this in for any non-trivial change before calling the design done. An unfilled row, or a concern with no clear owner, is a design smell – resolve it before merging.
| Concern | Layer | Owner module | Cross-cutting? |
|---|---|---|---|
| Authentication | HTTP / boundary | <module> |
Yes |
| Authorization | Service | <module> |
Yes |
| Capability resolution | Service | <module> |
Yes |
| Audit logging | Cross-cutting | <module> |
Yes |
| Rate limiting | HTTP / boundary | <module> |
Yes |
| Schema validation | HTTP / boundary | <module> |
Yes |
| Policy config | Service / config | <module> |
Yes |
| Domain logic | Service | <module> |
No |
| Storage | Infrastructure | <module> |
No |
References
- SOLID – the five object-design rules.
- DRY – one home for each piece of logic.
- Clean code – naming, function shape, comments, error boundaries.
- Cross-cutting concerns – which layer owns auth, authz, capability resolution, audit, rate limiting, schema, policy.
- NFRs – performance, scalability, security, observability, operability, resilience.
Layered architecture lives in the architectural skill (reference).
Hard rules
- Names carry the design. If a fresh reader can't infer the concept from the name, rename it before the next test.
- Layers depend inward. HTTP -> service -> infrastructure, never the reverse.
- One owner per cross-cutting concern. Overlapping auth/audit logic in two modules is a smell: one owns it, the rest delegate.
- No duplicated logic. Before writing a block, look for an existing copy and extract one shared helper; fix every call site of a bug together.
- NFR baseline before done. Skim performance / scalability / security / observability / operability / resilience.
- Public boundary tests, private refactors. A correct refactor never changes the outer-boundary tests.
- No import-time coupling to an optional build artifact. A module must import in every environment it ships to. An unconditional
StaticFilesmount / asset read at import scope greens where the artifact exists and crashes everywhere it does not (backend-only tests, CI before the client build, fresh clones). Mount/read it only when present; degrade clearly (a 503 "not built") when absent. Theimport-time-build-couplingsmell, enforced bylakebase-tdd-imports-clean.
Composition
lakebase-tdd-workflows– Architect Reviewer imports this in per-story review; Navigator in PLAN; Driver in REFACTOR.lakebase-scm-workflows– PRs reviewed against the layered-architecture + cross-cutting checks.lakebase-release-workflows– the NFR baseline is the release gate.