From c8f3aece3fa13c02b3817190631b3ee0456728bc Mon Sep 17 00:00:00 2001 From: bompus Date: Fri, 13 Nov 2026 00:28:44 -0700 Subject: [PATCH 1/2] A delegated worker never gives the user an offer or question card It returns the choice, with options and a recommendation, in its final report; the parent decides or asks the user. The rule is stated in Offers (and the end-of-reply case that gives an offer), the multi-agent brief contents, and the multi-agent modifier; the lines that treated a child's question as legitimate now treat it as a brief that lacked the rule or a child that broke it. --- CHANGELOG.md | 1 + rules/core.md | 7 ++++++- rules/modifiers/multi-agent.md | 3 ++- rules/modifiers/question-cards.md | 2 +- rules/references/multi-agent.md | 15 ++++++++++----- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e00e853..5bd82444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Notable changes to house-rules. Versions follow [semantic versioning](https://se ## Unreleased +- A delegated worker never gives the user an offer or a question card: `rules/core.md` § Offers (and the end-of-reply case that gives an offer) says it returns the choice, with options and a recommendation, in its final report to its parent, which decides or asks the user. The brief-contents rule in `rules/references/multi-agent.md` and the `multi-agent` modifier say to put that in every worker's brief, and the lines that treated a child's question as legitimate (the T3 delegated-task wake and the two-minute check) now treat it as a brief that lacked the rule or a child that broke it; the `question-cards` modifier's answer-a-delegated-card line says it applies only when one was raised despite the rule. - The T3 steps that read a thread or list threads state their own start, `limit` and `maxCharsPerItem`, so they read the same on T3 builds that differ in order and defaults (a read with no `afterPosition` returns the oldest items first on older builds and the newest first on newer ones; pingdotgg/t3code #33428): `rules/references/multi-agent.md` (the child check, the progress and end-of-thread reads, a finished child's result) and `hr-handoff`'s `references/successor-thread.md` (the header read for `projectId`, the list and the read-back after a settle). A header-only read is `limit: 1`, `maxCharsPerItem: 1`, `runLimit: 1`; the end of a thread is read from `afterPosition` max(0, `itemCount` minus 60), highest `position` newest. - `hr-sqlite`'s `references/evidence.md` adds a rerun of three measured rows (planner statistics after `PRAGMA optimize`, `synchronous` FULL against NORMAL, and `backup()` against `VACUUM INTO`) on Node 26.13.1 with SQLite 3.54.1. The first figures stay with their versions; the section says the new host, disk and data differ, so the gaps are not attributable to Node or SQLite. Planner statistics still fixed the query (20.4, 6.7 and 8.3 ms to 0.0059 ms); the `synchronous` gap is 7.5 times on this disk, not 87. - `hr-diagnosing-bugs`' `references/evidence-discipline.md` adds three rules for a chain of causes: label each claim measured, derived or inferred (an inference names the observation or report it rests on), test each causal link on timing, mechanism, magnitude and necessity (a case where the trigger fired without the cause, or a probe that removes it) and treat a refuted link as a dead theory unless a second cause could produce the same effect, and re-measure inherited numbers, with claims about people or ownership held to the same evidence as claims about systems. `SKILL.md` adds a stop rule for tracing a failure back cause by cause: stop at the step that names something you can change that would have prevented it (what produced a state that should never exist, or the code that mishandles a legitimate one), and merge steps past about seven. diff --git a/rules/core.md b/rules/core.md index eee6f30f..cef31b57 100644 --- a/rules/core.md +++ b/rules/core.md @@ -21,7 +21,8 @@ A completed step, a status answer or a notification does not skip that check: needing selection: give an offer using § Offers. Include decisions needed to finish authorized work and owned changes that need landing. Present the next ready decision on the session's purpose automatically; the user need not ask - "next?". Parked items (§ Session purpose) are not candidates. + "next?". Parked items (§ Session purpose) are not candidates. A delegated + worker returns the choice in its final report instead (§ Offers). 3. Otherwise, answer the current request and state the remaining blockers or the conditions that would reopen deferred items. Before claiming nothing remains or that the session can close, reconcile earlier requests, open offers and findings. @@ -34,6 +35,10 @@ the user's confirmation unless already directed. ## Offers +A delegated worker never gives the user an offer or a question card: it returns +the choice, with options and a recommendation, in its final report to its parent, +which decides or asks the user. + Ask the way your host and model normally ask. When your host gives you a multiple-choice question tool, you may use it for a decision with options, with the whole decision in the card and the text offer below still complete, because a diff --git a/rules/modifiers/multi-agent.md b/rules/modifiers/multi-agent.md index fe9167e9..22b5fd4d 100644 --- a/rules/modifiers/multi-agent.md +++ b/rules/modifiers/multi-agent.md @@ -16,7 +16,8 @@ schedule, read [the agent-work procedure](../references/multi-agent.md). An incomplete worker report is a checkpoint. A worker with a background command or subagent still running is not done. Verify reports against evidence and use host durations or timestamps for elapsed time. Keep workers from delegating -further unless asked. Never fork a reviewer or panel seat: a fork inherits the +further unless asked. Say in each worker's brief that it never offers or asks the +user (§ Offers). Never fork a reviewer or panel seat: a fork inherits the author's reasoning, so it is not independent. Give implementers the task, file boundaries, public APIs and architectural diff --git a/rules/modifiers/question-cards.md b/rules/modifiers/question-cards.md index fb81ab41..891cf031 100644 --- a/rules/modifiers/question-cards.md +++ b/rules/modifiers/question-cards.md @@ -40,6 +40,6 @@ chose text only (the opt-out above). hosts it arrives as a new turn. With no such tool, or when the tool fails, send the text offer alone and call no -substitute. When you answer a card a delegated agent raised, key each answer by +substitute. When you answer a card a delegated agent raised despite § Offers, key each answer by the question id in the request; some hosts end that agent's first run while its card waits, so wait for the run the answer starts. diff --git a/rules/references/multi-agent.md b/rules/references/multi-agent.md index d23a3587..51b576e1 100644 --- a/rules/references/multi-agent.md +++ b/rules/references/multi-agent.md @@ -12,7 +12,9 @@ run instead of polling, and keep workers from delegating further unless asked; a fork is no exception. Brief a fresh worker by default: its brief is its only context, so state the -goal, the files and what is ruled out. Where the host offers a fork (a worker +goal, the files and what is ruled out, and that it never offers or asks the user +anything: it returns any choice, with options and a recommendation, in its final +report, and you decide or ask the user. Where the host offers a fork (a worker that inherits the whole conversation), use one only when the task depends on so many decisions from the conversation that a brief would be long or lose them; a fork costs more context and time than a brief. Never fork a reviewer or panel @@ -142,8 +144,10 @@ On a host whose delegated tasks run through T3 Code (`delegate_task`), the T3 se ### Reading a T3 delegated task's progress How a parent thread tells whether a task from `delegate_task` is working, waiting -or stuck. Two events wake the parent: the task finishing, and a user question -from the child, which also ends a `mode=wait` call early (`hasPendingQuestion`). +or stuck. Two events wake the parent: the task finishing, and a question +pending in the child (`hasPendingQuestion`), which also ends a `mode=wait` call +early. A brief forbids a child to ask the user, so a pending question means the +brief lacked that rule or the child broke it. An approval request does not send an asynchronous wake. A blocking `mode=wait` returns `pendingApproval` on servers with pingdotgg/t3code #20037. Read the fresh request in the child; that result grants no authority to approve it. @@ -189,8 +193,9 @@ for progress. (`t3_thread_read` with `limit: 1`, `maxCharsPerItem: 1`, `runLimit: 1`) must show `pendingRequestCount` 0 and an `updatedAt` after the start. A count above zero is not by itself a blockage: read the pending requests first (see - `pendingRequestCount` below) and handle a legitimate question instead of - interrupting. Interrupt with `t3_thread_interrupt` only when the child waits + `pendingRequestCount` below) and handle a question by deciding it or asking the + user, then answering it in the child, instead of interrupting; fix the brief. + Interrupt with `t3_thread_interrupt` only when the child waits on an approval nobody will see, or the stall check under "Is it stuck?" (pending requests, then the newest activity) confirms nothing is moving. Say so to the user and relaunch only after fixing the cause. Do not poll beyond this check while From 75ba41f09e222834ab48ca1bc26beee49ac12bbd Mon Sep 17 00:00:00 2001 From: bompus Date: Fri, 13 Nov 2026 00:47:10 -0700 Subject: [PATCH 2/2] Worker no-question rule: state it in End of every reply and the default brief rule, not in the replaceable Offers section coded-offers and model-default-questions replace Offers, so a rule placed there disappeared with them; End of every reply is read by every session. The default brief-contents sentence in coordination-and-isolation.md now carries it too, since a configuration without the multi-agent modifier briefs workers from that reference. --- CHANGELOG.md | 2 +- rules/core.md | 11 +++++------ rules/modifiers/multi-agent.md | 2 +- rules/modifiers/question-cards.md | 2 +- rules/references/coordination-and-isolation.md | 2 +- rules/references/multi-agent.md | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bd82444..4cbe60da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Notable changes to house-rules. Versions follow [semantic versioning](https://se ## Unreleased -- A delegated worker never gives the user an offer or a question card: `rules/core.md` § Offers (and the end-of-reply case that gives an offer) says it returns the choice, with options and a recommendation, in its final report to its parent, which decides or asks the user. The brief-contents rule in `rules/references/multi-agent.md` and the `multi-agent` modifier say to put that in every worker's brief, and the lines that treated a child's question as legitimate (the T3 delegated-task wake and the two-minute check) now treat it as a brief that lacked the rule or a child that broke it; the `question-cards` modifier's answer-a-delegated-card line says it applies only when one was raised despite the rule. +- A delegated worker never gives the user an offer or a question card: `rules/core.md` § End of every reply (which every session reads; the Offers replacements of `coded-offers` and `model-default-questions` cannot drop it) says it returns the choice, with options and a recommendation, in its final report to its parent, which decides or asks the user. The brief-contents rules in `rules/references/coordination-and-isolation.md` (default rules), `rules/references/multi-agent.md` and the `multi-agent` modifier say to put that in every worker's brief, and the lines that treated a child's question as legitimate (the T3 delegated-task wake and the two-minute check) now treat it as a brief that lacked the rule or a child that broke it; the `question-cards` modifier's answer-a-delegated-card line says it applies only when one was raised despite the rule. - The T3 steps that read a thread or list threads state their own start, `limit` and `maxCharsPerItem`, so they read the same on T3 builds that differ in order and defaults (a read with no `afterPosition` returns the oldest items first on older builds and the newest first on newer ones; pingdotgg/t3code #33428): `rules/references/multi-agent.md` (the child check, the progress and end-of-thread reads, a finished child's result) and `hr-handoff`'s `references/successor-thread.md` (the header read for `projectId`, the list and the read-back after a settle). A header-only read is `limit: 1`, `maxCharsPerItem: 1`, `runLimit: 1`; the end of a thread is read from `afterPosition` max(0, `itemCount` minus 60), highest `position` newest. - `hr-sqlite`'s `references/evidence.md` adds a rerun of three measured rows (planner statistics after `PRAGMA optimize`, `synchronous` FULL against NORMAL, and `backup()` against `VACUUM INTO`) on Node 26.13.1 with SQLite 3.54.1. The first figures stay with their versions; the section says the new host, disk and data differ, so the gaps are not attributable to Node or SQLite. Planner statistics still fixed the query (20.4, 6.7 and 8.3 ms to 0.0059 ms); the `synchronous` gap is 7.5 times on this disk, not 87. - `hr-diagnosing-bugs`' `references/evidence-discipline.md` adds three rules for a chain of causes: label each claim measured, derived or inferred (an inference names the observation or report it rests on), test each causal link on timing, mechanism, magnitude and necessity (a case where the trigger fired without the cause, or a probe that removes it) and treat a refuted link as a dead theory unless a second cause could produce the same effect, and re-measure inherited numbers, with claims about people or ownership held to the same evidence as claims about systems. `SKILL.md` adds a stop rule for tracing a failure back cause by cause: stop at the step that names something you can change that would have prevented it (what produced a state that should never exist, or the code that mishandles a legitimate one), and merge steps past about seven. diff --git a/rules/core.md b/rules/core.md index cef31b57..8d3c8ab5 100644 --- a/rules/core.md +++ b/rules/core.md @@ -21,8 +21,7 @@ A completed step, a status answer or a notification does not skip that check: needing selection: give an offer using § Offers. Include decisions needed to finish authorized work and owned changes that need landing. Present the next ready decision on the session's purpose automatically; the user need not ask - "next?". Parked items (§ Session purpose) are not candidates. A delegated - worker returns the choice in its final report instead (§ Offers). + "next?". Parked items (§ Session purpose) are not candidates. 3. Otherwise, answer the current request and state the remaining blockers or the conditions that would reopen deferred items. Before claiming nothing remains or that the session can close, reconcile earlier requests, open offers and findings. @@ -33,11 +32,11 @@ or empty result is not one: diagnose, then retry or go around. Risky or irreversible actions, like publishing or pushing to a shared branch, need the user's confirmation unless already directed. -## Offers +A delegated worker never gives the user an offer or a question card, so case 2 +does not apply to it: it returns the choice, with options and a recommendation, +in its final report to its parent, which decides or asks the user. -A delegated worker never gives the user an offer or a question card: it returns -the choice, with options and a recommendation, in its final report to its parent, -which decides or asks the user. +## Offers Ask the way your host and model normally ask. When your host gives you a multiple-choice question tool, you may use it for a decision with options, with diff --git a/rules/modifiers/multi-agent.md b/rules/modifiers/multi-agent.md index 22b5fd4d..0dbf5889 100644 --- a/rules/modifiers/multi-agent.md +++ b/rules/modifiers/multi-agent.md @@ -17,7 +17,7 @@ An incomplete worker report is a checkpoint. A worker with a background command or subagent still running is not done. Verify reports against evidence and use host durations or timestamps for elapsed time. Keep workers from delegating further unless asked. Say in each worker's brief that it never offers or asks the -user (§ Offers). Never fork a reviewer or panel seat: a fork inherits the +user (§ End of every reply). Never fork a reviewer or panel seat: a fork inherits the author's reasoning, so it is not independent. Give implementers the task, file boundaries, public APIs and architectural diff --git a/rules/modifiers/question-cards.md b/rules/modifiers/question-cards.md index 891cf031..8ac306d6 100644 --- a/rules/modifiers/question-cards.md +++ b/rules/modifiers/question-cards.md @@ -40,6 +40,6 @@ chose text only (the opt-out above). hosts it arrives as a new turn. With no such tool, or when the tool fails, send the text offer alone and call no -substitute. When you answer a card a delegated agent raised despite § Offers, key each answer by +substitute. When you answer a card a delegated agent raised despite § End of every reply, key each answer by the question id in the request; some hosts end that agent's first run while its card waits, so wait for the run the answer starts. diff --git a/rules/references/coordination-and-isolation.md b/rules/references/coordination-and-isolation.md index 7f32af77..8ea6a881 100644 --- a/rules/references/coordination-and-isolation.md +++ b/rules/references/coordination-and-isolation.md @@ -25,4 +25,4 @@ directory is your own checkout. Run a long job under a supervisor that outlives the session and reports how it ended (a status record and a message to the thread that owns the job, with the job's output kept somewhere that survives the session), so a session reload or crash does not lose the result: no bare background shell and no detached unit without a reporter; the host supplies the command, and where it supplies none, run the job in the foreground or tell the user what is missing instead of detaching it. -Keep small or tightly coupled tasks local. Use subagents for bounded investigations or reviews; they stay read-only when they share your directory. Delegate implementation only when authorized, in its own worktree. Brief each worker with the user's request in their own words, then your reading of it, plus paths, constraints and what counts as done. Give each item a check that counts the effect (a delete sent exactly once), not "the button works". Number the items of a batch of feedback and give each an owner. Ask for evidence, checks run and open uncertainty. Weigh its evidence without redoing its investigation, but keep the required review and integration checks. Before building on a worker's claim that something is undefined, unused or missing, search the whole repository yourself. +Keep small or tightly coupled tasks local. Use subagents for bounded investigations or reviews; they stay read-only when they share your directory. Delegate implementation only when authorized, in its own worktree. Brief each worker with the user's request in their own words, then your reading of it, plus paths, constraints and what counts as done, and that it never offers or asks the user (§ End of every reply). Give each item a check that counts the effect (a delete sent exactly once), not "the button works". Number the items of a batch of feedback and give each an owner. Ask for evidence, checks run and open uncertainty. Weigh its evidence without redoing its investigation, but keep the required review and integration checks. Before building on a worker's claim that something is undefined, unused or missing, search the whole repository yourself. diff --git a/rules/references/multi-agent.md b/rules/references/multi-agent.md index 51b576e1..7438fb9b 100644 --- a/rules/references/multi-agent.md +++ b/rules/references/multi-agent.md @@ -13,8 +13,8 @@ a fork is no exception. Brief a fresh worker by default: its brief is its only context, so state the goal, the files and what is ruled out, and that it never offers or asks the user -anything: it returns any choice, with options and a recommendation, in its final -report, and you decide or ask the user. Where the host offers a fork (a worker +anything (§ End of every reply): it returns any choice, with options and a +recommendation, in its final report, and you decide or ask the user. Where the host offers a fork (a worker that inherits the whole conversation), use one only when the task depends on so many decisions from the conversation that a brief would be long or lose them; a fork costs more context and time than a brief. Never fork a reviewer or panel