Ohad Baruch / Engineering with judgment.
Field note · August 26, 2026

Road to Agentic SDLC: Starting a project from scratch

How a product interview, repository-native PRD, small GitHub issues, model routing, and independent validation turned an early project idea into agent-readable delivery state.

An AI-assisted project usually starts as a conversation. I needed a way to turn that conversation into decisions another session could use.

I learned this while building an unnamed full-stack project with a frontend, backend, database, and a growing user base. As the project expanded, each new session had to recover the product decisions, the current boundaries, and the evidence for what already worked. That recovery was where the delivery problems began.

I call the approach Project Zero because the project was a useful zero point: a small enough system to expose the workflow, and complete enough to make the workflow answer to real code.

Start with a hard conversation

The work began with /grill-me, a skill from Matt Pocock’s skills repository. Its job is uncomfortable and valuable: interview the person proposing a plan until the important decisions are explicit.

That changed the shape of the work before a line of application code existed. The conversation forced questions about the user, the first useful outcome, boundaries, failure cases, and what could wait. It surfaced assumptions that felt obvious while they were inside my head and became ambiguous as soon as another engineer, or an agent, had to act on them.

The result was still a conversation. It contained decisions, but they were mixed with exploration, alternatives, and context that had accumulated over time. A future task could quote the conversation, yet quoting it would make the next agent reconstruct the plan again. On early attempts, the agent could lose focus, hallucinate a detail, miss an acceptance criterion, repeat an instruction, drift from the product direction, or break behavior that already worked.

The reason I used /grill-me was the Known-Unknown Matrix, often called the Rumsfeld Matrix. It gave the grilling session four places to look:

Questioning moves items from the last three categories toward explicit decisions before they become implementation assumptions.

The Known-Unknown Matrix turns questioning into explicit decisions
Four-quadrant Known-Unknown Matrix showing known knowns, known unknowns, unknown knowns, and unknown unknowns across knowledge and awareness axes.

That reconstruction is a hidden tax. It also introduces drift. Two capable agents can read the same long discussion and leave with different definitions of done.

The next step was to turn the conversation into a project artifact.

Make the repository hold the plan

The local workflow used /to-prd and /to-issues, also from the skills family. Those names are historical names in this repository. The current upstream names are /to-spec and /to-tickets in Matt Pocock’s skills repository.

The naming matters because it describes the actual progression. The PRD step made the product intent durable: what the system should do, who it serves, and which constraints shape the first version. The issues step converted that intent into independently deliverable work.

One conversation becomes a durable PRD and several GitHub issues
Three-column flow from Codex Conversation to PRD.md to GitHub Issues, where PRD.md branches through separate arrows to GitHub Issue #1, GitHub Issue #2, an ellipsis, and GitHub Issue #n.

The repository became the source of truth. The discussion remained useful background, but the committed PRD and issues became the artifacts that implementation and review could point at. A new task could start with a bounded objective, acceptance behavior, and explicit exclusions. It no longer needed to recover the whole project from a chat transcript.

A repository-native requirement gave every participant something they could review, diff, link to a pull request, and recover after the originating conversation left immediate context.

Slice the system vertically

The /to-issues step shaped the plan into tracer-bullet issues. Each one crossed the relevant layers far enough to prove a user-visible or operational path: interface, application behavior, persistence or integration, and the checks that give the slice credibility.

Horizontal layers and vertical tracer-bullet slices
Side-by-side comparison of horizontal UI, Backend, Database, and Tests lanes with vertical tracer-bullet slices crossing every layer to complete testable outcomes.

Tracer bullets are useful for agentic work because they create a narrow feedback loop. An issue can be implemented, exercised, and reviewed without requiring every future layer to exist. Each slice proves one narrow user-visible or operational outcome through the layers it needs, so evidence becomes available while the rest of the system is still under construction.

The boundaries also made parallel work safer. Separate issues could have separate branches and separate delivery contexts. Inside one issue, the scope stayed coherent. That distinction matters. Parallelism between well-defined slices can increase throughput. Several writers changing the same slice usually increase reconciliation work.

The issue descriptions carried the details an agent needs to work responsibly: the outcome, acceptance criteria, dependencies, and verification plan. They also stated what was excluded. An exclusion is a delivery tool. It keeps a locally reasonable improvement from quietly becoming a second project.

Match reasoning to difficulty

Once the work was expressed as issues, model selection became a routing decision instead of a preference attached to the whole project.

Some tasks were straightforward and bounded. Others involved architecture, ambiguous behavior, or a high cost of being subtly wrong. They did not need the same model or the same reasoning effort.

{
	"repository": "example-org/example-service",
	"issue": 142,
	"title": "Add idempotency to payment retries",
	"target_model": "gpt-5.6-terra",
	"effort": "Low",
	"rationale": "The change is narrow, follows an existing adapter, and has explicit acceptance tests."
}
A somewhat easy task receives a lower-level model

The routing policy was difficulty-based. Low-risk work could use a faster, less expensive path. Work with more uncertainty or more consequential boundaries received a model and effort level appropriate to that difficulty. I wanted reasoning effort to follow the difficulty and consequence of each issue, with the allocation visible for later refinement.

This also made the tradeoff visible in the issue itself. A target model, effort, and rationale explain why a task is routed a certain way. They create a future record that can be compared with the observed result. Without that explanation, model selection becomes folklore: one model is used because it worked once, then the choice spreads to tasks with different risk.

My experience estimate is that roughly 70-80% of the work can be cheaper or faster with this routing than with the most capable path applied to every task. I have not measured that figure as a benchmark. I treat it as a working estimate that tells me where to collect better evidence.

Let validation start with less context

The most important change was the validation boundary. Validation benefits from a separate job, a clean context window, and authority to examine the implementation as a claim.

Implementation and validation share evidence while keeping context separate
Two-column diagram showing an Implementation Agent with a private implementation context and a Validation Agent with a separate private validation context, both pointing to the same GitHub Issue and exact pull request evidence.

The implementation context contains a strong bias toward completion. It knows the intended design, the decisions made during construction, and the compromises made to get the slice working. That context is valuable for writing code. It can make a weak interpretation feel inevitable.

Independent validation starts elsewhere. The validator receives the repository, the issue, the resulting artifact, and the verification instructions. It does not inherit the implementation conversation as authority. It can inspect the visible behavior, run the checks, and ask whether the result satisfies the issue rather than whether it matches the implementer’s explanation.

Clean context creates a productive asymmetry. The implementer tries to make the claim true. The validator tries to falsify the claim that the work is complete.

The review surfaced several concrete gaps:

The separate validation job exposed these cases because it started with a clean context and permission to examine the implementation as a claim. The validator could focus on the issue, the diff, the exact artifact, the tests, and the observed behavior.

The workflow is a control loop

The pieces form a small control loop:

The delivery loop from conversation to accepted outcome
First Codex Conversation flows to PRD.md and GitHub Issues; a second Codex Conversation sends one issue to Implementation, then Validation, GitHub Evidence, and Accepted Outcome, with corrections returning to Implementation.

Validation findings can revise the issue, the design, or the next slice. The repository records the durable decision, while the conversation remains a place to explore what the evidence means. That is why the loop returns from validation to the work instead of ending at the first passing check.

The output of each skill became a constraint for the next step. /grill-me exposed decisions that the PRD could record. The PRD gave /to-spec and /to-tickets the material for dependency-aware issues. Those issues carried the model-routing rationale into implementation. The resulting diff and exact commit then gave a clean-context validator something precise to examine.

What I would keep

Four practices survived the experiment:

  1. Start with adversarial clarification when the problem is still fuzzy.
  2. Commit the resulting product intent and delivery slices to the repository.
  3. Route work according to difficulty and consequence, with the rationale visible.
  4. Give validation enough independence to challenge the implementation’s story.

Together, these practices reduced the amount of project state that lived only in my memory or in one agent’s context. They also made the work easier to resume. A new session can begin from the current repository state and the current issue instead of asking someone to retell the project.

One concrete cost was the extra validation session. It added time to a slice, and one of those sessions found a behavior gap that sent the implementation back for correction. That was useful evidence: the issue, the changed files, the test result, and the observed behavior could be compared before anyone treated the slice as complete. The record remained attached to the GitHub issue and pull request for the next session to inspect.

The next experiment

Project Zero left me with a baseline to measure and revise as more projects provide evidence. I want to learn which issue sizes benefit most from tracer bullets, whether model routing changes cycle time or correction rate, and how much independent context catches boundary failures without recreating the implementation. I also want to compare findings from a clean-context validator with findings from a reviewer who participated in the build. Those measurements will show where agents help produce accepted changes while keeping engineering judgment visible and recoverable.

The first clean-context review ended with a practical question. What exactly should the implementation session hand to the validator: a summary, a commit, a test report, or all of them tied to the same issue? The next session exposed the answer through a failed handoff, which is where the story continues.