Source Built from main · latest release v0.4.0

Collaboration

Mentions, judgement, handoffs, turns.

On this page
  1. Handoff
  2. Delegation
  3. Participation
  4. Judgement
  5. Mention
  6. Pull-in
  7. Turn
  8. Redirect
  9. Fork
  10. Ask
  11. Stop
  12. Hold
  13. Control line
  14. Status question
  15. Plan
  16. Ticket
  17. Large job
  18. Sample
  19. Submission
  20. Review
  21. Review miss
  22. Capability ceiling
  23. External job
  24. Quality event
  25. Lesson
  26. Retrospective
  27. Work item
  28. Desk segment
  29. Attribution
  30. Group lead
  31. User quote
  32. Requirements ledger
  33. Scribe
  34. Line reading
  35. Organizer
  36. Organizer run log
  37. Check-back
  38. Supervisor
  39. Ball holder
  40. Closing check
  41. Acceptance check
  42. Check from your words

Handoff

One Bot passes work or a result to another Bot; delegation is the kind that explicitly requests handling and records an expected result, while an ordinary note is not automatically a delegation. Waking and waiting depend on the form of handoff.

Avoid: every private message is a delegation, speaking means delivery is complete, a note as a work request

Delegation

A named request from one work item to another Bot's work item, recording the shared job, the ask, whether it expects a deliverable/review/answer, and whether it has been replied to or cancelled. It relates a request to a result, not an ordinary chat message or permanent assignment of an entire Bot or conversation. Details: Behavior · Delegation.

Behavior details

Wired at level 3: delegate({to,ask,expects,ticket?,parts?,requirement_ids?,continue?}) requires a running work segment exactly bound to its work item and not held; a desk/read-only answer cannot impersonate it. to is an id or exact name of another non-archived Bot present in the segment's conversation, the work item's home or the plan's home. Tickets/parts must belong to the plan and cited requirements must apply to that work. Unknown targets do not relax these checks.

The app records the request, sender/recipient work items and originating turn, creates/reuses the recipient's work on the same plan/optional ticket and the exact Bot-pair direct, and queues priority-3 waking request mail. Unless continue:true, the sender becomes waiting with a delegation_wait record and its segment ends. continue:true creates no wait and keeps the segment going, while the delegation remains recorded. The sender may later finish independent work as answered/idle; a delayed answer still queues/wakes the eligible original sender without inventing a wait. Recipient admission/hearing/queueing still obeys I1/I1b, capacity and holds; being delegated does not duplicate a Bot's live work on the plan.

A delivery approved answers its delegation (from level 5): a delegation that expects a deliverable (expects: deliverable) is answered by the app when the hand-over the recipient made for it is approved (by a review, by the app on its checks, or by your 放行): the result says who handed in what, the submission id and its files, and the delegating Bot is woken at once, out of its wait. One that names parts is answered once the approval covers them all; one that names none, once the ticket is through. Nothing answered such a delegation before: the delegating Bot waited for good and never heard (the three in your database were each cancelled only when their group was cleared). A rejection answers nothing — the recipient still owes it. While the recipient's hand-over for it is being checked, reviewed or waits on your 放行, the delegation is not counted as owed by the recipient, so its segment ends once it has handed in. It used to count, so submit answered "carry on" and the Bot rewrote and handed in again over the one under review (2026-10-03); sent back, the ticket is in rework and owed again. A request for a deliverable on a ticket the caller owns, naming no part, is refused: what the recipient hands over for it would be the whole ticket's hand-over — on 2026-10-04's real-model run the poster group's lead, without laying the job out, sent the slogans straight to 文案 on the job's one ticket, and 文案's 宣传语.txt went to you to approve as the whole job, so 放行 would have delivered it with no poster. The refusal names the two ways on: give the piece its own ticket with plan_items (the recipient as owner, the caller as reviewer) and delegate on that, or ask with expects: "answer" and hand the ticket over yourself. On the same run the lead took the second: 文案 answered with the three lines and the lead made and handed in the poster.

A reply in words covers answer requests, and review requests with nothing handed over to review: the recipient calls end_turn({reason:"answered",answer:"…"}), which resolves the open delegations exactly bound to it: every one with expects="answer", and one with expects="review" only once it has read the request and nothing within the request's reach (its ticket, or the whole plan when it names none) is being checked or waits for review (checking/submitted/in_review) — say, a pre-review of a script or storyboard. A review request with a submission waiting goes through review (ADR 0046); expects="deliverable" has no reply in words. Ordinary closings or send_message are not results. The result commits once as priority-2 durable delegation_reply mail, marks replied and voids that delegation's wait, then queues/wakes an eligible sender. A held sender's result remains held. A reply in words only hands the verdict to the Bot that asked: it approves no submission and moves no ticket stage, and a prose claim cannot stand in for an approved review.

When a segment read such a request and ends answered without an answer (typically after posting its verdict with send_message in the thread), the ending bounces (unanswered_request) naming the request, who is waiting, and that the reply goes in answer; it shares the two-bounce budget, so running out ends needs_attention instead of quietly leaving a request nobody closes. On a done or prose ending, the unfinished-obligations bounce also says how to answer such a request it read.

Event waits are not timer check-backs: due scanning excludes delegation_wait at every level. Only this delegation's reply/cancellation resolves it. Level-3 timers replace by exact work item/dedupe key, not another job or event wait of the same Bot/conversation. A hold suspends/restores the matching records without an unrelated newer timer clobbering an event wait. With no real due time the view's due_at is null, not an internal placeholder displayed as a countdown.

Hold cascades follow still-open delegation edges whose plan/ticket bindings match, captured as downstream Bot × plan targets when the hold is made. They do not trust one delegated_by parent: one recipient item can have several senders. Stopping the owner's job covers its helper on that job while the helper's other plan continues. Later delegations do not quietly widen an existing snapshot, and only user actions lift holds.

Archiving/deleting a Bot or clearing/deleting a related conversation cancels affected open delegations and records the result. Archiving the recipient gives the still-existing eligible original sender one waking cancellation result; archiving the sender does not wake itself. Conversation-clear/delete cancellation results all have wakes=0, never restarting work because a chat was cleared. Requests/results remain recorded; cancellation is not completion. Archiving also closes that Bot's work items, ends live execution and aborts it after commit. The side-effect guard rechecks Bot eligibility, a nonclosed work item and execution authority, so an in-flight completion cannot keep writing after archival.

Read-only views: local and remote-whitelisted GET /v1/tasks/:id/delegations and GET /v1/sessions/:id/delegations return persisted DelegationView facts: who asked whom, the expectation, open/replied/cancelled, request/result, waiting/held and a real nullable due time. Live delegation.changed plus catch-up updates them. The pair direct shows structured delegation/result/wait records, not inferred prose status. These are read-only projections, not new user delegation buttons. Components are wired, and the parent confirmed synthetic-scenario checks in two browsers. That verifies the read-only view/interaction, not a paid real-model collaboration-loop acceptance.

Speaking differs from ending: level-3 successful send_message does not end the segment, allowing a note followed by more work. A segment may send at most 3 user-visible progress messages without parent_id; the fourth returns progress_limit. Currently parent_id is the exemption marker, with no implemented semantic classification of a real question: an arbitrary quoted reply is not a proven answer exemption. Group mentions can still wake; ordinary pair-direct messages do not. Files written after an earlier progress post remain tracked as uncited paths and can attach to the closing message; the earlier send does not lose later artifacts. This is message citation, not implicit submission.

Ending is wired, but 24b is not complete: level-3 end_turn reasons are done/answered/nothing_new/blocked/gave_up. It validates running status, exact work-item/plan/ticket binding and holds, records dispositions for read user/annotation mail and writes turns.end_reason / work.ended. Unacknowledged user mail bounces, except on a prose ending: the lines of yours the segment read and gave no word about are recorded as answered by that prose. Prose first passes retained closing/run-evidence checks; a bounce writes no premature work.ended, and the ending contract runs afterwards. Prose in a desk/readonly answer is answered; work prose uses the same contract. With unfinished To do/In progress/In review tickets, open delegations or waits and no valid wait, done/prose bounces once and then ends as nothing_new, not a submission. Two no-progress endings with obligations can become blocked and notify (in your interface language, naming the job and the Bot). With nothing owed on the work (no ticket of its own to do, no request, no wait), when the segment's last word to you (the closing itself for prose, else its newest message) says it is still working (正在编写, 结论随后, "I'll put the storyboard together and post it", "I'm now drafting", as read by line reading; by the words of later-words.ts when it cannot be read) and names no Bot to take it, done/answered/nothing_new bounces once (promised_later) with its own words: do it now, or book a check-back and end with nothing_new, or name who takes it. The next ending goes through, and a line in the conversation (in your interface language) says it said "…" but its turn has ended and nobody is carrying on with it, and to @ it to have it go on (in your direct with it, to tell it: whatever you say there reaches it; the two-endings-without-progress line does not ask you to @ it there either). On 2026-10-03 视频导演 ended as done eight seconds after saying it was writing the new EP01 setting bible and storyboard; the plan's one ticket still read as handed over from the earlier run, nothing woke it again, and the group showed no sign it had stopped. A segment a line of yours opened in your direct that is about to end with no word to you (no closing reply about to go out, no message of its own with words in it there, no words handed over; files alone are no reply — files it wrote, a line that only carries files, files handed over) bounces once too, on done/answered/nothing_new (said_nothing): what goes into end_turn — answer (only for a Bot that asked), note, inbox — never reaches you, and files are not a reply, so it is told to reply in the conversation; the next ending goes through with a line in your direct (in your interface language) saying it ended its turn without replying and to say it again to have it answer. On 2026-10-07 通识 put its whole answer into answer, and your line got nothing; the same day 视频导演 answered 「水印去不掉吗」 and 「它支持传参考图吗」 with files alone. In such a segment submit does not end the segment either, and tells the Bot to reply first (no bounce counted). Lines in a group, read-only answers and segments a routine woke are not covered. When the end contract sends a pure-text closing reply back (files of an approved ticket changed, a ticket not yet handed over…), the reply has already gone out: the bounce is about the work, not the words, and only the closing check holds the words back; the bounce opens with "your reply has gone out as written; do not say it again", and the same words go out once per segment. Held back before, the reply never went out once the Bot handed its files over as told and submit ended the segment — on 2026-10-07 视频导演's written answer to 「这个视频生成跟 Grok 的比哪个好」 was lost that way, leaving a folder card. An actually observed ticket-stage change is authoritative progress recorded as ticket.stage_changed with the matching turn id: a productive current segment's first ending is not counted as empty cycling, while later quiet endings accumulate. Unacknowledged-inbox/unfinished-obligation bounces and filing refusals share the two-bounce budget, ending as needs_attention when exhausted. In a desk segment, thrown malformed work_on/end_turn arguments count too (an unknown reason, blocked without needs_from_user, gave_up without a note), suppressing later effects in the same hop. Once the segment is bound, a refused delegate, work_on or end_turn does not count: it is an ordinary failed call the Bot reads and retries, three failures of one tool in a row step the job up; delegate binds a desk before it runs, so its validation never counts. Before, these counted too, and working segments that had done their work were cut off with the desk's line 「这句话需要先选归属,尚未执行有副作用的工具」.

A work item with a real timer/delegation wait stays waiting. A completed ticket or desk can close; other answered/nothing_new work may idle. Blocked needs needs_from_user, gave_up needs a note and records a notice/event. Blocked is only for what you alone can give: for a wait on another Bot, the tool description, the system prompt and the unfinished-obligations bounce all tell the Bot to delegate to it or end with nothing_new, rather than turn the wait into a question to you. Gaps remain: at level 3 blocked produces an app system line; the persistent answerable card is level 4's (work question card); I5 now has level-3 database triggers: a bound completed/stopped/interrupted/redirected row needs a nonblank end_reason on INSERT and every UPDATE, without restricting it to a reason enum. Legacy levels 0–2 are exempt; historical terminal rows get a one-time status backfill without overwriting explicit reasons. Old closing-check regexes still run. implicitSubmission.implemented=false only lists metadata for cited artifacts under the ticket directory: no existence/new-hash validation, bound checks, stored submission or submitted/approved transition. Supervisor 24c (orphan thresholds, periodic I6 checks, hourly recovery budgets, automatic restart policy, retiring old timers) is implemented at level 4, see Supervisor; level 3 has none of it.

Avoid: private message means delegation, ordinary acknowledgment means result, the whole Bot belongs to the sender, saying approved means a completed review

Participation

Which present Bots receive a group message: mentions name recipients, otherwise an eligible lead takes precedence; only with no lead are legacy group judgements retained. Receiving a message does not mean interrupting work already under way on that job. For the routing boundary, see the Group lead behavior details.

Avoid: asking the whole group for every line, automatic appointment before confirmation, receiving means redirecting

Judgement

A Bot's choice to join in or sit out on an unaddressed user line in an old group with no lead to receive it; it is not an execution segment and does not ask the user a question. Sitting out or failure produces no work reply, and an explicit mention needs no such judgement. For the routing boundary, see the Group lead behavior details.

Avoid: a segment for every bystander, joining on failure, judging every Bot line again, every group must judge

Mention

A way to name a group message's recipients: one Bot or all present Bots, bypassing participation judgement but not holds, attribution or execution slots. If that Bot is already working on the same plan, the mention makes the existing segment hear the line, not redirect; when that segment runs in another conversation, the Bot answers you here, where you named it. Details: Behavior · Mention.

Behavior details

@Bot names a Bot (one in the roster but outside the group still joins through existing Pull-in before receiving); @everyone names only Bots already in the group except the author and pulls in nobody outside it. A short name with one present match names that Bot. An unknown name wakes nobody: a Bot's send_message is first refused once for correction, then a still-unknown name leaves a system notice. An @ in a path, URL or Markdown link target is no mention; one glued to an ASCII letter, digit, _, - or a path separator is none, while @A/@B names both and one after Chinese text or punctuation still counts.

A Bot's line in a group that names another Bot and, the names aside, is only a bare acknowledgement (「@Beta 收到,已对齐」) wakes nobody when its turn was itself woken by such a line from the other Bot and neither turn ran a command or MCP tool (at every level; the same nod-to-a-nod rule as in Bot↔Bot directs), so two Bots cannot keep naming each other to agree forever. A question, a file, a path or a name nobody here has makes it more than a nod.

At level 2 a mention chooses recipients, not the end of an old turn: an existing same-plan segment hears it, while another plan opens or queues its own. Your group mentions do the same; Stop/holds interrupt immediately. Level-0/1 compatibility can still redirect a user's group line, carrying old written files, recent calls and unread mail, while Bot mentions and check-backs try to enter an existing segment. Old wake/ending semantics of ordinary Bot↔Bot directs and send_message remain at levels 0–2; level 3 uses explicit delegate and non-waking ordinary messages in delegation threads, under Delegation; a direct a Bot opens with create_direct wakes the other side on every line at every level (see Direct).

Avoid: mention means pause, a group mention cloning itself, mention bypassing a hold, a name in a path is a recipient

Pull-in

@-mentioning, in a group, a Bot that is not in the group but is on the roster and not deleted: it is added to the group first, then joins in. A name that is not on the roster does not create a new Bot; the message is still sent.

Avoid: @-mentioning without joining the group, implicitly creating a Bot for an unknown name

Turn

One Bot's execution segment triggered by a message or wake: working, choosing attribution at a desk, or answering read-only under a hold; waiting for your approval or answer still belongs to that segment. Ending it does not mean the job is delivered or accepted. Lines you send in a row are taken in the order they came: the first opens the turn, the next are read at its next step; one not read yet can be taken back, or inserted to be read now (ADR 0069). Details: Behavior · Turn.

Behavior details

A level-2 segment belongs to a work item; live states include running/waiting_approval/waiting_ask. One Bot × plan has one segment, not one Bot across the entire group forever. Different plans use the work slots (two by default), desks count separately (see Work item); an unrelated new request goes to a desk, not the old job. Same-plan mail is read between tool calls: a user change defers remaining unexecuted calls in that hop, a question does not, and a long command completes its current call unless a hold stops it.

A prose answer or end_turn can end the current segment. Existing inbox dispositions still record adopted, answered, declined (with why), deferred or unacknowledged. A disposition for an id that is no mail of this segment's (none at all — often the line that woke it — or mail another segment read) records nothing and sends nothing back: only a wrong word on mail it did read, or a line of yours left without one, bounces the ending (before 2026-10-03 a segment with no mail at all was bounced twice for naming the line that woke it, ended needing attention, and was picked up again). Ending is not an approved submission. Level-3 reason/obligation checks have a domain function and engine integration; see Delegation for implemented parts and gaps. Ball-holder supervision is still absent. Completion failure differs from interruption; existing 40-hop stuck reminders remain (they only ask; since 2026-10-17 the tools are no longer taken away at 160 hops), not a new supervisor. The transcript interleaves in time and spend is per call.

At old levels a user's group mention/join judgement can redirect: end the old segment and start from the new message, carrying files/calls/unread mail without reversing past effects. Peer lines and check-backs enter an existing segment. Legacy direct forks and one-Bot-one-turn across a group are compatibility, not promises in addition to level-2 plan uniqueness.

What a turn ran stays under its reply: each shell command is recorded as it finishes (turn_runs): the command (whitespace folded, clipped to 300 characters), its exit code, whether it succeeded, how long it ran, and the last 4000 characters it printed (stdout, then stderr; nothing when it printed nothing), the same for Bots on your endpoints and Claude Agent Bots; MCP calls are recorded too but are not commands. A turn keeps its first 80 calls. Once the turn has ended, its last reply carries the same command card (while it runs, a line it sent on the way carries none: its commands are in its working message), on the reply's last line with its time and reply time, wrapping only when they do not fit, read from that record (GET /v1/turns/:id/commands, when the reply comes near the screen); at the moment it ends the card shows what this page saw, until the record is read. The reply time is said in the interface's language, "5m 9s" in English and "5 分 9 秒" in Chinese, with a faint "·" between it and the time. Clearing or deleting the conversation deletes these records with it. Earlier builds kept no time or output, so turns from then have the command and exit code only.

Focus mode: the target icon at the top of the sidebar (beside the search on a phone) or the "Focus mode" switch in Settings › General › Preferences (chat/focus-mode.svelte.ts, kept per browser, shared by every conversation and pane) leaves the transcript with what was said and what waits on you. Left out is what is said about a line: the last line under a Bot's reply (command card, reply time, time; the time moves to the hover action bar), the time under your lines (an edited one keeps "Edited"), the time on questions and app lines, the "Bot" and model tags beside a name, the count over a run of your lines, and the entries into Bot ↔ Bot directs; a working bubble keeps only its pulse and "Thinking" ("streaming" once it has said something), without the step, its timer or command output. Kept as before: bodies, attachments, quotes, reactions, annotations, approval and question cards, work questions, buttons such as Continue, Insert now and Withdraw, the replying indicator, and the date and new-message dividers; in a Bot ↔ Bot direct its delegation records stay too, since they are what the direct is about.

Lines in a row (ADR 0063): your lines in one conversation are taken in the order they came. A line waits until the one before it is read, filed and routed before it is filed and routed itself — the turn that one opened is then there, and this line goes into its inbox, read at its next step — and its filing read sees where the line before it went. The wait counts from when the line ahead started and lasts at most 45 s; shutting down, nobody waits. What a line means is read without waiting: the reading starts as it arrives (from 2026-10-09, ADR 0070), and a line read as nothing but a stop is carried out at once, ahead of the lines still being read; a go on or a status question waits its turn like any line and goes to the Bot. A Bot's lines do not queue. So a direct's Send no longer greys out while your last line is read (an older daemon still locks it), the hint says "Enter to send — it reads it at its next step", and a Bot already at work is no longer drawn replying under each line you send meanwhile.

Avoid: turn as ticket, a turn ending means acceptance, a peer line clones same-plan work, endless tool calls, a later line overtaking an earlier one as the trigger

Redirect

Ending a segment's remaining actions and starting another from a new message, without rolling back past effects. It is a legacy migration-path behavior, not the default meaning of a group mention in the new work-item path; Stop or a hold is how to halt immediately. For the boundary, see the Turn behavior details.

Avoid: every new line redirects, a mention replaces a hold, one line clears the whole group's work

Fork

Starting a segment beside an existing one while the first continues; two executions, not two copies of a job. The new work-item path allows bounded parallelism on different plans only, and same-plan messages enter the existing segment. For the boundary, see the Work item behavior details.

Avoid: bypassing same-plan uniqueness, opening a turn bypasses a hold, group mentions clone the Bot

Ask

A Bot asks you about something that needs your judgment (not a tool approval). The question appears in the transcript, and the turn continues once you answer. When the possible answers can be listed, the Bot offers options: single choice when only one can hold, multiple choice when several can hold at once, with the recommended one first; you can always skip the options and write your own answer, or pick one and add a sentence. Your answer is recorded on the ask itself, not sent as a separate message from you: the card keeps what you picked and what you wrote, and later turns, the organizer and search all read it from there. Each ask is answered only once. From level 2, a line you type in the conversation while the Bot waits on its question (no files attached) is your answer to it, written as your own text, and the turn continues.
From level 4, a Bot that ends a segment of work as blocked, saying what it needs from you, leaves a work question card: that segment has ended, the card stays in the job's conversation, and your written answer queues the job again; answering lifts no stop, and under one the answer is only held. Details: Behavior · Work question card.
A Bot's question (an ask, or the work question card a blocked ending leaves) that reads as only asking your OK to go on with what you asked for — a sign-off on work in progress, whether it may start the next step — is sent back once, and the Bot goes on; asked again, it reaches you. The app itself asks you only when you have to let something through, when it needs what only you can give, or when it has stopped and will not go on by itself; what it decided for you, what you just said and what it will go on with, it does not ask about. The list: Behavior · When the app asks you.

Behavior details

From level 4, end_turn({reason: "blocked", needs_from_user}) leaves a question card (control.kind = "work_question", with the work item, plan and ticket) where the segment asked (when you are in it and it is not archived), else where you last spoke about the job, else the job's conversation, else the plan's, else your direct with the Bot (it used to go to the job's conversation first: a job opened in a group and taken up in your direct asked you to sign off in the direct while its card landed in the group, 2026-10-04); its author is the Bot, it shows as the app's card, and it comes with a "waiting for your answer" notification. The work item is blocked with waiting_on = {kind: "user"}, and the ball is yours. The same question from the same segment leaves one card.

POST /v1/messages/:id/work-answer {body} (on the phone too) records your words once: the same request id sent again queues nothing more, and answering an answered card under another request is refused. The answer goes into the job's inbox as a line of yours (priority 1; the words also become a user quote), the work item queues and dispatches at once, and the card records the answer and when, its notification resolved. When a stop covers the job, or the conversation the segment ran in, the answer is only held — saved all the same — and no stop is lifted by it; the work goes on after the lift. A card already answered, superseded by a later question, whose segment has not ended yet, whose work is closed, whose Bot is archived, or whose conversation is archived or cleared refuses the answer, and the draft stays on the card. When the job goes on without your answer (a later question, a segment woken by another line ending, the work closing), the card records superseded_at and reads "This work was waiting for your answer", saying it takes no answer any more, with no answer box; its notification is voided (superseded) and no longer counts toward the Dock badge. Opening the database does the same for the cards an older build left behind. An answered card is left as it is. At levels 3 and below blocked posts a plain line.

Nothing goes up that only asks your OK (from 2026-10-04, ADR 0058): from level 3, a blocked ending's needs_from_user and an ask_user question are read once by line reading; read as only asking your OK to go on with what you asked for — a sign-off on work in progress, whether it may start the next step — the end_turn is sent back (asks_go_ahead, one of the ending contract's bounces) and ask_user returns an error (the same code, work log ask.go_ahead_refused), with no card and no notification. The Bot hears that what you want is already said: not to wait for an OK or for you to look first, but to go on, as you look at what it hands over (and can stop it at any time); and to stop only for what you alone can give (an account, a permission, something only you know) or a choice between options that is yours, saying which. Once per segment: stopped or asked again, the question reaches you, unread; and when the contract's two bounces are already spent it reaches you too, never ending the work as needing attention. On 2026-10-04 the video director handed in the keyframe board for 《一拳超人》 and stopped blocked on 「请确认关键帧板(board.jpg)与设定集是否符合预期,确认后将正式启动视频片段生成与后期剪辑」; the card waited two and a half hours for your 「确认」. With no model to read lines, an error or no reading, the question goes to you as before.

Avoid: making the ask an approval card, sending the answer as a separate message from you, adding an "Other" option, changing the answer after answering, answering the card lifting a stop, the app asking you about what it decided for you, what you just said or what goes on by itself

Stop

An immediate stop that you issue. It applies to turns in progress; actions already done are not rolled back. A command still running stops along with everything it started: it is asked to exit, and whatever is still running 3 seconds later is killed. A Stop is not the job going quiet: it does not get the plan organized, and it calls nobody back; an organizing or a second look the job already had lined up is cancelled too. With the UI open, it hits the turn in the current pane (which must be a direct). When several sessions are laid out at once, the current pane is the one that has the keyboard, or the one you last clicked or scrolled in. From the menu bar with no UI open, it hits the turn in the most recently active direct. Until the engine level reaches holds, groups have no Stop; to stop group work, say "stop" in the group (see Control line). Once it has, each Bot's reply being written in a group has a Stop of its own, which stops only that Bot's turn while the other Bots go on, and the menu bar's item becomes "Stop everything" (see Hold); a Stop is also a hold: on that Bot's work in that plan only (on just that turn when it has no plan), so the check-backs it booked are set aside rather than voided and nothing else wakes it back; no receipt goes into the conversation (it stopped the very turn you pressed it on; where it stopped is recorded on the hold); your next line to it about that job — "continue" included; in a group, one naming it, answering it or naming nobody, not one only to another Bot; and not one you sent before pressing Stop — lifts it, and the Bot goes on from that line, with no note of the app's; for a job it was doing where you cannot speak (its direct with another Bot, say), say "continue" in its direct or naming it in a group: filed under that job, it lifts the hold, and the Bot goes on from your line where you said it. Clearing history, archiving, or deleting a group still ends that session's live turns, and is no hold. There is no step-count, roster or group-size circuit breaker.

Avoid: stopping the turns in every pane at once, deciding by the topmost floating pane, stopping only the shell itself

Hold

A stop of yours, recorded as a row of its own rather than as a "parked" label a model can set back. It has a scope — everything, one Bot, one session, one plan, one ticket, one Bot's work in one plan, or one turn — and may carry more it covers, fixed when it was made (the work that Bot handed on and has not had back). Only you lift it, with a line of yours or a button; the record is never deleted, not even by clearing a chat or deleting a group. In the same step it is made, the running turns it covers end (with their commands' processes and MCP calls), and where each had got to is recorded on the hold (the flow board and the status line read that record). A hold on a plan or a session shows the plans it covers as parked, and neither the organizer nor a resume can set them back to In progress; the check-backs it covers are set aside; lifting it puts both back, and each turn it ended starts again on a note. A hold on a Bot, a ticket, a turn or on everything leaves plan status alone. A stop is only "stop for now" (ADR 0071): nothing it covers wakes a Bot by itself — no turn opens, a held Bot's own line wakes nobody, and a call with an effect does not run — but nothing you say or do to a Bot is held: a line, a change to your line, Insert now, Send back, your answer to its question, Continue or Lift make it go on; every stop your word is about is lifted whole, one over more Bots too, though only the Bots you speak to go on (ADR 0081); a line only asking where the work stands releases nobody, and the Bot answers still stopped; only under a hold of the app's does your line open a read-only turn, where the Bot says it is still held; each wake it turns away is recorded in the work log, with the cause and the holds. Triggers in the database add a last layer, so not even an older build opens a turn a hold covers. Besides a line, a stop can come from a stop menu: while a Bot is at work in a group, the menu beside Send offers "Stop the work in this group", "Stop all of X's work", "Stop this job" and "Stop every Bot"; the flow board offers "Stop this job" and "Stop every Bot"; the menu bar offers "Stop everything". Every stop (a Stop on a card, the group menu, "Stop every Bot", the flow board, the tools menu, a "stop" you say) ends with your next line about it, and the Bots that line is said to go on from it, instead of waiting for you to lift it. Stopping and going on are built in, and the conversation gets no line about either (from 2026-10-30, ADR 0101): what was running stops and your next line goes on, and that is all — said, chosen from a menu or pressed alike. A stop leaves no state on screen: above the conversation list are only the stops you dropped a job with by a button, which no line ends, each with a Lift; the flow board lists its job's own parking and the holds that wait to be lifted. Holds exist only once the engine level has reached them (see Schema gate). Details: Behavior · Hold.

Behavior details

From 2026-10-09: a stop is only "stop for now" (ADR 0071). Every stop of yours — Stop on a card, a typed "stop" / "stop X" / "stop every Bot", the group and tools menus, the flow board — does two things: it stops the work it covers now, and until you speak it holds what would start the Bot again by itself (its check-backs, other Bots' lines, job completions, the supervisor's resumes). Nothing you say or do to a Bot is ever held: a line said to it, a change to your line, Insert now, Send back on a hand-over's card, your answer to its question, Continue on an interrupted or restart notice, "continue", Lift in the list — it does it. A stop on that Bot alone is lifted; one over more Bots (everything, a group, a job, a ticket) releases that Bot (effect.released_bots, read by every held check, the database's own triggers included), and the rest stay stopped until you speak to them or lift it; once every Bot it covers is released it is lifted and the plans it parked go back. A line only asking where the work stands ("still at it?") is no go on: the Bot answers it, still stopped. Lift is going on: the stopped work opens again on a note. Where the text below says a stop stays until you lift it, or that your line only opens a read-only turn, that now holds only for the app's own holds (old parked plans taken over at boot) and the one that drops the old job when you open a new one; a line you sent before the stop and no Bot has read yet is held, and Insert now reads it.

From 2026-10-10: a stop is just a stop (ADR 0081). Every stop your word is about is lifted whole, however many Bots it covers: any line to any Bot after "Stop every Bot", any line in a group after its stop, any line about a job after its stop ends it; every covered Bot's check-backs, other Bots' lines and job completions wake again, and parked plans go back. effect.released_bots is no longer written (one an older build wrote is still read until your word lifts the hold). Only the Bots you speak to go on (for "continue", with the job they stopped); the other Bots' stopped turns are not reopened on a note. A stop leaves no state on screen: no stop for now above the conversation list, no "Stopped" on rows, no sleeping avatar; the bar above the list is left for stops you dropped a job with by a button, which no line ends. The flow board lists only its job's own parking and holds that wait to be lifted. Where the text below says "releases", "the rest stay stopped", "all bots continue", "Stopped" in the list or "All go on", this paragraph wins.

P4b resume addition: the scopes, user-only lifts and receipts below remain valid. At level 2 resumed segments obey Bot × plan uniqueness and work slots: an existing same-plan segment hears the line; another plan starts or queues its own. “One Bot works one turn at a time in a group or Bot↔Bot direct” below describes level-0/1 compatibility only and no longer merges another job into that segment. Protected Continue for an interrupted desk is under Desk segment; this change activates no automatic restart supervision.

A stop of yours, recorded as a row. Scope: everything; one Bot (following it into every session it is in); one session (and the plans that session is home to, even where the work goes on in a Bot↔Bot direct — work in that direct is still the group's job); one plan (tickets included); one ticket; one Bot's work in one plan; or one turn (covering the check-backs that turn booked). It may also carry more it covers, fixed when it was made — the directs holding the work that Bot handed on, say — which does not change afterwards. Only you lift it: with a line of yours, or a button; no other caller has a way to lift one, neither a Bot nor the organizer. The record is never deleted: clearing a chat or deleting a group only blanks the line it points at, and the hold itself stays. A plan a hold names (a hold on that plan, on one Bot's work in it or on one of its tickets, or with any of those among its targets, lifted or not) stays when the chat is cleared too, so no hold points at a job that is gone. Deleting a group takes its surviving plans (the ones a turn or a line in another session still belongs to) out of it, and with that out of reach of a hold on the group; so each one that hold keeps parked first gets a plan hold of its own (source migration), carrying how to put it back. So does one stopped the old way before the hold (parked in its status and its spec): lifting its hold puts it back in progress, as the boot import of such plans does. One already under a hold on the plan itself needs none.

When it is made: in the same write that records it, every running turn it covers ends as stopped; once the write is in, the turn's model call, its MCP calls (the server is told the call is cancelled) and its commands' process groups (asked to exit, killed 3 seconds later) are aborted. Where each had got to — the files it wrote, its last few calls — is recorded on the hold (effect.stopped_turns), with the other Bots' turns still working in the same plans that it does not cover (working_beside) and anything it covers still running afterwards (still_running, empty unless something went wrong). A stop you say or press also covers the work the covered Bot handed on and has not had back: a turn of another Bot opened by a line of a covered turn — or by a line of such a turn, up to three handoffs down — that is still running or still has a check-back to come. Each becomes a target on that one turn, which covers the turn, what it booked and whom its lines would wake, and not the other Bot's own work; nothing upstream is stopped. A read-only turn a hold let open is left to finish its answer. The work log gets a control.hold row.

Plan status: a hold on a plan or a session sets the in-progress plans it covers to parked, in the status and in the spec's status both — the flow board sends the spec's status back with every edit, and the organizer revises the spec too, so changing only one of them would get the plan set back to In progress. The plan stays the session's current plan: it is stopped, not pushed aside by another job. A plan already pushed out of the current slot by a newer one (parked in its status, In progress in its spec) has its spec set to parked as well, and lifting puts it back to being pushed aside — In progress in its spec, parked in its status — rather than In progress, so that a plan out of the slot is not called back to work. While the hold stands, the organizer or a resume asking for In progress leaves it parked and only notes that lifting the hold should bring it back; one pushed out of the current slot meanwhile by a plan opened or resumed there goes back to being pushed aside when the hold is lifted; a plan opened in that session is parked from the start; marking it Done still goes through. Setting the spec to parked and setting it back on the lift are each a version of the spec: a flow board still on the version before has its edit refused (409 revision_conflict) instead of sending back the status the hold just changed — undoing the stop, or stopping again after the lift. Neither version counts as yours or as organizing: the organizer still reads what was said before the stop, and the revision history marks both cause: "hold". Lifting the hold puts it back as it was, and back into the session's current slot if that is free; if another hold on the plan or its session still has it, it stays parked, and that one keeps the note of how to put it back. A hold on a Bot, a ticket or a turn leaves plan status alone, and the plan's other Bots carry on; one on everything leaves it alone too (it would otherwise rewrite every plan there is), and a plan's held_by lists the holds over the plan as a whole (on the plan, on its session, on everything).

The old way of setting status: once the engine level has reached holds, setting a plan's status to parked (PATCH /v1/tasks/:id/spec, as older clients and the phone do) is a hold on that plan; setting it back to In progress, or marking it Done, lifts the holds on that plan. With a hold on its session or on everything still standing, setting it back to In progress leaves it parked (the session's) or as it was (everything's), and held_by says which. Whether an edit sets the status is judged against the spec's status, which is what the flow board shows and sends back: an edit of only the goal sends it back unchanged and neither stops nor resumes anything. A plan pushed aside reads parked in its status column and In progress in its spec, so judging by the column would take such an edit for a resume. Below that level, parked is only the status.

Check-backs: a pending check-back a hold covers is set aside, and marked voided at the same time so that an older build that knows nothing of holds never fires it; one booked while the hold stands is set aside too. Once lifted, with no other hold over it, it is pending again, and one whose time has already passed fires once shortly after. If, while it is set aside, the session is cleared or deleted, the Bot is deleted, or — before holds are on — the turn that booked it is Stopped, it is voided for good and lifting does not bring it back; at levels 0–2 another booking in the same session replaces the old one; at level 3 only a timer of the same exact work-item/dedupe key replaces it, never an unrelated job or delegation event wait.

Wakes and tools: nothing a hold covers is woken. Your line (it opens only a read-only turn, below), another Bot's line (naming it, or any line in a Bot↔Bot direct), a check-back of its coming due, the report-back when a Bot↔Bot direct it opened goes quiet, a quiet plan's call-back, a routine coming due, Continue on an interrupted turn: none opens a turn, and a running turn a hold covers hears no new line either: one about work beside the hold opens a turn of its own next to it, without cutting the held one off, and one of yours in another conversation that is filed under the job does not reach it. A held Bot's own line wakes nobody, and a Bot↔Bot direct whose other side is held calls nobody back when it goes quiet; nothing is kept for later, since that side's next turn in the direct after the lift makes it go quiet again, and that calls the opener back. When you say something in a group without naming anyone, a held Bot is not asked whether it is its to answer (that judgement call is not made). Each wake a hold turns away is recorded in the work log (wake.suppressed in work_events), with what would have woken the Bot — your line, a Bot's line, a check-back, a plan call-back, a routine, a Continue — and which holds turned it away. A check-back turned away is set aside and comes back when the hold is lifted, and so is the report-back to a held Bot that opened the direct. Lines a running turn heard but ended without reading are put to the holds one by one: each one about held work is recorded as a wake turned away and stays in the transcript for after the lift, and the newest check-back among them is set aside to fire then; the rest open one more turn on the newest of them as usual, and only those ride along into it; a quiet plan's call-back is not kept, and the plan is looked at again the next time a turn on it ends and it goes quiet; a routine that comes due is recorded once, counts as not yet run, and runs once for its latest due time after the lift; Continue answers 409 held, and the phone gets the same code. A turn a hold covers makes no call with an effect — each comes back held without running: the shell, writing or deleting files, sending a message, booking a check-back, asking you a question, changing a profile, skills, memories, routines, endpoints or MCP servers, and any MCP tool not marked read-only. Reading still works (reading files, listing folders, the list_* tools, read_skill, end_turn, and MCP tools their server marks readOnlyHint, such as looking up a video job). A call that was waiting on your approval does not run either if the hold came before you allowed it. The database adds a last layer: triggers on the turns table refuse to write a live turn a hold covers — including a row with no mode written by an older build that knows nothing of holds, since a stop comes before compatibility — and refuse moving a live turn into a hold's cover in place or changing its mode. The one turn they let through is the read-only one a line of yours opens (mode = readonly): a line of yours to a held Bot — in its direct, or naming it in a group — opens one beside whatever it was doing, bound to no plan, shown only the tools that change nothing, and opening on a line that says you stopped this work (with your words), that this turn can only answer, and, if you told it to go on, to say plainly that your stop still holds, not that it is going on. Its reply is posted as usual and wakes nobody; another Bot naming it meanwhile opens a turn beside it, not cutting it off. When such a turn ends without a word (an empty reply after reading files, or a bare end_turn), the app no longer answers in its place with a status line (from 2026-10-09, ADR 0070: the app does not speak for a Bot). That line came in on 2026-10-03: after the group was stopped, "start over from scratch, scrap what came before" got a read-only turn that read files for nine hops and replied with nothing, and the group showed nothing at all.

Your lines: whether a line stops or goes on is the reader's (a model's) to say (from 2026-10-09, ADR 0070). The control line's fixed rules (see Control line in CONTEXT) no longer read first or carry anything out; they keep one use, which carries nothing out: the scope the words name (who "you" is, every Bot, this job). When the reader cannot read the line — none set, an error, a timeout, so the word lists read it — nothing is carried out and the line goes to the Bot as said; for a stop that cannot wait there is the composer's Stop button. The reading starts as the line arrives, not after the lines still being read before it, so a line read as nothing but a stop still goes ahead of them (ADR 0063's order holds for the rest). The fixed rules used to read first: on the morning of 2026-10-09, 「继续」 in 视频导演's direct was taken for a pure go on and carried out before it was read or filed — lifting an old stop on 视频导演's 《一拳超人》 work from 16:59, which could not start again, while nothing moved on the MV and the line never reached the Bot.

  • A stop: a line read as nothing but a stop ("you haven't stopped" too: a stop again) goes nowhere else — no filing, no turn. It makes a hold per scope it names (source user_text, the line as its source_message_id), and nothing is said in the conversation (from 2026-10-30, ADR 0101): what was running stopping is the answer, and your next line goes on. The hold still records the turns ended, each with its plan, its conversation and its last step; the check-backs set aside; the plans parked; the other Bots still working in those plans (effect), for the flow board. The app used to post a receipt in the conversation you said it in: a system line kept from the Bots, carrying control: {kind: "receipt", verb: "stop", hold_ids, offer, scopes} for its buttons (undo; stop every Bot; drop the job, when you said 算了 with it), listing all that and what was running. On 2026-10-30, looking at one in 开发助手's direct — 「已停下开发助手的全部工作……挂起 1 个回看,继续时恢复。此刻在跑:无。你再对它说话,它就从你这句接着往下」 — you said stopping and resuming are built in and implicit, and should show no such notice.
  • A go on: a line read as one — 「继续」 alone, or with more in it like 「继续做第二集,……」 — is not carried out by the app and gets no receipt: the Bot that goes on says so. It is filed first, and then the stops that keep the Bots it is said to from the job it is filed under go: on the Bot, on its work in that job or on that ticket, on one of its turns; this conversation's own stop, and a job you stopped from here, only when the line is said to every Bot here (always, in a direct). A stop on any other job stays; only words that name everything (「所有 Bot」「全都」) lift every stop you made before the line, a Stop pressed anywhere included. A line filed under no job lifts only stops on the Bot as a whole. The line then wakes the Bot like any line, and the Bot goes on from it and answers you itself: said in your direct, it goes on there, and its stopped work on that job in another conversation does not open beside it (a Claude Code Bot starts a fresh session here and reads back the other one's work from the records). Stopped work of a lifted stop that the line did not wake the Bot to opens again where it was, on a note for that Bot alone (below). With nothing held, a go on is an ordinary line. A stop that still holds (one on everything; a whole group or job stopped elsewhere; the group or the job here, when the line is said to only some of the Bots) stays, for its buttons: the Bot can only read and answer the line, and is told the stop still holds and not to say it is going on. A go on used to be carried out by the fixed rules, lifting the holds the words named — for a Bot, its holds on every job, its work a Stop held elsewhere included — with a receipt, or a status line when something wider held it; that is how 2026-10-09's 「继续」 landed on another job.
  • Opening again: each turn a lifted stop ended (lifted by a line or a button) opens again in its conversation, on a system line with your words, its plan and ticket, the files it wrote and its last calls; the line says what happened and asks for nothing. It is the app's note to that Bot and, like a check-back's own line, for that Bot alone: only the turn it wakes, or is heard in, reads it, and the flow board still draws that turn picking up from the one the stop ended; the conversation, the phone, other Bots, the organizer, search, unread counts and the conversation list's last line never show it. In a direct with you it opens beside whatever the Bot took up there meanwhile; in a group or a Bot↔Bot direct, where a Bot works one turn at a time, a turn it already has there hears the line instead (a read-only one answering you does not). One the Bot has since taken up there does not open again. One another hold still covers does not either: it is handed to that hold (held_over) — to one that is not a Stop's, when there is one — and opens when that one is lifted. What you said to it while it was stopped got only a read-only answer, which cannot act: those lines are kept on the hold that held it (effect.answered_lines) and handed back when it is lifted — per Bot, conversation and job, the last of them opens the Bot's turn as it would have with nothing stopped, and the turn reads the others above it; a Bot whose stopped work opened again in that conversation reads them there; one another hold still covers keeps them on that hold until that one is lifted. Before, the read-only answer was the end of it: on 2026-10-04, 「片尾的 logo 再大一点」 ("make the logo at the end bigger") said under a stop got "I'll enlarge it and render again once you say continue", and the go on opened nothing (the job had been approved, with no stopped turn to open again), so the logo stayed small.
  • "Has it stopped?", 「怎么还在跑」 ("why is it still running?"), "can it stop?" and a status question are lines for the Bot (from 2026-10-09): into its inbox, read at its next step without cutting it off, when it is working, or waking it when it is not, and it answers. The app used to answer them from what was running (control.kind status): each hold over what was asked about with the line that made it, what of it was running now, and a stop button when nothing was held; first, anything still running under one of those holds was ended and recorded as a violation (effect.violations, hold.violation in the work log) — a status line a button brings (see Buttons below) still makes that check, and there should never be any.
  • A line read as a stop beside other words (「先停,把第三镜换成夜景」 "stop, and make shot 3 a night scene"), or as both (「今天先停,明天继续」 "stop for today, go on tomorrow"), is delivered as usual and carries control: {kind: "possible_control", offer, scopes} for the buttons; nothing in it is carried out: Stop on the first, Stop and Continue on the second; Continue is offered only while a stop it would lift holds what the line names, and once its stops are lifted the messenger stops showing it. A go on with more in it carries none and is a go on as above; one read as no control, or not read at all, carries none. 算了 / 不做了 / 取消 on its own no longer carries buttons: it is a line for the Bot.

Stop on a turn's card: once holds are on, it is a hold — in a direct it is the stop button in the composer (beside Send while its Bot has a turn going in that conversation; where the conversation is as narrow as a phone and the box holds nothing to send, Send, which could do nothing, is not drawn and Stop takes its place, with Send back beside it once you type; a tap on it within 0.6 s of a send does not count, being most likely the second tap of a double tap on Send; a direct has just this one stop, no menu and none on the reply's header). Stopping lives in the composer: a group's replies carry no Stop; to stop one Bot there, pick "Stop all of X’s work" in the stop menu beside Send, which stops only that Bot while the other Bots go on (see the stop menus below; ADR 0040 P2 overturns ADR 0016's no Stop in groups, and first put a Stop on each Bot's reply header, removed on 2026-10-06). A direct's stop button holds that Bot's work in the turn's plan (on the turn alone when it has none), source user_button, lifted by your next line (lift_on_next_user_message). The turn ends under it as above and the check-backs it booked are set aside instead of voided; no receipt goes into the conversation (from 2026-10-04, ADR 0058): it stopped the very turn you pressed it on, your next line lifts it, and the receipt with its Undo only repeated what you had just done. Where the turn stopped is recorded on the hold (effect), and the flow board marks the turn "Stopped". Your next line about that job — filed under that plan, or landing on it — lifts it before it wakes anyone, and the Bot goes on from that line; nothing opens again on a note, since Stop meant "not this". Said anywhere but its direct with you (in a group, say), only a line said to that Bot counts: one naming it (a reply to its line carries its name), naming everyone, or naming nobody in a group it is in; a line only to another Bot about the same job leaves the Stop, and the check-backs it set aside, where they are, so no check-back calls the Bot back into the job before you have said a word to it. Only a line said after the Stop counts: one sent just before, still being filed when you pressed it, does not. "Continue" on its own is such a line. A "continue" to that Bot said elsewhere lifts it too when it is filed under that job, and the Bot goes on from it where you said it; one filed under another job, or under none, does not (from 2026-10-09, above). A line that reads like control and carries the buttons, or a hold of any other scope, never lifts it that way.

Buttons: the buttons on a line the app read or wrote about your stops (control) are pressed once per line: the press is recorded in control.acted, the line then only says what was done, and pressing again (a double tap, a request the phone resends) does nothing. The lines the app writes itself — receipts from before 2026-10-30 (none is written since, above), the status lines a button brings (control.kind status), the line after a restart — show in the conversation as the app's: the Deskfolk mark where a face would be and "Deskfolk" with an "App" tag, not the face and name of the Bot the line is filed under, and a screen reader reads them as "Message from the Deskfolk app"; their buttons stay under them. Its answer to a status question went on 2026-10-09; old ones still show this way. The buttons on a line of yours stay under your line.

  • An older stop's receipt: Undo lifts its holds by button and the work they ended starts again on a note (so did a Stop's, when a Stop still had a receipt) — undo means as if it had not been pressed; when the stop came from a line of yours, that line then goes on as any line (filed, waking whom it wakes, as if it had never been read as a stop, and not read for control again); when that line was said in your direct with a Bot, the work stopped there does not start again on a note, and the line is what reaches the Bot: a line of yours there always opens its turn, so starting the work again as well would have the Bot at it twice. In a group the line wakes only whom it names (with nobody named and nobody still at work, each Bot only makes a judgement on it), so the work stopped there starts again on a note all the same, and the line then goes to the Bots as any line of yours in the group would. "Stop every Bot" makes a hold on everything. "Stop “…” too" makes a plan hold on the plan other Bots were still working in when the stop was made (the plans in effect.working_beside). "Only “…”" first makes, for each hold on a whole Bot in the receipt, a hold on that Bot's work in that plan (quoting the same line), then lifts the hold on the Bot: its work stopped elsewhere starts again on a note, and its work in that plan is handed to the new hold. One button per plan, three at most; the same for "Stop … too". "Drop this job" records the receipt's holds in force as dropping the job (action: cancel): they hold as before, and lifting one reopens the job; really dropping a job waits for work items.
  • "Only X goes on" on a status line or an older receipt of a lift by button (only a button brings these lines now; a go on you say gets none): each wider hold in the way is first split into one per other Bot, quoting the line that made it — one on everything into a hold on each Bot; one on a plan into each Bot's work in that plan; one on a conversation into each Bot's work in the plans it parked and the conversation's current plan, plus a turn hold on each other Bot's turn it stopped off those plans — and then lifted along with X's own holds: X's work starts again on a note, the others' is handed to the split holds. "All go on" lifts everything in the way. Neither posts a line (from 2026-10-30); an older receipt names the holds these buttons are about in held_ids.
  • On a line of yours: "Stop" makes the stop the line meant (source user_button, source_message_id the line), with no receipt; "Drop" the same, recorded as dropping the job (no longer offered from 2026-10-09; it stays on lines like 算了 from before); "Continue" (offered only on a line read as both) still goes by the old rule: it lifts what it can over the scope the line names — for a Bot, its holds on every job — the stopped work opening again on a note, with no line posted; it posts a status line when something wider holds it, and does nothing when nothing is held; ADR 0070 has not changed this one yet. "Stop" on an older status line stops what was asked about.

Stop menus and the list: while a Bot is at work in a group — or in a Bot↔Bot direct opened from it (what the lead handed on, and on down), which the group's stop holds anyway — a stop menu sits beside Send: "Stop the work in this group", each Bot at work there, "Stop this job" and "Stop every Bot"; a choice a hold in force already covers is left out. The first three go, like a Stop on a card, with your next line about them (lift_on_next_user_message), and the Bots go on from that line with no note: for the group, any line you say in it afterwards; for a Bot, a line said to it, wherever (as for a Stop: anything in its direct, in a group naming it, everyone, or nobody); for the job, a line that lands on it. "@X continue" in the group is such a line: the group's hold goes, only X's stopped work starts again on a note, and the other Bots' stopped work stays stopped, as if you had said a line to X alone. A line naming nobody is said to the whole group: it wakes whom it always wakes (the lead, when there is one), and the work the lifted holds stopped that it does not reach — a Bot's part done in its direct with the lead, say — starts again too, on a note with your words, and gets your line as an item of its inbox to answer for. Before, such a line woke only the lead: on the 2026-10-04 walkthrough the group was stopped while 文案 wrote slogans in its direct with 设计师, and after 「宣传语改成英文的,海报改横版」 it stayed stopped, never heard the line, and was called back by the supervisor three minutes later to "answer" the old request. (From 2026-10-30 nothing is said in the conversation; a receipt used to end by saying so: "Say anything more in this group and the stop is over; …".) It ends with your next line because before, a new instruction after the stop ("start over") got only a read-only answer, and the banner stayed up until you lifted it by hand long after the Bots had stopped. "Stop every Bot" works the same way since 2026-10-10 (ADR 0081): a line to any Bot ends it. A direct has no such menu, only the Stop above: it stops that turn and your next line lifts it; the menu bar's "Stop everything", the flow board's "Stop this job" and a typed "stop" are stops for now too — no stop waits for you to lift it any more. The flow board's title row offers "Stop this job" and "Stop every Bot". The tools menu has no stop (its "Stop everything" went on 2026-10-11, a repeat of "Stop every Bot" in the stop menus and on the flow board); the menu bar's "Stop everything" makes a hold on everything — on the turns that would start, not only those running, so it can be pressed with no Bot at work — and against a daemon that has no holds yet stops the latest live turn in a direct as before. A stop from a menu goes through POST /v1/holds with the menu's conversation, recorded in the work log, with no receipt. A lift the daemon refuses says "That did not work; try again" where it was pressed; with the daemon out of reach these buttons show but cannot be pressed. The stops you dropped a job with by a button, which no line ends, are listed above the conversation list: the scope, the time, "Dropped", each with a Lift (by button — going on; see API); a stop for now is not listed, and no row is marked (since 2026-10-10, ADR 0081). The flow board lists under its title the plan's own parking and the holds over its job that wait to be lifted — on a Bot's work in it, on its conversation, on everything — each with a Lift. When a hold is made or lifted, an open flow board reads its plan again, so the next edit starts from the version the hold wrote and is not refused with 409; on a 409 all the same it reads the plan again as before. The plan's footer and history mark the versions a hold wrote as "by a stop" (a revision's cause: "hold", the plan's revision_cause). All of this needs a daemon at the holds level: it appears only when the snapshot has holds.

At boot: once the engine level has reached holds, every boot checks again. A plan parked before holds existed — status and spec's status both parked, which is how you or the organizer stopped one — becomes a plan hold of source legacy, so from then on only you can put it back in progress; a plan only pushed out of the current slot by a newer one (its spec still says In progress) is left alone. Then any plan a hold covers that is not parked, and any check-back it covers that is not set aside, is put right, and daemon.log says so.

API: GET /v1/holds (holds in force by default, ?status=all for lifted ones too, newest first), GET /v1/holds/:id, POST /v1/holds (a stop you make from a button or a menu, recorded as user_button; the turns it covers end at once, as above), POST /v1/holds/:id/lift (the turns it ended open again as with a go on, a Stop's excepted; one already lifted comes back unchanged), POST /v1/messages/:id/control (the buttons above: {action, task_id?}, task_id naming the plan for "Stop … too" and "Only …"; returns {made, lifted}; 422 for a line with no buttons or without that one); the phone can do the same. POST /v1/holds takes an optional session_id: the menu's conversation, recorded on the work log's control.hold (before 2026-10-30 the receipt went there). The snapshot's holds are the holds in force, newest first, absent before the holds level; a hold's plan_title is the title of the plan it names. Parking a plan with PATCH /v1/tasks/:id/spec ends what runs in it the same way. POST /v1/turns/stop is the Stop above. A line the app read or wrote about your stops carries control (MessageControl). Making a hold, lifting it and recording what it did each reach clients as a hold.upsert event. A plan's held_by is as of when it was read: a hold that changes nothing on the plan's row, such as one on everything, sends only hold.upsert when it is made and when it is lifted, so a client that shows held_by reads the plan again on that event.

Avoid: taking parked for the hold itself, a Bot or the organizer lifting a hold, deleting a hold, parking a whole plan because one Bot in it was stopped, clearing holds with the chat history, a held Bot woken by another Bot, a check-back or a routine, letting a held turn run a command or send a message, letting a running turn finish its step after a stop, a stop still on after you gave a new instruction so it only gets a read-only answer, a stop left in the list for you to Lift, a receipt in the conversation saying what a stop or a go on did, a status question setting the Bot going, the app speaking for a held Bot

Control line

A line of yours that line reading (a model) reads as nothing but a stop ("stop", "stop what you're generating", "stop all your work"; "you haven't stopped" too, a stop again) is carried out by the app there and then: the hold is made and the running turns it covers end, with no turn and no organizer; a line read as a go on ("continue" alone, or with more in it like "continue with episode 2, …") is not carried out by the app: it is filed under the job it is about, lifts the stops that keep the Bots it is said to from that job, and goes to the Bot like any line, which goes on from it and answers you itself. Whether a line stops or goes on is the reading's alone (from 2026-10-09, ADR 0070): the fixed rules no longer read first or carry anything out, and only give the scope the words name; when the reader cannot read the line (none set, an error, a timeout, so the word lists read it), nothing is carried out and the line goes to the Bot — for a stop that cannot wait, press the composer's Stop button. The reading starts as the line arrives, so a line read as nothing but a stop still goes ahead of lines still being read. A "stop" in a script, a line or a picture ("Reviewer: stop"), a condition ("stop if it gets stuck") or a request about the work ("don't pad it with frozen frames again") is none; a question asking it to stop ("can you stop for a moment?") is a stop, while asking whether it stopped or can stop ("has it stopped?", "why is it still running?", "can it stop?") is a line for the Bot; a Bot's name without an @ counts as said to it only when a comma, "you" or "too" follows it. Once the app has carried it out it writes no receipt (ADR 0101): which turns it ended and where each had got to, how many check-backs it set aside, which plans it parked and who is still working beside it in the job are recorded on the hold. Where it applies comes from the words and the place: in a direct, the Bot on the other side, with the work it handed on and has not had back (three handoffs down); in a group with nobody named, the group; with a singular "you", the Bot you are answering (or the only one that spoke to you in the last ten minutes) and the group; each Bot named; "all Bots" or "stop, all of it", everything, routines too — unless the line also says "you", names a Bot, says in the group or in the direct, or says "this job", which wins as the narrower scope. "Continue" lifts only stops on the job it is filed under: on the Bot, on its work in that job or ticket, on one of its turns; this conversation's own stop, and a job you stopped from here, only when it is said to every Bot here; a stop on any other job stays, and only "all Bots" or "all of it" lifts every stop you made before it (Stops you pressed included); filed under no job, it lifts only stops on the Bot as a whole. Said in your direct, the Bot goes on there; stopped work the line did not wake it to starts again where it was, on a note for that Bot alone (your words, what it was doing) that the conversation does not show. With nothing held it is an ordinary line; after a Stop it is the next line about the job that lifts the Stop's hold; one said to a Bot leaves the other Bots' Stops alone; a stop that still holds (everything; a whole group or job stopped elsewhere) stays, and the Bot can only answer read-only, told the stop still holds and not to say it is going on; a stop from a group's stop menu goes with your next line in the group, "@X continue" included, and only the Bots it names start again on a note. A go on gets no receipt: the Bot that goes on says so. A line read as a stop beside other words ("stop, and make shot 3 a night scene") goes to the Bot as usual, carrying only a Stop button, and one read as both also Continue (which still lifts by the old rule); a go on with more in it, and "never mind" alone, carry none. Each button is pressed once (receipts are no longer written from 2026-10-30; the buttons on those already written still work): Undo on a receipt lifts that stop, the stopped work starts again, and a line that was read as the stop goes to the Bot as the line it was (in your direct with the Bot, that line is what reaches it, not a second turn beside the stopped one; in a group the line wakes only whom it names, so the stopped work starts again all the same); "Stop every Bot"; "Stop “…” too" stops the plan other Bots were still working in; "Only “…”" narrows a stop on all of a Bot's work to that one job, and the rest of its work starts again on a note; "Drop this job" records the stop as dropping the job, and lifting it reopens the job. On a status line or receipt a button brings, "Only X goes on" splits the wider hold in its way into one per other Bot and lets only X go; "All go on" lifts that hold too. "Stop" on a line with buttons makes the stop that line meant, recorded with that line, and again with no receipt. Exists only once the engine level has reached holds. Details: Behavior · Hold.

Behavior details

From 2026-10-09: a stop is only "stop for now" (ADR 0071). Every stop of yours — Stop on a card, a typed "stop" / "stop X" / "stop every Bot", the group and tools menus, the flow board — does two things: it stops the work it covers now, and until you speak it holds what would start the Bot again by itself (its check-backs, other Bots' lines, job completions, the supervisor's resumes). Nothing you say or do to a Bot is ever held: a line said to it, a change to your line, Insert now, Send back on a hand-over's card, your answer to its question, Continue on an interrupted or restart notice, "continue", Lift in the list — it does it. A stop on that Bot alone is lifted; one over more Bots (everything, a group, a job, a ticket) releases that Bot (effect.released_bots, read by every held check, the database's own triggers included), and the rest stay stopped until you speak to them or lift it; once every Bot it covers is released it is lifted and the plans it parked go back. A line only asking where the work stands ("still at it?") is no go on: the Bot answers it, still stopped. Lift is going on: the stopped work opens again on a note. Where the text below says a stop stays until you lift it, or that your line only opens a read-only turn, that now holds only for the app's own holds (old parked plans taken over at boot) and the one that drops the old job when you open a new one; a line you sent before the stop and no Bot has read yet is held, and Insert now reads it.

From 2026-10-10: a stop is just a stop (ADR 0081). Every stop your word is about is lifted whole, however many Bots it covers: any line to any Bot after "Stop every Bot", any line in a group after its stop, any line about a job after its stop ends it; every covered Bot's check-backs, other Bots' lines and job completions wake again, and parked plans go back. effect.released_bots is no longer written (one an older build wrote is still read until your word lifts the hold). Only the Bots you speak to go on (for "continue", with the job they stopped); the other Bots' stopped turns are not reopened on a note. A stop leaves no state on screen: no stop for now above the conversation list, no "Stopped" on rows, no sleeping avatar; the bar above the list is left for stops you dropped a job with by a button, which no line ends. The flow board lists only its job's own parking and holds that wait to be lifted. Where the text below says "releases", "the rest stay stopped", "all bots continue", "Stopped" in the list or "All go on", this paragraph wins.

P4b resume addition: the scopes, user-only lifts and receipts below remain valid. At level 2 resumed segments obey Bot × plan uniqueness and work slots: an existing same-plan segment hears the line; another plan starts or queues its own. “One Bot works one turn at a time in a group or Bot↔Bot direct” below describes level-0/1 compatibility only and no longer merges another job into that segment. Protected Continue for an interrupted desk is under Desk segment; this change activates no automatic restart supervision.

A stop of yours, recorded as a row. Scope: everything; one Bot (following it into every session it is in); one session (and the plans that session is home to, even where the work goes on in a Bot↔Bot direct — work in that direct is still the group's job); one plan (tickets included); one ticket; one Bot's work in one plan; or one turn (covering the check-backs that turn booked). It may also carry more it covers, fixed when it was made — the directs holding the work that Bot handed on, say — which does not change afterwards. Only you lift it: with a line of yours, or a button; no other caller has a way to lift one, neither a Bot nor the organizer. The record is never deleted: clearing a chat or deleting a group only blanks the line it points at, and the hold itself stays. A plan a hold names (a hold on that plan, on one Bot's work in it or on one of its tickets, or with any of those among its targets, lifted or not) stays when the chat is cleared too, so no hold points at a job that is gone. Deleting a group takes its surviving plans (the ones a turn or a line in another session still belongs to) out of it, and with that out of reach of a hold on the group; so each one that hold keeps parked first gets a plan hold of its own (source migration), carrying how to put it back. So does one stopped the old way before the hold (parked in its status and its spec): lifting its hold puts it back in progress, as the boot import of such plans does. One already under a hold on the plan itself needs none.

When it is made: in the same write that records it, every running turn it covers ends as stopped; once the write is in, the turn's model call, its MCP calls (the server is told the call is cancelled) and its commands' process groups (asked to exit, killed 3 seconds later) are aborted. Where each had got to — the files it wrote, its last few calls — is recorded on the hold (effect.stopped_turns), with the other Bots' turns still working in the same plans that it does not cover (working_beside) and anything it covers still running afterwards (still_running, empty unless something went wrong). A stop you say or press also covers the work the covered Bot handed on and has not had back: a turn of another Bot opened by a line of a covered turn — or by a line of such a turn, up to three handoffs down — that is still running or still has a check-back to come. Each becomes a target on that one turn, which covers the turn, what it booked and whom its lines would wake, and not the other Bot's own work; nothing upstream is stopped. A read-only turn a hold let open is left to finish its answer. The work log gets a control.hold row.

Plan status: a hold on a plan or a session sets the in-progress plans it covers to parked, in the status and in the spec's status both — the flow board sends the spec's status back with every edit, and the organizer revises the spec too, so changing only one of them would get the plan set back to In progress. The plan stays the session's current plan: it is stopped, not pushed aside by another job. A plan already pushed out of the current slot by a newer one (parked in its status, In progress in its spec) has its spec set to parked as well, and lifting puts it back to being pushed aside — In progress in its spec, parked in its status — rather than In progress, so that a plan out of the slot is not called back to work. While the hold stands, the organizer or a resume asking for In progress leaves it parked and only notes that lifting the hold should bring it back; one pushed out of the current slot meanwhile by a plan opened or resumed there goes back to being pushed aside when the hold is lifted; a plan opened in that session is parked from the start; marking it Done still goes through. Setting the spec to parked and setting it back on the lift are each a version of the spec: a flow board still on the version before has its edit refused (409 revision_conflict) instead of sending back the status the hold just changed — undoing the stop, or stopping again after the lift. Neither version counts as yours or as organizing: the organizer still reads what was said before the stop, and the revision history marks both cause: "hold". Lifting the hold puts it back as it was, and back into the session's current slot if that is free; if another hold on the plan or its session still has it, it stays parked, and that one keeps the note of how to put it back. A hold on a Bot, a ticket or a turn leaves plan status alone, and the plan's other Bots carry on; one on everything leaves it alone too (it would otherwise rewrite every plan there is), and a plan's held_by lists the holds over the plan as a whole (on the plan, on its session, on everything).

The old way of setting status: once the engine level has reached holds, setting a plan's status to parked (PATCH /v1/tasks/:id/spec, as older clients and the phone do) is a hold on that plan; setting it back to In progress, or marking it Done, lifts the holds on that plan. With a hold on its session or on everything still standing, setting it back to In progress leaves it parked (the session's) or as it was (everything's), and held_by says which. Whether an edit sets the status is judged against the spec's status, which is what the flow board shows and sends back: an edit of only the goal sends it back unchanged and neither stops nor resumes anything. A plan pushed aside reads parked in its status column and In progress in its spec, so judging by the column would take such an edit for a resume. Below that level, parked is only the status.

Check-backs: a pending check-back a hold covers is set aside, and marked voided at the same time so that an older build that knows nothing of holds never fires it; one booked while the hold stands is set aside too. Once lifted, with no other hold over it, it is pending again, and one whose time has already passed fires once shortly after. If, while it is set aside, the session is cleared or deleted, the Bot is deleted, or — before holds are on — the turn that booked it is Stopped, it is voided for good and lifting does not bring it back; at levels 0–2 another booking in the same session replaces the old one; at level 3 only a timer of the same exact work-item/dedupe key replaces it, never an unrelated job or delegation event wait.

Wakes and tools: nothing a hold covers is woken. Your line (it opens only a read-only turn, below), another Bot's line (naming it, or any line in a Bot↔Bot direct), a check-back of its coming due, the report-back when a Bot↔Bot direct it opened goes quiet, a quiet plan's call-back, a routine coming due, Continue on an interrupted turn: none opens a turn, and a running turn a hold covers hears no new line either: one about work beside the hold opens a turn of its own next to it, without cutting the held one off, and one of yours in another conversation that is filed under the job does not reach it. A held Bot's own line wakes nobody, and a Bot↔Bot direct whose other side is held calls nobody back when it goes quiet; nothing is kept for later, since that side's next turn in the direct after the lift makes it go quiet again, and that calls the opener back. When you say something in a group without naming anyone, a held Bot is not asked whether it is its to answer (that judgement call is not made). Each wake a hold turns away is recorded in the work log (wake.suppressed in work_events), with what would have woken the Bot — your line, a Bot's line, a check-back, a plan call-back, a routine, a Continue — and which holds turned it away. A check-back turned away is set aside and comes back when the hold is lifted, and so is the report-back to a held Bot that opened the direct. Lines a running turn heard but ended without reading are put to the holds one by one: each one about held work is recorded as a wake turned away and stays in the transcript for after the lift, and the newest check-back among them is set aside to fire then; the rest open one more turn on the newest of them as usual, and only those ride along into it; a quiet plan's call-back is not kept, and the plan is looked at again the next time a turn on it ends and it goes quiet; a routine that comes due is recorded once, counts as not yet run, and runs once for its latest due time after the lift; Continue answers 409 held, and the phone gets the same code. A turn a hold covers makes no call with an effect — each comes back held without running: the shell, writing or deleting files, sending a message, booking a check-back, asking you a question, changing a profile, skills, memories, routines, endpoints or MCP servers, and any MCP tool not marked read-only. Reading still works (reading files, listing folders, the list_* tools, read_skill, end_turn, and MCP tools their server marks readOnlyHint, such as looking up a video job). A call that was waiting on your approval does not run either if the hold came before you allowed it. The database adds a last layer: triggers on the turns table refuse to write a live turn a hold covers — including a row with no mode written by an older build that knows nothing of holds, since a stop comes before compatibility — and refuse moving a live turn into a hold's cover in place or changing its mode. The one turn they let through is the read-only one a line of yours opens (mode = readonly): a line of yours to a held Bot — in its direct, or naming it in a group — opens one beside whatever it was doing, bound to no plan, shown only the tools that change nothing, and opening on a line that says you stopped this work (with your words), that this turn can only answer, and, if you told it to go on, to say plainly that your stop still holds, not that it is going on. Its reply is posted as usual and wakes nobody; another Bot naming it meanwhile opens a turn beside it, not cutting it off. When such a turn ends without a word (an empty reply after reading files, or a bare end_turn), the app no longer answers in its place with a status line (from 2026-10-09, ADR 0070: the app does not speak for a Bot). That line came in on 2026-10-03: after the group was stopped, "start over from scratch, scrap what came before" got a read-only turn that read files for nine hops and replied with nothing, and the group showed nothing at all.

Your lines: whether a line stops or goes on is the reader's (a model's) to say (from 2026-10-09, ADR 0070). The control line's fixed rules (see Control line in CONTEXT) no longer read first or carry anything out; they keep one use, which carries nothing out: the scope the words name (who "you" is, every Bot, this job). When the reader cannot read the line — none set, an error, a timeout, so the word lists read it — nothing is carried out and the line goes to the Bot as said; for a stop that cannot wait there is the composer's Stop button. The reading starts as the line arrives, not after the lines still being read before it, so a line read as nothing but a stop still goes ahead of them (ADR 0063's order holds for the rest). The fixed rules used to read first: on the morning of 2026-10-09, 「继续」 in 视频导演's direct was taken for a pure go on and carried out before it was read or filed — lifting an old stop on 视频导演's 《一拳超人》 work from 16:59, which could not start again, while nothing moved on the MV and the line never reached the Bot.

  • A stop: a line read as nothing but a stop ("you haven't stopped" too: a stop again) goes nowhere else — no filing, no turn. It makes a hold per scope it names (source user_text, the line as its source_message_id), and nothing is said in the conversation (from 2026-10-30, ADR 0101): what was running stopping is the answer, and your next line goes on. The hold still records the turns ended, each with its plan, its conversation and its last step; the check-backs set aside; the plans parked; the other Bots still working in those plans (effect), for the flow board. The app used to post a receipt in the conversation you said it in: a system line kept from the Bots, carrying control: {kind: "receipt", verb: "stop", hold_ids, offer, scopes} for its buttons (undo; stop every Bot; drop the job, when you said 算了 with it), listing all that and what was running. On 2026-10-30, looking at one in 开发助手's direct — 「已停下开发助手的全部工作……挂起 1 个回看,继续时恢复。此刻在跑:无。你再对它说话,它就从你这句接着往下」 — you said stopping and resuming are built in and implicit, and should show no such notice.
  • A go on: a line read as one — 「继续」 alone, or with more in it like 「继续做第二集,……」 — is not carried out by the app and gets no receipt: the Bot that goes on says so. It is filed first, and then the stops that keep the Bots it is said to from the job it is filed under go: on the Bot, on its work in that job or on that ticket, on one of its turns; this conversation's own stop, and a job you stopped from here, only when the line is said to every Bot here (always, in a direct). A stop on any other job stays; only words that name everything (「所有 Bot」「全都」) lift every stop you made before the line, a Stop pressed anywhere included. A line filed under no job lifts only stops on the Bot as a whole. The line then wakes the Bot like any line, and the Bot goes on from it and answers you itself: said in your direct, it goes on there, and its stopped work on that job in another conversation does not open beside it (a Claude Code Bot starts a fresh session here and reads back the other one's work from the records). Stopped work of a lifted stop that the line did not wake the Bot to opens again where it was, on a note for that Bot alone (below). With nothing held, a go on is an ordinary line. A stop that still holds (one on everything; a whole group or job stopped elsewhere; the group or the job here, when the line is said to only some of the Bots) stays, for its buttons: the Bot can only read and answer the line, and is told the stop still holds and not to say it is going on. A go on used to be carried out by the fixed rules, lifting the holds the words named — for a Bot, its holds on every job, its work a Stop held elsewhere included — with a receipt, or a status line when something wider held it; that is how 2026-10-09's 「继续」 landed on another job.
  • Opening again: each turn a lifted stop ended (lifted by a line or a button) opens again in its conversation, on a system line with your words, its plan and ticket, the files it wrote and its last calls; the line says what happened and asks for nothing. It is the app's note to that Bot and, like a check-back's own line, for that Bot alone: only the turn it wakes, or is heard in, reads it, and the flow board still draws that turn picking up from the one the stop ended; the conversation, the phone, other Bots, the organizer, search, unread counts and the conversation list's last line never show it. In a direct with you it opens beside whatever the Bot took up there meanwhile; in a group or a Bot↔Bot direct, where a Bot works one turn at a time, a turn it already has there hears the line instead (a read-only one answering you does not). One the Bot has since taken up there does not open again. One another hold still covers does not either: it is handed to that hold (held_over) — to one that is not a Stop's, when there is one — and opens when that one is lifted. What you said to it while it was stopped got only a read-only answer, which cannot act: those lines are kept on the hold that held it (effect.answered_lines) and handed back when it is lifted — per Bot, conversation and job, the last of them opens the Bot's turn as it would have with nothing stopped, and the turn reads the others above it; a Bot whose stopped work opened again in that conversation reads them there; one another hold still covers keeps them on that hold until that one is lifted. Before, the read-only answer was the end of it: on 2026-10-04, 「片尾的 logo 再大一点」 ("make the logo at the end bigger") said under a stop got "I'll enlarge it and render again once you say continue", and the go on opened nothing (the job had been approved, with no stopped turn to open again), so the logo stayed small.
  • "Has it stopped?", 「怎么还在跑」 ("why is it still running?"), "can it stop?" and a status question are lines for the Bot (from 2026-10-09): into its inbox, read at its next step without cutting it off, when it is working, or waking it when it is not, and it answers. The app used to answer them from what was running (control.kind status): each hold over what was asked about with the line that made it, what of it was running now, and a stop button when nothing was held; first, anything still running under one of those holds was ended and recorded as a violation (effect.violations, hold.violation in the work log) — a status line a button brings (see Buttons below) still makes that check, and there should never be any.
  • A line read as a stop beside other words (「先停,把第三镜换成夜景」 "stop, and make shot 3 a night scene"), or as both (「今天先停,明天继续」 "stop for today, go on tomorrow"), is delivered as usual and carries control: {kind: "possible_control", offer, scopes} for the buttons; nothing in it is carried out: Stop on the first, Stop and Continue on the second; Continue is offered only while a stop it would lift holds what the line names, and once its stops are lifted the messenger stops showing it. A go on with more in it carries none and is a go on as above; one read as no control, or not read at all, carries none. 算了 / 不做了 / 取消 on its own no longer carries buttons: it is a line for the Bot.

Stop on a turn's card: once holds are on, it is a hold — in a direct it is the stop button in the composer (beside Send while its Bot has a turn going in that conversation; where the conversation is as narrow as a phone and the box holds nothing to send, Send, which could do nothing, is not drawn and Stop takes its place, with Send back beside it once you type; a tap on it within 0.6 s of a send does not count, being most likely the second tap of a double tap on Send; a direct has just this one stop, no menu and none on the reply's header). Stopping lives in the composer: a group's replies carry no Stop; to stop one Bot there, pick "Stop all of X’s work" in the stop menu beside Send, which stops only that Bot while the other Bots go on (see the stop menus below; ADR 0040 P2 overturns ADR 0016's no Stop in groups, and first put a Stop on each Bot's reply header, removed on 2026-10-06). A direct's stop button holds that Bot's work in the turn's plan (on the turn alone when it has none), source user_button, lifted by your next line (lift_on_next_user_message). The turn ends under it as above and the check-backs it booked are set aside instead of voided; no receipt goes into the conversation (from 2026-10-04, ADR 0058): it stopped the very turn you pressed it on, your next line lifts it, and the receipt with its Undo only repeated what you had just done. Where the turn stopped is recorded on the hold (effect), and the flow board marks the turn "Stopped". Your next line about that job — filed under that plan, or landing on it — lifts it before it wakes anyone, and the Bot goes on from that line; nothing opens again on a note, since Stop meant "not this". Said anywhere but its direct with you (in a group, say), only a line said to that Bot counts: one naming it (a reply to its line carries its name), naming everyone, or naming nobody in a group it is in; a line only to another Bot about the same job leaves the Stop, and the check-backs it set aside, where they are, so no check-back calls the Bot back into the job before you have said a word to it. Only a line said after the Stop counts: one sent just before, still being filed when you pressed it, does not. "Continue" on its own is such a line. A "continue" to that Bot said elsewhere lifts it too when it is filed under that job, and the Bot goes on from it where you said it; one filed under another job, or under none, does not (from 2026-10-09, above). A line that reads like control and carries the buttons, or a hold of any other scope, never lifts it that way.

Buttons: the buttons on a line the app read or wrote about your stops (control) are pressed once per line: the press is recorded in control.acted, the line then only says what was done, and pressing again (a double tap, a request the phone resends) does nothing. The lines the app writes itself — receipts from before 2026-10-30 (none is written since, above), the status lines a button brings (control.kind status), the line after a restart — show in the conversation as the app's: the Deskfolk mark where a face would be and "Deskfolk" with an "App" tag, not the face and name of the Bot the line is filed under, and a screen reader reads them as "Message from the Deskfolk app"; their buttons stay under them. Its answer to a status question went on 2026-10-09; old ones still show this way. The buttons on a line of yours stay under your line.

  • An older stop's receipt: Undo lifts its holds by button and the work they ended starts again on a note (so did a Stop's, when a Stop still had a receipt) — undo means as if it had not been pressed; when the stop came from a line of yours, that line then goes on as any line (filed, waking whom it wakes, as if it had never been read as a stop, and not read for control again); when that line was said in your direct with a Bot, the work stopped there does not start again on a note, and the line is what reaches the Bot: a line of yours there always opens its turn, so starting the work again as well would have the Bot at it twice. In a group the line wakes only whom it names (with nobody named and nobody still at work, each Bot only makes a judgement on it), so the work stopped there starts again on a note all the same, and the line then goes to the Bots as any line of yours in the group would. "Stop every Bot" makes a hold on everything. "Stop “…” too" makes a plan hold on the plan other Bots were still working in when the stop was made (the plans in effect.working_beside). "Only “…”" first makes, for each hold on a whole Bot in the receipt, a hold on that Bot's work in that plan (quoting the same line), then lifts the hold on the Bot: its work stopped elsewhere starts again on a note, and its work in that plan is handed to the new hold. One button per plan, three at most; the same for "Stop … too". "Drop this job" records the receipt's holds in force as dropping the job (action: cancel): they hold as before, and lifting one reopens the job; really dropping a job waits for work items.
  • "Only X goes on" on a status line or an older receipt of a lift by button (only a button brings these lines now; a go on you say gets none): each wider hold in the way is first split into one per other Bot, quoting the line that made it — one on everything into a hold on each Bot; one on a plan into each Bot's work in that plan; one on a conversation into each Bot's work in the plans it parked and the conversation's current plan, plus a turn hold on each other Bot's turn it stopped off those plans — and then lifted along with X's own holds: X's work starts again on a note, the others' is handed to the split holds. "All go on" lifts everything in the way. Neither posts a line (from 2026-10-30); an older receipt names the holds these buttons are about in held_ids.
  • On a line of yours: "Stop" makes the stop the line meant (source user_button, source_message_id the line), with no receipt; "Drop" the same, recorded as dropping the job (no longer offered from 2026-10-09; it stays on lines like 算了 from before); "Continue" (offered only on a line read as both) still goes by the old rule: it lifts what it can over the scope the line names — for a Bot, its holds on every job — the stopped work opening again on a note, with no line posted; it posts a status line when something wider holds it, and does nothing when nothing is held; ADR 0070 has not changed this one yet. "Stop" on an older status line stops what was asked about.

Stop menus and the list: while a Bot is at work in a group — or in a Bot↔Bot direct opened from it (what the lead handed on, and on down), which the group's stop holds anyway — a stop menu sits beside Send: "Stop the work in this group", each Bot at work there, "Stop this job" and "Stop every Bot"; a choice a hold in force already covers is left out. The first three go, like a Stop on a card, with your next line about them (lift_on_next_user_message), and the Bots go on from that line with no note: for the group, any line you say in it afterwards; for a Bot, a line said to it, wherever (as for a Stop: anything in its direct, in a group naming it, everyone, or nobody); for the job, a line that lands on it. "@X continue" in the group is such a line: the group's hold goes, only X's stopped work starts again on a note, and the other Bots' stopped work stays stopped, as if you had said a line to X alone. A line naming nobody is said to the whole group: it wakes whom it always wakes (the lead, when there is one), and the work the lifted holds stopped that it does not reach — a Bot's part done in its direct with the lead, say — starts again too, on a note with your words, and gets your line as an item of its inbox to answer for. Before, such a line woke only the lead: on the 2026-10-04 walkthrough the group was stopped while 文案 wrote slogans in its direct with 设计师, and after 「宣传语改成英文的,海报改横版」 it stayed stopped, never heard the line, and was called back by the supervisor three minutes later to "answer" the old request. (From 2026-10-30 nothing is said in the conversation; a receipt used to end by saying so: "Say anything more in this group and the stop is over; …".) It ends with your next line because before, a new instruction after the stop ("start over") got only a read-only answer, and the banner stayed up until you lifted it by hand long after the Bots had stopped. "Stop every Bot" works the same way since 2026-10-10 (ADR 0081): a line to any Bot ends it. A direct has no such menu, only the Stop above: it stops that turn and your next line lifts it; the menu bar's "Stop everything", the flow board's "Stop this job" and a typed "stop" are stops for now too — no stop waits for you to lift it any more. The flow board's title row offers "Stop this job" and "Stop every Bot". The tools menu has no stop (its "Stop everything" went on 2026-10-11, a repeat of "Stop every Bot" in the stop menus and on the flow board); the menu bar's "Stop everything" makes a hold on everything — on the turns that would start, not only those running, so it can be pressed with no Bot at work — and against a daemon that has no holds yet stops the latest live turn in a direct as before. A stop from a menu goes through POST /v1/holds with the menu's conversation, recorded in the work log, with no receipt. A lift the daemon refuses says "That did not work; try again" where it was pressed; with the daemon out of reach these buttons show but cannot be pressed. The stops you dropped a job with by a button, which no line ends, are listed above the conversation list: the scope, the time, "Dropped", each with a Lift (by button — going on; see API); a stop for now is not listed, and no row is marked (since 2026-10-10, ADR 0081). The flow board lists under its title the plan's own parking and the holds over its job that wait to be lifted — on a Bot's work in it, on its conversation, on everything — each with a Lift. When a hold is made or lifted, an open flow board reads its plan again, so the next edit starts from the version the hold wrote and is not refused with 409; on a 409 all the same it reads the plan again as before. The plan's footer and history mark the versions a hold wrote as "by a stop" (a revision's cause: "hold", the plan's revision_cause). All of this needs a daemon at the holds level: it appears only when the snapshot has holds.

At boot: once the engine level has reached holds, every boot checks again. A plan parked before holds existed — status and spec's status both parked, which is how you or the organizer stopped one — becomes a plan hold of source legacy, so from then on only you can put it back in progress; a plan only pushed out of the current slot by a newer one (its spec still says In progress) is left alone. Then any plan a hold covers that is not parked, and any check-back it covers that is not set aside, is put right, and daemon.log says so.

API: GET /v1/holds (holds in force by default, ?status=all for lifted ones too, newest first), GET /v1/holds/:id, POST /v1/holds (a stop you make from a button or a menu, recorded as user_button; the turns it covers end at once, as above), POST /v1/holds/:id/lift (the turns it ended open again as with a go on, a Stop's excepted; one already lifted comes back unchanged), POST /v1/messages/:id/control (the buttons above: {action, task_id?}, task_id naming the plan for "Stop … too" and "Only …"; returns {made, lifted}; 422 for a line with no buttons or without that one); the phone can do the same. POST /v1/holds takes an optional session_id: the menu's conversation, recorded on the work log's control.hold (before 2026-10-30 the receipt went there). The snapshot's holds are the holds in force, newest first, absent before the holds level; a hold's plan_title is the title of the plan it names. Parking a plan with PATCH /v1/tasks/:id/spec ends what runs in it the same way. POST /v1/turns/stop is the Stop above. A line the app read or wrote about your stops carries control (MessageControl). Making a hold, lifting it and recording what it did each reach clients as a hold.upsert event. A plan's held_by is as of when it was read: a hold that changes nothing on the plan's row, such as one on everything, sends only hold.upsert when it is made and when it is lifted, so a client that shows held_by reads the plan again on that event.

Avoid: carrying out a stop or a go on the word lists read, fixing a miss by adding words to a list, a stop line going through the organizer, taking "don't pad it with frozen frames again" for a stop, swallowing a request and acting only on the stop in it, a receipt in the conversation after a stop, a receipt that says what did not happen, the app answering "continue" or "has it stopped?" for the Bot, carrying out "continue" before it is filed, a "continue" lifting a stop on another job, swallowing "continue" instead of passing it to the Bot, lifting the whole group's stop with "@X continue", a Stop quietly left in force after "all Bots continue", taking a "stop" in quotes, in code or beside a 😂 for a stop, swallowing the line that was read as a stop after Undo, letting the other Bots go too on "Only X goes on", a line to another Bot in a group lifting this Bot's Stop

Status question

A line of yours that only asks how things stand ("how's it going", "where is episode 2 at", "where's the final cut?" — read so by line reading) is not answered by the app: it goes to the Bot it is said to like any line — into its inbox when it is working, read at its next step without cutting it off, or waking it when it is not — and the Bot answers. When the filing reads it as new work it counts as done in place: what the Bot looks up or runs for it opens no job, so "how's it going" never becomes a job of that name. The app used to answer itself, with a status line in the conversation that woke no Bot; that went on 2026-10-09 (ADR 0070): that morning you asked "where's the final cut?" twice in the video director's direct and both times got a status line under its name, while the Bot heard neither line; it was not working at all, so the line could only say nobody was. A status question costs a Bot's call.

Avoid: the app answering for a Bot about where the work stands, putting the app's status under a Bot's name, waking the whole group for a "how's it going", interrupting a working Bot to ask for status, filing "how's it going" as a new job, taking a line with an instruction for a status question

Plan

One job pursued around a goal and a deliverable, holding tickets, user quotes, requirements and artifacts, and continuing across conversations, days and rework; its home conversation is where it belongs, not the only place it can be worked on. Opening another job does not stop this one, and dormancy is neither acceptance nor abandonment. Details: Behavior · Plan.

Behavior details

Name: a plan is named after the first words of the line that opened it (at most 40 code points; a line with no words, only a picture or a file, names it after its first file, as in "screenshot.png and 1 more", and one with nothing at all "(attachments only)" — never blank). The app, the organizer and the Bots never rename it; only you do, in the plan's 要点 (Plan) on the board, and its folder keeps its name. Renaming changes the name, not the goal the Bots work to: once a new name is saved, a line under it says what the goal reads now, with an "Edit the goal" button, until you edit it or leave — on 2026-10-04 you renamed a job 「做《一拳超人》动画」 and its goal still read 「制作一部未来世界题材、时长超过2分钟…的短片」, further down the panel, where 视频导演 read it as the job. The turn's picture says so too: when you renamed the job after its goal was last written, the plan's line is followed by "the user renamed this job after its goal was written: where the goal disagrees with the name or with their own words, their words win", until you write the goal on the board. The board's heading, the job switcher, the stop menu, the flow's filing steps and every turn's picture all call it by that name (the goal is in the spec, and stands in only when the name is empty). A rename is an edit of yours: "Last change" says so, a dormant plan wakes, and map.md carries it. Before 2026-10-03 a name could not be changed, and 《一拳超人》 stayed under the line that opened it, 「让审片员回复视频导演,说明未回复原因并给出审片意见。」.

Current level-2 path: a job can span conversations, and a conversation can hold multiple non-dormant plans; the “current slot” must not guess a message's job. Code retains the historical tasks/task_id names. Attribution places a request in an existing plan; uncertainty opens a desk, and a quoted request or the first permitted effect opens a new job. Opening it does not park another job still being worked on. This change adds no new “all tickets approved → plan delivered/accepted” submission state machine: old active/done/parked and ticket statuses coexist, and importing done as delivered does not mean an approved submission exists.

Dormancy is separate from holds: it neither changes stage nor lifts a hold, removes default candidacy and suppresses automatic call-backs. Clearing the home conversation sets prior plans dormant. Opening a new plan (a desk opening a job, or work_on opening one from a quoted line) sets an older one aside only after two hours with no user activity or recent segment, no non-idle open work item and no registered pending job. When a database goes up from level 0/1 to level 2 or above, old plans parked by another job that have no live segment and none of your words in the last two hours go dormant too (work log plan.dormant, cause legacy_parked); otherwise they would all read as active candidates, and a desk with two or more candidates refuses to act. A delivered plan also ages into dormancy after 72 hours without user activity. Legacy done plans with no user quote in the last 24 hours import as delivered + dormant. The pending-job condition only checks a table that exists with the columns it reads (an abandoned draft's table of that name, without them, is set aside at open: dropped when empty, renamed external_jobs_draft_<time> otherwise), not a claim that the P4d poller is active. Explicit references, your correction or a continue can reactivate one, still subject to holds.

The following describes level-0/1 migration compatibility and existing plan presentation, not level-2 message attribution; its single current slot, organizing before a turn and parking on a new job do not apply at level 2:

The one thing currently being moved forward in a session, pieced together by the app itself; you do not have to define it first. The code keeps the tasks table and task_id (historical names; comments call it a plan). It is written up as the plan, with these fields: Kind, Goal (what exactly is to be done now), Done when (how completion is judged), Rules (the standards, constraints, and improvement notes you have set), Process (the process and who does what), Progress (done / to do / stuck), and Status (in progress / done / parked); it also keeps the verbatim text of the request that opened it (the original request). The organizer updates the plan after each of your messages and after the plan goes quiet (that second pass only files the handover; see Organizer), except Done when and Rules, which only you write, on the flow board: the organizer no longer writes those two, and what your lines ask is kept in the requirements ledger. Every revision leaves a record (which message or turn caused it, or that you made it), and you can also edit it directly on the flow board. A session has only one current plan at a time: when the organizer judges that you have moved on to a different thing, it opens a new plan and parks the old one; when it judges that you have returned to an earlier thing, it picks that plan back up; when it judges the plan done or parked, the slot is left empty. No clock switches things for you. When you stop the work, the plan is parked, and it goes back to in progress only when you say to continue (or change it on the flow board). Once the engine level has holds, the hold keeps it there (see Hold): a line that says it has not stopped ("you haven't stopped") is read as a stop again and carried out as one, never reaching the organizer (one that also asks for something else is filed as usual; one the reader cannot read goes to the Bot), and the organizer no longer parks a plan on its own reading of a line. Below that level the organizer does it: a line pushing for it to stop is never read as continue, and the filing after the plan goes quiet does not set it back to in progress. Nor does a turn a check-back or annotations wake working in it: opening a turn never changes a plan's status. Every turn's situation carries the plan, what you said in the job (see User quote), the requirements ledger's entries in force for it (see Requirements ledger), the ticket list and the ticket for this turn, and so does a turn handed off to another Bot or another session, woken by a check-back or fired by a routine, so the original goal and what you asked do not depend on whether that line is still in the transcript window. Looking up precedents of the same Kind is gone: neither the situation nor the organizer reads them. The head of the flow board says how long ago the job last changed and what changed ("Last change 3 min ago (ticket 02 "Rough cut": review)", the newest of the plan's latest version, a ticket's status, a check's run, a turn and a change to its requirements), and a dormant plan is marked "Dormant". The first turn is marked in the situation; it is the only turn that can still align on the request before starting work. When a session's history is cleared or the session is deleted, its plans no longer close; they go dormant: the closing time is still written, so an older build that knows nothing of dormancy still reads them as closed. Nothing touches a dormant plan: it is not filed (a filing already out when it went dormant lands nothing) and nobody is called back into it; clearing or deleting drops its pending filing and look-again, so nothing fires into the cleared session. It wakes when it is put back in its session's current slot (the organizer judges that a line of yours returns to it, you lift the hold that parks it, or an older build picks it back up); when a line of yours, or your answer to a question, is filed under it, from whichever session (it then stays closed unless that filing also puts it back in the slot); and when you edit its fields or its tickets on the flow board, any edit (checks alone do not count). A Bot's turn working in it (a check-back, a call-back, a turn named into it) only moves its closing time and leaves it dormant. When a session is deleted, plans nothing refers to are deleted with their tickets as before; the others go dormant and closed and belong to no session from then on, one the group's hold parked gets a hold of its own, and an edit on the flow board wakes one but can never put it back in a session's slot. A routine's standing plan only closes and does not go dormant, and the routine keeps adding tickets to it. On a clear, a plan stays as long as it still has a quote of yours you did not erase, or a requirement on it or on one of its tickets; only with neither, and no other turn or message of the transcript belonging to it, is it deleted with its tickets as before.

One-question jobs in the switcher, and a board that has ended (2026-10-10): in the switcher under the board's title, the jobs that were one question and its answer (closed, no tickets, one turn at most) are a kind of their own, "One question"; the job on screen is never put there. On a desktop the two kinds sit in a column on the left with the jobs on the right, as in the model picker (since 2026-10-21; before, they folded into a single row, "N one-question jobs", at the end of the list, out of sight below many jobs): it opens on "Work", hovering "One question" shows those, and pressing a kind goes into its list; the arrow keys walk the list, Left steps onto the kinds, Up and Down there switch kind, and Right goes back into the list. With one kind there is just the list. A phone's sheet from the bottom still folds them into that row, which opens in place, and the arrow keys walk through it. An older daemon does not report each job's turns, and then nothing folds. With no job asked for, the board opens on the newest job that was not a one-question one (the newest of all when every one was). When the job is done, parked or dormant, the ticket board wears a matching label beside its title and, while tickets are still open, a line under it: "Settled: no one will pick up the tickets left open" ("Dormant:" and "Parked:" for those); the cards still open fade back and lose their accent. Dragging and the status menu still work, and nothing says the job goes on because of it — as with the supervisor: in a done, parked or dormant plan the ball is nobody's (see Ball holder).

Avoid: one message is one job, only one job in a conversation, every rework opens a new plan, rewriting the original request, writing a Bot's decisions as user rules

Ticket

A unit of work under a plan with defined delivery content, a title, a description, who is on it and related artifacts; it is neither an execution segment nor a message. Every ticket has to meet its plan’s Done when lines, rules and what you asked for, and may have requests and checks of its own; the plan’s Progress is the organizer’s written account, and a ticket’s state is its own. A ticket being In review does not mean its delivery has passed a review. From engine level 5 it has a stage (to do, in progress, submitted, in review, rework, approved, dropped) that only submissions, reviews, the supervisor and your board edits move — never the organizer — its old status written alongside; the parts (shots) the lead declares with plan_items each have a stage too, a hand-over naming the ones it covers (a file's name makes none), and the board says "11/12 approved"; from level 5 the lead can lay out tickets, makers, reviewers and dependencies with plan_items in one call. Details: Behavior · Ticket.

Behavior details

Level-2 work identity: a ticket narrows a work item within its plan. work_on can explicitly select one or open a produce ticket for a new job; the app validates that it belongs to the selected plan. Neither the waking turn's ticket nor “the Bot has exactly one unclosed ticket” decides the execution directory. A Bot's output uses its own work-item attribution. Different tickets of one job still obey I1b. Existing To do/In progress/In review/Done/Parked can still be used by the current interface, observed progress and settle. In review is not P4e submitted/approved, and materializing a part from a filename is not a passed part review.

The following fields, artifacts and observed progress remain; organizer-created tickets and worker-based inheritance describe only legacy compatibility:

The smallest unit with a deliverable under a plan: number, title, description and Done when (what to hand over and how it is judged done; no progress notes and no don'ts a Bot set for itself), status (To do / In progress / In review / Done / Parked), who is on it (filled in first from "Process" when the organizer opens the ticket, then updated from what is observed; it is a record, not an assignment), and artifacts. Both the organizer and you edit tickets. The organizer refers to existing tickets by id and writes only the fields that changed (leaving out the title, status, or who is on it means that field is unchanged); it opens new tickets as new-N; it cannot delete a ticket, only mark it Done or Parked. You change status on the flow board. The app itself also moves a ticket forward one step based on what it sees, without calling a model: when a turn filed under the ticket starts writing files or running commands, To do becomes In progress; when that turn hands over files, it becomes In review; if no one is on it, that Bot is recorded. It only moves forward, and it never marks anything Done or Parked on anyone's behalf. The organizer waits until the plan goes quiet before organizing, so this step keeps the flow board showing truthfully who is doing what even while several Bots work back to back. Each ticket has its own folder NN-<title>/ under the plan folder; turns filed under the ticket work in it by default, and turns not filed under any ticket land in the plan folder. When a Bot is woken by a handoff, if the ticket handed over belongs to someone else while the Bot is on exactly one ticket in this plan that is not yet closed out, the turn lands on the Bot's own ticket instead of following the waking turn into someone else's ticket; if the handed-over ticket is its own, or no one is on it yet, the turn follows the handoff. Artifacts belong to tickets: a message carries a ticket_id, and the files it references are that ticket's artifacts; no files are moved. The rail of tickets sits left of the flow board (ADR 0086), a row per ticket: its number, title, its owner’s face, its status and how many turns, with a small lane under it. Every row shares one axis that draws the job’s turns in the order they happened, a silence of over half an hour folded into a thin bar, a stopped or cut turn as an outline; the first row is your lines and the last the turns under no ticket. Pressing a row picks it and lights its cards; pressing its lane also slides the flow to the nearest card. A button on the rail’s head opens it out into the board of five columns over the rail and the flow, where cards are dragged between columns as before. The picked ticket shows in the inspector right of the flow: its status menu, who has the ball, its description, files and a link to its latest turn, and its reviewer, model and dependency settings; a card picked on the board no longer unfolds them under itself. Tickets and the plan are linked: every ticket has to meet the plan’s Done when lines, rules and what you asked for (a ticket folder’s ticket.md is the ticket’s description followed by the plan’s Done when and rules), and some requests and checks hold for one ticket alone. The inspector lists what the picked ticket has to meet, and “See in the plan” turns it to the plan read against that ticket: a way back to the ticket on top, and the requests and checks held to other tickets dim. With nothing picked the inspector is the whole job’s plan, which one press widens over the whole tab. In the plan, a request or check held to one ticket names it, and pressing the name picks it and turns the inspector to it; above Progress, a row counts the tickets by status, and pressing a status lets only that status through on the rail until you clear it — the tickets’ own states are the ones to go by, and the Progress below is the organizer’s written account. Narrow (a phone, a narrow pane, under 900px) the rail, the flow and the plan are one at a time behind a switch under the title — Tickets, Trace, Plan — and a ticket picked or a step opened comes up as a sheet from the bottom.

Who does what (2026-10-12, ADR 0086): each rail row shows its owner's and its reviewer's faces; where the Bots who ran the ticket and its owner differ, the row says "Actually: X" (its owner ran none of it) or "Also X" (another Bot ran it too and it has no reviewer). Above the whole job's plan in the inspector, "Who does what in this job": what each Bot owns and reviews and how many turns it ran in the job (how many on someone else's ticket, how many under none), those who own tickets and ran nothing marked — owners are filled in by the organizer from the plan's process when it opens tickets, not from who works them; under it, the engine the job's calls run under (the job's conversation, the one it was opened from, then Settings' default), why it is that one, the steps it leaves off and how many conversations run it, with "Engine: X" in the title row too, opening Roles on that engine. A picked ticket's settings gain a line of who actually ran it; when a Bot that is neither its owner nor its reviewer ran at least five of its turns and it has no reviewer (with reviews on), a "Make X the reviewer" button shows, in the inspector only — no line in the conversation, no card. "N need you" in the title row adds up the failed checks, blocked progress and requirements waiting for your word, and one press turns the inspector back to the whole job.

Stages from level 5 (ADR 0046): a ticket also has a stage: to do, in progress, submitted, in review, rework, approved, dropped, with its old status written alongside (submitted and in review write In review, rework writes In progress, approved writes Done, dropped writes Parked). Only a submission's checks, a review, the supervisor, and your board edits of the status write it (the trigger tickets_stage_follows_status brings the stage along with yours), each move recorded as ticket.stage_changed. From level 5 the organizer writes no status for existing tickets, opens new ones as to do, and marks a plan done only when it has no ticket to approve; its "done" on a ticket nothing was ever handed over on becomes that ticket's submission (organizer, no files): with a reviewer set it goes to that reviewer like any other hand-over; with none, the next tick never ignores it or approves it on its word alone either — once everything else is clear, a card asks you to approve it or send it back (see Supervisor). When the producer still has a segment running on the ticket, or a work item that is not idle, this reading is skipped for the tick so it does not race ahead of real work still in progress; the organizer tries again next time it reads the ticket as done. The old "handed files over → In review" step is gone ("started working → In progress" stays). Changing a ticket's status on the board supersedes its undecided submissions, so one still in review cannot move it past you. The board's status label shows the stage (In review, Rework, Submitted, Approved), with how many parts passed beside it ("11/12 approved") and a Reviewer menu under the picked ticket (an unpicked one with a reviewer says "Reviewed by …" in the line under its title) — all only at level 5. A Bot's situation names the stage in its ticket list and "This turn's ticket" too. Parts are those the lead declares with plan_items (or you add on the board), and a hand-over names the ones it covers in submit's parts; one that names none, or that the app hands over for the Bot (implicit), is the whole ticket's — file names make and pick no part (ADR 0057). A Bot's situation lists its ticket's parts and their stages. Each submission counts an attempt and records its current file, and a part's stage follows submissions, checks and reviews: in progress → submitted → approved or rework. A ticket's reviewer is the one you pick in the picked ticket's Reviewer menu (which lists only Bots of the plan's conversation, never the owner; or PATCH /v1/tickets/:id {reviewer_bot_id}, local and remote), never the ticket's owner; else the recipient of an open request expecting a review (delegate with expects: review); never the producer. When every ticket of a plan not dropped is approved and its plan-wide gates (checks on no ticket) last passed, the plan is delivered by the path a done plan always takes (its spec says done, it closes as a done plan does, under a stop it still reads parked), with stage = delivered. A delivered plan one of whose tickets leaves approved — handed in again, or sent back — is active again (plan.reopened): delivered means every ticket approved, and the supervisor chases only active plans; it used to stay delivered, so the new hand-over a lead asked for after your complaint was never chased (2026-10-03). It is delivered again once that ticket is through. On the board an approved ticket says who made it ("By X") and no longer "waits for #NN"; a parked or dropped ticket says nobody's. A segment that ends with its ticket approved or dropped closes its work item; otherwise the item goes idle, since a rejection can bring it back. An approval usually happens in another Bot's reviewing segment, when the producer's item is already idle, and there it stays. Changes after delivery: a segment that wrote in the folder of an approved ticket and handed nothing over with submit has its ending sent back once, telling it what you approved is the old version and to hand the change over with submit for you to decide (an automatic hand-over never reopens an approved ticket); the paths it wrote are all it wrote in the segment, not only those no line has cited yet. And once a job is delivered a settle no longer calls it in progress again: from level 5 hand-overs and approvals decide when it is done. On 2026-10-04's real-model run, after 「第二句不够有画面感,换一句」 the lead redrew the poster and 文案 rewrote the slogans, both tickets still read approved with the old versions, the job still read done and no card came; and once it was handed over and approved, a settle 19 s later marked it in progress again.

Dropped and set aside, and the totals (2026-10-10): a ticket its lead dropped (it has a reason) reads "Dropped" on the board, with a muted "Dropped: " line on its card, in the Parked column all the same; a ticket you set aside yourself on the board has no reason and reads "Parked" as before. Neither is work still to do: in the ticket list's "N open · M in all · K dropped/set aside" the M leaves them out (the K part is left off when it is 0), and the completion percentage is a share of M alone; with no ticket counting at all there is no percentage or progress bar. The job's header and the switcher rows count the same way. In a large job, or one that already has a sample, a picked ticket that is not through and not the sample has "Make it the sample", which sends PATCH /v1/tickets/:id {sample: true} (see ADR 0053).

Avoid: one ticket per sentence, ticket as work item, handing over a file as acceptance, mirror files as a ticket's source of truth, letting a Bot write a ticket's stage, guessing parts from file names

Large job

A job only done well in several parts with a sample made first to set the standard, such as a video of several minutes or a book or report of many chapters. Found by the reader from your words, or when segments go by with nothing approved; you can say it needs no laying out. Until it is laid out nothing is generated or handed over on it; then the rest wait for the sample to be handed over, and the last part is yours to approve. Details: Behavior · Large jobs.

Behavior details

From level 5 (ADR 0060). A job that is only done well in several parts with one made first to set the standard — a video of several minutes, a whole episode, a book or report of many chapters, a many-page site, a batch of dozens of like things — is a large job. Two ways find one: when a line of yours is filed under a job not read yet, the reader reads it with all your words about the job (what is asked for, not wording; unsure is no; unread stays unread); and when a job not read, not laid out and with nothing approved has ended 3 or more segments, the supervisor has it read again with those facts, and marks it large itself when nothing can read. A reading only ever marks an unread job, never over yours. Under the plan panel's Name a large job reads "A large job: laid out in parts, with a sample made first for you to approve before the rest" with what showed it, and "No need" beside it; once you say no need nothing reads it as large again, and "Treat as large" marks one yourself.

Until a large job is laid out, a segment on it is refused side-effect MCP calls (generating images or video) and submit, and files left at its ending are not handed over; reading, notes, scripts and local commands go on, and its situation says to lay it out first. The lead does: one plan_items item marked sample: true is the sample — made first, to the whole job's standard. A job has one; a large job's layout stands only with a sample and something waiting for it. Once a sample is set, every ticket but the sample and what it depends on (however far back), not through, waits for it, and so do tickets laid out later.

Dependencies hold from level 5. A ticket whose dependency is not through does not start: the supervisor wakes nobody for it (the board reads "Waits for sample #02 to be handed over" or "Waits for #01 to be handed over"), work_on refuses it, a deliverable delegation of it is refused, and generating calls and hand-overs on it are refused. Through means handed over at least once (submitted, in review, approved, or back in rework after a hand-over), so the next one does not wait on your card; the sample too (from 2026-11-11, ADR 0109; before, the sample had to be approved by you). A dropped or parked ticket holds nobody. A ticket nobody has started, all it waits for through, has its owner called at the next supervisor tick rather than after the usual quiet window: the next part starts as the one before is handed in.

The last one is yours to approve; the sample is not. The last unapproved ticket of a laid-out large job (approving it delivers the job) waits on your word. The sample goes like the ones in between: its reviewer reviews it, a check of yours backs it, and only with neither does it wait on your word — while the tickets waiting for it are already under way; the situation tells the Bot not to ask you to approve it (from 2026-11-11, ADR 0109). Before, the sample always waited on your word, only a clear yes or a call to go on counted, and the rest waited with it; on 2026-11-10 the video director's second scene was refused for over an hour while 「继续」, 「第一场放过」 and an answer on a question card each failed to count. submit no longer tells the Bot handing the sample over what it took and what the rest would.

Held to the sample. Once the sample is approved (by whoever approves it), each ticket waiting for it gets a check, "Holds to the standard of sample #02 …". At each hand-over the app gathers the evidence itself and has the picture judge's model (the one chosen under Tools → Roles, the default model if none) compare: for video the longest file's length, size, sound, how many different pictures its keyframes show and how often one comes back, plus 5 evenly spaced frames; the first pictures; the opening, middle and end of a text. Content differs, as it should; only craft and form count — still pictures under camera moves where the sample moved fall short — and unsure passes. It is a gate: falling short sends the hand-over back with what falls short; keeping the standard backs an approval with no reviewer like a check of yours. A judgement it could not make (nothing handed over, no model, your stop, the day's picture budget spent) holds nothing, and the hand-over waits on your word. A comparison that sends pictures needs a chosen endpoint model to be marked "takes pictures" in its attributes, and otherwise runs that once on the default model; a chosen Claude model is always used; one that compares only words is not held to this. Picture judgements are a reference elsewhere (ADR 0046); this one gates, since the bar is the sample the job made first. It runs only when a hand-over is made or decided, never on a settle's rerun of every check, and once its ticket is approved or dropped it holds the plan open no more. The plan lists these under Done when as "Held to the sample": the sample's line, each ticket's check under it, failures first and passes last; a failed one is also named under the goal, in "Needs a look", with its ticket and its first reason.

Avoid: making a large job as one ticket in one go, judging size by word count or keywords, filling time with still pictures as a cheaper form, a reading overriding your "no need"

Sample

The part of a large job made first, to the whole job's standard; until it is handed over the other parts do not start, and once it is approved each is compared with it when handed over (a standard check). It does not wait for your approval (since 2026-11-11, ADR 0109): its own hand-over goes by the usual rules — its reviewer, a check of yours, else your word. A job has one at a time; when you turn down the direction it set, the lead lays the job out again around a new one (you can move it on the board too), and the checks held to the old one come down. Details: Behavior · Large jobs.

Behavior details

From level 5 (ADR 0060). A job that is only done well in several parts with one made first to set the standard — a video of several minutes, a whole episode, a book or report of many chapters, a many-page site, a batch of dozens of like things — is a large job. Two ways find one: when a line of yours is filed under a job not read yet, the reader reads it with all your words about the job (what is asked for, not wording; unsure is no; unread stays unread); and when a job not read, not laid out and with nothing approved has ended 3 or more segments, the supervisor has it read again with those facts, and marks it large itself when nothing can read. A reading only ever marks an unread job, never over yours. Under the plan panel's Name a large job reads "A large job: laid out in parts, with a sample made first for you to approve before the rest" with what showed it, and "No need" beside it; once you say no need nothing reads it as large again, and "Treat as large" marks one yourself.

Until a large job is laid out, a segment on it is refused side-effect MCP calls (generating images or video) and submit, and files left at its ending are not handed over; reading, notes, scripts and local commands go on, and its situation says to lay it out first. The lead does: one plan_items item marked sample: true is the sample — made first, to the whole job's standard. A job has one; a large job's layout stands only with a sample and something waiting for it. Once a sample is set, every ticket but the sample and what it depends on (however far back), not through, waits for it, and so do tickets laid out later.

Dependencies hold from level 5. A ticket whose dependency is not through does not start: the supervisor wakes nobody for it (the board reads "Waits for sample #02 to be handed over" or "Waits for #01 to be handed over"), work_on refuses it, a deliverable delegation of it is refused, and generating calls and hand-overs on it are refused. Through means handed over at least once (submitted, in review, approved, or back in rework after a hand-over), so the next one does not wait on your card; the sample too (from 2026-11-11, ADR 0109; before, the sample had to be approved by you). A dropped or parked ticket holds nobody. A ticket nobody has started, all it waits for through, has its owner called at the next supervisor tick rather than after the usual quiet window: the next part starts as the one before is handed in.

The last one is yours to approve; the sample is not. The last unapproved ticket of a laid-out large job (approving it delivers the job) waits on your word. The sample goes like the ones in between: its reviewer reviews it, a check of yours backs it, and only with neither does it wait on your word — while the tickets waiting for it are already under way; the situation tells the Bot not to ask you to approve it (from 2026-11-11, ADR 0109). Before, the sample always waited on your word, only a clear yes or a call to go on counted, and the rest waited with it; on 2026-11-10 the video director's second scene was refused for over an hour while 「继续」, 「第一场放过」 and an answer on a question card each failed to count. submit no longer tells the Bot handing the sample over what it took and what the rest would.

Held to the sample. Once the sample is approved (by whoever approves it), each ticket waiting for it gets a check, "Holds to the standard of sample #02 …". At each hand-over the app gathers the evidence itself and has the picture judge's model (the one chosen under Tools → Roles, the default model if none) compare: for video the longest file's length, size, sound, how many different pictures its keyframes show and how often one comes back, plus 5 evenly spaced frames; the first pictures; the opening, middle and end of a text. Content differs, as it should; only craft and form count — still pictures under camera moves where the sample moved fall short — and unsure passes. It is a gate: falling short sends the hand-over back with what falls short; keeping the standard backs an approval with no reviewer like a check of yours. A judgement it could not make (nothing handed over, no model, your stop, the day's picture budget spent) holds nothing, and the hand-over waits on your word. A comparison that sends pictures needs a chosen endpoint model to be marked "takes pictures" in its attributes, and otherwise runs that once on the default model; a chosen Claude model is always used; one that compares only words is not held to this. Picture judgements are a reference elsewhere (ADR 0046); this one gates, since the bar is the sample the job made first. It runs only when a hand-over is made or decided, never on a settle's rerun of every check, and once its ticket is approved or dropped it holds the plan open no more. The plan lists these under Done when as "Held to the sample": the sample's line, each ticket's check under it, failures first and passes last; a failed one is also named under the goal, in "Needs a look", with its ticket and its first reason.

Avoid: a sample as a cut-down preview, holding the rest until you approve the sample, several samples in one job, holding a new direction to the old sample

Submission

From engine level 5, one hand-over of a ticket's work: which files (by content hash), the checks the app ran on them at once, and the reviews it got. A Bot hands work over with submit (files of the plan's folder outside other tickets' folders, or the shared assets/); when it does not, new-hash files in the ticket's folder that the segment's lines cited are submitted for it when the segment ends (or on end_turn(done)) — the implicit submission, made for the ticket's producer only, never of a reviewer's notes. A ticket whose work is words hands those words over only through its producer's explicit end_turn(done, answer) — a plain-text closing reply is never inferred as one any more, and the words themselves must still pass a check (not an empty remark or a question, not a bare ack like "got it"/"sure"/"noted", not a bare claim like "done" with nothing else behind it; the length floor is only 2 code points, not the safety line — this check and your word below do the real work); failing that, the call is refused and the Bot hears to hand the words themselves over, or, if the work is a file, to keep working until it exists. The organizer's "done" on a ticket nothing was ever handed over on counts as a submission too. With a reviewer set, either kind goes to it like any other, but its approve does not approve either one — nobody actually made the words or the reading, so a clean approve only moves the submission to awaiting you, carrying the reviewer's own verdict; with no reviewer, a failing gate sends it back and the ticket does not move, and passing never approves an answer or an organizer's reading on its own — it waits on your word. A file hand-over is approved on its checks only when at least one check you wrote or confirmed backs it and every gate passes (the organizer's checks still block when they fail, but their pass backs nothing); with none of yours bound, it waits on your word as well. So does one with a requirement you said twice, or about the picture, that nothing backs, and letting it through counts those as met. Waiting on your word means no card: the Bot that made it tells you what it handed over, and the reader reads what you say next — a nod, using it or asking for the next step, or in your direct with it moving on to something else, lets it through; finding fault sends it back to rework; a change has the Bot hand over a new version. It goes through as approving on a card did (a failing gate sends it back), logged as yours; neither letting through nor sending back adds a line to the conversation (from 2026-10-14): on the flow your line is a decision card. Saying more about the job while it waits, which its Bot then works on, keeps your words off this version meanwhile; what the Bot hands over next is what waits on you. A routine's runs never wait on you: what a run hands over is approved once its gates pass. Nor does a file hand-over made in one go: on a job of one ticket that was never on an old approval card of yours or has had a hand-over approved, handed over by the only segment since it opened (or was last approved), it is approved, such requirements with nothing behind them included. Details: Behavior · Submission.

Behavior details

From level 5 (ADR 0046), one hand-over of a ticket's work, kept in submissions: which files (by content SHA-256), parts, the Bot's note and claims, the checks the app ran, and the reviews it got. An explicit submission takes files of the plan's folder (its deliverables/ and root too) but not of another ticket's folder, plus the workspace's shared assets/; an implicit one only the ticket's own folder; never a folder the app keeps for itself; a newer submission of a ticket supersedes the undecided ones, and one that failed its checks stays on record.

  • Explicit: submit({artifacts, parts?, claims?, note?, continue?}), paths relative to the workspace or to the Bot's work dir. The app hashes the files, posts the ones this segment has not cited yet on a line of the Bot's (so a check from your words can find the master it measures), then runs the submission's checks at once and waits: a failing gate comes back to the Bot with its details and the ticket does not move (back to rework if it had been handed over); passing, the ticket is submitted and queued for its reviewer if it has one. The segment ends with it unless a line of yours it read is not yet answered for, a line of yours in your direct opened the segment and no word of it has reached you, a request it sent is still open, or it is waiting on something — then it says why (no bounce counted). With no word to you yet, it replies after handing over; files that line already carries are not attached to the reply again. continue: true goes on with other parts. Files byte-for-byte the same (paths and hashes) as the ticket's last approved or still-open hand-over are refused (unchanged): there is nothing to decide. Writing into a job, a path in a folder shaped like a ticket's (work/<job>/NN-…) that no ticket has and that is not there yet is refused by write_file, with the job's real ticket folders. On 2026-10-04's real-model run, asked after delivery to change the second day's theme, a Bot built a folder name from the ticket's title (01-…每天一个主题; the real one is the title cut short, 01-…每天一个), wrote the new version there and handed in the untouched one, and the card asked you to approve a plan that had not changed.
  • Implicit: when a Bot does not call submit, files this segment's lines cited, in the ticket's folder, whose content hash is new since the ticket's last submission are submitted for it (origin = implicit) with the same checks — for the ticket's producer only: its owner (or worker), a Bot a request asks for a deliverable on it (expects: deliverable), or anyone on a ticket nobody owns. What the ticket's reviewer, a Bot asked to review it, or a segment woken by a request to review writes are review notes, never submitted. end_turn(done) posts the files the segment wrote and has not cited first, then submits (a failing check comes back as the reply to that end_turn); a pure-text closing that hands over files of the ticket's folder is posted, then submits — a failing check voids that closing and the Bot hears why and goes on; passing, it is weighed by the ending contract — and any other segment that ends normally (not blocked, gave up, or needing attention) submits when it ends, a failing check queuing a line that wakes the producer. The same bytes are never submitted twice; an approved or dropped ticket gets no implicit submission. A Bot that is not the owner and leaves files in an owned ticket's folder hears once at its ending (end_turn(done) or a closing reply) that they were not handed over for it, and to use submit if they are the ticket's work.
  • Words handed over: on a ticket no file was ever handed over on (topics, a conclusion — work that is words), only its producer may hand those words over, and only through an explicit end_turn(done, answer) — a plain-text closing reply is never inferred as a hand-over any more; that inference once let "the master is cut" approve a ticket nobody had checked. The text itself must still read as the deliverable: at least 2 code points after trimming (not a real floor — this kind of hand-over always waits on your word regardless, so length is not the safety line), not an empty remark, not a promise of more to come, not a question, not a bare ack (好的 / 收到 / 明白 / 了解, "got it" / "sure" / "noted"), and not a bare claim of being done, mid-progress, unable to or waiting (done / finished / completed / working on / waiting) with nothing else behind it, however it is dressed up — padded out long enough it may slip past this filter, which is not a bypass: it still waits on your word, for you to say what is wrong. Failing that, the call is refused and the Bot is told to hand over the words themselves — a title, a line, a list, a paragraph — as the answer; if the work is a file, to keep working until that file exists (no longer suggesting "write it to a file and submit that": that suggestion was once used to route around this very check — see "no reviewer" under Submission below). Passing, the words are handed over (origin = answer, kept as content); checks and review follow as for files, the same words are never handed over twice, and a Bot that is not the ticket's producer hears once that only the owner hands over words.
  • Checks: a submission is held to the plan's checks on its ticket, those reading one of its files or anything in the ticket's folder, commands run there, and checks from your words bound to its files (synced first, so a new master gets bound). Only runs started after the submission count. Gates are checks you or the organizer wrote and checks from your words you confirmed; unconfirmed ones are measured and shown, never holding back a submission nor an approval.
  • No reviewer: a checked submission with no reviewer waits as submitted for the supervisor's next tick, which reads the checks as they are then (see there); a gate not finished yet is waited for.
  • A routine's runs: what a ticket of a routine's standing plan (the one each due time opens) hands over gets no approve/reject card and no required-items card: it is approved once its gates pass (submission.approved, by: routine), or on a reviewer's approve when one is set; a failing gate bound to the run still sends it back (a plan-wide check binds no ticket a later run opens, so none holds a routine's run back for now); when a result is wrong, saying so still sends it back to rework when the reader reads the fault. A routine runs unattended by design, and on 2026-10-03 and 10-04 the morning brief waited for your Approve both days, never once sent back (from 2026-10-04; a card left waiting from before is approved and put away at the next tick, against the checks as they are then).
  • Details at GET /v1/tasks/:id/submissions (local and remote); the board shows stages, parts passed and the reviewer. Levels 4 and below have no submissions: handing files over moves a ticket to In review, as before.

Avoid: treating a cited path as a submission, moving a ticket to review without running its checks, submitting the same bytes twice, submitting into another ticket's folder, taking a reviewer's notes for a submission, leaving a ticket with no file unable to close, approving on the organizer's, an answer's or a reviewer's own say with nobody's work behind it, approving a file hand-over no check of yours backs, treating a status line as the answer handed over, letting a Bot that is not the owner hand over words, making approval a card you must press, reading moving on in your direct as not letting it through

Review

From engine level 5, another Bot's verdict on a submission, given with review: pass, fail, unknown or n/a for each required item (anything you said twice or more, anything about the picture), a pass with its evidence, then approve or reject. With a reviewer set only it may review, otherwise only a Bot in the plan's conversation. Before an approval the app runs the checks again, and it is refused while a gate fails (an unconfirmed proposal never blocks); a pass on anything about the picture needs an image of this job's folder read after the submission; a reviewer on the producer's own model is marked, and its pass on anything you said twice needs a passing check you confirmed, or your word — without either, it waits on your word (letting it through counts those items as met), and the ball is yours; an unconfirmed proposal that passes only records what it measured. A rejection sends the ticket to rework and wakes the producer. An approval of words or an organizer's reading does not approve either, nor one of files no check you wrote or confirmed backs when the reviewer runs on the producer's own model (or either model is unknown) or gave no evidence — each waits on your word instead, the verdict kept with it. "Approved" in words moves nothing. Details: Behavior · Review.

Behavior details

Letting work through by your word (from 2026-10-11, ADR 0084): a hand-over that needs your 放行 gets no card; it waits on your word. The reading of your line (see Line reading) is also shown the hand-overs waiting on you where you speak — in that job's conversations; in a direct only that Bot's; the latest six — and names those your line lets through. A nod (「可以」「不错」「就这样」), using it or asking for the next step, and in your direct moving on to something else without a word about it, let it through; finding fault sends it back (see "Your complaint sends it back at once" below); a change or an addition has the Bot make a new version; a question about it, a status question, a stop, a go on, a bare acknowledgement or "let me look", and in a group a line to another Bot do not count; a sample takes a clear yes or a call to go on. While its Bot works on what you said about it since, the old hand-over is not shown; the new version waits once handed over. It goes as 放行 on a card did: gates run again, a failing one sends it back, one not run yet is waited for; unbacked items count as met and a reviewer's approve takes effect; it is logged as yours (submission.approved, by: user, with your line's message_id), and on the trace your line is a 放行 decision card. Nothing is said under your line in the conversation, and there is no undo: if it was misread, say what is wrong and it goes back. Before 2026-10-14 your line said 「已放行:……」 ("Approved: …"; or 「检查没过,已退回:……」, 「等检查跑完再放行:……」): letting work through or sending it back is the app judging on your behalf, and the conversation need not say it again. One its checks sent back is no decision card on the flow: the ticket is back in rework there with the failing check, and the Bot that made it is told. With no reading nothing is let through. The paragraphs on the approval card below are about cards put up before 2026-10-11: they still take a press, and one whose hand-over your word let through says 「已放行。」 and loses its buttons.

The approval card: a card asking you to approve or send back a hand-over carries its files, to open and look at before 放行 / 退回. On a card the app posts, the first five files are each a small chip whose icon follows the extension (video, image, JSON, Markdown…; a picture shows its thumbnail), and after them always comes the same entry a Bot's message ends with, reading "N files", which opens every file of the card in the preview beside the chat. A chip opens its file over the whole app, the way a picture is enlarged: that one file, with no file tree, and annotations work as usual; Escape, a click outside, the close button or the phone's Back puts it away, asking first about unsaved changes (2026-10-06; the card used to list every file with one page icon, and a chip opened the preview beside the chat). The card says in plain words what came in and why it is yours to decide — the reviewer runs on the same model as the Bot that made it (a model passing its own kind of work does not count), the reviewer gave no grounds on what you asked, or there is no reviewer and no check you confirmed. It used to name the files only as paths in its words, with nothing to open, and give its reason as "a hand-over no check you confirmed backs" and "(fixture, the same model as the producer)" (2026-10-03). 退回 first opens a box under the card asking what should change (optional), and only "Send it back" in it sends it back: anything written there goes word for word to the Bot that made it (its rework turn reads "要改的地方,原话:「…」"), and the card then says "已退回:「…」". It also counts as your own words on the job, as an answer on a question card does: read into the requirement ledger, measured for numbers to check, and listed among your words in every later turn of the Bot (it used to reach the Bot once, as its rework note: on 2026-10-04 「一集时长20分钟,不是这么短的视频,而且要有剧情走向」 sent back with a 《一拳超人》 hand-over never reached the ledger, and the rework came back as a 27-second cut); note on POST /v1/messages/:id/control goes only with that press and is refused on any other. Before, 退回 was a bare button and the Bot was told only that you had sent it back, left to guess what was wrong (2026-10-04). On the phone neither button could be pressed until then: the phone's allowed buttons were written out in the relay route and had not kept up with the cards added since (from 2026-10-04 they come from the same list in the protocol). The situation's ticket list leaves dropped tickets out (but this turn's own), says who made an approved one, and nobody on one set aside — the opening ticket folded by the lead's layout read "parked; 设计师 on it" to the Bots, the approved slogans "approved; 文案 on it" (2026-10-04). Up to 6 files on the card are listed one by one (pictures with thumbnails) rather than folded into one folder as on other messages; where files do fold into a folder, it is named after the folder they are actually in (a ticket's folder, say), not the "work" every job's files share (on 2026-10-04's real-model run the card read "work · 3 files", and the poster was a folder away).

A card that waited (no card goes up since 2026-10-11, so none waits): while its Bot is still at work the card is held back and goes up when it stops; when that is more than 10 minutes after the hand-over and the Bot has sent other files in the job since, the card's first line says when this version was handed over and how many files came after it (and the latest one's name), which this approval does not cover. On the IG MV job the card for the 2D quarter-final cut handed over at 00:39 waited three hours and came up right under the Bot's new 3D sample shot; 放行 was pressed on the old cut.

Your approval is logged as yours: an approval you press on a card, or say, is recorded as yours (submission.approved with by: user, and your line's message_id when said; the ticket's stage change with source: user); before 2026-10-10 every one was recorded as the app approving on its own (by: no_reviewer), so for history the press recorded on the card is what tells.

Where cards go: the cards about one Bot's work — approve or send back (none since 2026-10-11), items waiting on you, the capability ceiling, a reflection's proposal — go to where you last spoke about the job: a group, or your direct with that Bot, never your direct with another of the job's Bots; past one you have left or archived, to the one before; with none, to the job's conversation. A line that sends work back to rework posts no card and says nothing in the conversation: on the flow it is a rework decision card. They all used to go to the job's conversation: on 2026-10-04 a job opened in a group and taken up that morning in your direct with the video director asked you to sign off in the direct while its card landed in the group. When you send work back, send it to rework or answer a ceiling card in your direct with the Bot that made it, it redoes the work in that direct (queued work otherwise runs where it began; a delegation in its own conversation): sent back from your direct with the copywriter, the slogans used to be redone in the group the job was opened in, and the new version landed there (2026-10-04, real-model run).

From level 5, another Bot judges a submission with review({submission_id?, verdicts, outcome, note?}); "approved" in words moves nothing. With a reviewer set on the ticket only it may review; otherwise only a Bot in the plan's conversation; the producer never reviews its own. A review needs a ticket that is submitted or in review. Without submission_id it takes the newest submission waiting on its ticket, its plan, a ticket it reviews, or a plan of the conversation it runs in. When a submission passes its checks and the ticket has a reviewer, a line asking for the review is queued in the reviewer's work item (source = review, priority 2) and dispatched at once.

  • Required items are the requirements in force on the job that you said twice or more, or whose category is about the picture (picture, shot, character, colour and the like). They need a pass with evidence to approve — unknown, n/a, no verdict or no evidence will not do; the rest may be n/a.

  • Before an approval the app runs the checks again, and refuses the approval, changing nothing and returning each reason to the reviewer (review.refused), when a gate fails, a required item has no pass or no evidence, or something about the picture passed without this segment having read, after the submission, an image in this job's folder with read_file (one artifact.viewed per path and segment, outside the 80-row command record, and never counted as having run a command). An unconfirmed check from your words is not among them: it never blocks an approval.

  • Waiting on you: when the reviewer runs on the producer's own model and passes something you said twice or more that no passing check you confirmed, standing on its words, backs and you have not confirmed, the approval waits on you (review.awaiting_user) — an unconfirmed proposal that passes does not count, since a misread number can pass a wrong cut: it is refused with what the app measured, and the hand-over waits on your word (from 2026-10-11; before, its approve/reject card carried the reviewer's verdict and named the items and the measurements), the verdict and the items kept with it: saying it is fine counts them as met and the reviewer's approve with them; finding fault sends it to rework. One card per hand-over (from 2026-10-07; before, a card asked about the items alone — Confirm the check, Count it as met, No longer require it — and was often followed by an approval card to press as well). The ball is yours; meanwhile the producer is told nothing and never sent to rework to a number you have not confirmed, and the submission takes no other review. Saying nothing and making the item not hold here on the board instead, or confirming the check on the flow board when it then passes, lets the supervisor's next tick approve it when the card waited on these items alone (a check you confirmed backs the rest); a confirmed check that fails sends it back to its producer at the next tick. A same-model review is marked same_model whatever its outcome.

  • A rejection always records: the ticket and its parts go to rework and the producer's work item wakes with the review's note. An approval: the ticket and parts are approved, the producer reads it when it next wakes (it is not woken for it), and the plan may be delivered — unless this submission is words or an organizer's reading (nobody actually made either), or files no check you wrote or confirmed backs while the reviewer runs on the producer's own model (or either model is unknown) or gave no evidence on a requirement that applies: then a reviewer's approve does not approve it; it moves the submission to awaiting your word, that verdict kept with it (see Supervisor).

  • In F-f: you said "about 2 minutes" twice; 审片员, on the same model as the director, passes it on the 107-second master and approves. The app runs ffprobe again and gets 107.00 s — the proposal is not confirmed, so it blocks nothing — but a same-model pass has no passing check behind it, so the approval waits on you: the refusal says "107.00 秒,要时长 108–132 秒", and the director hears nothing. You say what is wrong (it goes back to rework), or confirm the check on the flow board: it is a gate, measures a failure, and at the next tick the master goes back to the director, now against a number you confirmed.

  • Your complaint sends it back at once (from 2026-10-09, ADR 0070): a line of yours filed (by the rows or by you, not by a Bot's pick) under a ticket — or some of its parts — that is submitted, in review or approved (or filed only under the plan, when the plan's submitted, in-review or approved work is a single ticket whose maker is still here, neither archived nor deleted; with several, which one is meant is a guess, and nothing moves), in which line reading (a model) quotes a clause objecting to the work (a fault, dissatisfaction, a redo or a start over asked for, what came before scrapped; not praise, a redo turned down such as 别重做 or 不用从头再做, a question, a condition, another time or version, or something settled), sends that ticket back to rework there and then: the parts the line is filed under (else the whole ticket), never shot numbers picked from the clauses; a hand-over still waiting on you is superseded and its card taken down, every review that approved the current hand-over counts one miss (review.miss), a delivered plan is active again, and the Bot that made it is woken with your words — a Stop you pressed on its work in that job goes, as at 退回 on a card, even when the line was said to another Bot. Nothing is said under your line in the conversation; on the flow it is a rework decision card, A misreading has no undo here: the ticket stays in rework, it still counts as one send-back of yours and the reviewer's miss stands; to have the same version handed back, tell the Bot that made it. Before 2026-10-14 your line said 「已转回返工:……」 ("Sent back to rework: …") with Undo — while no newer hand-over had come and the ticket was still in rework, Undo put everything back and the misses no longer counted, and the Bot's call to rework was dropped if unread, or it was told the rework was taken back; when one line sent several tickets back, Undo put back only the last. That Undo went with the line; Undo on an older complaint card (the app's own line) still works. A line the reader cannot read (the word lists read it) sends nothing back; an annotation, a part-level entry from the scribe, or a mere reply to the line that carried the files no longer counts as a complaint by itself. The line still wakes whom it wakes (the lead, in a group with one), and that turn's situation says the line reads as a complaint about the handed-over ticket, which has gone back to rework with its maker told in these words, and not to hand the fix to anyone else. Before, the lead was not told and could hand the fix to someone else as well, the work twice (2026-10-04). It used to post a card first — "You said "…" — send it back to rework?" [Send back to rework] [Leave it] — the app asking about what you had just said; a card left from then can still be pressed. Approval stays a press on the card: no text ever approves (no longer so from 2026-10-11: approval goes by your word too, see "Letting work through by your word" above).

  • Calibration record: a reviewer's situation lists its approvals you overturned in that conversation (newest five, with your words and when), to judge the same kind of thing harder.

  • Capability ceiling: when a hand-over fails (its checks, a review's reject, your send-back on a card, or your finding fault that sends it back to rework), each part it covers (else the whole ticket, counting only hand-overs of no part) that, since you last answered a ceiling card about it, has failed the same requirement three hand-overs in a row, been sent back by you three times in a row, or failed more than six hand-overs, is stuck: the part reads Blocked, nothing more is handed over for it (submit gets ceiling_reached), a hand-over of no part is refused while a part is stuck, the ball is yours, the supervisor wakes nobody for it, and the producer only hears that you are being asked; a card asks — Another way, Change the plan, Relax this requirement (only when stuck on one; pressing it is your confirmation, and the requirement no longer holds for the plan), Take it as it is, Ignore, carry on. The first three and Ignore send it back to rework, tell the producer what you chose (Ignore gives no new direction, only that it goes on from what it was already told) and restart the count; Take it as it is approves the part, and the ticket once all its parts are approved or waived. When the ticket closes another way (approved, your board edit), a card still asking says why and loses its buttons. A send-back of yours need name no requirement: each send-back, on a card or by finding fault, counts as one; three in a row put up a card saying "you sent it back 3 times in a row", with no Relax. Undoing that rework takes it out of the count and takes down the card it put up. Only checks and reviews used to count: in October 2026 the MV's ticket 09 was sent back eight times, none tied to a requirement, the streak never formed, and it stopped only at the seventh hand-over (2026-10-11). A hand-over replaced by a newer version still does not count.

  • Pictures are a reference: when a seams check hands pictures to a model (video frames, images), that result is a reference only — shown in a hand-over's checks as judged by a model looking at pictures, it neither blocks nor backs an approval, and a plan-wide one does not hold the plan's delivery back. No pictures are judged while a stop covers the plan, nor once today's picture judging has cost $5; that run reads as not judged. A Bot's situation labels it as for reference only too. A text-only seams check is unchanged.

Avoid: reviewing your own submission, approving with an "APPROVED" in words, a review overruling a failing gate, passing the picture without reading frames, letting an unconfirmed number block an approval, sending a Bot to rework to a number you have not confirmed, treating a reviewer's approve of words or an organizer's reading as the actual approval

Review miss

From engine level 5, the mark a review gets when it approved a hand-over and your complaint then sent that hand-over back to rework (at once, when the reader reads the fault; it used to take a press on a card) (review.miss, once per hand-over and reviewer). It goes into the reviewer's calibration record: its situation lists the approvals you overturned in that conversation (newest five, with your words), to judge the same kind of thing harder. Undoing the complaint's rework drops it. Details: Behavior · Review.

Behavior details

Letting work through by your word (from 2026-10-11, ADR 0084): a hand-over that needs your 放行 gets no card; it waits on your word. The reading of your line (see Line reading) is also shown the hand-overs waiting on you where you speak — in that job's conversations; in a direct only that Bot's; the latest six — and names those your line lets through. A nod (「可以」「不错」「就这样」), using it or asking for the next step, and in your direct moving on to something else without a word about it, let it through; finding fault sends it back (see "Your complaint sends it back at once" below); a change or an addition has the Bot make a new version; a question about it, a status question, a stop, a go on, a bare acknowledgement or "let me look", and in a group a line to another Bot do not count; a sample takes a clear yes or a call to go on. While its Bot works on what you said about it since, the old hand-over is not shown; the new version waits once handed over. It goes as 放行 on a card did: gates run again, a failing one sends it back, one not run yet is waited for; unbacked items count as met and a reviewer's approve takes effect; it is logged as yours (submission.approved, by: user, with your line's message_id), and on the trace your line is a 放行 decision card. Nothing is said under your line in the conversation, and there is no undo: if it was misread, say what is wrong and it goes back. Before 2026-10-14 your line said 「已放行:……」 ("Approved: …"; or 「检查没过,已退回:……」, 「等检查跑完再放行:……」): letting work through or sending it back is the app judging on your behalf, and the conversation need not say it again. One its checks sent back is no decision card on the flow: the ticket is back in rework there with the failing check, and the Bot that made it is told. With no reading nothing is let through. The paragraphs on the approval card below are about cards put up before 2026-10-11: they still take a press, and one whose hand-over your word let through says 「已放行。」 and loses its buttons.

The approval card: a card asking you to approve or send back a hand-over carries its files, to open and look at before 放行 / 退回. On a card the app posts, the first five files are each a small chip whose icon follows the extension (video, image, JSON, Markdown…; a picture shows its thumbnail), and after them always comes the same entry a Bot's message ends with, reading "N files", which opens every file of the card in the preview beside the chat. A chip opens its file over the whole app, the way a picture is enlarged: that one file, with no file tree, and annotations work as usual; Escape, a click outside, the close button or the phone's Back puts it away, asking first about unsaved changes (2026-10-06; the card used to list every file with one page icon, and a chip opened the preview beside the chat). The card says in plain words what came in and why it is yours to decide — the reviewer runs on the same model as the Bot that made it (a model passing its own kind of work does not count), the reviewer gave no grounds on what you asked, or there is no reviewer and no check you confirmed. It used to name the files only as paths in its words, with nothing to open, and give its reason as "a hand-over no check you confirmed backs" and "(fixture, the same model as the producer)" (2026-10-03). 退回 first opens a box under the card asking what should change (optional), and only "Send it back" in it sends it back: anything written there goes word for word to the Bot that made it (its rework turn reads "要改的地方,原话:「…」"), and the card then says "已退回:「…」". It also counts as your own words on the job, as an answer on a question card does: read into the requirement ledger, measured for numbers to check, and listed among your words in every later turn of the Bot (it used to reach the Bot once, as its rework note: on 2026-10-04 「一集时长20分钟,不是这么短的视频,而且要有剧情走向」 sent back with a 《一拳超人》 hand-over never reached the ledger, and the rework came back as a 27-second cut); note on POST /v1/messages/:id/control goes only with that press and is refused on any other. Before, 退回 was a bare button and the Bot was told only that you had sent it back, left to guess what was wrong (2026-10-04). On the phone neither button could be pressed until then: the phone's allowed buttons were written out in the relay route and had not kept up with the cards added since (from 2026-10-04 they come from the same list in the protocol). The situation's ticket list leaves dropped tickets out (but this turn's own), says who made an approved one, and nobody on one set aside — the opening ticket folded by the lead's layout read "parked; 设计师 on it" to the Bots, the approved slogans "approved; 文案 on it" (2026-10-04). Up to 6 files on the card are listed one by one (pictures with thumbnails) rather than folded into one folder as on other messages; where files do fold into a folder, it is named after the folder they are actually in (a ticket's folder, say), not the "work" every job's files share (on 2026-10-04's real-model run the card read "work · 3 files", and the poster was a folder away).

A card that waited (no card goes up since 2026-10-11, so none waits): while its Bot is still at work the card is held back and goes up when it stops; when that is more than 10 minutes after the hand-over and the Bot has sent other files in the job since, the card's first line says when this version was handed over and how many files came after it (and the latest one's name), which this approval does not cover. On the IG MV job the card for the 2D quarter-final cut handed over at 00:39 waited three hours and came up right under the Bot's new 3D sample shot; 放行 was pressed on the old cut.

Your approval is logged as yours: an approval you press on a card, or say, is recorded as yours (submission.approved with by: user, and your line's message_id when said; the ticket's stage change with source: user); before 2026-10-10 every one was recorded as the app approving on its own (by: no_reviewer), so for history the press recorded on the card is what tells.

Where cards go: the cards about one Bot's work — approve or send back (none since 2026-10-11), items waiting on you, the capability ceiling, a reflection's proposal — go to where you last spoke about the job: a group, or your direct with that Bot, never your direct with another of the job's Bots; past one you have left or archived, to the one before; with none, to the job's conversation. A line that sends work back to rework posts no card and says nothing in the conversation: on the flow it is a rework decision card. They all used to go to the job's conversation: on 2026-10-04 a job opened in a group and taken up that morning in your direct with the video director asked you to sign off in the direct while its card landed in the group. When you send work back, send it to rework or answer a ceiling card in your direct with the Bot that made it, it redoes the work in that direct (queued work otherwise runs where it began; a delegation in its own conversation): sent back from your direct with the copywriter, the slogans used to be redone in the group the job was opened in, and the new version landed there (2026-10-04, real-model run).

From level 5, another Bot judges a submission with review({submission_id?, verdicts, outcome, note?}); "approved" in words moves nothing. With a reviewer set on the ticket only it may review; otherwise only a Bot in the plan's conversation; the producer never reviews its own. A review needs a ticket that is submitted or in review. Without submission_id it takes the newest submission waiting on its ticket, its plan, a ticket it reviews, or a plan of the conversation it runs in. When a submission passes its checks and the ticket has a reviewer, a line asking for the review is queued in the reviewer's work item (source = review, priority 2) and dispatched at once.

  • Required items are the requirements in force on the job that you said twice or more, or whose category is about the picture (picture, shot, character, colour and the like). They need a pass with evidence to approve — unknown, n/a, no verdict or no evidence will not do; the rest may be n/a.

  • Before an approval the app runs the checks again, and refuses the approval, changing nothing and returning each reason to the reviewer (review.refused), when a gate fails, a required item has no pass or no evidence, or something about the picture passed without this segment having read, after the submission, an image in this job's folder with read_file (one artifact.viewed per path and segment, outside the 80-row command record, and never counted as having run a command). An unconfirmed check from your words is not among them: it never blocks an approval.

  • Waiting on you: when the reviewer runs on the producer's own model and passes something you said twice or more that no passing check you confirmed, standing on its words, backs and you have not confirmed, the approval waits on you (review.awaiting_user) — an unconfirmed proposal that passes does not count, since a misread number can pass a wrong cut: it is refused with what the app measured, and the hand-over waits on your word (from 2026-10-11; before, its approve/reject card carried the reviewer's verdict and named the items and the measurements), the verdict and the items kept with it: saying it is fine counts them as met and the reviewer's approve with them; finding fault sends it to rework. One card per hand-over (from 2026-10-07; before, a card asked about the items alone — Confirm the check, Count it as met, No longer require it — and was often followed by an approval card to press as well). The ball is yours; meanwhile the producer is told nothing and never sent to rework to a number you have not confirmed, and the submission takes no other review. Saying nothing and making the item not hold here on the board instead, or confirming the check on the flow board when it then passes, lets the supervisor's next tick approve it when the card waited on these items alone (a check you confirmed backs the rest); a confirmed check that fails sends it back to its producer at the next tick. A same-model review is marked same_model whatever its outcome.

  • A rejection always records: the ticket and its parts go to rework and the producer's work item wakes with the review's note. An approval: the ticket and parts are approved, the producer reads it when it next wakes (it is not woken for it), and the plan may be delivered — unless this submission is words or an organizer's reading (nobody actually made either), or files no check you wrote or confirmed backs while the reviewer runs on the producer's own model (or either model is unknown) or gave no evidence on a requirement that applies: then a reviewer's approve does not approve it; it moves the submission to awaiting your word, that verdict kept with it (see Supervisor).

  • In F-f: you said "about 2 minutes" twice; 审片员, on the same model as the director, passes it on the 107-second master and approves. The app runs ffprobe again and gets 107.00 s — the proposal is not confirmed, so it blocks nothing — but a same-model pass has no passing check behind it, so the approval waits on you: the refusal says "107.00 秒,要时长 108–132 秒", and the director hears nothing. You say what is wrong (it goes back to rework), or confirm the check on the flow board: it is a gate, measures a failure, and at the next tick the master goes back to the director, now against a number you confirmed.

  • Your complaint sends it back at once (from 2026-10-09, ADR 0070): a line of yours filed (by the rows or by you, not by a Bot's pick) under a ticket — or some of its parts — that is submitted, in review or approved (or filed only under the plan, when the plan's submitted, in-review or approved work is a single ticket whose maker is still here, neither archived nor deleted; with several, which one is meant is a guess, and nothing moves), in which line reading (a model) quotes a clause objecting to the work (a fault, dissatisfaction, a redo or a start over asked for, what came before scrapped; not praise, a redo turned down such as 别重做 or 不用从头再做, a question, a condition, another time or version, or something settled), sends that ticket back to rework there and then: the parts the line is filed under (else the whole ticket), never shot numbers picked from the clauses; a hand-over still waiting on you is superseded and its card taken down, every review that approved the current hand-over counts one miss (review.miss), a delivered plan is active again, and the Bot that made it is woken with your words — a Stop you pressed on its work in that job goes, as at 退回 on a card, even when the line was said to another Bot. Nothing is said under your line in the conversation; on the flow it is a rework decision card, A misreading has no undo here: the ticket stays in rework, it still counts as one send-back of yours and the reviewer's miss stands; to have the same version handed back, tell the Bot that made it. Before 2026-10-14 your line said 「已转回返工:……」 ("Sent back to rework: …") with Undo — while no newer hand-over had come and the ticket was still in rework, Undo put everything back and the misses no longer counted, and the Bot's call to rework was dropped if unread, or it was told the rework was taken back; when one line sent several tickets back, Undo put back only the last. That Undo went with the line; Undo on an older complaint card (the app's own line) still works. A line the reader cannot read (the word lists read it) sends nothing back; an annotation, a part-level entry from the scribe, or a mere reply to the line that carried the files no longer counts as a complaint by itself. The line still wakes whom it wakes (the lead, in a group with one), and that turn's situation says the line reads as a complaint about the handed-over ticket, which has gone back to rework with its maker told in these words, and not to hand the fix to anyone else. Before, the lead was not told and could hand the fix to someone else as well, the work twice (2026-10-04). It used to post a card first — "You said "…" — send it back to rework?" [Send back to rework] [Leave it] — the app asking about what you had just said; a card left from then can still be pressed. Approval stays a press on the card: no text ever approves (no longer so from 2026-10-11: approval goes by your word too, see "Letting work through by your word" above).

  • Calibration record: a reviewer's situation lists its approvals you overturned in that conversation (newest five, with your words and when), to judge the same kind of thing harder.

  • Capability ceiling: when a hand-over fails (its checks, a review's reject, your send-back on a card, or your finding fault that sends it back to rework), each part it covers (else the whole ticket, counting only hand-overs of no part) that, since you last answered a ceiling card about it, has failed the same requirement three hand-overs in a row, been sent back by you three times in a row, or failed more than six hand-overs, is stuck: the part reads Blocked, nothing more is handed over for it (submit gets ceiling_reached), a hand-over of no part is refused while a part is stuck, the ball is yours, the supervisor wakes nobody for it, and the producer only hears that you are being asked; a card asks — Another way, Change the plan, Relax this requirement (only when stuck on one; pressing it is your confirmation, and the requirement no longer holds for the plan), Take it as it is, Ignore, carry on. The first three and Ignore send it back to rework, tell the producer what you chose (Ignore gives no new direction, only that it goes on from what it was already told) and restart the count; Take it as it is approves the part, and the ticket once all its parts are approved or waived. When the ticket closes another way (approved, your board edit), a card still asking says why and loses its buttons. A send-back of yours need name no requirement: each send-back, on a card or by finding fault, counts as one; three in a row put up a card saying "you sent it back 3 times in a row", with no Relax. Undoing that rework takes it out of the count and takes down the card it put up. Only checks and reviews used to count: in October 2026 the MV's ticket 09 was sent back eight times, none tied to a requirement, the streak never formed, and it stopped only at the seventh hand-over (2026-10-11). A hand-over replaced by a newer version still does not count.

  • Pictures are a reference: when a seams check hands pictures to a model (video frames, images), that result is a reference only — shown in a hand-over's checks as judged by a model looking at pictures, it neither blocks nor backs an approval, and a plan-wide one does not hold the plan's delivery back. No pictures are judged while a stop covers the plan, nor once today's picture judging has cost $5; that run reads as not judged. A Bot's situation labels it as for reference only too. A text-only seams check is unchanged.

Avoid: treating misses as a score to punish a Bot, counting your Send back on a card as a miss, keeping a miss after you undid the complaint

Capability ceiling

From engine level 5, a part (else the whole ticket) that, since you last answered a ceiling card about it, failed the same requirement three hand-overs in a row, was sent back by you three times in a row (on a card, or by finding fault in what you said, tied to no requirement), or failed more than six hand-overs stops and asks you: the part reads Blocked, nothing more is handed over for it, the ball is yours and the supervisor wakes nobody for it; the card offers Another way, Change the plan, Relax this requirement (pressing it confirms the requirement no longer holds), Take it as it is, and Ignore, carry on (no new direction: it goes on from what it was already told). Details: Behavior · Review.

Behavior details

Letting work through by your word (from 2026-10-11, ADR 0084): a hand-over that needs your 放行 gets no card; it waits on your word. The reading of your line (see Line reading) is also shown the hand-overs waiting on you where you speak — in that job's conversations; in a direct only that Bot's; the latest six — and names those your line lets through. A nod (「可以」「不错」「就这样」), using it or asking for the next step, and in your direct moving on to something else without a word about it, let it through; finding fault sends it back (see "Your complaint sends it back at once" below); a change or an addition has the Bot make a new version; a question about it, a status question, a stop, a go on, a bare acknowledgement or "let me look", and in a group a line to another Bot do not count; a sample takes a clear yes or a call to go on. While its Bot works on what you said about it since, the old hand-over is not shown; the new version waits once handed over. It goes as 放行 on a card did: gates run again, a failing one sends it back, one not run yet is waited for; unbacked items count as met and a reviewer's approve takes effect; it is logged as yours (submission.approved, by: user, with your line's message_id), and on the trace your line is a 放行 decision card. Nothing is said under your line in the conversation, and there is no undo: if it was misread, say what is wrong and it goes back. Before 2026-10-14 your line said 「已放行:……」 ("Approved: …"; or 「检查没过,已退回:……」, 「等检查跑完再放行:……」): letting work through or sending it back is the app judging on your behalf, and the conversation need not say it again. One its checks sent back is no decision card on the flow: the ticket is back in rework there with the failing check, and the Bot that made it is told. With no reading nothing is let through. The paragraphs on the approval card below are about cards put up before 2026-10-11: they still take a press, and one whose hand-over your word let through says 「已放行。」 and loses its buttons.

The approval card: a card asking you to approve or send back a hand-over carries its files, to open and look at before 放行 / 退回. On a card the app posts, the first five files are each a small chip whose icon follows the extension (video, image, JSON, Markdown…; a picture shows its thumbnail), and after them always comes the same entry a Bot's message ends with, reading "N files", which opens every file of the card in the preview beside the chat. A chip opens its file over the whole app, the way a picture is enlarged: that one file, with no file tree, and annotations work as usual; Escape, a click outside, the close button or the phone's Back puts it away, asking first about unsaved changes (2026-10-06; the card used to list every file with one page icon, and a chip opened the preview beside the chat). The card says in plain words what came in and why it is yours to decide — the reviewer runs on the same model as the Bot that made it (a model passing its own kind of work does not count), the reviewer gave no grounds on what you asked, or there is no reviewer and no check you confirmed. It used to name the files only as paths in its words, with nothing to open, and give its reason as "a hand-over no check you confirmed backs" and "(fixture, the same model as the producer)" (2026-10-03). 退回 first opens a box under the card asking what should change (optional), and only "Send it back" in it sends it back: anything written there goes word for word to the Bot that made it (its rework turn reads "要改的地方,原话:「…」"), and the card then says "已退回:「…」". It also counts as your own words on the job, as an answer on a question card does: read into the requirement ledger, measured for numbers to check, and listed among your words in every later turn of the Bot (it used to reach the Bot once, as its rework note: on 2026-10-04 「一集时长20分钟,不是这么短的视频,而且要有剧情走向」 sent back with a 《一拳超人》 hand-over never reached the ledger, and the rework came back as a 27-second cut); note on POST /v1/messages/:id/control goes only with that press and is refused on any other. Before, 退回 was a bare button and the Bot was told only that you had sent it back, left to guess what was wrong (2026-10-04). On the phone neither button could be pressed until then: the phone's allowed buttons were written out in the relay route and had not kept up with the cards added since (from 2026-10-04 they come from the same list in the protocol). The situation's ticket list leaves dropped tickets out (but this turn's own), says who made an approved one, and nobody on one set aside — the opening ticket folded by the lead's layout read "parked; 设计师 on it" to the Bots, the approved slogans "approved; 文案 on it" (2026-10-04). Up to 6 files on the card are listed one by one (pictures with thumbnails) rather than folded into one folder as on other messages; where files do fold into a folder, it is named after the folder they are actually in (a ticket's folder, say), not the "work" every job's files share (on 2026-10-04's real-model run the card read "work · 3 files", and the poster was a folder away).

A card that waited (no card goes up since 2026-10-11, so none waits): while its Bot is still at work the card is held back and goes up when it stops; when that is more than 10 minutes after the hand-over and the Bot has sent other files in the job since, the card's first line says when this version was handed over and how many files came after it (and the latest one's name), which this approval does not cover. On the IG MV job the card for the 2D quarter-final cut handed over at 00:39 waited three hours and came up right under the Bot's new 3D sample shot; 放行 was pressed on the old cut.

Your approval is logged as yours: an approval you press on a card, or say, is recorded as yours (submission.approved with by: user, and your line's message_id when said; the ticket's stage change with source: user); before 2026-10-10 every one was recorded as the app approving on its own (by: no_reviewer), so for history the press recorded on the card is what tells.

Where cards go: the cards about one Bot's work — approve or send back (none since 2026-10-11), items waiting on you, the capability ceiling, a reflection's proposal — go to where you last spoke about the job: a group, or your direct with that Bot, never your direct with another of the job's Bots; past one you have left or archived, to the one before; with none, to the job's conversation. A line that sends work back to rework posts no card and says nothing in the conversation: on the flow it is a rework decision card. They all used to go to the job's conversation: on 2026-10-04 a job opened in a group and taken up that morning in your direct with the video director asked you to sign off in the direct while its card landed in the group. When you send work back, send it to rework or answer a ceiling card in your direct with the Bot that made it, it redoes the work in that direct (queued work otherwise runs where it began; a delegation in its own conversation): sent back from your direct with the copywriter, the slogans used to be redone in the group the job was opened in, and the new version landed there (2026-10-04, real-model run).

From level 5, another Bot judges a submission with review({submission_id?, verdicts, outcome, note?}); "approved" in words moves nothing. With a reviewer set on the ticket only it may review; otherwise only a Bot in the plan's conversation; the producer never reviews its own. A review needs a ticket that is submitted or in review. Without submission_id it takes the newest submission waiting on its ticket, its plan, a ticket it reviews, or a plan of the conversation it runs in. When a submission passes its checks and the ticket has a reviewer, a line asking for the review is queued in the reviewer's work item (source = review, priority 2) and dispatched at once.

  • Required items are the requirements in force on the job that you said twice or more, or whose category is about the picture (picture, shot, character, colour and the like). They need a pass with evidence to approve — unknown, n/a, no verdict or no evidence will not do; the rest may be n/a.

  • Before an approval the app runs the checks again, and refuses the approval, changing nothing and returning each reason to the reviewer (review.refused), when a gate fails, a required item has no pass or no evidence, or something about the picture passed without this segment having read, after the submission, an image in this job's folder with read_file (one artifact.viewed per path and segment, outside the 80-row command record, and never counted as having run a command). An unconfirmed check from your words is not among them: it never blocks an approval.

  • Waiting on you: when the reviewer runs on the producer's own model and passes something you said twice or more that no passing check you confirmed, standing on its words, backs and you have not confirmed, the approval waits on you (review.awaiting_user) — an unconfirmed proposal that passes does not count, since a misread number can pass a wrong cut: it is refused with what the app measured, and the hand-over waits on your word (from 2026-10-11; before, its approve/reject card carried the reviewer's verdict and named the items and the measurements), the verdict and the items kept with it: saying it is fine counts them as met and the reviewer's approve with them; finding fault sends it to rework. One card per hand-over (from 2026-10-07; before, a card asked about the items alone — Confirm the check, Count it as met, No longer require it — and was often followed by an approval card to press as well). The ball is yours; meanwhile the producer is told nothing and never sent to rework to a number you have not confirmed, and the submission takes no other review. Saying nothing and making the item not hold here on the board instead, or confirming the check on the flow board when it then passes, lets the supervisor's next tick approve it when the card waited on these items alone (a check you confirmed backs the rest); a confirmed check that fails sends it back to its producer at the next tick. A same-model review is marked same_model whatever its outcome.

  • A rejection always records: the ticket and its parts go to rework and the producer's work item wakes with the review's note. An approval: the ticket and parts are approved, the producer reads it when it next wakes (it is not woken for it), and the plan may be delivered — unless this submission is words or an organizer's reading (nobody actually made either), or files no check you wrote or confirmed backs while the reviewer runs on the producer's own model (or either model is unknown) or gave no evidence on a requirement that applies: then a reviewer's approve does not approve it; it moves the submission to awaiting your word, that verdict kept with it (see Supervisor).

  • In F-f: you said "about 2 minutes" twice; 审片员, on the same model as the director, passes it on the 107-second master and approves. The app runs ffprobe again and gets 107.00 s — the proposal is not confirmed, so it blocks nothing — but a same-model pass has no passing check behind it, so the approval waits on you: the refusal says "107.00 秒,要时长 108–132 秒", and the director hears nothing. You say what is wrong (it goes back to rework), or confirm the check on the flow board: it is a gate, measures a failure, and at the next tick the master goes back to the director, now against a number you confirmed.

  • Your complaint sends it back at once (from 2026-10-09, ADR 0070): a line of yours filed (by the rows or by you, not by a Bot's pick) under a ticket — or some of its parts — that is submitted, in review or approved (or filed only under the plan, when the plan's submitted, in-review or approved work is a single ticket whose maker is still here, neither archived nor deleted; with several, which one is meant is a guess, and nothing moves), in which line reading (a model) quotes a clause objecting to the work (a fault, dissatisfaction, a redo or a start over asked for, what came before scrapped; not praise, a redo turned down such as 别重做 or 不用从头再做, a question, a condition, another time or version, or something settled), sends that ticket back to rework there and then: the parts the line is filed under (else the whole ticket), never shot numbers picked from the clauses; a hand-over still waiting on you is superseded and its card taken down, every review that approved the current hand-over counts one miss (review.miss), a delivered plan is active again, and the Bot that made it is woken with your words — a Stop you pressed on its work in that job goes, as at 退回 on a card, even when the line was said to another Bot. Nothing is said under your line in the conversation; on the flow it is a rework decision card, A misreading has no undo here: the ticket stays in rework, it still counts as one send-back of yours and the reviewer's miss stands; to have the same version handed back, tell the Bot that made it. Before 2026-10-14 your line said 「已转回返工:……」 ("Sent back to rework: …") with Undo — while no newer hand-over had come and the ticket was still in rework, Undo put everything back and the misses no longer counted, and the Bot's call to rework was dropped if unread, or it was told the rework was taken back; when one line sent several tickets back, Undo put back only the last. That Undo went with the line; Undo on an older complaint card (the app's own line) still works. A line the reader cannot read (the word lists read it) sends nothing back; an annotation, a part-level entry from the scribe, or a mere reply to the line that carried the files no longer counts as a complaint by itself. The line still wakes whom it wakes (the lead, in a group with one), and that turn's situation says the line reads as a complaint about the handed-over ticket, which has gone back to rework with its maker told in these words, and not to hand the fix to anyone else. Before, the lead was not told and could hand the fix to someone else as well, the work twice (2026-10-04). It used to post a card first — "You said "…" — send it back to rework?" [Send back to rework] [Leave it] — the app asking about what you had just said; a card left from then can still be pressed. Approval stays a press on the card: no text ever approves (no longer so from 2026-10-11: approval goes by your word too, see "Letting work through by your word" above).

  • Calibration record: a reviewer's situation lists its approvals you overturned in that conversation (newest five, with your words and when), to judge the same kind of thing harder.

  • Capability ceiling: when a hand-over fails (its checks, a review's reject, your send-back on a card, or your finding fault that sends it back to rework), each part it covers (else the whole ticket, counting only hand-overs of no part) that, since you last answered a ceiling card about it, has failed the same requirement three hand-overs in a row, been sent back by you three times in a row, or failed more than six hand-overs, is stuck: the part reads Blocked, nothing more is handed over for it (submit gets ceiling_reached), a hand-over of no part is refused while a part is stuck, the ball is yours, the supervisor wakes nobody for it, and the producer only hears that you are being asked; a card asks — Another way, Change the plan, Relax this requirement (only when stuck on one; pressing it is your confirmation, and the requirement no longer holds for the plan), Take it as it is, Ignore, carry on. The first three and Ignore send it back to rework, tell the producer what you chose (Ignore gives no new direction, only that it goes on from what it was already told) and restart the count; Take it as it is approves the part, and the ticket once all its parts are approved or waived. When the ticket closes another way (approved, your board edit), a card still asking says why and loses its buttons. A send-back of yours need name no requirement: each send-back, on a card or by finding fault, counts as one; three in a row put up a card saying "you sent it back 3 times in a row", with no Relax. Undoing that rework takes it out of the count and takes down the card it put up. Only checks and reviews used to count: in October 2026 the MV's ticket 09 was sent back eight times, none tied to a requirement, the streak never formed, and it stopped only at the seventh hand-over (2026-10-11). A hand-over replaced by a newer version still does not count.

  • Pictures are a reference: when a seams check hands pictures to a model (video frames, images), that result is a reference only — shown in a hand-over's checks as judged by a model looking at pictures, it neither blocks nor backs an approval, and a plan-wide one does not hold the plan's delivery back. No pictures are judged while a stop covers the plan, nor once today's picture judging has cost $5; that run reads as not judged. A Bot's situation labels it as for reference only too. A text-only seams check is unchanged.

Avoid: letting a Bot try the same way again once stuck, relaxing a requirement without asking you, treating a stuck part as a parked plan

External job

From engine level 6, one render a media server accepted (a paired submit_<x> / check_<x>, such as submit_video / check_video): registered when submitted and polled by the daemon itself, so a Bot's own check reads what the app last heard without reaching the server; done, failed or still pending after three hours, it wakes the Bot that submitted it and every Bot that checked on it. The same arguments within half an hour get the same job back; a part with a job running, or a result not handed over yet, takes a reason before it is submitted again. Details: Behavior · External job.

Behavior details

From level 6 (ADR 0047), a media server's paired submit_<x> / check_<x> (westlake-cpa's submit_video / check_video, for one) is waited on by the app:

  • Submitting: a submit that gets an id back is registered, and the Bot reads that the app polls it and wakes it when done. An answer in JSON is read as JSON; one written as key: value lines is read too (grok-imagine answers request_id: … so, a note in brackets at the end of a line not counting) — before, no such job was ever registered, and the Bot checked on it again and again inside its own turn. The same server, tool and arguments within half an hour get the job already started (deduped) without reaching the server, whatever the filing. When the prompt names exactly one part number and that part has a job running, or a finished result not handed over yet, a new submit is refused (job_pending); to submit again anyway, resubmit_reason says why (kept on the job, not sent to the server).
  • Checking: a Bot's check on a registered job reads what the app last heard (cached) without reaching the server, and the Bot becomes a waiter.
  • Polling: on each 15-second scheduler tick the daemon asks about the jobs due, outside any turn, every 30 s, 1, 2, 4, then 5 minutes. Done or failed, the Bot that submitted it and every Bot that checked on it are woken in their own conversations with the result (url, duration, cost; an answer written as lines is passed on whole, grok-imagine's "url is TEMPORARY — fetch promptly" included); one still pending after three hours is given up as lost and they are told so. While a job runs, the supervisor treats the ball as the job poller's and calls nobody back to poll it; a job a Bot submitted on the job as a whole, on no ticket yet, counts on the tickets that Bot holds.
  • Check-backs: from level 6 a Bot's own check-back is at least 5 minutes, at most six an hour per job, and refused when its note names a job being polled. It is refused too (ball_is_yours) while the ticket of the turn booking it waits on you — your answer (a question, its work blocked on you), your word on a hand-over, a capability ceiling card — and one booked earlier that comes due while it does is voided and wakes nobody (work log check_back.voided): what you say next wakes the Bot anyway. A stop of yours is not this: a check-back it covers is still set aside and comes back with the lift. Before, the director booked 22 check-backs on the MV, and 13 woke to nothing new after some 53 hops each, mostly "see what the user thinks of vN" (2026-10-08 to 10-11). Other tickets book as before.

Avoid: a Bot polling with one-minute check-backs, submitting the same arguments twice, treating a job as a Bot's turn

Quality event

From engine level 8, a work-log event that says something went wrong, filed by its type alone: execution (checks failed, a reject, a send-back, a complaint, a command timing out), unclear (a requirement that first came up after the hand-over), model (a reply that loops, declines, hits its cap), pipeline (a failed render, a part at the capability ceiling), review_miss (an approval you overturned), orchestration (a stall, a crash; for the maintainer only). No model is asked whether the model was at fault; you can mark a turn as the model's problem on its board card. A retrospective reads them for root causes, and what it writes into memories is a way of working, never the events themselves. Details: Behavior · Quality event, Lesson.

Behavior details

From level 8 (ADR 0050), no model call reviews a chain afterwards and writes its verdict into a memory; the one exception is the retrospective after a job you accepted is delivered (ADR 0062), in which the Bots that made it check their own conduct, judging no model:

  • Quality events: the work-log events that say something went wrong, filed by their type — checks failed, a review's reject, your send-back, a complaint's rework, a command timing out are execution (a check defined, or a requirement first said, after the hand-over is unclear); a reply that loops, declines, hits its cap or comes back incomplete is model; a failed render or a part at the capability ceiling is pipeline; an approval you overturned is review_miss; a stall, a crash, a stop broken is orchestration. Each carries the Bot and model it is about. Clearing a history keeps them and only drops where they came from.
  • Mark as the model's problem: a board card's model choice can mark that turn as the model's problem (press again to take it back); it feeds the model report only. The card also says why the turn ran on its model.
  • The report: GET /v1/quality/report gives per Bot × model × plan kind the hand-overs, approvals, rejects, send-backs, checks failed, complaints, failure shapes, review misses and the spend per approval.
  • Lessons: a search that walks a tree (grep -r, rg, find…) killed by the timeout makes that kind of call (program, place; no pattern, nothing quoted) a lesson of this workspace for every Bot; a render or a build running long is not one. The first call of that kind in a turn is then not run, and the Bot is told what happened and how to narrow it; repeating it in the same turn runs it; timing out again after that turns the lesson into a block, and that kind of call no longer runs. A folder one level down is another kind of call. Settings' Lessons page shows them and switches each between warn and block, retires it or brings it back.
  • Reflection (ADR 0051): an engine step that can be switched off, off by default in the general engine. only after an overturned approval or a capability ceiling, once a day per Bot and ticket, at most $2 and twenty a day; under a stop it waits for the lift. The Bot involved (the reviewer or the producer), on its own model (or the one chosen for Reflection under Tools → Roles, at high thinking), reads the ticket's work log, requirements and review verdicts, and may propose one checklist item (before reviewing, handing over or generating) or one check on a file (exists, contains, matches; never a command), or nothing. The proposal is a card (placed as approval cards are, see Review), Adopt / No, and a check proposal spells out what it checks: an adopted checklist item is read in that Bot's situation; an adopted check is added to the ticket, sends work back when it fails, but is not yours — it backs no approval nobody reviewed until you edit it on the board.
  • Project skills (ADR 0052): on the Project skills card in a Bot's Skills tab you can share one of its skills with every Bot (confirmed once more). What is shared is a copy as it was then: every Bot's catalog shows it, every Bot can read it, none can change it; when the owner edits its skill, the card says so, and "Update the shared copy" shows the body as it is now before you confirm. At most 20 are on at once; you can turn one off or stop sharing it; a deleted owner's copy stays, marked as from a deleted Bot.
  • The quality report: a "Quality, last 7 days" table at the bottom of the spend page, per Bot × model × plan kind: hand-overs, approvals, turn-backs, complaints, failed replies, review misses and the spend per approval.
  • Retrospective (ADR 0062): an engine step that can be switched off, on in all three built-in engines (in general since 2026-10-14). once a job is delivered (every ticket approved) and has stayed quiet for 30 minutes — a complaint right after an approval reopens it, and the retrospective waits for the next delivery — each Bot that handed something over in it looks back once (the three that handed over most), for deliveries within 7 days, never a routine's, waiting out a stop. When nothing went wrong for that Bot in the job (no hand-over sent back, rejected or failed by its checks, no complaint's rework, no requirement first said after a hand-over, no render lost, no search timed out, no ticket handed over more than once) it is recorded as skipped with no model call; delivered again after a reopen, it looks only at what went wrong since the last one. On its own model (a Bot run as a Claude Agent goes through the endpoint; one chosen for Retrospective under Tools → Roles is used instead, at high thinking) it reads the job's record: your words, every hand-over and what became of it (what you said sending it back, review verdicts, checks that failed, its own hand-over note), complaints after an approval, the requirements ledger (how often you said each, whether only after a hand-over), its quality events and tool calls that kept failing, all its memories and skills, project skills and checklist items, and what its earlier retrospectives wrote and which of those you undid; never the transcript. It answers with where it tripped up, which of its ways made you send work back and what to do again (at most five each), a verdict on the earlier conclusions this job tested (still holds, happened again, no longer holds), and a few changes: memories written, rewritten or merged (at most 3), memories deleted (at most 3), one of its skills changed or one made (at most 2, at most 1 made). The app checks each before writing it, and one refused takes no other with it: a memory follows the tool's rules (40-character subject, 160-character body, one deleted or merged away first when 20 are enabled); one you turned off, a project skill and another Bot's are not touched; a skill only gains a sentence after a passage, a passage at its end, or one wrong sentence corrected, and must keep every name in backticks, file name, link and environment variable it had — a passage rewritten whole is not written at all. An answer cut off, or not one whole JSON object, writes nothing. It posts no message, shows no card and sends no notification: the board's side panel lists it under Retrospective — who looked back, the summary, the three lists, the changes (opened to show before and now; for a skill only the lines that changed; one not made says why) — with an Undo for each change, which works only while the change is still as the retrospective wrote it; changed since, it is new. A memory a retrospective wrote is marked "Written by the retrospective of …" in the Bot's profile; rewritten by the Bot in a turn or its text changed by you, the mark goes. At most $2 and 12 a day, billed as its own "Retrospective" line (under organizing).
  • Chains are no longer reviewed, and your replies no longer count as feedback on the model choice.

Avoid: asking a model afterwards whether to switch models, counting a stall as the model's fault, writing quality events into memories

Lesson

From engine level 8, a rule the app learned from a failure and checks itself, of two kinds. One: once the timeout kills a search that walks a tree, that kind of call is held back once with a warning, and blocked when a Bot insists and it times out again — for every Bot. Another comes from the narrowed reflection: after an overturned approval or a capability ceiling, the Bot involved proposes a checklist item or a check, which holds once you adopt it on its card. Settings' Lessons page shows, switches and retires them. Unlike a memory, which is text a Bot reads, a lesson on a kind of call is enforced by the app before the call; a checklist item is read in the Bot's situation, and an adopted check is run by the app. Details: Behavior · Quality event, Lesson.

Behavior details

From level 8 (ADR 0050), no model call reviews a chain afterwards and writes its verdict into a memory; the one exception is the retrospective after a job you accepted is delivered (ADR 0062), in which the Bots that made it check their own conduct, judging no model:

  • Quality events: the work-log events that say something went wrong, filed by their type — checks failed, a review's reject, your send-back, a complaint's rework, a command timing out are execution (a check defined, or a requirement first said, after the hand-over is unclear); a reply that loops, declines, hits its cap or comes back incomplete is model; a failed render or a part at the capability ceiling is pipeline; an approval you overturned is review_miss; a stall, a crash, a stop broken is orchestration. Each carries the Bot and model it is about. Clearing a history keeps them and only drops where they came from.
  • Mark as the model's problem: a board card's model choice can mark that turn as the model's problem (press again to take it back); it feeds the model report only. The card also says why the turn ran on its model.
  • The report: GET /v1/quality/report gives per Bot × model × plan kind the hand-overs, approvals, rejects, send-backs, checks failed, complaints, failure shapes, review misses and the spend per approval.
  • Lessons: a search that walks a tree (grep -r, rg, find…) killed by the timeout makes that kind of call (program, place; no pattern, nothing quoted) a lesson of this workspace for every Bot; a render or a build running long is not one. The first call of that kind in a turn is then not run, and the Bot is told what happened and how to narrow it; repeating it in the same turn runs it; timing out again after that turns the lesson into a block, and that kind of call no longer runs. A folder one level down is another kind of call. Settings' Lessons page shows them and switches each between warn and block, retires it or brings it back.
  • Reflection (ADR 0051): an engine step that can be switched off, off by default in the general engine. only after an overturned approval or a capability ceiling, once a day per Bot and ticket, at most $2 and twenty a day; under a stop it waits for the lift. The Bot involved (the reviewer or the producer), on its own model (or the one chosen for Reflection under Tools → Roles, at high thinking), reads the ticket's work log, requirements and review verdicts, and may propose one checklist item (before reviewing, handing over or generating) or one check on a file (exists, contains, matches; never a command), or nothing. The proposal is a card (placed as approval cards are, see Review), Adopt / No, and a check proposal spells out what it checks: an adopted checklist item is read in that Bot's situation; an adopted check is added to the ticket, sends work back when it fails, but is not yours — it backs no approval nobody reviewed until you edit it on the board.
  • Project skills (ADR 0052): on the Project skills card in a Bot's Skills tab you can share one of its skills with every Bot (confirmed once more). What is shared is a copy as it was then: every Bot's catalog shows it, every Bot can read it, none can change it; when the owner edits its skill, the card says so, and "Update the shared copy" shows the body as it is now before you confirm. At most 20 are on at once; you can turn one off or stop sharing it; a deleted owner's copy stays, marked as from a deleted Bot.
  • The quality report: a "Quality, last 7 days" table at the bottom of the spend page, per Bot × model × plan kind: hand-overs, approvals, turn-backs, complaints, failed replies, review misses and the spend per approval.
  • Retrospective (ADR 0062): an engine step that can be switched off, on in all three built-in engines (in general since 2026-10-14). once a job is delivered (every ticket approved) and has stayed quiet for 30 minutes — a complaint right after an approval reopens it, and the retrospective waits for the next delivery — each Bot that handed something over in it looks back once (the three that handed over most), for deliveries within 7 days, never a routine's, waiting out a stop. When nothing went wrong for that Bot in the job (no hand-over sent back, rejected or failed by its checks, no complaint's rework, no requirement first said after a hand-over, no render lost, no search timed out, no ticket handed over more than once) it is recorded as skipped with no model call; delivered again after a reopen, it looks only at what went wrong since the last one. On its own model (a Bot run as a Claude Agent goes through the endpoint; one chosen for Retrospective under Tools → Roles is used instead, at high thinking) it reads the job's record: your words, every hand-over and what became of it (what you said sending it back, review verdicts, checks that failed, its own hand-over note), complaints after an approval, the requirements ledger (how often you said each, whether only after a hand-over), its quality events and tool calls that kept failing, all its memories and skills, project skills and checklist items, and what its earlier retrospectives wrote and which of those you undid; never the transcript. It answers with where it tripped up, which of its ways made you send work back and what to do again (at most five each), a verdict on the earlier conclusions this job tested (still holds, happened again, no longer holds), and a few changes: memories written, rewritten or merged (at most 3), memories deleted (at most 3), one of its skills changed or one made (at most 2, at most 1 made). The app checks each before writing it, and one refused takes no other with it: a memory follows the tool's rules (40-character subject, 160-character body, one deleted or merged away first when 20 are enabled); one you turned off, a project skill and another Bot's are not touched; a skill only gains a sentence after a passage, a passage at its end, or one wrong sentence corrected, and must keep every name in backticks, file name, link and environment variable it had — a passage rewritten whole is not written at all. An answer cut off, or not one whole JSON object, writes nothing. It posts no message, shows no card and sends no notification: the board's side panel lists it under Retrospective — who looked back, the summary, the three lists, the changes (opened to show before and now; for a skill only the lines that changed; one not made says why) — with an Undo for each change, which works only while the change is still as the retrospective wrote it; changed since, it is new. A memory a retrospective wrote is marked "Written by the retrospective of …" in the Bot's profile; rewritten by the Bot in a turn or its text changed by you, the mark goes. At most $2 and 12 a day, billed as its own "Retrospective" line (under organizing).
  • Chains are no longer reviewed, and your replies no longer count as feedback on the model choice.

Avoid: leaving "don't search like this" to a memory, the same kind of command timing out again and again, having a model write detectors

Retrospective

From engine level 8, once a job you accepted has been delivered and has stayed quiet for half an hour, each Bot that handed something over in it looks back once: on its own model (or the one chosen for Retrospective under Tools → Roles) it reads the job's record (your words, every hand-over and what became of it, complaints after an approval, the requirements ledger, what went wrong for it, and its current memories and skills), never the transcript; it writes down where it tripped up, which of its ways made you send work back and what to do again, then works the conclusions into its own memories and skills — the same subject overwritten, two about one thing merged, a wrong one corrected or deleted; a skill only gains a sentence after a passage, a passage at its end, or one sentence corrected, and loses none of its commands or names. The app checks each change before writing it and keeps what each replaced. It posts nothing, shows no card and asks you nothing: the board's side panel lists it under Retrospective, with an undo for each change. A Bot nothing went wrong for in the job does not look back, nor does a routine's job; it amends the line of ADR 0050 that stopped after-the-fact reviews, yet reviews no chain and asks nothing about the model. It is an engine step that can be switched off, on in all three built-in engines (ADR 0085; in general since 2026-10-14). Details: Behavior · Quality event, Lesson and ADR 0062.

Behavior details

From level 8 (ADR 0050), no model call reviews a chain afterwards and writes its verdict into a memory; the one exception is the retrospective after a job you accepted is delivered (ADR 0062), in which the Bots that made it check their own conduct, judging no model:

  • Quality events: the work-log events that say something went wrong, filed by their type — checks failed, a review's reject, your send-back, a complaint's rework, a command timing out are execution (a check defined, or a requirement first said, after the hand-over is unclear); a reply that loops, declines, hits its cap or comes back incomplete is model; a failed render or a part at the capability ceiling is pipeline; an approval you overturned is review_miss; a stall, a crash, a stop broken is orchestration. Each carries the Bot and model it is about. Clearing a history keeps them and only drops where they came from.
  • Mark as the model's problem: a board card's model choice can mark that turn as the model's problem (press again to take it back); it feeds the model report only. The card also says why the turn ran on its model.
  • The report: GET /v1/quality/report gives per Bot × model × plan kind the hand-overs, approvals, rejects, send-backs, checks failed, complaints, failure shapes, review misses and the spend per approval.
  • Lessons: a search that walks a tree (grep -r, rg, find…) killed by the timeout makes that kind of call (program, place; no pattern, nothing quoted) a lesson of this workspace for every Bot; a render or a build running long is not one. The first call of that kind in a turn is then not run, and the Bot is told what happened and how to narrow it; repeating it in the same turn runs it; timing out again after that turns the lesson into a block, and that kind of call no longer runs. A folder one level down is another kind of call. Settings' Lessons page shows them and switches each between warn and block, retires it or brings it back.
  • Reflection (ADR 0051): an engine step that can be switched off, off by default in the general engine. only after an overturned approval or a capability ceiling, once a day per Bot and ticket, at most $2 and twenty a day; under a stop it waits for the lift. The Bot involved (the reviewer or the producer), on its own model (or the one chosen for Reflection under Tools → Roles, at high thinking), reads the ticket's work log, requirements and review verdicts, and may propose one checklist item (before reviewing, handing over or generating) or one check on a file (exists, contains, matches; never a command), or nothing. The proposal is a card (placed as approval cards are, see Review), Adopt / No, and a check proposal spells out what it checks: an adopted checklist item is read in that Bot's situation; an adopted check is added to the ticket, sends work back when it fails, but is not yours — it backs no approval nobody reviewed until you edit it on the board.
  • Project skills (ADR 0052): on the Project skills card in a Bot's Skills tab you can share one of its skills with every Bot (confirmed once more). What is shared is a copy as it was then: every Bot's catalog shows it, every Bot can read it, none can change it; when the owner edits its skill, the card says so, and "Update the shared copy" shows the body as it is now before you confirm. At most 20 are on at once; you can turn one off or stop sharing it; a deleted owner's copy stays, marked as from a deleted Bot.
  • The quality report: a "Quality, last 7 days" table at the bottom of the spend page, per Bot × model × plan kind: hand-overs, approvals, turn-backs, complaints, failed replies, review misses and the spend per approval.
  • Retrospective (ADR 0062): an engine step that can be switched off, on in all three built-in engines (in general since 2026-10-14). once a job is delivered (every ticket approved) and has stayed quiet for 30 minutes — a complaint right after an approval reopens it, and the retrospective waits for the next delivery — each Bot that handed something over in it looks back once (the three that handed over most), for deliveries within 7 days, never a routine's, waiting out a stop. When nothing went wrong for that Bot in the job (no hand-over sent back, rejected or failed by its checks, no complaint's rework, no requirement first said after a hand-over, no render lost, no search timed out, no ticket handed over more than once) it is recorded as skipped with no model call; delivered again after a reopen, it looks only at what went wrong since the last one. On its own model (a Bot run as a Claude Agent goes through the endpoint; one chosen for Retrospective under Tools → Roles is used instead, at high thinking) it reads the job's record: your words, every hand-over and what became of it (what you said sending it back, review verdicts, checks that failed, its own hand-over note), complaints after an approval, the requirements ledger (how often you said each, whether only after a hand-over), its quality events and tool calls that kept failing, all its memories and skills, project skills and checklist items, and what its earlier retrospectives wrote and which of those you undid; never the transcript. It answers with where it tripped up, which of its ways made you send work back and what to do again (at most five each), a verdict on the earlier conclusions this job tested (still holds, happened again, no longer holds), and a few changes: memories written, rewritten or merged (at most 3), memories deleted (at most 3), one of its skills changed or one made (at most 2, at most 1 made). The app checks each before writing it, and one refused takes no other with it: a memory follows the tool's rules (40-character subject, 160-character body, one deleted or merged away first when 20 are enabled); one you turned off, a project skill and another Bot's are not touched; a skill only gains a sentence after a passage, a passage at its end, or one wrong sentence corrected, and must keep every name in backticks, file name, link and environment variable it had — a passage rewritten whole is not written at all. An answer cut off, or not one whole JSON object, writes nothing. It posts no message, shows no card and sends no notification: the board's side panel lists it under Retrospective — who looked back, the summary, the three lists, the changes (opened to show before and now; for a skill only the lines that changed; one not made says why) — with an Undo for each change, which works only while the change is still as the retrospective wrote it; changed since, it is new. A memory a retrospective wrote is marked "Written by the retrospective of …" in the Bot's profile; rewritten by the Bot in a turn or its text changed by you, the mark goes. At most $2 and 12 a day, billed as its own "Retrospective" line (under organizing).
  • Chains are no longer reviewed, and your replies no longer count as feedback on the model choice.

Avoid: a retrospective after every turn, summarizing the transcript, copying the requirements ledger into memories, rewriting a skill wholesale, a card asking you after the retrospective, asking a model whether the model was at fault, a retrospective touching another Bot's memories

Work item

One Bot's work on a plan and an optional ticket: “Bot × plan × ticket”; without a plan, a desk work item belongs to “Bot × conversation”. The work item is the work's identity and a turn is one execution segment; one Bot cannot execute two segments on the same plan at once. Details: Behavior · Work item.

Behavior details

The work identity is “Bot × plan × optional ticket”; without a plan, a desk work item is “Bot × conversation”. The new path binds each execution segment to a work item: neither a turn nor a ticket is a work item. A work item has at most one live segment (I1), and a Bot has at most one on a plan (I1b), including Running, Waiting approval and Waiting ask. Plan-level and ticket-level items cannot bypass the second constraint; other Bots can still work on their own items in that plan.

Once a Bot is working on a job, a later line filed under it goes to that segment's durable inbox: another conversation, another ticket or a user mention in a group does not redirect it or open a copy. A line you said to it in another conversation (naming it, given to it or judged its to answer in a group, or in your direct with it) goes there too, but its inbox line is marked "said to you" with that conversation's id (inbox_items.reply_in): nobody there answers it in the Bot's place, so the Bot answers there with send_message and that id, which does not end the segment in hand. A line that reaches it only because it is about the same job is not marked; it is answered over there. Before, no line was marked and the Bot was told it is answered over there, so @-ing a Bot in a group while it worked on that job in your direct got no reply (「@创意导演 你呢」, 2026-10-14). A different plan opens its own segment, subject to slots and holds. Current slot scope: each Bot defaults to at most two work segments globally. A desk uses no work slot; at most one live desk exists per Bot × conversation, with no global one-desk-per-Bot constraint. Code honors a valid positive integer in bots.parallel_limit, falling back to 2 when absent/invalid; this change adds no interface for changing it. Mail and work items beyond the work slots persist as queued, and the conversation says “Queued, at position N”. When a slot is available the dispatcher tries in priority and inbox order, including a cold queue with no live target. A held or dormant target does not start. Clearing the transcript does not resume work automatically; once you explicitly resume the target and it is eligible for admission, queued mail with a cleared source can create a Bot-only system trigger from its body snapshot, still passing slots and holds. This is not automatic restart supervision.

State after a segment ends: when a segment ends (a closing, Stop, interruption, failure), its work item does not stay running. Level 2 has no end contract, and from level 3 an ending the contract did not see (Stop, a closing without end_turn) is the same: the engine settles it at the segment's end, after the mail it did not read is handled — a desk's is closed, one on a plan goes idle, for the job's next line, its queue or the supervisor to take up; with unread mail still there it is queued. At level 4 a segment cut off (interruption, failure) still leaves needs_attention. After a crash, the next boot settles whatever the dead process left running the same way (at level 4 only desks: jobs on a plan are the supervisor's to repair by how their last segment ended).

Continue is not limited per conversation: from level 2, Continue on an interrupted or failed segment is limited only by one segment per job (I1b; for a desk, the conversation's desk) and the work slots. It works while the same Bot works on another job in the same conversation, instead of bot already has a live turn; a live segment on the same job answers 409 already_working.

Typing while it waits on your answer: from level 2, a line of yours that reaches a segment waiting on your answer to its question (waiting_ask), said in the conversation where it asked and carrying no files, is your answer to that question — text of your own rather than one of its choices — and the segment goes on with it, instead of waiting in an inbox the waiting segment never reads. A line with files, said elsewhere, or a Bot's line still goes to the inbox.

If work_on selects a job another segment of this Bot already occupies, that segment receives this segment's actual trigger message, not just a summary, and this segment ends as merged. Tickets retain distinct identities without allowing the Bot to do the plan twice concurrently. Unread mail adopted by a new segment retains its body snapshot and disposition audit; correcting already-read attribution does not rewrite the old segment's history.

Avoid: work item as message or turn, doing the same job once per conversation, correct ticket attribution in place of plan-level unique execution

Desk segment

An execution segment before the Bot has chosen which job to work on, able to read, answer and ask; choosing its work must precede acting on that job. There is one only when neither a reference nor the reading placed the line; for a line read as new, its first call with an effect opens a job for the line unless it chose another first. It is distinct from a held Bot's read-only answer, which cannot become work. Details: Behavior · Desk segment.

Behavior details

When no reference decides attribution and the reading did not place the line either (read as new, as no telling which, or not read; see Attribution), the called Bot opens its own mode=desk segment: its first hop, not an organizer's side-call guess. While that desk segment is open in the conversation, the next unfiled line for that Bot (by mention, lead, @everyone, a join judgement or a fork in your direct alike) is heard in it at its next hop; no second desk segment opens on the same work item, so no uniqueness refusal loses the line. If the segment ends before reading it, the line opens the next desk segment as its trigger instead of staying queued in the inbox. The candidate-id set is captured at admission, the same set the reading was shown (the conversation's candidates and the jobs of the six lines before the trigger). The desk prompt shows each captured plan's id/title, last activity, up to 3 recent artifact paths and its latest non-erased user quote, clipped to 300 display characters; absent artifacts or quotes are omitted. This evidence can refresh each hop without recomputing or widening the selectable ids. An unavailable captured candidate is marked unavailable, not replaced by a new one. work_on can choose only a plan in that snapshot, or open a new job by quoting a real user message from this conversation; with no quote ({new:{title}}) it quotes the line that opened the segment. A Bot is shown no message ids, so asked for a quote_message_id it could only guess: on 2026-10-14, with the reading down, 通识's curl look-up for Stripe was refused among three jobs, its new job then quoted a guessed id and was refused too, the two refusals ran out, and 「Payoneer + Stripe 能通吗」 got only the desk's cut-off line. An id that is not a line of yours in this conversation is still refused and counts. A plan added later cannot quietly enter the old segment's choices.

Before choosing, the segment is read-only: reading files, listing directories, no-effect queries and MCP tools marked readOnlyHint, plus replies, ask_user, work_on and end_turn. The first call asking for a side effect resolves attribution before execution — unless the line was read as something done in place:

  • Read as done in place (ADR 0057): however many candidates, the situation says the app read the line as something done right here, the reply saying how it went (a question, a look-up, a setting, a small action); effects run as usual (refused under a stop, cards as ever, commands from the workspace root) and open no job, and the reply ends it as answered. A Bot that finds there is something to hand over after all opens a job itself with work_on({new:{title}}) first. Whether a job opens is the reading's call, not the tool's: on 2026-10-08 「你能根据已经配置的模型补一下它们的上下文大小配置吗」 opened a job at update_endpoint; the window was set and the Bot said so, the ticket stayed To do, the supervisor called the Bot back ten minutes later and it said the same thing again, and the second ending with no progress stopped the job with a notice. A line no model read follows the rules below.
  • 0 candidates: only a user request can automatically open a plan with a produce ticket for this Bot; the call then runs. Since 2026-10-06 no “New job: …” card is posted: the new job can be seen in your line's flow. The new job's title leaves out the Bots the line names (「@Alpha 做一个 logo」 opens 「做一个 logo」), unless the names are all there is. A Bot or system line cannot invent a job through this fallback.
  • Read as new (ADR 0057): however many candidates, the situation says the app read the line as new work, about none of them, and the first call with an effect opens a job for it as with 0 candidates, unless the Bot chose one with work_on first. A reading never opens a job by itself: answering or chatting leaves none behind.
  • 1 candidate: the situation already names the default job; if unrelated, split it first with work_on({plan:{new:{title}}}). The call runs only after binding.
  • 2 or more candidates: refuse the call and list the choices, saying {new:{title}} opening one for your line is one of them, waiting for work_on or your answer; no writing files or running commands before filing.

Choosing does not grant a work slot: with work capacity occupied (two segments by default), a desk can still answer, but selecting a third job only queues durable work, ends the desk segment and executes no requested effect. Work starts once a slot is available; the desk exemption never becomes a third work segment. Continue on interrupted work also obeys capacity: it can queue, ending the admission segment with end_reason=queued, while actual work starts later.

work_on can name a ticket of that plan (or open one), and also adds this Bot's still-open work items in the captured candidates as message targets. The job the segment is already on need not be a candidate: a desk segment whose plan_items opened the job and bound it there goes on to its own first ticket with work_on. That step used to be refused as no candidate of the segment's while its ending was sent back to go on, so a lead could not start its own part at all (2026-10-04 walkthrough). Going from the whole job down to one of its tickets is the segment's own step, not a reading of your line: a line filed to the whole job stays with the job rather than moving to that ticket (a lead starting on the poster had your request for the poster and three slogans tagged with the poster alone). A Bot cannot drop locked targets or targets you corrected; a default can be split into a quoted new job before the first effect. The attribution refusal budget is two in a desk segment; exhausting it ends as needs_attention with the line "This line needs a job selected before work can proceed.", suppressing later effects in that same hop too. Once the segment is bound it no longer spends this budget.

Working directory (I8): the public constraint is at most one change per segment, with effects allowed only after attribution; typically no desk directory → ticket directory. A misfiled default may split a fresh request once before acting, not authorize repeated changes while working. A work segment bound to another directory, having written files or run calls, cannot use work_on to switch jobs and keep writing. Another ticket of the same job is the exception: a segment that has done nothing yet (no file written, no command run, its directory unused) can work_on another ticket of its job — a lead woken with the slogans approved goes on to its own poster; it used to be refused and wait minutes for the supervisor to open a segment on it (2026-10-03). Going from the whole job down to one of its own tickets is no change of directory either, even after acting: what the segment did, it did in the job, which holds the ticket's folder. On 2026-10-04's real-model run, after a stop, 「宣传语改成英文的,海报改横版」 was filed to the whole job and the lead's segment opened at that level; it made the poster, then could neither submit (no ticket) nor work_on ticket 01 (it had acted), and gave up with the job undelivered. Another job, or one ticket to another after acting, is still refused. A segment on the whole job that writes into the folder of one of the job's tickets it owns is bound to that ticket by the app (work.bound, by write), so its end hands over and owes as that ticket: on the same real-model runs the lead, woken at the job's level by the approved slogans, drew the poster in 03's folder and ended with nothing_new, nothing handed over. A command that ran once you approved it counts too (it used to be only commands that ran at once: on 2026-10-04 the lead rendered its poster with a python3 command you approved, the segment stayed on the whole job, submit asked it to bind first, and it gave up). And when a segment on the whole job hands in with submit files that all sit in the folder of one of its own tickets, it is bound to that ticket first, so files a tool (an image-generating MCP, say) or another command wrote, unseen by the app, still go in. Continue after interruption preserves desk mode, captured candidates and the used directory-change count, and still passes attribution and hold guards; it does not turn a desk into an ordinary writable turn. A held Bot's readonly answer is not a desk and cannot take on work through work_on.

New-job card actions: since 2026-10-06 this card is no longer posted (ADR 0058's addendum); one already out still acts as below. A level-2 new job used to display one persistent “New job: …” card, recording its opening segment and quoted user message, with Undo and Merge. A new job queued behind full work capacity can have a card without opening a third work segment. Actions remain available while the new job is active or delivered, including a quickly finished job. Once you have accepted it or it is abandoned, the old card returns 409 plan_changed: another explicit human action is required, not reopening through an old card. A successful card action is applied once; a repeat does not execute it again.

Undo explicitly holds the new plan and stops its live execution before marking it abandoned; it does not erase past execution. Files, old turns' execution records, quote text and requirements remain, and the quoted message stays filed under the abandoned job. Nothing is automatically cleaned up or deleted; lifting the hold does not automatically set abandoned back to active. Started effects such as writes, commands and MCP calls are honestly retained, without a promise to undo past external operations. Later effects are not let through after the stop.

Merge likewise stops and abandons the new job, but refiles only the user message quoted by the card: its target on the new plan moves to an offered active/delivered plan of the same project (home conversation). Its other targets stay, and the quote text is not erased. This follows message-correction inbox/source rules; it neither changes old turns' plan or directory, moves artifacts, merges whole plans nor lifts target holds. A quoted message already corrected away from the new job returns 409 attribution_changed; a target not offered, outside the project or no longer in an eligible stage is rejected.

Merge on a new-job card refiles the quoted line and stops/abandons this new job with it; since 2026-10-14 it is the only user action that still refiles a line (changing a filing by hand is gone, see Attribution). Cards use the existing local/remote POST /v1/messages/:id/control: {action:"undo_plan"} or {action:"merge_plan",task_id}. Scoped checks cover stopping live work, retained files, quickly delivered jobs, queued cards, correction and stale protection. They do not certify full P4b phase acceptance or later P4e submission/review completion.

Avoid: another Bot, a side call before a turn opens, acting before filing, bypassing a hold through a desk

Attribution

The relationship between a message and the plans, tickets or parts it concerns: it may name several targets, remain undetermined, or be explicitly left unfiled by you; a line of yours filed under the wrong job can also be made a new job of its own, by you. What the line points at comes first (your choice, an annotation, a quoted reply, a path, bound work); without that a model reads which job it is about (ADR 0057), and what it cannot place the Bot chooses at its desk. Attribution is not where a message was sent and does not move an entire plan into another job. Details: Behavior · Attribution.

Behavior details

message_filings holds all targets of a message (plan, optional ticket and optional part) and their provenance; legacy messages.task_id/ticket_id project only the first primary target, not the whole relationship. filed has targets, undetermined has not been decided, and none is an explicit unfiling or an app control line outside attribution. A line of yours that only might be a stop (marked possible_control with buttons: read as a stop beside other words, such as 「先停,把第三镜换成夜景」 "stop, and make shot 3 a night scene", or as both a stop and a go on) is filed like any line: its quote, paths and reading all count, and the segment at work on that job hears it. A line read as a go on (「继续」 alone included) is filed like any line too: which stops it lifts depends on the job it is filed under (see Hold). One line can concern several jobs or several parts of one ticket; multiple targets do not relax the Bot's plan-level execution uniqueness.

What the line itself points at comes first (the locked signals), in this order; distinct targets accumulate, deduplicated and retained:

Order Source Strength
1 An explicit choice on a card Locked
2 Sent annotations, inherited from the artifact path and delivering message/turn Locked
3 A quoted reply, inheriting all targets of the referenced message Locked
4 An attachment or prose path under a known plan/ticket directory Locked
5 An existing work-item/wake binding; a Bot's output uses its own current work item Locked; level-3 delegation bindings are wired, not future job/submission tools

These are references (chosen, annotated, quoted, a path written out, bound work), not guesses at what the line means. With none, which job the line is about is read by a model (ADR 0057; see "Where a line belongs" under Line reading): read as about some of the jobs, it is filed there (a default, correctable, with a ticket and parts when the reading names them, filed_by = reader); read as about none of them (new work, chat, another question), as no telling which, or not read at all (no model, the call failed), it stays unplaced and the Bot it wakes chooses at its desk. There is no "the one candidate left", "the group's one job" or "the job of the Bot's line just before" default any more, and nothing reads how the line opens or what numbers it carries — the three times new requests were glued onto old jobs on 2026-10-02 and 10-03 were all such defaults (「制作《一拳超人》动画」 went under 「让审片员回复视频导演…」).

The jobs a reading is shown: non-dormant active/delivered plans of the current conversation and of a Bot↔Bot thread's origin conversation, plans of the called Bot's (with none named, the conversation's Bots') open work items and its segments in the last 24 hours. A plan of another conversation comes in only through those two: being a member of that group does not count, so a line in your direct is never filed under a group plan the Bot never touched. The jobs of the six lines before it are in too while not accepted or abandoned — a routine's standing plan or a dormant job included: said three minutes after the morning brief, 「标题跟 LOGO 没有对齐」 is read with today's brief among the jobs and the brief said three minutes ago (on 2026-10-03 rule 6 filed it under a three-day-old address job). A desk segment captures the same candidates at admission, so what the reading could choose the Bot can. Explicit references or annotations can add an accepted or dormant plan.

Parts are only those the lead declares with plan_items (or you add on the board). A line's parts come from the reading (only the ones it asks to change, faults or asks about, not one it praises) or its references (an annotated file that is a part's current file); file names make or pick no part, and no shot number in the words is matched by pattern. This only records identities and artifact relationships, not approved part stages.

Filing is the app's own (ADR 0089, 2026-10-14): the conversation does not show where a line is filed, and it cannot be changed by hand — no tag under a message, no "Change attribution…" in its menu, no dialog, no "A new job". To see where a line went, use "This job's flow" in its menu: a line filed under a job opens that job's flow with the line and its ticket picked; a line filed under none opens its own flow (what it was read as, whom it woke). The flow's filing step names the jobs and tickets it read, by their current names ("Filed under: Promo › Cut", "Filed under: Promo, Poster" for several, a ticket named as its job said once; a count, "Filed under 2 jobs", when a name cannot be found), and its detail holds the model's answer as it came back; a filing set by a locked signal has no such step, and the line is drawn in that job's flow. A wrong filing is put right in words: quote a line of the right job (a quote inherits every filing of the line it quotes), or stop and say it again; when the same misreading keeps coming, tune the filing prompt on the Roles page. GET /v1/messages/:id/attribution stays, read-only: it lists the workspace's jobs and tickets (untouched or dormant plans included, none woken by the read) for a Bot's question card about a job to name them, and a conversation asks for it only when it holds such a question; the PATCH that changed a filing is gone, a 404 locally and over the relay.

A refile (since 2026-10-14 only Merge on an old "New job: …" card does one, see Desk segment) may change locked attribution and records attribution.changed. Unread queued/held mail moves to the new work item and remains held if the target's holds cover it. Already-read mail and its execution segment remain unchanged; Bots that actually read it get separate “This line was refiled to …” correction mail, queued even with no live target. Multiple targets get distinct mail. Explicit unfiling supersedes unread mail and does not roll back work. A correction neither lifts holds, moves files nor changes an old turn's working directory. A segment still running that read the line, on a job the line is no longer filed under (or at its desk, on none yet), reads an app note at its next step: where the line was refiled, that it is done there in a segment of its own, and not to act on it here — it used to hear nothing and finish the line in the wrong job (2026-10-03).

Persistent quotes are plural too: user_quote_filings relates one verbatim quote to every target, so a secondary job can still read it after the transcript is cleared, rather than keeping only the old scalar primary target. Requirement sources derived from that line move with a correction; a current ledger entry still has a single scope and is retargeted through the primary target. This is not a claim that one requirement already fans out into independent review obligations for every job. Changing a line you sent does not refile it, and the quote of the words you changed follows the line's filing; the "You changed this line" a Bot that read it receives is written into its inbox in the same write as the change, as a refile's correction is, without a wake (see User quote).

Avoid: one line can concern only one job, undetermined means no work exists, correction rewriting execution history, correction moving files, the one job left by default, guessing new work from an opening word, matching parts by numbers in the words

Group lead

The Bot you confirmed to receive unaddressed messages in this group; handoff records may suggest one, but a suggestion is not an appointment. A job's own lead takes precedence when present in that group. Details: Behavior · Group lead.

Behavior details

At level 2 an unaddressed user line in a group goes first to that job's present lead, then to the group lead you confirmed. With neither, the group retains legacy participation judgements (the existing per-Bot calls, not a claim that one call now decides the whole group; each runs on the Bot's own model, or the one chosen for Judgement under Tools → Roles). Mentions/@everyone still decide recipients, and an existing segment on the same plan hears the line rather than being redirected. A held lead does not cause another Bot to be picked to continue quietly. When such a line, reaching the lead (or the Bot already at work there) only by default, is filed under a ticket of another Bot that can still take work, the woken Bot starts on the whole job: it can hand that ticket out or go on to its own, but it does not work under someone else's ticket; a Bot you name, or talk to in your direct with it, takes the line's ticket. On 2026-10-04's real-model run 「宣传语改成英文的,海报改横版」 after a stop was read as about the copywriter's slogans ticket; the lead's turn landed on that ticket, and the poster it drew was handed in as the slogans, pushing the copywriter's English lines aside.

The last 7 days of handoffs only suggest a lead: the count includes real turn-sent group messages mentioning another member (everyone included), and the first real line in a Bot↔Bot direct opened from that group. Ordinary chatter, user mentions, empty directs and subsequent discussion do not add handoffs. Only present, non-archived, non-deleted Bots qualify; no evidence or a tie at the top gives no suggestion. Only your confirmation writes session_participants.is_lead; no Bot has an appointment tool. You can choose another present Bot or clear it with null.

GET /v1/sessions/:id/lead and PUT /v1/sessions/:id/lead {bot_id,confirmed:true} are local and on the remote whitelist; in the group's settings, each present Bot's row in the member list is the entry: one click on "Make lead" confirms it (to change, click another Bot), the current lead carries a "Lead" badge, and "Remove lead" on its row clears it; an archived Bot cannot be made lead, but can still be cleared if it is the current one. A suggestion appears only as a hint on that member's row ("Suggested: N handoffs in the last 7 days"): it takes no room in the conversation, needs no dismissing, and changes nothing until you click. Confirmation records group_lead.confirmed; a new top count never replaces your lead automatically.

Avoid: appointing the top count automatically, a Bot appointing itself, a lead lifting your holds

User quote

A verbatim copy of words you wrote, kept apart from the transcript and able to belong to several jobs they concern. Clearing the transcript does not erase it; only your explicit request empties its text, and a model's restatement cannot replace it. When you change a line you already sent, the clauses you changed are kept as another copy and the original stays (ADR 0063). Details: Behavior · User quote.

Behavior details

P4b addition: at level 2 quotes follow all message targets, not just the primary (see Attribution). user_quote_filings relates one verbatim body to several jobs, retaining secondary targets after transcript clearing. “Filed by the turn or organizer” below describes legacy paths; level 2 uses deterministic signals and desk choices. Numeric replacements in the ledger still obey ADR 0042: proposed, changed only by user confirmation, not the draft design's automatic numeric replacement.

What you said, kept as it came, apart from the transcript. Kept are: each line you send (except in the file drop, which has no Bot); each answer you give a Bot's question (the options you picked and what you wrote yourself); for a batch of annotations, the line you added when sending it (none if it only names the Bots) and each annotation itself; and what you write on the flow board yourself — the clauses of the goal or a ticket description you changed (what you only kept is not, since it may be the organizer's), each Done when line and rule you add (dragging a ticket's status is not writing). Each is stored in the same write that makes it: a line that did not go out is not kept either. One holds at most 2000 code points; a longer one keeps its head and its tail, with how much was left out marked between. It is filed under the plan and ticket it belongs to: your line is filed after it lands (by the turn it opens, or by the organizer), and the quote follows that filing, and any later refiling, an older build's included; an annotation is filed under the plan and ticket of the delivery it is about; an answer under the job that asked; what you write on the board under that plan (or ticket), in no session.

Clearing a session's history deletes the transcript and the turns, and keeps every quote, only nulling the id of the message it points at; deleting a group nulls which session it was said in as well. Both can be asked to erase them too (the box "Also erase what you said here" in the clear-history or delete-group confirm, off unless you tick it; erase_quotes on the clear or delete request, taken on the local and the remote API): the quotes said in that session have their text emptied and are marked erased, the rows stay, and a requirement standing on one loses its words and no longer applies; what you wrote on the board is in no session and is not touched. What happens to the session's plans: see Plan.

The first time a database is opened after updating to this version, the lines, answers and sent annotations still in the transcript are each kept once, filed as the transcript files them; what was cleared before is gone. From then on each is kept as it is written, never caught up again; lines an older build sharing the data folder writes meanwhile are not added later.

Every turn that works in a job — in a group, a direct, a Bot↔Bot direct, woken by a check-back, fired by a routine, all alike — has a section "What the user said in this job" in its situation: of your quotes filed under the job and not erased, the first 4 and the latest 6, verbatim (up to 400 code points each, a longer one cut with "…"), each with when (this machine's time, month-day hour:minute) and where you said it (the group, whose direct, answering a question, an annotation, or on the flow board), and how many were left out between; under 10, all of them. It reads the quotes, not the transcript, so a Bot reads the same after the session is cleared, in a Bot↔Bot direct where no line of yours appears, and forty lines past the transcript window. The job's first turn does not list them: its trigger is the request. A turn a hold covers reads them as they stood when the stop was made: what you said after it, and the requirements noted from that, reach its situation only after the lift, so a turn that may not act is not handed a fresh instruction first.

Changing a line you sent (ADR 0063): a plain line of yours can be changed after it went out — Edit on the bubble (its hover bar, or the right-click or long-press menu), or ↑ in an empty composer for your newest line. The bubble turns into the editor: Enter saves, Shift+Enter starts a new line, Esc cancels, and the Enter that confirms an input method's candidate is no save. A Bot's line, your answer to a question (a question is answered once), a batch of annotations, and a stop the app carried out itself cannot be changed (one you undid, handed on to the Bot as a line, can again); nor can a line in an archived conversation, a Bot↔Bot direct, or a direct whose Bot is gone. There is no time limit. A changed line says Edited beside its time, which opens what it said before; that history goes with the transcript when the conversation is cleared. Your words gain and never change: the clauses you changed (read as a board edit is, so what you left alone does not count) are kept as one more quote, pointing at the line's first quote and filed where the line is; taking words out keeps nothing new, and the old words are still there. The scribe reads every quote of the line, oldest first and each once, so it reads only what changed; checks from your words count a line's quotes as one source, so a number you left alone is not said twice. Ledger entries on the old quote stay: a changed number makes a replacement awaiting your confirmation, a gate in force whose number changed gets a replacement card, and an entry on words you deleted stays in force. From 2026-10-10 the scribe reads every change again, one that only took words out included: it is shown the line before and after, and the entries that stand on the line's earlier words, that you did not say again in another line and that are still in the ledger, and names those your change took back; they are listed first in the plan's "What you asked for" as "Words you took out", each with "No longer holds" ("Not a requirement" for one waiting to be confirmed) and "Keep it". Until you press, they stay in force. Who hears of it: a Bot that has not read the line yet gets the new words in its inbox and reads only those; a Bot that has read it (an item read, or a turn the line opened) gets a line of yours, "You changed this line. It now reads: “…” (it was: “…”)" — at its next step while it works, by a new turn on its work in the job once its turn ended; after you pressed Stop on it, the change is your next line: the Stop lifts and a new turn goes on from the change; under a stop that stays until you lift it (Stop all Bots, the board, the tools menu) it is held and delivered when the stop lifts — and must dispose of it in end_turn. A read-only answer under a stop has not read it: lifting the stop hands the line back as it then reads. A changed line is not carried out as a stop or a go on, not judged again as a complaint, not refiled, and wakes nobody it now names; a line nobody took up (every Bot in a group sat it out) wakes nobody when changed. In a Bot's transcript a changed line is marked "(发出后改过)", and in its situation's "What the user said in this job" the change reads "changed a line in X".

Taking back, or inserting, a line not read yet (ADR 0069): while no Bot has read a line of yours — it waits in a working Bot's inbox, or a stop holds it — a row under it says where it waits: "Queued · read at its next step" (its Bot is at work), "Queued · read when its turn comes" (it waits for that Bot's next turn or a free slot), "Held by a stop · read once it lifts"; once read, the row goes. Beside it are two buttons. Take back: no copy of the line in any inbox is delivered, the line is kept out of every transcript a Bot reads, your words kept from it are erased (the ledger entries made from them are waived), and work queued for it alone goes idle; the transcript shows "You took this line back · Edit again", its words go back into an empty box, and Edit again adds them after what you typed; a line taken back is not changed or refiled — send it again. A line a Bot has read, or one that opened a turn, cannot be taken back, which the row says; you can still change it. Insert now (for a queued line, and for one a Stop of yours holds — the Stop lifts and the Bot opens a turn on it; not under a stop that stays until you lift it, which the row says): a Bot run by Claude Code is interrupted — as Esc does in Claude Code, a command it runs stops — and the lines waiting for that turn go in at once, in order, telling it the step was stopped for them and to run again what was cut if it still needs it; the cut step's own end is neither a reply nor a failure. A Bot on the app's own loop has the model call in flight cut and the hop's waiting tool calls postponed, a command already running finishes, and the next hop opens by reading the lines. With no step to cut right now (it is wrapping up, or the turn ended), the row says "No step to cut right now; it reads this at its next step". Once a stop lifts, every line it held goes back to the Bot to read. Send back on a hand-over's card after Stop lifts that Bot's Stop on the job too, and it reworks with your note. The endpoints are POST /v1/messages/:id/withdraw and POST /v1/messages/:id/insert, on the phone too. A line a Claude Code turn read after a batch of calls no longer opens one more turn when the segment ends.

Avoid: transcript as the only source, clearing chat erases quotes, a model's summary replaces the words, multi-attribution keeping quotes only for the primary job, changing a line rewrites its quote

Requirements ledger

What you have asked of a job, one entry at a time, each standing on your own words: its quote is a piece of what you said, beside a number (R-12), a restatement, a category, what it holds for (one ticket, the job, every job in the job's session, or every job of a kind), how many times you have said it and in how many jobs. It only grows: an entry is added or raised again, and it goes out of force only one way: by your own action; a later line of yours giving a new number for the same thing (running time, resolution, aspect ratio, frame rate) only makes a replacement for you to confirm, and the old entry stays in force. The one real delete is your purge. What goes in: what the scribe notes from your words (the scribe is an engine step, off by default in the general and coding engines); when it notes nothing, a complaint of yours the app keeps as it is (to confirm, never a gate); the rules and Done when lines you write on the flow board (a line added is an entry; a line taken out goes out of force for that job, and altogether once no other job holds it); and the old rules, taken in once on upgrade (the ones you wrote or that are found in your words stay in force, the rest are marked "old rules (source unverified)", for reference only). Any other change a model gives likewise only makes a replacement for you to confirm; the database checks that each entry's quote is a piece of the line it came from. One you say every job should keep to ("every film from now on", "this series always"), as the scribe reads it, holds for the job's session, so a new job in the same session inherits it from its first turn, marked with the job it came from; "Not for this job" sets one aside for a single job. One said of this job only stays with it, even when it sounds like general craft or taste (from 2026-10-10; before, a video job widened such requirements to the session). Old rules get no card asking whether you said them: you confirm them one by one in the flow board's "unverified" group; nor does a kind of requirement you raised in several jobs get a card offering to make it standing. Every turn's situation and the flow board list it: the Bots read the same list you see. Clearing a session leaves it alone. Details: Behavior · Requirements ledger.

Behavior details

What you have asked of a job, one entry at a time, kept apart from the plan's fields. Each entry stands on your own words: its quote is a piece of what you said (at most 300 code points), beside a restatement, a category, whether it is a must or a must-not, what it holds for — one ticket, the job, or the session the job lives in (every job in that session from then on) — and how many times you have said it, with the line each time. A number you gave (a running time, a resolution, an aspect ratio, a frame rate, with "about", "at least" or "at most") is read out of the quote by fixed rules and kept on the entry, only when the quote gives exactly one. A moment, a stretch or a place in the picture ("at second 3", "at 12 s", "the first 3 seconds", 「logo 放在 3 秒」 "put the logo at 3 s", 「字幕定在 5 秒」), a range ("3-5 minutes", "a minute or two"), a time to answer or finish in ("reply within 5 minutes", 「限你 3 分钟弄完」 "you have 3 minutes to finish", "give you 10 minutes"), how long something else takes ("wait 5 minutes", "the render takes 20 minutes", "3 minutes ago", 「半小时左右能好吗」 "ready in about half an hour?", "ETA 30 minutes"), a count of words ("2k words") or a number you said no to ("not 4K", "not 3 minutes") gives none; a number right after a word setting the work to it reads whatever follows it (「剪成 90 秒发给我」 "cut it to 90 seconds and send it to me" is 90 seconds), and so do 「压在 90 秒以内」 and 「时长定在 90 秒」. A ratio is read only with a word for the picture's shape in the line (画幅, 比例, 屏, "aspect"), never after a score (「比分 2:1」); a bare 「24 帧」 is a count of frames, and a frame rate is written 「帧率 N」, "N fps" or 「每秒 N 帧」; "90s 港风" ("90s Hong Kong style") is a decade. "Don't go over 3 minutes", "no less than 2 minutes" and 「至少要 2 分钟」 read as at most and at least, and 「能不能改成 90 秒」 ("could it be 90 seconds") or 「要不要 4K」 ("4K or not?") asks rather than says no; with no ratio given, portrait (竖屏) and landscape (横屏) count as an aspect (横幅 and 竖幅 are as often a banner, and do not); a bare 分 or m is minutes only right before a number of seconds ("1分30秒", "2m30s") or after a word for a running time.

An entry is in force, to confirm, replaced, no longer applying, not a requirement, or an old rule (source unverified). It only grows: an entry is added, or raised again. It goes out of force only one way: by your own action. A later line of yours giving the same number a new value (first "about 2 minutes", later "make it 3 minutes") is no exception: the scribe can only make a replacement for you to confirm, pointing back to the old entry, which stays in force meanwhile; any other change a model gives does the same. The database holds to two things: an entry's quote must be a piece of the line it names as its source (compared the same folded way), whoever writes it, and one that is not, or whose line was erased, cannot be written; and an entry becomes replaced only by one standing on words of yours said after the old entry's (kept for the day you confirm a replacement). The one delete is your purge.

For now two things write it: the scribe, from your words (see Scribe), and the fallback capture. The fallback capture: when the scribe notes nothing for a line (no model set, a failed call, an answer that is no patch, no requirement found, or every item it gave failing its check), and the line was said after the job had delivered something (a Bot's line filed under it carried a file, or a ticket was in review or done when you said it, even if the line's filing or a turn it woke has sent that ticket back since) and has a word for something being wrong (fake, wrong, jumpy, breaks the shot, reversed, too short, redo, no good, broken…), the app keeps the line whole (cut at 300 code points) as an entry to confirm, under the ticket the line was filed under (else the job), never a gate.

Editing a plan's Rules or Done when on the flow board edits the ledger: each line you add becomes an entry of the job in force, standing on the quote the board kept of it (when the same words are already an entry for the job as a whole — its own, its session's or a standing one; one that holds for a single ticket does not count — you have said it again; an entry only proposed, or an old rule, is taken up as yours, and one you had set not to apply to this job applies again); each line you take out lets go of every entry with those words that holds for the job, whichever job first wrote it down: the job's own no longer applies, and an old rule with no source found is marked as no requirement; one that holds for the whole session, or a standing one, is set not to apply to this job only while another job still holds those words (the line is on its board, you said it in that job, that job first wrote it down, or you widened it yourself with "For the whole conversation" or "Make it standing"; a job that set it aside does not count), and the other jobs keep it (that covers the one entry an old rule several jobs of the session shared was taken in as, and a session entry your line only said again); when no other job holds it, the line you took out was its last hold, and it goes the way the job's own would: it no longer applies, or is marked as no requirement, so later jobs of the session neither inherit it nor ask you whether you said it. Each step (added, said again, confirmed, restored, no longer applying, no requirement, not for this job) is in the work log with the version of the plan your edit made. A change you later say to one ("make the robot arm a right arm") is kept as a replacement to confirm like any other: an entry written on the board has no category, so nothing tells that the scribe's change is about something else, and it is not dropped.

Where an entry holds: one the scribe says is about one ticket, on that ticket; one the scribe reads you saying every job should keep to ("from now on", "every film", "this series always"), on the session the job lives in; the rest on the job, even when it sounds like general craft or taste. Until 2026-10-10 a video job (one that delivered a video file or called a video tool) widened requirements about craft, choices of look and a series' constants to the session whatever the scribe read: the IG MV job's 19 such entries ("restore the real match shots", "the opponents", "you can't tell which champion it is") showed up in the plan of "Connect to ACE Studio" in the same direct, and in the situation of the Bots working there. Entries already widened are not moved; "Not for this job" on the board still narrows them per job; for the next job to inherit one, say "from now on", or press "For the whole conversation" on the board. A bare "consistent", "style", "pacing", "font" or "quality" (一致, 统一, 风格, 节奏, 字体, 画质) is no craft ("keep the numbers consistent with last month" is about that one job); it counts only with what it makes one (画风统一 "one art style", 色调一致 "a consistent colour grade"); a choice is the same, and "a cold grade" is that film's (or that series') choice, not craft. Which kind an entry is goes by the nature the scribe marked when it noted it (craft, a choice of look, a series' constant, other; see line reading); only an older entry without one is judged by the words above. An entry of the session holds for every new job opened in that session from its first turn, marked "inherited from" the job that set it; when one does not fit a job, "Not for this job" on that job's board takes it off for that job only, the others keep it, and "Restore" brings it back. When you say the very words of an entry you had set not to apply to a job again in that job, the scribe counts it as said again and it applies to the job again, rather than a second entry. A job's own entry can be widened with "For the whole conversation". When one kind of craft requirement (by the scribe's category) has come up in two or more video jobs of the same session (counted by the jobs the lines saying it were filed under, only those of this session that are video work; a job is video work once it delivered a video file or called a video tool), no card offers to make it standing any more (from 2026-10-04): an entry holding for the session is inherited by every new job of that session already, and widening it to other sessions is not something you have to decide. A card from before — "You have asked for "背景连贯" in 2 jobs: "背景要连贯". Make it hold for every video job from now on?" (one entry at a time when their words differed) — still takes its buttons: "Make it standing" widens only the entries that still meet the card's terms when you press it — holding for the session or one of its jobs, in force, craft, of the card's kind; never a ticket's or another session's, a number such as a running time, a choice (EP01 graded cold, EP02 warm), or what stays the same across one series (the left arm is that series' own). A standing entry holds for every video job (a job that has delivered no video does not read it yet).

The first time a database is opened after updating to this version, the Rules and Done when lines every plan already had are taken into the ledger once: what you typed on the flow board stays in force (standing on the board's quote of it, when there is one); a line found in your own words about the job (compared folded the same way) stays in force, standing on those words; the rest — mostly the organizer's — becomes "Old rules (source unverified)", for reference only, never a gate. In a video job the craft ones, the choices and what stays the same across a series go to the session; the rest (these too, in a job that is not video work) stay with their plan; a line several jobs of one session share is taken in once (so is a job's line in the same words as a session entry it inherits). Nothing is taken in after that. No card asks you whether old rules are yours (from 2026-10-04): they are for reference only, and you take one up on the flow board's "Old rules" group. Until then, the first time a line of yours was filed under a job bearing old rules nobody had asked you about, the app posted a card — "This job has N old rules from before the requirements ledger with none of your words found for them: … Did you say these?" — with "All mine" (all of them in force) and "Go through them" (opens the flow board, where each has its own buttons); the one of 2026-10-03 was never pressed. Cards already out still take their buttons. Once none of a card's rules is unverified any more (taken up or turned down on the board, or by a rules edit, whoever made it), a card nobody pressed reads "Gone through one by one on the board" with no buttons, and an "All mine" pressed from a page still showing them does nothing; a card pressed "All mine" keeps saying what was pressed.

Where the Bots read it: every turn's situation has a "User requirements" section listing the entries in force that hold for the job (not those set not to apply to it): nearest first (this turn's ticket, the job, other tickets, the session, standing), then by how many times you said it and how recently; every entry said twice or more is listed, the rest up to 20 lines and 2000 code points, with "and N more" past that. Each line reads "R-31 | "前三镜背景严重跳跃" (restated: 前三镜背景要连贯) | the user said it 7 times (across 3 plans) | holds for: ticket 01 Shot 01–03 | check: Running time 108–132 s (waiting for the user to confirm)": the number, your words, the restatement, how many times and in how many jobs you said it (nothing for once), where it holds (an inherited one says from which job), and the check from your words on the same number (in force or waiting). Replacements and complaints waiting for you are a section of their own, "Waiting for the user to confirm (not in force; do not act on these as requirements)", and old rules with no source found another, "Old rules (source unverified; for reference only)", 10 lines each at most.

On the flow board the plan has a block "What you asked for" listing the same entries: the job's own, those it inherits grouped by the job that set them, those waiting for you, the old rules (source unverified), and those set not to apply to this job. Each shows its number, your words, the restatement, where the words came from (you said, your answer, your annotation, you wrote on the board, old rule, your words kept whole as a complaint; one still in the transcript jumps back to that line), how many times you said it, where it holds, and the buttons it takes right now: "Confirm" and "Not a requirement" on a proposed one or an old rule, "Not for this job" on an inherited one, "Restore" on one set aside, "No longer holds" (not on the lines you wrote in the board's Rules or Done when: taking the line out is how) and "For the whole conversation" on the job's own. Each takes two lines: your words and how many times you said them (twice or more is an amber badge), then the restatement, the source, where it holds and the buttons. The job's own list shows the 10 said most often and "Show N more" for the rest (all of them while a ticket is picked). An entry in force shows its buttons when the pointer is on it, always on a touch screen; entries waiting for you get a line under the goal, in "Needs a look", that scrolls to them. The local API is POST /v1/requirements/:id/action, also on the remote whitelist; an entry that has moved on since answers 409.

Clearing a session leaves the ledger alone; deleting a group only makes entries that held for that session no longer name it. Erasing a quote empties the words of an entry standing on it and it no longer applies (see User quote).

Avoid: letting a model rewrite the requirements as a whole, letting a Bot write the ledger, recording a Bot's words as your requirement, deleting an old entry because a model says it is replaced, deleting requirements when a chat is cleared, taking a quote that cannot be found in what you said, dropping your change because its category does not match, keeping words you took out without asking

Scribe

A short, tool-free call on the scribe's model (the default model when none is chosen), made in the background once a line of yours is filed under a job, when it arrives or later (a desk opening a job for it, work_on, your correction), each line once (or you answer a Bot's question). It reads the line against what the job already asks and proposes a patch to the requirements ledger: entries to add, to raise again, to change. It holds no turn back and never speaks. Each item of the patch is checked on its own: one whose quote cannot be found in your line is dropped, the rest land; with no model set or a failed call it notes nothing, and only the fallback is left. Every raw answer goes into the work log. Questions about how it is going never reach it, and once the engine level has reached holds, neither do lines that only stop or go on. It is an engine step that can be switched off: on in the video engine, off by default in general and coding, leaving only the fallback (ADR 0085). Details: Behavior · Scribe.

Behavior details

The scribe is an engine step that can be switched off: on in the video engine, off by default in the general and coding engines; while it is off, only a line of yours finding fault with delivered work is kept, as an entry to confirm (the same fallback as when the scribe notes nothing).

Once a line of yours is filed under a job (the turns it opens have opened, the judgements it needs are made; for a line filed only later — a desk opening a job for it, work_on choosing one, your correction — at that moment), or you answer a Bot's question, the app makes one call in the background to the scribe's model (the one chosen under Tools → Roles, else the default model of the default endpoint; with one chosen, thinking at low): tool-free, at most 800 tokens of answer, 60 seconds. It reads your line (with the question, for an answer), which session it was said in, the job's goal and ticket list, and the entries already in force for it (the job's, its tickets', its session's and the standing ones, at most 60, each with its id and category), and proposes a patch to the ledger: what to add, what you are saying again, what you changed. There is no delete and no whole list: what it leaves out stays as it is. It holds no turn back: your line wakes the Bots and opens turns as usual, and it notes beside them, each line once (one it has read is not read again when filed again), one line at a time in order; what is still unnoted when the app quits or updates goes unnoted. It never reads a Bot's words. Questions about how it is going, which the app answers itself, never reach it, and once the engine level has reached holds, neither do lines that only stop or go on; below that level those are filed like any other line and reach it too.

Each item of the patch is checked on its own: its quote has to be found in your line (both compared with spaces, punctuation and symbols taken out and full-width folded), and what is kept is that stretch of your line as you wrote it; a new entry or a replacement to confirm needs at least 4 of those characters (or the whole line, when it is shorter), since a character or two of your line says nothing and the entry would stand on the restatement alone, except words that give one running time, resolution, aspect or frame rate (「90 秒」, "4K", "16:9"; 「片长 2 分钟」 inside a long line too); a raise or a change may name only an entry it was shown that is still in force; a new entry holds for the ticket it names (when it names exactly one; or the ticket your line was filed under, when it names none), for the session when the scribe reads that every job should (see Requirements ledger), and otherwise for the job; the same words as an entry in force there that holds at least as far are a raise (so are those of one you set not to apply to this job, which then applies again): a ticket's entry counts only for a new entry of the same ticket, and one for the whole job or session is an entry of its own, or the words would stay held for one ticket and the next job would inherit nothing; a line adds at most 8. Every change is only kept as a replacement to confirm, and the old entry stays in force: one giving the old entry's number a new value ("make it 3 minutes" against "about 2 minutes") whatever its category; the old entry's own number again ("about 2 minutes after all") is a raise; any other when its category is the old entry's; one of another category is kept as a replacement to confirm too, in the category the scribe gave (until 2026-10-10 it was dropped, the new words with it: on the IG MV job "rebuild it with the League map, champion models and real player models" was lost that way, and the "original stylised characters" it replaced stayed in force), unless the same words already went to an old entry of their own category in that answer — then aiming them at another is the scribe's mistake, and not kept; an old entry with no category (written on the board, an old rule taken in) cannot tell, so it is kept. Each item that fails is dropped and logged in the work log with the reason, and the rest of the patch still lands. So whatever the model answers, the entries in force lose none.

With no default model set, a failed call, a cut-off or unreadable answer, no requirement found, or nothing landing, the line only goes through the fallback capture. Every raw answer is kept in the work log as it came. Its spend is billed as the "Organizer" kind with the scribe as its purpose, gets a line of its own, "Scribe", in the spend view (under "Other"), sits in the line's session, and belongs to no Bot. A line you changed after sending it has the clauses you changed kept as one more quote; the scribe reads every quote of the line, oldest first and each once, so it reads only what changed (ADR 0063).

Avoid: the scribe holding turns back, the scribe deleting entries or handing in a whole list, reading a Bot's words, throwing the whole patch away when one item fails, using the Bot's model

Line reading

Before the app acts on a line, one tool-less short call reads what it means (ADR 0055): a line of yours, for whether it tells the Bots to stop or go on, whether it only asks where the work stands, and which of its clauses object to delivered work, and, with no reference in it, which job it is about (ADR 0057, read at the same time; this one has no word lists to fall back on, and a line it cannot place goes to the Bot's desk); a Bot's line, for whether it says the work is still going or more will follow, whether it claims a run, and whether it is only "nothing to do" or a bare status, and a question of its to you for whether it only asks your OK to go on (no word lists stand in for that one: unread, the question reaches you as before). A stop, a go on and a send-back to rework are carried out only on a reading, and none of them when the line cannot be read (ADR 0070); otherwise a reading is only understanding: a bounce or a card is still decided by the rules as before, and a quoted sentence must be words of the line. Each line is read once, on the model chosen for Reading under Tools → Roles (the default model otherwise), at its lightest thinking level; with no model, an error, more than 20 s or an unreadable answer, the old fixed word lists read it, and the work log says so. Your line wakes no Bot, and no stop is carried out, until it is read (a line read as nothing but a stop goes ahead of lines still being read), so pick a fast model for it. Billed as its own "Line reading" line. Details: Behavior · Line reading.

Behavior details

Before the app acts on a line, one tool-less short call reads what it means (ADR 0055, reader.ts). A stop, a go on and a send-back to rework are carried out only on a reading, and none of them when the line cannot be read (from 2026-10-09, ADR 0070); otherwise a reading is only understanding: whether an ending is bounced or a card asked is still decided by the rules each of those always had.

Your line: the line, the one it answers and the three before it are read for five things — whether it tells the Bots to stop or go on now (stop, go on, both, neither); whether it is nothing but that; whether it only asks where the work stands; which of its clauses object to delivered work as it stands (quoted); and which of the hand-overs waiting on you where you speak (shown to it, numbered, when there are any) the line lets through (from 2026-10-11, ADR 0084). Used for:

  • Control lines: by the reading alone; the fixed rules no longer read first or carry anything out (from 2026-10-09, ADR 0070). Nothing but a stop (「停下」, 「先别搞了,收手吧」 "drop it for now", and "you haven't stopped" too) makes holds over the scopes the rules give (@ names, you, all of you, every Bot, this job), undoable from the receipt; a go on (「继续」 alone, or with more in it like 「继续做第二集,……」) is not carried out by the app: it is filed first, lifts the stops that keep the Bots it is said to from that job, and then goes to the Bots like any line (see Hold); a stop beside other words, or both, only carries the buttons and goes on to the Bots; one read as no control carries none. Asking whether it stopped or can stop ("has it stopped?", 「怎么还在跑」 "why is it still running?", "can it stop?") is a line for the Bot. A line sent on again after you undid its stop is not read for control again.
  • Status questions: the app no longer answers them (its status line went on 2026-10-09); the line goes to the Bot, which answers. When its filing reads it as new work it counts as done in place, so what the Bot looks up or runs for it opens no job (「怎么样了」 "how's it going" once opened a job of that name that ran 79 turns by itself).
  • Complaints: whether the work goes straight back to rework goes by the quoted clauses objecting to work handed over, in review or approved (see Review); which parts go back is which parts the line is filed under (see "Where a line belongs" below), with no shot numbers picked from the clauses by pattern; the fallback capture when the scribe noted nothing goes by the clauses too. The word lists' reading sends nothing back.
  • 放行: only numbers matching the hand-overs it was shown count, the rest are dropped; one both objected to and let through is sent back (see Review, "Letting work through by your word"). The word lists never read this: with no reading nothing is let through.

Where a line belongs (ADR 0057): a line of yours with no reference (a choice on a card, an annotation, a quoted reply, an attachment or a written path, bound work) is read once more, alongside the reading above: the line, where it was said, the six lines before it (who, how long ago, which job each was on) and the jobs it may be about — the conversation's candidates and the jobs of those lines, each with its name, goal, stage, home, last move, tickets (state, owner, declared parts), recent files and what you last said about it. The answer is which of them (with a ticket and parts, by the refs it was shown), new work (something to hand over, or work that takes a while and is followed up), something done in place (a greeting, chat, a question, a look-up, a change to the app's settings, a one-off small action — the reply is the result), or no telling which. A line is read with no job open too, choosing between new work and done in place. It is checked against those refs, a ref it was not shown dropped; read as about some jobs, the line is filed there (a default, correctable), and anything else is the Bot's to choose at its desk. A line read as new work is marked, and the desk's first call with an effect opens a job for it; one read as done in place is marked too, and its effects open none. This one has no word lists: a line no model read goes to the desk, never guessed from how it opens or the numbers in it.

A Bot's line: the message is read, with what its segment answers (the line that woke it, unless its own, and the mail it read there), first for whether it mostly translates, restates, rewrites, polishes or summarises what it answers (restates), then for the sentence in which the Bot itself says the work is still going or more will follow (quoted; a sentence of the translation or restatement is not one, only what the Bot says beside it); whether it claims something was run, tested or verified and passed; whether it only says there is nothing to do or no reply needed; whether it is only an acknowledgement, a claim of being done, a wait or "let me look"; and whether a question to the user only asks their OK to go on with what they asked for (a sign-off on work in progress, whether it may start the next step — not something only they can give, a choice between options that is theirs, or what blocks the work). No word list stands in for that last one: with no model, or no reading, the question goes to you as before. Used for the closing check's promise and claimed run; the ending contract, which reads the segment's last word for promised_later; whether a send_message or a closing reply is a no-work closer (one that is empty, long, asks, names someone or carries a path or code is ruled out by shape first, unread); whether end_turn(done, answer) words are a bare status; whether a blocked ending's needs_from_user or an ask_user question only asks your OK (see Work question card).

Craft entries take no extra reading: the scribe marks each new entry's nature (craft, a choice of look, a series' constant, other), kept on the ledger, which the conversation-wide default and the standing offer go by; older entries without one still go by the word lists.

Checks: the answer must be JSON and the control one of its four values; quoted clauses and sentences must be words of the line (spaces, punctuation and width aside). A clause not found is dropped, and when none is the whole line stands as one; a "still going" not found falls back to the sentence the lists find, else the start of the message. A "still going" sentence (the lists' too) found word for word, at least 20 characters of it (spaces and punctuation aside), in what the Bot answers is that line's own, not a promise of the Bot's: on 2026-10-08 you gave 专业翻译官 an English paragraph in your direct, it put the paragraph back above its translation, and the model read the paragraph's "The community-site search is still running. Once it's back, I'll compare the two…" as the translator's promise; the ending bounced once (it went on idly for three minutes), and a line after it told you to @ it in your direct. A phrase of a few words both use (「结论随后」) is no repeat. A cut-off or unreadable answer is no reading.

When it cannot read: with no model, a failed call, more than 20 s (waiting for a slot included), an unreadable answer or a draining daemon, the old fixed word lists read the line, and the work log says why — a stop, go on or complaint the lists find is not carried out, and the line goes to the Bot (for a stop that cannot wait, the composer's Stop button); where a line belongs has no lists, and the line goes to the desk. The lists are not widened to fix a miss any more.

Speed and cost: your line wakes no Bot, and no stop is carried out, until it is read, and the Bots it would wake show as thinking meanwhile; what it says and where it belongs are read at once, so it waits on the slower. Readings have their own slots per endpoint instead of queueing behind the Bots' long streams, ask for the lightest thinking level the model lists, and run on the model chosen for Reading under Tools → Roles (the default model otherwise). That can also be a Claude model of Claude Agent (the ones Claude Code's own /model lists, haiku first, the fastest): each reading is then one tool-less, single-turn call to your own Claude Code on the Claude account you pick (when more than one is listed), spending that Claude plan's usage, shown on the spend page as Claude Agent at an estimated price; it takes none of the Bots' Claude Agent slots, and at most two run at once. Measured, haiku reads a line in 3–5 s, about 1–2 s of it starting claude, slower than a model like deepseek. With Claude Code missing or that account signed out a reading is logged claude_unavailable, an error claude_failed, and both are read by the word lists; when Claude Code gives a reason for the error ("You've hit your session limit · resets 11:10pm", the plan's allowance for this window used up), that is the step's raw answer in the flow. Only you can pick a Claude model for reading: a Bot can only set an endpoint's model or the default; an account lines are read on must be swapped out before it can be removed from the list. The phone offers them as the computer does, asking this computer's Claude Code over the relay (ADR 0061, 2026-10-10 addendum). Each line is read once: yours cached by message, a Bot's by its text and what it answers (every place in a segment that reads it passes the same, so they share one reading). Every reading is logged as reader.answer (what was read — your line, a Bot's, or where a line belongs, filing — the model, why it failed, the reading, the raw answer); spend bills as organize with purpose reader, its own "Line reading" line in the spend view.

Lines in a row, and changed lines: Lines you send in a row in one conversation are filed and routed one after another: each waits for the one before it to be read, filed and routed (see Turn); what a line means is read as it arrives, and one read as nothing but a stop goes ahead. A line you changed is not read again: its cached readings are dropped, and whatever reads it later reads the new words.

Still rules: who a stop or a go on is for (who "you" is, every Bot, this job) — it carries nothing out; numbers read from your words (running time, resolution, aspect, frame rate); the one-time import of old rules on a new build; whether a line heard by a working Bot is a question or a change; an endpoint's canned refusal.

Avoid: fixing a miss by adding words to a list, a reading writing state itself, using a quoted sentence that is not in the line, treating an unread line as unsaid instead of falling back to the lists, a stop, go on or send-back carried out on the word lists' reading

Organizer

Background organizing of a conversation's plan notes and ticket handovers, not a working Bot and not the source of user requirements. The new work-item path does not use it to choose message attribution; older migration-compatibility paths and quiet-plan handover organizing remain. Details: Behavior · Organizer.

Behavior details

Version boundary: engine_level >= 2 does not call organizeMessage, and a new segment does not use resolveTurnTask inheritance/fallback opening or ownOpenTicket to choose its job. Deterministic signals or the Bot's desk choice replace that pre-turn guess; no signal does not silently openTask. Levels 0/1 still use the old paths: their functions, message-mode prompts and run logs are not physically deleted. Settle after 30 quiet seconds still files only the handover; the organizer is not claimed fully retired before P4c/P4e replace its progression and delivery judgement. Quotes, the ledger and user confirmation still protect Rules and Done when (ADR 0042).

The following details are retained legacy message paths and settle behavior; pre-turn message mode applies only at levels 0/1:

A short, tool-free call that organizes the plan and tickets on a session's behalf, running on the model chosen for the Organizer under Tools → Roles, else on the default model of the default endpoint (thinking at high when one is chosen). It runs at two points. First, after your message enters the session and before any turn opens, it judges whether the message continues the current plan (continue), moves on to a different thing (new), returns to an earlier one (resume), or is about a job the Bots here are pushing forward in another session (join: say you tell a Bot in your direct about the job it is doing in a group; a job opened elsewhere stays there, and this session's current plan is unchanged), updates the plan and tickets, and marks which ticket the message is about; once the message is stamped with a plan and ticket, every turn it opens (mentions, joining in after a judgement, forks) lands in the same place. Second, 30 seconds after all of the plan's live turns have ended and it has gone quiet, it organizes again (a turn you Stop does not lead to this: a Stop asks the work to stop, and the call-back after organizing would have it carry on; a Stop also cancels the organizing an earlier turn of the same plan had lined up but not started, and the plan's own wait before looking at it again, and an organizing already under way calls nobody back when it ends; other plans are not affected): it files what those turns handed over under tickets and updates ticket status, who is on it, and Progress. It reads the current plan's fields and tickets (each ticket with the files that landed in its folder and have been referenced), what has happened since the last revision (who said what, what was handed over, the trace, and the commands those turns actually ran with their exit codes), the plans this session moved forward earlier, the jobs the Bots here are pushing forward elsewhere (the whole plan, its tickets, where it was opened, who is working on it where, and the lines of this session filed under it earlier), and the existing Kind tags; precedents of the same Kind are gone, and it no longer reads them. It also reads every line you said about the job: the earlier ones beyond what happened since the last revision, and your answers to questions (a repeated line counts once; when there are too many it keeps the first few and the latest, within a length cap), and whether the goal and each ticket description are ones you typed on the board yourself (these count as your words too, and cleanup leaves them alone). Every line is marked as said by you, by a Bot, or by the app, and an answer to a question counts as yours. It does not write Done when or rules: the prompt no longer asks for them, and any in its answer are not taken; a plan it opens has neither, and an existing plan keeps its own, what you wrote on the board and what earlier filings left; what your lines ask goes into the requirements ledger through the scribe (see Scribe). What a Bot decides goes into neither the Goal nor a ticket's description, but one of three ways: a hold it put on itself (pausing, freezing, no retries, doing only part of it) goes under Process with who decided it, and what is held back because of it goes under Progress as stuck, with what would unblock it; something that waits on you (an authorization, a key, a go-ahead to spend) goes under Progress as stuck, with what you need to do; a working constraint (don't overwrite the original file, where the delivery goes) goes under Process. Once you say keep going or don't stop, a hold a Bot put on itself is lifted wherever it was written (Process, Progress, or a ticket's description) and what it held back moves back to to do; a hold that waits on you is lifted only once you give what it waits for, and a working constraint stays. Only on a line of yours, and only when it can see every line you said, does it widen a goal a Bot narrowed back to what you asked for. Under Progress, to do lists only what is not done yet; something handed over and only waiting for you to look at it does not count. A ticket's description says what to hand over, not progress. When the plan goes quiet, organizing only files the handover: what was handed over, where each ticket stands, who is on what, Progress and Process, whether the plan is done, and any checks it proposes; it leaves the Goal, the Kind and each existing ticket's title and description exactly as they were (an empty description may still be filled), and does not park the plan; the app sends such changes back and logs a line for each. This holds whether or not you said anything since the last revision: your lines were filed, and handed to the scribe, when you said them, so the quiet pass has nothing new to go on. If the plan changes while that call is running (a line of yours was filed into it, or you edited it), nothing from that call is applied. A Bot saying "done" or "tests pass" does not count as evidence: marking a ticket In review requires files handed over by that ticket, and marking it Done also requires a record of a run. When several parties each build a part that only works once combined, a separate "Integrate the parts and give the start instructions" ticket is opened. If the organizer judges the plan done while tickets are still To do or In progress, the plan does not count as done: its other changes this time are still accepted, and the plan stays in progress (marking it done yourself on the flow board is not subject to this limit). A failure changes nothing: if no default model is configured, the endpoint refuses, the answer is malformed, or the database rejects the change, the plan stays as it was and turns open as usual. An answer that returns to an earlier plan or joins a job elsewhere, when by the time it is read that plan is no longer one it could pick (say the turn on it elsewhere ended while the call was out), files nothing either, and the message stays as it was: the answer was written for that plan, so landing it on the current plan would write over the current plan's fields, and with no current plan it would open a copy nobody asked for. An answer that names this session's current plan is the exception: that is a continue in other words, and it lands as one. No turn runs during the few seconds of organizing, but the Bots this message will wake (in a direct, that one Bot; in a group, those mentioned, or every present member if no one is mentioned) already show "Thinking" under it, and in the list and the header as well; once organizing finishes, each hands over to its own turn or judgement without a gap. Its spend is a separate category, "Organizer", under decision routing, and it belongs to no Bot.

What came of hand-overs (2026-10-10): the organizer reads each ticket's stage (handed over, in review, rework, approved, dropped) and how its newest hand-over came out — who decided it (you, a reviewer or the app), your words when you sent it back, and whether it waits on your approval — and every approval, send-back, and line of yours that put a ticket back to rework since the last version (with that line). Your send-back outweighs a Bot's word and the checks: a ticket in rework, or whose newest hand-over you sent back, is never written as passed, fine or "matches the sample" in the progress, and what you want changed goes under to do; a passing sample check only says it matches the sample, it is not your approval; one handed over again and waiting on you is not written as passed either. In the trace it reads, a turn that said nothing reads "said nothing this turn" and one that only handed over files reads "handed over N files", no longer as the line that woke it. Before, it saw only the ticket's status, and your send-back on a card lived only in the work record and a Bot-only notice it never read: one job's progress four times called a sample shot you had just sent back "matches the sample". A Bot's card on the trace also shows the turn's last part with words in it: a reply often ends on a part with files only, and the card used to take that one and draw blank. The trace also draws your decisions: your answers to a Bot's questions (with the question), your approvals and send-backs on cards (a send-back with your words; an approval whose checks then failed, with what came of it), and a line of yours that put a ticket back to rework are each a card of yours under the turn it answers, marked Answered, Approved, Sent back or Back to rework, and "only what matters" keeps them. Before, the trace drew only the lines that woke a turn: the IG MV job's 4 answers and 14 approvals and send-backs were nowhere on it.

Avoid: every message waiting for organizing first, retained compatibility code described as deleted, organizer rewriting user requirements, a Bot's claim treated as acceptance, a hand-over you sent back written up as passed, a passing sample check taken as your approval

Organizer run log

Every organizer call that actually reached the model, whether or not it landed, gets one row: the raw answer it read, the decision it parsed out, the candidates it could pick from (which plans it could resume or join, which acceptance checks it could edit — as read when the call went out) alongside the ones the answer actually picked (as the model wrote them, before validation — when a named resume/join target no longer qualifies, the decision falls back to continue, but the row still keeps what it named; a resume/join target only counts as named beside the decision that uses it. Whenever the written decision is not the one that applies — a target that no longer qualifies, no target at all, a word that is none of the four, anything but continue from a settle — the row says why), the same candidate sets re-read once the call returned (compare the two to see whether they shifted while it was out), whether it landed, why not when it didn't, notes on a clean apply that still held part of the answer back (a settle that called a parked plan active, a field a settle kept because it only files the handover, tickets that kept a plan called done still active), and which ledger row this call was billed as. GET /v1/debug/organizer-runs?task_id= reads a plan's rows, local only — never on the remote whitelist, never reachable from a phone; Bots can query it through the records (ADR 0065); each session keeps only its newest batch, and clearing history or deleting a group takes this log with it (unlike spend, which is kept on purpose). Only when the window spawns the source daemon itself does its stderr land in daemon-dev.stderr.log in the data directory (rotated once by size, checked only at each spawn) — pnpm dev's own daemon is pnpm's child and never passes through that code; where the window has no console at all this used to go straight to /dev/null, and under tauri dev it was already visible in the terminal and just moves into the file instead.

Avoid: a screen made for you, the main transcript, the remote whitelist, a packaged build also writing this stderr file (only the source-run dev daemon does), the pnpm dev daemon writing it too (it never runs through this code path)

Check-back

A one-time timer reminder a Bot books for itself, recording when to return, what to check and its original work; not an event wait for another Bot's result. Reminders of different work items must not replace one another; a hold can suspend one, while clearing/deletion can void it. From level 6 it is not for waiting on you: while the ticket waits on you (your answer, your word on a hand-over, a ceiling card) none is booked, and one due meanwhile is voided and wakes nobody — what you say next wakes the Bot anyway. Details: Behavior · Check-back.

Avoid: guessing delegation results from a timer, reminders of different work items replace each other, a timer reminder is a supervisor, a timer to wait for your reply

Level-0–2 legacy behavior: the conversation-replacement and quiet-callback detail below is retained as migration reference, not level-3 waiting rules. Level 3 deduplicates by work-item/key; see the behavior details above.
A one-time wake a Bot books for itself: how many minutes from now (one minute to seven days), what to check at that point, and what to do if nothing has happened. When it comes due, the daemon inserts a system line "Check-back: " into the same session to wake the Bot. That line is the Bot's reminder to itself: only the turn it wakes can read it, and the flow board draws the Bot waking itself; the session does not show it, and other Bots, the organizer, search and unread never see it, just as a person would not read their own memo aloud to everyone. That turn keeps the plan and ticket of the turn that booked it, and only works in them: it does not change the plan's status or make it the session's current plan. Its situation holds the job's plan, the ticket list, the files handed over so far and the trace. If the Bot already has a live turn there, the check-back is heard by that turn; in a direct with you, only by a turn on the same job, so two turns never do one job and write the same files at once. Otherwise a new turn starts, beside yours in a direct with you, as a second message of yours would. Use it after a handoff, or while waiting on a result outside the Bot's own control, so that someone comes back to check on handed-off work instead of relying on the other side to remember to mention the Bot again. A Bot has at most one pending check-back per session at a time, and booking another replaces it; the situation block marks the Bot's own pending check-back. It is voided if the turn that booked it is Stopped (once the engine level has reached holds, only set aside until you next speak about that job), if the session is cleared or deleted, or if the Bot is deleted; a hold over it only sets it aside until the hold is lifted; if the Bot has left the group or been archived, the check-back is only cleared when due and wakes no one. If the daemon slept through the due time or restarted, a check-back that came due without firing fires once to catch up. It does not appear on the routine calendar and is not an event trigger. The app also books one on the Bot's behalf: when a Bot↔Bot direct the Bot opened goes quiet (about 10 seconds after the last turn ends, with no live turn and no pending check-back inside), the app immediately wakes the Bot in the session that opened that direct. The check-back line says whom it talked with and who said what last (or, if the other Bot never replied, says so), so the Bot first reports the outcome there; this likewise replaces its existing pending check-back there. If nothing new has been said in the direct since the last call-back, it is not called again; for a direct opened from such a check-back, if the other Bot never replied, there is no call-back either, so two Bots do not spin back and forth over silence. When a turn in the direct is Stopped or interrupted by a restart, there is no call-back; that is for you to pick up. Plans work the same way: when a plan goes quiet (organized, no live turn, and no pending check-back inside; a turn you Stopped does not make it quiet) but still has tickets To do or In progress, the app books an immediate check-back for the Bot on the first ticket not yet closed out (or, if no one is on it, for the Bot that last spoke in this plan). The check-back lists the tickets not yet closed out and points out that Bot's own, and the turn runs in that ticket's directory. A group plan of more than one ticket that is not parked, with none To do or In progress and something handed over or done (In review or Done), whose Progress still lists work to do or held up has stopped too; held-up work counts, since a Bot's own freeze is filed there and nobody else will lift it. Once the plan has had nothing happen for ten minutes and you have not spoken in the session for ten minutes either, the app books one for the Bot that last spoke in this plan (if that Bot already has a pending check-back in the session for another plan, not yet: the plan is looked at again once that one has come due and ten quiet minutes have passed). It says first what is useful next — check each ticket In review against its Done when and give the commands run and what they showed, never passing someone else's work for them nor its own; hand what is not done yet to a Bot who can take it, by name; for what is held up, the situation records who set that pause or freeze; ask you what needs your decision or what only you can give — and then lists the tickets In review; that turn runs in the plan folder. What is still to do or held up is in the situation's Progress and is not copied again. In a direct, with a single ticket that is not parked, or with nothing to do or held up left in Progress, no one is called: that is most likely something handed over and waiting for you to look at it. A turn the call-back opens that only says again what that Bot already said in the job — identical once formatting comes off, or differing only in a few English articles or wording such as “run longer / be longer”, with numbers, negations, code, links and paths preserved in the comparison, and with no new files — ends without posting. If no ticket has moved to In review or Done after the call-back (rewording a ticket does not count) and no acceptance check has passed for the first time, the app stops calling Bots and only sends you a notification, "This plan has stopped…", so you decide whom to call; the review is not posted in the session; while you say nothing in the plan and answer none of its questions, it is called back no more times than it has tickets and acceptance checks, and never more than five, and then stops the same way. This happens only in sessions you are in. In a group, if the called-back Bot already has a live turn, the check-back is heard by that turn, just like a mention.

Behavior details

A check-back is a Bot's timer reminder to itself, not a delegation's event wait. Existing check_back(after_minutes,note) remains one minute to seven days; this round does not rename it into the planned wait_for(minutes>=5) or enable external-job polling. When due it creates a private trigger for that Bot under the original plan/ticket, without changing plan stage itself. Holds suspend it until a user lift permits firing.

Level-3 scope change: timer replacement/restoration uses exact work-item/dedupe keys, not “one appointment per Bot per conversation”, and cannot overwrite delegation_wait. Levels 0–2 retain legacy conversation-scoped dedupe, while no level fires delegation waits through due scanning. At levels 0–3 the old quiet-plan/direct plan_nudge/report_back remain; from level 4 they no longer run, ones booked before and still pending are voided when they come due, and the supervisor wakes the ball holder instead. In the dispatch queue a Bot's own appointments and routines come last (priority 4, after your lines 1, delegation results 2, supervisor wakes and delegation requests 3).

Avoid: polling, self-wake every few minutes, on the routine calendar, event trigger, central scheduler assigning work to Bots, duplicate check-backs in one session at old levels (not different level-3 work items), calling the same Bot again and again after a plan has stopped

The two the app booked for a Bot above (the call-back after a quiet direct, the plan call-back) run only at levels 0–3; from level 4 the supervisor takes over, and ones still pending from before are voided when they come due.

Supervisor

From engine level 4, every 15 seconds the daemon checks the work that is not closed: waits whose object is gone, segments interrupted or failed, tickets nobody is moving. From records in the database it wakes the ball holder or picks up from where things stopped, within limits; when those run out, or it must not go on by itself (an external call with no known outcome, you pressed Not now), it leaves a line in a conversation you are in, with a notification; work it picks up on its own gets no notification or card when a turn of it fails or a restart cuts it. No model calls and no in-process timers, so a restart loses no deadline; after a restart it goes on by the restart's cause (a clean stop, a crash, a development restart). Details: Behavior · Supervisor.

Behavior details

From level 4 (ADR 0045), on every 15-second scheduler tick, before due check-backs, the supervisor does three things in one write; levels 3 and below do none of it. Each call-back or pick-up is a fired check_backs row (kind = supervisor, its wait_spec saying why, which attempt, which progress cycle or restart), and repairs, restarts and notices go to the work log as supervisor.*; every time is read from those records, so a restart loses no deadline and repeats no wake. Delegation replies and cancellations, your answer on a question card, and lines queued into an inbox still queue in their own write and dispatch at once, without waiting for the tick.

  • I6: a waiting work item whose object is gone (the request cancelled, the other side's work closed, the check-back gone) needs attention (supervisor.wait_invalid), and in the same tick gets a Bot-only line saying that wait no longer stands. A wait a stop covers is a valid wait.
  • Idle work with mail in line: an idle work item with queued mail that would wake it is queued again (supervisor.requeued), so the dispatcher sends it. Only queued work is dispatched, and the mail in line keeps the supervisor from calling the Bot back, so the two would wait on each other for good. A segment's end does the same: mail queued on its work while it ran, unread by it, is the work's next step, and the work stays queued instead of going idle. On 2026-10-04's real-model run the copywriter was reviewing the poster when the lead handed in a newer version; the new review request was queued on the same work, the review segment then ended nothing_new and set the work idle, and the newer version was never reviewed. When a segment moves to other work (work_on to a ticket, a write binding it to one), work it leaves with mail still in line is not closed but left idle, and queued again as above; mail on closed work is sent by nothing, and the supervisor no longer counts it as mail in line. On 2026-10-09 three video results for IG MV were queued on the director's job-level work, a write bound the segment to a ticket eight seconds later and that work was closed, and the results stayed queued, never read; the supervisor took them for the director's mail in line on the job and never again called it to any of the job's tickets — on 2026-10-13 it handed over one ticket per segment and stopped, and each next one waited for you to speak.
  • Work that needs attention: a segment interrupted (a restart, a drain), failed (failed again after one retry on the same model, stuck past its limit, a runtime error), out of its two ending-contract bounces, or with its wait gone puts its work item in needs_attention (an interruption or failure in the same write as the segment's end; a running item with no live segment whose last segment was interrupted or failed is caught up by the tick; one whose last segment ended any other way — a Stop whose hold you lifted with its button, a closing the contract did not see — and that no stop covers goes idle on the tick, where the call-backs below find it). The supervisor picks it up: from that segment's own interrupted or failure line, as its Continue would — same conversation, same stops and slots, the line marked continued and its notification resolved — or, with no such line, with a Bot-only line saying what happened to the last segment, its last step and which attempt this is. At most 3 times an hour per work item; then one line in a conversation you are in, with a notification, and no more automatic pick-ups. A failed turn of work it will pick up gets no "turn not finished" notification of its own (from 2026-10-04): you are told by its line and notification once it stops retrying, or when the last step has no known outcome; a failure it does not take up (a turn on no job it watches, levels 3 and below) is notified as before. When the engine cannot continue from that line (the conversation archived, the job already under way elsewhere), the pick-up is recorded as supervisor.pickup_refused and voided: no attempt, no hourly budget spent, and the next tick picks the work up by a queued wake rather than that line again. The same Bot working on another job in the same conversation is no refusal any more (see Work item). Not while a stop covers it, the ticket is closed, or another request's recipient holds the ball; work a restart cut off follows the restart's cause first (see Interrupted). Mail in line on the work is no reason to wait (work that needs attention is not dispatched: on 2026-10-04's real-model run a review request queued on work whose segment had just failed made the two wait on each other); the segment that picks it up reads that mail too.
  • Tickets nobody moves: an open ticket whose ball holder is its owner, the plan's lead or an unanswering request recipient, where that Bot has no live segment, no valid wait and no queued line on the job, and no work cut off or failed on any ticket of the job that has not been taken up again (a Bot has one live segment per job, and the cut work comes first: while a restart notice said it would not go on by itself and waited for your Continue, or after you chose not to continue, the Bot used to be called to the next ticket of the same job two minutes later — on 2026-10-04 it redrew the cut ticket's frames under the next ticket), in an active, non-dormant, non-routine plan whose dependencies are done, is called back once it has been quiet past the threshold, with only the facts (which ticket, how long quiet, owner/lead/which request it owes) and the ending contract's choice. The threshold is 2 minutes from the job's last activity (lines filed to it, its segments' activity, its work log); 10 minutes when, among conversations you are in, the job's last line is a Bot's and came after your last line in the job, counted from that or from your last line in that conversation, whichever is later — whether it asked anything is not read. At most 2 call-backs per progress cycle; then it stops calling, recorded only in the work log (supervisor.notice, once per cycle): no line, no notification, and your next word to the Bot goes on (from 2026-11-11, ADR 0109; before, a "This has stopped" line and a notification went to a conversation you are in, one per open ticket of a job). A Bot whose last ended turn failed because its agent is missing, signed out or out of usage is not called back, nor its work picked up, until a turn of it ends some other way: only you can clear those, and each call fails the same way at once (on 2026-11-10 the video director, out of usage, was called back to four scenes twice each in 20 minutes, and its direct got ten identical failures in a row).
  • Progress is only what the work log records: a ticket's stage changing (board, organizer and observed work all record ticket.stage_changed), a check passing for the first time (check.first_passed; a model-judged seams check must pass twice in a row), a new content hash in the ticket's folder (written files are hashed, streamed, when the segment ends and recorded as artifact.changed; reserved folders and files over 2 GB are left out), and deliveries and reviews once P4e writes them. Editing a description, a changed updated_at, or words do not count.
  • From the moment it is on: when the database reaches level 4 the work log records engine.level_raised. Tickets already quiet, and work already waiting or needing attention before then, are not all woken or picked up on the first tick (even with dozens of old plans open at the upgrade); once anything happens in them (a line of yours, a board change, a new segment) they are the supervisor's. Work cut off by the restart that did the upgrade is not "before", and goes on by the restart's cause.
  • Its lines: pick-ups used up (retry_budget) and a last step with no known outcome (unknown_effect) each leave an app system line, out of every Bot's context, with control {kind: "supervisor", code, task_id, ticket_id, work_item_id, offer: []} and no buttons, plus a notification (failure, titled "stopped"). The line says how to go on: @ the Bot, press that segment's Continue, or change the ticket on the board. Two call-backs with no progress (stalled) leave no line from 2026-11-11 (above); older lines still show.
  • Effect ledger (tool_executions): write_file, delete_file, shell and non-read-only MCP calls record a start before acting (once per call; a repeat does not run and returns repeated_effect) and an outcome when done: succeeded, refused, failed or unknown — unknown when aborted, when an MCP call errored after it was sent, on a timeout, or when still running as the segment ended. The supervisor treats an unknown shell or MCP call as an external call with no known outcome: that segment does not go on by itself, and a line tells you (unless a restart notice already did). An older segment with no ledger rows but shell/MCP runs in its record counts the same when an interrupted segment would be picked up. A run that names its call, and whose call has a ledger row, is accounted for by that row, not counted by the clock; a named run with no row, in a turn the ledger covers, is a call that needed none (a read-only MCP query, a command refused before it ran) and is not unknown: the local agents (Claude Agent, Codex and the rest) record the run a millisecond or two before they close its row, so counting by time made every shell they ran unknown, and before 2026-10-12 none of their cut or failed segments went on by itself.
  • Submissions (from level 5): each tick (outside your stops and dormant plans) also takes on submissions checked, with no reviewer, waiting longer than 15 seconds, by their checks as they are now: one whose ticket has a reviewer by now goes to it, an organizer's reading included; a gate that ran and failed sends it back to its producer (a line wakes it), one not finished yet is waited for while the app runs it; an organizer's reading and an answer are never approved on their checks alone, period: they wait on your word (before 2026-10-11 a card asked you to approve or send them back); a file hand-over (explicit or implicit) is approved on its checks only when at least one check you wrote or confirmed is bound to it and every gate passes — the organizer's checks still send it back when they fail, but their pass backs nothing, since one may only ask that a file exists (submission.approved, by: no_reviewer) — with none bound at all it ends on the same card, which opens to the files themselves. A required item (said twice or more, or about the picture) with no passing check you confirmed behind it is yours to look at too: it is listed on that same approve/reject card, with what the app measured on it, and approving counts it as met, the ball yours — one card per hand-over (from 2026-10-07; before, such items got a card of their own first, another for each one read while it waited, and only then the approve/reject card). A routine's runs never end on a card: they are approved once their gates pass (by: routine, see Submission). Nor does a file hand-over made in one go (2026-10-06): on a job with one ticket not dropped, which no approval or required-items card has ever asked you about, handed over by the only segment since the job opened (or was last approved), it is approved (by: one_go), required items with nothing behind them included (from 2026-10-07); segments that start after the hand-over (your next line while it waits, say) do not count. A job of several tickets, of several segments, or once on your card still asks you. While a hand-over waits on you, card up or not, a line of yours on its job that its Bot is at work on (a segment opened by or hearing it still running, a question to you unanswered, a generation job of its own awaited, the line still queued) holds it: no card, and one already up comes down saying 「你又说了这件事,等X按你说的做完再问你。」; what the Bot hands over for the line supersedes it and is what you are asked about, and if the work ends with nothing new handed over, this one comes to a new card that says so first (from 2026-10-07; segments that only read, another Bot's work, lines about another ticket and a 放行 you already pressed do not count; from 2026-10-08 a segment that heard the line counts on whichever ticket of the job it was). A hand-over that needs your look comes to its card only once its Bot has stopped working on the job: no segment of its running there (one waiting on your answer or approval, or only reading, does not count), no generation job of its own still out, nothing just queued that wakes it, and its last segment there ended more than a tick ago; a large job's sample counts its own ticket only. What it hands over meanwhile supersedes the older one, which never came to a card; each hand-over held this way records submission.card_deferred once (from 2026-10-08, stillAtWork). A submission waiting on your card is taken up again each tick against what is true then: a card waiting only on its required items (a check you confirmed backs the rest) approves it with no resubmission once they no longer hold here or a confirmed check passes on them, and says 「已放行。」; any other approve/reject card waits on your press alone, never flipped by a later tick on its own — pressing Approve while a gate has not run yet runs it first and takes the press up again once it has, not a bare approval and not a failure either: meanwhile the card reads 「等检查跑完再放行…」 with only Send back left, and a second Approve is refused; a gate added while it waits is run at the next tick before deciding; the card does not say Approved until it actually is, and a failure shows as sent back with what failed. A card a newer hand-over took over, or one your status change on the board voided, loses its buttons and says which. A ticket in review that nobody moves calls back its reviewer; a reviewer's approve does not always approve it either: not an organizer's reading or an answer, which nobody actually made, nor a file hand-over no check you wrote or confirmed backs when the reviewer runs on the producer's own model (a model nobody recorded counts as the same) or gave no evidence on a requirement that applies to it (a made-up requirement id does not count) — one Bot passing another's claim. Then its approve only moves the submission to awaiting you, the card showing the reviewer's own verdict (name, model, whether it ran on the producer's own, its notes); its reject still sends the ticket to rework as before. The tick an organizer reads a ticket as done, if its producer still has a segment running on it, or a work item that is not idle, that reading is skipped rather than raced ahead of real work; the organizer tries again next time it reads the ticket as done. From 2026-10-11 (ADR 0084) none of the cards above goes up, nor any notification: what would have asked you is recorded at that tick as waiting on your word (awaiting, work event submission.awaiting_word, once per hand-over), the reviewer's verdict and the unbacked items kept with it; the rules for when a card goes up, comes down and goes up again (stillAtWork, submission.card_deferred, "handed over nothing new this time") are gone. Your word lets it through as 放行 on a card did: a gate not run yet runs first, a failing one sends it back; one waiting only on its required items still goes through by itself at a tick once they no longer hold or a confirmed check passes on them.
  • Not done: a failing plan-level check bound to no ticket calls nobody back (levels 0–3's plan call-back would; one bound to a ticket sends the ball back to its owner); external job polling (P4d), listed as unsupported in every tick's result (level 4 also lists reviewer assignment, which submissions take on from level 5); the board does not show "ball with: …" yet.

Avoid: polling every Bot on a timer, in-process call-back timers, counting an edited description as progress, picking up work under a stop, repeating an external call with no known outcome after a restart

Ball holder

Who an open ticket is waiting on right now: the recipient of an unanswered request; you, when a question of the job awaits your answer, it is blocked, a stop covers it (or a ticket it depends on), or it awaits your review; from level 5 you while its approval waits on your word, its reviewer while it is in review, and the app (taking it on at the next tick) when it was handed over with no reviewer; otherwise the ticket's owner, then the plan's lead, and with neither, nobody (unclaimed, yours). The supervisor wakes only the ball holder. Details: Behavior · Ball holder.

Behavior details

Derived for each open ticket in order; the first that holds is it:

  1. An open request on it whose recipient can still take work: the ball is with the recipient's work item. Not a request for a deliverable whose recipient's hand-over is in its checks or in review (waiting on your 放行 included): the ball is then the reviewer's or yours, as in 5, and approval answers the request. It used to count as owed by the recipient, so while your 放行 waited the supervisor called the recipient back every three minutes to "answer" it, and it handed the same work in each time (2026-10-04 walkthrough: five hand-overs in twelve minutes).
  2. A question awaiting your answer: a live turn's ask card, or the work question card a blocked work item left.
  3. A blocked work item: the ball is yours.
  4. A stop of yours covers it, or a ticket it depends on: yours (paused). Held work never counts as stalled and is not reassigned.
  5. Awaiting review: yours — unless a check bound to this ticket (its ticket_id, or a path/folder inside its folder) failed when it last ran, which sends it back to the owner. From level 5 this reads the submission instead: while its approval waits on your word (before 2026-10-11, your answer to a card), it is yours; in review, the reviewer holds it; handed over with no reviewer, the app (taking it on at the next tick); rework is the owner's; a ticket left in review from before level 5 with no submission is still yours.
  6. Otherwise the ticket's owner, then the plan's lead, and with neither, unclaimed (yours). External jobs (handed to the poller) arrive with P4d.

The owner is tickets.owner_bot_id, written with worker; at the upgrade it is imported once from a worker that can still take work, else the Bot with the most turns on that ticket that can. The plan's lead is read, not stored: the stored lead_bot_id, else the Bot that opened the plan, else a group lead you confirmed in one of the job's groups (the home's first, then where you spoke last), else the Bot with the most turns in the plan — each only while it can take work and is not archived. Storing it would change who gets your unaddressed group lines, so it is not stored. Able to take work means not archived or deleted and in one of the job's conversations: its home, or one you spoke about it in. A job often opens in a direct and goes on in a group (on 2026-10-03 《一拳超人》 opened in your direct with 审片员 and went on in the group once 审片员 was archived): counting the home alone, no Bot doing it in the group could take work and its tickets were nobody's. A holder with no work item is woken where it last worked on the job (a conversation you are in, not a Bot pair's thread), and if it never has, in one of the job's conversations it is in (where you spoke about the job last first). Before, where you spoke last decided alone: one question in a group about a job being done in your direct sent its next ticket to the group (2026-10-14); and the supervisor's notices go where you last spoke about the job, never to the direct of a Bot you archived or deleted.

Dependencies (tickets.depends_on) come only from you: PATCH /v1/tickets/:id {depends_on: [...]} (local and remote), other tickets of the same plan only, never itself, never a loop, never a newly added parked one, at most 39; while any is not done (a parked one does not count as waited for) the ticket is not called back, and while one is held the ball is yours. Whichever field changes, a ticket's owner is never its reviewer. On the board's ticket list, the picked ticket's "Depends on" setting opens checkboxes to change them, and the line under each ticket's title says what it waits for.

The ball on the board: from level 4, in an active plan that is not dormant, each open ticket on the list says who has the ball — with a Bot, waiting on the lead to hand it out, on a delegated part, waiting on someone's review, approved by the app at the next tick, waiting on a render, or waiting on you (an answer, something stuck, a stop, acceptance or an approval, the capability ceiling, nobody on it); at level 4 a ticket waiting for acceptance says to mark it done on the board, and from level 5, waiting on your word, it says "Waiting on your word: say it is fine, or what to fix" (before 2026-10-11 it said approval only with an approval card up). In a parked, done or dormant plan nobody waits, and nothing is said. A dependency cannot be a parked ticket (it would never end) or one that makes a loop.

Avoid: calling the Bot that spoke last, picking the worker of the first open ticket, letting the lead reassign held work

Closing check

A check made before a turn hands its deliverables to you, with no model guessing what is missing (ADR 0037): when the message a Bot is about to send cites workspace files or says it is still doing something (whether it promises more, and whether it claims a run, is read by line reading), you are in the session and the turn belongs to a job, the daemon looks at three things before sending: whether the job has acceptance checks that are not passing, whether a "the rest comes later" is backed by a check-back or a named handoff, and whether a "tested" is backed by a command this turn actually ran. If any is missing, the turn gets it back once; a turn is checked once, and it is a reminder with evidence, not a gate. A Bot that says it is still working and then ends with nothing owed on the work is turned back once more by the ending contract, and if it ends that way anyway the conversation tells you it stopped (see Behavior · Delegation). Details: Behavior · Closing check.

Behavior details

P4c checkpoint: the legacy regex/run-evidence checks below still run. Adding level-3 ending obligations does not remove “later” or pre-delivery checks; retaining claimsVerification and extending coverage to pair directs still need final-cutover verification. This round does not claim identical closing-check coverage in Bot↔Bot directs or treat this reminder as real implicit submission. Current ending facts and gaps are under Delegation.

A check made before a turn hands its deliverables to you. When it happens is unchanged: the message a Bot is about to send cites workspace files, or says it is still doing something unfinished ("working on it", "results to follow"; a start announced as under way counts too — 正在编写, "I'll put the storyboard together and post it", 我将按照…, "I'm now drafting" — while 正在 in a scene, 埼玉正在超市买菜, does not; whether a message promises more and whether it claims a run is read by line reading, by the old word lists when it cannot be), you are in the target session, and the turn belongs to a job. Since 2026-09-29 (ADR 0037) no model guesses what is missing; it applies three fixed rules, and if any of them fails the Bot gets an app note back: one, the job has acceptance checks (ADR 0036) that are not passing — file checks are judged again on the spot, so a file fixed in this very turn is not bounced on an old result, a check from your words is measured again with ffprobe (one you have not confirmed, or not bound to a file yet, is left out), and command checks use their latest run, skipping one this turn already ran successfully; at most three are listed, with the reminder to fix the deliverable rather than the check, or to say in the closing why it cannot be done now; this rule applies only to replies that deliver (cite files). Two, it says the rest comes later but has neither booked a check-back here nor handed the rest to someone by name — once the turn ends nobody picks it up, so finish now, book a check-back, or name who takes it. Three, it says something was run, tested or verified while this turn ran no command at all (unless it says it was not verified). Through send_message the call does not run and returns the note; a direct reply gets the note as a line in the loop. A turn is checked once and not stopped a second time; a send-back is not a tool error and the chain review does not count it as a failure; the check itself makes no model call, and reading the message is billed as line reading. A Bot↔Bot direct without you is not checked, nor a reply that cites no files and does not say it is still working. The earlier step that had the default model compare the delivery with the plan's spec line by line is gone: in the golden-path ablation switching it off cost no completion and saved about a quarter of the spend and time, and the machine-checkable part of the done-when now runs as acceptance checks.

Avoid: checking every step, blocking the send, counting a send-back as a tool error, having the Bot's own model check itself, letting the model rewrite the closing, treating a self-written report as evidence of a run

Acceptance check

A check attached to one line of a plan's Done when that the daemon runs itself on this Mac: whether a file exists, whether it contains some text or matches a regex, a command's exit code and output, or whether the parts several Bots made fit together (a report's chapters, a storyboard or a set of posters, a deck, a video's shots: the app takes both sides of every seam and a model compares them against the plan's rules). You add, edit, remove and run them on the flow board; the organizer may only add and change its own, and a command only if a turn of this job ran it successfully or you wrote it yourself; the app also offers some from the numbers you give, which count once you confirm them (see Check from your words); Bots cannot write checks. While a check fails, or has not run since it was defined, the organizer cannot mark the plan done, and when the plan goes quiet the app calls a Bot back once with the failing checks; closing a plan by hand is not held back. Details: Behavior · Acceptance check.

Behavior details

A plan's Done when is a list of results you could check yourself; acceptance checks hand the ones a machine can decide to the daemon, which runs them itself instead of trusting a Bot's claim or a model's reading of its closing. Four kinds: a file exists (and is not empty), a file contains some text (or, reversed, does not), a file matches a regex (or does not), or a command (an expected exit code, 0 by default, and optionally the expected output, compared without trailing blanks and trailing empty lines). File paths, and commands with no directory given, are relative to the workspace root, as the file tree shows it; paths outside the workspace and commands that reach outside cannot be saved, are judged again when they run, and are recorded as blocked and not run if they reach outside — the app never approves anything on your behalf. A command runs under /bin/sh in its own process group, killed whole when it ends or times out (120 seconds by default, 600 at most), with only the terminal's environment whitelist (without SSH_AUTH_SOCK, and nothing of the daemon's own). Each run records its outcome (passed, failed, blocked, error), a one-line detail in the app's language and the tail of its output; a check keeps its last 5 runs. When they run: when the plan goes quiet the stale ones run first (never run since defined, or the job has had turns since), and the ones the organizer just added run after it files; a check you create or change runs at once; Run checks on the flow board runs them all at any time. One run per plan at a time, one command check at a time on the whole Mac, at most 15 minutes of checks per quiet stretch. Who writes them: you add, edit and remove them on the flow board; editing one the organizer added makes it yours, and the organizer cannot touch it again; the organizer may add, change and remove its own in its answer (at most 3 new ones a time, 10 per plan), a command only if a turn of this job ran it successfully (exit code 0) in that directory or you wrote it yourself in a line filed under the job, and never one you removed; Bots have no tool to write checks and only see them in the situation block and in map.md. A check belongs to one line of the Done when, matched by its text: when you or the organizer reword that line the check follows it, and when the line goes, the check is listed under checks that match no line, still run and still counted. Where the results go: on the flow board each line carries its checks' results, which open to the detail, the last run and the output; the organizer sees every check's last result, cannot mark the plan done while one fails (or has not run since it was defined) and cannot mark its ticket done, and records blocked and errored ones under Progress · Blocked as no evidence either way; closing a plan by hand is not held back. Before a plan call-back posts, the app compares the Bot's last 40 replies in the same session and plan. An identical reply after Markdown removal ends silently. An English reply with at least 12 content words also counts as repeated when only articles or wording such as “run longer / be longer” change and the remaining word sequence is identical. Numbers, negations, question marks, code, link targets, mentions and file paths remain in the comparison; new content or newly delivered files still go out. Direct replies and send_message use the same check. Replies triggered by ordinary user messages and existing history are preserved. When a plan goes quiet with tickets open or checks failing, the app calls a Bot back once, quoting up to 3 failing checks and the tail of their output and asking it to fix the deliverable, not the check; a further call-back needs progress first (a ticket handed over or closed, or a check that existed before the last call-back passing for the first time), otherwise it notifies you once that the job stopped, and posts nothing in the session; between two of your lines there are no more call-backs than tickets plus checks. Every turn's situation block lists the job's checks and their results.

Seams (continuity) is the fifth kind, for work that several Bots make in parts and that only counts as one delivery once the parts come together: each Bot reviews its own part, and nobody sees the seams. The parts come, in order, from one of three places: a command that prints them one per line (the most precise); a glob (every match in natural order, C2 before C10; only when every match is a video and no command is given is it taken for a master that keeps being re-cut, and the newest one is used); or one file split up — Markdown and plain text at level-one and level-two headings, HTML at h1 and h2, a video at the cuts scene detection finds (it misses cuts between similar shots: 6 of 11 on a real episode). Each seam gets evidence from both sides: for video, the last frame of one shot and the first of the next; for images, the two images; put side by side in one picture under the plan folder's checks/<check>/ (a reserved folder, never an artifact), which needs a model that reads images; for text, about 700 characters from the end of one part and the start of the next, which does not. Text also gets one whole-set pass: each part's heading, opening and the numbers-with-units and proper names in it, as one digest, to see whether the same thing is named and counted the same way in every part. The judge is the picture judge's model (chosen under Tools → Roles, else the default model of the default endpoint; for the calls that send pictures, the default model when the chosen endpoint model is not marked as taking pictures, while a chosen Claude model is always used), with the acceptance line, the plan's rules and one general list: agrees with the rules; follows on (a missing transition is named); the same thing stays the same (characters, products and proper names, terms, numbers and units, orientation and direction); the same style (for pictures, the look, rendering, palette and character design; for text, tone, format and numbering); repeats or gaps (not called when the evidence cannot show it). Nearly identical frames or images across a seam are good news: the seam is invisible. It answers in JSON only and is asked again once if the answer does not parse. It passes only when every seam and the whole set hold; otherwise the detail reads "K of N seams have problems: 02-market→03-channels: …" and the output lists every seam (with its image path when there is one), then the whole-set line. These calls are billed as their own spend kind, acceptance checks. Code does not use it: the seams between modules are checked by an integration or start-up command. The organizer may propose one too, but only on parts this job delivered or with a list command the job actually ran successfully.

The app also offers one kind itself, from the numbers you give, which counts once you confirm it: a video's running time, resolution, aspect or frame rate; see Check from your words.

Avoid: letting Bots write or edit checks, the organizer changing checks you added, the organizer inventing commands, treating checks as a gate against you, the app deciding by itself that a plan is done, moving a ticket back when a check fails, running checks with the daemon's environment, approving outside-workspace checks on your behalf, calling back without limit on check results

Check from your words

When you give a job a running time, a resolution, an aspect (portrait or landscape included) or a frame rate, the app offers an acceptance check from your own words that measures the video the job finally delivers: read as soon as your line is filed under the job, by fixed rules, with no model and no waiting for the scribe. It reads narrowly: a line that asks, supposes, complains, tells how a cut came out or asks for another version, a number about one part (a shot, the opening, the logo, subtitles), or one with a no before it reads nothing. Your words never make a gate by themselves: a number read is only an offer, listed on the flow board, with no card asking whether you want it (you just said it; you are not asked again); said again in another line, it is the same offer. An offer is bound and measured too, its result ("Unconfirmed check: 107.00 s; you said about 2 minutes") shown to you and the Bots, holding nothing back; only your confirm (on the flow board, or on the card that asks you about a requirement you said twice when a hand-over has nothing behind it) makes it a gate (in F-f: the 107-second master measured failing but not held back, and one confirm holds it back). From level 5 it still holds nothing back; when a same-model review passes something you said twice, what it measured is written on the card that asks you. A check in force never changes by itself: a different target you give later (set with the word for what it measures — running time, resolution, frame rate, aspect — or a word like "cut it to", "make it") makes a replacement card, with Confirm, Change and No, and the check stays in force until you choose — the one time an offer gets a card, since until you answer the Bots are held to the old number; said again, the card is posted again saying "You have said it N times". When the words you confirmed it on are erased, it goes back to being an offer, never quietly deleted. Complaints never touch a check. "About 2 minutes" is 108–132 seconds, "2 minutes or more" holds the lower end only, "within 90 seconds" the upper end only, and any other number read is met within 10% either way. It measures the video a Bot delivered with the word MASTER in its name, else final, else under deliverables/; never a name naming a shot, another version, a format or a preview, nor anything in a footage or reference folder. On the flow board it can be confirmed or removed, not edited. Details: Behavior · Check from your words.

Behavior details

When you give a job a running time, a resolution, an aspect or a frame rate, the app offers an acceptance check from your words that measures the video the job finally delivers. As soon as your line is filed under the job (every turn it opens has opened), or you answer a question or change the goal, Done when, rules or a ticket description on the flow board, the app reads the numbers from the job's quotes by the same fixed rules as the requirements ledger (see Requirements ledger): no model call, and no waiting for the scribe. A board edit counts only for the clauses you changed (adding 「,加字幕」 "add subtitles" to 「剪一支约 60 秒的宣传片」 counts only 「加字幕」); text the organizer wrote that you only kept is not your words. It reads narrowly: a misread costs an extra offer, a miss one offer fewer. A running time needs a word for a bound ("about", "around", "at least", "at most", "within", 约, 左右, 以上, 以内), a word setting the work to it right before it (剪成, 做成, 改成, 控制在, "make it", "cut it to"), or the word for a running time earlier in its clause (片长, 时长, "duration"); a resolution, an aspect ratio, portrait or landscape counts as it stands, a ratio only with a word for the picture's shape in the line (画幅, 比例, 屏, "aspect"; 「比分 2:1」, a score, is none), and a frame rate only written as one (帧率, "fps", 每秒 N 帧: 「淡出 24 帧」 is a count of frames); 最长, 上限, 顶多, 别超 and "max" read as at most, 最低, 最短, 下限, 打底, 起步 and "min" as at least; 「预算 2k」 ("budget 2k"), 「报价 4k」 and 「码率 8k」 are no resolution. A line that asks (吗, a question mark, 能不能, 怎么样, 你觉得, 试试, "can you"), supposes (如果, 会不会, "if", "would"), complains (a word for something being wrong, 短了 and 有点短 "a bit short" included), tells how a cut, or an interim one, came out (上一版, 这版, 这次, 第一版, 之前, 原来, 现在, 你交的 "the one you delivered", 只有, 才, 已经, 显示 "shows", 为什么, 怎么, 粗剪 "rough cut", 完整版, "was", "it's", "now", "only", a clause that only says 可以 "fine", or 了 after the number), describes a file on hand (我拍的是 "I shot it in", 相机 "camera", 客户给的 "the client's", 显示器 "monitor", ffprobe), asks for another version (横屏的也做一版, 竖版的也要, 抖音版 30 秒左右, 横屏版, "a landscape version too") or is about a still picture or a screen (a photo, a poster, a cover, a wallpaper, a KV, a GIF, an interface) reads no number at all: 「太长了,改成 2 分钟」 ("too long, make it 2 minutes"), 「这版改成 90 秒」 and 「能不能改成 90 秒?」 read nothing; to change it, say it on its own (「片长改成 2 分钟」) or confirm on the flow board. A number about one part of the work counts for no dimension: a shot, a segment, the opening or ending, titles, the logo, subtitles, the voice-over, the climax, a scene, an empty shot or each page named in its clause («开头控制在 5 秒以内», «logo 在 5 秒左右出现», «C09 做成竖屏»), or named in an earlier clause when its own does not name the whole film (片长, 总长, 成片: «C09 这个镜头,时长 8 秒» is the shot's; «加中英字幕,片长约 2 分钟» still counts); 这段 / 那段 ("this segment") and 采访 ("the interview") are parts too; a line filed under a shot's ticket or an annotation counts for none either (the job's own ticket is not one: it is named after the job, even when that name is cut short on a word like 片尾). In a clause about the footage, a reference, the music or a song, or after an earlier clause about one when its own does not name the whole film, only a number set by such a word counts («把素材剪成 90 秒», "cut the footage to 90 seconds"). A no before a setting word drops the number («不要剪成 90 秒» "don't cut it to 90 seconds», «别压到 60 秒以下»); in «帧率 24 改成 60» or «分辨率从 4K 降到 1080» ("from 4K down to 1080") only the new number can read, and the old one or either of two choices («24 或 30») never does. A number you said no to, a moment or a place in the picture («1 分钟左右切到产品», "cut to the product at about a minute"), a decade ("90s 港风", 「90s 那种感觉」) or how long something else takes ("done within 2 hours", "the task takes about 3 hours") is not read in the first place (see the ledger).

The numbers read are of two kinds. A target sets the number for the deliverable: the word for what it measures in its clause (片长, 时长, 总长, 成片时长, 分辨率, 帧率, 画幅, 比例; "running time", "length", "resolution", "frame rate", "aspect ratio": 「片长约 2 分钟」, 「画幅 9:16」, 「帧率 30」), or a word setting the work to it right before it (剪成, 做成, 改成, 控制在, 压到, 砍到, "make it": 「剪成 90 秒发给我」, 「做成竖屏」), outside the context of the footage or a reference. Any other reading («约 90 秒», «不要超过 2 分钟», «1080p 就行», «要竖屏», «片子差不多 107 秒» "the cut's about 107 seconds") becomes an offer only while that dimension has no target at all. Your words never make a gate by themselves: a number read is only an offer, listed on the flow board, with no card asking whether you want it (from 2026-10-04; until then each offer had a card, 「按你的话加检查:时长 108–132 秒?」 ("Add a check from what you said: running time 108–132 s?"), posted again 「你已经说了 N 次」 each time you said it again — asking about what you had just said); the offer follows the latest target you gave, or failing any, the latest reading. When another line of yours says the same number again (the same number and bound, "about" and a bare number alike: "about 2 minutes", "2 minutes or so" and 「片长 120 秒」 are the same, 「片长 115 秒」 and 「片长改成 130 秒」 are not; saving the same board field again is not another line), it is the same offer, with the count. Only your confirm, on the flow board or on the required-items card (when a requirement you said twice has nothing behind a hand-over), makes it a gate. In F-f you said 「片长约 2 分钟」 twice: the 107-second master was measured as soon as it was delivered and the result shown on the board and in the Bots' situation, holding nothing back; one confirm, and it holds the 107-second master back. A number you removed or turned down, and every other number you had said before one you confirmed, no longer counts from the words you had said by then (no card, no count), only from words said later; when your latest number is the one you removed, nothing is offered, and no older number takes its place. A check in force never changes by itself: a different target you give later makes a replacement card (which number is in force and which you just gave, with Use the new one, Change and Keep the old one), and the check in force stays in force, and holds back, until you choose; said again, the card is posted again beginning 「你已经说了 N 次」 ("You have said it N times"). It is the one time an offer gets a card: unasked, the Bots stay held to the old number. Change puts 「片长改成 」 ("make the running time ") in your composer, so the number you type is what the check stands on. Choosing the new one removes the old; keeping the old removes the offer; giving the old number again withdraws the replacement card. A reading that is no target makes no replacement card. Complaints never touch a check: 「上一版 107 秒太短了」 ("the last cut's 107 seconds is too short"), 「107 秒左右,短了」 and 「你剪成 107 秒了,太短」 read no number.

How much each allows: "about 2 minutes" and "2 minutes or so" are 108–132 seconds, "over 2 minutes" and "no less than 2 minutes" set only a minimum, "within 90 seconds" and "don't go over 90 seconds" only a maximum, and every other number read ("make it 3 minutes", "running time 3 minutes") is also allowed 10% either way; a resolution is the picture's short side (1080p and 1920×1080 are both 1080, 4K is 2160), a frame rate is allowed 10% either way, an aspect ratio is met within 1%, and portrait (landscape) alone means taller than wide (wider than tall). Each dimension has at most one check in force and one offer; a line giving one dimension two different numbers counts for neither.

It measures the job's final cut: of the files a Bot delivered (attached to its lines filed under the job and not under a shot's or another version's ticket — 抖音版, 竖版, 预告…, never the ticket named after the job itself — and still there), a video whose name has the word MASTER (母带 in Chinese) comes before one with the word final (成片, 终版), and those before a video under deliverables/, the newest within each; but names are compared only within the same kind of place: a file in a deliverables/ folder or the job's own folder (its tickets' included) comes before one elsewhere, whatever the name. Whole words only (master_shot_03.mp4 and EP01finale.mp4 are not it); never a name that also names a shot, another version or format, titles, a preview or a proxy (C09_final.mp4, EP01_MASTER_9x16.mp4, EP01_30s_MASTER.mp4, EP01_douyin_MASTER.mp4, EP01_trailer_MASTER.mp4, intro_MASTER.mp4, logo_sting_final.mp4, EP01_MASTER_720p_preview.mp4, EP01_MASTER_proxy.mp4, one with 竖版, 片头 or 镜头); and nothing under footage/, raw/, ref/, 素材/ or 参考/. Newest by when it was first delivered, so a reviewer comparing the new master with EP01_MASTER_v1.mp4 does not move the check back to the old one. A newer one moves it there, and the result on the last file does not carry over. An offer finds the file too and is measured at once, its result shown to you and the Bots: on the board as "To confirm · Fail", expanded as 「未确认的检查:107.00 秒,你说的是时长约 2 分钟(待你确认)」 ("Unconfirmed check: 107.00 s; you said running time about 2 min"), and as such a line in the Bots' situation block and map.md; but it holds back no delivery and calls nobody back, lets the organizer mark the plan done, and is left out of "N/M checks pass", so a misread number or a check pointed at the wrong file can never refuse a good delivery (whether reviewers must answer to it waits for submissions and reviews). Once you confirm it, it is read again at once with ffprobe (the picture as it plays: a phone's portrait clip stored as 1920×1080 and flagged to turn 90° is portrait; a running time, picture size or frame rate that cannot be read, or no ffprobe installed, is an error and no evidence either way), and from then on it is an acceptance check like any other: it runs when the plan goes quiet, the organizer cannot mark the plan done while it fails, the app calls the Bot back over it, and handing the file to you again gets it measured on the spot by the closing check. Holding a reviewer's approval to it waits for submissions and reviews (ADR 0040 P4e).

A replacement card goes to the session the job lives in (when you are in it), with its three buttons, and again with the count each time you say it again. Nothing else gets a card; the flow board shows it: a new offer, a check you confirmed first finding its file (moving to a newer cut only measures again), and the line you confirmed a check on being erased — the check goes back to being an offer, never quietly deleted; erasing a later line saying the same number, or filing the line under another job, does not touch it. An offer goes when the words it stands on are erased or filed elsewhere. Each card takes one press; Confirm on an offer a later number already withdrew is refused. The cards are for you and are not in the Bots' transcript. On the flow board these checks are listed under "Checks from what you said", after the words they read ("Running time about 2 min"): an offer can be confirmed, removed and, once bound, rerun; one in force can be removed and rerun; none can be edited, and the local API refuses an edit (derived_check); a confirm is POST /v1/checks/:id/confirm. They do not count toward the 10-check cap of a plan. Clearing or deleting a session together with what you said there removes the offers standing on those words at once, and turns the checks you confirmed on them back into offers.

In the checks table it is recorded with you as its source and "file exists" as its kind, with further columns for what it measures, the quote it stands on, how it found its file, and whether it is offered or in force: an older build sharing the data folder reads it as a check that the file exists, and while it has no file as a check with no path, which runs as an error and holds nothing back.

From level 5 (ADR 0046) it still holds nothing back: no submission, no approval, however often you said it. When a same-model review passes something you said twice in the ledger with no passing check behind it, what this check measured is written on the card that asks you, and the card can confirm it.

Avoid: waiting for the scribe before making the check, having a model read the number, making a gate without your confirm, making a gate of a number said twice, a card asking whether you want the number you just said, taking a part's or another version's number for the deliverable's, letting a later number rewrite a check in force, letting a complaint change a check, treating an unbound check as a gate, measuring a shot or a source clip as the final cut, editing its number on the flow board, taking one shot's length for the whole film's