¿Alguna vez le pediste a un agente una tarea concreta y, a mitad de camino, cambió el plan en silencio — re-escribió sus propios objetivos, se salió del alcance, o te "confirmó" que había hecho algo que en realidad había descartado?
En el post anterior sobre agnosticBrain hablamos del conocimiento: la IA sobrescribiendo notas que refinaste a mano. Aquí el problema es distinto pero espejo: el agente sobrescribiendo su propio plan de ejecución. Y hoy por fin lo resolvemos de forma determinista, no aspiracional, gracias a DeepSeek Harness y a un plugin que construimos: @macorreag/dsh-todo-hardened.
El contexto: la lista de tareas siempre fue del agente
Todos los asistentes de código tienen algún mecanismo de tareas: TodoWrite en Claude Code, las task lists de Codex y Cursor, los todos de OpenCode. Funcionan, pero comparten un defecto estructural: la lista es propiedad del agente. El modelo la escribe, la edita y la completa como quiere, y la única barrera es un prompt que dice "mantén la lista actualizada".
Eso no es una garantía, es una sugerencia. Tres limitaciones que nos cansamos de sufrir:
- Es disciplina de prompt, no enforcement. Si el modelo deriva, re-encuadra el objetivo o se distrae, la lista lo acompaña. Nadie lo impide.
- No hay capa humana inviolable. No existe un "esto lo decidió el humano y tú no lo tocas". Todo lo que el agente ve, el agente lo puede mutar.
- La "aprobación" no existe como mecanismo. A lo sumo el agente te dice "¿te parece si hago X?" y luego él mismo reporta que lo hizo. La confirmación humana real, si existe, es externa y manual.
El resultado es un agente que se auto-gobierna su propio contrato. Y un contrato donde una de las partes puede reescribirlo unilateralmente no es un contrato.
El GAP: faltaba ownership para el estado de ejecución
En agnosticBrain resolvimos esto para el conocimiento con una tercera capa: curated/, inviolable para el LLM. El insight era simple y profundo:
El LLM propone. El humano decide. Nadie sobrescribe
curated/sin aprobación humana.
El GAP que quedaba abierto era llevar esa misma jerarquía al plan de trabajo del agente. Porque un agente no solo lee y escribe notas: decide, prioriza, completa y descarta tareas. Y si su lista de tareas no tiene la misma protección que curated/, entonces la parte más crítica de la ejecución — qué se decidió hacer — sigue siendo maleable.
La solución: dsh-todo-hardened, ownership para el todo-list
Construimos un plugin para DeepSeek Harness que replica el patrón de agnosticBrain, pero sobre la lista de tareas del agente. Tres capas de ownership:
| Capa | Dueño | Quién muta | Regla crítica |
|---|---|---|---|
active/ |
Agente | Agente (CRUD + finalizar) y humano | Trabajo en curso |
locked/ |
Humano | Solo humano | Inviolable para el agente |
archive/ |
Sistema | Nadie | Append-only: solo se entra |
La clave es locked/: cuando un humano cura una tarea (la bloquea), el agente no puede modificarla. Punto. Y esto no es una regla escrita en un prompt — es una FSM de estados + validación de schema + ownership que corre como gate mecánico antes de cada mutación.
Las reglas no son disciplina de prompt; se aplican mecánicamente en el plugin, igual que
curated/en agnosticBrain.
Si el agente quiere cambiar una tarea bloqueada, no la toca: propone.
El flujo: proponer, no imponer
Cuando el agente necesita modificar algo que está en locked/, la única vía es una propuesta:
- El agente crea una propuesta (
todo_propose) sobre la tarea bloqueada:kind=update | complete | cancel. - La propuesta queda en estado
open— no aplica nada. - El humano la aprueba (
todo_approve) o la rechaza (todo_reject). - Solo la aprobación humana aplica el cambio sobre
locked/.
Y aquí está lo que "otros nos limitaban": la aprobación es real. No es el agente preguntando y auto-respondiéndose. Las acciones humanas (todo_lock, todo_unlock, todo_approve, todo_reject) pasan por el approval seam del harness (ctx.approval.request), que muestra una UI de confirmación y concede allowed-once:
Sin canal de aprobación disponible, la acción falla cerrada. Un subagente no puede autorizarlas. Nadie aprueba por delegación.
Un rastro real, no un diagrama
Esto no es un whiteboard. Es el log append-only del plugin corriendo en una sesión real (cada operación registra su actor):
agent | add t-… → active
human | lock t-… → locked
agent | propose p-… target=t-… kind=update
human | approve p-… → aplica el cambio
agent | propose p-… target=t-… kind=complete
human | reject p-… → no se aplica
agent | propose p-… target=t-… kind=update
human | approve p-… → aplica
human | unlock t-… → active
El agente intentó completar la tarea; el humano lo rechazó; el agente reformuló la propuesta; el humano la aprobó. Todo quedó registrado, con actor y timestamp, en un log.md que es append-only. El agente puede intentar cualquier cosa, pero no puede modificar locked/ sin que quede un rastro y sin que un humano abra la puerta.
Por qué esto era imposible antes de DeepSeek Harness
El patrón no es nuevo: la idea de "humano decide, agente propone" ya la teníamos en agnosticBrain. Lo nuevo es que DSH expone los primitivos necesarios para hacerlo mecánico, en vez de dejarlo a la buena fe del modelo:
-
Sistema de plugins (Cordis) donde un paquete puede registrar tools y instalar un hook
tools.guardque rechazawrite/edit/bashdirectos sobretodo/. La única vía de escritura son las toolstodo_*(que están gated) o el panel humano. -
Un approval seam de verdad (
ctx.approval.request) con UI,allowed-oncey fail-closed. No es "el modelo dice que aprobó": es el harness el que pide y registra la confirmación. -
Política de sandbox por sesión, de modo que cada sesión escribe en su propio
<workspace>/todo/— resuelto por ejecución, no con un cwd global frágil.
En otros harnesses, para lograr esto tendrías que reimplementar el seam de aprobación y el guard a mano, y aún así no tendrías dónde anclarlos de forma durable. Aquí es un plugin npm que se declara en una composición y sobrevive a reinicios.
La conexión con agnosticBrain
Lo lindo es que no inventamos una filosofía nueva: es la misma, aplicada a otro dominio.
| Dominio | agnosticBrain | dsh-todo-hardened |
|---|---|---|
| Qué protege | Conocimiento refinado a mano | El plan/estado de ejecución |
| Capa inviolable | curated/ |
locked/ |
| Mecanismo |
/propose → aprobación |
todo_propose → aprobación |
| Garantía | El LLM nunca sobrescribe | El agente nunca muta sin humano |
Antes protegíamos lo que sabes. Ahora protegemos lo que decidiste que se haga.
En resumen
Los agentes son poderosos, pero un agente que es dueño absoluto de su propia lista de tareas es un agente que puede re-negociar el contrato contigo a espaldas tuyas. Con DeepSeek Harness y dsh-todo-hardened, por fin convertimos el "debería respetar el plan" en "no puede modificarlo sin que tú lo apruebes".
El agente propone. El humano decide. Y ahora, de verdad, es imposible lo contrario.
Si quieres verlo: el plugin está en github.com/Macorreag/dsh-todo-hardened (npm @macorreag/dsh-todo-hardened, MIT), y la filosofía que hereda, en github.com/Macorreag/agnosticBrain.
¿alguna vez un agente te reescribió el plan a mitad de una tarea, lo detectaste?

Top comments (0)