Skip to content

fix(config): report declared restart semantics in config-reference.md - #816

Merged
ericfitz merged 3 commits into
mainfrom
dev/1.9.1/config-spec-amendment
Aug 23, 2026
Merged

fix(config): report declared restart semantics in config-reference.md#816
ericfitz merged 3 commits into
mainfrom
dev/1.9.1/config-spec-amendment

Conversation

@ericfitz

Copy link
Copy Markdown
Owner

What

Two things, both following from the Phase A registry consolidation in #812.

1. config-reference.md reported every operational setting as hot-reloadable

The table printed hot for all 70 operational rows — not "mostly hot",
literally every one.

GenerateReferenceMarkdown reads GetMigratableSettings(), which assigns
Class via classificationFor(key). That path does not carry the per-entry
withMutability(...) overrides the Phase A audit set by reading each setting's
consuming code, so operationalRow was rendering the pre-audit default rather
than the declared value.

operationalRow now resolves Mutability from the registry via DefFor(key),
falling back to the projected value for generated provider keys that have no
def. The regenerated table reads 66 static / 4 hot.

The lookup is deliberately confined to the documentation generator.
GetMigratableSettings()'s observable output is untouched — making
classificationFor() itself consult the registry stays Phase E work per
Ruling 15, because it would also change seeded-vs-explicit classification and
the origin backfill that derives from the same set.

2. Spec §1 amended to the measured reality

docs/superpowers/specs/2026-08-22-config-model-redesign-design.md §1 was
written assuming operational settings are runtime-editable with
restart-required as the declared exception. Phase A measured the opposite:
roughly 89 Static to 11 Hot.

The amendment states that plainly, records the traced case
(features.saml_enabledNewService builds the SAML manager only when the
boot flag is true, so flipping the row at runtime changes nothing until a
restart), and is explicit about scope:

  • It does not invalidate the design; declaring restart semantics honestly is
    the point of promoting Mutability.
  • It does not change Phases C-E, whose mechanism already restarts at each
    step.
  • It does retire the informal claim that moving a setting to the database
    lets admins edit it live. True for ~11 settings, not the rest. The honest
    benefit is one source of truth, one delivery path, and a reproducible
    per-environment template.

Guardrail, watched to fail

Per the rule #812 established — a guardrail nobody has watched fail is not
evidence. Reverting declaredMutability to the projected value produces:

every operational row reports hot (70 rows) — the generator is rendering the
projected classification instead of the registry declaration; see declaredMutability
expected static to dominate per the registry audit, got static=0 hot=70
features.saml_enabled row does not report static: | `features.saml_enabled` | ... | hot | ...

Restored, it passes.

Noted, not fixed here

The reference lists 70 rows against ~100 operational settings, because the
generator reads the same OmitWhenEmpty-filtered projection that #810 reports.
Called out in the amendment; #810 owns the fix.

Gates

  • make lint — 0 issues
  • make build-server — clean
  • make test-unit2744 passed, 0 failed (2743 + the new guardrail)
  • SEM markers refreshed for reference_gen.go
  • No DB-touching code (documentation generation only), so no Oracle review

ericfitz and others added 3 commits August 22, 2026 23:18
The reference table printed "hot" for all 70 operational rows. Its source,
GetMigratableSettings(), assigns Class via classificationFor(key), which does
not carry the per-entry withMutability(...) overrides the registry audit set by
reading each setting's consuming code — so the column reported the pre-audit
default rather than the declared value.

operationalRow now resolves Mutability from the registry def via DefFor(key),
falling back to the projected value for generated provider keys that have no
def. The lookup is confined to the documentation generator, leaving
GetMigratableSettings()'s observable output untouched; making
classificationFor() itself consult the registry stays Phase E work per
Ruling 15.

The regenerated table reads 66 static / 4 hot.

Also amends §1 of the config model redesign design to the measured reality.
The spec was written assuming operational settings are runtime-editable with
restart-required as the declared exception; Phase A measured roughly 89 Static
to 11 Hot. That does not invalidate the design or change Phases C-E, whose
mechanism already restarts at each step, but it does retire the informal claim
that moving a setting to the database lets admins edit it live — true for about
eleven settings, not the rest. The honest benefit is one source of truth, one
delivery path, and a reproducible per-environment template.

The new guardrail was watched to fail: reverting declaredMutability to the
projected value makes it report 0 static rows and name declaredMutability in
the failure message.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FanMDLkRXPQEGY73Z4EsSL
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FanMDLkRXPQEGY73Z4EsSL
@ericfitz
ericfitz merged commit 93c6cb0 into main Aug 23, 2026
15 checks passed
@ericfitz
ericfitz deleted the dev/1.9.1/config-spec-amendment branch August 23, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant