Operations
Strategic feedback
How a teammate's Slack reply to Oko becomes a recorded strategic decision: one event per reply, its attempts, what a decision may change and the refusals.
Strategic feedback#
A teammate's reply to Oko in the suggestions channel, or in a thread Oko started there, can settle a strategic decision. oko suggestions tick reads those replies when the suggestions channel (the setting orchestrator.autoGoalChannelID.suggestions) is among the conversations it scans; a tick for one Slack trigger does not read them.
What is read#
Every thread Oko posts in the suggestions channel is watched. A watch keeps the thread, the text Oko posted and the timestamp of the newest reply already read. Each tick reads the channel after its cursor and each watched thread after its own, and keeps the human replies that answer an Oko message.
One event per reply#
Each reply becomes one row of oko_strategic_feedback_events, keyed by organization, channel and message timestamp. Its id is derived from those three values, so a retry and a second host write the same row instead of a second one. A row is:
pendingwhile an attempt is running;processedonce the model's decision is applied;ignoredwhen the model answers that the reply decided nothing;failedwhen the attempt was refused, with the refusal inlast_error.
A processed or ignored reply is never read again. A pending or failed reply is tried again on the next tick. The first attempt sets attempt_count to one and each later attempt adds one, so a reply that keeps failing shows how often it was tried and when (last_attempt_at).
What a decision may change#
The model answers in a fixed shape: whether the reply is a decision, its title, statement, rationale, the products and initiatives it affects, its reversibility and the strategic fields it changes. Every changed field must be one the build declares, carrying a value of the declared kind (a text, a list of texts, or a finite number). An undeclared field, a change without a value or a declared kind the build cannot read refuses the reply; it is recorded as failed and nothing is applied.
Cursors after a failure#
A failed reply holds its thread's cursor one microsecond before its own timestamp, because Slack leaves out a message stamped exactly at the cursor. The next tick reads that reply again.
Refusals#
The tick prints each refusal on standard error and goes on with the other replies:
# strategic feedback failed ts=<ts>: <refusal>: one reply was refused; the same refusal is in its row'slast_error.# strategic feedback ts=<ts> cannot be marked failed: <refusal>: the failure itself could not be recorded; the row stayspendingand is tried again.# strategic feedback scan failed channel=<channel>: <refusal>: the scan stopped before settling replies. It names, among others, a feedback row this build cannot read, a watch row without its thread, text or cursor, and a Slack timestamp that is not seconds and six digits of microseconds.
Migrated from src/content/docs/strategic-feedback.md