type: meta

slug: harness-tier-backlog

topic: Tier taxonomy rename (critical/regular/simple -> low/medium/high) + tier-downgrade backlog/triage feature

exec_mode: ship

scheduler: dag-parallel

land_mode: merge-to-main

base_branch: main

status_enum: BLOCKED PENDING WORKING WRITTEN REVIEWED COMMITTED

truth_rule: this file is ground truth for INTENT (goals/directions/task list); git is ground truth for DONE-NESS — reconcile statuses against git, never trust a COMMITTED line with no commit

refresh_how: native Read of THIS file — NEVER ctx_execute/ctx_search

refresh_what: meta + every goal/methodology/intent/direction record + all WORKING and BLOCKED tasks (skip COMMITTED lines)

refresh_when:
wave/phase boundary
any task status change
after a compaction system-reminder
before calling advisor

update_rule: on status change, rewrite that task's single line in place; append new tasks/session_memory as new lines

report_rule: at session end emit brief: done / blocked / deferred / canceled — NO 'next action' (if you know it, do it)


type: goal

text: Rename the tier taxonomy to low/medium/high with a closed-enum all-or-nothing coverage lint, then build the tier-downgrade backlog/triage feature on top: auto-detect silent rung-4 fallbacks, allow manual flagging, scope views per-plan/per-project/global, and support manual re-run at an explicit tier override.


type: methodology

text: Contract-level plan, fresh subagent per task via ship, two-stage review. Wave 1-3 (tier rename) is a hard gate before wave 4-8 (backlog feature) starts — enforced by wave ordering/deps, not a human gate.


type: intent

text: resolve-seat.sh silently falls back to a preset's flat/default binding when a role has no tier layer for the requested tier, with zero signal — tasks authored for a high tier can silently run on a weaker model. This closes that blind spot: surface it, record it durably, and make it triageable/re-runnable.


type: direction

verbatim: we don't want anything backwards compatible, i'm a single dev it's not a product for releasing... agents can deal with it, and in a few hours they won't need to.


verbatim: llm mismatch could not lead to a halt


verbatim: priority can be assigned... backlog per plan, per project, and global


type: task

desc: Close the tier enum in spec/presets.schema.json to low/medium/high

status: COMMITTED


desc: Add all-or-nothing tier-coverage lint to presets/_validate.mjs, update self-test fixtures


desc: Add low/medium/high tier layer to presets/codex.json — 3 genuinely distinct bindings per seat (coder.high=gpt-5.5-high kept, +medium=gpt-5.5-medium, +low=gpt-5.5-low; reviewer.low=gpt-5.5-low kept, +medium=gpt-5.5-medium, +high=gpt-5.5-high), with high->medium->low fallbacks


desc: Rename default tier fallback in src/runner.js (regular -> medium)


desc: Rename tier vocabulary in lib/test-resolve-seat.sh and test/runner-integration.sh (part of the frozen ship TESTCMD)


desc: Full validation gate: confirm tier rename complete and internally consistent before backlog feature work starts


desc: Add rung field (1|2|3|4) to resolve-seat.sh's resolved binding output


desc: Create lib/backlog.sh: backlog/v1 persistence helper (append, set-status, locking, independent of journal.sh)


desc: Capture tierExplicit at plan-parse time in src/runner.js loadPlan


desc: Auto-downgrade detector in src/runner.js: append backlog/v1 record when tierExplicit && rung==4


desc: Add runSingleTaskWithOverrides wrapper in src/runner.js for backlog requeue


desc: Gateway route: POST /api/gateway/runs/:runId/tasks/:taskId/backlog (manual flag)


desc: Gateway route: POST /api/gateway/backlog/:backlogId/requeue


desc: Gateway route: GET /api/gateway/backlog?scope=plan|project|global (list with reap-on-read)


desc: Backlog web UI page: scope tabs, priority set, re-run action