442 lines
14 KiB
YAML
442 lines
14 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Baseline Compare Strategy Extraction Internal Contract
|
|
version: 0.1.0
|
|
summary: Internal logical contract for compare strategy selection, compare launch validation, and strategy-owned subject results
|
|
description: |
|
|
This contract is an internal planning artifact for Spec 203. The affected
|
|
compare surfaces still render through Filament and Livewire, and compare
|
|
execution continues to run through the existing Laravel services and jobs.
|
|
The paths below are logical boundary identifiers for existing service, job,
|
|
and surface entry points only; they do not imply new HTTP controllers or
|
|
routes.
|
|
x-logical-artifact: true
|
|
x-baseline-compare-strategy-consumers:
|
|
- surface: baseline.compare.start
|
|
sourceFiles:
|
|
- apps/platform/app/Services/Baselines/BaselineCompareService.php
|
|
mustConsume:
|
|
- canonical_scope_v2
|
|
- deterministic_strategy_selection
|
|
- unsupported_or_mixed_scope_rejection
|
|
- strategy_key_recorded_in_run_context
|
|
- surface: baseline.compare.fanout
|
|
sourceFiles:
|
|
- apps/platform/app/Services/Baselines/BaselineCompareService.php
|
|
- apps/platform/app/Filament/Pages/BaselineCompareMatrix.php
|
|
- apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
|
|
mustConsume:
|
|
- visible_set_strategy_validation
|
|
- single_strategy_per_run_rule
|
|
- tenant_owned_compare_runs_only
|
|
- surface: baseline.compare.execution
|
|
sourceFiles:
|
|
- apps/platform/app/Jobs/CompareBaselineToTenantJob.php
|
|
- apps/platform/app/Services/Baselines/CurrentStateHashResolver.php
|
|
- apps/platform/app/Services/Drift/DriftHasher.php
|
|
mustConsume:
|
|
- compare_orchestration_context
|
|
- compare_subject_result
|
|
- strategy_provided_subject_projection
|
|
- surface: baseline.compare.review
|
|
sourceFiles:
|
|
- apps/platform/app/Filament/Pages/BaselineCompareLanding.php
|
|
- apps/platform/app/Support/Baselines/BaselineCompareSummaryAssessor.php
|
|
- apps/platform/app/Support/Baselines/BaselineCompareExplanationRegistry.php
|
|
mustRender:
|
|
- unsupported_scope_truth
|
|
- incomplete_or_ambiguous_truth
|
|
- failed_strategy_truth
|
|
paths:
|
|
/internal/tenants/{tenant}/baseline-profiles/{profile}/compare/validate:
|
|
post:
|
|
summary: Resolve one compatible compare strategy family before compare is enqueued
|
|
operationId: validateBaselineCompareStrategySelection
|
|
parameters:
|
|
- name: tenant
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
- name: profile
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareValidationRequest'
|
|
responses:
|
|
'200':
|
|
description: One compatible strategy family was selected for the requested compare scope
|
|
content:
|
|
application/vnd.tenantpilot.baseline-compare-strategy-selection+json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareStrategySelection'
|
|
'422':
|
|
description: Scope is unsupported or requires more than one strategy family
|
|
content:
|
|
application/vnd.tenantpilot.baseline-compare-strategy-errors+json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareStrategySelection'
|
|
'403':
|
|
description: Actor is in scope but lacks capability to start compare
|
|
'404':
|
|
description: Tenant or baseline profile is outside actor scope
|
|
/internal/tenants/{tenant}/baseline-profiles/{profile}/compare:
|
|
post:
|
|
summary: Start baseline compare using one selected strategy family
|
|
operationId: startBaselineCompareWithStrategySelection
|
|
parameters:
|
|
- name: tenant
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
- name: profile
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareValidationRequest'
|
|
responses:
|
|
'202':
|
|
description: Compare accepted with a deterministic strategy family recorded in the existing run context
|
|
content:
|
|
application/vnd.tenantpilot.baseline-compare-run+json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareLaunchEnvelope'
|
|
'422':
|
|
description: Scope is unsupported or mixed and compare was not started
|
|
'403':
|
|
description: Actor is in scope but lacks capability to start compare
|
|
'404':
|
|
description: Tenant or baseline profile is outside actor scope
|
|
/internal/workspaces/{workspace}/baseline-profiles/{profile}/compare-visible-assignments:
|
|
post:
|
|
summary: Start compare for the visible assigned tenant set only when one strategy family supports the shared scope
|
|
operationId: startVisibleAssignmentCompareWithStrategySelection
|
|
parameters:
|
|
- name: workspace
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
- name: profile
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/VisibleAssignmentCompareRequest'
|
|
responses:
|
|
'202':
|
|
description: Visible tenant compare fan-out accepted with the same selected strategy family for each tenant-owned run
|
|
content:
|
|
application/vnd.tenantpilot.baseline-compare-fanout+json:
|
|
schema:
|
|
$ref: '#/components/schemas/VisibleAssignmentCompareEnvelope'
|
|
'422':
|
|
description: Visible set scope is unsupported or mixed and no tenant compare runs were started
|
|
'403':
|
|
description: Actor is in scope but lacks workspace baseline manage capability
|
|
'404':
|
|
description: Workspace or baseline profile is outside actor scope
|
|
/internal/baseline-compare/subjects/classify:
|
|
post:
|
|
summary: Logical strategy-owned boundary for classifying one compare subject inside the compare job
|
|
operationId: classifyCompareSubject
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareSubjectInput'
|
|
responses:
|
|
'200':
|
|
description: Structured compare-subject result consumable by platform orchestration
|
|
content:
|
|
application/vnd.tenantpilot.compare-subject-result+json:
|
|
schema:
|
|
$ref: '#/components/schemas/CompareSubjectResult'
|
|
components:
|
|
schemas:
|
|
CompareStrategyKey:
|
|
type: string
|
|
examples:
|
|
- intune_policy
|
|
- entra_configuration
|
|
StrategySelectionState:
|
|
type: string
|
|
enum:
|
|
- supported
|
|
- unsupported
|
|
- mixed
|
|
ScopeEntryReference:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- domain_key
|
|
- subject_class
|
|
- subject_type_keys
|
|
properties:
|
|
domain_key:
|
|
type: string
|
|
subject_class:
|
|
type: string
|
|
subject_type_keys:
|
|
type: array
|
|
items:
|
|
type: string
|
|
CompareStrategyCapability:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- strategy_key
|
|
- domain_keys
|
|
- subject_classes
|
|
- compare_supported
|
|
- active
|
|
properties:
|
|
strategy_key:
|
|
$ref: '#/components/schemas/CompareStrategyKey'
|
|
domain_keys:
|
|
type: array
|
|
items:
|
|
type: string
|
|
subject_classes:
|
|
type: array
|
|
items:
|
|
type: string
|
|
subject_type_keys:
|
|
oneOf:
|
|
- type: string
|
|
enum:
|
|
- all
|
|
- type: array
|
|
items:
|
|
type: string
|
|
compare_supported:
|
|
type: boolean
|
|
active:
|
|
type: boolean
|
|
CompareStrategySelection:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- selection_state
|
|
- matched_scope_entries
|
|
- rejected_scope_entries
|
|
- operator_reason
|
|
- diagnostics
|
|
properties:
|
|
selection_state:
|
|
$ref: '#/components/schemas/StrategySelectionState'
|
|
strategy_key:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/CompareStrategyKey'
|
|
- type: 'null'
|
|
matched_scope_entries:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ScopeEntryReference'
|
|
rejected_scope_entries:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ScopeEntryReference'
|
|
operator_reason:
|
|
type: string
|
|
diagnostics:
|
|
type: object
|
|
additionalProperties: true
|
|
CompareValidationRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- baseline_profile_id
|
|
- normalized_scope
|
|
properties:
|
|
baseline_profile_id:
|
|
type: integer
|
|
baseline_snapshot_id:
|
|
type:
|
|
- integer
|
|
- 'null'
|
|
normalized_scope:
|
|
type: object
|
|
additionalProperties: true
|
|
CompareLaunchEnvelope:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- operation_run_id
|
|
- strategy_selection
|
|
properties:
|
|
operation_run_id:
|
|
type: integer
|
|
strategy_selection:
|
|
$ref: '#/components/schemas/CompareStrategySelection'
|
|
VisibleAssignmentCompareRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- baseline_profile_id
|
|
- normalized_scope
|
|
- visible_tenant_ids
|
|
properties:
|
|
baseline_profile_id:
|
|
type: integer
|
|
normalized_scope:
|
|
type: object
|
|
additionalProperties: true
|
|
visible_tenant_ids:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
VisibleAssignmentCompareEnvelope:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- strategy_selection
|
|
- started_runs
|
|
- skipped_tenants
|
|
properties:
|
|
strategy_selection:
|
|
$ref: '#/components/schemas/CompareStrategySelection'
|
|
started_runs:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
skipped_tenants:
|
|
type: array
|
|
items:
|
|
type: integer
|
|
CompareSubjectInput:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- strategy_key
|
|
- subject_identity
|
|
- baseline_state
|
|
- current_state
|
|
properties:
|
|
strategy_key:
|
|
$ref: '#/components/schemas/CompareStrategyKey'
|
|
subject_identity:
|
|
type: object
|
|
additionalProperties: true
|
|
baseline_state:
|
|
type: object
|
|
additionalProperties: true
|
|
current_state:
|
|
oneOf:
|
|
- type: object
|
|
additionalProperties: true
|
|
- type: 'null'
|
|
CompareSubjectState:
|
|
type: string
|
|
enum:
|
|
- no_drift
|
|
- drift
|
|
- unsupported
|
|
- incomplete
|
|
- ambiguous
|
|
- failed
|
|
CompareSubjectProjection:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- platform_subject_class
|
|
- domain_key
|
|
- subject_type_key
|
|
- operator_label
|
|
properties:
|
|
platform_subject_class:
|
|
type: string
|
|
domain_key:
|
|
type: string
|
|
subject_type_key:
|
|
type: string
|
|
operator_label:
|
|
type: string
|
|
summary_kind:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
additional_labels:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
CompareFindingCandidate:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- change_type
|
|
- severity
|
|
- fingerprint_basis
|
|
- evidence_payload
|
|
- auto_close_eligible
|
|
properties:
|
|
change_type:
|
|
type: string
|
|
severity:
|
|
type: string
|
|
fingerprint_basis:
|
|
type: object
|
|
additionalProperties: true
|
|
evidence_payload:
|
|
type: object
|
|
additionalProperties: true
|
|
auto_close_eligible:
|
|
type: boolean
|
|
CompareSubjectResult:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- subject_identity
|
|
- projection
|
|
- baseline_availability
|
|
- current_state_availability
|
|
- compare_state
|
|
- trust_level
|
|
- evidence_quality
|
|
- diagnostics
|
|
properties:
|
|
subject_identity:
|
|
type: object
|
|
additionalProperties: true
|
|
projection:
|
|
$ref: '#/components/schemas/CompareSubjectProjection'
|
|
baseline_availability:
|
|
type: string
|
|
current_state_availability:
|
|
type: string
|
|
compare_state:
|
|
$ref: '#/components/schemas/CompareSubjectState'
|
|
trust_level:
|
|
type: string
|
|
evidence_quality:
|
|
type: string
|
|
severity_recommendation:
|
|
type:
|
|
- string
|
|
- 'null'
|
|
finding_candidate:
|
|
oneOf:
|
|
- $ref: '#/components/schemas/CompareFindingCandidate'
|
|
- type: 'null'
|
|
diagnostics:
|
|
type: object
|
|
additionalProperties: true |