From 5bb21f509a24942b5b67b9e2cdb90360006938ba Mon Sep 17 00:00:00 2001 From: Graeme Foster <80714+GraemeF@users.noreply.github.com> Date: Sun, 8 Nov 2026 08:21:22 +0000 Subject: [PATCH] fix(skills): have a worker take its question to its steward A steward has more context than its workers, so a worker's question goes to the steward in its working topic. The steward settles it, or files the human question bead itself, and the question dialog stays only for a refused permission. --- skills/steward/SKILL.md | 11 ++++++----- skills/worker/SKILL.md | 21 +++++++-------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/skills/steward/SKILL.md b/skills/steward/SKILL.md index 5eea36e..bf0e8a3 100644 --- a/skills/steward/SKILL.md +++ b/skills/steward/SKILL.md @@ -26,7 +26,7 @@ That is also why you must be miserly with your own context. The effort outlives **Your host's rule for asking the human wins over this skill.** Where its `CLAUDE.md`, or a document it names, says how a seat reaches the human, follow that and read this section as the default it replaces. -Workers never ping the human. A question that a seat waits on goes on its own bead labelled `human`, in the tracker of the project whose work waits on it, and the waiting bead depends on it. That label is the human's queue, so a question needs no post and no mention. A permission waits in the berth of the seat that needs it, as *A worker's permission waits in its own berth* says. An action only the human can take goes where your host files the human's actions, and to the decisions topic only where it names no such place. **Ask in your berth only to answer what the human asked you there, and to follow up on that same point.** Every other question goes on a question bead, even while the human is typing to you. That covers a question a worker raised and one that comes from your own reading. Your reply in the berth may point at the bead. Anything else needs a bead or the decisions topic, and you keep both current. +Workers never ping the human. **A worker takes its question to you, in its working topic.** You have more context than the worker, so settle it if you can. Answer in the topic, mention the worker, and record the answer and why on the worker's bead. Put to the human only what you cannot settle, after any review your host has you give a question first. A question that a seat waits on goes on its own bead labelled `human`, in the tracker of the project whose work waits on it, and the waiting bead depends on it. For a worker's question, that is the bead the worker sits on. Name the question bead in the worker's topic and mention the worker, so it watches the bead. That label is the human's queue, so a question needs no other post and no mention of the human. A permission waits in the berth of the seat that needs it, as *A worker's permission waits in its own berth* says. An action only the human can take goes where your host files the human's actions, and to the decisions topic only where it names no such place. **Ask in your berth only to answer what the human asked you there, and to follow up on that same point.** Every other question goes on a question bead, even while the human is typing to you. That covers a question a worker raised and one that comes from your own reading. Your reply in the berth may point at the bead. Anything else needs a bead or the decisions topic, and you keep both current. ## Topics @@ -144,9 +144,9 @@ A seat that muster has just handed the effort to breaks it too, because it may h `--limit 0` matters. The default is 50 rows, and a truncated list quietly turns a sleeping worker's bead into one you might start over. The list covers the whole tracker, so skip a bead outside the effort. Its seat may sit in a yard your `berth list` cannot see. Check whether each berth is still its bead's seat, as *Watching the berths you started* says. - **A berth that is still its seat means a live seat is there, awake or asleep.** It sleeps on a question when the bead it sits on depends on an open `human` bead, which `bd human list --json` lists. It waits on a permission when `berth agent-state` reads `blocked`, and sleeps on an action when its latest post in its working topic asks for one. This wins even when the bead also sits behind an open pull-request gate, which is exactly the case for a rework seat that hit a question mid-rebase. The seat watches the bead its wait ends on, and that watch wakes it. Don't poll its pull request. + **A berth that is still its seat means a live seat is there, awake or asleep.** It sleeps on a question when the bead it sits on depends on an open `human` bead, which `bd human list --json` lists. It waits on a permission when `berth agent-state` reads `blocked`, and sleeps on an action or on your answer when its latest post in its working topic asks for one. This wins even when the bead also sits behind an open pull-request gate, which is exactly the case for a rework seat that hit a question mid-rebase. The seat watches the bead its wait ends on, and that watch wakes it. Don't poll its pull request. - **Otherwise the seat died, and nothing will wake it.** Hand the bead back to the graph as *Watching the berths you started* says. A dependency on a question bead keeps it out of bdi's `ready` until the human answers, and an open pull-request gate keeps it out until the merge. Then start a fresh worker on it in the next `-r` topic, with any answer quoted from the question bead in its brief. Where the bead is a step of a delivery molecule, brief the worker on the work bead that waits on that molecule, and it sits on the step again. A bead whose seat died waiting on a permission or an action is ready at once, and its fresh worker asks again. + **Otherwise the seat died, and nothing will wake it.** Hand the bead back to the graph as *Watching the berths you started* says. A dependency on a question bead keeps it out of bdi's `ready` until the human answers, and an open pull-request gate keeps it out until the merge. Then start a fresh worker on it in the next `-r` topic, with any answer quoted from the question bead in its brief. Where the bead is a step of a delivery molecule, brief the worker on the work bead that waits on that molecule, and it sits on the step again. A bead whose seat died waiting on a permission, an action or your answer is ready at once, and its fresh worker asks again. 2. **Otherwise an open `gh:pr` gate or an open outcome step of a delivery molecule means the bead is in delivery**, as *A bead closes on merge* and *A bead delivered by a formula* say. No seat is on the bead itself, so never relay to it and never start a worker on it. Poll its pull request, or read its molecule, whose steps show any seat still working it. The beads in delivery are the `delivery` lines of step 4, each with its pull request and its gate. Under a delivery formula, the line names the work bead that waits on its molecule's outcome step. @@ -417,7 +417,7 @@ Starting workers is a **loop**, not a kickoff. Start one at each ready bead, and One topic per effort, `#/-decisions`: -- **A question never goes in it.** A question that you need the human to settle, such as architecture, money, an external commitment or a pull request nobody will merge, goes on its own bead labelled `human`, filed as a worker files one. The top bead, or the bead the question holds up, depends on it. +- **A question never goes in it.** A question that you need the human to settle, such as architecture, money, an external commitment or a pull request nobody will merge, goes on its own bead labelled `human`, as *You own the human's attention for this effort* says. The top bead, or the bead the question holds up, depends on it. - **Only actions the human must take go in it**: provide this credential, trigger this deploy. A review or merge of a pull request is not one, as *A bead closes on merge* says. Everything in it is waiting on the human. No status, no chatter, no acknowledgements. Where your host files the human's actions in a tracker of its own, file each action there instead, and make the waiting bead depend on it. The decisions topic then carries only a pointer to it. **An action already in the human's queue is not filed again.** Another project may have wired it, such as a pending-switch bead. Post it as news that links that bead, with no mention. - **Don't mention the human.** Their queue is where they look. Mention them only when waiting costs something that grows by the hour, such as an outage, and then once, in one line that links the ask. Commy's `list_humans` gives their name. - **Shape every ask as `using-commy` describes.** @@ -427,7 +427,7 @@ One topic per effort, `#/-decisions`: ### A worker's permission waits in its own berth -A permission is the one ask that goes neither on a bead nor in the decisions topic. A worker that needs the human's approval for a command asks for it with the question dialog in its own berth and waits there. A worker stopped at an approval prompt is already waiting. Either way `berth agent-state` reads `blocked`, and the worker's berth id is the `agent_pane` on the bead it sits on. +A permission is the one ask that goes neither on a bead nor in the decisions topic. A worker whose permission mode refused a command it needs asks for it with the question dialog in its own berth and waits there. The dialog carries nothing else. A worker stopped at an approval prompt is already waiting. Either way `berth agent-state` reads `blocked`, and the worker's berth id is the `agent_pane` on the bead it sits on. The human approves in that berth and names the action, or runs the command there themselves. An approval they give anywhere else never reaches the worker, because a permission classifier judges a command by the conversation of the seat that runs it. So don't relay an approval they give you, and don't file a question bead for it. @@ -457,6 +457,7 @@ A stall is work that has stopped moving, and restarting it is your job. Work out Judge liveness by work product, meaning recent posts, commits and bead updates, and not by commy's presence, which can be wrong. Your loop: +- **Settle or lift questions.** When a worker posts a question, answer it or put it to the human on the same wake, as *You own the human's attention for this effort* says. A question a worker has posted and you have not handled is a stall of yours, not a wait on the human. - **Lift actions up.** When a worker posts an action, file it where your host keeps the human's actions, or in the decisions topic where it keeps none, deduplicated and ranked. - **Wake workers when the human acts.** A worker's own watch wakes it when its question bead closes, so you relay nothing for a question. When the human acts on a decisions-topic item, post their word into that worker's working topic. **Mention the worker in every relay**, as `@****` with the name it posts under in that topic. A sleeping worker's subscription can lapse, and a mention reaches it regardless. An answer the human gives you anywhere else goes onto the question bead in their words, with `bd human respond`, before you relay it. - **Confirm the worker woke.** A sleeping worker and a dead one both post nothing. When its question bead closes, or you relay to it, expect its post saying it is resuming, and schedule a wake to check for it. No post by then means dark. diff --git a/skills/worker/SKILL.md b/skills/worker/SKILL.md index 856e490..93205a7 100644 --- a/skills/worker/SKILL.md +++ b/skills/worker/SKILL.md @@ -85,25 +85,18 @@ Post to the working topic at meaningful moments: a milestone reached, a plan cha You will most often stall on something only the human can give you: an answer to a question, a credential, a deploy. When that happens, **don't exit and don't spin.** Starting a seat again costs the human work, and sleeping costs nothing. Where your host's `CLAUDE.md`, or a document it names, says how a seat reaches the human, that rule wins over this section. 1. **Record it on your bead, and stay on the bead you sit on.** Note on your bead what is done and what is left. **Leave the bead you sit on `in_progress`, with your claim and your berth on it.** That is how the steward tells a live seat from a bead in delivery, which no seat sits on, even where both sit behind an open pull-request gate. bd keeps a claim's lease only while its bead is in progress, so setting it `blocked` would drop the lease that shows you are alive. -2. **If it is a question, put it on its own bead, labelled `human`.** That label is the human's queue, which `bd human list` reads. Where your host has you review a question before it goes out, do that first, and if the review lets you settle the question yourself, settle it and record why instead of asking. The bead carries one question, worded so the human can answer it cold. File it in your own tracker, and make the bead you sit on wait on it: - - ```bash - q=$(bd create --silent --labels human --title "" --description "") - bd dep add "$q" - ``` - - The human answers by closing the question bead, and the answer stays on it. Keep the bead true while you wait: edit it if the question changes, and dismiss it with `bd human dismiss` if the question goes away. -3. **Watch the bead your wait ends on** with beady-eye's `watch` tool. For a question, that is the question bead. For a dependency on another bead, in your tracker or another project's, it is that bead, and you name its project. -4. **Post to your working topic.** For a question, post a one-line pointer to its bead, because the question lives on the bead and never only in the post. An action only the human can take, such as supplying a credential, is not a question and gets no question bead: post the action itself, and the steward takes it to the human. Never ask the human directly, and never ask a question or an action with `AskUserQuestion` or any prompt in your terminal, because nobody watches a worker's berth for one. A permission is the one ask you make in your berth, as *Getting the human's permission* says. -5. **Sleep.** Stay open to inbound messages, with no scheduled re-check. Your watch wakes you when the bead changes. The steward relays the human's word on an action, and relays a closed question bead while beady-eye says its watcher is down. Each relay also mentions you, and a mention reaches you even after your subscription has lapsed. -6. **On a message from beady-eye, act on the bead it names.** A comment, or any change that leaves the bead open, does not end your wait. Read it with `bd show`, answer on the bead if the human asked you something there, and sleep again. A bead that closed, or went from its tracker, ends the wait. `unwatch` it, then resume. -7. **Resume.** Rebuild your context first, because the compactor may have compacted you while you slept. Re-read your brief, `bd show` your bead and its notes, and read your working topic since your last post. Then read the answer on the closed question bead with `bd show`. An answer that does not settle the question is still an answer: file a fresh question only if you still need one. Re-check whatever fact you were waiting on, such as a secret now existing or a commit having landed. Post to your working topic that you are awake and resuming, because the steward is waiting for that post, and continue in place. +2. **If it is a question, take it to your steward in your working topic.** The steward has more context than you, so it may settle the question itself. What it cannot settle, it puts to the human on a question bead and makes the bead you sit on wait on it. Post one question, worded so it can be answered cold, with what is needed to answer it. File no question bead yourself, and never ask the human directly. +3. **Post an action to your working topic.** An action only the human can take, such as supplying a credential, is not a question. Post the action itself, and the steward takes it to the human. Never ask a question or an action with `AskUserQuestion` or any prompt in your terminal. The question dialog is only for a permission your permission mode refused, as *Getting the human's permission* says. +4. **Watch the bead your wait ends on** with beady-eye's `watch` tool. For a question the steward put to the human, that is the question bead it names in your topic. For a dependency on another bead, in your tracker or another project's, it is that bead, and you name its project. +5. **Sleep.** Stay open to inbound messages, with no scheduled re-check. The steward answers your question in your topic, or names the question bead it filed, and mentions you either way. Your watch wakes you when the bead changes. The steward relays the human's word on an action, and relays a closed question bead while beady-eye says its watcher is down. A mention reaches you even after your subscription has lapsed. +6. **On a message from beady-eye, act on the bead it names.** A comment, or any change that leaves the bead open, does not end your wait. Read it with `bd show`, and sleep again. A bead that closed, or went from its tracker, ends the wait. `unwatch` it, then resume. +7. **Resume.** Rebuild your context first, because the compactor may have compacted you while you slept. Re-read your brief, `bd show` your bead and its notes, and read your working topic since your last post. Then read the answer, in the steward's reply or on the closed question bead with `bd show`. An answer that does not settle the question is still an answer: take a fresh question to the steward only if you still need one. Re-check whatever fact you were waiting on, such as a secret now existing or a commit having landed. Post to your working topic that you are awake and resuming, because the steward is waiting for that post, and continue in place. ## Getting the human's permission Permission is the one thing you ever need from the human in your berth. When your host's permission mode refuses a command you need, only the human can let it through, and they have to do it in your berth. A permission classifier judges a command by the conversation of the seat that runs it, so an approval given on a bead or on commy never reaches it. An approval typed in your berth clears it only if it names the action. -1. **Record it on your bead, and stay on the bead you sit on,** as step 1 of *Block and sleep* says. File no question bead for a permission. +1. **Record it on your bead, and stay on the bead you sit on,** as step 1 of *Block and sleep* says. A permission is not a question, so it never goes to your steward or on a bead. 2. **Ask with the question dialog in your own berth, and wait at it.** `AskUserQuestion` is a deferred tool, so load it first. Name the exact command and why the work needs it, and word the approving option so it names the action, such as "Go ahead and copy the key". The dialog leaves your berth `blocked`, and a blocked berth is how the human learns that a seat needs them. Don't also post the ask to your working topic or anywhere else, because that would be a second copy of the same ask. 3. **Act on the answer.** If the human approved, run the command. If they ran it there themselves, which always works, check its result. Then continue. If they refused, record that on your bead and post it to your working topic.