Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .adr-kit.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ADR kit configuration for repository-level decision governance.
adr_directory: docs/adr
adr_directory: adr
filename_pattern: "ADR-[0-9]{4}-[a-z0-9-]+\.md"
statuses:
- Proposed
Expand Down
16 changes: 13 additions & 3 deletions .github/workflows/adr-governance.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
name: ADR Governance

permissions:
contents: read

on:
pull_request:
paths:
- 'docs/adr/**'
- 'adr/**'
- '.adr-kit.yaml'
- 'scripts/adr-governance.py'
- 'scripts/tests/**'
- '.github/workflows/adr-governance.yml'
push:
branches:
- main
- master
paths:
- 'docs/adr/**'
- 'adr/**'
- '.adr-kit.yaml'
- 'scripts/adr-governance.py'
- 'scripts/tests/**'
- '.github/workflows/adr-governance.yml'

jobs:
Expand All @@ -25,5 +30,10 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Run ADR governance regression tests
run: python3 -I -m unittest discover -s scripts/tests -p 'test_adr_governance.py'
- name: Run ADR governance checks
run: python3 scripts/adr-governance.py
env:
GITHUB_EVENT_BEFORE: ${{ github.event.before }}
run: python3 -I scripts/adr-governance.py
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ This repo documents the Autonomi 2.0 network. See `repo-registry.yml` for which
- ant-quic (excluded — older ancestor/fork; use saorsa-transport instead)
- Any repo not listed in the repo registry

## ADR governance

Before changing architecture, protocols, storage formats, cryptography, network behaviour, public APIs, data models, or operational invariants, inspect `adr/`. Use `adr/TEMPLATE.md` for new or changed architectural decisions. Never edit an Accepted ADR; create a superseding ADR instead. Never mark an ADR Accepted autonomously. Validate ADR work with `python3 -I scripts/adr-governance.py` and the repository's ADR governance tests.

## Audience and objectives

### Who these docs are for
Expand Down
69 changes: 69 additions & 0 deletions adr/ADR-0002-adrs-live-at-repo-root-not-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ADR-0002: Architecture Decision Records live at repo-root `/adr`, not `docs/adr`

- **Status:** Accepted
- **Acceptance:** Prospective — confirmed by Jim Collinson as decision owner during review of PR 73.
- **Date:** 2026-07-14
- **Decision owners:** Jim Collinson
- **Reviewers:** Jim Collinson
- **Supersedes:** ADR-0001 (location clause only; ADR governance remains in force)
- **Superseded by:** none
- **Related:** ADR-0001 (adopt ADRs — its governance decision remains in force while this ADR supersedes its location clause), ADR-0008 (GitBook platform — why `docs/` is the published product), ADR-0012 (the developer skill kept out of `docs/` for the same reason); `.gitbook.yaml` (`root: ./docs/`), `.adr-kit.yaml` (`adr_directory`), `scripts/adr-governance.py` (`ADR_DIR`), `.github/workflows/adr-governance.yml`

> Current (prospective) decision — made while adopting ADRs in this repo, not a retrospective reconstruction. It re-points the team standard's default ADR location for this repo's specific circumstances; the standard's mechanics are untouched.

## Context

The team ADR standard (ADR-0001, shipped via PR #56) defaults ADRs to `docs/adr/` — correct in a typical repo where `docs/` holds internal documentation. This repo is different: `.gitbook.yaml` sets `root: ./docs/`, so the **entire `docs/` tree is the published developer-documentation product**, synced to GitBook at `docs.autonomi.com/developers`. Placing ADRs under `docs/adr/` puts internal architecture records inside that published product tree.

## Decision Drivers

- Internal architecture records must not publish to, or surface on, the public developer-docs site — nav, search, or the auto-generated `llms.txt`.
- ADRs must stay out of the docs' machinery: the upstream-sweep scanner walks `docs/**/*.md` for verification blocks, and doc tooling (Diátaxis templates, terminology lint, link-checking) globs the same tree.
- A contributor browsing `docs/` as "the documentation" should not find architecture decisions mixed in with product pages.
- The team standard should still be honoured — its own `.adr-kit.yaml` `adr_directory` knob exists precisely so a repo can relocate the instance.
- Consistency with the existing decision to keep the developer skill at `skills/`, not `docs/skills/` (ADR-0012), for exactly this reason.

## Considered Options

1. **Keep ADRs at `docs/adr/`** (the team default). Rejected here: `docs/` is the published GitBook root, so ADRs would sit inside the product tree, risk leaking to the public site / `llms.txt`, and be swept by doc tooling.
2. **Keep `docs/adr/` but exclude it from GitBook** (SUMMARY omission or a `.gitbook.yaml` rule). Rejected: fragile — `root: ./docs/` keeps the files in scope, so it relies on GitBook silently ignoring unlisted files, and the conceptual mixing remains.
3. **Relocate ADRs to repo-root `/adr`.** Chosen. (`planning/adr/` was also considered and rejected: ADRs are formal, ratified decisions, distinct from the loose-thinking design docs that live in `planning/`.)

## Decision

Architecture Decision Records live at repo-root **`/adr`** in this repo. This is a repo-local *configuration* of the team standard, not a fork of it:

- `.adr-kit.yaml` → `adr_directory: adr`.
- `scripts/adr-governance.py` → `ADR_DIR = Path("adr")`.
- `.github/workflows/adr-governance.yml` → path filters point at `adr/**`.
- Move the standard's own files (`TEMPLATE.md`, `TOOLING.md`, `README.md`, and `ADR-0001`) from `docs/adr/` to `/adr`.

`/adr` is chosen over `planning/adr/` because ADRs are formal, ratified decisions — distinct from the loose-thinking design material (`implementation-plan.md`, `verification-workflow.md`, `routines/`, `sweeps/`) that already lives in `planning/`.

## Consequences

### Positive

- Architecture records stay entirely out of the published product tree and its tooling.
- Mirrors the skill's out-of-`docs/` placement (ADR-0012): one consistent rule — product content in `docs/`, internal artifacts at the repo root.
- Still fully governed — the gate validates ADRs at `/adr` once `ADR_DIR` is re-pointed.

### Negative / Trade-offs

- Diverges from the team-standard default (`docs/adr`), so a contributor arriving from another WithAutonomi/Saorsa repo must notice the repo-local location — this ADR is the signpost, and `docs/adr/` is left empty/removed so nothing looks half-moved.
- Requires the three config points (`adr_directory`, `ADR_DIR`, workflow paths) to stay in agreement. The governance script fails closed when they diverge, but the workflow must still become a required check to prevent bypass at merge time.

### Neutral / Operational

- The change is small and repo-local; the shared standard's mechanics (template, lifecycle, immutability) are unchanged — only the configurable location differs.
- Decided as too minor to route through the standard's owner; recorded here so the deviation is explicit and auditable.

## Validation

- `scripts/adr-governance.py` (with `ADR_DIR=adr`) is the validation entrypoint for the `/adr` set; `docs/adr/` no longer exists. Making its workflow a required check is tracked as an implementation-conformance gap.
- Spot-check after the move: no ADR path appears in the GitBook nav, site search, or `llms.txt`.
- Review trigger: a change to `.gitbook.yaml`'s `root`, or a move to a different docs platform, may reopen the location question.

## Notes for AI-assisted work

AI tools may help draft this ADR, but **must not mark it Accepted without human review**. Accepted ADRs are immutable: create a new superseding ADR rather than editing an Accepted ADR.
73 changes: 73 additions & 0 deletions adr/ADR-0003-verification-block-source-of-truth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# ADR-0003: Verification-block source-of-truth model for developer docs

- **Status:** Accepted
- **Acceptance:** Retrospective — this ADR records a decision made before the ADR process existed. The original decision owner confirms it as a faithful account; current implementation gaps are tracked separately.
- **Date:** 2026-07-14
- **Decision owners:** Jim Collinson
- **Supersedes:** none
- **Superseded by:** none
- **Related:** ADR-0001 (Adopt ADRs); `planning/verification-workflow.md`; `planning/implementation-plan.md` §8; original build 2026-04-02 → 2026-04-22 (repo baseline `a1110ea`, "Reverify against current merged truth" `3eaf653`)

> Retrospective ADR. The decision was taken and implemented across April 2026; this record captures it after the fact so the reasoning is preserved. Evidence is cited in **Related** and **Validation**.

## Context

The Autonomi developer docs describe fast-moving upstream code (`ant-sdk`, `ant-client`, `ant-node`, `ant-protocol`, `saorsa-*`, and others). Documentation that drifts from the code is worse than no documentation: it silently misleads developers. The repo needed a way to state, for every documented surface, *exactly which upstream commits that surface was verified against*, so drift is detectable mechanically rather than by re-reading everything by eye.

A second tension: docs must describe the latest merged default-branch source truth, not the expected future product shape. Installation, download, package, and version surfaces have an additional constraint: they must describe artifacts a developer can actually install or download, even when merged source is newer. Without explicit rules, pages tend to drift toward aspirational descriptions of unmerged branches or present unreleased artifacts as available. But a launch-hardening pass needs the opposite of following moving branches — the ability to pin a set of pages to a fixed release target.

## Decision Drivers

- Drift must be **detectable by a machine**, not only by human review.
- Every documented surface must be **traceable to exact upstream commit SHAs**.
- Docs must default to **current merged default-branch source truth**, never future state; installation, download, package, and version surfaces must additionally stay within installable or released truth.
- A launch/release pass must be able to **pin** pages to fixed refs without inverting the day-to-day default.
- Provenance metadata must not leak into rendered prose.

## Considered Options

1. **No embedded provenance** — track freshness out-of-band (a spreadsheet, issue tracker, or reviewer memory). Rejected: unmaintainable, not machine-checkable, drifts immediately.
2. **Page-level "last reviewed" date only.** Rejected: a date says *when* someone looked, not *what upstream state* was true; it cannot detect that upstream moved.
3. **Per-surface verification records pinning `(source_repo, source_ref, source_commit, verified_date, verification_mode)`, with two explicit modes.** Chosen.

## Decision

We will embed **verification metadata** in the docs and skill sources as the single machine-readable record of what each documented surface was verified against.

- Every rendered documentation surface carries one or more `<!-- verification: ... -->` blocks in `docs/**/*.md`. Each block records the full declared schema: `source_repo`, `source_ref`, `source_commit` (an exact SHA), `verified_date`, and `verification_mode`.
- The skill uses equivalent YAML metadata rather than documentation comment blocks. `skills/start/SKILL.md` frontmatter carries `verified_date`, `verification_mode`, and a per-repo `verified_commits` SHA map. The runtime `skills/start/version.json` manifest mirrors only the fields needed at runtime or for external inspection, including `version`, `verification_mode`, and `verified_commits`; it deliberately omits `verified_date`, which records when the skill content was reviewed.
- Two verification modes are defined, and they are an **invariant of the model**:
- **`current-merged-truth`** (default): verify against the latest merged commit on the upstream default branch at audit time. Unmerged branches and PRs are out of scope.
- **`target-manifest`**: launch/release-hardening mode. Verify against refs pinned in `target-manifest.yml`; **do not** follow moving default branches for pages in this mode.
- A page presented as verified must never carry `source_commit: TBD`.
- Provenance/verification language lives only in the comment blocks and metadata — never in rendered body text.

This model is the foundation the automation in ADR-0004 through ADR-0007 operates on: the scanner, the guards, and the routine all read and write these blocks and nothing else about freshness.

## Consequences

### Positive

- Drift becomes a deterministic diff: compare each `source_commit` against upstream HEAD (see ADR-0004). No human re-reading required to *detect* staleness.
- Every verification record is auditable to exact SHAs, so a reviewer can reproduce the evidence for that documented surface.
- The default keeps docs aligned with merged source truth, while install and release surfaces remain honest about artifacts developers can obtain; the `target-manifest` escape hatch supports launch hardening without weakening the default.

### Negative / Trade-offs

- Authors and automation must keep the blocks accurate; a stale-but-present block is a false "verified" signal, so block integrity itself must be guarded (ADR-0006) and reachability-checked (ADR-0007).
- Multi-repo pages carry multiple blocks, adding markup weight to sources.

### Neutral / Operational

- The rendered-documentation block schema (`source_repo`, `source_ref`, `source_commit`, `verified_date`, `verification_mode`) and the skill metadata split described above become stable contracts that downstream tools depend on; changing either is itself an architectural change requiring a superseding ADR.
- `target-manifest` blocks are deliberately excluded from automated bumping (see ADR-0007) so a launch pin is never silently overwritten.

## Validation

- The scanner (`scripts/sweep_poll.py`) parses every block and fails closed on a malformed block (missing `source_repo`/`source_ref`/`source_commit`/`verification_mode`) or an unknown mode — so a schema violation is caught, not ignored.
- `sweep-sha-reachability` (CI) confirms every recorded SHA is reachable on the declared upstream ref.
- Review trigger: any change to the block schema, the mode set, or the "no `TBD`" rule must supersede this ADR rather than edit it.

## Notes for AI-assisted work

AI tools may help draft this ADR, but **must not mark it Accepted without human review**. Accepted ADRs are immutable: create a new superseding ADR rather than editing an Accepted ADR.
Loading
Loading