Software Development Workflow

My software development process is designed around a simple principle: AI does the implementation, humans do the judgment. Here's how that works in practice.

The Flow

  1. I describe the outcome I want and the reason it matters
  2. The implementing AI loads the constitution and project context, verifies its host and identity, and checks repository freshness
  3. It implements on a feature branch, verifies the behavior, and opens a pull request
  4. Independent non-implementer AIs review the actual PR diff
  5. The implementer fixes substantive findings and sends the revision back through review
  6. I review the product outcome, UX, and important judgment calls — I don't rely on reading code diffs
  7. The change is merged only after the required reviews, checks, and explicit approval are complete

The task may begin in conversation, Basecamp, OmniFocus, or project documentation. The safety and review process is the same regardless of where the request originated.

PRs Are Non-Negotiable

Every non-trivial code change goes through a pull request. This is a hard rule in the constitution. The AI can ask to skip a PR for genuinely trivial changes, but it needs my explicit approval first.

PRs serve as:

  • A clean record of what changed and why
  • A gate for mandatory independent AI review
  • A natural checkpoint for my review

Branch Naming

Branches follow a simple convention:

  • feature/descriptive-slug — new functionality
  • fix/descriptive-slug — bug fixes
  • audit/descriptive-slug — code audit findings

AI Reviews AI

This is the most counterintuitive part of the process, and it's been remarkably effective.

After the implementing AI opens a PR, independent reviewers receive:

  • The actual GitHub PR diff
  • The relevant functional spec
  • The project's audit methodology
  • The verification evidence and known risks

The reviewers examine the code for bugs, security issues, architecture problems, and deviations from the intended behavior. Findings go back to the implementing AI, which applies fixes and repeats the review cycle.

The loop is capped. Repeated high-severity findings are a signal to stop patching and reconsider the approach, not to keep accumulating fixes indefinitely.

Review tiers

The amount of review scales with risk:

  • Typo-only documentation corrections can skip the PR and formal review process
  • Narrow copy, styling, rename, or patch-level dependency changes get one independent reviewer whose first job is to verify that the change really is classification-only
  • Normal code and configuration changes get two independent reviewers
  • Trust-critical products get three reviewers and require unanimous approval, even for apparently small changes

Every PR records its reviewers explicitly. A reviewer must be independent of the implementation and, where possible, come from a different provider or model family so the reviews do not share the same blind spots.

Why it works

Independent AIs catch real bugs — not theoretical ones, but things like missing error handling on API calls, unsafe trust assumptions, and logic errors that the implementing AI was too close to notice. It's the same reason human code review works: fresh eyes.

The key is independence. Asking the implementing model to reread its own work in the same conversation is useful self-checking, but it is not independent review.

Root-Cause-First Engineering

One lesson I learned the hard way: AI coding agents need explicit rules against "fake simplicity."

Left to themselves, they will sometimes:

  • introduce mock data instead of fixing the real data flow
  • replace a complex production component with a narrower toy version
  • add workaround logic that hides the symptom without fixing the cause
  • quietly create a second implementation path instead of repairing the original one

So I enforce a simple rule set:

  • work with the existing codebase
  • fix the root cause
  • do not replace real implementations with simplified stand-ins unless I explicitly ask for that

That rule dramatically improves the quality of AI-generated changes because it forces the model to respect the actual system instead of optimizing for a quick-looking patch.

What I Look For In Audits

When I ask an AI to audit a codebase, I don't just want generic lint or security advice. I want it to look for the characteristic AI failure modes too:

  • mock-data substitution
  • simplified replacement components
  • parallel code paths created to avoid fixing the original
  • workaround patches instead of root-cause fixes
  • fake recovery signals that make things look healthy without restoring correctness

That turns code review into something closer to a real engineering audit instead of a style check.

The Human Role

I don't read code diffs. I don't debug. My role in the development process is:

  • Define what to build — describing the desired outcome, intent, and constraints
  • Review outcomes — does the feature work? Does the UI feel right?
  • Make judgment calls — approve or reject product decisions, prioritize work, and challenge architecture when the implementation feels structurally wrong
  • Set the boundaries — decide what can run autonomously, what requires confirmation, and what must remain private

This works because the AI handles implementation, verification, and code-level review while I remain responsible for intent, product quality, risk, and final authorization.

Task and Job System

Interactive work can begin from several surfaces:

  • Basecamp for shared project work and assignable to-dos
  • OmniFocus for my personal commitments and planned work
  • Obsidian for durable context, plans, decisions, and project memory
  • Conversation for direct, interactive requests

Recurring automation uses a separate job registry. Each job declares its owner, class, schedule, executor, output route, state policy, and model role. Deterministic scripts run directly under the operating system; work requiring judgment runs inside an agent runtime.

This prevents a scheduled prompt from becoming an undocumented miniature application with unclear ownership and hidden state.

Activity Logs

Active projects maintain concise activity logs or topic memory where that history will matter later. Entries record meaningful decisions, operational changes, verification evidence, and PR references without reproducing the whole conversation.

This log is invaluable when I need to understand what happened in a project while I wasn't paying attention. It's project history written as it happens, not reconstructed after the fact.

Functional Specs

Products with meaningful behavior maintain a living functional spec that AIs update as they build. The spec is a byproduct of implementation, not a separate documentation effort. It answers: what does this software do, right now?

This means I always have an up-to-date description of each project's capabilities without having to read the code or remember what was shipped three months ago.