Repository & Documentation Standards

This is the standard the Quality Gate's Sustainability lens holds a repository to for how it is laid out and how it carries its own knowledge. One idea runs through all of it: the repository is the single source of truth β€” for the code, for the reasoning behind every change, and for the facts from which any report, diagram, or briefing is generated. When structure, history, and knowledge all live in the clone, anyone who opens it β€” the next developer, yourself in six months, the client's team, or an AI agent working in the tree without a colleague beside it β€” can find what they need by reasoning about where it must be, not by being given a tour. Deviations are allowed, but β€” as everywhere in the handbook β€” they must be deliberate and recorded in the project's README or design notes.

This standard is where three OSBR values become load-bearing structure. Be Nice: a predictable layout and a legible record are the clearest documentation a teammate or agent will ever read, so we write for whoever comes next. Be Kind: never leave a colleague to re-learn the map under incident pressure, or to inherit five drifting copies of the same fact β€” leave them one stable skeleton and one true source. Be Strong: invest effort where it compounds (the structural source that survives staff turnover and tool churn), not where it evaporates (a hand-polished one-off document). Humans and AI agents both read and write in this tree as collaborators, and every rule here is chosen so that collaboration stays cheap and correct.

How to read this standard

1. Goal

The goal is that structure carries knowledge. When the shape of the tree is predictable, a location becomes information: scripts/ is where the runnable scripts are, docs/ is where the prose lives, and there is exactly one obvious place for each kind of thing. When the reasoning behind a change is durable, local, and reconstructable, a reader with only this clone can answer, for any non-trivial change: what was decided and what was rejected, why, and when relative to the decisions around it. And when facts are stored structurally, OSBR stays permanently able to generate a correct explanation for any reader β€” a one-line answer for a busy manager, a deep trace for an engineer, a plain-language summary for a client β€” without anyone hand-maintaining a library of finished documents.

A person who has navigated one OSBR repo can navigate the next one without a guide, and an AI agent can act by deriving a path instead of listing directories until it stumbles on the right one. Every exploration step an agent avoids is context saved, latency removed, and a chance to guess wrong eliminated.

2. Responsibility

3. Repository structure β€” divide the top level by role

3-1. Divide the top level by role

The top level of a repository is carved into a small, fixed set of directories, one per role. The role is what the directory holds and why it exists β€” not which team owns it or which feature it belongs to. The OSBR baseline vocabulary:

Directory Role β€” what lives here
packages/ The shippable code units β€” one directory per package (Β§3-3)
scripts/ Runnable operational and developer scripts (setup, migration runners, one-off tasks)
workloads/ Deployable/runnable workloads β€” services, jobs, workers, functions
databases/ Schema, migrations, seed data β€” the persisted-state layer
docs/ Human-readable documentation and the models that back it
outputs/ Generated artifacts β€” build output, reports, exports (git-ignored unless a build genuinely needs to track them)

This is convention over configuration (the Rails Doctrine): a fixed default for where things go frees you from re-deciding and re-explaining the layout on every project. The productivity does not come from any one name being optimal β€” it comes from the name being the same every time so nobody has to think about it. OSBR adopts the stance, not Rails' specific folders.

3-2. Names are pronounceable, non-abbreviated words

A name you can say out loud is one a team can talk about, one that survives a code-review conversation, and one an AI agent tokenises and reasons over cleanly. Abbreviations save keystrokes once and cost comprehension forever: the keystrokes are yours; the expansion tax is everyone's.

3-3. One directory per package

This is the layout the major monorepo tools assume: Nx and Turborepo structure a workspace as many self-contained projects, each in its own directory under a small number of role folders; Bazel formalises it hardest, where a directory with a BUILD file is a package. OSBR uses packages/ for library code and workloads/ for the deployable units β€” the same split Nx/Turborepo draw as packages/ vs apps/, named for what we deploy.

3-4. Package by feature, not by layer β€” inside the package

Role divides the top of the tree. Inside a package, structure follows the feature/domain, not the technical layer. Do not create top-level controllers/, services/, models/, utils/ buckets that every feature has to be smeared across.

This is Robert C. Martin's screaming architecture: the top level of a system should scream what it does, not which framework built it. Package directories named invoices/, scheduling/, notifications/ tell you what the business is; the framework is a detail you find later, inside.

3-5. The same layout across every project

The Go community codified exactly this instinct as golang-standards/project-layout: one agreed set of role directories, reused everywhere, so familiarity transfers across the whole portfolio. The bar for a new top-level directory is a genuinely new role β€” not "it felt tidy today".

4. Documentation lives in the repository

The rationale behind a change is worth as much as the change itself β€” and it is worth nothing if a future reader cannot find it. The same is true of every durable fact the project depends on. So both the why of a change and the facts that back an explanation live inside the repository, reviewed in the same pull request, versioned in the same history, and found by the same grep.

4-1. Store the record in the repository, as markdown

Tickets, branch stories, and release notes MUST live as markdown files committed to the repository, not solely in an issue tracker, chat, or SaaS tool. External trackers MAY mirror or link to them, but the repository copy is canonical.

This is the docs-as-code discipline: documentation authored in plain text, versioned in git, reviewed through pull requests, travelling with the code it describes. A record that lives only in a hosted tool has a different lifecycle from the code β€” it can be edited without review, lost on a licence lapse, or made unreachable by an offline clone. A record in the repo cannot.

4-2. One fact, one place β€” store it structurally

The Pragmatic Programmer's DRY principle β€” "every piece of knowledge must have a single, unambiguous, authoritative representation within a system" β€” applies to knowledge, not just code. A fact duplicated across five deliverables is a fact that will be wrong in four of them within a month.

4-3. Keep terms composable

Composable content requires composable vocabulary. Two units that describe the same thing with different words cannot be safely assembled into one explanation.

4-4. Record architectural decisions as ADRs

Decisions with lasting structural consequence MUST be captured as Architecture Decision Records β€” short markdown files, one per decision, committed under the repository (conventionally doc/adr/ or docs/decisions/). Follow Nygard's original lightweight form or the MADR template:

ADRs are immutable once accepted: a reversed decision gets a new ADR that supersedes the old one, so the reasoning trail β€” including the roads not taken β€” stays intact. We amend history by appending, never by rewriting. A pull request itself serves as a lightweight ADR for smaller decisions (see the Development Guide); reserve a standalone ADR for the structural ones.

4-5. Let AI generate structured commit messages

Commit messages MUST follow Conventional Commits (type(scope): summary, with feat, fix, refactor, docs, etc., and BREAKING CHANGE: where it applies). This gives the history a machine-readable shape that both tooling and AI agents can parse for changelogs, release scoping, and traceability.

4-6. Documents are the curated record; commit history is raw material

The document files β€” tickets, branch stories, release notes, ADRs β€” are the central, curated record. The commit history is the raw material behind them: high-fidelity, append-only, never groomed away. This is living documentation in Martraire's sense β€” authoritative knowledge kept alongside the code and refreshed as the code changes.

4-7. Treat reports and diagrams as generated derivatives

A deliverable is an output, not an asset. A slide deck is a photograph; the repository is the subject β€” we invest in the subject.

4-8. Write for the next reader β€” human or AI

Structured facts answer what is true; the commit and PR history answers why it became true. Together they let an explanation be generated at any depth, including the reasoning β€” and, because the source is versioned, as of a point in time: what did we believe, and why, on a given date.

Every record MUST be written so that a reader with only this clone and no access to us can reconstruct the reasoning. Assume the tracker is gone, the chat is unsearchable, and the author has left. What remains is the repository β€” so the repository must carry enough. That is Be Kind made operational.

References

Repository & project layout

Records, decisions & change history

Docs-as-code, structured content & living documentation

Related OSBR standards