fix(web): ship degraded search readiness state

This commit is contained in:
master
2026-03-08 16:27:51 +02:00
parent 9f6fd0b4aa
commit f24d49ddeb
6 changed files with 145 additions and 2 deletions

View File

@@ -0,0 +1,99 @@
# Sprint 20260308-012 - FE Search Readiness Degraded Answer State
## Topic & Scope
- Formalize the current Web search batch that handles empty-corpus environments where starter-query viability cannot be checked.
- Replace misleading clarify or refine-the-query guidance with an explicit environment-readiness answer state when live search is not actually usable.
- Keep the iteration scoped to the top-bar search surface, its docs, and focused deterministic verification.
- Working directory: `src/Web/StellaOps.Web`.
- Allowed coordination edits: `docs/implplan/`, `docs/modules/ui/TASKS.md`, `docs/modules/ui/implementation_plan.md`, `docs/modules/ui/search-self-serve-contract.md`, `docs/modules/ui/search-zero-learning-primary-entry.md`, `src/Web/StellaOps.Web/src/app/layout/global-search/`, `src/Web/StellaOps.Web/src/tests/global_search/`, and `src/Web.StellaOps.Web/tests/e2e/`.
- Expected evidence: focused Angular tests, deterministic Playwright coverage, docs sync, and sprint execution log updates.
## Dependencies & Concurrency
- Depends on the archived search-shell and self-serve sprints that introduced answer-first search and viability-preflight behavior:
- `docs-archived/implplan/SPRINT_20260307_004_FE_self_serve_search_answer_first.md`
- `docs-archived/implplan/SPRINT_20260307_006_FE_self_serve_rollout_and_gap_closure.md`
- Safe parallelism:
- docs and tests can be prepared in parallel once the answer-state rule is frozen
- do not touch unrelated trust-admin, offline-kit, policy-workspace, or sidebar changes already present in the shared worktree
## Documentation Prerequisites
- `src/Web/StellaOps.Web/AGENTS.md`
- `docs/modules/ui/search-self-serve-contract.md`
- `docs/modules/ui/search-zero-learning-primary-entry.md`
- `src/Web/StellaOps.Web/src/app/layout/global-search/global-search.component.ts`
- `src/Web.StellaOps.Web/src/tests/global_search/global-search.component.spec.ts`
- `src/Web.StellaOps.Web/tests/e2e/unified-search-experience-quality.e2e.spec.ts`
## Delivery Tracker
### FE-SRD-001 - Bound the degraded-search readiness case
Status: DONE
Dependency: none
Owners: QA, Developer (FE)
Task description:
- Confirm the specific operator-facing failure mode: suggestion-viability preflight is unavailable and the search response shows zero indexed matches, yet the UI behaves as if the operator merely needs to refine the query.
- Keep the diagnosis focused on the search shell contract and not on general search ranking or corpus rebuild infrastructure.
Completion criteria:
- [x] The degraded-readiness condition is expressed as explicit frontend state, not scattered UI heuristics.
- [x] The rule is bounded to the combination of unavailable viability preflight plus zero indexed matches.
- [x] The sprint documents why this is an environment-readiness problem, not an operator-query problem.
### FE-SRD-002 - Render an explicit readiness answer state
Status: DONE
Dependency: FE-SRD-001
Owners: Developer (FE)
Task description:
- Update the answer panel so it renders environment-readiness copy and suppresses clarify guidance when the active environment cannot provide viability signals and also returns zero indexed matches.
- Preserve the existing grounded, clarify, and insufficient paths outside this specific degraded-readiness case.
Completion criteria:
- [x] Search renders an explicit readiness answer state with operator-facing copy.
- [x] Clarify guidance is suppressed for the degraded-readiness case.
- [x] Existing answer-state behavior remains intact for healthy grounded and clarify responses.
### FE-SRD-003 - Add focused deterministic regression coverage
Status: DONE
Dependency: FE-SRD-002
Owners: Test Automation, QA
Task description:
- Add focused Angular coverage for the readiness state and deterministic Playwright coverage for the UI path where suggestion viability is unavailable and indexed matches are zero.
- Keep tests bounded and memory-safe.
Completion criteria:
- [x] Angular tests assert the explicit readiness answer and absence of clarify guidance.
- [x] Playwright covers the degraded-readiness case end to end.
- [x] Verification remains deterministic and does not depend on live network access.
### FE-SRD-004 - Sync search docs and rollout guidance
Status: DONE
Dependency: FE-SRD-002
Owners: Documentation author, Project Manager
Task description:
- Update the search self-serve and zero-learning guidance so the degraded-readiness rule is explicit and traceable from the shipped UI behavior.
- Sync the UI task board and implementation plan to reflect the active sprint and the shipped result.
Completion criteria:
- [x] Search docs describe the degraded-readiness answer rule.
- [x] UI planning docs point to this active sprint while it is in flight.
- [x] Sprint execution log captures the verification evidence and any residual risks.
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-03-08 | Sprint created to formalize the in-progress Web search batch for degraded readiness handling after the active sprint inventory was cleaned and the remaining dirty search diffs were bounded to a coherent top-bar search fix. | Project Manager |
| 2026-03-08 | Bounded the real defect to a stale viability state on typed queries: the search shell refreshed viability on focus and route changes, but not on the debounced non-empty query path that actually drove search requests. | Developer (FE) |
| 2026-03-08 | Refreshed suggestion viability on the debounced query path, kept the degraded-readiness rule narrowly bound to unavailable viability plus zero indexed matches, and tightened the deterministic Playwright fixture to use a true zero-match response. | Developer (FE) |
| 2026-03-08 | Verified focused Angular coverage with `npm test -- --watch=false --include src/tests/global_search/global-search.component.spec.ts` (`26/26` passed) and deterministic Playwright coverage with `npx playwright test tests/e2e/unified-search-experience-quality.e2e.spec.ts --grep "search-readiness guidance" --workers=1` (`1/1` passed). | QA |
| 2026-03-08 | Synced search docs, added a checked-feature note, and archived the sprint after verification passed. | Documentation author |
## Decisions & Risks
- Decision: treat this as a frontend truthfulness fix, not a general search-platform recovery sprint.
- Decision: the degraded-readiness state is only valid when both conditions hold: viability preflight is unavailable and the search response reports zero indexed matches.
- Risk: broadening the heuristic could suppress legitimate clarify guidance for healthy but ambiguous queries.
- Mitigation: keep the rule narrowly tied to unavailable viability plus zero indexed matches.
- Risk: shared worktree changes in unrelated Web files could tempt a wider cleanup.
- Mitigation: stay inside the explicit sprint working directory and listed coordination files only.
## Next Checkpoints
- Archived 2026-03-08 after focused Angular and deterministic Playwright verification passed.

View File

@@ -0,0 +1,25 @@
# Search Readiness Degraded Answer State UI
## Scope
- Verifies the top-bar search surface tells the truth when suggestion-viability preflight is unavailable and the active search response reports zero indexed matches.
- Confirms the UI renders environment-readiness copy instead of clarify guidance for that bounded degraded-readiness case.
## Files
- `src/Web/StellaOps.Web/src/app/layout/global-search/global-search.component.ts`
- `src/Web.StellaOps.Web/src/tests/global_search/global-search.component.spec.ts`
- `src/Web.StellaOps.Web/tests/e2e/unified-search-experience-quality.e2e.spec.ts`
- `docs/modules/ui/search-self-serve-contract.md`
- `docs/modules/ui/search-zero-learning-primary-entry.md`
## Verification
1. Focused Angular coverage:
- `npm test -- --watch=false --include src/tests/global_search/global-search.component.spec.ts`
- Result: `26/26` tests passed.
2. Deterministic Playwright coverage:
- `npx playwright test tests/e2e/unified-search-experience-quality.e2e.spec.ts --grep "search-readiness guidance" --workers=1`
- Result: `1/1` test passed.
## Outcome
- Search now refreshes suggestion viability on the same debounced query path that drives the search request instead of leaving the viability state stale for typed queries.
- When viability preflight is unavailable and the response diagnostics show zero indexed matches, the answer panel renders `Search needs live data` and suppresses clarify guidance.
- Docs now describe this as an environment-readiness problem, not an operator-query problem.

View File

@@ -1,7 +1,7 @@
# UI Task Board
## Active Sprint Links
- None currently. Completed UI delivery and restoration sprints are archived under `docs-archived/implplan/`.
- None currently. Completed UI delivery and verification sprints are archived under `docs-archived/implplan/`.
## Delivery Tasks
- [DONE] 041-T1 Root IA/nav rewrite (Mission Control + Ops + Setup)
@@ -45,6 +45,10 @@
- [DONE] FE-SF-002 Automatic answer/overflow presentation cleanup
- [DONE] FE-SF-003 Suggestion execution and success-only history hardening
- [DONE] FE-SF-004 Search-first shell verification coverage
- [DONE] FE-SRD-001 Bound the degraded-search readiness case
- [DONE] FE-SRD-002 Render an explicit readiness answer state
- [DONE] FE-SRD-003 Add focused deterministic regression coverage
- [DONE] FE-SRD-004 Sync search docs and rollout guidance
- [DONE] QA-SF-001 Live route preflight and corpus readiness gate
- [DONE] QA-SF-002 Execute surfaced suggestions on supported routes
- [DONE] QA-SF-003 Align deterministic and live search-first matrices

View File

@@ -31,6 +31,7 @@ Provide a living plan for UI deliverables, dependencies, and evidence.
- `docs/features/checked/web/topology-trust-administration-ui.md` - shipped verification note for canonical topology and trust setup shells, repaired settings/admin/platform aliases, and platform-setup handoffs.
- `docs/features/checked/web/security-operations-leaves-ui.md` - shipped verification note for mission alerts/activity surfacing, unknowns route repair, notifications ownership, and legacy security alias cutover.
- `docs/features/checked/web/findings-compare-baseline-availability-ui.md` - shipped verification note for the truthful no-baseline findings compare state, disabled export behavior, live findings detail list, and removed stale audit export action.
- `docs/features/checked/web/search-readiness-degraded-answer-state-ui.md` - shipped verification note for truthful degraded-readiness search copy when suggestion viability is unavailable and the active response reports zero indexed matches.
- `docs/features/checked/web/platform-setup-canonical-route-preservation-ui.md` - shipped verification note for preserved `/ops/platform-setup/*` URLs during the shared setup/topology cutover.
- `docs/features/checked/web/release-promotions-cutover-ui.md` - shipped verification note for canonical release promotions routing, alias cutover, release-context wizard handoff, and end-to-end request submission.
- `docs/features/checked/web/evidence-capsules-canonical-cutover-ui.md` - shipped verification note for canonical Evidence-owned capsule routes, `/evidence-packs*` bookmark repair, and AI/release context handoffs.

View File

@@ -1407,11 +1407,13 @@ export class GlobalSearchComponent implements OnInit, OnDestroy {
if (term.length < 1) {
this.searchResponse.set(null);
this.suggestionViability.set(null);
this.suggestionViabilityStatus.set('idle');
this.isLoading.set(false);
this.selectedIndex.set(0);
return of(null);
}
this.refreshSuggestionViability();
this.isLoading.set(true);
const ambient = this.buildAmbientSnapshot();
return this.searchClient.search(term, undefined, 10, ambient).pipe(

View File

@@ -363,6 +363,18 @@ test.describe('Unified Search - Experience Quality UX', () => {
});
test('shows search-readiness guidance instead of blaming the query when the live search corpus is unavailable', async ({ page }) => {
const zeroMatchResponse = {
...emptyResponse('database connectivity'),
diagnostics: {
ftsMatches: 0,
vectorMatches: 0,
entityCardCount: 0,
durationMs: 38,
usedVector: true,
mode: 'hybrid',
},
};
await page.unroute('**/api/v1/search/suggestions/evaluate');
await page.route('**/api/v1/search/suggestions/evaluate', async (route) =>
route.fulfill({
@@ -370,7 +382,7 @@ test.describe('Unified Search - Experience Quality UX', () => {
body: '',
}),
);
await mockSearchResponses(page, () => emptyResponse('database connectivity'));
await mockSearchResponses(page, () => zeroMatchResponse);
await page.goto('/releases/versions');
await expect(page.locator('aside.sidebar')).toBeVisible({ timeout: 15_000 });