@naswerks/engineering-loop 0.8.0 → 0.9.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +94 -0
- package/package.json +1 -1
- package/references/docs-workflow.md +1 -1
- package/references/engineering-loop.md +4 -3
- package/skills/init/scripts/doctor.mjs +26 -0
- package/skills/spec-build/SKILL.md +4 -0
- package/skills/spec-coordinator/SKILL.md +48 -24
- package/skills/spec-pipeline/SKILL.md +27 -6
- package/skills/spec-retro/SKILL.md +5 -5
- package/skills/spec-review/SKILL.md +10 -4
- package/skills/spec-seat/SKILL.md +54 -27
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naswerks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "The engineering loop: a knowledge loop (docs-*) and an execution loop (spec-*) for repositories driven by hosted agent sessions, plus init to make a repository ready for both.",
|
|
5
5
|
"author": { "name": "naswerks" },
|
|
6
6
|
"license": "MIT",
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,100 @@ version is the one in `package.json` and `.claude-plugin/plugin.json`, which mus
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.9.0] - 2026-11-14
|
|
9
|
+
|
|
10
|
+
A minor: the skills act differently, the doctor can newly fail a brief, and a repository's copy of the loop text
|
|
11
|
+
takes one paragraph (§ Upgrading from 0.8). A pipeline that writes one repository runs as it did.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **A seat may also write a second repository: the `Repository` column.** A sequence row names the repositories its
|
|
16
|
+
seat also writes in, in an optional `Repository` column: one or more names, as the runner serves them. The column
|
|
17
|
+
never moves a seat: its home is the pipeline's own repository, where its spec, its board and the tracker are, and
|
|
18
|
+
one pull request still closes the pipeline. `spec-pipeline` states the column. `init doctor` reads it the way a
|
|
19
|
+
launcher does, and fails a cell holding a kind word, `step`, a name that is not one path segment of at most 200
|
|
20
|
+
characters, a ninth name, or a name twice. **A pipeline that writes one repository has no such column and is
|
|
21
|
+
unchanged.**
|
|
22
|
+
- **What a seat does in a second repository** (`spec-seat` § Git shapes, `spec-build`). Its home stays this
|
|
23
|
+
repository and nothing of the pipeline's record is written in the other one. Its code goes in its own tree of
|
|
24
|
+
that repository, never the owner's checkout: hosted, at the path the variable its seed names holds; by hand, at
|
|
25
|
+
the path its prompt names. Then a staging list, a `verify-staged` receipt, a commit and a push per repository;
|
|
26
|
+
that repository's whole gate, run in its tree; its own rules for commit and pull-request text; a draft pull
|
|
27
|
+
request where it checks them, its checks read after every push; no merge, tag or publish. Its commit there goes
|
|
28
|
+
on an `ALSO WRITING` line beneath BELIEFS, and its FINAL gives a list and a receipt per repository. A pin holds
|
|
29
|
+
every clause, because a launcher that knows this version says only where the tree is.
|
|
30
|
+
- **The push in a second repository has its own form:** `cd` into the tree, then the push, and nothing else on the
|
|
31
|
+
line. `spec-seat` said a leading `cd` disqualifies every push; that is the rule for the home repository, and it
|
|
32
|
+
now says so.
|
|
33
|
+
- **The coordinator's and the review's side of a second repository.** `spec-coordinator` tells such a seat where
|
|
34
|
+
its tree is and nothing else (by hand; hosted, the seed says where), diffs its `ALSO WRITING` line, checks two
|
|
35
|
+
receipts at the FINAL, reads a pull request's checks at every seat report in whichever repository the branch is,
|
|
36
|
+
and hands the review one diff range per repository (by release tags when the run released it mid-run).
|
|
37
|
+
`spec-review` reads each range and the seam between them. A pin holds every template line for a further
|
|
38
|
+
repository under a line saying when it applies.
|
|
39
|
+
- **A conditional fixit that must write a further repository is listed as a row, directly after the review row**
|
|
40
|
+
(`spec-pipeline`). Listed anywhere else, a launcher reads a second fixit beside the one the review implies, and
|
|
41
|
+
the doctor names it.
|
|
42
|
+
- **The model and the effort a run starts on are named in the brief and read back.** `spec-pipeline`'s `## Birth`
|
|
43
|
+
names both, each in backticks, because the launcher reads them from that section; a brief that names neither
|
|
44
|
+
leaves both to the launcher's default. A seat's BELIEFS line states the model and effort its session is running
|
|
45
|
+
on, as it can read them, and `spec-coordinator` settles a seat on a pair the brief does not name before it rules
|
|
46
|
+
that seat's plan.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **Pipelines never intertwine** replaces "one pipeline at a time", in `spec-coordinator`'s hard rules and in
|
|
51
|
+
`references/engineering-loop.md`. A brief's GATE still checks only that its predecessor merged, and no seat waits
|
|
52
|
+
on another pipeline; independent pipelines may run at the same time, each on its own branch. The coordinator takes
|
|
53
|
+
a moved base branch in between seats, by a merge. A repository's `docs/_meta/` copy takes the paragraph by hand.
|
|
54
|
+
- **A review's diff range reads the remote's copy of the base branch** (`origin/{base}...{branch}`), in
|
|
55
|
+
`spec-coordinator`'s REVIEW manifest, `spec-review` and `spec-pipeline`: a local base branch can sit behind it and
|
|
56
|
+
pull another effort's commits into the range.
|
|
57
|
+
- **`spec-coordinator`'s Step 0 is two numbered reads:** the seven floor docs, then every doc the repository's role
|
|
58
|
+
reading lists carry a path for. The second read was a trailing clause, and coordinators read the floor and stopped.
|
|
59
|
+
The status readback opens with how many docs each read took.
|
|
60
|
+
- **The coordinator edits its tracker and a seat's board with file tools, never a shell heredoc or an interpreter
|
|
61
|
+
one-liner** (`spec-coordinator`): one collapses backslashes, and one whose text quotes a publish is held.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- `spec-coordinator` said a backticked sha is fine for the plan verdict's workspace HEAD. The verb takes only the
|
|
66
|
+
bare 40-hex sha and refuses a backticked or quoted one, recording nothing, so a coordinator that followed the skill
|
|
67
|
+
spent a refused call on every plan ruling. It now says the bare sha; a seat's board may still fence its own.
|
|
68
|
+
- `spec-coordinator` wrote an amount as a dollar sign before a digit, which a harness that substitutes a skill's
|
|
69
|
+
arguments by position rewrote at load: the line about uncosted turns read with the invocation's first argument in
|
|
70
|
+
the amount's place. The amount is spelled out, and a pin holds every skill's text free of a dollar sign before a
|
|
71
|
+
digit and of the arguments token.
|
|
72
|
+
- `spec-seat`, `spec-coordinator` and `spec-retro` said the gate matches text and told a seat to keep git words out
|
|
73
|
+
of echo labels, section headers and searches. The gate reads the command the shell would run: what parks is the
|
|
74
|
+
operation, at any depth, and an echo label, a branch listing and a quoted search are data unless something on the
|
|
75
|
+
line could run them. Six passages say so now, in fewer lines, and a pin keeps the old rule out.
|
|
76
|
+
- `spec-seat` said the HEAD check takes the first `HEAD <sha>` it meets. It reads the newest line that carries
|
|
77
|
+
`BELIEFS`, so a seat whose HEAD moved appends a new BELIEFS line and never edits the old one.
|
|
78
|
+
|
|
79
|
+
### Upgrading from 0.8
|
|
80
|
+
|
|
81
|
+
In this order:
|
|
82
|
+
|
|
83
|
+
1. **Take the release where every session loads it:** `claude plugin marketplace update engineering-loop`, then
|
|
84
|
+
`claude plugin update naswerks@engineering-loop --scope <scope>` for each scope that runs sessions, and a new
|
|
85
|
+
session. A runner takes `@naswerks/engineering-loop@0.9.0` in the folder its plugin directories name, and is
|
|
86
|
+
restarted by its owner with no seat live.
|
|
87
|
+
2. **Replace one paragraph of loop text.** In `docs/_meta/engineering-loop.md`, the paragraph that opens
|
|
88
|
+
**One pipeline at a time.** becomes:
|
|
89
|
+
|
|
90
|
+
> **Pipelines never intertwine.** A pipeline's GATE is that its predecessor merged — never a seat of another
|
|
91
|
+
> pipeline — and no seat waits on another pipeline. Independent pipelines may run at the same time, each on
|
|
92
|
+
> its own branch, merged one after the other.
|
|
93
|
+
|
|
94
|
+
It is the only loop text that changed. `docs/_meta/docs-workflow.md` takes nothing but its stamp, and the four
|
|
95
|
+
repository-owned sections are yours and are not touched.
|
|
96
|
+
3. **Restamp and check:** `init refresh` (with `--write`) restamps both copies and leaves every other line as it
|
|
97
|
+
is; then `init doctor`. A repository that read clean on 0.8.0 reads clean, unless a brief lists a `fixit` row
|
|
98
|
+
away from its `review` row or holds a `Repository` cell that is not a list of names.
|
|
99
|
+
|
|
100
|
+
No pipeline folder changes shape, and a sequence with no `Repository` column reads as it always has.
|
|
101
|
+
|
|
8
102
|
## [0.8.0] - 2026-10-21
|
|
9
103
|
|
|
10
104
|
A minor: the skills act differently, and a repository must act — its method docs take new text, and every
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naswerks/engineering-loop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "The engineering loop as a Claude Code plugin: a knowledge loop (docs-*), an execution loop (spec-*), and init for a fresh repository. The package root is the plugin root.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- naswerks-loop: version=0.
|
|
1
|
+
<!-- naswerks-loop: version=0.9.0 -->
|
|
2
2
|
# The Engineering Loop — flow, seats, skills, and the ceremony
|
|
3
3
|
|
|
4
4
|
> The quick intro to how work gets built with this loop: the two loops (`docs-*` knowledge, `spec-*`
|
|
@@ -74,8 +74,9 @@ owner's — never a seat's job and never a doc's row: the coordinator offers a s
|
|
|
74
74
|
the chat, and `live-checks.md` holds only the rows the owner dictates. Everything between `idea` and
|
|
75
75
|
`archived` a pipeline can do for itself.
|
|
76
76
|
|
|
77
|
-
**
|
|
78
|
-
pipeline — and
|
|
77
|
+
**Pipelines never intertwine.** A pipeline's GATE is that its predecessor merged — never a seat of another
|
|
78
|
+
pipeline — and no seat waits on another pipeline. Independent pipelines may run at the same time, each on
|
|
79
|
+
its own branch, merged one after the other.
|
|
79
80
|
|
|
80
81
|
**`docs-audit-*` is never a pipeline row.** It runs off-hours and scheduled, over the whole doc tree — not
|
|
81
82
|
inside an effort, and not at an effort's close. A stale living doc is not something a pipeline must stop for.
|
|
@@ -197,6 +197,11 @@ for (const name of ['CLAUDE.md', 'AGENTS.md']) {
|
|
|
197
197
|
// The kick is sent verbatim as the coordinator's task, so a skill it names that this pack does not carry
|
|
198
198
|
// (a renamed one, most often) tells the coordinator to invoke nothing.
|
|
199
199
|
const packSkills = new Set(existsSync(join(packRoot, 'skills')) ? readdirSync(join(packRoot, 'skills')) : []);
|
|
200
|
+
// A repository's name as a sequence row may write it: one path segment, no separators, no spaces, of at most
|
|
201
|
+
// MAX_REPOSITORY_NAME characters; a row names at most MAX_REPOSITORIES, none twice.
|
|
202
|
+
const REPOSITORY_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
203
|
+
const MAX_REPOSITORY_NAME = 200;
|
|
204
|
+
const MAX_REPOSITORIES = 8;
|
|
200
205
|
const researchDir = join(repo, 'docs', 'research');
|
|
201
206
|
if (existsSync(researchDir)) {
|
|
202
207
|
for (const topic of readdirSync(researchDir)) {
|
|
@@ -217,17 +222,38 @@ if (existsSync(researchDir)) {
|
|
|
217
222
|
const cellsOf = (line) => line.trim().replace(/^\|/, '').replace(/\|$/, '').split('|').map((c) => c.trim().replace(/^`|`$/g, '').trim());
|
|
218
223
|
// The optional Role column, found by its header; a row's cell there is a role or empty.
|
|
219
224
|
const roleAt = tableRows.length ? cellsOf(tableRows[0]).findIndex((c) => c.toLowerCase() === 'role') : -1;
|
|
225
|
+
// The optional Repository column, found by its header; a row's cell there names the repositories the
|
|
226
|
+
// seat also writes in, or is empty. The table is read by kind value, so a kind word or `step` in that
|
|
227
|
+
// cell would be read as the row's kind: it fails by name, before either is looked for.
|
|
228
|
+
const repositoryAt = tableRows.length ? cellsOf(tableRows[0]).findIndex((c) => c.toLowerCase() === 'repository') : -1;
|
|
229
|
+
// The seat rows' kinds, in order: where a listed fixit sits is read from them.
|
|
230
|
+
const seatKinds = [];
|
|
220
231
|
for (const line of tableRows.slice(1)) {
|
|
221
232
|
const cells = cellsOf(line);
|
|
222
233
|
if (cells.every((c) => /^[-: ]*$/.test(c))) continue;
|
|
223
234
|
const spec = cells.map((c) => SPEC_FILE.exec(c)).find(Boolean);
|
|
224
235
|
if (spec) named.add(spec[1]);
|
|
236
|
+
const repositories = repositoryAt >= 0 ? (cells[repositoryAt] ?? '') : '';
|
|
237
|
+
const names = !repositories || /^[-—]$/.test(repositories) ? [] : repositories.split(/\s*[·,]\s*/).map((n) => n.replace(/`/g, '').trim()).filter((n) => n !== '');
|
|
238
|
+
const notNames = names.filter((n) => KINDS.includes(n) || n === STEP || !REPOSITORY_NAME.test(n) || n.length > MAX_REPOSITORY_NAME);
|
|
239
|
+
if (notNames.length) {
|
|
240
|
+
for (const n of notNames) problems.push(`a sequence row's repository \`${n.length > 60 ? `${n.slice(0, 60)}…` : n}\` is not a repository's name (one path segment of at most ${MAX_REPOSITORY_NAME} characters; a kind word or \`${STEP}\` there is read as the row's kind): \`${line.trim().slice(0, 200)}\``);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (names.length > MAX_REPOSITORIES) problems.push(`a sequence row names ${names.length} repositories and a seat writes at most ${MAX_REPOSITORIES}: \`${line.trim()}\``);
|
|
244
|
+
for (const n of new Set(names.filter((name, i) => names.indexOf(name) !== i))) problems.push(`a sequence row names the repository \`${n}\` twice: \`${line.trim()}\``);
|
|
225
245
|
if (cells.includes(STEP)) continue;
|
|
226
246
|
if (!cells.some((c) => KINDS.includes(c))) { problems.push(`a sequence row names no seat kind and composes nothing (a row that is not a seat says \`${STEP}\`): \`${line.trim()}\``); continue; }
|
|
247
|
+
seatKinds.push(cells.find((c) => KINDS.includes(c)));
|
|
227
248
|
const role = roleAt >= 0 ? (cells[roleAt] ?? '') : '';
|
|
228
249
|
if (role && !/^[-—]$/.test(role) && !ROLES.includes(role)) problems.push(`a sequence row's role \`${role}\` is not one of ${ROLES.map((r) => `\`${r}\``).join(' · ')}: \`${line.trim()}\``);
|
|
229
250
|
if (spec && !existsSync(join(researchDir, topic, spec[1]))) problems.push(`the sequence names \`${spec[1]}\` and it is missing from disk`);
|
|
230
251
|
}
|
|
252
|
+
// A listed fixit is the one its review implies only when it is the next seat row after that review. Listed
|
|
253
|
+
// anywhere else, a launcher reads a second fixit beside the implied one, and that one names no repository.
|
|
254
|
+
const reviewAt = seatKinds.indexOf('review');
|
|
255
|
+
const fixitAt = seatKinds.indexOf('fixit');
|
|
256
|
+
if (reviewAt >= 0 && fixitAt >= 0 && fixitAt !== reviewAt + 1) problems.push('the sequence lists a `fixit` row that is not the next seat row after its `review` row, so a launcher reads two fixits and the extra one names no repository: move the row directly after the review');
|
|
231
257
|
}
|
|
232
258
|
// An old-shape folder carries an umbrella: a `01-` file no sequence row names. It still runs on an older
|
|
233
259
|
// pack; carry it over before it runs on this one.
|
|
@@ -93,6 +93,10 @@ signal that a VERDICT changed, not that the test is stale.
|
|
|
93
93
|
Run the suite lanes **SERIALLY** — the lanes and their exact invocations are `patterns/testing.md`
|
|
94
94
|
§ Running tests; concurrent runs flake.
|
|
95
95
|
|
|
96
|
+
**A seat that wrote a further repository runs THAT repository's gate too, inside its tree of it** — the
|
|
97
|
+
lanes its own contributing rules name, serially, never beside this repository's — and reports each
|
|
98
|
+
repository's summaries under its own name. This repository's lanes do not run the code you wrote there.
|
|
99
|
+
|
|
96
100
|
**Capture FULL runner output to a UTF-8 file and search failures by name** — redirect to a file, then
|
|
97
101
|
search `^failed ` / `Failed!`. Piping through a "last N lines" filter destroys failure names.
|
|
98
102
|
|
|
@@ -35,14 +35,15 @@ hand-testing what shipped. Everything else that a human does hand-cranked, you d
|
|
|
35
35
|
|
|
36
36
|
## Read first
|
|
37
37
|
|
|
38
|
-
**Step 0 —
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
cannot spot a hand-written generated file.
|
|
38
|
+
**Step 0 — two reads, and neither is optional.** You verify every seat's work, so you start from the
|
|
39
|
+
context they build in. A coordinator that has not read `testing.md` cannot judge a receipt; one that has
|
|
40
|
+
not read `codegen.md` (when the repo has one) cannot spot a hand-written generated file.
|
|
42
41
|
|
|
43
|
-
`_meta/doc-index.md` · `_meta/docs-workflow.md` ·
|
|
44
|
-
`
|
|
45
|
-
`patterns/
|
|
42
|
+
1. **The floor every seat reads, all seven:** `_meta/doc-index.md` · `_meta/docs-workflow.md` ·
|
|
43
|
+
`_meta/engineering-loop.md` · `patterns/code-organization.md` · `patterns/backend-patterns.md` ·
|
|
44
|
+
`patterns/frontend-patterns.md` · `patterns/testing.md`.
|
|
45
|
+
2. **Then every doc `doc-index.md` § Role reading lists carries a path for.** Open that section and read
|
|
46
|
+
each one. The floor alone is not Step 0.
|
|
46
47
|
|
|
47
48
|
**Step 1 — the effort**, in order:
|
|
48
49
|
|
|
@@ -67,8 +68,9 @@ now, and again before you cut the retro. **A disagreement is a finding, not a ty
|
|
|
67
68
|
changed in one place and not the other. Say which is right, fix the other, and journal it.
|
|
68
69
|
|
|
69
70
|
Then produce a **5-line status readback** — shipped / in flight / next action / next prompt you expect to
|
|
70
|
-
cut. Hand-cranked that goes to the human so
|
|
71
|
-
opening journal entry in `project-status.md`,
|
|
71
|
+
cut — opening with how many docs each of Step 0's two reads took. Hand-cranked that goes to the human so
|
|
72
|
+
they can confirm the seat transferred; hosted it is your opening journal entry in `project-status.md`,
|
|
73
|
+
which is how anyone watching the cockpit catches up.
|
|
72
74
|
|
|
73
75
|
**Same-session graduation:** you just ran `spec-pipeline`, so you already hold most of Step 1 — confirm
|
|
74
76
|
the tracker exists and cut Prompt #1. **Step 0 still applies.**
|
|
@@ -88,7 +90,7 @@ plus the human relay.
|
|
|
88
90
|
| Verb | What it does | The part that bites |
|
|
89
91
|
|---|---|---|
|
|
90
92
|
| `seat_spawn` | Opens a DECLARED sibling's session | **It can never CREATE a seat** — the topology is the create door's, decided by a human — and you may only drive seats you `supervises`/`reviews`. With no `hostId` it opens on the host carrying your own session; `model` and `effort` override the seat's own for this session, judged against what the runner offers |
|
|
91
|
-
| `accept_plan` | The verdict act: `accept` · `accept-with-riders` · `blocking-precondition`, **and NOTHING ELSE carries a go** — and it DELIVERS ITSELF: the seat's live session receives a one-line pointer to the ruling, for an accepting verdict and for any verdict that filed a ruling in the seat's file | Write the ruling into the seat's `tldr.md` FIRST (`## COORDINATOR RULING (plan rev N — {verdict})`), then call with a one-line `ruling`: the file is mirrored before your act and the pointer names your section. Pass the workspace HEAD you observed
|
|
93
|
+
| `accept_plan` | The verdict act: `accept` · `accept-with-riders` · `blocking-precondition`, **and NOTHING ELSE carries a go** — and it DELIVERS ITSELF: the seat's live session receives a one-line pointer to the ruling, for an accepting verdict and for any verdict that filed a ruling in the seat's file | Write the ruling into the seat's `tldr.md` FIRST (`## COORDINATOR RULING (plan rev N — {verdict})`), then call with a one-line `ruling`: the file is mirrored before your act and the pointer names your section. Pass the workspace HEAD you observed as the bare 40-hex sha `git rev-parse HEAD` prints — a backticked or quoted one is refused and records nothing, though a seat's board may fence its own; an accepting verdict whose seat planned against a different tree is REFUSED, naming both shas. READ THE REPLY'S `delivery:` and `file:` LINES — `NOT DELIVERED` means the seat is idle and only a `callout` reaches it. When the verdict also answers the seat's question, pass `answeringActId` — one act rules and closes it |
|
|
92
94
|
| `accept` | The rev-bound FINAL receipt — and it TELLS the seat, so it carries your commit call | Put the next instruction (commit, push, close-out) in `ruling`, or write it under `## COORDINATOR ACCEPT` in the seat's `tldr.md` first — the receipt then binds to that mirrored revision. It binds to the seat's CURRENT tldr revision, so if the seat posts NEW CONTENT again your acceptance no longer covers what it publishes. **Re-accept — it is idempotent and cheap.** This receipt is what the push bar reads; prose is not a receipt. `answeringActId` closes the question it answers, as on `accept_plan` |
|
|
93
95
|
| `complete` | The reap, and it is HONEST | It re-reads the seat and reports ok only after the terminal state is OBSERVED |
|
|
94
96
|
| `callout` | **THE ONLY WAY YOU REACH A CHARGE** (besides the pointers `accept_plan` and `accept` send) | A charge that posted and ended its turn cannot resume any other way — without this verb it waits for a human. Your ruling must carry a DETERMINATE NEXT ACTION it can execute without inference. **Write it into the seat's `tldr.md` first and pass a one-line `ruling`:** the file is mirrored before your act and the seat is pointed at your section. Without a file, KEEP IT TO A LINE: over 600 chars the body is stored as a `ruling` artifact on the board and the seat receives a POINTER — the seat reads the body once, never twice |
|
|
@@ -171,6 +173,8 @@ and a seat's close-out. Never reconstruct it at the close.
|
|
|
171
173
|
call out / hand the human both sides when the call is genuinely theirs.
|
|
172
174
|
**The accepting verdict carries the workspace HEAD you observed, and a seat that planned against a
|
|
173
175
|
different tree is REFUSED with both shas named.** So read the BELIEFS sha before you rule, not after.
|
|
176
|
+
**A seat whose row names a further repository states that tree too,** on an `ALSO WRITING` line beneath
|
|
177
|
+
its BELIEFS: diff its commit and branch against that repository's branch, with your own `git` read of it.
|
|
174
178
|
**AND GRADE THE `CONTROLS` LINE — it is a required PLAN TLDR field and you are its only reader.** For
|
|
175
179
|
every probe or pin the seat plans, it must name the positive control and what would make it FAIL. A
|
|
176
180
|
missing or hand-wavy `CONTROLS` line is a rider, not a nit: a control that cannot fail is a green light
|
|
@@ -188,6 +192,8 @@ and a seat's close-out. Never reconstruct it at the close.
|
|
|
188
192
|
But spot-check the riskiest claim yourself (never trust self-reported "N green"), and **verify your own
|
|
189
193
|
rulings were APPLIED** — a ruling can silently drop, and a seat can rebuild the exact problem
|
|
190
194
|
the ruling solved. Diff the shipped behavior against your ruling list before accepting.
|
|
195
|
+
**A seat that wrote two repositories returns two of everything:** a staging list and its receipt per
|
|
196
|
+
repository, and each repository's gate under its own name. A green in one says nothing about the other.
|
|
191
197
|
**VERIFY THE CLAIM WHOSE FAILURE WOULD BE SILENT; MACHINE-COMPARE THE REST.** That is the rule that
|
|
192
198
|
keeps your own share of the spend honest — a seat producing receipts that reconcile arithmetically has
|
|
193
199
|
already done the work you would be repeating.
|
|
@@ -202,6 +208,10 @@ and a seat's close-out. Never reconstruct it at the close.
|
|
|
202
208
|
**Advance the tracker AT EVERY CHECKPOINT.** Plan accepted: the row says so; final TLDR accepted: the
|
|
203
209
|
row says so; push confirmed: SHIPPED with the hash. A stale tracker is your omission.
|
|
204
210
|
|
|
211
|
+
**WHEN A BRANCH A SEAT PUSHES HAS A PULL REQUEST OPEN, READ ITS CHECKS AT EVERY SEAT REPORT,** in
|
|
212
|
+
whichever repository it is, with your own read and not the seat's sentence about it: a check read at
|
|
213
|
+
the first commit says nothing about the tenth.
|
|
214
|
+
|
|
205
215
|
**CLOSING A HUMAN STEP: TAKE THE RECEIPT, DO NOT WRITE IT.** A `step` row has no seat to post a TLDR,
|
|
206
216
|
so the temptation is to transcribe the sitting into your tracker and call the step recorded. **That
|
|
207
217
|
leaves it with ONE voice — yours — and it is the only row in the effort with one.** Ask the human
|
|
@@ -330,9 +340,7 @@ and a seat's close-out. Never reconstruct it at the close.
|
|
|
330
340
|
`docs/_meta/engineering-loop.md` § This repository's rails (repository-owned) says (when it names no
|
|
331
341
|
route, ask the human once and suggest recording the answer there); if one is already open the push is
|
|
332
342
|
enough. These are your own git — gated and receipted like any other publish. **The
|
|
333
|
-
push command must be the ENTIRE command** (a leading `cd` disqualifies it)
|
|
334
|
-
out of any echo label around it — the deny layer matches TEXT, not parsed verbs, and a decorative
|
|
335
|
-
`=== remote tip ===` header over a read-only block will park.
|
|
343
|
+
push command must be the ENTIRE command** (a leading `cd` disqualifies it).
|
|
336
344
|
6. **Report the close:** commits, receipts, total cost with its uncosted-turn count, the findings ledger,
|
|
337
345
|
and the explicit list of what the human still owns. **The merge is theirs, never yours.**
|
|
338
346
|
7. **If the effort has a DOCS-PROCESS row, it runs last** — after the PR exists, as its own session,
|
|
@@ -397,7 +405,7 @@ so read them as run-time obligations, not close-out ones:
|
|
|
397
405
|
- **Verify a query FIRES on a known-positive before you trust a clean result.** A silently-empty result
|
|
398
406
|
is usually a broken query, not an empty table — and a false all-clear on an audit query is worse than
|
|
399
407
|
no query.
|
|
400
|
-
- **Costs: uncosted
|
|
408
|
+
- **Costs: an uncosted turn counts as nothing**, so any total is a FLOOR while the uncosted-turn count is above zero.
|
|
401
409
|
Report it with the count. **Never sum across instruments** — session footers ride the seats' wakes and
|
|
402
410
|
omit your own spend.
|
|
403
411
|
|
|
@@ -409,8 +417,10 @@ so read them as run-time obligations, not close-out ones:
|
|
|
409
417
|
approved seat commits and pushes its branch itself (the relay, below); hosted, the commit call rides your
|
|
410
418
|
acceptance. The PR is yours at the close. The merge is the human's, always. Explicit staging only —
|
|
411
419
|
never `git add -A` — and never a push to the base branch.
|
|
412
|
-
- **
|
|
413
|
-
another pipeline's seats, and never
|
|
420
|
+
- **Pipelines never intertwine.** A brief's GATE checks only that its predecessor merged; never gate a run
|
|
421
|
+
on another pipeline's seats, and never make a seat wait on one. Independent pipelines may run at the same
|
|
422
|
+
time, each on its own branch; never two over the same files or on one branch. When the base branch moves
|
|
423
|
+
under your run, take it in between seats, by a merge, never under a live seat and never as a rebase.
|
|
414
424
|
- **Never advise or run a runner restart while a seat is live.** A restart ends every live session on that
|
|
415
425
|
runner, and the plane may not notice. "Restarting it is fine" said to the human in that state is how a
|
|
416
426
|
run loses every seat at once; say instead which seats are live and that the restart waits.
|
|
@@ -426,9 +436,9 @@ so read them as run-time obligations, not close-out ones:
|
|
|
426
436
|
- **The unattended git form, and it binds YOU as much as the seats: one git command per call, no shell
|
|
427
437
|
metacharacters.** The FORM check reads the whole command string, so chaining, redirects or substitution
|
|
428
438
|
disqualify it — `git add … && git commit … && git push …` parks, while the same three sent separately
|
|
429
|
-
flow. Pushes always name the refspec; a push without one parks by design.
|
|
430
|
-
|
|
431
|
-
|
|
439
|
+
flow. Pushes always name the refspec; a push without one parks by design. The gate reads the command
|
|
440
|
+
the shell would run, not its words: an echo label or a quoted search naming a git verb is data, unless
|
|
441
|
+
a shell or an interpreter is on the same line.
|
|
432
442
|
- Seats never edit `project-status.md`, `live-checks.md` or memory files; never run `docs-write` unprompted;
|
|
433
443
|
respect the brief's § What this effort does NOT do; codegen only through the command `patterns/codegen.md` § Running codegen
|
|
434
444
|
names (when the repo has one); component files laid out as `patterns/frontend-patterns.md` § Component files states. Run the
|
|
@@ -438,9 +448,11 @@ so read them as run-time obligations, not close-out ones:
|
|
|
438
448
|
- **Cite symbols, not bare `file:line`.** In a seed, a ruling, or the tracker, name the symbol and use the
|
|
439
449
|
line as a hint — a line number is a comment, not an address, and the seat documenting why a line matters
|
|
440
450
|
is what moves it.
|
|
441
|
-
- Model policy: seats run **the effort's declared default model**
|
|
442
|
-
investigation-heavy sessions may warrant a
|
|
443
|
-
the
|
|
451
|
+
- Model policy: seats run **the effort's declared default model and effort** — the pair the brief's
|
|
452
|
+
`## Birth` names (allowlist-exact, set at creation); investigation-heavy sessions may warrant a
|
|
453
|
+
reasoning-heavier one. **A seat's BELIEFS line states the pair it started on, and one the brief does not
|
|
454
|
+
name is settled before you rule its plan:** re-open the seat on the named pair, or rule the difference in
|
|
455
|
+
by name. Parallel sessions only when the specs share no files — and sequence the *commits* regardless.
|
|
444
456
|
- **The gate is inverted (means are free, protocol is law):** benign tools/methods flow with audit rows;
|
|
445
457
|
only the ceremony's boundaries park — in EVERY tier, recon included. Reads, execs, suites, pipes,
|
|
446
458
|
redirects and in-worktree writes all flow pre-accept. **Do not seed tool-avoidance rules the platform
|
|
@@ -507,6 +519,9 @@ role={backend | frontend | mixed} before anything else, and ALWAYS after `spec-s
|
|
|
507
519
|
names `spec-seat` first, the job skill second. <- hand-cranked only; hosted, start at the spec
|
|
508
520
|
|
|
509
521
|
Your spec: {absolute path to the spec}
|
|
522
|
+
{only when the seat's row names a further repository, one line each; hand-cranked only — hosted, the
|
|
523
|
+
seed says where:}
|
|
524
|
+
You also write: {repository} — your tree of it is {absolute path}, on branch {branch}. Never its owner's checkout.
|
|
510
525
|
Pipeline context: {brief path} — the charter: its sections down to § Platform state bind you, and the owner's
|
|
511
526
|
rulings in it are settled (don't relitigate) + {project-status.md path}
|
|
512
527
|
(READ-ONLY, coordinator-owned — prior rows, deferred findings, and process incidents are your contract).
|
|
@@ -529,6 +544,10 @@ Baselines (cite, don't re-measure): {per lane, from the brief's § Baselines: N
|
|
|
529
544
|
THE TASK: {compressed spec restatement with the load-bearing specifics inline.}
|
|
530
545
|
```
|
|
531
546
|
|
|
547
|
+
**A seat that also writes a further repository is told WHERE, and nothing else about it:** what it does
|
|
548
|
+
there is `spec-seat` § Git shapes, and a prompt that restates it is a second copy of the contract. A seat
|
|
549
|
+
whose row names none gets no such line, and a prompt exactly as it would have been.
|
|
550
|
+
|
|
532
551
|
For investigation-first work, add **STEP 0 — INVESTIGATE, REPORT, STOP** before the task, or use
|
|
533
552
|
`role={...} fixit` for no-spec defect sessions (the skill carries the fix-it ceremony). Fallback: if the
|
|
534
553
|
seat can't invoke skills, paste the ceremony from the `spec-build` skill inline.
|
|
@@ -546,7 +565,10 @@ second** — this is the whole point of the row.
|
|
|
546
565
|
```
|
|
547
566
|
REVIEW row (R):
|
|
548
567
|
You are the REVIEW SEAT: invoke the spec-review skill before anything else.
|
|
549
|
-
Topic: {topic} · branch: {branch} · diff range: {base}...{branch}
|
|
568
|
+
Topic: {topic} · branch: {branch} · diff range: origin/{base}...{branch}
|
|
569
|
+
{when the run wrote a further repository, one more line each:}
|
|
570
|
+
Also: {repository}, at {its path} · diff range: origin/{its base}...{its branch}, or by its release
|
|
571
|
+
tags ({the release before}...{this run's release}) when the run released it mid-run
|
|
550
572
|
The brief, down to § Platform state and never past it (read as claims, not facts):
|
|
551
573
|
docs/research/{topic}/00-ignition-brief.md
|
|
552
574
|
Specs (read as claims, not facts): {every numbered spec path}
|
|
@@ -687,7 +709,9 @@ post-merge.
|
|
|
687
709
|
- **The tracker is the seat — ONE ledger, and you write it live.** `project-status.md` is your journal: you
|
|
688
710
|
own it, you advance it at every boundary, and the human never edits it. That file, not the chat, is the
|
|
689
711
|
product of this skill. **The mechanism is ordinary file tools** — edit it exactly as a seat edits
|
|
690
|
-
`tldr.md`/`plan.md`; the gate permits the path.
|
|
712
|
+
`tldr.md`/`plan.md`; the gate permits the path. **Never a shell heredoc or an interpreter one-liner,
|
|
713
|
+
for the tracker or for a seat's board:** one collapses backslashes in what it writes, and one whose
|
|
714
|
+
text quotes a publish is held as if it ran it. Git commits are the receipt: timestamped, attributed,
|
|
691
715
|
carrying the diff.
|
|
692
716
|
- **The session entry is a JOURNAL entry, not a status cell.** The ruling *and its reasoning*, recon
|
|
693
717
|
corrections, what you verified yourself, mid-build directives, and anything you don't want to forget —
|
|
@@ -141,15 +141,27 @@ sessions/ WHO PUTS IT THERE
|
|
|
141
141
|
reading list of a build seat should not be left to the default. Leave the column out when no row needs
|
|
142
142
|
it.
|
|
143
143
|
|
|
144
|
+
**A seat row may name the repositories it ALSO writes in** — in a `Repository` column, when the seat
|
|
145
|
+
builds something that lives in another repository: a package this repository consumes, say. The cell
|
|
146
|
+
holds one or more names, as the runner that carries the seat serves them, separated by ` · ` or `,`;
|
|
147
|
+
an empty cell, `-` or `—` means none. **The column never moves a seat:** its home is always the
|
|
148
|
+
pipeline's own repository, where the specs, the boards and the tracker are. The pipeline still closes
|
|
149
|
+
on ONE pull request, its own repository's; a release of the other repository is a `step` row. Leave
|
|
150
|
+
the column out when no row needs it — most pipelines write one repository, and nothing about them
|
|
151
|
+
changes.
|
|
152
|
+
|
|
144
153
|
Then write the rows into the brief's sequence, in this order:
|
|
145
154
|
|
|
146
155
|
```
|
|
147
156
|
0 the coordinator, with the brief as its spec
|
|
148
157
|
01..NN the build seats, with any `step` rows in their places
|
|
149
|
-
{R} REVIEW — spec-review, if chosen. Runs on `git diff {base}...<branch>` (the rails' base branch); no PR yet
|
|
158
|
+
{R} REVIEW — spec-review, if chosen. Runs on `git diff origin/{base}...<branch>` (the rails' base branch); no PR yet
|
|
150
159
|
{F} FIXIT — MAY materialise, one maximum, only if the review classifies an (a)+(b)
|
|
151
160
|
finding AND the coordinator rules it in. Not authored up front; the
|
|
152
|
-
coordinator charters it from the review's named list
|
|
161
|
+
coordinator charters it from the review's named list. Listed as a row
|
|
162
|
+
only when it must write a further repository: then directly after the
|
|
163
|
+
review row, with its `Repository` cell — anywhere else a launcher reads
|
|
164
|
+
a second fixit beside the one the review implies
|
|
153
165
|
— the coordinator's retro + PR (its own close-out, not a row)
|
|
154
166
|
{P} DOCS-PROCESS — if chosen
|
|
155
167
|
```
|
|
@@ -272,9 +284,15 @@ corrects drift; it does not re-author it.
|
|
|
272
284
|
What is wrong today and what the effort makes true — the vision a seat builds toward.
|
|
273
285
|
|
|
274
286
|
## Birth
|
|
275
|
-
Topic · spec path · receipt prefix · mode (hosted, or by hand) · shape · the effort's branch · the
|
|
276
|
-
chosen at authoring (review? docs-process?) and why ·
|
|
277
|
-
re-verify this brief's § Reference and re-measure
|
|
287
|
+
Topic · spec path · receipt prefix · mode (hosted, or by hand) · shape · the effort's branch · **the model
|
|
288
|
+
and the effort every seat starts on** · the rows chosen at authoring (review? docs-process?) and why ·
|
|
289
|
+
**the GATE**: only that the predecessor merged, then re-verify this brief's § Reference and re-measure
|
|
290
|
+
§ Baselines.
|
|
291
|
+
|
|
292
|
+
**Name the model and the effort, each in backticks** — the word model then the id, the word effort then the
|
|
293
|
+
level (*every seat starts on model `{id}` at effort `{level}`*) — because the launcher reads both from this
|
|
294
|
+
section. Write the id as the runner's catalog offers it. A brief that names neither leaves both to the
|
|
295
|
+
launcher's default; hand-cranked, the same line tells the human which model to open each seat's session on.
|
|
278
296
|
|
|
279
297
|
## The sequence
|
|
280
298
|
| Seat | Spec | Kind | Why it sits here |
|
|
@@ -285,7 +303,10 @@ prose role.** This table is READ, not just read by people: ignition derives the
|
|
|
285
303
|
(`spec-ignite` § the stage card is derived), the create door validates the kind against a closed set and
|
|
286
304
|
refuses an unknown by name, and the doctor fails a row whose kind is none of these. A cell saying "the one
|
|
287
305
|
that reviews" composes nothing. An optional `Role` column carries `backend` · `frontend` · `mixed` for a
|
|
288
|
-
seat whose reading list should not be left to the default.
|
|
306
|
+
seat whose reading list should not be left to the default. An optional `Repository` column names the
|
|
307
|
+
repositories a seat also writes in, by the runner's names; a seat's home is always this repository. Neither
|
|
308
|
+
column's cell may hold a kind word or `step`: the table is read by kind value, and a kind word anywhere in
|
|
309
|
+
a row is read as that row's kind.
|
|
289
310
|
|
|
290
311
|
**This is the only copy of the sequence.** The tracker's status lines name these rows by id and copy
|
|
291
312
|
nothing else.
|
|
@@ -73,9 +73,10 @@ population or only its failures.
|
|
|
73
73
|
silently-empty result is usually a broken query, not an empty table.
|
|
74
74
|
- **A search that times out is not a search that found nothing.** If a sweep backs an ABSENCE claim,
|
|
75
75
|
re-run it on the tool that completes before you report the absence.
|
|
76
|
-
- **
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
- **The gate reads the command the shell would run, not its words.** A quoted search pattern naming a
|
|
77
|
+
boundary operation is data; the same words handed to an interpreter, or carrying a substitution, are read
|
|
78
|
+
as something that could run, and park. **Reshape the command — never re-request it.** (The boundary half
|
|
79
|
+
of `spec-seat`'s discriminator.)
|
|
79
80
|
|
|
80
81
|
**READS ONLY. Never write to the platform's store.**
|
|
81
82
|
|
|
@@ -393,8 +394,7 @@ is the look of a record with none of a record's properties.
|
|
|
393
394
|
§ This repository's rails (repository-owned) says (when it names no route, ask the human once and suggest
|
|
394
395
|
recording the answer there); one branch, one PR from any seat. **If one is already open, the push is enough.** These three git commands are your own close-out
|
|
395
396
|
lane and they are gated and receipted like any other publish. **The push command must be the ENTIRE
|
|
396
|
-
command** — a leading `cd` disqualifies it
|
|
397
|
-
around it; the deny layer matches TEXT, not parsed verbs.
|
|
397
|
+
command** — a leading `cd` disqualifies it.
|
|
398
398
|
6. **Sweep for stale beliefs BY MEANING, NEVER BY PHRASE — and sweep the SIBLINGS that restate a rule, not
|
|
399
399
|
just the rule's own home.** A sweep keyed on wording only finds the wording it thought of. Ask what each
|
|
400
400
|
instruction *depends on being true* — which file it names, which lane it assumes exists, who it thinks
|
|
@@ -35,9 +35,12 @@ else's job.
|
|
|
35
35
|
Your seed carries **no beliefs about the pipeline, and that is deliberate** — but it should carry an
|
|
36
36
|
**inventory**, because you cannot review what you cannot find:
|
|
37
37
|
|
|
38
|
-
- the **topic**, the **branch**, and the **diff range** (`{base}...<branch>` — `{base}` is the base
|
|
39
|
-
`docs/_meta/engineering-loop.md` § This repository's rails (repository-owned) names, or the
|
|
40
|
-
default when it names none
|
|
38
|
+
- the **topic**, the **branch**, and the **diff range** (`origin/{base}...<branch>` — `{base}` is the base
|
|
39
|
+
branch `docs/_meta/engineering-loop.md` § This repository's rails (repository-owned) names, or the
|
|
40
|
+
remote's default when it names none; it is read from the remote's copy, because a local base branch can
|
|
41
|
+
sit behind it and pull another effort's commits into the range);
|
|
42
|
+
- **one more range per further repository the run wrote**, with that repository's path — by its release
|
|
43
|
+
tags when the run released it mid-run, since its branch is merged by then;
|
|
41
44
|
- **the brief** (`00-ignition-brief.md`) — its sections down to § Platform state, read as claims like the
|
|
42
45
|
specs, and **never the coordinator's sections after it** (its beliefs, its close-out, its kick);
|
|
43
46
|
- **every numbered spec path** — you read them as claims, not facts;
|
|
@@ -67,7 +70,10 @@ instrument, and a reader who takes it for a cold one over-trusts its independenc
|
|
|
67
70
|
3. **The working docs** in `docs/working/` — the narrative: what was tried, what failed, what changed.
|
|
68
71
|
4. **The tracker** — `project-status.md`, the coordinator's journal: rulings and their reasoning, recon
|
|
69
72
|
corrections, incidents.
|
|
70
|
-
5. **THEN the diff** — `git diff {base}...<pipeline-branch>`, plus `git log --oneline
|
|
73
|
+
5. **THEN the diff** — `git diff origin/{base}...<pipeline-branch>`, plus `git log --oneline
|
|
74
|
+
origin/{base}..<pipeline-branch>`; and the same pair for each further range your seed names, run inside
|
|
75
|
+
that repository. Read the two sides of a seam together: what one repository ships and what the other
|
|
76
|
+
consumes are one claim.
|
|
71
77
|
|
|
72
78
|
**Read the artifacts before the code, and the code before you conclude.** Reading the diff first makes
|
|
73
79
|
you review a patch; reading the claims first makes you review whether the pipeline did what it said.
|
|
@@ -278,24 +278,19 @@ Ask what the park is protecting:
|
|
|
278
278
|
- **A park on your own legitimate in-worktree work** — **re-request it** (no self-imposed cap, no
|
|
279
279
|
workaround, no silent giving-up) AND disclose ("blocked on X, re-requested N times"). A parked call is
|
|
280
280
|
the platform's turn, not your failure; routing around it hides the defect the park is surfacing.
|
|
281
|
-
- **A park on a boundary command** (push to the base branch, force-push, branch delete — or a command
|
|
282
|
-
|
|
283
|
-
**
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
**
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
the prose you write around a command, not only in the command:** no git-verb vocabulary (push, remote,
|
|
291
|
-
force, reset, branch delete) in any `echo`, comment, `--description` or section label. For upstream
|
|
292
|
-
verification use `git log origin/<branch>..HEAD | wc -l` and `git status -sb`, which carry no colliding
|
|
293
|
-
noun.
|
|
281
|
+
- **A park on a boundary command** (push to the base branch, force-push, branch delete — or a command the
|
|
282
|
+
gate read as one) — **never re-request; reshape the command.**
|
|
283
|
+
**THE GATE READS THE COMMAND THE SHELL WOULD RUN, NOT ITS WORDS.** What parks is the operation — a
|
|
284
|
+
publish, a remote change, a branch deletion, a merge — at any depth: wrapped, chained, or named inside
|
|
285
|
+
another program's words. An `echo` label naming a git verb, a branch listing and a quoted search pattern
|
|
286
|
+
are data to it. **They stop being data when something on the line could run them:** a shell or an
|
|
287
|
+
interpreter anywhere on the line, or a `$`, a backtick or an `xargs` in the pipeline. So keep a proof
|
|
288
|
+
command plain — one program, quoted literals — and give a search to a read-only search tool (`rg`,
|
|
289
|
+
`grep`, `git grep`, `Select-String`, `findstr`).
|
|
294
290
|
**RESHAPE MEANS A DIFFERENT COMMAND, NEVER A DISGUISED ONE — NEVER ROUTE AROUND A REFUSAL.** Rewriting a
|
|
295
|
-
path with a glob or a quote so
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
with the verbatim command and park text, and ask.
|
|
291
|
+
path with a glob or a quote so a word is no longer seen (a `?` in place of one letter of a folder name)
|
|
292
|
+
is a disguise, and the same disguise passes a real boundary command. When the only way through is to
|
|
293
|
+
hide the word, the park is a false one: disclose it, with the verbatim command and park text, and ask.
|
|
299
294
|
- **A POLICY WALL is none of the three.** If the refusal says `walled-by-policy`, **an approval cannot
|
|
300
295
|
grant it** and re-requesting is walking through a known fail-open. The two routes are **reshape the work**
|
|
301
296
|
(do it by a path the policy allows — often: hand the text to a seat whose scope covers it) or
|
|
@@ -325,9 +320,11 @@ Plain text, BEFORE any plan-approval presentation:
|
|
|
325
320
|
|
|
326
321
|
```
|
|
327
322
|
PLAN TLDR ({your assignment}), recon done against HEAD {sha}, anchors {verified fresh / drift: …}:
|
|
328
|
-
BELIEFS: HEAD {sha}; dirty files I see: {list, whose}; tool versions: {the harness, the runtimes
|
|
329
|
-
baseline suites: {cited from the brief's § Baselines, per
|
|
330
|
-
does not name, measured before you edit}.
|
|
323
|
+
BELIEFS: HEAD {sha}; dirty files I see: {list, whose}; tool versions: {the harness, the runtimes, and the
|
|
324
|
+
model and effort this session is running on}; baseline suites: {cited from the brief's § Baselines, per
|
|
325
|
+
lane: N (+known pre-existing reds); a lane it does not name, measured before you edit}.
|
|
326
|
+
{when your row names a further repository, one line each:}
|
|
327
|
+
ALSO WRITING {repository}: commit {sha} on {branch}; dirty files there: {list, whose}.
|
|
331
328
|
CONTROLS: for each probe or pin I will build — its positive control, and what would make it FAIL.
|
|
332
329
|
{one line each: "probe X — control: {the case that must go red}; fails when: {…}"}
|
|
333
330
|
{5-10 lines: what you will do, anchored to real files; the surfaces you will touch; departures flagged.}
|
|
@@ -343,9 +340,18 @@ coordinator with your question text and what the re-raise keys on (the two-headi
|
|
|
343
340
|
**BELIEFS sha — ONE line.** The build-go HEAD check scans for `HEAD` + a 40-hex token **on the same line**
|
|
344
341
|
(fenced or quoted is fine); a markdown break between them reads as a malformed sha and **refuses the
|
|
345
342
|
flip** (fail-closed by design). Paste the verbatim `git rev-parse HEAD` output, never hand-transcribe, no
|
|
346
|
-
wrapping. **Put the BELIEFS line near the top of BOTH `plan.md` and `tldr.md
|
|
347
|
-
|
|
348
|
-
|
|
343
|
+
wrapping. **Put the BELIEFS line near the top of BOTH `plan.md` and `tldr.md`. When your HEAD moves,
|
|
344
|
+
restate it by appending a new `BELIEFS:` line, never by editing the old one:** the check reads the newest
|
|
345
|
+
line that carries `BELIEFS`, and with none it takes the first `HEAD <sha>` it meets, so quoted command
|
|
346
|
+
output carrying another sha is then read as your belief.
|
|
347
|
+
|
|
348
|
+
**A further repository's commit goes on its own `ALSO WRITING` line, beneath the BELIEFS line and never
|
|
349
|
+
beside the word `HEAD`:** the BELIEFS line carries one sha, this repository's, and your coordinator diffs
|
|
350
|
+
the other line against that repository's branch.
|
|
351
|
+
|
|
352
|
+
**The model and effort in that line are the ones you can read, never the brief's copied back.** The brief's
|
|
353
|
+
`## Birth` names the pair every seat starts on, and a seat that finds itself on another says so here, before
|
|
354
|
+
its plan. Write *not visible from here* for a part your session cannot see.
|
|
349
355
|
|
|
350
356
|
**Cite symbols, not line numbers.** In anything that outlives a commit — a TLDR, a working doc, a handover
|
|
351
357
|
— **name the symbol and use the line as a hint.** A line number is a comment, not an address; an anchor
|
|
@@ -424,15 +430,34 @@ doorbell with no follow-through**; if you receive one bare, retry anyway and say
|
|
|
424
430
|
disqualifier is **anything else on the line**, and a leading `cd` — harmless on every OTHER git call you
|
|
425
431
|
make — disqualifies a push (the FORM check reads the whole command string). Qualifying forms, exactly:
|
|
426
432
|
first `git push -u origin <your-branch>`, later `git push origin <your-branch>` (`--set-upstream` also
|
|
427
|
-
qualifies). A push without a refspec parks by design.
|
|
433
|
+
qualifies). A push without a refspec parks by design. This is your push in THIS repository; a further
|
|
434
|
+
repository's push has its own form, below.
|
|
428
435
|
- **EVERY GIT COMMAND GOES ALONE — no shell metacharacters.** The FORM check reads the whole command
|
|
429
436
|
string, so chaining, redirects or substitution disqualify it: `git add … && git commit … && git push …`
|
|
430
|
-
parks where the same three commands, sent one at a time, flow unattended.
|
|
431
|
-
echo text — the deny layer matches text, not parsed verbs.
|
|
437
|
+
parks where the same three commands, sent one at a time, flow unattended.
|
|
432
438
|
- Prefer native read/glob/grep tools for reads; a shell read flows with its row like any other
|
|
433
439
|
non-boundary call. On a periscope 1.4.0 runner they reach anything outside your workspace except
|
|
434
440
|
credential material; on an older runner Read is jailed to your workspace, so read a file outside it —
|
|
435
441
|
the runner's installed package, say — with a shell command.
|
|
442
|
+
- **WHEN YOUR ROW NAMES A FURTHER REPOSITORY, YOU WORK IN TWO TREES, AND EACH KEEPS ITS OWN RULES.** Most
|
|
443
|
+
rows name none, and nothing in this bullet applies to them.
|
|
444
|
+
- **Your home is this repository:** your spec, board, plan and working doc stay here, and nothing of
|
|
445
|
+
the pipeline's record is ever written in the other repository.
|
|
446
|
+
- **The other repository takes your code, in your own tree of it — never its owner's checkout.**
|
|
447
|
+
Hosted, your seed names the environment variable holding that tree's path: read it, never build the
|
|
448
|
+
path. Hand-cranked, your prompt names the path. Read the branch in the tree itself; it need not carry
|
|
449
|
+
this repository's branch name.
|
|
450
|
+
- **This section applies once per repository:** an explicit staging list and its `verify-staged`
|
|
451
|
+
receipt, run inside that tree; its own commit; and before its push, the whole of ITS gate — the suite
|
|
452
|
+
and checks its own contributing rules name, which this repository's lanes never run.
|
|
453
|
+
- **Its commit and pull-request text follow ITS rules:** no effort ids, no board or seat words. Where it
|
|
454
|
+
checks pull requests, open a DRAFT one at your first push and read its checks after every push.
|
|
455
|
+
- **Push from inside that tree — `cd "$TREE" && git push origin <branch>`, and nothing else on the
|
|
456
|
+
line,** with the variable your seed names in `$TREE`'s place (hand-cranked, the path your prompt
|
|
457
|
+
names). It is the one push that takes a leading `cd`. Keep the variable out of the push itself:
|
|
458
|
+
`git -C "$TREE" push` cannot be read, and waits for a person. Your push may wait for one anyway: wait,
|
|
459
|
+
never reshape it, and report a refusal.
|
|
460
|
+
- **You never merge, tag or publish there.** A release is a person's act, at the pipeline's `step`.
|
|
436
461
|
- **Codegen only through the command `patterns/codegen.md` § Running codegen names** (when the repo has
|
|
437
462
|
one) — never hand-write a generated folder.
|
|
438
463
|
- **Never improvise a qualifying path in.** If a push parks and the remedy you can think of is touching a
|
|
@@ -462,7 +487,9 @@ FINAL TLDR — {your assignment}. Built on HEAD {sha}; {hand-cranked: committed
|
|
|
462
487
|
(f) EXPLICIT STAGING LIST — the exact list `verify-staged` was (hand-cranked) or will be (hosted)
|
|
463
488
|
run over; a path not on this list is a path nobody will notice missing — + the STAGING
|
|
464
489
|
VERIFIED receipt, or hosted "commit HELD awaiting the commit call" + which dirty files are NOT
|
|
465
|
-
mine.
|
|
490
|
+
mine. A seat that wrote a further repository gives a list and a receipt PER REPOSITORY, each
|
|
491
|
+
under its repository's name, and in (b) each repository's summaries under its own name.
|
|
492
|
+
SESSION ID + NAME.
|
|
466
493
|
```
|
|
467
494
|
|
|
468
495
|
## Close-out — the order is law
|