DocsThe data protocol
spec/v1
packages/core/schema/flower.schema.jsonOn this page
$defs.spec of urn:petal:schema:flower:v1
Fields
| Field | Type or allowed values | Presence in its parent | Description |
|---|---|---|---|
petal |
"spec/v1" | Required | |
network |
object | Required | |
network.id |
string | Required | |
network.chain |
string | Required | |
network.population |
string | Required | |
network.params |
object | Optional | |
network.params.* |
string | Optional | |
snapshot |
object | Required | |
snapshot.sha256 |
string | Required | |
snapshot.as_of |
string | Required | |
snapshot.block_height |
integer | Optional | |
labels |
choice | Required | |
labels (variant 1) |
"none" | Required | |
labels (variant 2) |
object | Required | |
labels (variant 2).sha256 |
string | Required | |
selection |
object | Required | |
selection.measure |
string | Required | |
selection.petals |
integer | Required | most petals to draw before the tail; a network with fewer included participants gets one petal each and no tail |
selection.tail |
object | Required | |
selection.tail.group |
boolean | Required | |
selection.tail.label |
string | Required | |
encodings |
object | Required | |
encodings.width |
object | Required | |
encodings.width.by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.width.scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.width.max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.width.meaning |
string | Required | plain words shown in the legend |
encodings.width.sources |
array | Required | |
encodings.width.sources[] |
string | Required | |
encodings.height |
object | Required | |
encodings.height.by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.height.scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.height.max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.height.meaning |
string | Required | plain words shown in the legend |
encodings.height.sources |
array | Required | |
encodings.height.sources[] |
string | Required | |
encodings.colour |
object | Required | |
encodings.colour.by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.colour.scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.colour.max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.colour.meaning |
string | Required | plain words shown in the legend |
encodings.colour.sources |
array | Required | |
encodings.colour.sources[] |
string | Required | |
encodings.outline |
choice | Required | |
encodings.outline (variant 1) |
null | Required | |
encodings.outline (variant 2) |
object | Required | |
encodings.outline (variant 2).by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.outline (variant 2).scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.outline (variant 2).max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.outline (variant 2).meaning |
string | Required | plain words shown in the legend |
encodings.outline (variant 2).sources |
array | Required | |
encodings.outline (variant 2).sources[] |
string | Required | |
encodings.segments |
choice | Required | |
encodings.segments (variant 1) |
null | Required | |
encodings.segments (variant 2) |
object | Required | |
encodings.segments (variant 2).by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.segments (variant 2).scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.segments (variant 2).max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.segments (variant 2).meaning |
string | Required | plain words shown in the legend |
encodings.segments (variant 2).sources |
array | Required | |
encodings.segments (variant 2).sources[] |
string | Required | |
encodings.lines |
choice | Optional | |
encodings.lines (variant 1) |
null | Optional | |
encodings.lines (variant 2) |
object | Optional | |
encodings.lines (variant 2).by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.lines (variant 2).scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.lines (variant 2).max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.lines (variant 2).meaning |
string | Required | plain words shown in the legend |
encodings.lines (variant 2).sources |
array | Required | |
encodings.lines (variant 2).sources[] |
string | Required | |
encodings.markings |
choice | Optional | |
encodings.markings (variant 1) |
null | Optional | |
encodings.markings (variant 2) |
object | Optional | |
encodings.markings (variant 2).by |
string | Required | what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status) |
encodings.markings (variant 2).scale |
"sqrt" / "linear" / "log" / "log-band" / "equal" | Optional | |
encodings.markings (variant 2).max_ratio |
number | Optional | width only: widest side / narrowest side |
encodings.markings (variant 2).meaning |
string | Required | plain words shown in the legend |
encodings.markings (variant 2).sources |
array | Required | |
encodings.markings (variant 2).sources[] |
string | Required | |
encodings.order |
object | Required | order is a primitive like any other: it declares what drives it, what it means, and its sources (constitution I) |
encodings.order.by |
"measure_desc" / "measure_asc" / "id" / "join_date" / "last_active" | Required | petals run clockwise from twelve o'clock in this order; default/v1 uses measure_desc |
encodings.order.meaning |
string | Required | plain words for the legend, e.g. 'largest first, clockwise from the top' |
encodings.order.sources |
array | Required | |
encodings.order.sources[] |
string | Required | |
convention |
object | Required | |
convention.id |
string | Required | default/v1, or a named convention |
convention.variation_of |
choice | Required | spec_sha256 of the spec this one changes |
convention.variation_of (variant 1) |
null | Required | |
convention.variation_of (variant 2) |
string | Required | |
convention.changes |
array | Required | |
convention.changes[] |
string | Required |
Examples
spec.v1.json
{
"petal": "spec/v1",
"network": {
"id": "sample-pools",
"chain": "near:mainnet",
"population": "validators"
},
"snapshot": {
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"as_of": "2026-11-03T19:42:00Z",
"block_height": 222915356
},
"labels": "none",
"selection": {
"measure": "validator_stake_current_epoch",
"petals": 60,
"tail": {
"group": true,
"label": "everyone else"
}
},
"encodings": {
"width": {
"by": "share",
"scale": "log",
"max_ratio": 2,
"meaning": "share of stake, in a 2x band",
"sources": [
"rpc-validators"
]
},
"height": {
"by": "share",
"scale": "sqrt",
"meaning": "square root of share",
"sources": [
"rpc-validators"
]
},
"colour": {
"by": "kind",
"meaning": "kind of account",
"sources": [
"rpc-validators"
]
},
"outline": {
"by": "identity_status",
"meaning": "solid: self-declared or verified; dashed: inferred",
"sources": [
"rpc-validators"
]
},
"segments": null,
"order": {
"by": "measure_desc",
"meaning": "largest first, clockwise from the top",
"sources": [
"rpc-validators"
]
}
},
"convention": {
"id": "default/v1",
"variation_of": null,
"changes": []
}
}
Full schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:petal:schema:spec:v1",
"title": "Petal spec v1",
"description": "$defs.spec of urn:petal:schema:flower:v1",
"$ref": "#/$defs/spec",
"$defs": {
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"datetime": {
"type": "string",
"format": "date-time"
},
"sourceIds": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"encoding": {
"type": "object",
"required": [
"by",
"meaning",
"sources"
],
"additionalProperties": false,
"properties": {
"by": {
"type": "string",
"description": "what drives the primitive, from the network's capabilities (e.g. share, kind, backers, identity_status)"
},
"scale": {
"enum": [
"sqrt",
"linear",
"log",
"log-band",
"equal"
]
},
"max_ratio": {
"type": "number",
"minimum": 1,
"maximum": 3,
"description": "width only: widest side / narrowest side"
},
"meaning": {
"type": "string",
"minLength": 3,
"description": "plain words shown in the legend"
},
"sources": {
"$ref": "#/$defs/sourceIds"
}
}
},
"orderEncoding": {
"type": "object",
"required": [
"by",
"meaning",
"sources"
],
"additionalProperties": false,
"description": "order is a primitive like any other: it declares what drives it, what it means, and its sources (constitution I)",
"properties": {
"by": {
"enum": [
"measure_desc",
"measure_asc",
"id",
"join_date",
"last_active"
],
"description": "petals run clockwise from twelve o'clock in this order; default/v1 uses measure_desc"
},
"meaning": {
"type": "string",
"minLength": 3,
"description": "plain words for the legend, e.g. 'largest first, clockwise from the top'"
},
"sources": {
"$ref": "#/$defs/sourceIds"
}
}
},
"spec": {
"type": "object",
"required": [
"petal",
"network",
"snapshot",
"labels",
"selection",
"encodings",
"convention"
],
"additionalProperties": false,
"properties": {
"petal": {
"const": "spec/v1"
},
"network": {
"type": "object",
"required": [
"id",
"chain",
"population"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"chain": {
"type": "string"
},
"population": {
"type": "string"
},
"params": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"snapshot": {
"type": "object",
"required": [
"sha256",
"as_of"
],
"additionalProperties": false,
"properties": {
"sha256": {
"$ref": "#/$defs/sha256"
},
"as_of": {
"$ref": "#/$defs/datetime"
},
"block_height": {
"type": "integer"
}
}
},
"labels": {
"oneOf": [
{
"const": "none"
},
{
"type": "object",
"required": [
"sha256"
],
"additionalProperties": false,
"properties": {
"sha256": {
"$ref": "#/$defs/sha256"
}
}
}
]
},
"selection": {
"type": "object",
"required": [
"measure",
"petals",
"tail"
],
"additionalProperties": false,
"properties": {
"measure": {
"type": "string"
},
"petals": {
"type": "integer",
"minimum": 5,
"maximum": 300,
"description": "most petals to draw before the tail; a network with fewer included participants gets one petal each and no tail"
},
"tail": {
"type": "object",
"required": [
"group",
"label"
],
"additionalProperties": false,
"properties": {
"group": {
"type": "boolean"
},
"label": {
"type": "string"
}
}
}
}
},
"encodings": {
"type": "object",
"required": [
"width",
"height",
"colour",
"outline",
"segments",
"order"
],
"additionalProperties": false,
"properties": {
"width": {
"$ref": "#/$defs/encoding"
},
"height": {
"$ref": "#/$defs/encoding"
},
"colour": {
"$ref": "#/$defs/encoding"
},
"outline": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/encoding"
}
]
},
"segments": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/encoding"
}
]
},
"lines": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/encoding"
}
]
},
"markings": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/encoding"
}
]
},
"order": {
"$ref": "#/$defs/orderEncoding"
}
}
},
"convention": {
"type": "object",
"required": [
"id",
"variation_of",
"changes"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "default/v1, or a named convention"
},
"variation_of": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/sha256"
}
],
"description": "spec_sha256 of the spec this one changes"
},
"changes": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"interpretation": {
"type": "object",
"required": [
"summary",
"power_means",
"mappings",
"conflicts",
"unknowns",
"inferred",
"documents"
],
"additionalProperties": false,
"properties": {
"summary": {
"type": "string",
"minLength": 20
},
"power_means": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"claim",
"sources"
],
"additionalProperties": false,
"properties": {
"claim": {
"type": "string"
},
"sources": {
"$ref": "#/$defs/sourceIds"
},
"figures": {
"type": "array",
"items": {
"type": "string",
"pattern": "^fig:"
}
}
}
}
},
"mappings": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"primitive",
"why",
"sources"
],
"additionalProperties": false,
"properties": {
"primitive": {
"enum": [
"width",
"height",
"colour",
"outline",
"segments",
"lines",
"markings",
"order"
]
},
"why": {
"type": "string"
},
"sources": {
"$ref": "#/$defs/sourceIds"
}
}
}
},
"conflicts": {
"type": "array",
"items": {
"type": "string"
}
},
"unknowns": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"inferred": {
"type": "array",
"items": {
"type": "string"
}
},
"documents": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"kind",
"url",
"fetched_at"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"kind": {
"enum": [
"docs",
"forum",
"constitution",
"chain",
"news",
"other"
]
},
"url": {
"type": "string"
},
"title": {
"type": "string"
},
"fetched_at": {
"$ref": "#/$defs/datetime"
}
}
}
}
}
},
"nep413Proof": {
"type": "object",
"required": [
"type",
"account_id",
"public_key",
"signature",
"message",
"nonce",
"recipient"
],
"additionalProperties": false,
"properties": {
"type": {
"const": "nep413"
},
"account_id": {
"type": "string"
},
"public_key": {
"type": "string",
"pattern": "^ed25519:"
},
"signature": {
"type": "string",
"description": "base64"
},
"message": {
"type": "string",
"description": "JSON text: {\"petal\":\"publish/v1\",\"entry_sha256\":\"...\"}"
},
"nonce": {
"type": "string",
"description": "base64 of 32 bytes issued by Petals' server"
},
"recipient": {
"type": "string"
}
}
},
"modelSignature": {
"type": "object",
"required": [
"provider",
"model",
"completion_id",
"signature_kind",
"text",
"signature",
"signing_address",
"signing_algo",
"request_sha256",
"response_sha256",
"fetched_at"
],
"additionalProperties": false,
"properties": {
"provider": {
"const": "near-ai-cloud"
},
"model": {
"type": "string",
"description": "canonical model id, requested with x-no-aliasing: true"
},
"completion_id": {
"type": "string"
},
"signature_kind": {
"enum": [
"provider_tee",
"gateway"
]
},
"text": {
"type": "string",
"description": "what was signed, as returned: model:sha256(request):sha256(response) for provider_tee"
},
"signature": {
"type": "string"
},
"signing_address": {
"type": "string"
},
"signing_algo": {
"enum": [
"ecdsa",
"ed25519"
]
},
"request_sha256": {
"$ref": "#/$defs/sha256"
},
"response_sha256": {
"$ref": "#/$defs/sha256"
},
"attestation": {
"type": "object",
"description": "the attestation report fetched before the completion, stored by Petals because the report endpoint needs a key",
"additionalProperties": false,
"properties": {
"nonce": {
"type": "string"
},
"report_sha256": {
"$ref": "#/$defs/sha256"
},
"report_url": {
"type": "string",
"description": "where anyone can read the full report: Petals' API at /api/v1/attestations/<report_sha256> (http-api.md)"
}
}
},
"fetched_at": {
"$ref": "#/$defs/datetime"
}
}
},
"correction": {
"type": "object",
"description": "a request to correct or remove an identity link or label (FR-022); key petal/v1/correction/<flower_id>/<id>; see shared-map.md",
"required": [
"petal",
"id",
"flower_id",
"target",
"request",
"reason",
"requester",
"proof",
"written_at"
],
"additionalProperties": false,
"properties": {
"petal": {
"const": "correction/v1"
},
"id": {
"type": "string",
"pattern": "^[0-9a-f]{24}$",
"description": "first 24 hex of SHA-256 of the canonical request without id and proof"
},
"flower_id": {
"type": "string",
"pattern": "^[0-9a-f]{24}$"
},
"target": {
"type": "object",
"required": [
"participant",
"caip2",
"address"
],
"additionalProperties": false,
"properties": {
"participant": {
"type": "string"
},
"caip2": {
"type": "string"
},
"address": {
"type": "string"
},
"label_key": {
"type": "string"
}
}
},
"request": {
"enum": [
"correct",
"remove"
]
},
"reason": {
"type": "string",
"minLength": 3
},
"evidence": {
"type": "array",
"items": {
"type": "object",
"required": [
"kind",
"url"
],
"additionalProperties": false,
"properties": {
"kind": {
"type": "string"
},
"url": {
"type": "string"
},
"note": {
"type": "string"
}
}
}
},
"requester": {
"type": "string",
"description": "NEAR account of the person asking"
},
"proof": {
"$ref": "#/$defs/nep413Proof"
},
"written_at": {
"$ref": "#/$defs/datetime"
}
}
},
"entryProvenance": {
"type": "object",
"required": [
"maker",
"agent",
"tools_version",
"created_at"
],
"additionalProperties": false,
"properties": {
"maker": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/nep413Proof"
}
],
"description": "null only for hero fixtures shipped in the repo"
},
"agent": {
"type": "object",
"required": [
"kind"
],
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"petal-agent",
"own-agent",
"hand-written"
]
},
"name": {
"type": "string",
"description": "e.g. claude-code, codex, ironclaw"
},
"model": {
"type": "string"
},
"signature": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/modelSignature"
}
]
}
}
},
"tools_version": {
"type": "string"
},
"created_at": {
"$ref": "#/$defs/datetime"
}
}
},
"entrySnapshot": {
"type": "object",
"required": [
"sha256",
"urls"
],
"additionalProperties": false,
"properties": {
"sha256": {
"$ref": "#/$defs/sha256"
},
"urls": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"entryV1": {
"type": "object",
"description": "id and signature cover everything but id, render_sha256 included. Still read and verified, no longer written.",
"required": [
"petal",
"id",
"spec",
"spec_sha256",
"interpretation",
"snapshot",
"render_sha256",
"provenance"
],
"additionalProperties": false,
"properties": {
"petal": {
"const": "flower/v1"
},
"id": {
"type": "string",
"pattern": "^[0-9a-f]{24}$"
},
"title": {
"type": "string"
},
"spec": {
"$ref": "#/$defs/spec"
},
"spec_sha256": {
"$ref": "#/$defs/sha256"
},
"interpretation": {
"$ref": "#/$defs/interpretation"
},
"snapshot": {
"$ref": "#/$defs/entrySnapshot"
},
"render_sha256": {
"$ref": "#/$defs/sha256"
},
"provenance": {
"$ref": "#/$defs/entryProvenance"
}
}
},
"entryV2": {
"type": "object",
"description": "id and signature cover everything but id and drawn_with, so the same facts drawn by another renderer stay the same flower.",
"required": [
"petal",
"id",
"spec",
"spec_sha256",
"interpretation",
"snapshot",
"provenance"
],
"additionalProperties": false,
"properties": {
"petal": {
"const": "flower/v2"
},
"id": {
"type": "string",
"pattern": "^[0-9a-f]{24}$"
},
"title": {
"type": "string"
},
"spec": {
"$ref": "#/$defs/spec"
},
"spec_sha256": {
"$ref": "#/$defs/sha256"
},
"interpretation": {
"$ref": "#/$defs/interpretation"
},
"snapshot": {
"$ref": "#/$defs/entrySnapshot"
},
"provenance": {
"$ref": "#/$defs/entryProvenance"
},
"drawn_with": {
"type": "object",
"description": "a receipt, outside what is hashed and signed: which renderer drew this when it was prepared, and the hash of those bytes. A drawing that differs from it later is normal.",
"required": [
"render",
"sha256"
],
"additionalProperties": false,
"properties": {
"render": {
"type": "string"
},
"sha256": {
"$ref": "#/$defs/sha256"
}
}
}
}
},
"entry": {
"description": "A published flower. Its `petal` says how to verify it (shared-map.md, Entry versions).",
"oneOf": [
{
"$ref": "#/$defs/entryV1"
},
{
"$ref": "#/$defs/entryV2"
}
]
}
}
}