Repository navigation
Suggestion Format
The agent writes its suggestions as a JSON list and hands the file to ew.py suggest. The script checks every item, saves the valid ones and lists the refused ones by item number. Fix those and run suggest again with the same file: items already saved are skipped. The skill's own copy of this format is references/suggestion-format.md.
| Field | Required | Rule |
|---|---|---|
level |
yes |
developmental, assessment, line, copy, proof or fact
|
category |
yes | a short kebab-case label such as pov-slip, pacing, stakes, dialogue-tag, filter-word, repetition, tense, agreement, typo, punctuation, consistency, claim-check, format. Reuse labels: author preferences are tallied per category. |
problem |
yes | what is wrong, in one or two plain sentences |
quote |
for anchored items and every change | copied exactly from clean.md as ew.py show prints it; the smallest span that shows the problem or that the change replaces |
para |
recommended | the P number from ew.py show. Without it the quote must be unique in the text. |
occurrence |
when the quote repeats in the paragraph | 1-based |
why |
recommended | why it matters to the reader or the market |
options |
recommended | kinds of fix, described, not drafted |
change |
optional |
{"replace": "..."}; "" cuts the quote |
severity |
optional | 1 minor, 2 worth fixing (the default), 3 serious |
The script adds id (S-001, S-002 and so on, in the order of the file), span (character offsets in clean.md), provenance, ai_words, marked_ai_text and status. An item without a change is a query: the fix is the author's to write.
This is the suggestions.json behind the examples on Commands. It has a typo fix, a cut, a tense fix, a change that brings in new words, a developmental query and a punctuation change that overlaps the cut.
[
{
"level": "proof",
"category": "typo",
"para": 5,
"quote": "teh",
"change": {"replace": "the"},
"problem": "Typo."
},
{
"level": "line",
"category": "repetition",
"para": 8,
"quote": "very hard, ",
"change": {"replace": ""},
"problem": "The repeat softens the sentence instead of stressing it.",
"why": "The cracked axle already shows how hard the cart was driven.",
"options": ["Cut the repeat.", "Keep it if Nell's voice leans on repeats elsewhere."],
"severity": 1
},
{
"level": "copy",
"category": "tense",
"para": 8,
"quote": "walks",
"change": {"replace": "walked"},
"problem": "Tense slip: the story is told in the past tense."
},
{
"level": "line",
"category": "rhythm",
"para": 7,
"quote": "as mules do",
"change": {"replace": "the way mules will"},
"problem": "The aside is flat.",
"severity": 1
},
{
"level": "developmental",
"category": "stakes",
"para": 9,
"quote": "She realized the stranger was her cousin.",
"problem": "The reveal has no setup, so it reads as coincidence.",
"why": "Readers accept a surprise they could have seen coming.",
"options": ["Plant the cousin earlier in the story.", "Move the reveal so the reader learns it with Nell."],
"severity": 3
},
{
"level": "copy",
"category": "punctuation",
"para": 8,
"quote": "hard, very",
"change": {"replace": "hard. Very"},
"problem": "A full stop would give the repeat its own beat."
}
]S-004 is there to show a refusal. In human-authored mode the skill should write it as a query instead: name the problem ("the aside is flat") and the kind of fix, and leave the words to the author.
A change is fine when it adds no words the author did not write. That covers a typo or spelling fix, an inflection or tense fix of the author's word, punctuation, a cut, or a reorder. Since 0.1.1 it also covers a fix between words people often confuse ("road" to "rode") and a swap to a word the author wrote close by. The script counts these as the author's; the exact rules are on Provenance and AI-text rules. The ledger for the file above shows each kind:
$ cat works/the-salt-road/jobs/*/provenance-ledger.md
# Provenance ledger: The Salt Road
Counts the words each proposed change would bring in that the author did not write. Reused words, cuts, reorders, punctuation and spelling or inflection corrections of the author's own words count as the author's. Words the author typed (`--author-text`) count as the author's.
- Piece: 133 words. Mode: human-authored. Limit: 0 words or 0.0%, whichever is lower.
- If every proposed change were applied: 3 AI-written words (2.26%).
- Applied so far: 0 AI-written words (0.00%) from 0 change(s).
| ID | Kind | AI-written words | Corrected | Removed | Applied |
|---|---|---|---|---|---|
| S-004 | new-words | 3 (the way will) | | 2 | |
| S-002 | cut | 0 | | 2 | |
| S-003 | correction | 0 | walks>walked | 0 | |
| S-006 | punctuation | 0 | | 0 | |
| S-001 | correction | 0 | teh>the | 0 | |Anything else (a new word, phrase or sentence) is AI-written text. The format asks the agent not to slip example wording into options either: if the author copies it, apply counts it (see Provenance and AI-text rules).
The quote must match clean.md character for character, after cleanup. A quote with one word wrong refuses that item:
[
{
"level": "line",
"category": "filter-word",
"quote": "She saw the cart standing empty by the barn.",
"problem": "Filter verb."
}
]$ python3 ew.py --works works suggest the-salt-road bad.json
added 0 suggestion(s), 0 in total; 0 carry AI-written words
refused 1 suggestion(s) (the others were saved); fix these and run suggest again with the same file:
- item 1: quote not found in the text: 'She saw the cart standing empty by the barn.'
quotes must match `ew.py show` exactly, curly quotes and apostrophes includedThe script refuses an item for these too:
- a missing
level,categoryorproblem - a level outside the list
- a
changewithout aquote, or withoutreplace - a
parapast the end of the text - a quote that appears more than once, with no
paraoroccurrence
When suggest runs a file again, it skips an item that is already saved. It compares the level, category, para, quote and change, but not the problem. Two faults in 0.1.1, found while writing these pages and not yet fixed:
- An item with a quote but no
parais saved a second time. The saved copy has itsparafilled in, so it no longer matches the item in the file. Give every item apara, or send only the fixed items. - Two items with the same level, category and
paraand no quote or change count as one. The second is skipped with "skipped 1 already in suggestions.json". Give whole-piece notes different categories or aparaeach.
This wiki describes editwright 0.1.1 (tag v0.1.1, commit 8d9a0d5) and was last updated on 2026-10-09. The plugin is MIT licensed. Report problems in the issues.