feat(tasks): phase 1 — elevate chat session to a task (schema + task entity)
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>
This commit is contained in:
53
migrations/018_tasks.up.sql
Normal file
53
migrations/018_tasks.up.sql
Normal file
@@ -0,0 +1,53 @@
|
||||
-- 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';
|
||||
Reference in New Issue
Block a user