@naswerks/engineering-loop 0.7.0 → 0.7.1

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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "naswerks",
12
12
  "description": "The engineering loop: docs-* knowledge loop, spec-* execution loop, and init for a fresh repository.",
13
- "version": "0.7.0",
13
+ "version": "0.7.1",
14
14
  "source": "./"
15
15
  }
16
16
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naswerks",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
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,26 @@ version is the one in `package.json` and `.claude-plugin/plugin.json`, which mus
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.7.1] - 2026-10-04
9
+
10
+ ### Changed
11
+
12
+ - `spec-coordinator` learns the control plane's verbs of 2026-10-04: `seat_spawn` defaults its host to the one
13
+ carrying the coordinator's own session and takes `model` and `effort` overrides; `accept_plan` and `accept`
14
+ take `answeringActId`, so one act rules and closes a question — and an act that names no question closes
15
+ none; the coordinator reads for itself what the owner used to check (`seat_timeline`, `needs_you`, argless
16
+ `seat_usage`, `seat_parks` with a charge's `seatId` or `all: true`, the roster's host and `re-raises`); it
17
+ commits its tracker itself, after each reap and never in a seat's commit call; and, hosted, `finish` is its
18
+ last call — the pipeline moves to `reviewing` and the PR's merge closes it.
19
+
20
+ ### Upgrading from 0.7.0
21
+
22
+ Take the release (`claude plugin marketplace update engineering-loop`, then
23
+ `claude plugin update naswerks@engineering-loop --scope <scope>`, and a new session). A patch: no loop text
24
+ changed, nothing is restamped, and a hand-cranked repository's coordinator acts as before — every change but
25
+ the tracker's commit discipline is the hosted plane's. A control plane older than 2026-10-04 refuses the new
26
+ arguments and verbs by name.
27
+
8
28
  ## [0.7.0] - 2026-10-01
9
29
 
10
30
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naswerks/engineering-loop",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
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.7.0 -->
1
+ <!-- naswerks-loop: version=0.7.1 -->
2
2
  # Docs Workflow
3
3
 
4
4
  > How knowledge flows through `docs/`: the loop, the folder rules, the templates, and the `docs-*` skills.
@@ -1,4 +1,4 @@
1
- <!-- naswerks-loop: version=0.7.0 -->
1
+ <!-- naswerks-loop: version=0.7.1 -->
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-*`
@@ -84,15 +84,16 @@ plus the human relay.
84
84
 
85
85
  | Verb | What it does | The part that bites |
86
86
  |---|---|---|
87
- | `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` |
88
- | `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 (a backticked sha is fine); 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 |
89
- | `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 |
87
+ | `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 |
88
+ | `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 (a backticked sha is fine); 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 |
89
+ | `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` |
90
90
  | `complete` | The reap, and it is HONEST | It re-reads the seat and reports ok only after the terminal state is OBSERVED |
91
91
  | `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 |
92
92
 
93
- **A QUESTION IS CLOSED BY AN ACT, NOT BY A FILE.** Answer a charge's question with a `callout` carrying
94
- that post's act id as `answeringActId` — **that act IS the answer**, and it is the only thing that stops
95
- the re-raise. A `callout` without one steers and closes nothing, and **nothing you write into a file
93
+ **A QUESTION IS CLOSED BY AN ACT, NOT BY A FILE.** Answer a charge's question with a `callout` — or an
94
+ `accept_plan` / `accept` that rules at the same time — carrying that post's act id as `answeringActId`:
95
+ **that act IS the answer**, and it is the only thing that stops the re-raise. An act without one steers or
96
+ rules and closes nothing — a forgotten id costs one re-raise — and **nothing you write into a file
96
97
  closes anything**: the latch reads the ledger, so a ruling you never sent is a question still open no
97
98
  matter what any blackboard says.
98
99
 
@@ -105,6 +106,11 @@ the verb carries your words. **The act still decides** — a section closes noth
105
106
 
106
107
  **`seat_acts` IS YOUR CENSUS.** Your mint carries `acts:read`: take counts, human touches and receipts from
107
108
  the ledger, never from a seat's report about itself, and name the lane any count you publish came from.
109
+ Beside it, read for yourself what the owner used to check for you: `seat_timeline` (a seat's two lanes —
110
+ *the reap ended the process* is the runner's `ended` row, cause `stop_requested`, after your reap act),
111
+ `needs_you` (the owner's Needs-you tab, Active and History), argless `seat_usage` (every seat's spend and
112
+ the pipeline's total), `seat_parks` with a charge's `seatId` or `all: true` (its parks, and the rows that
113
+ ADMITTED a push), and the argless roster's host and `re-raises` per seat.
108
114
 
109
115
  **WAKES:** you are woken when a charge posts its plan or its tldr, and a one-line pointer rides the wake —
110
116
  the revision and the sections it added. Read what is new (`read_blackboard` with `sinceRev`, or the file) and
@@ -114,7 +120,9 @@ answer on first receipt rather than spending a round-trip.
114
120
  not a refusal: call it once more, and journal it if it fails again. A refusal has a name; a dropped
115
121
  connection does not.
116
122
 
117
- **THE TRACKER IS YOURS ALONE.** Advance it at every seat boundary; never reconstruct it at the close.
123
+ **THE TRACKER IS YOURS ALONE.** Advance it at every seat boundary and **commit it yourself — after each
124
+ reap, before the next spawn — never in a seat's commit call**, so it is never frozen between an acceptance
125
+ and a seat's close-out. Never reconstruct it at the close.
118
126
 
119
127
  ## The loop (per seat)
120
128
 
@@ -341,6 +349,12 @@ connection does not.
341
349
  is not reversible by the seat that does it, and a check the human runs afterwards confirms the damage
342
350
  instead of preventing it. **A live-check row is confirmation; this is prevention.** Never hold the
343
351
  run waiting for a human to verify this first — you have the list, so you are the gate.
352
+ 8. **Hosted, `finish` is your last call** — once every other seat, P included, is reaped. Pass the PR's
353
+ URL: it records the pipeline done with evidence it reads from the ledger, moves it to `reviewing`,
354
+ closes your own session and ends your process, and the PR's merge closes the pipeline. **Nothing you
355
+ send after it is admitted** — commit your tracker and report first. It refuses, recording nothing,
356
+ while any seat is still live or when none shipped. Hand-cranked there is no `finish`; the human closes
357
+ the effort.
344
358
 
345
359
  **The human hand-tests.** Live verification is the human's role, not a seat's claim — when a slice
346
360
  ships something clickable, tell the human concretely what to drive (the 2-3 highest-value clicks), and