All commits to linuxboot/heads must be:
git commit -S -s -m "component: short description"-S— GPG-sign the commit (required; see CONTRIBUTING.md)-s— addSigned-off-by:trailer for DCO compliance (required; CI enforces this)
component: short imperative description (72 chars max)
Optional body explaining the why, not the what. Wrap at 72 chars.
Reference issues or PRs with #NNN.
Signed-off-by: Your Name <email@example.com>
- Subject line: imperative mood ("fix", "add", "remove", not "fixed"/"adds")
- Component prefix: the file or subsystem changed (
oem-factory-reset,tpmr,gui-init,Makefile,doc, etc.) - Body: explain motivation and context; the diff shows what changed
Add a Co-Authored-By: trailer only on commits whose primary content is
collaborative documentation (doc/*.md writing). Never add it to code
fixes, features, or refactors.
Co-Authored-By: Name <email@example.com>
| Location | Purpose | Signing required |
|---|---|---|
doc/*.md in this repo |
Developer-facing: architecture, patterns, internals, build conventions | Yes (same as all commits) |
linuxboot/heads-wiki |
User-facing: installation, configuration, how-to guides published at osresearch.net | No (lower bar for contribution) |
Content should live in doc/*.md when it describes how the code works or how
to build/develop. Content should live in heads-wiki when it describes how a
user installs, configures, or operates a Heads-equipped device.
Over time, doc/*.md and the wiki may overlap; the canonical user-facing
source is the wiki.
For CI internals, cache layering, and workspace-vs-cache behavior, see
circleci.md.
Use the maintainer checklist there when changing .circleci/config.yml.
See build-artifacts.md for the full ROM filename convention. Quick reference:
# Release build (clean tag, e.g. v0.2.1):
heads-x230-v0.2.1.rom
# Development build (any other state):
heads-x230-20260327-202007-my-feature-branch-v0.2.1-42-g0b9d8e4-dirty.rom
# ^timestamp ^branch name ^git describeThe timestamp sorts builds chronologically. The branch name identifies which PR or feature a binary corresponds to without consulting git.
When testing a development build, the ROM filename is your primary build identifier — include it verbatim in bug reports and PR comments.
When touching provisioning code (oem-factory-reset, seal-hotpkey,
gui-init):
- Run a full OEM Factory Reset / Re-Ownership with custom identity (name + email)
- Verify
gpg --card-statusreflects cardholder name and login data - Verify dongle branding shows correctly for the attached device
- Verify TOTP/HOTP sealing succeeds after reset
- Check
/bootsigning succeeds with the new GPG key
When touching the Makefile or build system:
- Verify dev build filename includes timestamp + branch
- Verify a locally-tagged clean commit produces the short filename
- Verify
.zippackage extracts andsha256sum -cpasses - If changing
.circleci/config.yml, verify the documented cache/workspace behavior in circleci.md still matches the pipeline
- All user-visible output through logging helpers:
STATUS,STATUS_OK,INFO,NOTE,WARN,ERROR,DEBUG(see logging.md) - Interactive prompts via
INPUTonly — never rawread - All interactive text output routed through
>"${HEADS_TTY:-/dev/stderr}"to avoid interleaving withDO_WITH_DEBUGbuffered stdout - Terminology: passphrase for TPM/LUKS secrets; PIN for GPG smartcard (OpenPGP spec); never "password" in user-facing text
- Diceware references when prompting users to choose passphrases
See ux-patterns.md for INPUT, STATUS/STATUS_OK,
DO_WITH_DEBUG, HEADS_TTY routing, and PIN caching conventions.