mixdog 0.9.40 → 0.9.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/package.json +2 -1
  2. package/scripts/agent-tag-reuse-smoke.mjs +124 -10
  3. package/scripts/anthropic-oauth-refresh-race-test.mjs +397 -0
  4. package/scripts/arg-guard-test.mjs +16 -0
  5. package/scripts/compact-pressure-test.mjs +383 -0
  6. package/scripts/compact-trigger-migration-smoke.mjs +8 -8
  7. package/scripts/internal-comms-bench.mjs +0 -1
  8. package/scripts/internal-comms-smoke.mjs +54 -31
  9. package/scripts/internal-tools-normalization-test.mjs +52 -0
  10. package/scripts/max-output-recovery-persist-test.mjs +81 -0
  11. package/scripts/max-output-recovery-test.mjs +271 -0
  12. package/scripts/mcp-client-normalization-test.mjs +45 -0
  13. package/scripts/provider-toolcall-test.mjs +55 -0
  14. package/scripts/result-classification-test.mjs +75 -0
  15. package/scripts/smoke.mjs +1 -1
  16. package/scripts/submit-commandbusy-race-test.mjs +99 -7
  17. package/scripts/tui-transcript-perf-test.mjs +56 -1
  18. package/src/agents/reviewer/AGENT.md +8 -0
  19. package/src/rules/lead/lead-brief.md +11 -3
  20. package/src/rules/lead/lead-tool.md +0 -2
  21. package/src/rules/shared/01-tool.md +4 -0
  22. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +20 -2
  23. package/src/runtime/agent/orchestrator/context/collect.mjs +7 -3
  24. package/src/runtime/agent/orchestrator/internal-tools.mjs +16 -3
  25. package/src/runtime/agent/orchestrator/mcp/client.mjs +17 -1
  26. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +193 -13
  27. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -2
  28. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +14 -0
  29. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +2 -2
  30. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +59 -2
  31. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +57 -25
  32. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +72 -12
  33. package/src/runtime/agent/orchestrator/session/context-utils.mjs +144 -84
  34. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +124 -8
  35. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +12 -1
  36. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +25 -7
  37. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +12 -3
  38. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +28 -1
  39. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +2 -1
  40. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +31 -4
  41. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +11 -2
  42. package/src/runtime/agent/orchestrator/session/result-classification.mjs +4 -1
  43. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +45 -0
  44. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +7 -2
  45. package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +8 -6
  46. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +15 -3
  47. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -21
  48. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +1 -1
  49. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
  50. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -10
  51. package/src/runtime/memory/tool-defs.mjs +4 -3
  52. package/src/runtime/shared/tool-surface.mjs +1 -2
  53. package/src/session-runtime/context-status.mjs +8 -2
  54. package/src/standalone/agent-tool/render.mjs +2 -0
  55. package/src/standalone/agent-tool.mjs +202 -22
  56. package/src/tui/components/StatusLine.jsx +4 -26
  57. package/src/tui/dist/index.mjs +46 -31
  58. package/src/tui/engine/session-api.mjs +3 -0
  59. package/src/tui/engine/session-flow.mjs +19 -8
  60. package/src/tui/engine/turn.mjs +24 -2
  61. package/src/tui/engine.mjs +0 -1
  62. package/src/ui/statusline-agents.mjs +0 -8
  63. package/src/ui/statusline.mjs +2 -4
  64. package/src/workflows/default/WORKFLOW.md +38 -24
  65. package/src/workflows/solo-review/WORKFLOW.md +47 -0
  66. package/src/workflows/bench/WORKFLOW.md +0 -36
@@ -2,13 +2,14 @@
2
2
  * src/tui/engine/session-flow.mjs - prompt queue drain + session clear/reset. Extracted from engine.mjs.
3
3
  */
4
4
  import { presentErrorText } from '../../runtime/shared/err-text.mjs';
5
+ import { resetAllStreamingMarkdownStablePrefixes } from '../markdown/streaming-markdown.mjs';
5
6
  import { createSessionStats } from './session-stats.mjs';
6
7
  import { queuePriorityValue, defaultQueuePriority, isQueuedEntryEditable, isQueuedEntryVisible, isSlashQueuedEntry, notificationDisplayText, sessionActivityTimestamp, promptDisplayText, mergePromptContents, mergePastedImages, mergePastedTexts, callCommitCallbacks, STEERING_SUPPRESSED_DISPLAY } from './queue-helpers.mjs';
7
8
  import { appendTuiSteeringPersist, dropTuiSteeringPersist, drainTuiSteeringPersist } from './tui-steering-persist.mjs';
8
9
 
9
10
  export function createSessionFlow(bag) {
10
11
  const {
11
- runtime, nextId, tuiDebug, flags, pending, pendingNotificationKeys, displayedExecutionNotificationKeys, clearExecutionDedupState, getState, set, pushItem, replaceItems, pushNotice, pushUserOrSyntheticItem, autoClearState, agentStatusState, routeState, syncContextStats, flushDeferredExecutionPendingResumeKick,
12
+ runtime, nextId, tuiDebug, flags, pending, pendingNotificationKeys, displayedExecutionNotificationKeys, clearExecutionDedupState, clearToastTimers, getState, set, pushItem, replaceItems, pushNotice, pushUserOrSyntheticItem, autoClearState, agentStatusState, routeState, syncContextStats, flushDeferredExecutionPendingResumeKick,
12
13
  } = bag;
13
14
 
14
15
  // Upper bound on the awaited compacting clear. requireCompactSuccess makes
@@ -382,7 +383,10 @@ export function createSessionFlow(bag) {
382
383
  // Shared clear body for idle auto-clear and the session_manage tool.
383
384
  // useCompaction=true mirrors auto-clear (summarize via configured
384
385
  // compactType, context carries forward); false is a plain /clear wipe.
385
- async function performSessionClear({ verb, doneLabel, skipLabel, surface, useCompaction }) {
386
+ async function performSessionClear({
387
+ verb, doneLabel, skipLabel, surface, useCompaction,
388
+ compactTimeoutMs = AUTO_CLEAR_COMPACT_TIMEOUT_MS,
389
+ }) {
386
390
  flags.autoClearRunning = true;
387
391
  const startedAt = Date.now();
388
392
  // commandBusy blocks concurrent session commands (resume/newSession/
@@ -401,6 +405,7 @@ export function createSessionFlow(bag) {
401
405
  const compaction = runtime.getCompactionSettings();
402
406
  compactType = compaction.compactType || compaction.type || null;
403
407
  }
408
+ let clearResult;
404
409
  if (compactType) {
405
410
  // Bounded watchdog around the compacting clear. On timeout we throw so
406
411
  // the catch below keeps the conversation, surfaces a user-visible
@@ -410,21 +415,22 @@ export function createSessionFlow(bag) {
410
415
  // new auto-clear attempts until the abandoned promise settles, and on
411
416
  // late fulfillment we run the same post-success UI sync as the normal
412
417
  // path so the UI cannot diverge from a runtime session that actually
413
- // got cleared. Late rejection is a no-op.
418
+ // got cleared. Late rejection or a false result is a no-op.
414
419
  const clearPromise = runtime.clear({ compactType, requireCompactSuccess: true });
415
420
  let timer = null;
416
421
  const timeout = new Promise((_, reject) => {
417
422
  timer = setTimeout(
418
- () => reject(new Error(`compaction timed out after ${AUTO_CLEAR_COMPACT_TIMEOUT_MS}ms; auto-clear deferred to next idle`)),
419
- AUTO_CLEAR_COMPACT_TIMEOUT_MS,
423
+ () => reject(new Error(`compaction timed out after ${compactTimeoutMs}ms; auto-clear deferred to next idle`)),
424
+ compactTimeoutMs,
420
425
  );
421
426
  });
422
427
  try {
423
- await Promise.race([clearPromise, timeout]);
428
+ clearResult = await Promise.race([clearPromise, timeout]);
424
429
  } catch (raceError) {
425
430
  flags.autoClearInFlight = true;
426
431
  clearPromise.then(
427
- () => {
432
+ (lateResult) => {
433
+ if (lateResult === false) return;
428
434
  if (getState().busy) {
429
435
  // A turn started after commandBusy released; applying the
430
436
  // cleared-session UI now would wipe items/queued and force
@@ -446,7 +452,10 @@ export function createSessionFlow(bag) {
446
452
  if (timer) clearTimeout(timer);
447
453
  }
448
454
  } else {
449
- await runtime.clear({});
455
+ clearResult = await runtime.clear({});
456
+ }
457
+ if (clearResult === false) {
458
+ throw new Error('runtime clear returned false');
450
459
  }
451
460
  applyClearedSessionUi(doneLabel);
452
461
  return true;
@@ -490,6 +499,8 @@ export function createSessionFlow(bag) {
490
499
  return getState().stats;
491
500
  };
492
501
  const clearUiActivityBeforeContextSync = () => {
502
+ clearToastTimers();
503
+ resetAllStreamingMarkdownStablePrefixes();
493
504
  getState().items = replaceItems([]);
494
505
  getState().toasts = [];
495
506
  getState().queued = [];
@@ -12,7 +12,7 @@ import { aggregateRawResult, aggregateBucketForCategory, aggregateSummaries, ass
12
12
 
13
13
  export function createRunTurn(bag) {
14
14
  const {
15
- runtime, nextId, tuiDebug, LEAD_TURN_TIMEOUT_MS, flags, pending, itemIndexById, getState, set, pushItem, patchItem, updateStreamingTail: updateStreamingTailFromStore, settleStreamingTail: settleStreamingTailFromStore, clearStreamingTail: clearStreamingTailFromStore, pushNotice, pushUserOrSyntheticItem, markToolCallActive, markToolCallDone, clearActiveToolSummary, agentStatusState, routeState, syncContextStats, denyAllToolApprovals, requestToolApproval, patchToolCardResult, flushToolResults, flushDeferredExecutionPendingResumeKick, drain, drainPendingSteering,
15
+ runtime, nextId, tuiDebug, LEAD_TURN_TIMEOUT_MS, flags, pending, itemIndexById, getState, set, pushItem, patchItem, replaceItems, updateStreamingTail: updateStreamingTailFromStore, settleStreamingTail: settleStreamingTailFromStore, clearStreamingTail: clearStreamingTailFromStore, pushNotice, pushUserOrSyntheticItem, markToolCallActive, markToolCallDone, clearActiveToolSummary, agentStatusState, routeState, syncContextStats, denyAllToolApprovals, requestToolApproval, patchToolCardResult, flushToolResults, flushDeferredExecutionPendingResumeKick, drain, drainPendingSteering,
16
16
  } = bag;
17
17
  // Small fallbacks keep isolated createRunTurn harnesses source-compatible;
18
18
  // the real engine supplies atomic implementations that also maintain revision.
@@ -209,7 +209,14 @@ export function createRunTurn(bag) {
209
209
  let cancelled = false;
210
210
  let askResult = null;
211
211
  let turnFinishedNormally = false;
212
+ let transcriptCompactedThisTurn = false;
212
213
  const itemsAtTurnStart = getState().items.length;
214
+ const submittedIdSet = new Set(submittedIds.filter((id) => id != null));
215
+ const firstSubmittedIndex = getState().items.findIndex((item) => submittedIdSet.has(item?.id));
216
+ // The submitted user row is pushed immediately before runTurn. Keep it and
217
+ // everything produced after it if compaction succeeds mid-turn; dropping all
218
+ // items would invalidate live tool-card ids and the streaming assistant tail.
219
+ let currentTurnItemsStart = firstSubmittedIndex >= 0 ? firstSubmittedIndex : itemsAtTurnStart;
213
220
  const cardByCallId = new Map();
214
221
  const toolCards = [];
215
222
  const toolGroups = new Map();
@@ -987,6 +994,13 @@ export function createRunTurn(bag) {
987
994
  // later same-category tool call doesn't reuse a card whose count
988
995
  // would then change above this statusdone item.
989
996
  clearAggregateContinuation();
997
+ const compactStatus = String(event?.status || '').toLowerCase();
998
+ if (!['failed', 'skipped', 'no_change'].includes(compactStatus)) {
999
+ const currentTurnItems = getState().items.slice(currentTurnItemsStart);
1000
+ set({ items: replaceItems(currentTurnItems, { preserveStreamingTail: true }) });
1001
+ currentTurnItemsStart = 0;
1002
+ transcriptCompactedThisTurn = true;
1003
+ }
990
1004
  pushItem({
991
1005
  kind: 'statusdone',
992
1006
  id: nextId(),
@@ -1103,6 +1117,13 @@ export function createRunTurn(bag) {
1103
1117
  } else {
1104
1118
  askResult = result;
1105
1119
  markPromptCommitted();
1120
+ if (result?.terminationReason === 'refusal') {
1121
+ pushNotice(
1122
+ '모델이 안전 분류기(refusal)로 응답을 거부했습니다 — 다시 시도하거나 문구를 바꿔주세요.',
1123
+ 'warn',
1124
+ { transcript: true },
1125
+ );
1126
+ }
1106
1127
 
1107
1128
  flushToolResults(session?.messages || [], toolCards, cardByCallId, toolGroups, resultsDone, { finalize: true });
1108
1129
  finalizeToolHeaders();
@@ -1208,7 +1229,8 @@ export function createRunTurn(bag) {
1208
1229
  }
1209
1230
  }
1210
1231
  const producedTranscriptItem =
1211
- getState().items.length + closingItems.length > itemsAtTurnStart;
1232
+ transcriptCompactedThisTurn
1233
+ || getState().items.length + closingItems.length > itemsAtTurnStart;
1212
1234
  const reclaimed = cancelled && flags.activePromptRestore?.reclaimed === true;
1213
1235
  flags.activePromptRestore = null;
1214
1236
  const elapsedMs = Date.now() - startedAt;
@@ -738,7 +738,6 @@ export async function createEngineSession({
738
738
  autoClearState, agentStatusState, baseRouteState, routeState, syncContextStats,
739
739
  presentNextToolApproval, finishToolApproval, denyAllToolApprovals, requestToolApproval,
740
740
  patchToolCardResult, flushToolResults,
741
- clearExecutionDedupState,
742
741
  kickExecutionPendingResume, flushDeferredExecutionPendingResumeKick, scheduleExecutionPendingResumeKick, discardExecutionPendingResume, updateAgentJobCard, subscribeRuntimeNotifications,
743
742
  });
744
743
  Object.assign(bag, createSessionFlow(bag));
@@ -14,14 +14,6 @@ import { num, GRN, R, B } from './statusline-format.mjs';
14
14
  const DEFAULT_HIDDEN_STATUSLINE_AGENTS = Object.freeze(['explorer', 'cycle1-agent', 'cycle2-agent', 'cycle3-agent', 'scheduler-task', 'webhook-handler']);
15
15
  let _hiddenStatuslineAgents = null;
16
16
 
17
- export function summarizeWorkerTags(workers, limit = 3) {
18
- const cleanLabels = [...new Set((Array.isArray(workers) ? workers : [])
19
- .map((worker) => String(worker?.tag || '').trim())
20
- .filter(Boolean))];
21
- if (cleanLabels.length <= limit) return cleanLabels.join(', ');
22
- return `${cleanLabels.slice(0, limit).join(', ')}, +${cleanLabels.length - limit}`;
23
- }
24
-
25
17
  function normalizeAgentWorkerForStatusline(worker = {}) {
26
18
  const tag = String(worker.tag || worker.agent || worker.name || '').trim();
27
19
  if (!tag) return null;
@@ -23,7 +23,7 @@ import {
23
23
  } from './statusline-format.mjs';
24
24
  import { shellJobsStatus, memoryCycleStatus } from './statusline-segments.mjs';
25
25
  import {
26
- summarizeWorkerTags, agentStatuslinePayload, classifyAgentWorkers, activeHiddenAgentWorkers, agentWebSearchStatus,
26
+ agentStatuslinePayload, classifyAgentWorkers, activeHiddenAgentWorkers, agentWebSearchStatus,
27
27
  } from './statusline-agents.mjs';
28
28
  export { createSessionStats, applyUsageDelta } from './session-stats.mjs';
29
29
  // Facade re-exports: keep these public symbols resolving from statusline.mjs.
@@ -362,14 +362,12 @@ function renderNativeStatusline({
362
362
  if (runningWorkers.length) {
363
363
  const n = runningWorkers.length;
364
364
  const label = `Running ${n} Agent${n === 1 ? '' : 's'}`;
365
- const tagSummary = summarizeWorkerTags(runningWorkers);
366
- const tags = tagSummary ? ` ${D}(${R}${B}${tagSummary}${R}${D})${R}` : '';
367
365
  const oldestStart = runningWorkers.reduce((min, w) => {
368
366
  const t = num(w?.startedAtMs);
369
367
  return t > 0 && t < min ? t : min;
370
368
  }, Infinity);
371
369
  const elapsed = Number.isFinite(oldestStart) ? formatElapsed(Date.now() - oldestStart) : '';
372
- addL2(`${spin} ${B}${label}${R}${tags}${elapsedSuffix(elapsed)}`);
370
+ addL2(`${spin} ${B}${label}${R}${elapsedSuffix(elapsed)}`);
373
371
  }
374
372
  const tools = activeTools && typeof activeTools === 'object' ? activeTools : {};
375
373
  const exploreInfo = tools.explore || null;
@@ -13,33 +13,47 @@ Approval is a later explicit user message after the latest plan ("do it",
13
13
  approval with a scope change needs a revised plan and fresh approval. Before
14
14
  approval: no edits, state mutation, or delegation.
15
15
 
16
- Lead supervises, delegates, coordinates, judges, decides. After approval,
17
- delegate by default; Lead only coordinates, does git, or an obvious 1-edit/
18
- 1-check change. Route other implementation/research/debugging to its matching
19
- agent. Worker: bounded established path, low local risk/coupling/verification,
20
- clear local check. Heavy Worker: high risk/coupling/verification (including any
21
- high-risk scope), or coupled staged work needing coordinated verification.
22
- Architecture, contracts, storage, concurrency, security, lifecycle are
23
- indicators, not automatic categories. Reviewer verifies an implementation;
24
- Debugger handles requested debugging or root cause after a failed fix.
16
+ Lead owns three duties, in order: plan — set the direction of the work from its own
17
+ understanding of the task; delegate hand execution to the matching agent; verify —
18
+ judge what comes back. Understanding is never delegated: without its own plan a Lead
19
+ can neither brief nor judge. Lead-direct work is allowed only for pure read/analysis,
20
+ git/configuration, or when the user explicitly supplies both the exact target and exact
21
+ replacement/output. Never infer an exemption from a task name, file count, or
22
+ perceived difficulty. Every other implementation, reverse engineering, debugging
23
+ application, or artifact generation delegates to the matching agent. Debugger is an
24
+ escalation role reserved for explicitly requested debugging or a bug surviving 2+ fix
25
+ cycles — not a default owner of analysis or reverse engineering, which route to
26
+ Worker/Heavy Worker like any implementation. Worker applies an established bounded
27
+ change or fully specified artifact; Heavy Worker owns implementation that must establish
28
+ the change through investigation or staged delivery. Applying a Debugger result is
29
+ implementation, not diagnosis.
25
30
 
26
31
  1. Plan: draft before any implementation; settle scope/plan, ask if ambiguous,
27
32
  then await the gate.
28
- 2. Delegate: maximize useful fan-out—one suitable Worker/Heavy Worker per ready
29
- independent scope whose parallel gain exceeds coordination/merge cost; spawn
30
- all in one turn, with no count cap. Serialize only a real dependency,
31
- overlapping write, or inseparable coupling. Briefs follow the Lead brief
32
- contract. After async spawn, end the turn.
33
- 3. Review: after approval, complete delegation, review, self-verification, and
34
- in-scope fixes without reapproval. Every delegated implementation gets one
35
- Reviewer (all ready reviewers in one turn) and Lead integration/cross-scope
36
- verification in parallel. Reviewer independently judges risk, intent,
37
- boundaries; Lead checks acceptance/interactions, not duplicate same-scope
38
- work. High-risk scopes add distinct lenses. Synthesize one verdict; send
39
- merged fixes to the original live session; loop fix -> re-verify (same
40
- Reviewer + Lead re-check) until clean. Debugger first for requested debugging
41
- or a bug surviving 2+ fix cycles. Agent reports relay scope, verdict, next
42
- work as in-progress, never conclusions.
33
+ 2. Delegate: one agent per ready independent scope; spawn all ready scopes in
34
+ one turn, with no count cap. Serialize only a real dependency, overlapping
35
+ write, or inseparable coupling. Briefs follow the Lead brief contract.
36
+ After async spawn, end the turn.
37
+ 3. Review: triage by the work performed, never by the size, form, or destination
38
+ of its result a one-line answer can carry non-trivial work, and a
39
+ conversational reply is not automatically exempt. Trivial work a routine
40
+ lookup answered directly, routine git/configuration confirmed by its own
41
+ mechanical check, a change whose correctness is test/build/diff-obvious, or
42
+ applying an exact target and replacement the user supplied — ships on shell
43
+ self-verification alone, and only after that check actually ran and passed.
44
+ Non-trivial work multi-step reasoning, interpretation, investigation, or
45
+ anything whose correctness is not verifiable at a glance gets a Reviewer
46
+ cross-check (one reviewer per scope, kept across the fix loop; all ready
47
+ reviewers spawn in one turn) and Lead integration/cross-scope verification
48
+ in parallel, whoever performed it, Lead solo included. Debugger analysis
49
+ cannot substitute for implementation review: applying a Debugger result triggers
50
+ the same Reviewer + Lead verification. Reviewer independently judges risk,
51
+ intent, boundaries; Lead checks acceptance/interactions, not duplicate
52
+ same-scope work. High-risk scopes add distinct lenses. Synthesize one
53
+ verdict; send merged fixes to the original live session; loop fix ->
54
+ re-verify (same Reviewer + Lead re-check) until clean. Debugger first for
55
+ requested debugging or a bug surviving 2+ fix cycles. Agent reports relay
56
+ scope, verdict, next work as in-progress, never conclusions.
43
57
  4. Report: final (not interim) report compares work to approved plan and gives
44
58
  verified result; never forward raw agent output. Ask about ship/deploy when
45
59
  relevant. Build/deploy/commit/push require an explicit user request after
@@ -0,0 +1,47 @@
1
+ ---
2
+ id: solo-review
3
+ name: Solo Review
4
+ description: "Lead implements directly; eligible low-risk single scopes receive one independent Reviewer."
5
+ agents: reviewer
6
+ ---
7
+
8
+ # Solo Review
9
+
10
+ GATE: Before approval, only read-only investigation/planning while consulting.
11
+ Approval is a later explicit user message after the latest plan ("do it",
12
+ "proceed", "go ahead"). Initial/additional/changed requests reset planning;
13
+ approval with a scope change needs a revised plan and fresh approval. Before
14
+ approval: no edits, state mutation, or delegation.
15
+
16
+ 1. Plan: before implementation, Lead classifies the scope as eligible
17
+ low-risk/single-scope or ineligible high-risk/multi-scope, drafts the plan,
18
+ settles scope, asks if ambiguous, then awaits the gate. Ineligible work must
19
+ switch to Default workflow with a revised Default plan and fresh approval
20
+ before implementation. After that switch, Solo Review constraints are
21
+ suspended: Default reviewer-per-scope fan-out and high-risk lenses override
22
+ Solo Review's single-Reviewer and concurrency limits.
23
+ 2. Execute: after approval, Lead performs all implementation and verification
24
+ directly. Never delegate implementation, investigation, debugging, or
25
+ maintenance to implementation helper roles (Worker, Heavy Worker, Explorer,
26
+ Debugger, or Maintainer). Complete in-scope fixes without reapproval; interim
27
+ updates are in-progress, never conclusions.
28
+ 3. Review: only an eligible low-risk, single-scope final deliverable, once
29
+ implemented and Lead-verified, receives exactly one Reviewer to critically
30
+ and independently evaluate the approved intent, complete deliverable,
31
+ affected boundaries, and verification. Lead evaluates the findings, applies
32
+ every necessary fix directly, and re-verifies. Send the revised deliverable
33
+ back to that same live Reviewer for every re-check. If that session is
34
+ unavailable, one cold replacement Reviewer may re-review the original intent,
35
+ current deliverable, and verification evidence; never run replacement or
36
+ additional Reviewers concurrently. Repeat fix -> Lead verification -> Reviewer
37
+ re-check until issue-free or blocked.
38
+ 4. Report: only after the review loop is clean, the final (not interim) report
39
+ compares the result to the approved plan and gives verification and material
40
+ remaining risk/next step; never forward raw Reviewer output. Ask about
41
+ ship/deploy when relevant. Verification builds/tests needed to evaluate the
42
+ deliverable are permitted during execution and review. Release builds,
43
+ deploy/commit/push require an explicit user request after issue-free feedback;
44
+ implementation approval alone is insufficient.
45
+
46
+ On outcome/direction change, pause and re-consult; otherwise continue approved
47
+ work without reapproval.
@@ -1,36 +0,0 @@
1
- ---
2
- id: bench
3
- name: Bench
4
- description: "Autonomous benchmark workflow — loop to completion without user approval."
5
- hidden: true
6
- agents: worker, heavy-worker, reviewer, debugger, maintainer
7
- ---
8
-
9
- # Bench
10
-
11
- Autonomous: no user. Never wait for approval or ask questions; decide/proceed.
12
- Loop until verified complete or provably blocked.
13
-
14
- Lead supervises, delegates, coordinates, judges, decides. Lead directly handles
15
- simple 1–2-step work, coordination, pre-planning, config, final git deployment.
16
- Worker: several-step implementation; Heavy Worker: high-complexity multi-step
17
- implementation; Reviewer: implementation diff/regression/missing-check review;
18
- Debugger: very high complexity or root cause already failed once.
19
-
20
- 1. Plan: form it and execute immediately; no approval step.
21
- 2. Delegate: split to the maximum independent scopes. Parallelize independent
22
- implementation/analysis/review/debugging, spawning every scope in one turn.
23
- Shared/cross-cutting code does not justify merging: split by path and verify
24
- shared parts yourself. A single scope needs a genuinely inseparable
25
- dependency; state it. Within one complex scope, sequence steps with a
26
- build/test-green gate between them. Briefs follow the Lead brief contract.
27
- After async spawn, end turn: no polling, guessing, or dependent work until
28
- completion notification.
29
- 3. Review: one Reviewer per implementation scope, spawned 1:1 in the same turn,
30
- never deferred/batched; wait. Fact-check agent responses and cross-check
31
- implementation/review yourself before acting. Return fixes to the original
32
- scope; loop verify -> fix -> re-verify until clean. Skip only simple,
33
- low-risk review. If a bug survives 2+ fix cycles, Debugger investigates
34
- before another fix round.
35
- 4. Finish: verify final state yourself; stop only verified complete or hard
36
- blocked. Final states outcome and evidence.