{
  "feature": "content-tree",
  "version": "1.0.0",
  "description": "Hierarchical content tree with zone-based storage, tree walking, flattening, indexed lookups, and schema migration",
  "category": "data",
  "tags": [
    "content-tree",
    "data-model",
    "serialization",
    "tree-operations",
    "page-data"
  ],
  "actors": [
    {
      "id": "editor",
      "name": "Editor System",
      "type": "system",
      "description": "System that modifies the content tree through user actions"
    },
    {
      "id": "renderer",
      "name": "Render Engine",
      "type": "system",
      "description": "System that reads the content tree to produce visual output"
    }
  ],
  "fields": [
    {
      "name": "root_props",
      "type": "json",
      "required": true,
      "label": "Root Properties"
    },
    {
      "name": "content",
      "type": "json",
      "required": true,
      "label": "Root Content"
    },
    {
      "name": "zones",
      "type": "json",
      "required": false,
      "label": "Zone Storage"
    },
    {
      "name": "node_index",
      "type": "json",
      "required": false,
      "label": "Node Index"
    },
    {
      "name": "zone_index",
      "type": "json",
      "required": false,
      "label": "Zone Index"
    }
  ],
  "rules": {
    "data_model": {
      "three_top_level_keys": true,
      "zone_compound_format": "parentId:slotName",
      "root_zone_id": "root:default-zone"
    },
    "tree_structure": {
      "slots_stored_inline": true,
      "unlimited_nesting_depth": true,
      "unique_instance_ids": true
    },
    "indexing": {
      "node_index_maintained": true,
      "zone_index_maintained": true,
      "path_tracking": true,
      "parent_tracking": true,
      "flat_data_cached": true
    },
    "flattening": {
      "nested_to_dotpath": true,
      "array_indexed": true,
      "empty_array_sentinel": "__puck_[]",
      "empty_object_sentinel": "__puck_{}"
    },
    "tree_walking": {
      "dual_mapper_pattern": true,
      "skip_optimization": true,
      "index_rebuild_on_walk": true
    },
    "migration": {
      "version_upgrades": true
    },
    "zone_registration": {
      "register_on_mount": true,
      "unregister_on_unmount": true,
      "cache_on_unregister": true
    }
  },
  "outcomes": {
    "insert_into_tree": {
      "priority": 1,
      "given": [
        "a valid component instance with unique ID exists",
        "the destination zone exists or will be created",
        "the destination index is within bounds"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "content_tree",
          "description": "Walk tree, insert component at destination zone and index"
        },
        {
          "action": "set_field",
          "target": "node_index",
          "description": "Add new node entry with path, parent, zone, and flat data"
        },
        {
          "action": "set_field",
          "target": "zone_index",
          "description": "Update zone's content IDs array"
        },
        {
          "action": "emit_event",
          "event": "tree.node.inserted",
          "payload": [
            "node_id",
            "zone",
            "index"
          ]
        }
      ],
      "result": "Component exists in tree at specified position, indexes updated"
    },
    "move_in_tree": {
      "priority": 2,
      "given": [
        "source zone and index point to an existing component",
        "destination zone and index are valid",
        "component is not being moved to its current position"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "content_tree",
          "description": "Walk tree, remove from source zone, insert at destination zone"
        },
        {
          "action": "set_field",
          "target": "node_index",
          "description": "Update path and parent for moved node and all descendants"
        },
        {
          "action": "set_field",
          "target": "zone_index",
          "description": "Update content IDs for both source and destination zones"
        },
        {
          "action": "emit_event",
          "event": "tree.node.moved",
          "payload": [
            "node_id",
            "source_zone",
            "destination_zone"
          ]
        }
      ],
      "result": "Component relocated, all indexes reflect new position"
    },
    "duplicate_in_tree": {
      "priority": 3,
      "given": [
        "source zone and index point to an existing component"
      ],
      "then": [
        {
          "action": "create_record",
          "type": "component",
          "target": "component_clone",
          "description": "Deep clone component with all props and nested children"
        },
        {
          "action": "set_field",
          "target": "clone_ids",
          "description": "Regenerate unique IDs for the clone and ALL nested descendant components"
        },
        {
          "action": "set_field",
          "target": "content_tree",
          "description": "Insert clone at source index + 1 in the same zone"
        },
        {
          "action": "emit_event",
          "event": "tree.node.duplicated",
          "payload": [
            "original_id",
            "clone_id",
            "zone"
          ]
        }
      ],
      "result": "Identical copy with unique IDs placed next to original"
    },
    "remove_from_tree": {
      "priority": 4,
      "given": [
        "target zone and index point to an existing component"
      ],
      "then": [
        {
          "action": "delete_record",
          "type": "component",
          "target": "component_and_descendants",
          "description": "Remove component and collect all descendant node IDs"
        },
        {
          "action": "set_field",
          "target": "node_index",
          "description": "Delete index entries for removed node and all descendants"
        },
        {
          "action": "set_field",
          "target": "zone_index",
          "description": "Delete zone entries owned by removed nodes, update parent zone"
        },
        {
          "action": "emit_event",
          "event": "tree.node.removed",
          "payload": [
            "node_id",
            "descendant_count"
          ]
        }
      ],
      "result": "Component and all nested children fully removed from tree and indexes"
    },
    "reorder_in_zone": {
      "priority": 5,
      "given": [
        "source and destination are in the same zone",
        "source index differs from destination index"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "content_tree",
          "description": "Move component from old index to new index within the zone"
        },
        {
          "action": "set_field",
          "target": "zone_index",
          "description": "Update content IDs order for the zone"
        },
        {
          "action": "emit_event",
          "event": "tree.node.reordered",
          "payload": [
            "node_id",
            "zone",
            "old_index",
            "new_index"
          ]
        }
      ],
      "result": "Component order updated within zone",
      "error": "INVALID_ZONE_FORMAT"
    },
    "register_zone": {
      "priority": 6,
      "given": [
        "a component with slots mounts in the editor"
      ],
      "then": [
        {
          "action": "create_record",
          "type": "zone",
          "target": "zone_entry",
          "description": "Create zone entry in data and zone index, or restore from cache if previously registered"
        },
        {
          "action": "emit_event",
          "event": "tree.zone.registered",
          "payload": [
            "zone_compound",
            "zone_type"
          ]
        }
      ],
      "result": "Zone is available as a drop target"
    },
    "unregister_zone": {
      "priority": 7,
      "given": [
        "a component with slots unmounts from the editor"
      ],
      "then": [
        {
          "action": "set_field",
          "target": "zone_cache",
          "description": "Cache zone content for potential restoration"
        },
        {
          "action": "delete_record",
          "type": "zone",
          "target": "zone_entry",
          "description": "Remove zone from data and zone index"
        },
        {
          "action": "emit_event",
          "event": "tree.zone.unregistered",
          "payload": [
            "zone_compound"
          ]
        }
      ],
      "result": "Zone removed but content cached for re-registration"
    },
    "lookup_node_by_id": {
      "priority": 8,
      "given": [
        "a valid component ID is provided"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "node_index",
          "description": "Return node data, flat data, path, parent ID, and zone from index"
        }
      ],
      "result": "Full node information returned in O(1) lookup"
    },
    "walk_tree": {
      "priority": 9,
      "given": [
        "a tree traversal is needed for any operation"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "tree_walker",
          "description": "Traverse root content, then recursively traverse slots of each component, applying mapContent and mapNodeOrSkip functions"
        }
      ],
      "result": "Modified tree with rebuilt indexes"
    },
    "migrate_data": {
      "priority": 10,
      "given": [
        "data was saved in an older schema version"
      ],
      "then": [
        {
          "action": "call_service",
          "target": "migration",
          "description": "Transform data structure to match current schema version"
        },
        {
          "action": "emit_event",
          "event": "tree.data.migrated",
          "payload": [
            "from_version",
            "to_version"
          ]
        }
      ],
      "result": "Data compatible with current editor version"
    }
  },
  "errors": [
    {
      "code": "NODE_NOT_FOUND",
      "status": 404,
      "message": "Component not found at the specified position"
    },
    {
      "code": "ZONE_NOT_FOUND",
      "status": 404,
      "message": "Zone does not exist"
    },
    {
      "code": "INVALID_ZONE_FORMAT",
      "status": 400,
      "message": "Zone ID must follow parentId:slotName format"
    },
    {
      "code": "MIGRATION_FAILED",
      "status": 500,
      "message": "Failed to migrate data to current schema version"
    }
  ],
  "events": [
    {
      "name": "tree.node.inserted",
      "description": "A component was inserted into the tree",
      "payload": [
        "node_id",
        "zone",
        "index"
      ]
    },
    {
      "name": "tree.node.moved",
      "description": "A component was moved between zones",
      "payload": [
        "node_id",
        "source_zone",
        "destination_zone"
      ]
    },
    {
      "name": "tree.node.duplicated",
      "description": "A component was cloned with new IDs",
      "payload": [
        "original_id",
        "clone_id",
        "zone"
      ]
    },
    {
      "name": "tree.node.removed",
      "description": "A component and its descendants were removed",
      "payload": [
        "node_id",
        "descendant_count"
      ]
    },
    {
      "name": "tree.node.reordered",
      "description": "A component was reordered within its zone",
      "payload": [
        "node_id",
        "zone",
        "old_index",
        "new_index"
      ]
    },
    {
      "name": "tree.zone.registered",
      "description": "A drop zone was registered (component mounted)",
      "payload": [
        "zone_compound",
        "zone_type"
      ]
    },
    {
      "name": "tree.zone.unregistered",
      "description": "A drop zone was unregistered (component unmounted)",
      "payload": [
        "zone_compound"
      ]
    },
    {
      "name": "tree.data.migrated",
      "description": "Data was migrated from an older schema version",
      "payload": [
        "from_version",
        "to_version"
      ]
    }
  ],
  "related": [
    {
      "feature": "component-registry",
      "type": "required",
      "reason": "Component configs define what can be stored in the tree"
    },
    {
      "feature": "drag-drop-editor",
      "type": "required",
      "reason": "Drag operations trigger insert, move, and reorder on the tree"
    },
    {
      "feature": "editor-state",
      "type": "required",
      "reason": "Tree is part of the centralized editor state"
    },
    {
      "feature": "undo-redo",
      "type": "recommended",
      "reason": "Tree state snapshots enable undo/redo"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_content_tree",
        "description": "Hierarchical content tree with zone-based storage, tree walking, flattening, indexed lookups, and schema migration",
        "success_metrics": [
          {
            "metric": "data_accuracy",
            "target": "100%",
            "measurement": "Records matching source of truth"
          },
          {
            "metric": "duplicate_rate",
            "target": "0%",
            "measurement": "Duplicate records detected post-creation"
          }
        ],
        "constraints": [
          {
            "type": "performance",
            "description": "Data consistency must be maintained across concurrent operations",
            "negotiable": false
          }
        ]
      }
    ],
    "autonomy": {
      "level": "supervised",
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "insert_into_tree",
          "permission": "autonomous"
        },
        {
          "action": "move_in_tree",
          "permission": "autonomous"
        },
        {
          "action": "duplicate_in_tree",
          "permission": "autonomous"
        },
        {
          "action": "remove_from_tree",
          "permission": "human_required"
        },
        {
          "action": "reorder_in_zone",
          "permission": "autonomous"
        },
        {
          "action": "register_zone",
          "permission": "autonomous"
        },
        {
          "action": "unregister_zone",
          "permission": "autonomous"
        },
        {
          "action": "lookup_node_by_id",
          "permission": "autonomous"
        },
        {
          "action": "walk_tree",
          "permission": "autonomous"
        },
        {
          "action": "migrate_data",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "data_integrity",
        "over": "performance",
        "reason": "data consistency must be maintained across all operations"
      }
    ],
    "coordination": {
      "protocol": "orchestrated",
      "consumes": [
        {
          "capability": "component_registry",
          "from": "component-registry",
          "fallback": "degrade"
        },
        {
          "capability": "drag_drop_editor",
          "from": "drag-drop-editor",
          "fallback": "degrade"
        },
        {
          "capability": "editor_state",
          "from": "editor-state",
          "fallback": "degrade"
        }
      ]
    }
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/puckeditor/puck",
      "project": "Page editor",
      "tech_stack": "TypeScript + React",
      "files_traced": 30,
      "entry_points": [
        "lib/data/walk-app-state.ts",
        "lib/data/flatten-node.ts",
        "types/Data.tsx",
        "reducer/actions/",
        "lib/migrate.ts"
      ]
    }
  }
}