Added PDF generation service for management reports as per Spec 378, including Gotenberg integration in docker-compose and configuration updates. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #449
47 KiB
Feature Specification: Spec 378 - Management Report PDF v1
Feature Branch: 378-management-report-pdf-v1
Created: 2026-06-14
Status: Renderer governance decision completed; renderer runtime/gateway boundary implemented; report generation not started (2026-06-14)
Input: User-provided "Spec 378 - Management Report PDF v1" draft plus repo truth from Specs 356, 357, 366, 365, 367, 372, 377, current Review Pack rendered-report runtime, StoredReport substrate, and roadmap/reporting productization docs.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: TenantPilot has a repo-real, profile-aware, management-style rendered Review Pack report, but there is no stored, downloadable PDF artifact that a customer executive or MSP service manager can archive, forward, or use in a management meeting without relying on browser print behavior.
- Today's failure: A stakeholder can open the HTML report, but the product cannot yet prove "this management report PDF was generated from this review/evidence basis, by this actor, at this time, with this profile and disclosure policy" as a durable artifact with generation and download audit.
- User-visible improvement: An entitled operator can generate a customer-executive management PDF from the current review/report truth, download it from a signed/authorized path, and show provenance, limitations, decisions, evidence readiness, accepted risks, and next actions without raw technical leakage.
- Smallest enterprise-capable version: Generate one management-ready PDF artifact for the existing
customer_executivereport profile from an existing ready/current Review Pack rendered-report source, store or reference it through the current StoredReport or canonical artifact substrate, expose one authorized download path, and audit generation plus download. - Explicit non-goals: No Technical Evidence Report, no Auditor Evidence Report, no Report Delivery Center, no scheduled delivery, no email/Teams delivery, no public links, no customer portal, no Word/PowerPoint/Excel export, no AI summary, no new review engine, no new finding engine, no framework-specific compliance report, no raw JSON appendix for customers.
- Permanent complexity imported: A bounded management-report generation service or equivalent action, a deterministic payload/readiness builder over existing rendered report/review-pack truth, a PDF rendering adapter or approved existing renderer path, minimal StoredReport/canonical artifact extension if required, one OperationRun type or current canonical run mapping if required, audit action IDs if current audit actions are insufficient, localization keys, and focused Unit/Feature/Browser tests.
- Why now: Specs 356, 357, and 366 made the rendered report route, profile/disclosure policy, and management layout repo-real. The remaining sellability gap is durable PDF generation and audit, not another HTML layout pass.
- Why not local: A browser print instruction or another HTML button cannot create durable artifact truth, generation/download audit, OperationRun observability, or repeatable proof that the PDF respected the selected profile and disclosure boundary.
- Approval class: Core Enterprise.
- Red flags triggered: New PDF rendering seam, possible StoredReport/artifact extension, possible OperationRun type. Defense: the slice stays bound to one existing report family and one
customer_executiveprofile, reuses current rendered-report/profile/disclosure truth, forbids a second report taxonomy, and includes a pre-implementation package/renderer gate. - Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve as a bounded PDF artifact productization slice with a renderer/package governance gate before runtime implementation.
Candidate Selection Gate
- Selected candidate: Spec 378 - Management Report PDF v1.
- Source: Direct user-provided attachment
/Users/ahmeddarrazi/.codex/attachments/9be0ca0f-b917-42f0-94d4-4a38f8477efc/pasted-text.txt. - Why selected: The active automatic queue says no safe next auto-prep target remains, but the user provided a concrete manual candidate that directly follows the implemented report productization chain.
- Roadmap relationship: Supports Governance-as-a-Service packaging, customer-safe review consumption, StoredReports/evidence artifact maturity, and management-ready reporting without opening auditor/technical delivery scope.
- Close alternatives deferred:
- Technical / Auditor Evidence Report v1: separate follow-up because it needs deeper evidence, appendix, and auditor-proof semantics.
- Report Delivery Center / Stored Reports UX: deferred until one management PDF artifact exists.
- Customer Review Workspace final polish: adjacent surface polish, not PDF artifact generation.
- Framework/compliance-specific reports: deferred until the general management PDF artifact path is proven.
- Scheduled/email delivery: deferred until generation, storage, access, and audit are stable.
- Completed-spec guardrail result:
specs/356-review-pack-pdf-html-renderer-v1/has completed tasks/validation and is historical HTML/rendered-report context only.specs/357-report-profiles-disclosure-policy-v1/has completed tasks/validation and is historical profile/disclosure context only.specs/366-management-report-layout-branded-report-themes-v1/has implementation close-out and browser evidence for the management HTML report; it must not be rewritten.specs/365-operations-ui-operator-actions-regression-gate/andspecs/367-operationrun-actionability-system/have completed actionability/OperationRun context and are not preparation targets.specs/372-customer-auditor-surface-safety-pass/andspecs/377-post-productization-browser-reaudit-closeout-gate/carry completed task markers/validation artifacts and are context only.- No
specs/378-management-report-pdf-v1/package existed before this preparation run.
- Smallest viable implementation slice: one on-demand management PDF generation path from an existing current ready Review Pack/rendered report using
customer_executive, with authorized generation/download, StoredReport or canonical artifact reference, OperationRun truth, audit, localization, and no raw technical appendix. - Gate result: PASS.
Renderer Governance Decision (2026-06-14)
- Decision: approved with controls.
- Approved renderer: Gotenberg 8 Chromium as an internal Docker-based PDF rendering service.
- Approved integration boundary: Laravel calls the renderer through a narrow
PdfRenderingGateway/PdfRendererClient; no direct Chromium, Chrome, Puppeteer, Playwright, Node, or browser runtime may be installed or executed in the Laravel app/queue containers for production PDF rendering. - Layer ownership:
PdfRendererClient: low-level HTTP transport to the internal Gotenberg service, including multipart request assembly, timeout handling, response status mapping, size-limit rejection, and correlation id headers.PdfRenderingGateway: shared application boundary that accepts sanitized server-generated HTML/assets plus render options and returns a safe success/failure result without exposing raw renderer errors.ManagementReportPdfRenderer: Spec 378 domain adapter that converts the management report payload into sanitized HTML/assets and callsPdfRenderingGateway; it must not own HTTP transport, OperationRun lifecycle, storage persistence, or billing/invoice semantics.
- Runtime implementation status: renderer runtime/gateway boundary implemented for Sail/local and Laravel app config. Root
docker-compose.ymlnow includes a pinned internalgotenberg/gotenberg:8.34.0-chromiumservice with no public port, health check, timeout/body-limit/concurrency/outbound controls, and app config now exposesPdfRenderingGateway/PdfRendererClientwith safe result mapping and size-limit checks. No Dokploy config file exists in the repo;docs/deployment-checklist.mdrecords the required Dokploy/runtime controls. Management report payload, storage, OperationRun, UI action, PDF templates, and report generation are not started. - Next required implementation task before report generation work: confirm the Gotenberg runtime controls in staging/Dokploy, then implement management report payload/readiness/storage/OperationRun/UI/PDF generation through this gateway only.
- Decision matrix:
artifacts/spec378-pdf-renderer-decision-matrix.md. - Constitution review:
artifacts/spec378-constitution-renderer-gate-review.md. - Package governance:
docs/package-governance.mdnow records Gotenberg 8 Chromium as an approved runtime service with controls. - Invoice / billing boundary: Gotenberg is approved as shared internal PDF rendering infrastructure for report-style documents only. This does not approve legal invoice generation, German B2B e-invoicing, XRechnung, ZUGFeRD/Factur-X, GoBD archival, tax calculation, invoice numbering, or billing compliance.
SaaS Invoice / Billing Boundary
The approved renderer is shared infrastructure, not shared billing truth:
Shared PDF Rendering Infrastructure
-> Gotenberg / Chromium Renderer
-> PdfRenderingGateway
-> Storage
-> Audit
-> OperationRun
Domain-specific generators
-> ManagementReportGenerator
-> EvidenceReportGenerator
-> InvoiceDocumentGenerator
-> CreditNoteDocumentGenerator
StoredReportis notBillingDocument.Report IDis notInvoice Number.OperationRun IDis notInvoice Number.StoredReport IDis notInvoice Number.- Future billing specs must separately define
BillingDocument,InvoiceNumberAllocator,InvoiceTaxCalculator,EInvoiceXmlBuilder,ZugferdFacturXBuilder,XRechnungBuilder,InvoicePdfRenderer via PdfRenderingGateway,BillingDocumentArchive, andBillingAuditTrailbefore any invoice implementation.
Repo Truth Reconciliation
The user draft is accepted with these repo-based corrections:
- The existing management-ready report surface is the authenticated signed route
/admin/review-packs/{reviewPack}/report, implemented byReviewPackRenderedReportControllerand productized by Spec 366. Spec 378 must reuse that route/payload/theme/disclosure family rather than create a second report universe. ReportProfileRegistryandReportDisclosurePolicyalready exist. The management PDF must usecustomer_executiveor the repo-canonical equivalent, and invalid/unimplemented profile requests must fail closed or resolve through the existing policy.- There is no native PDF package in
apps/platform/composer.json. Playwright exists as frontend/browser tooling, not an approved production PDF runtime. Gotenberg 8 Chromium is now approved with controls as an internal Docker-based renderer service; the Sail/local runtime service, app config, and gateway/client boundary now exist, while report generation remains gated until staging/Dokploy controls are confirmed. Any different renderer, new runtime package, or production browser dependency requiresdocs/package-governance.mdreview and spec/plan update before code changes. StoredReportcurrently storesworkspace_id,managed_environment_id,report_type, JSONBpayload,fingerprint, andprevious_fingerprint, and only supports existing permission/admin-role report types inStoredReportResource. Storing a PDF may require a narrow substrate extension; if a new persisted artifact entity is needed, the implementation must stop and split.- Review Pack generation already owns queued export and signed ZIP/download behavior. Spec 378 may reuse current Review Pack current-pack checks and signed URL patterns, but must not alter the ZIP contract or make historical/expired packs impersonate current management reports.
- OperationRun truth exists through
OperationRunService,OperationRunType,OperationCatalog, and Operations UI/actionability work. A newreport.management.generatemapping is allowed only if current repo truth has no suitable canonical type; if added, it must be cataloged, tested, and surfaced consistently. - Download audit exists for Review Packs through
AuditActionId::ReviewPackDownloaded. Management PDF generation/download must record distinct audit metadata if reusing that action would obscure artifact type, profile, format, or source review.
Problem Statement
TenantPilot can now render a customer-safe management report in HTML, but a management meeting or customer handoff usually needs a stable PDF artifact. The current HTML/print path is useful for viewing, but it does not provide durable PDF artifact truth, artifact retention/discovery, generation observability, or auditable download history.
Spec 378 closes only that productization gap: generate a management PDF from existing review/report truth, prove the report was profile-safe and disclosure-safe, store or reference it through the existing artifact model, and make access/download auditable.
Business / Product Value
- MSPs can hand customers a management-ready governance PDF without exporting raw technical evidence.
- Customers and executives can understand current posture, key risks, decisions, accepted risks, evidence readiness, limitations, and provenance from one document.
- TenantPilot can prove when and how a report artifact was generated and downloaded.
- Future Technical/Auditor reports, delivery center, scheduled delivery, and service packaging get a smaller, safer foundation.
Primary Users / Operators
- MSP service manager generating a customer governance report.
- IT lead, CISO, or executive reading the PDF.
- TenantPilot operator verifying that a report can be shared externally.
- Auditor-adjacent stakeholder who needs management context, not raw evidence detail.
Spec Scope Fields (mandatory)
- Scope: workspace, tenant/managed-environment, canonical artifact/report view.
- Primary Routes:
- Existing rendered report route:
/admin/review-packs/{reviewPack}/report. - Existing Review Pack detail route:
/admin/workspaces/{workspace}/environments/{environment}/review-packs/{record}. - Existing Environment Review detail route:
/admin/workspaces/{workspace}/environments/{environment}/environment-reviews/{record}. - Optional existing Customer Review Workspace entrypoint:
/admin/reviews/workspace. - One new signed/authorized management PDF download route only if the existing download route cannot safely represent PDF format/profile/artifact identity.
- Existing rendered report route:
- Data Ownership:
- Existing
EnvironmentReview,ReviewPack,EvidenceSnapshot,Finding,FindingException,StoredReport,OperationRun, andAuditLogremain the authoritative data/artifact sources. - Generated PDF is tenant-owned artifact truth bound to
workspace_id, constitution-compliant tenant scope, and the sourcemanaged_environment_id. - If the chosen persistence substrate does not already store
tenant_idfor tenant-owned artifact truth, implementation must add a NOT NULLtenant_idor stop and update this spec/plan with an explicit constitution-compliant exception before persistence changes.managed_environment_idalone is not sufficient for newly persisted tenant-owned artifact truth. - No live Microsoft Graph/provider call may occur during report render or PDF generation.
- Existing
- RBAC:
- Workspace membership, tenant entitlement, and managed-environment entitlement are required.
- Non-member / wrong workspace / wrong tenant / wrong environment access is deny-as-not-found.
- Member missing generation/download capability receives 403 after scope is established.
- Generation should reuse the existing review/export/manage capability path unless repo verification proves a new capability is required.
- Download should reuse current review-pack/stored-report view capability semantics unless repo verification proves a new download capability is required.
For canonical-view specs:
- Default filter behavior when tenant-context is active: The PDF is anchored to one concrete current ready Review Pack or its source Environment Review. It must not depend on hidden remembered environment/session state.
- Explicit entitlement checks preventing cross-tenant leakage: Generation, stored report lookup, artifact download, and signed route resolution must re-resolve workspace, tenant, and managed environment scope from the artifact source and actor, not from untrusted URL/query parameters alone.
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 (mandatory when UI Surface Impact is not "No UI surface impact")
- Route/page/surface:
ReviewPackRenderedReportControllerandresources/views/review-packs/rendered-report.blade.phpas source/render contract.EnvironmentReviewResourceand/orReviewPackResourceheader/detail action surfaces for generation/download.StoredReportResourceonly if the generated PDF appears in the stored-report register/detail.- New signed/authorized PDF download route if required.
- Current or new page archetype: Existing rendered review report / evidence artifact detail / report download action.
- Design depth: Strategic customer-facing report surface.
- Repo-truth level: repo-verified for HTML/rendered report; spec-required for generated PDF artifact.
- Existing pattern reused:
ui-099-rendered-review-report.md,ui-042-review-pack-detail.md,ui-048-stored-report-detail.md,ReportProfileRegistry,ReportDisclosurePolicy,ReviewPackService::generateRenderedReportUrl(), current signed download route pattern, current OperationRun/audit patterns. - New pattern required: Bounded PDF artifact generation and download state only. No report center, theme editor, portal, or second report taxonomy.
- Screenshot required: yes for browser smoke of generation/download state and PDF/content smoke where tooling supports it.
- Page audit required: Update UI-099 and/or UI-042/UI-048 only if implementation materially changes hierarchy, action placement, or report artifact presentation; otherwise record a no-update rationale in close-out.
- Customer-safe review required: yes. The management PDF is customer-facing by default.
- Dangerous-action review required: yes by high-impact classification. "Generate management PDF" is not destructive, but it creates a durable customer-facing artifact and must be authorization-gated, readiness-gated, confirmation-gated via Filament confirmation, auditable, and clear about profile/disclosure.
- Coverage files updated or explicitly not needed:
docs/ui-ux-enterprise-audit/route-inventory.md- update when a new signed/authorized PDF route is added.docs/ui-ux-enterprise-audit/design-coverage-matrix.md- update when the owner-surface action hierarchy, report artifact state, or customer-facing report surface materially changes.docs/ui-ux-enterprise-audit/page-reports/ui-099-rendered-review-report.md- update when rendered-report/PDF source content or customer-facing report presentation materially changes.docs/ui-ux-enterprise-audit/page-reports/ui-042-review-pack-detail.md- update when the Review Pack detail action/download state is used or changed.docs/ui-ux-enterprise-audit/page-reports/ui-048-stored-report-detail.md- update when the generated PDF appears in StoredReport registry/detail.docs/ui-ux-enterprise-audit/strategic-surfaces.md- update only if management PDF becomes a newly classified strategic surface beyond the existing rendered-report family.docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md- update only if deferred Delivery Center, Technical/Auditor report, or artifact lifecycle follow-up scope changes.docs/ui-ux-enterprise-audit/unresolved-pages.md- update only if implementation exposes a new unresolved reachable surface.N/A - no reachable UI surface impact
- No-impact rationale when applicable: N/A.
Cross-Cutting / Shared Pattern Reuse
- Cross-cutting feature?: yes.
- Interaction class(es): report generation, artifact download, status/readiness messaging, header actions, report viewer, audit, OperationRun links.
- Systems touched:
ReportProfileRegistry,ReportDisclosurePolicy,ReviewPackRenderedReportController,ReviewPackService,StoredReport,StoredReportResource,OperationRunService,OperationRunType,OperationCatalog, audit logging, localization, Review Pack and Environment Review owner surfaces. - Existing pattern(s) to extend: current rendered report payload, current profile/disclosure policy, current signed URL pattern, current Review Pack current-pack guards, current OperationRun start/completion UX, current stored-report registry if it can represent this artifact.
- Shared contract / presenter / builder / renderer to reuse: existing report profile/disclosure/theme state first. Add only a bounded management-report payload/PDF adapter when existing controller-local state is insufficient to test generation safely.
- Why the existing shared path is sufficient or insufficient: Existing paths are sufficient for report content, profile, disclosure, layout, and signed report URLs. They are insufficient for durable PDF artifact storage, generation readiness, artifact download state, and generation/download audit.
- Allowed deviation and why: A bounded
ManagementReportPayloadBuilder,ManagementReportPdfRenderer, andManagementReportGenerationServiceor equivalent names are allowed if they keep PDF generation out of Blade/controller code and avoid duplicating report truth. The domain renderer may consumePdfRenderingGateway, but HTTP transport and Gotenberg-specific request construction belong toPdfRendererClient. - Consistency impact: HTML report, PDF artifact, stored artifact metadata, OperationRun result, and audit metadata must agree on profile, source review, source Review Pack, evidence basis, generated time, actor, and limitations.
- Review focus: Confirm no raw provider payloads, internal MSP fields, signed URLs, access tokens, stack traces, SQL errors, or serialized jobs appear in the PDF body or audit metadata.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: yes.
- Shared OperationRun UX contract/layer reused:
OperationRunService,OperationRunType/OperationCatalogif a new type is needed,OperationRunLinks,OperationUxPresenter, and current Operations UI/actionability patterns. - Delegated start/completion UX behaviors: queued toast/link, artifact link, run-enqueued event, blocked/failed-to-start messaging, tenant/workspace-safe operation URL resolution, and terminal notification policy must use existing shared paths.
- Local surface-owned behavior that remains: only readiness explanation and the generation input/action placement.
- Queued DB-notification policy: explicit opt-in only if current shared OperationRun UX contract supports it; otherwise no running DB notification.
- Terminal notification path: central lifecycle mechanism.
- Exception required?: none expected. If PDF generation is implemented synchronously and under 2 seconds, implementation must still audit and justify skipping OperationRun; however the preferred v1 path is queued/observable because artifact rendering/storage can fail independently.
Provider Boundary / Platform Core Check
- Shared provider/platform boundary touched?: yes, indirectly through report content and source metadata.
- Boundary classification: platform-core report/artifact truth with provider-owned evidence details when already present in review/pack summaries.
- Seams affected: report profile, evidence basis, scope/limitations, source metadata, StoredReport artifact source descriptors, OperationRun type/catalog labeling.
- Neutral platform terms preserved or introduced: report, profile, audience, evidence basis, limitation, managed environment, workspace, generated artifact, provenance, operation.
- Provider-specific semantics retained and why: Existing Microsoft/provider details may appear only as summarized evidence/source context already allowed by
customer_executivedisclosure policy. No new provider-specific PDF renderer logic is introduced. - Why this does not deepen provider coupling accidentally: PDF generation consumes stored review/report truth only; it does not call Graph, inspect raw provider payloads, or make Microsoft-specific fields mandatory in platform-core artifact identity.
- Follow-up path: follow-up-spec for Technical/Auditor Evidence Report if detailed provider/evidence appendix is needed.
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 |
|---|---|---|---|---|---|---|
| Generate management PDF action on Environment Review / Review Pack owner surface | yes | Native Filament action | header action, status/readiness, OperationRun start | detail header, modal/notification | no | High-impact artifact creation, not destructive |
| PDF download action/link | yes | Native URL/action plus signed route | artifact download, report viewer | detail, URL, stored artifact | no | Must be scope-safe and audit download |
| Rendered report source/PDF payload mapping | yes | Existing custom report canvas plus server-side PDF renderer | report viewer, disclosure | report payload, PDF artifact | UI-EX-001 inherited for print/report canvas only |
Do not create new visual language beyond PDF layout constraints |
| Stored report list/detail representation, if used | yes | Existing Filament resource | evidence/report registry | table/detail/readiness state | no | Preserve read-only registry semantics |
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 |
|---|---|---|---|---|---|---|---|
| Management PDF artifact | Primary Decision Surface for customer report consumption | Executive or MSP decides what risks, decisions, and evidence limitations matter | cover, executive summary, posture, decisions, top risks, accepted risks, evidence readiness, limitations, provenance | technical/auditor evidence is out of scope | Primary because the PDF must stand alone outside the app | Follows review/report handoff workflow | Avoids opening ZIP/JSON/admin pages for management context |
| Generate action | Secondary Workflow Action | Operator decides whether the current review/pack is ready to create a durable customer artifact | readiness, profile, source review/pack, limitations, blocked reason | OperationRun detail and stored artifact detail | Secondary because it initiates artifact creation | Follows review pack/report owner surfaces | One action, disabled when not ready |
| Stored report/detail entry, if used | Tertiary Evidence / Diagnostics | Operator inspects generated artifact metadata or re-downloads | artifact type, generated at, profile, source review/pack, lifecycle | payload/source descriptors collapsed | Tertiary because management reading happens in PDF | Follows StoredReport evidence registry | Avoids raw payload as first-read path |
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 |
|---|---|---|---|---|---|---|---|
| Customer executive PDF | customer-read-only, operator-MSP | management summary, posture, decisions, top risks, accepted risks, evidence readiness, limitations, provenance | none by default | raw JSON/provider payloads absent | review recommended next actions | technical appendix, internal notes, raw context | PDF derives from existing profile/disclosure state |
| Generate/download UI | operator-MSP | readiness, profile, source artifact, generated/download status | OperationRun link and failure reason | raw stack/SQL/provider payload absent | generate or download management PDF | failed render diagnostics in logs/run detail only | OperationRun, audit, and artifact metadata use same IDs |
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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Environment Review / Review Pack detail action | Detail / Action | Report artifact generation | Generate management PDF or download existing PDF | Existing detail page | N/A | Header secondary or More if another primary exists | N/A | existing review/review-pack routes | existing review/review-pack routes | workspace + managed environment + profile | Management report PDF | readiness, profile, source review/pack, limitations | none |
| PDF download route | Artifact Download | Signed/authorized download | Download artifact | Direct signed/authorized URL | N/A | N/A | N/A | N/A | signed artifact URL | workspace + managed environment in resolved artifact | Management report PDF | provenance and safe filename/headers | none |
| StoredReport entry, if reused | Registry / Detail | Read-only report registry | Open/download current report | Clickable row/detail | required if listed | one safe shortcut max | N/A | existing stored reports route | stored report view | workspace + managed environment | Stored report | report type, profile, generated time, source review | 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 |
|---|---|---|---|---|---|---|---|---|---|---|
| Generate management PDF action | Tenant/MSP operator | Decide whether to create a durable customer-facing report artifact | Detail action | Is this review/pack ready and safe to generate as a management PDF? | source review/pack, profile, readiness, limitation/blocked reason | run failure details | readiness, generation status, disclosure, artifact availability | TenantPilot only; no Microsoft tenant mutation | Generate management PDF, View operation, Download PDF | none; high-impact artifact creation is confirmation/readiness-gated |
| Management PDF | Customer/executive/MSP | Decide management follow-up | Report artifact | What is the governance state and what decisions are needed? | executive summary, posture, decisions, risks, accepted risks, evidence readiness, limitations, provenance | none in v1 | evidence readiness, risk/posture, acceptance/decision state | N/A read-only artifact | Download/view/share outside app | none |
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: yes, a generated PDF artifact is durable artifact truth once created. It remains derived from source review/pack truth and must carry provenance.
- New persisted entity/table/artifact?: yes, generated PDF artifact storage/reference is required. Prefer a narrow extension of existing
StoredReport/storage substrate; a new table/entity requires a spec/plan update before implementation. - New abstraction?: likely yes, a bounded payload builder, renderer adapter, and generation service to keep queries/business logic out of Blade/controllers/jobs.
- New enum/state/reason family?: possibly one operation type/report type; no broad lifecycle/status family beyond current artifact/report states.
- New cross-domain UI framework/taxonomy?: no.
- Current operator problem: The product cannot produce and audit a durable management PDF artifact from a released review/report.
- Existing structure is insufficient because: The existing rendered report is HTML/print-only,
StoredReporthas no PDF artifact/download model today, and Review Pack ZIP download audit does not identify a management PDF profile/format artifact. - Narrowest correct implementation: One management PDF profile, one source family, one artifact output, one generation action, one download path, and focused storage/audit/OperationRun integration.
- Ownership cost: PDF renderer maintenance, artifact storage/retention considerations, generation/download tests, browser/content smoke, audit/action ID maintenance, and deployment worker/storage notes.
- Alternative intentionally rejected: Tell users to use browser print. That avoids code but does not provide stored artifact truth, generation audit, download audit, or consistent server-side proof.
- Release truth: Current-release truth; this directly follows repo-real report profile/layout work.
Compatibility posture
This feature assumes a pre-production environment. No legacy PDF/report compatibility is required. If storage schema changes are needed, implement the narrow current shape rather than compatibility shims.
Testing / Lane / Runtime Impact
- Test purpose / classification: Unit, Feature, Filament/Livewire action tests, Browser/PDF content smoke.
- Validation lane(s): fast-feedback, confidence, browser; PostgreSQL lane only if migrations/indexes/storage metadata require database-specific proof.
- Why this classification and these lanes are sufficient: Unit tests prove deterministic payload/readiness/disclosure; Feature tests prove authorization, OperationRun, storage, audit, and download; Browser/content smoke proves real operator generation flow and management PDF content/leakage boundaries.
- New or expanded test families: Spec378 unit/feature/browser files under Reports/ReviewPack/StoredReports as implementation decides.
- Fixture / helper cost impact: Reuse Spec 357/366 rendered-report fixtures and current review-output browser fixtures; any new helper must be local to Spec378 unless three current specs need it.
- Heavy-family visibility / justification: one explicit browser/content smoke is justified because the output is customer-facing and document-format dependent.
- Special surface test profile: report-viewer / customer-facing artifact surface plus high-impact artifact generation action.
- Standard-native relief or required special coverage: special coverage required for PDF text/content, leakage absence, signed/authorized download, and disabled/not-ready generation state.
- Reviewer handoff: Reviewers must confirm the renderer path is approved, no raw technical leakage appears, operation/audit/artifact metadata agree, and no Report Delivery Center/auditor report scope slipped in.
- Budget / baseline / trend impact: low to moderate; one browser/content smoke and artifact fixture may add runtime. Record budget follow-up if PDF rendering materially slows browser or confidence lanes.
- Escalation needed: document-in-feature for approved renderer/package decision; follow-up-spec for Technical/Auditor Report, Delivery Center, scheduled delivery, or artifact lifecycle expansion.
- Active feature PR close-out entry: Guardrail + Smoke Coverage.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec378cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec357cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec366cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec378ManagementReportPdfSmokeTest.php --compactcd apps/platform && ./vendor/bin/sail pint --dirtygit diff --check
User Scenarios & Testing
User Story 1 - Generate a management PDF from a ready review (Priority: P1)
As an MSP operator, I can generate a customer-executive management PDF from a current ready Review Pack or Environment Review so that I can provide a stable customer-facing governance artifact.
Why this priority: This is the core value of the feature.
Independent Test: Given a ready current Review Pack and authorized actor, invoking the action creates/queues generation, completes with a stored PDF artifact, records OperationRun/audit metadata, and exposes a download link.
User Story 2 - Read a decision-first PDF without technical leakage (Priority: P1)
As a customer executive, I can read the PDF and understand posture, decisions, top risks, accepted risks, evidence readiness, limitations, next actions, and provenance without raw Graph data, secrets, SQL errors, stack traces, or internal MSP details.
Independent Test: Extract PDF text or inspect rendered artifact content and assert required chapter labels are present while forbidden strings/payload markers are absent.
User Story 3 - Enforce scope and capability on generation/download (Priority: P1)
As a platform owner, I need cross-workspace and cross-environment report access to fail closed so that generated customer artifacts do not leak tenant data.
Independent Test: Users without workspace/environment entitlement cannot generate or download; scoped members without capability get 403 after scope; no artifact is created for denied generation.
User Story 4 - Fail safely when rendering or storage fails (Priority: P2)
As an operator, I need failed PDF generation to leave clear OperationRun/audit evidence and no half-visible false report.
Independent Test: Simulate renderer/storage failure; OperationRun ends failed or blocked with safe reason, no ready artifact/download is exposed, and user-facing copy avoids stack traces.
Functional Requirements
- FR-378-001: The system MUST generate a management PDF only from an existing current ready Review Pack or repo-equivalent ready Environment Review source.
- FR-378-002: The generated PDF MUST use
customer_executiveor repo-canonical management profile by default. - FR-378-003: The system MUST apply
ReportDisclosurePolicyor its repo-canonical successor before rendering PDF content. - FR-378-004: The PDF MUST include cover, executive summary, governance posture, key decisions, top risks/findings, accepted risks, evidence readiness, scope and limitations, recommended next actions, report provenance, and a short method summary.
- FR-378-005: The PDF MUST NOT include raw provider payloads, raw JSON appendix, access tokens, refresh tokens, client secrets, signed URLs, SQL errors, stack traces, serialized jobs, internal MSP-only notes, or raw operation context.
- FR-378-006: The PDF artifact MUST be stored or referenced through
StoredReportor the repo-canonical report/artifact substrate with workspace, tenant scope, managed environment, source review/pack, profile, format, generated-at, generated-by, and operation-run provenance. - FR-378-007: Generation MUST create or reuse a canonical
OperationRununless implementation proves a synchronous no-run path is safer and updates this spec/plan before code changes. - FR-378-008: Generation and download MUST write audit evidence with actor, workspace, tenant scope, managed environment, source review/pack, artifact/report id, operation run id, profile, format, and safe metadata.
- FR-378-009: Download MUST be signed and/or server-authorized, scope-safe, and short-lived when URL signing is used.
- FR-378-010: Generation action MUST be hidden or disabled with a safe reason when source review/pack is missing, not ready, expired, not current, profile-blocked, disclosure-blocked, or unauthorized.
- FR-378-011: Failure states MUST not expose a ready artifact or stale download link.
- FR-378-012: EN and DE labels MUST cover PDF chapter titles, generation/download actions, readiness reasons, and core disclosure labels through existing localization seams.
- FR-378-013: The
Generate management PDFaction MUST execute through a Filament action with server-side authorization and explicit confirmation (->requiresConfirmation()or the repo-approved equivalent) before artifact creation starts. - FR-378-014: PDF rendering MUST use the approved internal Gotenberg 8 Chromium service through a Laravel
PdfRenderingGateway/PdfRendererClient, unless this spec/plan are updated through package/runtime governance before implementation.
Non-Functional Requirements
- NFR-378-001: No live Graph/provider/API calls during render, generation, or download.
- NFR-378-002: PDF rendering MUST avoid remote fonts/assets and must be deterministic enough for tests and offline worker execution.
- NFR-378-003: PDF artifact storage MUST use a private disk or repo-approved private object storage path.
- NFR-378-004: PDF generation MUST be idempotent for the same source review/pack/profile/fingerprint when practical, or explicitly explain why a new artifact per generation is required.
- NFR-378-005: Queue/runtime failures MUST be observable through OperationRun and logs without secret leakage.
- NFR-378-006: Any new package/runtime dependency MUST pass package governance, license/security/version checks, and deployment impact review before implementation.
- NFR-378-007: Filament v5 and Livewire v4.0+ compliance MUST be preserved; no Livewire v3 or Filament v3/v4 APIs.
- NFR-378-008: Laravel panel provider registration MUST remain in
apps/platform/bootstrap/providers.php; no panel provider changes are planned. - NFR-378-009: Global search posture MUST remain explicit.
StoredReportResourcecurrently disables global search and has a View page; no globally searchable management report resource is introduced. - NFR-378-010: No new Filament assets are planned. If implementation registers assets unexpectedly, deployment must document
cd apps/platform && php artisan filament:assets. - NFR-378-011: Gotenberg MUST be internal-network only, pinned to an explicit Gotenberg 8 Chromium image tag or digest, health-checked, timeout-limited, request/output-size-limited, and unavailable-safe before management PDF generation can run.
- NFR-378-012: Spec 378 v1 MUST NOT use user-provided URL rendering, remote fonts/assets, signed URLs in HTML, secrets in HTML, raw provider payloads in HTML, or public renderer endpoints.
Acceptance Criteria
- AC-378-001: Authorized operator can generate a management PDF from a current ready review/pack.
- AC-378-002: Generated PDF uses the customer executive profile and disclosure policy.
- AC-378-003: PDF contains decision-first management sections and provenance.
- AC-378-004: PDF artifact is stored or referenced through the repo-canonical report/artifact substrate.
- AC-378-005: Generation is observable through OperationRun or an explicitly justified no-run path.
- AC-378-006: Generation and download are audit-visible.
- AC-378-007: Cross-workspace, cross-tenant, and cross-environment generation/download are denied.
- AC-378-008: Missing readiness or blocked disclosure prevents generation or produces a clearly limited/blocked state according to policy.
- AC-378-009: PDF text/content smoke proves required sections present and forbidden raw/internal content absent.
- AC-378-010: EN/DE labels are present or routed through existing localization fallback.
- AC-378-011: Spec357, Spec366, Review Pack, Customer Review Workspace, and OperationRun regressions remain green or unrelated failures are documented honestly.
Success Criteria
- Operators can create a management PDF without manual browser print instructions.
- The PDF can stand alone as a customer-facing management artifact.
- Audit and OperationRun records are sufficient to answer who generated/downloaded what, when, for which review/pack/profile.
- No technical/auditor evidence dump appears in v1.
Risks
- PDF runtime risk: Gotenberg 8 Chromium is approved with controls and the Sail/local service, app config, and gateway/client boundary now exist, but staging/Dokploy controls still need validation before report generation is enabled. Mitigation: confirm internal-only service wiring, health check, timeout/size controls, and queue failure behavior on staging before enabling generation.
- Artifact model risk: Existing
StoredReportmay be too narrow for file artifacts. Mitigation: extend narrowly or stop/split before creating a new artifact entity. - Disclosure leakage risk: PDF renderer may include hidden HTML or raw fields. Mitigation: build payload before render, test absence of forbidden content, and keep raw sections out of
customer_executive. - Queue/storage risk: PDF rendering may fail independently of source review readiness. Mitigation: OperationRun failed/blocked outcomes, private storage, no ready artifact on failure.
- Scope creep risk: Auditor/technical/report-center features are attractive adjacent work. Mitigation: explicit non-goals and follow-up candidates.
Assumptions
- The source of truth is an existing ready current Review Pack generated from an Environment Review.
- The existing HTML rendered report is the preferred content/layout source for management sections.
customer_executiveremains the default management profile.- The product is still pre-production, so narrow schema adjustments may replace current shape without compatibility shims if approved by the implementation spec/plan.
- Local/Sail and Dokploy deployment can provide a queue worker and private artifact storage path.
Open Questions
- Renderer governance decision is complete. Gotenberg 8 Chromium is approved with controls as the internal renderer service.
- Runtime/gateway boundary implementation has started and the Sail/local service plus Laravel app config now exist. No Dokploy config file is present in the repo; deployment checklist controls are documented for staging.
- Management report payload, storage, OperationRun, UI action, PDF templates, and report generation remain out of scope until staging/runtime controls are confirmed and the next implementation phase begins.
Out Of Scope
- Technical Evidence Report PDF.
- Auditor Evidence Report PDF.
- Full report delivery center.
- Scheduled/email/Teams delivery.
- Public share links or customer portal.
- New Review Engine or Finding Engine.
- AI-generated summaries.
- Word/DOCX, PowerPoint, Excel, or raw JSON customer appendix.
- Framework-specific compliance reports.
- Broad StoredReports UX redesign beyond the minimum artifact representation needed for this PDF.
Follow-Up Spec Candidates
- Spec 379 - Technical / Auditor Evidence Report v1.
- Report Delivery Center / Stored Reports UX.
- Scheduled Report Delivery and Approval v1.
- Customer Review Workspace final PDF handoff polish.
- Governance Service Packaging report cadence and co-branding follow-up.