The conductor
The conductor runtime (claude or codex), how its brief is built, auto mode and permission cards, turn tags, run news, wake and show_task. The brief summarises this page.
01the rule for the conductor#
The brief the conductor reads is a summary of this page. The code is the truth. When the brief and this page disagree, or this page and the code disagree, the page is the bug. Report it with report_issue, which follows the conductor role's own rule: use it when the user asks to report a problem, and draft the title and text from the conversation.
Anything the code can't settle is written "not checked" below.
02runtime#
The conductor runs on claude or codex. An empty runtime means claude. Both carry the conductor's tool loop through their drivers. grok is refused: it has no two-way stream-json session the desk can drive, no permission prompt tool to send asks to the operator's cards, no resume or compact for the desk's turns, and its sterile environment turns off memory and MCPs. Any other runtime is refused with "conductor runtime must be claude, codex or grok". The settings for the runtime, model, command and directory are in desk-json.
03how the brief is built#
(*Conductor).brief writes the session's brief, paragraph by paragraph, in this order. A paragraph that names a tool is written only when the chat holds that tool.
- Who you are. A delegated side chat reads "You are the ... in a side chat a manager delegated", and that it starts without the manager's memory. The manager's chat reads "You're . You work on the smith desk for the project ... with the person at the window", and "the conductor" stands in for the name when the desk's conductor name is empty or
conductor. - Persona. For a manager chat only, the persona text when the desk has one. See persona below.
- The base. The shared base text for the chat, when it has one. See roles.
- Whole toolset in auto mode. One paragraph saying the chat has the runtime's whole toolset in auto mode, that what auto mode won't do comes to the operator as a permission card, and which desk tools read conversations, runs and tickets.
classifierDenialBrief. What to do when auto mode's classifier denies a call outright. See auto mode below.- Building goes through runs. Code changes are launch cards; chores are done directly.
- Clicks are the operator's. Launching, sending to nodes, pausing or stopping runs, deciding gates and pressing cards are the operator's clicks, except autopilot's own tools while autopilot is on.
draft_launch. Draft a launch card per ask, read the ticket first, recommend one template, and plug an asset only when the ticket names it. It ends withversionsLine, the rule to resolve exact versions yourself and write them into a ticket comment before drafting a card that bumps one.open_board. Open a run's board only when the operator asks or to point at a node or gate.open_file. Show a file withopen_file, name files by what they are, refer to assets by id, and never paste localhost urls.propose_pause. Propose pause, continue, stop, send back and retry through the propose tools.propose_run_continue.runsBrief, the manager's paragraph on live runs, relaunching a failed run, repeating a red check yourself, and proof a run can't make.propose_send_back.gatesBrief, which says to move the unmet part of a gate that shows under half its items met to a new ticket by the gate's scope edit and not to send the whole list back.conversation_rename. What the window does, the conductor can do or propose; settings and config stay behindpropose_config_edit.propose_sync. When work has landed, check withgit_stateand propose a sync. The operator's click runs the checks, pushes and, only for smith's own source, restarts smith.propose_config_edit. When desk config should change, read the file and propose the whole new file. This includes a role asroles/<name>.json.propose_area_edit. An area's paths, brief, checks and fence change through this card.handoff. Each chat belongs to one project for good or to none; usehandoffto pass work to another project's chats. See chats.- The
[desk]paragraph. What a message starting with[desk]is, and that a word is enough in reply. See turn tags below. - The run news paragraph. What
[desk]run news lists, what a landed run means for the operator, and the gate read, ending withuiGateLine, the instruction to check the mock's written rules one at a time on the built page with real data. - Quick questions. Answer from the journals, name the run and node, and propose a change through the existing cards.
- Scope words, the project list and naming words. Three paragraphs the desk supplies when it has them. The naming paragraph also needs
conversation_rename. What each says is not checked here. - Autopilot, only while it is on.
AutopilotBrief(power)is added when the chat's autopilot power is above zero. It isautopilotBriefHead, the line for the current stop, thenautopilotBriefTail. See autopilot. surfaceStyleBrief. The reply style for each place the operator reads, keyed on the turn tag.- Question cards.
AskUserQuestionshows as a card the operator answers by clicking, and a dismissed question is not a choice. decisionsBrief. Only for a chat that is not delegated and holdsrecord_decision. It says when to record a decision, and that a decision should still be true next month.- Memory. Where memory lives, or "You keep your own memory", with the memory index.
voiceCloseBrief. For a chat that is not delegated, a closing line after the memory lines that says all of the above is how the desk works, not how the conductor sounds, with the conductor's name filled in (or "the conductor").brief_file. The text of desk.jsonconductor.brief_fileis appended last, after the desk's own brief. See desk-json.
The ten constants named above are classifierDenialBrief, versionsLine, runsBrief, gatesBrief, uiGateLine, autopilotBriefHead, autopilotBriefTail, surfaceStyleBrief, decisionsBrief and voiceCloseBrief. A test (internal/desk/conductor/brief_kb_test.go) reads the package's own source, collects the constants brief and AutopilotBrief use, and fails when this page doesn't name one. A new paragraph needs a line here.
04persona, name and pronouns#
The manager chat's brief opens with the conductor role's text (see roles) when the desk's conductor_persona setting is on. The desk fills {name} with the conductor's name and {pronouns_line} with " goes by she/her.", "he/him." or "they/them." for she, he or they. With any other pronoun setting the line is dropped. The settings are conductor_name, conductor_pronouns (she, he, they or it, unset means it) and conductor_persona, which only the desk's first setup sets. A user copy of the conductor role in the roles folder wins over the built-in. The settings page's wording for them is not checked.
05auto mode, permission cards and classifier denials#
Every session starts in auto mode. The other mode is manual, the CLI's default, where a call that needs approval goes to the permission prompt tool and so becomes a card. The tool is permission. Claude calls it itself before a call auto mode won't make; the conductor never calls it. The operator answers on a desk card.
An ask carries the tool, its input, a summary, what the conductor wants in a phrase, labelled fields, a key for "for this session" and, for a question card, the questions to answer. When the classifier denies a call outright, the conductor must not work around it with another command to the same end. It says in one line why it needs the call, and the operator gets a card. If they ask to be asked, the desk tells the conductor and it retries the same call once, unchanged. If they leave it, the conductor drops it. The permission rules in full are on permissions.
06turn tags#
The desk tags every turn it sends the conductor, and the tag can change from one turn to the next.
[desk]marks a message from the window, not the operator's keyboard. It reports a press, such as go on a launch card or a click on a proposal, and a word is enough in reply, then the conductor follows any runs it names.[via discord]means the operator is reading in Discord. Replies are one or two lines, short enough for a phone, with no ids or hashes, still in the conductor's own voice, and a question is asked the way a person would, never as a lettered menu.[via discord for mates]means people who aren't technical read in a Discord channel. Replies are plain words in one or two lines, with no ids, hashes, tool or command names, file paths or json, and no lettered options; a choice on a card is pointed at by its buttons.- No tag means the operator is in the window. Name tickets with short id and title so they link, and talk like the conductor: the window is longer, not more formal.
In either Discord style the conductor never invents what a gate means; it says what the gate's card shows.
07run news#
The desk watches the journals of the runs a conversation launched and queues what happened as news lines: a gate opening, work sent back, a node failing, a run finishing. A queued line is handed to the conductor as one [desk] run news, from the journals: turn once the oldest line has waited out the news window and the conductor is not mid-reply. The window is conductor.news_window_seconds in desk-json; with none set, the lines go as soon as the conductor is free. When the operator sends a message while news is waiting, the news goes with it as [desk] run news since your last turn:.
08wake#
register_wake asks the desk to wake the conductor with a [desk] turn that carries its note and the run news it missed. It wakes on:
start, when smith starts again. Its reason reads "after a crash or reboot" when nothing wrote one, or "after an update from vX to vY". The update reason is also worked out from the version recorded at the last start, so any update path (installer, auto restart, reinstall) reads it; a written reason still wins.sync, when a sync finishes.limit, when the session's usage limit resets.- A time, given as an RFC 3339
at. A set time always fires and is not one of the events.
A wake given an at and no on list is one-shot: once its timer fires the whole registration, note included, is cleared. With an explicit on list, only the time is cleared and the events stay. A timer that is already late at start wakes the chat once, with both the start reason and the late-timer detail.
With no on list, all three events are asked for. Any other event is refused with "use start, sync or limit". There is one registration per conversation, a new one replaces the old, and it is kept in wake.json so it outlives a restart. A conversation can set or clear only its own wake. clear_wake removes it.
Autopilot registers a wake for the manager chat when the operator switches it on, so the conductor is woken as the work goes. See autopilot.
09tools the conductor shows with#
show_task. Shows a long job as a card in the thread. It takes atitleand the job'slog_path, and optionally thecommandand apid. The card's status is a trailingexit Nline in the log, else a live pid, else lost. The full description.open_board. Opens one run's board in its own window, optionally on a node. It changes nothing in the run, and the outcome says opened, focused orno_shellwhen no app window is listening.open_file. Shows a file inline in the thread on the reply. Markdown renders, code has line numbers, alinescrolls to one, images show and json shows as a tree. It never changes the file.open_in_vscode. Opens a project, or one file or folder in it, in the operator's vscode through the app. The outcome says opened, failed orno_shell.react. An opinion on a record of this conversation: approve, send_back, look, like or seen, with an optional one-line why. It changes no gate, and a new reaction on a record replaces the old.desk_info. Which project the desk serves and the core's version.