Back to projects

GDDP

A 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.

PythonSQLiteGitHub ActionsYAMLAgent Orchestration

The core insight

Most agentic developer tools fall into two categories:

  • Inline assistants (Cursor, Copilot agent mode) work synchronously inside a single editor session. Good for line-by-line work, bounded by whatever you're looking at.
  • Async cloud agents (Jules, Devin, Codex) take a task description and run with it. They decide their own scope. You give them a goal and trust the model to figure out what "done" means.

Both share an assumption I think is wrong: that scope determination is the agent's job.

GDDP inverts that. The work graph is human-owned. Agents execute nodes from that graph. They don't get to redraw it.

Two repos, two owners

GDDP lives across two repositories because the project graph and the execution machinery have different owners, different update cadences, and different trust requirements.

gddp-config is the human-owned project graph. YAML schemas define nodes, jobs, events, results, queue records, artifact verifications, and task packets. Each node carries explicit scope, acceptance criteria, and dependency edges. main is protected — no agent can push here. Only humans write to this repo.

gddp-runtime is the execution machinery. Python 3.11+, Flask, SQLite. It reads graph truth from gddp-config, finds ready nodes (dependencies satisfied, no active job running), builds payloads, dispatches to executor adapters, and persists structured receipts. It reads the graph. It never writes to it.

The dispatch loop

A heartbeat loop runs on a schedule. Each tick:

  1. Read the project graph from gddp-config
  2. Identify ready nodes — dependencies complete, no job currently in flight
  3. Classify events — new node ready? job timed out? receipt arrived?
  4. Dispatch via an executor adapter — currently that means labeling a GitHub issue with a trigger label that routes work to Jules

The loop doesn't decide what to do. The graph already decided. The loop decides when the conditions are met to execute.

The receipt wall

When an agent finishes work and a PR merges, GDDP converts the result into a structured receipt: what artifact was produced, what the agent claimed was done, and links to generated artifacts.

The job moves into awaiting_review. Nothing auto-advances. Graph truth doesn't change until a human reviews the receipt and explicitly accepts, retries, or blocks the work.

This is the hardest line to hold. Every framework wants to auto-complete — "the tests passed, the PR merged, it's done." But "tests passed" and "this is what we actually needed" are different things. The receipt wall exists to hold that distinction open.

SQLite for receipts

Receipts are structured records: job metadata, agent identity, timestamps, artifact references, review status. They need to be queryable ("show me everything agent X has done this week"), durable, and zero-config.

SQLite fits because it's a single file, no server process, queries across receipts are trivial, and the file itself is an artifact you can version alongside the graph. There's no reason to stand up Postgres for what is fundamentally a structured log.

Executor-agnostic

The dispatch loop doesn't care what executes the work. Today the adapter routes to Jules via GitHub Actions labels. Tomorrow it could route to Codex, a local harness on a Raspberry Pi, or any executor that speaks the same contract: receive a payload, produce artifacts, return a receipt.

No single executor is right for every class of work. Cloud agents handle async throughput. Local harnesses handle constrained, safety-critical work. Pi Agent (see the Pi Agent page) is designed as a GDDP executor for that latter category.

GDDP Dispatch Flow

What changed

Before GDDP, I'd start a coding session and think "what should the agent work on?" After GDDP, I look at the graph. The answer is already there — whatever node is ready, bounded, and reviewable.

Scope is pre-negotiated. Execution is auditable.