Skip to content

§25: navigation contract drift gate + route-guard truth-up - #63

Merged
ivanball merged 4 commits into
mainfrom
feat/s25-navigation-drift-gate
Jul 16, 2026
Merged

§25: navigation contract drift gate + route-guard truth-up#63
ivanball merged 4 commits into
mainfrom
feat/s25-navigation-drift-gate

Conversation

@ivanball

Copy link
Copy Markdown
Owner

Summary

Ships the #25 maturity lever (the scorecard's stated gap: "NavigationFlow.md has no drift gate, Routes.razor auth wiring untested"):

  • NavigationContractTests (arch tier, CI merge gate): reflects every RouteAttribute component in MMCA.Common.UI and asserts NavigationFlow.md's routes table matches reality exactly: no undocumented routes, no phantom rows, and the documented auth posture (Anonymous/Any vs Authenticated) must match the presence of [Authorize] on the page. 8-route non-vacuity floor; the doc rides as an embedded resource.

The gate immediately surfaced three real drifts, fixed in the same change:

  1. The three notification pages had no route-level auth at all (/notifications, /notifications/inbox, /notifications/send), despite the doc promising Authenticated/Role-gated. All three now carry @attribute [Authorize], so AuthorizeRouteView actually guards them; the send page's role/claim gate remains consumer-declared (NavItem filter) + server-side API authz, and the doc now says exactly that.
  2. /counter (Blazor template leftover, referenced by nothing) was routable but undocumented: deleted, along with its three orphaned resx key pairs (en + es).
  3. /forbidden was documented Authenticated but the route is open: doc corrected to Any with the in-shell rendering explained.

Verification

  • Gate red-proofed on a seeded posture drift (doc claiming /login is Authenticated fails with the exact route), green on the trued-up files.
  • Full MMCA.Common.slnx suite: 2227/2227 green.
  • FACTS.md regenerated via build/facts (Common-executes count moved 46 to 49).

Behavior note for consumers: anonymous hits on the notification routes now redirect to /login instead of rendering a shell whose API calls fail; this ships to ADC/Store with the next release + pin sweep.

🤖 Generated with Claude Code

ivanball and others added 4 commits July 16, 2026 15:18
NavigationContractTests (arch tier, CI merge gate) machine-enforces the
NavigationFlow.md routes/auth table against the RouteAttribute and
AuthorizeAttribute reality of MMCA.Common.UI: set-equality of routes,
auth-posture consistency in both directions, and an 8-route non-vacuity
floor, with the doc embedded as a resource. The gate surfaced three real
drifts, fixed here: the three notification pages carried NO route-level
[Authorize] despite the documented Authenticated/Role-gated contract
(now guarded; the send role gate stays consumer-declared and the doc says
so), the template-leftover /counter page was routable but undocumented
(deleted, plus its orphaned resx pairs), and /forbidden was documented
Authenticated while the route is open (doc corrected to Any). Verified
red on a seeded posture drift, green on the trued-up files; full suite
2227/2227; FACTS regenerated (fitness counts unchanged, executes 46->49).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n scans

The route guards added for §25 surface as endpoint metadata on the Razor
Components endpoints, so the backend-less gallery threw (no
IAuthenticationService) and all three ui-e2e legs failed. The gallery now
registers a cookie-toggled GalleryFakeAuthenticationHandler (gallery_auth=1
authenticates a fixed principal, everything else stays anonymous) plus the
full authorization stack, and GalleryAuthenticationStateProvider mirrors
the request user in both render phases (HttpContext during SSR, host
handoff in circuits), replacing the always-anonymous stub. The three
notification scans seed the cookie; login/register/components scans stay
deliberately signed-out. Full UI E2E suite locally green 23/23 (chromium).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ivanball
ivanball merged commit aa4914c into main Jul 16, 2026
9 of 10 checks passed
@ivanball
ivanball deleted the feat/s25-navigation-drift-gate branch July 16, 2026 20:13
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