TenantAtlas/specs/236-canonical-control-catalog-foundation/tasks.md
2026-04-24 14:15:50 +02:00

21 KiB

Tasks: Canonical Control Catalog Foundation

Input: Design documents from /specs/236-canonical-control-catalog-foundation/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/canonical-control-catalog.logical.openapi.yaml, quickstart.md

Tests: Required. This feature changes shared governance semantics and downstream read-model composition, so Pest coverage must be added or extended in apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php, apps/platform/tests/Unit/Governance/CanonicalControlResolverTest.php, apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php, apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php, and apps/platform/tests/Feature/TenantReview/TenantReviewCanonicalControlReferenceTest.php. Operations: No new OperationRun type is introduced. Tasks that touch apps/platform/app/Services/Evidence/EvidenceSnapshotService.php or apps/platform/app/Services/TenantReviews/TenantReviewService.php must preserve existing run ownership, notifications, and audit behavior instead of creating a new catalog-specific workflow. RBAC: No new capability or route is introduced. Existing authorization on evidence and tenant review surfaces must remain tenant-safe, and any downstream control metadata must stay behind the current evidence and review authorization paths. UI Naming: No new operator-facing action surface is added. If any evidence or review copy changes, canonical control vocabulary must be primary and provider or workload labels must remain secondary descriptors. Cross-Cutting Shared Pattern Reuse: Extend the existing governance summary and composition paths in apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php, apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php, apps/platform/app/Services/TenantReviews/TenantReviewComposer.php, and apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php before introducing any feature-local control registry or formatter. Provider Boundary / Platform Core: Platform-core control identity, taxonomy, detectability, and evidence suitability live in apps/platform/app/Support/Governance/Controls/ and apps/platform/config/canonical_controls.php. Microsoft workload, subject-family, and signal metadata remain secondary binding data and must not become the primary key or vocabulary for canonical controls. UI / Surface Guardrails: N/A for new surfaces. This slice is report-only for existing evidence and review composition surfaces and must not introduce a new page, wizard, or custom Filament contract. Filament UI Action Surfaces: No new Filament Resource, RelationManager, or Page action is introduced. Existing global-search posture remains unchanged because no new Resource is added in this slice. Badges: No new badge domain or badge-mapping family is introduced.

Organization: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is US1, US2, US3, then US4, because consumer adoption depends on the shared catalog, metadata semantics, and provider-binding behavior being stable first.

Test Governance Checklist

  • Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
  • New or changed tests stay in the smallest honest family, and no heavy-governance or browser lane is introduced.
  • Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; seeded config drives the catalog.
  • Planned validation commands cover the change without pulling in unrelated lane cost.
  • The declared surface test profile or standard-native-filament relief is explicit.
  • Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.

Phase 1: Setup (Shared Anchors)

Purpose: Lock the implementation anchors, consumer scope, and narrow proving commands before adding the canonical control core.

  • T001 [P] Verify the feature anchor inventory across apps/platform/app/Support/Governance/, apps/platform/app/Services/Evidence/, apps/platform/app/Services/TenantReviews/, and apps/platform/config/canonical_controls.php
  • T002 [P] Create the Spec 236 proving entry points in apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php, apps/platform/tests/Unit/Governance/CanonicalControlResolverTest.php, apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php, apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php, and apps/platform/tests/Feature/TenantReview/TenantReviewCanonicalControlReferenceTest.php
  • T003 [P] Confirm the narrow validation commands and first-slice consumer scope in specs/236-canonical-control-catalog-foundation/spec.md and specs/236-canonical-control-catalog-foundation/quickstart.md

Checkpoint: Runtime anchors and proof entry points are fixed before implementation starts.


Phase 2: Foundational (Blocking Control Core)

Purpose: Establish the product-seeded catalog and shared resolution primitives that every user story depends on.

CRITICAL: No user story work should begin until this phase is complete.

  • T004 [P] Create the bounded seed-catalog configuration anchor in apps/platform/config/canonical_controls.php
  • T005 [P] Create canonical control metadata types in apps/platform/app/Support/Governance/Controls/CanonicalControlDefinition.php, apps/platform/app/Support/Governance/Controls/DetectabilityClass.php, apps/platform/app/Support/Governance/Controls/EvaluationStrategy.php, apps/platform/app/Support/Governance/Controls/EvidenceArchetype.php, and apps/platform/app/Support/Governance/Controls/ArtifactSuitability.php
  • T006 [P] Create provider-binding and resolution-contract primitives in apps/platform/app/Support/Governance/Controls/MicrosoftSubjectBinding.php, apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionRequest.php, and apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionResult.php
  • T007 [P] Create shared catalog and resolver service shells in apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php and apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php
  • T008 [P] Inventory first-slice downstream adoption seams in apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php, apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php, apps/platform/app/Services/Evidence/EvidenceSnapshotService.php, apps/platform/app/Services/TenantReviews/TenantReviewComposer.php, and apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php so consumer adoption stays derived and local registries are forbidden

Checkpoint: The repo has one shared catalog namespace, one config-backed seed source, and one explicit downstream adoption boundary.


Phase 3: User Story 1 - Resolve One Stable Control Identity (Priority: P1) 🎯 MVP

Goal: Resolve the same governance objective to one stable canonical control key and label across supported contexts.

Independent Test: Resolve the same objective through multiple subject families and consumer contexts and confirm the shared contract returns one identical canonical control key and canonical label.

Tests for User Story 1

  • T009 [P] [US1] Add stable-key, canonical-label, and same-objective convergence coverage in apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php and apps/platform/tests/Unit/Governance/CanonicalControlResolverTest.php
  • T010 [P] [US1] Add shared logical-contract coverage for catalog listing and resolution shapes in apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Implementation for User Story 1

  • T011 [US1] Populate stable canonical control keys, names, domains, subdomains, classes, summaries, operator descriptions, and historical_status in apps/platform/config/canonical_controls.php
  • T012 [US1] Implement deterministic catalog loading, lookup, and historical-key stability in apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php
  • T013 [US1] Implement shared canonical control resolution by provider, subject family, workload, signal, and consumer context in apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php, apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionRequest.php, and apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionResult.php

Checkpoint: User Story 1 is independently functional and stable canonical control identity no longer depends on feature-local naming.


Phase 4: User Story 2 - Preserve Honest Detectability and Evidence Meaning (Priority: P1)

Goal: Ensure each canonical control carries explicit detectability, evaluation, and evidence semantics so downstream consumers do not over-claim proof.

Independent Test: Resolve controls with direct, indirect, workflow-attested, and external-evidence-only semantics and confirm the returned metadata preserves those distinctions and allowed evidence forms.

Tests for User Story 2

  • T014 [P] [US2] Add detectability, evaluation-strategy, evidence-archetype, artifact-suitability, and required seed-family coverage in apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php
  • T015 [P] [US2] Add resolved-metadata contract coverage for honest detectability and suitability semantics in apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Implementation for User Story 2

  • T016 [US2] Expand every seed definition with detectability, evaluation, evidence-archetype, and artifact-suitability metadata in apps/platform/config/canonical_controls.php
  • T017 [US2] Enforce metadata completeness and narrow validation failures in apps/platform/app/Support/Governance/Controls/CanonicalControlDefinition.php and apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php
  • T018 [US2] Expose downstream-safe detectability and suitability metadata through apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionResult.php and apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php

Checkpoint: User Story 2 is independently functional and the shared contract carries honest proof semantics instead of a false universal verification model.


Phase 5: User Story 3 - Add Microsoft Bindings Without Making Microsoft the Control Model (Priority: P2)

Goal: Attach Microsoft workload, subject-family, and signal bindings to canonical controls while keeping provider-neutral control identity primary.

Independent Test: Add or modify Microsoft binding metadata for a seeded control and confirm the canonical control definition stays stable, duplicate controls are not created, and ambiguous cases fail deterministically.

Tests for User Story 3

  • T019 [P] [US3] Add multi-binding, provider-neutral identity, unresolved, ambiguous, retired-control, and historical_status coverage in apps/platform/tests/Unit/Governance/CanonicalControlResolverTest.php
  • T020 [P] [US3] Add workload, signal, and context-primary integration coverage for no-guess resolution in apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Implementation for User Story 3

  • T021 [US3] Model provider-owned Microsoft bindings, supported contexts, primary flags, and notes in apps/platform/config/canonical_controls.php and apps/platform/app/Support/Governance/Controls/MicrosoftSubjectBinding.php
  • T022 [US3] Implement binding selection, context-primary resolution, and deterministic unresolved or ambiguous reason codes in apps/platform/app/Support/Governance/Controls/CanonicalControlResolver.php
  • T023 [US3] Keep Microsoft metadata secondary and provider-neutral vocabulary primary across apps/platform/app/Support/Governance/Controls/CanonicalControlDefinition.php, apps/platform/app/Support/Governance/Controls/CanonicalControlCatalog.php, and apps/platform/app/Support/Governance/Controls/CanonicalControlResolutionResult.php

Checkpoint: User Story 3 is independently functional and Microsoft bindings extend coverage without becoming the control model.


Phase 6: User Story 4 - Prepare Later Readiness and Review Work Without Local Reinvention (Priority: P3)

Goal: Give first-slice downstream consumers one shared path to canonical control metadata so evidence and review composition stop inventing local control families.

Independent Test: Generate evidence and compose a tenant review, then confirm both paths consume canonical control metadata through the shared resolver without adding a local registry or fallback label.

Tests for User Story 4

  • T024 [P] [US4] Add evidence-snapshot control-reference coverage proving shared canonical-control contract use and no local fallback labels in apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php
  • T025 [P] [US4] Add tenant-review composition control-reference coverage proving shared canonical-control contract use and no local fallback labels in apps/platform/tests/Feature/TenantReview/TenantReviewCanonicalControlReferenceTest.php

Implementation for User Story 4

  • T026 [US4] Resolve canonical control references inside findings-derived evidence composition in apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php and apps/platform/app/Services/Evidence/EvidenceSnapshotService.php
  • T027 [US4] Preserve transient shared control metadata on evidence lookup and snapshot item payload consumption without introducing new canonical-control persistence ownership in apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php and apps/platform/app/Models/EvidenceSnapshotItem.php
  • T028 [US4] Reuse shared control resolution during review composition instead of local control wording in apps/platform/app/Services/TenantReviews/TenantReviewComposer.php and apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php
  • T029 [US4] Keep tenant review orchestration derived and persistence-neutral while passing canonical control context through apps/platform/app/Services/TenantReviews/TenantReviewService.php and apps/platform/app/Models/TenantReview.php

Checkpoint: User Story 4 is independently functional and first-slice consumers have one shared control-resolution path.


Phase 7: Polish & Cross-Cutting Validation

Purpose: Remove local semantic drift, run the narrow proving lanes, and close the feature with explicit guardrail notes.

  • T030 [P] Search apps/platform/app/Support/Governance/Controls/, apps/platform/app/Services/Evidence/Sources/FindingsSummarySource.php, apps/platform/app/Services/Evidence/EvidenceSnapshotResolver.php, apps/platform/app/Services/Evidence/EvidenceSnapshotService.php, apps/platform/app/Services/TenantReviews/TenantReviewComposer.php, apps/platform/app/Services/TenantReviews/TenantReviewSectionFactory.php, and apps/platform/app/Services/TenantReviews/TenantReviewService.php to confirm no feature-local control-family fallback, workload-first primary vocabulary, or framework-first primary control shape remains
  • T031 Run the fast-feedback unit lane from specs/236-canonical-control-catalog-foundation/quickstart.md with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Governance/CanonicalControlCatalogTest.php tests/Unit/Governance/CanonicalControlResolverTest.php
  • T032 [P] Run the confidence feature lane from specs/236-canonical-control-catalog-foundation/quickstart.md with cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php tests/Feature/TenantReview/TenantReviewCanonicalControlReferenceTest.php
  • T033 Run formatting for touched PHP and test files with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
  • T034 Record the Guardrail close-out entry, validation commands, and any bounded follow-up note in specs/236-canonical-control-catalog-foundation/quickstart.md and the active PR description
  • T035 [P] Confirm this slice introduces no Graph client change, no config/graph_contracts.php change, and no provider sync job by searching apps/platform/app/, apps/platform/config/graph_contracts.php, and apps/platform/app/Jobs/ before merge

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies; can start immediately.
  • Foundational (Phase 2): Depends on Setup completion and blocks all story work.
  • User Story 1 (Phase 3): Depends on Foundational completion and is the MVP cut.
  • User Story 2 (Phase 4): Depends on User Story 1 because honest detectability metadata builds on the shared canonical identity and resolver contract.
  • User Story 3 (Phase 5): Depends on User Story 1 and User Story 2 because provider-owned bindings must resolve the full canonical metadata set.
  • User Story 4 (Phase 6): Depends on User Story 1 through User Story 3 because downstream consumers should adopt the final shared catalog and binding behavior instead of an interim contract.
  • Polish (Phase 7): Depends on all completed story work.

User Story Dependencies

  • US1: No dependency beyond Foundational.
  • US2: Depends on US1 shared catalog and resolver behavior.
  • US3: Depends on US1 and US2 shared identity plus metadata semantics.
  • US4: Depends on US1, US2, and US3 to keep downstream consumer adoption on the final shared contract.

Within Each User Story

  • Write the story tests first and confirm they fail before implementation is considered complete.
  • Keep the catalog product-seeded and in-repo; do not introduce DB-backed control authoring or migrations.
  • Keep provider-specific binding metadata secondary to canonical control identity.
  • Keep consumer adoption derived in evidence and review composition; do not add feature-local registries or fallback labels.
  • Finish story-level validation before moving to the next dependent story.

Parallel Opportunities

  • T001, T002, and T003 can run in parallel during Setup.
  • T004, T005, T006, T007, and T008 can run in parallel during Foundational work.
  • T009 and T010 can run in parallel for User Story 1 before T011 through T013.
  • T014 and T015 can run in parallel for User Story 2 before T016 through T018.
  • T019 and T020 can run in parallel for User Story 3 before T021 through T023.
  • T024 and T025 can run in parallel for User Story 4 before T026 through T029.
  • T031, T032, and T033 can run in parallel during final validation once implementation is complete.

Parallel Example: User Story 1

# User Story 1 proof in parallel
T009 apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php
T010 apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Parallel Example: User Story 2

# User Story 2 proof in parallel
T014 apps/platform/tests/Unit/Governance/CanonicalControlCatalogTest.php
T015 apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Parallel Example: User Story 3

# User Story 3 proof in parallel
T019 apps/platform/tests/Unit/Governance/CanonicalControlResolverTest.php
T020 apps/platform/tests/Feature/Governance/CanonicalControlResolutionIntegrationTest.php

Parallel Example: User Story 4

# User Story 4 proof in parallel
T024 apps/platform/tests/Feature/Evidence/EvidenceSnapshotCanonicalControlReferenceTest.php
T025 apps/platform/tests/Feature/TenantReview/TenantReviewCanonicalControlReferenceTest.php

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3: User Story 1.
  4. Run T031 before widening the slice.

Incremental Delivery

  1. Ship US1 to establish one stable canonical control identity and shared resolver contract.
  2. Ship US2 to make detectability and evidence meaning explicit and honest.
  3. Ship US3 to add Microsoft bindings without turning Microsoft semantics into platform truth.
  4. Ship US4 to move evidence and tenant review composition onto the shared control contract.
  5. Finish with final validation, formatting, and close-out notes from Phase 7.

Parallel Team Strategy

  1. One contributor can prepare the config-backed catalog and metadata primitives while another prepares the dedicated test files.
  2. After Foundation is complete, one contributor can take US1 or US2 while another prepares US3 test coverage against the shared resolver.
  3. Once the shared resolver is stable, evidence adoption and tenant review adoption can proceed in parallel inside US4.

Notes

  • [P] tasks target different files or independent proof surfaces and can be worked in parallel once upstream blockers are cleared.
  • [US1], [US2], [US3], and [US4] map directly to the feature specification user stories.
  • The logical contract already exists in specs/236-canonical-control-catalog-foundation/contracts/canonical-control-catalog.logical.openapi.yaml; implementation tasks keep runtime behavior aligned to that shape rather than creating a public HTTP surface.
  • The suggested MVP scope is Phase 1 through Phase 3 only.