mixdog 0.9.89 → 0.9.91
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.
- package/package.json +5 -1
- package/src/output-styles/detailed.md +27 -0
- package/src/output-styles/extreme-minimal.md +8 -8
- package/src/output-styles/minimal.md +7 -10
- package/src/output-styles/simple.md +13 -21
- package/src/rules/lead/01-general.md +9 -1
- package/src/rules/lead/lead-brief.md +15 -14
- package/src/rules/shared/01-tool.md +31 -37
- package/src/runtime/agent/orchestrator/agent-runtime/commit-message-completion.mjs +67 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +35 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +28 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +116 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +74 -11
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +9 -10
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +15 -3
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +16 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +176 -16
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/pwsh-standby-pool.mjs +30 -1
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +96 -5
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +72 -1
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +48 -9
- package/src/runtime/channels/backends/discord.mjs +21 -1
- package/src/runtime/channels/tool-defs.mjs +1 -1
- package/src/runtime/memory/lib/trace-store.mjs +25 -3
- package/src/runtime/memory/tool-defs.mjs +5 -5
- package/src/runtime/search/tool-defs.mjs +2 -18
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/session-runtime/output-styles.mjs +7 -6
- package/src/session-runtime/tool-defs.mjs +0 -1
- package/src/session-runtime/tool-surface.mjs +9 -0
- package/src/session-runtime/workflow.mjs +7 -0
- package/src/standalone/explore-tool.mjs +2 -2
- package/src/workflows/default/WORKFLOW.md +2 -1
- package/src/workflows/solo/WORKFLOW.md +7 -5
- package/src/output-styles/default.md +0 -40
|
@@ -12,7 +12,9 @@ async function ensureDiscord() {
|
|
|
12
12
|
import {
|
|
13
13
|
mkdirSync,
|
|
14
14
|
statSync,
|
|
15
|
-
realpathSync
|
|
15
|
+
realpathSync,
|
|
16
|
+
readdirSync,
|
|
17
|
+
unlinkSync
|
|
16
18
|
} from "fs";
|
|
17
19
|
import { join, sep } from "path";
|
|
18
20
|
import { createHash } from "crypto";
|
|
@@ -83,8 +85,26 @@ class DiscordBackend {
|
|
|
83
85
|
}
|
|
84
86
|
// ── Lifecycle ──────────────────────────────────────────────────────
|
|
85
87
|
async connect() {
|
|
88
|
+
this._sweepInboxOnce();
|
|
86
89
|
return gateway.connect(this);
|
|
87
90
|
}
|
|
91
|
+
// Voice/attachment inbox retention: downloaded .ogg/.wav payloads are
|
|
92
|
+
// consumed at transcription time and were never cleaned up (audit: 477
|
|
93
|
+
// files / 55 MB accumulated since July). Best-effort, once per process.
|
|
94
|
+
_sweepInboxOnce() {
|
|
95
|
+
if (this._inboxSweepDone) return;
|
|
96
|
+
this._inboxSweepDone = true;
|
|
97
|
+
try {
|
|
98
|
+
const cutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
|
99
|
+
for (const name of readdirSync(this.inboxDir)) {
|
|
100
|
+
const p = join(this.inboxDir, name);
|
|
101
|
+
try {
|
|
102
|
+
const st = statSync(p);
|
|
103
|
+
if (st.isFile() && st.mtimeMs < cutoff) unlinkSync(p);
|
|
104
|
+
} catch { /* per-file best-effort */ }
|
|
105
|
+
}
|
|
106
|
+
} catch { /* inbox may not exist yet */ }
|
|
107
|
+
}
|
|
88
108
|
async disconnect() {
|
|
89
109
|
for (const interval of this.typingIntervals.values()) {
|
|
90
110
|
clearInterval(interval);
|
|
@@ -32,7 +32,7 @@ export const TOOL_DEFS = [
|
|
|
32
32
|
name: "fetch",
|
|
33
33
|
title: "Fetch",
|
|
34
34
|
annotations: { title: "Fetch", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
35
|
-
description: "Discord-only recent messages
|
|
35
|
+
description: "Discord-only: read recent messages from a channel.",
|
|
36
36
|
inputSchema: {
|
|
37
37
|
type: "object",
|
|
38
38
|
properties: {
|
|
@@ -465,13 +465,18 @@ async function ensureCurrentAndNextMonthPartitions(client) {
|
|
|
465
465
|
// Trace retention: drop named monthly partitions older than the configured
|
|
466
466
|
// window. Trace is regenerable observability data, so aging out old months is
|
|
467
467
|
// non-destructive to durable state. Config via MIXDOG_TRACE_RETENTION_MONTHS
|
|
468
|
-
// (default
|
|
468
|
+
// (default 1); set to 0 to disable. Only DROPs partitions strictly older than
|
|
469
469
|
// the cutoff month; the default catch-all partition is never dropped.
|
|
470
|
+
// Default rationale: a personal-machine audit found trace partitions at 76%
|
|
471
|
+
// of the 1.5 GB memory DB (July alone 787 MB) while durable entries were
|
|
472
|
+
// 207 MB. Monthly partitions mean retention 1 always keeps the current +
|
|
473
|
+
// previous month (30-60 days of full-resolution diagnostics) while bounding
|
|
474
|
+
// the DB to a rolling ceiling instead of unbounded growth.
|
|
470
475
|
const TRACE_RETENTION_MONTHS = (() => {
|
|
471
476
|
const raw = process.env.MIXDOG_TRACE_RETENTION_MONTHS
|
|
472
|
-
if (raw == null || raw === '') return
|
|
477
|
+
if (raw == null || raw === '') return 1
|
|
473
478
|
const n = Number(raw)
|
|
474
|
-
return Number.isFinite(n) && n >= 0 ? Math.floor(n) :
|
|
479
|
+
return Number.isFinite(n) && n >= 0 ? Math.floor(n) : 1
|
|
475
480
|
})()
|
|
476
481
|
|
|
477
482
|
async function dropAgedTracePartitions(client) {
|
|
@@ -499,6 +504,22 @@ async function dropAgedTracePartitions(client) {
|
|
|
499
504
|
`)
|
|
500
505
|
}
|
|
501
506
|
|
|
507
|
+
// Row-level ageing for the non-partitioned trace side tables. agent_calls and
|
|
508
|
+
// agent_llm grew unbounded (284 MB observed) because only trace_events had a
|
|
509
|
+
// retention path. Same window, same regenerable-diagnostics rationale; space
|
|
510
|
+
// is reclaimed by autovacuum row reuse rather than immediate disk shrink.
|
|
511
|
+
async function deleteAgedTraceRows(client) {
|
|
512
|
+
if (TRACE_RETENTION_MONTHS <= 0) return
|
|
513
|
+
const months = TRACE_RETENTION_MONTHS
|
|
514
|
+
for (const table of ['agent_calls', 'agent_llm', 'bridge_calls', 'bridge_llm']) {
|
|
515
|
+
try {
|
|
516
|
+
await client.query(`DELETE FROM ${table} WHERE ts < now() - interval '${months} months'`)
|
|
517
|
+
} catch (err) {
|
|
518
|
+
__mixdogMemoryLog(`[trace-store] aged-row delete skipped for ${table}: ${err?.message ?? err}\n`)
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
502
523
|
async function isBootstrapComplete(client) {
|
|
503
524
|
try {
|
|
504
525
|
// Harden the check: require (a) root is partitioned, (b) schema-version
|
|
@@ -624,6 +645,7 @@ export async function openTraceDatabase(dataDir) {
|
|
|
624
645
|
await c.query(`SET search_path = trace, public`)
|
|
625
646
|
await ensureCurrentAndNextMonthPartitions(c)
|
|
626
647
|
await dropAgedTracePartitions(c)
|
|
648
|
+
await deleteAgedTraceRows(c)
|
|
627
649
|
} catch (err) {
|
|
628
650
|
__mixdogMemoryLog(`[trace-store] periodic partition ensure failed: ${err?.message ?? err}\n`)
|
|
629
651
|
} finally {
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// tool registrations) but are not advertised via ListTools / tools.json, so
|
|
4
4
|
// they never reach an external LLM. `aiWrapped: true` routes dispatches
|
|
5
5
|
// through ai-wrapped-dispatch.mjs instead of the module's handleToolCall.
|
|
6
|
+
// Shared period grammar for recall/search_memories.
|
|
7
|
+
const PERIOD_DESCRIPTION = "last (recent sessions; +query topic-filter; limit=session count), Nm/Nh/Nd, today/yesterday/this_week/last_week, all, YYYY-MM-DD, date~date, HH:MM~HH:MM, or 'YYYY-MM-DD HH:MM~HH:MM'.";
|
|
6
8
|
export const TOOL_DEFS = [
|
|
7
9
|
{
|
|
8
10
|
name: 'memory',
|
|
@@ -46,24 +48,22 @@ export const TOOL_DEFS = [
|
|
|
46
48
|
name: 'recall',
|
|
47
49
|
title: 'Recall',
|
|
48
50
|
annotations: { title: 'Recall', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
49
|
-
description: 'Retrieve stored memory/session history for prior-work context (resumes, earlier decisions)
|
|
51
|
+
description: 'Retrieve stored memory/session history for prior-work context (resumes, earlier decisions). Query is topic/semantic, not regex; period selects the time window; id for exact follow-up.',
|
|
50
52
|
inputSchema: {
|
|
51
53
|
type: 'object',
|
|
52
54
|
properties: {
|
|
53
55
|
query: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Search text, or array for independent fan-out queries.' },
|
|
54
56
|
id: { anyOf: [{ type: 'number' }, { type: 'array', items: { type: 'number' }, minItems: 1 }], description: 'Exact #id(s) from recall. Do not invent ids.' },
|
|
55
|
-
period: { type: 'string', description:
|
|
57
|
+
period: { type: 'string', description: PERIOD_DESCRIPTION },
|
|
56
58
|
limit: { type: 'number', description: 'Max entries.' },
|
|
57
59
|
offset: { type: 'number', description: 'Skip entries.' },
|
|
58
60
|
sort: { type: 'string', enum: ['importance', 'date'], description: 'importance or date.' },
|
|
59
61
|
category: { anyOf: [{ type: 'string', enum: ['rule','constraint','decision','fact','goal','preference','task','issue'] }, { type: 'array', items: { type: 'string', enum: ['rule','constraint','decision','fact','goal','preference','task','issue'] }, minItems: 1 }], description: 'Category filter.' },
|
|
60
62
|
includeArchived: { type: 'boolean', description: 'Include archived entries.' },
|
|
61
|
-
sessionId: { type: 'string', description: 'Scoped session id.' },
|
|
62
63
|
includeMembers: { type: 'boolean', description: 'Include chunk members in output; does not widen the search pool.' },
|
|
63
64
|
includeRaw: { type: 'boolean', description: 'Include unchunked raw/episode rows.' },
|
|
64
65
|
sessionOnly: { type: 'boolean', description: 'Search this session only.' },
|
|
65
66
|
projectScope: { type: 'string', description: 'Project pool selector: inferred from cwd, common, all, or slug.' },
|
|
66
|
-
cwd: { type: 'string', description: 'Infer projectScope.' },
|
|
67
67
|
},
|
|
68
68
|
additionalProperties: false,
|
|
69
69
|
},
|
|
@@ -78,7 +78,7 @@ export const TOOL_DEFS = [
|
|
|
78
78
|
type: 'object',
|
|
79
79
|
properties: {
|
|
80
80
|
query: { type: 'string', description: 'Search text.' },
|
|
81
|
-
period: { type: 'string', description:
|
|
81
|
+
period: { type: 'string', description: PERIOD_DESCRIPTION },
|
|
82
82
|
sort: { type: 'string', enum: ['date', 'importance'], description: 'date or importance.' },
|
|
83
83
|
category: { anyOf: [{ type: 'string', enum: ['rule','constraint','decision','fact','goal','preference','task','issue'] }, { type: 'array', items: { type: 'string', enum: ['rule','constraint','decision','fact','goal','preference','task','issue'] }, minItems: 1 }], description: 'Category filter.' },
|
|
84
84
|
limit: { type: 'number', default: 30, description: 'Max entries.' },
|
|
@@ -8,7 +8,7 @@ export const TOOL_DEFS = [
|
|
|
8
8
|
{
|
|
9
9
|
name: 'search',
|
|
10
10
|
title: 'Mixdog Web Search',
|
|
11
|
-
description: `Web/docs/current-info search.
|
|
11
|
+
description: `Web/docs/current-info search. ${TOOL_SYNC_EXECUTION_CONTRACT} Cached; query supports array fan-out.`,
|
|
12
12
|
inputSchema: {
|
|
13
13
|
type: 'object',
|
|
14
14
|
properties: {
|
|
@@ -16,23 +16,7 @@ export const TOOL_DEFS = [
|
|
|
16
16
|
site: { type: 'string', description: 'Site/domain filter.' },
|
|
17
17
|
type: { type: 'string', enum: ['web', 'news', 'images'], description: 'Default web.' },
|
|
18
18
|
maxResults: { type: 'number', minimum: 1, maximum: 20, description: 'Result count, 1-20.' },
|
|
19
|
-
locale: {
|
|
20
|
-
description: 'Optional locale hint.',
|
|
21
|
-
anyOf: [
|
|
22
|
-
{ type: 'string' },
|
|
23
|
-
{
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: {
|
|
26
|
-
country: { type: 'string', description: 'Country.' },
|
|
27
|
-
language: { type: 'string', description: 'Language.' },
|
|
28
|
-
region: { type: 'string', description: 'Region.' },
|
|
29
|
-
city: { type: 'string', description: 'City.' },
|
|
30
|
-
timezone: { type: 'string', description: 'Timezone.' },
|
|
31
|
-
},
|
|
32
|
-
additionalProperties: false,
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
},
|
|
19
|
+
locale: { type: 'string', description: 'Optional locale hint, e.g. ko-KR or a city/region name.' },
|
|
36
20
|
contextSize: { type: 'string', enum: ['low', 'medium', 'high'], description: 'Default low.' },
|
|
37
21
|
},
|
|
38
22
|
required: [],
|
|
@@ -2,7 +2,7 @@ export const TOOL_SYNC_EXECUTION_CONTRACT =
|
|
|
2
2
|
'Runs synchronously in this tool call.';
|
|
3
3
|
|
|
4
4
|
export const TOOL_ASYNC_EXECUTION_CONTRACT =
|
|
5
|
-
'Runs sync inline
|
|
5
|
+
'Runs sync inline by default; async returns a background task_id and delivers a completion notification.';
|
|
6
6
|
|
|
7
7
|
export const TOOL_MANUAL_CONTROL_CONTRACT =
|
|
8
8
|
'wait/read/status/cancel are for explicit blocking or recovery only.';
|
|
@@ -5,10 +5,11 @@ import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
|
5
5
|
import { clean } from './session-text.mjs';
|
|
6
6
|
import { readJsonSafe } from './fs-utils.mjs';
|
|
7
7
|
|
|
8
|
-
const OUTPUT_STYLE_ORDER = ['
|
|
8
|
+
const OUTPUT_STYLE_ORDER = ['simple', 'detailed', 'minimal', 'extreme-minimal'];
|
|
9
9
|
const OUTPUT_STYLE_ALIASES = new Map([
|
|
10
|
-
['compact', '
|
|
11
|
-
['normal', '
|
|
10
|
+
['compact', 'simple'],
|
|
11
|
+
['normal', 'simple'],
|
|
12
|
+
['detail', 'detailed'],
|
|
12
13
|
['extreme', 'extreme-minimal'],
|
|
13
14
|
['extremesimple', 'extreme-minimal'],
|
|
14
15
|
['extreme-simple', 'extreme-minimal'],
|
|
@@ -146,15 +147,15 @@ export function findOutputStyle(value, styles) {
|
|
|
146
147
|
|
|
147
148
|
function configuredOutputStyleValue(dataDir) {
|
|
148
149
|
const unified = readJsonSafe(join(dataDir, 'mixdog-config.json')) || {};
|
|
149
|
-
return clean(unified.outputStyle || (unified.agent && unified.agent.outputStyle) || '
|
|
150
|
+
return clean(unified.outputStyle || (unified.agent && unified.agent.outputStyle) || 'simple') || 'simple';
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
export function outputStyleStatus(rootDir, dataDir, { fresh = false } = {}) {
|
|
153
154
|
const styles = listOutputStyleCatalog(rootDir, dataDir, { fresh });
|
|
154
155
|
const configured = configuredOutputStyleValue(dataDir);
|
|
155
156
|
const current = findOutputStyle(configured, styles)
|
|
156
|
-
|| findOutputStyle('
|
|
157
|
+
|| findOutputStyle('simple', styles)
|
|
157
158
|
|| styles[0]
|
|
158
|
-
|| { id: '
|
|
159
|
+
|| { id: 'simple', label: 'Simple', description: '', aliases: [], source: 'builtin' };
|
|
159
160
|
return { configured, current, styles };
|
|
160
161
|
}
|
|
@@ -18,7 +18,6 @@ export const TOOL_SEARCH_TOOL = {
|
|
|
18
18
|
type: 'object',
|
|
19
19
|
properties: {
|
|
20
20
|
names: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Exact deferred tool names/aliases to load.' },
|
|
21
|
-
select: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], description: 'Legacy alias for names; accepts exact names/aliases and select:name syntax.' },
|
|
22
21
|
},
|
|
23
22
|
additionalProperties: false,
|
|
24
23
|
},
|
|
@@ -26,8 +26,17 @@ export function createToolSurface({
|
|
|
26
26
|
|
|
27
27
|
// A workflow that delegates to NOBODY must not advertise the agent tool: a
|
|
28
28
|
// schema-visible tool policy always rejects is a guaranteed error turn.
|
|
29
|
+
// The SESSION's effective workflow wins over the config-active one: headless
|
|
30
|
+
// and per-session overrides (e.g. bench `workflow=solo`) never touch the
|
|
31
|
+
// config default, so keying off config alone left the agent tool visible in
|
|
32
|
+
// Solo sessions (observed across a full TB2.1 run: advertised, never used).
|
|
29
33
|
function workflowAllowsAgents() {
|
|
30
34
|
try {
|
|
35
|
+
const sessionWorkflow = getSession()?.workflow;
|
|
36
|
+
if (sessionWorkflow && typeof sessionWorkflow === 'object'
|
|
37
|
+
&& sessionWorkflow.agentsConfigured === true) {
|
|
38
|
+
return Array.isArray(sessionWorkflow.agents) && sessionWorkflow.agents.length > 0;
|
|
39
|
+
}
|
|
31
40
|
const pack = loadWorkflowPack(cfgMod.getPluginData?.() || dataDir, activeWorkflowId(getConfig()));
|
|
32
41
|
if (!pack || pack.agentsConfigured !== true) return true;
|
|
33
42
|
return Array.isArray(pack.agents) && pack.agents.length > 0;
|
|
@@ -229,6 +229,13 @@ export function createWorkflowHelpers({ rootDir, dataDir, readMarkdownDocument,
|
|
|
229
229
|
name: clean(pack?.name) || (id === DEFAULT_WORKFLOW_ID ? 'Default' : id),
|
|
230
230
|
description: clean(pack?.description),
|
|
231
231
|
source: clean(pack?.source),
|
|
232
|
+
// Delegation surface fields: the session stores this summary as
|
|
233
|
+
// session.workflow, and the agent-tool gate (tool-surface.mjs
|
|
234
|
+
// workflowAllowsAgents) needs them to filter the agent tool for
|
|
235
|
+
// packs that delegate to nobody — including headless/bench sessions
|
|
236
|
+
// whose workflow never touches the config-active pack.
|
|
237
|
+
agentsConfigured: pack?.agentsConfigured === true,
|
|
238
|
+
agents: Array.isArray(pack?.agents) ? pack.agents.slice() : [],
|
|
232
239
|
};
|
|
233
240
|
}
|
|
234
241
|
|
|
@@ -18,11 +18,11 @@ export const EXPLORE_TOOL = {
|
|
|
18
18
|
name: 'explore',
|
|
19
19
|
title: 'Explore',
|
|
20
20
|
annotations: { title: 'Explore', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
21
|
-
description: 'Locator for broad/uncertain targets with no known path, repo or machine-wide (dot dirs included).
|
|
21
|
+
description: 'Locator for broad/uncertain targets with no known path, repo or machine-wide (dot dirs included). query[] fans out up to 8 independent facets in parallel.',
|
|
22
22
|
inputSchema: {
|
|
23
23
|
type: 'object',
|
|
24
24
|
properties: {
|
|
25
|
-
query: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Narrow locator query; array = independent facets
|
|
25
|
+
query: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Narrow locator query; array = independent facets fanned out in parallel.' },
|
|
26
26
|
cwd: { type: 'string', description: 'Project/root directory.' },
|
|
27
27
|
},
|
|
28
28
|
required: [],
|
|
@@ -17,7 +17,8 @@ On approval, fan out at maximum width: one agent per independent scope, all
|
|
|
17
17
|
spawned in one turn; only a scope that depends on another's output waits.
|
|
18
18
|
Split the plan into as many scopes as possible: disjoint file/module sets
|
|
19
19
|
are independent; merge only on a true output dependency. Prefer parallel
|
|
20
|
-
scopes over sequential slices in one agent.
|
|
20
|
+
scopes over sequential slices in one agent. Brief each agent per the Lead
|
|
21
|
+
Brief contract.
|
|
21
22
|
|
|
22
23
|
Route by complexity: simple, well-understood implementation goes to Worker;
|
|
23
24
|
complex or investigative implementation goes to Heavy Worker; Lead itself
|
|
@@ -15,11 +15,13 @@ changed request resets planning; a scope change requires fresh approval.
|
|
|
15
15
|
On approval, Lead executes all work itself — never spawn, send, or delegate
|
|
16
16
|
to agents. Complete in-scope fixes without reapproval.
|
|
17
17
|
|
|
18
|
-
Verification is single-pass:
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Verification is single-pass and risk-proportional: exactly one check that
|
|
19
|
+
most directly proves the deliverable — a direct result check for trivial or
|
|
20
|
+
read-only work, full test/build runs only for risky or behavior-changing
|
|
21
|
+
work. A pass is final. Iterate only on a failing check, re-running just that
|
|
22
|
+
check after each fix, or report the blocker.
|
|
21
23
|
|
|
22
|
-
Report the result
|
|
23
|
-
|
|
24
|
+
Report the result against the approved plan. Build, deploy, commit, and push
|
|
25
|
+
happen only on an explicit user request.
|
|
24
26
|
|
|
25
27
|
On direction change, pause and re-consult the user.
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: default
|
|
3
|
-
title: Default
|
|
4
|
-
description: Concise engineering summaries
|
|
5
|
-
keep-coding-instructions: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Output Style
|
|
9
|
-
|
|
10
|
-
Mixdog default — the most detailed style, but always summary-form, never
|
|
11
|
-
essay-form. Depth comes from picking the right facts, not explaining more.
|
|
12
|
-
|
|
13
|
-
Content
|
|
14
|
-
- Lead with the outcome in one short sentence, then only the detail that
|
|
15
|
-
matters: what changed, key evidence (paths, commands, errors, verification).
|
|
16
|
-
- Summarize at the concept level: name the problem/behavior and direction,
|
|
17
|
-
not the code path; cite a symbol/path only as an anchor.
|
|
18
|
-
State conclusions, not reasoning: no mechanism walkthroughs or chained
|
|
19
|
-
qualifiers unless asked.
|
|
20
|
-
- Compress by cutting content (filler, hedging, restated facts), not grammar:
|
|
21
|
-
natural, complete sentences in the user's language; technical terms, paths,
|
|
22
|
-
commands, symbols, code, and exact errors stay verbatim.
|
|
23
|
-
- Say each point once: problem and fix in ONE compact statement. Size budget:
|
|
24
|
-
roughly TWICE the Simple style — about 2 rendered lines per point, whole
|
|
25
|
-
report ~10–15 lines, spent on evidence Simple would drop.
|
|
26
|
-
- Use labels such as `Changes`, `Verification`, and `Risks / next steps` in
|
|
27
|
-
final reports; skip labels on interim progress, and collapse trivial tasks
|
|
28
|
-
to a couple of sentences instead of forcing sections.
|
|
29
|
-
- Synthesize agent or retrieval results; never forward raw reports, long file
|
|
30
|
-
lists, tool traces, or session metadata.
|
|
31
|
-
- Do not hide blockers, failed verification, or required follow-up; surface them
|
|
32
|
-
in one short clause.
|
|
33
|
-
|
|
34
|
-
Layout (hard rules)
|
|
35
|
-
- One bullet or numbered item = one idea, at most 2 rendered lines, opened
|
|
36
|
-
with a short **bold key point**; if it needs more, cut the detail.
|
|
37
|
-
- Blank line between numbered items and between any multi-line list items —
|
|
38
|
-
never a wall of consecutive multi-line items. Paragraphs ~3 lines max with
|
|
39
|
-
blank lines between blocks; nest at most one sub-level.
|
|
40
|
-
- Never name this style unless asked.
|