Overrides & Locking
The system learns from your corrections. When you change a score dimension, lock a task to a specific lane, or override the model's lane assignment, an entry is written to score_overrides and fed into the next prompt as a calibration signal.
What records an override
Three endpoints write score_overrides rows:
POST /api/triage/overrides— generic, withtask_id+dimension+new_value+user_reason.POST /api/triage/lock/:task_id— locks a task to a lane.POST /api/triage/unlock/:task_id— unlocks a previously-locked task.
Code: optimalOS/src/routes/triage.ts:76-120.
Dimensions
The dimension column is one of:
| Dimension | Meaning |
|---|---|
impact | Override the I value (1-5). |
urgency | Override the U value. |
confidence | Override the C value. |
effort | Override the E value. |
lane | Force a specific lane regardless of score. |
locked | Mark task as locked or unlocked (new_value is "1" or "0"). |
Locking a task
POST /api/triage/lock/:task_id
Content-Type: application/json
{
"lane": "now",
"reason": "Customer demo Friday — must ship."
}Sets score_locked = 1 and locked_lane = "now" on the task and inserts a score_overrides row with dimension locked. Locked tasks:
- Bypass Ollama entirely on subsequent runs (filtered at query time via
score_locked = 0). - Keep their
locked_laneacross reruns; denorm columnscurrent_score/current_lane/current_rankare not touched on the locked task. - Are still mentioned in the prompt as "user locked this at LANE" so the model sees the constraint.
- Are exempt from auto-demotion when a lane is over cap. If locked tasks alone exceed a lane's cap, a warning is recorded but nothing moves.
Code: optimalOS/src/triage/db.ts:191-197, optimalOS/src/routes/triage.ts:91-107.
Unlocking
POST /api/triage/unlock/:task_idSets score_locked = 0 and inserts an override row with dimension locked, new_value = "0". The task rejoins normal scoring on the next run.
Code: optimalOS/src/routes/triage.ts:109-120.
The learning loop
Before every Ollama call, listUnappliedOverrides(db) retrieves all rows where applied_to_run_id IS NULL (optimalOS/src/triage/db.ts:161-164). The prompt builder includes them in a dedicated block:
USER OVERRIDES — corrections the user has made; calibrate against these:
- task_abc: impact 3 → 5 (reason: "carrier deadline moved")
- task_xyz: lane next → now (reason: "ed wants this Tuesday")
- task_mnp: locked at now (reason: "customer demo Friday")After the run succeeds, markOverridesApplied(db, ids, runId) (optimalOS/src/triage/db.ts:167-174) sets applied_to_run_id so the same override is not double-counted.
The model is expected to internalize the corrections over 2-3 cycles. Override frequency on the same tasks should drop as the model recalibrates.
Override window
The Loom charter promised "last 30 days" filtering on the override list. The current implementation lists all unapplied overrides (without a date filter), which is semantically close — applied overrides are by definition older — but not identical. Tracked in the charter at optimalOS/docs/superpowers/specs/2026-04-14-loom-charter.md.
Schema
The score_overrides table (optimalOS/src/db/migrations.ts:206-217):
| Column | Type | Notes |
|---|---|---|
id | INTEGER PK | |
task_id | TEXT FK→tasks(id) | |
dimension | TEXT | impact | urgency | confidence | effort | lane | locked |
old_value | TEXT nullable | |
new_value | TEXT nullable | |
user_reason | TEXT nullable | |
created_at | TEXT DEFAULT now | |
applied_to_run_id | INTEGER FK→triage_runs(id) nullable | Set on successful run. |
Index: idx_overrides_unapplied on applied_to_run_id IS NULL.
The tasks table additionally carries score_locked INTEGER DEFAULT 0 and locked_lane TEXT columns added in migration v5.