mixdog 0.9.41 → 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 (48) hide show
  1. package/package.json +1 -1
  2. package/scripts/agent-tag-reuse-smoke.mjs +124 -10
  3. package/scripts/anthropic-oauth-refresh-race-test.mjs +59 -0
  4. package/scripts/arg-guard-test.mjs +16 -0
  5. package/scripts/compact-pressure-test.mjs +256 -1
  6. package/scripts/internal-comms-bench.mjs +0 -1
  7. package/scripts/internal-comms-smoke.mjs +14 -32
  8. package/scripts/internal-tools-normalization-test.mjs +52 -0
  9. package/scripts/max-output-recovery-test.mjs +49 -0
  10. package/scripts/mcp-client-normalization-test.mjs +45 -0
  11. package/scripts/provider-toolcall-test.mjs +23 -0
  12. package/scripts/result-classification-test.mjs +75 -0
  13. package/scripts/smoke.mjs +1 -1
  14. package/scripts/submit-commandbusy-race-test.mjs +99 -7
  15. package/scripts/tui-transcript-perf-test.mjs +56 -1
  16. package/src/agents/reviewer/AGENT.md +4 -0
  17. package/src/runtime/agent/orchestrator/internal-tools.mjs +16 -3
  18. package/src/runtime/agent/orchestrator/mcp/client.mjs +17 -1
  19. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +49 -6
  20. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +14 -0
  21. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +59 -2
  22. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  23. package/src/runtime/agent/orchestrator/session/context-utils.mjs +140 -81
  24. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +23 -5
  25. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +3 -0
  26. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +12 -3
  27. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +4 -2
  28. package/src/runtime/agent/orchestrator/session/result-classification.mjs +4 -1
  29. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +7 -2
  30. package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +8 -6
  31. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +15 -3
  32. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
  33. package/src/runtime/memory/tool-defs.mjs +4 -3
  34. package/src/runtime/shared/tool-surface.mjs +1 -2
  35. package/src/session-runtime/context-status.mjs +8 -2
  36. package/src/standalone/agent-tool/render.mjs +2 -0
  37. package/src/standalone/agent-tool.mjs +202 -22
  38. package/src/tui/components/StatusLine.jsx +4 -26
  39. package/src/tui/dist/index.mjs +46 -31
  40. package/src/tui/engine/session-api.mjs +3 -0
  41. package/src/tui/engine/session-flow.mjs +19 -8
  42. package/src/tui/engine/turn.mjs +24 -2
  43. package/src/tui/engine.mjs +0 -1
  44. package/src/ui/statusline-agents.mjs +0 -8
  45. package/src/ui/statusline.mjs +2 -4
  46. package/src/workflows/default/WORKFLOW.md +29 -20
  47. package/src/workflows/solo-review/WORKFLOW.md +47 -0
  48. package/src/workflows/bench/WORKFLOW.md +0 -60
@@ -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,15 +13,20 @@ 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 orchestrates and verifies. Lead-direct work is allowed only for pure
17
- read/analysis, git/configuration, or when the user explicitly supplies both the
18
- exact target and exact replacement/output. Never infer an exemption from a task
19
- name, file count, or perceived difficulty. Every other implementation, reverse
20
- engineering, debugging application, or artifact generation delegates to the
21
- matching agent. Debugger owns diagnosis and reverse engineering; Worker applies
22
- an established bounded change or fully specified artifact; Heavy Worker owns
23
- implementation that must establish the change through investigation or staged
24
- delivery. Applying a Debugger result is implementation, not diagnosis.
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.
@@ -29,22 +34,26 @@ delivery. Applying a Debugger result is implementation, not diagnosis.
29
34
  one turn, with no count cap. Serialize only a real dependency, overlapping
30
35
  write, or inseparable coupling. Briefs follow the Lead brief contract.
31
36
  After async spawn, end the turn.
32
- 3. Review: review is exempt only for pure read/analysis with no edit, artifact,
33
- or state mutation; git/configuration; or a request where the user explicitly
34
- supplies both the exact target and exact replacement/output. Every
35
- non-exempt mutation or artifact, whether produced or applied by Worker,
36
- Heavy Worker, Debugger, or Lead, gets one Reviewer (all ready reviewers in
37
- one turn) and Lead
38
- integration/cross-scope verification in parallel. Debugger analysis cannot
39
- substitute for implementation review: applying a Debugger result triggers
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
40
50
  the same Reviewer + Lead verification. Reviewer independently judges risk,
41
51
  intent, boundaries; Lead checks acceptance/interactions, not duplicate
42
52
  same-scope work. High-risk scopes add distinct lenses. Synthesize one
43
53
  verdict; send merged fixes to the original live session; loop fix ->
44
54
  re-verify (same Reviewer + Lead re-check) until clean. Debugger first for
45
- requested debugging or a bug surviving 2+ fix cycles. Exempt mutations still
46
- require shell self-verification before report. Agent reports relay scope,
47
- verdict, next work as in-progress, never conclusions.
55
+ requested debugging or a bug surviving 2+ fix cycles. Agent reports relay
56
+ scope, verdict, next work as in-progress, never conclusions.
48
57
  4. Report: final (not interim) report compares work to approved plan and gives
49
58
  verified result; never forward raw agent output. Ask about ship/deploy when
50
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,60 +0,0 @@
1
- ---
2
- id: bench
3
- name: Bench
4
- description: "Autonomous headless benchmark workflow with directed execution and parallel cross-verification."
5
- hidden: true
6
- agents: worker, heavy-worker, reviewer, debugger, maintainer
7
- ---
8
-
9
- # Bench
10
-
11
- Autonomous headless run: no user exists. Never ask questions, propose plans
12
- for approval, or end the turn waiting — decide and proceed. Standing
13
- pre-approval covers every action: edits, state mutation, delegation, builds.
14
- Loop until the task is verified complete or provably blocked.
15
-
16
- The pipeline has exactly three stages. Lead directs and verifies it, but NEVER
17
- executes the work itself: no edits, answers, or artifact generation, regardless
18
- of task size, perceived simplicity, or number of steps.
19
-
20
- ## 1. Lead analysis and direction
21
- Lead performs real analysis first on EVERY task: task structure, required
22
- deliverables, boundaries, the task's own verification means, and solution
23
- direction. Convert it into clear execution direction and delegation briefs
24
- following the Lead brief contract.
25
-
26
- Hand the direction and briefs to executors. Analysis is not permission for
27
- Lead to implement any portion of the result: all edits, answer production, and
28
- artifact generation belong to executor sessions.
29
-
30
- ## 2. Executors perform the work
31
- Use Worker sessions, or Heavy Worker sessions for broad scopes, to execute the
32
- directed work. Multiple workers MAY fan out in parallel, one per independent
33
- scope. Keep ownership clear for each assigned deliverable.
34
-
35
- Executors build the answer or artifact and perform basic does-it-run checks.
36
- They are not a verification role and do not own acceptance, requirements
37
- judgment, or final correctness. Each executor reports its result to Lead.
38
-
39
- ## 3. Lead and Reviewer verify
40
-
41
- When executors report, Lead and Reviewer start cross-verification IN PARALLEL,
42
- never serially. Lead personally runs the task's own verification means, such
43
- as its test suite, grader script, simulator, or self-checkable output.
44
- Reviewer independently judges the result against every task requirement,
45
- including intent, correctness, boundaries, and deliverables.
46
-
47
- Judgment-type answers with no direct ground truth still require parallel
48
- cross-verification, even for a single small deliverable. Lead evaluates against
49
- available criteria while Reviewer independently judges requirements;
50
- perceived simplicity is no exemption.
51
-
52
- Merge any finding into a clear fix delta and return it to the SAME executor
53
- session owning the affected scope. The executor applies it and reports again.
54
- Lead and Reviewer repeat the same parallel cross-verification until both legs
55
- are clean; Lead never fixes or completes the work directly.
56
-
57
- Before declaring completion, Lead personally runs the task-required
58
- verification one final time and checks that every deliverable is present.
59
- Never end with a question, approval request, or proposed next step. Continue
60
- until verified complete or stop only when completion is provably blocked.