DOC / MRS-001 Revision 0.4 Apr 2026

mores.dev

A working specification for the unwritten rules of software: ethics, community standards, and the conventions practitioners hold in common.

Editors
The Standing Committee on Coding Mores
Status
Working Draft — open for review
Audience
Maintainers, contributors, and reviewers
Cite as
mores.dev/MRS-001


1.0

Premise

Every codebase carries a moral grammar — norms about how to name, when to ship, who to credit, and what to leave unwritten. These rules are mores: customs strong enough to feel like law, even when no law exists.

This document collects those mores and proposes a careful vocabulary for them. It is descriptive first — observing what good engineers already do — and only secondarily prescriptive. Where prescription appears, the reasoning is shown alongside.

The aim is not orthodoxy. It is to make our shared expectations legible enough to argue with.


1.1

On the meaning of “mores”

From the Latin mōrēs, plural of mōs: customs, manners, the settled ways of a people. Sumner distinguished mores from mere folkways by their moral weight — the conviction that breaking them is not just unusual but wrong.

Software has both. The choice between tabs and spaces is a folkway. The choice to disclose a known security flaw is a more.


1.2

Scope & non-scope

This specification addresses conventions observable across language communities, code review cultures, issue trackers, and release practices in mainstream open source.

  • In scopeConventions that recur and that practitioners can articulate.
  • In scopeEthical commitments embedded in routine engineering decisions.
  • Out of scopeStyle guides for any one language or framework.
  • Out of scopeLegal compliance, which is a floor, not a ceiling.

2.0

Conventions of the craft

The smallest decisions a programmer makes are also the most repeated. A name chosen poorly is read a thousand times before it is changed. A comment omitted is a question asked again next year.

Conventions are how a craft amortizes attention. They free the next reader, and the next maintainer, from re-deriving what was already settled.


2.1

Naming as social act

A name is a promise. fetchUser claims a kind of work; getUserOrThrow claims a discipline of failure. To name well is to commit to behaviour your colleagues can rely on without rereading the body.

2.1.a Names that keep their promises
// Anti-pattern: a name that lies about its risk.
function getUser(id) {
  return db.queryOne("SELECT * FROM users WHERE id = ?", [id]);
  // Throws on missing rows. The name does not warn the caller.
}

// Mores-aligned: the name carries the failure mode.
function getUserOrThrow(id) {
  const row = db.queryOne("SELECT * FROM users WHERE id = ?", [id]);
  if (!row) throw new UserNotFound(id);
  return row;
}

// Or, equally honest, name it for its return shape.
function findUser(id) /* : User | null */ {
  return db.queryOne("SELECT * FROM users WHERE id = ?", [id]) ?? null;
}

The convention here is not which verb to use. It is that a function’s name should not surprise a reader who has read only the signature.


2.2

Comments are debts to readers

Code says what. A good comment says why, and addresses a future engineer who has lost the context that made the choice obvious.

Comments that restate the next line are noise. Comments that explain a constraint, a workaround, or an intentional omission are the cheapest documentation we will ever write.

“The cost of a comment is paid once. The cost of its absence is paid every time the file is reopened.”

— observed, but not original

3.0

Standards of community

An open source project is a small republic. Its constitution is its README; its civic life is its issue tracker. The mores below describe how that republic stays habitable when its citizens are mostly strangers.


3.1

Reviewing as care

To review another’s code is to read it as if you intend to maintain it. The review is not a gate; it is an apprenticeship in both directions. The reviewer learns the contributor’s thinking; the contributor learns the project’s grain.

  • DoComment on the diff in front of you, not on the contributor.
  • DoDistinguish requests from questions, and questions from preferences.
  • DoApprove when the change improves the project, even if you would have written it differently.
  • AvoidWithholding approval to enforce private taste.

3.2

Issue triage as listening

Most issues are reports of a single user’s confusion. A few are signals of structural problems. Distinguishing them is the central craft of maintainership.

The triage acknowledges receipt before it diagnoses. A label is not a substitute for a sentence. Closing without explanation is, in this republic, a small unkindness.

3.2.a A bot that is honest about being one
# Mores-aligned: bot announces itself, defers, and links a human path.
on: issues
jobs:
  triage:
    steps:
      - uses: actions/labeler@v5
      - name: Acknowledge politely
        run: |
          gh issue comment "$ISSUE" --body \
            "Thanks for reporting this. A maintainer will review it
             within a week. (This message was posted by a bot;
             reply 'human?' to escalate.)"

4.0

Ethics in execution

Engineering ethics is not a separate field one consults in emergencies. It is the accumulation of ordinary decisions: which default to ship, which warning to suppress, which logline to keep.

The sections that follow describe two such ordinary decisions where the ethical content is unusually visible.


4.1

The cost of defaults

A default is a decision made on behalf of every user who will not change it — which is almost all of them. To set a default is to legislate.

4.1.a Defaults that respect the user
// Anti-pattern: opt-out tracking, hidden behind a verbose name.
const options = {
  enableUsageMetrics: true,   // silent default
};

// Mores-aligned: opt-in, with a sentence the user can read.
const options = {
  enableUsageMetrics: false,
  metricsConsentPrompt:
    "Send anonymous usage counts to help prioritise fixes? (y/N)",
};

The point is not that telemetry is wrong. It is that defaults that benefit the maintainer at the cost of the user must pass through an explicit conversation.


4.2

Telemetry & consent

If a project records the behaviour of its users, it has entered a relationship of trust whose terms must be plain. Three obligations follow:

  1. Disclose. State, in the README and on first run, what is collected and why.
  2. Minimise. Collect the smallest record that answers the question being asked.
  3. Forget. Provide a deletion path the user can exercise without writing an email.

A project that cannot meet these obligations should not collect telemetry. The cost of not knowing is bounded; the cost of breaching trust is not.


5.0

Closing

Mores are not invented; they are noticed. This document is a noticing exercise — an attempt to write down what good practitioners already do, so that the next generation does not have to rediscover it under deadline.

Revisions are welcome. Send patches in the spirit of § 3.1.

Document
MRS-001 — A Standard for Software Mores
Set in
Space Grotesk, Crimson Pro, IBM Plex Mono
Maintained at
mores.dev