Architecture
Transcript intelligence
Evidence-locked facts read from session transcripts: source adoption and one-off repairs.
Transcript intelligence#
Oko reads the operator's real session transcripts and turns them into evidence-locked facts: what was asked, what was delivered, and which manual repairs were made instead of product changes. Every fact carries the quote and the session provenance it came from; a claim with no recorded evidence is not reported.
Existing-source adoption#
Oko's catalogue can start from any transcript source Transcript Lake reads. Oko does not keep its own list of runtimes: oko lake sources shows what the Lake reports on this machine, and a runtime it does not read is refused by name — Transcript Lake does not read <runtime>; it reads <the real list>. On a typical Mac that is Claude Code, Codex, OMP, Factory Droid, Kimi and the shared hook transcripts; the moment the Lake learns another, it appears here with no change in Oko.
oko lake sources
oko lake adopt --source <runtime> --root <exact-discovered-root>OkoKit exposes this as TranscriptSourceAdoption.discover() and TranscriptSourceAdoption.adopt(runtime:root:indexer:); the CLI, Oko Desktop, and the host operation used by Oko iOS consume that same operation. It invokes Transcript Lake's structured CLI boundary rather than carrying a second vendor parser. Lake validates the whole supported input before mutation, masks and persists canonical events, retains the selected runtime/root identity in LAKE_DATA/sources.json, and updates exports/oko. Oko then indexes only that projection.
Existing Lake data and older source declarations are retained. Repeating unchanged input reports it unchanged through native byte cursors and catalogue session uniqueness. An unfinished last JSONL line is pending, not consumed. Malformed JSON, unsupported complete record types, non-discovered roots, empty sources, writer conflicts, or invalid receipts fail without a success fact. Receipts carry imported, unchanged, conflicting, rejected, pending, and catalogue counts, never transcript or credential contents.
Recorded sender provenance is retained when Oko reads the Lake projection or transcript-lake show <session> --include user --json. An agent-attributed message is not an operator instruction. Steering or synthetic messages are excluded unless the runtime explicitly attributes them to the user; Claude sidechain and prompt-source metadata keep their existing meaning. This reads structured source fields, not phrases in the message.
The archived-session reader requires each returned event's extra object. An older Lake that omits it, or a response containing a non-object value, is refused with the session, event timestamp and observed value instead of silently accepting every archived user-role event as an instruction. Update Transcript Lake before repeating that read. An extra object with only a source hash identifies the file, not who sent a user-role message. For a categorical supervisor verdict, its sender_session must identify either the supervisor recorded for that executor at the message time (followed or ignored) or a different sender (not_supervisor). Missing or contradictory sender identity leaves the model claim pending with the source, observed extra and model answer; message wording cannot supply it. Historical events whose ingestion discarded sender metadata are not retroactively attributed.
Reflection on work and instructions#
oko reflection scan [--session ID] --json queues Lake messages with ensuing agent work without Brama. process [--source ID] --json judges pending evidence through Brama; run combines them. list --pending --json shows source, context, defect link and exact failure cause. The standing transcript-reflection routine repeats intake and judgment.
Intake reads the selected Lake sessions before one locked queue update. It matches each queued source to Lake's genuine operator-turn projection, rather than treating synthetic user records as requests or allowing one to sever the genuine turn's ensuing answer. It reports each session's source count while reading and refuses missing or ambiguous occurrences without claiming a partial scan. A full intake compares the Lake user-event inventory again before writing, so an archive change refuses rather than publishing a stale queue. The indexed update preserves prior judgments when the source has not changed; its pending count comes from the persisted pass, not from a model answer.
The Desktop Defects → Evidence reflection screen shows the original Lake time beside each transcript entry, or names the missing coordinate and the intake operation needed before a defect-link audit. Infrastructure observations keep their own operation, cause and state instead of pretending to have a transcript timestamp.
Operator corrections, refusals, frustration and divergence become defects; aligned work remains a reading. For executors, the model compares Lake message provenance with the supervisor role at that time and ensuing work. A role or source hash does not identify the sender. A categorical verdict without matching sender evidence is refused into the pending queue, not counted as followed or ignored. The executor card separates confirmed ignored from pending and names unreadable registers.
Each reflection source retains Lake's original event time as well as its quote and provenance. When a real model judgment records a defect, oko rulings unlinked --session ID or oko rulings unlinked --all counts that exact message-to-defect link; a mere pending reading or a ruling cannot. Run oko reflection scan --session ID to recover source times for older reflection entries without changing their judgments or defects. A legacy entry with no time, or one naming a defect no longer registered, refuses the audit when its words could cover a genuine operator turn. Synthetic records outside Lake's operator projection do not block that audit. Repeated operator messages with the same source time and body are refused rather than assigned one another's defect.
For a named session, Operator messages and their records, oko tasks derive --session ID and oko rulings unlinked --session ID prefer its complete Lake source when it holds genuine operator turns, even over a shorter live transcript. If Lake has none, they read the available live or stored source instead. The whole-Lake audit never substitutes a local copy. For historical reconciliation, run oko tasks derive --all --write, oko tasks read, then derive with --all --write again to persist task carriage. Audit with oko rulings unlinked --all; inspect each uncovered message, link it to existing or newly registered work with oko tasks link, or classify it as a task and store its ledger. Repeat until no refusal or uncovered message remains.
The derivation report separates successfully read messages, unread readings and unattached messages by Lake runtime in byRuntime. The linkage audit reports audited, linked and unlinked operator messages for each runtime. A refused session is named with its cause and does not contribute to these totals. Check both the runtime breakdown and the failed-session list before treating a zero unlinked count as complete coverage.
The real archived-source journey under tests/rulings/archive/ requires OKO_TEST_STORED_SESSION and OKO_TEST_SOURCE_REVISION for a session whose Lake history extends past its stored snapshot. Run cargo test --manifest-path rust/Cargo.toml --test rulings-unlinked archive::archived_stored_messages_outlive_a_short_local_transcript -- --ignored --nocapture on a committed revision. It introduces a shorter local copy inside an isolated test home, proves named derivation and the linkage audit still read every original Lake turn, and leaves stored rows unchanged. Reports and actual CLI exit statuses stay in the build directory.
The whole-Lake audit prints a report even on failure. Its JSON and text forms both refuse when a session could not be read or an operator message still has no task or defect. A relation to a defect end no longer named exactly in the current register also refuses; the audit does not count a stale graph edge as work coverage.
The read-only stale-relation journey under tests/rulings/ requires OKO_TEST_RELATION_SESSION, OKO_TEST_RELATION_DEFECT and OKO_TEST_SOURCE_REVISION from a genuine stored relation. Run cargo test --manifest-path rust/Cargo.toml --test rulings-unlinked stale_relation::a_removed_defect_cannot_cover_a_persisted_message_relation -- --ignored --nocapture on the committed candidate. It first reads the registered relation through the real CLI, then points only that process at an isolated empty defect register and requires a refusal naming the missing end. It retains commands, exit statuses, outputs and source digests under the checkout's build directory; the shared task and relation rows remain unchanged.
The read-only reflection-link qualification under tests/rulings/ requires OKO_TEST_REFLECTION_SESSION, OKO_TEST_REFLECTION_SOURCE, OKO_TEST_REFLECTION_DEFECT and OKO_TEST_SOURCE_REVISION from a genuine model-assessed Lake source. Run cargo test --manifest-path rust/Cargo.toml --test rulings-unlinked reflection_links::a_reflection_defect_covers_only_its_original_lake_turn -- --ignored --nocapture on the committed candidate. It verifies the registered defect end and retains the source revision, binary and test digests, CLI commands, exit statuses and before/after reflection readings under the checkout's ignored build directory. An absent model assessment or timestamp is a failed fixture, not a pass.
The model journey under tests/reflection/ exercises real Lake intake, Brama judgment, persisted defect evidence and the resulting link through cargo test --manifest-path rust/Cargo.toml --test reflection-observations reflection_journey::real_transcript_to_contextual_defect -- --ignored --nocapture. It requires the named genuine session and quote, a responding Brama and a committed source revision. Its registers are isolated under the checkout's ignored build directory; a model outage is a pending result, not a qualified link.
Defect-bound supervisor sends also enter oko instructions. oko instructions settle --json locates the sent turn by the retained text and transcript position, then asks Brama whether the ensuing operations followed the instruction. Mentioning a defect or path does not establish compliance. If the transcript, supervisor provenance or model cannot answer, the instruction remains sent with pendingCause in CLI and Desktop; an ignored verdict is charged once to its defect and executor.
A defect-bound send is refused before it is typed when another session owns the defect, when another session's instruction on it still holds, and when the defect already carries a recorded repair: a message reaches an executor only after its current call, so an instruction to repair what is repaired spends that turn on a line that changed. The refusal names the revision and says to audit that repair, or to reopen the defect with oko defects reopen when it does not hold.
Earlier instruction states inferred from a defect or path mention are pending, not verified. The next settlement retains their old evidence, removes the old charge with an audit note and asks Brama to read the genuine turn. A charge from the new verdict is keyed by instruction identity, so retrying the pass cannot count it twice.
Every defect queues a model-derived design shape. A repeated shape creates one mechanism task for an observed live executor working in that product's checkout. The same checkout-membership rule selects claimable work in capacity planning, stopped-session continuation and repair audits. If a live executor's working directory or alive state is unreadable, or none works in the class product, reconciliation remains pending with that cause; it never assigns a different product's executor. Routine retries retain a live owner in the product, move a task whose executor stopped to another eligible executor, restore ready if an instance remains open, and reopen it for each new instance. A concurrent owner change refuses reconciliation and stays pending rather than overwriting that assignment. One patched defect cannot close the class.
A source-bound shape-review also queues that same mechanism work when one defect's construct occurs in multiple source paths. The task retains both the paths found across the commit and parent and those still present at the commit, beside its member defects; another review refreshes the same task. It stays ready if a private occurrence remains even after a member is closed, and does not create a second private backlog. A class task still needs a real journey and all instances closed on a released repair.
Brama or resolver refusal, invalid JSON and missing evidence remain pending with causes for the next pass, never keyword guesses or negative verdicts. Defects → Evidence reflection in Oko Desktop exposes the same operations. Infrastructure failures use `oko reflection observe`: intake retains machine, service, failed operation, cause and state without a model call or a fabricated transcript message. Identical observations reuse their source; changed evidence awaits assessment again. Intake is not defect admission or a repair verdict.
Factory signals
Transcripts show what the operator corrected; the registers show a missing system before he has to: repair claims withdrawn again and again, repairs that stand undelivered, instances of one shape piling up, supervisors stepping into the same class, executors idle or stuck in a model call. oko reflection signals declare names one such measure, the level past which it is a finding and the class defect it records (product, shape, sentence, impact, mechanism and priority). Oko states no level itself.
For mechanism consolidation, declare class_instances against one product and shape to count its open defect members, or shape_source_paths to count distinct source paths found by source-bound repair reviews of that same product and shape. The declared level, not a number in Oko, decides when the class defect opens. A different shape cannot trip that declaration. The class stays open while its members or reviewed paths remain above the level; an unreadable register is a refusal, not a zero. Executor dispatch names the same-shape and source sweep before a repair, and oko defects repaired requires the retained shape review at the repair revision.
oko reflection signals declare --name undelivered --measure undelivered_repairs \
--window-hours <hours a repair may stand> --level <how many may stand> \
--product stado --shape "repairs wait on a manual build" \
--title "Repairs stand undelivered because nothing builds them" \
--impact "every repaired defect stays open on the operator's list" \
--mechanism "a delivery queue that builds and releases each repair as it lands" \
--priority high --by operator
oko reflection signals list --jsonlist reads every signal and says what pass would do; pass, which the improvement loop runs with every model policy pass of Oko's service, records the class defect of each signal past its level, or notes the open class defect of that product and shape. A recorded class defect closes only when oko reflection signals remaining finds no subject past the level. A measure that cannot be read is named with its cause, never read as zero. Defects → Factory signals in Oko Desktop shows the same reading.
rediscovered_causes counts, for each open defect nobody has repaired or claimed, the observations noted on it and the open blockers waiting on it in the window. Each one is a session that met a known cause and traced it again. Its crossing is an optimization: the cause's repair goes first. To see which cause a symptom rests on, run oko blockers roots ID.
One-off repairs#
Oko asks its selected model service to interpret recorded commands together with operator requests and recorded tool results. It does not classify text by keywords. Quoted examples, help requests and source edits are not evidence that an operation ran. Each positive finding must cite text present in the recorded command and name a declared policy category.
oko index sync saves those findings. oko oneoff list --all --json reads them, the Activity screen shows them, and the task judge receives the findings after the task it is reviewing. No recorded call means no finding. The task judge classifies a transcript snapshot once, preserving the preceding operator context when it selects findings for individual tasks.
oko oneoff categories describes each category and its owning product operation. oko oneoff rules shows the semantic policies with synthetic examples, not fleet host names or credential records. oko oneoff check separately checks whether Tama refuses the examples; a model finding is not a gate result.
A finding records an attempt, not proof that live state changed. In JSON, outcome: "refused" and the refused count mean that the tool reported an error. They do not prove a hook prevented execution. ran means no tool error was reported; unrecorded means no matching result was recorded. A later commit counts only when both its command and recorded result support a completed commit. withoutCommit and --without-commit include attempts without that later observation, including attempts whose tools reported errors. The Activity screen uses the same distinctions.
Changed sessions and sessions classified by an older detector become pending before Oko asks the model. Only a complete, valid answer replaces their old findings and marks the current detector version. Old and pending interpretations are excluded from reported totals. pendingSessions remains visible; zero findings with pending sessions does not mean a clean catalogue.
The model answers one object under a strict JSON Schema whose categories are the declared policy categories or null, so it is never JSON read out of prose. An unavailable model, an answer that does not fit the schema, missing calls or unsupported evidence fails oko index sync with the actual judgment error. The session stays pending for a subsequent sync. A complete answer with no findings removes obsolete findings instead of leaving them in the catalogue. Unknown report categories are refused rather than presented as empty results.
Older Lake partitions can contain identical replayed events. Indexing reads each identical event once for conversation text, repair classification and the operator-message count used by reading coverage. A repeated record is not a second operator instruction or a second tool attempt. Distinct recorded calls remain separate, even when their source reused a tool-use ID. When calls or results share that ID, Oko cannot tell which result belongs to which call and records the outcome as unrecorded, not a guessed success or refusal. A previously inflated count is rewritten on the next sync, so it does not keep a session perpetually pending or make fully read messages appear incomplete. The changed detector version makes older classifications pending until oko index sync re-reads them; old outcomes are not counted as current while the recheck is incomplete. If a database write fails, Oko names the table, conflict keys, row count and database error. The failed batch is not reported as successfully indexed.
Model service and judge#
Provider choice, model readiness diagnostics and the real judge journeys are in The model service Oko asks.
Rules#
- Truth comes from user-authored evidence only; assistant claims never prove completion.
- Every surfaced claim carries its evidence quote and provenance.
- Anything that changes state beyond what the operator asked for goes through the approval flow.
- Scope is the local user; nothing aggregated leaves the machine without that approval.
Migrated from src/content/docs/transcript-intelligence/index.md