Skip to content

feat(widget): label tok/ctx% as substrate vs work (#32 tail) - #56

Merged
rz1989s merged 1 commit into
mainfrom
feat/issue-32-widget-substrate-label
Aug 8, 2026
Merged

feat(widget): label tok/ctx% as substrate vs work (#32 tail)#56
rz1989s merged 1 commit into
mainfrom
feat/issue-32-widget-substrate-label

Conversation

@rz1989s

@rz1989s rz1989s commented Aug 8, 2026

Copy link
Copy Markdown
Member

What

The fleet widget's tok/ctx% segment is a context-occupancy metric dominated by the armory substrate (~59% from turn 1, barely moving across turns — see #32). On substrate-dominated runs it reads as "frozen / same every session," indistinguishable from a stuck run.

This adds a substrate vs work label to the widget's foreground run line: capture a substrateBaseline = contextTokens at the end of turn 1 (first assistant message_end), then once past turn 1 label the segment substrate when growth is ≤5% of the baseline (flat overhead) or work when tool results are growing the context.

▶ "review the PR"  · coder  5s  575K tok  59%  substrate  $0.0001
▶ "refactor module"  · coder  12s  655K tok  67%  work  $0.0042

Before turn 2 (or when no baseline was captured — e.g. turn 1 produced no assistant message) no label is shown: there's nothing to compare against yet.

Scope (intentional)

Changes

  • src/engine/run-registry.tsRunRecord.substrateBaseline?: number (live-only, documented).
  • src/engine/spawnSubagent.ts — capture once at the turn-1 first assistant message_end (turnIdx === 0); threaded into the runRegistry.update patch.
  • src/panel/widget-rows.tsSUBSTRATE_GROWTH_THRESHOLD = 0.05 + substrateBaseline on WidgetRun/toWidgetRun + the label in widgetLine (after ctx%, before cost).
  • Tests — 6 widget cases (substrate flat / work growing / exactly-at-threshold / turn-1 no-label / no-baseline no-label / bg no-label) + 2 spawn cases (baseline captured at turn-1 message_end / not captured when no message_end).

Verification

  • pnpm typecheck clean.
  • pnpm test:run677/677 pass (669 existing + 8 new).
  • Read-only review subagent verdict: Ship (no critical/important findings; 2 nits, both non-blocking and in-scope).

Closes part of #32 (direction 4 — widget UX). The other two #32 directions (memory-scope trim, prompt compaction) need a substrate measurement and ship as separate PRs.

The fleet widget's tok/ctx% segment is a context-occupancy metric
dominated by the armory substrate (~59% from turn 1, barely moving
across turns). On substrate-dominated runs it reads as "frozen /
same every session," indistinguishable from a stuck run.

Capture a substrateBaseline = contextTokens at the end of turn 1
(the first assistant message_end) on RunRecord, then classify the
segment once past turn 1: "substrate" when growth is ≤5% of the
baseline (flat overhead), "work" when tool results are growing the
context. Before turn 2 (or when no baseline was captured) no label
is shown — there's nothing to compare against yet.

- src/engine/run-registry.ts: RunRecord.substrateBaseline (live-only)
- src/engine/spawnSubagent.ts: capture once at turn-1 message_end
- src/panel/widget-rows.ts: SUBSTRATE_GROWTH_THRESHOLD + label in widgetLine
- tests: 6 widget cases (substrate/work/threshold/turn-1/no-baseline/bg)
  + 2 spawn cases (baseline captured / not captured)
@rz1989s
rz1989s merged commit af01480 into main Aug 8, 2026
1 check passed
@rz1989s
rz1989s deleted the feat/issue-32-widget-substrate-label branch August 8, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant