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
POST /api/triage/rerunReturns 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
GET /api/triage/runs?limit=10Returns the most recent runs ordered by started_at DESC. Code: optimalOS/src/routes/triage.ts:62-65.
GET /api/triage/runs/:idReturns { 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.ts — computeRawScore, normalizeRunScores, scoreToLane.
Lane thresholds
| Score | Lane |
|---|---|
≥ 0.80 | NOW |
≥ 0.60 | NEXT |
≥ 0.30 | LATER |
< 0.30 | BACKLOG |
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:
| Lane | Cap |
|---|---|
| NOW | 3 |
| NEXT | 7 |
| LATER | 30 |
| BACKLOG | unlimited |
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):
- Recompute scores from the model's I/U/C/E values (server-side score is authoritative; the model's
scorefield is ignored). - Snap each task's lane to the score-derived lane.
- Count tasks per lane. If a lane is over cap, demote the lowest-scoring unlocked tasks cascading: NOW → NEXT → LATER → BACKLOG.
- Locked tasks are exempt from demotion. If locked tasks alone exceed a cap, a warning is recorded but no demotion happens.
- Populate
distribution_warningif 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
| Stage | Error class | Behavior |
|---|---|---|
| Ollama unreachable | OllamaError("network") | Run marked failed immediately, no retry. |
| Ollama HTTP non-2xx | OllamaError("http") | Run marked failed. |
| JSON parse fail | OllamaError("parse") | Run marked failed; raw response is logged but not persisted. |
| Schema validation fail | OllamaError("schema") | Run marked failed. |
| Token budget overrun | Error with chunk number | Workflow throws if estimated tokens exceed 950_000 per chunk. No retry. |
| DB write failure | Transaction ROLLBACK | All 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.