Base layer: the mesh as it is, under the mesh as it should be
HQ held only the to-be. Every reader had to already know the system the decisions were about, and an as-is claim had nowhere to live except inside an intention. Adds 02-DESIGN/00-as-is — eleven documents written from the implementation and the operational record, not from intent, including the parts nobody would choose again. The two existing designs move under 01-to-be. Layers are declared in frontmatter and never mix: a design that ships does not move, its as-is counterpart is written, and both stand. Back-fills adr/0001-0014 for decisions taken in implementation and never recorded — the broker, the module abstraction, the mesh database, managed files, provisioning, migrations, the workspace removal, failing loudly, the constitution, application placement, linking, the employee model, the artifact, the three silos. Each marked reconstructed, dated from the history, and citing the evidence it was recovered from. The two existing records renumber to 0015 and 0016 so the ledger runs oldest first; 0017 extends 0015 to modules outside the core, principle only — the domain list is deliberately not invented here. how-we-build.md becomes the source of the mesh constitution, with a sync playbook, so the enforced copy stops being the only one that is true. Process becomes explicit: five playbooks, eight thin skills that defer to them, a repository map, and AGENTS.md with CLAUDE.md as its include. The five Observations become 04-ISSUES 001-005 where they can be owned and closed. 006 is new and uncomfortable: HQ is not indexed into the knowledge base. That claim is what decision 27 rests on, it was never checked, and the README now says so instead of repeating it. Also corrects the ADR index into something generated, the "02-DESIGN is empty" claim, the VISION.md pointer that did not survive the repo split, and a note asserting the symlink rule was contradicted — it was a misreading; the rule forbids hand-made links, the installer links by design.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Process — overview
|
||||
|
||||
How work moves through hal-hq, and who may do what. Every other document in this folder is a
|
||||
playbook: trigger, who runs it, steps, outputs. Engineers and agents follow the same
|
||||
playbooks; agents must not act outside them.
|
||||
|
||||
## The audiences
|
||||
|
||||
| Audience | Contract |
|
||||
|---|---|
|
||||
| **Engineers** | Read and write everything. hal-hq is the single source of truth for mission, research, design, decisions and issue diagnosis. |
|
||||
| **Agents** | The same rights as engineers, exercised through these playbooks. |
|
||||
| **Anyone else** | This repository is public and written for them, but it is not a support channel. Nothing here identifies the mesh it describes. |
|
||||
|
||||
## The knowledge flow
|
||||
|
||||
```
|
||||
idea ──► 01-RESEARCH ──► decision (adr/) ──► 02-DESIGN/01-to-be ──► built (code repo)
|
||||
│ │ │
|
||||
│ │ └─► 02-DESIGN/00-as-is once shipped
|
||||
│ └────► abandoned (recorded, kept)
|
||||
└─(small/obvious, decision recorded in DECISIONS.md)────► 02-DESIGN directly
|
||||
|
||||
symptom ──► 04-ISSUES ──► diagnosis ──► code-repo fix and/or design amendment
|
||||
|
||||
how-we-build.md ──► constitution sync ──► knowledge base ──► injected into design meetings
|
||||
```
|
||||
|
||||
## The two design layers
|
||||
|
||||
`02-DESIGN` holds two layers that are never mixed:
|
||||
|
||||
| Layer | What it is | Changes when |
|
||||
|---|---|---|
|
||||
| `00-as-is/` | The mesh that exists today. Describes shipped behaviour, including behaviour nobody would choose again. | Something ships, or an as-is claim is found to be wrong. |
|
||||
| `01-to-be/` | The mesh being built toward. Every statement traceable to a record in `adr/`. | A decision is taken or amended. |
|
||||
|
||||
A to-be document that ships does not move. Its as-is counterpart is written or updated, the
|
||||
to-be document's frontmatter goes to `implemented`, and both stand — one describing what runs,
|
||||
the other recording what was intended. Deleting the intention loses the reasoning, which is
|
||||
the expensive half.
|
||||
|
||||
## The playbooks
|
||||
|
||||
| # | Playbook | Trigger |
|
||||
|---|---|---|
|
||||
| [01](01-research.md) | Research | An idea worth investigating before committing to design |
|
||||
| [02](02-graduation.md) | Graduation & design change | Research concludes, or a design must change |
|
||||
| [03](03-issues.md) | Issues | Something is wrong — often with the owner unknown |
|
||||
| [04](04-build-handoff.md) | Build handoff | A design is ready to be built |
|
||||
| [05](05-constitution-sync.md) | Constitution sync | `how-we-build.md` changed a rule the mesh enforces |
|
||||
|
||||
## Status lives in frontmatter
|
||||
|
||||
Research overviews, design docs, issue reports and decision records each carry their status as
|
||||
YAML frontmatter (schemas in the section READMEs and playbooks). There are **no central status
|
||||
files**. `DECISIONS.md` is a ledger of decisions as they were taken — an index and a home for
|
||||
decisions too small to warrant a record — and is explicitly *not* a status board. Cross-cutting
|
||||
views are generated on demand by the `hal-status` skill and never written to disk.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Playbook 01 — Research
|
||||
|
||||
**Trigger.** An idea, technology or approach worth investigating before it is committed to
|
||||
design. Also: an as-is document that raises a question nobody can answer.
|
||||
|
||||
**Who runs it.** Anyone.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Take the next free number: highest `01-RESEARCH/NNN-*` plus one, zero-padded to three
|
||||
digits. Never skip or reuse a number.
|
||||
2. Create `01-RESEARCH/NNN-descriptive-name/` and a `status.md` in it carrying:
|
||||
|
||||
```yaml
|
||||
---
|
||||
status: active
|
||||
initiated: YYYY-MM-DD
|
||||
touches: [] # areas, subsystems or as-is design docs the effort bears on
|
||||
---
|
||||
```
|
||||
|
||||
Then a short prose summary: **what** is being investigated, **why**, and **what it
|
||||
touches**.
|
||||
3. Do the research in further documents in the same folder — notes, option analyses, evidence,
|
||||
draft designs. Anything goes. Keep the summary in `status.md` current as the effort changes
|
||||
shape.
|
||||
|
||||
## What makes research worth reading
|
||||
|
||||
State evidence, not assertion. *"Zero of 124 modules declare `brain` as a dependency"*
|
||||
outranks *"the dependency rule is not followed"*. An effort that measured nothing has not
|
||||
finished.
|
||||
|
||||
Research describes real observations but never identifies the mesh it observed. The shape of a
|
||||
finding survives anonymisation intact — *a node publicly named but behind a household NAT*
|
||||
carries the whole lesson without naming anything.
|
||||
|
||||
## Do not
|
||||
|
||||
- Do not put status in prose. It lives in `status.md`'s frontmatter, and the prose must not restate it.
|
||||
- Do not set `became:` while the effort is open — playbook 02 sets it at closure.
|
||||
- Do not write into `02-DESIGN` from an open effort.
|
||||
|
||||
## Closing
|
||||
|
||||
An effort never just stops. It closes through playbook [02](02-graduation.md) as `graduated`
|
||||
or `abandoned`, always with `became:` pointing at what it turned into. Nothing is deleted —
|
||||
what was rejected, and why, is the more expensive half to rediscover.
|
||||
@@ -0,0 +1,60 @@
|
||||
# Playbook 02 — Graduation and design change
|
||||
|
||||
**Trigger.** A research effort concludes, or an existing design must change.
|
||||
|
||||
**Who runs it.** Anyone, with the decision recorded before the design moves.
|
||||
|
||||
## Graduating research
|
||||
|
||||
1. **Check it against GENESIS.** An effort graduates only if its conclusion is traceable to
|
||||
[`mission.md`](../mission.md), [`context.md`](../context.md) and
|
||||
[`effect.md`](../effect.md). If it conflicts, either the effort is wrong or GENESIS is —
|
||||
say which, in writing, before proceeding.
|
||||
2. **Record the decision.** Write a record in [`adr/`](../../adr/) taking the next free
|
||||
number. Format and rules are in [`adr/README.md`](../../adr/README.md). State evidence,
|
||||
not assertion, and record the options that were rejected — that is the half worth keeping.
|
||||
3. **Write the design.** Create the document under `02-DESIGN/01-to-be/` with frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
layer: to-be
|
||||
status: designed
|
||||
code: [] # owning code repo(s); set at build handoff, empty before
|
||||
updated: YYYY-MM-DD
|
||||
decisions: [adr/NNNN-....md]
|
||||
---
|
||||
```
|
||||
|
||||
4. **Close the effort.** Set the effort's `status.md` frontmatter to `status: graduated` and
|
||||
`became:` pointing at the design document and the decision record.
|
||||
5. **Add a ledger line.** Append the decision to [`DECISIONS.md`](../../DECISIONS.md) under
|
||||
today's heading, pointing at the record.
|
||||
|
||||
## Amending an existing design
|
||||
|
||||
A design changes only through a decision.
|
||||
|
||||
1. Write the decision record. If it reverses an earlier one, the earlier record's `status:`
|
||||
becomes `superseded-by: adr/NNNN-....md` — **its text is never edited**.
|
||||
2. Edit the to-be design document and set `updated:` to today.
|
||||
3. If the amendment came from an issue, set that issue's `amended-design:` to the document
|
||||
path.
|
||||
4. Add the ledger line.
|
||||
|
||||
## When something ships
|
||||
|
||||
Implementation state is a third axis, independent of both design and decision.
|
||||
|
||||
1. Write or update the matching document under `02-DESIGN/00-as-is/` so it describes what now
|
||||
runs — including anything that shipped differently from the intent. A design that shipped
|
||||
bent is an as-is fact, not a design amendment.
|
||||
2. Set the to-be document's `status: implemented` and its `code:` to the owning repositories
|
||||
from [`repos.md`](../repos.md).
|
||||
3. `status: implemented` must be defensible from the owning repository's main branch, not from
|
||||
intent. If it cannot be checked, it is `in-progress`.
|
||||
|
||||
## Do not
|
||||
|
||||
- Do not move a to-be document into `00-as-is/`. Write the as-is document; both stand.
|
||||
- Do not edit an as-is document to describe an intention. That is what the to-be layer is for.
|
||||
- Do not change a decision record's meaning. Supersede it.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Playbook 03 — Issues
|
||||
|
||||
**Trigger.** Something is wrong at the level of the mesh's design or governance — a rule that
|
||||
turns out to be unenforced, a stated behaviour that does not happen, a silent failure the
|
||||
design permits.
|
||||
|
||||
**Who runs it.** Anyone may open an issue. No localisation is required to report one.
|
||||
|
||||
## What belongs here, and what does not
|
||||
|
||||
| Belongs in `04-ISSUES` | Belongs in the knowledge base |
|
||||
|---|---|
|
||||
| The design permits a failure to be silent | How to fix one occurrence of it |
|
||||
| A documented rule is enforced by nothing | A command that works around it |
|
||||
| A stated invariant is false in practice | A node-specific quirk |
|
||||
| The owning component is unknown and finding it needs the whole mesh in view | Symptom → fix, once the answer is known |
|
||||
|
||||
The knowledge base already holds the operational record and is indexed on symptoms. This
|
||||
folder is not a second copy of it. An issue here is a question HQ must **answer**, not an
|
||||
incident someone must **clear**.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Take the next free number. Create `04-ISSUES/NNN-short-name/00-report.md`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
status: open
|
||||
opened: YYYY-MM-DD
|
||||
located-in: [] # owning repo(s)/module(s), filled by diagnosis
|
||||
fixed-by: # PR or commit reference, filled at resolution
|
||||
amended-design: # design doc path, when the root cause was a design gap
|
||||
---
|
||||
```
|
||||
|
||||
Then the symptom **as observed**, in plain terms, with the evidence that it happened.
|
||||
2. Investigate in `01-diagnosis.md` in the same folder — the trail, dated, including what was
|
||||
ruled out. Move `status:` to `diagnosing`, then `located` once the owner is known.
|
||||
3. Resolve. Set `status: resolved`, fill `fixed-by:`, and if the root cause was a design gap,
|
||||
run playbook [02](02-graduation.md) and fill `amended-design:`.
|
||||
|
||||
## Rules
|
||||
|
||||
- Closed issues are never deleted — they are the mesh's symptom-to-component memory.
|
||||
- An issue whose answer is a general lesson should also be written to the knowledge base, so
|
||||
the next person searching a symptom finds it. Both, not either.
|
||||
- `status: wontfix` is legitimate and requires a sentence saying why.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Playbook 04 — Build handoff
|
||||
|
||||
**Trigger.** A to-be design is settled and work is about to start in a code repository.
|
||||
|
||||
**Who runs it.** Whoever starts the build.
|
||||
|
||||
## Steps
|
||||
|
||||
1. **Confirm the design is settled.** Its frontmatter reads `status: designed`, and every
|
||||
claim in it traces to a record in [`adr/`](../../adr/). An open question in the text is a
|
||||
reason to run playbook [01](01-research.md), not to start building around it.
|
||||
2. **Name the owner.** Set `code:` in the design's frontmatter to the repositories from
|
||||
[`repos.md`](../repos.md). If the repository does not exist yet, add it to `repos.md` in
|
||||
the same change.
|
||||
3. **Check the as-is.** Read the matching `02-DESIGN/00-as-is/` document. What is being
|
||||
replaced is stated there; if it is not, write it before changing it. Building against an
|
||||
undocumented as-is is how a shipped behaviour gets lost.
|
||||
4. **Flip the status.** `status: in-progress`, `updated:` today.
|
||||
5. **Build in the code repository.** hal-hq is not a code repository and never carries
|
||||
implementation.
|
||||
6. **On completion**, run the "when something ships" section of playbook
|
||||
[02](02-graduation.md).
|
||||
|
||||
## Rules
|
||||
|
||||
- Every merge is a human checkpoint, without exception.
|
||||
- Never open a pull request unprompted. A permissions list saying it is allowed is not a
|
||||
request.
|
||||
- Work in an isolated worktree, never a shared checkout. A failed `cd` in a shared checkout
|
||||
commits to the wrong branch, and the error scrolls past.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Playbook 05 — Constitution sync
|
||||
|
||||
**Trigger.** [`how-we-build.md`](../how-we-build.md) changed a rule that the mesh enforces at
|
||||
runtime.
|
||||
|
||||
**Who runs it.** Whoever made the change.
|
||||
|
||||
## Why this playbook exists
|
||||
|
||||
The mesh injects a constitution into every eligible design meeting; agents check their output
|
||||
against it and a constitution-check phase can block a meeting. That text is **derived**.
|
||||
`how-we-build.md` is the source.
|
||||
|
||||
Two texts stating the same rules will drift, and the enforced copy winning by default means
|
||||
the reasoned copy quietly stops being true. This playbook is the mechanism that stops that —
|
||||
and, per the repository's own rule, it is how the rule "HQ is the source" is checked.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Edit [`how-we-build.md`](../how-we-build.md). Each rule keeps the reasoning that earned it;
|
||||
the derived page carries the rule alone.
|
||||
2. Record the change as a decision — a rule the mesh enforces is architecturally significant.
|
||||
Playbook [02](02-graduation.md).
|
||||
3. Publish the derived page to the knowledge base under the constitution slug, replacing its
|
||||
body. Keep the section numbering stable: the meeting orchestrator and the review fragments
|
||||
cite sections by number.
|
||||
4. Verify the derived page reads back with the change present. A publish that reported success
|
||||
and did nothing is exactly the failure class this repository exists to name.
|
||||
5. Note the sync in the ledger line for the decision.
|
||||
|
||||
## Rules
|
||||
|
||||
- **Never edit the derived page directly.** An edit there survives until the next sync and
|
||||
then vanishes, taking its reasoning with it.
|
||||
- The derived page may only be **tightened** by per-team override pages, never relaxed.
|
||||
- If the sync cannot be performed, say so in the ledger line. An unsynced rule is a rule the
|
||||
mesh does not enforce, whatever `how-we-build.md` says.
|
||||
Reference in New Issue
Block a user