---
title: "Inside an AI publishing harness that spends tokens like money"
description: "How Control Square built an AI publishing harness that spends model tokens only on judgment, with deterministic checks, file-based state, and one human publish decision."
url: "https://controlsquare.com/work/ai-publishing-harness"
---

# Inside an AI publishing harness that spends tokens like money

A solo publisher was losing the week to the work around the writing. We built an AI publishing harness that does that work and stops at the decision: files for state, scripts for the mechanical layer, a model only for judgment, and one human publish decision.

## Key facts

- Client: [Forgotten Education](https://forgotteneducation.substack.com), a one-person education publication
- Status: Live, 3 issues
- Scope: Research, drafting, checks, images, Substack drafts
- Stack: Python, Substack, Cloudflare, S3
- Code: [ControlSquare/token-frugal-harness](https://github.com/ControlSquare/token-frugal-harness), MIT

## The problem

Forgotten Education is a one-person publication. The writing was never the bottleneck. The week went to finding a topic with demand, checking the angle, sourcing claims, generating and resizing images, formatting for Substack, and keeping the voice consistent across issues.

The obvious fix is another tool. The useful fix is an AI control layer that knows which work is mechanical and which work is not. That distinction is the whole project.

## The architecture

The rules are not stylistic. They are how the AI harness stays cheap enough to run and small enough to move between machines.

### The four rules

1. **Return paths, never content.** A subagent writes a file and returns the path. The parent does not receive the research pasted back into the conversation.
2. **State lives in files.** The queue, the archive, and progress survive the session. A conversation is a cache, not a database.
3. **AI only where judgment is the point.** Formatting, resizing, link checks, and tests are scripts. If a script can do it, a model never sees it.
4. **Read on demand.** Voice rules load before drafting. The corpus is searched, not preloaded.

### Folder tree

```text
substack-runner/
  config/
    voice.yaml
    schedule.yaml
  data/
    queue.json
    drafts/
    published/index.csv
    research/
  scripts/
    research.py
    check_draft.py
    substack_draft.py
  references/
    writing-standards.md
  docs/
    workflow.md
```

This is the sanitized tree. The public repo carries a runnable version with example data.

## The gate

The public gate checks frontmatter, length, structure, source links, em dashes, and unfinished markers. The client system adds sourcing, voice drift, and layout checks. It returns a pass or a list of errors. It never rewrites the draft.

That restraint matters. If the gate rewrote the piece, the reviewer would be reviewing the gate's argument. The human keeps the argument, the voice, and the publish decision.

28 offline converter tests and 22 guard checks keep the mechanical layer honest.

```text
---
title: "The one decision rule for AI drafts"
slug: one-decision-rule
status: draft
audience: operators
sources: 1
---

## The rule

One draft, one decision.
```

This is a sanitized draft from the repo's examples, not client content.

## The result

Three issues are live. Each one passed the gate, carried sources, and arrived in Substack as a formatted draft. The publisher read it and decided. No post went live unreviewed.

- 3 issues live
- 1 decision per post
- 22 guard checks
- 28 converter tests

Read the [live publication](https://forgotteneducation.substack.com) or view the [reference implementation](https://github.com/ControlSquare/token-frugal-harness).

## What stayed human

The topic, the argument, the voice, and the publish action. The AI harness is designed to make those the only things that need a person. That is not a limitation. It is the point.

Publishing remains manual. An unreviewed post at 3am is how you hear about it from a reader.

## Limits

- **Not auto-publish.** The review decision is permanent. Scheduling is a separate, deliberate choice.
- **Not a taste engine.** The gate checks mechanics. It does not decide whether the piece is worth publishing.
- **Not the client repo.** The public code is sanitized. No client content, credentials, or session data.

## The code

The reference implementation is a small AI harness, public and MIT licensed. It includes the four rules, the queue, a working gate, tests, and example data.

[View the reference implementation](https://github.com/ControlSquare/token-frugal-harness)

## Start here

Tell us where the work piles up. We will tell you what AI can take, what it should not, and what it would take to build.

Contact: https://controlsquare.com/contact/

Built by Control Square. The publication is the client's, not ours. The code is a sanitized reference.

Back to [Work](https://controlsquare.com/work/).
