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 tofalsestops 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.jsonand 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.jsonwith 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 fromproposetomerge, and atmerge(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
- At
proposeormerge, 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 towardsmerge. - At
report, recommendations stay open. The watchdog flags any open longer thanautonomy.jsonrecommendations.maxOpenDays(7 by default), once a day, in the same alert as every other problem. - 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.
- Hand-offs close themselves. An entry handed over as a pull request is marked
implementedby the watchdog when the pull request merges, andrejected(with the date) when it is closed unmerged. - 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
verifiedBynaming that run. A check that did not run closes nothing. - 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.