openapi: 3.0.3
info:
  title: SOAT Memory Assertions
  version: 1.0.0
  description: >-
    Shared components for the append-only record of memory writes. This file
    declares no paths: an assertion is read through three different modules —
    a memory's own history, a store's write ledger, and the generation that
    made the writes — and the shape is defined once rather than three times.
  contact:
    name: SOAT Team
    url: https://github.com/ttoss/soat
paths: {}
components:
  schemas:
    MemoryAssertion:
      type: object
      description: >-
        One write attempt against a memory store: some principal, through some
        mechanism, claimed a fact. Append-only, and recorded whatever the
        outcome — including the skips, which left no record anywhere before.
      properties:
        id:
          type: string
          example: massert_V1StGXR8Z5jdHi6B
        memory_store_id:
          x-soat-ref: memory-stores
          type: string
          example: mstore_V1StGXR8Z5jdHi6B
        memory_id:
          type: string
          nullable: true
          description: >-
            The memory this assertion resolved into: the new memory for
            `created` and `superseded`, the existing memory that matched for
            `skipped`, the memory withdrawn for `retracted`. Null only once
            that memory has been deleted.
          example: mem_V1StGXR8Z5jdHi6B
        superseded_memory_id:
          type: string
          nullable: true
          description: >-
            The memory this assertion retired, on a `superseded` outcome; null
            otherwise, a retraction included — it retires its own memory, which
            `memory_id` already names. Read back from `memories.superseded_by_memory_id` rather
            than stored here, because validity lives on the memory — where
            every read filters it — and exactly one memory is superseded per
            assertion.
          example: mem_V1StGXR8Z5jdHi6B
        content:
          type: string
          description: >-
            The text as asserted, which is not necessarily the memory's text: a
            `skipped` assertion records what was claimed, while the memory keeps
            what it already held.
          example: The customer prefers email communication over phone calls
        mechanism:
          type: string
          enum: [tool, rule, api, formation]
          description: >-
            Which door the write came through. `tool` is the agent's
            `write_memory` call mid-turn; `rule` is a post-turn pass over the
            finished turn; `api` is `POST /api/v1/memories`; `formation` is a
            `memory` resource in an applied template. It answers *how*, never
            *who* — the principal fields answer that.
          example: tool
        rule_id:
          x-soat-ref: memory-rules
          type: string
          nullable: true
          description: >-
            The memory rule whose firing wrote this, set only when `mechanism`
            is `rule` — the built-in extractor included, since that is a rule
            with no handler. Null once the rule has been deleted, and on
            assertions written before memory rules shipped.
          example: mrule_V1StGXR8Z5jdHi6B
        generation_id:
          x-soat-ref: generations
          type: string
          nullable: true
          description: >-
            The turn that asserted the fact — the origin of anything an agent
            wrote, and the edge a conversation is reachable from. Null on the
            `api` and `formation` doors, which have no generation behind them.
          example: gen_V1StGXR8Z5jdHi6B
        principal_type:
          allOf:
            - $ref: './principals.yaml#/components/schemas/PrincipalType'
          description: >-
            Who claimed the fact: `user` or `api_key` on the `api` and
            `formation` doors, `agent` on both agent doors — the extractor runs
            under the agent's identity.
        principal_id:
          type: string
          example: agent_V1StGXR8Z5jdHi6B
        outcome:
          type: string
          enum: [created, superseded, skipped, retracted]
          description: >-
            What the write resolved to. `created` is a distinct fact,
            `superseded` is the same fact changed (the top match was
            invalidated and replaced), `skipped` is a fact already known,
            `retracted` is a fact that stopped holding with nothing replacing
            it.
          example: created
        similarity:
          type: number
          nullable: true
          description: >-
            The cosine similarity the outcome was decided against — the top
            match's, or the declared target's when `declared` is true, where it
            decides nothing and only records how far apart the two statements
            were. Null when there was nothing to compare against, when the
            content could not be embedded, and on a `retracted` outcome, which
            compares nothing.
          example: 0.97
        declared:
          type: boolean
          description: >-
            Whether the write named the memory it replaced (`supersedes` on
            create) instead of the thresholds choosing one. Always false on a
            `created`, `skipped` or `retracted` outcome.
          example: false
        created_at:
          type: string
          format: date-time
