e4a36f1133
capability_groups.md exige que toda funcion de un grupo lleve su tag plano para ser descubrible via fn_search tag='orchestration'. 6 de las funciones del grupo (reboot_all_claudes, classify_fleet_termination, list_claude_fleet, drain_fleet_events, mark_claude_role, set_dod_contract) no lo llevaban. Se anade sin borrar los tags existentes. notify_desktop_go_infra ya llevaba el tag pero no figuraba en la tabla del grupo: se decide que SI pertenece (la usa el orquestador/watcher para avisar de un RECLAMA u otro evento urgente) y se anade a la tabla en orchestration.md (commit anterior), en lugar de quitarle el tag. Resultado: 13 funciones con tag orchestration, identicas a las 13 filas de la tabla del grupo (sin drift). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.9 KiB
3.9 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | |||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| set_dod_contract | function | py | infra | 1.0.0 | impure | def set_dod_contract(session_id: str, contract: str, status: str = 'pending', goals_dir: str | None = None) -> dict | Escribe un DoD-contrato fijo y su estado en el sidecar goal.json de una sesion Claude (~/.claude/goals/<session_id>.json). Preserva TODOS los campos existentes (goal, phase, dod, history, prompts) y solo actualiza dod_contract y dod_status. Usado por el meta-orquestador de flota para fijar el criterio de aceptacion estable contra el que se evalua la terminacion de un agente. Escritura atomica via tmp + os.replace. |
|
false | error_go_core |
|
|
dict con session_id, path (ruta del goal.json escrito), dod_contract, dod_status y written=True | true |
|
python/functions/infra/set_dod_contract_test.py | python/functions/infra/set_dod_contract.py |
Ejemplo
from infra.set_dod_contract import set_dod_contract
# El meta-orquestador fija el criterio de aceptacion al lanzar un agente.
res = set_dod_contract(
session_id="a1b2c3d4-5678-90ab-cdef-1234567890ab",
contract="Los tests de python/functions/infra/ pasan en verde y fn doctor uses-functions no reporta drift",
status="pending",
)
print(res)
# {'session_id': 'a1b2c3d4-...', 'path': '/home/enmanuel/.claude/goals/a1b2c3d4-....json',
# 'dod_contract': '...', 'dod_status': 'pending', 'written': True}
# Mas tarde, al evaluar la terminacion: marcar el contrato cumplido (preserva goal/phase/dod).
set_dod_contract("a1b2c3d4-5678-90ab-cdef-1234567890ab", res["dod_contract"], status="met")
Cuando usarla
Usala cuando el meta-orquestador de flota lance un agente y necesite fijar el DoD-contrato estable, y cada vez que reevalue la terminacion para mover dod_status a met o failed. Es la unica via correcta para tocar dod_contract/dod_status sin pisar el resto del sidecar goal.json.
Gotchas
- El hook GOAL-TRACKER reescribe la clave
doddel goal.json (el DoD de trabajo, volatil) en cada turno, pero NO debe tocardod_contractnidod_status(el contrato FIJO de aceptacion). Esta funcion solo escribe esas dos claves y preservadodtal cual la dejo el hook. statussolo acepta "pending" | "met" | "failed". Cualquier otro valor lanza ValueError ANTES de escribir: el archivo en disco queda intacto.contractvacio o solo whitespace lanza ValueError sin escribir.- Escritura atomica (tmp + os.fsync + os.replace): si el proceso muere a mitad, el goal.json original no se corrompe.
- Si el goal.json existente es JSON corrupto o ilegible, se parte de un dict vacio (no se aborta) — se pierde el contenido viejo ilegible pero se preserva el contrato nuevo. Es deliberado: un sidecar ya roto no debe bloquear al orquestador.
goals_dirdefault es~/.claude/goals(real). En tests SIEMPRE pasargoals_dir=str(tmp_path)para no tocar las sesiones vivas.