feat(modernization): full architecture blueprint with hardening follow-up

Implement phased modernization infrastructure for transitioning from
multi-page legacy routing to SPA portal-shell architecture, plus
post-delivery hardening fixes for policy loading, fallback consistency,
and governance drift detection.

Key changes:
- Add route contract enrichment with scope/visibility/compatibility policies
- Canonical 302 redirects from legacy direct-entry to /portal-shell/ routes
- Asset readiness enforcement and runtime fallback retirement for in-scope routes
- Shared feature-flag helpers (env > config > default) replacing duplicated _to_bool
- Defensive copy for lru_cached policy payloads preventing mutation corruption
- Unified retired-fallback response helper across app and blueprint routes
- Frontend/backend route-contract cross-validation in governance gates
- Shell CSS token fallback values for routes rendered outside shell scope
- Local-safe .env.example defaults with production recommendation comments
- Legacy contract fallback warning logging and single-hop redirect optimization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
egg
2026-02-12 11:26:02 +08:00
parent 2c8d80afe6
commit 7cb0985b12
113 changed files with 4577 additions and 582 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-11

View File

@@ -0,0 +1,146 @@
## Context
The project has completed the no-iframe shell migration and fluid shell Phase 1, but frontend modernization remains fragmented across routing governance, styling ownership, and quality enforcement.
Current state:
- Shell contract currently governs a subset of report routes, and route governance is implemented through `frontend/src/portal-shell/routeContracts.js` + `nativeModuleRegistry.js`.
- Multiple page families still ship page-global CSS patterns (`:root`, `body`, page-level max-width wrappers), creating style ownership ambiguity and cross-page leakage risk.
- Existing specs still preserve fallback-era assumptions in several areas (runtime fallback continuity and coexistence-oriented style policy).
Scope decisions for this change:
- In scope: admin surfaces `/admin/pages`, `/admin/performance`.
- Out of scope (follow-up change): `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
Stakeholders:
- Frontend platform owners (shell/routing/design system)
- Report page module owners
- Backend maintainers for route serving and release gates
- QA/operations for release readiness and rollback governance
## Goals / Non-Goals
**Goals:**
- Define a shell-first canonical frontend architecture for in-scope routes with explicit route governance.
- Converge style architecture from permissive coexistence to enforceable isolation + token semantics.
- Modernize in-scope page content (charts, filters, interactions) with contract-first parity validation to prevent architecture drift during migration.
- Replace runtime fallback dependency for in-scope modules with build/deploy readiness gates.
- Add modernization-grade quality gates (behavioral, visual, accessibility, performance).
- Provide phased migration and rollback-safe program governance.
**Non-Goals:**
- Implementing code changes in this artifact phase.
- Rewriting excluded routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) in this change.
- Replacing backend business APIs or changing report data semantics.
- Introducing mandatory framework rewrites for all pages in one release window.
## Decisions
### D1. Route Scope Matrix with Explicit Inclusion/Exclusion
**Decision:** Define an explicit route matrix for modernization enforcement.
- Included: in-scope shell-governed report routes + `/admin/pages`, `/admin/performance`.
- Excluded for follow-up: `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
**Rationale:** Prevent uncontrolled scope creep while still addressing governance gaps for admin functionality.
**Alternatives considered:**
- Modernize all routes at once: rejected due to high blast radius and schedule risk.
- Only modernize report routes, defer admin pages: rejected because admin navigation governance remains inconsistent.
### D2. Canonical Shell Routing Policy for In-Scope Report Routes
**Decision:** In-scope report routes MUST have a canonical shell entry path and contract metadata. Direct route entry remains available only through explicit compatibility policy.
**Rationale:** Removes ambiguity between direct route behavior and shell-governed behavior; improves observability and testability.
**Alternatives considered:**
- Keep dual-mode indefinitely (direct vs shell): rejected due to long-term drift risk.
### D3. Admin Surfaces Become First-Class Contracted Navigation Targets
**Decision:** `/admin/pages` and `/admin/performance` are governed as explicit shell navigation targets with visibility and access policy, while retaining server authority for auth/session.
**Rationale:** Admin actions are part of platform governance and must be consistently modeled in route and visibility contracts.
### D4. Style Convergence Policy: Isolation + Token Enforcement
**Decision:** Move from "Tailwind and legacy CSS coexistence" to "controlled convergence":
- In-scope modules MUST avoid page-global selectors (`:root`, `body`) for page-local concerns.
- Shared semantics MUST be token-driven through `frontend/src/styles/tailwind.css` and shared UI layers.
- Legacy CSS usage in in-scope routes requires explicit exception policy.
**Rationale:** Reduces style collisions and maintenance overhead from fragmented style ownership.
### D5. Asset Readiness Over Runtime Fallback for In-Scope Modules
**Decision:** In-scope modules require build/deploy readiness guarantees; runtime fallback is no longer primary resilience strategy for these routes.
**Rationale:** Runtime fallback hides release failures and delays detection. Fail-fast at build/release is safer for correctness and easier to operate.
### D6. Modernization Quality Gates as Release Contract
**Decision:** Define mandatory route-level acceptance gates:
- Functional behavior parity
- Visual regression checks for critical states
- Accessibility checks (keyboard semantics, reduced-motion compatibility, landmark/label quality)
- Performance budgets (bundle and runtime thresholds)
**Rationale:** Architecture convergence without quality gates causes unstable rollouts and regressions.
### D7. Contract-First Page-Content Migration for Charts and Filters
**Decision:** In-scope chart/filter/page-content migration MUST follow a contract-first flow with reversible rollout:
- Freeze per-route content contracts before refactor (filter input semantics, query payload structure, chart data shape, interaction events, empty/error states).
- Implement a parity harness using golden fixtures and critical-state comparisons before switching default rendering.
- Cut over with route-scoped feature flags and immediate rollback controls (no irreversible flip in one step).
- Progress route-by-route only after manual acceptance sign-off is completed for the current route.
- Remove legacy content implementation only after parity checks and manual acceptance sign-off are completed.
**Rationale:** Prior migration failures were caused by implementation-first rewrites without strict parity and rollback controls, leading to layout/interaction drift and hard-to-debug regressions.
### D8. Mandatory "BUG Revalidation During Migration" Gate
**Decision:** Each route modernization MUST include explicit BUG revalidation before sign-off:
- Create a route-level known-bug baseline (within migrated scope: chart, filter, and page interaction behavior) before implementation.
- During manual acceptance, replay known-bug checks on the modernized route.
- If a known legacy bug is reproduced in the modernized implementation, route sign-off MUST fail and cutover/legacy-retirement MUST be blocked until fixed.
**Rationale:** Parity-only migration can accidentally preserve old defects. The modernization objective is not only structural migration, but also preventing legacy defect carry-over into the new architecture.
## Risks / Trade-offs
- **[Scope ambiguity]** Route inclusion can drift during execution. → Mitigation: publish a frozen in-scope/out-of-scope matrix in specs and tasks.
- **[Admin integration complexity]** Admin routes have different auth/session behavior than report modules. → Mitigation: keep backend auth authority unchanged; only modernize navigation contract layer in this change.
- **[Temporary dual standards]** Excluded routes still use legacy conventions. → Mitigation: explicit follow-up change linkage and governance deadline.
- **[Release friction increase]** Fail-fast asset readiness can block releases more often initially. → Mitigation: phased enforcement with warning mode then blocking mode.
- **[Style migration churn]** Token/isolation enforcement may require broad CSS refactor in in-scope pages. → Mitigation: staged rollout by route family and exception registry.
- **[Content migration instability]** Chart/filter rewrites can regress data semantics or interaction flows. → Mitigation: contract freeze + golden fixture parity + page-by-page manual acceptance + feature-flagged cutover with rollback.
- **[Legacy bug carry-over]** Modernized routes can pass parity yet still replicate known legacy defects. → Mitigation: mandatory per-route bug baseline and replay checks as blocking sign-off criteria.
## Migration Plan
1. Publish and freeze modernization scope matrix (included/excluded routes).
2. Define delta specs for route governance, style enforcement, quality gates, and asset readiness retirement policy.
3. Derive implementation tasks in phased waves (governance first, then style convergence, then gate enforcement).
4. Publish page-content contracts and golden fixtures for in-scope routes before chart/filter cutover.
5. Record route-level known-bug baselines for migrated scope and attach them to acceptance checklists.
6. Execute page-by-page manual acceptance sign-off (including bug replay checks) and only then move to the next route.
7. Enable non-blocking observability checks first (dry-run mode), then switch to blocking gates.
8. Roll out per route family with rollback criteria and runbook updates.
9. Open follow-up modernization change for excluded routes.
## Rollback Strategy
- Maintain reversible config switches for new quality gates during initial adoption.
- If blocking gates cause production-impacting false positives, revert gate mode to warning while preserving telemetry.
- Keep route-level rollback path documented for each in-scope family.
- Keep per-route manual acceptance records so rollback decisions can reference concrete pass/fail evidence.
- Keep per-route bug baseline and bug-replay results so cutover and rollback decisions can prove legacy bug non-carry-over.
## Open Questions
- Should admin pages remain backend-rendered targets with shell-managed links only, or move to shell-native view composition in a later phase?
- Which visual regression toolchain should be standardized (existing snapshot evidence extension vs dedicated UI visual diff pipeline)?
- What are initial enforceable performance thresholds for route bundles and shell startup latency?
- Should parity harness for charts use DOM-level snapshots only, or also include canonicalized data-level assertions as a blocking gate?

View File

@@ -0,0 +1,46 @@
## Why
The project has completed the critical iframe-to-Vue migration and Phase 1 shell fluidization, but the frontend architecture is still only partially modernized. Several routes remain outside shell contract governance, style ownership is still fragmented across page-local global CSS (`:root`, `body`, page-level `max-width`), and fallback-era patterns remain in docs and runtime expectations.
A full modernization blueprint is needed now to converge the system into a single, predictable frontend architecture before more feature work increases divergence and maintenance cost.
## What Changes
- Establish a shell-first architecture baseline where in-scope routes are contract-governed and module-registered with deterministic route visibility and ownership metadata.
- **BREAKING**: Retire legacy runtime fallback expectations for primary report routes in favor of build-readiness and deploy gating (fail-fast in CI/release instead of runtime degraded UX).
- **BREAKING**: Adopt canonical shell routing policy for report pages (legacy direct-entry routes become explicit compatibility redirects with sunset policy).
- Standardize style architecture: remove page-level global CSS side effects, enforce scoped styling boundaries, and converge to token-first Tailwind design primitives.
- Define contract-first page-content modernization for in-scope routes (charts, filters, and page interactions) with parity checkpoints before cutover.
- Use page-by-page manual acceptance sign-off as the required readiness gate for content migration progression.
- Enforce mandatory "BUG revalidation during migration" for each route so known legacy bugs in migrated scope SHALL NOT be carried into the new architecture.
- Introduce modernization quality gates covering interaction behavior, visual regressions, accessibility, and performance budgets.
- Define phased execution and rollback-safe governance for “full modernization” as a program (not a single code patch), including explicit completion criteria and deprecation milestones.
- Include admin surfaces in this change scope: `/admin/pages` and `/admin/performance` SHALL be first-class shell-governed routes with explicit contract metadata and visibility policy.
- Defer the following routes to a subsequent change (out of scope for this change): `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`.
## Capabilities
### New Capabilities
- `frontend-platform-modernization-governance`: Defines target frontend architecture, phased milestones, modernization guardrails, and deprecation policy.
- `unified-shell-route-coverage`: Ensures in-scope routes (including admin pages/performance) are covered by shell route contracts, loader registry, and navigation visibility rules with CI blocking on gaps.
- `style-isolation-and-token-enforcement`: Enforces CSS scope boundaries and token-first style semantics; eliminates page-global style leakage patterns.
- `page-content-modernization-safety`: Governs chart/filter/page-content migration with contract baselines, parity verification, legacy bug carry-over prevention, and reversible rollout controls.
- `frontend-quality-gate-modernization`: Adds behavioral, visual, accessibility, and performance acceptance gates for route-level changes.
- `asset-readiness-and-fallback-retirement`: Defines build/deploy guarantees and controlled retirement of runtime fallback-era behavior.
### Modified Capabilities
- `spa-shell-navigation`: Extend from current native route-view baseline to full route coverage, canonical shell routing, and contract completeness enforcement.
- `tailwind-design-system`: Shift from coexistence-with-legacy to convergence-and-enforcement with explicit legacy CSS deprecation rules.
- `full-vite-page-modularization`: Tighten from “fallback continuity” to “asset readiness governance” with stronger release-time guarantees.
- `vue-vite-page-architecture`: Update route serving expectations to shell-first canonical model with explicit compatibility redirects and sunset criteria.
## Impact
- **Frontend shell and routing**: `frontend/src/portal-shell/` (`App.vue`, `router.js`, `routeContracts.js`, `nativeModuleRegistry.js`, navigation metadata handling).
- **Frontend page style system**: `frontend/src/*/style.css`, `frontend/src/*/styles.css`, `frontend/src/styles/tailwind.css`, shared UI/style modules.
- **Frontend page-content modules**: chart, filter, and page interaction modules under `frontend/src/**` used by in-scope routes, including compatibility adapters where needed.
- **Backend route serving and compatibility**: Flask route handlers that serve page entries and legacy direct-entry paths, plus deploy-time asset-readiness checks.
- **Quality system**: `frontend/tests/`, Python integration tests, and potential new CI checks for visual/a11y/performance budgets.
- **Documentation and operations**: migration/runbook docs, architecture maps, and release governance docs aligned to modernization milestones.
- **Dependencies/tooling**: likely introduction of additional frontend QA tooling in dev workflow (subject to design artifact decisions).
- **Scope boundary note**: this change explicitly excludes `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`; those routes are planned for a follow-up modernization change.

View File

@@ -0,0 +1,25 @@
## ADDED Requirements
### Requirement: In-scope frontend assets SHALL be release-ready before deployment
In-scope routes SHALL rely on build/deploy readiness guarantees instead of runtime fallback behavior as the primary resilience mechanism.
#### Scenario: Build-readiness enforcement
- **WHEN** release artifacts are prepared for deployment
- **THEN** in-scope route assets SHALL be validated for presence and loadability
- **THEN** missing required in-scope assets SHALL fail the release gate
### Requirement: Runtime fallback retirement SHALL follow a governed phase policy
Runtime fallback behavior for in-scope modernization routes SHALL be retired under explicit governance milestones.
#### Scenario: Fallback retirement in phase scope
- **WHEN** a route is marked in-scope for fallback retirement
- **THEN** runtime fallback behavior for that route SHALL be removed or disabled by policy
- **THEN** reliability for that route SHALL be guaranteed by release-time readiness gates
### Requirement: Deferred routes SHALL keep existing fallback posture in this phase
Routes deferred from this modernization phase SHALL retain their existing fallback posture until handled by a follow-up change.
#### Scenario: Deferred fallback continuity
- **WHEN** `/tables`, `/excel-query`, `/query-tool`, or `/mid-section-defect` is evaluated in this phase
- **THEN** fallback retirement SHALL NOT be required for phase completion
- **THEN** fallback retirement decisions for those routes SHALL be addressed in a follow-up modernization change

View File

@@ -0,0 +1,26 @@
## ADDED Requirements
### Requirement: Frontend modernization scope SHALL be explicitly governed
The modernization program SHALL define an explicit in-scope and out-of-scope route matrix for each phase, and SHALL treat that matrix as a release-governed contract artifact.
#### Scenario: Scope matrix publication
- **WHEN** a modernization phase is created
- **THEN** the phase SHALL publish an explicit in-scope route list and out-of-scope route list
- **THEN** the matrix SHALL include `/admin/pages` and `/admin/performance` in scope for this phase
- **THEN** the matrix SHALL mark `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` as deferred routes for a follow-up phase
#### Scenario: Scope drift prevention
- **WHEN** implementation tasks are derived from the phase specs
- **THEN** tasks targeting routes outside the in-scope matrix SHALL be rejected for this phase
### Requirement: Modernization phases SHALL define completion and deprecation milestones
Each modernization phase SHALL define measurable completion criteria and deprecation milestones for legacy-era patterns.
#### Scenario: Phase completion criteria
- **WHEN** a phase reaches release review
- **THEN** it SHALL provide objective completion criteria for route governance, style governance, and quality gates
- **THEN** it SHALL identify any remaining deferred routes and their next-phase linkage
#### Scenario: Legacy deprecation milestones
- **WHEN** legacy fallback or legacy style exceptions remain in phase scope
- **THEN** the phase SHALL define a dated milestone or release gate to remove those exceptions

View File

@@ -0,0 +1,25 @@
## ADDED Requirements
### Requirement: Modernization releases SHALL pass multi-dimensional frontend quality gates
In-scope modernization releases SHALL pass functional, visual, accessibility, and performance gates before promotion.
#### Scenario: Gate bundle at release candidate
- **WHEN** a release candidate includes in-scope modernization changes
- **THEN** it SHALL execute functional behavior parity checks for affected routes
- **THEN** it SHALL execute critical-state visual regression checks for affected routes
- **THEN** it SHALL execute accessibility checks for keyboard and reduced-motion behavior
- **THEN** it SHALL execute performance budget checks for defined shell/route thresholds
### Requirement: Gate failures SHALL block release promotion
Blocking quality gates SHALL prevent release promotion for in-scope modernization changes.
#### Scenario: Blocking gate failure
- **WHEN** any mandatory modernization quality gate fails
- **THEN** release promotion SHALL be blocked until the failure is resolved or explicitly waived per governance policy
### Requirement: Deferred routes SHALL be excluded from this phase gate baseline
The route baseline for this modernization phase SHALL exclude deferred routes.
#### Scenario: Deferred route baseline exclusion
- **WHEN** gate baseline is computed for this phase
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded from mandatory modernization gate coverage

View File

@@ -0,0 +1,24 @@
## MODIFIED Requirements
### Requirement: Major Pages SHALL be Managed by Vite Modules
The system SHALL provide Vite-managed module entries for all in-scope modernization routes under shell-first governance, including admin surfaces `/admin/pages` and `/admin/performance` as governed targets. Deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are excluded from this phase's required module-governance completeness.
#### Scenario: In-scope module governance completeness
- **WHEN** modernization route coverage is validated for this phase
- **THEN** every in-scope route SHALL have deterministic module-governance metadata and ownership mapping
#### Scenario: Deferred route exclusion in this phase
- **WHEN** completeness validation executes for this phase
- **THEN** deferred routes SHALL be excluded from mandatory pass criteria
### Requirement: Build Pipeline SHALL Produce Backend-Served Assets
Vite build output for in-scope modernization routes MUST be emitted into backend static paths and validated at release time. Missing required in-scope assets SHALL fail release gates instead of relying on runtime fallback behavior.
#### Scenario: Build artifact readiness for in-scope routes
- **WHEN** frontend build is executed for release
- **THEN** required in-scope route artifacts SHALL be present in configured backend static dist paths
- **THEN** missing required artifacts SHALL fail readiness checks
#### Scenario: Deferred route fallback posture unchanged in this phase
- **WHEN** deferred routes are evaluated in this phase
- **THEN** existing fallback posture SHALL not block this phase's completion

View File

@@ -0,0 +1,54 @@
## ADDED Requirements
### Requirement: In-scope page-content modernization SHALL be contract-first
Before chart/filter/page interaction refactors are cut over, each in-scope route SHALL define a contract baseline that captures data and interaction semantics.
#### Scenario: Route contract baseline defined
- **WHEN** an in-scope route is selected for chart/filter modernization
- **THEN** the route SHALL define filter input semantics, query payload expectations, and chart data-shape contracts
- **THEN** the route SHALL define critical state expectations for loading, empty, error, and success interactions
### Requirement: Cutover SHALL require parity evidence against baseline behavior
In-scope chart/filter modernization cutover SHALL require parity evidence against baseline fixtures and critical interaction flows.
#### Scenario: Parity gate before default switch
- **WHEN** a route is proposed for defaulting to a modernized chart/filter implementation
- **THEN** golden fixture parity checks SHALL pass for defined critical states
- **THEN** interaction parity checks SHALL pass for filter apply/reset and chart selection/drill behaviors
### Requirement: Route-level content cutover SHALL be reversible
Modernized chart/filter content rollouts SHALL use reversible controls that allow immediate rollback without reverting unrelated shell architecture work.
#### Scenario: Controlled rollout and rollback
- **WHEN** a modernized route is enabled for users
- **THEN** the route SHALL be controlled by route-scoped feature flag or equivalent switch
- **THEN** rollback procedure SHALL be documented and executable within one release cycle
### Requirement: Page-content modernization progression SHALL require manual route acceptance
In-scope chart/filter/page-content migration SHALL progress one route at a time with explicit manual acceptance records.
#### Scenario: Route-by-route manual acceptance gate
- **WHEN** an in-scope route completes modernization implementation and parity checks
- **THEN** that route SHALL be manually accepted using a defined checklist covering filter flows, chart interactions, empty/error behavior, and visual correctness
- **THEN** the next route SHALL NOT begin cutover until manual acceptance for the current route is signed off
### Requirement: Known legacy bugs in migrated scope SHALL NOT be carried into modernized routes
Modernized route acceptance SHALL include explicit revalidation of known legacy defects in migrated scope, and reproduced defects SHALL block sign-off.
#### Scenario: Route-level legacy bug baseline and replay
- **WHEN** an in-scope route enters chart/filter/page-content modernization
- **THEN** a route-level known-bug baseline (within migrated scope) SHALL be recorded before implementation
- **THEN** manual acceptance SHALL replay those known-bug checks on the modernized route
#### Scenario: Legacy bug carry-over is blocked
- **WHEN** manual acceptance finds that a known legacy bug is still reproducible in the modernized route
- **THEN** route sign-off SHALL fail
- **THEN** route cutover completion and legacy code retirement SHALL be blocked until the bug is fixed
### Requirement: Legacy content path retirement SHALL require parity and manual acceptance
Legacy chart/filter implementations SHALL be removed only after parity checks and manual acceptance criteria are satisfied.
#### Scenario: Legacy removal approval
- **WHEN** legacy chart/filter code is planned for removal on an in-scope route
- **THEN** the route SHALL provide parity pass evidence and manual acceptance sign-off records
- **THEN** unresolved parity failures or manual acceptance defects SHALL block legacy removal

View File

@@ -0,0 +1,28 @@
## MODIFIED Requirements
### Requirement: Portal SHALL provide a SPA shell driven by Vue Router
The portal frontend SHALL use a single SPA shell entry and Vue Router to render in-scope page modules without iframe embedding. In-scope routes for this phase SHALL include the governed report routes and admin surfaces `/admin/pages` and `/admin/performance`, while deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are explicitly excluded from this phase contract.
#### Scenario: In-scope route renders through shell governance
- **WHEN** a user navigates to an in-scope shell-governed route
- **THEN** the route SHALL resolve through Vue Router with shell contract metadata
- **THEN** the shell SHALL render the corresponding module/target without iframe fallback
#### Scenario: Admin route appears as governed target
- **WHEN** an admin user opens shell navigation
- **THEN** `/admin/pages` and `/admin/performance` SHALL be exposed as governed navigation targets per access policy
#### Scenario: Deferred route is excluded from this phase route-governance requirement
- **WHEN** phase-level shell-governance compliance is evaluated
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred and excluded from pass/fail criteria for this phase
### Requirement: Existing route contracts SHALL remain stable in SPA mode
Migration to the shell-first SPA model SHALL preserve route/query compatibility for in-scope routes while introducing canonical shell routing policy and explicit compatibility handling.
#### Scenario: Canonical shell path behavior for in-scope routes
- **WHEN** a user opens an in-scope report route via canonical shell path
- **THEN** route behavior and query semantics SHALL remain compatible with established baseline behavior
#### Scenario: Compatibility policy for direct route entry
- **WHEN** a user opens an in-scope report route via direct non-canonical entry
- **THEN** the system SHALL apply explicit compatibility policy (preserve behavior or compatibility redirect) without breaking route semantics

View File

@@ -0,0 +1,25 @@
## ADDED Requirements
### Requirement: In-scope pages SHALL enforce style isolation boundaries
In-scope modernization pages SHALL avoid page-global selectors for page-local concerns and SHALL keep style concerns scoped to route-level containers or shared design-system layers.
#### Scenario: Global selector control
- **WHEN** style governance checks analyze in-scope page styles
- **THEN** page-local style changes SHALL NOT introduce new `:root` or `body` rules for route-local presentation concerns
- **THEN** shared cross-route concerns SHALL be authored in designated shared style layers
### Requirement: In-scope shared semantics SHALL be token-first
Shared UI semantics in in-scope routes SHALL be implemented with token-backed Tailwind/shared-style primitives before page-local overrides are allowed.
#### Scenario: Token-first UI pattern adoption
- **WHEN** an in-scope route introduces or updates shared UI semantics (layout shell, card, filter, action, status)
- **THEN** the route SHALL consume token-backed shared primitives
- **THEN** page-local hard-coded visual values SHALL require explicit exception justification
### Requirement: Legacy style exceptions SHALL be tracked and sunset
Legacy CSS exceptions for in-scope routes SHALL be tracked with ownership and removal milestones.
#### Scenario: Exception registry requirement
- **WHEN** an in-scope route cannot yet remove legacy style behavior
- **THEN** the route SHALL be registered with an exception owner and planned removal milestone
- **THEN** unresolved exceptions past milestone SHALL fail modernization governance review

View File

@@ -0,0 +1,24 @@
## MODIFIED Requirements
### Requirement: Frontend styles SHALL be governed by Tailwind design tokens
The frontend SHALL enforce a token-governed style system for in-scope routes. Shared visual semantics SHALL be expressed through token-backed Tailwind/shared layers, and ad-hoc page-local hard-coded values for shared semantics SHALL require explicit exception governance.
#### Scenario: Shared token usage across in-scope modules
- **WHEN** two in-scope modules render equivalent UI semantics (e.g., card, filter chip, primary action, status indicator)
- **THEN** they SHALL use the same token-backed style semantics
- **THEN** visual output SHALL remain consistent across those modules
#### Scenario: Token governance review
- **WHEN** an in-scope route introduces new shared UI styling
- **THEN** the styling SHALL map to shared tokens/layers or be recorded in an approved exception registry
### Requirement: Tailwind migration SHALL support coexistence with legacy CSS
Tailwind migration SHALL support controlled coexistence only as a transition state for this phase. In-scope routes SHALL move toward isolation-first style ownership and SHALL NOT introduce new page-global CSS side effects for route-local concerns.
#### Scenario: In-scope global selector control
- **WHEN** in-scope route styles are reviewed
- **THEN** new route-local styling SHALL NOT introduce page-global selectors (`:root`, `body`) for local presentation behavior
#### Scenario: Deferred route coexistence allowance
- **WHEN** deferred routes (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`) are evaluated during this phase
- **THEN** existing coexistence posture SHALL be allowed and handled by a follow-up modernization change

View File

@@ -0,0 +1,29 @@
## ADDED Requirements
### Requirement: In-scope routes SHALL be shell-contract governed
All in-scope modernization routes SHALL be represented in shell route contracts, loader registration policy, and navigation visibility governance.
#### Scenario: In-scope coverage validation
- **WHEN** shell route contract validation is executed
- **THEN** every in-scope route SHALL have route metadata, ownership metadata, and visibility policy metadata
- **THEN** missing in-scope route contracts SHALL fail validation
#### Scenario: Admin route inclusion
- **WHEN** shell navigation is built for admin users
- **THEN** `/admin/pages` and `/admin/performance` SHALL be represented as governed navigation targets according to visibility/access policy
### Requirement: Out-of-scope routes SHALL not block this phase
Routes explicitly marked as out-of-scope for this modernization phase SHALL be excluded from required shell-coverage gates in this phase.
#### Scenario: Deferred route exclusion
- **WHEN** modernization gates execute for this phase
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be treated as deferred routes
- **THEN** deferred route absence from new shell-governance gates SHALL NOT fail this phase
### Requirement: Route coverage governance SHALL be CI-enforced
Route coverage and contract completeness checks for in-scope routes SHALL run as CI gates.
#### Scenario: CI gate failure on in-scope gap
- **WHEN** CI detects an in-scope route without required contract metadata
- **THEN** the modernization gate SHALL fail
- **THEN** release promotion SHALL be blocked until resolved

View File

@@ -0,0 +1,20 @@
## MODIFIED Requirements
### Requirement: Pure Vite pages SHALL be served as static HTML
The system SHALL serve in-scope pure Vite pages through backend static HTML delivery under a shell-first canonical routing policy. Direct-entry compatibility for in-scope routes SHALL be explicit and governed. Admin targets `/admin/pages` and `/admin/performance` SHALL be represented as governed shell navigation targets, while maintaining backend auth/session authority.
#### Scenario: In-scope canonical shell entry
- **WHEN** a user navigates to an in-scope canonical shell route
- **THEN** the shell SHALL render the target route via governed route contracts and static asset delivery
#### Scenario: Direct-entry compatibility policy for in-scope routes
- **WHEN** a user opens an in-scope route through direct non-canonical entry
- **THEN** the system SHALL apply explicit compatibility behavior without breaking established query semantics
#### Scenario: Admin targets in shell governance
- **WHEN** shell navigation is rendered for an authorized admin user
- **THEN** `/admin/pages` and `/admin/performance` SHALL be reachable through governed admin navigation targets
#### Scenario: Deferred routes excluded from this phase architecture criteria
- **WHEN** this phase architecture compliance is evaluated
- **THEN** `/tables`, `/excel-query`, `/query-tool`, and `/mid-section-defect` SHALL be excluded and handled in a follow-up change

View File

@@ -0,0 +1,78 @@
## 1. Program Governance Baseline
- [x] 1.1 Publish a frozen in-scope/out-of-scope route matrix for this phase (include `/admin/pages`, `/admin/performance`; exclude `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`)
- [x] 1.2 Add modernization governance documentation for phase completion criteria and legacy deprecation milestones
- [x] 1.3 Create an exception registry format for temporary route/style exceptions (owner + milestone)
## 2. Shell Route Contract Expansion (In Scope)
- [x] 2.1 Extend shell route contract metadata to cover all in-scope routes for this phase
- [x] 2.2 Add governed navigation target definitions for `/admin/pages` and `/admin/performance`
- [x] 2.3 Ensure route visibility/access policy metadata is validated for in-scope routes
- [x] 2.4 Add CI contract checks that fail on missing in-scope route metadata
## 3. Canonical Routing and Compatibility Policy
- [x] 3.1 Define canonical shell entry behavior for in-scope report routes
- [x] 3.2 Implement explicit compatibility policy for direct non-canonical route entry
- [x] 3.3 Verify query-semantics compatibility for in-scope routes under canonical/compatibility paths
## 4. Admin Surface Modernization Integration
- [x] 4.1 Integrate `/admin/pages` and `/admin/performance` into shell-governed navigation flow
- [x] 4.2 Preserve backend auth/session authority while modernizing shell navigation governance
- [x] 4.3 Add admin visibility/access behavior tests for shell-governed admin targets
## 5. Style Isolation and Token Enforcement
- [x] 5.1 Inventory in-scope route styles for page-global selector usage (`:root`, `body`) and classify required refactors
- [x] 5.2 Refactor in-scope route-local styles to scoped/container-based ownership
- [x] 5.3 Move shared visual semantics to token-backed Tailwind/shared layers
- [x] 5.4 Add style-governance lint/check rules for in-scope routes and exception handling
## 6. Page-Content Modernization Safety (Charts/Filters/Interactions)
- [x] 6.1 Define route-level content contracts for in-scope pages (filter input semantics, query payload structure, chart data shape, state transitions)
- [x] 6.2 Build golden fixtures and parity assertions for chart/filter critical states before cutover
- [x] 6.3 Add interaction parity checks for critical flows (filter apply/reset, chart drill/selection, empty/error states)
- [x] 6.4 Add route-scoped feature flags and immediate rollback controls for content cutover
- [x] 6.5 Define a per-route manual acceptance checklist for chart/filter/page-content migration
- [x] 6.6 Require manual acceptance sign-off for each route before moving to the next route
- [x] 6.7 Require parity pass + manual acceptance sign-off before legacy content path retirement
- [x] 6.8 Create route-level known-bug baselines for migrated scope before implementation begins
- [x] 6.9 Add mandatory "BUG revalidation during migration" checklist items to manual acceptance for each route
- [x] 6.10 Block route sign-off and legacy retirement if known legacy bugs are reproduced in the modernized route
## 7. Asset Readiness and Fallback Retirement (In Scope)
- [x] 7.1 Define required in-scope asset readiness checks for build/release pipeline
- [x] 7.2 Enforce fail-fast release behavior when required in-scope assets are missing
- [x] 7.3 Retire runtime fallback posture for in-scope routes per governance milestones
- [x] 7.4 Keep deferred route fallback posture unchanged in this phase and document follow-up linkage
## 8. Frontend Quality Gate Modernization
- [x] 8.1 Define mandatory functional parity checks for in-scope modernization routes
- [x] 8.2 Define visual regression checkpoints for critical states in in-scope routes
- [x] 8.3 Define accessibility checks (keyboard flows, aria semantics, reduced-motion behavior)
- [x] 8.4 Define performance budgets and measurement points for shell/route behavior
- [x] 8.5 Configure gate severity policy (warn mode rollout -> blocking mode promotion)
## 9. Test and CI Wiring
- [x] 9.1 Extend frontend test suite for new route governance/admin scenarios
- [x] 9.2 Extend backend/integration tests for canonical routing and compatibility behavior
- [x] 9.3 Add CI jobs for route-governance completeness, quality-gate execution, and asset readiness checks
- [x] 9.4 Ensure deferred routes are excluded from this phase blocking criteria
## 10. Migration and Rollback Runbook
- [x] 10.1 Update runbook with phased rollout steps and hold points for modernization gates
- [x] 10.2 Document rollback controls for gate false positives and route-level reversion
- [x] 10.3 Add operational observability checkpoints for route governance and gate outcomes
## 11. Follow-up Change Preparation (Deferred Routes)
- [x] 11.1 Create a linked follow-up modernization change for `/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`
- [x] 11.2 Transfer deferred-route requirements and acceptance criteria into the follow-up change
- [x] 11.3 Record explicit handoff from this phase to the deferred-route phase

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-12

View File

@@ -0,0 +1,108 @@
## Context
Phase 1 modernization was completed and archived, but post-delivery review identified several hardening gaps across policy loading, fallback behavior consistency, feature-flag ergonomics, and route-governance drift detection. The gaps are cross-cutting: backend route hosts, frontend contract metadata, CI governance checks, and operator onboarding defaults.
Current risks include:
- shared mutable cached policy payloads via `lru_cache` return values,
- inconsistent retired-fallback 503 response surfaces between app routes and blueprint routes,
- local bootstrap failures caused by strict `.env.example` defaults,
- duplicated boolean feature-flag parsing with slightly different precedence logic,
- missing frontend/backend route-inventory cross-validation.
## Goals / Non-Goals
**Goals:**
- Make modernization policy loading deterministic, mutation-safe, and explicitly documented.
- Standardize retired-fallback error response behavior across all in-scope route hosts.
- Keep `.env.example` local-safe while documenting production hardening expectations.
- Centralize feature-flag resolution semantics in shared helpers.
- Enforce route-contract parity across backend artifacts and frontend shell contracts.
- Improve operational observability for legacy contract fallback loading.
**Non-Goals:**
- No new route migrations in this change.
- No redesign of shell navigation UX.
- No deferred-route modernization implementation (`/tables`, `/excel-query`, `/query-tool`, `/mid-section-defect`).
- No runtime hot-reload framework for all policy artifacts.
## Decisions
### Decision 1: Introduce shared feature-flag helpers for bool parsing and env/config precedence
- Choice: Add shared helpers (for example `parse_bool`, `resolve_bool_flag`) used by app/policy/runtime modules.
- Rationale: eliminates duplicated parsing and precedence drift.
- Alternative considered: keep local `_to_bool` and alignment-by-convention.
- Why not alternative: high regression risk from future divergence and incomplete audits.
### Decision 2: Protect cached policy payloads from cross-caller mutation
- Choice: keep internal cache, but return defensive copies to callers; document refresh semantics and expose explicit cache-clear helper for tests/controlled refresh points.
- Rationale: avoids shared-reference corruption without changing call sites.
- Alternative considered: return `MappingProxyType`.
- Why not alternative: nested list/dict payloads still remain mutable unless deeply frozen.
### Decision 3: Unify retired-fallback response generation
- Choice: move to a shared fallback-retirement response helper callable from both app-level and blueprint-level routes.
- Rationale: consistent status/template/body contract and easier testing.
- Alternative considered: leave blueprint-specific inline HTML responses.
- Why not alternative: inconsistent user/operator behavior and duplicated logic.
### Decision 4: Rebalance `.env.example` for safe local onboarding
- Choice: set strict modernization toggles to local-safe defaults and annotate production-recommended values inline.
- Rationale: avoid false-negative startup failures in local/test environments while preserving explicit production guidance.
- Alternative considered: keep strict defaults and require all local users to override manually.
- Why not alternative: unnecessary onboarding friction and frequent bootstrap failures.
### Decision 5: Add governance parity checks across frontend and backend route contracts
- Choice: extend governance checks/tests to compare backend route contract artifacts with frontend route inventory/scope metadata.
- Rationale: catches silent drift before release.
- Alternative considered: rely only on backend JSON consistency.
- Why not alternative: frontend contract drift can still break runtime behavior silently.
### Decision 6: Emit explicit warning when legacy contract source is used
- Choice: log warning when loader falls back from primary contract artifact to legacy path.
- Rationale: improves observability during migration tail.
- Alternative considered: silent fallback.
- Why not alternative: hard to detect stale-source dependency in production.
### Decision 7: Reduce unnecessary redirect hops in `/hold-detail` missing-reason flow
- Choice: when SPA shell mode is enabled, redirect directly to canonical shell overview path.
- Rationale: reduces redirect chain complexity and improves deterministic route tracing.
- Alternative considered: keep current two-hop behavior.
- Why not alternative: no benefit, adds trace/debug noise.
### Decision 8: Add token fallbacks for shell-dependent route styles
- Choice: where route-local CSS consumes shell variables, include fallback values in `var(--token, fallback)` form.
- Rationale: prevents degraded rendering when route is rendered outside shell variable scope.
- Alternative considered: assume shell-only render path.
- Why not alternative: fallback/compatibility entry paths still exist in this phase.
## Risks / Trade-offs
- [Risk] Shared helper refactor may alter existing truthy/falsey behavior in edge env values.
- Mitigation: add unit tests covering canonical and malformed env values before replacing call sites.
- [Risk] Contract parity gate can fail current CI if artifacts are already drifted.
- Mitigation: land parity test with synchronized artifacts in same change.
- [Risk] Defensive-copy strategy adds minor per-call overhead.
- Mitigation: policy payloads are small and low-frequency; prioritize correctness over micro-optimization.
- [Risk] `.env.example` default changes may be interpreted as weaker production stance.
- Mitigation: add explicit production recommendation comments next to each local-safe default.
## Migration Plan
1. Add shared feature-flag helpers and migrate existing bool parsing call sites.
2. Refactor modernization policy cache-return behavior to mutation-safe contract and document refresh semantics.
3. Introduce shared retired-fallback response helper and migrate hold-overview/hold-history/hold-detail route handlers.
4. Update `.env.example` defaults and production guidance comments.
5. Extend governance script/tests for frontend/backend route-contract parity.
6. Add warning log on legacy contract-source fallback.
7. Update `/hold-detail` missing-reason redirect to single-hop canonical target under SPA mode.
8. Add fallback values for QC-GATE shell-derived CSS variables.
9. Run targeted unit/integration/e2e + governance checks.
Rollback strategy:
- Changes are config/code-level and can be reverted by standard git rollback.
- If parity gate causes unexpected release blocking, gate can temporarily run in warning mode while drift is fixed in same release window.
## Open Questions
- Should policy cache refresh be strictly restart-based, or do we want an operator-triggered cache-clear hook in production later?
- Do we want a single centralized governance artifact as source-of-truth long-term, with generated frontend/backend contract outputs?

View File

@@ -0,0 +1,34 @@
## Why
Recent code review on the Phase 1 modernization delivery found several high-risk consistency gaps: mutable cached policy payloads, inconsistent fallback-retirement error behavior, aggressive `.env.example` defaults, and route-governance drift risks between backend JSON and frontend contract definitions. These issues can cause environment-dependent startup failures, silent policy drift, and hard-to-debug runtime behavior.
## What Changes
- Harden modernization policy loaders to prevent shared mutable cache corruption and make refresh semantics explicit/documented.
- Unify in-scope fallback-retirement response behavior across app-level routes and blueprint routes.
- Make `.env.example` safe for local onboarding while still documenting production-recommended hardening values.
- Consolidate feature-flag boolean resolution (`env > config > default`) into a shared helper and remove duplicated `_to_bool` implementations.
- Add route-contract cross-validation between backend contract artifacts and frontend `routeContracts.js` inventory.
- Add explicit warning telemetry when legacy shell-contract artifact fallback is used.
- Document and test intentional canonical-redirect scope asymmetry (report routes vs admin external targets).
- Reduce avoidable redirect chain length for `/hold-detail` missing-reason flow in SPA mode.
- Add shell-token fallback values for QC-GATE page CSS variables to prevent rendering degradation outside shell context.
## Capabilities
### New Capabilities
- None.
### Modified Capabilities
- `asset-readiness-and-fallback-retirement`: unify fallback-retirement failure surfaces and safe local defaults for readiness-related flags.
- `frontend-platform-modernization-governance`: add governance requirements for contract-source consistency and legacy artifact fallback observability.
- `spa-shell-navigation`: document and enforce canonical redirect scope rules, including missing-reason redirect behavior.
- `unified-shell-route-coverage`: require frontend/backend route-contract set consistency checks.
- `style-isolation-and-token-enforcement`: require token fallback behavior for route-local styles that may render outside shell variable scope.
- `maintainability-type-and-constant-hygiene`: require shared feature-flag and boolean parsing helpers for policy/runtime modules.
## Impact
- Affected backend modules: `src/mes_dashboard/core/modernization_policy.py`, `src/mes_dashboard/core/runtime_contract.py`, `src/mes_dashboard/app.py`, hold-related routes.
- Affected frontend modules: `frontend/src/portal-shell/routeContracts.js`, `frontend/src/qc-gate/style.css`.
- Affected governance and tests: modernization gate script/tests, route-contract consistency tests, redirect/fallback behavior tests, `.env.example` documentation.

View File

@@ -0,0 +1,12 @@
## ADDED Requirements
### Requirement: Fallback-retirement failure response SHALL be consistent across route hosts
When in-scope runtime fallback retirement is enabled and route assets are unavailable, app-level and blueprint-level route handlers SHALL return a consistent retired-fallback response surface.
#### Scenario: App-level in-scope route enters retired fallback state
- **WHEN** an in-scope app-level route cannot serve required dist assets and fallback retirement is enabled
- **THEN** the route SHALL return the standardized retired-fallback response contract
#### Scenario: Blueprint-level in-scope route enters retired fallback state
- **WHEN** an in-scope blueprint-level route cannot serve required dist assets and fallback retirement is enabled
- **THEN** the route SHALL return the same standardized retired-fallback response contract used by app-level routes

View File

@@ -0,0 +1,19 @@
## ADDED Requirements
### Requirement: Operator-facing environment defaults SHALL be onboarding-safe
`.env.example` SHALL prioritize local onboarding safety while clearly documenting production hardening recommendations for modernization controls.
#### Scenario: Local bootstrap from `.env.example`
- **WHEN** a developer initializes `.env` from `.env.example` in a local non-production environment
- **THEN** startup-critical modernization flags SHALL default to onboarding-safe values that do not fail boot solely because dist readiness gates are strict by default
#### Scenario: Production recommendation visibility
- **WHEN** operators review `.env.example` for deployment configuration
- **THEN** production-recommended values for shell-first and modernization-hardening flags SHALL be explicitly documented in adjacent comments
### Requirement: Policy cache refresh model SHALL be explicit in governance docs
Governance-owned policy artifacts that are loaded with in-process caching SHALL document runtime refresh behavior and operator expectations.
#### Scenario: Cached policy artifact behavior documentation
- **WHEN** maintainers read modernization governance artifacts
- **THEN** they SHALL find explicit guidance on whether policy JSON updates require process restart, cache clear, or automatic reload

View File

@@ -0,0 +1,19 @@
## ADDED Requirements
### Requirement: Feature-flag resolution SHALL use shared helper semantics
Environment/config/default feature-flag resolution logic SHALL be implemented through shared helper utilities instead of duplicated per-module parsing.
#### Scenario: Feature-flag evaluation in app and policy modules
- **WHEN** modules resolve boolean feature flags from environment variables and Flask config
- **THEN** they SHALL use a shared helper that enforces consistent precedence and truthy/falsey parsing behavior
### Requirement: Cached policy payloads SHALL protect against shared mutable-state corruption
Policy loader functions that cache JSON payloads in-process SHALL prevent downstream callers from mutating the shared cached object reference.
#### Scenario: Cached policy payload consumed by multiple callers
- **WHEN** multiple callers read cached policy payloads during process lifetime
- **THEN** one caller's accidental mutation SHALL NOT alter another caller's observed policy state through shared reference side effects
#### Scenario: Policy cache behavior documentation
- **WHEN** maintainers inspect cached policy loader code
- **THEN** they SHALL find explicit comments describing refresh/invalidation behavior expectations

View File

@@ -0,0 +1,20 @@
## ADDED Requirements
### Requirement: Canonical redirect scope boundaries SHALL be explicit and intentional
Canonical shell direct-entry redirects SHALL apply only to governed in-scope report routes and SHALL explicitly exclude admin external targets with documented rationale.
#### Scenario: In-scope report route direct entry
- **WHEN** SPA shell mode is enabled and a user enters an in-scope report route directly
- **THEN** the system SHALL redirect to the canonical `/portal-shell/...` route while preserving query semantics
#### Scenario: Admin external target direct entry
- **WHEN** SPA shell mode is enabled and a user enters `/admin/pages` or `/admin/performance` directly
- **THEN** the system SHALL NOT apply report-route canonical redirect policy
- **THEN** the exclusion rationale SHALL be documented in code-level comments or governance docs
### Requirement: Missing-required-parameter redirects SHALL avoid avoidable multi-hop chains
Routes with server-side required query parameters SHALL minimize redirect hops under SPA shell mode.
#### Scenario: Hold detail missing reason in SPA shell mode
- **WHEN** a user opens `/hold-detail` without `reason` while SPA shell mode is enabled
- **THEN** the route SHALL resolve via a single-hop redirect to the canonical overview shell path

View File

@@ -0,0 +1,12 @@
## ADDED Requirements
### Requirement: Route-local token usage SHALL include fallback values outside shell scope
Route-level styles that reference shell-provided token variables SHALL define fallback values to preserve rendering correctness when rendered outside shell variable scope.
#### Scenario: Route rendered outside portal shell variable scope
- **WHEN** a route-local stylesheet references shell token variables and the page is rendered without shell-level CSS variables
- **THEN** visual-critical properties (for example header gradients) SHALL still resolve through explicit fallback token values
#### Scenario: Style governance check for unresolved shell variables
- **WHEN** style-governance validation inspects in-scope route styles
- **THEN** unresolved shell-variable references without fallback SHALL be flagged as governance failures or approved exceptions

View File

@@ -0,0 +1,19 @@
## ADDED Requirements
### Requirement: Frontend and backend route-contract inventories SHALL be cross-validated
Route-governance checks SHALL verify that frontend shell route contracts and backend route contract artifacts describe the same governed route set and scope classes.
#### Scenario: Cross-source contract parity gate
- **WHEN** modernization governance checks run in CI
- **THEN** mismatches between backend route contract JSON and frontend `routeContracts.js` route inventory SHALL fail the gate
#### Scenario: Scope classification drift detection
- **WHEN** a route has inconsistent scope classification between frontend and backend contract sources
- **THEN** governance checks SHALL report the specific route and conflicting scope values
### Requirement: Legacy contract-source fallback SHALL emit operational warning
When contract loading falls back from the primary modernization contract artifact to a legacy artifact path, the service SHALL emit explicit warning telemetry.
#### Scenario: Legacy contract fallback path selected
- **WHEN** the primary contract artifact is unavailable and a legacy contract file is loaded
- **THEN** the system SHALL log a warning that includes the selected legacy source path

View File

@@ -0,0 +1,50 @@
## 1. Shared Flag and Policy Helper Hardening
- [x] 1.1 Introduce shared boolean parsing and feature-flag resolution helpers (`env > config > default`) in a common core utility module.
- [x] 1.2 Replace duplicated `_to_bool` / inline bool parsing in `app.py`, `modernization_policy.py`, and `runtime_contract.py` with shared helpers.
- [x] 1.3 Refactor modernization policy cached JSON loaders to prevent shared mutable-state corruption (defensive return strategy + clear cache helper for controlled refresh/testing).
- [x] 1.4 Add inline documentation comments describing policy cache refresh behavior and operator expectations.
## 2. Fallback and Redirect Behavior Consistency
- [x] 2.1 Implement a shared retired-fallback response helper usable by both app-level and blueprint-level route handlers.
- [x] 2.2 Migrate hold-related blueprint routes (`hold-overview`, `hold-history`, `hold-detail`) to the shared retired-fallback response contract.
- [x] 2.3 Update `/hold-detail` missing-`reason` logic to single-hop redirect to canonical shell overview when SPA shell mode is enabled.
- [x] 2.4 Document canonical redirect scope boundaries (report routes only, admin external targets excluded) in policy code comments.
## 3. Environment and Governance Documentation Safety
- [x] 3.1 Update `.env.example` modernization/runtime hardening flags to onboarding-safe defaults for local environments.
- [x] 3.2 Add explicit production-recommended values and rationale comments next to each adjusted flag in `.env.example`.
- [x] 3.3 Update modernization governance docs to clarify policy artifact cache refresh/invalidation model.
## 4. Route Contract Drift Detection and Observability
- [x] 4.1 Extend modernization governance checks to cross-validate backend route contract artifacts against frontend `routeContracts.js` route inventory and scope classifications.
- [x] 4.2 Add/extend tests that fail on frontend-backend route set drift and scope mismatch.
- [x] 4.3 Emit explicit warning logs when shell contract loading falls back to a legacy contract artifact path.
- [x] 4.4 Add test coverage verifying legacy contract fallback warning behavior.
## 5. Style Token Fallback Resilience
- [x] 5.1 Update QC-GATE route-local CSS variables that depend on shell tokens to include fallback values.
- [x] 5.2 Add style-governance check or test assertion that shell-derived route styles include fallback values unless explicitly exempted.
## 6. Test Coverage and Regression Validation
- [x] 6.1 Add redirect compatibility tests for non-ASCII query parameters through canonical redirect flows.
- [x] 6.2 Add explicit test for `/hold-detail` missing-`reason` redirect chain behavior under SPA enabled mode.
- [x] 6.3 Narrow broad `os.path.exists` patches in route/template tests to targeted path-specific behavior where feasible.
- [x] 6.4 Run relevant unit/integration/frontend/e2e governance test suites and record pass criteria for this hardening change.
## Validation Record
- `pytest -q tests/test_feature_flags.py tests/test_modernization_policy_hardening.py tests/test_asset_readiness_policy.py tests/test_hold_routes.py tests/test_portal_shell_routes.py tests/test_full_modernization_gates.py tests/test_template_integration.py``84 passed`
- `pytest -q tests/test_hold_overview_routes.py tests/test_hold_history_routes.py``34 passed`
- `pytest -q tests/test_wip_routes.py``27 passed`
- `pytest -q tests/test_runtime_contract.py tests/test_runtime_hardening.py -k "runtime_contract or runtime"``10 passed`
- `pytest -q tests/test_wip_hold_pages_integration.py``3 passed`
- `npm --prefix frontend test``64 passed`
- `python scripts/check_full_modernization_gates.py --mode block``[OK] modernization gates passed`
- `E2E_BASE_URL=http://127.0.0.1:8091 pytest -q tests/e2e/test_wip_hold_pages_e2e.py -k "hold_detail_without_reason_redirects_to_overview" --run-e2e``1 passed`
- `STRESS_TEST_URL=http://127.0.0.1:8091 STRESS_CONCURRENT_USERS=2 STRESS_REQUESTS_PER_USER=3 pytest -q tests/stress/test_api_load.py -k "hold_detail_lots_concurrent_load"``1 passed`