{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://github.com/avadisabelle/coaia-narrative/schema/data-model/entity.json",
  "title": "COAIA Entity",
  "description": "Core entity structure for COAIA memory system. Entities represent nodes in the knowledge graph with typed observations and rich metadata.",
  "type": "object",
  "required": [
    "name",
    "entityType",
    "observations"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Unique identifier for the entity. For structural tension components, follows naming convention: 'chart_{id}_{component}' (e.g., 'chart_123_desired_outcome', 'chart_123_action_1')"
    },
    "entityType": {
      "type": "string",
      "description": "Type of entity defining its role in the system",
      "enum": [
        "structural_tension_chart",
        "desired_outcome",
        "current_reality",
        "action_step",
        "narrative_beat",
        "wampum_belt",
        "person",
        "concept",
        "event",
        "location",
        "organization",
        "artifact",
        "custom"
      ]
    },
    "observations": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Array of observations/facts about this entity. For current_reality, observations accumulate over time as actions complete. For desired_outcome, typically contains a single clear statement."
    },
    "metadata": {
      "type": "object",
      "description": "Optional metadata providing additional context and structure",
      "properties": {
        "dueDate": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 timestamp for when an action_step or chart should be completed"
        },
        "chartId": {
          "type": "string",
          "description": "Reference to parent chart ID (e.g., 'chart_123')"
        },
        "phase": {
          "type": "string",
          "enum": [
            "germination",
            "assimilation",
            "completion"
          ],
          "description": "Creative phase of the chart or action (based on Robert Fritz's creative process)"
        },
        "completionStatus": {
          "type": "boolean",
          "description": "Whether an action_step has been completed"
        },
        "parentChart": {
          "type": "string",
          "description": "For telescoped charts, the ID of the parent chart"
        },
        "parentActionStep": {
          "type": "string",
          "description": "For telescoped charts, the entity name of the parent action step"
        },
        "level": {
          "type": "integer",
          "description": "Nesting level in chart hierarchy (0 = root chart, 1 = first telescoping, etc.)",
          "minimum": 0
        },
        "createdAt": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 timestamp of entity creation"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time",
          "description": "ISO 8601 timestamp of last update"
        },
        "act": {
          "type": "integer",
          "description": "For narrative_beat entities: Act number in three-act structure (1, 2, or 3)",
          "minimum": 1,
          "maximum": 3
        },
        "type_dramatic": {
          "type": "string",
          "description": "For narrative_beat entities: Dramatic type (e.g., 'inciting_incident', 'midpoint', 'climax')"
        },
        "perspective_types": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "For narrative_beat entities: the perspectives that read this beat (engineer, ceremony, story_engine)"
        },
        "universes": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "deprecated": true,
          "description": "For narrative_beat entities written before 0.17: the same list as perspective_types, with the values engineer-world, ceremony-world, story-engine-world. Old records keep it. Readers map the values to engineer, ceremony, story_engine"
        },
        "timestamp": {
          "type": "string",
          "description": "For narrative_beat entities: when the beat was recorded (ISO 8601)"
        },
        "relationalAlignment": {
          "type": "object",
          "description": "Assessment of alignment with relational protocol principles",
          "properties": {
            "assessed": {
              "type": "boolean",
              "description": "Whether relational alignment has been assessed"
            },
            "score": {
              "type": [
                "number",
                "null"
              ],
              "description": "Alignment score (0-100) or null if not assessed",
              "minimum": 0,
              "maximum": 100
            },
            "principles": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Array of aligned relational principles"
            }
          },
          "required": [
            "assessed",
            "score",
            "principles"
          ]
        },
        "fourDirections": {
          "type": "object",
          "description": "Four Directions wisdom framework assessment",
          "properties": {
            "north_vision": {
              "type": [
                "string",
                "null"
              ],
              "description": "North direction: Vision, clarity, big picture perspective"
            },
            "east_intention": {
              "type": [
                "string",
                "null"
              ],
              "description": "East direction: Intention, new beginnings, illumination"
            },
            "south_emotion": {
              "type": [
                "string",
                "null"
              ],
              "description": "South direction: Emotion, passion, relationships, heart wisdom"
            },
            "west_introspection": {
              "type": [
                "string",
                "null"
              ],
              "description": "West direction: Introspection, reflection, lessons learned"
            }
          },
          "required": [
            "north_vision",
            "east_intention",
            "south_emotion",
            "west_introspection"
          ]
        },
        "narrative": {
          "type": "object",
          "description": "Narrative context and storytelling elements",
          "properties": {
            "description": {
              "type": "string",
              "description": "Brief narrative description"
            },
            "prose": {
              "type": "string",
              "description": "Full prose narrative or story text"
            },
            "lessons": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Lessons learned or insights derived from this narrative"
            }
          },
          "required": [
            "description",
            "prose",
            "lessons"
          ]
        },
        "foundation": {
          "type": "object",
          "description": "Deep Research Foundations metadata tracking research packet context and evaluation status. Used by Atlas Chronicle and research delegation workflows.",
          "properties": {
            "packetRoot": {
              "type": "string",
              "description": "Root identifier for research packet (e.g., 'foundations/atlas-chronicle/')"
            },
            "foundationType": {
              "type": "string",
              "description": "Type of foundation research (e.g., 'atlas-chronicle', 'inquiry', 'baseline')"
            },
            "parentIssue": {
              "type": "string",
              "description": "GitHub issue reference for parent research context (e.g., 'owner/repo#number')"
            },
            "baselineIssue": {
              "type": "string",
              "description": "GitHub issue establishing baseline requirements"
            },
            "inquiryIssue": {
              "type": "string",
              "description": "GitHub issue defining research inquiry"
            },
            "protocolIssue": {
              "type": "string",
              "description": "GitHub issue documenting research protocol"
            },
            "schemaIssue": {
              "type": "string",
              "description": "GitHub issue defining data schema"
            },
            "visualizerIssue": {
              "type": "string",
              "description": "GitHub issue for visualization specifications"
            },
            "expectedArtifacts": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "List of expected research artifacts/deliverables"
            },
            "producedArtifacts": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "List of produced research artifacts/deliverables"
            },
            "evaluationStatus": {
              "type": "string",
              "enum": [
                "expected",
                "delegated",
                "produced",
                "evaluated"
              ],
              "description": "Current evaluation status of research: expected (planned), delegated (assigned), produced (completed), evaluated (reviewed)"
            },
            "privacyClass": {
              "type": "string",
              "enum": [
                "public-safe",
                "private",
                "mixed"
              ],
              "description": "Privacy classification of research data: public-safe (can be shared), private (confidential), mixed (requires filtering)"
            },
            "publicationStatus": {
              "type": "string",
              "enum": [
                "planned",
                "draft",
                "reviewed",
                "published"
              ],
              "description": "Publication workflow status"
            },
            "commitHandles": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Associated commit hashes or version control handles"
            }
          }
        },
        "sessionLineage": {
          "type": "object",
          "description": "Hermes session lineage metadata tracking conversation branching and handoff state. Enables reconstruction of session branch maps and parent-child traceability.",
          "properties": {
            "platform": {
              "type": "string",
              "description": "Platform where session originated (e.g., 'telegram', 'hermes', 'slack')"
            },
            "parentChartId": {
              "type": "string",
              "description": "Parent chart ID if session is branched from a parent context"
            },
            "sourceBeat": {
              "type": "string",
              "description": "Source narrative beat entity name that triggered session branching"
            },
            "originalSessionId": {
              "type": "string",
              "description": "Original session identifier before any branching occurred"
            },
            "branchSessionId": {
              "type": "string",
              "description": "Session ID of this specific branch point"
            },
            "branchIndex": {
              "type": "integer",
              "description": "Index of this branch among siblings (e.g., branch 1, 2, 3...)",
              "minimum": 0
            },
            "copiedMessageCount": {
              "type": "integer",
              "description": "Number of messages copied from parent session to this branch",
              "minimum": 0
            },
            "branchPurpose": {
              "type": "string",
              "description": "Purpose or reason for creating this session branch"
            },
            "relatedIssues": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Related GitHub issue references (e.g., 'owner/repo#number')"
            },
            "handoffState": {
              "type": "string",
              "enum": [
                "requirements-created",
                "implementation-ready",
                "returned-to-parent"
              ],
              "description": "State of handoff between parent and child sessions: requirements-created (initial), implementation-ready (actionable), returned-to-parent (completed handoff)"
            }
          }
        },
        "sessionContext": {
          "type": "object",
          "description": "Beat-level lived session context metadata capturing the embodied condition of working sessions. Records land-based learning, voice/terminal mode, environmental constraints, and continuity context.",
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "voice",
                "terminal",
                "mixed"
              ],
              "description": "Interaction mode of the session: voice (audio capture), terminal (text-based), mixed (alternating)"
            },
            "setting": {
              "type": "string",
              "enum": [
                "desk",
                "walking",
                "land-based",
                "transit",
                "unknown"
              ],
              "description": "Physical setting where session took place: desk (stationary workspace), walking (ambulatory), land-based (outdoor learning), transit (in motion), unknown (unrecorded)"
            },
            "landBasedLearning": {
              "type": "boolean",
              "description": "Whether session engaged land-based learning practices (e.g., walking the land, outdoor observation)"
            },
            "environmentNotes": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Environmental conditions and constraints affecting capture quality (e.g., 'wind', 'outdoor walking', 'traffic noise')"
            },
            "listeningContext": {
              "type": "string",
              "description": "Context about what user was listening to or engaging with during session (e.g., 'user listened to Atlas Chronicle while walking')"
            },
            "captureQuality": {
              "type": "string",
              "enum": [
                "clear",
                "windy",
                "partial"
              ],
              "description": "Quality of audio/text capture: clear (high quality), windy (environmental interference), partial (incomplete or interrupted)"
            },
            "continuationKind": {
              "type": "string",
              "enum": [
                "branch",
                "parent-return",
                "follow-up"
              ],
              "description": "Type of session continuation: branch (new thread), parent-return (returning to main), follow-up (sequential continuation)"
            },
            "privateChroniclePath": {
              "type": "string",
              "description": "File path to private chronicle recording or transcript (handle only, content not exposed by default)"
            },
            "publicSummaryAllowed": {
              "type": "boolean",
              "description": "Whether a public summary of this session context is permitted"
            }
          }
        },
        "wampumBelt": {
          "type": "object",
          "description": "Wampum Belt payload for non-linear mnemonic sequencing. Present on entities of type wampum_belt. Beads are NOT separate entities \u2014 the whole belt travels inside this one object, so reading the belt entity yields every bead without further lookups.",
          "properties": {
            "beltId": {
              "type": "string",
              "description": "Belt identifier, minted as belt_{timestamp}. The belt entity is named `{beltId}_belt`."
            },
            "title": {
              "type": "string",
              "description": "Name of this belt"
            },
            "purpose": {
              "type": "string",
              "description": "What this belt encodes or remembers"
            },
            "rows": {
              "type": "integer",
              "minimum": 1,
              "description": "Grid row count. A belt always renders at full declared dimension; vacant positions are content, not absence."
            },
            "cols": {
              "type": "integer",
              "minimum": 1,
              "description": "Grid column count"
            },
            "beads": {
              "type": "array",
              "description": "Beads placed on the grid, in insertion order \u2014 NOT spatial order. Position is carried by each bead, never by array index.",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "bead_{beltId}_{row}_{col} \u2014 position is fused into identity, and is the subject of this bead's ceremony relations"
                  },
                  "mnemonic": {
                    "type": "string",
                    "description": "Short anchor phrase; the label a viewer shows at grid scale"
                  },
                  "color": {
                    "type": "string",
                    "enum": [
                      "white",
                      "purple",
                      "black",
                      "mixed"
                    ],
                    "description": "Encoded meaning, not decoration. Reproduce it named as well as shown."
                  },
                  "position": {
                    "type": "object",
                    "description": "0-indexed grid position; one bead per cell, re-placement is rejected",
                    "properties": {
                      "row": {
                        "type": "integer",
                        "minimum": 0
                      },
                      "col": {
                        "type": "integer",
                        "minimum": 0
                      }
                    },
                    "required": [
                      "row",
                      "col"
                    ]
                  },
                  "reading": {
                    "type": "string",
                    "description": "Canonical meaning, always present"
                  },
                  "relationalReadings": {
                    "type": "object",
                    "description": "Perspective-specific readings. Resolution order on a positional read: col:N, then row:N, then the derived edge label (left when col is 0, right when col is cols-1, otherwise center), then the canonical reading. Keys outside those forms are stored but never resolved.",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "ceremonyLink": {
                    "type": "object",
                    "description": "The obligation this bead carries. Only chartId and beatName become graph relations; witnessNames, renewalDate and notes live ONLY here, so a consumer reading the relation graph alone cannot see them.",
                    "properties": {
                      "ceremonyType": {
                        "type": "string",
                        "enum": [
                          "commitment",
                          "accountability",
                          "witness",
                          "renewal"
                        ],
                        "description": "Also written to the relation's metadata.context"
                      },
                      "chartId": {
                        "type": "string",
                        "description": "Chart held accountable; produces a wampum_holds_accountable relation from this BEAD to `{chartId}_chart`"
                      },
                      "beatName": {
                        "type": "string",
                        "description": "Narrative beat witnessed; produces a wampum_witnesses relation from this BEAD to the beat entity name"
                      },
                      "witnessNames": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "People who stood present. No relation carries these \u2014 list them by name, never as a count."
                      },
                      "renewalDate": {
                        "type": "string",
                        "description": "Free-form; not validated on write. A date already passed means the obligation needs renewal."
                      },
                      "notes": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "ceremonyType"
                    ]
                  },
                  "observations": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  }
                },
                "required": [
                  "id",
                  "mnemonic",
                  "color",
                  "position",
                  "reading",
                  "observations",
                  "createdAt"
                ]
              }
            },
            "createdAt": {
              "type": "string",
              "format": "date-time"
            },
            "updatedAt": {
              "type": "string",
              "format": "date-time",
              "description": "Advances on every bead add"
            }
          },
          "required": [
            "beltId",
            "title",
            "purpose",
            "rows",
            "cols",
            "beads",
            "createdAt",
            "updatedAt"
          ]
        }
      }
    }
  }
}
