Every decision is a record; the ledger is gone
papa-hq has no ledger. Its root is AGENTS.md, CLAUDE.md, README.md, every decision is a numbered record, and its graduation playbook has no path for an unrecorded decision. hal-hq now matches. The ledger's 41 entries classified as: 10 restating a record, 11 restating design docs, 15 describing how this repository works with the reasoning sitting in a README rather than anywhere citable, 3 small rules with no home, 2 superseded stubs. Mostly a copy — and a hand-maintained index, the exact pattern ADR 0022 had just rejected for the decision index on the grounds it drifted after one addition. Keeping one copy of that while removing another is not a position. It also collided by name with 02-DECISIONS/ in any directory listing. Nothing was dropped. Records 0019-0025 give the repository decisions the reasoning they never had: HQ is its own repository and is public, design has two layers, work moves through playbooks, status lives in frontmatter, issues have a front door, the numbering is the flow, HQ is the source of the constitution. 0026 records the ledger's own removal. The three orphan rules went to how-we-build, where a rule is enforced and keeps the incident that earned it — the package rule was genuinely unwritten anywhere. Two lab decisions stated only in the ledger went into the lab design. "Deliberately not decided" went to the research effort and design document each question actually belongs to. The chronological view the ledger provided is now generated from record frontmatter, which is what it was for. The cost, stated in 0026 rather than glossed: a record is more work than a table row, so the risk is a small decision going unrecorded because nobody wanted to write a document. how-we-build takes rules cheaply, which is the mitigation, not a solution.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-22
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
supersedes: none
|
||||
---
|
||||
|
||||
# 19. HQ is its own repository, and it is public
|
||||
|
||||
## Context
|
||||
|
||||
The mesh's reasoning — mission, research, design, decisions — began inside the code
|
||||
repository, under a folder there. The objection to moving it out was specific and good: the
|
||||
mesh already has an operational memory and a structured archive, and adding a third store
|
||||
repeats the mistake that consolidation was meant to fix.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Keep it in the code repository.** Rejected, but the objection it rests on is correct and
|
||||
is answered rather than dismissed — see Consequences.
|
||||
2. **Put it in the structured archive**, alongside the governed documents. Rejected: the
|
||||
archive is not reviewable as a diff, and a design argument is exactly the thing that needs
|
||||
line-by-line review and a branch.
|
||||
3. **Its own repository.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
HQ is its own repository, and it is **public** — written for a reader who is not its author
|
||||
and has no access to the mesh it describes.
|
||||
|
||||
Three reasons it is separate:
|
||||
|
||||
- **The cadence differs.** A decision changes when thinking changes, not when code changes.
|
||||
Tying documents to a code branch merges them on the code's schedule.
|
||||
- **The reviewers differ.** A design argument is not reviewed the way an implementation is,
|
||||
and should not queue behind a build.
|
||||
- **The scope is wider than one repository.**
|
||||
[ADR 0015](0015-mesh-brokers-nodes-host-agents-think.md) sends most modules out of the
|
||||
monorepo; documentation governing several repositories cannot live inside one of them.
|
||||
|
||||
Being public is not incidental. It is enforceable only because
|
||||
[ADR 0003](0003-the-mesh-database-is-the-source-of-truth.md) made the code repository
|
||||
node-agnostic: there is no per-node content to leak. Nothing here may carry routable
|
||||
addresses, real domain names, hosting providers, node names, absolute paths, usernames,
|
||||
credentials, or operational detail useful only to an attacker.
|
||||
|
||||
The test is whether a paragraph would still teach a stranger running an entirely different
|
||||
mesh.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A document and the code it describes can no longer land in one commit. Keeping them honest
|
||||
is a discipline rather than a mechanism — which is why decisions are recorded as they are
|
||||
taken, and why a document stating a rule must say how the rule is checked.
|
||||
- Research must state evidence without identifying the mesh it observed. The shape of a
|
||||
finding survives anonymisation; the instance does not travel.
|
||||
- **The objection is answered by indexing, not by location** — the claim being that these
|
||||
documents remain searchable beside everything else, one source with many surfaces.
|
||||
**That indexing does not exist.** Checked 2026-08-23, it returns nothing. Until it does, the
|
||||
objection stands unanswered and this repository is the third knowledge store it was argued
|
||||
not to be. Recorded as
|
||||
[`04-ISSUES/006`](../04-ISSUES/006-hq-is-not-indexed-into-the-knowledge-base/00-report.md).
|
||||
|
||||
## References
|
||||
|
||||
- Supersedes the earlier position that documentation lives inside the code repository under a
|
||||
folder there. That position was never recorded separately and has no record of its own.
|
||||
- [`README.md`](../README.md) — the public-repository rule in full.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 20. Design is written in two layers: what is, and what is intended
|
||||
|
||||
## Context
|
||||
|
||||
HQ held only the intended mesh. Every reader had to already know the running system in order
|
||||
to understand what the decisions were about, and a statement about current behaviour had
|
||||
nowhere to live except inside a document describing an intention.
|
||||
|
||||
The consequence was invisible until looked for: an as-is claim inside a to-be document is
|
||||
indistinguishable from the intention around it, so the document silently stops being true as
|
||||
the system moves — and nobody can tell which half went stale.
|
||||
|
||||
The mesh also has a large body of shipped behaviour that nobody would choose again. It is not
|
||||
design in the sense of "what we decided"; it is design in the sense of "what is there", and it
|
||||
is exactly the part a person changing the system most needs.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **One layer, describing the target.** Rejected — the status quo. The running system goes
|
||||
undocumented and the target document accumulates unmarked claims about it.
|
||||
2. **One layer, describing what runs, with intentions only in decision records.** Rejected:
|
||||
a decision record is an argument, not a specification, and a multi-part intention has
|
||||
nowhere coherent to live.
|
||||
3. **Two layers, declared per document, never mixed.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
`03-DESIGN` holds two layers, and every document declares which it is:
|
||||
|
||||
| Layer | Describes | Written from |
|
||||
|---|---|---|
|
||||
| `00-as-is/` | The mesh that exists | The implementation and the operational record |
|
||||
| `01-to-be/` | The mesh being built toward | Decision records |
|
||||
|
||||
An as-is document **records what is, not what should be** — including behaviour nobody would
|
||||
choose again. A layer that keeps only the good decisions is a brochure.
|
||||
|
||||
When a to-be design ships it **does not move**. Its as-is counterpart is written or updated,
|
||||
the to-be document's status becomes `implemented`, and both stand: one describing what runs,
|
||||
the other recording what was intended. Deleting the intention loses the reasoning.
|
||||
|
||||
Where implementation and intention disagree, the as-is document records the implementation and
|
||||
says they disagree.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A reader can tell, from the folder and from one frontmatter field, whether they are reading
|
||||
a description or a plan. That distinction was previously unavailable at any price.
|
||||
- Correcting an as-is document requires evidence from the implementation, not agreement — and
|
||||
needs no decision record, because nothing was decided.
|
||||
- Two documents must be kept current per subsystem instead of one. This is the cost, and it is
|
||||
paid on every ship.
|
||||
- Something that shipped differently from its design becomes a visible divergence rather than
|
||||
a silently wrong document, and may deserve an issue.
|
||||
|
||||
## References
|
||||
|
||||
- [`03-DESIGN/README.md`](../03-DESIGN/README.md) — the layer contract and frontmatter schema.
|
||||
- [`03-DESIGN/00-as-is/`](../03-DESIGN/00-as-is/) — the first eleven as-is documents, written
|
||||
2026-08-23 from the monorepo and the operational memory.
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 21. Every workflow is a playbook, and agents operate through them
|
||||
|
||||
## Context
|
||||
|
||||
HQ stated a knowledge flow — research becomes design — and nowhere stated how anything moves
|
||||
along it. What graduation required, who wrote the decision, what closed an effort, what
|
||||
happened when something shipped: all of it was convention held in one person's head.
|
||||
|
||||
A large share of the work here is done by agents. An unwritten convention is not available to
|
||||
an agent at all, so each one either invents a procedure or asks. Both produce a repository
|
||||
whose shape depends on who last touched it.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Convention, learned by reading existing documents.** Rejected — the status quo. It
|
||||
transmits shape but not rules, and it transmits the mistakes along with the pattern.
|
||||
2. **One long contributing document.** Rejected: it is read once, and the step someone needs
|
||||
is never the step they are reading.
|
||||
3. **A playbook per workflow, each with trigger, steps and outputs, wrapped by a thin skill.**
|
||||
Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
Every workflow is a playbook in [`00-META/process/`](../00-META/process/): trigger, who runs
|
||||
it, steps, outputs. Engineers and agents follow the same playbooks, and **agents must not act
|
||||
outside them**.
|
||||
|
||||
Each playbook is wrapped by a thin skill that defers to it as authoritative and adds only
|
||||
mechanical scaffolding — next free number, frontmatter block, where the file goes. The
|
||||
playbook holds the reasoning; the skill holds the steps. When they disagree, the playbook
|
||||
wins.
|
||||
|
||||
## Consequences
|
||||
|
||||
- An agent arriving with no context can act correctly, because the procedure is retrievable
|
||||
rather than remembered.
|
||||
- The playbooks are themselves reviewable. A bad rule can be found and changed, which is not
|
||||
true of a convention.
|
||||
- Duplication between playbook and skill is real, and is managed by making the skill thin and
|
||||
naming the playbook as authoritative in the skill's first lines. Nothing prevents them
|
||||
drifting; the constraint is that only one carries reasoning.
|
||||
- A workflow with no playbook is a workflow agents will get wrong. Adding one is part of
|
||||
adding the workflow.
|
||||
|
||||
## References
|
||||
|
||||
- [`00-META/process/00-overview.md`](../00-META/process/00-overview.md) — the five playbooks
|
||||
and the flow they implement.
|
||||
- Modelled on the process layer in the sibling HQ repository for the PAPA platform, which
|
||||
arrived at the same shape and the same thin-skill split.
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 22. Status lives in frontmatter; cross-cutting views are generated
|
||||
|
||||
## Context
|
||||
|
||||
Status was carried in prose — a bold line near the top of a document saying what state it was
|
||||
in — and indexes were maintained by hand. The decision-record index had already drifted from
|
||||
the folder it described **after a single addition**, which is about as short a demonstration
|
||||
as the failure mode offers.
|
||||
|
||||
A hand-maintained index is a copy of something the filesystem already knows. It is correct
|
||||
only for as long as everyone remembers it exists, and its being wrong is silent.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Prose status plus hand-maintained indexes.** Rejected — the status quo, already
|
||||
demonstrably broken.
|
||||
2. **A central status file.** Rejected. It centralises the drift rather than removing it: the
|
||||
file and the documents disagree, and the file is the one people read.
|
||||
3. **Machine-readable frontmatter per document; every cross-cutting view generated on
|
||||
demand.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
Every document carries its state in YAML frontmatter — research overviews, design documents,
|
||||
decision records, issue reports — with a schema stated in the section README.
|
||||
|
||||
**There are no central status files.** Every cross-cutting view — a status matrix, the
|
||||
decision-record index, the open-issue list — is generated from frontmatter when asked for, and
|
||||
never written to disk.
|
||||
|
||||
Prose does not restate status. One place, and two is one too many.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A view cannot drift from what it describes, because it does not persist.
|
||||
- Status becomes queryable. Inconsistencies — a closed effort with nothing in `became:`, an
|
||||
`implemented` design with no owning repository — are findable mechanically, and the
|
||||
generator reports them as flags rather than silently rendering around them.
|
||||
- Frontmatter must be valid and paths in it must resolve, which is now something to check.
|
||||
- A reader browsing the repository on a forge sees no index. That is the trade: the index is
|
||||
correct and absent rather than present and wrong.
|
||||
|
||||
## References
|
||||
|
||||
- [`.claude/skills/hal-status/SKILL.md`](../.claude/skills/hal-status/SKILL.md) — the
|
||||
generator, including the inconsistencies it flags.
|
||||
- [`02-DECISIONS/README.md`](README.md) — the hand-written index that drifted, and its removal.
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 23. Issues have a front door, separate from the operational memory
|
||||
|
||||
## Context
|
||||
|
||||
Findings that were nobody's task accumulated in a table inside the decision ledger — a package
|
||||
install reporting success while installing nothing, a manifest key read by no code, an
|
||||
end-to-end harness dead for months. They were measured, true, and unowned: a table row cannot
|
||||
be assigned, diagnosed or closed.
|
||||
|
||||
The mesh already has an operational memory holding roughly a hundred and thirty entries,
|
||||
indexed on symptoms. The obvious move — put these there — is wrong, and the reason is the
|
||||
distinction worth recording.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Leave them in the ledger.** Rejected: a ledger records decisions taken, and these are
|
||||
the opposite — questions nobody has answered.
|
||||
2. **Put them in the operational memory.** Rejected. That store answers *how do I fix this
|
||||
occurrence*; these are *why does the design allow this at all*. Filing them there makes
|
||||
them findable by symptom and unfindable as open questions, and nothing there has a state
|
||||
that can be closed.
|
||||
3. **A numbered issue folder in HQ, deliberately narrow.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
`04-ISSUES` is the front door for something wrong at the level of **design or governance**:
|
||||
a rule enforced by nothing, a stated invariant that is false, a failure the design permits to
|
||||
be silent, or a symptom whose owner cannot be found without the whole mesh in view.
|
||||
|
||||
One numbered folder per issue: the report with the symptom as observed and the evidence, and
|
||||
a diagnosis document carrying the trail, dated, including what was ruled out.
|
||||
|
||||
**This is not a second copy of the operational memory.** An issue here is a question HQ must
|
||||
*answer*; an entry there is an incident someone must *clear*. An issue whose answer is a
|
||||
general lesson belongs in both — and the operational memory is searched first, because if the
|
||||
answer is already there this was never an issue.
|
||||
|
||||
## Consequences
|
||||
|
||||
- A finding gets a number, a state and an owner, and closing it is a visible act.
|
||||
- The symptom-to-component trail accumulates in a place where the whole mesh is visible, which
|
||||
is where cross-component diagnosis has to happen.
|
||||
- The boundary needs judgement on every report, and will sometimes be got wrong. Filing too
|
||||
narrowly loses a finding; filing too widely rebuilds the operational memory here, which is
|
||||
the outcome HQ's separation was argued against
|
||||
([ADR 0019](0019-hq-is-its-own-repository.md)).
|
||||
- Six issues opened on creation, all previously unowned observations.
|
||||
|
||||
## References
|
||||
|
||||
- [`04-ISSUES/README.md`](../04-ISSUES/README.md) — the boundary table and the frontmatter
|
||||
schema.
|
||||
- [`00-META/process/03-issues.md`](../00-META/process/03-issues.md) — the playbook.
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 24. The folder numbering is the flow, and decision records run oldest first
|
||||
|
||||
## Context
|
||||
|
||||
Two orderings were wrong in ways that only show up when someone new reads the repository.
|
||||
|
||||
**The folders.** Decisions lived in an unnumbered folder that sorted after the numbered ones,
|
||||
so the repository's most load-bearing content read as an annex.
|
||||
|
||||
The sibling HQ repository for the PAPA platform had already solved this and solved it
|
||||
crookedly: its design folder existed from its initial commit, and when its decision folder was
|
||||
finally promoted it took the **next free number** rather than its place in the sequence. That
|
||||
repository now reads `01 research → 03 decision → 02 design`. A decision precedes the design
|
||||
it authorises and is numbered after it. By the time this was visible, the design folder was too
|
||||
settled to renumber.
|
||||
|
||||
**The records.** Fourteen decisions had been taken in implementation and never written down —
|
||||
the broker, the module abstraction, the mesh database, the artifact, the three silos and the
|
||||
rest. Meanwhile two records existed, holding numbers 0001 and 0002, for decisions taken last.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Match the sibling repository exactly**, inheriting its ordering. Rejected: structural
|
||||
parity is worth something, but not the cost of copying a scar the other repository would
|
||||
not choose again.
|
||||
2. **Leave the folder unnumbered.** Rejected — the annex problem, and it leaves an unexplained
|
||||
gap for anyone arriving from the sibling repository.
|
||||
3. **Number by position in the flow, and renumber the records chronologically.** Chosen, on
|
||||
the grounds that this repository was four commits old and nothing outside it cited a
|
||||
number. That is the only window in which either renumbering is free.
|
||||
|
||||
## Decision
|
||||
|
||||
**The numbering is the flow.** Research produces a decision; the decision authorises a design.
|
||||
So `01-RESEARCH`, `02-DECISIONS`, `03-DESIGN`, `04-ISSUES`. Following the folder numbers walks
|
||||
the process in the order it happens.
|
||||
|
||||
**Decision records are a chronological ledger.** They run oldest first. The fourteen decisions
|
||||
already taken in implementation were back-filled as records 0001–0014, each dated from the
|
||||
history, each carrying `reconstructed: true` and saying so in its first lines, and each citing
|
||||
the commit, pull request or knowledge-base entry it was recovered from. The two existing
|
||||
records moved to 0015 and 0016.
|
||||
|
||||
A reconstructed record is not a transcript. Where the deliberation is not recoverable it states
|
||||
what the alternatives were and why the chosen one won on the evidence available — not a
|
||||
discussion that did not happen. Where a date is not establishable it says so.
|
||||
|
||||
The foundational folder is `00-META`, matching the sibling repository.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The repository reads in process order, and the gap at `03` that a reader coming from the
|
||||
sibling repository would notice is explained by this record.
|
||||
- The design documents can cite reasoning instead of asserting rules, because the reasoning now
|
||||
exists.
|
||||
- Structural divergence from the sibling repository, deliberately, in exactly one place. It is
|
||||
recorded here so that the difference reads as a choice rather than an accident.
|
||||
- **Record numbers are now stable and renumbering is over.** This decision spends the one
|
||||
window that existed; a future record takes the next free number regardless of its date.
|
||||
- Reconstructed records carry a standing risk: they are the most confident-sounding documents
|
||||
in the repository and the least directly witnessed. The `reconstructed` flag exists so that
|
||||
is never invisible.
|
||||
|
||||
## References
|
||||
|
||||
- The sibling repository's restructure of 2026-07-13 moved its decision folder in a single
|
||||
commit of twelve renames with no content change, alongside the same status-into-frontmatter
|
||||
and playbook changes made here.
|
||||
- [`02-DECISIONS/README.md`](README.md) — the format, and the note on reconstructed records.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 25. HQ is the source of the mesh constitution
|
||||
|
||||
## Context
|
||||
|
||||
[ADR 0009](0009-the-mesh-is-governed-by-a-constitution.md) established a canonical rule set,
|
||||
injected into every eligible design session and checked before output is accepted. It lives in
|
||||
the knowledge base, where the orchestrator reads it.
|
||||
|
||||
HQ separately carried a document stating overlapping rules with the reasoning that earned each
|
||||
one. Two texts, one enforced and one not.
|
||||
|
||||
That arrangement has a predictable outcome and it is not a tie. The enforced copy wins by
|
||||
default, because it is the one that blocks work. The reasoned copy quietly stops being true,
|
||||
and the rules survive without the incidents that justify them — at which point a rule reads as
|
||||
arbitrary, and an arbitrary rule is the kind people route around.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **The knowledge-base page is the source; HQ points at it.** Rejected, though it is the
|
||||
honest description of what was already happening. It leaves the reasoning downstream of the
|
||||
rule, and the reasoning is the part that makes a rule survive a challenge.
|
||||
2. **Accept the overlap and let both stand.** Rejected: two authorities is no authority, and
|
||||
the drift is silent.
|
||||
3. **HQ is the source; the governed page is derived and published from it.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
[`00-META/how-we-build.md`](../00-META/how-we-build.md) is the source. The governed page the
|
||||
mesh injects is **derived** from it — the rules without the reasoning — and is never edited
|
||||
directly.
|
||||
|
||||
Publishing is a playbook step, not a manual act, and it ends with **reading the page back and
|
||||
verifying the change is present**. A publish that reported success and did nothing is exactly
|
||||
the failure class this mesh keeps producing
|
||||
([ADR 0008](0008-a-failed-step-fails-the-job.md)).
|
||||
|
||||
Section numbering is stable, because the orchestrator and the review fragments cite sections by
|
||||
number.
|
||||
|
||||
## Consequences
|
||||
|
||||
- One source, many surfaces — the same argument HQ's separation already rests on
|
||||
([ADR 0019](0019-hq-is-its-own-repository.md)), applied to the rules themselves.
|
||||
- Each rule keeps the incident that earned it, in a place that is reviewed as a diff.
|
||||
- An edit to the derived page survives until the next sync and then vanishes. The playbook says
|
||||
so, and nothing mechanically prevents it.
|
||||
- **The sync is manual and is the weak point.** An unsynced rule is a rule the mesh does not
|
||||
enforce, whatever the source says — so the playbook requires the failure to be stated rather
|
||||
than passed over. This is the same class of gap as
|
||||
[`04-ISSUES/006`](../04-ISSUES/006-hq-is-not-indexed-into-the-knowledge-base/00-report.md),
|
||||
and it is worth watching for the same reason.
|
||||
- The document grew from four rules to seven sections, because it now has to carry everything
|
||||
the mesh enforces rather than only what someone thought to write down.
|
||||
|
||||
## References
|
||||
|
||||
- [`00-META/process/05-constitution-sync.md`](../00-META/process/05-constitution-sync.md) —
|
||||
the sync, including the read-back.
|
||||
- [ADR 0009](0009-the-mesh-is-governed-by-a-constitution.md) — the governed page and why it
|
||||
exists.
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
status: accepted
|
||||
date: 2026-08-23
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 26. Every decision is a record; there is no ledger
|
||||
|
||||
## Context
|
||||
|
||||
HQ carried a decision ledger at its root: a chronological table of forty-one numbered
|
||||
decisions, each with who decided and a pointer to where the reasoning lived. It was created
|
||||
deliberately, to make decisions findable and to give a home to decisions too small to warrant
|
||||
a document.
|
||||
|
||||
By the time the decision records were back-filled
|
||||
([ADR 0024](0024-the-numbering-is-the-flow.md)) the ledger had become three things at once,
|
||||
and only one of them was still needed.
|
||||
|
||||
Classified, its forty-one entries were: ten restating a record, eleven restating design
|
||||
documents, fifteen describing how this repository works — with the reasoning in a README rather
|
||||
than anywhere citable — three small rules with no home at all, and two superseded stubs.
|
||||
|
||||
So the ledger was mostly a copy. Worse, it was a **hand-maintained index**, which
|
||||
[ADR 0022](0022-status-lives-in-frontmatter.md) had just finished rejecting for the
|
||||
decision-record index on the grounds that it had drifted after a single addition. Keeping one
|
||||
copy of that pattern while removing another is not a position.
|
||||
|
||||
It had also produced a naming collision that a directory listing makes plain: `DECISIONS.md`
|
||||
beside `02-DECISIONS/`, holding different things.
|
||||
|
||||
## Considered options
|
||||
|
||||
1. **Keep the ledger.** Rejected. It duplicates the records, restates status, and is the exact
|
||||
hand-maintained index this repository decided against elsewhere.
|
||||
2. **Keep it, renamed, for small decisions only.** Rejected, and this is the option worth
|
||||
arguing with — it is genuinely useful to record a decision without writing a document. But a
|
||||
decision small enough to be one table row is almost always a **rule** rather than a
|
||||
decision, and a rule belongs in [`how-we-build.md`](../00-META/how-we-build.md) where it is
|
||||
enforced and where its reasoning is kept. That is where the three orphans went.
|
||||
3. **Every decision is a record; nothing else.** Chosen. This is how the sibling HQ repository
|
||||
for the PAPA platform works, and it has no ledger of any kind.
|
||||
|
||||
## Decision
|
||||
|
||||
**If a decision is worth recording, it is worth a record. If it is not worth a record, it is
|
||||
not recorded.**
|
||||
|
||||
`02-DECISIONS` holds every decision. There is no ledger, no index file, and no central status
|
||||
of any kind. The chronological view — decisions in the order they were taken — is *generated*
|
||||
from record frontmatter, which is what the ledger was actually for.
|
||||
|
||||
Content that was only in the ledger was rehomed rather than dropped:
|
||||
|
||||
| Was | Went to |
|
||||
|---|---|
|
||||
| Decisions about how this repository works | Records [0019](0019-hq-is-its-own-repository.md)–[0025](0025-hq-is-the-source-of-the-constitution.md) |
|
||||
| Small rules with no record | [`how-we-build.md`](../00-META/how-we-build.md) — the package rule, and two already there |
|
||||
| Lab decisions not stated in the design | [`03-DESIGN/01-to-be/01-end-to-end-testing.md`](../03-DESIGN/01-to-be/01-end-to-end-testing.md) |
|
||||
| "Deliberately not decided" | The research effort and design document each question belongs to |
|
||||
| Unowned observations | [`04-ISSUES`](../04-ISSUES/) ([ADR 0023](0023-issues-have-a-front-door.md)) |
|
||||
|
||||
## Consequences
|
||||
|
||||
- One place to look, and nothing to keep in sync. The collision between the ledger and the
|
||||
record folder is gone.
|
||||
- Structural parity with the sibling repository on decisions, which
|
||||
[ADR 0024](0024-the-numbering-is-the-flow.md) deliberately broke on folder numbering. The
|
||||
divergence is now exactly one thing, and it is the one thing that was argued for.
|
||||
- **Writing a record is now the only way to record a decision, and a record is more work than
|
||||
a table row.** The real risk is that a small decision goes unrecorded because nobody wanted
|
||||
to write a document. The mitigation is that a small decision is usually a rule, and
|
||||
`how-we-build.md` takes rules cheaply — but this is a cost, not a solved problem, and it is
|
||||
the thing to watch.
|
||||
- The chronological view now depends on the generator existing and being run. It did not
|
||||
before.
|
||||
- Two superseded ledger stubs had no record of their own. The position that documentation
|
||||
lives inside the code repository is now recorded only as superseded context in
|
||||
[ADR 0019](0019-hq-is-its-own-repository.md); the system-container position is explained in
|
||||
[ADR 0016](0016-a-lab-node-is-a-virtual-machine.md). Neither is lost.
|
||||
|
||||
## References
|
||||
|
||||
- The sibling PAPA HQ repository: root holds only agent instructions and a README; every
|
||||
decision is a numbered record, and its graduation playbook has no path for an unrecorded
|
||||
decision.
|
||||
- [ADR 0022](0022-status-lives-in-frontmatter.md) — the hand-maintained-index argument this
|
||||
applies consistently.
|
||||
@@ -11,7 +11,14 @@ One file per decision, numbered, never deleted. A superseded record has its `sta
|
||||
and gains a pointer to what replaced it — **its text is never edited**. The reasoning that was
|
||||
rejected is the expensive half to rediscover.
|
||||
|
||||
The records are a **ledger**: they run in the order the decisions were taken, oldest first.
|
||||
The records run in the order the decisions were taken, oldest first.
|
||||
|
||||
**Every decision is a record.** There is no ledger and no index file — if a decision is worth
|
||||
recording it is worth a record, and if it is not worth a record it is not recorded
|
||||
([ADR 0026](0026-every-decision-is-a-record.md)). A "decision" small enough to be one line is
|
||||
almost always a **rule**, and a rule belongs in
|
||||
[`00-META/how-we-build.md`](../00-META/how-we-build.md), where it is enforced and keeps the
|
||||
incident that earned it.
|
||||
|
||||
## Frontmatter
|
||||
|
||||
|
||||
Reference in New Issue
Block a user