gFactory
an attempt. building in public.

by Rupreet · solo build

← All entries

Journal / Week 3 / Sunday, October 18, 2026

From idea to first specs

gFactory's spec writer wrote the first specs for gFactory itself. Here's what that actually means, and why I trust it enough to automate.

Hand-drawn sketch: gates verify the work matches the spec through tests and code review, but only a human decides whether the spec was the right thing to build.

The story

gFactory's spec writer wrote the first specs for gFactory itself. Here's what that actually means, and why I trust it enough to automate.

First, a precise claim

gFactory doesn't exist yet, so it can't literally write its own specs. What did the job is the spec writer, the first stage of the pipeline, in its earliest form: a reusable skill. That skill read gFactory's PRD and produced gFactory's first builder specs, and I reviewed them. The spec writer was the first piece of the factory to produce real output, and what it worked on was the factory itself.

How the spec writer came to exist

My process for any project starts with a PRD and a tech design. The PRD comes from my own brainstorming and the direction I give, and it takes many iterations until I'm convinced it points the right way. gFactory's PRD went through five versions, and v0.5 is the one I treated as final.

From the PRD I used to write builder specs by hand, in a format my Pebble harness understands. I've fed that format to Pebble many times and seen exactly what comes out, so I trust it.

This time I didn't write them. I gave Claude one of my existing builder specs as an example of the detail and format I use, and asked it to create a reusable skill that produces specs the same way. Because it's a skill and not a prompt, any agent or tool can use it.

Then I validated it before trusting it:

I generated three specs. I read them closely, comparing them with specs I'd write myself. Only once they held up did I run it across the whole PRD.

The skill didn't have to earn trust from scratch. The format is proven, because it's the one my harness already works well with. What I was automating was the writing, not the standard.

What came out

The result is a spec pack for Milestone 0, the walking skeleton, covering specs 00 to 10. Each spec has a goal, a list of what it depends on, and acceptance criteria where every criterion has a Verify: step that passes or fails, so "done" isn't a matter of opinion. The pack also contains:

Two shared-context specs (engineering conventions and the data model) that go to the agent alongside every other spec, so each build starts with the same ground rules. A build order in six groups, where specs in the same group don't overlap in what they own, so they can be built in parallel, one spec per branch and per pull request, and I review and merge each. A testing playbook, which I'll explain in the next section, because it wasn't in the first draft. And a defined finish line: on my server, a small real change to gFactory itself goes from "ready" to an open pull request with passing acceptance evidence, and killing the daemon mid-run loses nothing.

Specs 11 to 26 aren't written yet, on purpose. Each later batch gets written just before its milestone, when I know what the earlier milestones taught me. That also helps with the drift problem below: I don't write 27 specs of direction up front and discover in month three that the direction was off.

What my review found: the first draft had no way to test it

The first draft of the pack looked complete. Specs, dependencies, acceptance criteria, build order, all there. Then I asked the obvious question: how will I actually test this?

There was no good answer. Every spec had Verify: steps, but nothing told me how to run a half-built factory safely. The factory's job is to hand real work to agents and open real pull requests. Where do I try that for the first time without pointing it at a real repo, spending real subscription time, or touching GitHub for real? The pack had no clear direction on that, and I'd have found out the hard way, in the middle of the build.

So I sent that gap back, and the pack was revised. The fixes were:

A local test factory on my laptop, with a throwaway sandbox repo to run packets against.

A fake agent that behaves like a coding agent but costs nothing and does exactly what I script, so I can test the pipeline without real runs.

A local stand-in for GitHub, so I can test pull-request creation without touching the real thing.

A dev command (gf dev) to bring that whole setup up in one step.

A checkpoint after each build group, so I know what "working so far" means before moving on.

A defined order for graduating: fake agent first, then real Claude, then the VPS. Each step adds one real thing, so when something breaks, I know which thing did it.

Guidance on building specs in parallel, since the groups are meant to run that way.

Six specs changed as a result (data model, config, the Claude Code adapter, the worktree manager, GitHub integration and the daemon/CLI spec), because testability turned out to be a design requirement of the components themselves, not a separate document.

That's the thing I'd flag for anyone generating specs with AI. The draft was internally consistent and still missed the question a builder would hit first. Consistency isn't completeness, and finding the gap is exactly why a human reads the specs.

Why spec writing moved into v1

My original plan was to keep writing specs by hand and automate that later, in phase two. That changed when I built the skill. I already had a generator that writes specs in the exact format Pebble is good with, so why leave it out of v1? A project like this runs to dozens of specs, and producing them one by one is its own tax. A factory that automates the build but not the part that feeds it would leave the most annoying part of the job exactly where it was.

Python over Rust, in my own words

I leaned Rust for weeks, and it wasn't a whim. I've used Rust where speed matters, on real-time data ingestion, where the APIs and infrastructure are in Rust and the SDKs point at them. I saw real performance gains there, and I assumed the same logic applied here.

It doesn't, because the problem isn't the same. Pebble has detailed rules for four languages (Python, TypeScript, Go and Rust), so any of them would have worked. Right now gFactory is an idea, not even an MVP. What I need is to change the pipeline's shape quickly as I learn what it should be, and to get it out of the door.

Pebble already writes about 90% of the code. I don't want to spend hours on the remaining 10%, so I picked the language where that 10% is quickest, which is Python. Rust stays an option for whatever turns out to be the real hot path, most likely the Kernel dispatch loop.

The risk I care about most: drift

This matters more than any code-review gate. Here's why:

Every gate in the pipeline checks work against the spec. The tests check that the spec's acceptance criteria hold. The reviewers check that the code does what the spec says. If the spec says "do X", the whole system will verify X perfectly. No gate and no agent can tell you whether X was the right thing to build.

That's a human's job, and it can't be delegated yet. If I automate spec writing and then stop reading specs, I haven't saved time, I've lost control of direction.

So I'm separating two kinds of trust:

Gates on the code can loosen over time. My plan is to run about 8 to 10 real projects with every gate on first, the same way I earned trust in Pebble. The gate on the specs is the one I believe should never switch off. That's my current belief, and I'll test it after the first few projects. It's possible the agents take over that job too, and I'm prepared to be proven wrong. For now, early review of the PRD and the specs is non-negotiable.

I don't yet have an automatic early-warning mechanism for drift. For now, the human spec gate is the mechanism.

The testing gap is a small example of the same problem. No gate would have caught it, because every acceptance criterion in the draft passed. Only me asking a question from outside the spec did.

What got done

  • Wrote and iterated the PRD to v0.5.
  • Built a reusable spec-writer skill from an existing spec format, and validated it on a few specs before using it on the full PRD.
  • Produced and reviewed the M0 spec pack (specs 00 to 10), with a build order, parallel build groups and acceptance criteria.
  • Caught a gap in review (no way to test the pack) and added a testing playbook, a fake agent and a local GitHub, which changed six specs.
  • Chose Python for the orchestrator.
  • Moved spec writing into v1.
  • Kept the spec-approval gate on by default for every project.

Learnings

  • Gates check compliance, not correctness. They can only tell you whether the work matches the spec. Whether the spec itself is right is a human question.
  • Automate the writing, not the standard. I trusted the skill because the format it produces was already proven.
  • Write specs close to when you build them. M0 is specced in full, and the rest waits until each milestone is near.
  • The right language depends on where your time goes. Rust helps when runtime is the bottleneck. Here the bottleneck is how fast I can change the design.
  • A spec can be consistent and still be unbuildable. The first draft had everything except a way to test it. Ask "how will I verify this works?" before approving a spec pack, not after.

Where things stand

The scope, the plan and the first spec pack exist, and nothing has run through the pipeline yet. Next is Milestone 0, where the machinery starts to actually exist.

Next up

  • Stand up the dev environment and the sandbox, and build the data model and config.
  • See whether the specs survive contact with an actual agent. That's the first real test of whether this approach works.

A question for you

If you use AI to draft specs or plans, how do you check that the direction is right, not just that the details are consistent?

More notes every Sunday. Browse the journal →