From d676eb502bcec0109f6be347dffbea5e4c4f16a8 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Tue, 3 Nov 2026 13:10:48 +0000 Subject: [PATCH] docs: shift brief, digest and proof-packet formats; shift watcher exemption; Lane: header Autonomous orchestrators phase 1 (PyAutoBrain#551). policy/end_at_deliverable.md stays byte-identical (repos_sync stamps it into 50 repos); the watcher exemption lives in the new policy/shift_watcher.md. Co-Authored-By: Claude Opus 5.5 --- REFERENCE.md | 9 ++++ batches/AGENTS.md | 111 ++++++++++++++++++++++++++++++++++++++++ policy/shift_watcher.md | 30 +++++++++++ 3 files changed, 150 insertions(+) create mode 100644 policy/shift_watcher.md diff --git a/REFERENCE.md b/REFERENCE.md index 0c96d5ce7..64338c810 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -330,6 +330,7 @@ Free-form markdown. Strong conventions: Status: draft Consequence: glance # notify | glance | judge — how much review it needs Witness: ids bit-identical, 62 -> 9.7 ms # what makes it checkable in minutes + Lane: any # any | local-dev | ral | gpu | wsl-data; the last three imply local-dev Review-minutes: 3 # a seed, not a measurement Unattended: ready # ready | needs-slicing | never Filed: 2026-07-09 # optional; the day the prompt was written @@ -496,6 +497,14 @@ faculty at conception and all overridable by declaring them: **compaction rule** — a task that would need context compaction to finish is too big to run unattended — so a single-repo `large` task is still `ready` while a `large` one across four repos is not. +- **`Lane:`** `any` | `local-dev` | `ral` | `gpu` | `wsl-data` — not a cost but + a resource: where the work can run at all. `any` runs anywhere, a cloud + session included; `local-dev` needs the laptop; `ral`, `gpu` and `wsl-data` + each **imply `local-dev`** and refine it (RAL test runs, the laptop GPU, data + under `/mnt/c`). Write `any`, never `none`. A `ral` task never submits on its + own: the Science orchestrator is the single RAL gateway, and a dev worker + hands it a **RAL test packet** (what to run, at which commit, the pass/fail + rule) — planned for phase 5 of the autonomous-orchestrators epic. Measured over the 153 backlog prompts the day this shipped: **151 grade `judge`, because three carry a witness.** Given one, the same backlog grades 33 `notify` / diff --git a/batches/AGENTS.md b/batches/AGENTS.md index 4b5155494..fd9eaeb1a 100644 --- a/batches/AGENTS.md +++ b/batches/AGENTS.md @@ -155,3 +155,114 @@ wrote here at dispatch. A run classifying a new reason as its sibling's doing on its own authority is an autonomous acknowledgement, which the hard invariants forbid (`AUTONOMY.md`, "Leg 4 under a batch launch", 2026-08-31 amendment). No line, no match, the run parks. + +## Shift brief (2026-11-03) + +A **shift brief** is a batch record with a `brief:` block. It is the same file in +the same folder, under the same ledger-merge rules; every key above keeps its +meaning, `heart-ack:` and `expected-effects:` included. What changes is who +picks the work: the human writes the brief, and **writing it with `review-at:` is +the dispatch** (`PyAutoBrain/AUTONOMY.md`, "Shift briefs and unattended +`glance`" — 2026-11-03). The grant covers the named tasks plus the brief's +backlog policy, until `review-at:`. The deterministic watcher that starts +sessions under it is the one exemption to `policy/end_at_deliverable.md`, and +only while a brief is open (`policy/shift_watcher.md`). + +```markdown +# Batch 2026-11-04 am +- dispatched: 2026-11-04T08:30Z +- review-at: 2026-11-04T11:30Z # stated by the human; the grant expires here +- shift: morning +- issue: https://github.com/PyAutoLabs/PyAutoMind/issues/ # the digest is posted here once +- packet: yes # optional; the HTML packet is opt-in under a brief +- heart-ack: + - +- expected-effects: + - : +- brief: + - goals: # in order; the first outranks the rest + - 1. land the next cluster-strong-lensing slice + - 2. clear review-ready glance PRs on PyAutoArray + - tasks: # named prompt paths, done first, in this order + - draft/feature/autolens/.md + - draft/bug/autoarray/.md + - backlog: scoped # none | fill-idle | scoped + - scoped: # only with backlog: scoped + - epics: cluster-strong-lensing, autonomous-orchestrators + - tags: jax-gradient + - tiers: notify, glance + - exclude: + - draft/feature/autofit/.md + - epics: euclid-dr1 + - review-minutes: 45 + - lanes: any local-dev ral # any subset of: any local-dev ral gpu wsl-data + - merge-cap: 3 # unattended glance merges this shift, at most + - token-budget: # tokens the shift may spend, all sessions + - ral-allowance: # only when lanes includes ral; phase 5 consumes it + - packets: 2 + - partition: ral + - cpu-hours: 64 +``` + +`backlog:` decides what happens once the named tasks are done or blocked: +`none` — nothing more; `fill-idle` — the planner's own ranking, under every +batch constraint; `scoped` — only prompts matching the `scoped:` epics, tags or +tiers. `exclude:` removes prompt paths or epics from either dip. Backlog the +brief does not cover is **never** dipped. + +**Calibration rule.** A new brief is not accepted while the previous record +lacks `review-minutes-actual:`. The planned figure is a seed; the 2026-08-31 +record never closed it, and an estimate nobody measures never improves. + +`batches/examples/` (phase 2) holds validator fixtures. It is **not** a record: +nothing in it was dispatched, and `lifecycle.py` does not read it as one. + +### Digest + +Appended to the record at collect, under a `## Digest` heading, and **posted +once** as a comment on the shift's `issue:`. The record plus that comment is +the review surface; the HTML packet is written only when `packet: yes`. + +```markdown +## Digest + +### Brief work +- — PyAutoLens# — HEALTHY — glance, auto-merged (1/3) +- — parked: awaiting-input (question on the issue) + +### Backlog picks +- — PyAutoArray# — HEALTHY — why: scoped epic cluster-strong-lensing, next phase, notify +- — draft filed — why: decomposed from goal 2; needs bulk approval + +### Proof packets + + +### Counters +- merges: 2 +- glance-auto-merges: 1 +- reverts: 0 +- pushes: 0 +- drafts-filed: 1 +- packets-sent: 0 +- workers-crashed: 0 +- tokens: of +- review-minutes-planned: 45 +``` + +Brief work and backlog picks stay separate, and **every backlog pick carries a +one-line reason** — the brief's rule it was picked under. A pick the human +cannot trace to the brief is a finding. + +### Proof packet + +One screen per task — if it does not fit, the task was too big: + +```markdown +#### — +- claim: +- before/after: +- witness: `` + +- not checked: +- revert: `` +``` diff --git a/policy/shift_watcher.md b/policy/shift_watcher.md new file mode 100644 index 000000000..b51063002 --- /dev/null +++ b/policy/shift_watcher.md @@ -0,0 +1,30 @@ +## The shift watcher — the one exemption to "sessions end at their deliverable" (2026-11-03) + +`policy/end_at_deliverable.md` stands as written for every Claude session, +orchestrator and worker alike, and its hook keeps blocking them. This page +names the single thing that is allowed to keep time. + +**The watcher is a deterministic script, not a session** (built in phase 3 of +the autonomous-orchestrators epic; a systemd user timer or cron entry). It polls +`gh pr checks`, the project `hpc/sync jobs` verb (never raw `squeue`) and Mind +state, and starts a Claude session (`claude --bg`) only when there is work to +do. No tokens are spent watching. + +What keeps the exemption narrow: + +- It **calls no Claude tool** and **arms nothing inside a session**. A session + it starts is an ordinary session: it ends at its deliverable, and + `send_later`, `ScheduleWakeup`, `CronCreate`, `RemoteTrigger` and `/loop` + stay blocked for it. +- It **dispatches nothing without an open shift brief** — a + `PyAutoMind/batches/.md` record carrying a `brief:` block whose + `review-at:` has not passed (`PyAutoBrain/AUTONOMY.md`, "Shift briefs and + unattended `glance`"). A tick with no open brief does nothing. +- **Kill switch:** it checks for a `STOP` file in its slot directory **first**, + before reading anything else, and does nothing while that file exists. + +Why it is this narrow: the timer rule was written after five batch members armed +hourly check-ins on 2026-08-31, and a mobile `/prm` re-armed a 60-minute +`send_later` hourly all night on 2026-09-03 with no task active, draining usage. +Both were sessions keeping time. The watcher keeps time so that no session has +to; anything wider than this page reopens those two nights.