diff --git a/README.md b/README.md
index 4acb715..f4ca28a 100644
--- a/README.md
+++ b/README.md
@@ -21,12 +21,28 @@ jobs:
- **Release contracts:** `installer-contract`
- **Policy gates:** `dco`, `main-guard`, `line-limit`
-Pin to a release **commit SHA** with the version in a comment — Dependabot bumps
+Pin to a release **commit SHA** with the version in a comment. Dependabot bumps
it when a newer release ships. Allowed action sources: `actions/*`, `Glyndor/*`,
and `oven-sh/setup-bun` (needed by `bun-ci`).
+## How a change reaches a repository
+
+```mermaid
+flowchart LR
+ E["Edit a reusable here"] --> M["Merge to main"]
+ M --> P["Prove it on one consumer
pinned at the merge SHA"]
+ P -->|green| T["Tag vX.Y.Z"]
+ T --> D["Dependabot opens a bump
in each consumer"]
+ D --> C["Consumer CI passes
then the pin moves"]
+ P -.->|red| E
+```
+
+The SHA pin is the buffer: a change here never reaches a repository until that
+repository's own CI has passed on it. Tag only after a real consumer is green,
+because a tag is immutable and reaches the whole organisation at once.
+
## Versioning
-Releases are semver tags on `main` — **major** for a breaking change to a
+Releases are semver tags on `main`: **major** for a breaking change to a
reusable's inputs or behavior, **minor** for additive changes, **patch** for
fixes.
diff --git a/profile/README.md b/profile/README.md
index 27ab44f..8fbcbf1 100644
--- a/profile/README.md
+++ b/profile/README.md
@@ -16,7 +16,7 @@ Website: glyndor.net
| [podup](https://github.com/Glyndor/podup) | Rust | docker-compose translator and runner for rootless Podman |
| [epistle](https://github.com/Glyndor/epistle) | Rust | Self-hosted, headless mail server (SMTP/IMAP/JMAP) |
| [epistle-panel](https://github.com/Glyndor/epistle-panel) | TypeScript | Web admin panel for epistle |
-| [authcore](https://github.com/Glyndor/authcore) | Go | Auth primitives library — passwords, tokens, OAuth2/OIDC |
+| [authcore](https://github.com/Glyndor/authcore) | Go | Auth primitives library: passwords, tokens, OAuth2/OIDC |
| [unitpm](https://github.com/Glyndor/unitpm) | Go | systemd-native process manager |
| [klyradb](https://github.com/Glyndor/klyradb) | Rust | Local database instance manager (desktop app) |
| [specio](https://github.com/Glyndor/specio) | TypeScript | Browser extension: on-device website tech-stack detection |
@@ -24,8 +24,8 @@ Website: glyndor.net
## Contributing
-Issues are open to everyone. Pull requests are invitation-only — this code
-touches kernel-level surfaces (SSH, firewall, ports). Report vulnerabilities
-privately via [`SECURITY.md`](https://github.com/Glyndor/.github/blob/main/SECURITY.md);
+Issues are open to everyone. Pull requests are invitation-only, because this
+code touches kernel-level surfaces (SSH, firewall, ports). Report
+vulnerabilities privately via [`SECURITY.md`](https://github.com/Glyndor/.github/blob/main/SECURITY.md);
contribution flow and conventions are in
[`CONTRIBUTING.md`](https://github.com/Glyndor/.github/blob/main/CONTRIBUTING.md).