TenantAtlas/specs/235-baseline-capture-truth/spec.md
ahmido 2752515da5
Some checks failed
Main Confidence / confidence (push) Failing after 54s
Spec 235: harden baseline truth and onboarding flows (#271)
## Summary
- harden baseline capture truth, compare readiness, and monitoring explanations around latest inventory eligibility, blocked prerequisites, and zero-subject outcomes
- improve onboarding verification and bootstrap recovery handling, including admin-consent callback invalidation and queued execution legitimacy/report behavior
- align workspace findings/workspace overview signals and refresh the related spec, roadmap, and spec-candidate artifacts

## Validation
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/BaselineDriftEngine/BaselineCaptureAuditEventsTest.php tests/Feature/BaselineDriftEngine/BaselineSnapshotNoTenantIdentifiersTest.php tests/Feature/BaselineDriftEngine/CaptureBaselineContentTest.php tests/Feature/BaselineDriftEngine/CaptureBaselineFullContentOnDemandTest.php tests/Feature/BaselineDriftEngine/CaptureBaselineMetaFallbackTest.php tests/Feature/Baselines/BaselineCaptureTest.php tests/Feature/Baselines/BaselineCompareFindingsTest.php tests/Feature/Baselines/BaselineSnapshotBackfillTest.php tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php tests/Feature/Monitoring/AuditCoverageGovernanceTest.php tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php tests/Feature/Notifications/OperationRunNotificationTest.php tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/AdminConsentCallbackTest.php tests/Feature/Filament/WorkspaceOverviewDbOnlyTest.php tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Feature/Onboarding/OnboardingVerificationTest.php tests/Feature/Operations/QueuedExecutionAuditTrailTest.php tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php`

## Notes
- browser validation was not re-run in this pass

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #271
2026-04-24 05:44:54 +00:00

37 KiB

Feature Specification: Baseline Capture Truthful Outcomes and Upstream Guardrails

Feature Branch: 235-baseline-capture-truth
Created: 2026-04-23
Status: Draft
Input: User description: "Baseline Capture Truthful Outcomes and Upstream Guardrails"

Spec Candidate Check (mandatory — SPEC-GATE-001)

  • Problem: Baseline capture can still present a green success path when no credible baseline was actually produced because the upstream inventory basis was unusable or because zero in-scope subjects resolved.
  • Today's failure: Operators can read a completed baseline capture run, an all-zero summary, or an empty/reused artifact as if the baseline was successfully refreshed even when there is no trustworthy baseline to compare against.
  • User-visible improvement: Capture start surfaces warn early, run detail states the real cause and next action first, and a failed or no-data capture no longer silently replaces the last trustworthy baseline.
  • Smallest enterprise-capable version: Reuse the existing snapshot lifecycle/usability rules from Spec 159 and the existing governance run-summary path from Spec 220, then harden only inventory eligibility, capture outcome mapping, reason codes, and no-data artifact promotion rules for baseline capture.
  • Explicit non-goals: No redesign of the whole OperationRun platform, no broad rewrite of inventory coverage semantics, no compare-engine redesign, no generic no-data framework for all operation types, no new artifact-lifecycle taxonomy, and no silent stale-inventory fallback.
  • Permanent complexity imported: A bounded extension of existing BaselineReasonCodes, translation/presenter mappings for baseline capture truth, a few targeted start-surface and run-detail states, and focused regression coverage.
  • Why now: This is a near-term governance hardening item and a direct trust gap in one of TenantPilot's core promises: a captured baseline must be meaningful and safe to reason about.
  • Why not local: The failure crosses capture execution, capture preflight, snapshot promotion, compare availability, Monitoring run detail, and audit/notification translation. A local copy fix would leave the same false-green semantics active elsewhere.
  • Approval class: Core Enterprise
  • Red flags triggered: Cross-cutting status messaging; queued-work truth semantics; current-release operator trust on a core governance artifact. Defense: the slice stays narrow by reusing existing baseline snapshot and Ops UX primitives rather than inventing a new generic framework.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexität: 1 | Produktnähe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve

Spec Scope Fields (mandatory)

  • Scope: workspace
  • Primary Routes: /admin/baseline-profiles/{record}, /admin/baseline-snapshots/{record}, /admin/t/{tenant}/baseline-compare, /admin/operations/{run}
  • Data Ownership: workspace-owned BaselineProfile and BaselineSnapshot truth, tenant-scoped baseline capture and inventory OperationRun context, workspace audit entries
  • RBAC: Existing workspace membership plus current baseline visibility/capture capability on /admin, tenant entitlement plus current compare capability on /admin/t/{tenant}/..., and existing Monitoring visibility plus tenant entitlement for tenant-bound run detail

Cross-Cutting / Shared Pattern Reuse (mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write N/A - no shared interaction family touched)

  • Cross-cutting feature?: yes
  • Interaction class(es): status messaging, header actions, run-detail explanations, audit prose, reason translation, terminal notification copy
  • Systems touched: baseline capture start surfaces, baseline compare availability surfaces, snapshot-truth presentation, Monitoring run detail, audit summary text, canonical reason translation
  • Existing pattern(s) to extend: existing BaselineCompareStats preflight reason-code path, existing snapshot lifecycle/usability contract from Spec 159, and the governance run-summary-first path from Spec 220
  • Shared contract / presenter / builder / renderer to reuse: App\Support\Baselines\BaselineReasonCodes, App\Support\Baselines\BaselineCompareStats, App\Services\OperationRunService, App\Support\OpsUx\OperationUxPresenter, App\Support\OpsUx\GovernanceRunDiagnosticSummaryBuilder, App\Support\Ui\OperatorExplanation\OperatorExplanationBuilder, and the existing ReasonTranslator
  • Why the existing shared path is sufficient or insufficient: The existing shared path already handles compare unavailability, centralized reason translation, and summary-first governance run explanations. The gap is baseline capture truthfulness, not the lack of a shared presentation path.
  • Allowed deviation and why: none
  • Consistency impact: The same reason code and operator message must mean the same thing on the profile view, compare landing, snapshot view, Monitoring run detail, audit summary, and any terminal notification derived from the run.
  • Review focus: Verify that no page-local copy branch or ad-hoc status mapping appears outside the shared baseline reason/summary/explanation path.

UI / Surface Guardrail Impact (mandatory when operator-facing surfaces are changed; otherwise write N/A)

Surface / Change Operator-facing surface change? Native vs Custom Shared-Family Relevance State Layers Touched Exception Needed? Low-Impact / N/A Note
Baseline profile view capture truth and header actions yes Native Filament + shared baseline/Ops UX primitives header actions, status messaging page, header action, related detail no n/a
Baseline compare landing availability and guidance yes Native Filament + shared baseline stats header actions, status messaging, navigation handoff page, action, explanation no n/a
Baseline snapshot detail no-data artifact messaging yes Native Filament + shared truth presenters status messaging, related navigation detail, artifact truth no n/a
Monitoring run detail for baseline capture yes Native Filament + shared Ops UX presenters status messaging, run summaries, audit-aligned explanation detail, diagnostics no n/a

Decision-First Surface Role (mandatory when operator-facing surfaces are changed)

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 profile view capture truth and header actions Secondary Context Surface Decide whether a new capture is safe to start or whether the current trustworthy baseline should remain in place Effective current baseline truth, latest capture truth, next safe action Historical snapshots, raw run context, low-level capture gaps Not primary because it is one profile's context page, not the tenant-wide decision queue Follows baseline maintenance workflow Removes the need to jump to Monitoring just to learn whether capture is safe
Baseline compare landing availability and guidance Primary Decision Surface Decide whether compare can run now or whether prerequisite work is required first Assigned profile, consumable baseline truth, dominant block reason, next action Compare matrix, related run detail, raw artifact history Primary because it is the tenant-scoped decision entry for compare Follows tenant baseline review workflow Stops operators from opening matrix or Monitoring first to discover a prerequisite failure
Baseline snapshot detail no-data artifact messaging Secondary Context Surface Decide whether a captured artifact is trustworthy, historical, or only an audit trace Lifecycle/usability, produced-run effect, whether the artifact can become current truth Raw metadata, counts, related run diagnostics Not primary because it explains an artifact after the operator chooses to inspect it Follows artifact review after capture Prevents operators from reading a zero-item artifact as a normal complete baseline
Monitoring run detail for baseline capture Tertiary Evidence / Diagnostics Surface Understand why the run did or did not produce a usable baseline after execution Dominant cause, next step, effect on current baseline truth Raw JSON, numeric counts, low-level inventory references Not primary because it is investigation after a run exists Follows Monitoring and audit review workflow Keeps investigation focused by stating the real capture truth before raw diagnostics

UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)

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 profile view capture truth and header actions Detail / Record View-first Resource Capture baseline or keep current trustworthy snapshot Header-led record view n/a Secondary safe actions in existing header grouping order Existing archive action only, still on detail header with confirmation /admin/baseline-profiles /admin/baseline-profiles/{record} Workspace context and related tenant assignment context Baseline profiles / Baseline profile Whether current baseline truth is still trustworthy and whether a new capture is safe none
Baseline compare landing availability and guidance Workflow / Start Surface Explanation-first Action Landing Run compare or fix the prerequisite first Single-page workflow entry forbidden Pure navigation to compare matrix or related record stays secondary none /admin/t/{tenant}/baseline-compare /admin/t/{tenant}/baseline-compare Tenant chip, assigned profile, current baseline state Baseline compare / Compare Whether compare is safe to run now and why not if blocked none
Baseline snapshot detail no-data artifact messaging Detail / Record Immutable Artifact Detail Open related record or accept that the artifact is only historical/no-data evidence Record detail page required from list Related-record links only none /admin/baseline-snapshots /admin/baseline-snapshots/{record} Workspace context, related profile, producing run Baseline snapshots / Baseline snapshot Whether the artifact is consumable current truth, historical, or only a no-data trace Existing immutable-artifact exemption
Monitoring run detail for baseline capture Detail / Diagnostics Operation Run Detail Open related baseline profile or rerun inventory/capture with the right prerequisite Run detail page n/a Related artifact/navigation actions stay secondary none /admin/operations /admin/operations/{run} Workspace context plus tenant context when the run is tenant-bound Operations / Operation run Why the run did not produce a usable baseline and what effect it had on current baseline truth Existing Monitoring diagnostics exemption

Operator Surface Contract (mandatory when operator-facing surfaces are changed)

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 profile view capture truth and header actions Workspace baseline manager Decide whether to start a capture now Detail / Record Will a new capture produce a trustworthy baseline or should I fix prerequisites first? Current effective snapshot truth, latest capture result, prerequisite summary, next step Raw gap details, low-level inventory run metadata execution outcome, artifact usability, lifecycle/history Microsoft tenant + TenantPilot Capture baseline; Compare now Archive baseline profile
Baseline compare landing availability and guidance Tenant operator Decide whether compare can start now Workflow / Start Surface Can I trust the current baseline enough to compare this tenant right now? Assigned profile, baseline availability, blocking reason or readiness message, next action Compare matrix deep detail, raw run diagnostics artifact usability, readiness, execution history simulation only Compare now; Open compare matrix none
Baseline snapshot detail no-data artifact messaging Workspace baseline manager Decide whether a specific artifact can be trusted or safely ignored as historical/no-data evidence Detail / Record Is this snapshot a usable current baseline, a historical artifact, or a no-data trace? Lifecycle/usability, producing run effect, current-vs-historical truth Raw metadata, raw counts, low-level subject resolution detail artifact usability, lifecycle/history TenantPilot only Open related record none
Monitoring run detail for baseline capture Workspace operator Diagnose the real cause of a non-usable capture result Detail / Diagnostics Why did this capture not give me a trustworthy baseline? Dominant reason, next step, whether current baseline changed Raw JSON, low-level counts, internal IDs execution outcome, readiness, artifact usability read-only Open related profile; Open related snapshot if present none

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no
  • New persisted entity/table/artifact?: no
  • New abstraction?: no
  • New enum/state/reason family?: yes, a bounded extension of the existing baseline capture reason-code family
  • New cross-domain UI framework/taxonomy?: no
  • Current operator problem: A core governance workflow can report success without a trustworthy baseline, which directly misleads operators and auditors.
  • Existing structure is insufficient because: The current shape checks capture completion too loosely and lets status/outcome, snapshot existence, and compare availability drift apart across start surfaces, Monitoring, and artifact truth.
  • Narrowest correct implementation: Reuse existing BaselineSnapshot lifecycle/usability semantics and existing Ops UX summary/explanation builders, then add only the missing eligibility rules, reason codes, and promotion guardrails for baseline capture.
  • Ownership cost: Small ongoing cost in one reason-code family, one translation path, a handful of presenter branches, and focused baseline/Monitoring regression tests.
  • Alternative intentionally rejected: A page-local copy fix or a generic artifact-truth framework. The first would leave contradictory behavior active elsewhere; the second would import much more structure than the problem needs.
  • Release truth: current-release truth

Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests remain out of scope unless implementation proves that one existing historical baseline-capture path must be backfilled deliberately.

Canonical replacement is preferred over preservation.

Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)

  • Test purpose / classification: Feature
  • Validation lane(s): fast-feedback, confidence
  • Why this classification and these lanes are sufficient: The change is proved by baseline capture outcome mapping, compare-start availability, and Monitoring run-detail truth on existing runtime paths. Focused feature coverage is the narrowest sufficient proof; no browser or heavy-governance lane is needed.
  • New or expanded test families: Expand baseline capture service/start-surface coverage, compare availability coverage, Monitoring baseline-capture run-detail truth coverage, and one positive plus one negative authorization case on affected surfaces.
  • Fixture / helper cost impact: Low-to-moderate. Tests can reuse current baseline/inventory fixtures but need explicit seeded inventory-run outcomes for no inventory, blocked inventory, failed inventory, valid-zero-subjects, and previous-good-snapshot preservation.
  • Heavy-family visibility / justification: none
  • Special surface test profile: mixed: standard-native-filament + monitoring-state-page
  • Standard-native relief or required special coverage: Ordinary feature coverage is sufficient, but it must include both profile-level action surfaces and Monitoring run detail so explanation and promotion truth cannot drift apart.
  • Reviewer handoff: Confirm that no test still encodes "empty capture succeeds", that the last trustworthy snapshot remains current after blocked/no-data capture paths, that Monitoring leads with the dominant explanation before raw JSON, and that 404 vs 403 behavior is preserved on the touched surfaces.
  • Budget / baseline / trend impact: Low increase in baseline and Monitoring feature assertions only; no new heavy or browser baseline expected.
  • Escalation needed: none
  • Active feature PR close-out entry: Guardrail
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineCaptureTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineProfileCaptureStartSurfaceTest.php tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php tests/Feature/Filament/BaselineCaptureResultExplanationSurfaceTest.php
    • cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/OperationRunBaselineTruthSurfaceTest.php tests/Feature/Monitoring/GovernanceOperationRunSummariesTest.php tests/Feature/Monitoring/AuditCoverageGovernanceTest.php tests/Feature/Notifications/OperationRunNotificationTest.php tests/Feature/Authorization/OperatorExplanationSurfaceAuthorizationTest.php

User Scenarios & Testing (mandatory)

User Story 1 - Block false-green capture starts (Priority: P1)

As a baseline manager, I need baseline capture to stop telling me it succeeded when there was no credible inventory basis to build from.

Why this priority: This is the core trust repair. If the feature does not eliminate false-green capture outcomes, the main problem remains.

Independent Test: Can be fully tested by seeding baseline profiles with no inventory run, blocked inventory run, and failed inventory run, then asserting that capture start/execution returns deterministic blocked truth and never advances effective baseline state.

Acceptance Scenarios:

  1. Given an active baseline profile and no relevant inventory sync for the target tenant, When a baseline manager tries to capture a new baseline, Then the operator-facing result explains that inventory must run first, and the resulting truth never lands on succeeded.
  2. Given an active baseline profile and the latest relevant inventory sync ended blocked or failed, When capture is started, Then the capture result is blocked with a baseline-capture-specific reason code, and the previously effective complete snapshot remains current baseline truth.

User Story 2 - Keep no-data captures visible but non-authoritative (Priority: P2)

As a baseline manager, I need a zero-subject capture to be visible as an auditable event without being treated like a trustworthy current baseline.

Why this priority: Zero-subject captures are the sharpest form of silent false reassurance after bad upstream prerequisites.

Independent Test: Can be fully tested by capturing against valid inventory that resolves zero in-scope subjects and verifying partial success, no promotion of baseline truth, and no-data artifact messaging where an artifact exists.

Acceptance Scenarios:

  1. Given a credible inventory basis but zero subjects in the effective baseline scope, When capture runs, Then the run ends partially_succeeded with a stable zero_subjects reason code and does not replace the current consumable snapshot.
  2. Given a previous complete snapshot exists and a later capture resolves zero in-scope subjects, When operators inspect the profile, snapshot, or compare-start surface, Then the product still points to the earlier trustworthy snapshot as current baseline truth and renders the newer result only as no-data evidence.

User Story 3 - Explain all-zero capture truth on Monitoring surfaces (Priority: P3)

As an operator reviewing capture history, I need Monitoring to tell me why a capture produced no usable baseline before showing raw counts or JSON.

Why this priority: Even with corrected outcomes, operators will still lose trust if Monitoring forces them to decode all-zero counts manually.

Independent Test: Can be fully tested by opening seeded baseline capture runs in Monitoring and asserting that the dominant cause and next step are visible before diagnostics.

Acceptance Scenarios:

  1. Given a baseline capture run was blocked because the latest inventory sync failed, When an operator opens the Monitoring run detail page, Then the page leads with that blocked prerequisite and the next step before raw diagnostics.
  2. Given a baseline capture run technically completed processing but resolved zero in-scope subjects, When an operator opens the Monitoring run detail page, Then the page states that no usable baseline was captured, explains the zero-subject result, and clarifies that current baseline truth was not advanced.

Edge Cases

  • The latest relevant inventory sync is blocked or failed, but an older successful inventory sync still exists. The system must not silently fall back to the older success in V1.
  • A zero-subject capture may persist a snapshot row or related artifact for audit purposes. If it does, that artifact must remain non-consumable and visibly marked as no-data evidence.
  • A blocked or no-data capture can occur while a prior complete snapshot is still current. Operator surfaces must show that the old trustworthy snapshot remains effective.
  • A capture can be preflight-blocked on the start surface and still need the same protection at execution time if prerequisite state changes after page load.
  • Scheduled or initiator-null capture runs must keep current Ops UX behavior: no terminal DB notification, Monitoring remains the audit surface, and the same dominant-cause explanation still applies.

Requirements (mandatory)

Constitution alignment (required): This feature changes existing baseline capture runtime behavior and operator truth but introduces no new Microsoft Graph endpoint, no new OperationRun type, and no new contract-registry object family. Existing capture start actions stay confirmation-gated, execution remains auditable and observable, and tenant/workspace isolation remains unchanged.

Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001): This feature does not add new persistence or a new abstraction layer. It extends an existing reason-code family because the current baseline capture truth is too weak and because page-local messaging would duplicate semantics across profile, compare, snapshot, and Monitoring surfaces.

Constitution alignment (XCUT-001): This is a cross-cutting interaction slice. It must extend the existing baseline reason/translation/stats path and the existing Ops UX run-summary path. No page may introduce a parallel local explanation language for blocked or no-data baseline capture outcomes.

Constitution alignment (TEST-GOV-001): Proof stays in focused feature coverage for baseline capture service/start surfaces and Monitoring run detail. No new heavy-governance or browser coverage is required. New fixtures must remain explicit and scenario-driven rather than becoming default test setup.

Constitution alignment (OPS-UX): Existing baseline_capture runs continue to use the three-surface feedback contract: start-intent feedback, active progress surfaces, and one terminal DB notification for interactive runs. OperationRun.status and OperationRun.outcome remain service-owned via OperationRunService. summary_counts remain numeric-only and compliant with existing summary-count rules. Scheduled or initiator-null runs still skip terminal DB notification. Regression coverage must prove that blocked/no-data capture truth does not bypass service-owned transitions.

Constitution alignment (RBAC-UX): The affected planes are admin /admin for baseline profile/snapshot surfaces, tenant-context /admin/t/{tenant}/baseline-compare for compare availability, and canonical /admin/operations/{run} Monitoring for capture detail. Non-members or non-entitled tenant viewers continue to receive 404. Members lacking the required current capability continue to receive 403. Server-side enforcement remains authoritative on every touched action/start surface. No raw capability strings or role-name checks may be introduced.

Constitution alignment (OPS-EX-AUTH-001): No /auth/* behavior is added or broadened.

Constitution alignment (BADGE-001): Any changed availability or no-data wording must stay centralized through existing baseline reason/badge/presenter semantics rather than ad-hoc page mappings.

Constitution alignment (UI-FIL-001): The feature reuses existing native Filament header actions, detail sections, and shared presenters. No local replacement markup is introduced for badges, alerts, or status language.

Constitution alignment (UI-NAMING-001): Primary operator-facing language must stay baseline-domain specific and consistent across buttons, modals, Monitoring summaries, notifications, and audit prose: Capture baseline, Compare now, Run tenant sync first, Latest inventory sync failed, No subjects were in scope, and No usable baseline was captured.

Constitution alignment (DECIDE-001): This feature does not add a new primary surface. It hardens one existing primary decision surface (BaselineCompareLanding), two secondary context surfaces (profile/snapshot detail), and one tertiary diagnostics surface (Monitoring run detail) so the first decision is based on trustworthy baseline truth rather than inferred success.

Constitution alignment (UI-CONST-001 / UI-SURF-001 / ACTSURF-001 / UI-HARD-001 / UI-EX-001 / UI-REVIEW-001 / HDR-001): The action hierarchy stays unchanged. Navigation remains separate from mutation. Existing compare and capture header actions keep their current placement. No new action groups or destructive actions are introduced.

Constitution alignment (ACTSURF-001 - action hierarchy): Existing visible safe header actions remain meaningful and bounded: one capture action and one compare action stay peer visible actions, mode-specific full-content labels replace the default labels instead of adding extra peer actions, and additional safe actions stay grouped under More. No new mixed catch-all action groups are added.

Constitution alignment (OPSURF-001): The default-visible truth on touched surfaces must stay operator-first: current trustworthy baseline, dominant failure/no-data cause, next action, and effect on baseline truth before raw implementation detail.

Constitution alignment (UI-SEM-001 / LAYER-001 / TEST-TRUTH-001): The feature extends existing explanation layers because direct mapping from status = completed or zero counts to the UI is insufficient. It must not create a second artifact-truth source beside the existing snapshot lifecycle/usability contract.

Constitution alignment (Filament Action Surfaces): The Action Surface Contract remains satisfied. Each touched Filament surface keeps one primary inspect/open model, no redundant view actions are added, no empty ActionGroup placeholders are introduced, and destructive-action placement remains unchanged.

Constitution alignment (UX-001 — Layout & Information Architecture): Existing profile/snapshot view layouts and explanation-first workflow layouts remain in place. This feature changes explanation and availability truth, not overall screen layout.

Functional Requirements

  • FR-235-001: Baseline capture eligibility MUST evaluate the most recent relevant inventory sync for the same workspace and target tenant scope using terminal outcome and coverage usability, not status = completed alone.
  • FR-235-002: The system MUST treat each of the following as non-credible capture prerequisites with deterministic baseline-capture reason codes in BaselineReasonCodes: no relevant inventory sync exists, the latest relevant inventory sync is blocked, the latest relevant inventory sync is failed, or the latest relevant inventory sync lacks usable coverage for baseline subject resolution.
  • FR-235-003: Baseline capture start surfaces MUST preflight known non-credible inventory prerequisites and explain the block with the same reason-code family used at runtime. Server-side capture execution remains authoritative if prerequisite state changes after page load.
  • FR-235-004: When baseline capture is attempted without a credible inventory basis, the resulting operator truth MUST never land on succeeded. The terminal capture truth MUST use a blocked prerequisite outcome with the matching baseline-capture reason code.
  • FR-235-005: Succeeded MUST be reserved for capture runs that produce or reuse a consumable baseline snapshot backed by at least one resolved in-scope subject and that leave effective baseline truth anchored to that consumable snapshot.
  • FR-235-006: When inventory is credible but zero in-scope subjects resolve, baseline capture MUST finish as partially_succeeded with a stable baseline.capture.zero_subjects reason code.
  • FR-235-007: A zero-subject capture MUST NOT advance active_snapshot_id or any equivalent effective-baseline pointer. The previously effective complete snapshot, if one exists, remains current baseline truth.
  • FR-235-008: If implementation persists a snapshot row or related artifact for a zero-subject capture, that artifact MUST reuse the existing snapshot lifecycle/usability contract, remain non-consumable by default, render as a no-data capture artifact on operator surfaces, and never become current baseline truth automatically.
  • FR-235-009: Capture eligibility in V1 MUST NOT silently fall back to an older successful inventory sync when a newer relevant inventory sync is blocked, failed, or otherwise non-credible. Older successful inventory runs may be shown as historical context only.
  • FR-235-010: Monitoring run detail for baseline capture MUST lead with one dominant operator-safe explanation and next action before raw JSON, low-level counts, or internal identifiers.
  • FR-235-011: Baseline capture run context, summary, and audit prose MUST record the chosen eligibility decision, the upstream inventory run reference when present, the terminal baseline-capture reason code, and whether current baseline truth changed.
  • FR-235-012: Existing baseline compare availability surfaces, including BaselineCompareLanding and profile-level compare affordances, MUST derive availability from effective consumable baseline truth after hardened capture outcomes, not from snapshot existence or latest capture completion alone.
  • FR-235-013: The feature MUST keep copy and translation centralized by extending BaselineReasonCodes, ReasonTranslator, BaselineCompareStats, and the existing Ops UX summary/explanation path rather than adding page-local message branches.
  • FR-235-014: Existing Capture baseline and Capture baseline (full content) actions MUST remain confirmation-gated, capability-enforced, and placed on their current surfaces. This feature changes truth and explanation only, not action topology.
  • FR-235-015: Regression coverage MUST replace existing assumptions that an empty or all-zero baseline capture is a benign success and MUST cover no inventory, blocked inventory, failed inventory, zero-subject capture, and preservation of the previously trustworthy snapshot.

Assumptions

  • Existing snapshot lifecycle/usability semantics from Spec 159 remain the baseline artifact truth source.
  • Existing governance run-summary/explanation primitives from Spec 220 remain the Monitoring explanation path.
  • The product chooses strict truthful capture behavior in V1: no silent stale-inventory fallback.
  • Zero-subject results may remain visible as audit evidence, but they do not become authoritative baseline truth.
  • Spec 159 (baseline-snapshot-truth) remains the source of truth for snapshot lifecycle/usability semantics.
  • Spec 220 (governance-run-summaries) remains the shared Monitoring explanation path for dominant-cause run detail.
  • Specs 116-119 remain the shipped baseline drift/cutover foundation that this spec hardens on the capture side.
  • Existing baseline compare availability and reason translation paths remain in scope for reuse, not redesign.

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 profile view app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php One visible capture action (Capture baseline or Capture baseline (full content) depending on mode), one visible compare action (Compare now or Compare now (full content) depending on mode), plus secondary safe actions grouped under More Existing list recordUrl() to view page Existing View / Edit pattern unchanged None Existing create CTA unchanged on list Same visible capture/compare actions plus existing related navigation and grouped secondary actions Existing save/cancel unchanged Yes Capture/compare actions stay confirmation-gated and capability-enforced. Capture baseline remains the primary visible header action; Compare now remains a justified visible secondary safe action on this record page because the operator's same-context decision is whether to refresh baseline truth first or use the current trustworthy snapshot immediately. Mode-specific full-content labels replace the default labels rather than adding extra peer header actions. Existing archive action remains the only destructive action and still requires confirmation.
Baseline compare landing app/Filament/Pages/BaselineCompareLanding.php Compare now, Compare now (full content) n/a None None Existing Open compare matrix remains the single empty/blocked-state CTA where applicable n/a n/a Yes, via compare run/audit This feature changes readiness and blocking guidance only. The page remains the primary compare decision/start surface.
Baseline snapshot view app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php None Existing clickable list row Existing related-record navigation only None None by design Existing related-record actions only n/a No direct mutation audit Immutable-resource exemption remains. This feature changes lifecycle/usability explanation for no-data artifacts only.
Monitoring run detail Existing Monitoring run detail surface resolved through OperationUxPresenter Existing related navigation only n/a n/a n/a n/a Existing related navigation only n/a Yes No new actions are introduced. The body must show the dominant baseline-capture truth before diagnostics.

Key Entities (include if feature involves data)

  • BaselineProfile: The workspace-owned governance definition whose effective baseline truth must remain anchored to the last consumable snapshot.
  • BaselineSnapshot: The captured baseline artifact whose existing lifecycle/usability semantics determine whether it can become current baseline truth.
  • Inventory Sync OperationRun: The upstream tenant-scoped execution record whose credibility determines whether baseline capture may trust the current inventory basis.
  • Baseline Capture OperationRun: The execution record that communicates blocked, partial, or successful capture truth to operators, Monitoring, audit, and notifications.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-235-001: In focused regression coverage, 100% of baseline-capture attempts without a credible inventory basis end without succeeded and expose a deterministic baseline-capture reason code.
  • SC-235-002: In focused regression coverage, 100% of valid-zero-subject capture scenarios end partially_succeeded, do not advance effective baseline truth, and preserve the previously consumable snapshot when one exists.
  • SC-235-003: On the default-visible baseline profile, compare landing, snapshot detail, and Monitoring run-detail surfaces touched by this feature, operators can identify the dominant cause and next step without opening raw diagnostics.
  • SC-235-004: No automated test path or default-visible operator surface treats an all-zero baseline capture as an unconditional successful baseline refresh after this feature lands.
  • SC-235-005: Compare availability remains aligned to effective consumable baseline truth after every covered blocked or no-data capture regression path.