Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #482
11 KiB
11 KiB
Implementation Report: Spec 415 - Generic Content-Backed Capture
Preflight
- Branch:
415-generic-content-backed-capture - Baseline HEAD:
dfda397e feat: migrate tcm first coverage core cutover (#481) - Initial dirty state:
specs/415-generic-content-backed-capture/untracked as the active spec artifact set. - Spec 414 dependency: treated as completed/validated context only; no files under
specs/414-tcm-first-coverage-core-cutover/were modified. - Existing equivalent check: no existing
tenant_configuration_resourcesortenant_configuration_resource_evidencetables/models were present before implementation.
Implementation Scope
- Added
tenant_configuration_resourcesandtenant_configuration_resource_evidencepersistence withworkspace_id,managed_environment_id,provider_connection_id, andresource_type_id; notenant_idfields. - Added PostgreSQL composite scope constraints for managed environment/workspace, provider connection/workspace/environment, evidence/resource/provider/type, evidence/latest-resource/provider/type, and evidence/operation-run/workspace/environment integrity while keeping SQLite-compatible migrations for tests.
- Added a database-level
provider_connections(managed_environment_id, workspace_id)binding so provider connections cannot be attached to a managed environment from another workspace. - Added a scoped
latest_evidence_idforeign key so a resource can only point at evidence for the same resource, workspace, managed environment, provider connection, and resource type. - Added models and factories for concrete resources and append-only evidence.
- Added bounded capture outcomes only:
captured,capture_blocked_missing_contract,capture_blocked_permission,capture_blocked_beta,capture_blocked_unsupported,capture_failed. - Added contract resolution through
GraphContractRegistrywith explicit mappings only:deviceAndAppManagementAssignmentFilter->assignmentFilter-> captured when Graph succeeds.notificationMessageTemplate->notificationMessageTemplate-> captured when Graph succeeds.roleScopeTag-> beta-backed and blocked by default.- Other initial TCM types remain
capture_blocked_missing_contractuntil explicit contracts are introduced.
- Added deterministic normalization, configured volatile-field stripping, SHA-256 payload hashes, and recursive secret/token/header/cookie redaction for metadata/context.
- Added
tenant_configuration.captureoperation type/catalog label and a queued capture job. - Added defense-in-depth scope validation before remote provider work: the job resolves provider connections only inside the OperationRun workspace/environment, and the capture service validates tenant/provider/run/context scope before calling the provider gateway.
Capture Eligibility Matrix
| Canonical type | Source class | Source contract key | Default outcome |
|---|---|---|---|
deviceAndAppManagementAssignmentFilter |
tcm |
assignmentFilter |
captured when Graph succeeds |
deviceEnrollmentLimitRestriction |
tcm |
none | capture_blocked_missing_contract |
deviceEnrollmentPlatformRestriction |
tcm |
none | capture_blocked_missing_contract |
deviceEnrollmentStatusPageWindows10 |
tcm |
none | capture_blocked_missing_contract |
appProtectionPolicyAndroid |
tcm |
none | capture_blocked_missing_contract |
appProtectionPolicyiOS |
tcm |
none | capture_blocked_missing_contract |
notificationMessageTemplate |
graph_v1_fallback |
notificationMessageTemplate |
captured when Graph succeeds |
roleScopeTag |
graph_beta_experimental |
roleScopeTag |
capture_blocked_beta unless beta capture is explicitly enabled |
Operation And RBAC
- Start capability: existing
Capabilities::EVIDENCE_MANAGE. - Authorization behavior:
- non-member and excluded explicit environment entitlement -> 404.
- workspace member without capability / readonly -> 403.
- same workspace/environment/provider connection -> allowed.
- OperationRun behavior:
- creates/reuses
tenant_configuration.capturequeued runs from idempotent provider/resource-type inputs. - remote/provider work is queued through the central OperationRun lifecycle.
- the central queued execution gate validates
provider_connection_idagainst both the OperationRun workspace and managed environment before provider work is allowed. - the capture job and capture service also fail closed before Graph access when the provider connection, managed environment, OperationRun columns, or OperationRun target scope do not match.
- summary keys are existing canonical keys only:
total,processed,succeeded,skipped,failed,errors_recorded. - raw payloads and Graph credential options are not written into OperationRun context or audit metadata.
- exception messages are reduced to bounded
RunFailureSanitizerreason codes for resource outcomes; dispatch/job failure audit messages are sanitized before persistence.
- creates/reuses
- Audit action IDs used:
tenant_configuration.capture.startedtenant_configuration.capture.completedtenant_configuration.capture.failed
Product Surface
- No rendered UI surface changed.
- No Filament resources, pages, widgets, relation managers, routes, panel providers, navigation entries, views, assets, review/report/evidence pages, or restore readiness surfaces were added or modified.
- Browser proof:
N/A - no rendered UI surface changed. - Human Product Sanity:
N/A - no product surface changed. - Visible complexity outcome: unchanged.
- Product Surface exceptions: none.
- No completed historical spec was rewritten or stripped of validation/task/review history.
Filament V5 Contract
- Livewire v4.0+ compliance: no Livewire/Filament runtime UI code changed; application package baseline remains Livewire v4.
- Provider registration location: unchanged; Laravel 11+/12 panel provider registration remains
bootstrap/providers.php. - Global search: no globally searchable resource was added;
N/A. - Destructive/high-impact actions: no UI action added; queued capture start is backend service only and RBAC-gated.
- Asset strategy: no assets registered; no
filament:assetsrequirement from this spec. - Testing plan: Unit/Feature/PostgreSQL lanes only; no Livewire page/widget/relation-manager/action tests required.
Files Changed
- Persistence:
apps/platform/database/migrations/2026_06_25_000415_create_tenant_configuration_capture_tables.phpapps/platform/app/Models/TenantConfigurationResource.phpapps/platform/app/Models/TenantConfigurationResourceEvidence.phpapps/platform/database/factories/TenantConfigurationResourceFactory.phpapps/platform/database/factories/TenantConfigurationResourceEvidenceFactory.php
- Capture support/services:
apps/platform/app/Support/TenantConfiguration/CaptureOutcome.phpapps/platform/app/Services/TenantConfiguration/CoverageSourceContractResolver.phpapps/platform/app/Services/TenantConfiguration/CoverageSourceContractDecision.phpapps/platform/app/Services/TenantConfiguration/GenericPayloadNormalizer.phpapps/platform/app/Services/TenantConfiguration/CoveragePayloadRedactor.phpapps/platform/app/Services/TenantConfiguration/CoverageCaptureOutcomeSummarizer.phpapps/platform/app/Services/TenantConfiguration/CoverageResourceUpserter.phpapps/platform/app/Services/TenantConfiguration/CoverageEvidenceWriter.phpapps/platform/app/Services/TenantConfiguration/GenericContentEvidenceCaptureService.phpapps/platform/app/Services/TenantConfiguration/StartTenantConfigurationCapture.phpapps/platform/app/Jobs/TenantConfiguration/CaptureTenantConfigurationEvidenceJob.php
- Operation/audit registry:
apps/platform/app/Services/Operations/QueuedExecutionLegitimacyGate.phpapps/platform/app/Support/OperationRunType.phpapps/platform/app/Support/OperationCatalog.phpapps/platform/app/Support/Audit/AuditActionId.php
- Tests:
apps/platform/tests/Unit/Support/TenantConfiguration/Spec415CoverageSourceContractResolverTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec415GenericPayloadNormalizerTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec415CoverageRedactionTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec415CoverageCaptureOutcomeTest.phpapps/platform/tests/Unit/Support/TenantConfiguration/Spec415CoverageCaptureOperationRunSummaryTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415CoverageEvidencePersistenceTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415ProviderConnectionScopeTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415CoverageCaptureAuthorizationTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415CoverageCaptureOperationRunTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415GenericContentBackedCaptureTest.phpapps/platform/tests/Feature/TenantConfiguration/Spec415NoLegacyNoUiActivationTest.phpapps/platform/tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php
Validation
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent-> pass.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfiguration-> 22 passed, 69 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Operations/QueuedExecutionLegitimacyGateTest.php-> 12 passed, 106 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration/Spec415GenericContentBackedCaptureTest.php-> 4 passed, 50 assertions.cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfiguration-> 24 passed, 7 skipped, 129 assertions.cd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/TenantConfiguration-> 31 passed, 141 assertions.- PostgreSQL migration smoke on
tenantatlas_testing:migrate:fresh --force-> pass; targeted rollback of2026_06_25_000415_create_tenant_configuration_capture_tables.php-> pass; finalmigrate:fresh --force-> pass. - PostgreSQL latest-evidence lifecycle coverage: scoped pointer mismatch is rejected, same-scope pointer is accepted, and resource deletion cascades linked evidence without constraint failure.
git diff --check-> pass.- Additional untracked-file whitespace scan -> pass.
Deployment Impact
- Migrations: yes, adds two new tenant configuration capture tables with PostgreSQL JSONB/check constraints and composite scope foreign keys; also adds a provider-connection environment/workspace binding constraint on the existing
provider_connectionstable. - Queue worker: yes, new queued capture job.
- Environment variables: no new variables.
- Scheduler: no change.
- Storage/volumes: no change.
- Assets: no change;
filament:assetsnot required by this spec. - Staging/production: run migrations before enabling any future caller; ensure queue workers are running; validate staging data has no existing provider-connection workspace/environment mismatches before production promotion.
Deferred Work
- Add explicit source contracts for the remaining TCM-backed resource types before claiming captured evidence for them.
- Add any UI start surface only through a future UI-affecting spec with Product Surface review.