diff --git a/docs/conventions/loop-lane/README.md b/docs/conventions/loop-lane/README.md index 175d0fec3f..b5424b1961 100644 --- a/docs/conventions/loop-lane/README.md +++ b/docs/conventions/loop-lane/README.md @@ -594,6 +594,24 @@ the adaptive cap. start; new automated intake arriving mid-cycle is **reported, never chased**, so an item-producing bot cannot hold a drain open indefinitely. +**Autonomous-pipeline reminder.** An autonomous lane carries standing clauses of its own against the +two stopping failures a pipeline cannot recover from: a turn ending on unexecuted intent, and a turn +stopping to ask permission nobody is there to give. In this repository those clauses are +hand-authored inline in each autonomous lane's launch prompt, and **deliberately so** — a launch +prompt is pasted into a terminal that may have no plugin installed, so it stays self-contained. +**Pointer-not-copy does not reach them**, and this is the one place in this doc where that is true: +the rule governs a *mechanism* a plugin owns, and a self-contained paste block owns its own text. + +The `autonomy` plugin's `reference/autonomous-pipeline-reminder.md` states the same clause set once, +with its provenance, as the artifact an adopting org drops into **its own** pipeline. No lane +consumes that file, and a lane author changing these clauses should read it as the reference wording +rather than as a source the prompts import. + +Two boundaries are lane-topology facts and so belong here rather than there: an **attended** lane +deliberately carries no such clauses, because "recommend, then wait for my direction" is the opposite +posture; and the `lane-stop-gate` hook mechanizes exactly one of them, so the clauses are not +redundant with a lane that has the gate armed. + **Subagent discipline preamble.** Every subagent a lane dispatches carries a standing discipline preamble, because a dispatched subagent runs in a fresh, non-inherited context: it inherits no posture from the cycle root's own sweep and has to set its own. When the `discipline` plugin is diff --git a/plugins/autonomy/.claude-plugin/plugin.json b/plugins/autonomy/.claude-plugin/plugin.json index 39b95192dd..96a171460f 100644 --- a/plugins/autonomy/.claude-plugin/plugin.json +++ b/plugins/autonomy/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "autonomy", - "version": "0.12.3", + "version": "0.13.0", "description": "Governed autonomous agent operation: role-topology, binding-seam, wiring-vs-advisor, telemetry, return-accounting, trigger-dispatch, per-work-class guardrail-matrix, standing-routine-catalog, and design-only runner-charter contracts for climbing the AI-adoption ladder, plus a guided-setup skill that discovers an adopting org's state, writes its schema-versioned binding, wires standards-pinned OTLP emission with a zero-cost file-artifact default, wires human-attested return capture at the task boundary, wires signal adapters with one governed dispatch entrypoint, binds the five-class guardrail matrix to an org's isolation substrates with an in-boundary live-validation probe before recording each fail-closed binding, and stands up standing-routine-catalog classes as scheduled temporal signal adapters behind the one governed queue with free scheduling defaults wired as reviewable changes and each routine's work-class mapping homed on the security surface.", "author": { "name": "Melodic Software", diff --git a/plugins/autonomy/CHANGELOG.md b/plugins/autonomy/CHANGELOG.md index f9cb700060..19f350f976 100644 --- a/plugins/autonomy/CHANGELOG.md +++ b/plugins/autonomy/CHANGELOG.md @@ -6,6 +6,57 @@ All notable changes to the `autonomy` plugin are documented here. Format follows Versions 0.1.0–0.7.0 predate this file (introduced with 0.7.1); their history lives in the merged work-package PRs (#333, #343, #356, #372, #377, #600, #676). +## [0.13.0] + +### Added + +- **`reference/autonomous-pipeline-reminder.md` — the standing reminder an adopting org drops into + its own pipeline.** Until now the guidance existed only hand-authored inline in two of this + repository's three lane launch prompts, which is a launch surface for these lanes and not a + reusable artifact for anyone else's. The file states the two stopping failures a pipeline cannot + recover from — a turn ending on unexecuted intent, and a turn stopping to ask permission nobody is + there to give — then gives the paste-ready clause set: proceed on anything reversible, pause only + for a destructive or irreversible action, a real scope change, or input only the launcher can + supply; ask once and never re-ask what is settled; read the final paragraph back before ending a + turn; and an enumeration of the shapes that are work orders to act on rather than messages to end + on. The companion checkpoint instruction its source guide asks to be paired with the reminder is + folded in, so a consumer pastes one block rather than assembling two. + + **Locally authored, not reproduced.** The clause set is this repository's own wording of guidance + published in Anthropic's Claude Fable 5 prompting guide, "Rare cases of early stopping" + (, + fetched 2026-08-08). Copying the upstream text would have violated this repository's own rule + against hand-copying upstream content; the file carries the pointer and a recheck trigger instead. + + **The block is internally consistent about the two things it is easiest to get wrong**, both + caught in review of the first draft. An action being visible outside the working tree does not by + itself make it one to ask about — the pause test is irreversibility, an outward action the request + did not ask for, a scope change, or user-only input, so authorizing "opening a draft" no longer + contradicts the pause clause. And naming further work is a *report* once the run is complete but a + *deferral* mid-run, so the enumerated shape is now "a mid-run offer to do work already within this + run's scope" rather than any offer at all; the discriminator is whether the run is over, stated in + the block itself. + + **Two boundaries ship with it**, because an artifact that reads as universally applicable would be + applied where it does damage. An **attended** lane deliberately does not carry the reminder — + "recommend, then wait for my direction" is the opposite posture, and pasting the block into one + converts a working human-in-the-loop review into an agent acting on its own recommendations, which + is why this repository's two-of-three lane split is the contract rather than an inconsistency. **No + lane references this file**, and the reference says so rather than implying otherwise: launch + prompts are pasted into a terminal that may have no plugin installed, so they stay self-contained + by design. The clauses previously existed only as prose duplicated across two launch surfaces and + reusable by nobody, which is the gap this file closes. And + the `lane-stop-gate` hook mechanizes exactly **one** clause: it performs no content classification + beyond its literal sentinel check, so it cannot tell a blocked-on-user stop from a lazy one, and + every other clause is carried by instruction alone. That scope is now stated in the hook's own + header as well, so a reader of the gate does not infer coverage it does not have. + +### Changed + +- The `loop-lane` convention now points at the new reference for the reminder's clause set instead + of leaving it implicit in the launch prompts, and keeps only the two boundaries that are + lane-topology facts rather than reminder content. + ## [0.12.3] ### Changed diff --git a/plugins/autonomy/README.md b/plugins/autonomy/README.md index 48ea08567d..f4e6b4b37f 100644 --- a/plugins/autonomy/README.md +++ b/plugins/autonomy/README.md @@ -52,6 +52,22 @@ state and records that binding. only — the build stays gated on the charter's own triggers and the runner-execution home stays unborn; setup records nothing runner-specific beyond the escalation notification routes (severity axis + personal-push tier) bound through the security binding. +- **Autonomous-pipeline reminder** (`reference/autonomous-pipeline-reminder.md`): a drop-in + standing reminder for an adopting org's *own* pipeline, against the two stopping failures a + pipeline cannot recover from — a turn ending on unexecuted intent, and a turn stopping to ask + permission nobody is there to give. States where it does not apply (an attended lane wants the + opposite posture) and what the `lane-stop-gate` hook does and does not cover of it — one clause + deterministically, the rest by instruction alone. + + **Provenance.** The clause set is this repository's own wording of guidance in Anthropic's Claude + Fable 5 prompting guide, section "Rare cases of early stopping", folded together with the + companion checkpoint instruction that section asks to be paired with it + (, + fetched 2026-08-08). It is authored locally rather than reproduced, per this repository's rule + against hand-copying upstream content. The citation lives here rather than in the contract file + because `reference/` docs are written in surface classes and may not name vendors. + **Recheck trigger:** that section changing its clause set, or a second model guide stating the same + guidance in materially different terms. - **Guided setup** (`/autonomy:setup`): discovery-first interview of the adopting org's state — role homes, substrate availability, budget posture — writing a schema-versioned binding under `.claude/autonomy/` as reviewable changes. Never assumes any particular org or repo shape. diff --git a/plugins/autonomy/hooks/lane-stop-gate.sh b/plugins/autonomy/hooks/lane-stop-gate.sh index 859a76ffa1..a2712ef2e2 100755 --- a/plugins/autonomy/hooks/lane-stop-gate.sh +++ b/plugins/autonomy/hooks/lane-stop-gate.sh @@ -10,6 +10,14 @@ # done"), and a lane that still stops after that one nudge is treated as a # genuine down-lane — allowed to stop (never wedged) and the operator is alerted. # +# SCOPE — this gate mechanizes ONE clause of the autonomous-pipeline reminder +# (reference/autonomous-pipeline-reminder.md): end the turn only on completion or +# a genuine block. It performs no content classification of the final message +# beyond the literal sentinel check below, so it cannot tell a blocked-on-user +# stop from a lazy one — both get the same single nudge. Every other clause of +# that reminder is carried by instruction alone; a shell hook cannot judge +# whether a final paragraph describes an action or reports one. +# # DEFAULT-OFF. A Stop-blocking hook that engaged by default would wedge every # interactive user's stop, so the gate is inert unless a session explicitly opts # in. Every other exit path allows the stop. diff --git a/plugins/autonomy/reference/autonomous-pipeline-reminder.md b/plugins/autonomy/reference/autonomous-pipeline-reminder.md new file mode 100644 index 0000000000..f28dfb8672 --- /dev/null +++ b/plugins/autonomy/reference/autonomous-pipeline-reminder.md @@ -0,0 +1,115 @@ +# Autonomous-pipeline reminder + +A drop-in standing reminder for a pipeline that runs without a human turn between steps. It is +written to be pasted into the system prompt, launch prompt, or dispatch brief of **an adopting +org's own pipeline** — this plugin's lanes are one consumer, not the audience. + +## The failure it prevents + +Two shapes, and neither announces itself as a failure: + +- **A turn that ends on unexecuted intent.** The final message states what will be done — "next + I'll update the callers", "now running the suite" — and no tool call follows it. In an + interactive session the human reads the sentence and says "go"; in a pipeline nobody does, so + the stated work never happens and the run reports as finished. +- **A turn that stops to ask for permission the pipeline already granted.** The model has + everything it needs to proceed and asks anyway. The cost is not one wasted cycle: the question + reaches no reader, so the lane sits until a timeout retires it. + +Both are *stopping* failures rather than *doing* failures, which is why review catches them late. +The artifact a run leaves behind looks reasonable; only the absent effect gives it away. + +## The reminder + +Paste this block verbatim. Its clauses are written to be read as a set — the self-check earns its +place only because the enumerated shapes below it say what to check *for*. The pause clause folds +in the companion checkpoint instruction the source guide asks to be paired with this reminder, +rather than leaving a consumer to notice the cross-reference and assemble two blocks. + +```text +You are running as an autonomous pipeline. No human is reading your messages between +turns, and no one will answer a question you ask. Work accordingly. + +Proceed without asking on anything reversible that follows from the original request. +Committing to a branch, opening a draft, writing a file, running a test, filing a +follow-up — all of these are yours to do, and an action being visible outside your +working tree does not by itself make it one to ask about. Pause only where the work +genuinely requires the person who launched you: a destructive or irreversible action, +an outward action the original request did not ask for, a real change of scope, or +input only they can supply. + +Asking once and proceeding is fine. Asking again about the same thing is not: if the +question was already settled, or the pipeline's standing authorization already covers +it, act rather than re-opening it. + +Once the task is genuinely complete, naming further work you did not do is a report +and is welcome. What is not welcome is offering, mid-run, to do something that is +already yours to do — that is the enumerated shape below, and the two are told apart +by whether the run is over, not by how the sentence is phrased. + +Before you end a turn, read your own final paragraph back. If it describes an action +rather than reporting one — if it says you will, are about to, are going to, or plans +to — that action has not happened yet. Do it now, in this turn, with tool calls. + +These shapes are work orders to act on, never messages to end on: + - a statement of what you intend to do next + - a plan, or a list of remaining steps + - an analysis that stands in place of acting on it + - a question of the form "want me to", "should I", "shall I", or "do you want" + - a mid-run offer to do work that is already within this run's scope + - a promise about work you have not done, including "let me know when" + - a summary that stands in place of the change it describes + +End the turn only when the goal is met, or when you are blocked on something only the +person who launched you can supply. If you are blocked, say what you are blocked on and +what you already tried — that message is the whole value of the stop. +``` + +## Where it applies, and where it does not + +**Applies** to any run with no human turn between steps: a scheduled routine, a queue drain, a +`/loop` lane, a dispatched worker, a background agent. + +**Does not apply** to an attended lane. A pipeline whose whole design is "recommend, then wait for +my direction" wants the opposite posture, and pasting this block into one converts a working +human-in-the-loop review into an agent that acts on its own recommendations. + +The loop lanes this repository ships are the worked example of that split, and of the gap this file +closes. Their two autonomous lanes state clauses of their own to this effect, hand-authored inline in +each launch prompt; the attended lane deliberately states none, because it opens by telling the +session a human is present. **No lane references this file** — the launch prompts are pasted into a +terminal that may have no plugin installed, so they stay self-contained by design. That is the point: +the clauses existed only as prose duplicated across two launch surfaces, reusable by nobody, which is +why they are stated once here for an adopting org to drop into its own pipeline. + +## Relationship to the lane-stop gate + +`hooks/lane-stop-gate.sh` is the mechanism half, and it covers exactly one clause: the last one. +On a lane's first unsignaled stop it blocks once and re-injects a completion self-check, and a +lane that stops again is treated as genuinely down and reported to the operator. + +Two limits are worth stating plainly, because a mechanism that looks like it covers the whole +reminder is worse than one known to cover a slice: + +- **The gate performs no content classification** of the final message beyond a literal check for + its completion sentinel. It cannot tell a turn ending on a genuine blocked-on-user question from + one ending on a lazy premature stop; both receive the same single nudge. The over-blocking is + benign — a genuinely blocked lane costs one wasted nudge, then stops with the operator alerted, + which is what a blocked lane wants — but it is over-blocking, not classification. +- **The remaining clauses have no mechanism** and are carried by this reminder alone. A shell hook + cannot judge whether a final paragraph describes an action or reports one. + +A mechanism outranks an admonition wherever the shape allows one. Here the shape allows one for a +single clause, and the honest arrangement is the gate for that clause plus stated instruction for +the rest — not a gate presented as if it covered all seven. + +## Provenance + +The clause set is this repository's own wording of guidance published in a model vendor's prompting +guide for its frontier model. It is authored here rather than reproduced, per this repository's rule +against hand-copying upstream content — so it is a locally-owned artifact that cannot silently drift +out of sync with a copy, while the guide stays the thing to read when the upstream advice changes. + +**The citation, the exact section, and the recheck trigger live in the plugin +[`README.md`](../README.md), not here.** These `reference/` contracts are written in surface classes +rather than vendor names, so naming the source belongs on the surface that is allowed to name it.