Skip to content

Step 1 of #874: three loaded harness tiers (harness:lite/medium/heavy), per-tier budgets, offline harnessPro, and the usage.harness column #937

Closed

Description

@Birfy

Step 1 of the harness RFC #874, tracked as its own ticket so a pull request can say Fixes # without closing the RFC. Step 2 (the experience library) stays open with #874; this ticket does not cover it.

The implementation is pull request #933 (tip ea8dec62), already judged PASS and waiting only for an issue reference in its body.

What it delivers

Three tiers — Lite, Medium, Heavy — loaded through Step 0's resolveHarness (core/src/host/harness.js). Each names the same four modules as default and adds a declared budget. applied is false: prompt.js, tools.js, models.js and turns.js keep running exactly as they do today, and install leaves rt.harness on default.

A tier is selected by exactly one label: harness:lite, harness:medium, harness:heavy. No such label — including risk:T* and every other label — stays on default. Two tier labels, or an unknown harness:* label, throw. The labels are declared in .github/labels.json; creating them on the repository is sync-labels.mjs --apply, which is not part of this ticket.

Declared budgets (Lite < Medium < Heavy):

Lite Medium Heavy
prompt maxChars 8000 16000 48000
tools maxCalls 8 24 64
tools allow six read tools those plus work tools, still without create_bot, delete_group, stop_bot null (the full set the host registers)
model maxTokens 2048 8192 16384
step maxSteps 4 12 32
step maxRetries 0 1 1

harnessPro is the offline check for a tier config: the same four modules, verifiers.offline = ci, core/dev/eval, rsi-baseline, and no key or token field. It runs none of those checks and calls no model.

rt.noteUsageHarness(sessionId, idOrLabels) stamps the routed tier on the harness column of a usage row. The resume cursor stays { provider, model, retry }.

Acceptance

  1. The default path is byte-identical. With applied: false, prompt.js/tools.js/models.js/turns.js are untouched, defaultHarness() is byte-identical to Step 0's, and install leaves rt.harness at default.
  2. Selection is one label, and it fails loudly on contradiction. One harness:* label selects that tier; two different tier labels throw; an unknown harness:* label throws; risk:T2 and no label stay on default; the same label repeated de-dupes.
  3. The mirrors are the source. patches/ds-bot/files/ copies and patches/ds-bot/0001-core-fixes.patch rebuild core/ byte for byte (0001 ends with a newline; the trailing-blank-line trap #934 hit is checked here).
  4. usage.harness is written only on an explicit route, and state stays exactly { provider, model, retry }.
  5. The budgets are ordered and bounded: Lite < Medium < Heavy on every row, and Lite/Medium tools.allow never contains create_bot, delete_group or stop_bot.
  6. harnessPro never carries a secret: no key or token field anywhere in its shape, whichever tier it is built for.

Not promised here (Step 2)

Two facts measured on the pull request, written here so nobody reads the merge as more than it is:

  • rt.noteUsageHarness has no caller today, so every live usage row still writes default. The label→tier path is API-only until a caller exists.
  • harnessBySession lives in memory only, so a restart re-folds and rewrites existing rows' harness back to default. Making it durable needs marks.fold, which is Step 2 (the same lifetime problem issuePr has had since Step 0: default harness + usage five fields (#903) #908).

Out of scope

Step 2 (experience library, durable harness marks), running sync-labels --apply on the repository, and any behaviour change to prompt/tools/models/turns.

Activity

  1. added
    enhancementNew feature or request
    agent-prPull request opened by an agent
    area:automationScheduled tasks and automation
    on Oct 24, 2026
  2. removed
    agent-prPull request opened by an agent
    on Oct 24, 2026
  3. added a commit that references this issue on Oct 24, 2026
    8b45067
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:automationScheduled tasks and automationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions