TenantAtlas/specs/417-canonical-identity-engine/tasks.md
ahmido 8cbf1f7fe3 feat: implement canonical identity engine (#484)
Automated PR provided by Codex via Gitea API.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #484
2026-06-26 06:50:25 +00:00

13 KiB

Tasks: Spec 417 - Canonical Identity Engine

Input: specs/417-canonical-identity-engine/spec.md, specs/417-canonical-identity-engine/plan.md, specs/417-canonical-identity-engine/checklists/requirements.md Prerequisites: completed Specs 414 and 415 as read-only context

Tests: Required. Runtime/data/security behavior must be covered with focused Pest unit, feature, and PostgreSQL-lane tests. Browser tests are N/A unless scope is amended to rendered UI.

Test Governance Checklist

  • Lane assignment is named and is the narrowest sufficient proof for changed identity behavior.
  • New or changed tests stay in Unit/Feature/PostgreSQL lanes; any heavy-governance or browser addition requires spec amendment.
  • Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default and opt-in.
  • Planned validation commands cover the change without pulling unrelated lane cost.
  • Browser proof is N/A - no rendered UI surface changed unless spec/plan/tasks are amended first.
  • Human Product Sanity is N/A because no product surface changes.
  • Material budget, baseline, trend, or escalation notes are recorded in the implementation report if test cost changes.

Phase 1: Preflight And Guardrails

  • T001 Capture branch, HEAD, and git status --short in specs/417-canonical-identity-engine/implementation-report.md.
  • T002 Confirm specs/414-tcm-first-coverage-core-cutover/ and specs/415-generic-content-backed-capture/ are completed/validated context only; do not modify their artifacts.
  • T003 Inspect current apps/platform/app/Services/TenantConfiguration/CoverageResourceUpserter.php, CoverageEvidenceWriter.php, GenericContentEvidenceCaptureService.php, ClaimGuard.php, and ResourceTypeRegistry.php before implementation.
  • T004 Inspect current tenant_configuration_resources, tenant_configuration_resource_evidence, and tenant_configuration_resource_types schema before deciding whether to add a new migration or make an approved pre-production schema adjustment.
  • T005 Confirm the implementation uses exactly one persisted canonical key truth via existing canonical_resource_key; if replacement appears necessary, stop and amend spec.md, plan.md, and tasks.md before continuing.
  • T006 Confirm no UI, route, navigation, customer output, review/report/evidence page, restore readiness surface, or browser-visible Coverage v2 activation is in scope.

Phase 2: Tests First - Identity Strategy And Resolver

  • T007 Add unit tests under apps/platform/tests/Unit/Support/TenantConfiguration/Spec417CoverageIdentityStrategyRegistryTest.php for the eight initial resource types and their preferred/fallback/display fields, provider connection scope requirement, derived allowance, experimental allowance, and claim behavior.
  • T008 Add unit tests under apps/platform/tests/Unit/Support/TenantConfiguration/Spec417CanonicalIdentityResolverTest.php proving stable provider/Graph/TCM ID, source composite, derived composite, missing external ID, unsupported identity, beta experimental identity, and display-name-only rejection.
  • T009 Add unit tests under apps/platform/tests/Unit/Support/TenantConfiguration/Spec417CoverageSecondaryKeyBuilderTest.php proving secondary keys are diagnostic metadata only and do not authorize, scope, or stabilize identity.
  • T010 Add unit tests under apps/platform/tests/Unit/Support/TenantConfiguration/Spec417IdentityConflictDiagnosticsTest.php proving diagnostics are bounded and redacted.
  • T011 Add or extend unit tests for apps/platform/app/Services/TenantConfiguration/ClaimGuard.php proving identity_conflict, missing_external_id, and unsupported_identity block customer claims and derived is limited/blocked unless explicitly allowed.

Phase 3: Tests First - Persistence, Scope, And No-Legacy Behavior

  • T012 Add feature tests under apps/platform/tests/Feature/TenantConfiguration/Spec417CanonicalIdentityPersistenceTest.php proving identity fields persist on captured resources and no duplicate canonical key truth appears.
  • T013 Add feature tests under apps/platform/tests/Feature/TenantConfiguration/Spec417CoverageResourceIdentityUpsertTest.php proving stable ID rename updates the same resource, duplicate display names with different stable IDs stay separate, and display-name-only payloads never become stable.
  • T014 Add feature tests under apps/platform/tests/Feature/TenantConfiguration/Spec417IdentityConflictScopeTest.php proving same-scope unsafe collisions conflict, while cross-workspace, cross-managed-environment, and cross-provider resources never merge.
  • T015 Add feature tests under apps/platform/tests/Feature/TenantConfiguration/Spec417IdentityClaimGuardFeatureTest.php proving unsafe identity states block or limit claim state during capture/upsert.
  • T016 Add or extend apps/platform/tests/Feature/TenantConfiguration/Spec415NoLegacyNoUiActivationTest.php or create Spec417IdentityNoLegacyNoUiActivationTest.php proving no UI files/routes/navigation are added, no tenant_id ownership appears, no old v1 gap taxonomy is emitted, and no v1-to-v2 adapter exists.
  • T017 Add feature coverage for tombstone behavior if implemented, proving last canonical identity is preserved and tombstoned resources do not become active proof; otherwise document tombstone deferral in the implementation report. Completed by documenting tombstone deferral; no tombstone behavior or field is implemented in this slice.
  • T018 Add PostgreSQL-lane coverage for any new identity indexes, check constraints, JSONB columns, or composite uniqueness/foreign-key behavior if SQLite cannot prove them.

Phase 4: Identity Persistence

  • T019 Add a focused migration under apps/platform/database/migrations/ for Spec 417 identity fields, unless implementation explicitly documents an approved pre-production adjustment to the existing 415 migration.
  • T020 Extend tenant_configuration_resources with the minimum necessary identity fields: key kind, canonical external/source identity if needed, strategy identifier, secondary keys JSONB, source identity JSONB, diagnostics JSONB, evaluated timestamp, and optional tombstone timestamp.
  • T021 Add targeted indexes for proven query paths: scope/type/canonical key, scope/type/identity state, and resource type/key kind where needed; avoid speculative JSONB indexes.
  • T022 Update apps/platform/app/Models/TenantConfigurationResource.php casts for new JSONB/datetime/enum fields.
  • T023 Update apps/platform/database/factories/TenantConfigurationResourceFactory.php with opt-in Spec 417 identity states without broadening unrelated defaults.

Phase 5: Identity Strategy And Resolver Implementation

  • T024 Add apps/platform/app/Support/TenantConfiguration/CanonicalKeyKind.php with bounded key-kind values and no display-name/name-only stable key kind.
  • T025 Add apps/platform/app/Services/TenantConfiguration/CoverageIdentityStrategyRegistry.php with strategies for the eight initial resource types.
  • T026 Add apps/platform/app/Services/TenantConfiguration/CanonicalIdentityResolver.php implementing the preferred ID -> stable source ID -> source composite -> derived composite -> conflict/missing/unsupported hierarchy.
  • T027 Add apps/platform/app/Services/TenantConfiguration/CoverageSecondaryKeyBuilder.php reusing or extending CoveragePayloadRedactor for redacted diagnostic metadata.
  • T028 Add apps/platform/app/Services/TenantConfiguration/IdentityConflictDiagnosticsBuilder.php for bounded candidate/reason/missing-field diagnostics without raw payloads or secrets.
  • T029 Add apps/platform/app/Services/TenantConfiguration/CoverageResourceIdentityEvaluator.php or a narrower repo-equivalent to detect same-scope unsafe collisions and assign claim-safe identity states.
  • T030 Extend apps/platform/app/Services/TenantConfiguration/ResourceTypeRegistry.php metadata only where needed for strategy defaults; do not introduce a broad provider framework. No ResourceTypeRegistry metadata change was needed; the bounded strategy registry owns identity defaults.

Phase 6: Capture, Upsert, And Claim Guard Integration

  • T031 Update apps/platform/app/Services/TenantConfiguration/CoverageResourceUpserter.php to require canonical identity resolver output and stop upserting by id/sourceId shortcut alone.
  • T032 Ensure stable identities upsert exact same-scope resources, derived identities upsert only when unique and allowed, and unsafe identities persist blocked/diagnostic state instead of throwing away actionable proof.
  • T033 Ensure duplicate display names do not merge and first/latest/fallback candidate behavior is not introduced.
  • T034 Update apps/platform/app/Services/TenantConfiguration/CoverageEvidenceWriter.php so latest identity/claim state follows resolver/evaluator output rather than resource-type defaults alone.
  • T035 Update apps/platform/app/Services/TenantConfiguration/GenericContentEvidenceCaptureService.php only as needed to pass normalized/source payload data into identity resolution without adding new provider calls. No code change was needed; the existing capture path already passes raw payload and source metadata into upsert.
  • T036 Update apps/platform/app/Services/TenantConfiguration/ClaimGuard.php signature or call path to account for identity state while preserving existing coverage/source/restore behavior.
  • T037 If a distinct identity re-evaluation command/job is introduced, add OperationRun type/catalog support, service-owned lifecycle, numeric-only summary counts, no raw payload context, no custom terminal notifications, and focused tests for lifecycle, scope, idempotency, capability access, readonly denial, wrong-scope 404, and missing-capability 403. Otherwise document No new OperationRun UX impact.

Phase 7: No-Legacy, Redaction, And Product Surface Guards

  • T038 Add a guard/static test proving no tenant_id appears as Coverage v2 identity ownership truth in new migrations/models/services.
  • T039 Add a guard/static test proving active v2 identity code does not emit old gap terms such as ambiguous_match, policy_record_missing, foundation_not_policy_backed, meta_fallback, raw_gap_count, or primary_gap_count.
  • T040 Add a guard/static test proving no v1 subject resolver, old snapshot identity promotion, v1-to-v2 adapter, fallback reader, or dual-write path is introduced.
  • T041 Add a no-UI guard proving no Filament Resource/Page, Blade view, route, navigation entry, customer report/review/evidence surface, restore readiness surface, or browser-visible Coverage v2 activation was added.
  • T042 Verify diagnostics and OperationRun/audit metadata do not persist raw payloads, tokens, secrets, cookies, authorization headers, private keys, certificates, or full provider response dumps.

Phase 8: Validation And Close-Out

  • T043 Run cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent.
  • T044 Run cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration.
  • T045 Run cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration.
  • T046 Run cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/TenantConfiguration if migrations/indexes/constraints/JSONB changed.
  • T047 Run git diff --check.
  • T048 Complete specs/417-canonical-identity-engine/implementation-report.md with candidate gate, dirty state before/after, files changed, identity strategy matrix, identity schema changes, Claim Guard integration, capture/upsert integration, conflict diagnostics, RBAC/scope proof, redaction proof, no-tenant_id, no-legacy/no-dual-truth, tests run, browser/no-browser decision, Livewire v4, provider registration, global search, destructive/high-impact actions, asset strategy, deployment impact, and deferred work.
  • T049 Confirm no completed historical spec was rewritten or stripped of close-out, validation, task, smoke, browser, or review history.

Stop Conditions

Stop and update spec.md, plan.md, and tasks.md before continuing if any of these appear:

  • A reachable UI surface, route, navigation entry, report/review/customer output, restore readiness surface, or browser-visible Coverage v2 activation is needed.
  • tenant_id is introduced as Coverage v2 ownership truth.
  • Display-name-only identity can become stable.
  • Cross-workspace, cross-managed-environment, or cross-provider resources can merge.
  • Identity conflicts do not block or limit claims.
  • Old v1 gap taxonomy or v1 subject matching becomes active v2 identity truth.
  • A v1-to-v2 adapter, fallback reader, dual write, fallback-to-latest evidence path, or old snapshot promotion is added.
  • Raw provider/evidence payloads, secrets, credentials, tokens, or unredacted PII enter diagnostics, OperationRun context/messages, audit metadata, or customer output.