21 KiB
Implementation Plan: Support Diagnostic Pack
Branch: 241-support-diagnostic-pack | Date: 2026-04-25 | Spec: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/spec.md
Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/spec.md
Note: This template is filled in by the /speckit.plan command. See .specify/scripts/ for helper scripts.
Summary
- Add one derived, support-safe diagnostic bundle contract that can be opened from exactly two existing admin-plane surfaces: the tenant dashboard and the canonical tenantless operation detail viewer.
- Reuse current canonical truth and shared paths instead of inventing support-local persistence or navigation:
OperationRun,ProviderConnection,Finding,StoredReport,TenantReview,ReviewPack,AuditLog,OperationRunLinks,GovernanceRunDiagnosticSummaryBuilder,ProviderReasonTranslator,RelatedNavigationResolver, and the existing audit recorder. - Keep the first slice strictly read-only and deterministic: no support-desk workflow, no external ticketing, no raw payload export, no persisted support-pack entity, no new
OperationRuntype, no notification changes, and no AI runtime behavior.
Technical Context
Language/Version: PHP 8.4 (Laravel 12)
Primary Dependencies: Laravel 12 + Filament v5 + Livewire v4 + Pest; existing OperationRunLinks, GovernanceRunDiagnosticSummaryBuilder, ProviderReasonTranslator, RelatedNavigationResolver, RedactionIntegrity, WorkspaceAuditLogger
Storage: PostgreSQL via existing operation_runs, provider_connections, findings, stored_reports, tenant_reviews, review_packs, and audit_logs; no new persistence planned
Testing: Pest unit + feature tests only
Validation Lanes: fast-feedback, confidence
Target Platform: Sail-backed Laravel admin panel under /admin and /admin/t/{tenant}
Project Type: web
Performance Goals: bundle collection and preview remain DB-only at render/action time, perform no outbound HTTP, create no new OperationRun, and deterministically compose the same result for unchanged authorized input
Constraints: derive-before-persist, provider-neutral top-level language, deterministic redaction, no raw payload/body export, no support-desk product, no external ticketing, no AI runtime features, no new run lifecycle semantics, no browser/heavy-governance drift, and RBAC non-member 404 versus capability 403 boundaries must remain explicit
Scale/Scope: one bundle contract, two entry contexts (TenantDashboard and TenantlessOperationRunViewer), existing canonical record references only, and focused unit + feature coverage
UI / Surface Guardrail Plan
- Guardrail scope: changed surfaces
- Native vs custom classification summary: native Filament + shared read-only preview composition
- Shared-family relevance: header actions, diagnostic summaries, related links, audit drill-throughs
- State layers in scope: page, detail, action preview
- Handling modes by drift class or surface: review-mandatory
- Repository-signal treatment: review-mandatory
- Special surface test profiles: standard-native-filament, monitoring-state-page
- Required tests or manual smoke: functional-core
- Exception path and spread control: the existing tenant dashboard action-surface exemption remains the only dashboard exception; no new support page, queue, or custom interaction family is introduced
- Active feature PR close-out entry: Guardrail
Shared Pattern & System Fit
- Cross-cutting feature marker: yes
- Systems touched:
App\Filament\Pages\TenantDashboard,App\Filament\Pages\Operations\TenantlessOperationRunViewer,App\Support\OperationRunLinks,App\Support\OpsUx\GovernanceRunDiagnosticSummaryBuilder,App\Support\Providers\ProviderReasonTranslator,App\Support\Navigation\RelatedNavigationResolver,App\Support\RedactionIntegrity, canonical review/provider/finding/audit viewers, andApp\Services\Audit\WorkspaceAuditLogger - Shared abstractions reused:
OperationRunLinks,GovernanceRunDiagnosticSummaryBuilder,ProviderReasonTranslator,ProviderConnectionSurfaceSummary,RelatedNavigationResolver,RedactionIntegrity,WorkspaceAuditLogger,AuditActionId - New abstraction introduced? why?: one narrow
SupportDiagnosticBundleBuilderunderApp\Support\SupportDiagnosticsis justified because there are now two concrete contexts that must emit the same machine-readable, redacted bundle contract. It should return one documented array shape, not a registry, strategy layer, or persisted model. - Why the existing abstraction was sufficient or insufficient: existing helpers already own canonical links, run explanation language, provider reason translation, and redaction-note wording; what is missing is a deterministic cross-record composition layer that assembles those existing truths into one support-safe bundle.
- Bounded deviation / spread control: preview stays on the two existing pages only, reuses current labels and URLs, and explicitly forbids a standalone support resource, export pipeline, or page-local link dialect.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: yes, for deep-link and explanation reuse only
- Central contract reused:
OperationRunLinksand the existing canonical tenantless run viewer, plusGovernanceRunDiagnosticSummaryBuilderfor run explanation reuse - Delegated UX behaviors: canonical
Open operationlabeling, tenant/workspace-safe run URL resolution, shared run explanation language, and existing related-record link labels - Surface-owned behavior kept local: one read-only
Open support diagnosticsaction plus preview/detail composition on the tenant dashboard and run-detail surfaces - Queued DB-notification policy:
N/A - Terminal notification path:
N/A - Exception path: none
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes
- Provider-owned seams: provider connection descriptors, consent/permission failure excerpts, translated provider error detail
- Platform-core seams: bundle shell, context labels, section ordering, freshness cues, redaction semantics, and canonical-reference vocabulary
- Neutral platform terms / contracts preserved:
support diagnostic bundle,tenant context,operation context,provider connection,related record,audit reference,redaction reason - Retained provider-specific semantics and why: Microsoft-specific permission, consent, and provider-failure wording stays only inside translated provider-owned summaries produced by
ProviderReasonTranslator, because the current operator still needs exact remediation context when provider readiness is the blocker - Bounded extraction or follow-up path: none in this slice; any future System Panel least-privilege support surface remains a separate follow-up spec instead of widening this tenant/admin-plane bundle contract
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
- Derive-before-persist /
PERSIST-001: PASS — nosupport_diagnostic_packstable or persisted entity is introduced; the bundle is composed at request time from existing workspace, tenant, run, provider, finding, report, review, and audit truth. - Proportionality /
PROP-001andABSTR-001: PASS — one narrow builder is justified by exactly two real contexts (tenant and run) that must share one deterministic contract; no registry, resolver lattice, or support framework is planned. - Provider boundary /
PROV-001: PASS — top-level bundle fields stay provider-neutral, while provider-specific semantics remain in provider-owned translated detail. - Shared path reuse /
XCUT-001: PASS — the feature reusesOperationRunLinks,GovernanceRunDiagnosticSummaryBuilder,ProviderReasonTranslator,ProviderConnectionSurfaceSummary,RelatedNavigationResolver, andRedactionIntegrityinstead of creating a second support vocabulary. - RBAC, workspace isolation, tenant isolation /
RBAC-UX: PASS — tenant dashboard access still requires established workspace + tenant scope,support_diagnostics.viewis scoped through the canonical tenant capability registry and tenant role map, the run-detail action only applies whenOperationRunPolicyhas already resolved an entitled tenant scope, non-members or non-entitled actors stay404, and an entitled actor lacking the new capability receives403on the action. - Read/write separation and auditability: PASS — the bundle is read-only, writes no Graph or product state, and logs bundle-open activity via the existing audit recorder with redacted metadata only.
- Graph contract path: PASS — no new Graph calls are added; render and action hydration remain DB-only.
- OperationRun lifecycle / Ops-UX: PASS — the feature does not create, update, or complete runs; it only reuses existing run explanation and link semantics.
- Global search / Filament resource requirements:
N/A— no new global-searchable Filament resource is introduced. - Panel/provider registration:
N/A— no panel or provider changes are planned; Laravel 12 provider registration remains inbootstrap/providers.php. - Test governance /
TEST-GOV-001: PASS — proof stays in focused unit + feature lanes, with no browser or heavy-governance family growth.
Test Governance Check
- Test purpose / classification by changed surface: Unit for bundle assembly, stable ordering, redaction, and related-reference shaping; Feature for tenant dashboard action behavior, operation-detail action behavior, audit logging, authorization boundaries, and no-side-effect execution proof
- Affected validation lanes: fast-feedback, confidence
- Why this lane mix is the narrowest sufficient proof: the feature is a server-driven Filament/Livewire read-only action over existing database truth. Unit tests can prove determinism and redaction logic directly, while Feature tests can prove action registration,
404/403boundaries, rendered canonical links, audit logging, and the absence of provider-backed or run-creating side effects without browser duplication. - Narrowest proving command(s):
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleBuilderTest.php tests/Unit/Support/SupportDiagnostics/SupportDiagnosticBundleRedactionTest.phpcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/SupportDiagnostics/TenantSupportDiagnosticActionTest.php tests/Feature/SupportDiagnostics/OperationRunSupportDiagnosticActionTest.php tests/Feature/SupportDiagnostics/SupportDiagnosticAuthorizationTest.php tests/Feature/SupportDiagnostics/SupportDiagnosticAuditTest.php
- Fixture / helper / factory / seed / context cost risks: reuse existing
Workspace,Tenant,OperationRun,ProviderConnection,Finding,StoredReport,TenantReview,ReviewPack, andAuditLogfactories; add only one opt-in support-diagnostic seeding helper local to these tests so browser or full provider fixtures do not become defaults. - Expensive defaults or shared helper growth introduced?: no; support-diagnostic test helpers must stay local and opt-in.
- Heavy-family additions, promotions, or visibility changes: none
- Surface-class relief / special coverage rule: standard-native-filament plus monitoring-state-page coverage is sufficient; assert the action and the resulting preview content rather than browser-level modal choreography.
- Closing validation and reviewer handoff: rerun the targeted unit and feature commands after implementation; reviewers should confirm
404versus403, explicit redaction markers, deterministic section ordering, canonical link reuse, absence of raw payload or token leakage, and that opening diagnostics creates no newOperationRun, Ops UX side effect, or provider-backed work. - Budget / baseline / trend follow-up: none expected beyond ordinary feature-local upkeep
- Review-stop questions: did the implementation introduce a standalone support page/resource, a persisted pack, a raw export path, or browser-only proof? did it bypass existing link/explanation helpers? did any test silently widen into a heavy family?
- Escalation path:
reject-or-splitif implementation adds persistence, export, support-desk workflow, or system-plane capability expansion;document-in-featurefor small shared-helper extensions that remain local to this slice - Active feature PR close-out entry: Guardrail
- Why no dedicated follow-up spec is needed: the planned unit and feature tests extend existing fixture families and do not create a new recurring governance or browser cost center.
Project Structure
Documentation (this feature)
specs/241-support-diagnostic-pack/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── checklists/
│ └── requirements.md
├── contracts/
│ └── support-diagnostics.openapi.yaml
└── tasks.md
Source Code (repository root)
apps/platform/
├── app/
│ ├── Filament/Pages/TenantDashboard.php
│ ├── Filament/Pages/Operations/TenantlessOperationRunViewer.php
│ ├── Policies/OperationRunPolicy.php
│ ├── Services/Audit/WorkspaceAuditLogger.php
│ ├── Support/Audit/AuditActionId.php
│ ├── Support/Auth/Capabilities.php
│ ├── Support/Navigation/RelatedNavigationResolver.php
│ ├── Support/OpsUx/GovernanceRunDiagnosticSummaryBuilder.php
│ ├── Support/OperationRunLinks.php
│ ├── Support/Providers/ProviderReasonTranslator.php
│ ├── Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php
│ ├── Support/RedactionIntegrity.php
│ └── Support/SupportDiagnostics/
│ └── SupportDiagnosticBundleBuilder.php
└── tests/
├── Feature/SupportDiagnostics/
│ ├── TenantSupportDiagnosticActionTest.php
│ ├── OperationRunSupportDiagnosticActionTest.php
│ ├── SupportDiagnosticAuthorizationTest.php
│ └── SupportDiagnosticAuditTest.php
└── Unit/Support/SupportDiagnostics/
├── SupportDiagnosticBundleBuilderTest.php
└── SupportDiagnosticBundleRedactionTest.php
Structure Decision: Single Laravel web application. The feature stays inside existing tenant and monitoring detail pages plus one narrowly scoped support-diagnostics builder; no new resource, panel, route group, or persistence layer is introduced.
Complexity Tracking
No constitution violations are required for this plan. The only new structural element is one bounded derived bundle builder, justified below and kept within current-release truth.
Proportionality Review
- Current operator problem: founder-led support still starts with manual cross-page reconstruction across tenant, provider, run, finding, report, review, and audit truth before the real issue can be understood.
- Existing structure is insufficient because: current pages explain their own local truth, but there is no support-safe, deterministic composition layer that can gather those existing truths into one reusable bundle without page-local drift.
- Narrowest correct implementation: one read-only bundle builder plus one read-only action on each of the two existing surfaces, reusing existing helpers, canonical links, and audit logging. No new entity, no export pipeline, no support queue, and no additional notification behavior.
- Ownership cost created: one array-shaped contract, one capability constant and role mapping entry, one audit action identifier, and focused unit + feature coverage.
- Alternative intentionally rejected: a persisted
SupportDiagnosticPackmodel, a standalone support page/resource, and raw payload export/download were rejected as premature persistence and over-broad workflow expansion; page-local copy helpers were rejected as too narrow and drift-prone. - Release truth: current-release truth
Phase 0 — Research (output: research.md)
See: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/research.md
Goals:
- Confirm the narrowest existing sources of truth for tenant, run, provider, finding, report, review-pack, and audit references.
- Resolve the capability and product-candidate open question by keeping support diagnostics on already-authorized tenant/admin surfaces only, with no new System Panel visibility bypass in this slice.
- Confirm that redaction, related navigation, and run explanation can stay on existing shared helpers instead of introducing a second support-local layer.
- Define deterministic ordering and graceful degradation rules for missing, stale, or inaccessible related records.
Phase 1 — Design & Contracts (outputs: data-model.md, contracts/, quickstart.md)
See:
/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/data-model.md/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/contracts/support-diagnostics.openapi.yaml/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/241-support-diagnostic-pack/quickstart.md
Design focus:
- Add one read-only
Open support diagnosticsheader action toTenantDashboardandTenantlessOperationRunVieweronly. - Compose a tenant-context bundle from existing tenant truth, current relevant provider connection state, the most relevant recent operation context, open or recent findings, latest stored-report freshness, latest tenant-review or review-pack reference when present, and authorized audit references.
- Compose an operation-context bundle from the existing humanized run summary plus related provider, finding, report, review, and audit references without changing
OperationRunlifecycle semantics. - Keep section order and reference ordering deterministic, with explicit
missing,stale,redacted, orinaccessiblecues instead of silent omission. - Reuse canonical navigation and explanation helpers so every link, label, and run explanation means the same thing elsewhere in the product.
- Add one tenant-plane capability in the canonical registry and tenant role map for bundle access, keep system-plane support diagnostics out of scope, only expose the run-detail action when the referenced run resolves to an entitled tenant scope, and record bundle-open activity with redacted metadata only.
- Keep preview composition native to Filament read-only actions or infolist-style rendering on existing pages. No standalone support page or export/download action is planned.
Phase 1 — Agent Context Update
After Phase 1 artifacts are generated, update Copilot context from the plan:
/Users/ahmeddarrazi/Documents/projects/wt-plattform/.specify/scripts/bash/update-agent-context.sh copilot
Phase 2 — Implementation Outline (tasks created in /speckit.tasks)
- Introduce
App\Support\SupportDiagnostics\SupportDiagnosticBundleBuilderthat exposes explicitforTenant(...)andforOperationRun(...)entry points and returns one documented derived bundle shape. - Wire a read-only
Open support diagnosticsaction intoApp\Filament\Pages\TenantDashboardand populate the preview from authorized tenant truth only. - Wire the same read-only action into
App\Filament\Pages\Operations\TenantlessOperationRunViewer, reusingGovernanceRunDiagnosticSummaryBuilder,OperationRunLinks, and existing related-navigation helpers. - Add the dedicated support-diagnostics capability to the canonical tenant capability registry and tenant role map, then enforce it server-side on both actions after membership/entitlement is established and after the run-detail surface has resolved an entitled tenant scope.
- Add an audit action identifier and record bundle-open activity with redacted metadata through the existing audit recorder, without storing excluded payload content.
- Add focused unit tests for deterministic ordering and redaction plus focused feature tests for tenant/run action behavior,
404/403boundaries, canonical links, and audit logging.
Constitution Check (Post-Design)
Re-check result: PASS. The design remains derived, provider-neutral at the shared boundary, anchored on existing shared link and explanation paths, explicit about 404 versus 403, bounded to two read-only surfaces, and contained to focused unit + feature proof with no browser or support-desk drift.
Implementation Close-out
- Guardrail close-out: PASS. The implementation remained read-only, DB-only at render/action time, and did not create new
OperationRunrecords or dispatch provider-backed or queued operation work. - Validation lanes passed: targeted unit coverage for deterministic ordering and redaction plus targeted feature coverage for tenant action, run action, authorization boundaries, and audit/no-side-effect guarantees.
- Shared-helper note: no follow-up spec was required. The final slice stayed on existing
OperationRunPolicy,OperationRunLinks,RelatedNavigationResolver,GovernanceRunDiagnosticSummaryBuilder,RedactionIntegrity, andWorkspaceAuditLoggerseams with one boundedSupportDiagnosticBundleBuilderabstraction.