# 0035 · A script can suggest a change to a page, and a person accepts it

**Status:** Accepted · 2026-11-06. It extends suggested changes ([0024](https://codna.me/docs/adr/0024-suggested-edits.md))
from AI tools over MCP to automation scripts, as `actions.suggestLink` already extends suggested
links. Scripts still write only in `output` ([0026](https://codna.me/docs/adr/0026-scripts-ask-a-model.md)).

## Context

A customer's daily campaign report runs as two automations on one incoming connection
([0027](https://codna.me/docs/adr/0027-other-apps-start-automations.md)). One writes the day's report. The other adds up each
campaign's month and keeps it in a page per campaign in `output`, linked from the wiki.

The wiki pages it describes have their own numbers: a table per campaign, one column a month, built
when the page was written. Those tables go stale. The script holds this month's figures, but it can
do nothing about the tables:

- **It cannot write the wiki.** `actions.write` and an ask's answer go only to `output`. That is
  right: the wiki is what people curate, and a script that rewrote it daily would drown their edits.
- **It cannot suggest either.** Suggested changes exist (0024), but only `suggest_edit` over MCP. A
  Claude routine could suggest, but starting a routine to copy figures a script already has is a
  model call where no judgement is needed.

So the figures sit in `output`, and the wiki's tables are updated by hand or not at all.

## Decision

**A script may suggest a change to a page with `actions.suggestEdit`.** The suggestion is an
ordinary one from 0024: someone who can edit the page accepts or rejects it, from their inbox or on
the page.

```js
actions.suggestEdit('wiki:campaigns/welcome-series', [
  { op: 'replace_section', section: 'Numbers', text: table },
], 'November 2026 added from the daily reports: 4,120 orders, 3,980 delivered')
```

### What it takes

- **A page, the edits and a reason,** in `edit_document`'s shape, as `suggest_edit` takes them.
  Optionally `{ title, tags }` as a fourth argument. Never a whole new body, for 0024's reason.
- **A reason is required,** and says what the script saw: the reviewer reads it first.

### How it runs

- **Proposed, then checked, like every action.** It is applied after the run, as the owner. The
  owner needs read on the page, as 0024 asks of anyone who suggests.
- **The edits are tried when the run is checked.** Edits that would not apply to the page as it is
  now are refused with the reason, in the run's record, and the run's other actions still apply.
- **A dry run** shows the diff each suggestion would make, so its author sees what reviewers will.
- **The suggester is the owner, named with the automation,** such as "Suggested by Dana
  (automation campaign-numbers)", as a suggested link says "proposed by automation".
- **Suggesting the same edits again** is refused as 0024 says: still waiting, or rejected before.
  So a monthly script that runs twice suggests once, and a rejected change stays rejected.

### Limits

- At most 10 suggestions a run, within its 50 actions. 0024's limits still apply: 20 waiting per
  page from one suggester, 200 in all.
- Not in `raw`, as 0024 says.

### Not in this step

- **A model writing the suggestion.** An ask whose answer becomes a suggested edit of one section
  would let a model suggest prose, such as a new gotcha. It needs the answer turned into edits safely,
  and a cost per suggestion. It can follow once script suggestions have been used.
- **Automations triggered by a decision.** 0024 has no outbox event for one yet; the script's next
  run learns the outcome only by suggesting again and being told it was rejected.

## Consequences

- A script that already holds figures can keep a wiki page current with one click a month from
  whoever owns the page, and the page's history says where each change came from.
- Editors get suggestions from scripts in the same inbox as from people and AI tools. The limits
  keep one script from filling it.
- The wiki stays written by people: nothing a script proposes reaches it without someone's yes.

## Alternatives rejected

- **Let scripts write the wiki.** Daily rewrites would overwrite people's edits and turn the wiki into
  another `output`.
- **A Claude routine for every update.** It works today, but it is a model call and a token to keep,
  for figures a script already has. Routines stay for judgement.
- **Keep the figures in `output` only.** That is what exists now. It leaves the wiki's own tables
  stale, and readers meet two sets of numbers.

## Building it

1. `actions.suggestEdit` in the sandbox's action collector, with the checks above, applied through
   `suggest.Service.SuggestEdit` with the automation named as the source.
2. The dry run's diff, in `run_automation` and the web's Try it.
3. Documentation in `docs/automations.md`, and the `set-up-an-automation` skill.
