src/organize.ts ships in #72 as flowrite's fourth standalone in-place editor. tsc is clean, 105
tests pass, and every recipe in its guide is verified against the fixture — but no run has proposed a
grouping. The feature is a judgement call, and judgement is the part no test reaches.
Blocked on the Anthropic quota reset — 2026-09-01 00:00 UTC. Tracked in the #66 umbrella alongside
#57, #59, #63, #65, #68, #70. Recorded as BACKLOG.md finding 13.
Step 0 — the fixture, free, no key needed
fixtures/tinyproject/docs/reference/ holds a single index.md, so it cannot exercise the
grouping. It is still the right first run, because it tests the bounds:
bash -c 'cd fixtures/tinyproject && flue run ../../src/organize.ts -m "Organize docs/reference into categories"'
Pass: it reports the section is too small (three pages minimum per category) and proposes no
change. Fail: it invents categories, or writes anything at all.
Cheap and worth doing first, because "proposes nothing when there is nothing to do" is the behaviour
that keeps this agent from making work for itself — and it is the same shape as the metadata
backfiller's stop conditions.
Also confirm the guide's recipes still hold, since they are the ported logic:
| recipe |
expected on the fixture |
| page list with titles |
docs/reference/index.md → "TinyProject API Reference" |
| sidebar parse check |
passes — and note it is not proof (see below) |
| id resolution by text extraction |
3 ids, all resolve; a planted bad id is caught |
Step 1 — a real section
Judging a grouping needs a dozen or more pages. ~/sources/scala/zio-2.x-new/docs/reference has 220
— on a branch, clean tree, diff read before anything is staged.
flue run src/organize.ts -m "Organize docs/reference into categories" \
--data '{"projectPath":"<checkout>"}'
Step 2 — what to check, in priority order
-
Is the taxonomy any good? The whole feature, and the only part offline coverage cannot touch.
A category is a claim about what a set of pages is for. Judge each name against the pages it
holds, not against whether it sounds plausible — the failure mode to look for is the predecessor's
substring heuristic, which produced categories that read fine and filed ChunkBuilder under
Collections. A wrong taxonomy is durable in a way a wrong link is not: readers navigate by it and
later pages get filed into it.
-
Did anything move? git status should show only new category index pages and one sidebars.js
edit. Any renamed or relocated page is a kill, not a tuning knob — a page's links are relative,
so moving it breaks every reference to it and every ../ inside it.
-
Does every sidebar id resolve? Use the guide's text-extraction recipe, not require().
Reason, found while building this: flowrite/package.json sets "type": "module", so a .js
sidebar under it loads as ESM and require() returns {} with no error for a file whose
module.exports never took effect. It catches a syntax error and nothing more.
grep -oE "(id|\"id\"): *['\"][^'\"]+['\"]|['\"](reference|guides)/[a-z0-9/-]+['\"]" docs/sidebars.js \
| sed -E "s/.*['\"]([^'\"]+)['\"]$/\1/" | sort -u | while read -r id; do
[ -f "docs/$id.md" ] || echo "MISSING docs/$id.md"
done
-
Were the bounds held? Three pages minimum per category, one home per page, leftovers left at the
top level, and no "Miscellaneous" invented to reach full coverage. A page appearing in two
categories renders twice and the second entry usually loses its label.
-
Did it leave other entries alone? A page it did not group must keep its existing sidebars.js
entry byte for byte. This is the edit that loses a sibling's work where nobody can see it is gone.
-
Do the index pages read like documentation? They ship unreviewed — there is no review phase on a
standalone pass — so this is the only time anyone looks at them. Two or three sentences on what the
category covers, a linked list of its pages, no duplicated API prose.
Kill criteria, not tuning knobs
Following the pattern findings 9, 10 and 12 set:
- any page moved or renamed
- a page created that is not a category index — especially one written to make a sidebar entry resolve
- a sidebar entry removed that was not part of the grouping
- a "Miscellaneous"-style catch-all category
- edits to any existing page's prose, frontmatter or links
Ordering
Still the #66 argument, now with four editors behind it: run #65 first. The metadata backfiller is
the cheapest test of the premise all four standalone editors share — instruct rather than wrap, and let
git diff on a clean tree be the safety net — because its invariant is mechanical (verify.sh asserts
the body comes out byte-identical). If it touches bodies, that premise is wrong, and this agent writes
prose and edits a shared file.
Note also that #70's port found git diff is not a sufficient net at scale: a link spliced inside an
inline-code span survived mdoc, onBrokenLinks, and a 94-file human review. This agent's diff is
small by construction (a few index pages and one sidebar edit), which is the main reason it is safer
than the cross-linker — but step 3's grep exists because "read the diff" was not enough there.
Done when
src/organize.tsships in #72 as flowrite's fourth standalone in-place editor.tscis clean, 105tests pass, and every recipe in its guide is verified against the fixture — but no run has proposed a
grouping. The feature is a judgement call, and judgement is the part no test reaches.
Blocked on the Anthropic quota reset — 2026-09-01 00:00 UTC. Tracked in the #66 umbrella alongside
#57, #59, #63, #65, #68, #70. Recorded as
BACKLOG.mdfinding 13.Step 0 — the fixture, free, no key needed
fixtures/tinyproject/docs/reference/holds a singleindex.md, so it cannot exercise thegrouping. It is still the right first run, because it tests the bounds:
bash -c 'cd fixtures/tinyproject && flue run ../../src/organize.ts -m "Organize docs/reference into categories"'Pass: it reports the section is too small (three pages minimum per category) and proposes no
change. Fail: it invents categories, or writes anything at all.
Cheap and worth doing first, because "proposes nothing when there is nothing to do" is the behaviour
that keeps this agent from making work for itself — and it is the same shape as the metadata
backfiller's stop conditions.
Also confirm the guide's recipes still hold, since they are the ported logic:
docs/reference/index.md→ "TinyProject API Reference"Step 1 — a real section
Judging a grouping needs a dozen or more pages.
~/sources/scala/zio-2.x-new/docs/referencehas 220— on a branch, clean tree, diff read before anything is staged.
Step 2 — what to check, in priority order
Is the taxonomy any good? The whole feature, and the only part offline coverage cannot touch.
A category is a claim about what a set of pages is for. Judge each name against the pages it
holds, not against whether it sounds plausible — the failure mode to look for is the predecessor's
substring heuristic, which produced categories that read fine and filed
ChunkBuilderunderCollections. A wrong taxonomy is durable in a way a wrong link is not: readers navigate by it and
later pages get filed into it.
Did anything move?
git statusshould show only new category index pages and onesidebars.jsedit. Any renamed or relocated page is a kill, not a tuning knob — a page's links are relative,
so moving it breaks every reference to it and every
../inside it.Does every sidebar id resolve? Use the guide's text-extraction recipe, not
require().Reason, found while building this:
flowrite/package.jsonsets"type": "module", so a.jssidebar under it loads as ESM and
require()returns{}with no error for a file whosemodule.exportsnever took effect. It catches a syntax error and nothing more.Were the bounds held? Three pages minimum per category, one home per page, leftovers left at the
top level, and no "Miscellaneous" invented to reach full coverage. A page appearing in two
categories renders twice and the second entry usually loses its label.
Did it leave other entries alone? A page it did not group must keep its existing
sidebars.jsentry byte for byte. This is the edit that loses a sibling's work where nobody can see it is gone.
Do the index pages read like documentation? They ship unreviewed — there is no review phase on a
standalone pass — so this is the only time anyone looks at them. Two or three sentences on what the
category covers, a linked list of its pages, no duplicated API prose.
Kill criteria, not tuning knobs
Following the pattern findings 9, 10 and 12 set:
Ordering
Still the #66 argument, now with four editors behind it: run #65 first. The metadata backfiller is
the cheapest test of the premise all four standalone editors share — instruct rather than wrap, and let
git diffon a clean tree be the safety net — because its invariant is mechanical (verify.shassertsthe body comes out byte-identical). If it touches bodies, that premise is wrong, and this agent writes
prose and edits a shared file.
Note also that #70's port found
git diffis not a sufficient net at scale: a link spliced inside aninline-code span survived
mdoc,onBrokenLinks, and a 94-file human review. This agent's diff issmall by construction (a few index pages and one sidebar edit), which is the main reason it is safer
than the cross-linker — but step 3's grep exists because "read the diff" was not enough there.
Done when
BACKLOG.mdfinding 13 closed, or narrowed to what actually failed