chore: sync from fn-registry agent

This commit is contained in:
fn-registry agent
2026-05-14 00:28:13 +02:00
commit 5d1dabb1eb
15 changed files with 935 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
-- call_monitor schema v1.0.0
-- Event-log de invocaciones del agente al registry + telemetria asociada.
-- Issue 0085. Aditivo. Aplicado via embed.FS al abrir operations.db.
PRAGMA journal_mode=WAL;
PRAGMA foreign_keys=ON;
-- Sesiones Claude Code. Una por arranque de claude-code.
CREATE TABLE IF NOT EXISTS sessions (
session_id TEXT PRIMARY KEY,
cwd TEXT NOT NULL DEFAULT '',
started_at INTEGER NOT NULL,
ended_at INTEGER,
health_score REAL,
mcp_ratio REAL,
notes TEXT NOT NULL DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at);
-- Cada invocacion del agente sobre funcion del registry (heredoc/mcp/fn_run).
CREATE TABLE IF NOT EXISTS calls (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL DEFAULT '',
function_id TEXT NOT NULL DEFAULT '',
tool_used TEXT NOT NULL,
args_hash TEXT NOT NULL DEFAULT '',
duration_ms INTEGER NOT NULL DEFAULT 0,
success INTEGER NOT NULL DEFAULT 1,
error_class TEXT NOT NULL DEFAULT '',
error_snippet TEXT NOT NULL DEFAULT '',
ts INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_calls_function ON calls(function_id);
CREATE INDEX IF NOT EXISTS idx_calls_session ON calls(session_id);
CREATE INDEX IF NOT EXISTS idx_calls_ts ON calls(ts);
CREATE INDEX IF NOT EXISTS idx_calls_tool ON calls(tool_used);
CREATE INDEX IF NOT EXISTS idx_calls_success ON calls(success);
-- Edit/Write del agente sobre archivos del registry.
CREATE TABLE IF NOT EXISTS code_writes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL DEFAULT '',
function_id TEXT NOT NULL DEFAULT '',
file_path TEXT NOT NULL,
lines_added INTEGER NOT NULL DEFAULT 0,
lines_removed INTEGER NOT NULL DEFAULT 0,
ts INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_code_writes_function ON code_writes(function_id);
CREATE INDEX IF NOT EXISTS idx_code_writes_ts ON code_writes(ts);
-- Test run de unit tests del registry (go test / pytest / etc.).
CREATE TABLE IF NOT EXISTS test_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL DEFAULT '',
function_id TEXT NOT NULL DEFAULT '',
test_id TEXT NOT NULL DEFAULT '',
passed INTEGER NOT NULL DEFAULT 1,
duration_ms INTEGER NOT NULL DEFAULT 0,
output_snippet TEXT NOT NULL DEFAULT '',
ts INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_test_runs_function ON test_runs(function_id);
CREATE INDEX IF NOT EXISTS idx_test_runs_passed ON test_runs(passed);
CREATE INDEX IF NOT EXISTS idx_test_runs_ts ON test_runs(ts);
-- E2E checks de apps que dependen de una funcion del registry.
CREATE TABLE IF NOT EXISTS e2e_runs_fn (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL DEFAULT '',
function_id TEXT NOT NULL,
app_id TEXT NOT NULL,
check_id TEXT NOT NULL,
passed INTEGER NOT NULL DEFAULT 1,
ts INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_e2e_function ON e2e_runs_fn(function_id);
CREATE INDEX IF NOT EXISTS idx_e2e_app ON e2e_runs_fn(app_id);
CREATE INDEX IF NOT EXISTS idx_e2e_passed ON e2e_runs_fn(passed);
-- Antipatrones detectados (sqlite3 inline, import *, heredoc reescribiendo, etc.).
CREATE TABLE IF NOT EXISTS violations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL DEFAULT '',
rule_id TEXT NOT NULL,
function_id TEXT NOT NULL DEFAULT '',
command_snippet TEXT NOT NULL DEFAULT '',
severity TEXT NOT NULL DEFAULT 'warning',
ts INTEGER NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_violations_rule ON violations(rule_id);
CREATE INDEX IF NOT EXISTS idx_violations_function ON violations(function_id);
CREATE INDEX IF NOT EXISTS idx_violations_severity ON violations(severity);
-- Heredocs/snippets clusterizados por similitud (alimenta proposals new_function).
CREATE TABLE IF NOT EXISTS patterns (
pattern_hash TEXT PRIMARY KEY,
representative_snippet TEXT NOT NULL,
occurrences INTEGER NOT NULL DEFAULT 1,
session_ids_json TEXT NOT NULL DEFAULT '[]',
first_seen INTEGER NOT NULL,
last_seen INTEGER NOT NULL,
proposal_id TEXT NOT NULL DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_patterns_occurrences ON patterns(occurrences);
CREATE INDEX IF NOT EXISTS idx_patterns_last_seen ON patterns(last_seen);
+100
View File
@@ -0,0 +1,100 @@
-- Vista agregada por funcion del registry. Lectura O(N) sobre tablas event-log.
-- Si performance degrada, materializar como TABLE refrescada por cron.
DROP VIEW IF EXISTS function_stats;
CREATE VIEW function_stats AS
WITH
call_agg AS (
SELECT
function_id,
COUNT(*) AS calls_total,
SUM(CASE WHEN ts >= CAST(strftime('%s','now','-1 day') AS INTEGER) THEN 1 ELSE 0 END) AS calls_24h,
SUM(CASE WHEN ts >= CAST(strftime('%s','now','-7 days') AS INTEGER) THEN 1 ELSE 0 END) AS calls_7d,
SUM(CASE WHEN ts >= CAST(strftime('%s','now','-30 days') AS INTEGER) THEN 1 ELSE 0 END) AS calls_30d,
SUM(CASE WHEN ts >= CAST(strftime('%s','now','-90 days') AS INTEGER) THEN 1 ELSE 0 END) AS calls_90d,
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) AS errors_total,
AVG(duration_ms) AS mean_duration_ms,
MAX(ts) AS last_used_at,
MAX(CASE WHEN success = 0 THEN ts ELSE 0 END) AS last_error_ts
FROM calls
WHERE function_id != ''
GROUP BY function_id
),
write_agg AS (
SELECT function_id, COUNT(*) AS writes_count, MAX(ts) AS last_write_at
FROM code_writes
WHERE function_id != ''
GROUP BY function_id
),
test_agg AS (
SELECT
function_id,
COUNT(*) AS tests_total,
SUM(CASE WHEN passed = 0 THEN 1 ELSE 0 END) AS tests_failed,
MAX(CASE WHEN passed = 0 THEN ts ELSE 0 END) AS last_test_failed_at
FROM test_runs
WHERE function_id != ''
GROUP BY function_id
),
e2e_agg AS (
SELECT
function_id,
COUNT(*) AS e2e_total,
SUM(CASE WHEN passed = 0 THEN 1 ELSE 0 END) AS e2e_failed,
COUNT(DISTINCT app_id) AS consumer_apps_count
FROM e2e_runs_fn
GROUP BY function_id
),
viol_agg AS (
SELECT function_id, COUNT(*) AS violations_caused
FROM violations
WHERE function_id != ''
GROUP BY function_id
),
all_fns AS (
SELECT function_id FROM call_agg
UNION
SELECT function_id FROM write_agg
UNION
SELECT function_id FROM test_agg
UNION
SELECT function_id FROM e2e_agg
UNION
SELECT function_id FROM viol_agg
)
SELECT
f.function_id,
COALESCE(c.calls_total, 0) AS calls_total,
COALESCE(c.calls_24h, 0) AS calls_24h,
COALESCE(c.calls_7d, 0) AS calls_7d,
COALESCE(c.calls_30d, 0) AS calls_30d,
COALESCE(c.calls_90d, 0) AS calls_90d,
COALESCE(c.errors_total, 0) AS errors_total,
CASE WHEN COALESCE(c.calls_total, 0) > 0
THEN CAST(c.errors_total AS REAL) / c.calls_total
ELSE 0 END AS error_rate,
COALESCE(c.mean_duration_ms, 0) AS mean_duration_ms,
c.last_used_at,
CASE WHEN c.last_error_ts > 0 THEN c.last_error_ts END AS last_error_ts,
COALESCE(w.writes_count, 0) AS writes_count,
w.last_write_at,
COALESCE(t.tests_total, 0) AS tests_total,
COALESCE(t.tests_failed, 0) AS tests_failed,
CASE WHEN COALESCE(t.tests_total, 0) > 0
THEN CAST(t.tests_failed AS REAL) / t.tests_total
ELSE 0 END AS test_fail_rate,
CASE WHEN t.last_test_failed_at > 0 THEN t.last_test_failed_at END AS last_test_failed_at,
COALESCE(e.e2e_total, 0) AS e2e_total,
COALESCE(e.e2e_failed, 0) AS e2e_failed,
CASE WHEN COALESCE(e.e2e_total, 0) > 0
THEN CAST(e.e2e_failed AS REAL) / e.e2e_total
ELSE 0 END AS e2e_fail_rate,
COALESCE(e.consumer_apps_count, 0) AS consumer_apps_count,
COALESCE(v.violations_caused, 0) AS violations_caused
FROM all_fns f
LEFT JOIN call_agg c ON c.function_id = f.function_id
LEFT JOIN write_agg w ON w.function_id = f.function_id
LEFT JOIN test_agg t ON t.function_id = f.function_id
LEFT JOIN e2e_agg e ON e.function_id = f.function_id
LEFT JOIN viol_agg v ON v.function_id = f.function_id;
+23
View File
@@ -0,0 +1,23 @@
-- function_versions: historial de versiones por function_id.
-- Fuente principal = `call_monitor snapshot` que lee registry.db.functions.content_hash
-- tras cada `fn index`. Edit-hook tambien anota cambios con sha256 del archivo.
-- copy_detected = source de la fase 0085k (fn doctor copied-code).
--
-- PK incluye source para permitir que cada source mantenga su propio espacio de
-- hashes (el sha256 del archivo NO coincide con el content_hash canonical del
-- registry.db, que incluye metadata adicional).
CREATE TABLE IF NOT EXISTS function_versions (
function_id TEXT NOT NULL,
content_hash TEXT NOT NULL,
version TEXT NOT NULL DEFAULT '',
snapped_at INTEGER NOT NULL,
source TEXT NOT NULL,
lines_added INTEGER NOT NULL DEFAULT 0,
lines_removed INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (function_id, content_hash, source)
);
CREATE INDEX IF NOT EXISTS idx_fn_versions_function ON function_versions(function_id);
CREATE INDEX IF NOT EXISTS idx_fn_versions_snapped_at ON function_versions(snapped_at);
CREATE INDEX IF NOT EXISTS idx_fn_versions_source ON function_versions(source);
+20
View File
@@ -0,0 +1,20 @@
-- copied_code: matches de cuerpos de funcion del registry encontrados en apps.
-- Poblado por `call_monitor copied-code` que invoca infra.AuditCopiedCode.
-- Cada fila representa un (app_file, app_function, registry_id) sospechoso.
-- UNIQUE incluye body_hash para que solo se inserte una vez por (path,fn,id,hash).
CREATE TABLE IF NOT EXISTS copied_code (
id INTEGER PRIMARY KEY AUTOINCREMENT,
app_file TEXT NOT NULL,
app_function TEXT NOT NULL,
registry_id TEXT NOT NULL,
body_hash TEXT NOT NULL,
similarity REAL NOT NULL DEFAULT 1.0,
kind TEXT NOT NULL,
detected_at INTEGER NOT NULL,
UNIQUE(app_file, app_function, registry_id, body_hash)
);
CREATE INDEX IF NOT EXISTS idx_copied_registry ON copied_code(registry_id);
CREATE INDEX IF NOT EXISTS idx_copied_kind ON copied_code(kind);
CREATE INDEX IF NOT EXISTS idx_copied_detected ON copied_code(detected_at);
@@ -0,0 +1,37 @@
-- session_capability_growth: vista que mide el ciclo "crear+usar" por sesion.
-- Una funcion se considera "creada en sesion X" si el primer code_writes
-- registrado para ese function_id (a nivel global) ocurrio dentro de la sesion X.
-- Una funcion "usada en sesion X" = >=1 fila en calls con misma sesion y ts >= created_at.
--
-- Lectura: created_this_session = COUNT(*) WHERE session_id = ?
-- used = COUNT(*) WHERE session_id = ? AND calls_in_session > 0
-- orphan = COUNT(*) WHERE session_id = ? AND calls_in_session = 0
--
-- Issue 0086. Aditivo. No reescribe schema previo.
CREATE VIEW IF NOT EXISTS session_capability_growth AS
WITH first_write AS (
SELECT
cw.function_id,
cw.session_id,
cw.ts AS created_at
FROM code_writes cw
WHERE cw.function_id != ''
AND cw.ts = (
SELECT MIN(ts) FROM code_writes
WHERE function_id = cw.function_id
)
)
SELECT
fw.session_id,
fw.function_id,
fw.created_at,
(SELECT MIN(c.ts) FROM calls c
WHERE c.function_id = fw.function_id
AND c.session_id = fw.session_id
AND c.ts >= fw.created_at) AS first_call_at,
(SELECT COUNT(*) FROM calls c
WHERE c.function_id = fw.function_id
AND c.session_id = fw.session_id
AND c.ts >= fw.created_at) AS calls_in_session
FROM first_write fw;