Commit Graph

1407 Commits

Author SHA1 Message Date
YeonGyu-Kim 4da48555ee fix(plugin): normalize event session ids
Handle OpenCode session events that carry the session ID under properties.info.id or properties.info.sessionID so background tasks and continuation hooks do not miss idle/error/delete events.

Add regression coverage for nested session.idle events completing background tasks and waking continuation hooks.
2026-05-12 12:32:26 +09:00
YeonGyu-Kim 71a63c20ec Revert "fix(hooks): dedupe native agent instructions"
This reverts commit 78d52872f2.
2026-05-11 18:02:13 +09:00
YeonGyu-Kim 78d52872f2 fix(hooks): dedupe native agent instructions 2026-05-11 17:21:58 +09:00
YeonGyu-Kim c849d0cbbc fix(ralph-loop): suppress stale iteration toasts 2026-05-11 15:17:07 +09:00
YeonGyu-Kim 2c299d2d9e Merge pull request #3943 from code-yeongyu/feature/boulder-evolution-and-discipline-agents
feat: boulder evolution + discipline agents (multi-work, timings, CLI, hooks, Oracle phase gates, no-excuses retry)
2026-05-11 14:54:58 +09:00
YeonGyu-Kim 29c42485a8 fix(hooks/atlas): capture plan snapshot for .sisyphus paths
Oracle review of PR #3943 surfaced that endTaskTimer never fires for real Prometheus plans because their canonical path is .sisyphus/plans/ and the snapshot capture was nested inside the !isSisyphusPath branch intended for direct-work warning suppression. Move the snapshot/path tracking out of the warning gate so all plan-file edits are snapshotted regardless of .sisyphus prefix. Keep the warning branch isSisyphus-gated so Atlas does not yell at legitimate plan edits.

Regression test now uses a real .sisyphus/plans/ path and fails against HEAD before the fix.
2026-05-11 14:48:49 +09:00
YeonGyu-Kim cf5fe757df feat(hooks/atlas): parse task_key from delegation prompt for parallel batches 2026-05-11 14:28:56 +09:00
YeonGyu-Kim e3cddb3650 feat(hooks/atlas): end task timer when plan checkbox flips to checked via edit 2026-05-11 14:27:03 +09:00
YeonGyu-Kim b8c25b3b75 refactor(hooks/atlas): remove unused resolveSessionOrigin helper 2026-05-11 14:26:10 +09:00
YeonGyu-Kim 079a2cd65a fix(start-work): preserve existing works when starting an explicit new plan 2026-05-11 14:25:52 +09:00
YeonGyu-Kim de9c28a095 fix(hooks/atlas): align completion behavior tests with task-4 timing updates 2026-05-11 13:49:36 +09:00
YeonGyu-Kim 1ebf89cb9f feat(hooks/atlas): inject boulder-complete elapsed-time nudge once per work
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-11 13:43:40 +09:00
YeonGyu-Kim a1c6e6b77d fixup! feat(hooks/atlas): use getWorkForSession in boulder lookups and session tracking 2026-05-11 13:42:39 +09:00
YeonGyu-Kim d6f4199cab feat(start-work): use getWorkResumeOptions for multi-work resume selection
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-11 13:40:57 +09:00
YeonGyu-Kim 29b44fffd0 feat(hooks/atlas): call completeBoulder when progress.isComplete 2026-05-11 13:40:48 +09:00
YeonGyu-Kim 127112e1e2 feat(hooks/atlas): wire per-task timers via startTaskTimer/endTaskTimer 2026-05-11 13:39:47 +09:00
YeonGyu-Kim f2a5ef0966 feat(hooks/atlas): add BOULDER_COMPLETE_PROMPT template and SessionState guard
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-11 13:37:35 +09:00
YeonGyu-Kim 18af3d3617 feat(hooks/atlas): use getWorkForSession in boulder lookups and session tracking 2026-05-11 13:37:19 +09:00
YeonGyu-Kim 49ff4b5f8d fix(compaction): ignore compaction agent updates
Fixes #3819
2026-05-11 13:25:29 +09:00
YeonGyu-Kim 2e36a92c25 fix(ralph-loop): revalidate ownership and harden commit/session-creation failures
Three correctness fixes on top of the dispatch-before-commit invariant:

- ralph-loop-event-handler.ts: after idleSettleMs, also require state ownership and non-verification-pending to match the event source before dispatching. Applied to both the session.idle and session.error retry paths.
- verification-failure-handler.ts: if incrementIteration fails after a successful continuation injection, clear the loop state and emit a warning toast instead of returning success.
- session-reset-strategy.ts: catch thrown session.create errors so they route through the typed session_creation_rejected path instead of surfacing as an unhandled rejection.
2026-05-11 13:02:16 +09:00
YeonGyu-Kim 35cab4db10 test(ralph-loop): cover ownership race, verification commit failure, session.create throw
Three additional invariant tests addressing the gaps surfaced by Cubic and the post-implementation review:

- idle path must not dispatch when state ownership changes during the idleSettleMs window
- verification-failure path must treat incrementIteration failure as a loud failure, not a success
- reset strategy must surface session.create rejections as session_creation_rejected even when the SDK throws instead of returning an error envelope
2026-05-11 13:02:07 +09:00
YeonGyu-Kim caaae19155 fix(ralph-loop): commit iteration only after verification continuation dispatches
Split the verification-failure restart into clearVerificationState (clears\nthe verification flags so we cleanly transition back to the main loop)\nfollowed by injectContinuationPrompt, with incrementIteration only on\nsuccessful injection. On rejection: clear the loop state and emit a loud\nwarning toast. Mirrors the dispatch-before-commit contract enforced for\nthe idle and session.error paths.
2026-05-11 12:46:35 +09:00
YeonGyu-Kim 09c45c3acb fix(ralph-loop): commit iteration only after continuation is dispatched
Reorder the session.idle and session.error retry paths so the durable\niteration counter and the progress toast advance only when continueIteration\nreturns dispatched. On dispatch_rejected or session_creation_rejected,\nclear the loop state and emit a loud failure toast instead of silently\nlogging while the loop appears to make progress.\n\nAdds an explicit settle-window state check so a session.deleted firing\nduring the idleSettleMs sleep no longer feeds dispatch against a cleared\nloop. Keeps idleSettleMs intact for the original idle-settle race.
2026-05-11 12:46:07 +09:00
YeonGyu-Kim d4cdeaccbe fix(ralph-loop): return typed ContinuationResult from continueIteration
Replace silent returns in continueIteration with a discriminated union\n(dispatched | session_creation_rejected | dispatch_rejected). Wraps\ninjectContinuationPrompt in try/catch so reset-strategy createIterationSession\nreturning null and promptAsync rejections both surface as typed failures\nthe caller can react to.
2026-05-11 12:45:59 +09:00
YeonGyu-Kim f0857a88fb test(ralph-loop): add dispatch-failure invariant tests
Lock the contract that durable iteration state and visible UI must only\nadvance when the continuation dispatch is semantically accepted. Adds 4\npermanent invariant tests covering the idle, session.error retry, and\nverification-failure orchestration paths, plus the reset-strategy\nsilent-null path.
2026-05-11 12:45:51 +09:00
wenghuayang863 f3f72fc96f fix(runtime-fallback): also classify Volcano Engine errors as quota_exceeded
- Add /exceeded.*quota/i and /usage\s*quota/i to classifyErrorType quota block
- Align /usage.?quota/i -> /usage\s*quota/i in RETRYABLE_ERROR_PATTERNS for consistency
- Strengthen auto-retry-signal test assertion
- Add classifyErrorType assertion to Volcano Engine regression test

Ensures Volcano Engine errors are both retryable AND logged as
errorType: quota_exceeded.
2026-05-11 01:03:02 +08:00
wenghuayang863 1c7881ec09 fix(runtime-fallback): match Volcano Engine 'exceeded the usage quota' errors
Volcano Engine sends quota exceeded errors with the words in reverse
order: 'You have exceeded the 5-hour usage quota'. The existing
patterns required 'quota' to precede 'exceeded', so they never matched.

- Add /exceeded.*quota/i and /usage.?quota/i to RETRYABLE_ERROR_PATTERNS
- Add exceeded.*quota and usage\s*quota to AUTO_RETRY_PATTERNS
- Add regression tests for both detection paths

Fixes: runtime-fallback not triggering on Volcano Engine quota errors
2026-05-11 00:43:58 +08:00
YeonGyu-Kim dd29e9b96a fix(compaction): restore context and todos before continue 2026-05-10 13:54:27 +09:00
YeonGyu-Kim 1ea4dfe215 fix(hooks): settle idle prompt continuations 2026-05-10 12:55:36 +09:00
YeonGyu-Kim 806842981f fix(ralph-loop): settle idle before continuation 2026-05-10 12:46:00 +09:00
YeonGyu-Kim c01a89ba43 feat(atlas): mandate parallel delegation and add per-model variants
Atlas was delegating tasks one-by-one because the workflow framed parallel
as a conditional ("if tasks can run in parallel..."), letting models default
to the safer sequential path. The new shared ATLAS_PARALLEL_BY_DEFAULT block
flips the default: parallel is mandatory; sequential requires a NAMED
blocking dependency (input dependency or file conflict).

Adds two new prompt variants — kimi (K2.6 thinking-mode calibration:
commitment framing + concrete budgets) and opus-4-7 (counters 4.7's lower
default subagent count and literal-following bias). Recalibrates default
(Claude 4.6 family), gpt (GPT-5.5 outcome-first / decision rules over
absolutes), and gemini (preserves TOOL_CALL_MANDATE; replaces stale
session_id with task_id). All five variants share the parallel mandate
positioned BEFORE the workflow so "mandate above" references resolve.

Strengthens the orchestrator-direct-edit reminder hooks
(ORCHESTRATOR_DELEGATION_REQUIRED + DIRECT_WORK_REMINDER) with the central
challenge "Do you ACTUALLY need to be the one doing this?" — replacing the
previous bullet-heavy framing.

Tests now parametrized over all 5 variants. Adds prompt-routing.test
covering GPT/Gemini/Kimi/Opus 4.7/default routing and edge cases, plus a
session_id rejection test (every variant must use task_id for retries).
2026-05-08 16:50:41 +09:00
YeonGyu-Kim 43b0529557 feat(hooks): surface fsync-skip warnings to AI agent via tool output
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-08 15:08:34 +09:00
YeonGyu-Kim 2dfa6336f5 fix(metis): switch primary model to claude-sonnet-4-6 + correct AGENTS.md inaccuracies
Source code change:
- src/shared/model-requirements.ts: prepend claude-sonnet-4-6 to metis fallback
  chain so Sonnet becomes the default. Opus 4.7 max remains as the immediate
  fallback for callers who want extra reasoning.
- src/shared/model-requirements.test.ts: update assertion to expect Sonnet
  primary + Opus secondary.

AGENTS.md accuracy fixes (verified against source):
- Agent modes: Sisyphus/Hephaestus are 'primary' (not 'all'); Sisyphus-Junior
  is 'subagent' (not 'all'). Confirmed via 'const MODE: AgentMode = ...' in
  each agent file. Also clarified Prometheus has no agentSources factory and
  is built via buildPrometheusAgentConfig.
- Sisyphus fallback chain: corrected order to kimi-k2.6 → k2p5 → kimi-k2.5
  → gpt-5.5 medium → glm-5 → big-pickle (was missing kimi-k2.5).
- Librarian/Explore: added missing minimax-m2.7 step between -highspeed and
  claude-haiku-4-5.
- Metis chain: removed fictitious gemini-3.1-pro entry.
- Sisyphus-Junior chain: spelled out the actual fallback (was 'user-configurable').
- Temperatures: Sisyphus/Hephaestus do not set explicit temperature (model
  default); Sisyphus-Junior is 0.1 via SISYPHUS_JUNIOR_DEFAULTS.
- Quick category default: gpt-5.4-mini (not gpt-5.4-mini-fast).

Team-mode corrections:
- Eligibility registry has 3 verdicts: eligible (sisyphus, atlas, sisyphus-junior),
  conditional (hephaestus — needs D-36 teammate permission), hard-reject
  (oracle, librarian, explore, multimodal-looker, metis, momus, prometheus).
- Schema has 11 fields, not 4: added max_messages_per_run, max_wall_clock_minutes,
  max_member_turns, base_dir, message_payload_max_bytes, recipient_unread_max_bytes,
  mailbox_poll_interval_ms.
- Hooks: 'team-session-events' is 4 sub-handlers in src/plugin/event.ts
  (team-idle-wake-hint, team-lead-orphan-handler, team-member-error-handler,
  team-member-status-handler), not a single Continuation-tier hook.
- Tier counts now show base + team-mode: ToolGuard 14/15, Transform 5/7.
- Total: 52 base hooks, 59 with team-mode.

Doc cascade for the Metis change:
- docs/guide/orchestration.md, agent-model-matching.md, installation.md
- docs/reference/configuration.md, features.md
2026-05-08 13:06:34 +09:00
YeonGyu-Kim 838b5ae216 docs(agents): refresh hierarchical AGENTS.md with team-mode coverage
Update root + 43 directory-level AGENTS.md files to reflect current state:
- Root AGENTS.md rewritten with accurate counts (1967 TS files, 1304 source +
  663 test, 278k LOC, 120 barrel index.ts), 7-step init flow, 5-tier hook
  composition, and full Team Mode section (12 team_* tools, eligibility,
  storage layout, config gate)
- src/AGENTS.md adds team-mode init step, current per-subdir file/LOC table
- src/tools/AGENTS.md documents conditional gates (team-mode +12, task
  system +4, hashline +1, interactive_bash +1, look_at +1) with always-on
  baseline of 20
- src/hooks/AGENTS.md splits into 5 tiers + 4 conditional team-mode hooks
- src/features/team-mode/AGENTS.md surfaces 12 tools, eligible agents,
  spawn-race-safe invariants, and integration points
- src/features/builtin-skills/AGENTS.md tracks 10 skills incl. team-mode
- src/agents/AGENTS.md, src/plugin/AGENTS.md, src/config/AGENTS.md updated
  for team-mode awareness, accurate counts, and current schema field list
- All other AGENTS.md files refreshed to 2026-05-08 generation date
2026-05-08 12:08:42 +09:00
YeonGyu-Kim ee938aa097 fix full-suite isolation regressions 2026-05-07 18:36:03 +09:00
YeonGyu-Kim ebe26eab17 fix(ralph-loop): guard runtime error retries 2026-05-07 11:50:44 +09:00
YeonGyu-Kim 83ec352899 merge dev into continuation runtime retry
# Conflicts:
#	src/hooks/ralph-loop/non-abort-error-continuation.test.ts
2026-05-07 11:34:33 +09:00
YeonGyu-Kim 2c70938d81 test(ralph-loop): cover ultrawork runtime retry 2026-05-07 11:27:46 +09:00
YeonGyu-Kim 6a2d19d605 fix(atlas): retry boulder after runtime errors 2026-05-07 11:27:44 +09:00
YeonGyu-Kim ef66516ea4 Merge pull request #3801 from code-yeongyu/fix/directory-agents-non-string-output
fix(directory-agents-injector): guard against non-string output.output (#3800)
2026-05-06 18:17:36 +09:00
YeonGyu-Kim 66a6f42d73 fix(todo-continuation-enforcer): preserve overload countdown 2026-05-06 17:36:03 +09:00
MoerAI a22416d270 fix(error-classifier): classify credit balance too low as quota_exceeded for fallback (fixes #3571) 2026-05-06 17:17:23 +09:00
YeonGyu-Kim 7ac1109611 Merge pull request #3636 from lucasyounger/codex/fix-3629-worktree-plan-path
fix(boulder): resolve continuation progress from worktree plan
2026-05-06 17:15:21 +09:00
Samuele Domenico Ruffino 6cd40df4cb feat(opencode-go): upgrade glm-5 → glm-5.1 and kimi-k2.5 → kimi-k2.6 in fallback chains 2026-05-06 16:45:30 +09:00
YeonGyu-Kim 47b5c56660 fix(ralph-loop): retry runtime errors immediately
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 16:27:45 +09:00
YeonGyu-Kim 8e1719968b fix(ralph-loop): retry runtime errors immediately
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 16:23:01 +09:00
YeonGyu-Kim 124845002b fix(keyword-detector): pin hyperplan roster hint
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim f6643e7e77 fix(keyword-detector): yield to slash commands so /hyperplan executes its template
When user types /hyperplan something, two pipelines race for the message:
  1. keyword-detector hook (chat.message): the regex \b(hyperplan|hpp)\b
     matches /hyperplan because \b is satisfied by the / boundary, so the
     hook prepends <hyperplan-mode> to the text part.
  2. auto-slash-command hook (chat.message, runs immediately after):
     detectSlashCommand() checks `text.trimStart().startsWith("/")`. After
     keyword-detector's prepend, the part now starts with <hyperplan-mode>
     and the slash check fails, so the builtin command template
     (with $ARGUMENTS substituted) is never injected.

The visible symptom: /hyperplan refactor X never runs the actual
HYPERPLAN_TEMPLATE - the user sees only the keyword-detector wrapper, which
is similar but not identical, and the slash command's $ARGUMENTS payload
is silently lost.

Fix: at the top of the keyword-detector hook, after isSystemDirective() but
before any keyword scan, bail out if the prompt text starts with a slash
command (^\s*\/[a-zA-Z][\w-]*\b). Slash commands are explicit invocations
and own their own mode-injection path; the keyword detector must not race
them. Free-form mentions like "hyperplan: refactor X" still trigger
keyword detection - only the leading-slash form is suppressed.

Lock the contract with three regression tests:
  - /hyperplan refactor ... must NOT inject <hyperplan-mode>
  - /hpp investigate ... must NOT inject (shorthand slash command)
  - "hyperplan: refactor src/auth/handler.ts" still injects (free-form)

Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode).
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 5c67482038 feat(keyword-detector): add hyperplan-ultrawork combo + tuple refactor
Adjacent "hpp ulw" or "ulw hpp" (8 form combinations: short/long, both
orders) triggers a fused mode that suppresses the standalone ultrawork
and hyperplan banners and toasts in favor of one combo banner. The
combo banner explicitly preserves hyperplan's mandatory adversarial
workflow contract (do NOT improvise, do NOT skip rounds) instead of
silently downgrading it.

Suppression runs as a named pipeline step (suppressComboStandalones)
immediately after detection and before all consumers (planner filter,
session filters, toasts, message injection), so standalone toast checks
naturally see the already-suppressed list. Combo is allowed in non-main
sessions like ultrawork, filtered for planner agents like both
standalones, and blocked in subagent sessions via the existing gate.

disabled_keywords uses the intersection rule: disabling either
"ultrawork" or "hyperplan" also disables the combo, so no flavored
content leaks via the combo embedding when either base keyword is
disabled.

Includes a same-PR refactor of KEYWORD_DETECTORS from {pattern, message}
to {type, pattern, message} tuple shape, dropping the parallel hardcoded
types array in detector.ts that previously coupled type assignment to
registry index. Future detector additions can no longer silently corrupt
DetectedKeyword.type via reorder or insertion.

10 behavioral contract tests in hyperplan-ultrawork.test.ts cover both
trigger orders, non-adjacent rejection, suppression of injection and
toast, intersection-rule disable behavior, session/agent policy, and
ultrawork variant routing through the combo. The pre-existing combined
"ultrawork hyperplan" assertion in hyperplan.test.ts is removed in
favor of the new file.

Plan distilled from a hyperplan adversarial review (5 members,
3 rounds: skeptic, validator, researcher, architect, creative).
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 09fe4ca3dd fix(hyperplan): align keyword detector and command template with mandatory plan handoff
Update both injection paths to reflect the 7-phase workflow with the
mandatory plan agent handoff in step 7. The keyword detector now lists
all 8 enumerated steps including the explicit "do not write the plan
yourself" guidance, and the /hyperplan command template references the
7-phase workflow count.

Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode).
2026-05-06 14:20:50 +09:00