Added jobs, controllers, and PDF generation logic for management report runtime as defined in Spec 379. Includes artifact migrations, payload builders, and testing coverage. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #450
38 KiB
Feature Specification: Spec 379 - Management Report PDF Runtime Validation & Generation Completion
Feature Branch: 379-management-report-pdf-runtime
Created: 2026-06-14
Status: Draft / Ready for implementation preparation review
Input: User-provided "Spec 379 - Management Report PDF Runtime Validation & Generation Completion" draft from /Users/ahmeddarrazi/.codex/attachments/9faae34d-2858-4176-a1d4-e614689099e4/pasted-text.txt.
Repo-Truth Adjustment
Spec 378 is present in the repo as specs/378-management-report-pdf-v1/ and the latest platform-dev commit (d43ebcb4) merged the PDF/Gotenberg runtime baseline:
- pinned internal Gotenberg 8 Chromium runtime in root
docker-compose.yml apps/platform/app/Services/Pdf/PdfRenderingGateway.phpapps/platform/app/Services/Pdf/PdfRendererClient.php- renderer config in
apps/platform/config/tenantpilot.php - package governance approval in
docs/package-governance.md - deployment checklist controls in
docs/deployment-checklist.md - Spec 378 renderer/gateway tasks through
G012
Spec 378 still contains pending downstream report-generation tasks. This Spec 379 does not rewrite that history. It treats the merged Spec 378 renderer/gateway work as the baseline and prepares the follow-up implementation package for the remaining runtime validation plus actual Management Report PDF generation completion.
Spec 379 is the sole active implementation owner for post-G012 runtime validation and downstream Management Report PDF generation completion. The unchecked downstream tasks in Spec 378 are historical baseline signals only and must not be executed as a parallel implementation queue.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: TenantPilot has an approved and implemented PDF renderer/gateway baseline, but it still cannot produce a real, stored, downloadable, auditable Management Report PDF from existing review/report truth.
- Today's failure: The product can validate the rendering infrastructure in code, but an operator still cannot complete the customer-safe PDF handoff with runtime validation, artifact storage, OperationRun tracking, download authorization, and audit evidence.
- User-visible improvement: An entitled operator can generate a customer-safe management PDF from a ready current review/report source, see truthful queued or blocked feedback, download the artifact through an authorized path, and rely on provenance, disclosure, and audit trail.
- Smallest enterprise-capable version: Validate the existing Gotenberg runtime controls in staging/Dokploy, then complete one on-demand
customer_executiveManagement Report PDF generation path over existing Review Pack/rendered-report/profile/disclosure truth. - Explicit non-goals: No new PDF renderer, no new Gotenberg service, no new PDF package, no package-governance redo, no invoice/billing/e-invoice scope, no Technical or Auditor Evidence Report, no Report Delivery Center, no scheduled/email delivery, no customer portal, no dashboard redesign, no AI summary, no Word/Excel/PowerPoint export, no full Localization v1.
- Permanent complexity imported: A bounded management-report payload/generation service or equivalent adapter, optional narrow existing artifact substrate extension, possible canonical operation type mapping if no existing type fits, focused localization keys, focused Unit/Feature/Filament/Browser tests, and a staging runtime validation artifact.
- Why now: Spec 378 established the infrastructure baseline but stopped before generation. Leaving the gap open means the repo has PDF runtime machinery without the customer-facing report artifact the runtime was approved to support.
- Why not local: A local button or browser print workaround would not prove staging renderer availability, durable artifact truth, OperationRun observability, authorization, download audit, or disclosure-safe customer content.
- Approval class: Core Enterprise.
- Red flags triggered: Durable artifact output, possible stored-report substrate extension, possible operation type, and customer-facing PDF surface. Defense: the slice reuses existing renderer/profile/disclosure/report truth, forbids new renderer infrastructure, and allows no new report center or generic document framework.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve as the bounded post-Spec-378 generation completion package.
Candidate Selection Gate
- Selected candidate: Spec 379 - Management Report PDF Runtime Validation & Generation Completion.
- Source: Direct user-provided Spec 379 draft and current repo truth after Spec 378 merge.
- Why selected: The active automatic candidate queue is not a safe auto-prep source, while the user provided a concrete follow-up that aligns with the latest merged PDF runtime baseline.
- Roadmap relationship: Supports management-ready reporting, customer-safe review consumption, governance artifact maturity, and Governance-as-a-Service packaging without opening delivery-center or auditor-report scope.
- Close alternatives deferred:
- Reopening Spec 378: deferred because its merged renderer/gateway history must remain intact.
- Technical/Auditor Evidence Report PDF: separate report profile and evidence-depth package.
- Report Delivery Center or scheduled delivery: deferred until one on-demand PDF artifact is generated, stored, and audited.
- Customer Review Workspace redesign: adjacent productization, not required for the first generation path.
- Billing/invoice PDF: separate domain with legal numbering, tax, archive, and e-invoice requirements.
- Completed-spec guardrail result:
specs/356-review-pack-pdf-html-renderer-v1/,specs/357-report-profiles-disclosure-policy-v1/, andspecs/366-management-report-layout-branded-report-themes-v1/contain completed task/validation signals and are historical context only.specs/378-management-report-pdf-v1/is read-only baseline context for the renderer/gateway merge. This package does not modify it or remove pending-task history.- No
specs/379-*package existed before this preparation run.
- Smallest viable implementation slice: G013 staging/Dokploy runtime validation plus one queued/observable customer-executive PDF generation, storage, download, and audit flow from existing ready current Review Pack/rendered-report truth.
- Gate result: PASS, with the explicit repo-truth adjustment that Spec 379 must not duplicate or rebuild Spec 378 renderer infrastructure.
Problem Statement
TenantPilot has the PDF rendering gateway, but not the finished Management Report PDF workflow. The next implementation must verify that the approved renderer runtime works in the deployed container environment and then complete the business flow: build the report payload from existing review truth, render it through the approved gateway, persist the artifact safely, expose authorized download, and record operation/audit evidence.
Business / Product Value
- MSP operators can produce a real PDF for customer governance reviews instead of relying on browser print behavior.
- Customer stakeholders receive a decision-first report that names posture, risks, decisions, accepted risks, evidence basis, limitations, and next actions without raw technical leakage.
- TenantPilot can prove who generated and downloaded the PDF, from which source review/pack, under which profile/disclosure policy, and with which renderer/runtime status.
- Future delivery, auditor, technical, and packaging specs become smaller because generation/storage/audit basics are proven once.
Primary Users / Operators
- MSP service manager generating a customer-ready management report.
- TenantPilot operator validating that a report is safe to share externally.
- Customer executive or IT lead reading the generated PDF.
- Support/platform operator diagnosing a failed generation through OperationRun and safe runtime validation evidence.
Spec Scope Fields (mandatory)
- Scope: workspace plus managed-environment artifact generation and canonical report/download view.
- Primary Routes:
- existing rendered report route
/admin/review-packs/{reviewPack}/report - existing Review Pack detail route under
/admin/workspaces/{workspace}/environments/{environment}/review-packs/{record} - existing Environment Review detail route under
/admin/workspaces/{workspace}/environments/{environment}/environment-reviews/{record} - one new signed and/or server-authorized PDF download route only if existing routes cannot safely represent PDF format/profile/artifact identity
- existing rendered report route
- Data Ownership: Generated Management Report PDF is tenant-owned artifact truth bound to workspace, managed environment, source review/pack, profile, generated actor/time, operation run, private storage location, and audit records. If new persisted tenant-owned artifact columns are added, tenant/workspace ownership must satisfy the constitution.
- RBAC: Workspace membership, managed-environment entitlement, and the existing review/report capability path are required. Generation uses
Capabilities::ENVIRONMENT_REVIEW_MANAGEwhen the Environment Review owner surface is selected andCapabilities::REVIEW_PACK_MANAGEwhen the Review Pack owner surface is selected. Download usesCapabilities::REVIEW_PACK_VIEWagainst the source managed environment. Wrong workspace/environment is deny-as-not-found. Scoped member without the required generation/download capability receives 403 after scope is established. Any new capability requires spec/plan update plus canonical capability-registry tests before implementation.
For canonical-view specs:
- Default filter behavior when tenant-context is active: Generation is anchored to one source review or current ready Review Pack. Hidden remembered environment/session state must not decide source scope.
- Explicit entitlement checks preventing cross-tenant leakage: Generation, artifact lookup, OperationRun link, and PDF download must re-resolve workspace and managed-environment scope from persisted source/artifact truth and current actor entitlement.
UI Surface Impact (mandatory - UI-COV-001)
Does this spec add, remove, rename, or materially change any reachable UI surface?
- No UI surface impact
- Existing page changed
- New page/route added
- Navigation changed
- Filament panel/provider surface changed
- New modal/drawer/wizard/action added
- New table/form/state added
- Customer-facing surface changed
- Dangerous action changed
- Status/evidence/review presentation changed
- Workspace/environment context presentation changed
UI/Productization Coverage
- Route/page/surface:
- selected owner surface: Review Pack detail or Environment Review detail
- existing rendered report source
/admin/review-packs/{reviewPack}/report - optional new PDF download route/controller
- StoredReport or existing artifact detail only if chosen as the artifact registry
- Current or new page archetype: existing report/artifact owner detail plus generated PDF artifact download.
- Design depth: Strategic customer-facing report surface.
- Repo-truth level: renderer/gateway baseline repo-verified; PDF generation flow spec-ready.
- Existing pattern reused:
PdfRenderingGateway,PdfRendererClient,ReportProfileRegistry,ReportDisclosurePolicy,ReportThemeResolver, current rendered-report payload, current Review Pack readiness/current-pack checks, current signed URL/download patterns, current OperationRun and audit patterns. - New pattern required: Bounded management PDF artifact generation and download state only.
- Screenshot required: yes, because Browser/content smoke is required for the generated/downloaded PDF artifact.
- Page audit required: update UI-099, UI-042, UI-048, route inventory, or design coverage only when implementation materially changes those surfaces; otherwise record a checked no-update rationale.
- Customer-safe review required: yes. The generated PDF is customer-facing by default.
- Dangerous-action review required: yes by high-impact artifact creation. It is not destructive to Microsoft tenant state, but it creates durable shareable output and therefore needs explicit confirmation, authorization, readiness gate, audit, and tests.
- Coverage files updated or explicitly not needed:
docs/ui-ux-enterprise-audit/route-inventory.mddocs/ui-ux-enterprise-audit/design-coverage-matrix.mddocs/ui-ux-enterprise-audit/page-reports/...docs/ui-ux-enterprise-audit/strategic-surfaces.mddocs/ui-ux-enterprise-audit/grouped-follow-up-candidates.mddocs/ui-ux-enterprise-audit/unresolved-pages.mdN/A - no reachable UI surface impact
- No-impact rationale when applicable: N/A.
Cross-Cutting / Shared Pattern Reuse
- Cross-cutting feature?: yes.
- Interaction class(es): report generation, report viewer, artifact download, status/readiness messaging, header action, OperationRun start/link UX, audit.
- Systems touched: PDF renderer gateway, Review Pack rendered report, report profiles, disclosure policy, review/report owner surfaces, artifact substrate, OperationRun, audit, localization, storage.
- Existing pattern(s) to extend: current rendered-report profile/disclosure path, Review Pack current-pack/readiness checks, signed download patterns, OperationRun start/completion UX, safe audit metadata patterns.
- Shared contract / presenter / builder / renderer to reuse:
PdfRenderingGateway,ReportProfileRegistry,ReportDisclosurePolicy,ReportThemeResolver,ReviewPackService,OperationRunService,OperationRunLinks,OperationUxPresenter, audit logger/action ID pattern. - Why the existing shared path is sufficient or insufficient: Existing paths are sufficient for runtime rendering, report content, profile/disclosure, and source readiness. They are insufficient for final PDF artifact identity, storage, OperationRun generation flow, staging runtime validation proof, and download audit.
- Allowed deviation and why: A bounded management report payload builder/generation service/renderer adapter is allowed to keep generation out of controller/Blade code. It must consume the existing gateway and report truth rather than define new infrastructure.
- Consistency impact: HTML source report, PDF artifact, OperationRun, artifact metadata, and audit records must agree on source review, source pack, profile, generation actor/time, environment scope, and limitations.
- Review focus: no second renderer, no raw provider payloads, no signed URL leakage, no stack traces/SQL errors, no internal MSP-only content in customer PDF, no hidden cross-environment source selection.
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 existing terminal notification path. - Delegated start/completion UX behaviors: queued toast,
View operationlink, artifact link, run-enqueued browser event, dedupe or blocked messaging, and tenant/workspace-safe URL resolution. - Local surface-owned behavior that remains: readiness explanation, source review/pack identity, and disabled/blocked reason.
- Queued DB-notification policy: no running DB notifications; queued DB notification only if explicitly supported by the shared OperationRun UX contract and approved in implementation notes.
- Terminal notification path: central lifecycle mechanism.
- Exception required?: none. Synchronous no-run generation is out of scope for Spec 379 and would require a future spec before implementation.
Provider Boundary / Platform Core Check
- Shared provider/platform boundary touched?: yes, indirectly through report/evidence content.
- Boundary classification: platform-core report artifact and operation truth; provider-owned evidence details only where already present in disclosure-safe review/report payloads.
- Seams affected: report artifact identity, source review/pack provenance, evidence basis, operation type/catalog label, artifact source descriptor.
- Neutral platform terms preserved or introduced: management report, profile, evidence basis, limitation, managed environment, workspace, generated artifact, provenance, operation.
- Provider-specific semantics retained and why: only existing profile-safe Microsoft/provider summaries already allowed by the source report. No new provider runtime calls or Microsoft-specific renderer behavior.
- Why this does not deepen provider coupling accidentally: PDF generation uses stored review/report truth only and calls only the internal PDF renderer gateway, not Microsoft Graph.
- Follow-up path: follow-up-spec for Technical/Auditor Evidence Report or provider-specific appendix depth.
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 | yes | Native Filament action | header action, readiness messaging, OperationRun start | detail header, modal, notification | no | High-impact artifact creation, not Microsoft tenant mutation |
| PDF download route/action | yes | signed/server-authorized route plus native action/link | artifact download, audit | detail, URL, storage | no | Must re-resolve scope before bytes |
| PDF content | yes | server-rendered PDF through approved renderer | report viewer, disclosure | report payload, PDF pages | bounded report-canvas exception inherited from Spec 366 | No new visual framework |
| Artifact registry/detail if reused | yes | native Filament resource | evidence/report registry | table/detail/readiness | no | Keep global search disabled unless spec updates |
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 Report PDF | Primary Decision Surface for customer consumption | Customer/MSP decides what risks and next actions matter | executive summary, posture, decisions, accepted risks, evidence basis, limitations, next actions, provenance | technical/auditor detail out of scope | Primary because the artifact must stand alone outside the app | review/report handoff | avoids ZIP/raw admin inspection for management context |
| Generate action | Secondary Workflow Action | Operator decides whether to create durable shareable output | source review/pack, profile, readiness, limitations, confirmation | run detail and logs | Secondary because it starts artifact creation | review-pack or environment-review owner flow | one clear action, disabled when unsafe |
| Download action/detail | Secondary Context Surface | Operator retrieves a generated artifact | artifact identity, generated time, source, profile | audit/run/source metadata | Secondary because reading happens in PDF | generated artifact follow-through | avoids duplicate generation |
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 | profile, readiness, executive story, risks, decisions, evidence basis, limitations, provenance | absent or summarized | raw JSON/provider/support detail absent | read/share report | internal fields, fingerprints, raw operation context | PDF states each blocker once, later sections add proof |
| Owner detail action | operator-MSP | readiness, current source, profile, blocked reason | OperationRun detail | logs/trace only outside PDF | generate, view operation, or download | raw renderer errors | one next action based on state |
| Download route | operator-MSP, entitled customer/admin if existing policy allows | artifact identity and file bytes | request/audit metadata | raw storage path hidden | download PDF | storage path/signed URL internals | audit metadata stores source once |
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 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Owner surface action | Detail / Action | High-impact artifact generation | Generate PDF or download existing PDF | existing detail page | N/A | secondary/header or More depending existing hierarchy | N/A | existing Review Pack or Environment Review collection | existing detail route | workspace, managed environment, profile | Management report PDF | readiness, source, profile, status | none |
| PDF artifact | Report / Artifact Viewer | Customer-safe report | Read/share/download | signed/server-authorized route | N/A | source/run links outside PDF | N/A | owner surfaces only | download route | workspace, managed environment, profile | Management report PDF | limitations, evidence basis, generated metadata | bounded report-canvas exception inherited from Spec 366 |
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 | MSP operator | decide whether to create durable customer output | detail action | Is this source safe and ready to generate as a PDF? | source, profile, readiness, limitations, confirmation text | run failure detail | readiness, generation status, disclosure | TenantPilot artifact only | Generate PDF, View operation, Download PDF | high-impact confirmed artifact creation |
| Management Report PDF | customer stakeholder, MSP operator | understand current governance posture and next actions | report artifact | What does the review say and what should happen next? | executive summary, risks, decisions, accepted risks, evidence, limitations, provenance | none in customer profile | evidence completeness, governance posture, source currency | read-only | Read/download/share according to policy | none |
Proportionality Review
- New source of truth?: yes, the generated PDF artifact is durable output truth once created. It derives from existing source review/report truth.
- New persisted entity/table/artifact?: no new table is approved by default. A narrow extension to the existing artifact/report substrate is allowed if repo verification proves it is the smallest safe representation. If a new table/entity is required, implementation must stop and update spec/plan.
- New abstraction?: yes, a bounded payload/generation/renderer adapter may be introduced to keep generation out of controller/Blade code and to reuse the approved gateway.
- New enum/state/reason family?: maybe. Add only behavior-changing operation/artifact status or reason values required for generation/download behavior, and test them. Presentation-only labels stay derived.
- New cross-domain UI framework/taxonomy?: no.
- Current operator problem: operators need a real customer-ready PDF artifact with provenance, storage, authorization, OperationRun, and audit.
- Existing structure is insufficient because: Spec 378's renderer/gateway baseline can render bytes but does not own management report payload, artifact lifecycle, generation intent, or download authorization.
- Narrowest correct implementation: validate the existing runtime, then add one customer-executive PDF generation path over existing Review Pack/rendered-report/profile/disclosure truth.
- Ownership cost: one bounded generation path, possible narrow schema migration, OperationRun/audit tests, Browser/content smoke, deployment validation artifact.
- Alternative intentionally rejected: second renderer, generic document engine, Report Delivery Center, new report taxonomy, browser-print workaround, public link.
- Release truth: current-release follow-through over merged Spec 378 runtime infrastructure.
Compatibility posture
This feature assumes pre-production runtime semantics. No legacy aliases, dual-write paths, compatibility shims, or historical artifact backfills are approved unless the spec is updated first.
Testing / Lane / Runtime Impact
- Test purpose / classification: Unit, Feature, Filament/Livewire, Browser/content smoke, PostgreSQL if schema/indexes are added.
- Validation lane(s): fast-feedback, confidence, browser, pgsql when persistence constraints require it.
- Why this classification and these lanes are sufficient: Unit tests prove deterministic payload/readiness/disclosure; Feature tests prove authorization, OperationRun, audit, storage, and download; Filament/Livewire tests prove action state; Browser/content smoke proves customer-facing content and leakage boundaries.
- New or expanded test families: Spec379 Unit/Feature/Browser tests under existing PDF/report/review-pack families.
- Fixture / helper cost impact: reuse existing Review Pack/rendered-report/browser fixtures; add explicit Spec379 fixture states only for ready, blocked, generated, running, and failed generation.
- Heavy-family visibility / justification: one bounded Browser/content smoke is required because the output is a customer-facing PDF artifact.
- Special surface test profile: report-viewer plus high-impact artifact generation action.
- Standard-native relief or required special coverage: owner surface stays native Filament; generated PDF needs content/leakage proof.
- Reviewer handoff: verify no renderer duplication, no raw leakage, no Graph calls, no public storage, no global-search enablement, and no unresolved staging runtime validation.
- Budget / baseline / trend impact: browser lane cost limited to one Spec379 smoke. PostgreSQL lane only if schema constraints are touched.
- Escalation needed:
document-in-featurefor storage/OperationRun decisions;follow-up-specfor delivery center, technical/auditor report, lifecycle/retention framework, or billing documents. - Active feature PR close-out entry: Guardrail + Smoke Coverage + Runtime Validation.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec379cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec379ManagementReportPdfSmokeTest.php --compactcd 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 pint --dirtygit diff --check
User Scenarios & Testing
User Story 1 - Validate the PDF runtime before generation (Priority: P1)
As an operator preparing report generation, I need confirmation that the approved Gotenberg runtime controls work in staging/Dokploy so that generation is not enabled against an unvalidated renderer.
Why this priority: Generation depends on the runtime. Enabling PDF output without staging/runtime proof would create false readiness.
Independent Test: Validate the configured Gotenberg service and record runtime evidence without creating a report artifact.
Acceptance Scenarios:
- Given the merged Spec 378 renderer config, When runtime validation runs in staging/Dokploy, Then the health check, network scope, timeout/body-limit/concurrency controls, and no-public-port posture are verified or generation remains blocked.
- Given runtime validation fails, When an operator tries to generate a PDF, Then generation is blocked with safe guidance and no artifact is created.
User Story 2 - Generate a customer-safe Management Report PDF (Priority: P1)
As an entitled MSP operator, I can generate a customer-executive PDF from a ready current review/report source so that the customer receives a stable report artifact.
Why this priority: This is the core product value of Spec 379.
Independent Test: Seed a ready source review/pack, trigger generation, and verify the generated artifact contains required chapters and excludes forbidden raw/internal content.
Acceptance Scenarios:
- Given a ready current Review Pack with allowed
customer_executivedisclosure, When an entitled operator confirms generation, Then TenantPilot queues or starts generation through OperationRun and stores a private PDF artifact on success. - Given missing evidence, expired pack, invalid profile, renderer unavailable, storage failure, or disclosure blocker, When generation is requested, Then no ready artifact is exposed and safe blocked/failed evidence is recorded.
User Story 3 - Download and audit the generated PDF (Priority: P2)
As an entitled operator, I can download the generated PDF through a scope-safe route so that every download is authorized and auditable.
Why this priority: A generated artifact is incomplete without safe retrieval and auditability.
Independent Test: Request the download as entitled, wrong-workspace, wrong-environment, and missing-capability actors.
Acceptance Scenarios:
- Given a generated ready PDF artifact, When an entitled actor downloads it, Then the route re-resolves source/artifact scope, returns PDF bytes from private storage, and writes a safe download audit entry.
- Given wrong workspace/environment or missing membership, When the artifact URL is requested, Then TenantPilot denies as not found without leaking existence.
- Given a scoped member without download capability, When the artifact URL is requested, Then TenantPilot returns 403 after scope is established.
User Story 4 - Preserve report/runtime boundaries (Priority: P3)
As a reviewer, I need the implementation to prove it did not rebuild PDF infrastructure or widen report scope so that Spec 379 remains a bounded completion slice.
Why this priority: Prevents duplicate renderer infrastructure, report-center scope creep, and customer-safe disclosure regressions.
Independent Test: Static and feature tests prove only the approved gateway is used and no forbidden runtime/package/report scope appears.
Acceptance Scenarios:
- Given the implementation diff, When reviewer checks runtime paths, Then no second renderer/client/config/service/package is introduced.
- Given generated PDF content, When content smoke inspects text, Then raw Graph payloads, secrets, internal MSP markers, stack traces, SQL errors, signed URLs, and serialized jobs are absent.
Functional Requirements
- FR-379-001: The implementation MUST verify the existing Spec 378 Gotenberg runtime controls before enabling Management Report PDF generation.
- FR-379-002: The implementation MUST use only the existing
PdfRenderingGateway/PdfRendererClientfor production PDF rendering. - FR-379-003: The implementation MUST NOT introduce a second renderer, second Gotenberg service, new PDF package, production browser runtime, or package-governance redo.
- FR-379-004: The implementation MUST generate the PDF from existing ready/current Review Pack or rendered-report/profile/disclosure truth.
- FR-379-005: The implementation MUST explicitly resolve v1 generation to
customer_executiveor the repo-canonical customer-executive profile and fail closed for unknown, unsupported, unimplemented, or fallback profile resolution. - FR-379-006: The generated PDF MUST include executive summary, governance posture, key risks/findings, decisions or decision summary, accepted risks, evidence basis, limitations, next actions, and provenance.
- FR-379-007: The generated PDF MUST exclude raw provider payloads, secrets, signed URLs, raw operation context, SQL errors, stack traces, internal-only MSP/support content, and serialized job markers.
- FR-379-008: Generation MUST be explicit, readiness-gated, server-authorized, confirmation-gated, and auditable.
- FR-379-009: Generation MUST be queued and tracked by
OperationRunthroughOperationRunServiceand the shared OperationRun UX path; synchronous no-run generation is out of scope for Spec 379. - FR-379-010: Successful generation MUST store or reference a private artifact with source review/pack, profile, workspace, managed environment, actor, generated time, and operation-run provenance.
- FR-379-011: Failed or blocked generation MUST not expose a ready/downloadable artifact.
- FR-379-012: Download MUST be signed and/or server-authorized, re-resolve scope, return private PDF bytes, and write a safe audit event.
- FR-379-013: Non-member or wrong-scope access MUST be deny-as-not-found; scoped members missing capability MUST receive 403.
- FR-379-014:
StoredReportResourceglobal-search posture MUST remain disabled unless a future spec explicitly updates it with safe View/Edit semantics. - FR-379-015: UI coverage artifacts MUST be updated or given a checked no-update rationale when implementation changes reachable report/action/download surfaces.
- FR-379-016: Generation and download authorization MUST use the existing capability registry: generation requires
ENVIRONMENT_REVIEW_MANAGEon an Environment Review owner surface orREVIEW_PACK_MANAGEon a Review Pack owner surface, and download requiresREVIEW_PACK_VIEW; any new capability requires spec/plan update and registry tests before implementation.
Non-Functional Requirements
- NFR-379-001: No live Microsoft Graph/provider calls may occur during PDF render, generation, or download.
- NFR-379-002: Report generation must be idempotent or explicitly explain when repeated generation creates separate artifacts.
- NFR-379-003: Renderer/storage errors must map to safe reason codes/messages without raw exception leakage.
- NFR-379-004: Artifact storage must be private and must not use public or user-controlled filenames.
- NFR-379-005: Deployment impact must include staging/Dokploy runtime validation, queue workers, storage persistence, env vars, and migration status if applicable.
Key Entities / Concepts
- Management Report PDF: Durable customer-safe PDF artifact generated from existing review/report truth.
- Source Review / Review Pack: Existing report basis; current ready Review Pack is preferred as source.
- PDF Runtime Validation Artifact: Spec-local evidence that staging/Dokploy Gotenberg runtime controls were validated or blocked.
- OperationRun: Canonical execution truth for generation.
- StoredReport or Existing Artifact Substrate: Possible persistence home for generated PDF metadata if current schema can be extended narrowly.
- AuditLog: Generation/download accountability record with redacted metadata.
Out Of Scope
- New renderer infrastructure, package choice, or Gotenberg replacement.
- Technical/Auditor Evidence Report.
- Report Delivery Center, scheduled delivery, email, Teams, public links, or customer portal.
- Billing/invoice/e-invoice PDF generation.
- AI summary or AI report drafting.
- Dashboard or Customer Review Workspace redesign.
- Full localization rollout beyond required report/action labels.
- Broad artifact lifecycle/retention framework.
Acceptance Criteria
- AC-379-001: Staging/Dokploy runtime validation is recorded before generation is treated as enabled.
- AC-379-002: A ready current source can produce a private customer-executive PDF through the existing PDF gateway.
- AC-379-003: Generated artifact metadata, OperationRun result, and audit entries agree on source, profile, actor, generated/downloaded times, and scope.
- AC-379-004: Unauthorized and wrong-scope generation/download attempts do not leak artifact/source existence.
- AC-379-005: Browser/content smoke over a generated/downloaded PDF proves required management chapters exist and forbidden raw/internal strings are absent.
- AC-379-006: No application code introduces duplicate renderer infrastructure or new PDF package/runtime.
Success Criteria
- SC-379-001: An entitled operator can complete generation and download for one ready source fixture in the focused test/browser lane.
- SC-379-002: All blocked source/runtime/storage/security cases produce safe feedback and no downloadable artifact.
- SC-379-003: Focused Spec379 tests plus Spec378 gateway regression pass.
- SC-379-004: Deployment notes clearly state env, storage, queue, migration, and staging validation impact.
Risks
- Runtime validation may be unavailable in local-only context; implementation must block enablement until staging/Dokploy proof exists.
- Extending
StoredReportcould become an artifact lifecycle framework if not kept narrow. - Generation could accidentally duplicate rendered-report payload logic; implementation should extract only when it reduces review risk.
- PDF content can leak internal or raw technical data unless disclosure tests are strong.
- Queue/storage failures could expose partial artifacts unless transaction boundaries are careful.
Assumptions
- Spec 378 renderer/gateway baseline is merged and available on the target branch.
- The first v1 owner surface will be Review Pack detail or Environment Review detail unless repo verification proves a better existing entry point.
- The generated PDF is a TenantPilot artifact only; it does not mutate Microsoft tenant state.
- Staging/Dokploy validation can be recorded as a spec-local artifact during implementation.
Open Questions
No blocking product questions. Implementation must make and record three repo-truth decisions during Phase 1:
- Which existing owner surface hosts the first generation action?
- Whether the existing artifact/report substrate can represent the PDF without a new table.
- Whether an existing OperationRun type fits or a new
report.management.generatemapping is required.
Follow-Up Spec Candidates
- Technical/Auditor Evidence Report PDF.
- Report Delivery Center and scheduled/email delivery.
- Governance artifact lifecycle and retention runtime.
- Billing/invoice/e-invoice document generation.
- Customer Review Workspace PDF discovery/productization, if the first owner-surface path is insufficient.