Repository navigation
docs: add the decision log, the docs folder guide and the ADR rule #1308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
96455d8
docs: add the decision log, the docs folder guide and the ADR rule
romchornyi e2b70ac
docs: name branch names and linked issues in the publicity checkbox, …
romchornyi 83cfa96
docs: name branch names in the CLAUDE.md publicity rule
romchornyi 4e05300
docs: drop the transient review status from the docs-layout summary
romchornyi ace51c4
docs: index ADRs by area and open Decision outcome with a Chosen sent…
romchornyi ebff2c4
docs: name the approving reviewer in the ADR-0001 Deciders line
romchornyi 6acde01
docs: name the publicity redaction exception in every ADR lifecycle s…
romchornyi 90285b8
docs: accept ADR-0001 and ADR-0002
romchornyi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # docs | ||
|
|
||
| If this page and [ADR-0001](adr/0001-record-architecture-decisions-as-adrs.md) disagree, ADR-0001 wins. | ||
|
|
||
| This folder holds the written record of dashwallet-ios: decisions, architecture docs, feature | ||
| folders and review captures. The repository is public, so everything here is public from the | ||
| first push of its branch. | ||
|
|
||
| ## Required | ||
|
|
||
| ADRs for significant decisions are required for everyone, whether or not you use the feature-spec | ||
| pipeline. An ADR (architecture decision record) is a short document that states one decision, why | ||
| it was made, the options considered and its consequences. | ||
|
|
||
| A decision is significant when it is hard to reverse, or affects more than one module or consumer. | ||
| The full rule, its examples and the "not needed" cases N1–N4 are in | ||
| [ADR-0001](adr/0001-record-architecture-decisions-as-adrs.md). The decision log and how to | ||
| add an ADR to it are in [adr/README.md](adr/README.md). | ||
|
|
||
| ## Optional | ||
|
|
||
| Feature summaries are optional. A feature built with the feature-spec pipeline gets one file, | ||
| `docs/features/<name>/README.md`: what changed, why, and links to its ADRs. The pipeline's working | ||
| drafts (spec, design, tasks, reviews) are not committed. Its ADRs are copied into `docs/adr/` in the | ||
| feature PR and follow the same rules as any other ADR. | ||
|
|
||
| ## Layout | ||
|
|
||
| | Path | Holds | Lifecycle | | ||
| |---|---|---| | ||
| | `docs/README.md` | this guide | edited as the layout changes | | ||
| | `docs/adr/` | the decision log: `NNNN-*.md` files and the index `README.md` | new entries; an existing Accepted ADR changes only in its status line when superseded (ADR-0001 rule 3) or by a redaction that the publicity rule requires (ADR-0001 rule 2) | | ||
| | `docs/architecture/` | architecture docs | living, edited as the code changes | | ||
| | `docs/features/<name>/README.md` | one summary per feature | written in the feature PR | | ||
| | `docs/review/` | review captures | unchanged | | ||
|
|
||
| ## Publicity rule | ||
|
|
||
| The repository is public: everything here, and everything else committed, pushed or posted on its | ||
| PRs and issues, is public too. Never write, here or anywhere in the repository and its PRs: | ||
|
|
||
| - customer data, including anything taken from a support case; | ||
| - details of a vulnerability that is not fixed yet; | ||
| - secrets: keys, tokens, credentials, recovery phrases; | ||
| - step-by-step attack detail against keys, PIN or encryption. | ||
|
|
||
| Describing the security design at the level already public in the code is allowed. Leave content | ||
| the rule keeps out of the repository and handle it privately with the maintainers; a doc may say | ||
| only that the detail is handled privately. A support case is described by its symptom, never by | ||
| the customer. Keep it out before pushing: the PR template's publicity | ||
| item, checked by the Reviewer, is the last net, not the first. Full rule: | ||
| [ADR-0001, rule 2](adr/0001-record-architecture-decisions-as-adrs.md). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # 0001 — Record architecture decisions as ADRs | ||
|
|
||
| - **Status:** Accepted | ||
| - **Date:** 2026-11-03 | ||
| - **Deciders:** romchornyi (author). Team agreement: approval of #1308 by llbartekll. | ||
|
|
||
| ## Context | ||
|
|
||
| dashwallet-ios has no agreed place for decisions. Decisions are not recorded in a form that says what was decided, why, and what later replaced it. Developers re-argue settled choices, Reviewers judge changes without the reasoning, and AI agents read only the agent instructions file (`CLAUDE.md`). The team is also starting to use a feature-spec pipeline that writes feature ADRs under its own per-feature numbering. Its working drafts are not committed; a feature publishes a short summary and its ADRs. The repository is public, so every document is published the moment its branch is pushed. | ||
|
|
||
| ## Decision drivers | ||
|
|
||
| - Every significant decision has one findable record with its reasoning and current status, in one place and under one numbering. | ||
| - The rule is shared: the whole team agrees to it and writes ADRs, not only the owner. | ||
| - Nothing published through the repository exposes customer data or exploitable security detail; 0 publicity-rule breaches reach the default branch. | ||
| - 100% of log ADRs are listed in the index with the correct status. | ||
| - Every primary source checked keeps one central, sequentially numbered log and states the threshold as a principle with exclusions, never as a pure category list (fact-check 2026-11-03: Nygard, MADR, Polar handbook). | ||
|
|
||
| ## Considered options | ||
|
|
||
| 1. **One central, sequentially numbered decision log with a rule that binds every Developer** — the rules below. | ||
| 2. **ADRs kept by the owner alone, with no team rule** — less discipline asked of others, but the records cover only one person's work. | ||
| 3. **ADRs only inside feature folders, under the pipeline's per-feature numbering, with no central log** — no extra step, but decisions are scattered under many numberings, and Developers who do not use the pipeline have nowhere to write. | ||
| 4. **One central log as in option 1, but only feature ADRs above the significance threshold are promoted** — the log grows more slowly, but every feature PR needs a per-ADR judgement about which drafts to promote, and unpromoted drafts stay in feature folders as a second set of numbered decisions. | ||
|
|
||
| ## Decision outcome | ||
|
|
||
| **Chosen:** option 1, with every feature ADR that the feature keeps promoted. It is the only option that meets the first two drivers together: one place and one numbering, shared by everyone. Over option 4 the owner chose one simple rule (promote everything) and accepted a faster-growing log; the threshold therefore governs decisions made outside the pipeline. The rules below also carry the publicity driver, which neither option 2 nor option 3 addresses. | ||
|
|
||
| ### Rule 1 — Significance threshold | ||
|
|
||
| A decision needs an ADR when it is **hard to reverse, or affects more than one module or consumer**. | ||
|
|
||
| Examples in this wallet: | ||
|
|
||
| - a new dependency or SDK; | ||
| - a storage schema or migration; | ||
| - the key and security model; | ||
| - a module boundary; | ||
| - a contract with platform or rust-dashcore. | ||
|
|
||
| **Not needed** — a code comment or the PR description covers these: | ||
|
|
||
| - **N1** — a local, easily reversible choice inside one module (naming, internal structure, a private helper); | ||
| - **N2** — a temporary workaround, marked `TODO(label)` in the code; | ||
| - **N3** — a bug fix that restores the intended behaviour without changing a contract; | ||
| - **N4** — a change that follows an Accepted ADR without changing its decision. | ||
|
|
||
| The PR template's ADR item is answered with one of: `ADR-NNNN added`, `no significant decision`, or `not needed: <N1–N4>`. | ||
|
|
||
| ### Rule 2 — Publicity | ||
|
|
||
| The repository is public. Everything that goes through it is public the moment it is pushed or posted: | ||
|
|
||
| - every committed file, anywhere in the tree: code and its comments, tests and fixtures, `docs/`, `CLAUDE.md`, the root documentation files, configuration; | ||
| - commit messages and branch names; | ||
| - the titles, descriptions and comments of PRs and issues, review comments and replies, and the files attached to them (screenshots, logs, crash reports). | ||
|
|
||
| Never put there: | ||
|
|
||
| - customer data, including anything taken from a support case; | ||
| - details of a vulnerability that is not fixed yet; | ||
| - secrets: keys, tokens, credentials, recovery phrases; | ||
| - step-by-step attack detail against keys, PIN or encryption. | ||
|
|
||
| Describing the security design at the level already public in the code is allowed. Content that the rule keeps out is left out of the repository and handled privately with the maintainers; a document, comment or PR may say only that the detail is handled privately. A support case is described by its symptom, never by the customer: no names, emails, addresses, transaction ids, wallet ids or unredacted logs and screenshots. | ||
|
|
||
| The author keeps such content out **before pushing**. The PR template's publicity item, checked by the Reviewer, is the last net and not the first. When a breach is found: | ||
|
|
||
| - in a file: it is removed and a short note says that the file was redacted and why. This redaction is allowed even in an Accepted ADR: the publicity rule wins over rule 3's "never edited". Git history still holds the removed text; | ||
| - in PR or issue text or an attachment: the comment or file is deleted, and an edited description also has the old revision deleted from its edit history, which GitHub otherwise shows to everyone. | ||
|
|
||
| A secret that reached any pushed branch or any PR text is treated as leaked and rotated, even if it was removed before merge. | ||
|
|
||
| ### Rule 3 — Lifecycle, numbering and supersede | ||
|
|
||
| - A new ADR takes the next free log number, starts as **Proposed**, and is listed in the index (`docs/adr/README.md`) in the same PR. | ||
| - An ADR becomes **Accepted** only when a Reviewer who is not its author approves the PR that carries it. An AI agent's approval never counts. After the approval, the author sets Accepted in the ADR and in the index as the last change before merge; this status-only change needs no new approval. | ||
| - The Status line is the ADR's only status field. An ADR in `docs/adr/` has no frontmatter. | ||
| - An Accepted ADR is **never edited**. The only exceptions are its status line when it is superseded and a redaction that rule 2 requires. | ||
| - To change a decision, write a new ADR that names the old one. In the old ADR only the status line changes, to `Superseded by ADR-NNNN`. | ||
| - A number is **never reused**. If two open PRs take the same number, the author of the PR that merges second moves the ADR to the next free number when rebasing and updates every reference to the old number in that PR. A renumbering alone needs no new approval. Before merging, the author checks that the number is still free on `develop`. | ||
|
|
||
| ### Rule 4 — Promotion of feature ADRs | ||
|
|
||
| Every feature ADR that the feature keeps goes to the decision log in the feature PR itself. A draft the pipeline rejected or replaced is not copied. | ||
|
|
||
| - it is copied to `docs/adr/` under the next free log number, without the pipeline's frontmatter, with the status Proposed, and listed in the index; from then on the copy in `docs/adr/` is the record; | ||
| - it becomes Accepted under rule 3, like any other ADR; | ||
| - the feature's public summary, `docs/features/<name>/README.md`, links it by its log number; | ||
| - the index lists log numbers only. | ||
|
|
||
| The status that the pipeline wrote into a draft does not count. | ||
|
|
||
| ### Rule 5 — Shape, and who writes ADRs | ||
|
|
||
| - File: `docs/adr/NNNN-<decision-in-kebab-case>.md`. The title states the decision, not the problem. | ||
| - Body: the Status, Date and Deciders lines, then Context, Decision drivers, Considered options, Decision outcome, Consequences and Links. Considered options and Consequences are required. Decision outcome opens with one sentence, `**Chosen:** …`, that states the decision on its own. Feature ADRs use the same shape, so promotion is a copy, not a rewrite. Links are relative to the file (`../README.md`), so they work on GitHub and in a local checkout, and point only at what is in the repository. | ||
| - Index row: number, title, Area, Status and Superseded by. Area is one value from the fixed list under the index table; a new value is added to that list in the PR that first needs it. | ||
| - Every Developer writes ADRs for their significant decisions, whether or not they use the feature-spec pipeline. Feature summaries are optional. | ||
| - Past decisions get an ADR when they are next revisited; no retroactive backlog is required. | ||
|
|
||
| ## Consequences | ||
|
|
||
| **Positive** | ||
| - Each significant decision has one record with its reasoning and its current status, findable from one index. | ||
| - Reviewers have a checklist item for asking for a missing ADR, and a written "not needed" list for accepting its absence. | ||
| - AI agents get a named source of settled decisions and a way to challenge one (supersede) instead of silently contradicting it. | ||
| - The publicity rule is written down and checked on every PR, for its files, its commits and its text. | ||
|
|
||
| **Negative** | ||
| - Every significant PR carries an extra document, and every PR carries two more checklist items. | ||
| - The log grows faster than a log that holds only threshold-level decisions, because every feature ADR that a feature keeps is promoted, including the small ones the pipeline produces by quota. | ||
| - Little is automated: the repository's gitleaks pre-commit hook (`.githooks/`, enabled per clone) catches secrets; index completeness, numbering and the other publicity cases rely on the Reviewer. | ||
|
|
||
| **Neutral** | ||
| - If the co-maintainers do not agree to a mandatory rule, this ADR is changed in its own PR before approval: the ADR checklist item becomes optional and ADRs are written by those who choose to. The publicity item stays mandatory, because the repository is public whatever the team decides. | ||
|
|
||
| ## Links | ||
|
|
||
| - Feature summary: [docs/features/docs-and-adr-layout/README.md](../features/docs-and-adr-layout/README.md) | ||
| - Related ADR: [0002 — Keep the decision log in docs/adr](0002-keep-the-decision-log-in-docs-adr.md) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # 0002 — Keep the decision log in docs/adr | ||
|
|
||
| - **Status:** Accepted | ||
| - **Date:** 2026-11-03 | ||
| - **Deciders:** romchornyi (author) | ||
|
|
||
| ## Context | ||
|
|
||
| The decision log needs a fixed path. `CLAUDE.md`, the PR template, the docs folder guide, the feature-spec pipeline's promotion step, and links from issues and PRs all refer to it. On `develop`, `docs/` holds only `docs/review/`. The rest of the docs folder layout is decided together with the log's home, because the guide explains all the sections in one place. | ||
|
|
||
| ## Decision drivers | ||
|
|
||
| - One place for every ADR, named so that people, agents and links can find it. | ||
| - Links from issues and PRs are permanent, so the path should not change once ADRs are linked. | ||
| - The pipeline already writes feature ADRs to an `adr/` folder, and promotion copies them into the log (ADR-0001 rule 4). | ||
|
|
||
| ## Considered options | ||
|
|
||
| 1. **`docs/adr/`** — the name used by Nygard's original post and adr-tools, and the same name as the pipeline's feature-folder subfolder. | ||
| 2. **`docs/decisions/`** — the folder MADR recommends since version 3; it avoids the acronym and matches the glossary term "decision log". | ||
|
|
||
| ## Decision outcome | ||
|
|
||
| **Chosen:** option 1, `docs/adr/`. It matches the pipeline's own `adr/` folder that promotion copies from. Option 2's main advantage, avoiding the acronym, is covered by the docs folder guide, which explains what an ADR is. | ||
|
|
||
| The resulting layout of the docs folder: | ||
|
|
||
| | Path | Holds | Lifecycle | | ||
| |---|---|---| | ||
| | `docs/README.md` | the docs folder guide: what is required (ADRs for significant decisions, for everyone), what is optional (feature summaries), where architecture docs and reviews go, and the publicity rule in short | edited as the layout changes | | ||
| | `docs/adr/` | the decision log: `NNNN-*.md` files and the index `README.md` (`# \| Title \| Area \| Status \| Superseded by`) | new entries; an existing Accepted ADR changes only in its status line when superseded (ADR-0001 rule 3) or by a redaction that the publicity rule requires (ADR-0001 rule 2) | | ||
| | `docs/architecture/` | architecture docs | living, edited as the code changes | | ||
| | `docs/features/<name>/README.md` | one summary per feature: what changed, why, and links to its ADRs; the pipeline's working drafts are not committed | written in the feature PR | | ||
| | `docs/review/` | review captures (already exists) | unchanged | | ||
|
|
||
| ## Consequences | ||
|
|
||
| **Positive** | ||
| - Promotion is a copy between two folders with the same name: `adr/` → `docs/adr/`. | ||
|
|
||
| **Negative** | ||
| - "adr" is jargon; a newcomer learns its meaning from `docs/README.md`, not from the path. | ||
|
|
||
| **Neutral** | ||
| - Renaming the folder later is a quick change inside the repository, but it breaks external links to ADRs. That is why this ADR exists. | ||
| - The loose root documentation files are not part of this layout until the follow-up PR moves them. | ||
|
|
||
| ## Links | ||
|
|
||
| - Feature summary: [docs/features/docs-and-adr-layout/README.md](../features/docs-and-adr-layout/README.md) | ||
| - Related ADR: [0001 — Record architecture decisions as ADRs](0001-record-architecture-decisions-as-adrs.md) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.