Skip to the content
Short ID MutuaL-1.3 Status current Clauses 15 Versions ›

Contributing

How to propose a change to a legal instrument without breaking it.

Updated 2026-09-17 Read the source file

Thanks for your interest in MutuaL, and for wanting to make it better.

Unlike a typical software project, this one is about a legal instrument. A single misplaced comma can change the meaning of a clause, and a well-intentioned “fix” can accidentally open a loophole that corporations could exploit to strip users of their rights.

So the process here is deliberately slower and stricter than you may be used to. We measure success by stability and clarity, not by the number of commits or new features.

Before you start

Please read the Development Guidelines.

This is not optional. If your contribution violates the guidelines (for example, by using “heretofore,” creating a trapdoor, or breaking compatibility with the Open Source Definition), it will be rejected.

Please note: all development of MutuaL happens exclusively on the devel branch. We do not live-update anything that is not a trivial documentation change on the main branch.

How to contribute

1. Start with an issue

Please do not open a pull request with text changes until we have discussed them. You are, of course, free to fork the repository to experiment however you’d like without submitting a pull request. You can also use these changes as a reference.

Open an issue first. Explain:

  1. The Problem: What specific ambiguity, loophole, or error have you found?
  2. The Scenario: Give us a concrete example of how the current text fails (e.g., “If I use this with a WASM module, the network clause is unclear, because…”).
  3. The Proposed Fix: Sketch out your idea.

You may answer these however suits the change you’re proposing. As you may have noticed, we’re not terribly formal people.

We’ll discuss the legal and philosophical implications in the issue. Once we agree on the intent, we can collaborate on drafting the specific text.

2. Run the stress tests

If you are proposing a change to the rules, you must run it against our “Big Three” scenarios:

  1. The Corporate Wrap: Can a bad actor wrap this in a proprietary product?
  2. The Library Link: Does this break linking with a standard MIT library?
  3. The SaaS Loophole: Does this allow someone to run it over a network without sharing source?

3. Draft the change

When you are ready to write, remember the development guidelines. Check every change you make against them.

4. Submit the PR

Reference the original issue in your pull request.

Writing a gloss

Most sections of the current version carry a gloss. A gloss explains a clause in plain English. It sits beside the clause on the site, not inside the license file, so no reader mistakes explanation for a term.

A gloss lives at glosses/<version>/<slug>.md. The slug is the section name in lowercase, with each run of non-alphanumeric characters replaced by one hyphen. For example, Non-Liability becomes non-liability.

Each file holds a YAML block and a short body:

---
title: Redemption
role: The off-ramp. Thirty days to fix a mistake.
binding: true
obliges:
  - Stop the thing that breaks the rules, and fix it, within 30 days of a valid notice.
not_required:
  - A notice that is not accurate in a material way does not start the clock.
depends_on:
  - Innovation
see_also:
  - label: FAQ — breaking a rule by mistake
    href: /docs/faq#what-if-i-break-a-rule-by-mistake
---

The fields mean this:

  • title names the section. It must equal the section name exactly, because the loader stops the build when the two disagree.
  • role gives the job of the clause in one line.
  • binding states whether the clause imposes terms. Only Purpose sets it to false.
  • obliges lists what the clause demands.
  • not_required lists what the clause does not demand. This field matters as much as obliges, because a reader often needs to know the limit of a rule.
  • depends_on names the sections that this clause needs in order to make sense.
  • see_also links to a heading that exists, usually in the docs.

Write the body in plain English. Keep it short, explain the clause, and do not restate the binding text.

The site test suite fails when a section of a version with glossed: true in site/src/lib/versions.ts has no gloss, when a gloss declares a title that does not match its section, when depends_on names a section that does not exist, or when a see_also link points at a heading that does not exist.

Add or correct a gloss in the same change as the clause it explains. A stale gloss is a false statement about the license.

Translations

Translations are welcome. They are how the license reaches people who do not read English.

Per the Clarity section of the license, only the English version is legally binding. Every translation must say at the top that it is for information only, and that the English text governs a dispute.

By contributing to this repository, you agree that your contributions are licensed to us under the CC0 1.0 Universal waiver (or the closest equivalent possible in your jurisdiction). That way we can fold your wording into the license text without working out attribution each time.

We use a “flipped form” drafting style. This means we prioritize human readability over legalistic ritual.

If you are a lawyer or used to working with legal forms, this may feel uncomfortable. You may feel the urge to add “to the extent permitted by law” or “without limitation” to every sentence. Resist this urge. We rely on the Holism, Clarity, and Non-Liability sections to handle the safety nets so that the main text can remain as readable as possible.

Releasing a new version

A release touches several files. Work through this list:

  1. Bump the version in LICENSE.md and update its Short ID.

  2. Update every version reference in README.md: the SPDX identifier, the versioning notes, the badge, the file-header template, and the license summary.

  3. Move the previous version into former-versions/, with its original filename.

  4. Update the FAQ in docs/faq.md, including any section that quotes the license text.

  5. Revise the plain-English glosses in glosses/<version>/ (see Writing a gloss). Add a gloss for any clause the release adds, and correct any gloss the release makes wrong. A gloss carries the explanatory text that the license itself no longer holds, so a stale gloss is a false statement about the license.

  6. Update site/src/lib/versions.ts. Mark the new version as current, mark the previous one superseded with its date, and correct its Short ID and clause count if either changed. Write the new version's changelog in the same place: each entry in changes says what the new version changed from the one before it, in plain English. The site's test suite fails when the Short ID or the clause count disagrees with the file. Marking the version current before the deploy is a claim; the next step is what makes it true.

  7. Publish the site so that https://mutualist.dev/license/<version>/LICENSE.md serves the new version's text, then run the release gate from site/ and make it pass:

    pnpm verify:release --strict
    

    The gate fetches that address and passes only when the home serves this repository's own copy of that version's text — the bytes of the file itself, line endings aside. It fails on an HTTP error, on the parking page's HTML, on another version's text, and on any answer that differs from the file the repository holds: a placeholder page that merely names the version is not a publication. --strict also makes an unreachable home a failure, so a warning is not enough to release.

  8. Delete or rewrite the "unreleased" warning in the README "Status and scope" section, name the new release there, and update the version-status wording in PRODUCT.md's "Operating Context" section. This belongs to the same launch as the deploy and waits for step 7: until the gate passes, the README is the record and the site's status strip is a claim.

  9. Check that every cross-reference in LICENSE.md still names a real section.

  10. Tag the release. Foresight only accepts official releases, so a version that never reaches a tag or release at the license's home does not count.

While the README and the deployed site disagree, the repository is the record: README.md "Status and scope" is the accurate account of what is released, and the site's status strip is a claim about the launch. Do not merge to main until this list is complete and the two agree.

Code of Conduct

Be mutualist. Assume good faith, share freely, and don’t bite the hand that feeds you.

This applies everywhere the project happens: issues, pull requests, and any other discussion about the license. Disagreement is welcome—a license gets stronger by being challenged—but challenge the text, not the person. Harassment, personal attacks, and bad-faith argument have no place here.

If someone’s behavior crosses that line, contact the repository head through katsuricata.com. She may edit or remove comments, close discussions, or block contributors who keep crossing it.