Transitrix ADR · diff
git:20260728.642e9d3 to git:20260816.66542bc
20 added, 22 removed. Audit A to A.
---
name: Transitrix ADR
- description: Help a user formulate an architecture decision and land it as a valid, gated Architecture Decision Record in the repo's per-repo decision log — the input door to the agent-authored decision flow method/03-architecture-decision-log.md specifies but ships no workflow for. Runs a Context → Decision → Consequences interview, derives the id from today's date and a slug (no allocation step), validates against scripts/check-adl.mjs, and opens a PR. Never self-accepts a decision and never edits an accepted record's body — course changes are a new record plus a status-pointer flip on the old one (supersession).
+ description: Help a user formulate an architecture decision and land it as a valid, gated Architecture Decision Record in the repo's per-repo decision log — the input door to the agent-authored decision flow method/07-decisions.md specifies but ships no workflow for. Runs a Context → Decision → Consequences interview, derives the id from today's date and a slug (no allocation step), validates against scripts/check-adl.mjs, and opens a PR. Never self-accepts a decision and never edits an accepted record's body — course changes are a new record plus a status-pointer flip on the old one (supersession).
when_to_use: User says "we decided X, write it up", "record this architecture decision", "log an ADR for this", "supersede ADR-…", "we're changing course on that decision", or an agent working autonomously in a Transitrix (or Team-Operations-adopting) repo needs to leave an auditable trace of a consequential choice it made (e.g. "bumped a version pin", "chose library X over Y").
min_version: "0.6.0"
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, WebFetch
---
# Transitrix ADR Skill
Turns "we decided X" into a committed, `scripts/check-adl.mjs`-clean Architecture
Decision Record on a PR — without the user (or the calling agent) hand-writing the
front-matter, numbering the file, or working out the ratification gate themselves.
This is the **entry point** to the agent-authored decision flow
- [`method/03-architecture-decision-log.md`](../../../method/03-architecture-decision-log.md)
- specifies (§6) but ships no workflow for.
+ [`method/07-decisions.md`](../../../method/07-decisions.md)
+ specifies (§4) but ships no workflow for.
This directory is the **`adr` skill** within the `transitrix` plugin (the plugin root
is [`transitrix/`](../../), which carries the shared
[`.claude-plugin/plugin.json`](../../.claude-plugin/plugin.json) manifest, one
`skills/<name>/` directory per skill). Invoked as `/transitrix:adr`. Written for any
coding agent that can read/write files and run shell commands, not only Claude Code —
same portability discipline as every other skill in this plugin.
Mechanism this skill sequences (read before or during first use):
- [`method/02-team-operations.md`](../../../method/02-team-operations.md) §3.1 (the
- per-repo record shape) and
- [`method/03-architecture-decision-log.md`](../../../method/03-architecture-decision-log.md)
- (the `author`/`source` extension, the ratification gate, immutability, the harvest
- job). This `SKILL.md` does not restate the mechanism — it sequences it.
+ [`method/07-decisions.md`](../../../method/07-decisions.md) §2 (the per-repo record
+ shape, the `author`/`source` fields) and §4–§7 (the ratification gate, immutability,
+ the harvest job). This `SKILL.md` does not restate the mechanism — it sequences it.
---
## The three invariants this skill enforces
1. **Ratification gate — never self-accept.** Every record this skill writes carries
`author: agent`, `status: proposed`. It never sets `status: accepted` — that is a
- separate, human-reviewed change (`method/03` §6). This is the whole safety story:
+ separate, human-reviewed change (`method/07-decisions.md` §4). This is the whole safety story:
the worst this skill can do unattended is leave a *proposed* record for review.
2. **Supersession, not mutation.** "Change a decision" is never an edit to an
`accepted` record's body — it is a **new** record plus a `superseded_by` /
- `supersedes` pointer flip on the old one (`method/03` §7). See Step 6.
+ `supersedes` pointer flip on the old one (`method/07-decisions.md` §6). See Step 6.
3. **ADR vs living-design-doc.** A genuinely evolving artefact (a current-state design
spec that changes as understanding improves) is not a decision. This skill detects
that shape and routes it away from the append-only log instead of forcing it in
- (`method/03` §7; Step 1 below).
+ (`method/07-decisions.md` §6; Step 1 below).
---
## Step 0 — Locate (or scaffold) the decisions folder
Detect the repo's decision-record path:
- - **Canonical** — `operations/decisions/` (`method/02` §2, extended by `method/03`).
+ - **Canonical** — `operations/decisions/` (`method/06-team-operations.md` §2, extended by `method/07-decisions.md`).
Use this for any repo that does not already have an established alternative.
- **Existing alternative** — if the repo already has `docs/decisions/` in active use
(a general code repo that adopted the convention before the canonical path was
set), use it as-is; pass `--dir docs/decisions` to `check-adl.mjs` in Step 5. Do
**not** create a second, parallel folder. Per
[`patterns/enterprise-adr-registry.md`](../../../patterns/enterprise-adr-registry.md)
"Legacy path variants", `docs/decisions/` is a legacy alias, not a co-equal option —
mention this once to the user, but don't force a migration mid-task.
- **Neither exists** — scaffold `operations/decisions/` now (empty folder, `.gitkeep`
if the repo needs an explicit placeholder for git to track it). Tell the user this
is the start of their per-repo ADL and point at
[`patterns/enterprise-adr-registry.md`](../../../patterns/enterprise-adr-registry.md)
"Start here" for the one-time CI-guard wiring — do not wire CI yourself unless asked;
this skill's own Step 5 validates locally regardless of whether CI is wired.
**Never** create `docs/decisions/` or a central `Architecture/` folder from scratch —
- those are legacy aliases only (`method/03` was reconciled onto `operations/decisions/`
+ those are legacy aliases only (`method/07-decisions.md` was reconciled onto `operations/decisions/`
+ `architecture/decision-log/`; see the pattern doc). This skill only ever writes the
**per-repo** record — it never writes to a central `architecture/decision-log/`
- directly (that is the harvest job's job alone, `method/03` §5; Step 4 below only
+ directly (that is the harvest job's job alone, `method/07-decisions.md` §5; Step 4 below only
*marks* a record promotable).
---
## Step 1 — Is this actually a decision?
Before running the interview, check the shape of what the user is describing:
- **A point-in-time choice** ("we picked X over Y", "we're pinning to version N", "we
decided to stop doing Z") → it's an ADR. Continue to Step 2.
- **An evolving description of current state** (an architecture-overview doc, a spec
that will keep changing as the system does) → **not** an ADR. Tell the user this
- belongs in a `doc_type: living-design-doc` artefact instead (`method/03` §7) — it
+ belongs in a `doc_type: living-design-doc` artefact instead (`method/07-decisions.md` §6) — it
evolves freely and does not go through this skill's append-only flow. Stop here; do
not force it into `operations/decisions/`.
If genuinely ambiguous, ask the user directly rather than guessing — routing a live
spec into the append-only log is a one-way mistake (the immutability discipline in
Step 5 will actively fight the user on every subsequent edit).
---
## Step 2 — Formulation interview
Extract, conversationally, in this order:
1. **Context** — why a decision was needed; the constraints in play.
2. **Decision** — one declarative sentence, plus any necessary qualifiers.
3. **Consequences** — what this commits the team to; what it rules out; what becomes
easier or harder.
4. **`source`** — the forum this came from: an architecture review board, a named
design review, a specific meeting, or `ad-hoc`. Optional but recommended
- (`method/02` §3.1.1) — it's the context a future reader needs and the methodology
+ (`method/07-decisions.md` §2.1) — it's the context a future reader needs and the methodology
does not get to skip just because it's convenient to omit.
5. **Scope — single-repo or cross-project candidate?** Walk through
[`patterns/enterprise-adr-registry.md`](../../../patterns/enterprise-adr-registry.md)
"When to add the enterprise layer": does this decision affect an interface, a
shared library, or a cross-cutting concern another repo depends on; does a
governance/compliance requirement call for an aggregated record; is an autonomous
agent making an architecturally-significant cross-repo change right now? Any yes →
candidate for promotion (Step 4). Otherwise it's single-repo only — most decisions
are, and that's a complete, valid outcome, not a lesser one.
6. **`relates_to`** (optional) — model entity IDs (Goals, Capabilities, …) this
decision concerns, if the repo has a Transitrix `canon/` to link into
- (`method/02` §4). Skip if not applicable.
+ (`method/06-team-operations.md` §4). Skip if not applicable.
State your understanding back before writing anything — a wrong Context/Decision
split is expensive to fix once the record exists (Step 5 makes the record immutable
the moment a human accepts it).
---
## Step 3 — Derive the id, write the record
1. Derive a short kebab-case slug from the title (3–6 words).
2. The id is today's date plus that slug: `ADR-YYYY-MM-DD-<slug>`. No folder listing,
no counter, nothing to allocate — an author on a branch that cannot see another
author's unmerged work computes this alone, and two records authored the same day
get distinct filenames from their distinct slugs. **Existing repos with legacy
`ADR-NNNN` records:** do not renumber or touch them — the two forms coexist; only
- new records use the date-slug form (`method/02` §3.1.2).
+ new records use the date-slug form (`method/07-decisions.md` §2.2).
3. Copy [`templates/ADR-template.md`](templates/ADR-template.md) to
`<decisions-folder>/ADR-YYYY-MM-DD-<slug>.md` — the same string for `id:` and the
filename.
4. Fill in `id`, `title`, `date` (today — must equal the id's date), `source`,
`relates_to`, and the three body sections from Step 2. Leave `status: proposed` and
`author: agent` — **never** change these to `status: accepted` (Step 5's guard
rejects it anyway, but don't rely on the guard catching what you already know not
to do).
---
## Step 4 — Mark promotable, if the Step 2 scope check said cross-repo candidate
If Step 2.5 flagged this as enterprise-significant, add a `scope:` field to the
front-matter (e.g. `scope: enterprise` — match whatever scope value the
organisation's central `architecture/decision-log/harvest.config.yaml`
- `promote.scopes` list actually uses, per `method/03` §5; ask the user if unknown).
+ `promote.scopes` list actually uses, per `method/07-decisions.md` §5; ask the user if unknown).
This is the **only** thing this skill does to participate in promotion — the harvest
job (`scripts/adl-harvest.mjs`, run from the *central* architecture repo, not this
one) reads `scope:` on its own schedule and copies the record into
`architecture/decision-log/promoted/` itself. This skill never writes into
`architecture/decision-log/` — that folder does not exist in this repo and this
skill does not create it.
If the user doesn't know the org's promotion scope vocabulary yet, leave `scope:` off
— an unpromoted record is still a complete, valid ADR; promotion can be added later by
editing the front-matter (a non-status field edit is only blocked once the record is
`accepted`, per Step 5's A2 — while `proposed`, it's still freely editable).
---
## Step 5 — Validate before commit
Run the ADL guard. If `scripts/check-adl.mjs` is not present in this repo (true for
most adopter repos — it's a methodology-canon script, not something every repo
vendors), fetch it once from the pinned methodology release rather than `main`:
1. Read `methodology_version` from this repo's `transitrix.yaml`, if one exists.
2. Fetch `https://raw.githubusercontent.com/transitrix/methodology/v<methodology_version>/scripts/check-adl.mjs`
(fall back to the latest release tag if the pin doesn't resolve, or to `main` with
an explicit warning to the user if neither does) and write it to
`.validators/check-adl.mjs` — the same location the onboarding skill fetches
`lint.py` into, so a repo scaffolded by `/transitrix:onboard` grows one coherent
`.validators/` folder rather than a second ad hoc one.
3. Run it:
```
node .validators/check-adl.mjs --dir <decisions-folder> --base origin/<default-branch>
```
(Use `scripts/check-adl.mjs` directly, no fetch needed, when working inside the
methodology repo itself.) Fix every finding — A1 front-matter, A4 filename/id — before
proceeding. A2/A3 (immutability, agent gate) are diff-based against the base branch;
they will not fire against a brand-new `proposed` file, but do not bypass or skip the
check to get past them — if either fires, something is wrong (e.g. accidentally
touched a different, already-accepted record) and needs fixing, not overriding.
---
## Step 6 — Supersede an existing decision (course change)
Triggered by "supersede ADR-…" / "we're changing this decision" instead of a fresh
decision:
1. Read the target record. If its `status` is `proposed` (not yet ratified), a
straightforward edit in place is fine — nothing is immutable yet, so there is no
supersession to perform; just revise it and re-run Step 5.
- 2. If its `status` is `accepted`, immutability applies (`method/03` §7) — do **not**
+ 2. If its `status` is `accepted`, immutability applies (`method/07-decisions.md` §6) — do **not**
edit its body or non-status front-matter:
- Run Steps 1–5 to author a **new** record (its id is always the date-slug form,
whichever form the record it supersedes uses) capturing the revised decision, its
own Context/Decision/Consequences, and add `supersedes: <old-id>` to its
front-matter.
- On the **old** record, change only `status: superseded` and
`superseded_by: <new-id>` — leave every other field and the entire body
untouched. This is the one front-matter edit Step 5's A2 check permits on an
accepted record.
3. Both changes land in the same PR (Step 7) — a supersession is one logical change,
reviewed together.
---
## Step 7 — PR, not merge
1. Branch: `adr/<id>` (or `adr/<id>-supersedes-<old-id>` for Step 6).
2. Commit the new record file (and, on a supersession, the old record's status-pointer
edit) — nothing else. If Step 5 freshly fetched `.validators/check-adl.mjs` for the
first time in this repo, that's a separate, reviewable addition; call it out in the
PR description rather than burying it in the same diff silently.
3. Open a PR. **Never merge it** — ratification (`proposed → accepted`) is a distinct,
human-reviewed change per the gate in the three invariants above, not something
this skill or its calling agent performs.
4. PR description states: the decision in one line, its `source`, whether it's marked
promotable (Step 4) and to what scope, and an explicit note that ratification
(flipping `status` to `accepted`) is a separate follow-up for a human reviewer to
make — not part of this PR.
---
## What this skill does NOT do
- Does **not** ever set `status: accepted` on a record it authors — ratification is
- always a separate, human-reviewed change (`method/03` §6).
+ always a separate, human-reviewed change (`method/07-decisions.md` §4).
- Does **not** edit an `accepted` record's body or non-status front-matter, ever, for
any reason — course changes are always a new record + a status-pointer flip
(Step 6).
- Does **not** write to a central `architecture/decision-log/` directly — that is the
harvest job's exclusive output, run from the central architecture repo on its own
- schedule (`method/03` §5). This skill only marks a per-repo record `scope:` for the
+ schedule (`method/07-decisions.md` §5). This skill only marks a per-repo record `scope:` for the
harvest to pick up later.
- Does **not** force an evolving design artefact into the append-only ADR shape —
Step 1 routes that case to `doc_type: living-design-doc` instead.
- Does **not** invent `docs/decisions/` or `Architecture/` from scratch — those are
legacy path variants; the canonical paths are `operations/decisions/` (per-repo) and
`architecture/decision-log/` (central), per the reconciled
`patterns/enterprise-adr-registry.md`.
- Does **not** merge its own PR, or skip/bypass `scripts/check-adl.mjs` findings to
get a record committed faster.