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
82 changes: 82 additions & 0 deletions DOCS-STYLE.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
# Docs and README style

This document specifies the register and section structure for READMEs and other docs prose
in pipe23 projects.

## Register

- Every sentence states a fact: what a thing is, what it does, how to run it, what it needs.
A sentence whose only job is emphasis, significance, or drama is cut.
- No aphoristic closers, no "not X but Y" reversals, no "deliberately", "simply", "literally",
or "quietly", no restating a virtue a second time, no colon-flourishes, no personification of
software.
- Target register: a good man page or Debian README.
- The subject of a sentence is the artifact, stating its function. Agentless passive ("is used
to") is acceptable. Naming the user of a thing when the interface does not care who uses it
is narration and is cut. An actor is the subject only when the actor is the fact — topology
("only the consumer backend talks to the verifier") or a responsibility boundary ("handling
the rejection is the page's responsibility").
- No scene-setting clauses ("Before any of this...", "When a user needs X, ..."). A sentence
starts at the fact.
- Headings are the noun a reader would grep for, never a step, an imperative, or an abstract
"The X" phrase. No "What's not here" sections.
- No implementation vocabulary in behavior documentation. Document the observable contract,
not the mechanism behind it.
- One fact per sentence. Multiple behaviors are not chained into one sentence with semicolons.
- Name the things a section covers rather than counting or summarizing them: list the actual
routes, keys, or files, not a count or a paraphrase of them. No coined abstractions in place
of the plain fact.
- A flat noun phrase is preferred over an em-dash appositive. An em-dash triad ("— X, Y, or
Z") is redundant when the adjacent rendered content (a table, a list, a code block) already
lists the same items. No vacuous example blocks.
- Terms come from the ecosystem itself (submodule, subclass, package, raises), not from
architecture vocabulary ("surface", "hangs off", "contract").
- Design rationale has one home. It lives in the project's spec, not in a README or reference
page.

## README skeleton

Section order: title, intro paragraph, badges, Installation, Usage, Configuration,
Documentation, Development, Status, License.

- **Title.** The heading text equals the repository or directory name.
- **Intro.** No "Overview" heading — the paragraph follows the title directly. The first
sentence is a complete definition of what the project is. Safety-relevant facts (auth,
network exposure, data handled) get one or two further sentences. While the project is
experimental, the paragraph's final sentence is the stability hedge, "It is experimental and
unstable."
- **Badges.** CI, docs, package, and license badges, placed below the intro paragraph.
- **Installation.** Command-first: the install command with no surrounding narration.
- **Usage.** Fenced examples showing real, captured command or code output, not invented
output. The fenced-line budget for the section is about 25 lines total; one compound
configuration key may take a longer single line. Error and reason-code vocabulary is
enumerated on the docs site, not in the README; an example transcript may show one instance
of a code without listing the rest.
- **Configuration.** The configuration keys the project reads, each with its default and its
effect. A project with no configuration omits this section.
- **Documentation.** One line pointing at the full documentation URL.
- **Development.** The commands to set up the environment, run tests, lint, and type-check.
- **Status.** See below.
- **License.** The license identifier.

## Example-directory READMEs

A README inside an example directory (a demo, a compose stack, a worked sample built on the
parent project) is a delta on the skeleton, not a separate template.

- No Installation section — the example runs from the parent project checkout.
- A Routes section (or the equivalent surface for the example's kind: CLI subcommands,
message topics) replaces the parent project's API reference material.
- The Documentation section becomes a pointer to the parent project's documentation, not to a
documentation build of the example itself.

## Status section

- The first line is the blunt verdict sentence, "You should not rely on this code."
- The lines that follow are a bulleted list of verified, project-level limitations, stated as
terse facts (platform coverage, missing rate limiting, in-process state, and similar).
- The intro paragraph's stability hedge (see README skeleton, above) stays in place alongside
this section.
- The section sits between Development and License.
- At maturity, the section is deleted wholesale, along with the intro's stability hedge. It is
never softened in place.
3 changes: 3 additions & 0 deletions README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,9 @@ Copier conditional paths: the segment renders only when the condition holds, so
project contains no `deploy/` at all. This template uses `[% %]` / `[[ ]]` as Jinja delimiters
instead of the defaults so GitHub Actions' own `${{ }}` expressions pass through untouched.

See [`DOCS-STYLE.md`](DOCS-STYLE.md) for the README skeleton this template's `README.md.jinja`
implements.

## Use it

```bash
Expand Down
25 changes: 19 additions & 6 deletions template/README.md.jinja
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
# [[ project_name ]]

<!-- First sentence must be a complete definition: what [[ project_name ]] is and does. Add 1-2 more sentences for safety-relevant facts (auth, network exposure, data handled) if applicable. -->
[[ description ]]
It is experimental and unstable.

[![CI](https://github.com/[[ github_org ]]/[[ repo_name ]]/actions/workflows/ci.yml/badge.svg)](https://github.com/[[ github_org ]]/[[ repo_name ]]/actions/workflows/ci.yml)
[![Docs](https://app.readthedocs.org/projects/[[ project_name | lower | replace('_', '-') ]]/badge/?version=latest)](https://[[ project_name | lower | replace('_', '-') ]].readthedocs.io/en/latest/)
[% if publish_to_pypi %][![PyPI](https://img.shields.io/pypi/v/[[ project_name ]])](https://pypi.org/project/[[ project_name ]]/)
[![Python](https://img.shields.io/pypi/pyversions/[[ project_name ]])](https://pypi.org/project/[[ project_name ]]/)
[% endif %][![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)

## Overview

[[ description ]]

[% if publish_to_pypi %]## Install
[% if publish_to_pypi %]## Installation

```
pip install [[ project_name ]]
```

[% endif %]## Usage

<!-- Replace with live-captured real output. Usage fenced-line budget is ~25 lines total; one compound config key may take a longer line. -->
```python
import [[ module_name ]]
```
Expand All@@ -28,7 +29,13 @@ As a command line tool:
[[ cli_command ]] --help
```
[% endif %]
For the full API, read the docstrings — they render to the docs site (mkdocstrings + Material).
## Configuration

<!-- Enumerate the configuration keys the project reads: name, default, effect. Delete this section if the project has no configuration. -->

## Documentation

Full documentation: https://[[ project_name | lower | replace('_', '-') ]].readthedocs.io/

## Development

Expand All@@ -39,6 +46,12 @@ uv run ruff check && uv run mypy # lint + types
uv run mkdocs serve # docs preview
```

## Status

You should not rely on this code.

<!-- List verified, project-level limitations as terse fact bullets. Delete this section wholesale at maturity. -->

## License

Apache-2.0.