TASK_CLEANUP_DELAY_MS is the delay between a task reaching a terminal
state (completed/cancelled/errored) and its removal from the in-memory
task store. It is currently a hard-coded 10 minute constant, which is
too short for long-running background workflows: users routinely hit
'task not found' on background_output lookups when they inspect
results more than ~10 minutes after completion.
taskTtlMs (landed in #2825) already exposes the non-terminal task TTL
on BackgroundTaskConfigSchema. This PR mirrors that pattern for the
terminal-state cleanup delay:
- Add taskCleanupDelayMs: z.number().min(60000).optional() to
BackgroundTaskConfigSchema with JSDoc matching taskTtlMs's style.
- BackgroundManager.scheduleCompletionRemoval() reads
this.config?.taskCleanupDelayMs ?? TASK_CLEANUP_DELAY_MS, preserving
the existing 10 min default for unconfigured users.
- Regenerate assets/oh-my-opencode.schema.json.
Default: 600000 ms (10 min, unchanged from current hard-coded value).
Minimum: 60000 ms (1 min).
bun run typecheck: clean.
bun test src/features/background-agent: 411/411 pass.
Reports from david_66 on Discord: sessions get perceived as 'stuck' when
context usage crosses the 78% threshold. Investigation confirmed two
issues in the preemptive compaction hook:
1. PREEMPTIVE_COMPACTION_TIMEOUT_MS was 120s. While the summarize
request is in flight, tool.execute.after short-circuits via the
compactionInProgress guard. A hung summarize blocked the session
for two full minutes before giving up, which users reasonably
experience as a hang.
2. On failure (timeout or exception) only a log line was emitted. The
user had no visibility into why their session was unresponsive or
why auto-compaction never ran, so a transient upstream error could
silently leave them well above the threshold with no signal.
Fix:
- Reduce timeout 120s -> 60s. Still gives the upstream a generous
window, but caps the worst-case perceived hang at one minute.
- Show a warning toast via ctx.client.tui.showToast whenever the
catch block fires, including the underlying error string so users
can act (retry, manual /compact, or adjust provider).
- Include providerID/modelID in the Compaction failed log entry so
wild failures are easier to correlate to a specific target model.
Two existing failure-path assertions were updated to match the new
log shape and a new test covers the toast notification contract.
Discord report: https://discord.com/channels/1452487457085063218/1490536332961906829/1491345441399505037
discoverInstalledPlugins read scope from installed_plugins.json but
never filtered by it, so project/local scoped Claude Code plugins
leaked into every session regardless of process.cwd().
Add projectPath to PluginInstallation and InstalledPluginEntryV3,
propagate it through v3EntryToInstallation, and introduce
shouldLoadPluginForCwd which reuses shared/contains-path for safe
symlink- and ancestor-aware matching and expands a leading tilde.
user and managed scopes still always load; project and local without
a projectPath are skipped as a safe default.
Covered by 13 new shouldLoadPluginForCwd unit tests (including tilde
expansion against a mocked homedir) and 13 new discoverInstalledPlugins
integration tests spanning v1, v2, and v3 database formats plus the
existing enabledPluginsOverride path.
Fixes#3216
Replace fragile regex text matching with structured detection for Oracle verification evidence.
- Add oracle-verification-detector.ts with parseOracleVerificationEvidence()
- Use structured parsing instead of multiple regex patterns
- Add comprehensive test coverage for edge cases
- Update completion-promise-detector.ts to use isOracleVerified()
- Update pending-verification-handler.ts to use structured extraction
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>