667 lines
18 KiB
YAML
667 lines
18 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Heavy Suite Segmentation Logical Contract
|
|
version: 1.0.0
|
|
summary: Logical contract for classifying heavy UI test families, validating lane placement, and reading heavy-attribution reports.
|
|
description: |
|
|
This is a logical contract for repository tooling, tests, and planning artifacts.
|
|
It does not imply a new runtime HTTP service. It documents the expected
|
|
semantics of heavy-family classification, lane-placement validation, and
|
|
heavy-lane report attribution so the existing lane-governance seams remain
|
|
consistent as Spec 208 is implemented.
|
|
x-logical-contract: true
|
|
servers:
|
|
- url: https://tenantatlas.local/logical
|
|
paths:
|
|
/heavy-test-classifications:
|
|
get:
|
|
summary: Read the checked-in heavy classification catalog.
|
|
operationId: listHeavyTestClassifications
|
|
responses:
|
|
'200':
|
|
description: Current heavy classification catalog.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- classifications
|
|
properties:
|
|
classifications:
|
|
type: array
|
|
minItems: 5
|
|
items:
|
|
$ref: '#/components/schemas/HeavyTestClassification'
|
|
/heavy-test-placement-rules:
|
|
get:
|
|
summary: Read the checked-in lane placement rules.
|
|
operationId: listHeavyTestPlacementRules
|
|
responses:
|
|
'200':
|
|
description: Current lane placement rules.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- rules
|
|
properties:
|
|
rules:
|
|
type: array
|
|
minItems: 5
|
|
items:
|
|
$ref: '#/components/schemas/LanePlacementRule'
|
|
/heavy-test-families:
|
|
get:
|
|
summary: Read the seeded heavy test family inventory.
|
|
operationId: listHeavyTestFamilies
|
|
responses:
|
|
'200':
|
|
description: Current heavy family inventory.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- families
|
|
properties:
|
|
families:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: '#/components/schemas/HeavyTestFamily'
|
|
/heavy-test-families/mixed-file-resolutions:
|
|
get:
|
|
summary: Read the checked-in mixed-file resolution inventory.
|
|
operationId: listMixedFileResolutions
|
|
responses:
|
|
'200':
|
|
description: Current mixed-file resolution records.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- resolutions
|
|
properties:
|
|
resolutions:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/MixedFileResolution'
|
|
/heavy-test-families/placement-validations:
|
|
post:
|
|
summary: Validate that a heavy class or family is assigned to a compatible lane.
|
|
operationId: validateHeavyFamilyPlacement
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LanePlacementValidationRequest'
|
|
responses:
|
|
'200':
|
|
description: Placement validation result.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LanePlacementValidationResult'
|
|
/test-lanes/{laneId}/reports/heavy-attribution/latest:
|
|
get:
|
|
summary: Read the latest heavy-attribution report for a lane.
|
|
operationId: getLatestHeavyAttributionReport
|
|
parameters:
|
|
- name: laneId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
$ref: '#/components/schemas/LaneId'
|
|
responses:
|
|
'200':
|
|
description: Latest heavy-attribution report for the requested lane.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/HeavyAttributionReport'
|
|
components:
|
|
schemas:
|
|
ClassificationId:
|
|
type: string
|
|
enum:
|
|
- ui-light
|
|
- ui-workflow
|
|
- surface-guard
|
|
- discovery-heavy
|
|
- browser
|
|
LaneId:
|
|
type: string
|
|
enum:
|
|
- fast-feedback
|
|
- confidence
|
|
- heavy-governance
|
|
- browser
|
|
- profiling
|
|
- junit
|
|
PlacementAllowance:
|
|
type: string
|
|
enum:
|
|
- required
|
|
- allowed
|
|
- discouraged
|
|
- forbidden
|
|
ValidationStatus:
|
|
type: string
|
|
enum:
|
|
- seeded
|
|
- reviewed
|
|
- migrated
|
|
- guarded
|
|
BudgetStatus:
|
|
type: string
|
|
enum:
|
|
- within-budget
|
|
- warning
|
|
- over-budget
|
|
BudgetBaselineSource:
|
|
type: string
|
|
enum:
|
|
- measured-current-suite
|
|
- measured-lane
|
|
- measured-post-spec-207
|
|
BudgetEnforcement:
|
|
type: string
|
|
enum:
|
|
- report-only
|
|
- warn
|
|
- hard-fail
|
|
BudgetLifecycleState:
|
|
type: string
|
|
enum:
|
|
- draft
|
|
- measured
|
|
- documented
|
|
- enforced
|
|
HeavyFamilySelector:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- selectorType
|
|
- selectorValue
|
|
- selectorRole
|
|
- sourceOfTruth
|
|
properties:
|
|
selectorType:
|
|
type: string
|
|
enum:
|
|
- suite
|
|
- path
|
|
- group
|
|
- file
|
|
selectorValue:
|
|
type: string
|
|
minLength: 1
|
|
selectorRole:
|
|
type: string
|
|
enum:
|
|
- include
|
|
- exclude
|
|
- inventory-only
|
|
sourceOfTruth:
|
|
type: string
|
|
enum:
|
|
- manifest
|
|
- pest-group
|
|
- guard-test
|
|
- report-attribution
|
|
rationale:
|
|
type: string
|
|
HeavyTestClassification:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- classificationId
|
|
- purpose
|
|
- dominantCostDrivers
|
|
- defaultLaneId
|
|
- allowedLaneIds
|
|
- forbiddenLaneIds
|
|
- reviewerSignals
|
|
- escalationTriggers
|
|
properties:
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
purpose:
|
|
type: string
|
|
dominantCostDrivers:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
defaultLaneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
allowedLaneIds:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: '#/components/schemas/LaneId'
|
|
forbiddenLaneIds:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/LaneId'
|
|
reviewerSignals:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
escalationTriggers:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
allOf:
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: browser
|
|
then:
|
|
properties:
|
|
defaultLaneId:
|
|
const: browser
|
|
allowedLaneIds:
|
|
type: array
|
|
minItems: 1
|
|
maxItems: 1
|
|
items:
|
|
const: browser
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: surface-guard
|
|
then:
|
|
properties:
|
|
defaultLaneId:
|
|
const: heavy-governance
|
|
forbiddenLaneIds:
|
|
allOf:
|
|
- contains:
|
|
const: fast-feedback
|
|
- contains:
|
|
const: confidence
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: ui-workflow
|
|
then:
|
|
properties:
|
|
defaultLaneId:
|
|
const: confidence
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: discovery-heavy
|
|
then:
|
|
properties:
|
|
defaultLaneId:
|
|
const: heavy-governance
|
|
forbiddenLaneIds:
|
|
allOf:
|
|
- contains:
|
|
const: fast-feedback
|
|
- contains:
|
|
const: confidence
|
|
HeavyTestFamily:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- familyId
|
|
- classificationId
|
|
- purpose
|
|
- currentLaneId
|
|
- targetLaneId
|
|
- selectors
|
|
- hotspotFiles
|
|
- costSignals
|
|
- validationStatus
|
|
properties:
|
|
familyId:
|
|
type: string
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
purpose:
|
|
type: string
|
|
currentLaneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
targetLaneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
selectors:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: '#/components/schemas/HeavyFamilySelector'
|
|
hotspotFiles:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
costSignals:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
confidenceRationale:
|
|
type: string
|
|
validationStatus:
|
|
$ref: '#/components/schemas/ValidationStatus'
|
|
allOf:
|
|
- if:
|
|
properties:
|
|
targetLaneId:
|
|
const: confidence
|
|
then:
|
|
required:
|
|
- confidenceRationale
|
|
properties:
|
|
confidenceRationale:
|
|
type: string
|
|
minLength: 1
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: ui-light
|
|
then:
|
|
properties:
|
|
targetLaneId:
|
|
enum:
|
|
- fast-feedback
|
|
- confidence
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: ui-workflow
|
|
then:
|
|
properties:
|
|
targetLaneId:
|
|
enum:
|
|
- confidence
|
|
- heavy-governance
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: surface-guard
|
|
then:
|
|
properties:
|
|
targetLaneId:
|
|
const: heavy-governance
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: discovery-heavy
|
|
then:
|
|
properties:
|
|
targetLaneId:
|
|
const: heavy-governance
|
|
- if:
|
|
properties:
|
|
classificationId:
|
|
const: browser
|
|
then:
|
|
properties:
|
|
targetLaneId:
|
|
const: browser
|
|
MixedFileResolution:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- filePath
|
|
- primaryClassificationId
|
|
- resolutionStrategy
|
|
- rationale
|
|
- followUpRequired
|
|
properties:
|
|
filePath:
|
|
type: string
|
|
minLength: 1
|
|
primaryClassificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
secondaryClassificationIds:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
resolutionStrategy:
|
|
type: string
|
|
enum:
|
|
- split-file
|
|
- broadest-cost-wins
|
|
rationale:
|
|
type: string
|
|
minLength: 1
|
|
followUpRequired:
|
|
type: boolean
|
|
LanePlacementRule:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- ruleId
|
|
- classificationId
|
|
- laneId
|
|
- allowance
|
|
- reason
|
|
properties:
|
|
ruleId:
|
|
type: string
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
laneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
allowance:
|
|
$ref: '#/components/schemas/PlacementAllowance'
|
|
reason:
|
|
type: string
|
|
exceptionPolicy:
|
|
type: string
|
|
LanePlacementValidationRequest:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- laneId
|
|
properties:
|
|
laneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
familyId:
|
|
type: string
|
|
filePath:
|
|
type: string
|
|
observedCostSignals:
|
|
type: array
|
|
items:
|
|
type: string
|
|
anyOf:
|
|
- required:
|
|
- classificationId
|
|
- required:
|
|
- familyId
|
|
- required:
|
|
- filePath
|
|
LanePlacementValidationResult:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- laneId
|
|
- resolvedClassificationId
|
|
- allowance
|
|
- valid
|
|
- reasons
|
|
properties:
|
|
laneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
resolvedClassificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
familyId:
|
|
type: string
|
|
allowance:
|
|
$ref: '#/components/schemas/PlacementAllowance'
|
|
valid:
|
|
type: boolean
|
|
reasons:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: string
|
|
remediationOptions:
|
|
type: array
|
|
items:
|
|
type: string
|
|
mixedFileResolution:
|
|
$ref: '#/components/schemas/MixedFileResolution'
|
|
HeavyBudgetEvaluation:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- targetType
|
|
- targetId
|
|
- thresholdSeconds
|
|
- measuredSeconds
|
|
- baselineSource
|
|
- enforcement
|
|
- lifecycleState
|
|
- status
|
|
properties:
|
|
targetType:
|
|
type: string
|
|
enum:
|
|
- lane
|
|
- classification
|
|
- family
|
|
targetId:
|
|
type: string
|
|
thresholdSeconds:
|
|
type: integer
|
|
minimum: 1
|
|
measuredSeconds:
|
|
type: number
|
|
minimum: 0
|
|
baselineSource:
|
|
$ref: '#/components/schemas/BudgetBaselineSource'
|
|
enforcement:
|
|
$ref: '#/components/schemas/BudgetEnforcement'
|
|
lifecycleState:
|
|
$ref: '#/components/schemas/BudgetLifecycleState'
|
|
status:
|
|
$ref: '#/components/schemas/BudgetStatus'
|
|
HeavyAttributionReport:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- laneId
|
|
- finishedAt
|
|
- wallClockSeconds
|
|
- slowestEntries
|
|
- classificationAttribution
|
|
- familyAttribution
|
|
- budgetEvaluations
|
|
- artifactDirectory
|
|
properties:
|
|
laneId:
|
|
$ref: '#/components/schemas/LaneId'
|
|
finishedAt:
|
|
type: string
|
|
format: date-time
|
|
wallClockSeconds:
|
|
type: number
|
|
minimum: 0
|
|
slowestEntries:
|
|
type: array
|
|
description: Canonical top 10 runtime hotspot entries ordered by slowest wall-clock time.
|
|
minItems: 10
|
|
items:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- label
|
|
- wallClockSeconds
|
|
properties:
|
|
label:
|
|
type: string
|
|
wallClockSeconds:
|
|
type: number
|
|
minimum: 0
|
|
classificationAttribution:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- classificationId
|
|
- totalWallClockSeconds
|
|
properties:
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
totalWallClockSeconds:
|
|
type: number
|
|
minimum: 0
|
|
hotspotFiles:
|
|
type: array
|
|
items:
|
|
type: string
|
|
familyAttribution:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- familyId
|
|
- classificationId
|
|
- totalWallClockSeconds
|
|
properties:
|
|
familyId:
|
|
type: string
|
|
classificationId:
|
|
$ref: '#/components/schemas/ClassificationId'
|
|
totalWallClockSeconds:
|
|
type: number
|
|
minimum: 0
|
|
hotspotFiles:
|
|
type: array
|
|
items:
|
|
type: string
|
|
budgetEvaluations:
|
|
type: array
|
|
minItems: 1
|
|
allOf:
|
|
- contains:
|
|
type: object
|
|
required:
|
|
- targetType
|
|
- targetId
|
|
properties:
|
|
targetType:
|
|
const: lane
|
|
targetId:
|
|
const: heavy-governance
|
|
- contains:
|
|
type: object
|
|
required:
|
|
- targetType
|
|
properties:
|
|
targetType:
|
|
const: classification
|
|
- contains:
|
|
type: object
|
|
required:
|
|
- targetType
|
|
properties:
|
|
targetType:
|
|
const: family
|
|
items:
|
|
$ref: '#/components/schemas/HeavyBudgetEvaluation'
|
|
artifactDirectory:
|
|
type: string
|
|
const: storage/logs/test-lanes
|