mixdog 0.9.45 → 0.9.47

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 (123) hide show
  1. package/package.json +5 -2
  2. package/scripts/agent-dispatch-abort-compose-test.mjs +31 -0
  3. package/scripts/agent-model-liveness-test.mjs +618 -0
  4. package/scripts/agent-trace-io-test.mjs +68 -4
  5. package/scripts/bench-run.mjs +30 -3
  6. package/scripts/compact-pressure-test.mjs +187 -4
  7. package/scripts/compact-prior-context-flatten-test.mjs +252 -0
  8. package/scripts/compact-trigger-migration-smoke.mjs +8 -6
  9. package/scripts/compacted-placeholder-scrub-test.mjs +20 -34
  10. package/scripts/context-mcp-metering-test.mjs +75 -0
  11. package/scripts/explore-prompt-policy-test.mjs +15 -16
  12. package/scripts/explore-timeout-cancel-test.mjs +345 -0
  13. package/scripts/headless-pristine-execution-test.mjs +614 -0
  14. package/scripts/internal-comms-smoke.mjs +15 -6
  15. package/scripts/live-worker-smoke.mjs +1 -1
  16. package/scripts/memory-core-input-test.mjs +137 -0
  17. package/scripts/memory-rule-contract-test.mjs +5 -5
  18. package/scripts/openai-oauth-refresh-race-test.mjs +120 -0
  19. package/scripts/openai-oauth-ws-1006-retry-test.mjs +26 -0
  20. package/scripts/parent-abort-link-test.mjs +22 -0
  21. package/scripts/provider-toolcall-test.mjs +22 -0
  22. package/scripts/reactive-compact-persist-smoke.mjs +8 -4
  23. package/scripts/session-bench.mjs +3 -70
  24. package/scripts/task-bench.mjs +0 -2
  25. package/scripts/terminal-bench-isolation-guards-test.mjs +102 -0
  26. package/scripts/tool-smoke.mjs +21 -21
  27. package/scripts/tool-tui-presentation-test.mjs +68 -0
  28. package/scripts/tui-transcript-jitter-harness-entry.jsx +91 -10
  29. package/src/app.mjs +28 -103
  30. package/src/cli.mjs +17 -13
  31. package/src/defaults/cycle3-review-prompt.md +10 -4
  32. package/src/defaults/memory-promote-prompt.md +4 -3
  33. package/src/headless-command.mjs +139 -0
  34. package/src/headless-role.mjs +121 -10
  35. package/src/help.mjs +4 -1
  36. package/src/rules/agent/00-common.md +3 -3
  37. package/src/rules/agent/00-core.md +8 -9
  38. package/src/rules/agent/20-skip-protocol.md +2 -3
  39. package/src/rules/agent/30-explorer.md +50 -56
  40. package/src/rules/agent/40-cycle1-agent.md +10 -12
  41. package/src/rules/agent/41-cycle2-agent.md +12 -9
  42. package/src/rules/agent/42-cycle3-agent.md +4 -6
  43. package/src/rules/lead/01-general.md +5 -6
  44. package/src/rules/lead/02-channels.md +1 -1
  45. package/src/rules/lead/lead-brief.md +14 -17
  46. package/src/rules/lead/lead-tool.md +3 -3
  47. package/src/rules/shared/01-tool.md +41 -43
  48. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +46 -10
  49. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +44 -31
  50. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +18 -3
  51. package/src/runtime/agent/orchestrator/config.mjs +96 -30
  52. package/src/runtime/agent/orchestrator/context/collect.mjs +9 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +18 -5
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +6 -6
  56. package/src/runtime/agent/orchestrator/providers/gemini.mjs +6 -6
  57. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +123 -3
  58. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -3
  59. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +148 -30
  60. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +5 -7
  61. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +62 -14
  62. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +141 -19
  63. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -4
  64. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +19 -1
  65. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +85 -17
  66. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -8
  67. package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -17
  68. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +159 -20
  69. package/src/runtime/agent/orchestrator/session/context-utils.mjs +83 -10
  70. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +75 -7
  71. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +4 -374
  72. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +0 -75
  73. package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +0 -5
  74. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +20 -3
  75. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +32 -16
  76. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +5 -2
  77. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +86 -15
  78. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +30 -27
  79. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +1 -14
  80. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +21 -27
  81. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +1 -3
  82. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -51
  83. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +4 -4
  84. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +26 -0
  86. package/src/runtime/memory/index.mjs +0 -1
  87. package/src/runtime/memory/lib/core-memory-store.mjs +44 -24
  88. package/src/runtime/memory/lib/http-router.mjs +0 -193
  89. package/src/runtime/memory/lib/memory-action-handlers.mjs +37 -11
  90. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +13 -5
  91. package/src/runtime/memory/lib/memory-cycle2.mjs +8 -5
  92. package/src/runtime/memory/lib/memory-cycle3.mjs +41 -6
  93. package/src/runtime/memory/lib/query-handlers.mjs +49 -6
  94. package/src/runtime/memory/lib/recall-format.mjs +21 -6
  95. package/src/runtime/memory/tool-defs.mjs +5 -6
  96. package/src/runtime/shared/config.mjs +11 -34
  97. package/src/runtime/shared/pristine-execution-contract.json +75 -0
  98. package/src/runtime/shared/pristine-execution.mjs +356 -0
  99. package/src/runtime/shared/provider-api-key.mjs +43 -0
  100. package/src/runtime/shared/provider-auth-binding.mjs +21 -0
  101. package/src/session-runtime/context-status.mjs +61 -13
  102. package/src/session-runtime/mcp-glue.mjs +29 -2
  103. package/src/session-runtime/plugin-mcp.mjs +7 -0
  104. package/src/session-runtime/resource-api.mjs +38 -5
  105. package/src/session-runtime/runtime-core.mjs +5 -1
  106. package/src/session-runtime/session-turn-api.mjs +14 -2
  107. package/src/session-runtime/settings-api.mjs +5 -0
  108. package/src/session-runtime/tool-catalog.mjs +13 -2
  109. package/src/session-runtime/tool-defs.mjs +1 -3
  110. package/src/standalone/agent-task-status.mjs +50 -11
  111. package/src/standalone/agent-tool/tool-def.mjs +1 -1
  112. package/src/standalone/explore-tool.mjs +257 -49
  113. package/src/standalone/seeds.mjs +1 -0
  114. package/src/tui/App.jsx +23 -10
  115. package/src/tui/app/use-transcript-scroll.mjs +4 -3
  116. package/src/tui/app/use-transcript-window.mjs +12 -21
  117. package/src/tui/components/ContextPanel.jsx +19 -25
  118. package/src/tui/dist/index.mjs +77 -65
  119. package/src/tui/engine/agent-envelope.mjs +16 -5
  120. package/src/tui/engine/labels.mjs +1 -1
  121. package/src/workflows/default/WORKFLOW.md +21 -51
  122. package/src/workflows/solo/WORKFLOW.md +12 -17
  123. package/src/workflows/solo-review/WORKFLOW.md +0 -47
@@ -0,0 +1,139 @@
1
+ const VALUE_OPTIONS = new Set(['--provider', '--model', '--effort', '--workflow']);
2
+ const FLAG_OPTIONS = new Set([
3
+ '--readonly', '--help', '-h', '--plain', '--react', '--remote', '--onboarding', '--fast',
4
+ ]);
5
+ const HEADLESS_ROLE_ALIASES = new Map([
6
+ ['explorer', 'explore'], ['explore', 'explore'],
7
+ ['maint', 'maintainer'], ['maintenance', 'maintainer'], ['maintainer', 'maintainer'],
8
+ ['worker', 'worker'],
9
+ ['heavy', 'heavy-worker'], ['heavyworker', 'heavy-worker'], ['heavy-worker', 'heavy-worker'],
10
+ ['review', 'reviewer'], ['reviewer', 'reviewer'],
11
+ ['debug', 'debugger'], ['debugger', 'debugger'],
12
+ ['web', 'web-researcher'], ['web-researcher', 'web-researcher'],
13
+ ]);
14
+ const HEADLESS_WORKFLOW_ERROR = 'option --workflow is not supported for headless role commands';
15
+
16
+ function roleKey(value) {
17
+ return String(value || '').trim().toLowerCase().replace(/[\s_]+/g, '-');
18
+ }
19
+
20
+ function argvIndicatesHeadlessRole(argv) {
21
+ for (let index = 0; index < argv.length; index += 1) {
22
+ const arg = String(argv[index] ?? '');
23
+ if (VALUE_OPTIONS.has(arg)) {
24
+ const value = argv[index + 1];
25
+ if (value !== undefined && value !== '' && !String(value).startsWith('-')) {
26
+ if (HEADLESS_ROLE_ALIASES.has(roleKey(value))) return true;
27
+ index += 1;
28
+ }
29
+ continue;
30
+ }
31
+ if (FLAG_OPTIONS.has(arg) || arg.startsWith('-')) continue;
32
+ return HEADLESS_ROLE_ALIASES.has(roleKey(arg));
33
+ }
34
+ return false;
35
+ }
36
+
37
+ function parseTokens(argv, { strictValues = true } = {}) {
38
+ const positional = [];
39
+ const values = {};
40
+ const allowHeadlessIntent = strictValues && !argv.includes('--react');
41
+ for (let index = 0; index < argv.length; index += 1) {
42
+ const arg = String(argv[index] ?? '');
43
+ if (VALUE_OPTIONS.has(arg)) {
44
+ const value = argv[index + 1];
45
+ if (value === undefined || value === '' || String(value).startsWith('-')) {
46
+ if (strictValues) {
47
+ return {
48
+ error: `option ${arg} requires a non-option value`,
49
+ skipHostPrelude: arg === '--provider' || arg === '--model',
50
+ };
51
+ }
52
+ continue;
53
+ }
54
+ const valueKey = roleKey(value);
55
+ if (allowHeadlessIntent && arg === '--workflow' && HEADLESS_ROLE_ALIASES.has(valueKey)) {
56
+ return {
57
+ error: HEADLESS_WORKFLOW_ERROR,
58
+ skipHostPrelude: true,
59
+ };
60
+ }
61
+ if (allowHeadlessIntent
62
+ && (arg === '--provider' || arg === '--model' || arg === '--effort')
63
+ && HEADLESS_ROLE_ALIASES.has(valueKey)) {
64
+ return {
65
+ error: `option ${arg} requires a route value before headless role ${JSON.stringify(String(value))}`,
66
+ skipHostPrelude: true,
67
+ };
68
+ }
69
+ if (!(arg in values)) values[arg] = String(value);
70
+ index += 1;
71
+ continue;
72
+ }
73
+ if (FLAG_OPTIONS.has(arg)) continue;
74
+ if (arg.startsWith('-')) {
75
+ return {
76
+ error: `unknown option ${arg}`,
77
+ ...(allowHeadlessIntent
78
+ && argvIndicatesHeadlessRole(argv)
79
+ ? { skipHostPrelude: true }
80
+ : {}),
81
+ };
82
+ }
83
+ positional.push(arg);
84
+ }
85
+ return { positional, values };
86
+ }
87
+
88
+ function headlessFromPositional(positional) {
89
+ if (!positional.length) return null;
90
+ if (String(positional[0]).toLowerCase() === 'role') {
91
+ return { error: 'usage: mixdog <role> <message...>' };
92
+ }
93
+ const key = roleKey(positional[0]);
94
+ const agent = HEADLESS_ROLE_ALIASES.get(key) || null;
95
+ if (!agent) return null;
96
+ const message = positional.slice(1).join(' ').trim();
97
+ if (!message) return { error: `usage: mixdog ${positional[0]} <message...>` };
98
+ return { agent, message };
99
+ }
100
+
101
+ export function classifyCliInvocation(argv = []) {
102
+ const hasHelp = argv.includes('--help') || argv.includes('-h');
103
+ const hasPlain = argv.includes('--plain');
104
+ const parsed = parseTokens(argv, { strictValues: !hasHelp && !hasPlain });
105
+ if (parsed.error) return { kind: 'error', ...parsed };
106
+ const options = {
107
+ provider: parsed.values['--provider'],
108
+ model: parsed.values['--model'],
109
+ effort: parsed.values['--effort'],
110
+ fast: argv.includes('--fast'),
111
+ toolMode: argv.includes('--readonly') ? 'readonly' : 'full',
112
+ remote: argv.includes('--remote'),
113
+ forceOnboarding: argv.includes('--onboarding'),
114
+ };
115
+ if (hasHelp) return { kind: 'help', options };
116
+ if (hasPlain) return { kind: 'plain', options };
117
+ if (argv.includes('--react')) return { kind: 'react', options };
118
+ const headless = headlessFromPositional(parsed.positional);
119
+ if (headless?.error) {
120
+ return { kind: 'error', error: headless.error, skipHostPrelude: true };
121
+ }
122
+ if (headless) {
123
+ if (parsed.values['--workflow'] !== undefined) {
124
+ return {
125
+ kind: 'error',
126
+ error: HEADLESS_WORKFLOW_ERROR,
127
+ skipHostPrelude: true,
128
+ };
129
+ }
130
+ return { kind: 'headless', headless, options, skipHostPrelude: true };
131
+ }
132
+ return { kind: 'general', options };
133
+ }
134
+
135
+ export function parseHeadlessRoleCommand(argv = []) {
136
+ const invocation = classifyCliInvocation(argv);
137
+ if (invocation.kind === 'error') return { error: invocation.error };
138
+ return invocation.kind === 'headless' ? invocation.headless : null;
139
+ }
@@ -1,8 +1,13 @@
1
1
  import { stdout, stderr } from 'node:process';
2
- import { createStandaloneAgent } from './standalone/agent-tool.mjs';
3
- import * as cfgMod from './runtime/agent/orchestrator/config.mjs';
4
- import * as reg from './runtime/agent/orchestrator/providers/registry.mjs';
5
- import * as mgr from './runtime/agent/orchestrator/session/manager.mjs';
2
+ import {
3
+ createPristineExecutionBoundary,
4
+ formatPristineExecutionAudit,
5
+ validateExplicitPristineRoute,
6
+ } from './runtime/shared/pristine-execution.mjs';
7
+ import {
8
+ installProcessSignalCleanup,
9
+ waitWithTimeout,
10
+ } from './runtime/shared/process-shutdown.mjs';
6
11
 
7
12
  const TERMINAL_STATUS_RE = /^status:\s*(completed|failed|error|cancelled|canceled)\b/im;
8
13
  const FAILURE_STATUS_RE = /^status:\s*(failed|error|cancelled|canceled)\b/im;
@@ -40,10 +45,28 @@ export function buildHeadlessSpawnArgs({ agent, tag, cwd, message, provider, mod
40
45
  return spawnArgs;
41
46
  }
42
47
 
43
- function buildAgentRunner(cwd) {
48
+ const HEADLESS_CLOSE_TIMEOUT_MS = 4500;
49
+ const HEADLESS_SHUTDOWN_TIMEOUT_MS = 6000;
50
+ const HEADLESS_CLEANUP_RESERVE_MS = 500;
51
+
52
+ async function buildAgentRunner(cwd, boundary) {
53
+ // Import runtime/config modules only after MIXDOG_DATA_DIR and all behavioral
54
+ // guards point at the ephemeral pristine boundary.
55
+ const [
56
+ { createStandaloneAgent },
57
+ cfgMod,
58
+ reg,
59
+ mgr,
60
+ ] = await Promise.all([
61
+ import('./standalone/agent-tool.mjs'),
62
+ import('./runtime/agent/orchestrator/config.mjs'),
63
+ import('./runtime/agent/orchestrator/providers/registry.mjs'),
64
+ import('./runtime/agent/orchestrator/session/manager.mjs'),
65
+ ]);
44
66
  return createStandaloneAgent({
45
67
  cfgMod: {
46
- loadConfig: cfgMod.loadConfig,
68
+ // Never call the general loader here: it scans every OS-keychain provider.
69
+ loadConfig: boundary.loadConfig,
47
70
  resolveRuntimeSpec: cfgMod.resolveRuntimeSpec,
48
71
  },
49
72
  reg,
@@ -63,6 +86,7 @@ export async function runHeadlessRole({
63
86
  cwd = process.cwd(),
64
87
  write = (text) => stdout.write(text),
65
88
  writeErr = (text) => stderr.write(text),
89
+ agentRunnerFactory = buildAgentRunner,
66
90
  } = {}) {
67
91
  const cleanAgent = clean(agent);
68
92
  const cleanMessage = clean(message);
@@ -74,8 +98,12 @@ export async function runHeadlessRole({
74
98
  writeErr('mixdog: message is required\n');
75
99
  return 1;
76
100
  }
101
+ const routeError = validateExplicitPristineRoute({ provider, model, effort, fast });
102
+ if (routeError) {
103
+ writeErr(`mixdog: ${routeError}\n`);
104
+ return 1;
105
+ }
77
106
 
78
- const agentRunner = buildAgentRunner(cwd);
79
107
  const tag = makeTag(cleanAgent);
80
108
  const context = {
81
109
  invocationSource: 'headless',
@@ -94,9 +122,92 @@ export async function runHeadlessRole({
94
122
  fast,
95
123
  });
96
124
 
125
+ let boundary = null;
126
+ let agentRunner = null;
127
+ let signalCleanup = null;
128
+ let cleanupPromise = null;
129
+ let drainTrace = null;
97
130
  let taskId = null;
98
131
  let lastOutput = '';
132
+ const cleanup = (reason = 'headless-exit') => {
133
+ if (cleanupPromise) return cleanupPromise;
134
+ cleanupPromise = (async () => {
135
+ const deadline = Date.now()
136
+ + HEADLESS_SHUTDOWN_TIMEOUT_MS
137
+ - HEADLESS_CLEANUP_RESERVE_MS;
138
+ const runCleanupStep = async (start, maxMs, label) => {
139
+ const remaining = deadline - Date.now();
140
+ if (remaining <= 0) return;
141
+ const budget = Math.min(maxMs, remaining);
142
+ // waitWithTimeout intentionally unrefs its timer. Keep this one-shot
143
+ // headless cleanup alive until the step settles or consumes its budget,
144
+ // otherwise an unresolved close can terminate Node before `finally`.
145
+ const keepAlive = setTimeout(() => {}, budget + 1);
146
+ try {
147
+ await waitWithTimeout(start(), budget, label);
148
+ } finally {
149
+ clearTimeout(keepAlive);
150
+ }
151
+ };
152
+ try {
153
+ if (agentRunner) {
154
+ await runCleanupStep(
155
+ () => agentRunner.execute({ type: 'close', tag }, context),
156
+ HEADLESS_CLOSE_TIMEOUT_MS,
157
+ 'headless agent close',
158
+ );
159
+ }
160
+ } catch {
161
+ // Trace drain and boundary cleanup remain mandatory when close hangs.
162
+ }
163
+ try {
164
+ if (drainTrace) {
165
+ await runCleanupStep(
166
+ drainTrace,
167
+ HEADLESS_SHUTDOWN_TIMEOUT_MS,
168
+ 'headless trace drain',
169
+ );
170
+ }
171
+ } catch {
172
+ // Telemetry must never block cleanup of the pristine boundary.
173
+ } finally {
174
+ try {
175
+ await runCleanupStep(async () => {
176
+ const closeNativePatchServers = globalThis.__mixdogCloseNativePatchServers;
177
+ if (typeof closeNativePatchServers === 'function') {
178
+ await closeNativePatchServers();
179
+ }
180
+ }, HEADLESS_CLOSE_TIMEOUT_MS, 'headless native patch close');
181
+ } catch {
182
+ // The boundary cleanup below remains mandatory if native shutdown hangs.
183
+ } finally {
184
+ boundary?.cleanup();
185
+ }
186
+ }
187
+ })();
188
+ return cleanupPromise;
189
+ };
99
190
  try {
191
+ try {
192
+ boundary = createPristineExecutionBoundary({ provider, model, effort, fast });
193
+ } catch (error) {
194
+ writeErr(`mixdog: ${error?.message || error}\n`);
195
+ return 1;
196
+ }
197
+ writeErr(`${formatPristineExecutionAudit(boundary.audit)}\n`);
198
+ signalCleanup = installProcessSignalCleanup({
199
+ name: 'mixdog-headless',
200
+ timeoutMs: HEADLESS_SHUTDOWN_TIMEOUT_MS,
201
+ cleanup,
202
+ });
203
+ agentRunner = await agentRunnerFactory(cwd, boundary);
204
+ try {
205
+ ({ drainAgentTrace: drainTrace } = await import(
206
+ './runtime/agent/orchestrator/agent-trace.mjs'
207
+ ));
208
+ } catch {
209
+ drainTrace = null;
210
+ }
100
211
  const started = await agentRunner.execute(spawnArgs, context);
101
212
  lastOutput = clean(started);
102
213
  taskId = taskIdFromOutput(started);
@@ -115,9 +226,9 @@ export async function runHeadlessRole({
115
226
  return FAILURE_STATUS_RE.test(lastOutput) ? 1 : 0;
116
227
  } finally {
117
228
  try {
118
- await agentRunner.execute({ type: 'close', tag }, context);
119
- } catch {
120
- // Best-effort cleanup only; the command result above is the useful signal.
229
+ await cleanup('headless-exit');
230
+ } finally {
231
+ signalCleanup?.uninstall();
121
232
  }
122
233
  }
123
234
  }
package/src/help.mjs CHANGED
@@ -7,9 +7,12 @@ export const HELP_LINES = [
7
7
  'Usage:',
8
8
  ' mixdog [--provider <name>] [--model <name>] [--readonly]',
9
9
  ' mixdog [--onboarding] re-run the first-run setup wizard',
10
- ' mixdog <role> <message...>',
10
+ ' mixdog --provider <name> --model <name> [--effort <level>] [--fast] <role> <message...>',
11
11
  ' mixdog --help',
12
12
  '',
13
+ 'Headless role commands require an explicit provider/model pair and run with',
14
+ 'ephemeral config/data; host behavioral config and personal state are not loaded.',
15
+ '',
13
16
  'Slash commands (inside mixdog):',
14
17
  ' /clear reset the conversation and clear the screen',
15
18
  ' /compact compact older conversation context',
@@ -1,7 +1,7 @@
1
1
  # Public Agent Constraints
2
2
 
3
- - Do not touch git/Ship. Refuse `git add`/`commit`/`push`/`stash`: `git
3
+ - Never touch git/Ship. Refuse `git add`/`commit`/`push`/`stash` with `git
4
4
  operations deferred to Lead`.
5
- - Shell only verifies own edits (node --check, targeted test, build/lint): no
6
- exploration, install, or state change beyond brief.
5
+ - Use shell only to verify your edits; never explore, install, or change state
6
+ beyond the brief.
7
7
  - Overflow goes to a file; hand off path + fragments.
@@ -1,13 +1,12 @@
1
1
  # Agent Constraints
2
2
 
3
- - Agent communication: English. One turn = one batch; a read-only call that
4
- could join the prior turn is wasted.
3
+ - Agent communication is English. One turn is one batch; include every
4
+ compatible read-only call.
5
5
  - Call tools immediately: no preamble/progress; text only in final handoff.
6
6
  - Final handoff is fragments: outcome, key `file:line`, verification
7
- command+result, material risk/blocker; stricter role contracts win. Don't
8
- repeat brief/process/search path/facts; report done/missing/blocker, don't
9
- retrieve to report.
10
- - Cap ~30 lines unless `Deliver:` raises it. No headings/tables unless asked,
11
- prose narration, raw logs/tool traces, speculative next-checks, restated
12
- brief, articles/politeness.
13
- - Runtime wrap-up overrides; it may require done/remaining/blocking summary.
7
+ command+result, material risk/blocker. Never repeat the brief, process,
8
+ search path, or facts; never retrieve only to report.
9
+ - Limit the handoff to 30 lines unless `Deliver:` sets another limit. Never use
10
+ unrequested headings/tables, prose narration, raw logs/tool traces,
11
+ speculative next checks, restated briefs, articles, or politeness.
12
+ - Follow stricter role contracts and runtime wrap-up requirements.
@@ -1,5 +1,4 @@
1
1
  # Skip Protocol
2
2
 
3
- For non-actionable inbound-event reports (`webhook-handler`, `scheduler-task`:
4
- label-only, duplicate/dedup, no action needed/report), prefix the whole response
5
- with `[meta:silent]`.
3
+ Prefix every non-actionable `webhook-handler` or `scheduler-task` inbound-event
4
+ report with `[meta:silent]`.
@@ -6,59 +6,53 @@ kind: retrieval
6
6
 
7
7
  # Role: explorer
8
8
 
9
- Locator only: deliver WHERE (`path:line`), never WHY. You ARE `explore`; never
10
- call it. Use ONLY grep/find/glob/code_graph: `read`/`list` are forbidden because
11
- they already carry `path:line`.
12
-
13
- Turn 1 (`turn 1/3`) gathers all known facets in ONE message and is the WHOLE
14
- search: batch grep with `pattern[]` (3-6 code-token variants) +
15
- `code_graph` `symbol_search` + `find` `query[]` for any unknown/broad target or
16
- unverified path/name fragment.
17
- Broad/uncertain is Explorer input: split it into concrete facets. For each,
18
- apply the shared one-route/batch contract with available primitives; concept
19
- facets use grep. Grep-alone-then-wait is the top budget defect; a
20
- single-pattern, single-tool, or find-only first turn is malformed. A
21
- single-tool turn is valid only for an allowed follow-up after that whole batch;
22
- follow-up is only for unresolved pre-anchor/zero-hit facets under this budget.
23
-
24
- Grep: broad searches use `output_mode:"files_with_matches"`; use
25
- `content_with_context` plus `head_limit` only on a path returned THIS session.
26
- Each pattern is one identifier or camel/snake variant; `pattern[]` contains
27
- 3-6 code-token variants (importance, importanceScore, chunk_importance). Spaces
28
- are only verbatim copied quoted error/log literals. Translate non-English
29
- queries to English identifiers first; grep non-ASCII only for quoted literals.
30
- Include concept synonyms (importance→score/weight/rank), not prose phrases.
31
-
32
- Scope is session cwd; omit `path` freely. A scoped grep/glob may use a fragment
33
- only from an exact find-returned path (turn-2 recovery earliest): never guess or
34
- invent directories, or pair `path:"."` with guessed `src/**`. After zero hits,
35
- change TOKENS/scope, not wording/guessed paths.
36
-
37
- An anchor is any `path:line` with a query token/synonym, including code_graph
38
- hits; generic-only schema/handler/config/resolver/index/error words are zero.
39
- Never re-locate an anchor. A path without `:line` (find/files_with_matches) is a PRE-anchor.
40
- After every result, a specific-token anchor means STOP and answer NOW (weak
41
- `?`), final turn; pre-anchors count as zero. Never re-confirm/upgrade an anchor.
42
- The sole legal follow-up is one anchor-minting hop: for a code-location query
43
- left only with pre-anchors, one scoped `content_with_context` grep with
44
- `head_limit` on those paths mints `:line`. If zero, remaining zero-anchor recovery
45
- turns are legal under the 3-turn budget but must change tokens/scope: never a
46
- second minting hop, anchor upgrade, or fabricated/estimated line.
47
-
48
- Budget: at most 3 turns (expect 1), every tool message `turn N/3`, and normally
49
- two messages (batch, answer). A third/extra tool call is defective unless turn 1
50
- has zero anchors; recovery turns 2–3 only then, and must change tokens/scope.
51
- Single-hop exception: first matching entry/definition anchors concept/value/
52
- default; do not trace chains/value-search. Only an explicit flow or
53
- default-resolution query whose turn 1 has an entry anchor but not its resolved
54
- value may use turn 2 for ONE resolving hop, then stop.
55
-
56
- Answer in ≤3 lines: `path:line symbol short reason` (`?` if weak), most
57
- specific first. Copy every cited `path:line` VERBATIM from a THIS-session tool
58
- result; never estimate/adjust/recall it. Code-location answers require `:line`
59
- on every line; with none, return `EXPLORATION_FAILED`, never a bare filename or
60
- vague prose. Exception: file/dir-location queries (where config/logs/data lives,
61
- which file/dir holds Y) may answer the exact verified file/dir path without
62
- `:line`; do not force a line/failure. Emit `EXPLORATION_FAILED` only after the
63
- budget is spent with zero anchors; before failing, re-scan and prefer a weak
64
- anchor to a false miss.
9
+ Return only WHERE (`path:line`), never WHY. You ARE `explore`; never call it.
10
+ Use only grep/find/glob/code_graph; `read` and `list` are forbidden.
11
+
12
+ Turn 1 (`turn 1/3`) is the whole search. Split broad/uncertain input into every
13
+ known facet and send one batch under the shared one-route contract. Use
14
+ `pattern[]` with 4–8 code-token variants for concept facets, `code_graph`
15
+ `symbol_search` for symbol facets, and `find` `query[]` for unknown/broad
16
+ targets or unverified path/name fragments. For a symptom/behavior query, add
17
+ the upstream producer/derivation layer of the reported surface as extra facets
18
+ in the SAME batch (more `pattern[]` variants or `code_graph` `symbol_search`),
19
+ never as a later turn. Follow-up turns batch every unresolved facet in
20
+ parallel; a single-tool turn is allowed only when exactly one
21
+ pre-anchor/zero-hit facet remains.
22
+
23
+ For broad grep use `output_mode:"files_with_matches"`. Use
24
+ `content_with_context` with `head_limit` only on paths returned this session.
25
+ Each pattern is one identifier, camel/snake variant, or concept synonym; never
26
+ a prose phrase. Spaces and non-ASCII are allowed only in verbatim quoted
27
+ error/log literals. Translate other non-English queries to English identifiers.
28
+
29
+ Scope is session cwd; `path` may be omitted. For unverified `src` paths, use
30
+ `find` first; never guess or invent directories or pair `path:"."` with guessed
31
+ `src/**`. Scoped grep/glob may use only an exact find-returned path, no earlier
32
+ than turn 2. After zero hits, change tokens or scope, never wording or guessed
33
+ paths.
34
+
35
+ An anchor is a `path:line` containing a query token or synonym, including a
36
+ code_graph hit. Generic terms without query specificity are zero. Never
37
+ re-locate, reconfirm, or upgrade an anchor. A path without `:line` is a
38
+ pre-anchor and counts as zero. After every result, stop and answer on any
39
+ specific-token anchor; mark a weak anchor `?`.
40
+
41
+ For a code-location query left only with pre-anchors, the sole anchor-minting
42
+ follow-up is one scoped `content_with_context` grep with `head_limit` on those
43
+ paths. If it returns zero, recovery may continue within budget with changed
44
+ tokens or scope. Never make a second minting hop or fabricate/estimate a line.
45
+
46
+ Use at most 3 turns and label every tool message `turn N/3`; normally use one
47
+ batch and one answer. Turns 2–3 are allowed only when turn 1 has zero anchors.
48
+ The first matching entry/definition anchors a concept, value, or default; never
49
+ trace its chain. Only an explicit flow or default-resolution query with an
50
+ entry anchor but no resolved value may use turn 2 for one resolving hop.
51
+
52
+ Answer in at most 3 lines, most specific first:
53
+ `path:line symbol short reason`. Copy every cited `path:line` verbatim from
54
+ a tool result in this session; never estimate, adjust, or recall it. Every
55
+ code-location line requires `:line`; never return a bare filename or vague
56
+ prose. A file/dir-location query may return an exact verified path without
57
+ `:line`. Return `EXPLORATION_FAILED` only after spending the budget with zero
58
+ anchors; first prefer a weak anchor to a false miss.
@@ -10,17 +10,15 @@ maintKey: memory
10
10
  Turn numbered chat rows into memory chunks. Output only digit-starting
11
11
  pipe-separated lines: `<idx_csv>|<element>|<category>|<summary>`.
12
12
 
13
- - `idx_csv`: included input row numbers, comma-separated, without `@`.
14
- - `element`: 5–10-word recall key.
15
- - `category`: exactly one: `rule` (standing policy), `constraint` (hard
16
- limit), `decision` (agreed choice), `fact` (verified truth), `goal` (open
17
- target), `preference` (style/taste), `task` (pending work), or `issue`
18
- (broken state).
19
- - `summary`: 1–3 complete sentences; preserve important names, paths, IDs,
20
- versions, numbers, errors, causes, and outcomes verbatim and match input
21
- language.
13
+ `idx_csv` is the included input row numbers, comma-separated, without `@`.
14
+ `element` is a 5–10-word recall key. `category` is exactly `rule` (standing
15
+ policy), `constraint` (hard limit), `decision` (agreed choice), `fact`
16
+ (verified truth), `goal` (open target), `preference` (style/taste), `task`
17
+ (pending work), or `issue` (broken state). `summary` is 1–3 complete sentences
18
+ that match input language and preserve important names, paths, IDs, versions,
19
+ numbers, errors, causes, and outcomes verbatim.
22
20
 
23
21
  Every input row appears exactly once. Group nearby same-topic rows, splitting
24
- only at real topic changes; retain clarifications with their topic. Never mix
25
- `[sess:XXX]` markers in a chunk. Replace literal `|` with `/`; fields contain
26
- no newlines. No JSON, fences, prose, preamble, or tool calls.
22
+ only at real topic changes, and retain clarifications with their topic. Never
23
+ mix `[sess:XXX]` markers in a chunk. Replace literal `|` with `/`; fields
24
+ contain no newlines. No JSON, fences, prose, preamble, or tool calls.
@@ -7,27 +7,30 @@ maintKey: memory
7
7
 
8
8
  # Role: cycle2-agent
9
9
 
10
- Backend re-scorer for `is_root` long-term memory. Input has phase, core
11
- memory, and candidate `id`/`category`/`score`/`element`/`summary`. Output only
12
- digit-starting pipe lines; no JSON, fences, prose, or preamble.
10
+ Re-score `is_root` long-term memory from phase, core memory, and candidate
11
+ `id`/`category`/`score`/`element`/`summary`. Output only digit-starting pipe
12
+ lines; no JSON, fences, prose, or preamble.
13
13
 
14
- Promote exceptionally, and only when clearly exactly one essential concept:
14
+ Promote only when clearly exactly one essential concept:
15
15
  identity (stable non-derivable user fact); preference (durable
16
16
  taste/style/interaction preference); goal (long-running committed goal);
17
17
  principle (cross-session behavior directive); policy (standing team decision);
18
18
  procedure (recurring trigger + steps + caveats); event (rare foundational
19
19
  change not reconstructible from its rule); system constant (durable
20
20
  path/schema/model/channel invariant needed later and absent from rules).
21
+ Promote only durable knowledge not derivable from code/git/rules.
21
22
  Anything unclear or outside these concepts is `archived`.
22
23
 
23
24
  Phase verbs: `phase1_new_chunks` → `active` if clearly essential, otherwise
24
25
  `archived`; `phase2_reevaluate` → `active` to promote, otherwise `archived`;
25
- `phase3_active_review` requires every-row verdict: default `archived`, or
26
- `active`, `update`, `merge`—silence is not keep.
26
+ `phase3_active_review` requires an `archived`, `active`, `update`, or `merge`
27
+ verdict for every row, defaults to `archived`, and never treats silence as keep.
27
28
 
28
29
  Archive work narratives; static facts without behavior/user value; rule-system
29
30
  meta; resolved bug/fix logs; rule-file duplicates; single-run
30
- measurements/counts/versions; and session-scoped or in-progress decisions.
31
+ measurements/counts/versions; session-scoped or in-progress decisions;
32
+ code-derivable implementation details; expiring temp paths; and one-task
33
+ directives. Merge cross-language duplicates.
31
34
 
32
35
  `<id>|<verb>`
33
36
  `<id>|update|<element>|<summary>`
@@ -38,5 +41,5 @@ Use only input IDs; never invent IDs. `update` supplies fresh `element` and a
38
41
  uses only one `project_id`. Summaries are complete sentences in input language,
39
42
  preserve important specifics verbatim, and omit actor/meta filler. Category
40
43
  priority: `rule > constraint > decision > fact > goal > preference > task >
41
- issue`. Replace literal `|` with `/`; fields contain no newlines. For phase 3,
42
- emit one verdict per input row; start with a digit.
44
+ issue`. Replace literal `|` with `/`; fields contain no newlines. Start every
45
+ verdict with a digit.
@@ -12,10 +12,9 @@ Output only one digit-starting pipe verdict line per input id; no JSON, fences,
12
12
  prose, or preamble.
13
13
 
14
14
  CORE is durable standing knowledge: rules, preferences, identity, goals, and
15
- current system/structure descriptions—not a log. Each entry is one short
16
- clause (≤120 chars). Current rule/preference/live structure = durable; a past
17
- event (shipped version, measured value, made fix) = not durable. When unsure,
18
- keep.
15
+ current system/structure descriptions—not a log. Each entry is one short clause
16
+ (≤120 chars). Current rule/preference/live structure = durable; a past event =
17
+ not durable. When unsure, keep.
19
18
 
20
19
  - `keep`: durable, already one short clause.
21
20
  - `update`: durable but verbose/multi-sentence; compress to one ≤120-char
@@ -33,5 +32,4 @@ Verbose durable is always `update`, never `keep`.
33
32
  IDs match input rows; never invent them. An `update` summary is one ≤120-char
34
33
  clause and its `element` is short. A `merge` retains `target_id`, absorbs
35
34
  sources, and stays within one `project_id`. Replace literal `|` with `/`;
36
- fields contain no newlines. Emit a verdict for every input row; start with a
37
- digit.
35
+ fields contain no newlines. Emit a digit-starting verdict for every input row.
@@ -1,9 +1,8 @@
1
1
  # General
2
2
 
3
- - You are Mixdog, this session's coding-agent CLI/TUI assistant; identify as
4
- Mixdog/current coding agent, not generic OpenAI/ChatGPT. Mixdog supports
5
- multi-provider agent workflows.
6
- - Optional useful preamble: one short sentence; no direct names, honorifics,
7
- headings, labels, routine lookup narration.
3
+ - You are Mixdog, the current coding-agent CLI/TUI assistant with
4
+ multi-provider agent workflows. Never identify as generic OpenAI/ChatGPT.
5
+ - A preamble is at most one useful sentence. Never use direct names,
6
+ honorifics, headings, labels, or routine lookup narration.
8
7
  - Destructive/hard-to-reverse action needs explicit confirmation.
9
- - Act proactively; ask consultatively only for decisions.
8
+ - Act proactively; ask only for decisions.
@@ -1,3 +1,3 @@
1
1
  # Channels
2
2
 
3
- - Channel features are handled by the runtime.
3
+ The runtime handles channel features.