All projects

Employer work

AI-Augmented Engineering Setup

A twelve-repository workspace instrumented as an environment for coding agents — authored skills, guard-rail rules, four human gates, parallel execution in isolated worktrees, and adversarial review before anything merges.

Role
Design and implementation
Period
2026
Stack
  • Claude Code
  • Cursor
  • Bash
  • Git worktrees
  • Playwright
  • Python
  • Markdown

This is employer work. Names of companies, clients, products and repositories are withheld; the architecture and the reasoning are not.

The problem

Using an AI coding tool well is not the same problem as using one at all. On a workspace of twelve repositories in several languages, an agent with no map does the same three things every time: it edits the wrong repository, it invents a convention that already exists somewhere else, and it commits to a branch it should never have been on.

None of those are model failures. They are missing infrastructure.

The approach

Treat the workspace as a system with an interface for agents, the same way it has one for humans.

Artefact Count What it holds
Root agent instructions 2 files, ~12.7 KB Workspace map, a routing table of “when doing X, use skill Y”, branch policy with ❌/✅ examples
Skills lockfile 1 7 external skills pinned by source, path and SHA-256 hash
Skills 16 9 authored, 7 vendored by symlink
Cursor rules 5 3 always applied, 2 on demand
Specifications 23 features 79 files, ~10,700 lines of spec, design and task breakdown

The nine authored skills split into flow orchestration, technical planning and refinement, performance diagnosis, and automated documentation. Two of them are worth describing because they have opinions embedded in them.

The API performance investigator explicitly forbids proposing a cache as a solution. Not discourages — forbids. A cache in front of an N+1 query makes the graph look better and leaves the problem in place, and “add Redis” is the answer a model reaches for first because it is the answer written most often on the internet. Removing it from the option set forces the actual diagnosis: eager loading, payload size, a duplicated request, a missing index.

The network profiler logs in through a real browser, captures every request on a screen with real timing, aggregates by endpoint, detects duplicated requests, and diffs two runs. It is the natural input to the investigator above.

The pipeline

Ticket, or a free-form description

   ├─ PHASE 1  PLAN ── spec, context, design, tasks
   │      ├─ automatic critique: a separate agent reviews the specs against a
   │      │  two-axis rubric, and valid findings are applied to the spec files
   │      │  directly — except where a finding contradicts a decision already
   │      │  recorded as settled
   │      └─ GATE 2 (hard stop) — a human approves the already-critiqued specs

   ├─ PHASE 2  TICKET — GATE 3 confirms creation on the board

   ├─ PHASE 3  EXECUTION
   │      ├─ working branch established before any code is written
   │      ├─ parallelisable tasks → isolated Git worktrees
   │      └─ sequential tasks → in series on the working branch

   ├─ CONSOLIDATION — only tasks with a passing verdict are merged

   └─ PHASE 4  DELIVERY — GATE 4 (always a hard stop)
          plan shown → explicit go-ahead → push with an explicit refspec
          → verify the upstream → only then open the pull request

Decisions worth defending

Human gates are part of the architecture, not good intentions. Four gates, two of them hard stops. Delivery is never automatic. The temptation to remove the last gate — the work is reviewed, the tests pass, the verdict is positive — is the reason it is a hard stop rather than a configurable default.

Review is adversarial in two layers. On the specifications: a critic agent evaluates the plan against a rubric before a human sees it, so the human reviews an improved draft rather than a first attempt. On the code: each parallelisable task runs in its own worktree through a two-phase pipeline — a build agent that must leave the gate command green, then a judge agent whose prompt is explicitly try to refute that this is done, returning a structured verdict. A task that fails is not merged, and appears in the summary with the reason.

Prompting a reviewer to approve produces approval. Prompting it to refute produces findings. The asymmetry is the whole mechanism.

Delivery policy is an executable, tested shell script — the markdown is the mirror. It classifies each of the twelve repositories into branch-and-pull-request, direct commit allowed, or refuse, and it has its own tests and semantic exit codes. Policy that lives only in prose is policy that is followed approximately.

One layered defence exists because of a real incident. Creating a branch from the production branch sets that branch as upstream, and a bare push then goes straight to production. The defences stack: an instruction with a worked ❌/✅ example, a required command form that does not set that upstream, pushes always carrying an explicit refspec, and a check that aborts before opening the pull request if the resolved upstream is a production branch. Any one of those alone would have failed eventually.

State is recorded with verified evidence, not impressions. The workspace state file logs dated decisions with the gates that were run, exact passing test counts, numbered new findings and classified blockers. “I think it works” is not an entry that can be written.

Scale

  • 12 repositories, 16 skills, 5 rules, 23 specified features (~10,700 lines)
  • 9 authored skills; 7 external skills pinned by SHA-256 in a lockfile
  • 4 human gates, 2 hard stops; adversarial review at both the spec and the code layer