Skip to content

v0.1.10

Latest

Choose a tag to compare

@github-actions github-actions released this 25 Aug 14:00
· 0 commits to dev since this release

Action required

Run specflow upgrade in every repo that has specflow installed, and update the binary. This
release changes the CLI and four managed files: the claim-batch, finish-batch, and
prune-ledgers procedures, and their skill triggers.

curl -fsSL https://raw.githubusercontent.com/MatanKoby/specflow/main/install.sh | sh
specflow upgrade
specflow status     # `stale` should read `none` afterwards

One thing upgrade deliberately will not do for you: add the new pointer markers to your
BUILD_QUEUE.md. Your queue is a seed file that no verb rewrites, so that edit is yours, once. See
Wrap your pick-order pointer, below. A queue with no markers keeps working and is simply not
measured separately.

Four batches, one subject: the queue preamble

Batch What
QD the preamble warning says what is wrong, not just how long: an address, a staleness split, a stale claimable line, a near-miss heading
PD prune-ledgers section 3 greps before it judges, and asks once instead of once per paragraph
FL a finish leaves the queue smaller: the queue edit is subtractive, and the pick-order pointer is a bounded, replace-only block
OD a batch can wait on an outcome, not just on a finish: the new Blocked on: line

All four came out of one downstream install whose BUILD_QUEUE.md held 446 lines of prose above
its first batch
, in a file whose own header says it lists un-done batches only. The 0.1.8 cap
reported that as a number and stopped there. QD makes the report diagnostic, PD makes the cleanup
affordable, and FL and OD close the two inlets that filled it: about 9 lines per finish, which puts
a freshly pruned 45-line preamble back over its cap inside five batches.

The preamble warning is now a diagnosis

specflow next used to print BUILD_QUEUE.md preamble is 467 lines, over its 45-line cap, and the
user who saw it read it as a bug in specflow. It was not, but the message gave a number with no
anchor. Four read-only diagnostics, all in Weigh, so verify reports them too.

  • The count carries an address. Preamble lines are attributed to the nearest heading above them:
    467 lines above the first "## Batch" heading (446 of them under "## Un-done batches").
  • The staleness split is the signal the length never was. The distinct batch ids a preamble
    names, split by whether each is still in the queue or already archived in BUILD_QUEUE_DONE.md.
    The install above named 43 archived against 2 live. That fires on a short rotten preamble and
    stays quiet on a long current one, which is exactly what a line count cannot do. The floor is 5
    archived, and archived must outnumber live, so an honest pointer naming a shipped dependency stays
    silent.
  • A stale claimable line is named with its line number. It is the one preamble defect that
    misdirects rather than merely reading old: the field case said Claimable now: 50 while the queue
    held 49, 51 and 58 and Batch 50 had shipped weeks earlier. The check reads the batch named in the
    sentence the word sits in, so "Claimable: nothing. QD shipped" claims nothing and reports one.
  • A near-miss heading is named, and this one guards the count itself. A heading that misses the
    declared shape (an h3, a lower-case "batch", a colon after it) is not a batch anywhere: it inflates
    the preamble count and vanishes from next at the same time.

Over-counting is noisy but visible, so the boundary was deliberately not loosened to accept a
near-miss heading: under-counting is silent.

prune-ledgers section 3 greps before it judges

Section 3 asked the agent to sort every preamble paragraph into keep / relocate / delete and put the
three piles to the user. At the 59 lines this repo dogfooded it on, that is right. At 446 lines and
73 paragraphs it produced two findings.

The relocate pile came back empty. Every durable fact in that preamble was already carried by
BUILD_QUEUE_DONE.md or spec/, many of them citing their own destination in their own text. The
expensive half of the section was answering a question a grep had already settled 73 times over.
And 73 asks is an audit that gets abandoned.

So 3a greps first: take a distinctive phrase from each paragraph and look for a home in
specflow/history/, CLAIMS.md, and spec/. A paragraph with a citation is a delete, mechanically,
with the file and line as the evidence, and no ask. Only uncited paragraphs reach the three piles,
and the stop-and-ask is put once, as piles with counts. 3b prescribes the report: one row
per paragraph (line range, opening words, pile, evidence or destination, reason), the content that
lives nowhere else, and the projected line count. Relocation is explicitly verbatim, since a
paragraph reworded on its way into spec/ is no longer the thing that was reviewed.

The section also states the ordering QD's four signals imply: length is the weakest of them. A
40-line preamble naming a dozen shipped batches is rotten; a 60-line one that is all live pick-order
may be fine.

A finish leaves the queue smaller

The finish-time queue edit is subtractive. finish-batch.md step 4 now says so outright: delete
the batch's section, rewrite the pick-order pointer, append nothing. The batch's narrative already
has a home in specflow/history/BUILD_QUEUE_DONE.md and specflow finish already files it there,
so a status paragraph added to the top of the queue is a second copy of prose that already exists,
sitting in the file every future agent reads, that no retention rule ever reaches.

The pick-order pointer is bounded. It is the one region of the preamble a finish is expected
to rewrite, which is exactly why it is the region that grows a line per batch when a finish appends
instead. It is now a marker-delimited block capped at 20 lines of content, measured by Weigh
and reported beside the preamble count:

ledger weight: BUILD_QUEUE.md 125 lines (preamble 34/45, pointer 8/20, ...) · CLAIMS.md 142 lines (5 completed)

Over the cap, the warning names the rule rather than just the number: it is replace-only, rewrite
it, do not append a line per batch. 20 is set where an honest pointer (what is claimable, what it
waits on, what is not ready) stays silent, while one status paragraph per batch clears it
immediately.

specflow finish now prints the ledger weight on its way out. This is the last moment the agent
can still fix a preamble that grew: the meta: complete commit is the next thing it does, and after
that the growth is someone else's to find.

Wrap your pick-order pointer

Once, by hand, in each repo's BUILD_QUEUE.md:

<!-- specflow:pointer:start - replace-only, 20 lines max: rewrite this block, never append to it. -->
> **Pick-order pointer.** ... your existing pointer, unchanged ...
<!-- specflow:pointer:end -->

The markers use the same specflow:<tag>:start shape as the render regions and deliberately not the
specflow:start token the managed-file check matches, so wrapping your pointer does not turn
your queue into a managed region: upgrade and verify go on leaving it alone. A start marker with
no end is reported rather than guessed at. Absent markers mean no separate measurement, not an
error.

Blocked on: gates a batch on an outcome

Depends on: takes batch ids and means completed, so there was no way to say a batch waits on
what an earlier batch found. Downstream, two batches declared they depended on "Batch 46 having
come back answers"; Batch 46 shipped, reported package presence only, and specflow next went on
offering both as claimable. The only thing standing between an agent and a wrong claim was a prose
caveat in the queue preamble: the format could not express the fact, so it got parked where nothing
reads it and nothing prunes it.

A batch section now takes an optional free-text line:

## Batch 47 - the thing that waits

**Blocked on:** Batch 46 having come back with the package answer, which it did not.
  • It is a hard gate. next never offers the batch, and claim refuses it and writes nothing.
  • The reason printed is the author's own text, not a gloss over it, folded to the terminal
    width. Every other reason next prints is a string the CLI wrote and kept short; this one is
    whatever you typed.
  • It coexists with a tag, whose canned gloss the stated reason replaces:
    [NOT READY] blocked on Batch 46 having come back with the package answer. The tag is the
    category, the line is the specific why, and printing both would say the same thing twice.
  • Deleting the line clears it, and that is for whoever can answer it, not for an agent on the
    way past. Blocked on: none is accepted too, so an agent that writes the word does not strand a
    batch, but the procedures say delete: a leftover "none" is a line that states nothing and that
    nothing ever prunes.
  • An empty Blocked on: line still blocks, with "no reason given" as the reason. A gate nobody
    can act on is a defect in the queue, not a claimable batch, and reading it as absent would let a
    truncated line quietly re-open a batch someone meant to close.

Depends on: is untouched: a batch id still means completed, and the two gates are evaluated
separately, so a batch can be waiting on both.

Behavior changes

  • next and verify report a pointer N/20 count when the queue carries the markers, and warn
    past the cap or on an unclosed block.
  • finish prints the ledger weight after it writes, which it did not before.
  • next applies a new blocked-on check, prints a Blocked on: reason as its author wrote it, and
    folds a long one to 72 columns. claim refuses a blocked batch.
  • next --json carries blocked and blockedOn per item, beside the rendered reason, and
    weight carries pointerBlock, pointerLines, and pointerLimit.
  • templates/base/BUILD_QUEUE.md declares both: the preamble names Blocked on: in the batch
    shape, and a fresh init seeds a pointer already wrapped in its markers.
  • The preamble warning from 0.1.8 is reworded and now comes with up to four companions. If you parse
    next output, the preamble line changed shape.
  • prune-ledgers.md section 3 and the prune-ledgers skill changed substantially; re-read them
    before the next audit.

Install

curl -fsSL https://raw.githubusercontent.com/MatanKoby/specflow/main/install.sh | sh
# or
go install github.com/MatanKoby/specflow/cmd/specflow@v0.1.10

Full diff: v0.1.9...v0.1.10