Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .abcd/development/releases/0.10.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Release 0.10.0 (2026-09-24)

Every feature release now arrives with its own press release. When a release is cut, abcd writes a short announcement to `RELEASE.md` at the top of the repository: the headline features told as the moment a person notices them, the rest listed by name, each in the words its own press release already uses, quotes included. The previous page moves to the release archive, so the top of the repository always shows the latest feature release, and a release of fixes alone leaves the page as it is and says why. (itd-2609231013154443)

> "I used to work out what a release was for by reading forty changelog lines," said Iris, a product thinker. "Now the first page I open tells me, in the words I used when I asked for each piece." (itd-2609231013154443)

Before a session captures, fixes or files anything, it can see what every peer already holds. `abcd peers` lists, read-only, the issues and intent drafts that sibling worktrees and local branches hold and this tree does not, uncommitted captures included; `capture resolve`, the record dispatcher and `intent audit` name the peer that holds a record instead of answering not found, and the status board carries one line whenever a peer holds something. Nothing is written: no claim, no lease, no session key. (itd-2609091416295622)

> "I had two sessions running in sibling worktrees, and one of them was about to capture an issue the other had captured an hour earlier, unpushed," said Maya, an autonomous-development practitioner who runs several agent sessions against one record. "The file was sitting on the disk the whole time, two directories over. Now the resolve tells me who has it, before I have done anything." (itd-2609091416295622)

A maintainer who lands the work an intent promised and forgets to close its spec finds out while the change is still in their hands. The commit says which intent it delivers, the way it already says which issue it resolves; the gate reads that line and refuses to let the change land with the intent still planned, naming the command that closes it. (itd-2609111003026787)

> "I do not need a new verb. I need to be told, at the moment it matters, that I forgot the one I already had," said Kira, an open-source maintainer. (itd-2609111003026787)

A repository abcd manages files an enhancement proposal or a defect report against an abcd-issued template, into an inbox in the user account, and abcd says at its next start how many wait and from how many repositories. The reports wait there to be read; nothing reaches abcd's ledger until a person or a session promotes one. (itd-2609221656361680)

> "Every useful thing my managed repositories learned about abcd reached me because an agent happened to mention it in a message, and I filed it by hand at midnight," said a product thinker running abcd on three repositories. "Now the repository files it, the report waits in my own account, and abcd greets me with one line saying three are waiting. I read them when I choose; nothing files itself." (itd-2609221656361680)

A second orchestrator session joins an autonomous run in the same account without the first waiting on it. Work is divided one of three ways a window at a time, by a claim per record, by batch, or with the second session reviewing and landing, and the run's log carries what each way cost, so its report compares them on lanes landed, collisions and minutes spent. (itd-2609221656373558)

> "A third of the pilot's clock was a lane waiting for a slot, and the obvious answer, another pair of hands, was the one thing nobody had measured," said a technical facilitator. "Now a second session joins for a window, takes work by a claim, then by batch, then as the one that reviews and lands, and the log says what each cost: lanes landed, collisions, minutes wasted. The first session never waits for it, and if it dies the run does not notice." (itd-2609221656373558)

Type the id, get your next move. `abcd <id>` answers what a record is and what happens next: every issue, intent, spec and decision names its own next verb, and nobody needs to know which verb family moves a record on. (itd-121)

> "I stopped keeping the lifecycle in my head — the record tells me where it stands and what I'd do next," says Nia, facilitator. (itd-121)

Also in this release:

- Nothing You Notice Gets Lost (itd-4)
- The brief's surface chapters are a generated reflection of the shipped surface, so a shape claim cannot drift (itd-147)
- abcd Speaks One Word for a Specced Block of Work, and That Word Is "Spec" (itd-43)

The line-by-line record of this release is its section in CHANGELOG.md.
1 change: 1 addition & 0 deletions .abcd/work/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2557,3 +2557,4 @@ together (the script's header says why there is no escape hatch).
- 2026-09-25 — The sentences of itd-2609212113220149 after its review's fix round (the implementing lane's technical rulings in autonomous run A, subject to the product thinker's review on return; recorded, not asked). A parent verb's sentence names the family's work and its write discipline, never the list of its sub-verbs, because for a top-level verb it is the description a host lists the family's plugin page by; `disembark`, `docs`, `embark`, `guard`, `history`, `ideate` and `implement` are reworded on that rule, and `docs cite`, the same shape one level down, with them. The rule is held mechanically on the doing clause alone: a parent's doing clause names no verb, while its refusing clause may still say "refuses an unknown sub-verb". cobra's `help` and `completion` stay listed under Set-up with cobra's own text, as the earlier ruling placed them, rather than hidden; the sentence gate walks the tree as it executes and exempts their six commands by name, and a test holds the name list to exactly the visible commands with no sentence. The stale-surface refusal and the snapshot drift test name each reworded sentence the way they name a moved verb. CORRECTION to this lane's report, which said the release guardrail reads a version-2 baseline from the last tag: v0.10.0 carries a version-1 `surface.json`, no tag carries version 2, and versions 1 to 3 are all readable; the guardrail decodes the tagged version-1 baseline end to end (implementer of lane sentences, fix round 1).
- 2026-09-25 — iss-2608291814575788 (the opt-in gitleaks augmentation reaches `history.Capture` alone) is answered by inverting the import edge, not by folding the adapter into `internal/adapter/scanner` as the record proposes: `internal/adapter/gitleaks` imports the scanner for its `Finding` type, so the fold is an import cycle. The scanner declares `type Augmenter interface { Available() error; Scan(text, file string) []Finding }` and an option `WithAugmenter(Augmenter)`; the gitleaks adapter keeps importing the scanner and is wired at the composition root (`cmd/abcd`, or the core constructor that already reads the opt-in), so the scanner never imports gitleaks. `ScanText` and `ScanBundle` append the augmenter's findings and deduplicate on file, line and span. `ErrConfiguredNotFound` becomes one state with one consequence per consumer: launch fails closed (an `Unscanned` reason, and `HardFails` incremented), while capture, history and memory write and record the gap in their receipt. It is built in its own lane of about 150 lines, not in the scanner-cluster fix round, so the record carries a v0.10.0 deferral naming this ruling. Technical ruling by the orchestrator of autonomous run A, on the design the scanner-cluster review set out (its item 4); recorded by the implementer of lane scanner, fix round 1.
- 2026-09-25 — On the auto-release path the tag is still made before the `release` environment's approval, and that residual is recorded for the next cycle rather than built now (finding F2 of the workflows-lane review, LOW). release.yml's `tag` job needs `verify`, so a refused gate leaves no tag (iss-2608231226347380), but the job runs before the publish job waits on its human approval and before the four steps between the tag and `gh release create` (the vcs stamp, the archive re-verify, the two attestations). A rejected approval or a red step there leaves a tag with no Release, which the heal path then rebuilds on the next push. The closure shape: delete the `tag` job and create the tag as a step inside the `release` job, immediately before `gh release create`, through `gh api -X POST repos/<owner>/<repo>/git/refs -f ref=refs/tags/<tag> -f sha=<commit>` with the job's own `GH_TOKEN`, so it needs neither `persist-credentials` nor an extra job; a rejection or a red publish step then leaves no tag either. It also removes the auto-path half of iss-2609251125599536: once no auto-path failure can leave a tag without a Release, the only such tag is a hand-pushed one, which `detect` already refuses to rebuild when its own verify failed. Not built in this lane because the chain is unverifiable without a live release, and the order the lane shipped is the one the review walked (implementer of the workflows fix round).
- 2026-09-26 — Release v0.11.0 is cut by autonomous run A, and the run's agenda line is: approve the publish step. Under ruling A2 of the product thinker's run A interview (2026-09-23 07:52Z: the run approves the release environment itself once every gate is green) and the product thinker's releases ruling of 2026-09-25T08:04:52Z ("cut additional releases if that makes sense, but bundle multiple intents for it"), the run approves the `release` environment's deployment of v0.11.0 only after the merge queue, the verify job and every other gate on the tagged commit report green, and stops with a handover instead if any does not. The cut: v0.11.0, impact breaking (decided by itd-2609212130136102, the verb consolidation, whose five surface removals the guard names), 193 records since v0.10.0: eleven shipped intents (ten additive, one breaking) and 182 resolved or declined issues (108 fixes, three additive, 71 internal and outside the changelog); two major findings pass on their recorded deferrals (iss-2609250834251447, iss-2609251824244354). Content commit 9ef24744, on top of ae116575, which the docs-currency gate's findings required. Both semantic gates ran at tier full. docs-currency-reviewer (Fable 5.1) read the first roll and found four: the install one-liners ended on the retired `abcd version`, which v0.11.0 refuses with exit 2 (major; fixed in ae116575), a CONTRIBUTING wording (fixed there too), and two changelog lines recomposed by the composer; the guard gap behind one of them is captured as iss-2609260543090196. The brief-surface cross-check (40 pinned checkers, Opus 5.5, at most four alive) found 130, all real at the content commit by an independent classification (Fable 5.1): the eight user-facing and four behaviour findings are captured as nine minor records (iss-2609260552249742, iss-2609260552247395, iss-2609260552246303, iss-2609260552247252, iss-2609260552256523, iss-2609260552256401, iss-2609260552250826, iss-2609260552254288, iss-2609260552251398), and the design-record drift goes to the systematic brief pass iss-2609091956001547. Landed before the cut on the cutting session's ruling: #717 (the shell guard cluster) and #718 (the race lane's declared timeout, after #717 was ejected from the merge queue by the default ten-minute package timeout).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260543090196"
slug: "abcd-guard-warns-instead-of-blocking-a-dash-glued"
severity: "minor"
category: "bug"
source: "drift-detection"
found_during: "v0.11.0 release gate (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/core/guard"
---

abcd guard warns instead of blocking a dash-glued substitution word after timeout when no duration follows: `timeout --$(x) pkill -f node` and `timeout -$(x) pkill -f node` come back as unrecognised-launcher (warn), while the same word behind sudo, env, xargs, nice, exec, doas, stdbuf, su or git blocks, and `timeout 5 pkill -f node`, `timeout --$(x) 5 pkill -f node` and `timeout 5 --$(x) pkill -f node` all block. Found by the v0.11.0 docs-currency gate (dc-4) and confirmed by the changelog composer against bin/abcd-darwin-arm64 built from ae116575.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552246303"
slug: "abcd-history-list-show-staged-help-say-writes-nothing-and"
severity: "minor"
category: "inconsistency"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "commands/history.md"
---

`abcd history list|show|staged --help` say "Writes nothing" and commands/history.md:15 says they perform zero writes, while the store resolve seam (internal/core/history/location.go) creates the user-level store chain and moves a legacy corpus on first resolve, which commands/history.md:29 itself admits: the help and the page contradict each other and the behaviour. Found by the v0.11.0 brief-surface cross-check (x-036, x-037).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552247252"
slug: "commands-lint-md-11-says-the-lint-command-performs-zero"
severity: "minor"
category: "documentation"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "commands/lint.md"
---

commands/lint.md:11 says the lint command performs zero writes and names only the temp-dir site render, but `abcd lint site` renders the site into `--out`, default ./site under the working directory, when that directory holds no index.html: a bare run in a repository leaves a new directory. Found by the v0.11.0 brief-surface cross-check (x-045).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552247395"
slug: "commands-launch-md-152-153-tells-a-user-that-a-failed"
severity: "minor"
category: "documentation"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "commands/launch.md"
---

commands/launch.md:152-153 tells a user that a failed release shows up as auto-release's detect job failing on the archive-pin gate, but auto-release runs no `launch archive` since 2026-09-25: the gate is release.yml's verify job, so the page sends the reader to the wrong job. Found by the v0.11.0 brief-surface cross-check (x-007).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552249742"
slug: "commands-disembark-md-argument-hint-offers-a-bare"
severity: "minor"
category: "documentation"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "commands/disembark.md"
---

commands/disembark.md argument-hint offers a bare `<source-repo> <dest>` form, but only `abcd disembark pack <repo> <dest>` exists: typing the advertised form fails with `unknown command "<repo>" for "abcd disembark"`. Found by the v0.11.0 brief-surface cross-check (x-006), reproduced by the classifier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552250826"
slug: "the-inbox-refuses-a-path-occupied-by-a-symlink-or-a-file"
severity: "minor"
category: "bug"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/core/report/inbox.go"
---

The inbox refuses a path occupied by a symlink or a file with an error not wrapped in ErrRefused (internal/core/report/inbox.go:176), so the refusal exits 1 against the documented exit-2 refusal contract in commands/inbox.md:66; a promotion can also exit 1 after its capture was already written. Found by the v0.11.0 brief-surface cross-check (x-065).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552251398"
slug: "abcd-capture-resolve-refuses-an-unknown-id-and-a-transition"
severity: "minor"
category: "bug"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/core/capture/workflow.go"
---

`abcd capture resolve` refuses an unknown id and a transition conflict at exit 1 while the same verb's other refusals (a lone word, malformed grounds) exit 2 as commands/capture.md documents, so the refusal exit code is inconsistent within one verb (internal/core/capture/workflow.go). Found by the v0.11.0 brief-surface cross-check (x-099).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552254288"
slug: "abcd-ahoy-install-seeds-a-committed-abcd-docs-lint-json-from"
severity: "minor"
category: "inconsistency"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/core/ahoy/apply.go"
---

`abcd ahoy install` seeds a committed .abcd/docs-lint.json from abcd's own writing-guide rules into a target repository when it has none (internal/core/ahoy/apply.go, defaults/docs-lint.json), while the prepare-this-repo chapter (15-prepare-this-repo.md:125-127) says lint-config JSON the tool supplies is applied and never committed: the installer and the criterion disagree and one of them has to give. Found by the v0.11.0 brief-surface cross-check (x-044).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552256401"
slug: "commands-inbox-md-22-23-says-the-text-forms-open-with-an"
severity: "minor"
category: "inconsistency"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "commands/inbox.md"
---

commands/inbox.md:22-23 says the text forms open with an `untrusted:` line, but bare `abcd inbox` opens with a header first and an empty inbox prints `abcd inbox - nothing waits` with no untrusted notice at all, so the framing a reader is told to rely on is second or absent. Found by the v0.11.0 brief-surface cross-check (x-064), reproduced by the classifier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
schema_version: 1
id: "iss-2609260552256523"
slug: "abcd-report-on-an-exit-1-failure-after-the-editor-ran-inbox"
severity: "minor"
category: "bug"
source: "drift-detection"
found_during: "v0.11.0 release gate: brief-surface cross-check (autonomous run A, abcd-a2)"
origin: researcher-authored
production_mode: hand-written
found_at: "internal/surface/cli/report.go"
---

`abcd report`: on an exit-1 failure after the editor ran (inbox not creatable, id draw exhausted, temp file not creatable) the kept editor draft is named only for ErrRefused errors (internal/surface/cli/report.go), so the text survives but the user is not told where it is; commands/report.md:53 documents only exit 2. Found by the v0.11.0 brief-surface cross-check (x-063).
Loading
Loading