44 KiB
Feature Specification: Provider-neutral Artifact Source Taxonomy
Feature Branch: 284-provider-neutral-artifact-source-taxonomy
Created: 2026-05-08
Status: Implementation Ready
Input: User description: "Follow the next-best-prep workflow for reserved slot 284 and prepare the Provider-neutral Artifact Source Taxonomy v1 package without implementing application code."
Implementation Acceptance Update (2026-05-09): Runtime implementation is now explicitly requested. The prior SCOPE-001 prerequisite block is resolved for this slice by repo truth: Specs 281, 282, and 283 are present on the implementation branch, Spec 279 records the approved managed-environment core exception, and the touched artifact tables now carry the established workspace plus managed-environment ownership boundary. No new table, ownership plane, descriptor columns, or backfill is introduced by this status update.
Spec Candidate Check
- Problem: TenantPilot already stores and renders artifact truth through
finding_type,source,report_type,policy_type,source_kind, provider-owned payload fields, and ad hoc canonical-control bindings, but those seams still let Microsoft-specific type names behave like platform-core truth. Findings, evidence snapshots, stored reports, inventory metadata, and review sections describe the same artifact lineage in parallel vocabularies instead of one provider-neutral source contract. - Today's failure: Operators and contributors must reinterpret the same artifact through different discriminator families.
FindingsSummarySourcetreatspermission_posture,entra_admin_roles, anddeviceCompliancePolicyas if they were interchangeable core-domain truth;StoredReportpersistsreport_typeas the main summary noun;EvidenceSourceProvideronly exposessource_kindplus raw record type or id; and inventory still treatspolicy_typeas the top-level metadata key even where the platform already differentiates governed-subject vocabulary from provider-owned detail. - User-visible improvement: Findings, evidence, reports, inventory items, and review or support summaries expose one canonical source descriptor first: source family, target, detector, and control summary. Microsoft-specific object types, report types, Graph-facing detector details, and legacy
policy_typevalues remain available, but they become provider-owned detail instead of the first thing an operator or contributor must decode. - Smallest enterprise-capable version: Introduce one bounded artifact-source descriptor across existing finding, evidence, stored-report, and inventory seams; pin the initial
source_family,source_kind, andsource_target_kindinventories; separate inventorycanonical_type,provider_object_type, andprovider_display_type; and align touched evidence or review presenters to disclose the canonical descriptor before provider detail. Do not add a new artifact table, no compliance engine, no full detector catalog, no control-catalog expansion, and no historical backfill. - Explicit non-goals: No new compliance engine, no full control-catalog expansion, no historical backfill, no provider framework, no package-execution runtime, no workspace-first RBAC rewrite from Spec
285, no copy or localization neutralization from Spec286, no no-legacy enforcement pack from Spec287, and no UI-polish-first redesign. - Permanent complexity imported: One bounded artifact-source descriptor contract, one pinned inventory for
source_family,source_kind, andsource_target_kind, one narrow normalizer or presenter seam if existing helpers cannot carry the contract cleanly, one inventory type descriptor split, and focused unit, feature, guard, and browser proof. No new table or independent persisted entity is imported. - Why now: Specs
279through283already moved the platform toward workspace-first managed environments, provider-neutral connection scope, artifact-surface ownership, and provider capability truth. The remaining gap is artifact lineage and artifact-type semantics. If284does not land now, later package-output work and later copy neutralization will still inherit Microsoft-shaped artifact truth. - Why not local: The drift is shared across models, evidence-source contracts, stored-report readers, inventory metadata, review sections, and operator surfaces. A local rename in one page or one service would immediately diverge from the other artifact consumers.
- Approval class: Core Enterprise
- Red flags triggered: New taxonomy, new shared abstraction, and derived descriptor scope fields. Defense: the repo already has multiple real consumers and conflicting artifact vocabularies.
284is intentionally bounded to one descriptor contract, a small pinned inventory, and the minimum surface convergence needed to make current-release artifacts provider-neutral. - Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve
Spec Scope Fields
- Scope: workspace, tenant
- Primary Routes:
- workspace-first findings resource list and detail surfaces
- workspace-first evidence snapshot list and detail surfaces
- workspace-first stored-report list and detail surfaces
- workspace-first inventory item list and detail surfaces
- workspace-first tenant-review detail surfaces and shared review sections that already summarize canonical controls and supporting evidence
- Data Ownership:
Finding,EvidenceSnapshotItem,StoredReport, andInventoryItemremain tenant-owned persisted truth bound to the established workspace plus tenant scope at authorization time; current repo truth reaches that scope through existingworkspace_idcolumns where present and throughmanaged_environment_idrelations everywhere else- the shared artifact-source descriptor remains a derived read-model or presenter contract over those existing records in
284v1; no new descriptor columns, no second descriptor payload, and no new table or ledger are introduced provider_connection_idmay be persisted or derived only where current artifact truth already knows the connection;284does not invent a new provider-connection ownership modelpackage_run_idremains an optional nullable reference in the shared descriptor contract only;284does not create package-execution truth or package artifacts
- RBAC:
- workspace membership remains the first
404boundary - managed-environment entitlement remains the second
404boundary - existing view capabilities for findings, evidence, reports, inventory, and tenant reviews remain authoritative
284introduces no new destructive action and no new authorization plane
- workspace membership remains the first
Cross-Cutting / Shared Pattern Reuse
- Cross-cutting feature?: yes
- Interaction class(es): evidence/report viewers, read-only detail sections, inventory metadata, status messaging, support-diagnostic and AI source descriptors
- Systems touched:
EvidenceSourceProvider,EvidenceSnapshotService,FindingsSummarySource, stored-report producers and readers,InventoryPolicyTypeMeta,TenantReviewSectionFactory,ArtifactTruthPresenter, and existing support or AIsource_familyconsumers - Existing pattern(s) to extend:
PlatformVocabularyGlossary,GovernanceSubjectTaxonomyRegistry,CanonicalControlResolutionRequest,CanonicalControlResolver,InventoryPolicyTypeMeta,ArtifactTruthPresenter, and the existing support or AIsource_familynaming precedent - Shared contract / presenter / builder / renderer to reuse:
CanonicalControlResolutionRequest,CanonicalControlResolver,InventoryPolicyTypeMeta,EvidenceSnapshotService,TenantReviewSectionFactory, andArtifactTruthPresenter - Why the existing shared path is sufficient or insufficient: the repo already has vocabulary, control-binding, and presenter seams, but it still lacks one shared artifact-source descriptor that all artifact families can carry without page-local or service-local remapping
- Allowed deviation and why: one bounded
ArtifactSourceDescriptoror equivalent normalizer or presenter seam is allowed if the current helpers cannot carry the pinned descriptor fields without duplication - Consistency impact: findings, evidence snapshots, stored reports, inventory summaries, review sections, and touched support or AI bundles must expose the same
source_family,source_kind,source_target_kind, and descriptor semantics before disclosing provider detail;control_keystays mandatory for touched findings, evidence, stored reports, and review sections, while inventory keeps the shared descriptor plus the canonical and provider type split as its primary summary - Review focus: verify that no touched page, presenter, or service rebuilds the descriptor locally and that Microsoft-specific nouns remain nested provider detail rather than new shared platform truth
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no
- Shared OperationRun UX contract/layer reused:
N/A - Delegated start/completion UX behaviors:
N/A - Local surface-owned behavior that remains:
N/A - Queued DB-notification policy:
N/A - Terminal notification path:
N/A - Exception required?: none
Provider Boundary / Platform Core Check
- Shared provider/platform boundary touched?: yes
- Boundary classification: mixed
- Seams affected:
Findingdiscriminator fields,EvidenceSourceProviderresult shape,EvidenceSnapshotItempersisted source metadata,StoredReportreport typing, inventory metadata, canonical-control binding inputs, review-section evidence summaries, and support or AIsource_familyconsumers if touched - Neutral platform terms preserved or introduced:
workspace_id,tenant_id,managed_environment_id,source_family,source_kind,source_target_kind,source_target_identifier,provider_key,provider_connection_id,canonical_type,detector_key, andcontrol_key - Provider-specific semantics retained and why:
finding_type,report_type,policy_type, Microsoft object types, report domains, Graph-facing detector keys, and provider display labels remain provider-owned because the platform still needs to preserve Microsoft-native evidence and because284is not a fake generic rewrite of the adapters - Why this does not deepen provider coupling accidentally: the shared descriptor moves provider detail out of the top-level artifact summary instead of expanding Microsoft-specific semantics. It adds one neutral envelope over already existing provider detail and rejects new provider registries or fake multi-provider engines.
- Follow-up path: package-execution adoption remains for later work, broader copy neutralization remains in Spec
286, and no-legacy enforcement remains in Spec287
UI / Surface Guardrail Impact
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Findings resource summary and detail copy | yes | Native Filament + existing shared presenters | findings, evidence, review | page, detail | no | summary fields and presenter ordering only |
| Evidence snapshot resource summary and item detail | yes | Native Filament + shared artifact truth presenters | evidence, reports, reviews | page, detail | no | read-only evidence surface |
| Inventory item list and detail metadata | yes | Native Filament | inventory metadata, governed-subject labeling | page, detail | no | descriptor and type-label split only |
| Stored report list and detail summary | yes | Native Filament + shared artifact truth presenters | reports, evidence, support | page, detail | no | read-only reporting surface |
| Tenant review detail sections that summarize supporting artifacts | yes | Mixed native Filament + shared review factory | reviews, evidence, reports | detail | no | section summary and disclosure order only |
Decision-First Surface Role
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Findings resource | Primary Decision Surface | Decide whether the finding needs follow-up now | Canonical source family, governed subject or source target, detector summary, control summary, severity, status | Provider object type, raw legacy finding type, low-level evidence payload | Primary because findings are already an operator decision queue | Follows governance-review workflow | Removes the need to decode Microsoft-only type names before triage |
| Evidence snapshot resource | Tertiary Evidence / Diagnostics Surface | Inspect which supporting artifacts prove the current state | Canonical source descriptor and control summary per item | Raw payloads, record ids, provider object types, legacy report or finding types | Not primary because it explains evidence after a decision surface points here | Follows evidence-inspection workflow | Keeps diagnostic depth available without making it the first summary |
| Inventory item resource | Secondary Context Surface | Inspect what provider object the platform currently knows about | Canonical type, provider display type, lifecycle timestamps | Raw provider object type, legacy policy_type, low-level metadata |
Not primary because inventory is an inspection surface, not the first decision queue | Follows inventory-inspection workflow | Removes ambiguity between platform type and provider object type |
| Stored report resource | Tertiary Evidence / Diagnostics Surface | Inspect a generated provider report behind other summaries | Canonical source family, report summary, control summary when present | Provider-native report type, payload, provider detail | Not primary because reports are evidence or reporting artifacts | Follows diagnostics and reporting workflow | Keeps report meaning readable without turning report_type into platform truth |
| Tenant review detail sections | Secondary Context Surface | Cross-check which supporting artifacts justify the review state | Canonical source summary and control summary | Raw artifact payloads and provider-native identifiers | Not primary because the review decision already exists at the review level | Follows review workflow | Prevents section summaries from restating provider-native detail as the main conclusion |
Audience-Aware Disclosure
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Findings resource | operator-MSP, support-platform | canonical source family, governed subject, detector summary, control summary, severity, status | provider display type, legacy finding type, related operation or review links | raw payloads and provider-native evidence | Open finding detail or the existing remediation path |
raw payload excerpts remain collapsed or lower on the page | finding summary states artifact meaning once; detail adds proof rather than a second competing label |
| Evidence snapshot resource | operator-MSP, support-platform | source descriptor per snapshot item, completeness state, control summary | provider object type, source record references, freshness detail | raw evidence payloads | Inspect evidence item |
payload detail remains secondary | canonical item summary stays aligned with findings and review sections |
| Inventory item resource | operator-MSP, support-platform | canonical type and provider display type | provider object type, source timestamps, sync provenance | raw metadata | Open inventory item |
raw meta_jsonb remains diagnostics-only |
canonical type is shown once and not duplicated as a second headline |
| Stored report resource | operator-MSP, support-platform | source family, report headline, latest freshness | provider-native report type, detector detail, fingerprints | raw payload | Open report detail |
raw JSON remains hidden or lower priority | report summary uses canonical source family once and nests provider detail |
| Tenant review detail sections | operator-MSP, support-platform | artifact source summary and control summary inside each section | provider object type, legacy type names, supporting links | raw evidence bundles and payloads | Inspect related artifact |
raw provider detail remains gated to deeper disclosure | section summary stays aligned with the owning review summary instead of restating a second truth |
UI/UX Surface Classification
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Findings resource | Monitoring / Queue / Workbench | Queue / Review Surface | Open the finding and decide follow-up | Full-row open to detail | required | Existing contextual actions stay in row More or detail header |
existing destructive-like mutations remain grouped and confirmation-protected | workspace-first findings list | workspace-first finding detail | workspace, managed environment, severity, status | Finding | canonical source family, governed subject, and control summary | none |
| Evidence snapshot resource | List / Table / Bulk | Read-only Registry / Report Surface | Open the snapshot item that proves a state | Existing list or detail page | required | Existing safe links remain contextual | none | workspace-first evidence list | workspace-first evidence detail | workspace, managed environment, completeness state | Evidence snapshot | source descriptor and control summary | none |
| Inventory item resource | List / Table / Bulk | Read-only Registry / Report Surface | Open the provider object behind the canonical type | Full-row open to detail | required | Existing safe links remain contextual | none | workspace-first inventory item list | workspace-first inventory item detail | workspace, managed environment, canonical type | Inventory item | canonical type and provider display type | none |
| Stored report resource | List / Table / Bulk | Read-only Registry / Report Surface | Open the report that explains the current posture | Full-row open to detail | required | Existing safe links remain contextual | none | workspace-first stored-report list | workspace-first stored-report detail | workspace, managed environment, freshness | Stored report | source family and report summary | none |
| Tenant review detail sections | Record / Detail / Edit | Detail-first Operational Surface | Open the related artifact or supporting evidence | Existing review detail section links | n/a | Contextual related links only | none | workspace-first tenant-review list | workspace-first tenant-review detail | workspace, managed environment, review status | Review section evidence | canonical artifact source and control summary | none |
Operator Surface Contract
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Findings resource | Tenant operator | Decide whether the finding needs action | Queue / Review Surface | What artifact triggered this finding and what control does it affect? | source family, governed subject, detector summary, control summary, severity, status | raw payloads, provider-native ids, legacy type names | lifecycle, severity, governance state | existing finding workflow only | existing inspect and remediation actions | existing closure or governance actions only |
| Evidence snapshot resource | Tenant operator | Inspect which artifacts prove the current evidence state | Read-only Registry / Report Surface | Which artifact family produced this evidence and what control does it support? | source descriptor, control summary, freshness, completeness | raw payloads, source record references | evidence completeness, freshness | read-only | existing inspect links | none |
| Inventory item resource | Tenant operator | Inspect inventory classification and provider provenance | Read-only Registry / Report Surface | What canonical thing is this item, and what provider object produced it? | canonical type, provider display type, platform, timestamps | raw provider object type, legacy metadata | freshness, sync recency | read-only | existing inspect links | none |
| Stored report resource | Tenant operator | Inspect a report backing another summary | Read-only Registry / Report Surface | What report family is this and what artifact lineage does it represent? | source family, freshness, summary headline | raw payload, fingerprints, provider report type | freshness, availability | read-only | existing inspect links | none |
| Tenant review detail sections | Tenant operator | Inspect supporting artifact context behind the review | Detail-first Operational Surface | Which artifact family and control summary justify this review section? | canonical artifact summary and control summary | raw evidence bundles, provider-native ids | review lifecycle, evidence completeness | existing review workflow only | existing inspect links | none |
Proportionality Review
- New source of truth?: no new persisted source of truth; one derived shared contract over existing artifact truth
- New persisted entity/table/artifact?: no
- New abstraction?: yes
- New enum/state/reason family?: yes
- New cross-domain UI framework/taxonomy?: yes, but only as a bounded artifact-source and inventory-type taxonomy tied to current-release artifact seams
- Current operator problem: the same artifact lineage is currently described with Microsoft-specific nouns in one surface and platform-adjacent summaries in another, which makes evidence, reports, findings, inventory, and reviews harder to interpret safely
- Existing structure is insufficient because: current helpers already normalize vocabulary, control bindings, or display order in isolation, but no shared contract pins what an artifact source is across findings, evidence, reports, and inventory metadata
- Narrowest correct implementation: add one descriptor contract, one inventory type split, and the smallest normalizer or presenter seam necessary to derive them from existing records, current payloads, and presenters
- Ownership cost: additive migrations or payload shape updates, translator or presenter upkeep, legacy-row interpretation rules, and focused proof for both read models and touched Filament surfaces
- Alternative intentionally rejected: page-local aliasing or report-local mapping was rejected because it would keep artifact meaning inconsistent; a larger detector catalog or provider framework was rejected because it is future-facing and not required for current repo truth
- Release truth: current-release provider-neutral artifact interpretation over existing Microsoft-first artifacts, not a speculative package engine or cross-provider platform rewrite
Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, legacy aliases, migration shims, historical fixtures, and compatibility-specific tests are out of scope unless explicitly required by this spec.
Canonical replacement is preferred over preservation, except where existing Microsoft-produced artifacts must remain readable as provider-owned historical detail.
Testing / Lane / Runtime Impact
- Test purpose / classification: Unit, Feature, Browser
- Validation lane(s): fast-feedback, confidence, browser
- Why this classification and these lanes are sufficient: the pinned taxonomy inventory and descriptor normalizer are pure derivation and need unit proof; findings, evidence snapshots, stored reports, inventory metadata, and touched presenters need feature proof; one browser smoke is enough to prove the operator sees the new descriptor-first disclosure under the live Filament shell
- New or expanded test families: focused artifact-source unit tests, artifact-contract feature tests, one guard test, and one browser smoke
- Fixture / helper cost impact: moderate because proof needs workspace, managed environment, findings, reports, evidence snapshots, and inventory fixtures without widening shared defaults
- Heavy-family visibility / justification: none beyond one narrow browser smoke for touched operator-facing read paths
- Special surface test profile: standard-native-filament, shared-detail-family
- Standard-native relief or required special coverage: most surfaces need ordinary feature coverage; the read-only review section and evidence summary contract need shared-detail-family assertions to keep disclosure ordering stable
- Reviewer handoff: verify the exact pinned inventories across artifacts, confirm touched surfaces show canonical descriptor first and provider detail second, confirm no new table or backfill appears, and rely on the proof commands below rather than broad suite guesses
- Budget / baseline / trend impact: contained feature-local increase only
- Escalation needed:
reject-or-splitif implementation adds a detector catalog, package runtime, provider framework, historical backfill, or adjacent copy or RBAC scope - Active feature PR close-out entry: Guardrail
- Planned validation commands:
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/Artifacts/ArtifactSourceTaxonomyCatalogTest.php tests/Unit/Inventory/InventoryCanonicalTypeDescriptorTest.php)export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/Artifacts/FindingArtifactSourceTaxonomyTest.php tests/Feature/Artifacts/EvidenceSnapshotSourceTaxonomyTest.php tests/Feature/Artifacts/StoredReportSourceTaxonomyTest.php tests/Feature/Artifacts/InventoryArtifactTypeTaxonomyTest.php tests/Feature/Filament/Artifacts/ArtifactSourceTaxonomySurfaceTest.php tests/Feature/Guards/ArtifactSourceProviderTruthGuardTest.php)export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec284ArtifactSourceTaxonomySmokeTest.php)export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent)
User Scenarios & Testing
User Story 1 - Interpret findings, evidence, and reports with one source descriptor (Priority: P1)
As an operator, I want findings, evidence snapshots, and stored reports to expose the same artifact source summary so I can understand what produced the current signal without decoding Microsoft-only type names first.
Why this priority: this is the core reason for 284. If findings, evidence, and reports still describe the same lineage differently, the taxonomy does not solve the real product problem.
Independent Test: create or load one finding, one evidence snapshot, and one stored report for the same managed environment and confirm they each expose the canonical source family, target, detector summary, and control summary before any provider-native detail.
Acceptance Scenarios:
- Given a drift finding still carries
policy_typeinevidence_jsonb, When the operator opens the finding or evidence summary, Then the surface shows the canonical source descriptor first and keeps the Microsoft policy type as provider detail. - Given a stored permission-posture or Entra-admin-roles report exists, When the operator opens the report, Then the surface shows the shared source family and report meaning first and nests the raw
report_typeand provider payload below that summary.
User Story 2 - Read inventory items without treating policy_type as universal platform truth (Priority: P1)
As an operator, I want inventory items to distinguish the platform's canonical type from the provider's object type and display type so I can inspect inventory without assuming Microsoft naming is the only valid domain model.
Why this priority: the candidate explicitly calls out inventory metadata. If inventory keeps using policy_type as top-level truth, later package-output and reporting work will keep inheriting that false universal.
Independent Test: open one inventory item with an existing Microsoft-backed policy type and confirm the page exposes canonical_type, provider_object_type, and provider_display_type as separate concepts.
Acceptance Scenarios:
- Given an inventory item was captured from a Microsoft object type such as
deviceCompliancePolicy, When the operator opens the item, Then the page shows the canonical platform type separately from the raw provider object type. - Given the inventory item has a user-facing label, When the operator scans the list or detail view, Then the provider display type is readable without replacing the canonical type as the platform's primary metadata.
User Story 3 - Keep evidence, reviews, and reporting surfaces descriptor-first (Priority: P2)
As an operator, I want evidence, review, and reporting surfaces to disclose canonical artifact source summaries first and provider detail second so review decisions stay readable and diagnostic depth remains available.
Why this priority: changing the underlying model without changing the first-decision summary would still leave the UI teaching the old artifact truth.
Independent Test: open the evidence snapshot resource, a tenant review with supporting sections, and a stored report, then confirm each touched summary leads with the same canonical descriptor fields and keeps raw provider detail in secondary disclosure.
Acceptance Scenarios:
- Given a tenant review section summarizes evidence from findings and reports, When the operator opens the review detail, Then the section shows the same source family and control summary used by the underlying artifacts instead of inventing a third summary label.
- Given an evidence snapshot item or stored report has raw provider payload available, When the operator opens the detail page, Then canonical descriptor fields stay in the summary region and raw provider payload remains diagnostics-only.
User Story 4 - Reuse source-family semantics in downstream shared consumers without adding package runtime (Priority: P3)
As a maintainer, I want touched support or AI source-family consumers and future package-output work to reuse the same source-family semantics so later packaging or summarization features do not need a second artifact taxonomy.
Why this priority: later package-output work is explicitly an acceptance target for 284, but 284 itself must stop before inventing package runtime.
Independent Test: inspect the shared descriptor contract, touched support or AI source-family consumers, and the logical contract package slot, then confirm they use the same source-family nouns and leave package_run_id optional and unused in the current release.
Acceptance Scenarios:
- Given a touched support or AI summary declares a
source_family, When it references artifact-source semantics after284, Then it uses the same source-family vocabulary as the new artifact descriptor. - Given the
ArtifactSourceDescriptorincludes optionalpackage_run_id, When current-release artifacts are rendered, Then the field stays null or absent and does not imply that package runtime already exists.
Edge Cases
- A historical finding has
source = nulland onlyfinding_typeplusevidence_jsonbfrom an older write path. - A drift finding still carries only Microsoft
policy_typeor raw detector detail, but the canonical type mapping is missing or incomplete. - A stored report already has
provider_key = microsoftin payload whilereport_typeremains a Microsoft-shaped top-level discriminator. - An evidence source summary aggregates many records and therefore has no single
source_record_id, so the shared descriptor must still point to the rightsource_target_kindand optional identifier. - An inventory item has no friendly provider display label, so the canonical type and provider object type must still remain distinct without inventing fake display copy.
provider_connection_idis not available for a historical artifact even though the provider key and managed environment are known.- A touched support or AI consumer already uses
source_familysemantics that would conflict with the new artifact family names if left unchanged.
Requirements
Constitution alignment (required): This slice changes artifact typing, artifact-source derivation, read-only summary disclosure, and canonical-control binding inputs across findings, evidence, stored reports, inventory, and review summaries. It does not introduce a new Graph contract path, a new long-running workflow, or a new persisted artifact ledger.
Constitution alignment (PROP-001 / ABSTR-001 / PROV-001 / BLOAT-001): One shared descriptor and one inventory type split are justified because the repo already has multiple live artifact families and conflicting interpretations of the same Microsoft-produced truth. No provider framework, no detector registry, no control-catalog expansion, and no new table are in scope.
Constitution alignment (XCUT-001 / UI-FIL-001 / DECIDE-001): The feature must reuse the existing findings, evidence, stored-report, inventory, and tenant-review surfaces. It may refine their summary ordering and view models, but it must not create a new dashboard, a second evidence viewer, or local semantic color or status systems.
Constitution alignment (RBAC-UX): Workspace and managed-environment boundaries remain unchanged. Existing view capabilities remain authoritative, and provider-neutral artifact typing must not widen who can see findings, evidence, reports, inventory, or reviews.
Constitution alignment (TEST-GOV-001): Proof stays bounded to focused unit, feature, guard, and one narrow browser smoke. The descriptor inventory, descriptor fields, and proof commands must stay pinned identically across the package.
Functional Requirements
- FR-001: The system MUST introduce one shared artifact-source descriptor for findings, evidence snapshots, stored reports, inventory metadata, and touched review or summary consumers.
- FR-002: The shared artifact-source descriptor MUST standardize these fields:
workspace_id,tenant_id,managed_environment_id,source_family,source_kind,provider_key,provider_connection_id,source_target_kind,source_target_identifier,detector_key,control_key, and optionalpackage_run_id. - FR-003: The initial
source_familyinventory for284v1 MUST be exactlyfinding,stored_report,evidence_snapshot,inventory, andoperation_run. - FR-004: The initial
source_kindinventory for284v1 MUST be exactlymodel_summary,stored_report,operation_rollup, andinventory_projection. - FR-005: The initial
source_target_kindinventory for284v1 MUST be exactlymanaged_environment,governed_subject,provider_connection, andoperation_run. - FR-006:
284v1 MUST NOT introduce a global detector catalog or a broader control-catalog expansion;detector_keyremains a standardized field and naming rule, not a new registry of every detector in the platform. - FR-007: Findings MUST derive the shared descriptor from existing
finding_type,source, andevidence_jsonbfields without requiring historical backfill. - FR-008:
EvidenceSourceProviderandEvidenceSnapshotServiceMUST carry or derive the shared descriptor consistently soEvidenceSnapshotItemdoes not rely onsource_record_typealone as its top-level artifact identity. - FR-009: Stored reports MUST align
report_typewith shared source-family semantics while keepingreport_typeitself as provider-owned detail where needed. - FR-010: Inventory metadata MUST expose
canonical_type,provider_object_type, andprovider_display_typeas separate concepts and MUST stop treating rawpolicy_typeas the only platform-wide artifact type. - FR-011: Touched canonical-control consumers MUST resolve or disclose
control_keythrough the shared descriptor path instead of rebuilding platform truth from page-local Microsoft type checks. - FR-012: Touched findings, evidence, stored-report, and tenant-review presenters MUST show canonical descriptor fields and
control_keybefore provider-native detail. Inventory presenters MUST show the shared source descriptor and the canonical/provider type split before raw provider metadata. - FR-013: Existing Microsoft artifacts MUST remain valid and interpretable as
provider_key = microsoftsources after284lands. - FR-014:
284MUST NOT require historical backfill; legacy rows may be normalized on read or through additive future writes only. - FR-015:
package_run_idMAY exist as a nullable field in the shared descriptor contract, but284MUST NOT create package runtime, package-run persistence, or package-output surfaces. - FR-016: Touched support or AI source-family consumers MUST use the same source-family nouns as the shared descriptor if they are updated in this slice.
- FR-017: The implementation MUST NOT introduce a new artifact table, provider framework, compliance engine, detector registry, full control-catalog expansion, RBAC rewrite, copy-neutralization pass, or no-legacy enforcement pack.
- FR-018: The descriptor inventory and source-type split MUST stay pinned identically across
spec.md,plan.md,research.md,data-model.md,quickstart.md,tasks.md, the logical contract, and the readiness checklist. The canonical proof commands MUST stay pinned identically acrossspec.md,plan.md,quickstart.md,tasks.md, and the readiness checklist. - FR-019: Before runtime implementation begins, SCOPE-001 ownership compliance for touched tenant-owned artifact tables MUST be satisfied or explicitly excepted;
284MUST NOT silently waive that prerequisite.
Authorization and Safety Requirements
- AR-001: Workspace membership MUST remain the first access boundary for touched findings, evidence, reports, inventory, and review surfaces.
- AR-002: Managed-environment entitlement MUST remain the second access boundary for those surfaces.
- AR-003: Non-members or cross-workspace or cross-environment access attempts MUST continue to resolve as
404, while in-scope actors missing resource capabilities still resolve as403. - AR-004:
284introduces no new destructive action. Any touched destructive or high-impact action on findings or adjacent resources MUST remain confirmation-protected and server-authorized under the current action contract. - AR-005: Navigation-only related links on touched read-only artifact surfaces MUST remain clearly navigation-only and must not be re-expressed as mutations during this slice.
- AR-006: Provider-neutral artifact typing MUST NOT bypass or weaken the current resource policies and capability checks.
Non-Functional Requirements
- NFR-001: Filament remains v5 on Livewire v4.
- NFR-002: Provider registration remains in
apps/platform/bootstrap/providers.php; nothing moves tobootstrap/app.php. - NFR-003: Asset strategy remains unchanged. No new panel or shared asset registration is expected from
284. - NFR-004:
FindingResourceandInventoryItemResourcekeep validViewpages for any existing or future global-search posture.EvidenceSnapshotResource,StoredReportResource, andTenantReviewResourceremain non-globally-searchable while keepingViewpages. - NFR-005: The feature must remain reviewable as one bounded artifact-source slice and MUST NOT silently absorb work reserved for Specs
285through287. - NFR-006: Default-visible summary fields on touched operator-facing surfaces must stay Filament-native and avoid page-local card, badge, or semantic color systems.
UI Action Matrix
| Surface | Location | Header Actions | Inspect Affordance (List or Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create or Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Findings resource | FindingResource |
preserve existing header actions | clickable row to View | preserve existing contextual actions and grouping | preserve existing grouped bulk actions only | preserve current empty-state behavior | preserve existing detail-header actions | preserve existing edit or workflow forms where applicable | preserve current mutation audit behavior | 284 changes descriptor and summary semantics only |
| Evidence snapshot resource | EvidenceSnapshotResource |
preserve existing read-only actions | clickable row to View | preserve current safe related links only | none | preserve current empty-state behavior | preserve existing read-only header actions | N/A |
no new audit surface | descriptor-first disclosure only |
| Inventory item resource | InventoryItemResource |
preserve current no-header-action posture | clickable row to View | preserve current row behavior | none | preserve current no-CTA posture | preserve existing read-only detail actions | N/A |
no new audit surface | inventory type split only |
| Stored report resource | StoredReportResource |
preserve existing read-only actions | clickable row to View | preserve current safe actions only | none | preserve current empty-state behavior | preserve existing read-only header actions | N/A |
no new audit surface | source-family and summary semantics only |
| Tenant review detail sections | TenantReviewResource and TenantReviewSectionFactory |
preserve existing header and section actions | existing section links remain inspect affordances | preserve current safe contextual links | none | N/A |
preserve existing review-header actions | preserve current review flows | preserve current review audit behavior | section summary ordering only |
All other touched support or AI consumers must keep their existing action contracts and only adopt the shared source-family vocabulary where 284 touches them.
Key Entities
- Artifact Source Descriptor: one shared contract describing source family, source kind, provider, source target, optional target identifier, detector key, control key, and optional package-run reference for an artifact or summary.
- Inventory Type Descriptor: the bounded inventory metadata split separating
canonical_type,provider_object_type, andprovider_display_typewhile preserving legacypolicy_typeas provider-owned detail. - Artifact Provider Detail: provider-owned raw fields such as
finding_type,report_type, provider object type, Graph-facing detector detail, or legacypolicy_typeretained as nested evidence rather than top-level platform truth. - Artifact Source View Model: the derived presenter contract used by findings, evidence, reports, inventory, and tenant-review sections to disclose canonical descriptor fields first and provider detail second.
Success Criteria
Measurable Outcomes
- SC-001: 100% of touched findings, evidence snapshots, stored reports, inventory items, and tenant-review artifact summaries expose the shared source descriptor before provider-native detail.
- SC-002: 100% of touched inventory item summaries expose
canonical_type,provider_object_type, andprovider_display_typeas separate fields. - SC-003: 100% of touched artifact summaries that already resolve a canonical control continue to expose
control_keyconsistently through the shared descriptor path. - SC-004: The implementation introduces no new artifact table, no historical backfill requirement, and no package runtime while keeping existing Microsoft-produced artifacts readable as Microsoft provider sources.