Migration 018 adds goal/status/outcome/summary/entity_id to agent_sessions and creates session_plan_steps + session_questions. Registers a 'task' entity type and an 'involves' (task→entity) relationship in the ontology so each session anchors its knowledge and involved-entity edges on the existing relationships graph. nomos createSession now mints a task:<session-id> entity (type task) and links it via agent_sessions.entity_id — best-effort so chat never blocks on it. listSessions/GET /sessions surface the new task fields. No behaviour change yet; this is the data foundation for the task board and live context panel. Verified end-to-end against the local stack: migration applied, ontology ingested (60 types/47 rels), a new session mints a linked task entity and the API returns status/goal/entity_id. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.7 KiB
SQL
54 lines
2.7 KiB
SQL
-- 018_tasks.up.sql
|
|
-- Elevate a chat session into a "task": a goal-structured unit of work with a
|
|
-- lifecycle status, an outcome, and a one-line summary — the first-class object
|
|
-- the task board and the live context panel render. See
|
|
-- plans/2026-07-11-goal-oriented-chat-control-panel.md.
|
|
--
|
|
-- entity_id links the session to its OWN entity (type 'task', registered in
|
|
-- seeds/ontology.yaml) so knowledge notes and involved-entity edges hang off
|
|
-- the existing relationships graph unchanged — get_relations and
|
|
-- get_entity_knowledge just work. Intentionally no hard FK (mirrors 017's
|
|
-- decoupling): a race between task-entity creation and the session insert must
|
|
-- not be able to break the session.
|
|
|
|
ALTER TABLE agent_sessions ADD COLUMN IF NOT EXISTS goal TEXT NOT NULL DEFAULT '';
|
|
ALTER TABLE agent_sessions ADD COLUMN IF NOT EXISTS status TEXT NOT NULL DEFAULT 'active';
|
|
ALTER TABLE agent_sessions ADD COLUMN IF NOT EXISTS outcome TEXT;
|
|
ALTER TABLE agent_sessions ADD COLUMN IF NOT EXISTS summary TEXT NOT NULL DEFAULT '';
|
|
ALTER TABLE agent_sessions ADD COLUMN IF NOT EXISTS entity_id UUID;
|
|
|
|
-- Ordered plan steps. A step is a described unit of work that maps to a
|
|
-- run/request_execution call (no fixed step enum, per general-gated-execution).
|
|
-- execution_id is the gated action a step runs, if any; its terminal status
|
|
-- auto-closes the step server-side.
|
|
CREATE TABLE IF NOT EXISTS session_plan_steps (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
session_id UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
|
|
seq INT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
detail TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
-- pending | running | done | failed | skipped | blocked
|
|
execution_id UUID,
|
|
target_slug TEXT,
|
|
started_at TIMESTAMPTZ,
|
|
finished_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_plan_steps_session ON session_plan_steps(session_id, seq);
|
|
|
|
-- Structured decisions the agent surfaces to the operator mid-task. context
|
|
-- carries { entities:[], options:[], why:"" } for the pinned question card.
|
|
CREATE TABLE IF NOT EXISTS session_questions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
session_id UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
|
|
prompt TEXT NOT NULL,
|
|
context JSONB NOT NULL DEFAULT '{}',
|
|
status TEXT NOT NULL DEFAULT 'open', -- open | answered | dismissed
|
|
answer TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
answered_at TIMESTAMPTZ
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_questions_session_open
|
|
ON session_questions(session_id) WHERE status = 'open';
|