TenantAtlas/specs/163-baseline-subject-resolution/contracts/openapi.yaml
ahmido c17255f854 feat: implement baseline subject resolution semantics (#193)
## Summary
- add the structured subject-resolution foundation for baseline compare and baseline capture, including capability guards, subject descriptors, resolution outcomes, and operator action categories
- persist structured evidence-gap subject records and update compare/capture surfaces, landing projections, and cleanup tooling to use the new contract
- add Spec 163 artifacts and focused Pest coverage for classification, determinism, cleanup, and DB-only rendering

## Validation
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Unit/Support/Baselines tests/Feature/Baselines tests/Feature/Filament/OperationRunEnterpriseDetailPageTest.php`

## Notes
- verified locally that a fresh post-restart baseline compare run now writes structured `baseline_compare.evidence_gaps.subjects` records instead of the legacy broad payload shape
- excluded the separate `docs/product/spec-candidates.md` worktree change from this branch commit and PR

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #193
2026-03-25 12:40:45 +00:00

335 lines
8.7 KiB
YAML

openapi: 3.1.0
info:
title: Baseline Subject Resolution Semantics Contract
version: 0.1.0
description: >-
Read-model and validation contracts for baseline compare and capture subject-resolution
semantics. This contract documents the payloads existing operator surfaces consume after
the foundation upgrade and the capability matrix used to keep baseline support truthful
at runtime.
servers:
- url: https://tenantpilot.local
paths:
/admin/api/operations/{operationRun}/baseline-gap-semantics:
get:
summary: Get structured baseline gap semantics for an operation run
operationId: getBaselineGapSemanticsForRun
parameters:
- name: operationRun
in: path
required: true
schema:
type: integer
responses:
'200':
description: Structured baseline gap semantics for the run
content:
application/json:
schema:
$ref: '#/components/schemas/BaselineGapSemanticsResponse'
'404':
description: Run not found or not visible in current workspace or tenant scope
'403':
description: Caller is a member but lacks permission to inspect the run
/admin/api/tenants/{tenant}/baseline-compare/latest-gap-semantics:
get:
summary: Get latest baseline compare gap semantics for a tenant and profile
operationId: getLatestTenantBaselineCompareGapSemantics
parameters:
- name: tenant
in: path
required: true
schema:
type: integer
- name: baseline_profile_id
in: query
required: true
schema:
type: integer
responses:
'200':
description: Latest tenant baseline compare semantics projection
content:
application/json:
schema:
$ref: '#/components/schemas/BaselineGapSemanticsResponse'
'404':
description: Tenant or run not found for current entitled scope
'403':
description: Caller lacks compare or review visibility within the established tenant scope
/admin/api/baseline-support/resolution-capabilities:
get:
summary: Get runtime baseline support and resolution capability matrix
operationId: getBaselineResolutionCapabilities
responses:
'200':
description: Capability matrix used to validate truthful compare and capture support
content:
application/json:
schema:
type: object
required:
- data
properties:
data:
type: array
items:
$ref: '#/components/schemas/SupportCapabilityRecord'
components:
schemas:
BaselineGapSemanticsResponse:
type: object
required:
- summary
- buckets
properties:
summary:
$ref: '#/components/schemas/BaselineGapSummary'
buckets:
type: array
items:
$ref: '#/components/schemas/BaselineGapBucket'
BaselineGapSummary:
type: object
required:
- count
- by_reason
- detail_state
- recorded_subjects_total
- missing_detail_count
- structural_count
- operational_count
- transient_count
- legacy_mode
- requires_regeneration
properties:
count:
type: integer
minimum: 0
by_reason:
type: object
additionalProperties:
type: integer
minimum: 0
detail_state:
type: string
enum:
- no_gaps
- structured_details_recorded
- details_not_recorded
- legacy_broad_reason
recorded_subjects_total:
type: integer
minimum: 0
missing_detail_count:
type: integer
minimum: 0
structural_count:
type: integer
minimum: 0
operational_count:
type: integer
minimum: 0
transient_count:
type: integer
minimum: 0
legacy_mode:
type: boolean
requires_regeneration:
type: boolean
BaselineGapBucket:
type: object
required:
- reason_code
- reason_label
- count
- recorded_count
- missing_detail_count
- structural_count
- operational_count
- transient_count
- detail_state
- search_text
- rows
properties:
reason_code:
type: string
reason_label:
type: string
count:
type: integer
minimum: 0
recorded_count:
type: integer
minimum: 0
missing_detail_count:
type: integer
minimum: 0
structural_count:
type: integer
minimum: 0
operational_count:
type: integer
minimum: 0
transient_count:
type: integer
minimum: 0
detail_state:
type: string
enum:
- structured_details_recorded
- details_not_recorded
- legacy_broad_reason
search_text:
type: string
rows:
type: array
items:
$ref: '#/components/schemas/EvidenceGapDetailRecord'
EvidenceGapDetailRecord:
type: object
required:
- policy_type
- subject_key
- subject_class
- resolution_path
- resolution_outcome
- reason_code
- operator_action_category
- structural
- retryable
properties:
policy_type:
type: string
subject_external_id:
type:
- string
- 'null'
subject_key:
type: string
subject_class:
$ref: '#/components/schemas/SubjectClass'
resolution_path:
$ref: '#/components/schemas/ResolutionPath'
resolution_outcome:
$ref: '#/components/schemas/ResolutionOutcome'
reason_code:
type: string
operator_action_category:
$ref: '#/components/schemas/OperatorActionCategory'
structural:
type: boolean
retryable:
type: boolean
source_model_expected:
type:
- string
- 'null'
enum:
- policy
- inventory
- derived
- 'null'
source_model_found:
type:
- string
- 'null'
enum:
- policy
- inventory
- derived
- 'null'
legacy_reason_code:
type:
- string
- 'null'
SupportCapabilityRecord:
type: object
required:
- policy_type
- subject_class
- compare_capability
- capture_capability
- resolution_path
- config_supported
- runtime_valid
properties:
policy_type:
type: string
subject_class:
$ref: '#/components/schemas/SubjectClass'
compare_capability:
type: string
enum:
- supported
- limited
- unsupported
capture_capability:
type: string
enum:
- supported
- limited
- unsupported
resolution_path:
$ref: '#/components/schemas/ResolutionPath'
config_supported:
type: boolean
runtime_valid:
type: boolean
SubjectClass:
type: string
enum:
- policy_backed
- inventory_backed
- foundation_backed
- derived
ResolutionPath:
type: string
enum:
- policy
- inventory
- foundation_policy
- foundation_inventory
- derived
- unsupported
ResolutionOutcome:
type: string
enum:
- resolved_policy
- resolved_inventory
- policy_record_missing
- inventory_record_missing
- foundation_inventory_only
- resolution_type_mismatch
- unresolvable_subject
- permission_or_scope_blocked
- retryable_capture_failure
- capture_failed
- throttled
- budget_exhausted
- ambiguous_match
- invalid_subject
- duplicate_subject
- invalid_support_config
OperatorActionCategory:
type: string
enum:
- none
- retry
- run_inventory_sync
- run_policy_sync_or_backup
- review_permissions
- inspect_subject_mapping
- product_follow_up