Skip to content

chore(license): adopt the fleet license posture, one declaration rendered per repo - #12

Merged
forkwright merged 3 commits into
mainfrom
chore/fleet-license-posture
Aug 21, 2026
Merged

chore(license): adopt the fleet license posture, one declaration rendered per repo#12
forkwright merged 3 commits into
mainfrom
chore/fleet-license-posture

Conversation

@forkwright

Copy link
Copy Markdown
Owner

Finding

fleet/license-postures.toml declares this repo fleet, which renders PolyForm Noncommercial 1.0.0.
It ships PolyForm Shield 1.0.0, and its Required Notice names forkwright (https://github.com/forkwright).

forkwright is a GitHub organisation handle. It is not a legal entity, it cannot hold copyright, and
a noncommercial or noncompete restriction is enforceable only by a legal person who does — so in the
one place where using the handle as an identity has legal effect, it is used as one. Thirteen fleet
repos already carry Ardent Works LLC (https://ardent.tools) on exactly that reasoning.

What changes

Two artifacts, because splitting them leaves the repo internally contradictory — a scanner reports
the stricter of a config/LICENSE disagreement and a reader cannot tell which is authoritative.

  • LICENSE — the full canonical PolyForm Noncommercial text, rendered from the declaration rather
    than written here. sha256 60cd10e4f7e2e2f98514f157b34e0ebf62d4a7828324b255656e1fb093dcdb0a, which
    is the hash MANIFEST/license-spdx-match pins for this posture, so a byte of drift fails the rule
    rather than passing quietly.
  • .kanon-ci.toml's spdx: declaration, which MANIFEST/license-spdx-match reads. Updating the
    licence text alone would leave the repo asserting one licence in CI config and shipping another.

This is a change of axis, not a tightening. Shield permits commercial use and forbids competing
use; Noncommercial forbids commercial use and places no restriction on what the user builds. Neither
contains the other. For a library whose consumers are repos the same licensor owns, fleet is the
declared intent — and that decision lives in the posture file, not in this PR.

Verification

apply-license-posture.py --check --repo mneme --into <this worktree> reports 0 artifact groups
differ
: the branch satisfies the declaration exactly, checked with the current renderer rather than
the one that produced it. The rendered LICENSE hashes to the pinned value above.

Gate-Passed: kanon 0.12.0 +stages:fmt,check,clippy,nextest,lint
             sha:7f863166bc51a918f408b555a59e0a7ccf5ca8ae

The trailer's sha: is the tip's tree exactly. The third commit is an empty one whose only purpose is
to give that trailer somewhere to land — --stamp amends HEAD and refuses when HEAD is the pushed
upstream tip. It is honest because the trailer binds to the tree, and an empty commit does not
change the tree, so the attestation covers exactly the content that was gated. Its own message records
why a merge of main was rejected as the alternative: merging pulls main's workflows into the changed
file set and fails repo-lint on two pre-existing SHELL/unpinned-action findings this branch does
not touch.

mneme is public, so its CI is unaffected by the billing stop on the eight private repos.

Scope

Three fleet repos still carry the handle notice after this: kanon (PR #3545, open), logismos (PR #113, open), and
thumos. thumos is the one that matters most — it is public, so its unenforceable notice is
already relied upon by third parties — and it was invisible to the drift check until
kanon#3588 was fixed, because a crate-scoped copyleft hold was suppressing the whole repository's
licence comparison.

Refs forkwright/kanon#3588.

forkwright added 3 commits August 17, 2026 13:15
License across the fleet was a per-repo accident: five regimes with no visible logic,
plus six repos carrying no LICENSE at all -- which means all rights reserved by
default, the most restrictive possible outcome, reached without anyone deciding it.

Posture is now declared once and rendered, rather than written per repo. Four
postures: `fleet` (PolyForm Noncommercial -- read freely, use noncommercially,
commercial use asks), `product` (PolyForm Shield, for business surface), `interop`
(Apache-2.0 OR MIT, for libraries other repos depend on), and `private` (an explicit
proprietary notice).

The licensor is `Ardent Works LLC` everywhere. Previous notices named the GitHub org
handle `forkwright`, which is not a legal entity and can neither hold copyright nor
enforce a noncompete, or -- in one repo -- an individual.

The correction that drove the choice: AGPL does not restrict commercial use. It
permits it explicitly and requires share-alike instead, so the eight AGPL repos were
providing neither property they were chosen for.

The manifest `license` field moves in the same commit as the license text
deliberately. A repo whose Cargo.toml claims one license while its LICENSE states
another is internally contradictory, and that is worse than either original state --
a scanner reports the stricter of the two and a reader cannot tell which governs.

Repos carrying an inherited copyleft obligation are deliberately NOT changed here:
aletheia, akroasis and thumos keep their current licenses until the derived upstream
code is rewritten greenfield. An inherited obligation is not ours to override, and
relicensing derived code would be a violation performed as tidying.
`MANIFEST/license-spdx-match` reads the `spdx:` declaration here, and for a repo with
no Cargo.toml -- pinax is one, it is not a Rust project -- this is the ONLY place the
SPDX is declared. Updating manifests alone left those repos asserting one license in
CI config while shipping another in LICENSE, which is the internal contradiction this
change exists to remove.
`kanon gate --stamp` amends HEAD and refuses when HEAD is already the pushed upstream tip, since
amending there would rewrite a commit origin has. This commit exists solely to give the trailer
somewhere to land.

It is honest because the trailer binds to the TREE, and an empty commit does not change the tree —
the attestation still covers exactly the content that was gated.

WHY not a merge of main instead, which is the usual way to get a fresh commit: merging main puts
main's own `.github/workflows/*` into the gate's changed-file set, which selects the `repo-lint` step
and fails it on two pre-existing `SHELL/unpinned-action` findings in files this branch does not
touch. That is main's CI-pinning debt, not this change's, and pinning a reusable workflow to a SHA is
a fleet-wide policy call rather than a side fix in a licence PR. Filed separately.

Gate-Passed: kanon 0.12.0 +stages:fmt,check,clippy,nextest,lint sha:7f863166bc51a918f408b555a59e0a7ccf5ca8ae
@forkwright
forkwright merged commit f0b4ff0 into main Aug 21, 2026
2 checks passed
@forkwright
forkwright deleted the chore/fleet-license-posture branch August 21, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant