Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0085 | Estandarizar llamadas a funciones del registry desde Claude + app de monitorizacion de uso | completado | feature |
|
multi-app | alta |
|
2026-05-13 | 2026-05-17 |
Cierre 2026-05-15
Todas las piezas del plan implementadas:
- Schema event-log + vistas (0085a/0085l) — 7 tablas +
function_statsview +function_versions. - Hook Bash PostToolUse (0085b) capturando mcp/heredoc/sqlite_direct/edit_registry/violations.
- Wrappers opt-in (0085c py + 0085c-bash) activables via
FN_TELEMETRY=1, smoke verificado. - Interceptor en
fn run(0085d-go) con duration real medida. - UI tab "Claude Usage" en
registry_dashboard(0085d/0085e) con KPIs + sub-tabs. - Clusterizacion de patrones inline (0085f) —
call_monitor cluster-patterns [--persist], 11 clusters detectados, upsert idempotente. - Reglas violation declarativas (0085g, parcial) —
dev/violation_rules.yamlsource-of-truth con 4 activas + 4 propuestas inactivas; runtime YAML reader TBD. - Pipeline
call_monitor propose(0085h) genera proposals con evidencia desdefunction_stats+copied_code+violations. - Auditoria estatica de copia (0085k)
fn doctor copied-code. - Documentacion (0085j) — CLAUDE.md +
.claude/rules/registry_calls.md.
Piezas futuras documentadas pero fuera del MVP: build-tag Go telemetry (0085m), macro C++ FN_CALL (0085n), runtime YAML reader del hook, vistas adicionales del dashboard (drill-down por sesion + diff entre sesiones).
Contexto
Claude actualmente invoca funciones del registry de formas heterogeneas y sin trazabilidad:
| Patron de invocacion | Frecuencia esta sesion (meta_bigq) | Trazabilidad |
|---|---|---|
Heredoc Python inline (python/.venv/bin/python3 - <<'PYEOF' ... PYEOF) |
~15 veces | ninguna (queda en transcript) |
Bash inline con sqlite3 registry.db "..." |
1 (violando regla MCP-first) | ninguna |
./fn run <id> CLI |
0 | log en stdout, no persistido |
mcp__registry__fn_run MCP tool |
0 | mensaje tool-result |
mcp__registry__fn_search/show/code |
0 (deberia haber sido obligatorio) | ninguna |
Imports directos from metabase import ... en heredoc |
en cada heredoc | ninguna |
client._http.request(...) directo saltando funciones del registry |
varias veces (para PUT custom como result_metadata) | ninguna |
Consecuencias:
- No sabemos que funciones del registry usa Claude realmente. Hay ~1200 funciones indexadas pero solo unas pocas se usan en cada sesion. Imposible decidir cuales deprecar, cuales mejorar, cuales son criticas.
- Cada sesion reinventa boilerplate. Patrones repetitivos (refresh
result_metadata, dispatchdimensionvsvariablemapping, batch param config) se reescriben inline. Si se extraen como funciones del registry nadie lo nota porque no hay metricas de "esto se repite mucho". - CLAUDE.md tiene reglas (MCP-first, registry-first) que se violan silenciosamente. Sin telemetria, la regla es aspiracional.
- No hay datos para que el bucle reactivo mejore el registry. El analizador/mejorador deberian saber "esta funcion se uso 50 veces, esta 0 veces, esta fallo 8 veces" — info que ahora mismo no existe.
Objetivo
- Estandarizar como Claude invoca funciones del registry (un patron canonico por caso de uso).
- Instrumentar todas las invocaciones para que dejen rastro en una BD local.
- App
claude_call_monitor(TUI o web) que muestra uso por funcion, latencia, errores, patrones repetidos, violaciones de reglas. - Feedback al registry: marcar funciones "huerfanas", proponer extracciones cuando un mismo bloque inline se repite N veces, sugerir helpers nuevos.
Diseno
Fase 1 — Estandarizacion de invocaciones
Tres patrones canonicos. Cada uno con su tool de entrada y formato de log.
| Caso de uso | Patron canonico | Cuando usar |
|---|---|---|
| Inspeccion del registry (buscar, leer, ver dependencias) | mcp__registry__fn_search/show/code/uses |
SIEMPRE. Reemplaza sqlite3 registry.db "..." inline. CLAUDE.md ya lo exige; ahora se hace cumplir via lint del log |
| Ejecucion de pipeline/funcion 1-shot | mcp__registry__fn_run <id> [args] o ./fn run <id> [args] |
Cuando hay UNA funcion/pipeline a lanzar con sus args. Salida estructurada |
| Composicion ad-hoc multi-funcion | Heredoc Python via Bash, importando del registry | Cuando hay logica intermedia (loops, conditionals, dispatch). Esta sesion casi todo el trabajo cae aqui |
Para composiciones que se repiten: extraer a python/functions/pipelines/ o a una funcion del registry. Decision basada en datos del monitor (ver fase 3).
Fase 2 — Instrumentacion
Hook + libreria que captura cada invocacion. Stack propuesto:
2a. Hook en Bash tool: parsea cada comando Bash. Si contiene heredoc Python python/.venv/bin/python3 o invoca ./fn run o mcp__registry__fn_*, captura:
- timestamp_start, timestamp_end, duration_ms
- session_id (del log de Claude Code)
- tool_used (Bash heredoc / fn_run / mcp_fn_X / mcp_fn_search / sqlite_direct / etc.)
- functions_imported (parse
from <pkg> import <names>) - functions_called (mejor esfuerzo: regex sobre el codigo del heredoc + para fn_run el id explicito)
- success / exit_code / error_snippet
- patron_detected (refresh_metadata, build_mappings, etc — clasificadores configurables)
Implementacion: hook PostToolUse en ~/.claude/settings.json que llama a un binario Go que escribe en ~/.claude/projects/<proj>/call_monitor.db (SQLite).
2b. Wrapper Python: from registry_telemetry import wrap que parchea las funciones del paquete metabase/bigquery/etc al importarse en heredoc. Cada llamada se loguea (function_id, args_hash, duration, success). Solo se activa si env var FN_TELEMETRY=1 (no romper otros usos).
2c. Hook directo en MCP registry: si el server MCP esta bajo nuestro control, anadir logging en cada tool call (mas confiable que parsear bash).
Las 3 fuentes se cruzan: si una sesion tiene Bash heredoc usando metabase_get_dashboard pero no aparece en MCP logs, es violacion (deberia haber usado mcp__registry__fn_show para inspeccionar antes).
Fase 3 — App claude_call_monitor
App standalone en apps/claude_call_monitor/ o projects/fn_monitoring/apps/claude_call_monitor/. Stack:
- Backend Go (sirve datos de
call_monitor.db+ agregados) - Frontend React + Mantine (consume
@fn_library) o TUI concpp/frameworkImGui — segun preferencia
Vistas minimas:
- Top funciones por uso — tabla rankada:
function_id, calls_24h, calls_7d, mean_duration_ms, error_rate, last_used_at. Filtros por dominio/lang/purity. - Funciones huerfanas — listado de funciones del registry con
calls_30d = 0. Cruzado confn doctor unusedpara distinguir "nunca usada" vs "no usada por Claude pero si por humanos". - Patrones repetidos — clusterizacion de heredocs Python por similitud. Detecta cuando un bloque inline se repite N veces → proposal automatico para extraer a funcion.
- Violaciones de regla — usos de
sqlite3 registry.dbdirecto, uso deCentros_ISO_Limpiocuando deberia ser via card snippet, etc. Reglas configurables en YAML. - Sesion view — timeline de una sesion (Claude Code session_id) con todas las llamadas, errores, duraciones. Util para post-mortem.
- Health score — score 0-100 por sesion: ratio de invocaciones canonicas vs ad-hoc, errores, repeticiones. Telemetria para mejorar prompts del agente.
Fase 4 — Feedback al registry
Hooks de salida del monitor:
- Proposals automaticas: cuando un patron inline se repite >5 veces en distintas sesiones, se crea proposal
new_functionenregistry.dbcon evidencia (lista de session_ids + snippet representativo). El humano (ofn-mejorador) decide si aprobar. - Deprecation candidates: funciones con
calls_90d = 0y sinuses_functionsupstream → proposaldeprecate_function. - Performance regressions: funciones cuyo
mean_duration_mscrece >50% entre semanas → flag al humano.
Implementacion por pasos
| Paso | Tarea | Sub-issue |
|---|---|---|
| 1 | Migracion call_monitor.db schema (calls, sessions, patterns, violations) |
0085a |
| 2 | Hook Bash PostToolUse que parsea comandos y escribe a calls |
0085b |
| 3 | Wrapper Python opcional con FN_TELEMETRY=1 |
0085c |
| 4 | App claude_call_monitor skeleton (Go API + frontend) |
0085d |
| 5 | Vistas: top usage, huerfanas, sesiones | 0085e |
| 6 | Clusterizacion de heredocs + deteccion de patrones | 0085f |
| 7 | Reglas de violacion configurables (YAML) | 0085g |
| 8 | Pipeline fn-monitor proposal que crea proposals automaticas en registry.db desde patrones detectados |
0085h |
| 9 | e2e_checks para la propia app del monitor |
0085i |
| 10 | Documentacion en CLAUDE.md: patrones canonicos + como leer el monitor | 0085j |
Criterios de exito
- Todas las invocaciones de funciones del registry desde Claude quedan registradas (>95% cobertura medida cruzando 3 fuentes).
- App
claude_call_monitormuestra top-20 funciones usadas por Claude en los ultimos 7 dias con metricas reales. - Se detectan al menos 5 patrones repetidos como candidatos a extraccion (con evidencia trazable).
- Se identifican >50 funciones huerfanas para decision (deprecar/promover/dejar).
- CLAUDE.md tiene seccion "Como llamar a funciones del registry" con los 3 patrones canonicos + tabla "cuando usar cual".
- El bucle reactivo (0068) tiene un nuevo input: assertions sobre uso de funciones → proposals.
Anti-patrones a prohibir explicitamente
| Patron | Por que | Alternativa |
|---|---|---|
sqlite3 registry.db "SELECT ..." para inspeccionar funciones |
Salta MCP, no hay logging, FTS5 gotchas | mcp__registry__fn_search "..." |
python -c "import metabase; print(dir(metabase))" para descubrir helpers |
Salta el registry como fuente de verdad | mcp__registry__fn_search "metabase" + mcp__registry__fn_show <id> |
| Heredoc que reescribe logica que ya existe como funcion | Reinvento + perdida de capitalizacion | Primero fn_search, luego importar |
client._http.request(...) directo cuando hay un wrapper del registry |
Salta validacion y telemetria del wrapper | Usar la funcion del registry; si falta una, delegar a fn-constructor |
Crear scripts en temp/ o paths sueltos cuando es composicion repetida |
Codigo se pierde, no se monitoriza | Si patron se repite → pipeline en python/functions/pipelines/ |
Stakeholders
- Usuario humano (Lucas / Emanuel): revisa proposals automaticas, prioriza extracciones, decide deprecaciones.
- Claude (agente principal): lee CLAUDE.md actualizado, usa patrones canonicos, recibe feedback de monitor en CLAUDE.md (top huerfanas, top errores).
- fn-mejorador (fase 5 bucle reactivo): consume
call_monitor.dbpara generar proposals con evidencia real de uso. - fn-orquestador (issue 0069): usa health score del monitor como criterio adicional de exito.
Notas
- Esta issue no requiere refactorizar las 1200 funciones existentes — solo capturar como se invocan.
- El monitor empieza pasivo (solo loguea). En una fase posterior puede bloquear violaciones criticas (ej.
sqlite3 registry.dbdirecto aborta con mensaje + sugerencia). - Datos sensibles: el
args_hashse guarda pero los valores concretos NO. Para queries SQL que contienen secretos por accidente, mantener allowlist de redaccion. - Compatible con el patron de
task_runsdel issue 0069 — comparten el concepto de "ejecucion trazable".
Decisiones 2026-05-13
- UI: tab dentro de
registry_dashboard(proyectofn_monitoring). Reusa C++/ImGui +sqlite_api. Razon: pregunta clave "que deprecar" = JOIN entrefunctionsyfunction_stats; una sola app gana. - Plumbing:
projects/fn_monitoring/apps/call_monitor/(Go + hook BashPostToolUse). Repo Gitea propio (dataforge/call_monitor). - Hook scope: solo proyecto (
.claude/settings.local.json). Captura solo sesiones de fn_registry. - Orden de sub-issues: 0085j (docs) → 0085a (schema) → 0085b (hook) → 0085c (wrapper Python).
- 0085j hecho (2026-05-13): seccion "Como invocar funciones del registry (CANONICO)" en
.claude/CLAUDE.md, regla.claude/rules/registry_calls.md(rule #27), entradaINDEX.md, memoriafeedback_canonical_registry_calls.md. - MCP ampliado: tool nuevo
fn_proposal(read-only, list + show by id) enapps/registry_mcp/tool_proposal.go. Cierra el gap desqlite3 registry.db "SELECT ... FROM proposals"inline. Rebuild aplicado.
Schema extendido — contadores por funcion
Event-log tables (append-only):
| Tabla | Captura |
|---|---|
calls |
function_id, tool_used, session_id, duration_ms, success, error_class, error_snippet, args_hash, ts |
code_writes |
function_id (derivado del path), session_id, lines_added, lines_removed, ts |
test_runs |
function_id, test_id, passed, duration_ms, output_snippet, ts |
e2e_runs_fn |
function_id, app_id, check_id, passed, ts (cruza con apps.uses_functions) |
violations |
rule_id, session_id, command_snippet, severity, ts |
patterns |
pattern_hash, session_ids[], representative_snippet, occurrences, last_seen |
sessions |
session_id, cwd, started_at, ended_at, health_score, mcp_ratio |
Vista agregada function_stats por function_id:
- Uso:
calls_total,calls_24h/7d/30d/90d,last_used_at - Errores:
errors_total,error_rate,last_error_class,last_error_ts - Performance:
mean_duration_ms,p95_duration_ms - Codigo:
writes_count,last_write_at - Tests:
tests_total,tests_failed,test_fail_rate,last_test_failed_at - E2E:
e2e_total,e2e_failed,e2e_fail_rate,consumer_apps_count - Salud:
violations_caused
Assertions derivadas → proposals automaticas:
| Regla | Threshold | Proposal |
|---|---|---|
| Huerfana absoluta | calls_90d=0 AND writes_count=0 |
deprecate_function |
| Bug prioritario | error_rate>0.1 AND calls_7d>5 |
improve_function (bug) |
| Regresion performance | p95_24h > 1.5 * p95_30d |
improve_function (perf) |
| Test flaky | test_fail_rate>0.1 AND tests_total>10 |
improve_function (flaky) |
| Wrapper saltado | violations_caused>3 |
improve_function (API gap) |
| Patron inline sin funcion | patterns.occurrences>5 AND no match FTS |
new_function con snippet |
| Blast radius alto | e2e_fail_rate>0 AND consumer_apps_count>=3 |
improve_function (critical) |
Migracion: projects/fn_monitoring/apps/call_monitor/migrations/001_init.sql con las 7 tablas + indices sobre function_id, session_id, ts. Vista function_stats se construye en 002_function_stats_view.sql (materializar como TABLE si performance bajo, recalcular cada N min).
Cobertura por lenguaje — capas de monitorizacion
Cada lenguaje del registry tiene un "techo" de lo monitorizable runtime. Las 8 capas de cobertura propuestas, ordenadas por ROI:
| # | Capa | Lenguaje | Cubre | Esfuerzo | Estado |
|---|---|---|---|---|---|
| 1 | Hook PostToolUse Bash | universal | mcp__registry__*, ./fn run, Edit/Write sobre functions/, violations |
bajo | hecho (0085b) |
| 2 | Wrapper Python (registry_telemetry) activable con FN_TELEMETRY=1 |
py | heredocs Python + notebooks Jupyter + scripts dentro del registry | bajo | pending 0085c |
| 3 | Wrapper Bash bash/lib/telemetry_prelude.sh (redefine cada funcion del registry con cronograma + log) |
bash | heredocs bash + scripts/apps Bash | bajo | pending 0085c-bash |
| 4 | Interceptor en fn run (binario Go) |
go/py/bash/ts | invocaciones via CLI con duration/error real medido | medio | pending 0085d-go |
| 5 | fn doctor copied-code — fingerprint match registry vs apps |
universal (estatico) | codigo copiado/parafraseado sin import | medio | pending 0085k |
| 6 | Tabla function_versions + snapshot en Edit-hook |
universal (estatico) | drift de versiones, forks silenciosos | bajo | pending 0085l |
| 7 | Build-tag telemetry Go + codegen wrappers |
go | runtime de apps Go (parcial, opt-in por build) | alto | futuro |
| 8 | Macro FN_CALL(name, ...) C++ opt-in |
cpp | C++ apps cooperantes | alto | futuro |
Reglas duras:
- Go y C++ compilados: sin monkey-patch dinamico. Apps que linkean estaticamente la funcion no se pueden auditar runtime salvo capas 7/8 con opt-in.
- Solucion realista Go/C++: medir 3 caminos legitimos —
./fn run,mcp_fn_run,go test/ctest. Runtime de app en produccion queda fuera. - Wrapper Python/Bash: activacion explicita via
FN_TELEMETRY=1. Si la app no exporta esa env var, no se mide.
Drift detection — funciones copiadas y modificadas
5. Codigo copiado en apps (sin import)
Problema: app reescribe el cuerpo de una funcion del registry en vez de importarla. Invisible runtime — el codigo nunca pasa por el registry. Solo se detecta por analisis estatico.
Tecnicas (ordenadas por precision/coste):
| Tecnica | Pilla | Limitacion |
|---|---|---|
| Hash exacto del cuerpo normalizado (strip whitespace + comments) | copy-paste literal | 0 false-positives, miss si renombran 1 var |
| AST fingerprint via Tree-Sitter → token sequence → SimHash | copia con renames | requiere parser por lenguaje |
| ssdeep / TLSH fuzzy hash sobre cuerpo normalizado | copia con tweaks pequeños | umbral arbitrario ~85% true match |
| Embeddings de codigo (Code2Vec, starcoder, etc.) | parafraseado / refactor parcial | costoso, opaco |
MVP propuesto: fn doctor copied-code que cruza fingerprints de cada funcion del registry contra cuerpos de funciones declaradas en apps/, projects/*/apps/. Salida: {app_id, app_file, app_func_name, matched_registry_id, similarity, kind}. Severidad:
exact_copy→ critical → proposalimport_insteadnear_copy(>0.85 fuzzy) → warningpartial_match(>0.6) → info
Persistencia: tabla nueva copied_code en call_monitor.operations.db. Aporta a function_stats columna copies_detected.
6. Versiones modificadas (function_versions)
registry.db.functions.content_hash ya existe — fn index lo recalcula. Falta historial.
Schema propuesto (migracion 003_function_versions.sql en call_monitor):
CREATE TABLE function_versions (
function_id TEXT NOT NULL,
content_hash TEXT NOT NULL,
version TEXT NOT NULL,
snapped_at INTEGER NOT NULL,
source TEXT NOT NULL, -- 'index' | 'edit_hook' | 'copy_detected'
lines_added INTEGER DEFAULT 0,
lines_removed INTEGER DEFAULT 0,
PRIMARY KEY (function_id, content_hash)
);
Llenado:
- Cada
fn indexinserta snapshot consource='index'. - Hook PostToolUse Edit/Write sobre
functions/...inserta snapshot consource='edit_hook'(ya tenemoscode_writes— extender o cross-reference). fn doctor copied-coderegistra version observada en la copia consource='copy_detected'.
Consultas utiles:
- Forks silenciosos: app copio version X, registry esta en version Y, app sigue en X.
- Velocidad de cambio: funciones con muchas versions en poco tiempo → inestables.
- Backport candidates: app tiene version vieja, version nueva resuelve bug → flag.
Que se escapa del monitor (boundary explicito)
| Caso | Capturado? | Capa que lo cubriria |
|---|---|---|
mcp__registry__fn_* |
si | hook PostToolUse |
./fn run X desde Bash |
si | hook PostToolUse |
Edit/Write sobre functions/*/*.{go,py,sh,ts} |
si | hook PostToolUse |
| Heredoc Python importando registry | parcial (solo heredoc_py, no funciones internas) |
wrapper Python (0085c) |
| Heredoc Bash sourcing registry | parcial | wrapper Bash (0085c-bash) |
| Notebook Jupyter (MCP jupyter) ejecutando codigo registry | parcial | wrapper Python (0085c) — el kernel hereda env vars |
Sub-agente (Agent tool) |
NO transitivo | requiere registrar hooks en cada sub-agente |
| Funcion Go llamada por codigo de app en runtime | NO | capa 7 (build-tag) — futuro |
| Funcion Bash sourceada por otro script en runtime | NO | wrapper Bash (0085c-bash) si se sourcea el prelude |
| Funcion C++ compilada y llamada por app | NO | capa 8 (macro FN_CALL) — futuro |
| Test automatico que ejecuta funciones | NO si corre fuera de Claude | capa 4 (fn run instrumentado captura go test via fn) |
Service de produccion (registry_api.service) recibe HTTP |
NO | sin cobertura — runtime sistema, no agente |
| Cron / Dagu / systemd timer | NO | sin cobertura |
Funcion clonada/copiada (sin import) |
NO runtime | capa 5 (fn doctor copied-code) detecta estatico |
Verdad operativa: monitorizamos al agente y a las invocaciones canonicas del registry. El runtime de cada app en produccion queda fuera. Compensar con: tests, e2e_checks (capa propia por app, issue 0068), y telemetria de invocacion via fn run/MCP.
Implementacion por pasos (actualizado 2026-05-13)
| Paso | Tarea | Sub-issue | Estado |
|---|---|---|---|
| 1 | Migracion call_monitor.operations.db schema (7 tablas event-log + vista function_stats) |
0085a | hecho |
| 2 | Hook Bash PostToolUse que parsea tools y escribe calls/code_writes/violations |
0085b | hecho |
| 3a | Wrapper Python registry_telemetry (activable con FN_TELEMETRY=1) |
0085c | hecho — python/functions/infra/registry_telemetry.py, sys.meta_path importer + wrap_namespace. Smoke verificado 2026-05-15: filter_list_py_core logged con tool_used=python_wrapper. |
| 3b | Wrapper Bash telemetry_prelude |
0085c-bash | hecho — bash/functions/infra/telemetry_prelude.sh, autowrap idempotente via declare -f + eval rename. Smoke verificado 2026-05-15: wait_for_http_bash_infra logged con tool_used=bash_wrapper. |
| 3c | Interceptor en fn run (binario Go) |
0085d-go | hecho |
| 4 | Tab "Claude Usage" en registry_dashboard (datasource ops:call_monitor, KPIs + 3 sub-tabs) |
0085d | hecho |
| 5 | Top usage, huerfanas, sesiones (vistas UI) | 0085e | hecho — implementadas en registry_dashboard tab "Claude Usage" (projects/fn_monitoring/apps/registry_dashboard/views.cpp, data.h, data_http.h). KPIs Reg%, MCP, Errors, Violations + sub-tabs top/huerfanas/sesiones. |
| 6 | Clusterizacion heredocs + tabla patterns populada |
0085f | hecho 2026-05-15 — call_monitor cluster-patterns [--persist] (cluster.go). Normaliza snippets (quoted strings -> STR, paths -> /PATH, hex 8+ -> HEX, numbers -> N), hashea sha256-truncado, agrega ocurrencias + session_ids. 11 clusters detectados de 286 calls inline; persistencia con UPSERT idempotente. 3 unit tests (TestNormalizeSnippet/TestHashSnippetStable/TestSplitCSV) pass. |
| 7 | Reglas violation configurables YAML | 0085g | parcial 2026-05-15 — dev/violation_rules.yaml cataloga 4 reglas activas (sqlite3_registry_select, python_dir_inspect, import_star_in_heredoc, client_http_request_direct) + 4 propuestas inactivas (mcp_ratio_low, heredoc_repetition, edit_registry_without_fn_index, protected_path_modified). YAML es source-of-truth declarativo. Runtime reader TBD: el hook PostToolUse sigue hardcoded; futura iteracion requiere jq/yq + refactor para leer reglas dinamicamente. |
| 8 | Pipeline call_monitor propose (funcion infra.GenerateProposalsFromTelemetry + infra.PersistProposalDrafts) que escribe a registry.db.proposals desde function_stats + copied_code + violations. 4 reglas MVP: copy_detected, orphan, bug, wrapper_skip. INSERT OR IGNORE con id determinista |
0085h | hecho |
| 9 | e2e_checks propios de call_monitor (en app.md, ya declarados) |
0085i | parcial (declarado) |
| 10 | Documentacion CLAUDE.md + rules (registry_calls.md) | 0085j | hecho |
| 11 | fn doctor copied-code + tabla copied_code + subcomando call_monitor copied-code |
0085k | hecho |
| 12 | Tabla function_versions + subcomando call_monitor snapshot + edit-hook con sha256 file |
0085l | hecho |
| 13 (futuro) | Go build-tag telemetry con codegen |
0085m | futuro |
| 14 (futuro) | C++ macro FN_CALL opt-in |
0085n | futuro |