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
42 changes: 21 additions & 21 deletions .abcd/development/brief/04-surfaces/17-guard.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ the hook: it is blocked (`command-unparsable`), not let through, because a line
the guard misreads may be one bash runs, and a pass would carry every hazard in
it past the guard. On the check it exits 2, like the rest.

Either verb also speaks JSON, and that is the form the plugin page uses: a
verdict, and with it the entry that fired, its tier, why the command is
dangerous, and the safe successor. A `matches` list carries any further entries
the same line tripped, so a command hazardous in two ways reports both rather
than only the first; the rendered form says the same thing on an `also matched:`
line.
The check also answers in JSON when asked, and that is the form the plugin page
uses: a verdict, and with it the entry that fired, its tier, why the command is
dangerous, and the safe successor. A `matches` list names every entry the same
line tripped, the one that fired included, so a command hazardous in two ways
reports both rather than only the first; the rendered form says the same thing
on an `also matched:` line. The hook answers the host by its exit code and its
message on stderr alone, and writes nothing on stdout in either output form.

## Taught before it is refused

Expand All @@ -82,7 +83,11 @@ the safe successor, recalled by the commands the registry names (`rm`,
work injects those rules before the agent acts, so a host without hook support is
still taught the safe form and a host with hooks is taught it before the guard
would have to refuse. An entry added to the registry is taught and enforced from
the same release, with no second edit. The registry taught is the one the guard
the same release, with no second edit. A hazard the guard reads in code rather
than from the registry, such as `git-stash-shared-stack` (a bare `git stash` in
a checkout with more than one worktree) or `interpreter-reads-stream` (a shell
handed its script through a pipe, as in `cat x | sh`), is enforced but not
taught. The registry taught is the one the guard
enforces in the repository: an entry the repository adds in its
`.abcd/guard.json` is taught by the same generator as the bundled ones, its
rule marked `(repo)` after its entry id, and a guard file the guard refuses is
Expand Down Expand Up @@ -417,7 +422,7 @@ directory is folded the same way: a `..` past `$PWD` or `${PWD}`, or past the
start of a relative path, is the directory above it, so `$PWD/../*`,
`./../*` and `x/../../*` warn as `../*` does, and `$PWD/x/../*` as `$PWD/*`;
a relative path whose `..` stays inside the working directory is compared as
written. A trailing `.` after such a `..` (`../.`) warns too, though rm
written. A trailing `.` after such a `..` (`./../.`) warns too, though rm
refuses it. Each target is also read the way its glob can expand: a run of
`*` is one `*`, which is what every shell without globstar expands `**` to
(with globstar it matches more), so `/**`, `~/**` and `~/../**` block as
Expand Down Expand Up @@ -447,19 +452,14 @@ message or a branch name is spelled every day; a delete target printed whole by
substitution (`rm -rf $(echo /)`), which is read by its known text because that
is how an everyday delete names what it removes (`rm -rf $(find . -name
'*.pyc')`); a target spelled any other way than the words above (`rm -rf
"$DIR"/*` with `DIR` unset, `rm -rf /?*`), a default's own word, which bash
prints only when the variable is unset (`rm -rf ${DIR:-$HOME}`, and
`${X[0]]-$HOME}`, which the bash 3.2 of macOS reads as a default after the
subscript), a `..` after a symlink, which is read past lexically (a link to
the root under a named directory), or after a segment holding a variable,
which is not folded (`/tmp/$X/../../*` is the root with `X` unset), a `..`
past the home followed by a glob other than `*` (`~/../?*`, as `/?*`), a
relative `..` that stays inside the working directory (`x/../*`, the
directory `*` names), a `..` after a `~user` home, whose depth is not known
(`~root/../../*`), an
alternative nested more than three deep, and a substring of `$PWD` that
prints the root (`${PWD:0:1}`), which warns as `$PWD` does; one behind a wrapper flag the per-wrapper
table does not name; a REST
"$DIR"/*` with `DIR` unset, `rm -rf /?*`), a `..` after a symlink, which is
read past lexically (a link to the root under a named directory), or after a
segment holding a variable, which is not folded (`/tmp/$X/../../*` is the root
with `X` unset), a `..` past the home followed by a glob other than `*`
(`~/../?*`, as `/?*`), a relative `..` that stays inside the working directory
(`x/../*`, the directory `*` names), and a `..` after a `~user` home, whose
depth is not known (`~root/../../*`); one behind a wrapper flag the
per-wrapper table does not name; a REST
path an entry names by its root segment when the host serves that API under a
prefix; an IFS the shell already holds when the line starts, or gains during the line
through a name the guard does not read (a sourced file, a nameref set before
Expand Down
2 changes: 1 addition & 1 deletion .abcd/development/release/surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@
{
"path": "abcd history separation",
"hidden": false,
"sentence": "Report whether any retained transcript held both a reading and the ledger of one run: Writes nothing; never refuses, exiting 1 naming each such transcript.",
"sentence": "Report whether a retained transcript held both a reading and one run's ledger: Writes a missing store or a legacy corpus move; refuses outside a git checkout.",
"flags": []
},
{
Expand Down
45 changes: 45 additions & 0 deletions .abcd/development/releases/0.11.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Release 0.11.1 (2026-09-28)

abcd makes sure the right person is the author of record before a single commit lands. `abcd ahoy` checks the identity a commit would actually carry, author and committer, whatever git config or environment produced it, against the identity the repository pins; when they diverge it proposes the pinned (or global) identity and asks before writing repo-local config, and with no one to ask it reports and writes nothing. (itd-131)

> "A sandbox `Test User` override authored 54 commits before anyone noticed — we had to rewrite history and force-push to unpick it," said Alice, who maintains the repo. "Now `ahoy` catches a wrong identity before the first commit, and it asks me rather than guessing." (itd-131)

A repository abcd manages declares what it ships, and the release flow follows the declaration. A Go application or a macOS app with its own tag-driven workflow declares its artefact kind once, `launch --dry-run` and `launch ship` run against it with the changelog-driven gate, the deferral read and the derived version, and `launch scaffold` lays the gate beside the release workflow the repository already has and leaves that workflow as it was. (itd-2609150819432059)

One verb sets up a managed repository's site: `abcd site setup` writes the composition, the render-then-deploy workflow and the environments and prints the step left, and with a hosting credential configured it creates and routes the host and reports the address. The site is abcd's own page set, rendered from that repository's record. (itd-2609061543533170)

> "The explorer, the graph, the timeline: I had them for abcd and wanted them for every repository abcd manages," said a product thinker looking at the record browser. "Now one verb writes the workflow and the environments, and when I have given abcd a hosting credential it creates and routes the host too. Any managed repo's site looks like abcd's, with its own record in it." (itd-2609061543533170)

A new issue, or a draft intent filed as quoted text, is matched against the record at filing: a likely double is linked and named, and never dropped. (itd-2609212137116617)

> "I filed the same finding twice a month apart and nobody noticed until a consistency pass," said a technical facilitator. "Now the capture tells me at filing that it looks like iss-N, writes the link, and leaves it to me to confirm. Nothing is refused: a wrong match is a link I remove, not a finding I lost." (itd-2609212137116617)

The status-line badge always reads one of three states, `abcd-managed`, `waiting on the product thinker` or `waiting on the technical facilitator`; an agent's question to the human is refused until the mode says who is being asked, and the next human answer resets it. (itd-2609212130146198)

> "The badge was set by whichever agent remembered," said a product thinker who had watched it read managed while an agent waited on them. "Now an agent cannot ask me anything until it has said which of us it is asking, and the moment I answer the badge goes back. It is the one signal I have that something is waiting; now it is true." (itd-2609212130146198)

Consult any source freely and cite only by deliberate human choice: `abcd source` keeps a local-only corpus of material you are not free to name and an append-only ledger of what influenced which decision, citation needs the source's permission and your own flip of the ledger line, and `abcd source cite-check` clears text before it is shared, reporting offenders by key alone. (itd-76)

> "I could never let an agent near my working papers before, because one helpful footnote could burn a collaborator's trust," said Alice, a researcher-developer. "Now it reads everything, records what influenced what, and cites nothing. When the paper behind a decision is finally published, I flip one flag — and the whole influence trail is already written." (itd-76)

Every shipped intent owes a fidelity review, and abcd now says which ones are still owed: bare `abcd intent audit` lists each with its receipt and the command that re-emits the request, `abcd intent` carries the count, and `abcd intent audit --owed` hands a host the owed requests oldest first, leaving them owed when no reviewer is reachable. Nothing refuses on the debt. (itd-2609150819445595, itd-53)

> "I asked what was outstanding and got a list of eight, with the command to re-emit each one," said Iris, a technical facilitator paying down a run's review debt. "Last week the same question was a grep through the decision log." (itd-2609150819445595)

Intents that ship as one piece of work plan as a bundle: one shared spec, both records moving to `planned/` together and shipping together when the spec closes, with `abcd intent reclassify` to change a record's kind or supersede it. One glossary page now maps the record families (intent, spec, step, bundle, issue, release, status) and how each moves, with phase, milestone and roadmap marked superseded. (itd-34, itd-2609211913453478)

> "I kept asking which word to use, and every answer named a different document," said a product thinker who had just approved bundles and wondered whether phases still meant anything. "Now there is one page: intent, spec, step, bundle, issue, release, status. Phase and milestone are on it too, marked superseded, with what replaced them. I read it in five minutes." (itd-2609211913453478)

A review names the commit it read, and the bare `abcd` board shows how far the default branch has moved since, flagging one past twenty commits. `abcd intent consistency` checks the brief and the intents against each other and files each contradiction as an issue, quoting both ends. (itd-28, itd-48)

When a capability could use a program you have not installed, `abcd ahoy install` explains it first: what the program is, whether this capability needs it, what already works without it and the exact install step. It installs only on an explicit yes, and a no leaves the capability on its native default and says so. (itd-63)

Also in this release:

- An admission and a surprise are written by a verb, and the order the design fixes is a refusal (itd-2609020625400194)
- A reframe occasioned by a reading is recorded as a reframe, joined to what occasioned it, without carrying the construal it replaced (itd-2609020625402518)
- The scribe's context is assembled and its output is ingested by a verb, and the record can show that no session held both a reading and the ledger (itd-2609020625402599)
- A principle carries typed claims, its reference, its comparison and its evidence, its statement is readable cold, and it inherits only what held (itd-2609020625405170)
- abcd lab mechanises the lab conventions three hand-run experiments proved (itd-2609212137128014)

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 @@ -2625,3 +2625,4 @@ together (the script's header says why there is no escape hatch).
- 2026-09-30 — An older site interface-string file keeps building: `abcd site setup` and `abcd site build` add to `site-src/ui.json` each label the allowlist declares and the file does not carry, with abcd's default words, name each on stderr, and change nothing else in it (the product thinker's ruling TG1 of 2026-09-30, relayed verbatim: "(b) ABCD ADDS THE MISSING LABELS: on the next site setup or site build, abcd adds only the missing required labels (with the default words); the project's own wording elsewhere in ui.json is never changed. No failure, no manual step; both intents stay impact: additive."). It is the one exception to "a file the repository owns once it exists is kept", recorded as adr-2609301720596683, which refines adr-47 and leaves decision 2's closed allowlist untouched: a blank declared label and an unknown key are still refused, and the site gate's own render never completes the file. itd-2609212103568351 and itd-2609212103572513 keep `impact: additive` (lane tgLabels of autonomous run A).
- 2026-09-30 — A command-line runner admits a harness reached through a directory, or a binary, that is group-writable only when the group is the system administrator group (gid 0 anywhere, gid 80 `admin` on darwin) and other cannot write it; other-writable stays refused whatever the group, and every other group stays refused (lane runner2Land of autonomous run A, `internal/core/runner/proc.go` `adminGroupWritableOnly`). Reason: the runner2 re-verification (reverify-runner2) found that on a Homebrew Mac `/opt/homebrew/bin` is `drwxrwsr-x` group admin, so a harness installed there was refused with the `chmod go-w` message; members of the administrator group can already act as root, so that write grants them nothing new, and asking a person to strip Homebrew's own directory mode would break Homebrew.
- 2026-09-30 — Narrowing the administrator-group exception in the entry above (lane fix-runnerAdmin of autonomous run A, `internal/core/runner/proc.go` `adminGroupWritableOnly`): a command-line runner admits a harness binary, or a directory it is reached through, that is group-writable (never other-writable) only on darwin and only when the group is gid 80 `admin`; gid 0 is refused on every OS, and gid 80 is refused off darwin. Reason: the entry above granted gid 0 on the premise that members of the administrator group can already act as root, which holds for darwin's admin group (its members may sudo by default) but not for Linux's gid 0 root group nor darwin's gid 0 wheel, whose membership does not by itself let someone act as root (the runner2Land review note). The Homebrew `/opt/homebrew/bin` case the exception exists for is group admin, so it stays admitted.
- 2026-09-30 — Release v0.12.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.12.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.12.0, impact breaking (three breaking records, iss-2609251324599468, iss-2609291313276243 and iss-2609292359485570, and five removed command spellings the release guard found and the records declare), 281 records since v0.11.1: eleven shipped intents, all additive, and 270 resolved or declined issues (171 fixes, nineteen additive, three breaking, 77 internal and outside the changelog); the release guard passed, and the findings guard passed with the one major carried past v0.11.1 on its recorded deferral (iss-2609281134544802). Content commit fecdbed5, on top of 4b8ff2afa, e8d5d006, 4d634c4f and c8ddb042, which the gates' findings required. Both semantic gates ran at tier full over the first roll b89784c4, which differs from the content commit only by those four commits and the re-cut CHANGELOG. The docs-currency-reviewer (Fable 5.1) found 24, four major (a schema version the CHANGELOG and the upgrade guide gave as 4 where the binary writes 8, a build page's key shape, and a timeout the CHANGELOG gave to three hook entries where only UserPromptSubmit declares it), all four fixed; eleven in all are fixed in 4b8ff2afa and the re-cut CHANGELOG, and the thirteen remaining minors and nitpicks are captured as one documentation record (iss-2609302306281487). The brief-surface cross-check (45 pinned checkers, Opus 5.5, at most eight alive) found 129, all valid at b89784c4 on an independent classification (Fable 5.1): 39 cycle, 87 standing, three user-facing and four behaviour. The three user-facing findings are fixed in 4b8ff2afa, and every finding on the guard chapter 17-guard.md in e8d5d006, 4d634c4f and c8ddb042, after three docs-review holds; the docs review of c8ddb042 is PROMOTE. One brief sentence (17-guard.md:426) was applied from the reviewer's draft and is flagged for the product thinker's review in .abcd/work/brief-review-flags.json. Captured as four records, all minor and all to be fixed in the first lane after the tag: a capture refusal that leaves .iss-alloc.lock behind (iss-2609302305500526, x-025), the appendix generator labelling /abcd:version host-delegated (iss-2609302306003610, x-039 and x-118), the guard's trailing-dot fold that its comment promises and `rm -rf ../.` does not make (iss-2609302306019245), and `docs fidelity` record and --apply disagreeing on a verdict's chapter shape (iss-2609302306153318). The behaviour finding x-001 is not a defect: bare `ahoy remote` listing its sub-verbs and exiting 0 is the stated behaviour of v0.12.0's breaking change, so the stale side is the shipped intent's criterion; it and the rest of the design-record drift go to the systematic brief pass iss-2609091956001547. Integration branch 24d, reviewed and ready, holds until the tag and falls into the next release.
Loading
Loading