Skip to content

Documentation

Agents and autonomy

You decide how much each agent may do on your site, and you can stop any of them without a deploy. Each of the 16 agents runs on a schedule in your GitHub repository at the level you set (off, report, propose or merge), and all start at report, so nothing changes until you raise one. An agent set to merge keeps asking for approval until it has a record of clean runs.

The agents

Agent Runs Starts at Never above What it does
Memory agent (memory) Every Monday report propose Learns your products, services, buyers, locations, proof points, competitors and voice, and keeps them current, so every other agent works from the same facts.
Research agent (research) Every Monday report merge Maps the searches your buyers make before they decide who to call, and checks whether Google and AI answers mention you for each one.
Strategy agent (strategy) Every Monday report merge Studies what already ranks, finds the gaps, and builds a ranked plan of pages and posts to fill them.
Content agent (content) Every day report merge Writes pages and explainers around real buyer searches and news in your field, and publishes them once every check passes.
Page families agent (families) Every Wednesday report propose Adds the next comparison, alternative, location or integration pages, in order of measured demand.
Writer (writer) Every day report propose Turns the content agent's briefs into posts, every fact from a linked source.
SEO agent (seo) Every day report merge Fixes the pages sitting just off page one: titles that lead with the phrase buyers type, direct answers, and links from pages that already rank.
Refresh agent (refresh) Every Thursday report merge Keeps improving pages after they go live, so they stay relevant as searches and AI answers change.
Authority agent (authority) Every Tuesday report propose Earns the links and listings that tell search engines and AI answers your business is worth recommending.
Design and development agent (site) Every Tuesday report propose Keeps the site fast, readable and easy to act on, so buyers understand what you offer, trust you and take the next step.
Follow-up agent (followup) Hourly, working days report propose Makes sure every enquiry gets a fast, personal answer and doesn't go cold.
Paid boost agent (paid) Every Monday report propose Plans paid search for the searches you don't rank for yet, so the pipeline keeps moving while organic grows, and retires each campaign when the page ranks.
Covers agent (covers) Every day off merge Draws a cover for every post that has none, in your brand, so the blog and every shared link show what the post is about.
Video agent (video) Every Wednesday off propose Turns a topic your buyers search into a short narrated explainer for your site and your YouTube channel.
Watchdog (watchdog) Every hour merge merge Checks every hour that every agent has run and succeeded, and emails once per problem.
Canary (canary) Every night merge merge Sends a test brief through the real pipeline every night and throws the result away, to catch a broken model, key or check before real work hits it.

Run any of them by hand with heddle agent <id> <site> --dry-run to see what it would do without doing it.

Levels

Every agent runs at one level, set per company in heddle/autonomy.json. No agent decides its own level, and none is hard-coded to merge.

Level What the agent does
off Nothing.
report Reads, decides, and emails what it would have done. Changes nothing.
propose Opens a pull request or a draft. A named person approves it through a signed link before anything ships.
merge Merges its own pull request once every gate passes, deploys, and reports what it did with an undo link.

Outreach (pitches to publications) has the same four levels and one extra rule. At merge, it sends only to addresses a publication lists for editorial contact. Anything that would go through a contact form goes to a person instead.

Earning a level

A person sets the level in autonomy.json; the code then holds merge back until it is earned. An agent configured at merge proposes until its last promoteAfterCleanRuns runs (default 5) were all clean, and merges from the next run on, without anyone touching the file again.

Runs at any level count, so an agent that ran clean at report for a week arrives at merge already earned. A clean run is one that finished, skipped nothing it needed a model for, passed every gate it held its own work to, and left no recommendation open (recommendations.md).

One unclean run resets the count to zero.

So the decision is the person's and the timing is the record's. To see how far an agent is from merging, count the clean runs at the end of its list in heddle/agent-state.json.

On the original site, the SEO agent ran at propose for about a month before merging its own retitles, and explainers were approved by hand for two days of clean output before they published themselves. Both were moved up because the owner asked, with the record in front of them.

What every agent has regardless of level

  • A kill switch. A repository variable named in autonomy.json. Setting it to false stops the agent at its next run, without a deploy.
  • A budget floor. Agents read the remaining model and data credit before each run and stop above the floor. They never top up.
  • A watchdog. An hourly job checks that each agent has succeeded recently and emails once per problem per day. An agent that fails silently is worse than no agent.
  • A canary. A nightly run of a fixed brief through the real pipeline, draft discarded, that emails only on failure. It catches a broken model, credential or check before a real run does.
  • A signed approval link. Approvals are HMAC-signed links over the item and its exact content hash. The agent's own credentials cannot mark anything approved. A link for an older version of a draft does nothing.
  • A report to a named person after every run that changed anything.
  • A ledger. Every recommendation goes into heddle/recommendations.json and stays until it is implemented, rejected with a reason, or handed to a person with the exact step (recommendations.md).

What never becomes autonomous

  • Claiming anything not in company.json with evidence.
  • Publishing under a person's byline without that person's approval. Agents may draft for an author; only the author approves. A person can give that approval once, for agent-sourced posts, by being listed in publish.bylines; anyone not listed is never the byline on a post that published itself.
  • Changing a slug that has been published.
  • Spending above the budget, or topping up credit.

Agent-sourced posts

Whether the writer's posts publish themselves is one setting per install, not code:

"publish": { "agentSourced": "auto", "dailyFloor": 1, "bylines": [] }
  • agentSourced. "approve" (the default). Every post waits for an approver's signed link, at every level. "auto": the writer's ceiling rises from propose to merge, and at merge (earned by clean runs like any other agent) a post that passed every gate merges itself. The gates are the fact-check against the sources, the site's prose checks and the restatement measure. A draft that misses one is revised against the failures, twice, and held if it still misses.
  • dailyFloor. How many posts a day the install aims to publish. The writer drafts enough of the queue to reach it and reports a day the queue cannot.
  • bylines. Authors who agreed that agent-sourced posts may carry their name. Every other post that publishes itself carries the company's name.

What it never covers. A post a person asked for. Ideas sent by email (ideas-by-email.md) always wait for that person's signed approval, whatever publish says.

The origin. On the source site, agent-filed explainers waited for approval after the fact-check and the helpful gate had already read them. Its owner decided on 11 October 2026 that agent-sourced posts publish every day once their checks pass, and that a post a person asked for still waits for that person.

Another company may keep every gate; that is why it is a setting.

Kill switches

Each agent's kill switch is a repository variable named in autonomy.json, HEDDLE_<AGENT> by default (HEDDLE_SEO for the SEO agent). Any of off, false, 0, no, stop, disable, disabled stops the agent at its next run; unset, or any other value, lets it run. No deploy is needed:

gh variable set HEDDLE_SEO -b off -R <owner>/<site>

The recommendations ledger

Every recommendation an agent makes goes into heddle/recommendations.json, and stays there until it is closed. Read it with:

heddle recommendations <site-repo>          # what is open or waiting, oldest first
heddle recommendations <site-repo> --all    # everything, closed included

You know it is working when the daily digest has a "Recommendations, oldest first" section, and nothing in it is older than maxOpenDays without the watchdog having said so.

What an entry is

Field Meaning
id <agent>-<hash>, stable: the same finding raised again is the same entry
agent Who raised it, or person for one added by hand
date The day it was first raised
recommendation, evidence What to do, and what the agent measured or read
status open, implemented, rejected or needs-person
pr / commit / verifiedBy What closed it (implemented needs one)
reason Why it was turned down (rejected needs one)
step Exactly what a person must do (needs-person needs one)
lastSeen The last run that raised it; a closed entry raised again keeps its status and moves this

heddle validate fails an entry whose status lacks its field: "implemented" with nothing that shows it, "rejected" without a reason, "needs a person" without the step. A closed status without its evidence is the thing the ledger exists to stop.

The rules

  1. At propose or merge, an agent addresses everything it raises. It implements it (a pull request it opens), hands it to a person with the exact step, or rejects it with a reason. One left open makes the run unclean, and unclean runs never count towards merge.
  2. At report, recommendations stay open. The watchdog flags any open longer than autonomy.json recommendations.maxOpenDays (7 by default), once a day, in the same alert as every other problem.
  3. Anything that leaves the company is a person's step at every level. Pitches, listings, replies to buyers and ad campaigns are drafted, and the entry says where the draft is and that nothing was sent.
  4. Hand-offs close themselves. An entry handed over as a pull request is marked implemented by the watchdog when the pull request merges, and rejected (with the date) when it is closed unmerged.
  5. A finding the agent re-reads closes when it is gone. Checks that run in full every time (the canary's probes, the site agent's findings, the SEO agent's indexing, headline and gate findings, the memory agent's claims) close their own entries when a later run no longer finds them, with verifiedBy naming that run. A check that did not run closes nothing.
  6. People close entries by editing the file. Set the status and its field, run heddle validate, commit. A person adding a recommendation of their own uses "agent": "person" and "source": "person".

Generated from the Heddle repository at ddb1b16.

Questions

Can an agent publish without anyone approving it?

Only an agent set to merge in autonomy.json, after its last clean runs, and only within its ceiling. Pitches, replies to buyers, ad campaigns and the company's own facts stop at propose at every level, and a post a person asked for always waits for that person.

How do I stop an agent now?

Set its kill switch, a repository variable such as HEDDLE_SEO, to off. It stops at its next run without a deploy.