JJijibora Docs
docs.jijibora.online
On this page (45 sections)

Lifelong Entities API (non-fungible lifespan) — OpenAPI 1.0.0

<!-- GENERATED by scripts/render-platform-map-api-docs.mjs — do not hand-edit; edit apps/agent-bff/openapi/<spec>.json and re-run. --> Scope: The published reference for Lifelong Entities API (non-fungible lifespan). 37 paths — the measured spec-vs-implementation coverage lives in the complete API inventory. Status: rendered 2026-11-09 from the OpenAPI source for Lifelong Entities API (non-fungible lifespan) — regenerate with node scripts/render-platform-map-api-docs.mjs. See also: the OpenAPI spec index.

Servers

URLNotes
https://dev.agent.jijibora.onlineDokku DEV Agent BFF
https://uat.agent.jijibora.onlineDokku UAT Agent BFF
http://127.0.0.1:3030Local laptop only — not for public codegen

Tags

TagSummary
entities-lifespanMint, resolve, history, aliases, graph, thread
entities-projectionSearch, query profiles, criteria, index projection
entities-governanceLeases, present, packages, backup, anchor, compaction, sourcing deltas

Paths — 37 paths / 39 operations

MethodPathOperation IDSummary
POST/v1/entitiesmintEntityMint an entity (lifelong claim + tip)
GET/v1/entities/resolveresolveEntityResolve an entity by reference (alias/VIN/plate/…).
GET/v1/entities/ops/readinessgetEntitiesReadinessLifelong desk readiness (Soft≠LIVE honesty probe)
GET/v1/entities/{entityId}getEntityProjectionRead the index projection (scrubbed per indexability)
GET/v1/entities/{entityId}/tipgetEntityTipRead the current tip (hash chain head)
GET/v1/entities/{entityId}/aliaseslistEntityAliasesList entity aliases
POST/v1/entities/{entityId}/aliasesregisterEntityAliasRegister an alias
POST/v1/entities/{entityId}/changesappendEntityChangeAppend a hash-chained change
GET/v1/entities/{entityId}/historylistEntityHistoryPaged history (headers; lease-bound)
GET/v1/entities/{entityId}/history/{changeId}getEntityChangeRead one change
GET/v1/entities/{entityId}/threadgetEntityThreadEntity thread (history + projection)
GET/v1/entities/{entityId}/graphgetEntityGraphTruth-graph neighbors (paged)
GET/v1/entities/{entityId}/leaseslistEntityLeasesList active leases
POST/v1/entities/{entityId}/leasesissueEntityLeaseIssue a purpose-scoped lease
POST/v1/entities/{entityId}/leases/cascade-revokecascadeEntityLeasesCascade-revoke leases for a grantee/subject
POST/v1/entities/{entityId}/queryqueryEntityProfileQuery-profile enforced query (search/match/hydrate)
POST/v1/entities/queryqueryEntitiesQuery without a path entity id (body carries entity_id)
POST/v1/internal/entities/queryqueryEntitiesInternalInternal query alias (same enforcement as /v1/entities/query)
POST/v1/entities/searchsearchEntitiesSearch indexed facets (allow-listed only)
POST/v1/entities/{entityId}/presentpresentEntityBBS+ selective-disclosure presentation
POST/v1/entities/{entityId}/packagesissueEntityPackageIssue a sync package for the entity
POST/v1/entities/{entityId}/backup/blindblindBackupEntityRegister a blind backup (ciphertext only)
POST/v1/entities/{entityId}/anchoranchorEntityRequest a fabric anchor for the entity tip
POST/v1/entities/{entityId}/series/chunksregisterSeriesChunkRegister a series chunk
GET/v1/entities/{entityId}/compaction/planplanCompactionCompaction plan (declarative, no side effects)
POST/v1/entities/{entityId}/compaction/runrunCompactionRun compaction (LIVE-gated; refuses until the worker adapter exists)
POST/v1/entities/{entityId}/criteria/normalizenormalizeEntityCriteriaSoft-normalize a change to platform.criteria.v1.entity_state
POST/v1/entities/{entityId}/criteria/publishpublishEntityCriteriaPublish the criteria event (LIVE only with ENTITY_CRITERIA_LIVE=1)
POST/v1/entities/{entityId}/sourcing/offer-deltabuildOfferDeltaBuild a scrubbed offer/capacity delta (Soft, no publish)
POST/v1/entities/{entityId}/sourcing/offer-delta/publishpublishOfferDeltaAppend change → outbox delta → meter/prefilter update (Soft chain)
GET/v1/entities/{entityId}/sourcing/offer-delta/proveproveOfferDeltaProve meter-wake readback (no Surreal poll)
POST/v1/entities/emergency/scrubemergencyScrubEmergency CAP scrub to the sourcing-safe projection (INTRQ-15)
POST/v1/entities/{entityId}/sourcing/publishpublishSourceryPublish-sourcable recipe (exposure + scrubbed claim + outbox → meter)
POST/v1/entities/{entityId}/sourcing/onboardonboardProviderOnboard a provider (affiliation + leases + exposure publish)
POST/v1/entities/{entityId}/panel-meshstandUpPanelMeshPanel mesh recipe (affiliation approve + role lease)
POST/v1/provider-capability/attestationsregisterCapabilityAttestationRegister a customer-signed capability attestation
POST/v1/provider-capability/attestations/verifyverifyCapabilityAttestationVerify an attestation (check only)
POST/v1/provider-capability/intakeintakeCapabilityIntake a provider capability feed (field-map → upsert)
POST/v1/sourcing/admitgateSourcingAdmitVerifier gate for sourcing admits (customer-key atest check)

Operations

POST /v1/entities

Summary: Mint an entity (lifelong claim + tip)

Tags: entities-lifespan Operation ID: mintEntity Responses:

StatusMeaning
201Entity minted; returns entity_id and tip hash
402Membership/tip gate refused

GET /v1/entities/resolve

Summary: Resolve an entity by reference (alias/VIN/plate/…).

Tags: entities-lifespan Operation ID: resolveEntity

Parameters:

NameInRequiredTypeNotes
refquerynostring

Responses:

StatusMeaning
200Canonical entity binding
404unresolvable ref

GET /v1/entities/ops/readiness

Summary: Lifelong desk readiness (Soft≠LIVE honesty probe)

Tags: entities-governance Operation ID: getEntitiesReadiness Responses:

StatusMeaning
200Tip KV / index / criteria + fabric probe status

GET /v1/entities/{entityId}

Summary: Read the index projection (scrubbed per indexability)

Tags: entities-lifespan Operation ID: getEntityProjection

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Scrubbed projection (facets only)
404entity_not_found

GET /v1/entities/{entityId}/tip

Summary: Read the current tip (hash chain head)

Tags: entities-lifespan Operation ID: getEntityTip

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Tip record

GET /v1/entities/{entityId}/aliases

Summary: List entity aliases

Tags: entities-lifespan Operation ID: listEntityAliases

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Alias bindings

POST /v1/entities/{entityId}/aliases

Summary: Register an alias

Tags: entities-lifespan Operation ID: registerEntityAlias

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Alias bound

POST /v1/entities/{entityId}/changes

Summary: Append a hash-chained change

Tags: entities-lifespan Operation ID: appendEntityChange

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
201Change appended; returns change_id + tip hash

GET /v1/entities/{entityId}/history

Summary: Paged history (headers; lease-bound)

Tags: entities-lifespan Operation ID: listEntityHistory

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring
limitquerynoint
cursorquerynostring

Responses:

StatusMeaning
200History page

GET /v1/entities/{entityId}/history/{changeId}

Summary: Read one change

Tags: entities-lifespan Operation ID: getEntityChange

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring
changeIdpathyesstring

Responses:

StatusMeaning
200Change record
404change_not_found

GET /v1/entities/{entityId}/thread

Summary: Entity thread (history + projection)

Tags: entities-lifespan Operation ID: getEntityThread

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Thread view

GET /v1/entities/{entityId}/graph

Summary: Truth-graph neighbors (paged)

Tags: entities-lifespan Operation ID: getEntityGraph

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Graph page

GET /v1/entities/{entityId}/leases

Summary: List active leases

Tags: entities-governance Operation ID: listEntityLeases

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Active leases

POST /v1/entities/{entityId}/leases

Summary: Issue a purpose-scoped lease

Tags: entities-governance Operation ID: issueEntityLease

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
201Lease issued (purpose + TTL + grantee)
422Lease refused (purpose not permitted for the grantee)

POST /v1/entities/{entityId}/leases/cascade-revoke

Summary: Cascade-revoke leases for a grantee/subject

Tags: entities-governance Operation ID: cascadeEntityLeases

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Cascade complete

POST /v1/entities/{entityId}/query

Summary: Query-profile enforced query (search/match/hydrate) Description: Mode is gated by the consumer's query_profile (forbidden modes refuse). Hydrate is forbidden for sourcing consumers and returns the sealed-payload guidance.

Tags: entities-projection Operation ID: queryEntityProfile

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Request body:

Content type: application/json

FieldTypeNotes
modestring enum: projection, resolve, history_headers, thread, proof, predicate, hydrate, graph,…
consumerstring
lease_idstring

Responses:

StatusMeaning
200Profile-enforced result
403mode_forbidden_for_consumer / mode_not_allowed
422query_profile_missing (fail closed) or use_dedicated_opaque_path

POST /v1/entities/query

Summary: Query without a path entity id (body carries entity_id)

Tags: entities-projection Operation ID: queryEntities Responses:

StatusMeaning
200Profile-enforced result
403Forbidden mode

POST /v1/internal/entities/query

Summary: Internal query alias (same enforcement as /v1/entities/query)

Tags: entities-projection Operation ID: queryEntitiesInternal Responses:

StatusMeaning
200Profile-enforced result
403Forbidden mode

POST /v1/entities/search

Summary: Search indexed facets (allow-listed only)

Tags: entities-projection Operation ID: searchEntities Responses:

StatusMeaning
200Facet search results

POST /v1/entities/{entityId}/present

Summary: BBS+ selective-disclosure presentation

Tags: entities-governance Operation ID: presentEntity

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Credential envelope (no sealed payload)
422Lease required for present

POST /v1/entities/{entityId}/packages

Summary: Issue a sync package for the entity

Tags: entities-governance Operation ID: issueEntityPackage

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Package issued

POST /v1/entities/{entityId}/backup/blind

Summary: Register a blind backup (ciphertext only)

Tags: entities-governance Operation ID: blindBackupEntity

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Blind backup registered

POST /v1/entities/{entityId}/anchor

Summary: Request a fabric anchor for the entity tip

Tags: entities-governance Operation ID: anchorEntity

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
202Anchor requested

POST /v1/entities/{entityId}/series/chunks

Summary: Register a series chunk

Tags: entities-lifespan Operation ID: registerSeriesChunk

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
201Chunk registered

GET /v1/entities/{entityId}/compaction/plan

Summary: Compaction plan (declarative, no side effects)

Tags: entities-governance Operation ID: planCompaction

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Compaction plan

POST /v1/entities/{entityId}/compaction/run

Summary: Run compaction (LIVE-gated; refuses until the worker adapter exists)

Tags: entities-governance Operation ID: runCompaction

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
503invent_refuse_live (no LIVE compaction adapter yet)

POST /v1/entities/{entityId}/criteria/normalize

Summary: Soft-normalize a change to platform.criteria.v1.entity_state Description: Facets only (indexability-scrubbed); raw metadata refused. No publish.

Tags: entities-projection Operation ID: normalizeEntityCriteria

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Request body:

Content type: application/json

FieldTypeNotes
facetsobject
event_typestring
change_hashstring

Responses:

StatusMeaning
200Criteria envelope (Soft; live: false)
422facets_required_not_raw_metadata

POST /v1/entities/{entityId}/criteria/publish

Summary: Publish the criteria event (LIVE only with ENTITY_CRITERIA_LIVE=1)

Tags: entities-projection Operation ID: publishEntityCriteria

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Published
503invent_refuse_live (no criteria plane)

POST /v1/entities/{entityId}/sourcing/offer-delta

Summary: Build a scrubbed offer/capacity delta (Soft, no publish)

Tags: entities-governance Operation ID: buildOfferDelta

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Delta envelope preview
422exposure_sourcing_required / cap_scrub_leak

POST /v1/entities/{entityId}/sourcing/offer-delta/publish

Summary: Append change → outbox delta → meter/prefilter update (Soft chain)

Tags: entities-governance Operation ID: publishOfferDelta

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Chain result (meter wake)
503counter_plane_down (invent_refuse on LIVE)

GET /v1/entities/{entityId}/sourcing/offer-delta/prove

Summary: Prove meter-wake readback (no Surreal poll)

Tags: entities-governance Operation ID: proveOfferDelta

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring
meter_keyquerynostring

Responses:

StatusMeaning
200Wake proof (surreally_polled: false)

POST /v1/entities/emergency/scrub

Summary: Emergency CAP scrub to the sourcing-safe projection (INTRQ-15)

Tags: entities-governance Operation ID: emergencyScrub Responses:

StatusMeaning
200Scrubbed projection
422scrub_profile_missing / cap_scrub_leak

POST /v1/entities/{entityId}/sourcing/publish

Summary: Publish-sourcable recipe (exposure + scrubbed claim + outbox → meter)

Tags: entities-governance Operation ID: publishSourcery

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Published offer (claim + meter)
422profile missing / sealed leak / default-deny
503counter plane down (LIVE)

POST /v1/entities/{entityId}/sourcing/onboard

Summary: Onboard a provider (affiliation + leases + exposure publish)

Tags: entities-governance Operation ID: onboardProvider

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Per-step ledger

POST /v1/entities/{entityId}/panel-mesh

Summary: Panel mesh recipe (affiliation approve + role lease)

Tags: entities-governance Operation ID: standUpPanelMesh

Parameters:

NameInRequiredTypeNotes
entityIdpathyesstring

Responses:

StatusMeaning
200Affiliation + lease
503affiliation_plane_down (invent_refuse)

POST /v1/provider-capability/attestations

Summary: Register a customer-signed capability attestation

Tags: entities-governance Operation ID: registerCapabilityAttestation Responses:

StatusMeaning
201Attestation registered (verified)
422vendor key / expired / invalid signature

POST /v1/provider-capability/attestations/verify

Summary: Verify an attestation (check only)

Tags: entities-governance Operation ID: verifyCapabilityAttestation Responses:

StatusMeaning
200Valid attestation
422Invalid attestation

POST /v1/provider-capability/intake

Summary: Intake a provider capability feed (field-map → upsert)

Tags: entities-governance Operation ID: intakeCapability Responses:

StatusMeaning
200Intake mapped + validated (Soft)
422Map unknown / contract violation

POST /v1/sourcing/admit

Summary: Verifier gate for sourcing admits (customer-key atest check)

Tags: entities-governance Operation ID: gateSourcingAdmit Responses:

StatusMeaning
200Admitted (verified attestation)
422attestation_required / invalid / expired

Full specification — verbatim source of truth

{
  "openapi": "3.1.0",
  "info": {
    "title": "Lifelong Entities API (non-fungible lifespan)",
    "version": "1.0.0",
    "description": "Universal lifelong entity façade: mint, resolve, change-append (hash-chained history), index projection, search, query profiles, leases, evidence present, packages, blind backup, fabric anchor, series chunks, and sourcing offer deltas. Any non-fungible asset CNS type (vehicle, building, person, organization, resource) shares this single surface; disclosure is controlled per type by indexability profiles (allow/deny fields) and query profiles (forbid-hydrate for sourcing). Soft≠LIVE: sealed payloads require purpose leases; hydrate through this façade is forbidden for sourcing consumers. Never invent sealed/LIVE success."
  },
  "servers": [
    {
      "url": "https://dev.agent.jijibora.online",
      "description": "Dokku DEV Agent BFF"
    },
    {
      "url": "https://uat.agent.jijibora.online",
      "description": "Dokku UAT Agent BFF"
    },
    {
      "url": "http://127.0.0.1:3030",
      "description": "Local laptop only — not for public codegen"
    }
  ],
  "tags": [
    {
      "name": "entities-lifespan",
      "description": "Mint, resolve, history, aliases, graph, thread"
    },
    {
      "name": "entities-projection",
      "description": "Search, query profiles, criteria, index projection"
    },
    {
      "name": "entities-governance",
      "description": "Leases, present, packages, backup, anchor, compaction, sourcing deltas"
    }
  ],
  "paths": {
    "/v1/entities": {
      "post": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Mint an entity (lifelong claim + tip)",
        "operationId": "mintEntity",
        "responses": {
          "201": {
            "description": "Entity minted; returns entity_id and tip hash"
          },
          "402": {
            "description": "Membership/tip gate refused"
          }
        }
      }
    },
    "/v1/entities/resolve": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Resolve an entity by reference (alias/VIN/plate/…).",
        "operationId": "resolveEntity",
        "parameters": [
          {
            "name": "ref",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Canonical entity binding"
          },
          "404": {
            "description": "unresolvable ref"
          }
        }
      }
    },
    "/v1/entities/ops/readiness": {
      "get": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Lifelong desk readiness (Soft≠LIVE honesty probe)",
        "operationId": "getEntitiesReadiness",
        "responses": {
          "200": {
            "description": "Tip KV / index / criteria + fabric probe status"
          }
        }
      }
    },
    "/v1/entities/{entityId}": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Read the index projection (scrubbed per indexability)",
        "operationId": "getEntityProjection",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Scrubbed projection (facets only)"
          },
          "404": {
            "description": "entity_not_found"
          }
        }
      }
    },
    "/v1/entities/{entityId}/tip": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Read the current tip (hash chain head)",
        "operationId": "getEntityTip",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tip record"
          }
        }
      }
    },
    "/v1/entities/{entityId}/aliases": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "List entity aliases",
        "operationId": "listEntityAliases",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alias bindings"
          }
        }
      },
      "post": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Register an alias",
        "operationId": "registerEntityAlias",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alias bound"
          }
        }
      }
    },
    "/v1/entities/{entityId}/changes": {
      "post": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Append a hash-chained change",
        "operationId": "appendEntityChange",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Change appended; returns change_id + tip hash"
          }
        }
      }
    },
    "/v1/entities/{entityId}/history": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Paged history (headers; lease-bound)",
        "operationId": "listEntityHistory",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "History page"
          }
        }
      }
    },
    "/v1/entities/{entityId}/history/{changeId}": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Read one change",
        "operationId": "getEntityChange",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "changeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Change record"
          },
          "404": {
            "description": "change_not_found"
          }
        }
      }
    },
    "/v1/entities/{entityId}/thread": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Entity thread (history + projection)",
        "operationId": "getEntityThread",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Thread view"
          }
        }
      }
    },
    "/v1/entities/{entityId}/graph": {
      "get": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Truth-graph neighbors (paged)",
        "operationId": "getEntityGraph",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Graph page"
          }
        }
      }
    },
    "/v1/entities/{entityId}/leases": {
      "get": {
        "tags": [
          "entities-governance"
        ],
        "summary": "List active leases",
        "operationId": "listEntityLeases",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active leases"
          }
        }
      },
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Issue a purpose-scoped lease",
        "operationId": "issueEntityLease",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Lease issued (purpose + TTL + grantee)"
          },
          "422": {
            "description": "Lease refused (purpose not permitted for the grantee)"
          }
        }
      }
    },
    "/v1/entities/{entityId}/leases/cascade-revoke": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Cascade-revoke leases for a grantee/subject",
        "operationId": "cascadeEntityLeases",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cascade complete"
          }
        }
      }
    },
    "/v1/entities/{entityId}/query": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Query-profile enforced query (search/match/hydrate)",
        "description": "Mode is gated by the consumer's query_profile (forbidden modes refuse). Hydrate is forbidden for sourcing consumers and returns the sealed-payload guidance.",
        "operationId": "queryEntityProfile",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "projection",
                      "resolve",
                      "history_headers",
                      "thread",
                      "proof",
                      "predicate",
                      "hydrate",
                      "graph",
                      "anchor",
                      "search"
                    ]
                  },
                  "consumer": {
                    "type": "string",
                    "example": "sourcing"
                  },
                  "lease_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile-enforced result"
          },
          "403": {
            "description": "mode_forbidden_for_consumer / mode_not_allowed"
          },
          "422": {
            "description": "query_profile_missing (fail closed) or use_dedicated_opaque_path"
          }
        }
      }
    },
    "/v1/entities/query": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Query without a path entity id (body carries entity_id)",
        "operationId": "queryEntities",
        "responses": {
          "200": {
            "description": "Profile-enforced result"
          },
          "403": {
            "description": "Forbidden mode"
          }
        }
      }
    },
    "/v1/internal/entities/query": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Internal query alias (same enforcement as /v1/entities/query)",
        "operationId": "queryEntitiesInternal",
        "responses": {
          "200": {
            "description": "Profile-enforced result"
          },
          "403": {
            "description": "Forbidden mode"
          }
        }
      }
    },
    "/v1/entities/search": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Search indexed facets (allow-listed only)",
        "operationId": "searchEntities",
        "responses": {
          "200": {
            "description": "Facet search results"
          }
        }
      }
    },
    "/v1/entities/{entityId}/present": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "BBS+ selective-disclosure presentation",
        "operationId": "presentEntity",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Credential envelope (no sealed payload)"
          },
          "422": {
            "description": "Lease required for present"
          }
        }
      }
    },
    "/v1/entities/{entityId}/packages": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Issue a sync package for the entity",
        "operationId": "issueEntityPackage",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Package issued"
          }
        }
      }
    },
    "/v1/entities/{entityId}/backup/blind": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Register a blind backup (ciphertext only)",
        "operationId": "blindBackupEntity",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Blind backup registered"
          }
        }
      }
    },
    "/v1/entities/{entityId}/anchor": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Request a fabric anchor for the entity tip",
        "operationId": "anchorEntity",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Anchor requested"
          }
        }
      }
    },
    "/v1/entities/{entityId}/series/chunks": {
      "post": {
        "tags": [
          "entities-lifespan"
        ],
        "summary": "Register a series chunk",
        "operationId": "registerSeriesChunk",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Chunk registered"
          }
        }
      }
    },
    "/v1/entities/{entityId}/compaction/plan": {
      "get": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Compaction plan (declarative, no side effects)",
        "operationId": "planCompaction",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Compaction plan"
          }
        }
      }
    },
    "/v1/entities/{entityId}/compaction/run": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Run compaction (LIVE-gated; refuses until the worker adapter exists)",
        "operationId": "runCompaction",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "503": {
            "description": "invent_refuse_live (no LIVE compaction adapter yet)"
          }
        }
      }
    },
    "/v1/entities/{entityId}/criteria/normalize": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Soft-normalize a change to platform.criteria.v1.entity_state",
        "description": "Facets only (indexability-scrubbed); raw metadata refused. No publish.",
        "operationId": "normalizeEntityCriteria",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "facets": {
                    "type": "object"
                  },
                  "event_type": {
                    "type": "string"
                  },
                  "change_hash": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Criteria envelope (Soft; live: false)"
          },
          "422": {
            "description": "facets_required_not_raw_metadata"
          }
        }
      }
    },
    "/v1/entities/{entityId}/criteria/publish": {
      "post": {
        "tags": [
          "entities-projection"
        ],
        "summary": "Publish the criteria event (LIVE only with ENTITY_CRITERIA_LIVE=1)",
        "operationId": "publishEntityCriteria",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published"
          },
          "503": {
            "description": "invent_refuse_live (no criteria plane)"
          }
        }
      }
    },
    "/v1/entities/{entityId}/sourcing/offer-delta": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Build a scrubbed offer/capacity delta (Soft, no publish)",
        "operationId": "buildOfferDelta",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delta envelope preview"
          },
          "422": {
            "description": "exposure_sourcing_required / cap_scrub_leak"
          }
        }
      }
    },
    "/v1/entities/{entityId}/sourcing/offer-delta/publish": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Append change → outbox delta → meter/prefilter update (Soft chain)",
        "operationId": "publishOfferDelta",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Chain result (meter wake)"
          },
          "503": {
            "description": "counter_plane_down (invent_refuse on LIVE)"
          }
        }
      }
    },
    "/v1/entities/{entityId}/sourcing/offer-delta/prove": {
      "get": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Prove meter-wake readback (no Surreal poll)",
        "operationId": "proveOfferDelta",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "meter_key",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wake proof (surreally_polled: false)"
          }
        }
      }
    },
    "/v1/entities/emergency/scrub": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Emergency CAP scrub to the sourcing-safe projection (INTRQ-15)",
        "operationId": "emergencyScrub",
        "responses": {
          "200": {
            "description": "Scrubbed projection"
          },
          "422": {
            "description": "scrub_profile_missing / cap_scrub_leak"
          }
        }
      }
    },
    "/v1/entities/{entityId}/sourcing/publish": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Publish-sourcable recipe (exposure + scrubbed claim + outbox → meter)",
        "operationId": "publishSourcery",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published offer (claim + meter)"
          },
          "422": {
            "description": "profile missing / sealed leak / default-deny"
          },
          "503": {
            "description": "counter plane down (LIVE)"
          }
        }
      }
    },
    "/v1/entities/{entityId}/sourcing/onboard": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Onboard a provider (affiliation + leases + exposure publish)",
        "operationId": "onboardProvider",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Per-step ledger"
          }
        }
      }
    },
    "/v1/entities/{entityId}/panel-mesh": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Panel mesh recipe (affiliation approve + role lease)",
        "operationId": "standUpPanelMesh",
        "parameters": [
          {
            "name": "entityId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Affiliation + lease"
          },
          "503": {
            "description": "affiliation_plane_down (invent_refuse)"
          }
        }
      }
    },
    "/v1/provider-capability/attestations": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Register a customer-signed capability attestation",
        "operationId": "registerCapabilityAttestation",
        "responses": {
          "201": {
            "description": "Attestation registered (verified)"
          },
          "422": {
            "description": "vendor key / expired / invalid signature"
          }
        }
      }
    },
    "/v1/provider-capability/attestations/verify": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Verify an attestation (check only)",
        "operationId": "verifyCapabilityAttestation",
        "responses": {
          "200": {
            "description": "Valid attestation"
          },
          "422": {
            "description": "Invalid attestation"
          }
        }
      }
    },
    "/v1/provider-capability/intake": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Intake a provider capability feed (field-map → upsert)",
        "operationId": "intakeCapability",
        "responses": {
          "200": {
            "description": "Intake mapped + validated (Soft)"
          },
          "422": {
            "description": "Map unknown / contract violation"
          }
        }
      }
    },
    "/v1/sourcing/admit": {
      "post": {
        "tags": [
          "entities-governance"
        ],
        "summary": "Verifier gate for sourcing admits (customer-key atest check)",
        "operationId": "gateSourcingAdmit",
        "responses": {
          "200": {
            "description": "Admitted (verified attestation)"
          },
          "422": {
            "description": "attestation_required / invalid / expired"
          }
        }
      }
    }
  },
  "x-cross-vertical": {
    "note": "One façade for every non-fungible asset CNS type. Never insurance-named: the lifecycles here are the same for vehicle, building, person, organization and resource principals; insurer/motor filing is one pack among many (claim_processing.md), not a branch.",
    "cns_type_examples": [
      "cns://claim/type/entity/vehicle",
      "cns://claim/type/entity/building",
      "cns://claim/type/person",
      "cns://claim/type/organization",
      "cns://claim/type/resource"
    ],
    "compose_with_claims": "Processing claims link entities via metadata.entity_id; entities link claims via links. The voyage (correlation_id) joins both planes.",
    "query_profiles": "sourcing forbids hydrate (CAPSRC-03); emergency mirrors the rule (INTRQ-15)."
  }
}