Add Context Manager client and log schema
- context_manager.py: Full stateless client for Anthropic API - Builds context from cto.blocks + cto.memory + log.messages - Logs all messages to immutable log.messages table - Interactive chat mode with CLI commands - context_bridge.py: PostgreSQL bridge for context queries - Peer auth support for local connections - get_all_relevant_blocks() single query optimization - build_system_prompt() from blocks - 04_log.sql: Immutable log schema - log.messages with hash chain integrity - Triggers preventing UPDATE/DELETE - 07_initial_blocks.sql: Initial context blocks - tzzr_base, rules_base, r2_storage - server_architect, server_deck, server_corp - cm: Launcher script with venv support
This commit is contained in:
@@ -1,119 +1,60 @@
|
||||
-- ============================================
|
||||
-- SCHEMA LOG - Sistema TZZR
|
||||
-- Log inmutable de mensajes
|
||||
-- Versión: 2.0
|
||||
-- Fecha: 2026-01-01
|
||||
-- ============================================
|
||||
-- Schema LOG para Context Manager
|
||||
CREATE SCHEMA IF NOT EXISTS log;
|
||||
|
||||
DROP SCHEMA IF EXISTS log CASCADE;
|
||||
CREATE SCHEMA log;
|
||||
|
||||
-- Extensiones
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
-- Tipos
|
||||
CREATE TYPE log.ref_type AS ENUM ('context', 'accountant', 'secretary');
|
||||
|
||||
-- ============================================
|
||||
-- Tabla principal: messages
|
||||
-- ============================================
|
||||
CREATE TABLE log.messages (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
hash CHAR(64) UNIQUE NOT NULL,
|
||||
session_hash CHAR(64) NOT NULL,
|
||||
thread_hash CHAR(64),
|
||||
owner_id CHAR(64) NOT NULL,
|
||||
players_id CHAR(64)[] NOT NULL DEFAULT '{}',
|
||||
master_player CHAR(64),
|
||||
role TEXT,
|
||||
content TEXT NOT NULL,
|
||||
attachments JSONB DEFAULT '{}',
|
||||
prev_hash CHAR(64),
|
||||
hashtags CHAR(64)[] DEFAULT '{}',
|
||||
flag_id CHAR(64),
|
||||
master_item_id CHAR(64),
|
||||
item_id CHAR(64)[] DEFAULT '{}',
|
||||
loc_id CHAR(64),
|
||||
ambient JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
CREATE TABLE IF NOT EXISTS log.messages (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
hash CHAR(64) UNIQUE NOT NULL,
|
||||
session_hash CHAR(64) NOT NULL,
|
||||
thread_hash CHAR(64),
|
||||
owner_id CHAR(64),
|
||||
players_id CHAR(64)[],
|
||||
master_player CHAR(64),
|
||||
role TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
attachments JSONB DEFAULT '{}',
|
||||
prev_hash CHAR(64),
|
||||
hashtags CHAR(64)[],
|
||||
flag_id CHAR(64),
|
||||
master_item_id CHAR(64),
|
||||
item_id CHAR(64)[],
|
||||
loc_id CHAR(64),
|
||||
ambient JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Índices messages
|
||||
CREATE INDEX idx_messages_session ON log.messages(session_hash);
|
||||
CREATE INDEX idx_messages_thread ON log.messages(thread_hash);
|
||||
CREATE INDEX idx_messages_owner ON log.messages(owner_id);
|
||||
CREATE INDEX idx_messages_players ON log.messages USING gin(players_id);
|
||||
CREATE INDEX idx_messages_master ON log.messages(master_player);
|
||||
CREATE INDEX idx_messages_prev ON log.messages(prev_hash);
|
||||
CREATE INDEX idx_messages_hashtags ON log.messages USING gin(hashtags);
|
||||
CREATE INDEX idx_messages_flag ON log.messages(flag_id);
|
||||
CREATE INDEX idx_messages_master_item ON log.messages(master_item_id);
|
||||
CREATE INDEX idx_messages_items ON log.messages USING gin(item_id);
|
||||
CREATE INDEX idx_messages_loc ON log.messages(loc_id);
|
||||
CREATE INDEX idx_messages_created ON log.messages(created_at);
|
||||
|
||||
-- ============================================
|
||||
-- Tabla relacional: message_refs
|
||||
-- Referencias a contexto y conocimiento
|
||||
-- ============================================
|
||||
CREATE TABLE log.message_refs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
message_hash CHAR(64) NOT NULL,
|
||||
ref_hash CHAR(64) NOT NULL,
|
||||
ref_type log.ref_type NOT NULL,
|
||||
position INT NOT NULL,
|
||||
thread_hash CHAR(64),
|
||||
UNIQUE(message_hash, ref_hash, ref_type)
|
||||
CREATE TABLE IF NOT EXISTS log.message_refs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
message_hash CHAR(64) NOT NULL,
|
||||
ref_hash CHAR(64) NOT NULL,
|
||||
ref_type VARCHAR(20) NOT NULL,
|
||||
position INT,
|
||||
thread_hash CHAR(64)
|
||||
);
|
||||
|
||||
-- Índices message_refs
|
||||
CREATE INDEX idx_refs_message ON log.message_refs(message_hash);
|
||||
CREATE INDEX idx_refs_ref ON log.message_refs(ref_hash);
|
||||
CREATE INDEX idx_refs_type ON log.message_refs(ref_type);
|
||||
CREATE INDEX idx_refs_thread ON log.message_refs(thread_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_log_session ON log.messages(session_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_log_thread ON log.messages(thread_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_log_owner ON log.messages(owner_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_log_prev ON log.messages(prev_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_log_created ON log.messages(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_refs_message ON log.message_refs(message_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_refs_ref ON log.message_refs(ref_hash);
|
||||
|
||||
-- ============================================
|
||||
-- Funciones
|
||||
-- ============================================
|
||||
CREATE OR REPLACE FUNCTION log.sha256(data TEXT) RETURNS CHAR(64) AS $$
|
||||
CREATE OR REPLACE FUNCTION log.prevent_modification() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
RETURN encode(digest(data, 'sha256'), 'hex');
|
||||
END;
|
||||
$$ LANGUAGE plpgsql IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION log.prevent_update() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
RAISE EXCEPTION 'UPDATE no permitido en %', TG_TABLE_NAME;
|
||||
RAISE EXCEPTION 'Log is immutable';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION log.prevent_delete() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
RAISE EXCEPTION 'DELETE no permitido en %', TG_TABLE_NAME;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
DROP TRIGGER IF EXISTS no_update_messages ON log.messages;
|
||||
DROP TRIGGER IF EXISTS no_delete_messages ON log.messages;
|
||||
CREATE TRIGGER no_update_messages BEFORE UPDATE ON log.messages FOR EACH ROW EXECUTE FUNCTION log.prevent_modification();
|
||||
CREATE TRIGGER no_delete_messages BEFORE DELETE ON log.messages FOR EACH ROW EXECUTE FUNCTION log.prevent_modification();
|
||||
|
||||
-- ============================================
|
||||
-- Triggers de protección (inmutabilidad)
|
||||
-- ============================================
|
||||
CREATE TRIGGER protect_messages_update BEFORE UPDATE ON log.messages
|
||||
FOR EACH ROW EXECUTE FUNCTION log.prevent_update();
|
||||
CREATE TRIGGER protect_messages_delete BEFORE DELETE ON log.messages
|
||||
FOR EACH ROW EXECUTE FUNCTION log.prevent_delete();
|
||||
DROP TRIGGER IF EXISTS no_update_refs ON log.message_refs;
|
||||
DROP TRIGGER IF EXISTS no_delete_refs ON log.message_refs;
|
||||
CREATE TRIGGER no_update_refs BEFORE UPDATE ON log.message_refs FOR EACH ROW EXECUTE FUNCTION log.prevent_modification();
|
||||
CREATE TRIGGER no_delete_refs BEFORE DELETE ON log.message_refs FOR EACH ROW EXECUTE FUNCTION log.prevent_modification();
|
||||
|
||||
CREATE TRIGGER protect_refs_update BEFORE UPDATE ON log.message_refs
|
||||
FOR EACH ROW EXECUTE FUNCTION log.prevent_update();
|
||||
CREATE TRIGGER protect_refs_delete BEFORE DELETE ON log.message_refs
|
||||
FOR EACH ROW EXECUTE FUNCTION log.prevent_delete();
|
||||
|
||||
-- ============================================
|
||||
-- Permisos
|
||||
-- ============================================
|
||||
GRANT USAGE ON SCHEMA log TO tzzr;
|
||||
GRANT SELECT, INSERT ON log.messages TO tzzr;
|
||||
GRANT SELECT, INSERT ON log.message_refs TO tzzr;
|
||||
GRANT USAGE ON SEQUENCE log.messages_id_seq TO tzzr;
|
||||
GRANT USAGE ON SEQUENCE log.message_refs_id_seq TO tzzr;
|
||||
|
||||
-- Verificación
|
||||
SELECT 'Schema log v2.0: 2 tablas creadas' as status;
|
||||
GRANT USAGE ON SCHEMA log TO architect;
|
||||
GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA log TO architect;
|
||||
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA log TO architect;
|
||||
|
||||
Reference in New Issue
Block a user