Shaping an issue
You will learn
What the Queen does with an issue that lacks sections, and why she stops after two tries.
A bee can start only on an issue that says what to do and which files it may touch. The Queen holds every open issue to judge() of specs/policy/issue_shape.t27. One that is not ready she shapes: a model writes the missing sections, and the body goes back only if judge() then finds nothing missing. After SHAPE_ATTEMPT_LIMIT, 2 failed shapes, she stops and comments once with what is missing, and an epic is never shaped. shape_action in shaping.t27 decides, and a new try waits 360 minutes.
Try it
Set two sections missing and step through the tries; then mark the author told and see which column the issue goes to.

Set how many sections an issue lacks and how often shaping failed: the Queen leaves it, shapes it, or tells its author once what is missing.
specs/queen/shaping.t27
// SPDX-License-Identifier: Apache-2.0
; specs/queen/shaping.t27 -- the Queen shapes an issue that is not ready, or says once what it lacks
; Owner, 2026-10-08 (translated): forbid issues that break the rules; find every fragile place and fix
; it; 233 + 115 issues are not ready for work because their spec is missing or incomplete.
; Measured that morning on /queen/status: of 704 candidates, the round said "nothing to choose" in most
; rounds while 63 of 70 lanes stood idle. 233 issues were skipped as missingBoundary and 115 as
; incompleteSpec. Some of them have a `## Boundary` heading with prose under it and no path (#7703,
; #7642), which the rule counts as missing.
; --
; The rule an issue must meet is specs/policy/issue_shape.t27 (judge: one bit per missing section).
; A workflow cannot hold that line here: .yml is owner-only, and `gh issue create` never sees a
; template. So the Queen holds it in her own round. Every open issue that judge() refuses is either
; SHAPED by her (the missing sections are written by a model, every boundary path is checked against
; the repository, and the body is written back only if judge() then returns 0), or, when shaping
; failed SHAPE_ATTEMPT_LIMIT times, its author is told ONCE what is missing.
; --
; A wrong boundary is worse than a missing one (tools/queen/propose_boundary.py): it reserves files the
; work does not own. So path_accepted refuses a path the model invented: a path that does not exist is
; accepted only when the issue itself cites it and its directory exists, and never when it would be a
; new file in a language the only-t27 rule denies.
; Containers (labels epic, roadmap) are not tasks, as issue_shape says; they are never shaped.
; ASCII only (L3).
; phi^2 + 1/phi^2 = 3 | TRINITY
module QueenShaping;
/// What the Queen does with one open issue.
/// LEAVE nothing: it is ready, a container, or already told
/// SHAPE ask for the missing sections, judge them, write them back if they pass
/// TELL comment once, naming what is missing
pub const SH_LEAVE : u8 = 0;
pub const SH_SHAPE : u8 = 1;
pub const SH_TELL : u8 = 2;
/// Attempts at shaping one issue before its author is told instead.
pub const SHAPE_ATTEMPT_LIMIT : u32 = 2;
/// Issues shaped per round. A shape is one model call; the round has other work.
pub const SHAPES_PER_ROUND : u32 = 3;
/// Minutes between two attempts on one issue, so a refused shape is not retried every round.
pub const SHAPE_RETRY_MINUTES : u32 = 360;
/// A boundary is a reservation; one naming more files than this is not a task, it is a project.
pub const MAX_BOUNDARY_PATHS : u32 = 12;
/// `missing`: judge()'s bits for the body (0 = ready); `container`: labelled epic or roadmap;
/// `attempts`: shapes tried so far; `told`: the author was already told.
pub fn shape_action(missing: u8, container: bool, attempts: u32, told: bool) -> u8 {
if (missing == 0) { return SH_LEAVE; }
if (container) { return SH_LEAVE; }
if (attempts < SHAPE_ATTEMPT_LIMIT) { return SH_SHAPE; }
if (told) { return SH_LEAVE; }
return SH_TELL;
}
/// Is one proposed boundary path acceptable?
/// exists the file is in the repository at the base ref
/// dir_exists its directory is (a new file beside its siblings)
/// cited the issue's own title or body names this path
/// foreign_new it would be a NEW file whose extension the only-t27 rule denies to new work
/// A file that exists is always acceptable: finding the file a title describes is the point. A file
/// that does not exist must be cited by the issue, in a directory that exists, and not foreign.
pub fn path_accepted(exists: bool, dir_exists: bool, cited: bool, foreign_new: bool) -> bool {
if (exists) { return true; }
if (dir_exists == false) { return false; }
if (foreign_new) { return false; }
return cited;
}
/// Does a shape land? Only when the body it produces is ready (judge() = 0), it names between 1 and
/// MAX_BOUNDARY_PATHS paths, and every one of them was accepted.
pub fn shape_lands(missing_after: u8, paths: u32, rejected: u32) -> bool {
if (missing_after != 0) { return false; }
if (paths == 0) { return false; }
if (paths > MAX_BOUNDARY_PATHS) { return false; }
return rejected == 0;
}
/// Is an attempt due? Never twice inside SHAPE_RETRY_MINUTES on one issue.
pub fn attempt_due(attempts: u32, minutes_since_last: u32) -> bool {
if (attempts == 0) { return true; }
return minutes_since_last >= SHAPE_RETRY_MINUTES;
}
test a_ready_issue_and_a_container_are_left_alone {
assert shape_action(0, false, 0, false) == SH_LEAVE;
assert shape_action(15, true, 0, false) == SH_LEAVE;
assert shape_action(1, true, 9, false) == SH_LEAVE;
}
test an_unready_issue_is_shaped_then_its_author_is_told_once {
assert shape_action(1, false, 0, false) == SH_SHAPE;
assert shape_action(15, false, SHAPE_ATTEMPT_LIMIT - 1, false) == SH_SHAPE;
assert shape_action(15, false, SHAPE_ATTEMPT_LIMIT, false) == SH_TELL;
assert shape_action(15, false, SHAPE_ATTEMPT_LIMIT, true) == SH_LEAVE;
assert shape_action(8, false, SHAPE_ATTEMPT_LIMIT + 3, true) == SH_LEAVE;
}
test a_boundary_path_must_be_true_of_the_repository {
// an existing file, cited or found
assert path_accepted(true, true, false, false) == true;
assert path_accepted(true, true, true, false) == true;
// a new spec the issue asks for, beside its siblings
assert path_accepted(false, true, true, false) == true;
// a new file the issue never mentioned: invented
assert path_accepted(false, true, false, false) == false;
// a new file in a directory that does not exist
assert path_accepted(false, false, true, false) == false;
// a new .py or .ts the only-t27 rule denies, even when cited
assert path_accepted(false, true, true, true) == false;
}
test a_shape_lands_only_when_the_body_is_ready_and_every_path_holds {
assert shape_lands(0, 1, 0) == true;
assert shape_lands(0, MAX_BOUNDARY_PATHS, 0) == true;
assert shape_lands(1, 3, 0) == false;
assert shape_lands(0, 0, 0) == false;
assert shape_lands(0, MAX_BOUNDARY_PATHS + 1, 0) == false;
assert shape_lands(0, 3, 1) == false;
}
test a_refused_shape_is_not_retried_every_round {
assert attempt_due(0, 0) == true;
assert attempt_due(1, SHAPE_RETRY_MINUTES - 1) == false;
assert attempt_due(1, SHAPE_RETRY_MINUTES) == true;
}
invariant the_codes_and_limits_never_move {
assert SH_LEAVE == 0 and SH_SHAPE == 1 and SH_TELL == 2;
assert SHAPE_ATTEMPT_LIMIT > 0 and SHAPES_PER_ROUND > 0;
assert MAX_BOUNDARY_PATHS > 0;
}
All lessons
Module 1 · The task
An issue becomes work only once it is shaped: the sections it lacks are written or asked for, its boundary names real files, and one filter reads every kind of task.
Module 2 · Who goes next
The order the Queen takes issues in: a label ages one step, at most 3 criticals run as critical, and nothing new starts while finished work waits for review.
Module 3 · A bee's life
From candidate to done: twelve states and sixteen events, a ship in the game that flies home, and a deploy that does not cut a bee short.
Module 4 · The reviewer bee
Finished work is judged on its own clock: enough reviews at once to keep up, a pause that doubles for a row that waits, and a merge gate that zero checks cannot open.
Module 5 · The review jam
A pull request that will not move is in exactly one of ten cases, each with the Queen's move, and a red check is inherited only when master says so.
Module 6 · Keys
A bee's model key can be refused: the code in the body sorts the refusal, a transient one rests the key for seconds, and the bee moves on to the next free key.
Module 7 · Credit and money
Lending a key earns no credit, an operation is sold at twice its cost in half-cent tokens, and tokens burn 30 days after they land.
Module 8 · Agents among themselves
One bot per agent in one group: who is called, a chain three bot messages deep, and the clocks that keep agents from flooding a chat.
Module 9 · Night and the board
What the hive shows: a night watch that opens, comments on and closes issues, the columns of the public board, and the comb that flashes for each event.