TenantAtlas/specs/357-report-profiles-disclosure-policy-v1/spec.md
ahmido b7907bd69d feat: add report profile and disclosure policy to rendered review reports (#428)
Implementing report profiles and disclosure policy as per spec 357.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #428
2026-06-06 09:41:19 +00:00

33 KiB

Feature Specification: Spec 357 - Report Profiles & Disclosure Policy v1

Feature Branch: 357-report-profiles-disclosure-policy-v1
Created: 2026-06-05
Status: Draft
Type: Reporting policy / disclosure governance / rendered-report hardening
Runtime posture: Static profile registry plus disclosure-policy evaluation over the current ReviewPack rendered-report contract. No profile admin UI, no new persistence, no scheduling, no customer portal, no AI, and no native PDF stack.
Input: User-provided Spec 357 draft (pasted-text.txt) plus repo truth from Specs 347, 355, and 356 and the current rendered review-report runtime.

Dependencies And Repo-Truth Adjustments

This spec is a bounded follow-up over already repo-real review-output work:

  • Spec 347 - Review Pack Output Contract & Readiness Semantics
  • Spec 355 - Platform Sellable Smoke Matrix
  • Spec 356 - Review Pack PDF/HTML Renderer v1
  • Current runtime seams:
    • apps/platform/app/Http/Controllers/ReviewPackRenderedReportController.php
    • apps/platform/app/Support/ReviewPacks/ReviewPackOutputReadiness.php
    • apps/platform/app/Support/ReviewPacks/ReviewPackOutputResolutionGuidance.php
    • apps/platform/resources/views/review-packs/rendered-report.blade.php
    • apps/platform/app/Services/ReviewPackService.php

Repo-truth adjustments against the draft:

  • The rendered stakeholder report already exists on the authenticated route /admin/review-packs/{reviewPack}/report; this spec must extend that route, not create a second report family.
  • Any v1 profile-selection parameter must flow through the existing signed rendered-report URL generation seams (ReviewPackService::generateRenderedReportUrl() plus current owner-surface helpers/actions), not a controller-only ad hoc query contract.
  • The current renderer already derives readiness, limitations, evidence basis, and disclosure copy from stored ReviewPack and EnvironmentReview truth.
  • Native server-side PDF is still not implemented. This spec must remain HTML/report-policy only.
  • ReviewPackOutputReadiness::derive() currently receives protectedValuesHidden and disclosurePresent as boolean inputs. Those values are not yet modeled as independent proof-state results. Spec 357 must preserve that distinction and avoid silently upgrading assumptions into verified truth.
  • No report profile registry currently exists in config or support code. No report_profile persistence, delivery policy ledger, or profile selector surface exists today.

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

  • Problem: TenantPilot can now render a customer-facing review report, but it still lacks an explicit policy layer that determines which audience the report is for, which sections are allowed, and which disclosures must remain visible regardless of presentation preferences.
  • Today's failure: The current rendered report is effectively one output shape with readiness-driven copy. That makes future customer, internal, technical, and auditor-oriented report variants risky because the renderer has no bounded policy contract to stop a profile from hiding limitations, evidence gaps, internal-only boundaries, or the non-certification disclosure.
  • User-visible improvement: Operators can trust that rendered reports are audience-aware without becoming truth-optional. Customer-safe variants stay conservative, internal variants stay clearly internal, and every report shows the required readiness, evidence, limitation, and disclosure metadata.
  • Smallest enterprise-capable version: Add a static profile registry, a disclosure-policy evaluator with explicit proof states, and profile-aware rendering on the existing report route and linked review/report surfaces.
  • Explicit non-goals: No profile CRUD, no database table, no scheduling, no delivery workflow, no customer portal, no AI/HITL runtime, no native PDF, no branding editor, no framework-specific NIS2/CIS/BSI report implementation, and no second artifact family.
  • Permanent complexity imported: One bounded static registry, one bounded disclosure-policy evaluator, one local rendered-report payload/view-model layer if needed, focused localization additions, focused Unit/Feature/Browser tests, and UI-audit follow-through. No new persisted truth, no new queue family, and no new cross-domain framework.
  • Why now: Spec 356 made the rendered report repo-real. The next honest gap is no longer "can we render HTML?" but "can we prove which truths every report profile must show before broader delivery or customer-consumption work grows?"
  • Why not local: Copy-only changes in the Blade view would not create a reusable, testable policy boundary. Broader delivery or portal work would be premature without a profile/disclosure contract underneath.
  • Approval class: Core Enterprise.
  • Red flags triggered: New policy layer, customer-facing disclosure semantics, and rendered-output surface changes. Defense: the slice stays on one existing report family, keeps policy static, forbids new persistence and delivery execution, and explicitly models assumptions instead of faking proof.
  • Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
  • Decision: approve.

Candidate Source And Completed-Spec Guardrail

  • Candidate source:
    • direct user-provided Spec 357 draft from /Users/ahmeddarrazi/.codex/attachments/5b0bf308-47d5-449d-be56-f3946cc8a20b/pasted-text.txt
    • current roadmap/productization lane for report delivery and customer-safe review consumption
    • immediate runtime follow-through over Specs 347, 355, and 356
  • Completed-spec guardrail result:
    • no specs/357-* package existed before this preparation run
    • Specs 347, 355, and 356 carry implementation, screenshots, tests, or close-ready evidence and are treated as historical/runtime context only
    • related review-productization specs such as 308, 342, 349, and 351 are also context only and must not be rewritten back into preparation wording
  • Close alternatives deferred:
    • Billing & Subscription Truth Layer v1
    • Customer-Facing Localization Adoption v1
    • Governance Artifact Lifecycle & Retention v1
    • First Governed AI Runtime Consumer v1
    • Customer Portal Report Consumption Boundary
  • Smallest viable implementation slice: existing rendered review-report route plus linked review/report surfaces only: static report profiles, disclosure proof-state evaluation, profile-aware section filtering, visible profile metadata, and truthful customer/internal disclosure behavior.

Summary

Spec 357 introduces a static report-profile and disclosure-policy layer for the current rendered review report. The report must become profile-aware without becoming truth-optional. Profiles may change presentation depth and section selection, but they must never hide readiness state, evidence limitations, internal-only or PII warnings, non-certification disclosure, or source metadata.

The implementation remains intentionally narrow:

  • extend the current ReviewPack rendered-report family
  • keep all evaluation based on stored review-pack and review truth
  • model verified, assumed, not_applicable, missing, and unknown disclosure proof states where the repo cannot independently prove a safety claim
  • avoid delivery, portal, PDF, AI, or framework-report scope

Spec Scope Fields (mandatory)

  • Scope: canonical-view
  • Primary Routes:
    • /admin/reviews/workspace
    • /admin/workspaces/{workspace}/environments/{environment}/environment-reviews/{record}
    • /admin/workspaces/{workspace}/environments/{environment}/review-packs/{record}
    • /admin/review-packs/{reviewPack}/report
    • /admin/review-packs/{reviewPack}/download
  • Data Ownership:
    • ReviewPack remains the current artifact truth
    • EnvironmentReview and EnvironmentReviewSection remain review and section truth
    • EvidenceSnapshot remains evidence-basis truth
    • readiness, profile selection, and disclosure results remain derived-only request-time truth
  • RBAC:
    • existing workspace membership and managed-environment entitlement remain mandatory
    • Capabilities::REVIEW_PACK_VIEW and current review/report view permissions remain authoritative
    • no public routes, no unauthenticated profile selection, and no new capability family by default

For canonical-view specs:

  • Default filter behavior when tenant-context is active: keep the current explicit environment_id workspace filter behavior and do not introduce hidden shell or legacy query scope.
  • Explicit entitlement checks preventing cross-tenant leakage: all rendered report, review, and review-pack access continues to resolve through current workspace and managed-environment scope plus current-export and not-expired guards.

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:
    • CustomerReviewWorkspace review-pack launch and readiness area
    • EnvironmentReviewResource customer-workspace detail handoff
    • ReviewPackResource detail/download context
    • rendered report route /admin/review-packs/{reviewPack}/report
  • Current or new page archetype: existing customer-safe report/detail surfaces and existing rendered artifact viewer
  • Design depth: Strategic Surface
  • Repo-truth level: repo-verified existing runtime surfaces
  • Existing pattern reused: current review-pack output contract, ReviewPackOutputResolutionGuidance, rendered report viewer, customer-safe disclosure hierarchy
  • New pattern required: one bounded report-profile/disclosure-policy layer over the existing rendered report
  • Screenshot required: yes, under specs/357-report-profiles-disclosure-policy-v1/artifacts/screenshots/
  • Page audit required: yes, update the existing reports for UI-006, UI-042, and UI-099 if the hierarchy or visible contract changes materially
  • Customer-safe review required: yes; customer-facing profiles are central to this slice
  • Dangerous-action review required: no; the slice stays on read-only report surfaces
  • Coverage files updated or explicitly not needed:
    • docs/ui-ux-enterprise-audit/route-inventory.md
    • docs/ui-ux-enterprise-audit/design-coverage-matrix.md
    • docs/ui-ux-enterprise-audit/page-reports/...
    • docs/ui-ux-enterprise-audit/strategic-surfaces.md
    • docs/ui-ux-enterprise-audit/grouped-follow-up-candidates.md
    • docs/ui-ux-enterprise-audit/unresolved-pages.md
    • N/A - no reachable UI surface impact
  • No-impact rationale when applicable: N/A

Cross-Cutting / Shared Pattern Reuse (mandatory)

  • Cross-cutting feature?: yes
  • Interaction class(es): status messaging, report viewers, disclosure messaging, action links, evidence/report truth presentation
  • Systems touched:
    • ReviewPackRenderedReportController
    • ReviewPackOutputReadiness
    • ReviewPackOutputResolutionGuidance
    • ReviewPackService
    • CustomerReviewWorkspace
    • EnvironmentReviewResource
    • ReviewPackResource
    • rendered-report Blade template and localization files
  • Existing pattern(s) to extend: current output-readiness semantics, current rendered-report route, current customer-safe workspace handoff, current artifact truth and download seams
  • Shared contract / presenter / builder / renderer to reuse: ReviewPackOutputReadiness, ReviewPackOutputResolutionGuidance, ArtifactTruthPresenter, current rendered-report payload composition, current review-pack authorization and current-export guards
  • Why the existing shared path is sufficient or insufficient: it already holds readiness and report truth, but it does not yet define a first-class audience/profile policy or proof-state-aware disclosure result
  • Allowed deviation and why: one bounded ReportProfileRegistry, one bounded ReportDisclosurePolicy, and one local rendered-report profile payload layer are allowed inside App\Support\ReviewPacks because the controller already carries complex report-state composition
  • Consistency impact: profile labels, audience labels, readiness state, limitations, evidence basis, internal-only warnings, non-certification disclosure, and source metadata must stay aligned across workspace, review detail, review-pack detail, and rendered report
  • Review focus: block any second artifact family, any report-profile persistence, any public link contract, any hidden mandatory disclosure, or any fake upgrade from assumed to verified proof

OperationRun UX Impact (mandatory)

  • Touches OperationRun start/completion/link UX?: reuse only
  • Shared OperationRun UX contract/layer reused: the existing review-pack generation and current-export reuse path remains authoritative
  • Delegated start/completion UX behaviors: queued run, dedupe, current-pack reuse, and completion notification behavior remain unchanged
  • Local surface-owned behavior that remains: profile metadata, disclosure evaluation, section filtering, and rendered-report copy only
  • Queued DB-notification policy: unchanged
  • Terminal notification path: unchanged
  • Exception required?: none

Provider Boundary / Platform Core Check (mandatory)

  • Shared provider/platform boundary touched?: no new provider seam
  • Boundary classification: platform-core review/report disclosure semantics
  • Seams affected: existing review-pack and rendered-report semantics only
  • Neutral platform terms preserved or introduced: report profile, audience, readiness, limitation, disclosure, proof state, internal-only, customer-safe
  • Provider-specific semantics retained and why: only where existing review content already carries provider-backed section labels
  • Why this does not deepen provider coupling accidentally: no provider call, provider model, or provider registry change is introduced
  • Follow-up path: framework-specific report profiles remain deferred to later specs

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
Customer Review Workspace review-pack handoff yes Native Filament page plus existing report/download primitives customer-safe output guidance page, URL-query no Existing route only
Rendered report route yes Bounded custom report view over existing controller route report viewer, disclosure hierarchy, profile metadata detail, route payload no Existing route family only
Review Pack detail/report handoff yes Native detail plus existing artifact-truth primitives rendered output vs ZIP truth detail no Keep read-only
Review detail handoff yes Native detail plus shared review/output truth audience-aware launch copy detail no No new route family

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
Customer Review Workspace Primary Decision Surface Decide whether the current review output is ready for external/customer consumption readiness, limitations, profile-safe action, evidence basis summary review detail, report detail, download Primary because it remains the handoff start surface keeps current customer-safe review workflow intact reduces explanation work around output meaning
Rendered report Primary Delivery Surface Decide whether the chosen report profile is fit for the audience profile, audience, limitations, disclosures, generated/source metadata supporting appendix and technical detail Primary because this is the actual human-readable output keeps report delivery inside the current review-pack family prevents "pretty report hides risk" drift
Review Pack detail Secondary Proof Surface Verify the artifact and open the rendered output artifact status and current-export truth ZIP/download metadata and related proof Secondary because it supports, not replaces, the delivery decision preserves artifact ownership keeps detail out of the main handoff surface

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 Review Workspace operator-MSP, customer-read-only, customer-admin readiness, limitations, current safe handoff path current review detail and evidence basis raw artifact diagnostics open the current review/report safely raw diagnostics remain secondary workspace states handoff truth once
Rendered report customer, technical customer, internal MSP, controlled auditor profile, audience, generated/source metadata, readiness, limitations, mandatory disclosures technical appendix only where allowed by profile raw JSON or protected internals stay hidden read the report or step back to the review diagnostics and internal-only detail stay profile-gated the report states its audience and limitations once
Review Pack detail operator-MSP current pack truth and rendered-output availability artifact metadata ZIP internals open rendered report raw ZIP detail remains secondary artifact proof does not duplicate report narrative

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
Customer Review Workspace Utility / Workspace Decision Customer-safe review hub open the currently appropriate report/review surface existing review-open path existing supporting report/download actions stay secondary none /admin/reviews/workspace existing review detail route workspace plus optional environment_id Customer review whether the output is safe and which audience it fits none
Rendered review report Detail / Report Viewer Read-only report read or print the report for the current audience explicit report route open forbidden appendix/technical detail stays below primary sections none existing owner surfaces only /admin/review-packs/{reviewPack}/report workspace/environment artifact entitlement Rendered review report profile, audience, readiness, limitations, disclosures none
Review Pack detail Detail / Artifact Viewer Read-only artifact detail verify or open the current rendered report existing detail inspect path existing ZIP/download proof stays secondary none existing review-pack collection route existing review-pack detail route environment + record entitlement Review pack artifact status and report availability 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
Customer Review Workspace MSP operator decide whether the current output can be shared and which audience path is truthful read-first workspace surface Is there a safe report to hand over now? readiness, limitations, profile-safe path deeper review detail and evidence links output readiness, evidence basis, package status none open review or report none
Rendered report MSP operator or entitled customer reader consume the report for the chosen audience read-only detail/report viewer Who is this report for, and what limits still apply? profile, audience, readiness, evidence state, disclosure, generated/source metadata appendix and technical details if allowed audience, boundary, readiness, evidence completeness none print or return to owner surface none
Review Pack detail MSP operator verify the current artifact and its rendered-output relationship read-only artifact detail Does this artifact match the report path I am about to use? artifact status, rendered report availability ZIP internals, operation proof artifact readiness, expiry none open rendered report none

Proportionality Review (mandatory when structural complexity is introduced)

  • New source of truth?: no
  • New persisted entity/table/artifact?: no
  • New abstraction?: yes, but bounded to local report-output support (ReportProfileRegistry, ReportDisclosurePolicy, and one local rendered-report profile layer if needed)
  • New enum/state/reason family?: no new persisted family; one derived disclosure proof-state vocabulary is allowed if it remains local and request-scoped
  • New cross-domain UI framework/taxonomy?: no
  • Current operator problem: the current rendered report can become unsafe to evolve because there is no explicit audience/profile policy and no proof-state-aware disclosure contract
  • Existing structure is insufficient because: the current readiness helpers describe output state but not which truths every profile must keep visible, and they cannot distinguish assumed from independently verified disclosure safety
  • Narrowest correct implementation: keep everything inside the current ReviewPack report family with a static registry, a local disclosure evaluator, and existing owner surfaces
  • Ownership cost: maintain a small static registry, disclosure evaluator, local copy, and focused tests/browser proof
  • Alternative intentionally rejected: a profile CRUD system, delivery workflow, or generic reporting framework was rejected as larger than current-release truth requires
  • Release truth: current-release delivery hardening and follow-through, not future portal or automation groundwork alone

Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, migration shims, legacy profile aliases, public query stability guarantees, and second artifact families are out of scope unless explicitly required by a later spec.

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

  • Test purpose / classification: Unit, Feature, Browser
  • Validation lane(s): confidence, browser
  • Why this classification and these lanes are sufficient: the registry and disclosure evaluator are deterministic unit concerns; the rendered report, route guards, and owner-surface handoff need Feature and one bounded Browser proof because this is a customer-facing strategic surface
  • New or expanded test families: one new Unit pair for report policy, one new Feature rendered-report profile test, one bounded Browser smoke file
  • Fixture / helper cost impact: low to moderate; reuse existing review-pack, environment-review, and rendered-report fixtures instead of adding a new heavy family
  • Heavy-family visibility / justification: one explicit Browser smoke only because audience-safe rendered output is visual and disclosure-order dependent
  • Special surface test profile: shared-detail-family
  • Standard-native relief or required special coverage: no standard-native relief; the rendered report needs explicit disclosure and audience-profile proof
  • Reviewer handoff: reviewers must confirm that invalid or placeholder profiles fail closed, mandatory disclosures always render, customer profiles never overclaim readiness, and no second report artifact family appears
  • Budget / baseline / trend impact: none expected beyond one bounded Browser smoke
  • Escalation needed: document-in-feature only if an authenticated query-parameter fallback is kept temporarily for profile selection
  • Active feature PR close-out entry: Guardrail / Exception / Smoke Coverage
  • Planned validation commands:
    • cd apps/platform && ./vendor/bin/sail artisan test tests/Unit/ReviewPacks/Spec357ReportProfileRegistryTest.php tests/Unit/ReviewPacks/Spec357ReportDisclosurePolicyTest.php --compact
    • cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/ReviewPack/Spec357RenderedReportProfileTest.php --compact
    • cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec357ReportProfilesSmokeTest.php --compact
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=Spec356
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=ReviewPack
    • cd apps/platform && ./vendor/bin/sail artisan test --compact --filter=EnvironmentReview
    • cd apps/platform && ./vendor/bin/sail pint --dirty
    • git diff --check

User Scenarios & Testing (mandatory)

User Story 1 - Profile-safe customer report delivery (Priority: P1)

As an MSP operator, I need a customer-facing report profile that can never hide readiness or limitation truth, so that external handoff stays conservative and defensible.

Why this priority: This is the core trust problem introduced by broader rendered-report delivery.

Independent Test: Request a customer profile for both customer-safe and limited outputs and verify the report still shows limitations, evidence state, and non-certification disclosure.

Acceptance Scenarios:

  1. Given a customer-safe ready review pack, When an entitled user opens the rendered report with customer_executive, Then the report shows customer-facing profile metadata and still renders mandatory disclosures and source metadata.
  2. Given a limited or internal-only review pack, When an entitled user opens customer_executive or customer_technical, Then the report remains visibly limited or blocked for external use and does not pretend the output is customer-safe.

User Story 2 - Clear internal MSP report boundary (Priority: P1)

As an MSP operator, I need an internal profile that can show more context while still clearly labeling itself as internal-only when customer-safe delivery is not justified.

Why this priority: The default authenticated report path is inside the operator/admin plane and must stay honest about internal-only output.

Independent Test: Open the report with internal_msp_review on a pack with PII or unresolved limitations and verify the report remains visibly internal and still shows mandatory warnings.

Acceptance Scenarios:

  1. Given a pack that includes PII or internal-only detail, When the internal profile is used, Then the report clearly states internal-only boundary and keeps evidence/limitation disclosures visible.
  2. Given an invalid or placeholder profile key, When the report route is requested, Then the system fails closed to the safe internal path or a truthful not-implemented response without exposing a broken public contract.

User Story 3 - Proof-state-aware disclosure contract (Priority: P2)

As a reviewer, I need the profile layer to distinguish verified, assumed, missing, unknown, and not_applicable, so the report does not silently overstate disclosure safety that the repo cannot prove.

Why this priority: This prevents the new policy layer from laundering assumptions into certified truth.

Independent Test: Unit-test the disclosure-policy result for readiness, evidence, and protected-value handling states without requiring a browser.

Acceptance Scenarios:

  1. Given stored report truth where a safety claim is only inferred from existing generator behavior, When the disclosure policy is evaluated, Then the result marks that claim as assumed rather than verified.
  2. Given a mandatory disclosure is unavailable, When a profile is evaluated, Then the output marks it as missing or unknown and still renders the warning path instead of hiding it.

Functional Requirements

  • FR-357-001: A static report-profile registry MUST define at least customer_executive, customer_technical, internal_msp_review, auditor_appendix, and placeholder framework_readiness.
  • FR-357-002: A disclosure-policy evaluator MUST derive mandatory disclosures, warnings, blocking reasons, and proof states from stored review-pack and review truth only.
  • FR-357-003: The rendered report MUST use an effective profile to drive section inclusion, appendix visibility, and audience metadata.
  • FR-357-004: Mandatory disclosures MUST override profile section-hiding rules.
  • FR-357-005: Customer-facing profiles MUST NOT overclaim readiness. Limited, blocked, internal-only, or assumption-heavy output must remain visibly limited.
  • FR-357-006: Internal profiles MUST remain visibly internal when applicable and must not suppress PII/internal-only warnings.
  • FR-357-007: The rendered report MUST show profile key, audience, generated/source metadata, readiness, limitations, and non-certification disclosure.
  • FR-357-008: framework_readiness MUST remain placeholder-only and not appear as a falsely implemented framework report.
  • FR-357-009: No report-profile persistence, CRUD surface, delivery workflow, or new artifact family may be introduced in this slice.
  • FR-357-010: Invalid or unimplemented profiles MUST fail closed and must not widen the signed route contract or bypass existing signed URL builders.

Non-Functional Requirements

  • NFR-357-001: Output must remain deterministic for the same review pack and effective profile.
  • NFR-357-002: If uncertainty exists, the renderer must show limitations rather than infer customer-safe certainty.
  • NFR-357-003: No live provider or Graph calls may happen during report rendering.
  • NFR-357-004: Registry and policy logic must be unit-testable without Browser coverage.
  • NFR-357-005: Localization for dominant profile/disclosure copy must be available in both en and de.

Acceptance Criteria

  • AC1: A static implemented-profile registry exists and is tested.
  • AC2: A disclosure-policy evaluator exists and returns mandatory disclosures, blocking reasons, and explicit proof states.
  • AC3: The rendered report is profile-aware and visibly shows profile and audience metadata.
  • AC4: Customer-facing profiles cannot hide limitations, evidence gaps, internal-only warnings, or the non-certification disclosure.
  • AC5: Internal profiles remain clearly internal when current output truth requires it.
  • AC6: Invalid or placeholder profiles fail closed and do not pretend to be implemented.
  • AC7: No new persistence, delivery workflow, portal, PDF stack, or AI runtime is added.
  • AC8: Focused Unit, Feature, Browser, and report-regression validation passes.

Assumptions

  • The current rendered report route /admin/review-packs/{reviewPack}/report remains the single human-readable report route for this slice.
  • The current ReviewPack and EnvironmentReview truth is sufficient to derive audience-safe disclosure results without new persistence.
  • Authenticated internal profile selection may use a bounded current-route mechanism only through the existing signed rendered-report URL builders if a richer action surface would over-expand scope.
  • Existing rendered-report and review-pack regressions from Specs 347 and 356 remain the baseline to extend, not replace.

Risks

  • A broader "report profile system" could sprawl into delivery, branding, or portal scope.
  • Assumption-vs-verification semantics could drift unless tests pin them down explicitly.
  • Profile selection UI could widen scope if it becomes a settings surface instead of a bounded report-viewer affordance.
  • Appendix handling could accidentally reintroduce internal-only detail into customer-facing profiles unless the policy contract stays strict.

Open Questions

  • Should authenticated profile selection remain signed-URL-parameter-based on the current report route for v1, or is one bounded action group on existing owner surfaces justified without over-expanding UI scope?
  • Should auditor_appendix remain internal-only by default in v1, or be rendered but always marked non-deliverable externally until a later delivery workflow spec?
  • Can any current protectedValuesHidden or disclosurePresent signals be upgraded from assumed to verified without broadening generator scope, or should v1 explicitly preserve them as assumed?

These questions do not block preparation because the safe default is to keep profile selection bounded, keep auditor output conservative, and preserve assumption states unless implementation proves otherwise.

Follow-up Spec Candidates

  • Branded / themed management report layouts
  • Scheduled report delivery and approval workflow
  • Framework-specific readiness report profiles
  • Customer portal report consumption boundary
  • Private AI/HITL report review preparation