Operator Messages

March 29, 2026 · View on GitHub

What this capability is

Operator Messages is the current system-owned emission surface for exactly two gardener-authored note classes:

  • tend_survey
  • recently_concluded

It exists to remove the ambiguity caused by writing raw markdown files directly into the same top-level reply directory that pak2 chat treats as ordinary conversation replies.

This capability does not change startup status or startup garden-reply representation. Those paths remain separate in this slice.

Record and validation surfaces

Persisted records:

Validation boundaries:

  • system.validate.validate_operator_message_request(data: dict) -> ValidationResult
  • system.validate.validate_operator_message_record(data: dict) -> ValidationResult

Runtime entry points:

Entry pointLayerResponsibility
system.operator_messages.emit_tend_survey()Public APIEmit one gardener-authored tend survey note with validated routing.
system.operator_messages.emit_recently_concluded()Public APIEmit one gardener-authored recently concluded note with validated routing.
system.operator_messages.read_operator_message_records()Read helperLoad durable per-run emission records.
system.driver._emit_tend_finished()Tend observabilityDerive operator_note_written and operator_note_path from the validated tend survey records for that run instead of diffing raw inbox files.

Routing rules

The routing decision is not caller-selected in this slice. The system derives it from the current goal's origin metadata.

Current goal originCanonical human recordDelivery policyFilesystem path behavior
origin.kind == "conversation"Append a sender: "garden" message to the originating conversationreply_copyAttempt a top-level reply-surface delivery copy in <runtime-root>/inbox/<garden-name>/
No originNo conversation appendout_of_band_noteWrite one note file under <runtime-root>/inbox/<garden-name>/notes/

The top-level reply directory is therefore reserved for transcript-backed delivery copies only. Background or otherwise no-origin notes move to the dedicated notes/ subdirectory so pak2 chat does not render them as ordinary replies.

Persisted record shape

Each successful emission appends one validated JSON object to runs/<run-id>/operator-messages.jsonl.

Required fields:

  • schema_version
  • kind
  • sender
  • transcript_policy
  • delivery_policy
  • emitted_at
  • source_goal_id
  • source_run_id

Conditional fields:

  • origin for conversation-backed emissions
  • conversation_message_id for conversation-backed emissions
  • delivery_path when a filesystem file was written

Current policy values:

  • sender = "garden"
  • transcript_policy = "canonical" for conversation-backed emissions
  • transcript_policy = "none" for no-origin emissions
  • delivery_policy = "reply_copy" for conversation-backed emissions
  • delivery_policy = "out_of_band_note" for no-origin emissions

Request validation and context rules

The public emitters validate the request before any write:

  • only tend_survey and recently_concluded are accepted
  • only sender: "garden" is accepted
  • source_goal_id and source_run_id must come from the current run context
  • tend_survey is only valid from a current tend goal
  • recently_concluded is only valid from a durable non-converse, non-tend goal

If a conversation-backed emission is requested, the origin conversation must exist and still be open.

Failure modes

Named rejections currently include:

CodeMeaning
MISSING_RUNTIME_CONTEXTThe current goal/run context was not available in the environment
OPERATOR_MESSAGE_NOT_AUTHORIZEDA non-gardener caller attempted to use this gardener-only slice
UNKNOWN_OPERATOR_MESSAGE_FIELDAn unsupported field was provided to the request or record validator
INVALID_OPERATOR_MESSAGE_KINDThe request named an unsupported message kind
INVALID_OPERATOR_MESSAGE_SENDERThe request named an unsupported sender
INVALID_OPERATOR_MESSAGE_CONTEXTThe requested kind does not match the current goal type or conversation state
INVALID_OPERATOR_MESSAGE_ORIGINThe provided origin linkage was malformed
INVALID_OPERATOR_MESSAGE_POLICYThe persisted record does not match the allowed routing policy combinations
INVALID_OPERATOR_MESSAGE_PATHThe persisted delivery_path does not match the allowed reply or notes surfaces
CONVERSATION_NOT_FOUNDThe conversation-linked emission referenced a missing conversation
EMPTY_CONTENTThe emitted content was empty or whitespace-only
IO_ERRORWriting the durable record or an out-of-band note failed

Current scope boundary

This slice intentionally does not:

  • change startup status emission
  • change the startup seed's raw garden-reply path
  • introduce a general-purpose message helper for unrelated classes
  • change broader chat UX beyond keeping out-of-band notes off the ordinary top-level reply scan

Grounding in implementation and tests

Implementation:

Focused tests: