All checks were successful
CI / Auth e2e pack (pull_request) Successful in 8m34s
CI / Import/export fidelity gate (pull_request) Successful in 57s
CI / Lint, typecheck, test (pull_request) Successful in 6m19s
CI / Build container images (pull_request) Successful in 1m14s
CD / Build and push images (push) Successful in 17s
CD / Deploy to Test (push) Successful in 15s
CD / Smoke tests against Test (push) Successful in 1m16s
CD / Promote to Int (push) Successful in 12s
CI / Lint, typecheck, test (push) Successful in 6m25s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 8m24s
CI / Import/export fidelity gate (push) Successful in 59s
Stefan reviewed and accepted all nine VS-NfD ADRs one by one. Two adjustments from the review: ADR 0021 decision 3 now states the #216 refinement in the decision itself (PAT/feed-token issuance stays available to IdP-authenticated sessions — API authorization under its own switches, not interactive sign-in) instead of contradicting the later Decisions section; and the ADR 0020 dual-verify window will be removed early (issue #296) rather than waiting for its stated expiry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
3.4 KiB
3.4 KiB
ADR 0027: VS-NfD hardening-profile mode and configuration catalog
- Status: accepted (2026-07-31)
- Date: 2026-07-31
Context
The hardening guide (issue #227, docs/vs-nfd/50-haertungsleitfaden.md)
names a reference configuration for VS-NfD operation, but it is prose: the
application cannot answer whether the running configuration matches it,
and an operator flipping a switch in the admin UI gets no hint that the
choice leaves the profile. Requested by the operator (2026-07-30) as a
follow-up to the M24/M25 switches: the application itself should know
which options violate the profile — while deployments outside any VS
context stay entirely unaffected.
Decision
- A deploy-level mode, not a runtime setting.
VS_NFD_MODE(off | marked | hidden | enforced) is an environment variable, validated in the shared env schema and passed through compose — for the same reason asBACKUP_ALLOWED_TARGETS(#192, ADR 0026): a compromised Site-Admin account must not be able to widen it. The modes escalate:markedshows violations at the point of decision (#244),hiddenremoves violating options and marks the hiding (#245),enforcedadditionally rejects violating writes server-side (#246) — hiding alone is UI cosmetics a scripted client bypasses. offis the default. Outside a VS context the profile is not a topic: no marking, no card, no behavioural difference. Existing deployments upgrade without noticing the feature exists.- The machine-readable catalog is the single source of truth
(
packages/shared/src/vs-nfd-profile.ts): every profile-relevant setting with a decidable compliant value (a tiny predicate model — equals, upper bound, non-empty) and its hardening-guide section. Judgement-call entries ("only what the service needs") live in an explicit advisory list. A fence test (pattern of the audit-catalogue fence #201) parses the guide's reference tables and fails when a switch is neither in the catalog nor in the advisory list — the guide keeps its binding maintenance rule, the catalog can never silently lag. - Pond-level opt-ins are deliberately absent (
apiEnabled,mcpEnabled): their instance master switches govern; a pond opt-in under a compliant master switch cannot violate the profile on its own. The evaluation and enforcement paths are scope-generic, so pond entries can be added if that judgement changes. - Exposure first (#243): the api evaluates the catalog against the
typed settings registry and the validated env and reports mode +
verdict on
GET /admin/system/vs-nfd-profile; the admin settings view shows the card whenever the mode is notoff. The three treatments build on exactly this evaluation.
Consequences
- The guide gains a second consumer: every new switch line must be triaged (catalog or advisory) or CI fails — a deliberate speed bump, same trade-off as the audit-catalogue fence.
- Deploy-level means changing the mode requires a deployment change and an api restart; that is the point (role separation, operations handbook §6).
- The verdict describes decidable entries only; advisory entries remain an assessor's reading of the guide. The card says what deviates, the guide says why it matters.
Implementing issues
#243 (mode, catalog, fence, exposure), #244 (marked), #245 (hidden),
#246 (enforced).