Skip to content

Admin Settings: enforce the form field contract before stage D moves cards - #1306

Merged
Paul Lizer (paullizer) merged 2 commits into
microsoft:feature/admin-settings-iafrom
paullizer:admin-ia-field-contract
Aug 19, 2026
Merged

Admin Settings: enforce the form field contract before stage D moves cards#1306
Paul Lizer (paullizer) merged 2 commits into
microsoft:feature/admin-settings-iafrom
paullizer:admin-ia-field-contract

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Groundwork before stage D moves any cards. Targets the feature/admin-settings-ia staging branch.

Why now

Admin Settings submits one form, and the backend reads every value by field name. That makes the set of name attributes the real contract between the template and route_frontend_admin_settings.py.

Renaming or dropping one is uniquely nasty: no error is raised, the control still renders, the form still submits — the value just never arrives. Nothing fails until someone notices a setting stopped sticking.

Every stage of this rework has been verified against a field-name fingerprint, and it has caught nothing so far because the moves have been careful. But that check lived in a scratch script that only ran when I remembered to run it. Stage D moves 96 cards between tabs, which is exactly when an accidental rename is most likely and least visible.

So the check becomes a test, with the baseline committed beside it.

What it enforces

1. No field may silently disappear. Every name in the baseline must still exist.

Adding settings is unaffected — new names are reported, not failed. Removing or renaming one requires regenerating the baseline in the same commit:

python functional_tests/test_admin_settings_field_contract.py --update-baseline

That turns a silent loss into a visible, reviewed decision.

2. No unexpected duplicate names. Two controls sharing a name submit the value twice. Five legitimate radio/checkbox groups are recorded as allowed; anything else fails.

This is the property the Access and Roles roster in stage E depends on — it mirrors 10 require_member_of_* toggles, and those mirrors must carry no name attribute. This test is what stops that going wrong.

Both assertions were verified to actually fail

A test that never fails is worthless, so I checked each one against a deliberately broken template:

Simulated break Result
Renamed enable_conversation_archiving Failed, naming the exact missing field
Duplicated enable_user_feedback Failed, reporting enable_user_feedback x2

Both pass again once reverted.

Baseline

451 literal field names, 5 known groups. Jinja-templated names are excluded, since they can't be compared literally.

Also included: status and handoff doc

docs/explanation/features/ADMIN_SETTINGS_IA_REWORK_STATUS.md

This rework spans several PRs into a staging branch, and the context needed to continue it safely has been living in conversation history rather than the repo. The doc records:

  • what has shipped across stages 1, A and B
  • how to run each guardrail, and the regression baseline of 33 pre-existing failures that must not change
  • the three structural complications found while splitting the template — interleaved modals, three nested cards, and the ~985-line Data Management migration block
  • the locked decisions (D1–D5, Q2)
  • the CI branch filters that must be reverted before the staging branch merges into Development

That last one is easy to forget and would otherwise leave Development's CI config permanently altered.

Verification

  • Field names and card ids unchanged: 462 names, 110 card ids
  • 75 functional test files covering admin_settings.html: 33 pre-existing failures before and after, identical sets
  • Both new assertions verified to fail correctly and pass when restored

Version 0.260.009. No application behaviour changes in this PR — it is a test, a fixture, and a document.

Paul Lizer (paullizer) and others added 2 commits August 19, 2026 14:16
Admin Settings submits a single form and the backend reads every value by
field name, so the set of name attributes is the real contract between the
template and route_frontend_admin_settings.py. Renaming or dropping one
silently stops that setting from saving: no error is raised, the control still
renders, and the value simply never arrives.

Every stage of the information architecture rework has been verified against a
field-name fingerprint, but that check lived in a scratch script and only ran
when someone remembered to run it. Stage D moves 96 cards between tabs, which
is exactly when an accidental rename is most likely and least visible.

The check is now a functional test with the baseline committed alongside it, so
it runs in CI on every commit and protects anyone editing these templates
later, not just this migration.

Adding settings is unaffected: new field names are reported, not failed.
Removing or renaming one requires regenerating the baseline in the same commit
via --update-baseline, which turns a silent loss into a reviewed decision.

The test also rejects duplicate field names outside the five known radio and
checkbox groups. That is the property that stops a mirrored control from
submitting its value twice, which the Access and Roles roster in stage E
depends on.

Both assertions were verified to fail correctly: renaming a field is reported
by name, and introducing a duplicate is reported with its count.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The rework spans several pull requests into a staging branch, and the context
needed to continue it safely has been living in conversation history and in
scratch scripts rather than in the repository.

Records what has shipped, how to run each guardrail, the regression baseline of
33 pre-existing failures, the three structural complications found while
splitting the template, the locked decisions, and the CI branch filters that
must be reverted before the staging branch merges into Development.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paullizer
Paul Lizer (paullizer) merged commit 2422d86 into microsoft:feature/admin-settings-ia Aug 19, 2026
11 checks passed
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