openapi: 3.1.0 info: title: BaselineSnapshot Artifact Truth Operator Contract version: 1.0.0 summary: Logical operator-action contract for baseline snapshot lifecycle and compare guards description: | This contract captures the intended request/response semantics for the operator-facing capture, compare, and snapshot-truth flows in Spec 159. These are logical contracts for existing Filament/Livewire-backed actions and read models, not a commitment to public REST endpoints. servers: - url: https://tenantpilot.local tags: - name: BaselineProfiles - name: BaselineSnapshots - name: BaselineCompare paths: /workspaces/{workspaceId}/baseline-profiles/{profileId}/captures: post: tags: [BaselineProfiles] summary: Start a baseline capture description: Starts a baseline capture attempt. The produced snapshot begins in `building` and becomes consumable only if finalized `complete`. parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/ProfileId' requestBody: required: true content: application/json: schema: type: object required: [sourceTenantId] properties: sourceTenantId: type: integer responses: '202': description: Capture accepted and queued content: application/json: schema: type: object required: [operationRunId, snapshot] properties: operationRunId: type: integer snapshot: $ref: '#/components/schemas/BaselineSnapshotTruth' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /workspaces/{workspaceId}/baseline-profiles/{profileId}/effective-snapshot: get: tags: [BaselineProfiles] summary: Resolve effective current baseline snapshot description: Returns the latest complete snapshot that is valid as current baseline truth for the profile. parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/ProfileId' responses: '200': description: Effective current baseline truth resolved content: application/json: schema: type: object required: [profileId, effectiveSnapshot] properties: profileId: type: integer effectiveSnapshot: oneOf: - $ref: '#/components/schemas/BaselineSnapshotTruth' - type: 'null' latestAttemptedSnapshot: oneOf: - $ref: '#/components/schemas/BaselineSnapshotTruth' - type: 'null' compareAvailability: $ref: '#/components/schemas/CompareAvailability' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /workspaces/{workspaceId}/baseline-snapshots/{snapshotId}: get: tags: [BaselineSnapshots] summary: Read baseline snapshot truth parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/SnapshotId' responses: '200': description: Snapshot truth returned content: application/json: schema: $ref: '#/components/schemas/BaselineSnapshotTruth' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' /tenants/{tenantId}/baseline-compares: post: tags: [BaselineCompare] summary: Start baseline compare description: Starts compare only when the resolved or explicitly selected snapshot is consumable. parameters: - $ref: '#/components/parameters/TenantId' requestBody: required: false content: application/json: schema: type: object properties: baselineSnapshotId: type: integer nullable: true responses: '202': description: Compare accepted and queued content: application/json: schema: type: object required: [operationRunId, snapshot] properties: operationRunId: type: integer snapshot: $ref: '#/components/schemas/BaselineSnapshotTruth' '409': description: Compare blocked because no consumable snapshot is available content: application/json: schema: $ref: '#/components/schemas/CompareAvailability' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' components: parameters: WorkspaceId: name: workspaceId in: path required: true schema: type: integer ProfileId: name: profileId in: path required: true schema: type: integer SnapshotId: name: snapshotId in: path required: true schema: type: integer TenantId: name: tenantId in: path required: true schema: type: integer responses: Forbidden: description: Member lacks the required capability NotFound: description: Workspace or tenant scope is not entitled, or the record is not visible in that scope schemas: BaselineSnapshotTruth: type: object required: - id - workspaceId - baselineProfileId - lifecycleState - consumable - capturedAt properties: id: type: integer workspaceId: type: integer baselineProfileId: type: integer lifecycleState: type: string enum: [building, complete, incomplete, superseded] consumable: type: boolean capturedAt: type: string format: date-time completedAt: type: string format: date-time nullable: true failedAt: type: string format: date-time nullable: true supersededAt: type: string format: date-time nullable: true completionMeta: type: object additionalProperties: true nullable: true usabilityLabel: type: string examples: [Complete, Incomplete, Building, Superseded, Not usable for compare] reasonCode: type: string nullable: true reasonMessage: type: string nullable: true CompareAvailability: type: object required: - allowed properties: allowed: type: boolean effectiveSnapshotId: type: integer nullable: true latestAttemptedSnapshotId: type: integer nullable: true reasonCode: type: string nullable: true enum: - no_consumable_snapshot - snapshot_building - snapshot_incomplete - snapshot_superseded - invalid_snapshot_selection reasonMessage: type: string nullable: true nextAction: type: string nullable: true examples: - Wait for capture completion - Re-run baseline capture - Review failed capture