Skip to main content

Advice Broker Runbook

Use this when Grove, Claude Code, Codex, or another OMEGA-coordinated session asks for advice and the owner wants the loop handled without manual copy/paste.

The broker is intentionally draft-only until owner approval:

  • It can poll coord_messages requests.
  • It can assemble context and generate advice drafts.
  • It can show an owner approval queue.
  • It cannot approve advice.
  • It cannot send advice unless the owner explicitly runs send-approved.

Quick Manual Loop

Run one visible non-send cycle:

omega broker tick --project /path/to/project --to-session lily

Then inspect the queue:

omega broker queue
omega broker review <advice_id>

If the draft is acceptable, approve it:

omega broker approve <advice_id> --edit "Prompt to send back to the requesting session."

Then send it:

omega broker send-approved <advice_id>

Overnight Daemon

Create and start an explicit dry-run contract before installing an overnight daemon:

omega broker run-create \
  --mode overnight_dry_run \
  --project /path/to/project \
  --target-session lily \
  --objective "Draft advice requests overnight; do not send" \
  --expires-at 2099-01-01T00:00:00+00:00 \
  --max-runtime-minutes 60 \
  --max-sends-total 0 \
  --stop-condition missing_approval \
  --stop-condition ambiguous_or_unknown_recipient \
  --stop-condition runtime_or_budget_limit \
  --stop-condition owner_kill_switch

omega broker run-start <run_id>

Preview the daemon configuration before installing:

omega broker daemon-config --project /path/to/project --to-session lily --run-id <run_id>

Write the launchd plist without loading it:

omega broker daemon-install --project /path/to/project --to-session lily --run-id <run_id> --no-load

Install and load the draft-only broker daemon:

omega broker daemon-install --project /path/to/project --to-session lily --run-id <run_id>

Check state:

omega broker daemon-status
omega broker run-status <run_id>
omega broker run-events <run_id>
omega broker run-digest <run_id>
omega broker queue

run-status <run_id> shows the run contract and current execution state: expiry, approval policy, limits, configured stop conditions, validation schema, lease owner, lease expiry, event count, and any stop-condition totals. Only one daemon can hold the lease for a run. If another daemon owns the run, the new daemon refuses to process it rather than polling or drafting concurrently.

Stop and remove the daemon:

omega broker daemon-uninstall

Message Flow

  1. A peer session sends a coord_messages row with msg_type=request.
  2. omega broker poll-messages or daemon polling finds the message.
  3. The message becomes one idempotent advice request keyed by source_message_id.
  4. The orchestrator processes the advice job up to draft_ready.
  5. The owner reviews the draft with omega broker review <advice_id>.
  6. The owner approves or rejects.
  7. Only after approval can omega broker send-approved <advice_id> send the response.

Useful Commands

Create a supervised run:

omega broker run-create --mode supervised --objective "Visible owner-gated loop"
omega broker run-start <run_id>

Create a bounded run contract with explicit limits:

omega broker run-create \
  --mode overnight_dry_run \
  --objective "Draft only within a one-hour supervised window" \
  --owner-session-id owner \
  --target-session lily \
  --message-type request \
  --expires-at 2099-01-01T00:00:00+00:00 \
  --max-runtime-minutes 60 \
  --max-requests-total 20 \
  --max-drafts-total 20 \
  --max-sends-total 0 \
  --max-sends-per-thread 0 \
  --max-errors-total 3 \
  --max-consecutive-errors 2 \
  --max-duplicate-drafts 1 \
  --max-idle-minutes 30 \
  --stop-condition missing_approval \
  --stop-condition ambiguous_or_unknown_recipient \
  --stop-condition runtime_or_budget_limit \
  --stop-condition owner_kill_switch \
  --require-field owner_session_id \
  --require-stop-condition owner_kill_switch \
  --limit-min max_sends_total=0 \
  --limit-max max_sends_total=0

Dry-run message discovery:

omega broker poll-messages --project /path/to/project --to-session lily --dry-run

Ingest a specific message:

omega broker ingest-message <message_id>

Show the exact context packet:

omega broker review <advice_id> --with-context

Show orchestrator jobs and events:

omega orchestrator status
omega orchestrator jobs --status queued
omega orchestrator show <job_id>

Create a scoped auto-send approval token for future bounded auto-send tests:

omega broker token-create <run_id> --to-session hawk --thread-id <thread_id> --max-uses 1 --expires-minutes 30
omega broker token-check <token_id> --run-id <run_id> --to-session hawk --thread-id <thread_id>
omega broker token-revoke <token_id> --reason "owner revoked"

Tokens are valid only for scoped_auto_send runs. They do not make the normal overnight daemon send messages.

Troubleshooting

No items in broker queue

Run:

omega broker poll-messages --dry-run

If no candidates appear, confirm the peer sent msg_type=request, the body is non-empty, and the --project / --to-session filters match.

A message was found but no draft appears

Check the job:

omega orchestrator jobs --status queued
omega orchestrator watch --once

Then run one visible cycle:

omega broker tick

If a run id is configured, also check the run lease:

omega broker run-status <run_id>
omega broker run-events <run_id>

If the lease is owned by another daemon, stop the duplicate daemon or wait for the lease to expire before retrying.

Drafting stops with owner input required

The policy layer is fail-closed. This usually means the request asks for online/current/latest information while the request policy does not allow it. Review the item:

omega broker review <advice_id> --with-context

Then decide whether to reject it, request clarification, or recreate/ingest with a different research policy.

Daemon appears installed but not running

Check:

omega broker daemon-status
launchctl list com.omega.advice-broker

Reinstall with:

omega broker daemon-uninstall
omega broker daemon-install --project /path/to/project --to-session lily

A draft is approved but not sent

This is expected. Approval and sending are separate. Run:

omega broker send-approved <advice_id>

Safety Contract

The launchd broker daemon is allowed to poll, ingest, assemble context, evaluate policy, and draft. It is not allowed to approve, reject, edit, or send. Sending requires the owner to run omega broker send-approved.

overnight_dry_run runs enforce max_sends_total=0. scoped_auto_send remains a separate future mode and requires an exact approval token; missing, expired, revoked, overused, or scope-mismatched tokens fail closed.