Workflow guide

Notes, comments, board messages and agent chat: which one to use

Five surfaces look alike. Pick by audience, storage and destination, not by icon shape.

Pre-release. Reviewed October 23, 2026. This review covers code behavior, not a packaged release or provider certification. Desktop app labels and icons cited below are the current ConversationLanguage vocabulary; command flags are the installed CLI's own -h text, not paraphrased.

Decide by audience first

Before you start: all five surfaces can hold a short piece of text about your work, and that is the only thing that makes them look alike. They differ in who can read the result, whether it costs provider quota, and whether a network write is ever attempted. Saving a Private Note or a Local Comment never starts an agent turn and never leaves this machine. Work in Chat always starts an agent turn and can send context to the selected provider. An External Tracker Comment is the only one of the five that deliberately writes to an audience outside Commandem, and only when you have explicitly chosen that destination.

The five surfaces, by audience and effect
SurfaceTargetWho can read itEffect
Private NoteOne projectYou, on this machine, by defaultPreserves knowledge; starts no agent turn
Local CommentA Project, Campaign or Mission (durable id)Local by default; optionally mirrored per your chosen destinationAttaches discussion to a durable target; replies name a parent comment
Board MessageAnother registered project, or allWhoever opens that project's board (you, or an agent orienting in it)Records an addressed message with its own unread/history state; never starts a run
Work in ChatAn agent session for one projectYou and the selected provider/accountStarts an agent turn; can send context to that provider's inference
External Tracker CommentA reviewed external thread (currently: a GitHub issue)Whoever can read that tracker threadDeliberately writes to the selected tracker audience, only after an explicit reviewed digest approval

These names describe routing, storage and persistence, not identical feature depth on every screen. The sections below name the real gaps rather than implying uniform support.

Keep it to yourself, or attach it to a target

Private Note: a scratchpad, not a shared document

A Private Note is a per-project scratchpad. The current commandem notes command and the desktop app's Notes tab write to a separate timestamped Markdown file under the support directory, distinct from the native Comment store below. It is owner-private by default and is never an agent turn.

commandem notes PROJECT "Remember: the staging key rotates on the 1st."
commandem notes PROJECT --json
commandem notes PROJECT --clear

App entry point: the project detail pane's Notes tab (icon note.text, labeled Private Notes elsewhere in the app). A failed load or append preserves your draft and last-good history and offers a read-only Refresh/Retry; it never silently drops what you typed.

Local Comment: discussion attached to a durable target

A Local Comment is a native, versioned thread keyed to a Project, Campaign (c-xxxxxxxx) or Mission (m-xxxxxxxx) durable id, never a row position that can shift when the roadmap reorders. Edits and deletes keep revision/tombstone history. The built-in destination is Local only; inspect the effective destination before assuming anything is shared, because a saved project or global default can differ.

commandem comment destination PROJECT --json
commandem comment thread PROJECT --json
commandem comment thread PROJECT --mission-id m-xxxxxxxx \
  --add "Please review the acceptance criteria."
commandem comment thread PROJECT --campaign-id c-xxxxxxxx --add "..." --reply-to COMMENT_ID
commandem comment thread PROJECT --mission-id m-xxxxxxxx --edit COMMENT_ID --body "Revised text."
commandem comment thread PROJECT --mission-id m-xxxxxxxx --delete COMMENT_ID
commandem comment thread PROJECT --counts

App entry point: the Comments button and count (icon square.and.pencil) on Project, Campaign and Mission rows and cards across Roadmap list, Plan board, project detail and relevant Home surfaces. It opens the same local thread the CLI reads; a bounded thread sheet shows full local history, add/edit/delete controls, draft preservation, immediate count refresh and explicit empty/error states. A failed read is distinguished from a verified-empty thread, and a read-only Refresh/Retry preserves your draft.

Address another project: Board Message

A Board Message is addressed to one other registered project, or to all, and is stored in the local, append-only board.jsonl. It has its own unread/read and history semantics, separate from Local Comment revisions and separate from Private Notes. Posting never starts a run; the recipient project (or an agent orienting in it) reads the message when it next checks its board. Scope a message to the one project it is actually about rather than broadcasting to all for anything less than a genuinely fleet-wide note.

commandem tell PROJECT "Please hold off touching the chat pane until I land this."
commandem tell all "Shared outage: the registry is temporarily read-only." --kind status
commandem board PROJECT --json
commandem board PROJECT --unread
commandem board PROJECT --mark-read
commandem board PROJECT --history --json --source board --n 20

App entry point: the project detail pane's Board tab (Board Message button, icon paperplane). Reading or acknowledging a Board message changes its shared unread state and preserves history; it does not delete a message or repair whatever the message was about. Board messages remain Board/Activity audit records rather than human notifications or OS banners.

Start work: Work in Chat

Work in Chat is the one surface of the five that is an agent turn. Selecting Work in Chat (icon bubble.left.and.text.bubble.right) on a Mission or Campaign, or opening a project's Chat pane directly, hands the target's context to the provider/account/model you have selected and can spend that provider's quota the moment you send. It is covered in full elsewhere; what matters for this decision is the contrast: a Private Note, Local Comment or Board Message is a local write with no agent turn and no provider call, while Work in Chat is deliberately neither of those.

commandem chat PROJECT --agent claude --mode plan
commandem ask PROJECT "" --mode plan

See the reviewed provider/account and permission-mode guides before sending a first real prompt; this page is about choosing the surface, not about chat's own flags.

Reach an external tracker, deliberately

Every outbound write starts from a Local Comment. There is no comment kind that is "external-only" in storage; External Tracker Comment describes a destination choice layered on top of the same local thread, and the local write always lands first.

Three destinations, one default

Set the destination per comment, per project, or globally. local_only is the built-in default everywhere; nothing is mirrored anywhere until you explicitly choose otherwise.

commandem comment destination PROJECT --json
commandem comment destination PROJECT --destination-set local_only
commandem comment destination PROJECT --destination-set local_and_tracker
commandem comment destination --destination-set tracker_only
commandem comment destination PROJECT --destination-clear
  • local_only: the default. The comment exists only in the native local thread; no provider is ever contacted.
  • local_and_tracker: the local write happens first and always succeeds or fails on its own; a tracker mirror is then attempted and reviewed separately.
  • tracker_only: still writes the local comment first (local-first is unconditional per Mission 608.8); the UI/CLI simply does not also keep it as the primary read surface going forward.

When there is no tracker: forge = "none"

The external adapter is an optional forge capability, not a GitHub assumption. A project's resolved forge posture (its commandem.toml manifest's forge field, or the global default in settings.toml) can be "none". With no forge configured, a tracker preview discloses cleanly instead of erroring or silently doing nothing: it reports the destination as unavailable, writes no durable outbox state, and leaves the native Local Comment exactly as it was. A Local Comment is fully usable — create, edit, delete, read — with no network and no forge configured; only the External Tracker Comment destination is unavailable, and it says so.

commandem sync collaboration --preview-forge-comment request.json --json

A failed mirror never costs the local write

The local-first ordering is atomic: the native Local Comment is persisted before any optional mirror is attempted, so a tracker failure can never lose, block or roll back what you already saved. A transient failure (a network error, a temporary tracker outage) lands the outbound mirror operation in a retry state, never failed or done; the reported error names the local comment as safe, and the retry is deduplicated rather than re-posting a duplicate. Inspect retry/conflict state, then explicitly re-approve the exact reviewed delivery — never create a second comment to guess whether the first one eventually landed.

commandem sync collaboration --json
commandem sync collaboration --inspect-recovery-inbox --json

App entry point: a project's Comments → Adapters panel, then Recovery inbox, and the Tracker icon (link) wherever a comment is already mirrored. See the full destination-setup and delivery-review guide for the exact preview/approve/apply steps, and the field-by-field reference for every destination and recovery boundary.

Expected result and recovery

Across all five surfaces: a local save survives even when a remote step fails or is unavailable, and remote delivery is only ever claimed with its own receipt. Never make a repository public, or widen a saved destination's audience, to make an unsupported mirror succeed. If an app read fails, distinguish "could not load right now" from "verified empty," retain your draft, and use the read-only Refresh/Retry the sheet or pane already offers rather than assuming the discussion was lost.

What is not yet uniform across every screen

Desktop app parity for Private Notes, Local Comments (Project, Campaign and Mission), Board Messages and the destination/forge/offline-retry behavior above is complete and covered by real CLI and local-fixture tests (Mission 608, tasks 1–8 and 11).

Honest remainder, not yet shipped as of this review: the iOS app currently supports only a read-only Local Comments recovery view (loading, a verified-empty vs. unavailable distinction, and a read-only Retry) — it does not yet offer adding, editing or deleting a comment, and it has no Private Notes or Board Message surface at all. Visual snapshot coverage, accessibility-label parity across every surface, and dedicated migration/offline/private-repository e2e fixtures for the CLI remain open follow-up work, tracked against Mission 608 task 9. Do not infer mobile or snapshot/accessibility completeness from this guide's desktop and CLI coverage.

Current source boundaries

These are source-level boundaries reviewed against 8f06da03. They do not replace the dated source captions or screenshots elsewhere in this handbook, or certify installed-app, physical-input, device, provider or OS-permission behavior.

Board is an audit and coordination surface, not a human-notification channel: posting a Board message does not create an OS banner or start an agent turn. Acknowledge/read and history retain their own semantics. The Notifications panel's delivery policy is separate from whether an append-only Board record exists.

The Notes pane's separate Read stored Notes launcher is an explicitly selected-project reader. It does not edit the scratchpad, create a Local Comment, synchronize to Matrix or authorize an external write. Incognito clears and blocks persistent reads; Refresh after returning to an allowed mode is explicit. This adds a reader entry point, not new audience or delivery parity.