openapi: 3.1.0
info:
  title: Heavy Governance Cost Recovery Logical Contract
  version: 1.0.0
  summary: Logical contract for inspecting heavy-governance hotspots, recording slimming decisions, and publishing the final budget outcome.
  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 hotspot inventory, family decomposition, budget normalization,
    and explicit recovery or recalibration outcomes so the existing heavy-lane
    seams remain consistent as Spec 209 is implemented.
x-logical-contract: true
servers:
  - url: https://tenantatlas.local/logical
paths:
  /heavy-governance/budget-contract:
    get:
      summary: Read the current heavy-governance budget contract.
      operationId: getHeavyGovernanceBudgetContract
      responses:
        '200':
          description: Current heavy-governance budget contract.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HeavyGovernanceBudgetContract'
  /heavy-governance/hotspots:
    get:
      summary: Read the current heavy-governance hotspot inventory.
      operationId: listHeavyGovernanceHotspots
      responses:
        '200':
          description: Current hotspot inventory.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - hotspots
                properties:
                  hotspots:
                    type: array
                    minItems: 1
                    items:
                      $ref: '#/components/schemas/HeavyGovernanceHotspot'
  /heavy-governance/hotspots/{familyId}/decomposition:
    get:
      summary: Read the decomposition record for a hotspot family.
      operationId: getHeavyGovernanceFamilyDecomposition
      parameters:
        - name: familyId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Current decomposition record for the family.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FamilyCostDecomposition'
    put:
      summary: Record or update the decomposition record for a hotspot family.
      operationId: putHeavyGovernanceFamilyDecomposition
      parameters:
        - name: familyId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FamilyCostDecomposition'
      responses:
        '200':
          description: Decomposition record stored logically.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FamilyCostDecomposition'
  /heavy-governance/slimming-decisions:
    get:
      summary: Read the current slimming decisions for targeted hotspot families.
      operationId: listHeavyGovernanceSlimmingDecisions
      responses:
        '200':
          description: Current slimming decisions.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - decisions
                properties:
                  decisions:
                    type: array
                    items:
                      $ref: '#/components/schemas/HeavyFamilySlimmingDecision'
  /heavy-governance/budget-snapshots:
    get:
      summary: Read the recorded heavy-governance budget snapshots.
      operationId: listHeavyGovernanceBudgetSnapshots
      responses:
        '200':
          description: Current before-and-after snapshots.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - snapshots
                properties:
                  snapshots:
                    type: array
                    items:
                      $ref: '#/components/schemas/BudgetRecoverySnapshot'
  /heavy-governance/budget-outcome/latest:
    get:
      summary: Read the latest explicit heavy-governance budget outcome.
      operationId: getLatestHeavyGovernanceBudgetOutcome
      responses:
        '200':
          description: Latest heavy-governance budget outcome.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BudgetOutcomeRecord'
  /heavy-governance/author-guidance:
    get:
      summary: Read the reviewer and author rules for future heavy-governance tests.
      operationId: listHeavyGovernanceAuthorGuidance
      responses:
        '200':
          description: Current author guidance rules.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - rules
                properties:
                  rules:
                    type: array
                    minItems: 4
                    items:
                      $ref: '#/components/schemas/HeavyAuthorGuidanceRule'
components:
  schemas:
    ClassificationId:
      type: string
      enum:
        - ui-workflow
        - surface-guard
        - discovery-heavy
    CostDriverCategory:
      type: string
      enum:
        - overbroad
        - redundant
        - discovery-heavy
        - workflow-heavy
        - surface-heavy
        - helper-driven
        - fixture-driven
        - intentionally-heavy
    BudgetDecisionStatus:
      type: string
      enum:
        - pending
        - recovered
        - recalibrated
    HotspotStatus:
      type: string
      enum:
        - seeded
        - decomposed
        - slimmed
        - retained
        - follow-up
    PriorityTier:
      type: string
      enum:
        - primary
        - secondary
        - residual
    ResidualCostSource:
      type: string
      enum:
        - family-breadth
        - helper-driven
        - fixture-driven
        - mixed
        - intentional-depth
    RecommendedAction:
      type: string
      enum:
        - split-family
        - centralize-work
        - narrow-assertions
        - retain-as-heavy
        - route-follow-up
    SlimmingDecisionType:
      type: string
      enum:
        - split
        - centralize
        - trim-duplicate-work
        - retain
        - follow-up
    BudgetStatus:
      type: string
      enum:
        - within-budget
        - warning
        - over-budget
    HeavyGovernanceBudgetContract:
      type: object
      additionalProperties: false
      required:
        - laneId
        - summaryThresholdSeconds
        - evaluationThresholdSeconds
        - normalizedThresholdSeconds
        - baselineSource
        - enforcementLevel
        - lifecycleState
        - decisionStatus
      properties:
        laneId:
          type: string
          const: heavy-governance
        summaryThresholdSeconds:
          type: number
          exclusiveMinimum: 0
        evaluationThresholdSeconds:
          type: number
          exclusiveMinimum: 0
        normalizedThresholdSeconds:
          type: number
          exclusiveMinimum: 0
        baselineSource:
          type: string
        enforcementLevel:
          type: string
          enum:
            - report-only
            - warn
            - hard-fail
        lifecycleState:
          type: string
          enum:
            - draft
            - documented
            - recalibrated
        reconciliationRationale:
          type: string
        decisionStatus:
          $ref: '#/components/schemas/BudgetDecisionStatus'
    HeavyGovernanceHotspot:
      type: object
      additionalProperties: false
      required:
        - familyId
        - classificationId
        - purpose
        - measuredSeconds
        - hotspotFiles
        - costDriverCategory
        - priorityTier
        - status
      properties:
        familyId:
          type: string
        classificationId:
          $ref: '#/components/schemas/ClassificationId'
        purpose:
          type: string
        measuredSeconds:
          type: number
          minimum: 0
        hotspotFiles:
          type: array
          minItems: 1
          items:
            type: string
        costDriverCategory:
          $ref: '#/components/schemas/CostDriverCategory'
        priorityTier:
          $ref: '#/components/schemas/PriorityTier'
        currentBudgetSeconds:
          type: number
          minimum: 0
        status:
          $ref: '#/components/schemas/HotspotStatus'
    FamilyCostDecomposition:
      type: object
      additionalProperties: false
      required:
        - familyId
        - trustType
        - requiredBreadth
        - duplicateWorkSources
        - residualCostSource
        - recommendedAction
        - notes
      properties:
        familyId:
          type: string
        trustType:
          type: string
          enum:
            - workflow-trust
            - surface-trust
            - guard-trust
            - discovery-trust
        requiredBreadth:
          type: string
        duplicateWorkSources:
          type: array
          items:
            type: string
        duplicateWorkEstimateSeconds:
          type: number
          minimum: 0
        residualCostSource:
          $ref: '#/components/schemas/ResidualCostSource'
        recommendedAction:
          $ref: '#/components/schemas/RecommendedAction'
        notes:
          type: string
    HeavyFamilySlimmingDecision:
      type: object
      additionalProperties: false
      required:
        - familyId
        - decisionType
        - guardPreservationPlan
        - owner
        - validationPlan
      properties:
        familyId:
          type: string
        decisionType:
          $ref: '#/components/schemas/SlimmingDecisionType'
        scope:
          type: array
          items:
            type: string
        guardPreservationPlan:
          type: string
        expectedDeltaSeconds:
          type: number
        owner:
          type: string
        validationPlan:
          type: array
          minItems: 1
          items:
            type: string
    BudgetRecoverySnapshot:
      type: object
      additionalProperties: false
      required:
        - snapshotId
        - capturedAt
        - wallClockSeconds
        - classificationTotals
        - familyTotals
        - slowestEntries
        - artifactPaths
        - budgetStatus
      properties:
        snapshotId:
          type: string
        capturedAt:
          type: string
          format: date-time
        wallClockSeconds:
          type: number
          minimum: 0
        classificationTotals:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - classificationId
              - totalWallClockSeconds
            properties:
              classificationId:
                $ref: '#/components/schemas/ClassificationId'
              totalWallClockSeconds:
                type: number
                minimum: 0
        familyTotals:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - familyId
              - totalWallClockSeconds
            properties:
              familyId:
                type: string
              totalWallClockSeconds:
                type: number
                minimum: 0
        slowestEntries:
          type: array
          minItems: 1
          items:
            type: object
            additionalProperties: false
            required:
              - label
              - wallClockSeconds
            properties:
              label:
                type: string
              wallClockSeconds:
                type: number
                minimum: 0
        artifactPaths:
          type: object
          additionalProperties: false
          required:
            - summary
            - budget
            - report
          properties:
            summary:
              type: string
              pattern: ^storage/logs/test-lanes/
            budget:
              type: string
              pattern: ^storage/logs/test-lanes/
            report:
              type: string
              pattern: ^storage/logs/test-lanes/
        budgetStatus:
          $ref: '#/components/schemas/BudgetStatus'
    BudgetOutcomeRecord:
      type: object
      additionalProperties: false
      required:
        - outcomeId
        - decisionStatus
        - finalThresholdSeconds
        - finalMeasuredSeconds
        - deltaSeconds
        - deltaPercent
        - remainingOpenFamilies
        - justification
      properties:
        outcomeId:
          type: string
        decisionStatus:
          $ref: '#/components/schemas/BudgetDecisionStatus'
        finalThresholdSeconds:
          type: number
          exclusiveMinimum: 0
        finalMeasuredSeconds:
          type: number
          minimum: 0
        deltaSeconds:
          type: number
        deltaPercent:
          type: number
        remainingOpenFamilies:
          type: array
          items:
            type: string
        justification:
          type: string
        followUpDebt:
          type: array
          items:
            type: string
    HeavyAuthorGuidanceRule:
      type: object
      additionalProperties: false
      required:
        - ruleId
        - whenToUse
        - requiredDecision
        - antiPattern
        - preferredOutcome
      properties:
        ruleId:
          type: string
        whenToUse:
          type: string
        requiredDecision:
          type: string
        antiPattern:
          type: string
        preferredOutcome:
          type: string