@assuredloop/cli 0.2.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -17
- package/bin/al.js +8 -2
- package/package.json +1 -1
- package/skills/assuredloop/SKILL.md +38 -17
- package/src/v4/blocks.js +321 -0
- package/src/v4/check.js +37 -16
- package/src/v4/checks.js +27 -11
- package/src/v4/commands.js +3 -1
- package/src/v4/conclude.js +8 -4
- package/src/v4/indexer.js +4 -10
- package/src/v4/issues.js +256 -0
- package/src/v4/phrases.js +78 -0
- package/src/v4/scope.js +13 -1
- package/src/v4/state.js +29 -8
package/README.md
CHANGED
|
@@ -10,8 +10,10 @@ AssuredLoop keeps an AI focused on one change. It holds together:
|
|
|
10
10
|
- the code, the tests and the documents that came with the change.
|
|
11
11
|
|
|
12
12
|
Its command, `al`, keeps these records, checks them, and says what to do
|
|
13
|
-
next. It refuses only in its own `al conclude`.
|
|
14
|
-
|
|
13
|
+
next. It refuses only in its own `al conclude`. `al check` gives the AI
|
|
14
|
+
review hints, and the review decides. Only a few exact rules are `not ok`
|
|
15
|
+
(see "Hints, and the rules that block"). A project that wants them to block
|
|
16
|
+
turns on `al check --strict` in its CI.
|
|
15
17
|
|
|
16
18
|
AssuredLoop is not a lifecycle tool. It has no phases, no roles, no task
|
|
17
19
|
states and no approvals beyond the owner's sign-off. How and when you design,
|
|
@@ -109,16 +111,16 @@ The user picks the path. The skill has the steps of each path.
|
|
|
109
111
|
| 0. Fix | no promise changes: it restores what the spec says, or claims a typo in any paragraph | none | no | the PR merges |
|
|
110
112
|
| 1. Small promise amend | one or a few promise paragraphs change | a short request; the PR edits `specs/` directly | yes | the PR merges |
|
|
111
113
|
| 1d. Small design correction | names or wording of design paragraphs only | a short request with a one-line source note; the PR edits `specs/` directly | no | the PR merges |
|
|
112
|
-
| 2. Big change | a real design, one or a few PRs | a request and a change spec | if a promise kind changes | the close rule holds |
|
|
114
|
+
| 2. Big change | a real design, one or a few PRs | a request and a change spec | if a promise kind changes, or the request has an R<n> | the close rule holds |
|
|
113
115
|
| 3. Epic | big, in parts over time | as 2, with optional task references | as 2 | the close rule holds |
|
|
114
116
|
| S. Spike | not yet clear what to build | a request with an organized question; the findings open with the answer | yes, on the question | the answer names the question version |
|
|
115
117
|
|
|
116
118
|
Every PR states its path and its claim in a commit message, for example
|
|
117
119
|
`Tier: 0 — typo in INV-3` or `Tier: 2 — invoice-payments, part 1`. `al check`
|
|
118
120
|
reads the newest `Tier:` line in the branch's commits, and checks the claim
|
|
119
|
-
against the kinds and the changed paragraphs
|
|
120
|
-
|
|
121
|
-
meaning.
|
|
121
|
+
against the kinds and the changed paragraphs. Where they disagree, it gives
|
|
122
|
+
a hint, for example "path 0, but a rule paragraph is changed with no typo
|
|
123
|
+
claim". It checks the labels, not their meaning.
|
|
122
124
|
|
|
123
125
|
**The close rule.** `al conclude <name>` refuses while a promise change has
|
|
124
126
|
no sign-off, a spike's current question is not signed, or a change paragraph
|
|
@@ -140,7 +142,10 @@ with a baseline effect has no valid disposition for its current version.
|
|
|
140
142
|
- `al index`: write the derived facts and the new bindings, and list the AI
|
|
141
143
|
hints to refresh. `al index --align <ID>` moves the bindings of one
|
|
142
144
|
paragraph to its targets' current text, on purpose.
|
|
143
|
-
- `al check [--strict]`: the checks of this branch
|
|
145
|
+
- `al check [--strict] [--issues <folder>]`: the checks of this branch
|
|
146
|
+
against its base. With `--issues <folder>`, it also checks the work items
|
|
147
|
+
that the caller saved in the folder (see "Hints from the linked work
|
|
148
|
+
items").
|
|
144
149
|
- `al context [<name> | <ID>]`: where the project, a request or a paragraph
|
|
145
150
|
stands. `--diff <range> --for review` is the review view. `--audit` gives a
|
|
146
151
|
request's whole trace; `--at <commit>` any v4 state.
|
|
@@ -173,18 +178,101 @@ results: .assuredloop/results # where result files are
|
|
|
173
178
|
outputs: # in the central repo: its output repos
|
|
174
179
|
- {name: invoicer-web, path: ../invoicer-web, commit: <sha>}
|
|
175
180
|
central: {path: ../invoicer} # in an output repo: the central repo
|
|
181
|
+
phrases: # text for the review to look at; each match is a hint
|
|
182
|
+
- the requester # a phrase: ignoring case, across a line break too
|
|
183
|
+
- {pattern: "Avery (asked|wants)"} # a JavaScript regular expression
|
|
176
184
|
```
|
|
177
185
|
|
|
186
|
+
`al check` gives the hint `phrase` for each match of `phrases:` in the spec
|
|
187
|
+
docs, the ADRs and the Markdown files of the open requests, but their
|
|
188
|
+
`origin/` folders; with `--issues <folder>`, in the work items too. The list is empty by
|
|
189
|
+
default. A bad entry or an invalid pattern stops `al check` with exit 2.
|
|
190
|
+
|
|
178
191
|
`.assuredloop/schema.yaml` holds the kinds and the link words, with a version.
|
|
179
192
|
`al spec --add-ids` writes both files when they are absent.
|
|
180
193
|
|
|
181
194
|
ADRs are `specs/adr/NNNN-<slug>.md`, with `Status: proposed`, `accepted` or
|
|
182
|
-
`superseded
|
|
183
|
-
`decides:`, `source:` and `supersedes:` links.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
195
|
+
`superseded by ADR-<n>` on the first line. The heading's marker holds
|
|
196
|
+
`ADR-<n>` and its `decides:`, `source:` and `supersedes:` links.
|
|
197
|
+
|
|
198
|
+
- Any text may be rewritten in other words when its meaning stays the same,
|
|
199
|
+
an accepted or superseded ADR's text too. A new ADR that supersedes it is
|
|
200
|
+
needed only when the decision changes, in whole or in part.
|
|
201
|
+
- The review judges whether a rewrite keeps the decision; `al` does not. So
|
|
202
|
+
a changed ADR text, or a changed or removed link in its marker, gives a
|
|
203
|
+
hint: check that its decision is unchanged. Links added to the marker of
|
|
204
|
+
an accepted ADR, with nothing else changed, give no finding.
|
|
205
|
+
- After a rewrite, `al index --align <ID>` moves the bindings of paragraph
|
|
206
|
+
`<ID>` to the ADR's new text, for an accepted or a superseded ADR.
|
|
207
|
+
- `al check` gives a hint for a proposed or accepted ADR with no `source:`
|
|
208
|
+
or no `decides:`.
|
|
209
|
+
- A current place that names a superseded ADR also names the ADR that
|
|
210
|
+
supersedes it, in the same marker or the same paragraph. Current places
|
|
211
|
+
are the spec docs, the open requests and the proposed and accepted ADRs.
|
|
212
|
+
The chain itself and dated records are exempt: an ADR that supersedes it,
|
|
213
|
+
a superseded ADR, an ADR's `## History`, a request's `## Decisions`, the
|
|
214
|
+
`origin/` files and the archived requests. Else `al check` gives
|
|
215
|
+
`not ok superseded-cited`.
|
|
216
|
+
- A superseded ADR's status line names the ADR that supersedes it, and that
|
|
217
|
+
ADR's marker has `supersedes:` for it. Else `al check` gives
|
|
218
|
+
`not ok superseded-status`.
|
|
219
|
+
|
|
220
|
+
## Hints from the linked work items
|
|
221
|
+
|
|
222
|
+
A project may keep its work items in any tracker, or in none. `al` never
|
|
223
|
+
contacts a tracker. The caller saves the items in a folder, and
|
|
224
|
+
`al check --issues <folder>` checks the items that the `tasks:` of the open
|
|
225
|
+
requests name. Without `--issues`, `al check` reads no item. A task's `ref`
|
|
226
|
+
names an item as `#n`, `owner/repo#n`, `<name>#n` for an output repo that
|
|
227
|
+
config names, an issue URL on any host, or the item's own `ref`, for
|
|
228
|
+
example `PROJ-12`. Each finding is a hint:
|
|
229
|
+
|
|
230
|
+
- `issue-missing`: a task names an item that is not in the folder;
|
|
231
|
+
- `issue-superseded`: the item's text names a superseded ADR without the ADR
|
|
232
|
+
that supersedes it, by the rule of `superseded-cited`;
|
|
233
|
+
- `issue-bare-ref`: a bare `#n` in an item of another repository, which
|
|
234
|
+
GitHub reads as that repository's issue. The request's own repository
|
|
235
|
+
comes from `git remote get-url origin`;
|
|
236
|
+
- `issue-not-sub`: the item is not a child of the request's own item, the
|
|
237
|
+
item that the `url` of an origin source names (`al record <name> origin
|
|
238
|
+
--url <its URL>`);
|
|
239
|
+
- `phrase`: a phrase of `phrases:` matches;
|
|
240
|
+
- `issue-unread`: a file in the folder is not valid JSON, or holds an entry
|
|
241
|
+
that is not an item.
|
|
242
|
+
|
|
243
|
+
The folder holds `*.json` files. Each file holds one item, or a list of
|
|
244
|
+
items. An item is the JSON that the GitHub CLI prints with
|
|
245
|
+
`--json number,url,body,comments,parent`, so GitHub issues need no
|
|
246
|
+
conversion:
|
|
247
|
+
|
|
248
|
+
| Field | What it is | Needed |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| `body` | the item's text | yes |
|
|
251
|
+
| `url` | its address, `https://<host>/owner/repo/issues/n` for GitHub | one of `url`, `number` with `repository`, or `ref` |
|
|
252
|
+
| `number` | its number in its repository | |
|
|
253
|
+
| `comments` | a list, each with `body`, and `isMinimized` true for a hidden comment | no |
|
|
254
|
+
| `parent` | the parent item, with `url` and `number`, or `ref`; `null` for none | no: with no `parent`, the child check is not made |
|
|
255
|
+
| `ref` | the reference that a task names, for another tracker, for example `PROJ-12` | for another tracker |
|
|
256
|
+
| `repository` | `owner/repo`, or a project key | no |
|
|
257
|
+
|
|
258
|
+
To save GitHub issues, GitHub Enterprise included, save each issue with
|
|
259
|
+
`gh issue view`. `gh issue list` gives at most 100 comments of an issue.
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
mkdir -p /tmp/items
|
|
263
|
+
gh issue view 31 --repo acme/invoicer \
|
|
264
|
+
--json number,url,body,comments,parent > /tmp/items/invoicer-31.json
|
|
265
|
+
GH_HOST=github.example.com gh issue view 5 --repo acme/web \
|
|
266
|
+
--json number,url,body,comments,parent > /tmp/items/web-5.json
|
|
267
|
+
al check --issues /tmp/items
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
An item of another tracker:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{"ref": "PROJ-12", "repository": "PROJ", "body": "Build the export (ADR-3).",
|
|
274
|
+
"comments": [{"body": "Done.", "isMinimized": false}], "parent": {"ref": "PROJ-1"}}
|
|
275
|
+
```
|
|
188
276
|
|
|
189
277
|
## Search
|
|
190
278
|
|
|
@@ -266,21 +354,63 @@ does not change; `al` hashes each paragraph without its marker.
|
|
|
266
354
|
|
|
267
355
|
**From 0.1.0.** v4 (0.2.0) does not read 0.1.0 records. Keep 0.1.0 pinned
|
|
268
356
|
until you move. Older records stay readable as files; run the pinned 0.1.0 at
|
|
269
|
-
those commits.
|
|
357
|
+
those commits.
|
|
358
|
+
|
|
359
|
+
In a project where `.assuredloop` is a file, as 0.1.0 writes it, each `al`
|
|
360
|
+
command refuses with exit 2 and one line: `al: .assuredloop is a file, so the
|
|
361
|
+
project has 0.1.0 records, which v4 does not read; keep 0.1.0 pinned, or move
|
|
362
|
+
as "From 0.1.0" in the README says`. It reads and writes nothing else, so
|
|
363
|
+
`al check` never passes there. `al --version` and the usage message still
|
|
364
|
+
work. To move:
|
|
270
365
|
|
|
271
366
|
1. Finish each open 0.1.0 request on its pinned copy, or start it again
|
|
272
367
|
under v4.
|
|
273
368
|
2. Install 0.2.0 (see "Install").
|
|
274
|
-
3.
|
|
369
|
+
3. Remove the 0.1.0 file: `git rm .assuredloop`. v4 keeps its settings in
|
|
370
|
+
the folder `.assuredloop/`. If the file had a `root:` line, write the
|
|
371
|
+
same line in `.assuredloop/config.yaml` (see "Settings").
|
|
372
|
+
4. Run `al spec --add-ids`, as in steps 1-5 above. It marks every paragraph
|
|
275
373
|
and writes the adoption record.
|
|
276
374
|
|
|
375
|
+
## Hints, and the rules that block
|
|
376
|
+
|
|
377
|
+
`al check` gives the AI review hints, and the review decides. A finding is
|
|
378
|
+
`not ok` only for a rule that meets two tests: breaking it lets an
|
|
379
|
+
unapproved or wrong decision be built, and an exact check of the records,
|
|
380
|
+
hashes and links decides it, with no judgement. These rules are:
|
|
381
|
+
|
|
382
|
+
- **An unsigned requirement** (`not ok unsigned-requirement`). In each
|
|
383
|
+
request whose record has `requirements:`, open or archived, the latest
|
|
384
|
+
version of each requirement has a valid sign-off. A sign-off is valid only
|
|
385
|
+
when a `covers` entry matches the requirement's id, version and `sha256`
|
|
386
|
+
exactly; its file is in the request's `origin/` folder, and the hash of
|
|
387
|
+
its signed text equals the sign-off's `sha256`; and it records when it was
|
|
388
|
+
signed and the signer's words. A requirement in `request.md` that is not
|
|
389
|
+
its latest recorded version is not signed. An entry that `al check` cannot
|
|
390
|
+
read is `not ok` too. A promise paragraph that changes with no signed
|
|
391
|
+
requirement that covers it stays `not ok signoff-coverage`.
|
|
392
|
+
- **Changed record evidence** (`not ok record-evidence`). Each origin file
|
|
393
|
+
under `sources:`, and each sign-off file, still has the hash that the
|
|
394
|
+
record lists. `al check` hashes the snapshot's text after its `---` line,
|
|
395
|
+
as `al record` did.
|
|
396
|
+
- **A citation of a superseded ADR** (`not ok superseded-cited` and
|
|
397
|
+
`superseded-status`; see "Settings").
|
|
398
|
+
|
|
399
|
+
A request record that cannot be read (`record-unreadable`) and a spec root
|
|
400
|
+
that cannot be read (`spec-root`) are `not ok` too. Every other finding is a
|
|
401
|
+
hint in every mode, `--strict` included: the marker and ID lints, the path
|
|
402
|
+
claim, a link that does not resolve, an ADR's changed text or missing links,
|
|
403
|
+
an invalid disposition, and the rest. `--strict` changes only the exit code:
|
|
404
|
+
it is 1 when a `not ok` prints.
|
|
405
|
+
|
|
277
406
|
## What is enforced, and by whom
|
|
278
407
|
|
|
279
408
|
| The tool checks | The skill asks | The owner decides |
|
|
280
409
|
|---|---|---|
|
|
281
410
|
| `al conclude` refuses on its three conditions (see "The close rule") | write the owner's words and the organized requirement, and ask for the sign-off | what is wanted, by signing the organized requirement |
|
|
282
|
-
|
|
|
283
|
-
|
|
|
411
|
+
| `not ok`: sign-off coverage of promise changes, unsigned requirement versions, changed record evidence, citations of superseded ADRs and their status lines, and records or a spec root that cannot be read | choose the path, and state it in a commit message and the PR | whether a changed requirement is signed again |
|
|
412
|
+
| hints for the review: IDs missing, used twice, lost or used again; kinds and links; links that do not resolve; path and typo claims; dispositions and exact equality; stale bindings; overlapping changes; ADR text changes; a proposed or accepted ADR with no `source:` or no `decides:`; result applicability; a design paragraph that links to none of its requirement's promise paragraphs in its change spec; a `for:` that names no task; matches of the configured phrases; with `--issues <folder>`, the hints from the linked work items | record each later decision, with its source | decisions whose source is the owner, such as dropping or keeping work |
|
|
413
|
+
| `check --strict` exits 1 on a `not ok`, when a project opts in | | |
|
|
284
414
|
|
|
285
415
|
`al` checks that declarations are well formed and that references resolve.
|
|
286
416
|
It does not check that a kind is right, that a requirement is fully
|
package/bin/al.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// al, the v4 command (T17 made it the one in package.json's bin).
|
|
3
3
|
import { parseArgs } from 'node:util';
|
|
4
4
|
import { execFileSync } from 'node:child_process';
|
|
5
|
-
import { readFileSync, realpathSync } from 'node:fs';
|
|
5
|
+
import { readFileSync, realpathSync, statSync } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
8
|
import { check } from '../src/v4/check.js';
|
|
8
9
|
import { Fail, spec } from '../src/v4/spec.js';
|
|
@@ -28,7 +29,7 @@ const COMMANDS = {
|
|
|
28
29
|
},
|
|
29
30
|
index: { run: index, positionals: 0, options: { align: { type: 'string' } } },
|
|
30
31
|
spec: { run: spec, positionals: (o) => (o['add-ids'] === undefined ? Infinity : 0), options: { 'add-ids': { type: 'string' }, prefix: { type: 'string' }, yes: { type: 'boolean' } } },
|
|
31
|
-
check: { run: check, positionals: 0, options: { strict: { type: 'boolean' } } },
|
|
32
|
+
check: { run: check, positionals: 0, options: { strict: { type: 'boolean' }, issues: { type: 'string' } } },
|
|
32
33
|
export: { run: exportCommand, positionals: 0, options: { at: { type: 'string' }, out: { type: 'string' }, yes: { type: 'boolean' } } },
|
|
33
34
|
search: {
|
|
34
35
|
run: search,
|
|
@@ -102,6 +103,11 @@ async function main(argv) {
|
|
|
102
103
|
throw new Fail(`extra argument ${JSON.stringify(extra)}: ${used} takes ${n === 0 ? 'no' : n} positional argument${n === 1 ? '' : 's'}`,
|
|
103
104
|
'quote an option value that holds spaces, and leave out the extra argument');
|
|
104
105
|
}
|
|
106
|
+
// 0.1.0 kept its settings in a file .assuredloop; v4 keeps a folder (#241).
|
|
107
|
+
if (statSync(join(top, '.assuredloop'), { throwIfNoEntry: false })?.isFile()) {
|
|
108
|
+
throw new Fail('.assuredloop is a file, so the project has 0.1.0 records, which v4 does not read; keep 0.1.0 pinned, or move as "From 0.1.0" in the README says',
|
|
109
|
+
'npm install --global @assuredloop/cli@0.1.0, or move as "From 0.1.0" in the README says');
|
|
110
|
+
}
|
|
105
111
|
let out;
|
|
106
112
|
try {
|
|
107
113
|
out = await command.run({ top, cwd, args: parsed.positionals, opts: parsed.values });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assuredloop/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "AssuredLoop keeps an AI focused on one change: the al command gathers and checks a change's requirement, spec, decisions, code and tests.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -10,8 +10,9 @@ description: >-
|
|
|
10
10
|
# AssuredLoop v4
|
|
11
11
|
|
|
12
12
|
`al` keeps the records of what was asked, decided, changed and delivered,
|
|
13
|
-
and gives hints. It refuses only in
|
|
14
|
-
test and review is your project's
|
|
13
|
+
and gives the review hints. The review decides. It refuses only in
|
|
14
|
+
`al conclude`. How and when you design, test and review is your project's
|
|
15
|
+
way of working; this skill does not set it.
|
|
15
16
|
|
|
16
17
|
## Start here, on every path
|
|
17
18
|
|
|
@@ -31,16 +32,19 @@ test and review is your project's way of working; this skill does not set it.
|
|
|
31
32
|
| 0 | No promise changes: a fix that restores what the spec says, or a typo in any paragraph. | none | no |
|
|
32
33
|
| 1 | One or a few promise paragraphs change. | a short request; no change spec | yes |
|
|
33
34
|
| 1d | Only names or wording of design paragraphs change. | a short request; no change spec | no |
|
|
34
|
-
| 2 | A real design, in one or a few PRs. | a request and a change spec | if a promise changes |
|
|
35
|
+
| 2 | A real design, in one or a few PRs. | a request and a change spec | if a promise changes, or the request has an R<n> |
|
|
35
36
|
| 3 | A big change, delivered in parts over time. | as path 2, part by part | as path 2 |
|
|
36
37
|
| S | It is not clear yet what to build. | a request with a question | yes, on the question |
|
|
37
38
|
|
|
38
39
|
The promise kinds are purpose, scope, rule, limit and definition. Work that
|
|
39
40
|
grows changes its path: a small change that needs a design becomes path 2.
|
|
40
41
|
|
|
41
|
-
4. Before you ask for review, run `al index`, then `al check`.
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
4. Before you ask for review, run `al index`, then `al check`. A `not ok` is
|
|
43
|
+
one of the few exact rules: a promise change or a requirement version
|
|
44
|
+
with no valid sign-off, changed record evidence, a citation of a
|
|
45
|
+
superseded ADR, or a record that cannot be read. Fix each one. A hint is
|
|
46
|
+
for the review, not a verdict: deal with it, or say in the PR why it
|
|
47
|
+
stays. A finding has the same severity with or without `--strict`.
|
|
44
48
|
5. Put the claim in a commit message and in the PR, for example
|
|
45
49
|
`Tier: 1 — amends INV-10`. `al check` reads the newest `Tier:` line of the
|
|
46
50
|
branch.
|
|
@@ -63,7 +67,7 @@ The export link MUST expire 30 minutes after the email is sent.
|
|
|
63
67
|
marker. Its ID is retired and never used again. `al check` gives a hint
|
|
64
68
|
that names the deletion; when it is on purpose, nothing more is needed. In
|
|
65
69
|
`specs/`, a removal needs `removes:<ID>` in a change spec: a lost ID there
|
|
66
|
-
|
|
70
|
+
gets a hint that asks for it.
|
|
67
71
|
- For a new paragraph, write the text with no marker. Then run
|
|
68
72
|
`al spec --add-ids <file> --yes`: it gives each unmarked paragraph the next
|
|
69
73
|
free ID. Then write the kind and the links into each new marker.
|
|
@@ -78,10 +82,19 @@ The export link MUST expire 30 minutes after the email is sent.
|
|
|
78
82
|
needs at least one link. In `specs/`, the ID of a change spec paragraph
|
|
79
83
|
names its request: `invoice-exports/SP-12`.
|
|
80
84
|
- An ADR in `specs/adr/` has one marker on its heading: `ADR-<n>`, its kind,
|
|
81
|
-
and its `decides:`, `source:` and `supersedes:` links.
|
|
82
|
-
|
|
83
|
-
`decides:`.
|
|
84
|
-
|
|
85
|
+
and its `decides:`, `source:` and `supersedes:` links. `al check` gives a
|
|
86
|
+
hint for each proposed or accepted ADR with no `source:` or no
|
|
87
|
+
`decides:`.
|
|
88
|
+
- Any text may be rewritten in other words when its meaning stays the same,
|
|
89
|
+
an accepted or superseded ADR's text too. Write a new ADR that supersedes
|
|
90
|
+
it only when the decision changes, in whole or in part. `al check` gives a
|
|
91
|
+
hint on a changed ADR: check that its decision is unchanged. After the
|
|
92
|
+
rewrite, run `al index --align <ID>` for each paragraph that links to it.
|
|
93
|
+
- When an ADR is superseded, set its first line to
|
|
94
|
+
`Status: superseded by ADR-<m>`, and put `supersedes:ADR-<n>` in the marker
|
|
95
|
+
of ADR-m. Where a spec paragraph, an open request or a proposed or accepted
|
|
96
|
+
ADR names ADR-n, name ADR-m beside it: in the same marker for a link, in
|
|
97
|
+
the same paragraph for a word. Else `al check` gives `not ok`.
|
|
85
98
|
- `al` writes every hash and every derived field. Do not write them by hand.
|
|
86
99
|
|
|
87
100
|
## Path 0: a fix
|
|
@@ -127,9 +140,9 @@ The export link MUST expire 30 minutes after the email is sent.
|
|
|
127
140
|
1. `al new <name> --tier 1d --from -`, with a one-line note of where the
|
|
128
141
|
correction comes from.
|
|
129
142
|
2. Change only names or wording of design paragraphs in `specs/`. Add or
|
|
130
|
-
remove no paragraph.
|
|
131
|
-
supersedes it.
|
|
132
|
-
3. Claim `Tier: 1d — <what changes>`. `al check` gives
|
|
143
|
+
remove no paragraph. You may reword an ADR when its decision stays; a
|
|
144
|
+
changed decision is a new ADR that supersedes it.
|
|
145
|
+
3. Claim `Tier: 1d — <what changes>`. `al check` gives a hint when the PR
|
|
133
146
|
touches a promise paragraph, or adds or removes a design paragraph. No
|
|
134
147
|
sign-off is needed.
|
|
135
148
|
4. Run `al conclude <name> --yes` with the PR.
|
|
@@ -138,8 +151,11 @@ The export link MUST expire 30 minutes after the email is sent.
|
|
|
138
151
|
|
|
139
152
|
1. `al new <name> --tier 2 --from -`. Write the organized requirement as in
|
|
140
153
|
path 1, with `Out:` and `Assumed:` lines where they help. Draft freely;
|
|
141
|
-
deliver with the owner's sign-off or after it.
|
|
142
|
-
promise kind
|
|
154
|
+
deliver with the owner's sign-off or after it. Each R<n> needs the
|
|
155
|
+
owner's sign-off, also when the change touches no promise kind: until it
|
|
156
|
+
is signed, `al check` gives `not ok unsigned-requirement`. For a
|
|
157
|
+
design-only change, which needs no sign-off, write the organized section
|
|
158
|
+
with no `### R<n>`: a short note of what the design changes and why.
|
|
143
159
|
2. Write the design in `requests/<name>/spec.md`, the change spec: the
|
|
144
160
|
promises this change adds or changes, its design, its plan. The order
|
|
145
161
|
of the paragraphs is free. The recommended order is one section per
|
|
@@ -198,7 +214,12 @@ project uses them, list them in the record as
|
|
|
198
214
|
`tasks: [{id: T2, ref: "issue #34", delivers: [R3]}]`, and name the task in
|
|
199
215
|
the commit messages of its PRs. Plan, step and migration paragraphs may live
|
|
200
216
|
in the tracker issue that the task's `ref` names, instead of in the change
|
|
201
|
-
spec.
|
|
217
|
+
spec. `al` never contacts a tracker: save the items in a folder (the README
|
|
218
|
+
has the format and the `gh` commands), and `al check --issues <folder>`
|
|
219
|
+
gives hints on them: an item missing from the folder, a superseded ADR
|
|
220
|
+
named without its successor, a bare `#n` in another repository's item, an
|
|
221
|
+
item that is not a child of the request's own item, and the phrases of
|
|
222
|
+
`phrases:` in `.assuredloop/config.yaml`. Run `al conclude <name> --yes` with the last part.
|
|
202
223
|
|
|
203
224
|
## Path S: a spike
|
|
204
225
|
|