Skip to content

Triage Runs

A triage run is one execution of the priority-triage Loom workflow: snapshot tasks → assemble prompt → ship to Ollama → parse → enforce caps → write back. Every run is recorded in the triage_runs table with timing, token counts, summary, and any distribution warnings.

For the workflow's internal step-by-step, see priority_triage Reference.

Triggering a run

HTTP

http
POST /api/triage/rerun

Returns immediately with { "run_id": 42, "status": "started" } after the first DB write. The actual run executes asynchronously.

Code: optimalOS/src/routes/triage.ts:16-60.

From the widget

Click Rerank on the TODAY widget. The widget calls the same endpoint and polls /api/triage/runs until the run completes.

From Loom UI

The workflow priority-triage can be triggered manually from the Loom tab. There is no cron schedule attached.

Inspecting runs

http
GET /api/triage/runs?limit=10

Returns the most recent runs ordered by started_at DESC. Code: optimalOS/src/routes/triage.ts:62-65.

http
GET /api/triage/runs/:id

Returns { run: TriageRun, scores: ScoreHistoryRow[] } — the run row plus every score it produced. Code: optimalOS/src/routes/triage.ts:67-74.

The rubric: RICE-lite

Each task gets four 1-5 scores from the model:

  • Impact — how much does this move the needle if completed?
  • Urgency — how time-sensitive is it?
  • Confidence — how sure are we about Impact and Urgency?
  • Effort — how much work is it?

Raw score: (Impact × Urgency × Confidence) ÷ Effort. Per-run normalization divides each raw by the run's max so all scores fall in [0, 1].

Code: optimalOS/src/triage/scoring.tscomputeRawScore, normalizeRunScores, scoreToLane.

Lane thresholds

ScoreLane
≥ 0.80NOW
≥ 0.60NEXT
≥ 0.30LATER
< 0.30BACKLOG

The model picks a lane in its JSON output. The server then snaps the lane to whichever the score-derived threshold says — model-vs-server lane mismatches are noted in clash_resolution and the server is authoritative.

Distribution caps

Hard caps enforced by both prompt and server:

LaneCap
NOW3
NEXT7
LATER30
BACKLOGunlimited

Configurable via triage.max_now, triage.max_next, triage.max_later. See Configuration.

Server-side enforcement

After Ollama returns, the server runs enforceCaps() (optimalOS/src/triage/distribution.ts:35-69):

  1. Recompute scores from the model's I/U/C/E values (server-side score is authoritative; the model's score field is ignored).
  2. Snap each task's lane to the score-derived lane.
  3. Count tasks per lane. If a lane is over cap, demote the lowest-scoring unlocked tasks cascading: NOW → NEXT → LATER → BACKLOG.
  4. Locked tasks are exempt from demotion. If locked tasks alone exceed a cap, a warning is recorded but no demotion happens.
  5. Populate distribution_warning if any demotions or lock-overflow occurred.

The run is rejected only on:

  • JSON parse failure
  • Zod schema validation failure
  • Empty scores[] array

Distribution overflow never rejects — it auto-demotes.

Batching

Default triage.batch_size = 25. Tasks are split into chunks of ≤25; each chunk gets its own Ollama call. Briefs and overrides are included in every chunk's prompt. Server-side, raw scores from all chunks are merged, deduplicated by task_id, normalized globally, and capped.

Set triage.batch_size = 0 to disable batching and send every task in a single call.

Code: optimalOS/workflows/priority-triage.ts:100-170; default referenced at optimalOS/src/routes/triage.ts:35.

Failure modes

StageError classBehavior
Ollama unreachableOllamaError("network")Run marked failed immediately, no retry.
Ollama HTTP non-2xxOllamaError("http")Run marked failed.
JSON parse failOllamaError("parse")Run marked failed; raw response is logged but not persisted.
Schema validation failOllamaError("schema")Run marked failed.
Token budget overrunError with chunk numberWorkflow throws if estimated tokens exceed 950_000 per chunk. No retry.
DB write failureTransaction ROLLBACKAll score_history inserts and task updates roll back together.

Code references: optimalOS/src/triage/ollama-client.ts:40-109, optimalOS/workflows/priority-triage.ts:115-244.

WebSocket events

Two events are broadcast through the state hub:

  • triage_run_completed — payload { runId, status: "succeeded", summary }
  • triage_run_failed — payload { runId, status: "failed", error }

Code: optimalOS/src/routes/triage.ts:39-53.

The Command Center bridges these to a window-level triage:updated CustomEvent so widgets can listen without owning a WebSocket connection (optimalOS/client/dashboard.ts:832-837).

Step-level events not shipped

The Loom charter promised per-step broadcasts (triage_run_step for each of snapshot_inputs, assemble_prompt, etc.). The workflow currently runs as a single Loom step run; per-step visibility is on the roadmap. Charter file: optimalOS/docs/superpowers/specs/2026-04-14-loom-charter.md.

Built by Carlos Lenis in Miami