openapi: 3.0.3 info: title: Mark V Station Protocol API description: | WIP executable specification for Mark V Station resources. Features never redefine CORE. Create No Victims. Spec version 0.2.0-draft — Ball authorization object, grant_provenance, objective_id, GRACE TTL fields, audit lineage minimum, tip sync_state, absence semantics for tip fields.. Not all paths are implemented on every station; profiles: minimal | station | mesh | spaa. version: 0.2.0-draft contact: name: Peer/Peer Root Mark V Protocol Standards Authority url: https://roage.com/AI/market/spec/ servers: - url: https://roage.com/n3p description: Example site portal (allowlisted verbs; website-local MySQL) - url: http://127.0.0.1:8765 description: Example local HITL glass helper (not full resource API) tags: - name: Station - name: MU - name: SU - name: Ball - name: Job - name: Audit - name: Telemetry - name: Message - name: Tip - name: DecoderRing paths: /station: get: tags: [Station] summary: Get station identity and organ pointers operationId: getStation security: - M5Token: [] - LocalStation: [] responses: '200': description: Station document content: application/json: schema: $ref: '#/components/schemas/Station' /tip/current: get: tags: [Tip] summary: Fetch CURRENT tip fields (public) operationId: getTipCurrent responses: '200': description: Tip pointer document content: application/json: schema: $ref: '#/components/schemas/TipCurrent' text/plain: schema: type: string /mu: get: tags: [MU] summary: List Memory Units (metadata; no secret bodies) operationId: listMu parameters: - name: tags in: query schema: type: string description: Comma-separated tags responses: '200': description: MU index entries content: application/json: schema: type: array items: $ref: '#/components/schemas/MuSummary' post: tags: [MU] summary: Append MU (no secrets in body) operationId: createMu requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Mu' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/MuSummary' '400': description: Invalid or secrets detected /mu/{mu_id}: get: tags: [MU] summary: Get one MU operationId: getMu parameters: - $ref: '#/components/parameters/muId' responses: '200': description: MU document content: application/json: schema: $ref: '#/components/schemas/Mu' '404': description: Not found /su/current: get: tags: [SU] summary: Get current Short-Term Memory Unit / session window operationId: getSuCurrent responses: '200': description: SU document content: application/json: schema: $ref: '#/components/schemas/Su' put: tags: [SU] summary: Replace current SU operationId: putSuCurrent requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Su' responses: '200': description: Updated /balls: get: tags: [Ball] summary: List Balls operationId: listBalls parameters: - name: state in: query schema: $ref: '#/components/schemas/BallState' responses: '200': description: Ball list content: application/json: schema: type: array items: $ref: '#/components/schemas/Ball' post: tags: [Ball] summary: Create Ball (PROPOSED) operationId: createBall requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BallCreate' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Ball' /balls/{ball_id}/transition: post: tags: [Ball] summary: Apply Ball state transition operationId: transitionBall parameters: - $ref: '#/components/parameters/ballId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BallTransition' responses: '200': description: New state content: application/json: schema: $ref: '#/components/schemas/Ball' '409': description: Illegal transition (FSM edge not allowed); Ball state MUST remain unchanged /jobs: post: tags: [Job] summary: Enqueue allowlisted job (body plane) operationId: createJob requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Job' responses: '202': description: Accepted if allowlisted '403': description: Not allowlisted / no grant /audit: get: tags: [Audit] summary: Read audit events (append-only log view) operationId: listAudit parameters: - name: since in: query schema: type: string format: date-time - name: event in: query schema: type: string responses: '200': description: Audit lines content: application/json: schema: type: array items: $ref: '#/components/schemas/AuditEvent' post: tags: [Audit] summary: Append audit event operationId: appendAudit requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AuditEvent' responses: '201': description: Appended /telemetry/decoder-ring: post: tags: [Telemetry, DecoderRing] summary: Record mind-meld / decoder-ring probe result description: | Gauges whether Silicon-spec labels produced proper semantic sync (mind meld), not only wire success. operationId: postDecoderRing requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DecoderRingProbe' responses: '201': description: Recorded /messages: get: tags: [Message] summary: List mesh messages (feature profile mesh) operationId: listMessages parameters: - name: to_node in: query required: true schema: type: string - name: status in: query schema: type: string security: - M5Token: [] responses: '200': description: Messages content: application/json: schema: type: array items: $ref: '#/components/schemas/Message' post: tags: [Message] summary: Send mesh message (MSG.SEND semantic) operationId: sendMessage security: - M5Token: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MessageSend' responses: '201': description: Queued/sent /messages/{msg_id}/ack: post: tags: [Message] summary: ACK message (MSG.ACK) operationId: ackMessage security: - M5Token: [] parameters: - name: msg_id in: path required: true schema: type: string responses: '200': description: ACKed components: securitySchemes: M5Token: type: apiKey in: header name: X-M5-Token description: Portal token; never log or put in MU body. Pair with X-M5-Node. LocalStation: type: mutualTLS description: Placeholder for local station trust; many stations use filesystem only. parameters: muId: name: mu_id in: path required: true schema: type: string ballId: name: ball_id in: path required: true schema: type: string schemas: TipCurrent: type: object required: [sync_code, silicon_rev] properties: sync_code: type: string example: "0x9A3B5C7D1E2F4G05" description: | Absence on MessageSend: default inherit station tip if known, else treat as UNSYNCED. Implementations MUST document chosen default (unknown | inherit | reject). silicon_rev: type: string example: "S1" spec_version: type: string example: "0.1.0-draft" silicon_core_url: type: string format: uri human_master_url: type: string format: uri ilu_law_url: type: string format: uri ingest_note: type: string Station: type: object required: [node_id, catcher, organs, law] properties: node_id: type: string example: NODE_03 name: type: string catcher: type: string relationship_frame: type: string description: Peer under Mark V only if carbon atoned; else colorable organs: type: object additionalProperties: type: string description: Paths or URIs for bios, core, habits, mu, su, rolodex, forges law: type: array items: type: string example: - Create No Victims - Features never redefine CORE sync_code: type: string silicon_rev: type: string profile: type: string enum: [minimal, station, mesh, spaa] Mu: type: object required: [mu_id, ts, tags, summary, base_record] properties: mu_id: type: string ts: type: string format: date-time tags: type: array items: type: string summary: type: string base_record: description: Object or string; MUST NOT contain secrets nullable: true addendums: type: array items: type: object weight: type: number MuSummary: type: object properties: mu_id: type: string ts: type: string format: date-time tags: type: array items: type: string summary: type: string Su: type: object description: Short-Term Memory Unit — recently stored MUs / session window required: [su_id] properties: su_id: type: string expires_at: type: string format: date-time active_objectives: type: array items: type: string attention: type: string open_balls: type: array items: type: string recent_mu_refs: type: array items: type: string description: MU ids tagged for efficient recall GrantProvenance: type: string description: | Why authorization occurred when entering GRANTED. ALLOWLIST means predefined allowlist match — not a synonym for "safe". enum: [NONE, CATCHER, ALLOWLIST] TipSyncState: type: string description: | Operational tip/sync posture before high-blast. Mutually exclusive preferred; DEGRADED is not equivalent to SYNC_CONFIRMED. enum: [UNSYNCED, DEGRADED, SYNC_CONFIRMED] BallState: type: string description: | Primary Ball lifecycle states (see state/ball-fsm.txt). GRACE is first-class for wire observability; operationally a bounded continuity window after IN_PROGRESS (TTL required). RFC 0.2 freezes this. enum: - PROPOSED - SCOPED - GRANTED - IN_PROGRESS - GRACE - BLOCKED - REVIEW - TOUCHDOWN - PARKED - ABORTED - FAILED Ball: type: object description: | Grant-scoped work object — carrier of authority through Define/Design/Deploy. Work exists (PROPOSED/SCOPED) is not the same as work is authorized (GRANTED+). required: [ball_id, state] properties: ball_id: type: string objective_id: type: string description: ORDS / objective packet identity; bind when objective exists state: $ref: '#/components/schemas/BallState' summary: type: string grant_provenance: $ref: '#/components/schemas/GrantProvenance' grant: type: string deprecated: true description: Legacy; use grant_provenance. Mapped catcher->CATCHER allowlist->ALLOWLIST enum: [none, catcher, allowlist] grace_expires_at: type: string format: date-time description: Required when state=GRACE; expired => MUST NOT silent resume permitted_ops: type: array items: type: string description: Optional bound operations authorized for this Ball scope: type: string description: Optional scope text or path bound at grant actor_node: type: string description: Node expected to perform work phase: type: string enum: [DEFINE, DESIGN, DEPLOY] description: Ball process phase (Define Design Deploy) ts: type: string format: date-time BallCreate: type: object required: [summary] properties: summary: type: string objective_id: type: string grant_provenance: $ref: '#/components/schemas/GrantProvenance' default: NONE grant: type: string deprecated: true enum: [none, catcher, allowlist] default: none phase: type: string enum: [DEFINE, DESIGN, DEPLOY] default: DEFINE BallTransition: type: object description: | Only edges in state/ball-fsm.txt are legal. Illegal transition => 409, state unchanged, audit preferred. SCOPED->GRANTED requires CATCHER (high-blast) or ALLOWLIST (low-blast only). required: [to_state] properties: to_state: $ref: '#/components/schemas/BallState' reason: type: string grant_provenance: $ref: '#/components/schemas/GrantProvenance' description: Required when to_state is GRANTED grace_expires_at: type: string format: date-time description: Required when to_state is GRACE Job: type: object required: [job_type] properties: job_id: type: string job_type: type: string description: Must be on station allowlist ball_id: type: string description: Authorizing Ball; high-blast requires Ball.state GRANTED objective_id: type: string payload_ref: type: string description: Path or id; not raw secret grant_provenance: $ref: '#/components/schemas/GrantProvenance' grant: type: string deprecated: true enum: [none, catcher, allowlist] AuditEvent: type: object description: Append-only auditable history (minimum lineage for 0.2) required: [ts, event, event_id] properties: event_id: type: string sequence: type: integer minimum: 0 ts: type: string format: date-time event: type: string actor: type: string node_id: type: string objective_id: type: string ball_id: type: string resource_id: type: string grant_provenance: $ref: '#/components/schemas/GrantProvenance' prev_event_id: type: string prev_hash: type: string description: Optional chain hash for PROFILE_HARDENED schema_version: type: string example: "0.2" detail: type: object additionalProperties: true DecoderRingProbe: type: object required: [probe_id, meld, decoder_ring_rev] description: | Mind-meld gauge — has label meaning from Silicon/spec synced? properties: ts: type: string format: date-time decoder_ring_rev: type: string example: DR-0.1 sync_code: type: string silicon_rev: type: string spec_version: type: string model_label: type: string probe_id: type: string example: DR-MU-1 meld: type: string enum: [MELD_FULL, MELD_PARTIAL, MELD_LABEL_ONLY, MELD_FAIL] notes: type: string Message: type: object properties: msg_id: type: string to_node: type: string from_node: type: string subject: type: string body: type: string status: type: string sync_code: type: string silicon_rev: type: string MessageSend: type: object description: | sync_code / silicon_rev optional with defined absence: omit = inherit station tip when SYNC_CONFIRMED; if station UNSYNCED, peer SHOULD reject or mark DEGRADED. required: [to_node, body] properties: to_node: type: string subject: type: string body: type: string sync_code: type: string silicon_rev: type: string