One-on-Ones
A 1:1 is the in-life management tier — the recurring (or on-demand) coaching conversation a manager and a report have between hire and fire: review recent work together, give feedback, surface blockers, agree on action items. In Crewlet a 1:1 is not a subsystem and not a dedicated tool — it is a usage pattern that composes three things that already exist:
| Piece | Role in a 1:1 | Where it lives |
|---|---|---|
| Scheduler | fires the recurring 1:1 (the trigger) | Scheduling |
| A2A bus | the private, multi-round manager↔report conversation | Agent Runtime (a2a_ask) |
| Learning loop | turns the conversation into durable memory | Agent Learning (PersistDecider) |
Because it reuses these, the engine ships no 1:1 code — what an operator provides is a schedule and a playbook.
Why no dedicated tool
Section titled “Why no dedicated tool”A 1:1 is mechanically just a private, back-and-forth agent-to-agent
conversation, which a2a_ask and the A2A bus already provide: every message
on a channel wakes the other participant for a fresh turn, so the channel is
inherently multi-round (see A2A). A request_1on1
wrapper over A2AService would be a thin alias of the kind the project
deliberately avoids (slack_message, jira_comment-style wrappers —
see crewlet.tools.colleague); it would carry a different description
and nothing else.
The one apparent objection — a2a_ask’s own guidance steers agents toward
Slack/Jira for “reviews / feedback / status” — dissolves on inspection. That
guidance exists because work-product reviews (a PR review, a status update)
need a visible trail a human teammate would want to see. A 1:1 is the
opposite: it is private by design. It passes a2a_ask’s actual test
(“if a human teammate would want to see this message, it does not belong on
A2A”) cleanly, so the private bus is the correct surface for it — not an
exception to the rule.
Rule of thumb. Public coaching artifacts (action items, a standing rule that becomes team policy) belong on Slack / Jira / Confluence. The 1:1 conversation itself belongs on A2A.
The two triggers
Section titled “The two triggers”The 1:1 action (the A2A conversation) is the same regardless of what kicks it off. Only the trigger differs:
Recurring — a schedule
Section titled “Recurring — a schedule”Put a schedule on the unit with the default each target. The scheduler
fans out one independent turn per direct member (its at-most-once ledger,
own trace, and own timeout per member — a slow report never blocks the
others). Each member’s turn opens the 1:1 with its manager:
units: - name: Core type: team lead: CTO schedules: - name: weekly-1on1 cron: "0 14 * * 4" # 14:00 every Thursday # target: each (default) — every direct member runs its own 1:1 task: > Hold your weekly 1:1 with your manager. Open it over the private A2A bus with a2a_ask (a 1:1 is private — do NOT use Slack or Jira): use query_episodes to recall what you shipped and where you got stuck, walk your manager through it, ask for feedback, and note the action items you agree on. Follow the "Manager 1:1" playbook page in the team knowledge base. roles: - name: Engineer A - name: Engineer BThe manager does not loop. The engine does the fan-out (that is what
each is), so there is no long O(N) manager turn opening N channels under
one timeout. Each report initiates its own 1:1; the manager simply responds
on each channel as it is woken (A2A wakes are per-channel, so each 1:1 is an
independent, bounded unit). This is also the natural model — a 1:1 belongs to
the employee (“my weekly 1:1 with my manager”), so scheduling it per
employee is correct, not a workaround.
each fires to every direct member, including a lead that is itself a
direct role of the unit (it would then 1:1 its manager). That is usually
desirable — everyone gets a 1:1 with their manager, the same pattern at
every level. each resolves direct roles only (never descendant units),
and schedules are not inherited, so declare the 1:1 schedule on each unit
that should run it.
On-demand — the manager initiates
Section titled “On-demand — the manager initiates”When a manager notices a problem and wants a 1:1 now, it just calls
a2a_ask against the report (usually one report — no fan-out needed) with a
brief that frames the conversation as a 1:1. Same conversation, same
playbook, same durability.
Who initiates, and the human-manager case
Section titled “Who initiates, and the human-manager case”- Agent manager ↔ agent report → the A2A bus, as above. On the scheduled path the report opens the channel; on-demand the manager opens it. Either way the manager drives the review — authority is in the playbook, not in who clicked “start”.
- Human manager ↔ agent report → A2A is agents-only (
a2a_askrejects human targets — there is no inbox behind a human seat). A human manager holds the 1:1 in a Slack thread / DM instead: each reply is a turn, and the same learning loop persists the takeaways. This needs no configuration beyond the human seat already being in the org chart.
Durability — nothing new to build
Section titled “Durability — nothing new to build”Every round of the report’s 1:1 is a normal turn, so the post-turn
PersistDecider
runs on each one automatically — it even sees who spoke and what they
said (the inbound message + sender are in its prompt). The conversation’s
residue lands in the right place on its own:
- Facts (“my manager wants EOD updates”, “Sam reviews PRs in the
morning”) → written to the report’s private
agent_diaryasLONG/SHORT. - Standing directives (“always get review before merging”) → classified
DOC: deliberately not memorised, but surfaced as aDirectiveObservedobservation that nudges a handoff to update the team docs (Confluence), which every member then picks up via the## Relevant knowledgeprefetch. (Memory holds declarative facts, not instructions — see the PersistDecider writing-style rule.)
So a 1:1 does not need its own memory machinery; it inherits the standard loop. The conversation itself stays private and ephemeral (A2A channels are in-memory); only the outcomes — diary facts, Jira action items, Confluence policy — persist.
Bounds
Section titled “Bounds”- Convergence is the playbook’s job: it tells the manager to wrap up in a small number of exchanges (≤ ~4) with explicit action items.
- Loop safety is the engine’s job: A2A wakes carry the delegation depth + chain, and the TurnEngine’s delegation-depth cap bounds an unbounded ping-pong regardless of what the LLMs do.
- Scheduled timeout bounds only the kickoff turn (the report opening
the channel), not the whole conversation — the conversation spans many
turns (each reply re-wakes the other side), so
timeout_secondsis not the convergence control.
The 1:1 playbook
Section titled “The 1:1 playbook”The behavioral contract — how the report prepares, how the manager gives
feedback, the round budget, what to capture — lives as a knowledge-base
page (a Confluence page or a Plane page,
whichever backend the org runs), not in engine prose. This is the project’s
standard home for shared procedures (the same place runbooks, ADRs, and
onboarding pages live), and it reaches both parties through the
## Relevant knowledge prefetch and the backend’s page-search tools. It is
not a Tool Skill: tool
skills trigger on a tool / MCP-server name and are enforced load-before-use,
so a skill keyed on a2a_ask would block every mechanical A2A call — there
is no 1:1-specific tool to key on.
A ready-to-publish playbook ships at
examples/nimbus-docs/LEAD/Manager 1-1.md
— its LEAD/ parent directory routes it to the org-wide LEAD container
(the Confluence space or Plane project every agent can read) and its
# Manager 1:1 H1 becomes the page title. The example org runs on Plane,
so publish it with
crewlet plane import <company.yaml> examples/nimbus-docs/
(it has no trigger:, so it imports as a knowledge doc);
the directory conventions are identical across backends, so the same tree
imports with crewlet confluence import on a Confluence org. Edit it in
the backend’s page editor thereafter — no redeploy.
What this is deliberately not
Section titled “What this is deliberately not”- No
request_1on1tool, noOneOnOneCompletedevent. The conversation ridesa2a_askand is observable through the existingA2AChannelOpened/A2AMessageSent/A2AChannelClosedevents; scheduled 1:1s are additionally identifiable by theirScheduledTaskFiredschedule_name. - No memory reset. Wiping a report’s memory is a destructive operator break-glass action (memory poisoning, role repurposing), not a coaching move — it is tracked separately, not as part of the 1:1 pattern.
- No 1:1-specific scheduler primitive. A 1:1 is “just a scheduled task”,
exactly like a standup; the fan-out is the generic
eachtarget.
See also
Section titled “See also”- Scheduling — the
each/leadtargets, at-most-once delivery, catchup, the per-fire timeout. - Agent Runtime —
a2a_askand the A2A bus; built-in tools (query_episodes). - Agent Learning — the
PersistDecidertiers and the## Relevant knowledgeprefetch that surfaces the playbook. - Humans in the Org Chart — why a human manager’s 1:1 runs over Slack, not A2A.
Generated from crewlet/crewlet v0.1.0 at b40ea18.