Skip to main content

Plan de implementación — agentes SOTA (2026)

Nota interna de arquitectura (sesión 2026-07-09, parte 2). Convierte el diagnóstico de agents-100x.md en un plan de ejecución, calibrado contra el estado del arte verificado por research web (fuentes al final de cada punto). El objetivo: que los agentes de Driftless operen al nivel de los mejores harnesses de 2026 sin romper las invariantes del producto (gobernanza, determinismo explicable, proposer ≠ approver, no-scripting del broker).

0. Los diez principios SOTA que gobiernan este plan

  1. El loop canónico es gather → act → VERIFY → repeat. La pierna de verificación es la que nuestro loop no tiene. Pipelines de refutación adversarial matan ~79–91% de hallazgos falsos antes de llegar al humano (Refute-or-Promote, arXiv:2604.19049; SAST-Genius −91% FPs).
  2. El presupuesto es de tokens-en-contexto, no de pasos. “Context rot” es la restricción real; limpiar tool-results viejos dio +29% solo, +39% con memoria de archivo, −84% de tokens en tareas de 100 turnos (Anthropic context-management).
  3. Fan-out solo para lectura paralelizable; síntesis y decisión single-context. Multi-agente de research superó al single-agent 90.2% — a ~15× el costo; Cognition: nunca paralelizar decisiones (anthropic.com/engineering/multi-agent-research-system; cognition.com/blog/dont-build-multi-agents). Workers devuelven resúmenes estructurados de 1–2k tokens.
  4. Delta updates, nunca rewrites totales. El “context collapse” de ACE: un rewrite iterativo erosionó 18,282 tokens → 122 en un paso y dejó accuracy DEBAJO del baseline sin adaptación (arXiv:2510.04618, ICLR 2026). Vale para el vault y para cualquier skill que se auto-edite.
  5. La memoria gana confianza con contadores de uso. ACE: unidades atómicas con contadores helpful/harmful alimentados por feedback de ejecución. Mem0: la escritura es un clasificador ADD/UPDATE/DELETE/NOOP contra la memoria existente. Zep: invalidación temporal, no borrado.
  6. Cache-first prompt architecture. Reads de cache a 0.1× (Anthropic) / ~2% (DeepSeek). El Knowledge inyectado debe ser un bloque estable versionado que solo se re-renderiza cuando el topic cambia de versión — re-escribir memoria por run es un impuesto de cache además de un riesgo de gobernanza.
  7. Drift de claims en dos etapas. Detector barato → verificador caro → gate humano (DocPrism LCEF, arXiv:2511.00215: filtrar categorías de inconsistencia relevantes antes de reportar; el juicio one-shot de un LLM sobre drift no lo shippea nadie).
  8. Autonomía graduada con promoción ganada y demotion automática. Tres niveles (auto-apply reversible / notify-and-proceed / HITL); reversibilidad es el factor #1 de routing; promoción = evidencia empírica en esa clase de acción + autorización humana registrada; demotion automática al degradarse (arXiv:2606.22484; patrón Mintlify PR-gated→opt-in-push; Rovo admin-gated).
  9. pass^k, no pass@1, para decidir autonomía. Un agente 90% pass@1 es ~57% consistente a k=8 (τ-bench). Un skill no gradúa ni shippea sin pass^k sobre corpus sembrado.
  10. Supresión > generación. Presupuesto de FP <10% (el “cry-wolf effect” es la razón #1 de abandono de bots de review); suprimir 35% de sugerencias subió la aceptación +15.8pp (arXiv:2511.18849). Invertir en cuándo callar tanto como en la calidad del draft.
Validación externa de las apuestas existentes: notas atómicas ≈ bullets de ACE; el gate Note→Knowledge es exactamente la defensa que la literatura de seguridad converge a recomendar contra memory poisoning (OWASP ASI06; MINJA >95% de éxito de inyección sin gate); el drift temporal ≈ invalidación de Zep; retrieve por tiers ≈ just-in-time retrieval de Anthropic. La arquitectura de Driftless está bien apostada — lo que falta es ejecución del loop completo.

Workstreams

WS1 — Fiabilidad (pre-requisito; sin esto nada de lo demás es creíble)

#CambioDónde
1.1Fix gate legacy→gateway (bug): dispatch exige opencode_key_enc; el runner acepta cualquier credencial. Cambiar a hasAnyCredentialagent-schedule.service.ts:62, pr-processor.service.ts:155
1.2Singleton jobs (pg-boss singletonKey) + leader election para crons (hoy corren en cada réplica)agent-queue.service.ts, agent-schedule.service.ts
1.3Librarian a la cola y fuera del web tier (viola su propia invariante)agent-schedule.service.ts:177, controller :32
1.4Alerta/telemetría cuando pg-boss no arranca (hoy: drop silencioso a debug)agent-queue.service.ts:88-94
1.5Reaper que cancela el sandbox del run zombie (hoy marca failed y el gasto sigue); alinear expiry 600s vs reaper 30minagent-schedule.service.ts:80-91
1.6Budget con superficie de escritura: PATCH /config acepta budget + UI en Settingsagent-config.service.ts:85-87, Settings.tsx
1.7Reemplazar parseChangedFiles (regex sobre string humano) por payload tipado de driftagent-schedule.service.ts:27-35
Aceptación: cero dobles-runs en multi-réplica; un workspace gateway-only despacha por push/PR; un run zombie no sigue gastando.

WS2 — Loop económico: tokens, cache, profundidad

#CambioDónde
2.1Tool-result clearing: al acumular N tokens, sustituir resultados viejos ya supersedidos por stubs ((cleared — re-read if needed)); presupuesto por tokens complementa maxStepsagentic-loop.ts (messages), checkRunCaps ya da el cap duro
2.2maxSteps/deadline dinámicos por tamaño del trabajo (nº topics × tamaño diff), cap duro = budgetPolicyagent-runner.service.ts:290
2.3Tool git_history (log/blame acotado, formato conciso) + fetch --depth 50 on-demand — hoy el clone --depth 1 tira el porqué históricosandbox-executor.ts (INVESTIGATION_TOOLS + Sh)
2.4Tool find_references sobre el LSP ya montado en el sandbox (blast radius real, no grep)sandbox-executor.ts:251-280
2.5Respuestas de tool en formato conciso con paginación y errores accionables (“narrow your query”) — el formato conciso de Anthropic midió −65% tokens sin pérdidasandbox-executor.ts, graph-tool-executor.ts
2.6Bloque de Knowledge estable y versionado en prompts (re-render solo cuando topic.version cambia) para maximizar prefix-cache en runs programados; ya se hace a medias (volatile al final) — formalizarloagent-runner.service.ts buildPrompts
Aceptación: cache hit-rate ≥80% en runs warm (ya medido ~81% en el mejor caso — sostenerlo); tokens/run del Auditor −30% con igual o mejor recall en el eval de loop.

WS3 — Verificación adversarial (la pierna que falta)

#CambioDónde
3.1Refuter pass: post-parse y pre-landing, cada proposal pasa por un turno corto de refutación con “kill mandate”, contexto asimétrico y modelo DISTINTO de la lista (los verificadores de la misma familia comparten sesgos). El refuter ve el claim + el código, no el razonamiento del generador. Sobrevive → aterriza con verified:true; muere → se registra en el trace (no llega al humano)nuevo paso en agent-runner.service.ts:339-347 (land loop); reusar ThinLoopRuntime con maxSteps 4-6
3.2Filtrado de claims estilo DocPrism para drift: clasificar cada claim del topic localmente (fact/invariant/decision/ephemeral) y filtrar qué categorías de inconsistencia son reportables antes de auditar — mata el FP de “abstracción ≠ inconsistencia”skill del Auditor + agent-output.ts
3.3agent_stats desagregado por clase de acción (update/flag/new_topic/relate/…) — el insumo de WS5proposals.service stats
3.4Política de supresión: presupuesto FP <10%; el comment de PR solo cuando el hallazgo sobrevivió al refuter Y la clase de acción tiene approval histórico >Xauditor-comment.ts
Aceptación: en el corpus sembrado, el refuter mata ≥70% de proposals falsas plantadas sin matar >5% de verdaderas; approval rate humano sube de 86% → ≥92%.

WS4 — Cross-surface + Steward (drift multi-superficie)

#CambioDónde
4.1Componer los E2 read tools (search_topics, docs, collections) en los executors del Auditor/Architect — ya son canónicos y la policy engine ya los gobierna; Chat probó el patrónagent-tools.ts (nuevo set compuesto), runners
4.2Drift-event tipado + cola: drift local (--mark), drift manual del Inbox y doc-drift despachan al Auditor — hoy solo el push webhook lo hacetopic-drift.service.tsagent-queue
4.3Steward (agente nuevo, graph+broker-read, sin Daytona): sensa diffs de content_digest en ConnectorDocuments + webhooks de sync de Nango; activa las anclas doc/connection (hoy inertes) como fuente de drift; corre audit doc↔topic (mismo branch fact-vs-invariant); setea records.drifted. Patrón RAG estándar: last_modified cuando es confiable, digest-compare como fallback, “staleness gap” como SLA. Nadie shippea drift semántico contra fuentes SaaS — es terreno abierto y es exactamente la tesis del productonuevo runner (patrón LibrarianRunner); connector-index.service.ts, broker.service.ts:1183-1273 (webhooks), anchor.dto.ts
4.4Coverage multi-superficie del Architect: collections activas sin criterion, docs indexados con uso alto en Chat sin topic gobernantecoverage.service.ts
Aceptación: un cambio en una página Notion indexada que contradice Knowledge produce una propuesta de update en <1h (staleness gap SLA); drift local llega al Auditor sin clicks.

WS5 — Autonomía graduada (earn-autonomy)

#CambioDónde
5.1Ladder de 3 niveles POR CLASE DE ACCIÓN: L2 auto-apply (solo reversible con undo) / L1 notify-and-proceed / L0 HITL. Reversibilidad = factor #1 de routinggeneraliza librarian_autovouch en agent-config
5.2Promoción = pass^k ≥ umbral en evals de esa clase + approval rate humano sostenido + autorización humana registrada (el owner activa el nivel, como Rovo). Demotion automática cuando la métrica cae — sin humanoagent-config.service.ts + stats de 3.3
5.3Primer graduado: safe-lane del Librarian (relate, normalizar tags, archive de zombies) — todo con undo (el patrón Undo ya existe para autovouch)librarian-runner.service.ts:257-273
5.4Todo auto-apply escribe al audit trail existente + evento con actor agent:<rol>audit.service, TopicEvent
Aceptación: ninguna acción auto-aplicada irreversible; demotion dispara sola en el eval de regresión; el humano ve el nivel vigente y el porqué (métrica) en Settings.

WS6 — El vault que aprende (ACE aplicado a Driftless)

#CambioDónde
6.1Contadores helpful/harmful por topic desde feedback de ejecución: retrieval seguido de propuesta aceptada que lo cita, “Still good” clicks, drift confirmado vs falso. Complementa matched_runs/topic_signals (estructura) con outcome (uso)proposals.service.topicSignals + eventos
6.2Write classifier ADD/UPDATE/DELETE/NOOP en context add/update (patrón Mem0): detectar conflicto/solapamiento con lo existente y sugerir el update coherente en vez de aceptar el wall — es la regla E del skill, hecha estructuraltopics.service write path / vault-validator.ts
6.3Sleep-time compute: job nocturno de consolidación (doctor→curator) que PROPONE merges/dedupe/re-anclajes — siempre deltas, nunca rewrite total (context collapse), siempre a la Review Queueextiende context doctor + Librarian nightly
6.4Lessons (ya existen) cierran con contadores: una lesson que los runs siguen y correlaciona con approvals sube; una ignorada/害ful se propone archivarfindLessons + 6.1

WS7 — Runtime y orquestación

#CambioDónde
7.1Daytona snapshots por repo (base nightly con el repo clonado + LSP warm) + warm pool: sub-90ms p99 vs clone por run; estandarizar el spec del sandbox (el warm-pool hit exige match exacto). Costo marginal ~$0.17/hr por worker 2vCPU — el fan-out es barato en compute, caro en tokenssandbox-executor.ts, sandbox-factory.ts (y los otros 2 sitios de daytona.create — gotcha conocida)
7.2Fan-out selectivo: para sweeps del Architect y auditorías multi-topic (>5), orquestador que lanza workers read-only por módulo/hipótesis con contrato explícito (objetivo, formato, límites) y retorno estructurado de 1–2k tokens; síntesis single-context. Reemplaza el hack de batches encadenados con setImmediateagent-runner.service.ts:392-400 → nuevo orquestador sobre la cola
7.3Materializar AgentManifest/Registry (hoy tipos muertos) con drift_event e integration_event como triggers de primera clase — añadir el Steward debe ser un manifiesto, no un servicio bespokecognitive/contracts.ts:195-235

WS9 — Observabilidad viva + Agent Activity como sala de control

El observador interno ya existe — observeToolExecutor (Agent Tool Platform T3, cognitive/tool-observability.ts): un ToolExecutionEvent sanitizado por llamada (duración, error class, preview redactado). Estado real: Chat lo envuelve pero descarta los eventos (chat.service.ts:592), y los agentes autónomos lo omiten. Es la señal que WS2 (presupuestos por tool), WS5 (autonomía medida) y WS8 (trajectory evals) necesitan — cablearlo va primero.
#CambioDónde
9.1Cablear el observador T3 en los tres runners vía buildAgentToolExecutor({emit}); cada métrica se fusiona en el evento tool_result del trace (ms, error_class) — un solo stream enriquecido, sin migraciónagent-runner.service.ts, librarian-runner.service.ts
9.2Exponer matched_topics en el detalle del run (los chips de “qué auditó”)agent-runs.service.ts:get
9.3Agent Activity página pulida: stat strip 30d (runs, % merged, % cached, avg run, spend), filtros por agente, feed agrupado por día, drawer con stat grid + chips de topics auditados + rollup por tool (llamadas/avg ms/errores) + timeline con args expandibles, reasoning clampeado y autoscroll en liveDashboard.tsx (Agents/RunTrace), dashboard.css
9.4Siguiente iteración: rutear también los eventos de Chat al mismo plano; panel “por tool” agregado en Usage (Settings); export de trazas fallidas → casos de eval (alimenta WS8)chat.service.ts, Settings.tsx, evals/
9.1–9.3 quedaron implementados como spike verificado (tests + typecheck) en esta branch — revisable/revertible como commit independiente.

WS8 — Evals como gate de release

#CambioDónde
8.1Corpus sembrado por skill sobre el golden repo (bugs/drifts plantados con verdad conocida) + pass^k a nivel de hallazgo (k≥4) como métrica de graduaciónevals/loop/ (ya existe la base)
8.2Trajectory evals sobre agent_run.trace (ya se guarda): el grading solo-de-output esconde 20–40% de fallos; trazas fallidas → casos offline automáticamenteevals/ + export de traces
8.3Juez LLM de familia distinta al modelo del run, rúbrica por criterio separado; híbrido con checks deterministas (el output contract ya es parseable)evals/lib.mjs
8.4Gate de CI: un cambio a un skill no mergea sin pasar sus evals (los skills son artefactos de primera clase — tratarlos como código con tests)CI + cognitive/skills/**

Secuencia (6 sprints)

SprintEntregas
1WS1 completo (fiabilidad) + 3.3 (stats por clase) + 8.1 base (corpus sembrado)
2WS2 (clearing, git_history, find_references, cache-first, budgets dinámicos)
3WS3 (refuter + DocPrism filtering + supresión) — medir contra el corpus
44.1–4.2 (cross-surface + drift queue) + 7.1 (snapshots/warm pool) + 8.4 (gate CI)
54.3–4.4 (Steward) + 5.1–5.3 (autonomía graduada v1)
6WS6 (contadores, write classifier, sleep-time) + 7.2–7.3 (fan-out + registry) + 8.2–8.3

KPIs del programa

  • MTTR de drift (detección → Knowledge reparado), por superficie (git / docs / records).
  • pass^k (k=4) por skill en el corpus sembrado — gate de release y de autonomía.
  • Approval rate por clase de acción (hoy 86% global) — objetivo ≥92% con refuter.
  • FP rate de hallazgos <10% (presupuesto cry-wolf).
  • Tokens/run y cache hit-rate (objetivo: −30% tokens, ≥80% cache warm).
  • Staleness gap de fuentes conectadas (SLA <1h con webhook, <24h batch).

Trampas a evitar (todas documentadas en la literatura)

  • Context collapse: jamás un rewrite total del vault o de un skill por un LLM — solo deltas.
  • Memory poisoning: el gate humano Note→Knowledge es la defensa SOTA (OWASP ASI06) — la autonomía graduada nunca se aplica a la verdad (contenido), solo a higiene reversible.
  • Verificador correlacionado: el refuter usa otro modelo/contexto — mismo modelo = mismos sesgos.
  • Multi-agente para decisiones: fan-out solo lectura; síntesis y writes single-context.
  • Leaderboard-itis: los números de memoria (LoCoMo etc.) están inflados por retrieval-k; medir con nuestros evals, no con benchmarks ajenos.