mesh-issues: import hq's issue folders at their own numbers, and an issue with a folder is whole in the tracker (hq ADR 0275, to-be 53 slice 3)
mesh/merge-gate pass: builds mesh-issues → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
mesh/merge-gate pass: builds mesh-issues → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
This commit is contained in:
@@ -22,16 +22,66 @@ what it refuses.
|
||||
| `move` | `number`, `status`, and what that status needs | changes the status under the development cycle's rules |
|
||||
| `note` | `number`, `text` | appends a note; a note is never edited |
|
||||
| `link` | `number`, `kind`, `target`, optionally `remove` | adds or removes a typed link |
|
||||
| `import` | optionally `dry-run`, `commit` | hq's issue folders, read through the records module, each written as an issue under its own number; see below |
|
||||
|
||||
**The cycle's rules, at the write** (hq `00-META/checks/cycle.py`): a status is one of `open`,
|
||||
**The cycle's rules, at the write** (hq playbook 03, which `00-META/checks/cycle.py` enforced on the
|
||||
folders until the import): a status is one of `open`,
|
||||
`diagnosing`, `located`, `resolved`, `wontfix`; `located` needs `located-in`; `resolved` needs
|
||||
`located-in` and `fixed-by`; a core issue (located in the controller, the node-engine, the tool runner,
|
||||
the SDK, or the catalogue's bus, forge or build agent) resolves with `replay` or `replay-none`; `wontfix`
|
||||
needs a `reason`. A refused change changes nothing and says which rule refused it.
|
||||
|
||||
**An issue with a folder in hq** (`record` at open: the folder's name, without the number) keeps its
|
||||
status in that folder's report until the import of slice 3. The tracker holds its number, title, folder,
|
||||
notes and links, and `move` refuses it, saying where its status lives.
|
||||
**An issue with a folder in hq** (`record` at open: the folder's name, without the number) is whole in the
|
||||
tracker like any other: the folder holds its narrative, the tracker its status. Until the import of
|
||||
slice 3 ran, such an issue kept its status in the folder and `move` refused it; the import filled it.
|
||||
|
||||
## The import of hq's issues (slice 3)
|
||||
|
||||
`issue-tracker.import` reads every `04-ISSUES/NNN-slug/00-report.md` of hq **through the records module
|
||||
over the bus** (`records_status`, `records_list`, `records_read`, called as this module through the SDK's
|
||||
`Ask`), at the commit the records module's checkout stands at, and writes each as an issue **at its own
|
||||
number**: `record` is the folder, the title is the report's heading, the report is the text under it, and
|
||||
`status`, `opened`, `located-in`, `fixed-by`, `amended-design`, `replay` and `replay-none` are the
|
||||
frontmatter's, as written — the status one to one, no cycle rule applied, because the folder's status is
|
||||
the snapshot hq kept. The issues and decision records the report names (`issue 155`, `ADR 0275`,
|
||||
`04-ISSUES/203-…`, `02-DECISIONS/0019-…`) become `relates-to` and `decision` links.
|
||||
|
||||
It is a verb on the seat, callable by any agent, because it can do only this:
|
||||
|
||||
- **It only creates an issue that is not there** (`create` on the key, refused when the key exists) **or
|
||||
fills the status of one the tracker holds without a status** — an issue opened with a folder before this
|
||||
slice, whose folder kept its status; one whose folder hq does not hold at the commit becomes `open`.
|
||||
- **It never overwrites.** An issue the tracker holds differently is reported as `differs`, naming the
|
||||
fields, and left alone: the tracker is the truth. An issue it holds the same is `same`. So a second run
|
||||
changes nothing and says so.
|
||||
- **It never touches the counter**, and refuses the whole run when a folder is numbered past the counter.
|
||||
A folder numbered at or past the setting `first-number` without an issue in the tracker is refused on its
|
||||
own: a folder from the tracker's time carries a number the tracker gave.
|
||||
- **It cannot forge an issue's history.** An issue it writes is `opened-by: import`, its `opened` the date
|
||||
the report gave, and it carries `imported: {at, by, commit, from}` — when, who ran the import (the bus
|
||||
credential, `unproven` until the runtime proves it), the commit of hq and the document. Each is an
|
||||
`imported` event. What it writes comes from hq's `main` as the records module holds it, which is reviewed
|
||||
in pull requests.
|
||||
- **What it keeps is bounded** as every verb's text is: the title 200 bytes, the report 64 KiB, one issue
|
||||
256 KiB; a report that trips a credential's shape is refused. An entry of `located-in` or `fixed-by` hq
|
||||
wrote is prose at times, so it is taken within a reason's bound (2000 bytes), not a line's.
|
||||
- **An owner hq named that the registered list does not know is kept as written and marked**, in
|
||||
`located-in-unverified` on the issue and `unverified-owners` in the answer, never refused: the list is
|
||||
the setting's problem (hq issue 366), and a `move` that gives `located-in` anew checks every entry and
|
||||
clears the mark.
|
||||
- **With `dry-run`** it reads everything, writes nothing, and answers the same rows with `would-` on each
|
||||
action. **With `commit`** it refuses a checkout standing elsewhere; it refuses a run during which the
|
||||
checkout moved.
|
||||
|
||||
The answer is a row per folder — number, action (`create`, `fill`, `same`, `differs`, `refused`, with why),
|
||||
status, title — the counts, the counts by status, what was odd (a title numbered otherwise than its
|
||||
folder, a frontmatter key not imported, an `amended-design` that is no design document) and the unverified
|
||||
owners. A call that outlives the tool runner's wait is still running: the import goes on, and the answer
|
||||
is read back through the controller's `calls` verb by the call's id.
|
||||
|
||||
Before the module is rolled out, `mesh-issues dry-run <hq checkout> <settings.json>` at the terminal runs
|
||||
the same dry run over a checkout on disk against an empty tracker, and prints the answer. It is not a way
|
||||
to import: only the verb writes, and it reads the record over the bus.
|
||||
|
||||
**Every argument is read strictly.** One a verb does not take is refused, never dropped. Every field has a
|
||||
size limit, a one-line field takes no control character, a folder's name is no path, and text shaped like
|
||||
@@ -64,8 +114,8 @@ Two states, declared in the manifest and made by the controller; the module neve
|
||||
(ADR 0201): `issues`, one key per issue by number, keeping 8 values per key; `counters`, one value per key.
|
||||
Neither expires. One issue is kept in at most 256 KiB; a note that would pass it is refused.
|
||||
|
||||
Every change is an event: `mesh-issues.opened`, `.moved`, `.noted`, `.linked`, each with the number, what
|
||||
changed, who changed it and when. The events are the audit trail. A change whose event the bus did not take
|
||||
Every change is an event: `mesh-issues.opened`, `.moved`, `.noted`, `.linked`, `.imported`, each with the
|
||||
number, what changed, who changed it and when. The events are the audit trail. A change whose event the bus did not take
|
||||
is kept, and its answer says the event was not said (`announced: false`).
|
||||
|
||||
## Who acted
|
||||
@@ -85,7 +135,9 @@ verb takes an argument naming a caller, and none can be given one.
|
||||
```
|
||||
|
||||
- `first-number` — the number the first issue gets: the one after the highest issue number on hq's main
|
||||
and every open branch at the moment the module is switched on. Read once.
|
||||
and every open branch at the moment the module is switched on. Read once for the counter; the import
|
||||
reads it as the boundary between the folders hq numbered before the tracker and the numbers the tracker
|
||||
gave.
|
||||
- `owners` — the registered list `located-in` may name: repositories, and modules as
|
||||
`mesh-catalog modules/<module>`. An entry of `located-in` is an owner, or an owner followed by a space or a
|
||||
slash and where in it (`mesh-controller internal/broker`, `mesh-catalog modules/nats/module.json`). A module
|
||||
@@ -102,3 +154,10 @@ the test, two instances of this bundle (the test binary started again) speaking
|
||||
test against the buckets the manifest declares, fifty opens at once, fifty distinct numbers from the first
|
||||
in a row. It counts the writes lost to another opener, so it fails when the openers never collided. With
|
||||
the counter written without its revision check, it fails.
|
||||
|
||||
The import is tested over `testdata/hq`, copies of seven real reports of hq chosen for their shapes (a
|
||||
bracketed list with commas inside parentheses, quoted block items, an apostrophe in prose, a `resolved:`
|
||||
date, a replay, an empty list, a wontfix): the frontmatter read as written, each issue created at its own
|
||||
number with the counter untouched, a second run changing nothing, an issue the tracker holds differently
|
||||
left alone, a folder-backed issue filled once, a folder past the counter or past the first number refused,
|
||||
a dry run writing nothing, and a report that cannot be read refused alone with why.
|
||||
|
||||
Reference in New Issue
Block a user