TenantAtlas/specs/259-compliance-evidence-mapping/research.md
ahmido 866875559f
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m4s
feat(specs/259): compliance evidence mapping (#312)
Implements platform feature branch `259-compliance-evidence-mapping`.

Target branch: `platform-dev`.

Follow-up integration path after merge:

`platform-dev` -> `dev`.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #312
2026-04-30 21:27:49 +00:00

10 KiB

Research — Compliance Evidence Mapping v1

Date: 2026-04-30
Spec: spec.md

This document resolves the planning decisions for the smallest safe versioned interpretation overlay over the repo's existing canonical control references and released review truth.

Decision 1 — Keep the existing customer review workspace and released-review detail flow as the only primary and secondary surfaces

Decision: Reuse ../../apps/platform/app/Filament/Pages/Reviews/CustomerReviewWorkspace.php as the primary decision surface and ../../apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php under the existing customer_workspace query flag as the only secondary context surface.

Rationale:

  • The repo already has the admin-plane route, tenant-safe prefilter behavior, customer-workspace query context, and bounded feature and browser tests for these surfaces.
  • The missing piece is shared interpretation, not new routing, a new panel, or a portal shell.
  • Reusing the existing surfaces keeps the feature aligned with the authoritative spec and avoids a second customer-review UX vocabulary.

Alternatives considered:

  • Add a dedicated compliance portal or a second customer-only page.
    • Rejected: duplicates the current review-consumption path and widens scope into shell-level IA.
  • Push all explanation into the workspace only.
    • Rejected: would leave the first drilldown without the detailed control explanation the spec requires.

Decision 2 — Derive the interpretation once during tenant review composition and reuse it through existing review payloads

Decision: Materialize the mapped control/readiness contract during tenant review composition by extending ../../apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php and ../../apps/platform/app/Services/TenantReviews/TenantReviewComposer.php, then reuse that stored result in both workspace and detail surfaces.

Rationale:

  • The spec requires the same mapped control meaning and interpretation version to remain consistent between workspace and released-review detail.
  • Carrying the result inside existing TenantReview and TenantReviewSection payloads preserves traceability for older released reviews without a new persistence table.
  • A single compose-time pass is the narrowest way to prevent page-level drift.

Alternatives considered:

  • Compute the interpretation separately in each page.
    • Rejected: two local mappers would drift and would not preserve older review history against the version used at release time.
  • Add a new projection table or report artifact for the overlay.
    • Rejected: violates the no-new-persistence constraint.

Decision 3 — Keep canonical control identity on the existing catalog and resolver seams

Decision: Reuse ../../apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php, ../../apps/platform/app/Support/Governance/Controls/CanonicalControlDefinition.php, and ../../apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php as the only control identity and resolution path.

Rationale:

  • The catalog already exposes provider-neutral control keys, names, summaries, and domain metadata suitable for customer-safe labels.
  • The resolver already maps Microsoft-owned evidence signals onto canonical controls upstream in evidence collection.
  • The feature needs an interpretation overlay over canonical controls, not a second control taxonomy or framework registry.

Alternatives considered:

  • Add a second customer-facing control catalog.
    • Rejected: duplicates platform-core control truth and increases drift risk.
  • Move provider-specific signal mapping into the UI.
    • Rejected: deepens provider coupling in the wrong layer and violates the one-shared-path requirement.

Decision 4 — Carry one explicit version label inside existing review truth and audit metadata

Decision: Use one explicit overlay version key, carried inside existing review payloads and surfaced anywhere the mapped control/readiness view appears. The planning baseline is a single v1 key such as compliance_evidence_mapping.v1.

Rationale:

  • FR-003 and FR-014 require the interpretation version to be visible and traceable.
  • Embedding the version into current review payloads preserves what an older released review meant at the time it was composed.
  • The existing audit pipeline can carry the same version context without a new audit store.

Alternatives considered:

  • Recompute the current version at render time only.
    • Rejected: older released reviews could silently change meaning after later rule updates.
  • Add a dedicated database column or separate version-history model.
    • Rejected: broader persistence change than the current release truth needs.

Decision 5 — Use a bounded readiness contract with explicit limitation flags instead of pass/fail or certification language

Decision: Keep the customer-safe interpretation contract bounded to a small readiness vocabulary plus explicit limitation flags. The planned primary readiness buckets are:

  • follow_up_required
  • review_recommended
  • evidence_on_record

The planned limitation flags are:

  • accepted_risk_influenced
  • partial_mapping
  • stale_evidence
  • supporting_evidence_unavailable
  • unmapped

Rationale:

  • The feature must help a customer decide what needs follow-up without implying formal certification or legal compliance.
  • A small readiness vocabulary with explicit limitation modifiers is easier to localize, easier to test, and less likely to overstate the evidence basis than a large scoring system.
  • Keeping accepted risk as a modifier preserves the distinction between a governed exception and a fully positive readiness claim.

Alternatives considered:

  • Use compliant / non-compliant / certified language.
    • Rejected: overstates what the product can legitimately claim.
  • Add a larger scorecard or framework-specific status ladder.
    • Rejected: imports framework-engine complexity that the spec explicitly defers.

Decision 6 — Keep supporting proof on the existing evidence routes and current capability checks

Decision: Reuse ../../apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php and existing evidence detail pages as the only supporting-proof routes for this slice.

Rationale:

  • Existing evidence resources already enforce tenant scope, capability checks, and audit semantics.
  • The spec calls for deeper proof only after explicit drilldown, not a new proof viewer or raw payload surface.
  • Keeping proof access secondary preserves one dominant workspace action and avoids export/package redesign.

Alternatives considered:

  • Add a new customer-only proof viewer.
    • Rejected: duplicates evidence routing and widens scope.
  • Put raw proof details directly on the workspace row.
    • Rejected: violates the decision-first disclosure hierarchy.

Decision 7 — Reuse existing audit action IDs and enrich metadata before creating new audit concepts

Decision: Keep the audit path on ../../apps/platform/app/Support/Audit/AuditActionId.php and ../../apps/platform/app/Services/Audit/WorkspaceAuditLogger.php, reusing customer_review_workspace.opened, tenant_review.opened, and evidence_snapshot.opened with interpretation-version metadata where needed.

Rationale:

  • The required access moments already exist as auditable actions in the repo.
  • The remaining requirement is traceability of the interpretation version and source surface, which fits shared metadata better than a new event family.
  • Reusing the current audit path preserves consistent redaction and workspace or tenant context handling.

Alternatives considered:

  • Create a new compliance-evidence audit stream.
    • Rejected: unnecessary persistence and ownership cost for a read-only slice.
  • Leave version context unaudited.
    • Rejected: weakens FR-014 traceability.

Decision 8 — Keep validation inside the current review and evidence feature families plus the single existing browser smoke

Decision: Expand the existing review and evidence feature tests and keep ../../apps/platform/tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php as the only browser proof.

Rationale:

  • The repo already has narrow feature files for canonical control references, workspace behavior, detail explanation, authorization, navigation context, and evidence routes.
  • Those files are the cheapest honest proof for isolation, consistent wording, and cross-surface reuse.
  • One bounded smoke is enough to catch rendered disclosure regressions without creating a new heavy test family.

Alternatives considered:

  • Add a broader browser suite for every control state and evidence path.
    • Rejected: too expensive for the bounded value of this slice.
  • Rely only on unit tests around a new helper.
    • Rejected: feature behavior and tenant-safe disclosure still need surface-level proof.

Decision 9 — Keep Governance-as-a-Service Packaging and framework-specific overlays explicitly deferred

Decision: Treat this package as the foundational shared interpretation contract only. Governance-as-a-Service Packaging and framework-specific overlays remain follow-up work after the v1 overlay is stable.

Rationale:

  • The spec explicitly defers both areas.
  • Packaging work should consume a proven shared interpretation contract rather than shaping it prematurely.
  • Framework-specific overlays would force broader taxonomy and copy decisions before one customer-safe path is validated.

Alternatives considered:

  • Fold packaging-ready exports into this feature.
    • Rejected: broadens scope into report-system territory.
  • Add BSI, NIS2, CIS, or ISO-specific overlay semantics now.
    • Rejected: imports a framework engine before the base interpretation path is proven.