novolis-governance / architectural-ideals/README.md
Architectural ideals
Policies that keep the org coherent
dotnetgovernancenovolis
| Ideal | Topic |
|---|---|
| [hexgame-authoritative-core.md](./hexgame-authoritative-core.html) | HexGame-shaped game loops on Novolis (Tick in Simulation/apps; Physics as callee) |
| [workspace-snapshot-timeline.md](./workspace-snapshot-timeline.html) | Editor workspaces, snapshots, and branchable timelines |
| [distributed-services-architectural-guideline.md](./distributed-services-architectural-guideline.html) | Distributed services structure and conformance |
Distributed Services Architectural Guideline
This guideline defines how Novolis distributed services are structured, bounded, and evolved. It applies to multi-project service repositories that expose APIs or workers, persist operational state, and communicate through typed clients and transport contracts.
Assumptions: Services run behind platform routing (proxy, ingress, or container host). Each service owns isolated data stores (which may be tables in a shared database); no service mutates another service’s persistence directly.
Document map
| Section | Topic |
|---|---|
| [1. Introduction](./distributed-services-architectural-guideline.html#1-introduction) | Purpose, scope, assumptions, non-goals |
| [2. Foundational principles](./distributed-services-architectural-guideline.html#2-foundational-principles) | System of record, data ownership, semantics, contracts |
| [3. Service package structure](./distributed-services-architectural-guideline.html#3-service-package-structure) | Assembly roles and responsibilities |
| [4. Dependency and boundary rules](./distributed-services-architectural-guideline.html#4-dependency-and-boundary-rules) | In-repo and cross-repo references |
| [5. Data access and persistence](./distributed-services-architectural-guideline.html#5-data-access-and-persistence) | EF Core usage, repositories, wrappers |
| [6. Mutation, consistency, and side effects](./distributed-services-architectural-guideline.html#6-mutation-consistency-and-side-effects) | Writes, transactions, interceptors |
| [7. Query safety and policy enforcement](./distributed-services-architectural-guideline.html#7-query-safety-and-policy-enforcement) | Mechanical enforcement, multi-tenancy |
| [8. Application structure](./distributed-services-architectural-guideline.html#8-application-structure) | Models, use cases, vertical slices |
| [9. Evolution and modernization](./distributed-services-architectural-guideline.html#9-evolution-and-modernization) | Incremental change without wholesale rewrites |
| [10. Conformance criteria](./distributed-services-architectural-guideline.html#10-conformance-criteria) | How implementations are evaluated |
| [11. Inter-service integration](./distributed-services-architectural-guideline.html#11-inter-service-integration) | Contracts, no shared persistence, async |
| [Appendix A](./distributed-services-architectural-guideline.html#appendix-a-reference-implementations) | Template alignment status |
The normative specification is [distributed-services-architectural-guideline.md](./distributed-services-architectural-guideline.html).
Summary principles
- Optimize for operational correctness, clarity, and maintainability over theoretical purity.
- Patterns are optional tools; every abstraction must deliver measurable value.
- Each service owns isolated data stores; shared databases are allowed if write boundaries are clear.
- Never mutate another service’s persistence—integrate via public contracts (
.Client/ API / agreed messaging). - Services assume platform routing; callers use capabilities, not hard-coded public URLs.
- Persistence entities represent storage truth; business meaning is contextual and may be projected.
.Modelspackages are public transport contracts only and must not leak inward.DbContextis permitted when it is the clearest, safest choice; see bulk-update rules in §6.2.- Thin wrappers over
DbContextorDbSet<>that add no policy or behavior are prohibited. - Repositories and application services are justified when they centralize policy, orchestration, or safety.
- Prefer explicit, atomic, idempotent database operations with intentional interceptor behavior.
- Enforce critical invariants mechanically (analyzers, filters, interceptors, tests); apply tenant filters by default.
- Organize code by feature and use case, not by technical category alone.
- Mixed styles may coexist when each is purposeful; simple operations stay simple.
- Cross-repo dependencies use published NuGet packages per nuget-only policy—not sibling
ProjectReference. - Resilience playbooks (chaos, circuit breakers) are out of scope; client retry and idempotent writes are in scope.
- Conformance is judged by operational outcomes and comprehension, not layer count.