Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #482
36 KiB
Feature Specification: Spec 415 - Generic Content-Backed Capture
Feature Branch: 415-generic-content-backed-capture
Created: 2026-06-25
Status: Draft
Input: User-provided candidate "415 - Generic Content-Backed Capture" as the next bounded follow-up after Spec 414.
Candidate Selection Summary
- Selected candidate: Spec 415 - Generic Content-Backed Capture.
- Source: Direct user-provided candidate in
/Users/ahmeddarrazi/.codex/attachments/b061549c-2e15-4bb3-b5ab-a2c3e23d0d55/pasted-text.txt. - Why selected: Spec 414 is implemented as an inactive Coverage v2 kernel and explicitly defers OperationRun-backed content-backed capture. This spec is the next narrow foundation slice: store real v2 payload evidence without activating v2 as customer-facing truth.
- Roadmap relationship: Supports evidence/coverage hardening, provider-boundary discipline, OperationRun observability, and future Coverage v2 activation. It does not create a new product surface.
- Close alternatives deferred:
docs/product/spec-candidates.mdcurrently has no safe automatic next-best-prep target. Manual backlog items require explicit product promotion. Spec 416 Canonical Identity Engine is deferred until v2 can persist payload-backed evidence. - Related completed-spec guardrail:
specs/414-tcm-first-coverage-core-cutover/is completed and validated. It is dependency context only and must not be rewritten. No existing415-*spec or branch was found before creation. - Smallest viable implementation slice: Add internal, OperationRun-backed, contract-driven capture for the Spec 414 initial resource types, with concrete resource/evidence persistence, deterministic normalization/hashing, redaction, RBAC/scope guards, and no rendered UI activation.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: Coverage v2 can classify resource types after Spec 414, but it still cannot persist concrete, content-backed evidence for resources in a managed environment.
- Today's failure: Later activation would risk registry-only claims, metadata-only proof, hidden reliance on v1 snapshots, or future compare/render work without durable v2 payload truth.
- User-visible improvement: No immediate UI change. The trust improvement is that future customer/operator coverage claims can be grounded in append-only v2 evidence instead of registry assertions.
- Smallest enterprise-capable version: Persist concrete v2 resources and append-only evidence for the initial 414 resource types, capture only where explicit repo contracts exist, block unsafe/missing/beta contracts, and summarize execution through OperationRun.
- Explicit non-goals: No Coverage v2 UI activation, no Evidence Overview/Review Workspace/Review Pack/Report/Restore/Compare conversion, no v1-to-v2 adapter, no full TCM catalog import, no semantic diff, no rendering, no restore/apply, no browser-visible UI.
- Permanent complexity imported: New environment-owned resource/evidence tables and models, a bounded capture outcome family, capture/source/normalization/redaction services, an OperationRun type, job/start service, authorization tests, and focused guard tests.
- Why now: Spec 414 completed the inactive kernel and named generic content-backed capture as the next dependency. Payload evidence is a prerequisite for identity hardening, operator surface activation, compare/render packs, certification, and legacy removal.
- Why not local: Reusing v1 snapshots or adding a local metadata helper would keep dual truth and would not prove provider-connection ownership, payload redaction, Graph contract discipline, or OperationRun execution truth.
- Approval class: Core Enterprise.
- Red flags triggered: New persisted truth, new service abstractions, new outcome/status-like family, foundation terminology. Defense: the slice is bounded to real current dependency value, no UI activation, no compatibility layer, initial 414 resource types only, and security/audit/queue correctness justify the added structure.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 1 | Wiederverwendung: 2 | Gesamt: 10/12
- Decision: approve as a bounded preparation package.
Spec Scope Fields (mandatory)
- Scope: tenant / managed-environment operational evidence under workspace ownership.
- Primary Routes: N/A - no route or rendered UI surface is added or changed.
- Data Ownership: Environment-owned capture records use
workspace_id+managed_environment_id; provider-sourced records includeprovider_connection_id. Provider-native tenant/directory/account IDs remain metadata only. - RBAC: Workspace membership and managed-environment entitlement are required. Missing membership/entitlement returns 404. Established members without the capture capability return 403. Server-side Gate/Policy enforcement is required on the start service.
No Legacy / No Backward Compatibility Constraint (mandatory)
TenantPilot is pre-production unless this spec explicitly records a compatibility exception.
- Compatibility posture: canonical v2 evidence path; no compatibility exception.
- Legacy aliases, fallback readers, hidden routes, duplicate UI, old labels, or historical fixtures kept?: no.
- Why clean replacement is safe now: Coverage v2 is inactive and not customer-facing. No production data migration or external contract compatibility is required. Spec 415 must not read v1 snapshots as v2 proof, dual-write v1/v2 evidence, or translate old gap taxonomy.
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"; otherwise write N/A - no reachable UI surface impact plus rationale)
N/A - no reachable UI surface impact. This spec adds internal persistence, services, a queued job/start service, OperationRun tracking, authorization, and tests. It must not add Filament resources/pages, Blade views, routes, navigation, customer output, report output, or review/evidence UI activation.
Existing generic Monitoring -> Operations and central database-notification surfaces may show OperationRun records produced by this backend operation through the existing shared lifecycle contract. That is allowed only as existing technical/operational truth. This spec must not add feature-local notification copy, custom operation UI, custom run links, or new rendered capture controls without first amending spec.md, plan.md, and tasks.md.
Product Surface Impact (mandatory for UI-affecting specs; otherwise write N/A - no rendered product surface changed plus rationale)
Reference: docs/product/standards/product-surface-contract.md.
- Product Surface Contract applies?: no - no rendered product surface changes.
- Page archetype: N/A.
- Primary user question: N/A.
- Primary action: N/A.
- Surface budget result: N/A.
- Technical Annex / deep-link demotion: N/A - no default product view exposes OperationRun, evidence IDs, source keys, payloads, fingerprints, or logs.
- Canonical status vocabulary: N/A - no product-facing labels added.
- Visible complexity impact: neutral; no rendered UI surface changes.
- Product Surface exceptions: none.
Browser Verification Plan (mandatory)
- Browser proof required?: no.
- No-browser rationale:
N/A - no rendered UI surface changed. - Focused path when required: N/A.
- Primary interaction to execute: N/A.
- Console, Livewire, Filament, network, and 500-error checks: N/A.
- Full-suite failure triage: N/A; no browser lane is expected unless implementation changes rendered UI, routes, downloads, reports, or reachable actions.
Human Product Sanity Check (mandatory)
- Required?: no.
- No-human-sanity rationale: N/A - no product surface changed.
- Reviewer questions: N/A for rendered UI; reviewers should instead verify that v2 evidence remains inactive and hidden from customer/operator proof surfaces.
- Planned result location: implementation-report.
Product Surface Merge Gate Checklist (mandatory)
- No-legacy posture or approved exception recorded.
- Product Surface Impact is completed or
N/Ais justified. - Browser proof is completed or
N/A - no rendered UI surface changedis justified. - Human Product Sanity is completed or not applicable with rationale.
- Product Surface exceptions are documented or
none. - Implementation report will state Livewire v4 compliance, provider registration location, global search posture, destructive/high-impact action posture, asset strategy, tests/browser result, deployment impact, visible complexity outcome, and no completed-spec rewrite assertion.
Cross-Cutting / Shared Pattern Reuse (mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write N/A - no shared interaction family touched)
- Cross-cutting feature?: yes.
- Interaction class(es): OperationRun execution lifecycle, terminal notification lifecycle, audit logging, provider Graph contract boundary.
- Systems touched:
OperationRun,OperationRunService,OperationRunType,OperationCatalogif required by current repo conventions,OperationSummaryKeys,GraphClientInterface,GraphContractRegistry,AuditLog/audit recorder path, RBAC capability checks. - Existing pattern(s) to extend: OperationRun lifecycle service, Graph contract registry/client seam, canonical capability registry, existing role capability map, existing audit recorder pattern.
- Shared contract / presenter / builder / renderer to reuse: OperationRun start/lifecycle contract where any start feedback/link is introduced. No rendered start UX is planned, so no local toast/link composition is allowed.
- Why the existing shared path is sufficient or insufficient: Existing OperationRun and Graph seams are sufficient for execution truth and provider calls. New local UI or notification semantics are unnecessary.
- Allowed deviation and why: none.
- Consistency impact: capture must not invent local operation notifications, local run-link wording, or local summary counter keys.
- Review focus: verify OperationRun transitions use
OperationRunService, terminal notification remains lifecycle-owned, Graph calls go throughGraphClientInterface, and summary counts use allowed keys.
OperationRun UX Impact (mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an OperationRun; otherwise write N/A - no OperationRun start or link semantics touched)
- Touches OperationRun start/completion/link UX?: yes for backend execution lifecycle; no rendered start surface.
- Shared OperationRun UX contract/layer reused: central OperationRun lifecycle and start contract. If any UI/start surface is unexpectedly added, implementation must stop and patch spec/plan/tasks before continuing.
- Delegated start/completion UX behaviors: no local UI behavior planned; terminal notification path remains central lifecycle mechanism through the existing generic OperationRun notification path only.
- Local surface-owned behavior that remains: initiation inputs only through an internal service/action; no Filament page/action, no toast, no local run link.
- Queued DB-notification policy: no queued DB notifications. Terminal notification behavior remains whatever
OperationRunService/lifecycle emits for initiator-owned runs. - Terminal notification path: central lifecycle mechanism /
OperationRunCompleted. - Exception required?: none.
Provider Boundary / Platform Core Check (mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write N/A - no shared provider/platform boundary touched)
- Shared provider/platform boundary touched?: yes.
- Boundary classification: mixed. Coverage resource/evidence ownership and outcome semantics are platform-core. Microsoft TCM/Graph source details are provider-owned source metadata.
- Seams affected: Coverage v2 resource type registry, Graph contract resolution,
GraphClientInterface, provider connection provenance, source metadata, permission context redaction. - Neutral platform terms preserved or introduced: provider, source contract, managed environment, evidence, resource, capture outcome, operation.
- Provider-specific semantics retained and why:
tcm,graph_v1_fallback, andgraph_beta_experimentalremain from Spec 414 because this is a TCM-first Microsoft coverage path. They must not become generic platform ownership keys. - Why this does not deepen provider coupling accidentally: source-specific values stay in registry/source metadata and resolver decisions. Concrete resource/evidence ownership remains
workspace_id,managed_environment_id, and same-scopeprovider_connection_id; provider-native tenant IDs remain metadata. - Follow-up path: Spec 416 Canonical Identity Engine is deferred; no multi-provider framework is introduced here.
UI / Surface Guardrail Impact (mandatory when operator-facing surfaces are changed; otherwise write N/A)
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Coverage v2 internal capture persistence and service path | no | N/A | OperationRun and Graph service seams only | none | no | N/A - backend/internal evidence capture only |
Decision-First Surface Role (mandatory when operator-facing surfaces are changed)
N/A - no operator-facing surface change.
Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)
N/A - no operator-facing surface change. Raw and normalized payloads are persisted only in internal evidence storage and must not be exposed through customer/operator default views in this spec.
UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)
N/A - no operator-facing surface change.
Operator Surface Contract (mandatory when operator-facing surfaces are changed)
N/A - no operator-facing surface change.
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: yes. Append-only Coverage v2 evidence becomes durable internal evidence truth for captured resource payloads.
- New persisted entity/table/artifact?: yes.
tenant_configuration_resourcesandtenant_configuration_resource_evidenceor repo-equivalent names. - New abstraction?: yes. Bounded source contract resolver, capture service, resource upserter, evidence writer, payload normalizer, and outcome summarizer.
- New enum/state/reason family?: yes. Capture outcomes:
captured,capture_blocked_missing_contract,capture_blocked_permission,capture_blocked_beta,capture_blocked_unsupported,capture_failed. - New cross-domain UI framework/taxonomy?: no.
- Current operator problem: future operators must not receive false Coverage v2 claims or evidence-backed reports when no concrete payload evidence exists.
- Existing structure is insufficient because: Spec 414 registry/scope/claim guard has no concrete resource rows and no content payload persistence. v1 inventory/snapshot truth would create hidden dual truth and cannot enforce Coverage v2 source class, provider provenance, or claim safety.
- Narrowest correct implementation: concrete resources, append-only evidence, minimal generic normalization/hash, source-contract resolver, OperationRun-backed async capture, RBAC/scope guards, and tests for the initial 414 resource types only.
- Ownership cost: new migrations/models/services/jobs/tests and ongoing care for payload redaction, schema constraints, OperationRun keys, and provider contract mapping.
- Alternative intentionally rejected: using v1 snapshots as v2 evidence, storing metadata-only capture rows, or adding UI activation before evidence is durable. These alternatives would hide dual truth or overclaim coverage.
- Release truth: current-release foundation required by the completed 414 kernel and immediately following 416/417/418 lanes.
Compatibility posture
This feature assumes a pre-production environment. Backward compatibility, legacy aliases, migration shims, historical fixtures, v1 fallback readers, v1-to-v2 adapters, and compatibility-specific tests are out of scope.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Unit for source contract resolution, normalization, hashing, redaction, and outcomes. Feature/PostgreSQL for persistence, JSONB, provider-connection same-scope constraints, OperationRun, RBAC, fake GraphClientInterface capture, and no-legacy guards.
- Validation lane(s): fast-feedback, confidence, and PostgreSQL lane where JSONB/check constraints/composite FKs/partial indexes are introduced. Browser lane is N/A unless UI changes are introduced by amendment.
- Why this classification and these lanes are sufficient: The change is backend/runtime and persistence-heavy. Unit tests prove deterministic pure behavior; feature/PostgreSQL tests prove ownership, authorization, persistence, and OperationRun behavior. Browser tests would not add proof without a rendered UI surface.
- New or expanded test families:
tests/Unit/Support/TenantConfigurationandtests/Feature/TenantConfigurationmay expand with Spec 415-specific files. - Fixture / helper cost impact: managed-environment, workspace, provider-connection, user-role, and fake Graph setup must remain opt-in and local to Spec 415 tests.
- Heavy-family visibility / justification: none planned. Do not add heavy-governance or browser families for this slice.
- Special surface test profile: N/A - no rendered UI surface changed.
- Standard-native relief or required special coverage: N/A.
- Reviewer handoff: verify no real Graph/TCM calls, no UI activation, no v1 adapter, no
tenant_id, same-scope provider connection, allowed summary keys, redaction, and OperationRunService lifecycle. - Budget / baseline / trend impact: none expected; if new tests materially slow fast-feedback, document in implementation report.
- Escalation needed: document-in-feature if focused tests require a new helper; follow-up-spec only if identity matching or surface activation becomes necessary.
- Active feature PR close-out entry: Guardrail / N/A no rendered UI surface changed.
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/TenantConfigurationcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/TenantConfigurationcd apps/platform && ./vendor/bin/sail php vendor/bin/pest -c phpunit.pgsql.xml tests/Feature/TenantConfigurationwhen migrations add JSONB/check constraints/composite FKs/partial unique indexesgit diff --check
User Scenarios & Testing (mandatory)
User Story 1 - Persist Content-Backed Coverage v2 Evidence (Priority: P1)
As a platform engineer preparing Coverage v2 activation, I need concrete managed-environment resources and append-only evidence rows so future claims can be backed by durable payload truth.
Independent Test: Run the capture service against a fake GraphClientInterface response for an eligible resource type and assert concrete resource upsert plus append-only evidence persistence with raw payload, normalized payload, hash, and OperationRun link.
Acceptance Scenarios:
- Given an eligible registered resource type with an explicit source contract, When capture runs for a managed environment and same-scope provider connection, Then a concrete Coverage v2 resource exists with deterministic identity fields.
- Given a successful payload fetch, When evidence is written, Then a new append-only evidence row stores raw payload, normalized payload, payload hash, source metadata, permission context, captured timestamp, and OperationRun link.
- Given the same normalized payload captured twice, When hashes are compared, Then the payload hash is deterministic and identical.
- Given a changed normalized payload captured later, When evidence is written, Then a new evidence row is appended instead of mutating prior evidence.
User Story 2 - Fail Safe On Missing, Beta, Unsupported, Or Unauthorized Capture (Priority: P1)
As a release reviewer, I need capture eligibility to fail safe so v2 does not guess endpoints, certify beta data, or emit old v1 gap reasons.
Independent Test: Resolve capture eligibility for one TCM-aligned type, one Graph v1 fallback type, and the beta experimental type; assert missing contracts, beta default, unsupported states, and permission denial produce structured v2 outcomes only.
Acceptance Scenarios:
- Given a registered type without an explicit source contract, When capture eligibility is resolved, Then the outcome is
capture_blocked_missing_contract. - Given a beta experimental resource type without explicit beta capture opt-in, When capture is requested, Then the outcome is
capture_blocked_betaand no customer/certified claim is possible. - Given an unsupported or out-of-scope type, When capture is requested, Then it is skipped safely without endpoint guessing.
- Given a missing provider permission, When capture fails due to authorization from the provider, Then the outcome is
capture_blocked_permissionwith sanitized context only. - Given any blocked/failed capture, When outcomes are inspected, Then no old v1 gap vocabulary is emitted.
User Story 3 - Run Capture As An Observable Authorized Operation (Priority: P1)
As an operator-authorized backend workflow, I need generic capture to be authorized, queued when remote work is involved, and observable through OperationRun without rendering a new UI.
Independent Test: Start capture through the internal service for authorized and unauthorized users; assert 404/403 semantics, OperationRun creation/dedupe, queued job dispatch, OperationRunService transitions, numeric-only summary counts, and audit entry.
Acceptance Scenarios:
- Given a non-member user, When capture start is attempted, Then access is denied as not found (404).
- Given a workspace member without managed-environment entitlement, When capture start is attempted, Then access is denied as not found (404).
- Given a managed-environment member without the capture capability, When capture start is attempted, Then access is denied as forbidden (403).
- Given an authorized actor, When capture starts, Then a
tenant_configuration.captureOperationRun is created or reused and remote work is queued. - Given the capture job runs, When it updates execution state, Then status/outcome transitions go through
OperationRunService. - Given capture outcomes are summarized, When
summary_countsis saved, Then only canonical numeric keys are used. Default keys aretotal,processed,succeeded,skipped,failed, anderrors_recordedunless the implementation explicitly extendsOperationSummaryKeys::all()with tests and spec-aligned rationale.
User Story 4 - Keep Coverage v2 Inactive And Non-Legacy (Priority: P1)
As a product/release reviewer, I need proof that content-backed v2 evidence does not become an active customer/operator truth or compatibility bridge in this slice.
Independent Test: Static/feature guards assert no Filament resources/pages/routes/views/navigation are added, no v1-to-v2 adapter or dual-write path appears, no v1 snapshots are read as v2 evidence, and no Coverage v2 table introduces tenant_id.
Acceptance Scenarios:
- Given v2 evidence rows exist, When current customer/operator surfaces render, Then they do not display v2 coverage claims from this spec.
- Given existing v1 runtime remains, When capture implementation is inspected, Then there is no v1-to-v2 adapter, fallback reader, or dual-write path.
- Given new migrations/models, When schema and code are inspected, Then no Coverage v2 ownership field uses
tenant_id. - Given raw provider payloads exist in evidence storage, When logs, OperationRun context/messages, notifications, and audit metadata are inspected, Then raw payloads, tokens, secrets, and PII are absent.
Requirements (mandatory)
Functional Requirements
- FR-415-001: The system MUST keep Coverage v2 inactive for customer-facing and operator-facing proof surfaces in this spec.
- FR-415-002: The system MUST create or reuse concrete Coverage v2 resource persistence for managed-environment resources, using
workspace_id,managed_environment_id, andprovider_connection_idfor provider-sourced records. - FR-415-003: The system MUST create append-only Coverage v2 evidence persistence linked to concrete resource, workspace, managed environment, provider connection, OperationRun, source metadata, raw payload, normalized payload, payload hash, permission context, and capture timestamp.
- FR-415-004: The system MUST use JSONB for raw payload, normalized payload, and permission/source metadata where persisted.
- FR-415-005: The system MUST compute deterministic payload hashes from normalized payloads.
- FR-415-006: The system MUST normalize payloads minimally: stable JSON key ordering, configured volatile-field handling only where explicit, source metadata separation, and no semantic compare/render/restore mapping.
- FR-415-007: The system MUST resolve capture source contracts from the Coverage v2 registry and the repo's Graph contract path; it MUST NOT guess endpoints.
- FR-415-008: All Microsoft Graph calls MUST go through
GraphClientInterface; direct HTTP/SDK/quick endpoint calls outside the contract path are forbidden. - FR-415-009: The initial resource scope is limited to the Spec 414 resource types:
deviceAndAppManagementAssignmentFilter,deviceEnrollmentLimitRestriction,deviceEnrollmentPlatformRestriction,deviceEnrollmentStatusPageWindows10,appProtectionPolicyAndroid,appProtectionPolicyiOS,notificationMessageTemplate, androleScopeTag. - FR-415-010: The implementation MUST classify each initial resource type as
captured,capture_blocked_missing_contract,capture_blocked_permission,capture_blocked_beta,capture_blocked_unsupported, orcapture_failed. - FR-415-011: The implementation MUST prove every initial resource type has an explicit capture decision: each TCM-aligned type is either captured through an explicit contract or blocked with a clear missing-contract reason, the Graph v1 fallback type is captured or blocked with a clear contract reason, and the beta experimental type is blocked by default.
- FR-415-012: Beta experimental capture MUST be blocked by default unless this spec is amended with explicit beta capture opt-in and safety tests.
- FR-415-013: Missing contracts MUST produce
capture_blocked_missing_contractwithout failure escalation or endpoint guessing. - FR-415-014: Unsupported/out-of-scope types MUST be skipped safely.
- FR-415-015: Provider connection provenance MUST be same-scope: any stored
provider_connection_idmust belong to the sameworkspace_idandmanaged_environment_idas the resource/evidence row. - FR-415-016: External Microsoft tenant/directory/subscription/account IDs MUST be metadata only and MUST NOT become platform ownership keys.
- FR-415-017: Capture start MUST enforce workspace membership, managed-environment entitlement, and capture capability server-side through Gate/Policy or existing capability resolver.
- FR-415-018: The default capture capability is
Capabilities::EVIDENCE_MANAGEunless implementation discovers a more specific existing repo-approved capture capability. Adding a new capability is allowed only with registry, role-map, and tests in this spec. - FR-415-019: Capture MUST create or reuse a canonical
tenant_configuration.captureOperationRun for remote/provider-backed work. - FR-415-020: Remote/provider capture MUST execute asynchronously through a queued job.
- FR-415-021: OperationRun status and outcome transitions MUST go through
OperationRunService. - FR-415-022: OperationRun
summary_countsMUST use flat numeric values and canonical keys fromOperationSummaryKeys::all(). Default planned keys aretotal,processed,succeeded,skipped,failed, anderrors_recorded. - FR-415-023: OperationRun context/messages, notifications, audit metadata, and logs MUST NOT include raw payloads, tokens, secrets, or PII.
- FR-415-024: Permission context MUST be redacted before persistence.
- FR-415-025: Capture MUST emit safe audit evidence for start/completion/failure attempts through the repo's existing
AuditRecorder/AuditEventBuilderpath, using stable action IDstenant_configuration.capture.started,tenant_configuration.capture.completed, andtenant_configuration.capture.failed, including actor, workspace, managed environment, provider connection, OperationRun, resource type counts, and no raw payloads. - FR-415-026: No v1-to-v2 adapter, dual write, fallback reader, old snapshot promotion, legacy route, or old gap taxonomy may be introduced.
- FR-415-027: No Filament Resource/Page, Blade view, route, navigation entry, customer report/review/evidence surface, or browser-visible Coverage v2 activation may be added in this spec.
- FR-415-028: An implementation report MUST include the capture eligibility matrix for all initial resource types.
Non-Functional Requirements
- NFR-415-001: Capture must fail safe under missing contracts, missing permissions, beta resources, provider errors, and cross-scope provider connections.
- NFR-415-002: Tests must fake all Graph/TCM/provider calls. No test may call real Microsoft Graph or TCM.
- NFR-415-003: Raw provider payloads may live only in evidence storage and must not leak into logs, audit metadata, OperationRun context/messages, or notifications.
- NFR-415-004: New indexes must follow proven query paths only. JSONB GIN indexes are allowed only when the implementation adds a real query path.
- NFR-415-005: The implementation must remain bounded to the initial Spec 414 resource set.
- NFR-415-006: The queue and deployment impact must be documented: migrations and queue workers are expected; no asset or browser deployment change is expected.
Required Redaction Keys
At minimum, redaction must handle case-insensitive keys containing:
access_tokenrefresh_tokenid_tokenclient_secretsecretpasswordprivate_keycertificateauthorizationcookieset-cookiebearer
Key Entities (include if feature involves data)
- Tenant Configuration Resource: Concrete Coverage v2 resource observed in one workspace/managed environment/provider connection. It carries resource type, source class, canonical identity key, latest evidence state, and timestamps.
- Tenant Configuration Resource Evidence: Append-only payload evidence for a concrete Coverage v2 resource, linked to OperationRun and source metadata. It stores raw and normalized JSONB payloads, payload hash, redacted permission context, capture level/state, and captured timestamp.
- Capture Outcome: Non-UI service result classifying each resource type attempt as captured, blocked, skipped, or failed with a v2 reason.
- OperationRun: Execution truth for capture lifecycle, queue status, sanitized context, and numeric summary counts. It is not payload truth.
Success Criteria (mandatory)
- SC-415-001: Focused tests prove concrete v2 resources and append-only evidence can be persisted for an eligible fake source response.
- SC-415-002: Focused tests prove missing contract, beta default, unsupported, permission blocked, and failed capture outcomes are safe and use v2 vocabulary only.
- SC-415-003: Focused tests prove Graph calls use
GraphClientInterfaceand no direct endpoint bypass exists in the capture path. - SC-415-004: Focused tests prove same-scope
provider_connection_idenforcement for resource/evidence writes. - SC-415-005: Focused tests prove no
tenant_idownership field is introduced in new Coverage v2 tables/models/migrations. - SC-415-006: Focused tests prove OperationRun creation/reuse, queued execution, service-owned transitions, numeric-only summary counts, and sanitized context.
- SC-415-007: Focused tests prove non-member 404, missing environment entitlement 404, missing capability 403, readonly denial, and authorized capture start.
- SC-415-008: Static/feature guards prove no v1 adapter, dual-write path, fallback reader, old snapshot promotion, old gap outcome vocabulary, or customer-facing v2 activation is introduced.
- SC-415-009: Implementation report includes the resource-type capture eligibility matrix and no-browser decision.
Assumptions
- Spec 414 is implemented and accepted as the inactive Coverage v2 kernel. Repo artifacts show completed tasks, implementation report, tests, and kernel models/services/migration.
tenant_configuration_resourcesandtenant_configuration_resource_evidencewere deferred in Spec 414 and are expected to be added in Spec 415 unless implementation discovers equivalent repo-real tables.- The local Boost database schema output may not reflect all migrations; implementation should use repo migrations/code as source of truth unless the Sail/PostgreSQL lane is explicitly run.
- Existing Graph contracts include some related Graph fallback/foundation types such as
notificationMessageTemplate,roleScopeTag, andassignmentFilter, but exact source eligibility must be resolved by repo-real contract mapping rather than guessed endpoints. - No rendered UI surface is required for capture start in this spec. Tests may start capture through an internal service/action.
Risks
| Risk | Severity | Mitigation |
|---|---|---|
| Capture becomes an activation/cutover spec | High | No UI, no customer proof, no v1 removal, no dual truth, stop-and-amend rule |
| Graph endpoints get guessed or hardcoded | High | Graph contract resolver + GraphClientInterface tests |
| Raw payloads/secrets leak | High | Redaction tests, OperationRun/audit/log context tests |
| Provider connection leaks across environments | High | Same-scope validation and tests |
| OperationRun lifecycle bypass | High | Use OperationRunService and existing guards |
| Summary counts drift into free-form keys | Medium | Use OperationSummaryKeys only; default existing keys |
| Capture tries to support too many types | Medium | Initial 414 resource types only; eligibility matrix |
| New tests become expensive | Medium | Unit/feature/pgsql only; fake Graph; no browser |
Follow-up Spec Candidates
- Spec 416 - Canonical Identity Engine.
- Spec 417 - Coverage v2 Operator Surface.
- Spec 418 - Legacy Coverage Cutover and Removal.
- Spec 419 - Intune Core Comparable/Renderable Pack.
- Spec 420 - Certified Intune Core Coverage Pack.
- Spec 421 - Pilot Readiness Gate.
Open Questions
None blocking. Implementation must document any repo-real source contract mismatch in the eligibility matrix rather than guessing endpoints or broadening scope.