---
name: morning-standup
description: Daily standup across every active session on this repo — everyone reports, everyone hears the digest, the work nobody is on gets owned, and the morning ends with a Today plan proposed for the human to confirm.
argument-hint: "Anything to put on the agenda? (optional)"
disable-model-invocation: true
---

# Morning standup

A real standup: everyone says what they did, what they're doing, what's in their way — and
**everyone hears everyone**. Cheap, timeboxed, no arbitration.

Collisions get flagged here, not solved here. Solving them is `/get-aligned`, which publishes a
binding ownership map. Taking it offline is the point of saying "take it offline".

Doctrine for how peers talk lives in `coordinating-with-peer-sessions`. The messages below inline the
rules they depend on, because a receiving session may never invoke that skill.

## Phase 0 — the board

Lanes come from issues, not from plan files. Plan-file checkboxes are not progress: measured in one
repo, 359 unchecked and zero checked across seven plans, including work that had shipped. Ticking is
friction for the ticker and invisible to everyone else, so nobody ticks. Read a plan only when a lane
names one, and only as the *how*.

Find the phase **map issue** — the GitHub issue labelled `wayfinder:map`, the convention already
documented in that repo's `docs/agents/issue-tracker.md`, reused rather than duplicated with one of
our own:

```bash
gh issue list --state open --label wayfinder:map --json number,title,body
```

**Exactly one match is required, and zero versus several are not the same failure.** Several matches
means the board convention is in use and something is broken — a duplicate map — worth raising to the
human. Zero matches needs one more check before it counts as ambiguous: `gh label list`, for a
`wayfinder:*` label anywhere in the repo. None at all means this repo has simply never adopted the
board convention (below). A `wayfinder:*` label that exists with no open issue wearing it is the real
ambiguity: the board cannot be read deterministically — degrade to human-named lanes (below) rather
than guess which issue is the map.

With the map issue found, list its children — GitHub sub-issues where the repo has them enabled:

```bash
gh api repos/{owner}/{repo}/issues/<n>/sub_issues --jq '.[] | {number, title, state}'
```

Where sub-issues are not enabled, that call returns nothing usable: fall back to the task list in the
map issue's body, whose children each carry a `Part of #<n>` line at the top of their own body — the
convention documented in `docs/agents/issue-tracker.md`.

**Read that convention as a union, not only as a fallback.** An issue can declare membership in its
own body and never have been attached, and on a busy repo most of them have not been:

```bash
gh issue list --state open --limit 200 --search '"Part of #<n>" in:body' --json number,title,labels
```

Attached children are **the board**, in map order. Issues that declare membership and were never
attached are **the unattached**.

**The unattached are reported, and never dispatched from the board's order.** No dispatch order is
invented for them — not by severity, not by issue number, not by age. Attaching is the only way into
the board's order, and attaching is the human's act.

**Reporting order and dispatch order are different things, and only the second is forbidden.** This
skill already ranks a *report* by severity where no map order exists. So the digest names the
unattached: the count, and the issues at the top severity tier present, so the human can see what is
sitting outside the board. Print the attach command beside them:

```bash
gh api -X POST repos/{owner}/{repo}/issues/<n>/sub_issues -f sub_issue_id=<id>
```

**Attaching is how the human re-orders, and it is the only way into dispatch.** One call, ten
seconds. This skill never attaches anything: boarding is an ordering decision, and the one time a
lane made that decision for itself the attach was reverted 68 seconds later.

**Why they are not simply dispatched in severity order.** That would be a *dispatch* order nobody
chose, and one label edit would reorder it overnight — the instability the map-order rule exists to
prevent — while severity is absent from a third of these issues anyway. Map order is the human's
priority decision. A map with many children in an invented order is worth less than one with few in a
real one, and that holds for a dispatch queue exactly as it holds for a map.

Then check each open child's own blockers, one issue at a time:

```bash
gh api repos/{owner}/{repo}/issues/<child> --jq '.issue_dependencies_summary.blocked_by'
```

`blocked_by` comes back `null` on an issue with no dependency data recorded at all — not on one with
zero blockers. Treat `null` as **dependency data unavailable** and report it as such: `null == 0` is
false, so reading `null` as unblocked silently drops that child from the board, and reading it as
blocked is just as much a guess. Report it; don't resolve it either way.

A candidate lane is an open child of the map issue that is:

- **unblocked** — `issue_dependencies_summary.blocked_by == 0`
- **unclaimed** — no row for this lane in the ownership file `~/.claude/align/<repo-basename>/map.md`
  whose `sessionId` appears in the unfiltered `claude agents --json` listing — the same listing Phase 6's
  release check uses. This is about liveness, not row status, and it is not `get-aligned`'s own
  `live/parked/held/prospective` vocabulary for that file. This skill reads only rows in a shape it can
  interpret; a row written by `get-aligned` or `split-the-plan` is left alone, never reinterpreted.
- **region-declared** — its region (below) is stated; a lane with no declared region is excluded here,
  not carried forward on a guess
- **typed** — a candidate carrying a label marking it as awaiting a ruling (`needs-decision`, or this
  repo's equivalent) is **not excluded; it is routed.** `blocked_by` models **issue-to-issue edges
  only**, so an issue blocked on a decision nobody has made reports `blocked_by == 0` and reads as
  ready. Dispatching it **as remediation** gets a seat to guess at the ruling, and that rule stands —
  measured on this machine, two such issues sat at the top of a freshly built board and one was the
  second lane the first dispatch would have handed out. But excluding it altogether turns the item
  nobody can *start* into the item nobody ever *works*, and on that board those were the two most
  severe items on it. It is a **decide lane**: its deliverable is the package that makes the ruling
  cheap, and its explicit prohibition is making the ruling. Everything else is a **remediate lane**.

  **Decide lanes are board-independent, and this is the one carve-out from the unattached rule.** A
  decision-bearing issue is a decide lane whether or not it is an attached child, so **this list's
  opening clause — "an open child of the map issue" — does not bind a decide lane.** Every other
  property in the list still does: unblocked, unclaimed, region-declared.

  **The carve-out is narrow and its edge is exact.** It reaches an unattached issue *only* where that
  issue carries the ruling label or is carried forward from the previous digest. An unattached issue
  with no such label stays reported-only. **Why it is safe:** a decide lane's deliverable is a package
  for the human, not a change to the code the board orders, so it neither consumes the board's priority
  ordering nor needs a place in it. Remediate lanes do need the board, because their priority is a
  human judgement only the board holds. That asymmetry is the point — a boarding gap starves
  remediation and leaves decisions reachable, rather than killing both.

  **This is not re-deriving priority from labels.** Routing is not ordering. Boarded children keep map
  order; the label decides only which deliverable a lane owes. Phase 0 already reads labels this way.

  **Carry-forward.** A lane named under the previous digest's **`## Decisions for the human`** heading
  and still open is a decide lane whether or not it carries the label. **Read that heading, not the
  prose around it** — Phase 3 writes it under exactly that string every morning so this rule has
  something to find rather than a section to infer. The digest is this skill's own durable record; a decision
  it reported yesterday does not become undecided because nobody labelled the issue. Where the label
  and the carry-forward disagree, take the **union** and report the disagreement in one line — label
  it, or correct the map. Do not resolve it silently in either direction.

  **A decision-bearing issue that already carries a decision package is not a lane.** A package is two
  or more **named options with their consequences**. Dispatching a seat to restate an analysis another
  lane already wrote is how a fleet audits its own audit.

  Pre-filter by size, then read:

```bash
gh issue view <n> --json body,comments --jq '.body + "\n" + ([.comments[].body]|join("\n"))' | wc -l
```

  **The size is a pre-filter, not the verdict.** Read the body of each candidate — there are rarely
  more than a handful — and report what you found, quoting the option list where one exists. A grep
  count is a verdict dressed as a measurement. Under the absence rule, say what you read.

  **A consequence must be stated, not implied.** Naming two branches — *do X, or do Y* — is not a
  package. What makes it one is that each option carries what it costs or what it forecloses, written
  down, so a human can rule without reconstructing the argument.

  Package present → an item on Phase 3's decision list, never a lane. Package absent → a decide lane.
  **Uncertain → a decide lane, and say so.** An issue whose package is arguable is one whose options
  are not clearly stated, which is precisely what a decide lane produces — and the decide-lane briefing
  in Phase 5 makes *"the package already existed and the question is moot"* a valid answer and the
  strongest one, so nothing is lost by choosing that direction under doubt.

  **This resolves and then reports; it does not decline to resolve.** That is the carry-forward pattern —
  take the reading, state the disagreement — and deliberately *not* the pattern used for
  absent dependency data, which is left unrouted precisely because no reading of it is
  available. Here a reading is available; it is only uncertain. Say what you read.

  Being wrong toward a lane costs one seat restating a package that existed. Being wrong toward an item
  puts a half-argued decision in front of the one person whose attention the whole list exists to
  protect. Not running the test at all costs a fleet re-deriving its own findings.

Take the candidate lanes in map order. That order is the human's priority decision, made once when the
children were ordered. Do not re-ask it, and do not re-derive it from titles, age, or labels.

**Each candidate lane carries a region**, read from that sub-issue's body — Phase 4's collision check
compares that region against the poll's **`owns`** answers as well as against live `map.md` rows, so a
lane without one can't be reconciled. A sub-issue that names no region is never a candidate lane: it is excluded from what Phase 2
polls on, not merely deprioritized. It is not dropped from the run — Phase 3 still surfaces it as a
flag, `→ the human`, exactly like any other region-undeclared lane.

**A candidate whose region is already claimed rides; it is not dispatched.** A region is claimed when
**either** test holds, and both are run every time:

1. a **live lane** holds it — a `map.md` row for that region whose `sessionId` is still in the live
   session listing; **or**
2. **a lane this same run has already dispatched** holds it.

**Both tests read the `map.md` file and this run's own dispatches — and nothing else.** The poll has
not gone out yet, so no `owns` answer exists here to read. Naming the source is not pedantry: Phase 4
reads a third one, and a test that leaves its source unnamed is what put a land lane behind its own
author's declaration.

Compare **region heads** — the text before the em dash — by string equality, never by a judgement
about adjacency. Anything subtler goes to the poll, and Phase 4 resolves it against the poll's
**`owns`** field — the source Phase 0 does not have.

A rider is routed to that incumbent as a **decision request**, recorded `held-in-region`, and named
on Phase 3's decision list. It gets no `map.md` row: nothing was bound.

**A rider carries the ruling, never the work.** Measured: two lanes handed a question sideways
mid-flight both answered fast and well — one with three reasons to refuse, including one the overseer
had missed — and **neither did the work**. Filing is where a lane offloads, not where it queues: one
lane filed two issues from inside its own review and worked neither. So a rider whose item needs
implementing returns to the dispatch pool — it stays an ordinary candidate and is dispatched on its
own terms — rather than sitting with the incumbent.

**Riders are reported grouped by incumbent, and a group larger than two is a flag `→ the human`, not
a queue.** Six decisions dropped on one seat is not routing, it is a split signal — `/split-the-plan`
on that lane, which is the human's call and not this skill's. Without this the rule quietly converts
one overloaded region into one overloaded seat. Measured on one morning: the board gained six
children and every one of them shared a region head with a single live lane, so the board grew by six
and the dispatchable set grew by nothing.

**The rider rule is not type-blind — it applies the same pairwise test Phase 4 uses.** Riding runs
*before* the poll, so a pair resolved silently here never reaches Phase 4's matrix at all. Resolve the
pair before riding:

- **`decide` ∩ `remediate`** — not a collision. The decide candidate is **dispatched and paired** with
  the remediate lane; it does not ride. A decide lane writes no code.
- **`decide` ∩ `decide`** — a collision. The later in order rides, **and the pair is flagged
  `→ /get-aligned` on the decision list** rather than silently resolved. Phase 4's handling exists for
  exactly this pair, and a silent ride is what would stop it ever firing.
- **`remediate` ∩ `remediate`** — the later in order rides.

No `land` pairing appears in this test: no land lane exists before the poll, so `anything ∩ land` is
not computable here and is not attempted (see the end of this phase).

**Ordering between an attached candidate and a board-independent decide lane on one region:** the
attached one goes first. Map order is a decision a human made; board-independence is an exemption from
needing one, not a claim to precedence. State it rather than leaving it to whichever the query
returned first.

**That is pairwise. Generalised, the ordering below is the one every "first in order" and "later in
order" in this skill reads — including Phase 5's. The *ordering* is universal; the *resolution* of a
tie inside it is not, and each site states its own.** Some candidates have **no position at all** —
none in map order, and none in any order a human stated: a **board-independent decide lane**, which the
carve-out above admits whether or not it was ever attached. It was never taken in map order, and Phase
0 forbids supplying one — not by severity, not by issue number, not by age. **A human-named lane is not
in that population**: the ask is for today's lanes *in priority order* (below), so naming them
positions them and a human-named lane has a position like any boarded child. So, over any set of
candidates this skill must order:

1. **the candidates that have a position — map order, or the order the human named them in — in it**;
   then
2. **the candidates that have none, as one group.**

**Inside that group there is no order and none is invented.** Where a rule needs *the first* or *the
later* and any candidate in contention has a position, the order above answers it — the positioned one
wins and the group never comes up. **Where every candidate in contention lacks one, the tie is
undefined, and what happens then is the contending site's rule, not this paragraph's.** Two sites
contend, over two different things:

**Phase 0 contends for a region.** Where several candidates share a region head and every one of them
lacks a position, which of them rides is undefined, so **none of them is dispatched from that region
this run.** They go together on Phase 3's flag list as an ordering question `→ the human` — beside the
region-undeclared lanes they most resemble, and not on the decision list, which carries
`held-in-region` resolutions and these are not one. They keep whatever flag they already carry: a
`decide` ∩ `decide` among them still goes `→ /get-aligned`. Exactly like a region-undeclared sub-issue,
they **do not enter Phase 4's three states**. The human settles it — by attaching the issue where there
is a board to attach to, by naming its place in today's order where there is not. Picking one for them
is the invented dispatch order this phase spends the most text forbidding.

**Phase 5 contends for a seat, and that resolution above does not reach it.** Its group is not in a
region contention at all: those lanes **did** enter Phase 4's three states — they resolved to `needs a
chat`, which is the only way they reached the chat list and were counted into N — and the ambiguity is
that the chats ran out inside the group. Phase 5 routes them to **unbound with a reason**, a Phase 5
output, never onto Phase 3's flag list, and states that rule where it arises.

**A rider older than two standups is a flag `→ the human`, or a long-running lane makes its whole
region invisible to dispatch.** Its age comes from the decision list, where every rider is named with
its day count and that count carries forward — riders get no `map.md` row and no first-seen stamp of
their own, so the list is the only place that count exists.

**Why the second test exists**, since it is the one an implementer will be tempted to drop: without
it, a run that releases an incumbent dispatches every candidate in that region at once.
Measured: when one lane's owner exited, its issue was released and the five children sharing its
region head had no incumbent left to ride to — six candidates, one region, and a rule checking only
*live* lanes sees no collision. Where several candidates share a region head and nothing claims it,
**dispatch the first in order — the generalised ordering above, which is map order where there is a
board and the human's named order where there is not — and hold the rest `held-in-region` behind it**,
named on the decision list as a split question exactly like riders behind a live incumbent.

**Region-head equality has false negatives and this skill states so rather than claiming coverage.**
Two issues can name the same code under different heads. Report the rule's shape, not a claim that it
is complete.

**Where the map body records a child as awaiting a ruling and the issue carries no such label**, the
carry-forward rule makes it a decide lane **and** the digest asks for the label in one line. Two
sources of truth disagreeing is a thing to report, never a thing to resolve silently.

**This repo has no `wayfinder:*` label at all?** State that once, flatly: this repo is not on the board
convention. That is a fact about the repo, not a question — never re-litigate it morning to morning.
It is not, on its own, a reason to stop: fold straight into the open-issues report below, the same as
any other degradation, and let the human name today's lanes from that list, **in priority order**, if
they want to.

**No map issue found, or more than one, in a repo that does use the convention?** Say so in one line,
list the open issues as context, and ask the human to name today's lanes **in priority order**. **The
run does not block waiting on that answer, and it does not invent lanes to fill the gap.** It reports the board, states
plainly that lanes are unnamed and why, and continues through Phase 1's roster and Phase 3's digest
exactly as if lanes had been named. The run ends having asked; an ask that goes unanswered is a
reported state, not a failure. A human-named lane carries whatever region the human states when naming
it; one named without a region is **region undeclared**, exactly like a sub-issue that declares none.
With no map issue, there are no sub-issues and therefore no declared regions at all: Phase 4's collision
check has nothing to run against, and lane-to-session matching is the human's call that morning.
Never invent a priority order from an unordered issue list — a different order every morning is worse
than no order.

**The ask says *in priority order* because naming is positioning.** The sequence the human names lanes
in is their order, read exactly as the board's order is read off the sequence of attached children —
and read, not derived: a human typing lanes in sequence is the same act as attaching them, performed
through the only mechanism a repo with no board has. This skill already reads structure out of that
act, in the paragraph above, when it takes a lane's region from how the human named it. Deriving one
would be the forbidden thing; reading the one stated is not. So **a human who names lanes and states
no separate ordering has still stated one**, in the sequence; take it and do not ask again. **Where
the names cannot be told apart** — one run-on answer with no separation this skill can read — **no
lane was named**: continue with lanes reported unnamed, exactly as on silence, and say that is why.
Human-named lanes therefore never join the unpositioned group above.

**Both branches fold into the same open-issues report, and the same offer to name lanes from it.** A
repo with open issues always has work to report, whether or not a map issue exists and whether or not
it has ever adopted the convention. List them, name the ones nobody is assigned to, and rank them by
label, matched case-insensitively against this fixed sequence, most severe first: **critical, high,
medium, low**. Issues carrying none of those four come last, in issue-number order — a label that is a
status rather than a severity (e.g. `refuted`) does not enter the ranking, and an issue marked resolved
or refuted is not surfaced as work at all. **If no label in the repo matches any of the four tiers,
there is no severity ordering available:** present the issues in issue-number order and say in one line
that no severity labels were found, rather than deriving an order from titles, age, or anything else.
Let the human name today's lanes from that list, **in priority order**, if they choose to —
non-blocking, per the rule above: silence continues the run with lanes reported unnamed, never
invented. **"Quiet" means no open issues and no live sessions** (see the sideways table) — never
describe a morning with open issues sitting unassigned as quiet, map issue or not.

**Before any lane is dispatched, measure what the fleet failed to retire.** One line, and it opens the
digest:

```
open <N> · retired <M> since <window start> · filed since <window start>: <F> · unlanded <B> branches /
<C> commits (<blocked>, <stale>) · <R> refs at +0 with uncommitted worktrees · <U> unreferenced merges
· measured <instant>
```

- **open** — every open issue in the repo, not only the board's children. The gap between this and the
  board is the point: a board that cannot grow while `open` climbs is the thing the line exists to show.
- **window start** — the same instant Phase 1 computes for the roster, the mtime of the newest file in
  the standups directory. Computed once, used by both.
- **retired** — issues closed since the window start.
- **filed** — issues opened since the window start, and the lane that filed each. On one measured day
  that was 41 across 9 lanes and no phase of this skill could see it.
- **unlanded** — local branches **ahead of `origin/master`**. Count by `ahead > 0`, never by
  `--no-merged`, for two separate reasons. `git branch --no-merged | wc -l` counts **lines, not
  branches** — a detached HEAD prints an extra pseudo-branch line that is not one. And past that,
  `--no-merged` answers *ancestry*, where this line asks *has unique work*. **Never count with `-a`
  either**: remote-tracking refs duplicate the local branches.
- **`<blocked>` and `<stale>`** split `unlanded` by whether the branch has fallen behind. A branch
  `0` behind is **blocked** — a clean fast-forward waiting on a ruling, not rotting. A branch behind
  is **stale**. A land lane that assumes staleness is wrong about the branches that matter most.
- **`<R> refs at +0`** — refs carrying no commits at all whose worktree holds uncommitted work. These
  are **not** unlanded branches and are never counted inside that number; they are reported beside it.
  A `+0` ref reads as *no progress* and can be a written-but-uncommitted changeset — measured, two such
  refs held reviewed work, and all three committed within two minutes of being looked at. **Report
  them; never reap one.**
- **Nothing in this skill fetches, so `origin/master` is only as fresh as this machine's last fetch
  from some unrelated cause.** A branch merged upstream since that fetch still reads as unlanded, so
  `<B>` is an over-count and never an under-count: an unfetched `origin/master` is missing commits,
  never carrying extra ones. The line's `measured <instant>` stamps when the counts were taken, not
  when the ref was last fetched — two different instants, and only the first is on the line.
- **`origin/master` not resolving at all is the other case, and it is the one that produces
  *unavailable*.** With no baseline there is nothing for a branch to be ahead of, so **unlanded is
  *unavailable*, not zero.** Report it as unavailable.

- **`<U>` unreferenced merges** — merged PRs whose head branch maps to a lane and whose body carries no
  closing reference. **This is a detectable defect, not a judgement call:**

```bash
for p in $(gh pr list --state merged --limit 30 --json number --jq '.[].number'); do
  gh pr view $p --json body,headRefName \
    --jq 'select((.body | test("(?i)(close[sd]?|fixe?[sd]?|resolve[sd]?) +#[0-9]+")) | not) | .headRefName'
done
```

  It measures whether **the record is consistent**, not whether a lane was productive — so it does not
  punish the lane whose best output was a finding rather than a diff. **The count goes in the line; the
  branch names go beneath it whenever `<U>` is non-zero**, the same shape the unattached are reported
  in. A bare count of a defect nobody can locate is not actionable.

**The ledger governs nothing.** It is measured and reported so the fleet's inability to retire is
visible on the line above the lanes, every morning, in a number nobody can skip. It is not a cap and
must never be used as one. **And it never reads PR count as a lane's worth** — the most valuable
output of one measured lane was a single sentence that no diff contains.

**`filed` is two mechanisms and the digest separates them.** Measured on one day: 22 of 34 new issues
landed in the first 72 minutes, before any lane wrote code — nine agents inventorying nine regions for
the first time, which is one-time and does not recur once those regions are known. The remaining 12
trickled over seven and a half hours and were review-generated. **A first-contact number and a
review-generated number mean opposite things**, and reporting them as one total invites the reader to
mistake a new region's inventory for a fleet that cannot stop filing.

**The line carries the instant it was measured, because on a live fleet it is perishable.** Measured
in one sitting: three branches committed between two consecutive commands, the board grew by six,
open PRs went from one to ten, and closed issues went from three to five. **A branch or board state is
a measurement with a lifetime of minutes, not a standing property.**

**Land lanes are formed in Phase 4, after the poll — not here.** Phase 0's ledger *counts* unlanded
branches, and that count is a measurement, not a candidate list. A land lane needs two facts only the
poll can supply: **who owns the branch**, and **which issue it served**, whose region becomes the
lane's region. Forming one here would mean knowing the answers the poll exists to ask.

**So the rider rule never pre-empts on a land region.** No land lane exists before the poll, so
`anything ∩ land` is not computable in Phase 0 and is not attempted. It resolves in Phase 4, where both
sides are known.

**`backup/*` and other rebase-safety refs never enter that branch list and never become land lanes** —
snapshots, not work. **And where `origin/master` does not resolve, the unlanded count is *unavailable*,
not zero** (above), so the land stream is unavailable too: report it that way rather than running a
morning with no land lanes and no reason given. **An `origin/master` that resolves but is unfetched is
not that case**: it makes the branch list an over-count, and what an over-count costs is a land lane
for a branch that already landed — which the land brief's re-measure obligation retires in the lane's
first act.

**What Phase 0 hands forward is a branch list, not a candidate list.** Phase 2 carries the unlanded
branches to the poll **by branch, not by owner** — *these branches are unlanded; if one is yours, say
so in `stranded`* — because naming an owner here would require knowing the answer the poll exists to
ask. The branches are a measurement passed forward; Phase 4 is where a `stranded` claim turns one into
a lane.

**The split is a precedence order, not a quota, a ratio, or a cap.** Every candidate that survives the
filters is dispatched. Urgency does exactly one thing: it decides which stream draws first.

1. **A standing lane pre-empts everything.** An item the *previous* digest marked `⚠️ LIVE` — harm that
   is **occurring**, not harm that is possible — is re-dispatched every morning until its issue closes.
   This is not a derived priority: the previous run wrote it down, and this skill already carries facts
   forward. The distinction that matters is tense. The rest of the queue is rulings; a standing item is
   current output, and it recurs on the next run unless something changes.
2. **Then, if any unclaimed *remediate* candidate carries the top severity tier present among
   remediate candidates, remediation draws first. Otherwise decisions draw first.** Measured: nine
   defect lanes produced zero merges because every branch waited on a ruling. **Remediation that
   terminates in an unmade decision is not remediation.**

   **If no unclaimed remediate candidate carries any severity label, there is no top tier present.**
   Say so in one line and draw decisions first. That is a fact about the labels, not a judgement about
   the work — and it is the same fallback this skill already applies when it has to rank an unordered
   open-issues report and finds no matching label in the repo.
3. **Claimed land lanes bypass this order entirely; only the orphan sweep draws.** A land lane bound
   to its claiming author consumes no chat — authorship binds it, not a seat — so it never competes
   here. **That bypass is the larger of the two allocation calls in this item, and it is stated as
   one:** it means every claimed branch is served every morning, ahead of and independent of
   everything this order rations. What is left to ration is the **orphan sweep lane**: nobody claimed
   those branches, it resolves to `needs a chat` (Phase 4), and it therefore spends one of the seats.
   It draws last because orphans are the branches nobody claimed, so their first question is whether
   they should live at all.

**What the order actually rations.** It does not limit how many lanes exist — it decides which lanes
get the seats, and the seats are the real constraint: live sessions plus the chats the human opens.
**The fleet's size is the cap. The precedence order decides who gets the seats.** Do not read this as a
throttle and do not add one: capping what a morning may start was considered and rejected, on the
measurement that the arithmetic would have permitted one lane on the most productive day on record.

**The unattached are not in this order at all** — they are reported, and attaching is the only way into
dispatch.

## Phase 0b — the repo's health

If `.claude/health.md` exists at the repo root, run the `health_command` from its front matter and
fold the output into Phase 3's digest. Interpret it with the prose in that file — that is what the
prose is for. **File absent → skip this phase silently**; not every repo has one, and its absence is
not a finding.

**The split is the point.** `health_command` is one tested command producing identical reads every
time; the prose beside it is how to read the output. Determinism where drift is fatal, judgment where
interpretation is needed.

**Do not re-derive any of it by hand, and do not add checks here.** Every wrong fact on 2026-08-21
came from an agent deriving production state in prose: four sessions quoted four different droplet
SHAs, none had read the broker, and an unprotected-position alert sat eight hours. If you find
yourself about to write "also check X" into the digest, X belongs in that repo's health command, with
a test.

**Read the descriptor's known-false-positive section before flagging anything from it.** A check it
names as noise is noise; flagging it anyway trains the reader to skip the report, and the next real
finding goes past.

**`health_command` missing or non-zero?** Render its stderr as a finding and carry on — the roster
and the poll still run. A broken health command never stops the standup.

This is the morning half of a pair: `/eod-digest` runs the same descriptor at close-out.

## Phase 0c — intent

The board says what work exists. It does not say what today is for. Landing orders inside active
specs, unticked acceptance items for the current phase, open items in a progress file — real
next-steps live in these before anyone files an issue for them, and a standup that reads only the
tracker proposes a day that is blind to them.

If `.claude/standup.md` exists at the repo root, read `intent_sources` from its front matter — a list
of files or globs, named by the repo the same way `health.md` names its `health_command`. **File
absent, or no `intent_sources` key → skip this phase silently.** Same contract as Phase 0b: the repo
declares where its intent lives; this skill never guesses at a repo's layout.

From each named source, take only what the source itself marks as next or open — the first unshipped
step of a spec's landing order, an unticked acceptance item in the current phase, an entry under an
open-items heading. Quote it with file and line. **Do not mine prose for implied work**: an intent
item is one the author wrote down as a next step, not one inferred from a document's gaps.

Each item becomes an **intent item**: reported in Phase 3, offered in Phase 5's Today proposal, and
nothing else. Check whether an open issue already covers it and say which — a title match is a report,
not a verdict, under the absence rule. An item no issue covers is marked **off-board**, with the
filing command printed beside it, the same pattern the unattached get:

```bash
gh issue create --title "..." --body "..."
```

**Intent items are never lanes and are never dispatched from here.** They have no map position, no
region, no claim — Phase 0's rules do not know them. The one door into dispatch is the human
confirming one in the Today reply (Phase 5), which makes it a **human-named lane** under the existing
rule: named in priority order, positioned by the order named. Nothing here weakens the boarding rule;
it moves off-board work to where the human rules on it, instead of leaving it in files the standup
never read.

## Phase 1 — roster

```bash
claude agents --json
git worktree list --porcelain
```

`claude agents --json --cwd <repo-root>` matches by **exact path**, not by repo identity — measured,
not assumed. It drops every session sitting in a worktree, which on a busy repo is most of them. So
call `claude agents --json` unscoped and keep only rows whose `cwd` equals `<repo-root>` or sits under
one of the paths `git worktree list --porcelain` reports (that list includes the repo root plus every
registered worktree, in or out of tree).

Match by **exact-path equality or containment under `path + "/"`** — never a bare string-prefix test.
Siblings like `fund-probes/`, `fund-worktrees/`, and `fundablePlayground/` share a string prefix with a
repo root called `fund` without being under it, and `cwd.startswith(repo_root)` sweeps their sessions
into the roster.

Each surviving row carries `name`, `sessionId`, `cwd`, `kind`, `startedAt`. The listing **includes
you**. Call the `ListAgents` tool too: it lists the same peers but **excludes** the calling session,
where `claude agents --json` includes it. Your own row is the set difference — whichever row `claude
agents --json` reports that `ListAgents` does not — computed over the rows already filtered to this
repo. **Exactly one row must survive that difference.** Zero means a listing was partial or you got
filtered out along with everyone else; more than one means the repo filter under-selected and the
difference may hold a real peer as well as you. Either way, self-identification failed: stop rather than
poll a set that might include yourself or drop a peer. Exactly one row: exclude it from the poll; you do
not poll yourself.

This is why both are called, not one. The old rule, "you are the one `ListAgents` omits," is unreliable
taken alone: by itself it cannot tell "absent because it is me" apart from "absent because the listing
was partial." Diffing against `claude agents --json` — a listing known to contain everyone — is what
makes the identification exact.

Window start is the **mtime** of the newest-by-filename file in
`~/.claude/align/<repo-basename>/standups/` (filenames are `YYYY-MM-DD.md`, so newest-by-filename is a
plain lexicographic max) — a concrete instant, since that's what gets interpolated into the poll's
"since <window start>" field, not a bare date. No file yet — first standup — use the last 24 hours.

**Split the surviving rows on that instant; do not drop either side.** Activity is the mtime of
`~/.claude/projects/<escaped-cwd>/<sessionId>.jsonl`, where `<escaped-cwd>` is the cwd with every `/`
and `.` turned into `-` (`tr './' '-'`).

- **The roster** — sessions active since the window start. These get the full seven-field poll.
- **The idle set** — sessions that exist in the listing and were not active since the window start.
  These get the `stranded`-only poll of Phase 2: one question, not seven. **An idle session is not a
  gone session**, and the difference matters because a branch it left is a fact only it holds.

Still true, and still the things that catch people out:

- **`cwd` is where a session sits, not what it edits.** A session in the main checkout can commit into
  a worktree with `git -C`. The roster is a floor; reconcile it against what people report.
- **A session that entered a worktree writes to a worktree-scoped projects directory**, and its old
  path goes quiet. One round read that as a 3.5-hour stall on a session that was working. Check the
  worktree path before calling anyone idle.
- **Key records on `sessionId`.** Names churn — six renamed inside one day — and refs proved
  unreliable. Send to the name; record the id.
- **A peer's other repos are invisible to you.** "Nothing is mine" covers this repo only.
- **Re-check the roster immediately before you dispatch.** Fleets grow: one run built a roster of 3 and
  found 11 live sessions nineteen minutes later. **State coverage in all three numbers**, because the
  idle set is messaged too and "polled 3 of 11" reads as eight sessions nobody contacted: how many got
  the full poll, how many got the `stranded`-only poll, and how many exist that got neither —
  "full poll 3, `stranded` only 5, not polled 3 of 11". That last number is the one Phase 4 needs: a
  session that got neither poll is why a branch can be *unclaimed — author not polled*.

If `claude agents --json` fails, stop with the error. Do not fall back to name matching.

No manual gate — this runs every morning. Say who gets the full poll and who gets the `stranded`-only
one, then send. **Carry the idle set forward — Phase 2 consumes it.** A session skipped for the full
poll still exists, and a session that exists can be the author of an unlanded branch. Asking it the
one question is what keeps Phase 4 from inferring *no author* from *not asked*: go and check rather
than infer, which is the same move Phase 6 makes when it refuses to release a claim on a session it
merely did not poll.

## Phase 2 — poll

One `SendMessage` per rostered peer, and only one: the same call carries `notify_when_idle: true`, so
the poll and the idle subscription go out together, never as two sends. Send this, with the user's
agenda line appended if given:

> Morning standup. Answer at your next natural pause — do not abandon work in flight. Keep it to a
> few lines; this is a standup, not a report.
>
> Seven fields:
> - **did** — what you worked on since <window start>, in your own words. Not a commit list. Point at
>   whatever artifact backs it *if one exists*. "No artifact yet, spent the morning reading `gate/`"
>   is a fine answer. Design work, debugging, and dead ends all count.
> - **doing** — one line. Name the lane or issue it serves if there is one; "not on the board" is a
>   fine and useful answer
> - **next** — one line
> - **blocked** — what unblocks you and who owns that. "nothing" is valid. **If what unblocks you is a
>   decision only the human can make, say so and name the decision** — those answers go on the
>   decision list, and they need nobody to have labelled anything.
> - **capacity** — today's candidate lanes are listed below. Could you take **ownership** of one at
>   your next task boundary, or are you too deep in what you have? Owning a lane means running it —
>   fanning out to subagents, or splitting it — not typing it yourself. Name which lane if yes.
>   **This field asks about the `remediate` and `decide` lanes only.** Landing a branch you wrote
>   yourself is finishing what you started, not taking on new work — claim it in `stranded` and it is
>   yours whatever you answer here.
>   **This is not an assignment and nothing has been decided** — you are being asked, not told.
> - **owns** — regions, not filenames (`parse_config` and its callers; the retry block in `send()`).
>   "nothing" is a complete answer.
> - **stranded** — branches you or your subagents left ahead of `origin/master` and unmerged. For each,
>   **two things**: its disposition — `ready` / `dead` / `blocked-on: #<issue>` — **and the issue it
>   served**, as `serves #<issue>`, or `serves nothing`. Name the issue in every case, not only when you
>   are blocked: that issue's region becomes the lane's region, and a branch with no issue named cannot
>   be dispatched. **Check it, do not recall it:**
>   `git rev-list --count origin/master..<branch>` — `0` means not stranded, and an error is not `0`:
>   if `origin/master` does not resolve, use local `master` and add the marker **`baseline: local`** to
>   that branch's answer, in those words. It qualifies the claim rather than remarking on it: the
>   digest prints it and the lane you are given carries it.
>
> <candidate lanes under two headings — `remediate` / `decide` — one per line:
> `#<issue> — <title>` for an issue-derived lane, the name itself for a human-named one. State what
> each type produces: a remediate lane produces one or more PRs; a decide lane produces a decision
> package and no code.>
>
> <the unlanded branches from the ledger line, one per line, under their own heading. Say what
> claiming one costs: a land lane produces a PR, an obituary, or a named blocker, and may not extend
> its branch.>
>
> **Those are branches, not lanes — no land lane exists yet.** Each line is a branch ahead of
> `origin/master`: *if one of these is yours, say so in `stranded` and it becomes your lane.*
> Claiming it there is the whole of what binds it to you; you do not also name it under `capacity`.
> Do not claim a branch you did not write — reconstructing another session's intent from a diff is
> the most expensive guess available, and Phase 4 refuses a non-author's claim anyway.
>
> Where you name a fact — a branch, a path, a state — check it rather than recalling it. A session
> that compacted an hour ago will confidently report a branch it left.

**No candidate lanes today?** The poll still goes out, with the other six fields — the capacity field
and the candidate-lane list beneath it are omitted from the send entirely, never sent empty. **The
unlanded-branch list is not part of that omission.** It belongs to the `stranded` field, not to the
candidate-lane list, and it goes out whenever the ledger counted a branch — candidate lanes or none.
Suppressing it would silence the only question that can produce a land lane.

**The idle set gets the `stranded` question and nothing else.** One `SendMessage` each, carrying the
same `notify_when_idle: true`. **Where the ledger counted no unlanded branch at all, this send is
omitted entirely** — the question has no content, and there is nothing a land lane could be made of:

> Morning standup — one question, at your next natural pause; do not abandon work in flight.
>
> **stranded** — of the branches below, did you or your subagents leave any of them ahead of
> `origin/master` and unmerged? For each that is yours, **two things**: its disposition — `ready` /
> `dead` / `blocked-on: #<issue>` — **and the issue it served**, as `serves #<issue>` or
> `serves nothing`. "None of these are mine" is a complete answer, and so is "nothing is mine".
> **Check it, do not recall it:** `git rev-list --count origin/master..<branch>` — `0` means not
> stranded, and an error is not `0`: if `origin/master` does not resolve, use local `master` and add the
> marker **`baseline: local`** to that branch's answer, in those words — it qualifies the claim, and the
> digest prints it. Do not claim a branch you did not write.
>
> <the same unlanded-branch list the full poll carries, one per line. Say what claiming one costs: a
> land lane produces a PR, an obituary, or a named blocker, and may not extend its branch.>

**Why one question and not seven.** Phase 1's window decides who is asked to account for a period they
spent idle and to volunteer for new work; it does not decide who exists, and it does not decide who
wrote a branch. Without this send, every idle session's branches read as authorless and land in a
sweep that briefs a **non-author** to decide whether somebody else's work should live — inferring *no
author* from *not asked*, which is the inference Phase 6 forbids against this same listing. And on a
busy repo most sessions are idle at nine in the morning, so a sweep gated on every existing session
having been *fully* polled would almost never fire at all.

**Nothing else about an idle session changes.** It is not on the roster. It is not asked `capacity`,
so it can never be bound to a `decide` or `remediate` lane. It declares no `owns`, so it contributes
no region claim it did not already hold through a `map.md` row. If it
does claim a branch, that branch becomes its land lane under Phase 4's ordinary rules, including the
one that reads a missing `capacity` answer as *not a capacity no*.

**The idle set is in neither the full-house nor the notified-and-took-a-turn exit, and that is what
keeps the standup timeboxed.** It gets the same `notify_when_idle: true` subscription, and an answer
that arrives while collection is still open is counted exactly as if it had arrived first. But **a
full house is the roster answering**, and the "every subscribed
session notified and took a turn" exit counts **subscribed rostered sessions only**. Were idle
sessions in either condition, both would wait on sessions that may take no turn all day, and on a
busy repo most sessions are idle at nine in the morning — so every morning would run to the 2-hour
cap. This skill opens *cheap, timeboxed*; a standup that routinely waits two hours is a different
product and nobody chose it. **An idle answer that arrives after collection closes is simply not in
this run** — it is not waited for, not chased, and its branches are orphans this morning like any
other unclaimed branch.

**An idle session's silence is silence on `stranded` and on nothing else.** That is the one field it
was asked, so the one field it can be silent on; its other six were never asked, and Phase 3 prints
those as not asked rather than as silence. The two rules do not collide: unanswered at the cap is a
fact about the question that was put, never about the six that were not.

Then **end the turn**, saying who you are waiting on. The idle subscription already went out on each
poll's own `SendMessage` call above — full or `stranded`-only — so there is no second send to anyone.

**An idle notice is not a reply.** It fires when that session next finishes a turn — and fires
immediately if the session is already idle, possibly before it has read the poll at all. The notice
bounds the wait; the seven fields are what count. Collection ends on a **full house of the roster**,
on a **2-hour wall-clock cap** from when the poll went out, or when every subscribed **rostered**
session has both notified and taken a turn since the poll landed — whichever comes first. **The idle
set is in neither the full house nor the notified-and-took-a-turn condition** (above); the cap is
wall-clock and ends collection for everyone. A peer still unanswered when the cap
expires is silent, and is treated as silent, the same as a peer who never notifies at all — the run
proceeds either way.

**Both of those exits require at least one rostered session, and that has to be said because the empty
roster is a morning that happens.** A quiet night, a weekend, a fleet that all idled: nothing was
active since the last standup, so the roster is empty and the idle set is everyone. Read plainly, both
exits are then **vacuously true** — zero rostered sessions have all answered, and all zero have
notified and taken a turn — and collection closes at the instant the poll went out, before any idle
session could answer the `stranded` question just sent it. Every branch would then be unclaimed, every
unclaimed branch an orphan, and the sweep would hand a live author's work to a **non-author on the
morning every author was alive and was asked**.

**So with an empty roster neither exit fires.** Collection instead runs for **20 minutes** from when
the `stranded` poll went out, ending early only when **every idle session that was sent it has
answered**. That window, not the 2-hour cap, is what governs this morning: it is short because an
empty roster means there is nothing else to wait on, and it is not zero because an idle notice can
fire before that session has read the poll at all. An idle session still unanswered when it expires is
silent, exactly as a rostered one is at the cap.

**Where the roster is empty and no poll went out, there is nothing to collect and collection does not
open.** Two ordinary ways that happens: the ledger counted no unlanded branch, so the idle set's
`stranded` send is omitted entirely (above); or the listing held no session at all, so neither poll
was sent (see the sideways table). Do not wait out the window for a question nobody was asked.

## Phase 3 — digest

Build the digest:

1. **The ledger line, first.** Phase 0's one line, verbatim, with its measurement instant. It is the
   only line about the fleet rather than about a lane, which is why it goes above everything.

2. **The decision list — and it carries human-bound items only.** One numbered entry each for: decide
   lanes' packages, packages found by the package test, riders routed to incumbents and anything else
   resolved `held-in-region`, **any `blocked`
   answer naming a decision only the human can make**, `blocked-on:` answers from the `stranded` field,
   and anything carried from a previous digest that this run cannot show retired. **Both blocked-shaped
   sources count** — the prose one in `blocked` and the structured one in `stranded` — because Phase 2
   promises the decision list to each, and a field promised a home and not given one is worse than a
   field never asked for. Each entry states the question in one sentence, the options with what each costs, **what
   stays stopped until it is answered**, and how many days it has been open.

   **One `held-in-region` resolution is not a decision-list item: a `land` lane held *solely* behind
   its own author's capacity.** It has no question in it — the branch is owned, the owner is known, and
   nothing is being asked of the human. It is reported instead on that session's own `stranded` line
   in item 3, as **unlanded-with-owner**. **Where that lane's region is *also* claimed by another lane,
   both causes hold and the carve-out does not** — there is a question now, which is whose region it
   is — so it goes on this list as well as on the `stranded` line. Every other `held-in-region`
   resolution is a decision request and belongs on this list.

   **The list is written under the fixed heading `## Decisions for the human`.** Phase 0's
   carry-forward reads that heading in the previous digest, so it must be spelled the same every
   morning. A rule that has to find a section by prose inspection is a consumer with an unreliable
   writer — the same defect as a marker nothing produces.

   **No human-bound decision leaves the run except in this list.** It is assembled once and reported
   once. **It is assembled here and completed after Phase 5**, because two of its inputs do not exist
   yet: `held-in-region` resolutions come from Phase 4 and unbound lanes from Phase 5. Phase 3 holds a
   draft; Phase 6 writes the finished list. It is still reported exactly once — an item discovered
   mid-run joins the list rather than getting its own message.

   **Mark a standing item `⚠️ LIVE`, and this is the only thing that produces one.** Where the run
   records harm that is *occurring* — wrong output reaching production now, not a defect that could
   produce some — mark that item `⚠️ LIVE`. Phase 0's precedence order reads this marker from the
   *previous* digest and pre-empts everything with it, so **a run that sees live harm and does not
   mark it leaves the next run blind to it.** The distinction is tense, not severity: the rest of the
   queue is rulings, a standing item is current output, and it recurs on the next run unless something
   changes.

   **Technical rulings are not batched and stay serial.** This distinction is measured, and getting it
   backwards makes things worse: on the day this rule comes from, the technical rulings genuinely
   depended on what each lane went and read — one ruling was made early, made wrong, and reversed by a
   file the lane opened afterwards — while the human-bound decisions were independent of each other
   and sittable in one sitting at hour two, and were instead trickled out across seven hours. Batch
   the second class. Never the first.

   **A decision ruled in the human's own window is invisible to this skill.** It carries with a growing
   day count, marked `possibly ruled elsewhere — unverified; checked: issue open, label present`. Say
   what was checked.

   **Riders are grouped by incumbent**, and a group larger than two is flagged as a split question
   rather than listed as several routings.

3. **One block per session** — did / doing / next / blocked / capacity / owns / stranded. Silent
   sessions named as silent. **A session from the idle set gets a block with `stranded` alone**,
   marked as having been asked that one question — its other six fields were never asked, which is not
   the same fact as unanswered and must not be printed as silence. **An idle session that did not
   answer is silent on `stranded`, and on nothing else:** print that one field as silent and the other
   six as not asked. The two facts sit in the same block and are not the same fact.

   Print each capacity answer beside two numbers: the session's age (from `startedAt`) and its
   transcript size. The answer is what routes the lane; the numbers stop a "yes, I'm free" from a
   six-hour session being read blind. **Label them as proxies** — compaction count is not observable
   on this machine, so age and size hint at context pressure and do not measure it.

   **Print the same two numbers beside the `stranded` line of any session that claimed a branch and
   has no capacity answer to print them against.** An idle-set session was never asked `capacity`, and
   a rostered claimant may have answered `stranded` and skipped it. A claim is what binds a land lane
   (Phase 4), so that session is about to be given work with no capacity answer standing behind it —
   which is exactly the session the numbers were invented for, and the one place they would otherwise
   never print. Same proxy label, same two numbers. The claim is a poll answer and is in hand here; how
   it resolves is Phase 4's.

   **Print `baseline: local` on the `stranded` line of every branch whose claimant reported it.** The
   marker is part of the claim, not a remark about it, and a reader holding two claims side by side has
   to be able to see which of them was measured against `origin/master` and which was not. **An answer
   carrying no marker was measured against `origin/master`** — that is what the poll asks for, so its
   absence is the default and never an unknown to chase. What a marked claim becomes is Phase 4's; that
   it is visible here is this phase's.

4. **Drift becomes two-sided.** The existing drift lines report work no issue covers and issues
   someone treats as done that are still open. Add the other direction:
   **issues opened since the window start, counted, with the lane that filed each.** On one measured
   day that was 41 across nine lanes and no phase of this skill could see it. Report it as a fact, not
   a verdict — a fleet filing issues is a fleet reading its regions for the first time as often as it
   is a fleet failing to finish.
5. **Against the board** — three lines, no more:
   - lanes in flight, and who has each
   - **the next unclaimed lane nobody is on** — the single most useful line in the standup
   - **drift** — work reported that no open issue covers, and issues someone is treating as done that
     are still open

   Report drift as a fact, not a verdict. A session working off-board is often right and the board is
   often stale; the standup's job is to make the divergence visible, not to rule on it.
6. **Flags** — surfaced, never resolved:
   - two sessions working the same region
   - a blocker whose owner is another session in this standup
   - a blocker carried over from the previous standup, marked with how many days it has been open
   - two sessions stating contradictory facts about the same code
   - a lane whose region is undeclared — stays unassignable, `→ the human`, since assigning it would
     be guessing about what it touches

   Each flag ends with where it goes: `→ /get-aligned` for ownership collisions, `→ ask <peer>
   directly` for a one-to-one unblock.

   **Mark each flag reported or verified — and when it is unverified, say what you ran.** A failed
   verification attempt is not an unverifiable claim. One run marked a database claim unverified
   after `find -name "*.db"` returned nothing; it was the wrong host and the wrong extension, and the
   peer who knew the system fixed it in one message *because it could see the search*. "Unverified"
   with no method attached is unfalsifiable, and it makes everyone else stop looking.

   The general form: **a session can report an absence, never verify one.** Nothing found, nobody
   owning a region, no explanation for a staged change — each is a fact about your search, not about
   the world. Say what you looked at and let the session that holds the missing context correct you.

Where Phase 0c ran, the digest also carries its intent items in one short block after the session
blocks — each with its citation, off-board ones marked, the covering issue named where one exists.
They are inputs to Phase 5's Today proposal; the digest is where the human sees the citations behind
what that proposal will offer, so the proposal itself can stay to one line per objective.

Phase 3 stops here, holding the digest in hand. Phase 6 is what writes it to disk, releases stale
claims, and does the single broadcast and the single report to the human — this phase does neither, so
neither happens twice.

## Phase 4 — reconcile

**One lane, one overseer** — the seat that owns a lane runs it, and never types it itself. A lane is
*owned*, never *worked*. The seat that takes it runs it — fans out to subagents, or fires
`/split-the-plan` if it is big enough — and does not implement it directly. This is uniform: a session
that was already running and a chat opened this morning take a lane on exactly the same terms, so
"covered" means one thing in every row of the digest.

Each candidate lane resolves to exactly one of:

- **covered** — **for a `decide` or `remediate` lane:** a live session answered capacity yes **naming
  this lane**, and the lane's region collides with nothing — read against all three claim sources
  named below, **except that answering session's own `owns` answer on this lane's region, which is
  exempt (below)** — or the only overlap is a `decide` lane paired with a
  `remediate` lane on the same region, a pairing, not a collision (see the matrix below).
  **For a `land` lane, capacity does not decide who owns it — it decides only
  whether it moves now** (see "`stranded` binds a land lane" below): it is covered when its claiming
  author is live, **did not answer capacity no**, and the lane's region collides with nothing.

  **For a `land` lane, two claims on that region are the lane's own, and a lane does not collide with
  itself.** They come from two of the three sources Phase 4 reads, and both are exempt:

  1. the **`map.md` row for this same lane** — the row this skill wrote for it on an earlier run; and
  2. **this same lane's own claiming author's `owns` answer**. A session that wrote a branch almost
     always names that branch's region under `owns`, because it wrote it. Without this exemption the
     `land ∩ anything` row fires on the claimant's own declaration and the lane is held behind its own
     owner, which is the one party who can never be in conflict with it.

  **Both exemptions are exactly this narrow: this lane, its own row, its own claimant's answer, on
  this lane's region.** A `map.md` row for any *other* lane the same author holds, and the `owns`
  answer of any *other* session, are ordinary collisions and resolve through the matrix like any
  other. The exemption is not a property of the author — it does not reach the other regions that
  author holds, and it does not reach that author's other lanes in this region.

  **A `decide` or `remediate` lane is exempt on one source only — the volunteer's own `owns` answer
  on this lane's region — and that is the exemption stated in the clause above.** A session answers
  capacity yes for a lane in region R and names R under `owns` for the same reason: it is the session
  that knows R. Read its own declaration as a claim against it and the lane resolves `held-in-region`
  behind the answer that offered to take it — the volunteer best placed to hold the lane is the one
  who can never be given it. **`owns` cannot carry the argument that was made for reading it here.**
  It is defined at the poll as **regions, not filenames**: it establishes a region and never names a
  lane, so it cannot show that this session would be taking a *second lane* in that region. The source
  that names lanes is the `map.md` row, and that source is read here and is **not** exempt for these
  two types — a live row for another lane the same session holds in R is an ordinary claim and holds
  this candidate exactly as it holds anyone else's.

  **Scope it exactly this wide: this lane, this answering session, this lane's region.** Another
  session's `owns` answer on R is an ordinary claim. This session's `owns` answer on any *other*
  region is untouched — it still claims that region against every other lane. And the exemption
  reaches nothing but `owns`: the same session's live `map.md` rows and the lanes this run has already
  dispatched are read against this lane in full.

  **On the `map.md`-row source, `decide` and `remediate` must never be given a symmetric one.** Those
  two pass Phase 0's candidate filters, where **unclaimed** already drops any
  candidate holding a live `map.md` row of its own — so a recurring lane never reaches Phase 4 to
  collide with itself, and if its author has exited that row is not live and the claim test does not
  fire on it either. A land lane bypasses those filters entirely: it is formed here, in Phase 4, out
  of the poll, so `unclaimed` was never applied to it and its own prior artifacts are still sitting in
  the claim sources. Adding a `map.md`-row exemption to `decide` or `remediate` to restore symmetry
  would punch a hole in the `unclaimed` filter, which is the thing keeping yesterday's live lanes off
  today's board.

  **That argument reaches the `map.md` row and stops there — the `owns` source is different in
  kind.** `owns` does not exist at Phase 0: the poll has not gone out, so **`unclaimed` never tested
  it**, and no upstream filter drops a candidate because its volunteer declares its region. There is
  no filter behind the `owns` exemption to punch a hole in, and reading the sentence above as a
  prohibition on the whole of Phase 4's claim sources is what would block the fix in the clause above.

  **A claimant who answered `stranded` and gave no `capacity` answer at all did not answer capacity
  no**, so this clause covers it. That is stated rather than left to fall out: `stranded` already
  bound the lane, and the only thing a capacity answer can add is a reason to wait, which an absent
  answer does not give.

  **A wedged session needs no exception here, because the state is unreachable.** The worry is a
  session that is live in the listing, claimed a branch, and is stuck — bound to a lane it cannot
  move. It cannot arise: **claiming happens inside a poll answer.** A wedged session answers no poll,
  so it submits no `stranded` field, so it claims nothing; its branches are unclaimed, they are
  orphans, and they go to the sweep (below). Any session that reaches `covered` by the `stranded`
  path has answered a poll sent this morning and has therefore **demonstrated liveness within this
  run** — a stronger signal than the roster window an idle-set claimant failed. Written down so a
  future round does not add the exception
- **needs a chat** — for a `decide` or `remediate` lane: **nothing collides on its region** — an
  overlap that is only a `decide` ∩ `remediate` pairing is not a collision and does not count here —
  **and** nobody is free for it; or a claim on its region is a `decide` ∩ `decide` pair, sent to
  `/get-aligned`. That is the only pair this resolves to a chat — every other collision resolves to
  `held-in-region` instead (see the matrix below), and where a region carries several colliding claims
  **a `decide` ∩ `decide` among them wins**, since `/get-aligned` resolves the whole region while
  holding behind one of the others would leave the contradictory pair standing. **A colliding region
  is decided before a free seat is looked for**, so a candidate that is both held and unwanted is
  `held-in-region`, not a chat: opening a chat for a lane nothing can start yet spends the scarcest
  thing this skill rations. **The orphan sweep lane always resolves here** — it has no author to bind
  it, and no one region to hold the whole lane behind, though its branches may carry regions of their
  own (see the sweep rules below)
- **held-in-region** — a lane that is owned but waiting. **Two things put a candidate here, and both
  are this state.** *One:* its region is already claimed, and the collision is not one of the two
  exceptions above (`decide` ∩ `decide`, which needs a chat, and `decide` ∩ `remediate`, which pairs
  as covered) — claimed by a live `map.md` row, by a lane this run has already dispatched (a `land`
  lane included), or by a session's `owns` answer, **and a self-claim the `covered` clause exempts for
  this candidate is not a claim for this purpose either**. **That exemption is a property of the
  pairing, never of the claim** — `owns: R` from session S is a self-claim while S's own lane in R is
  the candidate being resolved, and an ordinary claim against every other candidate in R. Read it as a
  fact about the claim and two lanes go into one region. *Two:* it is a **`land` lane whose claiming author
  answered capacity no**. The author
  owns it either way; capacity only decides whether it moves now or waits, and it waits here until
  that session has room. Report that one as **unlanded-with-owner**, never as unowned. **An orphan is
  never held-in-region** — it has no author to wait on, and the sweep is one lane over many branches,
  so a collision on one branch's region cannot be allowed to hold the others. It resolves through the
  sweep instead (above); where a swept branch carries a region, that region is collision-checked per
  branch rather than by holding the lane. Recorded as a decision request, never sent to
  `/get-aligned` — this state opens no chats

A candidate lane becomes a **lane** once it resolves to one of the three states above — every phase
from here on says "lane," never "candidate."

**Region** means what `get-aligned` means: an area of code, not a filename (`parse_config` and its
callers; the retry block in `send()`). One file routinely has three owners, so filename matching
produces false conflicts and hides real ones.

**A lane's type is part of the binding.** A session that answers yes to `#38` takes it as the type the
board typed it. Never silently retype a lane to fit an answer.

**Collision depends on the pair of types, because a decide lane writes no code.** Every row below is
read against the three claim sources named under the table, minus the self-claims the `covered`
clause exempts — for a `land` lane its own `map.md` row and its own claimant's `owns` answer, for a
`decide` or `remediate` lane the answering session's own `owns` answer, each on that lane's region
only:

| Pair | Resolution |
|---|---|
| `decide` ∩ `decide` on one region | **Collision** → `/get-aligned`. Two packages over one region produce two contradictory recommendations |
| `decide` ∩ `remediate` on one region | **Not a collision — a pairing.** The decide lane reads the remediate lane's issue thread first and addresses that owner as its first correspondent |
| `land` ∩ anything on one region | **Collision.** A branch and a live lane in the same code are the merge conflict, not the risk of one. **A `land` lane has a region wherever the issue it served was named** — by a claimant still live, or by one who has since exited. **The orphan sweep lane has no region of its own, but its branches may:** each swept branch carrying a region enters this row on that region, per branch |

**A claim arising from `owns` alone carries no lane type**, so a pair one side of which is such a
claim cannot be looked up in the table above. Where that session holds a lane row in the region, the
type is read from **that row** — Phase 6 writes a type onto every row it writes — and the pair is
typed from there. **Where it holds no row this skill can read a type from, the pair cannot be typed
and the candidate resolves `held-in-region` — never guess a type to reach a different state.** That is
the conservative state: it holds the candidate instead of dispatching it, so an untypeable pair can
never produce a wrong dispatch. A row this skill did not write — one in `get-aligned`'s or
`split-the-plan`'s own shape — is not a row it can read a type from, here as everywhere else.

**The genuinely untypeable case is narrow**, and saying so keeps this from swallowing the table: it is
a session declaring a region it holds no lane in. Where it does hold one, Phase 6 wrote the type onto
that row and `owns` adds nothing the row does not already say.

**`held-in-region` is the general state, not a land-lane special case.** Any candidate whose region is
already claimed resolves to it — claimed by a live `map.md` row, by a lane this run has already
dispatched (a `land` lane included), or by a session's `owns` answer, and never by a self-claim the
`covered` clause exempts **for this candidate** — the exemption is per pairing, not per claim, so the
same declaration that is exempt against its own lane is an ordinary claim against every other
candidate in that region. **The orphan sweep lane is never
held-in-region** — it is one lane over many branches, and holding it on one branch's region would
stall every other branch on it. It resolves
through the sweep instead, and its branches are collision-checked one at a time.

**A region has three claim sources, and every test in this skill names which ones it reads.** Phase 0's
rider rule reads two of them — live `map.md` rows, and lanes this run has already dispatched — because
the poll has not gone out yet. **Phase 4 reads all three:** those two, plus the poll's **`owns`**
answers, which is the only place a region nobody has written down can surface — **minus the self-claims
the `covered` clause exempts**, which is where a lane's own author's or own volunteer's declaration is
taken out. So Phase 4's check is a superset of Phase 0's, not the same test, and that third source is
the one that made a land lane collide with its own author and a decide or remediate lane collide with
the volunteer who offered to take it.

**So the other party to a `land` collision has a state.** A `decide` or `remediate` candidate sharing a
region with a `land` lane is **`held-in-region` behind it** — not covered, and not needing a chat. A
land lane is about work that already exists, so letting it reach its terminal state clears
the region rather than racing it. Without this rule that candidate matches none of the three states and
falls through, which is the defect this phase exists to prevent. **The land lane it waits behind may
itself be waiting** — `held-in-region` on its author's capacity no — so the held candidate's
decision-list entry names which land lane holds it and whether that lane is moving. Surfacing that is
this skill's job; deciding what to do about it is not.

**Land lanes are formed here, from the poll's answers — this is the only thing that creates one.**
Every branch a session claimed in `stranded`, **and named an issue for**, becomes a land lane **owned
by that session**, carrying **the region of that issue**. Both facts arrive in the same answer, which is why
formation waits for the poll — but **they have different producers and they do not expire together**:
the claim names the **owner**, and the **issue** names the **region**. That is why a claimant's exit
takes the ownership and leaves the region behind (below).

**`stranded` binds a land lane; `capacity` does not.** There is exactly one producer of a land lane's
owner, and it is the `stranded` claim. Landing your own branch is finishing what you started, not
taking on new work, so the lane is that session's whatever it answered under `capacity`, and whether
it answered there at all — a capacity no does not hand the branch to anyone else and does not make it
an orphan. Capacity governs one thing here and one only: whether the lane moves now (`covered`) or
waits (`held-in-region`, unlanded-with-owner).

- A branch claimed **`baseline: local`** still becomes a land lane, on exactly the terms above, and
  **the marker rides with it** — onto that session's `stranded` line in the digest, and into the
  lane's briefing. It is a **weaker claim, not a missing one**: the author did go and check, against a
  baseline that can differ from `origin/master` in either direction, so the branch may already be
  landed upstream, and a count taken that way can also under-report. **Take the reading and report
  what you read** — the pattern the package test uses, and deliberately not the pattern used for a
  fact nobody supplied, which is left unrouted precisely because no reading of it is available. Here
  one is available; it is only weaker. Nothing else about the lane changes: the author owns it,
  `capacity` decides only whether it moves now, and **Phase 5's brief already carries the receiver** —
  it states the command and the instant and requires the lane to re-measure before sizing, and a
  locally-baselined count is a command naming `master`, so stating the command states the baseline.
  **The marker gets no `map.md` field**: no later run reads it, and a field with no receiver is the
  defect this rule exists to close, not one to add a second instance of.
- A branch whose owner named **`serves nothing`** has no region, and so never becomes a candidate lane
  at all: flagged `→ the human`, never dispatched, exactly as Phase 0 treats a region-undeclared
  sub-issue. It does not enter the three states above. **This holds while that owner is still in the
  unfiltered `claude agents --json` listing, and stops holding once it is not.** The flag is *for* the
  owner: they are the one who can say what the branch was, and the branch is theirs to close.
  **Where the owner has exited, the exited-claimant rule below wins and the branch joins the sweep** —
  that ordering is deliberate and holds only for this case. A flag with nobody left to act on it is
  re-raised every morning and resolved on none of them, which is how a decision list becomes
  furniture; and the sweep is precisely the lane whose first job is *should this live*. Such a branch
  reaches the sweep **with no region** — no issue was ever named for it — so it is never
  region-matched, exactly like a branch nobody ever claimed.
- A branch **no session claimed** is an **orphan** — subject to the next bullet, which is the one
  qualifier on this and not a competing rule. An orphan nobody ever claimed **has no region**, because
  nothing ever named the issue it served. Such an orphan is never region-matched —
  inventing a comparison for it is the failure this skill spends its Phase 0 forbidding.
- **An unclaimed branch is an orphan once every session that exists has been asked — and on an
  ordinary morning it has been.** Whenever the ledger counted an unlanded branch — the only condition
  under which this question arises at all — Phase 2 sends to every session in the unfiltered `claude
  agents --json` listing: the roster gets the full poll, the idle set gets the `stranded` question. Phase 1's
  window decides which of the two a session gets; it never decides who exists, and it no longer
  decides who is asked about branches. **The condition fails only where a session in that listing was
  sent neither poll** — its `SendMessage` failed, or it entered the listing after the poll went out.
  That session was given no chance to claim, and reading its silence as *no author* is the conflation
  Phase 6 forbids against this same listing. A branch left unclaimed while such a session exists is
  **unclaimed — author not polled**: reported with the count of existing-but-unasked sessions, held
  out of the sweep, briefed to nobody. It does not enter the three states above, exactly like a
  `serves nothing` branch with a live owner. **This is not the silence rule below**: a session that was
  asked and stayed silent claimed nothing, and its branches are orphans; a session that was never
  asked was never given the chance to claim.
- **A claim binds only while its claimant is live — the region it named does not depend on that.**
  **Liveness here is the unfiltered `claude agents --json` listing** — the same listing Phase 0 checks
  `unclaimed` against and Phase 6 checks release against — **and never the Phase 1 roster.** Say it
  rather than leaving it to be inferred: every claimant was sent a poll by construction — the roster
  in full, or the idle set's one question — so a check against the set this run messaged reports every
  claimant present and this rule would never fire once. Those sets are who was asked; the listing is
  who exists. Where the session that claimed a branch is absent from the unfiltered listing at the
  moment Phase 4 runs, the branch has no owner: the **ownership** is orphaned and the branch joins the
  sweep. **The region stays with the branch.**
  The owner named only *which issue* the branch served; it is the **issue** that names the region, and
  the issue is still readable after the session exits. Say in the digest that the branch *was* claimed
  and its claimant exited, so the sweep's overseer knows a claim once existed and does not read the
  branch as never-touched.
- **All orphans gather into one sweep lane per run**, which resolves to **`needs a chat`** — the one
  land-shaped lane that does, precisely because it has no author. Its first job is to establish, for
  each branch, whether it should live. **The sweep lane has no region of its own, but the branches on
  it may:** a branch orphaned by its claimant's exit keeps the region of the issue that claimant named.
  A branch nobody ever claimed has none, and neither has one whose owner named `serves nothing` before
  exiting — in both cases no issue was ever named, so there is nothing to read a region from.
  **A swept branch that has a region is collision-checked on
  it, per branch, through the `land ∩ anything` row above** — otherwise a branch sitting in code a live
  lane is editing is handed to a non-author with no collision check at all, which is the merge conflict
  that row exists to catch. **The collision does not hold the sweep**: it is named in the sweep's
  briefing, branch by branch, with which lane holds the region, and any *candidate* sharing that region
  is `held-in-region` behind that branch exactly as it would be behind any other land lane. **It is
  the only lane in this skill briefed to a non-author**, and its briefing says so.

Once formed, a land lane **that has an owner and a region** resolves through the matrix above like any
other candidate. The sweep lane itself never resolves through the matrix — it resolves to `needs a
chat` whatever its branches collide with — but each branch on it that carries a region enters the
matrix on that region.

**Land lanes bind by authorship, or to nobody — and exactly one of them opens a chat.** A claimed
branch is already owned and needs no seat. The orphan sweep lane is owned by nobody, resolves to
`needs a chat`, and so spends one of the seats Phase 0's precedence order rations — where it draws
last. Where a lane must go to a non-author — which is the sweep, and only the sweep — say so in the
briefing: *"You did not write this. Your first job is to establish whether it should live, not to
finish it."* Reconstructing another session's intent from a diff is the most expensive guess
available.

A capacity yes whose region collides is a **flag, not an assignment** — for `decide` ∩ `decide` it is
said so and sent to `/get-aligned`; every other colliding pair is recorded `held-in-region` instead, per
the matrix above, and never sent to `/get-aligned`. A capacity yes that names no lane, names a lane a
session already covers, or names a `land` lane the answering session did not claim in `stranded`, is a
flag of a different kind: there
is no region collision to reconcile, just an answer this phase cannot bind, so it goes to the human as
a flag, not to `/get-aligned`. Never bind two lanes to one session to make the numbers work, and never
bind a lane to a session that did not name it.

**Silence is not a release.** A rostered session that never answered has not given up its region. For
`decide` and `remediate` lanes, silence resolves to needing a chat only where no live session claims
that region.

**A session that was asked and stayed silent claims no branch, so there is no such thing as a land lane
with a silent owner.**
Claiming happens inside a poll answer, and that holds for both shapes of poll: a session that never
answered submitted no `stranded` field, so every branch it left is simply unclaimed. Those are orphans
— no region, gathered into the sweep lane, resolved `needs a chat` like every other orphan. They do not
become that session's land lanes and are not held behind it. **A session that was sent neither poll is
not this case** — it was given no chance to claim, and its branches are *unclaimed — author not
polled*, above. What silence does
*not* release is the silent session's **region**, recorded from an
earlier run, which still holds candidates that collide with it. Replacing a silent session's head is
the human's decision, never an inference from a missing reply.

## Phase 5 — dispatch

Record `T = now` (epoch ms). **N is the count of lanes that resolved to `needs a chat` in Phase 4.**
**N = 0 means there is nothing to ask** — skip this message entirely, there is no chat to open.
Otherwise tell the human exactly this much:

> Open **N** chats in this repo. Nothing else — I'll take it from there.

List what each will own so they can sanity-check the split. Do not give them prompts to paste. Do not
ask for session ids.

**The same message carries the Today proposal — one ask per morning, not two.** Beneath the open-N
line, propose **at most three objectives** for the day: drawn first from the top of the dispatch
order this phase is about to bind, in that order, then from Phase 0c's intent items, each with its
citation and its off-board marker where it has one. One line per objective — what it is, where it
came from (map position, or file:line), and what done looks like today. Where N = 0 and intent items
exist, the proposal still goes out; a day with no chats to open can still have a plan.

**An objective is day-sized: closeable by EOD in one of a lane's terminal artifacts** — a merged PR,
a decision package, or a closed branch. An item that cannot plausibly close today is not proposed as
an objective; propose **its split** instead (`/split-the-plan` is how), and the split's first
day-sized piece takes the slot. Sizing is enforced here, at proposal time, not discovered at EOD —
and the hit-rate number (Phase 6) makes this self-correcting: chronic carryover means the objectives
are too big, and the number says so.

**Yesterday's unclosed confirmed objectives are today's first proposal input.** Read the previous
standup file's `## Today`: any `confirmed` objective whose issue is still open and whose terminal
artifact never landed is proposed first, marked `carried (day 2)` (or higher). Carry-forward is
explicit and visible — never a silently held claim: EOD released the day's claims, so a carried
objective re-enters through the same confirm step as everything else.

**The proposal is a proposal.** The human confirms, reorders, strikes, or replaces — their reply is
the decision, and an objective they name that the proposal never contained wins verbatim. A confirmed
off-board objective becomes a human-named lane in the order named — the existing human-named-lane
rule doing its job, not a new door into dispatch. A confirmed objective that is already a lane
changes nothing about that lane's dispatch: confirmation is commitment, not re-ordering, and map
order stays the priority decision it was.

**Silence follows the standing rule: non-blocking, and never adopted.** No reply by the time the run
ends → Phase 6 records the proposal marked `proposed — unconfirmed`, and dispatch proceeds from the
board exactly as if this paragraph did not exist. An unconfirmed proposal is a report, not a plan.

**This ask does not block the run — the same non-blocking rule Phase 0 gives its own ask.** Read the
roster again, using the same **exact-path-or-containment-under `path + "/"`** rule Phase 1 uses, never a
bare prefix test, and take every session with `startedAt > T`. Those are the new chats. **If fewer
appear than asked, or none do before the run ends**, bind what exists and record the remaining lanes as
unbound, with the reason ("no confirmation" or "fewer chats opened than asked" — or `order undefined →
the human`, the third reason, added below) — an unbound lane is
recorded in the digest and the human report only, and gets no `map.md` row, because it has no owning
`sessionId` to key on. Phase 6 writes the digest and broadcasts regardless of whether confirmation ever
came — a run always produces its digest.

**Bind the chats in Phase 0's precedence order; the overflow is what goes unbound.** This is the step
that order rations, and until it is stated here nothing reads it: the seats are the chats that
actually appear, and which lanes get them would otherwise fall to whichever the query returned first.
Put the `needs a chat` lanes in this order and hand out the chats down the list:

1. a standing lane the previous digest marked `⚠️ LIVE`
2. the stream that draws first under Phase 0's item 2 — remediation if any unclaimed remediate
   candidate carries the top severity tier present, decisions otherwise
3. the other of those two streams
4. the orphan sweep lane, which draws last

Within a stream, keep the order Phase 0 took them in, and not a new one.

**A stream can hold lanes that have no position at all, and this is where that bites.** The decide
stream is where it happens: a board-independent decide lane is a decide lane whether or not it was ever
attached, so it was never taken in map order and there is nothing for "keep the order Phase 0 took them
in" to keep. **Human-named lanes are not such lanes** — the human named them in priority order, so they
carry positions and sort with the positioned ones. Order the stream by **Phase 0's ordering rule** —
positioned lanes in their order first, unpositioned ones after as one group, no order inside the group
— and hand out the chats down that list. When the group is reached, exactly one of three things is
true:

- **chats remaining ≥ the size of the group** — every lane in it is bound, and no ordering question
  ever arises
- **no chats remaining** — every lane in it is unbound for the ordinary overflow reason ("no
  confirmation" / "fewer chats opened than asked"). No ordering question here either: there was
  nothing to order *for*
- **between one chat and one fewer than the group holds** — the only ambiguous case, and it needs a group of
  two or more. **Bind none of them.** Record every lane in the group unbound with the reason
  **`order undefined → the human`**, name the lanes, and **report those chats as freed and where they
  went, never as unused** — *"2 chats freed from the ambiguous group, passed to `<lane>`, `<lane>`"*, or,
  where nothing below in the order can take them, that they were freed and went unspent. They are not
  withheld: **the freed chats pass on down the list** to the next item in the precedence order, because
  a seat a higher item cannot deterministically claim is not forfeit to nobody. "Unused" describes
  neither outcome and hides the one thing the human needs to see here — **the split they were given to
  sanity-check when the N chats were asked for (above) has just changed**, and this is the step that
  changed it. Ranking the group to spend those chats invents the dispatch order Phase 0 forbids;
  reporting them costs a line and the human settles it — an attach where there is a board to attach
  to, a place in today's named order where there is not

**Lanes past the last chat are the unbound ones**, recorded with the reason above. `covered` lanes are
not in this list at all: they are already bound to a session and consume no chat, which is the same
reason Phase 0's item 3 keeps claimed land lanes out of the order.

**This skill provisions nothing.** A seat that owns a lane is an overseer, and an overseer does not
edit files — it reconciles, fans out, and reviews. It sits in the repo root. Isolation belongs one
level down, to whatever that overseer dispatches, and it is that overseer's call to make with the lane
in front of it. Creating worktrees for seats that may never write a line is cost paid on speculation,
and a worktree nobody wrote in still has to be reaped.

So: **this skill never creates a branch, a worktree, or a commit.** It reads, it messages, and it
writes two files under `~/.claude/align/`. Everything that touches the repo is done by a seat that owns
a lane.

Brief each bound session as an **overseer**, not an implementer — and that includes a `covered` session
exactly as much as a newly opened chat: Phase 4 already holds that a session that was already running
and a chat opened this morning take a lane on identical terms, so a `covered` session gets this same
briefing, not a lighter one:

- the lane — issue number, title, and the region it covers. **For the orphan sweep lane, which has
  neither, this line is the list of branches it holds** — that is what it owns. **Name each swept
  branch's region where it has one, and which lane holds that region**, so the overseer knows which
  branches sit in code somebody else is editing before it touches anything
- **that it owns the lane and does not implement it itself**, and that `owning-a-lane` is how to run
  one. That skill carries the rest: how to size the fan-out, what to escalate, where progress goes
- **the escalation address** — your session name, because you are its overseer and an escalation with
  nowhere to go becomes a guess
- its neighbours: who owns the adjacent lanes, under what name, and that
  `coordinating-with-peer-sessions` governs how they talk

Those four are inlined rather than left to the pointer because a briefed session may never invoke the
skill, and a session that misses the first two starts typing.

**Every lane ends in a durable artifact that is not a message to you.** A report to the overseer does
not survive the session, is not observable to the human, and closes nothing. Measured: nine lanes ran
seven hours, all nine reported completion, and the open-issue count went **up 39**.

- **remediate** — *"You end in one or more PRs. Each PR body carries `closes #<issue>` for the issue
  it closes."* **Not one PR per lane** — one lane produced three unrelated changesets, and bundling
  them to satisfy a rule is worse than three PRs. A lane whose work is a feature may produce none for
  days, and its terminal artifact is then a decision package.
- **decide** — *"You own the question, not the answer. Produce a decision package on the issue: the
  named options, what each costs, the evidence for each, and the one thing the human must choose. You
  may not choose it and you may not implement any option. If your reading makes the question moot, say
  so — that is a valid package and the strongest one."*
- **land** — *"This branch is ahead of `origin/master` and unmerged. Your deliverable is exactly one
  of: a PR with a named reviewer; a closed branch with a one-paragraph obituary in the issue it
  served; or a `blocked-on: #<issue>` naming the exact question. **Do not extend it.** A branch that
  grows during a land lane has failed the lane."* **The orphan sweep lane carries several branches and
  owes that deliverable once per branch**, and its briefing carries the non-author sentence Phase 4
  requires: *"You did not write these. Your first job is to establish whether each should live, not to
  finish it."*

**`closes #N` is why this works — but it is a convention, not a mechanism, and the brief must treat it
as required.** Lanes decline registry writes on principle: measured, one fleet performed zero issue
closures across seven hours and explicitly refused to correct records serving as evidence. Where a
merged PR carried the reference, **GitHub performed the write** and the issue closed, every time.

**The omission is silent and common.** Measured on one repo: **a minority of merged PRs had ever
carried a closing reference**, and several of the most recent batch omitted it while their fixes
shipped. Nothing warns, nothing fails, and the issue simply stays on the board reading as outstanding
work while its fix sits on `master`. (Deliberately stated as a shape rather than a count — this skill
ships to every repo, and a number measured in one of them expires in days. Re-measure yours.) So the briefing does not say *the merge will close your issue* — it
says **the reference is part of the deliverable, and a remediate lane's terminal artifact is
incomplete without it.**

**The one case plumbing cannot reach is a decision, which has no merge event.** There, the decide lane
retires the marker itself — and frame it as a **correction, not an exception**: once the ruling is
recorded, the label is a *false instruction* telling every future run that a decision is outstanding
when it is not. Correcting false instructions is already what these seats do unprompted; overwriting
records that are *evidence* is what they refuse, and rightly. **The lane retires the marker on its own
decision, records the ruling that made it false, and touches nothing that is evidence.**

**Every brief carries the source pin:** the ref to read against, plus *"report the ref you read in your
first answer."* And the **staleness obligation**: verify the issue body against that ref **before
sizing**. Measured: four of nine lanes were corrupted by an unpinned source, two of them reading their
agreement as corroboration; three lanes checked unprompted and every one of them shrank its lane.

**A branch's state is an input to the brief, never a verdict.** State the classification, the command,
and the instant it was measured, and require the lane to re-measure first. **Never reap a ref on a
classification** — three refs that read as empty held reviewed uncommitted work, and all three
committed within two minutes of being measured.

Then stop. Do not brief in waves and do not follow up to check receipt.

## Phase 6 — record

Write the digest to `~/.claude/align/<repo-basename>/standups/YYYY-MM-DD.md` — outside every repo, so
no working tree is dirtied.

**Write the day's plan under the fixed heading `## Today`**, immediately after the ledger line.
Confirmed objectives in the order the human left them, each with its source (issue number, or
file:line for an intent item) and its state — `confirmed`, or the whole section marked
`proposed — unconfirmed` when no reply came. The heading is spelled the same every morning for the
same reason `## Decisions for the human` is: `/eod-digest` reads it at close-out to report the day
against what the morning committed to — moved, untouched, or displaced by what actually happened.
Displacement is a fact to report, never a fault: the plan is the morning's best information, and a
day that diverged from it for good reasons should say so in one line rather than be graded against
it.

**The cycle this heading serves: lanes are day-sized, and EOD is the closeout.** The evening half
(`/eod-digest`) sweeps `## Today`, verifies each objective's terminal artifact, releases the day's
claims, and records what carried — so every morning starts from a clean claims file and carried
objectives arrive as the next proposal's first input. A lane is never held silently overnight: it
either closed, or it is carried in writing.

**Beneath the ledger line, write a `numbers:` line** — three figures, computed from reads this run
already does: **closed vs opened** since the last standup file's timestamp (issue events); **hit
rate** — of the previous `## Today`'s confirmed objectives, how many landed their terminal artifact
(from the carryover read above); **oldest open alert** — age in days of the oldest open issue at the
top severity tier present. Three numbers, no more: they are the trend the weekly process review runs
on, and a line nobody reads daily is still a line the week can read. Where a figure cannot be
computed (first run, no previous file, `gh` failure), write it `unavailable` — never omit the line,
and never guess.

Write lane rows to `~/.claude/align/<repo-basename>/map.md`, the same file `get-aligned` and
`split-the-plan` use. One ownership map per repo, or those two will route around work this standup just
assigned. **A lane row states, at minimum: the lane (issue number or human-named lane), its region, the
owning `sessionId`, its status, and which skill wrote it.** Update rows keyed on `sessionId`; never
rewrite the file wholesale, and stamp which skill touched it last. This skill reads only rows in a shape
it can interpret; a row written by `get-aligned` or `split-the-plan`, in that skill's own shape, is left
alone rather than guessed at.

A lane row also states its **type**, and for a land lane its **branch**. A land lane bound to its
claiming author carries that author's `sessionId` and the lane's region, and that row is a true claim —
the author owns the region and is live in it. It is also the row Phase 4's `covered` clause exempts on
the next run, for this same lane only.

**The sweep lane's row lists every branch it holds and states no region at all** — not a region of its
own, and not its branches' regions. The sweep does not hold those regions: Phase 4 says in as many
words that a collision on a swept branch *does not hold the sweep*, and the region belongs to whichever
lane actually claims it, which has its own row in this file. Writing it here would make a claim the
sweep does not have — and because a sweep row's `sessionId` is a chat opened this morning, and
therefore live, the next run's first claim test would read that row as a live claim and hold real
candidates behind code nobody is editing, while `get-aligned` and `split-the-plan` routed around it.
**A swept branch's region reaches the people who need it through Phase 5's briefing, which names it
branch by branch together with the lane that holds it — never through this file.**

Release gains one clause: a land-lane row whose branch is merged into
`origin/master` is released and struck, checked observationally with `git branch --merged
origin/master`, never by asking. A sweep row is struck only when every branch on it is merged or
closed.

The ledger line is written as the **first line** of the standup file, so the next run reads the trend
rather than re-deriving it.

**Report that the board changed, never who changed it.** Every session authenticates as the same
GitHub user, so a `sub_issue_added` event names the human whether the human attached the child or an
agent did. Map order is the human's priority decision and this skill **cannot verify that it is**.
State what changed and by how much, under the same rule that lets a session report an absence but
never verify one.

**Release stale claims before writing new rows.** A row whose `sessionId` is no longer live, or whose
issue is closed, is released and struck. The measured failure in fleets like this is not two agents
racing for one task — it is an agent finishing and never letting go of the slot. Check liveness against
the full, unfiltered `claude agents --json` listing — the same listing Phase 0 checks `unclaimed`
against — never against the Phase 1 roster, which was already filtered to sessions active since the
last standup. That window governs which of the two polls a session gets; it never governs who still
exists. Check release
observationally (is the session live, is the issue closed); never ask.

Then **broadcast the digest to every session this run messaged** — the roster including its silent
ones, and the idle set that got the `stranded` question. That is the part that makes it a standup: a
session asked for something gets to hear what its answer went into. Give each copy a personalized tail naming **what concerns them**, never what they
should do next:

> **Concerns you:** <peer> is blocked on <thing> and named you as the owner. / You and <peer> are both
> in <region>. / You now own lane #<issue>. / Nothing concerns you today.

For a `covered` session, "You now own lane #<issue>" **confirms** the briefing it already got in Phase
5 rather than announcing something new — the fact was already stated to it directly; this is the
standup's own record of it.

A tail is a relevance filter, not an instruction slot. You are a peer, and a peer cannot assign work to
a peer — "this is yours by authorship" is an assignment wearing a hint's clothing. Unowned work goes to
the human as a flag and stays unowned until they say otherwise.

Report to the human last, leading with the unclaimed lanes and the flags — those are the parts needing
a decision.

## When it goes sideways

| Situation | Do this |
|---|---|
| No sessions in the listing at all, board has work | Skip both polls entirely. Report the lanes and say "open N". This is a normal run with an empty listing, not a failure. **Sessions that exist but were idle are not this row** — they are in the listing, they get the `stranded`-only poll, and their unclaimed branches are orphans like anyone else's |
| No sessions active, no open issues at all | Say so, write no file, stop. This is the only "quiet" morning — no work and no one active |
| No map issue in this repo, or several | Say so in one line, ask the human to name today's lanes **in priority order** — the sequence they name them in is their position, so they never join the unpositioned group — and continue without blocking. Still report the open issues, unassigned ones named and ranked critical/high/medium/low as Phase 0 defines (unlabelled last) — never call this quiet |
| No `wayfinder:*` label in this repo at all | Say so once, flatly — not a daily question. Report the open issues ranked critical/high/medium/low as Phase 0 defines (unlabelled last), and let the human name today's lanes from them **in priority order** if they want to |
| First run, no `standups/` dir | Create it, window is the last 24 hours, say that in the digest |
| Peer answers with a wall of text | Summarize to the seven fields in the digest. Do not re-ask; a standup does not block on one person |
| Peer never answers | Named silent; still receives the digest; its region is not reassigned |
| Human opens fewer chats than asked | Bind what exists **in Phase 0's precedence order** — standing lane, the stream that draws first, the other stream, the orphan sweep last — and the lanes past the last chat are the unbound ones, named with the reason. Within a stream, lanes with a position go first in it — map order, or the order the human named them in — and lanes with none follow as one unordered group; **where chats remain but fewer than that group holds, bind none of it** and record those lanes unbound as `order undefined → the human`, reporting those chats as **freed and passed down the order** to whatever takes them, never as unused; **where no chats remain at all, that group is ordinary overflow** — unbound with the reason above, never `order undefined` (Phase 5). The run does not block. Never double-bind a session |
| Capacity yes but the region collides | For `decide` ∩ `decide`, a flag → `/get-aligned`. Every other colliding pair is `held-in-region` instead — a decision request, never sent to `/get-aligned`. **The volunteer's own `owns` answer on that lane's region is not a collision** — Phase 4's `covered` clause exempts it; a live `map.md` row for another lane it holds there is |
| A flag looks urgent | Still just a flag. Let the human fire the next skill |
| A `map.md` row's session is gone | Released and struck before new rows are written |
| `claude agents --json` fails | Stop with the error. Do not fall back to name matching |
| A candidate's region is held by a live lane | It rides — routed to that incumbent as a decision request, `held-in-region`, no `map.md` row. Phase 0 reads that claim from live `map.md` rows and this run's own dispatches only; `owns` does not exist yet |
| More than two riders on one incumbent | A flag `→ the human` as a split question, never a queue on one seat |
| `origin/master` does not resolve | `unlanded` is **unavailable**, not zero — and the land stream with it. Report it as unavailable. **A resolving-but-unfetched `origin/master` is not this row.** This skill never fetches, so that is the ordinary case, not a failure: it over-counts `unlanded`, over-counts a peer's `stranded` check, and strikes fewer rows than it should in Phase 6's `git branch --merged origin/master` release check — each in that one direction, never the other |
| A branch reads `+0` ahead | Report it. **Never reap a ref** — it may hold uncommitted work, and the measurement is minutes old |
| An unlanded branch nobody claims in `stranded` | An orphan. Every session in the listing is asked — the roster in full, the idle set about `stranded` only — so this is the ordinary case, not the rare one. **Only a session sent neither poll** (send failed, or it appeared after the poll went out) makes its branches *unclaimed — author not polled*, reported and held out of the sweep. An orphan nobody ever claimed has no region and is never region-matched. All orphans gather into one sweep lane per run, which resolves to `needs a chat` and is briefed to a non-author |
| A session exists but was idle since the last standup | It still gets asked `stranded`, and only `stranded`. Not on the roster, never asked `capacity`, declares no `owns`. **Not in collection's full-house or notified-and-took-a-turn exits** — its answer counts if it lands before collection closes, and is not in this run if it lands after. **Unless the roster is empty**, when neither of those exits fires at all and collection runs for a 20-minute window, ending early only if every idle session polled has answered (Phase 2). Its unclaimed branches are orphans if it stays silent; a branch it claims becomes its own land lane |
| A claiming author has exited by Phase 4 | Exited means **absent from the unfiltered `claude agents --json` listing**, never absent from the Phase 1 roster. The ownership is orphaned and the branch joins the sweep, but **it keeps the region of the issue that author named** — the issue names the region, not the owner. Collision-checked per branch; say in the digest that it was claimed and its claimant exited |
| A branch whose owner named `serves nothing` | While that owner is in the unfiltered listing: a flag `→ the human`, no region, never dispatched, not one of the three states. **Once that owner has exited, the exited-claimant rule wins** and the branch joins the sweep with no region — a flag nobody is left to act on is furniture |
| A claiming author answers capacity **no** | The land lane is still theirs — `stranded` binds it, capacity does not. `held-in-region`, reported as unlanded-with-owner, and not on the decision list *unless* its region is also claimed by another lane, which is a second cause and a real question |
| A claiming author gives no capacity answer at all | Not a capacity no. `stranded` already bound the lane, so it is `covered` if the author is live and the region is free |
| A decision-bearing issue already carries a package | An item on the decision list, never a lane |
| `.claude/standup.md` absent, or no `intent_sources` key | Skip Phase 0c silently — same contract as a missing `health.md`. The Today proposal draws from the dispatch order alone |
| An `intent_sources` entry does not exist or does not parse | One line as a finding, carry on — a broken intent source never stops the standup |
| Human silent on the Today proposal | Record it `proposed — unconfirmed` under `## Today`, dispatch from the board as usual. Never adopt silently |
| Human's reply names objectives the proposal never contained | Theirs win, verbatim — the reply is the decision. Off-board ones become human-named lanes in the order named |
| A confirmed objective did not close by EOD | Carried, in writing: it is tomorrow's first proposal input, marked `carried (day N)`. Claims were still released at EOD — carry-forward is a proposal fact, never a held claim |
