Design 55: follow ADR 0592's sixth version and the review by aspect: whole-or-refused writes, caps, the move's window and rollback, the delivery order, the judge's judged event, events with what they carry, a test per failure path, and a section Reviewed by aspect
The glossary gains opened and drafted, so a draft's first step is never called drafted.
This commit is contained in:
@@ -995,6 +995,11 @@ Not a domain of the mesh but of the way it is built, listed because its words me
|
||||
**author**, until it is submitted as a version or dropped; another session may **take it over** with a reason, as a
|
||||
proposal (ADR 0592). Not a **drafted** clause, which the import's judgement wrote from prose (see
|
||||
[Homonyms](#homonyms)).
|
||||
- **opened** — of a draft: begun by `open` on a reserved or existing record, with its author, and said by the event
|
||||
`opened` (ADR 0592). Not **drafted**.
|
||||
- **drafted** — of a clause: written by the import's judgement from a prose Decision section, and never served as in
|
||||
force until a second judgement confirms it; the event `drafted` says so (ADR 0290, ADR 0321). Never said of a
|
||||
draft, which is **opened**.
|
||||
- **form-only version** — of a record: a version that changes only its sections' titles and the targets of its links,
|
||||
proved by a check rather than judged, and marked `form`; never a change of meaning (ADR 0592).
|
||||
- **search index** — the knowledge base's full-text index of the records, built in the module's memory from the bus
|
||||
|
||||
@@ -55,7 +55,9 @@ and the knowledge base works out each design's state (ADR 0423, ADR 0424).
|
||||
├ on the bus, written by it alone (§ 2)
|
||||
│ state heads one key per record: its fields, clauses, links, sections as title and digest
|
||||
│ state drafts one key per record being written: its author and its sections as title and digest
|
||||
│ state findings the whole-set findings standing now, and when each was told
|
||||
│ state asked one key per part asked of the judge and not yet answered: ticket, node, when
|
||||
│ state names per digest: how many versions and drafts name it, and since when none has
|
||||
│ state findings the whole-set findings standing now, and the told marks (told.<topic>)
|
||||
│ stream versions one message per version: who, when, why, its mark, the head as it stood
|
||||
│ stream reviews one message per part reviewed: the digest judged, the verdict, the findings
|
||||
│ objects sections every section's body, once, named by its sha256 digest
|
||||
@@ -65,14 +67,17 @@ and the knowledge base works out each design's state (ADR 0423, ADR 0424).
|
||||
│ withdraw, retract, import, return
|
||||
│ served by the control-node's tool runner
|
||||
├ events reserved, opened, written, removed, ordered, submitted, dropped, taken-over, proposed,
|
||||
│ reviewed, accepted, changed, imported, drafted, confirmed, returned, moved, formed
|
||||
│ part-reviewed, reviewed, accepted, changed, swept, moved, checked, formed,
|
||||
│ imported, drafted, confirmed, returned
|
||||
├ consumes the router's warrants: the operator's Approve for a record that needs it (§ 5)
|
||||
├ consumes claude-code's judged: the judge's answer to a part (§ 5)
|
||||
└ consumes the delivery module's delivery-done announcement: a design's state (§ 9)
|
||||
|
||||
mesh-issues (control-node) the counters for decision and research numbers (§ 6);
|
||||
the issues' design links, read for a design's state (§ 9)
|
||||
mesh-delivery (its seat) announces each delivery done, on the bus (§ 9)
|
||||
claude-code (same node) claude_code_judge: review a section or a head (§ 5), draft and confirm clauses (§ 7)
|
||||
claude-code (same node) claude_code_judge: review a section or a head (§ 5), draft and confirm clauses (§ 7);
|
||||
emits judged with the answer of each ticket (§ 5, a dependency of the fifth slice)
|
||||
records (any node) records_read at a commit: the import's source (§ 8)
|
||||
messenger (control-node) the router: the operator's ask and its warrant
|
||||
|
||||
@@ -84,35 +89,67 @@ The module is written in Go against the SDK. It holds no checkout of this reposi
|
||||
the records module, as the issue tracker's import does. Until the move of § 8.1, its records are in a database in
|
||||
the store; from the move on, it requires no database (ADR 0592 §1, changing ADR 0290 §7).
|
||||
|
||||
**A write is whole or refused** (ADR 0592 §9). Every change to `heads`, `drafts`, `asked`, `names` and `findings` is a
|
||||
compare-and-set on the key's revision, retried at most three times and then refused with the reason. `submit`
|
||||
writes the message on `versions` first, then the head against its revision, then the event; a failed step refuses
|
||||
the call. At start the module rebuilds any head behind its last version. A reservation is a head created only if
|
||||
the key is absent, so two sessions reserving at once get two numbers or one refusal.
|
||||
|
||||
**The search index** is a full-text index in the module's own memory, written with the pure Go library bleve. At
|
||||
start the module reads every head and the bodies of every current version into it, and says it is not ready until it
|
||||
holds as many records as `heads`; then it keeps the index current by watching `heads`. `ask` and `holds` answer from
|
||||
it, ranked by title, clauses and sections as before. Nothing but the module writes it, and nothing outside it reads it.
|
||||
start the module reads every head and the bodies of every current version into it, then keeps it current by watching
|
||||
`heads`, noting the last revision of `heads` it took in. `ask` and `holds` answer from it, ranked by title, clauses
|
||||
and sections as before, and refuse with "index not built" while it is built; `get`, `list` and `propose` answer from
|
||||
`heads` at once (ADR 0592 §10). The integration test measures the start; the estimate is 20 to 40 seconds and about
|
||||
100 MB of memory for today's 736 records. Nothing but the module writes it, and nothing outside it reads it.
|
||||
|
||||
### 1.1 Its tools, health and events
|
||||
|
||||
Every piece of state has a tool that reads it, and every act the module does by itself can be done by hand
|
||||
(ADR 0592 §20):
|
||||
(ADR 0592 §26):
|
||||
|
||||
| Tool | Reads or does |
|
||||
|---|---|
|
||||
| read a head | one key of `heads`, whole |
|
||||
| read a version | one message of `versions`, with its sections' titles and digests |
|
||||
| read a section | one object of `sections`, by its digest |
|
||||
| read a draft | one key of `drafts`, with who holds it and since when |
|
||||
| read a review | the part reviews of one version, from `reviews` |
|
||||
| read a version | one message of `versions`, with its sections' titles, digests and authors |
|
||||
| read a section | one object of `sections`, by its digest, checked against it |
|
||||
| read a draft | one key of `drafts`, with its author and since when |
|
||||
| read a review | the part verdicts of one version, from `reviews` |
|
||||
| in-flight parts | the keys of `asked`: each part waiting on the judge, its ticket and since when; ask one again |
|
||||
| told marks | the `told.<topic>` keys; clear one, so it is told again |
|
||||
| fill | each bucket's and stream's size and count against its cap |
|
||||
| rebuild the index | the search index, built again from the bus |
|
||||
| review again | asks one part's review again, for a version still proposed |
|
||||
| sweep | lists the objects no version or draft names and since when; sweeps them now; dry run |
|
||||
| integrity | checks every named digest has its object; restores a body from given text once its digest matches |
|
||||
| form-only | lists, dry-runs and runs the form-only versions of § 2.2 |
|
||||
| move, and check the move | § 8.1, each with a dry run |
|
||||
|
||||
**Health** says whether every bucket and stream answers, and whether the search index is built and holds as many
|
||||
records as `heads`. A stream that keeps its history raises its condition past 75 percent of its cap. A review waiting more than 30 minutes is named in the health and told to the operator once; the
|
||||
module stays healthy, because a record waiting on its review is not the module failing (issue 508).
|
||||
**Health** (ADR 0592 §27) is unhealthy, naming the cause, when a bucket or stream does not answer, when the index is
|
||||
behind the latest revision of `heads`, when a digest some version names has no object (counted, each named), and
|
||||
when a bucket or stream is at its cap. It names the source it serves from (the database or the bus) and the result
|
||||
of the move's last check, and counts drafts idle more than a week, records the form-only check refused, and parts
|
||||
waiting more than 30 minutes. A part waiting more than 30 minutes is asked of the operator once through the operator
|
||||
channel, and the ask clears when the part is judged; the module stays healthy meanwhile, because a record waiting on
|
||||
its review is not the module failing (issue 508). The condition at 75 percent of a cap is the controller's (§ 2.1).
|
||||
|
||||
**Events** say each step: `opened`, `written`, `removed`, `ordered`, `submitted`, `dropped` and `taken-over` for a
|
||||
draft; `moved` for each record the move copies; `formed` for each form-only version (§ 2.2); beside the events the
|
||||
module emits for reserving, proposing, reviewing, accepting, changing and the import.
|
||||
**Events** (ADR 0592 §28) are kept 30 days; what a later reader needs is also in the version message. Each carries:
|
||||
|
||||
| Event | Carries |
|
||||
|---|---|
|
||||
| `opened` | the record, the version it starts from, the author |
|
||||
| `written`, `removed` | the record, the section's title and digest, the author |
|
||||
| `ordered` | the record, the titles in order, the author |
|
||||
| `submitted` | the record, the new version, its section digests, the author |
|
||||
| `dropped` | the record, the author, the reason (asked, or idle 14 days) |
|
||||
| `taken-over` | the record, the previous author, the new author, the reason |
|
||||
| `part-reviewed` | the record, the version, the part, its digest, the verdict |
|
||||
| `reviewed` | the record, the version, every part's verdict: one event per version, as before |
|
||||
| `swept` | the digest removed, since when nothing named it |
|
||||
| `moved` | the record, its counts on the bus |
|
||||
| `checked` | the move's check: records compared, every difference |
|
||||
| `formed` | the record, the version, the names changed |
|
||||
|
||||
None is named `drafted`, which stays the event of a clause the import's judgement wrote.
|
||||
|
||||
## 2. What one record holds
|
||||
|
||||
@@ -158,23 +195,40 @@ A record is kept in three of the bus's own forms, so that a new version costs on
|
||||
- **The head** is one key in the state `heads`, `<kind>.<number>`: the record's fields, its clauses with their status
|
||||
and source, its links, the operator's ask and warrant, its current and pending version, the latest verdict of each
|
||||
part's review (§ 5), and its sections in order, each a title and a digest. A key's value stays under 256 KiB
|
||||
(ADR 0201).
|
||||
(ADR 0201). A reserved number is a head at `reserved`, with who reserved it, when, for what and when it expires.
|
||||
- **A version** is one message on the stream `versions`: who wrote it (the caller the bus proved), when, why, its
|
||||
mark, and the head as it stood. It never copies a section's body. The stream keeps its history: every message,
|
||||
mark, who wrote each section, the reason of any take-over since the version before, and the head as it stood. It never copies a section's body. The stream keeps its history: every message,
|
||||
with no age limit, and when it reaches its cap it refuses a new message rather than dropping its oldest, with a
|
||||
condition raised at 75 percent of the cap. A module's stream may declare that retention; before, a stream was kept at
|
||||
most 30 days (ADR 0592 §6, changing ADR 0363 §1). The stream `reviews` keeps its history the same way.
|
||||
most 30 days (ADR 0592 §6, changing ADR 0363 §1). The stream `reviews` keeps its history the same way. The
|
||||
condition at 75 percent is raised by the controller, in one place, for every history stream and object bucket of
|
||||
every module.
|
||||
- **A section's body** is one object in the bucket `sections`, named by the sha256 digest of the body: a section
|
||||
unchanged in a new version costs nothing. An object no version and no draft names is removed a day after the last
|
||||
stopped naming it. The bucket is storage of the bus, as the controller's object bucket of ADR 0486 is. Any module
|
||||
unchanged in a new version costs nothing. The module checks that a body hashes to its name each time it reads one.
|
||||
The state `names` keeps, per digest, how many versions and drafts name it and since when none has; an object no
|
||||
version and no draft names is removed a day after the last stopped naming it, each removal the event `swept`. The bucket is storage of the bus, as the controller's object bucket of ADR 0486 is. Any module
|
||||
may declare an object bucket of its own in its manifest, with a local name and a cap, created as its state buckets
|
||||
are, kept with no age limit and refusing a new object when full (ADR 0592 §5).
|
||||
- **A draft** is a key in the state `drafts` (§ 4). **A part's review** is a message on the stream `reviews` (§ 5).
|
||||
**The whole-set findings** standing now, and when each was told to the operator, are keys in the state `findings`.
|
||||
- **A draft** is a key in the state `drafts` (§ 4). **A part's verdict** is a message on the stream `reviews`, and a
|
||||
part asked of the judge and not yet answered a key in the state `asked` (§ 5). **The whole-set findings** standing
|
||||
now are keys in the state `findings`, and what was told to the operator once is a key `told.<topic>` there.
|
||||
|
||||
**Caps** (ADR 0592 §21). Each is set from the move's dry run, within ADR 0363's 8192 MiB; the starting figures, from
|
||||
today's 83 MB for 736 records with every version copying every section, are:
|
||||
|
||||
| Bucket or stream | Cap |
|
||||
|---|---|
|
||||
| `versions` (stream) | 1 GiB |
|
||||
| `reviews` (stream) | 512 MiB |
|
||||
| `sections` (object bucket) | 1 GiB |
|
||||
| `drafts` (state) | 64 MiB |
|
||||
| `heads`, `asked`, `names`, `findings` (state) | ADR 0201's 64 MiB |
|
||||
|
||||
A write refused at a cap names the cap, and the module's health turns unhealthy naming it.
|
||||
|
||||
**Who may read each** is announced in the manifest. `heads`, `versions`, `sections` and `reviews` may be read by a
|
||||
module the manifest names, such as the web page that shows records once it exists; `drafts` and `findings` by
|
||||
mesh-knowledge alone. No secret is kept in any of them. A grant cannot limit a reader to some objects of a bucket
|
||||
module the manifest names, such as the web page that shows records once it exists, and every such grant is read-only;
|
||||
`drafts`, `asked`, `names` and `findings` by mesh-knowledge alone. No secret is kept in any of them. A grant cannot limit a reader to some objects of a bucket
|
||||
(ADR 0488), which is why reading is announced per bucket and never per record.
|
||||
|
||||
### 2.2 A section is a part with a title
|
||||
@@ -182,17 +236,21 @@ mesh-knowledge alone. No secret is kept in any of them. A grant cannot limit a r
|
||||
A section's name is a plain title, unique in its record: "Context", "Direction", "The move". It is never a file's
|
||||
name: a name with an extension, a number prefix such as `00-`, or a slash is refused, and so is a text that holds a
|
||||
local path (in a person's home folder or the temporary folder), a reference to a file and line, or a link whose
|
||||
target is a relative path or a file (ADR 0592 §17).
|
||||
target is a relative path or a file (ADR 0592 §23).
|
||||
|
||||
**A reference to a part has one form**, which `get` resolves and a web page links: the record, then each title down
|
||||
to the part, joined by ›, such as "research 081 › Direction › D3"; a clause as its record and number, "ADR 0290 §7".
|
||||
**A reference has one form** (ADR 0592 §24): the record, a section's title, then a row or clause inside that
|
||||
section's text, joined by ›, such as "research 081 › Direction › D3"; a clause as its record and number,
|
||||
"ADR 0290 §7". Sections never nest: `get` resolves a record and a section's title, and the row is an anchor in the
|
||||
section's text, which a web page links.
|
||||
|
||||
**The records imported with file-named sections** (the research efforts' `00-overview.md` and the like) get titles in
|
||||
one form-only version per record, written by the module after the move. It changes only section names and the
|
||||
one form-only version per record, written after the move by the move's tool alone; no verb writes one. It changes only section names and the
|
||||
targets of links, each link to a record's file becoming a reference in the form above. It is marked `form`, lists the
|
||||
names it changed, and is accepted without a judgement because a check proves only form changed: each section's text,
|
||||
with every link replaced by its label, is the same before and after. It is not a change of meaning; `history` shows
|
||||
it as a change of form (ADR 0592 §19).
|
||||
with every link replaced by its label, is the same before and after, and each new link target resolves to the record
|
||||
the old name named. `get` accepts the old section names as aliases, recorded in that version. A part's review carries
|
||||
over to it, its meaning being unchanged. It is not a change of meaning; `history` shows it as a change of form
|
||||
(ADR 0592 §25).
|
||||
|
||||
## 3. Clauses
|
||||
|
||||
@@ -214,7 +272,7 @@ A clause holds its record's number and its own (`0276 §4`), its wording, a `sta
|
||||
## 4. Writing a record
|
||||
|
||||
`reserve` gives a number (§ 6). A record is then written in a **draft**, one section per call, and submitted as a
|
||||
version (ADR 0592 §11):
|
||||
version (ADR 0592 §14):
|
||||
|
||||
| Verb | Does |
|
||||
|---|---|
|
||||
@@ -238,13 +296,19 @@ version (ADR 0592 §11):
|
||||
A draft is a key in the state `drafts`: its author, when it was opened, the version it starts from, the record's
|
||||
fields and clauses, and its sections in order as title and digest. Each `write` stores the section's body in the
|
||||
object bucket `sections` and its digest in the draft, so the knowledge base holds the only copy of a draft and a
|
||||
session on any node can read it. A draft is kept until it is submitted or dropped; `list` names one untouched for a
|
||||
week.
|
||||
session on any node can read it. A draft holds at most 64 sections and 1 MiB; one untouched for a week is counted in
|
||||
the health, and one idle for 14 days is dropped and its author told by `dropped`.
|
||||
|
||||
**A draft and a proposal have one author** (ADR 0592 §13). Only the author writes a draft or revises a proposal;
|
||||
**A draft and a proposal have one author** (ADR 0592 §16). Only the author writes a draft or revises a proposal;
|
||||
another caller is refused, naming the author. `take-over` makes the caller the author, keeps the reason on the
|
||||
record, and tells the previous author by the event `taken-over`. It answers a proposal that only the machine that
|
||||
wrote it could revise (issue 1102) and one left proposed for ever by a version from an unproven writer (issue 465).
|
||||
A proposal waiting for the operator's Approve cannot be taken over: its author withdraws it first. The reason of a
|
||||
take-over is carried in the next version's message.
|
||||
|
||||
**Only a proven caller writes** (ADR 0592 §17): `open`, `write`, `submit`, `propose` and `take-over` refuse a caller
|
||||
the runtime could not prove. The operator's Approve binds the section digests of the version shown; a version with
|
||||
any other section is asked again.
|
||||
|
||||
`submit` and `propose` are refused, with every reason at once, when one of the rules that judge one record or its
|
||||
prose fails, among them:
|
||||
@@ -268,17 +332,21 @@ as in force.
|
||||
## 5. Review and acceptance
|
||||
|
||||
When a version is submitted (by `submit` or `propose`, a new version of a proposed record included), the knowledge
|
||||
base reviews it itself, **in parts** (ADR 0592 §14 to §16, changing ADR 0290 §4): one judgement per part, each in a
|
||||
base reviews it itself, **in parts** (ADR 0592 §18 to §22, changing ADR 0290 §4): one judgement per part, each in a
|
||||
separate call, with no tools, that answers `approve` or `changes` with its findings, the way the issue tracker's
|
||||
triage judges an issue. The judgement goes through the agent module's judge (`claude_code_judge`) today, and through
|
||||
the mesh's inference layer once one exists; nothing in this design depends on which.
|
||||
|
||||
- **The head** is one part: the title, the brief, the clauses (at most 40 KiB together) and the links, judged
|
||||
against the clauses of the records it links, in what room is left, those not shown named.
|
||||
- **Each changed section** is a part of its own, judged with **the frame** of at most 16 KiB, filled in this order
|
||||
until full: the title and the links, every clause's bold lead, in full each clause the section names, then the
|
||||
Context section (the Overview, for a research effort). What does not fit is cut, and the question says what was cut.
|
||||
A section is at most 40 KiB, so each question stays under the judge's 60 KiB.
|
||||
- **Each changed section** is a part of its own, judged with **the frame** of at most 16 KiB: the title, the links,
|
||||
and only what the section names (rows of other sections, clauses, the clauses of linked records), with the digest
|
||||
of the Context section (the Overview, for a research effort) it is read beside. What does not fit is cut, and the
|
||||
question says what was cut. A section is at most 40 KiB, so each question stays under the judge's 60 KiB.
|
||||
- **What is judged again.** A section is judged again only when its own text or what it names changes; the Context
|
||||
only when it changes. So a usual revision judges only the sections it changed.
|
||||
- **At most two judge calls of one version run at once.** A revision of eight sections takes a few minutes, and
|
||||
about four times the tokens of one whole judgement.
|
||||
- **The rules on the whole record** (§ 4) stay code, run at `submit`; no judgement is asked to find a link to nothing.
|
||||
|
||||
```
|
||||
@@ -290,13 +358,23 @@ the mesh's inference layer once one exists; nothing in this design depends on wh
|
||||
version 3 stays proposed, with the findings of Direction
|
||||
```
|
||||
|
||||
A part's review is a message on the stream `reviews`: the record, its version, the part, the digest judged, the
|
||||
verdict, the findings, who judged and when; the head keeps the latest verdict of each part. A part's review is kept
|
||||
for a new version when its digest and its frame's digest are both unchanged; any other part is judged again. **A
|
||||
version is accepted when every part's review approves.** On `changes`, the record stays proposed, the findings are
|
||||
kept with that version and the part they name, and its author revises it with a new version. A part that cannot be
|
||||
judged (the judge unreachable, or its answer unreadable) leaves the version proposed and says which; it is never
|
||||
taken as an approval. When every part approves:
|
||||
**The parts wait on the bus** (ADR 0592 §19). Each part asked of the judge is a key in the state `asked` (the part,
|
||||
the judge's ticket, the node, when it was asked), collected again at start, so a restart loses no review. The judge's
|
||||
answer comes as the event `judged`, which the claude-code module emits for each ticket and the knowledge base
|
||||
consumes; until claude-code emits it, the knowledge base polls the ticket, which is not NATS-native and is tracked by
|
||||
issue 1956. The judge is a tool of the claude-code module, not a seat's verb: a seat for judgements (held by the
|
||||
mesh's inference layer once one exists) is a note on that issue. A part waiting more than 30 minutes asks the
|
||||
operator once through the operator channel, and the ask clears when the part is judged.
|
||||
|
||||
**A part's verdict** is the event `part-reviewed` and a message on the stream `reviews`: the record, its version, the
|
||||
part, the digest judged, the verdict, the findings, who judged and when; the head keeps the latest verdict of each
|
||||
part. **`reviewed` keeps its meaning**: one event per version, once every part is judged, carrying each part's
|
||||
verdict, so every wait on it keeps working. A part's review is kept for a new version when what it was judged with is
|
||||
unchanged, and for a form-only version (§ 2.2); any other part is judged again. **A version is accepted when every
|
||||
part's review approves.** On `changes`, the record stays proposed, the findings are kept with that version and the
|
||||
part they name, and its author revises it with a new version. A part that cannot be judged (the judge unreachable,
|
||||
or its answer unreadable) leaves the version proposed and says which; it is never taken as an approval. When every
|
||||
part approves:
|
||||
|
||||
1. a record that does not need the operator is accepted at once;
|
||||
2. a record whose author marked it `needs operator` gets an ask on the router with Approve and Decline, shown on a
|
||||
@@ -366,23 +444,36 @@ field by field and section by section, and the result is written on issue 426.
|
||||
### 8.1 The move off the store
|
||||
|
||||
The records leave the store once, and the database is dropped only after a check and the operator's yes
|
||||
(ADR 0592 §10):
|
||||
(ADR 0592 §11 to §13):
|
||||
|
||||
1. **Copy.** The move copies everything the database holds onto the bus, every record, version, clause, link,
|
||||
review, finding, ask with its warrant, reservation and record of what was told: each version's sections into `sections` by digest, each version as a message on `versions`, each record's
|
||||
head into `heads`, each standing finding into `findings`. A clause keeps its number, status and source as the
|
||||
database holds them (ADR 0321). It emits `moved` per record, writes nothing twice, and a second run changes
|
||||
nothing and says so. A dry run lists what it would write.
|
||||
2. **Check.** A tool compares the database and the bus record by record: for each record the count of each of
|
||||
1. **Order.** Three deliveries, in order: mesh-sdk (the manifest's field types for `objects` and
|
||||
`retention: history`, and the catalog's check of them); then the controller (it creates the object buckets and
|
||||
history streams, grants their readers read-only, and raises the condition at 75 percent for every such bucket and
|
||||
stream in one place); then mesh-knowledge. An older controller refuses a manifest with these keys through the
|
||||
catalog's check, so mesh-knowledge cannot be delivered before them. The claude-code module's `judged` event is
|
||||
delivered beside, and is not needed for the move (§ 5).
|
||||
2. **Copy.** The move copies everything the database holds onto the bus, every record, version, clause, link,
|
||||
review, finding, ask with its warrant, reservation and told mark: each version's sections into `sections` by
|
||||
digest, each version as a message on `versions`, each record's head into `heads`, each standing finding into
|
||||
`findings`, each told mark as `told.<topic>`. A clause keeps its number, status and source as the database holds
|
||||
them (ADR 0321). It emits `moved` per record, writes nothing twice, and a second run changes nothing and says so.
|
||||
A dry run lists what it would write and the size each bucket and stream will need, from which the caps are set.
|
||||
3. **The window.** From the move's final copy through the check to the switch, every writing verb is refused with
|
||||
its reason ("the knowledge base is moving"). Reading verbs answer throughout.
|
||||
4. **Check.** A tool compares the database and the bus record by record: for each record the count of each of
|
||||
those, the digest of every section of every version, computed from the database's text and read from the bus,
|
||||
and a digest of every review's, finding's and ask's content. Its result names every difference.
|
||||
3. **Switch.** The module answers from the bus only once the check shows no difference; until then it answers from
|
||||
the database, and a difference is told to the operator.
|
||||
4. **Tell and ask.** The operator is told the check's result and asked whether the database may be dropped, because
|
||||
dropping it removes data.
|
||||
5. **Drop.** On the operator's yes, the delivery after it removes the module's requirement of a database, and the
|
||||
that each body hashes to its name, and a digest of every review's, finding's and ask's content. It emits
|
||||
`checked` with every difference, and the health shows its last result.
|
||||
5. **Switch.** Only once the check shows no difference, the module answers from the bus. The switch is a key on the
|
||||
bus, so a restart never falls back to the database. A difference is told to the operator, and the module stays on
|
||||
the database.
|
||||
6. **Rollback.** Until the database is dropped, the module writes each change to the database too, so a rollback of
|
||||
the delivery reads a current database. A rollback is safe only until the drop.
|
||||
7. **Tell and ask.** Once the check is clean, the operator is told its result and asked, once, whether the database
|
||||
may be dropped, because dropping it removes data.
|
||||
8. **Drop.** On the operator's yes, the delivery after it removes the module's requirement of a database, and the
|
||||
database is dropped by the store's module, through its tool for it, which is built there first if it has none.
|
||||
6. **Titles.** The module then writes the form-only versions of § 2.2, one per record with file-named sections.
|
||||
9. **Titles.** The move's tool then writes the form-only versions of § 2.2, one per record with file-named sections.
|
||||
|
||||
## 9. The slices after the first
|
||||
|
||||
@@ -392,7 +483,7 @@ The records leave the store once, and the database is dropped only after a check
|
||||
| 2 | the decision records and research efforts leave this repository; path mentions become "ADR NNNN" and "research NNN"; playbooks 01 and 02 changed | this repository holds no decision record, and `get` answers every one | issue 426 |
|
||||
| 3 | designs and the glossary's entries as records, moved in one delivery, and each design's state worked out by the knowledge base (§ 9.1 to § 9.3; ADR 0423, ADR 0424) | `get` answers design 47 with its sections and links, a word's entry answers from the knowledge base, and a design's state follows its issues' deliveries without anyone writing it | issue 428 |
|
||||
| 4 | meeting notes, drawings and blog posts | not decided; needs its own decision | issue 429 |
|
||||
| 5 | the records on the bus, written and reviewed by section, the move off the store and the titles (§ 1, § 2, § 4, § 5, § 8.1; ADR 0592) | the acceptance tests of the fifth slice in § 10, live; the knowledge base requires no database | the issues its hand-off opens (playbook 04) |
|
||||
| 5 | the records on the bus, written and reviewed by section, the move off the store and the titles (§ 1, § 2, § 4, § 5, § 8.1; ADR 0592), delivered as mesh-sdk, then the controller, then mesh-knowledge, with claude-code's `judged` event beside | the acceptance tests of the fifth slice in § 10, live; the knowledge base requires no database | the issues its hand-off opens (playbook 04) |
|
||||
|
||||
Numbers from the issue tracker, which `reserve` needs, are the tracker's own slice, tracked by issue 424. This
|
||||
repository keeps no copy of the records, generated or otherwise (issue 435, answered by the operator). Playbooks
|
||||
@@ -495,6 +586,34 @@ milestones and nothing of how a delivery runs; it only listens for the announcem
|
||||
| A draft is written by section and has one author, and a take-over tells the previous one | unit tests of each verb of § 4, of a refusal naming the author, and of `take-over` emitting `taken-over` |
|
||||
| A stream that keeps its history, and an object bucket of a module's own | in the integration test: a history stream at its cap refuses a new message and keeps its oldest, its condition raised at 75 percent and cleared below; an object no version or draft names is removed after a day, one still named is kept; unit tests of registration refusing a name already taken |
|
||||
| A long record is judged whole, one part at a time | unit tests: the frame never passes 16 KiB and says what it cut, with twenty clauses of 2000 bytes and a 40 KiB Context; every question stays under 60 KiB with a 40 KiB section and that frame, and the head part with 40 KiB of clauses; a section over 40 KiB is refused saying split it; an unchanged section keeps its review, a changed frame asks it again |
|
||||
|
||||
**The fifth slice's tests, one per failure path** (ADR 0592; the review by aspect's testing ruling). Unit tests are
|
||||
table-driven; one integration test starts the module whole against the real bus server. The module's count today is
|
||||
1 integration and 104 unit tests; these add about 20 table cases and stay within the budget of 50 and 500.
|
||||
|
||||
| Failure path | Test |
|
||||
|---|---|
|
||||
| two writes race on one draft | unit: the second compare-and-set loses, is retried, and is refused with the reason past its tries |
|
||||
| `submit` races `take-over` | unit: one wins; the other is refused naming the new author or the new version |
|
||||
| two reservations race | unit: two numbers, or one refused; never one number twice |
|
||||
| a write cut between the stream and the head | unit: a start rebuilds the head from its last version |
|
||||
| a named digest has no object | unit: health unhealthy, naming it; the integrity tool restores it from given text |
|
||||
| a body does not hash to its name | unit: the read refuses it, naming the digest |
|
||||
| a full object bucket | integration: a write refused naming the cap; health unhealthy |
|
||||
| a full history stream | integration: `submit` refused with the head unchanged; the condition at 75 percent raised and cleared |
|
||||
| a judge timeout for one part | unit: that part stays asked and the version proposed, saying which; the others keep their verdicts |
|
||||
| a restart with parts asked | integration: the parts in `asked` are collected again and judged |
|
||||
| `reviewed` once per version | unit: one `reviewed` after the last `part-reviewed`, carrying every verdict |
|
||||
| told once | unit: a whole-set finding told once across a restart, again only after its mark is cleared |
|
||||
| a second run of the move | unit: changes nothing and says so |
|
||||
| the move's check | unit: a changed review, a missing finding and a missing ask, each named |
|
||||
| writes during the switch | unit: every writing verb refused with its reason; reading verbs answer |
|
||||
| an older controller | the controller's test: a manifest with `objects` or `retention: history` refused through the catalog's check |
|
||||
| a reference | unit: "record › title › row" resolves to the section; a nested title is refused |
|
||||
| a form-only version | unit: accepted when only names and links changed and each target resolves; refused otherwise |
|
||||
| an unproven caller | unit: `open`, `write`, `submit`, `propose` and `take-over` refuse it |
|
||||
| the index behind | unit: health unhealthy while the index's revision is behind `heads`; `ask` refuses "index not built" |
|
||||
| the start | integration: the time to a built index measured and reported |
|
||||
| A section is a part with a title | a table test, one case per refused name and text of § 2.2; a form-only version whose text changed beyond its links is refused |
|
||||
| Every bucket has a tool, and health says the index | the manifest test compares tools and events with the code; a unit test of the health before and after the index is built |
|
||||
|
||||
@@ -536,8 +655,32 @@ done:
|
||||
change of form, and `get` of "research 062 › Direction" answers that section.
|
||||
7. The fill tool shows each bucket and stream against its cap; the second version of a record with one changed
|
||||
section adds one object, not one per section.
|
||||
8. During the move's window a `write` is refused saying the knowledge base is moving; after the switch a restart
|
||||
still serves from the bus; the health names the source and the check's result.
|
||||
9. A part's review waiting on the judge survives a restart of the module, and one past 30 minutes reaches the
|
||||
operator once.
|
||||
10. Every test of the table above passes in the one check of the pull requests, within the test budget.
|
||||
|
||||
## What it leaves out
|
||||
|
||||
Semantic or vector search; a browser view (its reading of the buckets is announced, ADR 0592); line comments on a proposal (the judgement's findings name the section and
|
||||
clause instead); and the rules of how-we-build, which are not decision records. Each needs a decision of its own.
|
||||
|
||||
## Reviewed by aspect
|
||||
|
||||
The fifth slice was reviewed by aspect on 2026-11-02 (four reviewers, two aspects each; the knowledge base's own
|
||||
review of ADR 0592's fourth version beside), and the lead ruled on every finding. What was found, and what answers it:
|
||||
|
||||
| Aspect | Found | Answered by |
|
||||
|---|---|---|
|
||||
| security | unproven callers could write or take over; an Approve did not bind the sections shown; a proposal waiting on the operator could be taken over; readers' grants and a body's match with its name were unsaid; a draft had no bound | ADR 0592 §4, §8, §14, §16, §17; § 2.1, § 4 |
|
||||
| seams | asked parts lived only in memory; told marks and reservations had no form on the bus; the judge's ticket is polled; who creates buckets and grants was unsaid; the judge is a module's tool, not a seat | ADR 0592 §2, §7, §13, §19; § 1, § 5 (the judge's seat a note on issue 1956), § 8.1 |
|
||||
| running qualities | three writes could stop halfway; caps had no figures; a usual revision judged every section again, with no limit on parallel calls; start time unknown | ADR 0592 §9, §18, §21; § 1, § 2.1 (caps), § 5 |
|
||||
| health | a stale index, a missing body, a full bucket and the move's state were not visible; waiting reviews and idle drafts were not counted | ADR 0592 §21, §27; § 1.1 |
|
||||
| events and logs | per-part verdicts would have broken every wait on `reviewed`; events did not say what they touched; a take-over's reason and each section's author were lost after 30 days | ADR 0592 §3, §22, §28; § 1.1 (the events table) |
|
||||
| testing | each failure path lacked a test; the budget was not counted | ADR 0592's How it is checked; § 10 (the failure-path table) |
|
||||
| upgrade | writes during the switch, a rollback after it, and the order of the three deliveries were unsaid; the form-only check did not prove new link targets | ADR 0592 §12, §13, §25; § 8.1, § 2.2 |
|
||||
| tools | unnamed objects, missing bodies, form-only versions, asked parts and told marks had no tool | ADR 0592 §26; § 1.1 (the tools table) |
|
||||
|
||||
The knowledge base's review of the fourth version found that the reference form read as nested sections: ADR 0592
|
||||
§24 and § 2.2 say sections never nest.
|
||||
|
||||
Reference in New Issue
Block a user