Depends on #4.
#28 produces a page per plugin. #20 gives the roster one sentence per row, and
that sentence is already spoken for twice over: it is what the landing page's
table prints and what the organisation profile publishes.
gh api repos/Flowfin/.github/contents/profile/README.md --jq '.content' \
| base64 -d | grep -c '^| \['
12
Run 2026-08-08. Twelve rows, one sentence each. If nothing else is decided, a
plugin page is that same sentence, a state word and a link to a repository, which
is the table row with more space around it. Twelve pages of that are twelve
addresses a reader can be sent to for no reason, and they would still have to be
kept, checked, budgeted and rendered.
The decision is that per-plugin prose lives in this repository, one file per
roster identifier under content/, that the roster keeps exactly its one
sentence and gains no prose field, and that the build refuses a roster row with
no prose file and a prose file matching no roster row.
The reasoning.
The split this board was made for puts machine-readable data on one side and
paragraphs on the other. A paragraph in the roster is prose sitting in the file
whose other consumer is a table that will never print it, and it would mean the
site's voice is edited in the repository that exists to hold data.
Keying by the roster identifier is what keeps the two halves from drifting apart
without anybody noticing. A row with no page prose and a page with no row are
both decidable by reading the tree, they are the same walk the sitemap check in
#69 already does, and the failure names the identifier rather than the file.
The one sentence stays in the roster because two consumers outside this
repository read it. Moving it here would make the profile table depend on a
website for the words in it, which is the direction #5 rejected.
What the alternatives cost.
A second, longer field in the roster. Cost: the data file grows a field one of
its two consumers ignores, and the reviewing of the site's prose moves to a
repository whose review is about data.
Fetch each plugin repository's README at build time. Cost: the build reaches the
network and stops working offline, which #24 and #66 both refuse for the same
reason; a document written for somebody reading source lands on a page written
for somebody deciding whether to install; and the site publishes text nobody here
reviewed.
Leave the pages at one sentence. Cost: twelve addresses that repeat the table,
against a budget in #6 that counts every page, and the install question a reader
actually arrived with is answered nowhere.
What would make this worth revisiting: prose per plugin that a client also has to
show, which would make it data with two consumers rather than a page.
Done when
decisions/0010-where-the-plugin-page-prose-comes-from.md exists, carries the
measurement above with the command that produced it, states that the prose lives
here keyed by the roster identifier and that the roster gains no prose field,
states that a row without prose and prose without a row are both failures, names
the three rejected sources with their costs, and states the revisit condition.
Depends on #4.
#28 produces a page per plugin. #20 gives the roster one sentence per row, and
that sentence is already spoken for twice over: it is what the landing page's
table prints and what the organisation profile publishes.
Run 2026-08-08. Twelve rows, one sentence each. If nothing else is decided, a
plugin page is that same sentence, a state word and a link to a repository, which
is the table row with more space around it. Twelve pages of that are twelve
addresses a reader can be sent to for no reason, and they would still have to be
kept, checked, budgeted and rendered.
The decision is that per-plugin prose lives in this repository, one file per
roster identifier under
content/, that the roster keeps exactly its onesentence and gains no prose field, and that the build refuses a roster row with
no prose file and a prose file matching no roster row.
The reasoning.
The split this board was made for puts machine-readable data on one side and
paragraphs on the other. A paragraph in the roster is prose sitting in the file
whose other consumer is a table that will never print it, and it would mean the
site's voice is edited in the repository that exists to hold data.
Keying by the roster identifier is what keeps the two halves from drifting apart
without anybody noticing. A row with no page prose and a page with no row are
both decidable by reading the tree, they are the same walk the sitemap check in
#69 already does, and the failure names the identifier rather than the file.
The one sentence stays in the roster because two consumers outside this
repository read it. Moving it here would make the profile table depend on a
website for the words in it, which is the direction #5 rejected.
What the alternatives cost.
A second, longer field in the roster. Cost: the data file grows a field one of
its two consumers ignores, and the reviewing of the site's prose moves to a
repository whose review is about data.
Fetch each plugin repository's README at build time. Cost: the build reaches the
network and stops working offline, which #24 and #66 both refuse for the same
reason; a document written for somebody reading source lands on a page written
for somebody deciding whether to install; and the site publishes text nobody here
reviewed.
Leave the pages at one sentence. Cost: twelve addresses that repeat the table,
against a budget in #6 that counts every page, and the install question a reader
actually arrived with is answered nowhere.
What would make this worth revisiting: prose per plugin that a client also has to
show, which would make it data with two consumers rather than a page.
Done when
decisions/0010-where-the-plugin-page-prose-comes-from.mdexists, carries themeasurement above with the command that produced it, states that the prose lives
here keyed by the roster identifier and that the roster gains no prose field,
states that a row without prose and prose without a row are both failures, names
the three rejected sources with their costs, and states the revisit condition.