# ADR-0026: Runtime-mutable ACL default-fill (in-memory store, seeded from config) - **Status:** Accepted - **Date:** 2026-07-24 - **Deciders:** Respellion engineering - **Slice:** S-15b (#131), second of the S-15 (#16) split ## Context ADR-0003 made the ACL *default-fill* the ZGW-mandatory fields it stamps on every zaak, supplied as static configuration (`Acl:Defaults`, read once at startup as an immutable singleton). S-15b lets a beheerder **edit** those values from the portal and have the next zaak reflect them — so the defaults must become mutable at runtime. Two questions: **what** is editable, and **where** the mutable state lives. ## Decision **Make the three ZGW default-fill fields a runtime-mutable, in-memory store (`IDefaultFillStore`), seeded from `Acl:Defaults` at startup. The ACL reads it per zaak; the beheer `PUT /default-fill` replaces it.** ### Only the three ZGW fill fields are editable `Acl:Defaults` also carries the S-27 catalog-resolution keys (`ZaaktypeIdentificatie`, `InformatieobjecttypeOmschrijving`). Those feed the resolved-URL cache (`CachedZaaktypeCatalog`, ADR-0021); editing them at runtime would leave a stale cache and is catalogus *wiring*, not "default fill". So they **stay static config** and are out of scope for the CRUD. The editable set is exactly `Bronorganisatie`, `VerantwoordelijkeOrganisatie`, `Vertrouwelijkheidaanduiding` (`DefaultFillSettings`). ### In-memory, not persisted The store is a thread-safe in-memory singleton. **An edit is lost on restart**, when it reverts to the configured env. That is acceptable for this reference app: the slice demonstrates the *pattern* (beheer edits config that the ACL honours), not durable config management. The ACL stays stateless — no DB, no EF, no migration, no extra compose service. - ponytail ceiling: no persistence, no audit trail, no optimistic concurrency. - Upgrade path: back `IDefaultFillStore` with a DB (or an Objecten record) if durable, audited, multi-instance config is needed — the port stays the same. ## Consequences **Positive** - Demoable end to end (edit in portal → next zaak reflects it) with minimal moving parts. - The read path is per-zaak, so no restart and no cache concerns for the ZGW fields. **Negative / costs** - Edits don't survive a restart and aren't shared across replicas (single-instance assumption). Documented ceiling above. - Two sources of default config now (static keys on `AclDefaults`, mutable fields in the store) — a deliberate split by editability. ## Coupling rules touched (CLAUDE.md §8) None new. The BFF→ACL edge already exists (ADR-0025); this adds a read/write pair on it. The ACL remains the owner of the ZGW-facing config.