Mechanical ouroboros - self-healing loop

LOOP-DEMO: Dogfooding Until It Worked

We built gateproof. Then we tried to use it. It wasn't ready.

PART 4 2026.01.30

THE SERIES SO FAR

THE GAP

gateproof had the pieces: gates, PRDs, verification. But no auto-heal. No "push and walk away."

We kept babysitting it. Run gates. See failure. Manually fix. Run again. That's not a loopβ€”that's just me with extra steps.

What we wanted:

Push a PRD β†’ Agent loops until gates pass β†’ Done

WHAT WE ADDED

scripts/heal.ts

Agent reads PRD + failure output, calls OpenCode Zen, writes fixes.

.github/workflows/loop.yml

Push triggers healing loop. Run gates β†’ if fail β†’ heal β†’ repeat.

deja integration

Memory from previous sessions injected into each iteration.

PAUSED kill switch

Touch .gateproof/PAUSED to stop. Delete to resume.

THE DOGFOOD

We built loop-demo: a repo that heals itself.

Added a gate that required src/greeting.ts to export a greet() function. File didn't exist.

// gates/greeting.gate.ts
if (!existsSync("src/greeting.ts")) {
  return { status: "failed", error: "src/greeting.ts does not exist" };
}
const mod = await import(modulePath);
if (mod.greet("World") !== "Hello, World!") {
  return { status: "failed", error: "greet() returned wrong value" };
}
return { status: "success" };

Pushed. CI triggered. Agent created the file:

// src/greeting.ts (created by agent)
export function greet(name: string): string {
  return `Hello, ${name}!`;
}

Gate passed. File committed. The loop healed itself.

WHAT BROKE

This is what dogfooding looks like. Everything broke.

tee swallows exit codes

Fix: set -o pipefail

Relative imports fail in gates

Fix: Use process.cwd() for absolute paths

git add -A commits node_modules

Fix: Add .gitignore, commit only .gateproof/ and src/

Bash JSON parsing is fragile

Fix: Use TypeScript (scripts/heal.ts) instead of jq

Each fix: push β†’ watch CI β†’ see failure β†’ fix β†’ push again. The meta was real.

WHERE IT RUNS

Now: GitHub Actions. Free, triggered by push. Limited to 6 hours per job, but each push triggers a new batch.

Later: Cloudflare Containers. Persistent compute, no time limits. The loop runs until done or paused.

bun run loop Β Β Β Β Β Β Β Β Β Β Β Β # runs until complete

touch .gateproof/PAUSED Β Β # stop

rm .gateproof/PAUSED Β Β Β Β Β # resume

THE FULL PICTURE

You:

Talk to agent β†’ update prd.ts β†’ push β†’ walk away

gateproof:

Run gates β†’ if fail β†’ agent heals β†’ repeat β†’ done

deja:

Memory from past failures β†’ injected into each iteration

WHAT'S NEXT

myfilepath.com β€” the platform for agents.

Agents get their own accounts. Their own environments. Their own secrets, files, and compute. Humans approve the billing.

That's the product. This series was the journey to get there.

TRY IT

git clone https://github.com/acoyfellow/loop-demo
cd loop-demo
bun install
bun run prd.ts  # see the gates
bun run loop    # watch it heal

Repo: github.com/acoyfellow/loop-demo

We used gateproof to build gateproof's demo.

The loop built the loop. That's the whole point.