Added `BaselineSubjectResolution` page and supporting logic to visualize missing identities, ambiguous matches, and skipped coverages as defined in Spec 384. Replaces legacy compare warnings with an actionable, deterministic UI surface. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #455
49 KiB
Feature Specification: Spec 384 - Baseline Subject Resolution UI and Operator Decisions v1
Feature Branch: 384-baseline-subject-resolution-ui
Created: 2026-06-16
Status: Implemented / Close-out recorded
Input: User-provided candidate "Spec 384 - Baseline Subject Resolution UI & Operator Decisions v1" from /Users/ahmeddarrazi/.codex/attachments/e9f8b1ac-2968-4c6f-8326-af19f7f7b8ad/pasted-text.txt.
Repo-Truth Adjustment
The user supplied a complete numbered candidate for Spec 384. Repo truth confirms:
specs/381-provider-resource-identity-binding/is implemented and closed out. It createdprovider_resource_bindings,ProviderResourceBinding,ProviderResourceBindingService,ProviderResourceResolutionMode, audit IDs, policy coverage, and DB-backed active binding uniqueness.specs/382-baseline-matching-canonicalization/is implemented and closed out. It added provider-resource matching, canonicalization, binding-first matching, and removed legacy/display-name identity paths.specs/383-baseline-result-semantics/is implemented and closed out on the current branch. It added structured compare result semantics and explicitly did not implement Spec 384 operator resolution UI.- Historical
specs/163-baseline-subject-resolution/is related context only. It targeted semantic/evidence gap foundation on existing surfaces and explicitly did not require a new operator screen. It must not be rewritten by this prep.
This prepared Spec 384 narrows the candidate to the smallest implementation-ready slice:
- A focused environment-scoped Baseline Subject Resolution surface.
- A query/read model over existing Spec 383 structured compare outcomes to list actionable subject-resolution items.
- Operator decisions persisted through existing
provider_resource_bindingsandProviderResourceBindingService. - Actions for manual binding, exclusion, accepted limitation, unsupported coverage, missing expected where already supported, and revocation.
- Contextual links from existing Baseline Compare and OperationRun surfaces.
- Audit, RBAC, workspace/environment isolation, and no display-name identity.
- No Evidence/Review readiness final mapping, customer-facing report wording, generic workflow engine, broad Governance Inbox, or Management Report/PDF scope.
V1 reuses current baseline capabilities (workspace_baselines.view and workspace_baselines.manage) unless implementation proves that a separate capability family is required. Introducing granular baseline_subject_resolution.* capabilities would require updating this spec and the plan with a proportionality review before implementation continues.
Candidate Selection Gate
- Selected candidate: Spec 384 - Baseline Subject Resolution UI and Operator Decisions v1.
- Source: Direct user-provided candidate attachment; follow-up references in Specs 381, 382, and 383.
- Why selected: It is the next sequence item after completed Specs 381-383 and is the first visible operator decision layer for unresolved baseline subject identity and coverage outcomes.
- Roadmap relationship: Supports baseline governance productization, provider-neutral identity decisions, auditability, and future Evidence/Review readiness without reopening completed productization or report lanes.
- Close alternatives deferred:
- Spec 385 - Evidence and Review Readiness Integration v1: depends on durable decisions from Spec 384.
- Management Report/PDF runtime validation: unrelated manual follow-through lane.
- Broad Governance Inbox or approval workflow: would turn this into a generic workflow engine and is out of scope.
- Provider readiness onboarding productization: optional manual-promotion backlog, not part of baseline subject resolution.
- Completed-spec guardrail result:
- Specs 381, 382, and 383 are completed and used as dependency context only.
- Spec 163 is historical/adjacent and not selected or modified.
- No existing
specs/384-*package or384-*local/remote branch was found before the Spec Kit create script ran.
- Smallest viable implementation slice: Add one focused resolution page and service/query layer that lets authorized operators make audited binding/scope/limitation decisions for Spec 383 actionable outcomes and then rerun/refresh compare through existing baseline compare mechanisms.
- Gate result: PASS. The candidate is user-provided, not already covered by an active/completed Spec 384 package, aligns with the 381-385 sequence, and is scoped as a bounded UI/decision slice.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: Structured compare outcomes can identify unresolved identity, duplicate candidates, missing provider resources, unsupported coverage, accepted limitations, excluded subjects, and foundation limitations, but operators do not yet have a focused place to turn those outcomes into durable decisions.
- Today's failure: The same actionable blockers can reappear across future compares because operators cannot bind the correct provider resource, exclude a non-governed subject, accept a limitation, mark unsupported coverage, or revoke stale decisions from a safe UI.
- User-visible improvement: Operators can clear real baseline subject decision blockers from a dedicated resolution surface, with clear impact language and links from Baseline Compare and OperationRun context.
- Smallest enterprise-capable version: One environment-scoped resolution page, DB-only decision actions through existing binding service/policy/audit paths, contextual links, and targeted tests.
- Explicit non-goals: No generic workflow engine, no approval workflow, no Governance Inbox, no customer-facing readiness wording, no Evidence/Review final mapping, no Management Report/PDF work, no legacy subject-key UI, and no display-name identity.
- Permanent complexity imported: One focused Filament page or equivalent Livewire/Filament surface, a query/read service for actionable subject outcomes, action form/modal wiring, tests, and UI coverage artifacts. No new primary decision table is approved.
- Why now: Spec 383 now produces structured actionability/readiness semantics, and Spec 385 needs durable operator decisions before evidence/review readiness can be truthful.
- Why not local: Local buttons on existing gap rows would scatter decision behavior across OperationRun, Baseline Compare, and dashboard contexts. A focused page keeps one decision context, one audit path, one RBAC contract, and one route for filtered links.
- Approval class: Core Enterprise.
- Red flags triggered: New UI surface, high-impact decision actions, possible new query/service layer. Defense: the scope reuses existing persisted truth and policy/audit service paths, avoids new workflow tables, and contains decisions to baseline subject resolution only.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve as a narrowed Core Enterprise UI/decision slice.
Problem Statement
Baseline compare can now classify why a governed subject is not fully comparable or ready: unresolved identity, duplicate candidates, missing local evidence, missing provider resource, unsupported resource class, foundation limitation, accepted limitation, excluded non-governed subject, low-trust identity, drift, no drift, or compare failure.
Some of those states require a human decision. Examples:
- A baseline subject has multiple tenant-owned provider candidates and must be bound to the correct resource.
- A foundation object is inventory-only and requires an accepted limitation.
- A subject is intentionally outside governed scope and should be excluded.
- A previously expected provider resource is intentionally absent.
- An accepted limitation or binding is no longer valid and must be revoked.
Without a focused resolution surface, these decisions cannot be made safely, audited consistently, or consumed predictably by later compares.
Business / Product Value
- Converts structured compare blockers into operator actions.
- Reduces repeated false blockers across future baseline compares.
- Preserves auditability for customer-impacting decisions.
- Prevents false green states by making exclusions and accepted limitations explicit and not no-drift.
- Makes Spec 385 Evidence/Review readiness possible without embedding customer-output rules in Spec 384.
- Keeps baseline governance productized without creating a generic workflow engine.
Primary Users / Operators
- Workspace manager or baseline governance operator resolving compare blockers.
- MSP engineer selecting the correct provider resource when multiple candidates exist.
- Support/platform operator diagnosing why compare output remains blocked or limited.
- Release reviewer verifying provider-neutral identity, RBAC, audit, and UI safety.
Spec Scope Fields (mandatory)
- Scope: tenant-owned/environment-owned baseline subject decision surface inside the admin panel.
- Primary Routes: Add an environment-scoped admin page, preferred route
/admin/workspaces/{workspace}/environments/{environment}/baseline-subject-resolution. Existing links may originate from/admin/workspaces/{workspace}/environments/{environment}/baseline-compare, OperationRun detail, environment dashboard, and Baseline Profile detail. - Data Ownership: Existing
provider_resource_bindingsremains tenant-owned operational decision truth. Existing OperationRun context/result payloads remain execution/proof truth. Existing baseline snapshots and compare outputs remain their current truth sources. No new primary decision table is approved. - RBAC: View requires existing baseline compare visibility (
workspace_baselines.view). Mutating decisions require existing baseline manage capability (workspace_baselines.manage) through policies/gates. Non-members are deny-as-not-found. Entitled members missing capability receive forbidden.
For canonical-view specs:
- Default filter behavior when tenant-context is active: Not applicable. The new page is environment-scoped by route. OperationRun links must include environment/workspace-safe filters.
- Explicit entitlement checks preventing cross-tenant leakage: Every page load, query, action, and linked candidate must enforce workspace and managed-environment entitlement before revealing subject, candidate, binding, source run, or audit context.
UI Surface Impact (mandatory - UI-COV-001)
Does this spec add, remove, rename, or materially change any reachable UI surface?
- No UI surface impact
- Existing page changed
- New page/route added
- Navigation changed
- Filament panel/provider surface changed
- New modal/drawer/wizard/action added
- New table/form/state added
- Customer-facing surface changed
- Dangerous action changed
- Status/evidence/review presentation changed
- Workspace/environment context presentation changed
UI/Productization Coverage
- Route/page/surface: New Baseline Subject Resolution page at the environment route above; contextual links from Baseline Compare, OperationRun detail, environment dashboard, and Baseline Profile detail where relevant.
- Current or new page archetype: Decision Workbench / Resolution Queue for an environment-owned governance workflow.
- Design depth: Strategic Surface because it is a new human decision surface with high-impact audited actions.
- Repo-truth level: repo-verified foundations; new page is spec-backed until implemented.
- Existing pattern reused: Existing Baseline Compare page report
docs/ui-ux-enterprise-audit/page-reports/ui-015-baseline-compare.md, OperationRun detail progressive disclosure,UiEnforcement,WorkspaceUiEnforcement,BadgeCatalog, native Filament tables/forms/actions/modals, andProviderResourceBindingService. - New pattern required: Domain pattern for baseline subject resolution, documented through the UI coverage registry during implementation. No target mockup is required before implementation, but a screenshot/browser smoke is required before close-out because this is a new strategic surface.
- List-surface standards: Because this spec adds a new list/table surface, implementation must apply
docs/product/standards/list-surface-review-checklist.mdand record any deviation in the feature close-out. - Screenshot required: yes during implementation close-out for desktop and a narrow/mobile viewport if the page is reachable in browser fixtures.
- Page audit required: yes, add or update a page report for the new route and update the design coverage matrix.
- Customer-safe review required: no. Spec 384 is admin/operator-only. Spec 385 decides customer-facing readiness and limitations.
- Dangerous-action review required: yes. Bind, exclude, accept limitation, mark unsupported, missing expected, and revoke are high-impact governance decisions that require confirmation, server-side authorization, required notes where specified, audit, and tests.
- Coverage files updated or explicitly not needed:
docs/ui-ux-enterprise-audit/route-inventory.mddocs/ui-ux-enterprise-audit/design-coverage-matrix.mddocs/ui-ux-enterprise-audit/page-reports/...docs/ui-ux-enterprise-audit/strategic-surfaces.mddocs/ui-ux-enterprise-audit/grouped-follow-up-candidates.mddocs/ui-ux-enterprise-audit/unresolved-pages.mdN/A - no reachable UI surface impact
- No-impact rationale when applicable: Not applicable.
Cross-Cutting / Shared Pattern Reuse
- Cross-cutting feature?: yes.
- Interaction class(es): status messaging, action links, header actions, deep links, audit entries, OperationRun follow-up links, baseline compare evidence/status presentation, and high-impact Filament action modals.
- Systems touched: Baseline Compare page, OperationRun detail, baseline compare evidence gap table/presentation, environment dashboard summaries where present, provider resource binding service/policy/audit, baseline compare rerun links, UI coverage registry, tests.
- Existing pattern(s) to extend: Native Filament pages/tables/forms/actions,
UiEnforcementandWorkspaceUiEnforcement,ProviderResourceBindingService,ProviderResourceBindingPolicy,AuditRecorder,OperationRunLinks,OperationUxPresenterfor rerun/start UX if rerun is offered. - Shared contract / presenter / builder / renderer to reuse:
ProviderResourceBindingServicefor all decisions; existing OperationRun link helpers; existing badge/status helpers; existing reason/presentation helpers where status labels are rendered. - Why the existing shared path is sufficient or insufficient: Binding mutation paths already exist and are sufficient for decision truth. A new query/read surface is needed because current evidence-gap tables are read-only and do not provide a single decision context for candidates, current decisions, and audit history.
- Allowed deviation and why: A focused resolution query/read service may be added because it derives one operator worklist from structured compare outcomes and existing bindings. It must not become a generic workflow, task, or approval engine.
- Consistency impact: Baseline Compare, OperationRun follow-ups, and the new page must use the same actionability/readiness/result semantics and must not invent separate labels for the same blocker.
- Review focus: no display-name identity, no local authorization-only UI visibility, no duplicate decision table, no customer readiness wording, no ad-hoc OperationRun start UX, no raw provider identifiers as primary UI.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: yes for links and optional rerun/refresh only; no new OperationRun type is created by resolution decisions.
- Shared OperationRun UX contract/layer reused: Existing Baseline Compare start/rerun UX,
OperationRunLinks, andOperationUxPresentermust be reused if the page offers rerun/refresh compare. - Delegated start/completion UX behaviors: Any queued toast, run link, browser event, dedupe/already-running messaging, terminal notification, and tenant/workspace-safe operation URL resolution must remain delegated to existing baseline compare OperationRun UX paths.
- Local surface-owned behavior that remains: The resolution page may collect decision inputs and may offer a navigation/control to rerun compare, but it must not locally compose queued operation notifications or run lifecycle semantics.
- Queued DB-notification policy: no new queued DB notifications. Existing baseline compare terminal notification behavior remains unchanged.
- Terminal notification path: existing OperationRun lifecycle mechanism only.
- Exception required?: none.
Resolution decisions themselves are DB-only audited mutations and do not create an OperationRun. Baseline compare rerun remains the existing queued/observable operation.
Provider Boundary / Platform Core Check
- Shared provider/platform boundary touched?: yes.
- Boundary classification: mixed. The resolution workflow and decision semantics are platform-core; provider resource descriptors and concrete IDs remain provider-owned proof.
- Seams affected: governed subject identity, provider resource binding, canonical subject key, candidate presentation, compare actionability, audit metadata, operator vocabulary.
- Neutral platform terms preserved or introduced: governed subject, provider resource, binding, exclusion, accepted limitation, unsupported coverage, missing expected, actionability, readiness impact, decision.
- Provider-specific semantics retained and why: provider key, provider resource type, provider resource ID, external ID, and descriptors are retained as proof/candidate data because the operator must bind to real provider resources. They must not become display-name identity or platform-wide taxonomy.
- Why this does not deepen provider coupling accidentally: The UI uses existing provider-neutral descriptors and stable resource identity metadata. Microsoft/Intune labels may appear only as provider-provided labels, not as canonical identity or core branching logic.
- Follow-up path: Spec 385 consumes the decisions for evidence/review readiness. Granular capability family, approval workflow, decision expiration, or customer output mapping require separate spec updates/follow-ups.
UI / Surface Guardrail Impact
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | yes | Native Filament page/table/actions with shared primitives | decision workbench, status messaging, action links, audit | page, URL-query, detail/modal | no | New strategic surface; requires coverage registry and browser smoke |
| Baseline Compare contextual link/counts | yes | Existing native/shared surface | status messaging, header/context action | page, URL-query | no | Existing route changed only to link/count unresolved decisions |
| OperationRun follow-up link | yes | Existing OperationRun detail surface | OperationRun proof and follow-up link | detail, URL-query | no | Link only; no local run UX |
| Environment dashboard/Baseline Profile shortcuts | yes, if implemented | Existing native/shared surfaces | dashboard signal/action link | page, URL-query | no | Summary link only; no redesign |
Decision-First Surface Role
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | Primary Decision Surface | Resolve unresolved identity or scope/coverage decision blockers | subject label, reason, readiness impact, actionability, candidate count, current decision, safe primary action | raw provider IDs, source inventory/policy/run proof, audit history | Primary because this is where the operator makes the binding/exclusion/limitation decision | Follows "resolve compare blockers" workflow, not storage object browsing | Removes search across run detail, gap table, binding records, and audit logs |
| Baseline Compare page | Secondary Context Surface | Decide whether compare output needs subject resolution | action-required counts and one link to resolution | full gap table and run proof | Secondary because it identifies the need but does not host all decision inputs | Follows compare review workflow | Directs operator to one focused resolution surface |
| OperationRun detail | Tertiary Evidence / Diagnostics Surface with follow-up | Understand why a run is blocked and open filtered resolution | concise follow-up text and filtered link | raw run context, gap proof, diagnostics | Tertiary because it proves execution and points to decision surface | Follows operation troubleshooting workflow | Avoids requiring operators to resolve from raw run context |
Audience-Aware Disclosure
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | operator-MSP, support-platform | blocker reason, subject class/type, environment, readiness impact, candidate count, current decision, required action | candidate details, source run, source inventory/policy references, compare context | full provider IDs, external IDs, fingerprints, raw proof payloads, audit history | Resolve subject or revoke decision | raw identifiers and proof stay truncated/collapsed/capability-gated where applicable | page owns the decision summary; linked surfaces show counts and route into it |
UI/UX Surface Classification
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | Queue / Table / Workbench | Decision workbench | Resolve subject | row focus opens detail drawer/modal or focused detail area | allowed if it opens the same detail as primary inspect | secondary navigation in row More or detail area | high-impact state changes in confirmed actions, grouped by risk | /admin/workspaces/{workspace}/environments/{environment}/baseline-subject-resolution |
same route with query/focused subject or modal state | workspace and environment are visible from route/page context | Baseline subject decision | actionability, reason, readiness impact, current decision, candidate count | none |
Operator Surface Contract
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | Baseline governance operator | Bind, exclude, accept limitation, mark unsupported/missing expected, revoke | Primary Decision Surface | What subject decision is blocking compare, and what action is safe now? | subject, problem, readiness impact, actionability, candidates, current decision, environment, next action | raw provider IDs, fingerprints, source proof, full audit trail | identity, comparison, coverage, actionability, readiness, decision status | TenantPilot only for decision storage; future compare uses it; no direct provider mutation | Bind subject, Exclude subject, Accept limitation, Mark unsupported, Revoke decision, Run comparison again | exclude, accept limitation, mark unsupported, missing expected, revoke, and manual binding are high-impact and require confirmation, server authorization, note rules, and audit |
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no new source of truth. Existing active
provider_resource_bindingsremains the durable decision truth. The resolution query is derived from existing compare output and active bindings. - New persisted entity/table/artifact?: no new primary table or artifact is approved. Additive fields/indexes are out of scope unless implementation updates this spec and proves current-release need.
- New abstraction?: yes, a focused query/read service may be introduced to derive actionable resolution rows from existing OperationRun/compare payloads and bindings.
- New enum/state/reason family?: no new V1 reason family is approved. Use existing
ProviderResourceResolutionMode,ProviderResourceBindingStatus, and Spec 383 compare semantics. - New cross-domain UI framework/taxonomy?: no. Use native Filament/shared primitives and direct mapping from canonical domain truth.
- Current operator problem: Operators cannot act on actionable subject-resolution blockers without manually reconstructing candidates and decisions from run payloads and binding records.
- Existing structure is insufficient because: Existing gap tables are read-only, OperationRun detail is diagnostics-oriented, and binding service methods have no focused operator surface or filtered worklist.
- Narrowest correct implementation: One derived query/read service, one environment-scoped page, and action modals wired to existing binding service/policy/audit.
- Ownership cost: A new page/query/test surface and UI coverage registry updates. Reviewers must prevent it from growing into a broad workflow/approval engine.
- Alternative intentionally rejected: Add local buttons to evidence-gap rows only. That would scatter decision state, duplicate action semantics, and make OperationRun/Baseline Compare surfaces own decisions they should only link to.
- Release truth: Current-release truth. Specs 381-383 have prepared the backend and semantics; operator resolution is now the missing product layer.
Compatibility posture
TenantPilot is pre-production. V1 must not add legacy subject-key UI, old OperationRun payload readers, display-name matching, display-name-derived canonical keys, historical payload compatibility screens, or dual old/new decision paths.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Unit for query/read service and binding service guard cases; Feature for DB/action/RBAC/audit/future-compare behavior; Filament/Livewire action tests for page/table/modals; Browser smoke for the new reachable decision surface.
- Validation lane(s): fast-feedback, confidence, browser. PostgreSQL lane only if implementation adds indexes, constraints, locks, JSONB query behavior, or migrations.
- Why this classification and these lanes are sufficient: The feature is a DB-only decision workflow plus Filament/Livewire surface. No provider calls or direct Microsoft mutations are introduced.
- New or expanded test families: focused
BaselineSubjectResolution*tests, ProviderResourceBinding decision/action tests, OperationRun follow-up tests, baseline compare rerun/consumption regression, and one browser smoke for the new page. - Fixture / helper cost impact: reuse existing baseline compare matrix/gap fixtures and provider-resource binding factories. Any new provider candidates or workspace/environment setup must stay feature-local and opt-in.
- Heavy-family visibility / justification: no heavy-governance family by default. Browser smoke is explicit because this adds a strategic surface with high-impact actions.
- Special surface test profile:
shared-detail-familyplusstandard-native-filamentfor native Filament table/action behavior. - Standard-native relief or required special coverage: ordinary Filament action tests for native actions; browser smoke for route/page/action-modal reachability and no JS/visual overlap.
- Reviewer handoff: verify lane fit, no display-name identity, no local OperationRun UX, no new table without spec update, no customer readiness mapping, and every high-impact action has confirmation, server authorization, audit, and tests.
- Budget / baseline / trend impact: expected moderate feature/Filament test increase. Escalate as
document-in-featureif browser fixtures are expensive;follow-up-speconly if a reusable resolution-workbench pattern is needed later. - Escalation needed: document-in-feature for UI coverage/browser-smoke notes; follow-up-spec for approval workflow, decision expiration, granular capabilities, or customer readiness.
- Active feature PR close-out entry: Baseline Subject Resolution UI / Operator Decision Coverage.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Baselines tests/Unit/Support/Resourcescd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Baselines tests/Feature/ProviderResourcescd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineSubjectResolutionPageTest.php tests/Feature/Filament/OperationRunSubjectResolutionFollowUpTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Evidence/BaselineDriftPostureSourceTest.php tests/Feature/ReviewPack/Spec347ReviewPackReadinessSemanticsTest.php tests/Feature/ReviewPack/Spec349ReviewPackResolutionGuidanceTest.phpcd apps/platform && ./vendor/bin/sail test:browser --filter BaselineSubjectResolutioncd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentgit diff --check
User Scenarios & Testing (mandatory)
User Story 1 - Find actionable subject decisions (Priority: P1)
As a baseline governance operator, I need one filtered page that lists unresolved or decision-required baseline subjects from the current compare context, so I can see what blocks trustworthy compare output without reading raw run payloads.
Why this priority: This is the MVP because decisions cannot be made safely until the operator can see actionable subjects and candidates in one context.
Independent Test: Given a baseline compare run with unresolved duplicate candidates, missing provider resources, unsupported coverage, accepted limitations, and excluded subjects, the page lists only actionable items by default, supports filters, and shows empty states when no decisions are required.
Acceptance Scenarios:
- Given an environment has a latest baseline compare with duplicate provider candidates, When an entitled operator opens Baseline Subject Resolution, Then the subject appears with problem, candidate count, readiness impact, actionability, and a resolve action.
- Given a compare has only trusted no-drift and resolved subjects, When the page loads, Then the empty state says no baseline subject decisions are required.
- Given no compare context exists for the environment, When the page loads, Then the empty state directs the operator to run baseline compare first.
User Story 2 - Make audited resolution decisions (Priority: P1)
As an authorized operator, I need to bind a subject to a provider resource, exclude it, accept a limitation, mark unsupported or missing expected, and revoke stale decisions, so future compares can consume real operator decisions.
Why this priority: This is the primary product value. The page must do more than report blockers; it must create durable audited decisions.
Independent Test: Each decision action is executed through the page against a scoped subject and candidate; the resulting active binding/decision exists, previous active decision is superseded or revoked, audit is written, and unauthorized actors are denied.
Acceptance Scenarios:
- Given a subject has valid provider candidates, When an authorized operator binds one candidate with a note, Then an active
manual_bindingdecision is persisted and audited. - Given a subject is intentionally not governed, When an authorized operator excludes it with a reason and note, Then an active
excluded_non_governeddecision is persisted and the UI states that exclusion is not no-drift. - Given an active decision exists, When an authorized operator revokes it with a note, Then the decision becomes inactive for future compares and the revocation is audited.
- Given a subject has only display-label data and no valid provider identity, When an operator attempts to bind it, Then the action is blocked and no display-name identity is stored.
User Story 3 - Navigate from compare and operation context (Priority: P2)
As an operator reviewing compare output or an OperationRun, I need contextual links into the resolution page with filters already applied, so I can resolve blockers without reconstructing context manually.
Why this priority: Links make the decision surface discoverable while avoiding a broad top-level workflow hub.
Independent Test: OperationRun detail and Baseline Compare surface show resolution counts/links only when actionable subject-resolution outcomes exist; links open the resolution page scoped to the same workspace/environment and filtered by operation run/reason/actionability.
Acceptance Scenarios:
- Given a baseline compare OperationRun has actionable subject-resolution outcomes, When an entitled operator opens the run detail, Then the follow-up link opens the resolution page filtered to that run.
- Given Baseline Compare has action-required subject outcomes, When the operator opens the compare page, Then the page shows a concise count and a "Resolve baseline subjects" link.
- Given the operator lacks manage capability, When they follow the link, Then they can view entitled resolution context but decision actions are disabled or forbidden according to the 404/403 rules.
User Story 4 - Re-run or refresh compare after decisions (Priority: P3)
As an operator who has resolved one or more subject decisions, I need a clear path to run or refresh baseline compare through existing operation UX, so I can confirm whether blockers are cleared.
Why this priority: Decisions affect future compares, but starting a compare must remain in the existing queued/observable baseline compare workflow.
Independent Test: After decisions are saved, the page offers a rerun/refresh path that delegates to existing baseline compare start UX and does not create local OperationRun messaging.
Acceptance Scenarios:
- Given a decision was saved, When the operator chooses to run comparison again, Then the existing baseline compare service and OperationRun UX are used.
- Given the next compare consumes an active decision, When results are rendered, Then the subject is no longer listed as unresolved for the same reason.
Edge Cases
- A subject has multiple candidates with similar display labels but different provider identities.
- A subject has no valid
ResourceIdentity; display label exists only for human readability. - The previous active decision was superseded, revoked, or belongs to another workspace/environment.
- A user is a workspace/environment member but lacks manage capability.
- A user is not entitled to the workspace or environment.
- A linked OperationRun is from another environment or workspace.
- Compare payload lacks structured Spec 383 semantics; the page must not parse legacy payloads and should show a safe empty/error state.
- Provider resource IDs or external IDs are long or sensitive; primary UI truncates/masks and pushes full details into diagnostics.
- Accepted limitation, excluded, unsupported, and missing expected decisions must never render as verified no-drift.
Requirements (mandatory)
Constitution alignment (required): This feature adds DB-only high-impact governance decisions and a new operator surface. It does not add Graph calls, direct provider mutations, new OperationRun type, or new persisted decision table. Every decision must use server-side authorization, confirmation, required note rules where specified, audit logging, workspace/environment isolation, and tests.
Constitution alignment (RBAC-UX): Non-members receive deny-as-not-found before any subject, candidate, binding, or run detail is exposed. Entitled members missing capability receive forbidden for execution; UI visibility/disabled state is never the security boundary.
Constitution alignment (OPS-UX): Resolution decisions do not create an OperationRun. Any rerun/refresh compare path must reuse existing baseline compare OperationRun start UX. OperationRun status/outcome transitions remain service-owned.
Constitution alignment (UI-COV-001): The feature adds a new strategic operator surface and high-impact actions, so implementation must update UI coverage artifacts and perform browser smoke.
Constitution alignment (PROV-001): Provider identifiers are proof/candidate data, not platform-core semantics. Display names remain labels only.
Constitution alignment (TEST-GOV-001): Unit, feature, Filament/Livewire, and browser lanes are explicitly planned. Fixture setup must remain feature-local and opt-in.
Functional Requirements
- FR-384-001: TenantPilot MUST provide a focused Baseline Subject Resolution surface scoped to workspace and managed environment.
- FR-384-002: The surface MUST derive actionable items from Spec 383 structured compare semantics and existing active binding decisions.
- FR-384-003: The surface MUST NOT parse legacy subject-key or historical compare payload shapes as authoritative resolution input.
- FR-384-004: The default list MUST show subject, subject class, resource type, provider, environment, problem, readiness impact, actionability, candidate count, current decision, last seen/source context, and available action.
- FR-384-005: The list MUST support filters for environment context, provider, subject class, resource type, actionability, readiness impact, reason, active binding, candidates, and operation run where relevant.
- FR-384-006: The page MUST show safe empty states for no decisions required and for no compare context available.
- FR-384-007: Operators MUST be able to bind unresolved subjects to valid provider resources through
manual_binding. - FR-384-008: Operators MUST be able to confirm canonical built-in or virtual target decisions only when the candidate identity comes from provider/canonical metadata, not display names.
- FR-384-009: Operators MUST be able to exclude a subject as non-governed through
excluded_non_governed. - FR-384-010: Operators MUST be able to accept a limitation through
accepted_limitation. - FR-384-011: Operators MUST be able to mark unsupported coverage through
unsupported_coverage. - FR-384-012: Operators SHOULD be able to mark missing expected through
missing_expectedif existing service/model support is sufficient without new persistence. - FR-384-013: Operators MUST be able to revoke an active decision.
- FR-384-014: Manual binding, exclusion, accepted limitation, unsupported coverage, missing expected, and revocation MUST require an operator note.
- FR-384-015: Decision actions MUST supersede previous active decisions for the same scoped canonical subject according to existing binding service behavior.
- FR-384-016: Revoked decisions MUST NOT affect future baseline compares.
- FR-384-017: Every manual decision MUST emit audit metadata including actor, workspace, environment, provider, subject key, mode, previous/new decision where applicable, note metadata, source compare/run, and source references when available.
- FR-384-018: Every action MUST enforce workspace/environment scoped authorization server-side.
- FR-384-019: Non-member access MUST be denied as not found; entitled members missing manage capability MUST be forbidden on mutation.
- FR-384-020: Display names MUST NOT be accepted or persisted as identity. They may appear only as labels.
- FR-384-021: OperationRun detail MUST link to filtered resolution context where actionable subject-resolution outcomes exist.
- FR-384-022: Baseline Compare MUST link to the resolution surface where actionable outcomes exist.
- FR-384-023: Environment dashboard and Baseline Profile shortcuts MAY be added only as summary links, not full redesigns.
- FR-384-024: The page MUST offer a safe path to rerun/refresh comparison through existing baseline compare OperationRun UX.
- FR-384-025: Subsequent baseline compares MUST consume active decisions through the existing matching pipeline.
- FR-384-026: Accepted limitation, exclusion, unsupported, and missing expected decisions MUST NOT be presented as verified no-drift.
- FR-384-027: The feature MUST NOT finalize Evidence Snapshot readiness, Review Pack publication readiness, or customer-facing limitation wording.
- FR-384-028: The feature MUST NOT introduce a generic workflow/task/approval engine.
Non-Functional Requirements
- NFR-384-001: Workspace isolation is mandatory for all reads, candidates, decisions, links, and audit context.
- NFR-384-002: Managed-environment isolation is mandatory; decisions must not cross environment boundaries.
- NFR-384-003: Rendering the page and details must be DB-only and must not call Graph or provider runtime APIs.
- NFR-384-004: Provider resource IDs and external IDs must be truncated or progressively disclosed by default.
- NFR-384-005: The UI must be calm, scan-first, and decision-led, with diagnostics secondary.
- NFR-384-006: Native Filament components/shared primitives must be used before custom Blade or local styling.
- NFR-384-007: High-impact action modals must clearly state mutation scope: TenantPilot decision only, not direct provider mutation.
- NFR-384-008: Test fixtures must remain feature-local and must not widen default provider/workspace setup.
UI Action Matrix (mandatory when Filament is changed)
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Baseline Subject Resolution page | apps/platform/app/Filament/Pages/... preferred |
Run comparison again only if delegated to existing compare UX; no broad nav action |
row focus/detail drawer or focused detail area; exactly one inspect model | primary contextual Resolve or Review decision; risky actions in modal/detail More |
none in V1 | Run baseline compare if no compare context and user can manage; no CTA when no decisions required unless compare rerun is useful |
N/A unless detail subpage is chosen | N/A | yes for every decision action through binding service | Action labels must use Verb + Object. Destructive/high-impact actions require confirmation, authorization, note rules, and audit. |
| Baseline Compare page link | existing BaselineCompareLanding |
Resolve baseline subjects link only when actionable outcomes exist |
existing inspect paths unchanged | no new row mutation | none | existing compare CTA remains | N/A | N/A | N/A for link | Link is navigation, not mutation. |
| OperationRun detail follow-up | existing OperationRunResource detail |
no new mutation | existing detail sections unchanged | follow-up link only | none | N/A | N/A | N/A | N/A for link | Link opens filtered resolution page; no local run UX. |
Key Entities
- Baseline subject decision row: Derived UI row representing a governed subject outcome from structured compare semantics plus current binding/decision state.
- Provider resource candidate: A provider-backed identity option with
ResourceIdentity/descriptor proof that can be selected for binding. - Provider resource binding: Existing persisted decision truth in
provider_resource_bindings. - Resolution mode: Existing
ProviderResourceResolutionModevalue such asmanual_binding,excluded_non_governed,accepted_limitation,unsupported_coverage, ormissing_expected. - Current decision: Active binding/decision for a scoped canonical subject.
Out of Scope
- Evidence Snapshot readiness final mapping.
- Review Output readiness or Review Pack publication blocker final mapping.
- Customer-facing report wording.
- Generic workflow/task/approval engine.
- Broad Governance Inbox.
- Management Report/PDF runtime or staging validation.
- Legacy subject-key UI or old OperationRun payload compatibility UI.
- Display-name-based matching or binding.
- Broad Baseline Profile redesign.
- Bulk destructive actions.
- New primary decision table.
- Direct Graph/provider mutation.
- New granular capability family unless this spec and plan are updated first.
Acceptance Criteria
- AC-384-001: A focused Baseline Subject Resolution page exists and is reachable through environment-scoped admin routing.
- AC-384-002: The page lists actionable outcomes from Spec 383 semantics and hides resolved/no-action subjects by default.
- AC-384-003: Manual binding to a valid provider resource creates or supersedes an active audited decision.
- AC-384-004: Exclusion, accepted limitation, unsupported coverage, missing expected where supported, and revocation actions require notes, confirmation, authorization, and audit.
- AC-384-005: Unauthorized/non-entitled access follows 404/403 rules.
- AC-384-006: Display-name-only identity is rejected.
- AC-384-007: OperationRun and Baseline Compare contextual links open filtered resolution context.
- AC-384-008: Future compare consumes active decisions and ignores revoked decisions.
- AC-384-009: Exclusion and accepted limitation are not displayed as verified no-drift.
- AC-384-010: UI coverage registry and browser smoke evidence are updated during implementation.
- AC-384-011: No Evidence/Review final mapping, customer-facing wording, Management Report/PDF work, or workflow engine is introduced.
Success Criteria (mandatory)
Measurable Outcomes
- SC-384-001: In validation fixtures with actionable subject blockers, an entitled operator can identify the problem, candidate count, current decision, and next action for each subject from the default page without opening raw diagnostics.
- SC-384-002: 100% of decision actions in targeted tests write an audit entry and enforce server-side authorization.
- SC-384-003: 100% of display-name-only binding attempts in targeted tests are rejected without creating or updating a binding.
- SC-384-004: After an active binding/exclusion/limitation decision is created and compare is rerun in targeted tests, the same subject no longer appears as unresolved for the prior reason.
- SC-384-005: Automated or manual browser smoke reaches the new surface and verifies the page is nonblank, scoped, and action modals are reachable without overlapping or broken UI.
Assumptions
- Specs 381, 382, and 383 remain implemented on the target branch before Spec 384 implementation begins.
- Existing
provider_resource_bindingsfields and modes are sufficient for V1 decisions. - Existing baseline capabilities are sufficient for V1 RBAC; granular capabilities are a later follow-up unless proven necessary.
- Resolution decisions are TenantPilot-only DB decisions and do not mutate provider resources.
- Existing compare rerun/start behavior remains the only path for refreshing compare output.
- Browser fixtures can provide a reachable workspace/environment/baseline compare scenario; if not, implementation must perform and document manual browser-smoke evidence instead of skipping browser validation.
Risks
- Workflow creep: The surface could become a generic remediation queue. Mitigation: only baseline subject decision actions are in scope.
- False green: Accepted limitations or exclusions could look healthy. Mitigation: UI and tests must state they are not no-drift.
- Identity regression: Display names could be treated as identity. Mitigation: bind only valid
ResourceIdentitycandidates. - Permission risk: Operators could hide real issues. Mitigation: manage capability, required notes, confirmations, and audit.
- UI noise: Too many categories can overwhelm operators. Mitigation: group by actionability and keep diagnostics progressive.
- Provider-specific leakage: Microsoft labels could become core truth. Mitigation: keep provider-specific data as descriptors/proof only.
Open Questions
No open question blocks implementation readiness.
Non-blocking follow-up decisions:
- Whether a later spec should introduce granular
baseline_subject_resolution.*capabilities. - Whether accepted limitations should expire or require renewal.
- Whether subject-level exclusions should later roll up to Baseline Profile scope policy.
- Whether revocation history should appear in the main list or only in compact audit history after V1.
Follow-Up Spec Candidates
- Spec 385 - Evidence and Review Readiness Integration v1.
- Accepted limitation expiry and renewal policy.
- Granular baseline subject resolution capabilities.
- Baseline Profile subject-scope policy productization.
- Approval workflow for high-risk exclusions, if customer evidence demands it.