Fast-fail with a shell steer before any prompt; docstring names the closed catalog
and stops citing semgrep (pip/brew, deliberately unmanaged) as an example.
More fold gains a Files section listing workspace/scratch/granted roots.
Roots open in the artifact viewer (Files breadcrumb); folder click-through was already there.
Gated sessions run workspace+scratch dual-root; artifact listing scans scratch only.
Artifact chips resolve across workspace, scratch, and granted roots; request_directory registers for all sessions.
List groups General/Security with quiet disclosures for unshipped coworkers and the installer (native pickers for folder/zip); gallery is internal-build only.
Detail: markdown About with bundle screenshot carousel, one Connectors table (Status/Enable), tool calls collapsed under Advanced, management controls moved here.
Account menu drops Automations (sidebar nav has it) and the OpenWorker Cloud suffix.
Token savings + compaction move from Models to a new Settings - Context optimization tab.
Coworkers page loses its duplicate intro line.
Custom - MCP group after Connected; Add custom server modal at top; per-server detail subpage with Test.
Status never claims connected for stdio: Live / Ready + persisted tested-at / Not tested / Needs sign-in / Error.
Explicit connect reports stderr tails; a 401 on an anonymous http probe becomes needs-sign-in with a one-click OAuth switch.
Test button probes any enabled server row without opening a session.
Capture stdio stderr tail; record generic connect errors for /v1/mcp (status=error);
persistent session notice via mcp_error; tests for client, manager, and GUI mapping.
Team members move from sidebar to a drawer panel; RECENT keeps one entry per team.
All sections collapsed by default; Journal/Access fold behind More; leads drop Progress.
Lead mentions the board once via a [.](board:) chip that opens the drawer.
Worker delivery is now a read-time feed over its slice (assigned ∪ filed) — send-backs, comment answers, reassignments, cancels, and acceptance all arrive through one relation; per-event recipient addressing retired.
Reassignment delivers before interest ends; a new assignee replays the item's story. Detail pane gains Add a note (never changes state); external pending/consume become space-scoped feed calls.
Send-back/unblock/cancel by someone else now land in the worker's queue (only cancel did — send-backs woke nobody); done stays unaddressed.
The Request changes button drops the send-to-X phrasing — it's a board write, delivery is the queue's job.
Sections are the store's states (In progress / Awaiting review / Queued), no row buttons or badges; blocked rows carry the blocker fact.
Detail pane merges the item's events into one timeline (filed/assigned/moves/comments/attachments), links the assignee to its worker session, and hosts the verdicts: Mark done / Request changes… (returns to the worker with the comment).
Any model routed through /v1/responses (gpt-5.6+ with tools, i.e. the
default gpt-5.6-sol) reported 0 tokens for every call: both
AssistantTurn constructions omitted usage while every sibling adapter
populated TokenUsage. First consumer to notice was the Auto-Approve
reviewer metering; the 2026-08-13 eval report printed 'Tokens: 0 in /
0 out' across ~40 live calls.
_usage_from maps the Responses shape like the Chat Completions adapter:
fresh input = input_tokens - cached_tokens (input_tokens is INCLUSIVE
of the cached share), cached share -> cache_read, output_tokens as-is
(reasoning already included). Defensive reads: compat servers may omit
input_tokens_details; a missing usage object stays None, never a fake
zero. Wired in _parse_response, which both complete() and the stream's
terminal response.completed event flow through - one extraction, both
paths.
Tests: cache split, partial/missing degradation, stream terminal event,
stream-without-terminal stays None. Verified live against gpt-5.6-sol:
call 1 'in=1820 cache_read=0', call 2 'in=3 cache_read=1817' - the
0-token era ends and the cache split reports correctly.
Auto-caching providers (OpenAI/Together/Gemini) serve most of the
reviewer's 1,400-token prefix from cache and report the split; dropping
it made calls read as '16 in' - present-tense misreporting, not a v2
optimization (owner call 2026-08-17). Probed live: Together sends
prompt_tokens=1430 + cached_tokens=1408 OpenAI-style; the adapter
already normalized it, the Verdict just discarded it.
Verdict + reviewer.stats gain cache_read/cache_write; the eval token
line now reads 'X fresh in / Y out / Z cached in (billed ~10%) - N
input tokens actually processed'. The OPT-IN caching decision
(Anthropic cache_control, TTL economics) stays in OPE-77 - this commit
only stops lying about what already happens.
A provider outage (Together GLM 5xx, live 2026-08-17) turned rows into
unsure verdicts indistinguishable from genuine caution - a benign gate
read FAIL and a dangerous gate would have read PASS, both meaningless.
Verdict gains error:bool - set only when the MACHINERY fails (provider
error, timeout), never on a parse defect (the model DID answer; a
contract-violating answer is a real model property the eval should see).
The live engine is unaffected: error and caution both mean card+human.
Harness: run_corpus retries an errored row once (transient 5xx must not
decide a gate), counts what remains, and a corpus with ANY error row
CANNOT pass its gate - pass means 'measured clean', and the fix for an
outage is re-run, not certify-through-it. Report gains an Errors column
and lists the errored ids. Tests cover the retry, the error-count, and
the can-never-pass rule.