Skip to content

Architecture Decision Records

Architecture Decision Records (ADRs) document the significant architectural choices made across our projects. Each record captures the context, options considered, the decision, and its consequences.

Why We Write These

When you join a project or review a pull request, you often ask "why is it done this way?" These records answer that question. They capture not just what was decided, but why — including what we considered and rejected.

How to Read an ADR

Each ADR follows the same structure:

  • StatusProposed (under discussion), Accepted (implemented or being implemented), Superseded (replaced by a newer decision)
  • Context — The problem or situation that prompted the decision
  • Options Considered — Alternatives we evaluated, with reasons for rejection
  • Decision — What we chose and how it works
  • Consequences — The trade-offs we accepted, both positive and negative

Decision Index

Kendo

#DecisionStatusSummary
1Audit Logging SystemAcceptedPer-entity audit tables with hash chains for ISO 27001 compliance
6Two-Tier AuthorizationAcceptedRoute-level model permissions + action-level interaction permissions
3AI Interaction LoggingAcceptedThree-channel logging for outbound AI calls, MCP tools, and AI runs
8Multi-TenancyAcceptedDIY database-per-tenant for 3 fixed companies
13Adapter-Store PatternAcceptedCustom reactive store factory over Pinia for 15+ domain stores
25GitHub Integration SplitAcceptedSplit GithubService into OAuth handshake + bearer-token-parametrized API client; per-call token argument

Brick Inventory

#DecisionStatusSummary
4Import AtomicityAcceptedSave-what-you-can with honest reporting for API imports

Emmie

#DecisionStatusSummary
22Schedule End Date InclusiveAcceptedSchedule.end_date is the last active day; canonical predicates use inclusive <= / >=
23Schedule Mutation ChokepointAcceptedSingle Action owns Schedule date mutation; wrapping normalizer, schema unchanged
31Datetime Instant-vs-Wall-Clock ClassificationAcceptedEvery datetime field declared instant or wall-clock; wall-clock serialized naive (self-describing wire); backend WallClock* casts + arch test, frontend Temporal helper (polyfilled)

Town-crier

#DecisionStatusSummary
36Cross-Harness Producer IngressAcceptedOne bus-hosted GitHub App replaces 14 per-repo announce-pr.yml; HMAC-verified pull_request/pull_request_review ingress dispatching in-process to announce/resolve/consensus with the internally-minted github-action identity; first bus outbound HTTP (timeout-bound, installation_id-keyed token cache); pull-first /github/health observability for the silent per-org failure mode

Cross-Project

#DecisionStatusSummary
2Cascade Deletion & Soft DeletesAcceptedModel declares, Action executes, tests verify. No ON DELETE CASCADE.
9Unified ResourceData PatternAccepted (amended 2026-07-03)Custom ResourceData base class replaces Laravel's JsonResource; loud-failure eager-load gate + Hydrator supply side
11Action Class ArchitectureAcceptedfinal readonly Actions with single execute() method, explicit DI
12FormRequest → DTO FlowAcceptedType-safe pipeline from HTTP validation to business logic
14Domain-Driven Frontend StructureAcceptedVertical slices by business domain, not technical layers
16Config Attribute InjectionAccepted#[Config] attribute for all config access, config() helper prohibited
17Page Integration TestsAcceptedMount domain pages with real components, mocked services, separate coverage accounting
19Explicit Model HydrationAcceptedBan $fillable/$guarded, require explicit property assignment in Actions
15ADR GovernanceAcceptedSingle source of truth at adrs.script.nl
18ISMS Information SystemAcceptedLaravel + Vue ISMS with policies as markdown, operational data in PostgreSQL
20Input/Result DTO SplitAcceptedSplit DTOs by usage direction at the Action boundary — arch tests enforce
21PHPStan Rules PackageAcceptedCanonical war-room PHPStan rules distributed as script-development/phpstan-warroom-rules Composer package
24Automated External ProvisioningAccepted (amended 2026-05-20)Async + provider-abstracted + rollback-on-failure + audit-mandatory + flag-gated for tenant-resource provisioning
26Decrement Action SymmetryAcceptedCaller-side symmetry discipline + Pest arch test for counter-mutation decrement Actions; no internal floor guard at Action layer
27Canonical Territory SkeletonAcceptedBIO-aligned baseline + Audit/ for app/; Architecture/ for tests; apps/<role>/ + shared/ for frontend; trip-point arch tests from day 1
28Canonical Git Hooks (v1)AcceptedPlain core.hooksPath + .githooks/ shell scripts; fast pre-commit + heavy pre-push; per-territory copy from /templates/githooks/; lefthook + distributed package as documented future iterations
29Audit Row Durability ContractAcceptedAudited Actions' DB::transaction(...) closure contains only DB writes; throws exit via sentinel-return; non-transactional state mutates post-commit
32Cached-Store Hash-Bumping ProtocolAcceptedSubscribe-via-header: SPA declares cached keys per request; middleware authorizes (per-key Tier-1 policy) + stamps the entitled subset, one-resolve-per-distinct-parent (N+1 arch-tested)
33AVG Erasure by Anonymization-in-PlaceAcceptedErasure = anonymize-in-place (not hard-delete): per-column scrub contract across the user aggregate + framework tables, S3 delete, emmie revoke-only + OpenAI persist-then-delete residuals, audit-trail identity-PII accepted as lawful record; completeness Feature+arch tests
34Ambulatory Financing Care-Type / Rate-Interval CouplingAcceptedEmmie territory-specific: ambulatory registration ↔ AMBULATORY financing ↔ HOUR/MINUTE interval three-way coupling; interval-keyed Invariant A (revenue correctness) enforced at the registration chokepoint + arch test; care-type-keyed Invariant B (hygiene) held for prod breach-check
35Appointment-Slot Inverted-Window DB CHECK BackstopAcceptedwijs territory-specific: end_date >= start_date enforced by a DB CHECK on appointment_slots (MySQL 8.0.45) as a write-path-agnostic Level-1 backstop below the shipped Action/validation guards; two-step clean-then-constrain (repoint 9 cancelled-appointment occupations → delete 576 inverted rows → ADD CHECK)

Architecture documentation for contributors and collaborators.