openapi: 3.1.0
info:
  title: Test Runtime Trend Reporting & Baseline Recalibration
  version: 1.0.0
  description: |
    Logical contract for the repository-owned workflow that updates bounded lane
    history, evaluates drift status, emits hotspot deltas, and records explicit
    recalibration evidence. This file documents wrapper/support-class semantics,
    not a public HTTP API.
servers:
  - url: https://tenantatlas.local/logical
paths:
  /test-governance/lanes/{laneId}/trend-history:
    post:
      summary: Update one lane's bounded trend history artifact
      operationId: updateLaneTrendHistory
      parameters:
        - $ref: '#/components/parameters/LaneId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TrendHistoryUpdateRequest'
      responses:
        '200':
          description: Updated bounded history artifact for the lane
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaneTrendHistoryArtifact'
  /test-governance/lanes/{laneId}/trend-assessment:
    post:
      summary: Evaluate drift status and hotspot deltas for one lane
      operationId: evaluateLaneTrendAssessment
      parameters:
        - $ref: '#/components/parameters/LaneId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LaneTrendAssessmentRequest'
      responses:
        '200':
          description: Current lane assessment including health class and hotspot snapshot
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaneTrendAssessmentResponse'
  /test-governance/lanes/{laneId}/recalibration:
    post:
      summary: Evaluate or record an explicit recalibration decision for one lane
      operationId: evaluateLaneRecalibration
      parameters:
        - $ref: '#/components/parameters/LaneId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecalibrationEvaluationRequest'
      responses:
        '200':
          description: Structured recalibration decision or candidate record
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecalibrationDecision'
  /test-governance/cycles/{cycleId}/summary:
    get:
      summary: Read the trend-aware summary for one reporting cycle
      operationId: getTrendSummaryCycle
      parameters:
        - name: cycleId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Trend-aware cycle summary spanning the relevant lanes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrendSummaryCycle'
components:
  parameters:
    LaneId:
      name: laneId
      in: path
      required: true
      schema:
        type: string
        enum:
          - fast-feedback
          - confidence
          - heavy-governance
          - browser
          - junit
          - profiling
  schemas:
    TrendHistoryUpdateRequest:
      type: object
      additionalProperties: false
      required:
        - currentRecord
      properties:
        currentRecord:
          $ref: '#/components/schemas/TrendRecord'
        priorHistory:
          type: array
          items:
            $ref: '#/components/schemas/TrendRecord'
          description: |
            Previously retained history records, typically hydrated from the
            most recent comparable uploaded artifact bundle.
        policyOverride:
          $ref: '#/components/schemas/TrendPolicy'
    LaneTrendAssessmentRequest:
      type: object
      additionalProperties: false
      required:
        - policy
        - history
      properties:
        policy:
          $ref: '#/components/schemas/TrendPolicy'
        history:
          type: array
          items:
            $ref: '#/components/schemas/TrendRecord'
        includeHotspots:
          type: boolean
          default: true
    LaneTrendAssessmentResponse:
      type: object
      additionalProperties: false
      required:
        - assessment
      properties:
        assessment:
          $ref: '#/components/schemas/DriftAssessment'
        hotspotSnapshot:
          $ref: '#/components/schemas/HotspotSnapshot'
        warnings:
          type: array
          items:
            type: string
    RecalibrationEvaluationRequest:
      type: object
      additionalProperties: false
      required:
        - targetType
        - assessment
        - evidenceRunRefs
      properties:
        targetType:
          type: string
          enum:
            - baseline
            - budget
        assessment:
          $ref: '#/components/schemas/DriftAssessment'
        evidenceRunRefs:
          type: array
          minItems: 1
          items:
            type: string
        proposedValueSeconds:
          type:
            - number
            - 'null'
        rationaleCode:
          type:
            - string
            - 'null'
          enum:
            - lane-scope-change
            - infrastructure-shift
            - post-improvement-reset
            - sustained-erosion
            - noise-rejected
            - manual-hold
            - null
        recordLocation:
          type:
            - string
            - 'null'
          description: Active spec path or implementation PR reference for the human-reviewed decision record.
    LaneTrendHistoryArtifact:
      type: object
      additionalProperties: false
      required:
        - schemaVersion
        - laneId
        - workflowProfile
        - generatedAt
        - policy
        - history
        - currentAssessment
      properties:
        schemaVersion:
          type: string
        laneId:
          type: string
        workflowProfile:
          type: string
        generatedAt:
          type: string
          format: date-time
        policy:
          $ref: '#/components/schemas/TrendPolicy'
        history:
          type: array
          items:
            $ref: '#/components/schemas/TrendRecord'
        currentAssessment:
          $ref: '#/components/schemas/DriftAssessment'
        hotspotSnapshot:
          $ref: '#/components/schemas/HotspotSnapshot'
        recalibrationDecisions:
          type: array
          items:
            $ref: '#/components/schemas/RecalibrationDecision'
        warnings:
          type: array
          items:
            type: string
    TrendPolicy:
      type: object
      additionalProperties: false
      required:
        - retentionLimit
        - comparisonWindowSize
        - minimumComparableSamples
        - varianceFloorSeconds
        - nearBudgetHeadroomSeconds
        - hotspotFamilyLimit
        - hotspotFileLimit
        - slowestEntryRetention
      properties:
        retentionLimit:
          type: integer
          minimum: 1
        comparisonWindowSize:
          type: integer
          minimum: 1
        minimumComparableSamples:
          type: integer
          minimum: 3
        varianceFloorSeconds:
          type: integer
          minimum: 0
        nearBudgetHeadroomSeconds:
          type: integer
          minimum: 0
        hotspotFamilyLimit:
          type: integer
          minimum: 1
        hotspotFileLimit:
          type: integer
          minimum: 1
        slowestEntryRetention:
          type: integer
          minimum: 1
        recalibrationPolicy:
          type: object
          additionalProperties: false
          properties:
            baselineRequiresExplicitReview:
              type: boolean
            budgetRequiresExplicitReview:
              type: boolean
            minimumBudgetEvidenceSamples:
              type: integer
              minimum: 1
    TrendRecord:
      type: object
      additionalProperties: false
      required:
        - runRef
        - laneId
        - workflowId
        - triggerClass
        - generatedAt
        - wallClockSeconds
        - budgetSeconds
        - budgetStatus
        - blockingStatus
        - comparisonFingerprint
      properties:
        runRef:
          type: string
        laneId:
          type: string
        workflowId:
          type: string
        triggerClass:
          type: string
          enum:
            - pull-request
            - mainline-push
            - manual
            - scheduled
            - local
        generatedAt:
          type: string
          format: date-time
        wallClockSeconds:
          type: number
          minimum: 0
        baselineSeconds:
          type:
            - number
            - 'null'
        baselineSource:
          type:
            - string
            - 'null'
        budgetSeconds:
          type: number
          minimum: 0
        budgetStatus:
          type: string
        blockingStatus:
          type: string
        comparisonFingerprint:
          type: string
        classificationTotals:
          type: array
          items:
            $ref: '#/components/schemas/RuntimeBucket'
        familyTotals:
          type: array
          items:
            $ref: '#/components/schemas/RuntimeBucket'
        hotspotFiles:
          type: array
          items:
            $ref: '#/components/schemas/RuntimeBucket'
        slowestEntries:
          type: array
          items:
            $ref: '#/components/schemas/SlowestEntry'
        artifactRefs:
          type: object
          additionalProperties: false
          properties:
            summary:
              type: string
            report:
              type: string
            budget:
              type: string
            junit:
              type: string
            trendHistory:
              type: string
    DriftAssessment:
      type: object
      additionalProperties: false
      required:
        - healthClass
        - recalibrationRecommendation
        - budgetHeadroomSeconds
        - summaryLine
        - windowStatus
        - sampleCount
      properties:
        healthClass:
          type: string
          enum:
            - healthy
            - budget-near
            - trending-worse
            - regressed
            - unstable
        recalibrationRecommendation:
          type: string
          enum:
            - none
            - investigate
            - review-baseline
            - review-budget
        budgetHeadroomSeconds:
          type: number
        deltaToPreviousSeconds:
          type:
            - number
            - 'null'
        deltaToPreviousPercent:
          type:
            - number
            - 'null'
        deltaToBaselineSeconds:
          type:
            - number
            - 'null'
        deltaToBaselinePercent:
          type:
            - number
            - 'null'
        worseningStreak:
          type: integer
          minimum: 0
        varianceObservedSeconds:
          type: number
          minimum: 0
        windowStatus:
          type: string
          enum:
            - stable
            - insufficient-history
            - scope-changed
            - noisy
        sampleCount:
          type: integer
          minimum: 0
        previousComparableRunRef:
          type:
            - string
            - 'null'
        summaryLine:
          type: string
    HotspotSnapshot:
      type: object
      additionalProperties: false
      required:
        - evidenceAvailability
        - familyDeltas
        - fileHotspots
      properties:
        evidenceAvailability:
          type: string
          enum:
            - available
            - unavailable
        familyDeltas:
          type: array
          items:
            $ref: '#/components/schemas/DeltaBucket'
        fileHotspots:
          type: array
          items:
            $ref: '#/components/schemas/DeltaBucket'
        newEntrants:
          type: array
          items:
            type: string
        droppedEntrants:
          type: array
          items:
            type: string
    DeltaBucket:
      type: object
      additionalProperties: false
      required:
        - name
        - currentSeconds
        - previousSeconds
        - deltaSeconds
      properties:
        name:
          type: string
        currentSeconds:
          type: number
          minimum: 0
        previousSeconds:
          type: number
          minimum: 0
        deltaSeconds:
          type: number
        deltaPercent:
          type:
            - number
            - 'null'
        direction:
          type:
            - string
            - 'null'
          enum:
            - up
            - down
            - flat
            - null
    RuntimeBucket:
      type: object
      additionalProperties: false
      required:
        - name
        - runtimeSeconds
      properties:
        name:
          type: string
        runtimeSeconds:
          type: number
          minimum: 0
    SlowestEntry:
      type: object
      additionalProperties: false
      required:
        - label
        - runtimeSeconds
      properties:
        label:
          type: string
        runtimeSeconds:
          type: number
          minimum: 0
        file:
          type:
            - string
            - 'null'
    RecalibrationDecision:
      type: object
      additionalProperties: false
      required:
        - targetType
        - decisionStatus
        - evidenceRunRefs
        - previousValueSeconds
        - rationaleCode
        - recordedIn
        - notes
      properties:
        targetType:
          type: string
          enum:
            - baseline
            - budget
        decisionStatus:
          type: string
          enum:
            - candidate
            - approved
            - rejected
        evidenceRunRefs:
          type: array
          minItems: 1
          items:
            type: string
        previousValueSeconds:
          type: number
          minimum: 0
        proposedValueSeconds:
          type:
            - number
            - 'null'
        rationaleCode:
          type: string
          enum:
            - lane-scope-change
            - infrastructure-shift
            - post-improvement-reset
            - sustained-erosion
            - noise-rejected
            - manual-hold
        recordedIn:
          type: string
          description: Active spec path or implementation PR reference for the approved or rejected decision.
        notes:
          type: string
    TrendSummaryCycle:
      type: object
      additionalProperties: false
      required:
        - cycleId
        - generatedAt
        - laneSummaries
        - laneAssessments
      properties:
        cycleId:
          type: string
        generatedAt:
          type: string
          format: date-time
        laneSummaries:
          type: array
          items:
            $ref: '#/components/schemas/CycleLaneSummary'
        laneAssessments:
          type: array
          items:
            $ref: '#/components/schemas/DriftAssessment'
        hotspotSnapshots:
          type: array
          items:
            $ref: '#/components/schemas/HotspotSnapshot'
        recalibrationDecisions:
          type: array
          items:
            $ref: '#/components/schemas/RecalibrationDecision'
        artifactPublicationStatus:
          type: array
          items:
            type: string
        warnings:
          type: array
          items:
            type: string
    CycleLaneSummary:
      type: object
      additionalProperties: false
      required:
        - laneId
        - currentRuntimeSeconds
        - budgetSeconds
        - assessment
      properties:
        laneId:
          type: string
          enum:
            - fast-feedback
            - confidence
            - heavy-governance
            - browser
            - junit
            - profiling
        currentRuntimeSeconds:
          type: number
          minimum: 0
        previousComparableSeconds:
          type:
            - number
            - 'null'
        baselineSeconds:
          type:
            - number
            - 'null'
        budgetSeconds:
          type: number
          minimum: 0
        assessment:
          $ref: '#/components/schemas/DriftAssessment'
        hotspotSnapshot:
          $ref: '#/components/schemas/HotspotSnapshot'
        warnings:
          type: array
          items:
            type: string