Skip to content
Merged
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
322 changes: 322 additions & 0 deletions docs/AFFIRMATION-STANDARD.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
// SPDX-License-Identifier: CC-BY-SA-4.0
= AFFIRMATION authoring standard
:toc: preamble
:toc-title: Contents
:icons: font
:doctype: article
Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> v1.0, 2026-09-09

[NOTE]
====
This standard governs `AFFIRMATION.adoc` across the Hyperpolymath estate. Unlike
`README.adoc` and `EXPLAINME.adoc`, which every RSR-compliant repo MUST have, an
affirmation is *optional* — but where a repo carries one, it MUST conform to
this document. See link:README-EXPLAINME-STANDARD.adoc[the README + EXPLAINME
authoring standard] for its two siblings.

This standard was derived from the ten affirmations already in the estate, not
designed in advance of them. The census that produced it is recorded in
<<derivation>>.
====

== Why the genre exists

An *affirmation* is a solemn declaration of the truth of a statement, made by
someone who declines to swear an oath. The estate borrows the word precisely:
the file makes no appeal to authority, reputation, or intention. It asserts only
what was checked, states how it was checked, and names the moment at which it
was true.

The value is falsifiability. A reader who distrusts the file can re-run the
commands in it and catch the author out. That is the point.

== Relationship to README and EXPLAINME

[cols="1,2,1", options="header"]
|===
| File | Answers | Tense

| `README.adoc`
| Where is this going, and why?
| Future / aspirational

| `EXPLAINME.adoc`
| How is it built, and what is the evidence?
| Descriptive / mechanism

| `AFFIRMATION.adoc`
| What can we honestly affirm was *true and checkable* at a stamped moment?
| A frozen instant, falsifiable
|===

README sells. EXPLAINME proves. AFFIRMATION *dates* — it is the only one of the
three that goes out of date by design, and says so in its own text.

[IMPORTANT]
====
An affirmation is not a status page, not a changelog, and not a roadmap. If a
claim in it cannot be checked by a reader running a command, it does not belong
in the file. Move it to README (if aspirational) or EXPLAINME (if mechanism).
====

== The three parts of trustworthiness

Every conforming affirmation rests on three things. All three are mandatory.

Ground truth, not memory::
Every claim MUST be produced by running the tool in the session that wrote the
file. Where a live run and a status document disagree, the live run wins and
the
status document is recorded as stale. Claims copied from a previous
affirmation,
from a README, or from recollection are forbidden.

A frozen anchor::
The file MUST record an exact commit SHA, the branch, a UTC timestamp, and the
toolchain versions used. Move the SHA and the file becomes a draft.

A real signature::
The file MUST be landed by a *signed* git commit. The commit signature over
the
file content, at the recorded SHA, is the cryptographic form of the
affirmation.

== Conformant profiles

Two shapes are in use across the estate, and both are conformant. Choose the one
that fits the repo; do not mix them within a single file.

[cols="1,2,2", options="header"]
|===
| Profile | Use when | In use by

| *A — evidential*
| The repo has runnable evidence: builds, test suites, proofs, benchmarks. The
affirmation is a report of runs.
| affinescript, ephapax, tropical-types, typed-wasm, KnotTheory.jl

| *B — modal*
| The repo is primarily a normative or policy surface, where the honest content
is
what is binding versus merely intended.
| hypatia, wokelang
|===

=== Profile A — required sections

. `= AFFIRMATION — {project}, as of {YYYY-MM-DD}`
. *What this is, and how it works* — one paragraph of orientation.
. *The epistemic contract* — what the reader may and may not conclude from the
file.
. *Verifiable anchor* — the table specified in <<anchor>>. Mandatory.
. *Companion documents and repo metadata (cross-check)* — the other files a
sceptic should read against this one, including any that contradict it.
. *The honest state (one breath)* — the summary, with these subsections:
.. *What is solid (and how we checked)* — claim plus the command that
establishes it.
.. *The honest nuance you must not lose* — where a true claim is easily
over-read.
.. *Known-incomplete but honestly fenced* — gaps that fail loudly rather than
silently.
.. *Outstanding / weak / refuted (no spin)* — including anything this session
refuted.
. *Reproduce it yourself* — the exact commands, in order, with expected output.
. *One-line characterisation (quote this)* — the sentence the author is
willing to be quoted on.
. *Joint attestation* — per <<attestation>>.

=== Profile B — required sections

. `= AFFIRMATION — {project}`
. *We affirm* — the normative core (MUST). Binding now.
. *We intend* — committed next actions (INTEND). Not yet true.
. *We wish* — horizon aspirations (WISH). Explicitly not commitments.
. *Held* — anything under coordinated realignment and therefore *not* affirmed
here.
. *Provenance* — the anchor fields of <<anchor>>, in table or list form.

[CAUTION]
====
Profile B's power comes from the reader being able to tell MUST from WISH at a
glance. Never promote an item between sections without re-running whatever check
justifies the promotion, and never let an INTEND item quietly acquire the
grammar of an affirmation.
====

[[anchor]]
== The verifiable anchor

Every affirmation MUST carry these fields. Profile A renders them as a
two-column table; Profile B may use a list under *Provenance*.

[cols="1,2", options="header"]
|===
| Field | Contents

| Repo
| `owner/name`, disambiguated if the estate holds a similarly-named repo.

| Branch
| The branch the claims were measured on.

| Commit (HEAD)
| Full 40-character SHA. Never abbreviated, never a tag.

| Permalink
| `https://github.com/{owner}/{repo}/tree/{sha}`

| Verified (UTC)
| ISO-8601 with the `Z` suffix, e.g. `2026-09-09T00:52:11Z`.

| Working-tree delta at verification
| Any modification or untracked file present when the checks ran, and an
explicit statement of whether it affects the results. Write `clean` if there
was none.

| Toolchain
| Every compiler, prover, and runtime version the claims depend on.
|===

[IMPORTANT]
====
A tag MUST NOT be used as the anchor. Tags move, and a moved tag silently
invalidates every claim in the file. This is not hypothetical in this estate: a
pin recorded against a force-pushed branch rots on every upstream release.
====

The file MUST also carry, near the anchor, a warning in this spirit:

[quote]
____
If you are reading this at a later commit, the claims may have drifted. Re-run
the reproduction steps and write a fresh affirmation; do not trust a stale one.
____

[[attestation]]
== Joint attestation and signing

Profile A MUST end with a joint attestation naming both parties:

* *Engineering party (AI)* — the exact model identifier, the UTC timestamp at
which it ran the checks, and a statement that the wording is a faithful
report of those runs.
* *Owner / maintainer* — Jonathan D.A. Jewell, who signs by committing the file
with `-S` (`id_ed25519_signing`).

[source,bash]
----
git commit -S -s docs/AFFIRMATION.adoc -m "docs: affirm state at <sha>"
git log --show-signature -1
----

[WARNING]
====
Do not use `--no-verify`. The pre-commit hook enforces the SPDX header, and an
affirmation landed past its own repo's gates is self-refuting.
====

The authoritative, tamper-evident signature is the signed commit that lands the
file. If the SHA in the anchor matches the parent of that commit and the commit
verifies, the affirmation is anchored. If they do not match, the file is a draft
and MUST be read as one.

== Required format

* AsciiDoc (`.adoc`) — not Markdown.
* Line 1: `// SPDX-License-Identifier: CC-BY-SA-4.0`. An affirmation is
documentation, so it takes the docs licence, never `MPL-2.0`.
* `:toc:`, `:icons: font`, and an author line, per house style.
* Headings in sentence case. Tables carry `options="header"`. Admonitions are
AsciiDoc blocks, not emoji. Source wraps at 80 columns.
* Dates are ISO-8601. Times are UTC with an explicit `Z`.

See the AsciiDoc style rules in link:README-EXPLAINME-STANDARD.adoc[the README +
EXPLAINME standard]; they apply here unchanged.

== File naming and placement

[cols="1,2", options="header"]
|===
| File | Location

| `AFFIRMATION.adoc`
| Repository root, or `docs/`. One per repo. Root is preferred for visibility.

| `AFFIRMATION.md`
| Banned, as `README.md` is banned.

| Superseded affirmations
| `docs/affirmations/AFFIRMATION-{YYYY-MM-DD}.adoc`. Never delete a superseded
affirmation — it is the historical record that makes drift visible.
|===

== Exceptions

[cols="1,2", options="header"]
|===
| Repo / pattern | Rationale

| Upstream fork checkouts
| Do not add an affirmation to a fork. There is nothing of ours to affirm, and
it
would conflict on every upstream pull.

| `repos-monorepo` subdirectories
| Not standalone repos. The parent monorepo's affirmation covers them.

| Repos with no runnable evidence
| An affirmation with nothing checkable is worse than none. Use profile B if
there
is a normative surface to affirm, otherwise omit the file.
|===

== Anti-patterns

Do not::
* Copy claims forward from a previous affirmation without re-running the checks.
This is the single most common way the genre fails.
* Cite a green CI badge as evidence. A badge can be green because the gate never
ran; a gate that startup-fails emits no jobs and no check runs at all, so its
absence is indistinguishable from success unless you look at the run
conclusion.
* Write "all tests pass" without the command and the count.
* Record an anchor SHA that is not the commit the checks actually ran against.
* Quietly drop a claim that was refuted. Refutations belong in *Outstanding /
weak / refuted*; deleting them is the spin the genre exists to prevent.

== Enforcement

* `rsr-template-repo` carries a canonical `AFFIRMATION.adoc` skeleton with the
anchor table pre-stubbed.
* The `doc-format` workflow checks the SPDX header and AsciiDoc validity.
* Presence is *not* gated: an affirmation is optional by design, and a mandated
affirmation would be an affirmation written to satisfy a gate rather than a
reader.

[[derivation]]
== Derivation

This standard was written after a census of every `AFFIRMATION.adoc` in the
estate on 2026-09-09, rather than in advance of them. Ten were found and read in
full: affinescript, typed-wasm, ephapax, tropical-types, KnotTheory.jl,
neurophone, echidna, hypatia, my-lang, wokelang.

Five shared an identical twelve-section skeleton, which became profile A. Two
used a MUST / INTEND / WISH modal form, which became profile B. Three were
lighter variants that this standard supersedes; they should be migrated to
profile A or B at their next refresh, and are not in breach until then.

The standard was written because it was already being cited: `ephapax`
referenced this path before the file existed. That is recorded here rather than
quietly fixed, because a dangling citation is exactly the kind of drift an
affirmation is supposed to expose.

== See also

* link:README-EXPLAINME-STANDARD.adoc[README + EXPLAINME authoring standard] —
the
two mandatory siblings.
* link:https://github.com/hyperpolymath/rsr-template-repo[rsr-template-repo] —
canonical templates.
* link:HYPATIA-BASELINE-FORMAT.adoc[Hypatia baseline format] — machine-readable
companion for scanner findings.
Loading