{
  "id": "2026-04-24-platform-entity-model-4bc903c65d",
  "scope": "redkey",
  "source_of_truth": "repo",
  "source_path": "docs/specs/2026-04-24-platform-entity-model.md",
  "source_kind": "markdown",
  "visibility": "internal",
  "renderer_id": "design_doc.dreamborn-forge.generated.v1",
  "design_system": "dreamborn-design-system:forge",
  "generated_at": "2026-05-09T13:00:55.670Z",
  "artifact_type": "design_doc",
  "schema_version": "design_doc.generated.v1",
  "title": "RedKey Platform — Entity Model v2",
  "summary": "RedKey Platform — Entity Model v2 Date: 2026 04 24 Status: Design complete, awaiting implementation spec Next step: Priya specs the implementation. Vikram architects the migration. What This Is A foundational redesign of how RedKey models work. The current system has workflow instances, UUIDs, and a flat execution model that can't express project lifecycles,...",
  "format_source": "markdown",
  "sections": [
    {
      "title": "RedKey Platform — Entity Model v2",
      "level": 1,
      "body": "**Date:** 2026-04-24  \n**Status:** Design complete, awaiting implementation spec  \n**Next step:** Priya specs the implementation. Vikram architects the migration.\n\n---"
    },
    {
      "title": "What This Is",
      "level": 2,
      "body": "A foundational redesign of how RedKey models work. The current system has workflow_instances, UUIDs, and a flat execution model that can't express project lifecycles, department-agnostic work, or real control actions (cancel, hold, replace). This spec defines the clean model everything else builds on.\n\nKV continues on the current model. This lands as Platform Phase 3.\n\n---"
    },
    {
      "title": "Core Principles",
      "level": 2,
      "body": "**1. Workers receive tasks only.**  \nPriya, Quinn, Vikram, and all worker agents never see project, stage, or phase structure. They receive a task with a self-contained brief and execute it. Operations roles (Claire, Engine, Justin) own the structure above tasks.\n\n**2. HCS topic ID is the entity ID.**  \nEvery entity — project, stage, phase, task — has an HCS topic. The topic ID (`0.0.XXXXX`) is the primary key everywhere: Supabase tables, message payloads, dependency references, URLs. No UUIDs. Topic creation is always step one.\n\n**3. Supabase is current state, not a mirror.**  \nOne row per entity showing where it is right now. The listener applies HCS events as state transitions. If you need history, read the HCS topic. If you need current state, read Supabase. `cluster_events` becomes an audit log only.\n\n**4. Control actions originate on-chain.**  \nCancel, hold, resume — all HCS messages first. Supabase state follows from the listener. Writing status directly to Supabase is never a control action.\n\n**5. Stage types are configurable, not hardcoded.**  \nThe taxonomy works for engineering, sales, marketing, finance. Stage vocabulary is defined per deployment via the definitions topic.\n\n---"
    },
    {
      "title": "Entity Taxonomy",
      "level": 2,
      "body": "```\nProject  →  Stage  →  Phase  →  Task\n```\n\n| Entity | What it is | Example |\n|---|---|---|\n| **Project** | The thing being built. Long-lived, outlives all execution. | Knowledge Vault AI |\n| **Stage** | A major lifecycle episode with a defined type. | Build, Design, Release, Qualify |\n| **Phase** | A logical chunk of work within a stage. Optional for simple stages. | Phase 1: Foundation |\n| **Task** | The atomic work item an agent executes. Self-contained brief. | Write schema migrations |\n\n**Simpler work collapses levels naturally:**\n- One-off task: just a Task, no project or stage overhead\n- Small feature: Project → Stage → Task (no phases)\n- Full project: Project → multiple Stages → Phases → Tasks\n\n---"
    },
    {
      "title": "Stage Types",
      "level": 2,
      "body": "Configurable per deployment. Published to the `definitions` topic. Examples:\n\n**Engineering:** `design | architect | planning | build | break_fix | release | feature | maintenance`  \n**Sales:** `prospect | qualify | demo | proposal | negotiate | close | onboard`  \n**Marketing:** `strategy | brief | produce | review | publish | analyze`  \n**Finance:** `collect | reconcile | review | approve | file | report`\n\nStage type definitions are published to HCS like agent and role definitions. The engine treats all stage types identically — it routes tasks, checks dependencies, advances state. Meaning is in the persona and the brief.\n\n---"
    },
    {
      "title": "Operations vs Execution Roles",
      "level": 2,
      "body": "| Layer | Roles | What they see |\n|---|---|---|\n| Operations | coordinator (Claire), engine, exec (Justin) | Projects, stages, phases, tasks — create structure, advance state |\n| Execution | developer, reviewer, architect, ba, content, analyst, ... | Tasks only — self-contained brief, output path, prior output refs |\n\nRole definitions include a `role_type: operations | worker` field.\n\n---"
    },
    {
      "title": "Static topics (fixed at deployment)",
      "level": 3,
      "body": "| Logical name | What it is |\n|---|---|\n| `definitions` | Agent, role, stage-type, workflow template registry |\n| `roles.coordinator` | Operations queue — Claire |\n| `roles.engine` | Engine queue |\n| `roles.exec` | Justin exec review |\n| `roles.developer` | Work queue — Quinn |\n| `roles.reviewer` | Work queue — Vikram |\n| `roles.architect` | Work queue — Vikram |\n| `roles.ba` | Work queue — Priya |\n| `agents.*` | Per-agent status topics (unchanged) |"
    },
    {
      "title": "Dynamic topics (created per entity, topic ID = entity ID)",
      "level": 3,
      "body": "| Entity | Topic pattern | Created by |\n|---|---|---|\n| Project | `0.0.XXXXX` | Justin / intake agent |\n| Stage | `0.0.XXXXX` | Claire / coordinator |\n| Phase | `0.0.XXXXX` | Engine / claire_spawn |\n| Task | `0.0.XXXXX` | Engine |\n\nListener discovers dynamic topics by querying entity tables in Supabase each poll cycle.\n\n---"
    },
    {
      "title": "Project topic",
      "level": 3,
      "body": "```\nproject.created        title, brief, client_id, created_by, stage_sequence[]\nproject.stage_changed  from_stage, to_stage\nproject.on_hold        reason\nproject.resumed\nproject.deferred       reason, revisit_date\nproject.cancelled      reason\nproject.complete\n```"
    },
    {
      "title": "Stage topic",
      "level": 3,
      "body": "```\nstage.created          project_id, stage_type, title, step_snapshot[]\nstage.transition       from_step, to_step, output_ref\nstage.on_hold          reason\nstage.resumed\nstage.cancelled        reason\nstage.superseded       replaced_by: 0.0.XXXXX\nstage.complete\n```"
    },
    {
      "title": "Phase topic",
      "level": 3,
      "body": "```\nphase.created          stage_id, project_id, name, depends_on: [0.0.XXXXX]\nphase.started\nphase.on_hold          reason\nphase.resumed\nphase.cancelled        reason\nphase.complete\n```"
    },
    {
      "title": "Task topic",
      "level": 3,
      "body": "```\ntask.created           phase_id?, stage_id, project_id?, role, brief, depends_on: [0.0.XXXXX]\ntask.assigned          role, model_hint\ntask.claimed           agent, ts\ntask.on_hold           reason\ntask.resumed\ntask.blocked           reason\ntask.cancelled         reason, replaced_by: 0.0.XXXXX\ntask.complete          output_ref, cost_usd, duration_seconds, agent\n```"
    },
    {
      "title": "Role topics (work queues — shape change only)",
      "level": 3,
      "body": "```\ntask.available         task_id: 0.0.XXXXX, model_hint, posted_at\ntask.claim             task_id: 0.0.XXXXX, agent, ts\n```\n\nBrief is no longer in the role topic message. Agent fetches from `tasks.brief` in Supabase. Eliminates the HFS brief workaround entirely.\n\n---"
    },
    {
      "title": "Supabase Entity Tables",
      "level": 2,
      "body": "One row per entity. PK is the HCS topic ID (`0.0.XXXXX`)."
    },
    {
      "title": "`projects`",
      "level": 3,
      "body": "```sql\nid          text primary key,  -- 0.0.XXXXX\nclient_id   text not null,\ntitle       text not null,\nbrief       text,\nstatus      text not null,     -- active | on_hold | deferred | cancelled | complete\nactive_stage_id text,          -- current stage topic ID\ncreated_by  text,\ncreated_at  timestamptz\n```"
    },
    {
      "title": "`stages`",
      "level": 3,
      "body": "```sql\nid          text primary key,  -- 0.0.XXXXX\nproject_id  text references projects(id),\nclient_id   text not null,\nstage_type  text not null,     -- build | qualify | produce | etc (configurable)\ntitle       text,\nstatus      text not null,     -- active | paused | cancelled | superseded | complete\ncurrent_step int,\nsteps       jsonb,             -- step snapshot\ncreated_at  timestamptz\n```"
    },
    {
      "title": "`phases`",
      "level": 3,
      "body": "```sql\nid          text primary key,  -- 0.0.XXXXX\nstage_id    text references stages(id),\nproject_id  text,\nclient_id   text not null,\nname        text not null,\nstatus      text not null,     -- pending | active | on_hold | cancelled | complete\ndepends_on  text[],            -- phase topic IDs\ncreated_at  timestamptz\n```"
    },
    {
      "title": "`tasks`",
      "level": 3,
      "body": "```sql\nid          text primary key,  -- 0.0.XXXXX\nphase_id    text,              -- nullable — tasks can exist without a phase\nstage_id    text references stages(id),\nproject_id  text,\nclient_id   text not null,\nrole        text not null,\nagent       text,\nstatus      text not null,     -- created | assigned | claimed | in_progress | on_hold | blocked | cancelled | complete\nbrief       text,              -- materialized from task.created for fast agent lookup\ndepends_on  text[],            -- task topic IDs\noutput_ref  text,\nreplaced_by text,              -- task topic ID if cancelled and replaced\ncost_usd    numeric,\nduration_seconds int,\ncreated_at  timestamptz,\nupdated_at  timestamptz\n```\n\n---"
    }
  ],
  "html_path": "artifacts/2026-04-24-platform-entity-model-4bc903c65d.html",
  "json_path": "artifacts/2026-04-24-platform-entity-model-4bc903c65d.json"
}