Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,12 @@ the site.
`decisions/` is what has been settled and why, and it is not published.

The separation that matters most is between the generator and everything
published, because only the first one is a program. Whether the design system
ends up under a different licence from the generator is entry 1 of #1, and the
boundary that answer would fall on is `docs/design-system.html` plus the token
file #39 extracts from it.
published, because only the first one is a program. The design system does carry
a different licence from the generator, and the boundary falls inside
`docs/design-system.html` rather than around it: the words are CC-BY-4.0 and the
markup, stylesheet and script they sit in are not. `decisions/licensing.md` is
the declaration, and `docs/design-tokens.json` is on the design system's side of
it.

## What runs today

Expand Down Expand Up @@ -250,10 +252,12 @@ tense. Read the relevant one before arguing with a rule, because most
disagreements about a rule are disagreements with the decision behind it and
those are easier to have directly.

Some things are deliberately not settled. Those are in #1 and are not decided in
a pull request. The license this repository carries is no longer one of them: it
is AGPL-3.0, in [LICENSE](LICENSE), and what remains open in entry 1 of #1 is
whether the published pages and the design system carry different terms.
Some things were deliberately not settled, and those were in #1 rather than in a
pull request. Every entry of that issue now carries an answer. The licence is one
of them: the code is AGPL-3.0-or-later, in [LICENSE](LICENSE), and the design
system and the words on the published pages are CC-BY-4.0.
`decisions/licensing.md` is the declaration that says which bytes are which,
because the boundary runs inside two files rather than between them.

## Style

Expand Down
62 changes: 33 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,40 +185,44 @@ own documentation.

## License

The GNU Affero General Public License, version 3 or any later version. The full
text is in [LICENSE](LICENSE), and the "or any later version" is the option the
licence's own application notice offers rather than an addition to it.
Two licences over one tree.

The detector reads it:
The code is under the GNU Affero General Public License, version 3 or any later
version. The full text is in [LICENSE](LICENSE), and the "or any later version"
is the option the licence's own application notice offers rather than an addition
to it.

gh api repos/Flowfin/hub --jq '.license.spdx_id'
AGPL-3.0

Run 2026-08-09.
The design system and the words on the published pages are under CC-BY-4.0,
attribution required, so that a project adopting the design system does not
inherit a code licence with it.

### What it covers

Every path in this repository, with no exception and no second licence anywhere
in the tree. That is worth saying out loud because this tree holds three kinds of
thing with three different audiences, and a reader who knows that will look for a
boundary:

| Path | What it is | Under |
|---|---|---|
| `manifest/`, `internal/`, `main.go` | The generator, which is a program | AGPL-3.0-or-later |
| `docs/` | The published site, including the design system | AGPL-3.0-or-later |
| `decisions/`, `*.md` | The documents | AGPL-3.0-or-later |
| `sources/` | The declared source set, which is data | AGPL-3.0-or-later |

The design system is prose and numbers other projects are invited to adopt, and
adopting them means following what they say rather than copying the file, which
the licence does not reach. Copying the file, or a client built from it, is a
derivative and does.

Whether the published pages and the design system should carry different terms
from the generator is entry 1 of #1 and is open. A single `LICENSE` at the root
reads as covering the whole tree, which is what the table above states, so a split
would be a change to this rather than a reading of it.
The boundary between the two does not run between files. Both served pages hold
the page's own stylesheet, its markup and its script in the same bytes as the
words a reader reads, so a table of paths would be wrong about part of every file
it named. [`decisions/licensing.md`](decisions/licensing.md) is the declaration,
part by part, and it is the authority rather than this section: it says which
bytes are under which licence, what a reader who copies a whole file takes, and
what the tree does not carry.

The short of it. The generator, the site's own markup, stylesheets and script,
the documents and the declared source set are AGPL-3.0-or-later. The words on the
published pages, and the design system including `docs/design-tokens.json`, are
CC-BY-4.0.

Adopting the design system means following what it says rather than copying the
file, which no licence reaches. Copying the file, or a client built from it, is a
derivative and does, and CC-BY-4.0 is the licence that reaches it.

The repository detector reads the root file and only the root file, so it reports
one licence for a tree that grants under two:

gh api repos/Flowfin/hub --jq '.license.spdx_id'
AGPL-3.0

Run 2026-08-25. Nothing on the platform side can be made to state both, which is
why the declaration is a file in the tree.

The plugin repositories this catalogue lists are separate repositories under
their own terms. A catalogue listing something is not a statement about its
Expand Down
141 changes: 141 additions & 0 deletions decisions/licensing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Two licences over one tree, declared by parts

This tree holds a program, a published site and a design system. The program is
under the AGPL. The design system and the words on the published pages are under
CC-BY-4.0. The boundary between them does not run between files, so it is
declared here, by part, and nowhere else.

That is entry 1 of #1, and it is the last entry of that issue to be answered.

## What was decided

**The code is AGPL-3.0-or-later.** The licence was taken by the maintainer on
2026-08-08 in entry 1 of #1 and applied to every board that carried none. The
`or-later` half is the option the licence's own application notice offers rather
than an addition to it, and it was made precise fleet-wide on 2026-08-09.

Entry 1 carried two answers naming different variants of the same licence for a
while: `AGPL-3.0-or-later` on 2026-08-09 and `AGPL-3.0-only` on 2026-08-11,
neither referring to the other. That was recorded in the issue on 2026-08-11 and
settled by the maintainer on 2026-08-24, who read the `-only` answer as a slip
and kept the variant the tree already stated. So this file states one variant and
does not carry a live disagreement forward.

**The design system and the words on the published pages are CC-BY-4.0.**
Decided by the maintainer on 2026-08-11, with the reason: a design system other
projects are invited to adopt must not raise code-licence questions for the
adopter. Attribution stays required.

**The form is one declaration by parts, not a header in each file.** Decided by
the maintainer on 2026-08-24, because the boundary does not run between files and
a per-file header would have to claim it does.

## Why a path table cannot carry it

Both served pages hold the page's own stylesheet, its markup and its script in
the same bytes as the words a reader reads. At `2a8f88a`:

grep -n '<style>\|</style>\|<script>\|</script>' docs/index.html docs/design-system.html
docs/index.html:5:<style>
docs/index.html:22:</style>
docs/design-system.html:4:<style>
docs/design-system.html:149:</style>
docs/design-system.html:411:<script>
docs/design-system.html:447:</script>

grep -c "" docs/index.html docs/design-system.html docs/design-tokens.json
docs/index.html:71
docs/design-system.html:447
docs/design-tokens.json:276

Run 2026-08-25. A row saying `docs/` is under one licence is wrong about part of
every file it names, and a header at the top of either page would be a statement
about the whole file made in the one place a reader trusts it least.

Three shapes were open when the entry was recorded on 2026-08-11: a per-file
header, a declaration naming parts, and moving the prose into files of its own.
The third was not chosen, so a page's words stay in the page they are read from.

## The declaration

**Under AGPL-3.0-or-later**, whose text is in [LICENSE](../LICENSE):

- The generator, meaning `main.go`, `internal/` and `manifest/`, together with
the suites and the specimen data that go with them.
- The site's own code: in `docs/index.html` and `docs/design-system.html`, the
`<style>` block, the `<script>` block, and the elements, attributes and class
names that arrange the page. That is a program in the sense that matters here,
because it is what runs in a browser, and it is not part of what an adopter is
asked to take.
- The documents: `README.md`, `CONTRIBUTING.md`, `decisions/`, and the other
documents at the root of the tree. The answer of 2026-08-11 moved the design
system and the page prose and named nothing else, so these stay where the tree
already had them rather than following the page prose out.
- The declared source set under `sources/`, which is this project's data about
which repositories it reads.

**Under CC-BY-4.0**, `https://creativecommons.org/licenses/by/4.0/`, attribution
required:

- The words a reader reads on `docs/index.html` and `docs/design-system.html`:
the running text, the headings, the table contents and the captions. Not the
markup they sit in.
- The design system as a whole, which is those words on `docs/design-system.html`
plus the values in `docs/design-tokens.json`. The token file is on this side
because it is the design system's values in the form an adopter is asked to
take, and putting it on the other side would raise for the adopter exactly the
code-licence question the answer exists to prevent.

**Under neither, because it is not this project's to license:**
`docs/manifest.json` is generated, and the names, descriptions and overviews in
it are read out of descriptors the listed repositories publish.
`decisions/manifest-is-generated.md` is how it is produced and
`decisions/names-are-data.md` is why no such value is typed here. The plugin
repositories the catalogue lists are separate repositories under their own terms,
and listing something is not a statement about its licence.

## What a reader who takes a whole file takes

Both. A served page is bytes under two licences, and copying the file copies both
parts of it. That is the cost of the boundary running inside a file rather than
between files, and it is stated here rather than argued away: an adopter who
wants only the design system takes the words and the token file and leaves the
page, and an adopter who wants the page takes it under both sets of terms.

## What the tree does not carry

The CC-BY-4.0 text. `LICENSE` holds the AGPL in full and there is no second
licence file:

git ls-files | grep -i -E '^(LICENSE|COPYING|LICENSES)'
LICENSE

Run 2026-08-25 at `2a8f88a`. So the second licence is named by identifier and
address above and is not reproduced in this repository, which is weaker than what
the first one gets. That is a gap rather than a decision, and #140 is where it is
held.

The repository detector reads the first licence and only the first one, which is
what a single root `LICENSE` gets:

gh api repos/Flowfin/hub --jq '.license.spdx_id'
AGPL-3.0

Run 2026-08-25. A reader who takes that field for the whole answer will miss this
file, and nothing on the platform side can be made to state two.

## What refuses a departure

Nothing. No leg of the gate reads a licence, and a file added tomorrow under
neither part of this declaration is refused by no route here. This is prose, and
the review is where a departure is caught.

The one thing that is mechanical is negative: `no-hardcoded-names` and the other
legs are printed by `go run .` and none of them has a licence as its subject.

## What this does not settle

Whether the plugin repositories the catalogue lists should carry the same licence
as the catalogue. Entry 1 of #1 raised it in its own body and no answer in that
issue reaches it; it is a decision about twelve other repositories rather than
about this tree, and this file states no answer to it.
Loading