Files
tiny-pattern-ts/development/README.md
T
tmu 95d73d11b6 ♻️ Single-home the actionable rules and the rationale
development/ had restated the actionables that CONTRIBUTING.md owns: the
branching step list, the script prefix list, the feedback-tier rule of thumb,
the commit convention and the type-driven test loop. Those now live only in
CONTRIBUTING.md; development/ keeps the decision blocks and links to the rule.
development/README.md, CONTRIBUTING.md and AGENTS.md state the 'write each fact
once' principle explicitly.
2026-09-15 13:46:31 +00:00

90 lines
4.0 KiB
Markdown

# Development documentation
These files explain **why** this project works the way it does: the decisions
behind it, what was rejected, and the shortcomings and known issues we carry.
They are written for maintainers and contributors of the project itself.
The actionable rules — how to set up, run, test, and submit — live in
[CONTRIBUTING.md](../CONTRIBUTING.md). This folder is the "why" behind those
rules: read the relevant file here before changing an area, and update it when
a decision changes, rather than leaving an obsolete reason behind. A rule and
its reason drift apart when they live in one place and are maintained in two;
keeping the rule in CONTRIBUTING.md and the reason here keeps each single-homed.
**Each fact is written once**: the actionable rule in CONTRIBUTING.md, the
reason here. Neither restates the other — when the same fact would be useful in
both, one links to the other instead of copying it.
User-facing documentation lives in [README.md](../README.md). A `docs/` folder
is deliberately not used yet: the convention is that `docs/` is the future
user documentation site, and deploying that site is out of scope. When it
exists, these files stay here — they are not user documentation.
## Layout
One file per category:
| File | Covers |
| -------------------------------- | ----------------------------------------------------------------------- |
| [library.md](./library.md) | Public API design, the type-level contract, and its limitations |
| [workflow.md](./workflow.md) | Branching and merging, script prefixes, feedback tiers, commit messages |
| [tooling.md](./tooling.md) | Toolchain choices and configuration, editor setup |
| [testing.md](./testing.md) | Test strategy and type-driven development |
| [ci.md](./ci.md) | CI pipeline, runner image, coverage serving |
| [publishing.md](./publishing.md) | Release and npm publishing |
A category that outgrows one file becomes a folder with an index, but we start
with one file per category because each area is small enough to hold in mind at
once. When a category splits, the links in CONTRIBUTING.md and README.md keep
pointing at the category, not at a single decision.
## Decision blocks
Every non-obvious choice is recorded as a block inside the relevant category
file, using this shape:
```md
## Runner image
#### Decision (2026-09)
Bake Node into the CI job image at the setup-node tool-cache layout instead
of downloading per job.
#### Why
- ...
#### Rejected
- Gitea Pages / per-job download
- force-pull
#### Known issue
- a Dockerfile-only change re-pushed under an unchanged tag is invisible to the runner
- recover with `docker rmi <image>`
```
- The date is the month the decision was made, not the date the file was last
edited. It is the anchor a reader uses to tell "this is current" from "this
was current once".
- `Rejected` is what makes the record worth keeping: it stops the project from
re-litigating the same alternatives. An empty `Rejected` usually means the
alternatives were never written down.
- `Known issue` is where shortcomings live. If a caveat is not tied to one
decision, put it under a `## Known issues` section at the end of the file.
- A superseded decision is **replaced in place**, not archived in a second
file — the file always describes the current world, and git history is the
archive.
## Adding to these docs
1. Pick the category file for the area you are changing: `library`, `workflow`,
`tooling`, `testing`, `ci`, or `publishing`.
2. Add or update a decision block. Keep the existing text unless the decision
actually changed.
3. If the change alters an actionable rule, update
[CONTRIBUTING.md](../CONTRIBUTING.md) in the same commit and cross-link the
two. The reverse also holds: never change a rule in CONTRIBUTING.md without
updating its rationale here.