El Hidratador¶
El Hidratador is the Context Expansion and Execution Staging Engine. It is the bridge between human-approved intent (the Ticket Board) and deterministic machine action (Taskrivet).
A ticket arrives dry: fifty words of intent. Execution needs wet context — a structured, byte-budgeted, self-describing instruction that a local worker can follow without further deduction. El Hidratador performs that hydration, stages the execution boundary, and records every step so that acceptance stays a human decision.
Pipeline position: upstream from Taskrivet, downstream from the Ticket Board.
This site documents the engine. For the project overview and install instructions, see the repository README.
Pipeline position¶
human intent deterministic action
(approved) (machine)
| |
v v
+-------------+ +-----------------+ +-----------------+ +-------------+
| Ticket | | El Hidratador | | Taskrivet | | Repository |
| Board |->| (hydration + |->| (execution |->| / working |
| (dry ticket)| | staging) | | agent) | | tree |
+-------------+ +-----------------+ +-----------------+ +-------------+
| ^ | |
| | | |
v | v |
+------------------+ +------------------+ |
| Ledger (SQLite) | | Sandbox boundary |--------+
| tasks, sessions, | | image, mounts, |
| evidence, events | | caps, limits |
+------------------+ +------------------+
|
v
+------------------+
| Operator review | -- accept --> DONE
| (acceptance gate)|
+------------------+
El Hidratador never executes work itself. It produces prepared state — a hydrated packet, an ordered manifest, a sandbox specification — and hands that state onward. A handoff is prepared state, not permission to execute. Whether that state is executed, and whether the result is accepted, are decisions made outside this package.
The six guarantees¶
These hold across the whole package. They are not aspirations; each one is enforced by code that refuses rather than degrades.
- The core is standard-library only. No network calls, no shell execution, no telemetry. The ledger is a local SQLite file.
- Nothing is accepted without an explicit operator decision.
finish()producesREVIEW; onlydecide(accept)producesDONE. The acceptance gate is never bypassed. - Every refusal is visible. Conflicts, failures, expired leases, omitted context, and byte budget overruns are all reported explicitly, with a reason.
- Context is untrusted reference data, never authorization. Attached context is quoted inside
--- BEGIN UNTRUSTED CONTEXT ... ---banners and is never treated as an instruction. - Eligibility is not authorization. Routing, sandboxing, and handoff can recommend; none of
them can grant.
execution_authorizedis alwaysfalsein emitted payloads. - Execution is not acceptance. Completed work is a proposal until an operator says otherwise. Declared is not measured: reported token counts come from workers and are never presented as provider metering.
Start here¶
Two commands, in order, if you have never seen the project.
# 1. Is this machine ready? It reports; it never repairs anything.
hidratador doctor
# 2. Watch a whole ticket lifecycle, narrated, on a scratch ledger.
hidratador demo --text
demo runs a ticket from INBOX to DONE in a temporary directory and explains each step. It
never touches your own ledger.
Three commands, in order, if you want to drive it yourself. This is the shortest path from an empty directory to a ledger with one task in it.
# 1. Create the ledger (default: ~/.el-hidratador/ledger.sqlite)
hidratador init
# 2. Create a task with an objective, acceptance criteria, and resource scope
hidratador task-add M-1001 \
--objective "Expose GET /healthz that echoes the edge request id" \
--acceptance "GET /healthz returns 200 with the X-Request-Id header; unit test passes" \
--scope repo/api --scope repo/edge \
--budget 4000
# 3. Inspect the whole ledger
hidratador status
Every command prints exactly one JSON object on stdout. Nothing else is written to stdout, so the
CLI composes with jq, pipes, and scripts without parsing prose.
For the full lifecycle — triage, lease, checkpoint, finish, accept — read the walkthrough, or the getting started page, which explains the vocabulary as it appears.
Documentation map¶
| Page | What it covers |
|---|---|
| Getting started | The five-minute path, with the vocabulary explained as it appears |
| Glossary | Every domain term, defined once, in one place |
| FAQ | The questions newcomers actually ask, answered without hedging |
| Install | Every install path: PyPI, checkout, container, devcontainer, from source |
| Architecture | The five layers, module map, data model, ticket lifecycle, DAG and context algorithms, trade-offs |
| CLI reference | Every command, every flag, exit codes, JSON keys returned |
| Context and packets | How context is attached, deduplicated, prioritised, budgeted, and omitted |
| DAG and sandbox | Node parsing, topological order, manifest schema, sandbox spec, boundary report |
| GitHub sync | Observations, outbox, idempotency keys, markers, reconciliation |
| Failure playbook | Every failure category, its ledger effect, and the exact recovery commands |
| Troubleshooting | Symptom, cause, and the exact fix, for the errors you will actually hit |
| Security | Trust boundaries, what is deliberately not done, reporting process |
| Operations | Ledger location, environment variables, backup, restore, event log, stuck-task runbook |
| Development | How to work on the project: conventions, adding a command, adding a migration |
| Community | How to get help, how to propose a change, how decisions are made |
| Decisions | The architecture decision records: what was decided, and what it cost |
| Roadmap | Now / next / later phases, and an explicit not-planned list |
| Walkthrough | A complete runnable session, start to DONE |
| Sample ticket | The ticket markdown shape that the DAG parser reads |
| Example configuration | Deployment shape for flags and environment variables |
| Example sandbox spec | A realistic build_sandbox() output |
The shape of a session¶
INBOX -> READY -> IN_PROGRESS <-> BLOCKED -> REVIEW -> ACCEPTED -> DONE
| | |
| | +-- only decide(accept)
| +-- decide(retry) returns to READY
+-- start() acquires a lease; expiry blocks the task
task-addcreates a ticket inINBOX.triagemoves it toREADYonce scope exists.startacquires an execution lease and moves it toIN_PROGRESS.checkpointrecords summary, evidence, next step, and cumulative tokens; it renews the lease.finishmoves it toREVIEW.decide acceptmoves it throughACCEPTEDtoDONE.decide retryreturns it toREADY.decide cancelmoves it toCANCELLED.
Library use¶
The package is importable and the core has no runtime dependencies.
from el_hidratador import Ledger
from el_hidratador.context_expander import expand_from_ledger
with Ledger("/tmp/ledger.sqlite") as ledger:
ledger.add_task(
"M-1001",
objective="Expose GET /healthz that echoes the edge request id",
acceptance="200 with the X-Request-Id header; unit test passes",
)
result = expand_from_ledger(ledger, "M-1001", max_bytes=8000)
print(result["prompt"])
Console script: hidratador. Module entry point: python -m el_hidratador. Python 3.11 or newer.
License¶
MIT. See LICENSE.