Nine things this plan runs into that are my call. Each one states
the options and what each option costs. None of them is decided here, and
nothing in the plan assumes an answer.
1. The licence of this repository
There is no LICENSE file in this repository today:
gh api repos/Flowfin/site/contents/LICENSE
gh: Not Found (HTTP 404)
Without one the default is all rights reserved, which means nobody may copy the
pages, the generator or the design tokens even to report a bug against them.
Everything else in this plan can proceed, but the release cannot.
The repository holds three kinds of thing and they do not want the same licence
naturally: generator source code, the prose on the pages, and the design system
tokens. The tokens are a borrowed case rather than a third party to the
question. #65 puts the token file with the machine-readable data and leaves a
pinned copy here, so what this repository would be licensing is the copy and the
page that renders it, and the values themselves carry whatever their home says.
Whichever answer comes back has to work for a file this repository holds and
does not author.
One permissive licence for everything, such as Apache-2.0 or MIT. Cost: one
file, one SPDX header rule, no ambiguity about which part is which. Apache-2.0
adds an express patent grant and a notice requirement. Prose under a code
licence is unusual but legally fine, and a reader who quotes a paragraph carries
a notice obligation they will not expect.
Copyleft for everything, GPL-3.0-only, matching the plugin that ships today.
Cost: consistency across the project, and a reader who copies a snippet of
markup into their own page inherits an obligation that has nothing to do with
what they took. For a site that is partly documentation this is the strongest
deterrent to reuse of the three.
A split: a permissive or copyleft licence for the generator and a Creative
Commons licence for the prose and the design tokens. This is what documentation
sites usually do. Cost: two licences means a rule for which file is under which,
an SPDX header on every file to make that rule checkable, and a REUSE-style
compliance check to keep it true. It is the most work and the clearest result.
Public domain dedication, CC0, for the prose only. Cost: maximum reuse, no
attribution, and no way to ask for attribution later on what has already been
published.
A separate question inside this one: whether the design system tokens are meant
to be reusable by other projects at all, because that is a brand decision rather
than a licensing one, and it changes which of the above fits.
2. The published language of the site
The pages served today are in German:
curl -s https://flowfin.dev/ | grep -o 'Plugins und native Clients'
Plugins und native Clients
Everything else the project publishes is in English: the organisation profile,
the repository documents, the plugin documentation and the issue trackers.
German only. Cost: the current text survives, and the audience is the German
speaking part of a self-hosting community that mostly reads English.
English only. Cost: matches everything else the project publishes, and the
existing German pages are rewritten rather than translated.
Both, with a switch. Cost: every page, every review and every check doubles, and
a rule is needed for which language is authoritative when the two disagree,
because they will.
This answer is the one that reaches furthest into work already planned, and it is
worth knowing that before choosing rather than after. #68 fixes the address of
every page on the assumption of one published language, so the two-language
answer replaces that record rather than extending it: each address gains a
language segment, the root has to answer in one of them without reading anything
about the reader, and each page gains a link to its counterpart so the two are
not read as duplicates competing with each other. The other two answers cost
nothing there. Nothing in the plan is blocked while this is open, because the
pages take their words from content/ either way.
3. When and how the domain moves
flowfin.dev is served from the other repository's docs directory, with the
CNAME committed there:
gh api repos/Flowfin/hub/pages --jq '{cname,source}'
{"cname":"flowfin.dev","source":{"branch":"main","path":"/docs"}}
Moving it here is a settings and DNS action, and there is a window in which the
domain resolves to nothing if the CNAME leaves one repository before Pages has
accepted it on the other.
Cut over at the first release. Cost: one short window, and the old pages
disappear the moment the new ones appear.
Serve the new site on a subdomain first and cut over later. Cost: two live sites
for a while, and a period where search results and links point at the old one.
Keep serving from where it is and have this repository publish into it. Cost:
zero risk, and it defeats the separation this repository exists for.
Whichever answer this is, the same name also carries the catalogue address an
operator pastes into a server, and that address is a commitment that cannot be
withdrawn. It does not answer today, so the cost of the coupling is currently
zero and it will not stay that way:
curl -sS -o /dev/null -w '%{http_code}\n' https://flowfin.dev/manifest.json
404
Run 2026-08-08. What has to be true of that one path on any of the three answers
above is #64, which decides none of them.
4. The catalogue address the install page prints
The page served today tells a reader to paste https://flowfin.dev/manifest.json
into Jellyfin. That address does not resolve:
curl -s -o /dev/null -w '%{http_code}\n' https://flowfin.dev/manifest.json
404
The organisation profile says the opposite policy in writing, that the catalogue
URL will be published once there is more than one release behind it. The two
statements disagree today and the site will inherit the disagreement.
Publish the aggregate manifest now and accept a catalogue with one entry in it.
Cost: the permanent address starts working, and the first thing it tells every
server that adds it is that there is one plugin.
Remove the address from the site until the manifest exists. Cost: honest, and a
reader has nothing to paste.
Print the shipping plugin's own channel address instead. Cost: it works today,
and it is a second permanent address that servers will keep fetching after the
aggregate one exists.
One published rule already narrows this without answering it, and presenting the
three as free choices would misrepresent what is open:
gh api repos/Flowfin/hub/contents/decisions/manifest-address.md --jq '.content' \
| base64 -d | grep -n 'may appear in a tracked file'
30:An install address may appear in a tracked file only once the address answers
Run 2026-08-08. So the second option is what holds until one of the other two has
actually been carried out, and neither of those is a change this board can make.
The choice is which of the three the site is built towards, not which one it may
print tomorrow.
5. Whether plugin pages carry screenshots
A screenshot answers what a plugin looks like faster than any paragraph.
With screenshots. Cost: they go stale silently, every one needs alt text that
says what the picture shows rather than that it is a picture, and images are the
only thing in this plan large enough to threaten the byte budget.
Without. Cost: the pages are text, and a reader decides from a description.
A single wide image on the landing page only. Cost: one image to keep current
instead of twelve.
6. Who lands the files this board only reads, and what it starts from
Everything the site says about the twelve plugins comes out of one
machine-readable roster, and #2 places that file in the repository that already
holds the machine-readable data. #65 puts a second file in the same position,
the design tokens, for the same reason. Nothing on this board may write there,
so no issue here can create either file the rest of the plan reads. The
sequencing is a call rather than a detail, and the issues that read a real
roster or a real token file wait on it.
Land them in the data repository first. Cost: this board waits on a change
somewhere else, and what waits is the parser, the two vendored copies and the
two freshness checks, which is most of one milestone and part of another.
Start here against committed fixtures and vendor the published files when they
appear. Cost: the parser, the pages and the golden files get built and tested on
schedule, and the freshness checks have nothing to compare against until the
published files exist. A check that reports green having compared nothing is
worse than one that is off, so on this answer both ship disabled by name until
there is a file behind them.
Keep them in this repository after all. Cost: this reverses #2 and #65 and pays
what each says it costs. The profile table would be generated out of the site
repository rather than out of the tree that exists to hold machine-readable
data, and every client would read its conformance target out of a website. The
split this board was made for gets a hole in it on the first files that matter.
The two files can be answered differently. The roster is read by this site and
by the profile table. The token file is read by this site and by the clients,
which is the part that makes holding it here awkward for a reason the roster
does not have.
7. Whether the project has a mark, and what the icon is
There is no image anywhere in what the project publishes. The served pages
reference none, and neither the tree behind the domain nor the organisation
profile holds one:
curl -sS https://flowfin.dev/ | grep -c -i '<img'
0
gh api 'repos/Flowfin/hub/git/trees/HEAD?recursive=1' --jq '[.tree[].path|select(test("(png|svg|ico|jpg|webp)$"))]'
[]
gh api 'repos/Flowfin/.github/git/trees/HEAD?recursive=1' --jq '[.tree[].path]'
[".github",".github/FUNDING.yml","FUNDING.yml","SECURITY.md","profile","profile/README.md"]
Run 2026-08-08. #69 has the build produce an icon, because a browser asks for one
on every visit whether or not a page offers it, and an unanswered request is
served the not-found page. What that icon shows is not a build question.
No mark, and the icon is a letter or a glyph built out of the design tokens.
Cost: nothing to design and nothing to keep, and the project has no visual
identity beyond its typography and its accent, which is a position rather than an
omission only if it is stated as one.
A mark, drawn once, used as the icon and wherever else the project appears. Cost:
somebody draws it, it becomes a thing to keep current in more than one place, and
it is the first asset the project owns that nothing in this plan can derive or
check.
No icon at all. Cost: every visit asks for one and gets an error page, which is
the failure #69 exists to remove, so this answer costs a request per reader
rather than costing nothing.
This does not touch entry 5. That one is about photographs of the software.
This one is about whether the project has a face.
8. What the site says about who publishes it
The site names nobody today and offers no route to anybody:
curl -sS https://flowfin.dev/ | grep -o -i -E 'impressum|imprint|datenschutz|privacy'
exit=1
Run 2026-08-08. #76 builds the page that carries the answer and deliberately
holds no words that identify anybody, because what goes on it is a personal cost
rather than a design question. Two things make it a real question rather than a
formality. Publishing a site under a name of one's own carries a provider
identification duty in some jurisdictions, and the organisation profile carries a
donation link, which is the kind of detail that decides whether a site is read as
private or as commercial:
gh api repos/Flowfin/.github/contents/profile/README.md --jq '.content' \
| base64 -d | grep -c -i 'buymeacoffee'
1
Nothing here is legal advice and none of the options below is safe by
construction. What each one costs is what can honestly be written down.
A full provider identification with a postal address. Cost: a private address
becomes permanently public on a page built to be indexed, and scrapers keep a
copy after any later change. It is what the strictest reading of the duty asks
for and it is the only answer that satisfies service of documents.
A name and a contact route with no postal address. Cost: a reader can reach
somebody, and a jurisdiction that asks for a summonable address is not
satisfied. This is what most personal projects do.
A service that supplies an address for exactly this purpose. Cost: money every
year, a third party in the chain, and the address is real for service of
documents without being anybody's home.
A name and nothing else. Cost: cheapest, and it leaves both a reader and any
obligation with nothing.
A separate question inside this one: which contact route, given that an address
printed on a public page is collected within days. A route that can be rotated
without changing anything else is worth more here than a memorable one, and #76
renders whichever it is from data so that rotating it is a data change.
9. Whether the site asks for money, and in what form
A sponsor button already applies to every repository in the organisation,
including this one, from a single file:
gh api repos/Flowfin/.github/contents/FUNDING.yml --jq '.content' | base64 -d \
| grep -v '^#'
buy_me_a_coffee: iderex
Run 2026-08-08. That button is a repository feature and it is not a page. Whether
the site itself carries the same ask is a separate decision, and this plan would
otherwise answer it silently in two places: the budget in #6 refuses a request to
a domain the project does not own, and entry 8 above already treats the existing
donation link as one of the details that decides whether the site reads as
private or as commercial.
Nothing on the site, and the button stays where it is. Cost: the ask reaches
somebody browsing the source and nobody reading the pages, which is most readers.
A plain text link on the legal notice or the landing page. Cost: one line, no
third-party request because a link is not a fetch, and the commercial reading in
entry 8 gets a second thing pointing at it.
The provider's own button or badge embedded in a page. Cost: this one is refused
by the budget rather than merely expensive, because the image and the script come
from a domain the project does not own and every reader's address reaches that
domain before they have done anything. Taking this answer means changing #6 and
saying so there.
A page of its own explaining what money would be for. Cost: the most honest and
the most work, and it is a page that has to stay true as the answer to who
publishes the site changes.
Done when
Every one of the nine entries carries an answer written down where the work
that depends on it can read it, and each issue that waited on an entry names the
answer it proceeded on rather than an assumption it made. An entry whose answer
belongs in a decision record points at the record that carries it. Nothing here
is answered by this plan on my behalf, and an entry closed that
way is reopened.
Nine things this plan runs into that are my call. Each one states
the options and what each option costs. None of them is decided here, and
nothing in the plan assumes an answer.
1. The licence of this repository
There is no LICENSE file in this repository today:
Without one the default is all rights reserved, which means nobody may copy the
pages, the generator or the design tokens even to report a bug against them.
Everything else in this plan can proceed, but the release cannot.
The repository holds three kinds of thing and they do not want the same licence
naturally: generator source code, the prose on the pages, and the design system
tokens. The tokens are a borrowed case rather than a third party to the
question. #65 puts the token file with the machine-readable data and leaves a
pinned copy here, so what this repository would be licensing is the copy and the
page that renders it, and the values themselves carry whatever their home says.
Whichever answer comes back has to work for a file this repository holds and
does not author.
One permissive licence for everything, such as Apache-2.0 or MIT. Cost: one
file, one SPDX header rule, no ambiguity about which part is which. Apache-2.0
adds an express patent grant and a notice requirement. Prose under a code
licence is unusual but legally fine, and a reader who quotes a paragraph carries
a notice obligation they will not expect.
Copyleft for everything, GPL-3.0-only, matching the plugin that ships today.
Cost: consistency across the project, and a reader who copies a snippet of
markup into their own page inherits an obligation that has nothing to do with
what they took. For a site that is partly documentation this is the strongest
deterrent to reuse of the three.
A split: a permissive or copyleft licence for the generator and a Creative
Commons licence for the prose and the design tokens. This is what documentation
sites usually do. Cost: two licences means a rule for which file is under which,
an SPDX header on every file to make that rule checkable, and a REUSE-style
compliance check to keep it true. It is the most work and the clearest result.
Public domain dedication, CC0, for the prose only. Cost: maximum reuse, no
attribution, and no way to ask for attribution later on what has already been
published.
A separate question inside this one: whether the design system tokens are meant
to be reusable by other projects at all, because that is a brand decision rather
than a licensing one, and it changes which of the above fits.
2. The published language of the site
The pages served today are in German:
Everything else the project publishes is in English: the organisation profile,
the repository documents, the plugin documentation and the issue trackers.
German only. Cost: the current text survives, and the audience is the German
speaking part of a self-hosting community that mostly reads English.
English only. Cost: matches everything else the project publishes, and the
existing German pages are rewritten rather than translated.
Both, with a switch. Cost: every page, every review and every check doubles, and
a rule is needed for which language is authoritative when the two disagree,
because they will.
This answer is the one that reaches furthest into work already planned, and it is
worth knowing that before choosing rather than after. #68 fixes the address of
every page on the assumption of one published language, so the two-language
answer replaces that record rather than extending it: each address gains a
language segment, the root has to answer in one of them without reading anything
about the reader, and each page gains a link to its counterpart so the two are
not read as duplicates competing with each other. The other two answers cost
nothing there. Nothing in the plan is blocked while this is open, because the
pages take their words from
content/either way.3. When and how the domain moves
flowfin.dev is served from the other repository's
docsdirectory, with theCNAME committed there:
Moving it here is a settings and DNS action, and there is a window in which the
domain resolves to nothing if the CNAME leaves one repository before Pages has
accepted it on the other.
Cut over at the first release. Cost: one short window, and the old pages
disappear the moment the new ones appear.
Serve the new site on a subdomain first and cut over later. Cost: two live sites
for a while, and a period where search results and links point at the old one.
Keep serving from where it is and have this repository publish into it. Cost:
zero risk, and it defeats the separation this repository exists for.
Whichever answer this is, the same name also carries the catalogue address an
operator pastes into a server, and that address is a commitment that cannot be
withdrawn. It does not answer today, so the cost of the coupling is currently
zero and it will not stay that way:
Run 2026-08-08. What has to be true of that one path on any of the three answers
above is #64, which decides none of them.
4. The catalogue address the install page prints
The page served today tells a reader to paste
https://flowfin.dev/manifest.jsoninto Jellyfin. That address does not resolve:
The organisation profile says the opposite policy in writing, that the catalogue
URL will be published once there is more than one release behind it. The two
statements disagree today and the site will inherit the disagreement.
Publish the aggregate manifest now and accept a catalogue with one entry in it.
Cost: the permanent address starts working, and the first thing it tells every
server that adds it is that there is one plugin.
Remove the address from the site until the manifest exists. Cost: honest, and a
reader has nothing to paste.
Print the shipping plugin's own channel address instead. Cost: it works today,
and it is a second permanent address that servers will keep fetching after the
aggregate one exists.
One published rule already narrows this without answering it, and presenting the
three as free choices would misrepresent what is open:
Run 2026-08-08. So the second option is what holds until one of the other two has
actually been carried out, and neither of those is a change this board can make.
The choice is which of the three the site is built towards, not which one it may
print tomorrow.
5. Whether plugin pages carry screenshots
A screenshot answers what a plugin looks like faster than any paragraph.
With screenshots. Cost: they go stale silently, every one needs alt text that
says what the picture shows rather than that it is a picture, and images are the
only thing in this plan large enough to threaten the byte budget.
Without. Cost: the pages are text, and a reader decides from a description.
A single wide image on the landing page only. Cost: one image to keep current
instead of twelve.
6. Who lands the files this board only reads, and what it starts from
Everything the site says about the twelve plugins comes out of one
machine-readable roster, and #2 places that file in the repository that already
holds the machine-readable data. #65 puts a second file in the same position,
the design tokens, for the same reason. Nothing on this board may write there,
so no issue here can create either file the rest of the plan reads. The
sequencing is a call rather than a detail, and the issues that read a real
roster or a real token file wait on it.
Land them in the data repository first. Cost: this board waits on a change
somewhere else, and what waits is the parser, the two vendored copies and the
two freshness checks, which is most of one milestone and part of another.
Start here against committed fixtures and vendor the published files when they
appear. Cost: the parser, the pages and the golden files get built and tested on
schedule, and the freshness checks have nothing to compare against until the
published files exist. A check that reports green having compared nothing is
worse than one that is off, so on this answer both ship disabled by name until
there is a file behind them.
Keep them in this repository after all. Cost: this reverses #2 and #65 and pays
what each says it costs. The profile table would be generated out of the site
repository rather than out of the tree that exists to hold machine-readable
data, and every client would read its conformance target out of a website. The
split this board was made for gets a hole in it on the first files that matter.
The two files can be answered differently. The roster is read by this site and
by the profile table. The token file is read by this site and by the clients,
which is the part that makes holding it here awkward for a reason the roster
does not have.
7. Whether the project has a mark, and what the icon is
There is no image anywhere in what the project publishes. The served pages
reference none, and neither the tree behind the domain nor the organisation
profile holds one:
Run 2026-08-08. #69 has the build produce an icon, because a browser asks for one
on every visit whether or not a page offers it, and an unanswered request is
served the not-found page. What that icon shows is not a build question.
No mark, and the icon is a letter or a glyph built out of the design tokens.
Cost: nothing to design and nothing to keep, and the project has no visual
identity beyond its typography and its accent, which is a position rather than an
omission only if it is stated as one.
A mark, drawn once, used as the icon and wherever else the project appears. Cost:
somebody draws it, it becomes a thing to keep current in more than one place, and
it is the first asset the project owns that nothing in this plan can derive or
check.
No icon at all. Cost: every visit asks for one and gets an error page, which is
the failure #69 exists to remove, so this answer costs a request per reader
rather than costing nothing.
This does not touch entry 5. That one is about photographs of the software.
This one is about whether the project has a face.
8. What the site says about who publishes it
The site names nobody today and offers no route to anybody:
Run 2026-08-08. #76 builds the page that carries the answer and deliberately
holds no words that identify anybody, because what goes on it is a personal cost
rather than a design question. Two things make it a real question rather than a
formality. Publishing a site under a name of one's own carries a provider
identification duty in some jurisdictions, and the organisation profile carries a
donation link, which is the kind of detail that decides whether a site is read as
private or as commercial:
Nothing here is legal advice and none of the options below is safe by
construction. What each one costs is what can honestly be written down.
A full provider identification with a postal address. Cost: a private address
becomes permanently public on a page built to be indexed, and scrapers keep a
copy after any later change. It is what the strictest reading of the duty asks
for and it is the only answer that satisfies service of documents.
A name and a contact route with no postal address. Cost: a reader can reach
somebody, and a jurisdiction that asks for a summonable address is not
satisfied. This is what most personal projects do.
A service that supplies an address for exactly this purpose. Cost: money every
year, a third party in the chain, and the address is real for service of
documents without being anybody's home.
A name and nothing else. Cost: cheapest, and it leaves both a reader and any
obligation with nothing.
A separate question inside this one: which contact route, given that an address
printed on a public page is collected within days. A route that can be rotated
without changing anything else is worth more here than a memorable one, and #76
renders whichever it is from data so that rotating it is a data change.
9. Whether the site asks for money, and in what form
A sponsor button already applies to every repository in the organisation,
including this one, from a single file:
Run 2026-08-08. That button is a repository feature and it is not a page. Whether
the site itself carries the same ask is a separate decision, and this plan would
otherwise answer it silently in two places: the budget in #6 refuses a request to
a domain the project does not own, and entry 8 above already treats the existing
donation link as one of the details that decides whether the site reads as
private or as commercial.
Nothing on the site, and the button stays where it is. Cost: the ask reaches
somebody browsing the source and nobody reading the pages, which is most readers.
A plain text link on the legal notice or the landing page. Cost: one line, no
third-party request because a link is not a fetch, and the commercial reading in
entry 8 gets a second thing pointing at it.
The provider's own button or badge embedded in a page. Cost: this one is refused
by the budget rather than merely expensive, because the image and the script come
from a domain the project does not own and every reader's address reaches that
domain before they have done anything. Taking this answer means changing #6 and
saying so there.
A page of its own explaining what money would be for. Cost: the most honest and
the most work, and it is a page that has to stay true as the answer to who
publishes the site changes.
Done when
Every one of the nine entries carries an answer written down where the work
that depends on it can read it, and each issue that waited on an entry names the
answer it proceeded on rather than an assumption it made. An entry whose answer
belongs in a decision record points at the record that carries it. Nothing here
is answered by this plan on my behalf, and an entry closed that
way is reopened.