GDDP
Active buildA control plane for bounded agent autonomy. GDDP turns a project into an explicit dependency graph of bounded work, dispatches nodes to agent executors, and stops at human review — no silent writeback.
Why this exists
Agentic developer tools split into two camps. Inline assistants work synchronously inside your editor, bounded by whatever you're looking at. Async cloud agents take a task description and run — they decide their own scope, and you trust the model to work out what "done" means.
Both share an assumption I think is wrong: that scope determination is the agent's job.
GDDP inverts it. The work graph is human-owned. Agents execute nodes from that graph. They don't get to redraw it.
[SAB — the story that earned this claim.] The brief asks for the specific session where an agent went off-track and crystallized this. Right now the insight is asserted; the story is what makes a reader believe it.
What it does
Graphs define projects. Agents do not.
A project becomes an explicit dependency graph of bounded work. Each node carries its own scope, acceptance criteria, and dependency edges — written by a human, before any agent runs. The runtime finds nodes whose dependencies are satisfied, dispatches them, and collects structured receipts. Nothing advances without a human accepting it.
How it works
Two repos, because the graph and the machinery have different owners and different trust requirements.
gddp-config is the human-owned graph. YAML schemas define the vocabulary — event, node, job, result, queue record, artifact verification, task packet, shape profile. main is protected. No agent pushes here. Humans are the only merge authority.
gddp-runtime is the execution machinery — Python 3.11+, Flask, SQLite. It reads graph truth from gddp-config, finds ready nodes, builds payloads, dispatches to executor adapters, and persists receipts. It reads the graph. It never writes to it.
The intake pipeline runs webhook → classify → scope → queue → execute. The loop doesn't decide what to do — the graph already decided. It decides when the conditions are met.
The receipt wall. When an agent finishes and a PR merges, the result becomes a structured receipt: the artifact produced, what the agent claimed, links to what it generated. The job moves to awaiting_review and stops. Graph truth doesn't change until a human accepts, retries, or blocks.
This is the hardest line to hold. Every framework wants to auto-complete — tests passed, PR merged, done. But "tests passed" and "this is what we actually needed" are different things, and the receipt wall exists to hold that distinction open.
SQLite for receipts, because receipts are a structured log: queryable, durable, zero-config, a single file you can version alongside the graph. There's no reason to stand up Postgres for that.
Where it stands
Executor-agnostic by design. The dispatch loop doesn't care what runs the work — today the adapter routes to Jules via GitHub Actions labels; tomorrow it could be Codex, or Pi Agent for work that needs to stay local and gated. Any executor that speaks the contract — receive a payload, produce artifacts, return a receipt — can plug in.
[SAB — real usage numbers.] How many nodes dispatched? Accepted vs. retried vs. blocked? Is the real workflow "write nodes in gddp-config, push, watch the runtime pick them up"? A node you're proud of?
What's next
[SAB — where this lands.] The brief asks whether the Pi Agent connection was planned or emergent. Worth answering here.