feat: executions, assertions y bucle reactivo en fn_operations
Añade Execution, Assertion, AssertionResult al paquete fn_operations. Motor de evaluación de assertions con reescritura SQL automática. Bucle reactivo: ExecuteAndReact evalúa assertions y cambia status de entities (corrupted/stale) + auto-crea proposals en registry. CLI fn ops: assertion (add/list/show/delete/eval) y execution (add/list/show). Migración 002_executions_assertions.sql con FTS para assertions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-85
@@ -9,89 +9,6 @@ import (
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
const schemaSQL = `
|
||||
CREATE TABLE IF NOT EXISTS types_snapshot (
|
||||
id TEXT PRIMARY KEY,
|
||||
version TEXT NOT NULL DEFAULT '1.0.0',
|
||||
lang TEXT NOT NULL,
|
||||
algebraic TEXT NOT NULL CHECK(algebraic IN ('product','sum')),
|
||||
definition TEXT NOT NULL DEFAULT '',
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
snapped_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS entities (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
type_ref TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active','stale','corrupted','archived')),
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
domain TEXT NOT NULL DEFAULT '',
|
||||
tags TEXT NOT NULL DEFAULT '[]',
|
||||
source TEXT NOT NULL,
|
||||
metadata TEXT NOT NULL DEFAULT '{}',
|
||||
notes TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS relations (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
from_entity TEXT NOT NULL DEFAULT '',
|
||||
to_entity TEXT NOT NULL,
|
||||
via TEXT NOT NULL DEFAULT '',
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
purity TEXT NOT NULL DEFAULT '' CHECK(purity IN ('','pure','impure')),
|
||||
direction TEXT NOT NULL DEFAULT 'unidirectional' CHECK(direction IN ('unidirectional','bidirectional','inverse')),
|
||||
weight REAL,
|
||||
status TEXT NOT NULL DEFAULT 'designed' CHECK(status IN ('designed','implemented','tested','running','deprecated')),
|
||||
started_at TEXT,
|
||||
ended_at TEXT,
|
||||
"order" INTEGER,
|
||||
tags TEXT NOT NULL DEFAULT '[]',
|
||||
notes TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS relation_inputs (
|
||||
id TEXT PRIMARY KEY,
|
||||
relation_id TEXT NOT NULL REFERENCES relations(id) ON DELETE CASCADE,
|
||||
entity_id TEXT NOT NULL REFERENCES entities(id),
|
||||
role TEXT NOT NULL,
|
||||
"order" INTEGER
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
tags,
|
||||
domain,
|
||||
content='entities',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
-- Triggers to keep entities FTS in sync
|
||||
CREATE TRIGGER IF NOT EXISTS entities_ai AFTER INSERT ON entities BEGIN
|
||||
INSERT INTO entities_fts(rowid, id, name, description, tags, domain)
|
||||
VALUES (new.rowid, new.id, new.name, new.description, new.tags, new.domain);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS entities_ad AFTER DELETE ON entities BEGIN
|
||||
INSERT INTO entities_fts(entities_fts, rowid, id, name, description, tags, domain)
|
||||
VALUES ('delete', old.rowid, old.id, old.name, old.description, old.tags, old.domain);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS entities_au AFTER UPDATE ON entities BEGIN
|
||||
INSERT INTO entities_fts(entities_fts, rowid, id, name, description, tags, domain)
|
||||
VALUES ('delete', old.rowid, old.id, old.name, old.description, old.tags, old.domain);
|
||||
INSERT INTO entities_fts(rowid, id, name, description, tags, domain)
|
||||
VALUES (new.rowid, new.id, new.name, new.description, new.tags, new.domain);
|
||||
END;
|
||||
`
|
||||
|
||||
// DB wraps a SQLite connection for an operations database.
|
||||
type DB struct {
|
||||
conn *sql.DB
|
||||
@@ -115,9 +32,9 @@ func Open(path string) (*DB, error) {
|
||||
return nil, fmt.Errorf("setting WAL mode: %w", err)
|
||||
}
|
||||
|
||||
if _, err := conn.Exec(schemaSQL); err != nil {
|
||||
if err := migrate(conn); err != nil {
|
||||
conn.Close()
|
||||
return nil, fmt.Errorf("applying schema: %w", err)
|
||||
return nil, fmt.Errorf("running migrations: %w", err)
|
||||
}
|
||||
|
||||
return &DB{conn: conn, path: path}, nil
|
||||
|
||||
Reference in New Issue
Block a user