openapi: 3.1.0
info:
  title: Pijul Webhook Color API
  description: |
    Webhook receiver for nest.pijul.com events with Gay.jl deterministic coloring.
    Each event type maps to a GF(3) trit for color assignment.
  version: 1.0.0
  contact:
    name: ies
    url: https://nest.pijul.com/ies/duck

servers:
  - url: https://duck.ies.dev/webhooks
    description: Production webhook endpoint

paths:
  /pijul:
    post:
      operationId: receivePijulEvent
      summary: Receive pijul webhook event and assign color
      description: |
        Nest.pijul.com posts here only on:
        - patch_applied: originary world change
        
        Each world change gets a deterministic color from Gay.jl based on:
        - seed: derived from repo name hash
        - index: patch sequence number (world version)
      security:
        - webhookSecret: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PijulWebhookEvent'
      responses:
        '200':
          description: Event received and colored
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ColoredEvent'
        '401':
          description: Invalid webhook secret
        '422':
          description: Malformed event payload

  /colors/{repo}:
    get:
      operationId: getRepoColorHistory
      summary: Get color history for a repository
      parameters:
        - name: repo
          in: path
          required: true
          schema:
            type: string
          example: ies/duck
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
        - name: event_type
          in: query
          schema:
            $ref: '#/components/schemas/EventType'
      responses:
        '200':
          description: Color history
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ColoredEvent'

  /colors/palette:
    get:
      operationId: getEventPalette
      summary: Get the triadic color palette for event types
      description: |
        Returns the three colors assigned to event types.
        Colors are deterministic from Gay.jl with seed derived from "pijul".
      responses:
        '200':
          description: Event type color palette
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventPalette'

components:
  securitySchemes:
    webhookSecret:
      type: apiKey
      in: header
      name: X-Pijul-Signature
      description: HMAC-SHA256 of payload with webhook secret

  schemas:
    EventType:
      type: string
      enum:
        - patch_applied
      description: |
        Only originary world change matters.
        patch_applied → the world changed (+1)
        
        Excluded (not world change):
        - new_discussion: discourse about world, not world itself
        - patch_added: potential change, not actual change

    PijulWebhookEvent:
      type: object
      required:
        - event
        - repository
        - timestamp
      properties:
        event:
          $ref: '#/components/schemas/EventType'
        repository:
          type: object
          properties:
            owner:
              type: string
              example: ies
            name:
              type: string
              example: duck
            url:
              type: string
              format: uri
              example: https://nest.pijul.com/ies/duck
        timestamp:
          type: string
          format: date-time
        patch:
          type: object
          description: Present for patch_added and patch_applied events
          properties:
            hash:
              type: string
              example: M7UPPKWXWA37Y4VJOLDX745E66WDKMNPSC3XYNQOLWITZCQZO2LAC
            message:
              type: string
              example: "rename: hdresearch → ies"
            author:
              type: string
            channel:
              type: string
              default: main
        discussion:
          type: object
          description: Present for new_discussion events
          properties:
            id:
              type: integer
            title:
              type: string
            author:
              type: string

    ColoredEvent:
      type: object
      properties:
        event:
          $ref: '#/components/schemas/EventType'
        trit:
          type: integer
          enum: [-1, 0, 1]
          description: GF(3) classification
        color:
          $ref: '#/components/schemas/GayColor'
        repository:
          type: string
          example: ies/duck
        sequence:
          type: integer
          description: Event index for this repo (used as Gay.jl index)
        timestamp:
          type: string
          format: date-time
        payload:
          type: object
          description: Original event data

    GayColor:
      type: object
      description: Deterministic color from Gay.jl
      properties:
        hex:
          type: string
          pattern: '^#[0-9A-Fa-f]{6}$'
          example: '#A855F7'
        seed:
          type: integer
          description: Seed derived from repo name
          example: 69
        index:
          type: integer
          description: Sequence number for this event
          example: 4
        hue:
          type: number
          minimum: 0
          maximum: 360
        saturation:
          type: number
          minimum: 0
          maximum: 1
        lightness:
          type: number
          minimum: 0
          maximum: 1

    EventPalette:
      type: object
      properties:
        seed:
          type: integer
          description: Base seed for palette ("pijul" hashed)
        colors:
          type: object
          properties:
            new_discussion:
              $ref: '#/components/schemas/GayColor'
            patch_added:
              $ref: '#/components/schemas/GayColor'
            patch_applied:
              $ref: '#/components/schemas/GayColor'
        trits:
          type: object
          properties:
            new_discussion:
              type: integer
              enum: [-1]
            patch_added:
              type: integer
              enum: [0]
            patch_applied:
              type: integer
              enum: [1]

    GF3Balance:
      type: object
      description: Verify GF(3) conservation across events
      properties:
        sum:
          type: integer
          description: Must equal 0 for balanced triads
        balanced:
          type: boolean
        events:
          type: array
          items:
            type: string