TenantAtlas/specs/328-operations-hub-decision-first-workbench-productization/repo-truth-map.md
ahmido 815262399a feat: productize operations hub decision-first workbench (#389)
## Summary
- productize the operations hub decision-first workbench and related monitoring page surfaces
- add the operations workbench stats widget plus tenantless run viewer and admin scope updates
- extend monitoring, ops UX, and browser coverage for the new workbench behavior
- add Spec 328 artifacts under `specs/328-operations-hub-decision-first-workbench-productization`

## Testing
- not run as part of this handoff

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #389
2026-05-19 00:49:13 +00:00

14 KiB

Spec 328 Repo Truth Map

Status: implemented / validated Created: 2026-05-18 Purpose: classify each Operations Hub decision-first workbench element before runtime implementation. This map is based on repository inspection only; implementation must update it before runtime changes if new source gaps appear.

Classification Legend

  • repo-verified: exact runtime source exists and was inspected.
  • foundation-real: backend model/service/policy exists, but exact page binding still needs implementation verification.
  • derived from existing model: display value can be derived from existing persisted/domain truth.
  • empty state / unavailable: no safe source/action exists for v1; show explicit unavailable state or omit.
  • deferred future capability: outside Spec 328 and must not be shown as live runtime truth.

Required Data Areas

Data area Repo source Preparation finding
Operations route apps/platform/routes/web.php, route admin.operations.index repo-real path is /admin/workspaces/{workspace}/operations
Operations page Operations Filament page and operations.blade.php repo-real current layout is decision-first workbench with secondary history table
OperationRun table OperationRunResource::table() repo-real status/outcome/type/timing table with filters, row URL, empty state
OperationRun detail TenantlessOperationRunViewer, OperationRunResource::infolist() repo-real detail/proof/diagnostic destination
OperationRun statuses OperationRunStatus repo-real queued, running, completed
OperationRun outcomes OperationRunOutcome repo-real pending, succeeded, partially_succeeded, blocked, failed; cancelled is reserved
OperationRun problem classes OperationRun::problemClass(), scopes activeStaleAttention(), terminalFollowUp(), dashboardNeedsFollowUp() repo-real for attention grouping without new priority engine
Summary counts summary_counts, OperationSummaryKeys, SummaryCountsNormalizer repo-real numeric keys and normalized rendering
Progress OperationRunProgressContract repo-real active-only progress semantics; terminal runs return none
Operation labels OperationCatalog::label() repo-real labels for canonical/legacy operation types
Environment relationship OperationRun::tenant() relation to ManagedEnvironment repo-real affected environment where present and accessible
Artifact/evidence links OperationRunLinks::related(), ArtifactTruthPresenter, related resources foundation-real/repo-real depending on operation type and linked artifact
Diagnostics run detail technical sections, support diagnostics action, failure_summary, context repo-real but default index must not expose raw data
RBAC OperationRunPolicy, OperationRunCapabilityResolver, source policies/capabilities repo-real membership, environment entitlement, capability checks
Workspace / Environment filter state WorkspaceContext, WorkspaceHubEnvironmentFilter, WorkspaceHubFilterStateResetter, CanonicalAdminEnvironmentFilterState, filter chip partial repo-real canonical environment_id, clear filter, alias rejection, cross-workspace guard

UI Element Map

UI element Source model/service/page Status source Authorization/capability Workspace/Environment scope OperationRun/evidence/artifact/audit link Fallback/empty state Classification
Operations Hub route admin.operations.index, OperationRunLinks::index() route + helper workspace middleware and page access current workspace route param none workspace chooser / 404 per existing middleware repo-verified
Operations Hub title Operations page/view static copy to update page access workspace none static title repo-verified
Workspace scope label OperateHubShell, WorkspaceContext current workspace/session workspace membership workspace shell none omit/404 if unavailable repo-verified
Environment filter chip environmentFilterChip(), shared chip partial WorkspaceHubEnvironmentFilter::fromRequest() and table state actor must access environment ?environment_id={id} only none no chip on clean URL repo-verified
Clear filter action cleanWorkspaceHubUrl(), shared resetter generated clean route page access removes canonical filter/table state none omit when unfiltered repo-verified
Legacy alias rejection WorkspaceHubFilterStateResetter, navigation tests forbidden query/session keys page/source access aliases do not set filter none workspace-wide view or safe 404 repo-verified
Cross-workspace environment guard WorkspaceHubEnvironmentFilter::fromRequest() environment scoped by workspace and entitlement workspace and environment entitlement current workspace only none abort(404) / safe no-access repo-verified
Main workbench question Operations::decisionWorkbench() and operations.blade.php static stable copy page access current scope none visible with no-attention state repo-verified
Highest-priority operation Operations::selectedWorkbenchOperation(), OperationRun problem class, outcome, status, freshness, timestamps derived ordering from existing status/outcome/problem class existing scoped Operations page query and OperationRun visibility current workspace/filter canonical detail link No operations need attention derived from existing model
Operation title/type OperationCatalog::label($run->type) type field run visibility current workspace/filter detail link fallback raw-safe type label repo-verified
Outcome/status OperationRun.status, outcome, badge renderer status/outcome enums run visibility current workspace/filter detail link Outcome unavailable only if missing repo-verified
Reason problem class, lifecycle/freshness, outcome, OperationUxPresenter, ReasonPresenter, failure_summary summary where safe derived from run truth run/detail/source capabilities current scope detail link Reason unavailable derived from existing model
Impact outcome, problem class, artifact truth, related artifact/review/restore context derived from existing run/artifact truth run/source capabilities current scope related links if authorized Impact unavailable derived from existing model
Environment OperationRun::tenant() / ManagedEnvironment managed environment relationship entitlement via OperationRunPolicy / scope resolver workspace and environment related environment/resource links if existing Workspace-level operation or unavailable repo-verified
Timing created_at, started_at, completed_at, RunDurationInsights timestamps run visibility current scope detail link Timing unavailable repo-verified
Proof/artifact state OperationRunLinks::related(), ArtifactTruthPresenter, related resources related route presence, artifact truth envelope source policies/capabilities current scope artifact/evidence/review/backup/restore links Proof unavailable or omit foundation-real
Operation detail proof OperationRunLinks::tenantlessView() run id / route OperationRunPolicy current workspace/filter canonical run detail unavailable only if unauthorized repo-verified
Progress state OperationRunProgressContract::forRun() summary counts/context/status run visibility current scope detail link no progress for terminal or unsupported repo-verified
Determinate progress summary_counts.processed, summary_counts.total numeric trustworthy counts run visibility current scope detail link indeterminate/activity/unavailable repo-verified
Terminal outcome guidance OperationRunResource::surfaceGuidance(), resolvePrimaryNextStep(), OperationUxPresenter status/outcome/problem class run visibility current scope detail link/source links generic review operation foundation-real
Primary next action OperationRunLinks::tenantlessView(), existing detail/source actions route/action availability run/source capability current scope operation detail link unavailable when no selected operation repo-verified for open operation; stronger proof links remain deferred to detail/source surfaces
Summary card: needs attention dashboardNeedsFollowUp() / problem class scopes stale active + terminal follow-up scoped query current workspace/filter operations tab/deep link 0 count with careful copy repo-verified
Summary card: active operations status in queued/running status field scoped query current workspace/filter active tab link 0 count repo-verified
Summary card: failed/blocked completed failed/blocked outcomes outcome field scoped query current workspace/filter failed/follow-up tab link 0 count repo-verified
Summary card: follow-up required terminal follow-up/problem class problem class/outcome/reconciliation scoped query current workspace/filter follow-up tab link 0 count repo-verified
Summary card: completed recently completed_at within window timestamp/outcome scoped query current workspace/filter table filter/tab 0 count repo-verified
Summary card: artifact available related artifact/evidence/link presence related route / artifact truth source capabilities current workspace/filter artifact/evidence links unavailable if no safe aggregate foundation-real
Right operation/proof panel operations.blade.php over selected run payload selected/highest run payload run/source capabilities current scope operation detail link no-attention/empty panel repo-verified
Operations table/history OperationRunResource::table() table query, filters, row URL run visibility workspace + environment scoping canonical detail route existing No operations found repo-verified
Tabs / problemClass links activeTab, problemClass, tabUrl() query/livewire state page access current scope active/stale/follow-up/succeeded/partial/failed views all tab default repo-verified
Diagnostics disclosure run detail technical sections, support diagnostics action raw context/failure summary/support bundle SUPPORT_DIAGNOSTICS_VIEW where action exposed current scope detail/support diagnostics only collapsed/hidden foundation-real
Raw provider payloads raw Graph/provider payloads not safe default support-only future N/A N/A never default-visible deferred future capability
Retry/cancel/rerun action existing detail/source actions only if present action availability source capability and confirmation source scope existing action owner hidden/unavailable foundation-real / deferred if unsupported
Platform-context tenant copy guard runtime copy/tests string assertions N/A page copy N/A use Workspace/Environment repo-verified need; implementation test required

Required Runtime Element Decisions

Element v1 decision
Top summary-card rendering native Filament StatsOverviewWidget / Stat; no custom Blade/Tailwind card component or explicit accent-bar system
New persisted operations workbench item deferred future capability; do not build
New priority engine deferred future capability; derive local ordering from existing status/outcome/problem class
New OperationRun status/outcome deferred future capability; do not add
New summary-count keys deferred future capability; do not add
AI operation summary deferred future capability; do not show
Owner/due for operation unavailable unless source operation context already proves it
Artifact/evidence where absent explicit unavailable/missing state; do not invent
Green success state allowed only for exact execution completion copy; never environment/governance health
Diagnostics collapsed/hidden by default and capability-aware if exposed
Dangerous/mutating actions do not add unless spec/plan updated first
Legacy query aliases rejected/neutralized; do not support

Implementation Update Rule

If implementation discovers that a planned UI element has no safe source, no authorization path, or would require new persisted truth, the element must become empty state / unavailable or deferred future capability. Do not create backend foundation inside Spec 328 without updating spec.md, plan.md, and this map first.

Implementation Close-Out

  • Implemented the decision-first workbench on the existing /admin/workspaces/{workspace}/operations page.
  • Selected-operation priority is derived locally from existing OperationRun status, outcome, problem class, timestamps, and scoped queries; no persisted priority engine was added.
  • Determinate progress is delegated to OperationRunProgressContract and remains hidden for terminal outcomes.
  • Primary next action is OperationRunLinks::tenantlessView() only; artifact/evidence/source-specific actions remain on existing detail/source surfaces.
  • Summary cards are compact execution/attention signals backed by scoped OperationRun counts; they now render through the narrow native OperationsWorkbenchStats Filament StatsOverviewWidget using Stat::make(...), descriptions, description icons, semantic colors, and disabled polling. No fake trends, sparklines, chart placeholders, custom Blade/Tailwind stat-card component, explicit custom accent bars, generic total-operation KPI, or average-duration KPI is used.
  • OperationsKpiHeader remains available as existing widget code, but the Operations page no longer renders it above the workbench because the first viewport is owned by the decision-first summary cards.
  • Diagnostics stay collapsed by default and raw provider/debug payloads are not default-visible.
  • Clean workspace entry remains workspace-wide; environment_id remains the only accepted visible filter key.
  • UI coverage registry files were not changed because the route and archetype remain the existing UI-003 Operations strategic surface; screenshots were stored under artifacts/screenshots/.