forked from heavy-duty/ceremony
Merge pull request #191 from dan-claude-bot/build/189-ci-red-deployed
docs(fleet): ci-red is deployed engine — advance the stamp to crew@4da17c4
This commit is contained in:
commit
432dff0613
2 changed files with 78 additions and 45 deletions
108
FLEET.md
108
FLEET.md
|
|
@ -10,7 +10,7 @@
|
||||||
> into [heavy-duty/crew](https://github.com/heavy-duty/crew) (private to the
|
> into [heavy-duty/crew](https://github.com/heavy-duty/crew) (private to the
|
||||||
> org; the fleet can read it), the *mechanism* lives there and this file only
|
> org; the fleet can read it), the *mechanism* lives there and this file only
|
||||||
> points at it. Last reconciled against the merged engine at
|
> points at it. Last reconciled against the merged engine at
|
||||||
> [`heavy-duty/crew@01fb49c`](https://github.com/heavy-duty/crew/tree/01fb49cd717a0f4c83df286af86411c69e3c2363),
|
> [`heavy-duty/crew@4da17c4`](https://github.com/heavy-duty/crew/tree/4da17c49594c2d86bd3793fa3567846cbca38e90),
|
||||||
> 2026-07-27 — a descriptive file with no reconciliation stamp gives the next
|
> 2026-07-27 — a descriptive file with no reconciliation stamp gives the next
|
||||||
> reader nothing to diff, which is exactly how the #149 drift went unnoticed.
|
> reader nothing to diff, which is exactly how the #149 drift went unnoticed.
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ network path — GitHub is the only queue.
|
||||||
|
|
||||||
This table is the **as-built** bench — five boxes, two of them dual-role. It
|
This table is the **as-built** bench — five boxes, two of them dual-role. It
|
||||||
is not the same thing as crew's
|
is not the same thing as crew's
|
||||||
[`fleet.roster`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/fleet.roster),
|
[`fleet.roster`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/fleet.roster),
|
||||||
whose own header declares it the **target** environment: seven single-role
|
whose own header declares it the **target** environment: seven single-role
|
||||||
boxes, the dual-role claude and codex boxes each split into a builder and a
|
boxes, the dual-role claude and codex boxes each split into a builder and a
|
||||||
reviewer member. The delta is exactly that split (plus each new box needing
|
reviewer member. The delta is exactly that split (plus each new box needing
|
||||||
|
|
@ -49,13 +49,13 @@ second repo is a second thing to keep true — this one drifted (it said cron
|
||||||
ran `duty.sh` directly and gave the hygiene sweep its own cron line; crew's
|
ran `duty.sh` directly and gave the hygiene sweep its own cron line; crew's
|
||||||
`duty.sh` records that separate line as the bug it fixed, sharing
|
`duty.sh` records that separate line as the bug it fixed, sharing
|
||||||
`~/duty/work` unlocked). How a tick actually works — cron fires
|
`~/duty/work` unlocked). How a tick actually works — cron fires
|
||||||
[`bin/tick.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/bin/tick.sh),
|
[`bin/tick.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/bin/tick.sh),
|
||||||
the only cron target, which wraps
|
the only cron target, which wraps
|
||||||
[`bin/duty.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/bin/duty.sh)
|
[`bin/duty.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/bin/duty.sh)
|
||||||
in a non-blocking `flock` with one evidence line per boundary; the boot gate
|
in a non-blocking `flock` with one evidence line per boundary; the boot gate
|
||||||
and crash recovery; the session runner; backlog hygiene self-scheduling
|
and crash recovery; the session runner; backlog hygiene self-scheduling
|
||||||
inside the duty tick under the same lock — lives with the code:
|
inside the duty tick under the same lock — lives with the code:
|
||||||
[`shared/README.md`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/README.md)
|
[`shared/README.md`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/README.md)
|
||||||
is the map, provenance table included. Sessions stay stateless and
|
is the map, provenance table included. Sessions stay stateless and
|
||||||
disposable — all state lives on the board (issues, PRs, labels) and in git
|
disposable — all state lives on the board (issues, PRs, labels) and in git
|
||||||
branches; detection is the engine's, judgment is the session's.
|
branches; detection is the engine's, judgment is the session's.
|
||||||
|
|
@ -73,11 +73,13 @@ What belongs here is what a wake *means*:
|
||||||
write surface the whole org, which no registry could bound: the drill's
|
write surface the whole org, which no registry could bound: the drill's
|
||||||
containment interlock narrowed `repos.txt` and so confined triage and
|
containment interlock narrowed `repos.txt` and so confined triage and
|
||||||
hygiene, but not review, the one module that submits verdicts.
|
hygiene, but not review, the one module that submits verdicts.
|
||||||
[`lib/duty-review.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/lib/duty-review.sh)
|
[`lib/duty-review.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/lib/duty-review.sh)
|
||||||
states the rule and implements the WARN.
|
states the rule and implements the WARN.
|
||||||
- **One wake is registry-independent, by design: attention** (next section).
|
- **No wake is exempt, including attention** (next section). The attention
|
||||||
The registry bounds what a box goes *looking for*, not what is handed to
|
*query* is cross-repo by construction — it is one call to the
|
||||||
this identity *by name*.
|
authenticated-user endpoint, which has no repo filter — but the *action*
|
||||||
|
it authorizes is bounded like every other. A demand parked on this box in
|
||||||
|
a repo nobody listed is reported, never worked.
|
||||||
|
|
||||||
### Wake conditions
|
### Wake conditions
|
||||||
|
|
||||||
|
|
@ -92,20 +94,26 @@ very thing that unparks the work resume would otherwise pick up. The query is
|
||||||
the authenticated-user endpoint —
|
the authenticated-user endpoint —
|
||||||
`gh api "/issues?filter=assigned&state=open&labels=attention"` — one call, no
|
`gh api "/issues?filter=assigned&state=open&labels=attention"` — one call, no
|
||||||
search index (the review queue below already records that the index lags) —
|
search index (the review queue below already records that the index lags) —
|
||||||
and, **alone among the wakes, it reaches repos `~/duty/repos.txt` does not
|
and it **sees** repos `~/duty/repos.txt` does not name, because that endpoint
|
||||||
name.**
|
takes no repo filter.
|
||||||
|
|
||||||
That reach is deliberate, and it survives the registry rule above as its one
|
**Seeing is not acting, and that is a ruling** (crew#66, danmt, 2026-07-27).
|
||||||
stated exception. An `attention` assignment is work handed to this identity
|
The wake used to work every row it saw, which for a builder meant a clone and
|
||||||
by name, and **the assignment is what carries the authorization** — there is
|
the full worktree and round rule set against a repo no operator had listed —
|
||||||
nothing here for a repo list to scope, because the box is not choosing where
|
write authority outside the registry, and the one hole left in the
|
||||||
to look.
|
containment story. Rows are now partitioned against the registry: inside it,
|
||||||
[`lib/duty-attention.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/lib/duty-attention.sh)
|
a session as before; outside it, reported and never acted on, exactly like an
|
||||||
queries the cross-repo endpoint on purpose and says so in its header; a fix
|
out-of-scope review request or authored PR.
|
||||||
that bounds this wake to the registry would re-create the #16 incident below.
|
[`lib/duty-attention.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/lib/duty-attention.sh)
|
||||||
(Crew's `conf/repos-default.txt` header currently claims *every* duty module
|
implements the partition and states the ruling in its header.
|
||||||
is registry-bounded — that contradiction is crew's, raised there as a
|
|
||||||
discussion; this file records the exception as it is implemented today.)
|
The cost was argued before the ruling rather than discovered after it: an
|
||||||
|
assignment plus a label **is** a targeted authorization, so a cross-repo
|
||||||
|
handoff now waits on an operator adding the repo, and the box most likely to
|
||||||
|
be handed work outside its beat is the one that goes quiet. That is why an
|
||||||
|
out-of-scope demand does not only reach `duty.log` — it pings the operator
|
||||||
|
over the same channel the boot gate uses. A bounded wake that failed silently
|
||||||
|
would trade an unbounded write surface for a broken channel to the human.
|
||||||
|
|
||||||
Each demand gets **exactly one session, and the ack bounds it**: the
|
Each demand gets **exactly one session, and the ack bounds it**: the
|
||||||
session's first act, before any of the demanded work, is the pickup comment
|
session's first act, before any of the demanded work, is the pickup comment
|
||||||
|
|
@ -113,9 +121,13 @@ plus removing the label — [the `attention`
|
||||||
contract's](https://github.com/heavy-duty/ceremony/blob/bce09aa7648dbd74b8e91b1d4fbc2fa8d145f705/LABELS.md#L143-L149)
|
contract's](https://github.com/heavy-duty/ceremony/blob/bce09aa7648dbd74b8e91b1d4fbc2fa8d145f705/LABELS.md#L143-L149)
|
||||||
ack (#85), which here becomes the session's ack-then-act ordering.
|
ack (#85), which here becomes the session's ack-then-act ordering.
|
||||||
Then it acts on the thread and exits — short by construction. Until the label
|
Then it acts on the thread and exits — short by construction. Until the label
|
||||||
is removed the flag is still up, so a session that dies before acking is
|
is removed the flag is still up, so a session that **dies** before acking is
|
||||||
simply relaunched at the next tick; that is the whole crash-recovery story,
|
simply relaunched at the next tick — the same crash-only shape as resume
|
||||||
and it is the same crash-only shape as resume below.
|
below. A session that **completes** without acking is a different fact: that
|
||||||
|
is a decline, and a seen-ledger stops it re-firing until the issue moves.
|
||||||
|
Dying and declining used to look identical to the engine, which meant a
|
||||||
|
demand a session had considered and correctly left alone woke a new one every
|
||||||
|
tick forever.
|
||||||
|
|
||||||
The design this replaces was built and rejected: polling notifications for
|
The design this replaces was built and rejected: polling notifications for
|
||||||
`reason: mention` re-arms a thread on every comment, so ordinary round
|
`reason: mention` re-arms a thread on every comment, so ordinary round
|
||||||
|
|
@ -131,14 +143,13 @@ wake is no longer on paper: `duty-attention.sh` is deployed engine, and
|
||||||
`duty.sh` runs it first on every box, whatever its roles.
|
`duty.sh` runs it first on every box, whatever its roles.
|
||||||
|
|
||||||
The engine's duty order is fleet-standard
|
The engine's duty order is fleet-standard
|
||||||
([`bin/duty.sh`](https://github.com/heavy-duty/crew/blob/01fb49cd717a0f4c83df286af86411c69e3c2363/shared/bin/duty.sh)):
|
([`bin/duty.sh`](https://github.com/heavy-duty/crew/blob/4da17c49594c2d86bd3793fa3567846cbca38e90/shared/bin/duty.sh)):
|
||||||
**attention → triage signals → review queue → resume → ci-red → build →
|
**attention → triage signals → review queue → resume → ci-red → build →
|
||||||
handoff → rebase → worktree hygiene → backlog hygiene (hourly)** — attention
|
handoff → rebase → worktree hygiene → backlog hygiene (hourly)** — attention
|
||||||
role-independent and first, then each duty family the box's roles enable.
|
role-independent and first, then each duty family the box's roles enable.
|
||||||
One position in that order is **on paper**: ci-red is
|
Every position in that order is deployed engine at the stamped SHA:
|
||||||
[crew#64](https://github.com/heavy-duty/crew/pull/64)'s, unmerged at the
|
[crew#64](https://github.com/heavy-duty/crew/pull/64) merged ci-red between
|
||||||
stamped SHA, where `duty.sh` still runs resume straight into build — it
|
resume and build, and `duty.sh`'s own header carries the same order.
|
||||||
reads as deployed engine only once that PR merges.
|
|
||||||
The earlier form of this file folded handoff and rebase into the other
|
The earlier form of this file folded handoff and rebase into the other
|
||||||
builder wakes; they are duties of their own.
|
builder wakes; they are duties of their own.
|
||||||
|
|
||||||
|
|
@ -167,23 +178,30 @@ builder wakes; they are duties of their own.
|
||||||
— a session died between first push and PR creation. A branch whose PR
|
— a session died between first push and PR creation. A branch whose PR
|
||||||
already **merged** is a post-merge wait, never resumed (#172,
|
already **merged** is a post-merge wait, never resumed (#172,
|
||||||
incubator#55/#64).
|
incubator#55/#64).
|
||||||
- **ci-red** (builders; **on paper** — crew#64's spec, unmerged at the
|
- **ci-red** (builders): a non-draft PR of mine whose check at the current
|
||||||
stamped SHA): a non-draft PR of mine whose check at the current head is
|
head is failing. Evaluated before the build wake, so a red PR of mine
|
||||||
failing. Evaluated before the build wake, so a red PR of mine outranks a
|
outranks a new claim — repairing my own red head comes ahead of new work
|
||||||
new claim — repairing my own red head comes ahead of new work
|
|
||||||
(ceremony#163: full-panel approvals at the head, mergeable, stranded on
|
(ceremony#163: full-panel approvals at the head, mergeable, stranded on
|
||||||
a transient failure no wake covered). A round owed at a red head is
|
a transient failure no wake covered). A round owed at a red head is
|
||||||
excluded from the build wake below but reported rather than silent, and
|
excluded from the build wake below but reported rather than silent, and
|
||||||
an unchanged red head goes quiet after one attempt, through the
|
an unchanged red head goes quiet after one attempt, through the
|
||||||
`report_suppressed` path — suppressed, still said. How a red head is
|
`report_suppressed` path — suppressed, still said. A check that has not
|
||||||
detected and kept quiet is the engine's mechanism, described in crew's
|
finished is **not** a red head and wakes nothing here: nothing has failed
|
||||||
|
yet, so there is no investigation to launch. How a red head is detected
|
||||||
|
and kept quiet is the engine's mechanism, described in crew's
|
||||||
`shared/README.md`, not here.
|
`shared/README.md`, not here.
|
||||||
- **Build**: a `ready` **unclaimed** issue (an assignee means mid-claim, not
|
- **Build**: a `ready` **unclaimed** issue (an assignee means mid-claim, not
|
||||||
pickable), or a completed review round on my PR — a changes-request with
|
pickable), or a completed review round on my PR — a changes-request with
|
||||||
no panel review request still outstanding; whole rounds, never single
|
no panel review request still outstanding; whole rounds, never single
|
||||||
verdicts, and — once ci-red deploys — never a round at a red head: that
|
verdicts, and never a round the check at its head does not support. The
|
||||||
head has already woken ci-red above, and the excluded round is reported,
|
wake admits a **green** head, and a head with **no checks configured** —
|
||||||
not swallowed.
|
terminal, not transient, so holding there would retire the round rather
|
||||||
|
than delay it. It holds a **red** head (already woken ci-red above) and a
|
||||||
|
head whose check has **not finished** (opening the round there spends the
|
||||||
|
panel on a head that may go red — crew#45's measured cost — and it admits
|
||||||
|
itself a tick later once the check settles). Both holds are reported, not
|
||||||
|
swallowed, and they are reported *differently*: only one of them is the
|
||||||
|
author's own work to do.
|
||||||
- **Handoff**: a round of mine that converged — every panelist's latest
|
- **Handoff**: a round of mine that converged — every panelist's latest
|
||||||
opinionated review approves the current head, no panel request
|
opinionated review approves the current head, no panel request
|
||||||
outstanding, mergeable right now, `state:needs-human` not already set.
|
outstanding, mergeable right now, `state:needs-human` not already set.
|
||||||
|
|
@ -248,10 +266,14 @@ The duty engine is crew's shared tree, one source deployed to every box;
|
||||||
makes the registry rule an operator decision rather than a sweep's. Specs
|
makes the registry rule an operator decision rather than a sweep's. Specs
|
||||||
written in this file have a record of becoming engine: the attention wake
|
written in this file have a record of becoming engine: the attention wake
|
||||||
and the reviewers' request sweep both started here as paper (the sweep's
|
and the reviewers' request sweep both started here as paper (the sweep's
|
||||||
org-wide form was then retired by the 2026-07-25 scope ruling). Two are
|
org-wide form was then retired by the 2026-07-25 scope ruling), and the
|
||||||
still on paper: the notifier's `needs-ruling` queue — at the stamped crew
|
builders' ci-red wake above is the latest: written here as paper while
|
||||||
SHA, `notify.sh`'s only label filter is `state:needs-human` — and the
|
crew#64 was open, engine at the stamped SHA. Two rows are still on paper, and
|
||||||
builders' ci-red wake above, engine the moment crew#64 merges.
|
both are `needs-ruling`: the notifier's queue — at that SHA, `notify.sh`'s
|
||||||
|
only label filter is `state:needs-human` — and triage's **past 24h**
|
||||||
|
detection row above, which the triage-signals bullet already marks. Earlier
|
||||||
|
counts here said "two" while silently excluding the second; naming them is
|
||||||
|
cheaper than a number that has to be recounted every time a wake lands.
|
||||||
|
|
||||||
### Conventions on the board
|
### Conventions on the board
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,19 @@
|
||||||
of your own PR is picked up before claiming another issue, is never a
|
of your own PR is picked up before claiming another issue, is never a
|
||||||
parked claim, and follows crew#17's recovery path (#189).
|
parked claim, and follows crew#17's recovery path (#189).
|
||||||
- `FLEET.md` writes the ci-red wake into the duty order between resume
|
- `FLEET.md` writes the ci-red wake into the duty order between resume
|
||||||
and build, marked on paper until crew#64 merges, with the
|
and build, now as deployed engine rather than on paper: the
|
||||||
reconciliation stamp unchanged (#189).
|
reconciliation stamp advances to the crew SHA carrying crew#64 (#189).
|
||||||
|
- `FLEET.md` describes the build wake's check gate as the engine
|
||||||
|
implements it: a green head, or one with no checks configured, opens a
|
||||||
|
round; a red head and an unfinished one are held and reported
|
||||||
|
separately (#189).
|
||||||
|
- `FLEET.md` corrects the attention wake to the crew#66 ruling: the query
|
||||||
|
is cross-repo, the action is registry-bounded, and an out-of-scope
|
||||||
|
demand is reported and escalated to the operator rather than worked. It
|
||||||
|
no longer claims attention is exempt from the registry (#189).
|
||||||
|
- `FLEET.md` distinguishes an attention session that dies before acking,
|
||||||
|
which relaunches, from one that completes without acking, which is a
|
||||||
|
decline a ledger keeps from re-firing (#189).
|
||||||
- `BUILDER.md` re-requests by head, not by verdict: a push while
|
- `BUILDER.md` re-requests by head, not by verdict: a push while
|
||||||
answering a round stales every approval, so every panelist is
|
answering a round stales every approval, so every panelist is
|
||||||
re-requested; only an unchanged head re-requests the non-approvers
|
re-requested; only an unchanged head re-requests the non-approvers
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue