- prometheus-prompt.test.ts: close missing }) on the OpenSpec expanded
commands describe block (introduced by d66b6bcbf, parse error).
- agent-sort-shim/agent-config-integration/continuation-injection/
unstable-agent-babysitter/subagent-resolver/sync-executor/
resolve-caller-team-lead tests: expect 'Sisyphus - ultraworker'
(lowercase) to match production after cd39f8858, which lowercased the
display name to dodge a TUI ZWSP rendering glitch. Legacy uppercase
inputs that exercise the normalization path are preserved.
- sync-executor.ts + resolve-caller-team-lead.ts: route legacy display
name inputs through normalizeAgentForPrompt so prompt agent names and
caller team lead lookups produce the canonical lowercase form.
Both injectors call resolveRegisteredAgentName, which returns the
registered alias verbatim. OpenCode TUI registers agent names with
leading zero-width characters (U+200B) for sort ordering, so that
alias can be e.g. "\u200B\u200BAtlas - Plan Executor". Passing it
directly to promptAsync produces "Agent not found" because the
OpenCode SDK does an exact match against its canonical display
name registry.
Strip the ZWSP sort prefix on the resolved name before sending it
to promptAsync in:
- src/hooks/atlas/boulder-continuation-injector.ts
- src/hooks/todo-continuation-enforcer/continuation-injection.ts
Add regression tests asserting promptAsync receives the canonical
display name (no \u200B) even when the registered alias carries
a ZWSP sort prefix. Same root cause class as #3494 / #3547. Tests
were RED on dev before the fix and GREEN after.
All 5 continuation paths now send variant as top-level body field:
- boulder-continuation-injector.ts
- ralph-loop/continuation-prompt-injector.ts
- todo-continuation-enforcer/continuation-injection.ts
- unstable-agent-babysitter-hook.ts
- session-recovery/resume.ts
Plus type/helper updates in atlas, todo-continuation-enforcer,
unstable-agent-babysitter, and session-recovery.
TDD: 18 regression tests added, all pass. tsc clean.
Display names with parentheses like 'Atlas (Plan Executor)' cause HTTP
header validation errors in x-opencode-agent-name. This was blocking
Atlas/Prometheus from working via /start-work and auto-retry.
Changes:
- Display names: parens -> dashes ('Atlas - Plan Executor')
- Hooks (start-work, no-hephaestus-non-gpt, no-sisyphus-gpt): use
config keys ('atlas', 'sisyphus', 'hephaestus') for agent API fields
- auto-retry: use config key instead of display name for promptAsync
- agent-override-protection: handle dash-suffix normalization
- Updated all test expectations to match new format
Closes#3138
The todo-continuation-enforcer was passing raw agent names (which could be
display names like 'Sisyphus (Ultraworker)') to promptAsync. These names
contain spaces/parentheses that violate HTTP header specs, causing the
x-opencode-agent-name header validation to fail with 'unknown error' toast.
Added normalizeAgentForPromptKey() that converts display names to config keys
(e.g., 'Sisyphus (Ultraworker)' -> 'sisyphus') before API calls.
TDD: Added regression test that verifies config key is sent to promptAsync.
The todo-continuation-enforcer injects continuation prompts when
sessions go idle with pending todos. When Plan Mode agents (which are
read-only) create todo items, the continuation prompt contradicts
Plan Mode's STRICTLY FORBIDDEN directive, causing an infinite loop
where the agent acknowledges the conflict then goes idle, triggering
another injection.
Adding 'plan' to DEFAULT_SKIP_AGENTS prevents continuation injection
into Plan Mode sessions, matching the same exclusion pattern already
used for prometheus and compaction agents.
Fixes#2526
Apply the internal initiator marker to automated continuation, recovery, babysitter, stop-hook, and hook-message injections so Copilot attribution consistently sets x-initiator=agent for system-generated prompts.