@wrongstack/core 0.308.6 → 0.309.0
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/dist/coordination/agents/index.js +1 -0
- package/dist/coordination/agents/role-skills.d.ts +1 -0
- package/dist/coordination/director/director-toolset.d.ts +2 -2
- package/dist/coordination/director-mutation-test-tool.d.ts +29 -0
- package/dist/coordination/director-tools.d.ts +2 -0
- package/dist/coordination/director.d.ts +9 -0
- package/dist/coordination/explore-companion.d.ts +191 -0
- package/dist/coordination/fleet.d.ts +26 -0
- package/dist/coordination/index.d.ts +2 -1
- package/dist/coordination/index.js +1396 -370
- package/dist/coordination/mail-tools.d.ts +10 -6
- package/dist/coordination/mailbox-codecs.d.ts +31 -0
- package/dist/coordination/multi-agent-coordinator.d.ts +14 -0
- package/dist/coordination/multi-agent-timeout.d.ts +11 -1
- package/dist/coordination/mutation-engine.d.ts +74 -0
- package/dist/coordination/subagent-budget.d.ts +54 -0
- package/dist/coordination/subagent-finish.d.ts +78 -0
- package/dist/core/index.js +19 -4
- package/dist/defaults/index.js +731 -52
- package/dist/execution/compaction-core.d.ts +1 -1
- package/dist/execution/compaction-elision.d.ts +0 -10
- package/dist/execution/index.js +269 -16
- package/dist/goal/index.js +54 -27
- package/dist/goal/phase-orchestrator.d.ts +7 -0
- package/dist/goal/types.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1280 -201
- package/dist/kernel/events/agent-events.d.ts +31 -2
- package/dist/models/index.js +11 -1
- package/dist/plugin/discovery.d.ts +73 -0
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/index.js +270 -29
- package/dist/plugin/loader.d.ts +5 -1
- package/dist/plugin/trust.d.ts +78 -0
- package/dist/tools/index.js +1 -0
- package/dist/types/config/mcp-features.d.ts +21 -0
- package/dist/types/config/skills-fleet-brain.d.ts +18 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +14 -0
- package/dist/types/multi-agent.d.ts +15 -0
- package/dist/types/provider.d.ts +29 -1
- package/instructions/agents/chaos-monkey.md +57 -0
- package/instructions/agents/explore-companion.md +35 -0
- package/package.json +3 -3
package/dist/plugin/loader.d.ts
CHANGED
|
@@ -49,8 +49,12 @@ export interface LoadPluginsOptions {
|
|
|
49
49
|
* method that contradicts its declared `capabilities` — instead of
|
|
50
50
|
* just logging a warning. Use in CI/strict deployments to enforce
|
|
51
51
|
* manifest honesty. Default: false (log-only, backward-compatible).
|
|
52
|
+
*
|
|
53
|
+
* A predicate form is also accepted so hosts can enforce selectively —
|
|
54
|
+
* e.g. strictly for external (third-party) plugins while keeping
|
|
55
|
+
* first-party plugins warn-only.
|
|
52
56
|
*/
|
|
53
|
-
enforceCapabilities?: boolean | undefined;
|
|
57
|
+
enforceCapabilities?: boolean | ((plugin: Plugin) => boolean) | undefined;
|
|
54
58
|
/**
|
|
55
59
|
* Timeout in milliseconds for each plugin's `setup()` call. If the
|
|
56
60
|
* plugin's setup exceeds this deadline it is treated as a failure
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-on-first-use (TOFU) pinning for external plugins.
|
|
3
|
+
*
|
|
4
|
+
* In-process plugins run with full host privileges, so the only practical
|
|
5
|
+
* supply-chain signal available before plugin code executes is "has this
|
|
6
|
+
* plugin's entry file changed since the user first ran it?". On first load
|
|
7
|
+
* the host records a SHA-256 of the resolved entry file in
|
|
8
|
+
* `~/.wrongstack/plugin-trust.json`. Later loads compare hashes:
|
|
9
|
+
*
|
|
10
|
+
* - match → plugin loads silently
|
|
11
|
+
* - no pin yet → pin is written now, plugin loads (first use)
|
|
12
|
+
* - hash mismatch → plugin is REFUSED until the user re-pins it with
|
|
13
|
+
* `wstack plugin trust <name>`
|
|
14
|
+
*
|
|
15
|
+
* The pin covers the entry file only (not the whole dependency tree) —
|
|
16
|
+
* it catches swapped/updated plugin builds, not deep transitive changes.
|
|
17
|
+
* It is a tamper signal, not a signature scheme.
|
|
18
|
+
*
|
|
19
|
+
* Disable entirely with `features.pluginsTrust: false` in config.
|
|
20
|
+
*/
|
|
21
|
+
export interface PluginTrustEntry {
|
|
22
|
+
/** Absolute entry file path that was hashed at pin time. */
|
|
23
|
+
entry: string;
|
|
24
|
+
/** `sha256-<hex>` of the entry file contents at pin time. */
|
|
25
|
+
integrity: string;
|
|
26
|
+
/** ISO timestamp of when the pin was written. */
|
|
27
|
+
pinnedAt: string;
|
|
28
|
+
/** Optional provenance — the config spec/path the plugin was loaded from. */
|
|
29
|
+
spec?: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
export interface PluginTrustStore {
|
|
32
|
+
pinned: Record<string, PluginTrustEntry>;
|
|
33
|
+
}
|
|
34
|
+
export type PluginTrustVerification = {
|
|
35
|
+
status: 'unpinned';
|
|
36
|
+
integrity: string;
|
|
37
|
+
} | {
|
|
38
|
+
status: 'trusted';
|
|
39
|
+
integrity: string;
|
|
40
|
+
} | {
|
|
41
|
+
status: 'changed';
|
|
42
|
+
expected: string;
|
|
43
|
+
actual: string;
|
|
44
|
+
pinnedAt: string;
|
|
45
|
+
};
|
|
46
|
+
/** Default trust store location: `~/.wrongstack/plugin-trust.json`. */
|
|
47
|
+
export declare function defaultPluginTrustPath(globalRoot: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Canonical pin-key form: forward slashes on every platform, so a plugin
|
|
50
|
+
* pinned by discovery (forward-slash paths) and re-pinned from a config
|
|
51
|
+
* entry (backslashes on Windows) addresses the same store key.
|
|
52
|
+
*/
|
|
53
|
+
export declare function normalizeTrustKey(path: string): string;
|
|
54
|
+
export declare function hashFileContents(entryPath: string, readFileFn?: (path: string) => Promise<Buffer>): Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* Read the trust store. A missing file is an empty store (first run).
|
|
57
|
+
* A corrupt file is a hard error — silently ignoring it would downgrade
|
|
58
|
+
* every existing pin to "unpinned" and re-trust changed code, which is
|
|
59
|
+
* exactly the attack this file exists to catch.
|
|
60
|
+
*/
|
|
61
|
+
export declare function readPluginTrustStore(storePath: string, readFileFn?: (path: string) => Promise<string>): Promise<PluginTrustStore>;
|
|
62
|
+
/**
|
|
63
|
+
* Write the trust store atomically (temp file + rename, 0o600 — it is a
|
|
64
|
+
* security-relevant record, same treatment as the profile config).
|
|
65
|
+
*/
|
|
66
|
+
export declare function writePluginTrustStore(storePath: string, store: PluginTrustStore): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Pure verification: compare a freshly computed integrity hash against the
|
|
69
|
+
* pinned entry. Keyed by plugin name; the pinned `entry` path is advisory
|
|
70
|
+
* (an npm update can legitimately move the entry inside node_modules while
|
|
71
|
+
* the content hash is what decides trust).
|
|
72
|
+
*/
|
|
73
|
+
export declare function verifyPluginTrust(name: string, integrity: string, store: PluginTrustStore): PluginTrustVerification;
|
|
74
|
+
/** Insert or replace the pin for `name` and persist the store. */
|
|
75
|
+
export declare function pinPluginTrust(storePath: string, name: string, entry: string, integrity: string, spec?: string): Promise<PluginTrustStore>;
|
|
76
|
+
/** Remove the pin for `name` (if present) and persist the store. */
|
|
77
|
+
export declare function unpinPluginTrust(storePath: string, name: string): Promise<PluginTrustStore>;
|
|
78
|
+
//# sourceMappingURL=trust.d.ts.map
|
package/dist/tools/index.js
CHANGED
|
@@ -3499,6 +3499,7 @@ function inferRuntimeCapabilities(toolNames) {
|
|
|
3499
3499
|
var skillSet = (...names) => names;
|
|
3500
3500
|
var ROLE_SKILL_SETS = {
|
|
3501
3501
|
explore: skillSet("research-web", "node-modern", "typescript-strict"),
|
|
3502
|
+
"explore-companion": skillSet("node-modern", "typescript-strict"),
|
|
3502
3503
|
search: skillSet("bug-hunter", "typescript-strict", "research-web"),
|
|
3503
3504
|
research: skillSet("research-web", "tech-stack", "security-scanner", "api-design"),
|
|
3504
3505
|
analyst: skillSet("sdd", "api-design", "testing", "security-scanner"),
|
|
@@ -79,6 +79,17 @@ export interface PluginConfig {
|
|
|
79
79
|
name: string;
|
|
80
80
|
enabled?: boolean | undefined;
|
|
81
81
|
options?: Record<string, unknown>;
|
|
82
|
+
/**
|
|
83
|
+
* Load this plugin from an explicit location instead of resolving the
|
|
84
|
+
* npm specifier through the host's own module resolution. Accepts:
|
|
85
|
+
* - a relative path (resolved against the project root),
|
|
86
|
+
* - an absolute path,
|
|
87
|
+
* - a `file:` URL.
|
|
88
|
+
* The target may be an entry file (`plugin.js`) or a directory that
|
|
89
|
+
* contains `package.json` / `index.js`. External plugins loaded through
|
|
90
|
+
* `path` are subject to the TOFU trust pin (`~/.wrongstack/plugin-trust.json`).
|
|
91
|
+
*/
|
|
92
|
+
path?: string | undefined;
|
|
82
93
|
}
|
|
83
94
|
/**
|
|
84
95
|
* Human-owned policy for the LLM-facing `plugin_manager` tool.
|
|
@@ -105,6 +116,16 @@ export interface FeaturesConfig {
|
|
|
105
116
|
mcp: boolean;
|
|
106
117
|
/** Load + initialise npm plugins declared in `plugins`. */
|
|
107
118
|
plugins: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Trust-on-first-use pinning for external (third-party) plugins.
|
|
121
|
+
* The first load of an external plugin records a SHA-256 of its entry
|
|
122
|
+
* file in `~/.wrongstack/plugin-trust.json`; subsequent loads refuse to
|
|
123
|
+
* run the plugin when the hash changes until the user re-pins it via
|
|
124
|
+
* `wstack plugin trust <name>`. Set to false to disable pinning
|
|
125
|
+
* (not recommended — this is the only supply-chain signal for in-process
|
|
126
|
+
* plugins). Default: true.
|
|
127
|
+
*/
|
|
128
|
+
pluginsTrust?: boolean | undefined;
|
|
108
129
|
/** Register `remember` / `forget` tools backed by memory store. */
|
|
109
130
|
memory: boolean;
|
|
110
131
|
/**
|
|
@@ -128,6 +128,13 @@ export interface FleetConfig {
|
|
|
128
128
|
} | undefined;
|
|
129
129
|
/** Brain-gated fleet supervisor (rebalance/steer/spawn-helper). */
|
|
130
130
|
supervisor?: FleetSupervisorConfig | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Explore Companion — state-triggered background codebase explorer behind
|
|
133
|
+
* the leader. Watches the leader's in-progress work state and assigns
|
|
134
|
+
* read-only exploration probes to a resident `explore-companion`
|
|
135
|
+
* subagent; findings return via mailbox. Default enabled.
|
|
136
|
+
*/
|
|
137
|
+
exploreCompanion?: ExploreCompanionConfig | undefined;
|
|
131
138
|
/** Roster-agent self-learning: capture → optimize → per-skill addenda. */
|
|
132
139
|
learning?: AgentLearningConfig | undefined;
|
|
133
140
|
}
|
|
@@ -188,6 +195,17 @@ export interface FleetSupervisorConfig {
|
|
|
188
195
|
/** Allow the supervisor to terminate subagents (highest risk). Default false. */
|
|
189
196
|
allowTerminate?: boolean | undefined;
|
|
190
197
|
}
|
|
198
|
+
/** Config surface for the ExploreCompanion host wiring. */
|
|
199
|
+
export interface ExploreCompanionConfig {
|
|
200
|
+
/** Kill switch. Default true. */
|
|
201
|
+
enabled?: boolean | undefined;
|
|
202
|
+
/** Min gap between probes on the same subject (ms). Default 120000. */
|
|
203
|
+
cooldownMs?: number | undefined;
|
|
204
|
+
/** Pending probe queue cap (drop oldest when full). Default 8. */
|
|
205
|
+
maxPending?: number | undefined;
|
|
206
|
+
/** Mailbox poll interval for explicit asks (ms). Default 5000. */
|
|
207
|
+
pollIntervalMs?: number | undefined;
|
|
208
|
+
}
|
|
191
209
|
/**
|
|
192
210
|
* One member of the Brain's LLM pool or council. String entries elsewhere
|
|
193
211
|
* (`Config.brain.models`, council voters) parse with the same `parseModelRef`
|
package/dist/types/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export { BUILTIN_PROMPT_CATEGORIES, isBuiltinCategory, PROMPT_CATEGORY_LABELS }
|
|
|
34
34
|
export type { InstalledPromptEntry, ManifestValidation, PromptManifestData, PromptRegistryManifest, PromptRegistryRef, RegistryDiff, } from './prompt-registry.js';
|
|
35
35
|
export { diffRegistry, validateRegistryManifest } from './prompt-registry.js';
|
|
36
36
|
export type { CacheTtl, Capabilities, JsonSchemaSpec, Provider, ProviderContextLimit, ProviderErrorBody, ProviderErrorKind, ReasoningConfig, ReasoningEffort, ReasoningRequest, Request, RequestCacheControl, Response, ResponseFormat, SafetySetting, StopReason, StreamEvent, Usage, } from './provider.js';
|
|
37
|
-
export { classifyProviderError, effectiveInputTokens, isContextOverflowShaped, isFallbackWorthy, isRetryableKind, ProviderError, StreamHangError, } from './provider.js';
|
|
37
|
+
export { classifyProviderError, effectiveInputTokens, isContextOverflowShaped, isFallbackWorthy, isReasoningEffort, isRetryableKind, ProviderError, REASONING_EFFORT_LEVELS, StreamHangError, } from './provider.js';
|
|
38
38
|
export type { ProviderRunner, RunProviderOptions } from './provider-runner.js';
|
|
39
39
|
export type { Renderer } from './renderer.js';
|
|
40
40
|
export type { SecretScrubber } from './secret-scrubber.js';
|
package/dist/types/index.js
CHANGED
|
@@ -914,6 +914,18 @@ function truncate(s, max) {
|
|
|
914
914
|
var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\s]*limit[-_\s]*(?:reached|exceeded)/i;
|
|
915
915
|
|
|
916
916
|
// src/types/provider.ts
|
|
917
|
+
var REASONING_EFFORT_LEVELS = [
|
|
918
|
+
"none",
|
|
919
|
+
"minimal",
|
|
920
|
+
"low",
|
|
921
|
+
"medium",
|
|
922
|
+
"high",
|
|
923
|
+
"xhigh",
|
|
924
|
+
"max"
|
|
925
|
+
];
|
|
926
|
+
function isReasoningEffort(value) {
|
|
927
|
+
return typeof value === "string" && REASONING_EFFORT_LEVELS.includes(value);
|
|
928
|
+
}
|
|
917
929
|
function effectiveInputTokens(usage) {
|
|
918
930
|
return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
919
931
|
}
|
|
@@ -1346,6 +1358,7 @@ export {
|
|
|
1346
1358
|
ParseError,
|
|
1347
1359
|
PluginError,
|
|
1348
1360
|
ProviderError,
|
|
1361
|
+
REASONING_EFFORT_LEVELS,
|
|
1349
1362
|
SESSION_MARKER_EVENT_TYPES,
|
|
1350
1363
|
SYSTEM_INJECTION_PREFIXES,
|
|
1351
1364
|
SddError,
|
|
@@ -1377,6 +1390,7 @@ export {
|
|
|
1377
1390
|
isImageBlock,
|
|
1378
1391
|
isParseError,
|
|
1379
1392
|
isPluginError,
|
|
1393
|
+
isReasoningEffort,
|
|
1380
1394
|
isRetryableKind,
|
|
1381
1395
|
isSddError,
|
|
1382
1396
|
isSessionError,
|
|
@@ -142,6 +142,21 @@ export interface SubagentConfig {
|
|
|
142
142
|
end: string;
|
|
143
143
|
mode?: 'advisory' | 'enforce' | undefined;
|
|
144
144
|
} | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Model-driven completion policy. When set, this subagent is NEVER killed
|
|
147
|
+
* by the wall-clock watchdog at its deadline: instead the deadline (or an
|
|
148
|
+
* explicit `Director.requestFinish()`) triggers an in-band
|
|
149
|
+
* `subagent.finish_requested` notification that the agent loop folds into
|
|
150
|
+
* the conversation between tool batches — the model then finishes its task
|
|
151
|
+
* in its own turn within `graceMs` of legitimate working time. Only after
|
|
152
|
+
* that grace window elapses does the existing terminal stop apply, so the
|
|
153
|
+
* subagent still has a bounded maximum lifetime.
|
|
154
|
+
*
|
|
155
|
+
* `undefined` (default) keeps the legacy watchdog behavior unchanged.
|
|
156
|
+
*/
|
|
157
|
+
gracefulFinish?: boolean | {
|
|
158
|
+
graceMs?: number | undefined;
|
|
159
|
+
} | undefined;
|
|
145
160
|
/**
|
|
146
161
|
* Runtime request overrides for THIS subagent. When present, these are merged
|
|
147
162
|
* over the leader's `Config.modelRuntime` before the subagent request pipeline
|
package/dist/types/provider.d.ts
CHANGED
|
@@ -23,6 +23,21 @@ import type { Tool } from './tool.js';
|
|
|
23
23
|
* cached tokens twice and skew cache-hit-ratio reporting.
|
|
24
24
|
*/
|
|
25
25
|
export type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
26
|
+
/**
|
|
27
|
+
* The canonical runtime list of {@link ReasoningEffort} values, in
|
|
28
|
+
* menu/display order. Single source of truth for every surface that needs to
|
|
29
|
+
* iterate the levels (CLI `/settings` + `/setmodel`, the TUI picker, the
|
|
30
|
+
* WebUI dropdown) — import this instead of re-declaring a local array, which
|
|
31
|
+
* is how drift crept in before.
|
|
32
|
+
*
|
|
33
|
+
* `satisfies` pins the literal to the union: a value here core's type doesn't
|
|
34
|
+
* know is a compile error. Note the reverse is NOT caught — core adding a
|
|
35
|
+
* level does not force this array to grow, so consumers validating user input
|
|
36
|
+
* against it must decide deliberately whether to expose the new level.
|
|
37
|
+
*/
|
|
38
|
+
export declare const REASONING_EFFORT_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
39
|
+
/** Type guard for untrusted strings (CLI args, WS payloads, config files). */
|
|
40
|
+
export declare function isReasoningEffort(value: unknown): value is ReasoningEffort;
|
|
26
41
|
export type CacheTtl = '5m' | '1h';
|
|
27
42
|
/**
|
|
28
43
|
* Provider-agnostic response-format directive.
|
|
@@ -119,7 +134,20 @@ export interface RequestCacheControl {
|
|
|
119
134
|
export interface ReasoningConfig {
|
|
120
135
|
default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';
|
|
121
136
|
disableSupported: boolean;
|
|
122
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Tri-state effort support:
|
|
139
|
+
* `true` — the catalog documents this model's effort levels
|
|
140
|
+
* (`effortLevels` is authoritative).
|
|
141
|
+
* `false` — the catalog documents effort control as absent
|
|
142
|
+
* (toggle-only or budget_tokens-only reasoning options).
|
|
143
|
+
* `undefined` — the model is known to reason (`reasoning: true`) but its
|
|
144
|
+
* effort vocabulary is not documented. The resolver forwards
|
|
145
|
+
* the requested effort; each wire adapter then applies its
|
|
146
|
+
* own transport-level gating (allowlist, mapping, or omit),
|
|
147
|
+
* so an undocumented model can only match-or-omit — never
|
|
148
|
+
* receive a field shape it did not advertise.
|
|
149
|
+
*/
|
|
150
|
+
effortSupported?: boolean | undefined;
|
|
123
151
|
effortLevels: ReasoningEffort[];
|
|
124
152
|
preserveThinking: 'unsupported' | 'optional' | 'always_on';
|
|
125
153
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
You are the Chaos Monkey ("Kaos Maymunu") — a mutation-testing saboteur for the
|
|
2
|
+
WrongStack fleet. Your job is to prove whether a test suite actually pins down
|
|
3
|
+
the code it claims to cover, by deliberately breaking that code and watching
|
|
4
|
+
which mutants survive.
|
|
5
|
+
|
|
6
|
+
Core belief: green tests prove nothing if they cannot detect sabotage. A mutant
|
|
7
|
+
that survives means the tests are fake or insufficient — and that is the most
|
|
8
|
+
valuable finding you can return.
|
|
9
|
+
|
|
10
|
+
## Your task contract
|
|
11
|
+
|
|
12
|
+
The director hands you a mutation plan: an exact list of mutation ids, each with
|
|
13
|
+
file, line, column, kind, original token and replacement token. The plan is
|
|
14
|
+
authoritative — you NEVER invent, move, or "improve" mutations. Your freedom is
|
|
15
|
+
execution order and diagnosis, never the mutation set.
|
|
16
|
+
|
|
17
|
+
## Check pass (per mutant)
|
|
18
|
+
|
|
19
|
+
1. Apply exactly ONE mutation from the plan to its anchored (file, line, column).
|
|
20
|
+
If the anchored token no longer matches `original`, mark the mutant
|
|
21
|
+
`skipped` with the drift as evidence — do not hunt for a "similar" site.
|
|
22
|
+
2. Run the provided test command exactly as given.
|
|
23
|
+
3. Record the outcome:
|
|
24
|
+
- Tests fail → mutant `killed` (quote the first failing assertion).
|
|
25
|
+
- Tests pass → mutant `survived` (this is a weak-test finding, not your failure).
|
|
26
|
+
4. Restore the original source byte-for-byte before moving to the next mutant.
|
|
27
|
+
The suite is only honest if every mutant ran against pristine code except
|
|
28
|
+
its own single mutation.
|
|
29
|
+
|
|
30
|
+
## Hard rules
|
|
31
|
+
|
|
32
|
+
- **One mutation at a time.** Never stack mutants; a stacked run measures nothing.
|
|
33
|
+
- **Always restore.** Your worktree must be clean of sabotage at the end of the
|
|
34
|
+
pass. If restore fails, stop and report which file is left mutated.
|
|
35
|
+
- **Stay inside the plan's files.** No refactors, no fixes, no formatting churn
|
|
36
|
+
— even when the mutated code looks wrong to you. You are the saboteur, not
|
|
37
|
+
the reviewer.
|
|
38
|
+
- **Deterministic.** Same plan + same suite → same report.
|
|
39
|
+
- **One-shot lifecycle.** Finish the assigned pass, submit the report, stop.
|
|
40
|
+
|
|
41
|
+
## Report
|
|
42
|
+
|
|
43
|
+
Submit via `submit_result`, then repeat it as your final text (fenced JSON):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"summary": "<one line: N killed / M survived / K skipped>",
|
|
48
|
+
"mutants": [
|
|
49
|
+
{ "id": "<plan id>", "file": "...", "line": 0, "kind": "...",
|
|
50
|
+
"status": "killed | survived | skipped",
|
|
51
|
+
"evidence": "<failing assertion, or 'suite green' for survivors>" }
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Order survivors first — they are the actionable findings. For each survivor,
|
|
57
|
+
name the boundary or behavior the tests failed to assert.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
You are the Explore Companion — a read-only reconnaissance agent running
|
|
2
|
+
behind a leader agent that is executing the main task. You do not lead
|
|
3
|
+
work, you do not block the leader, and you never modify anything: you
|
|
4
|
+
answer narrow probes by scanning the codebase intensively and feeding
|
|
5
|
+
findings back asynchronously ("this file is here, that component works
|
|
6
|
+
like this").
|
|
7
|
+
|
|
8
|
+
Scope:
|
|
9
|
+
- Answer probes scoped to the leader's current in-progress work
|
|
10
|
+
- Locate files, entry points, symbols, and their callers/dependents
|
|
11
|
+
- Explain how a component works across the files that implement it
|
|
12
|
+
- Stay inside the probe scope; if the probe is ambiguous, state your
|
|
13
|
+
interpretation and answer anyway
|
|
14
|
+
|
|
15
|
+
Input format you accept (a probe task):
|
|
16
|
+
{ "probe": "<what to find>", "hint": { "file": "...", "symbol": "..." }, "context": "<what the leader is doing>" }
|
|
17
|
+
|
|
18
|
+
Output: findings, not prose. Markdown block with:
|
|
19
|
+
- ## Findings — table or bullets: `file:line` — what it is, how it works
|
|
20
|
+
- Confidence: 0.0–1.0 for the overall answer
|
|
21
|
+
- Next read: one `file:line` suggestion the leader should read next
|
|
22
|
+
|
|
23
|
+
Working rules:
|
|
24
|
+
- Read-only, always — never edit, write, or run shell commands
|
|
25
|
+
- Always cite file:line; never describe code you have not read
|
|
26
|
+
- Index-first discovery: `codebase-repo-map`, `codebase-search`,
|
|
27
|
+
`codebase-skeleton`, `codebase-incoming-calls`, `codebase-outgoing-calls`
|
|
28
|
+
before `read`/`grep`/`glob`/`tree`
|
|
29
|
+
- Keep the mailbox message compact: findings + confidence + one next-read
|
|
30
|
+
suggestion. The leader reads it inside its own context window.
|
|
31
|
+
- Report findings to the leader via the mailbox (`type=result` for a direct
|
|
32
|
+
probe answer, `type=btw` for ambient/low-urgency context, subject
|
|
33
|
+
prefixed `[explore]`), then always finish with `submit_result`
|
|
34
|
+
(`SubagentStructuredReport`): summary, findings[], files_examined[],
|
|
35
|
+
confidence, suggested_next_steps[].
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.309.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack core: kernel, types, defaults, and shared utilities for the WrongStack CLI agent.",
|
|
6
6
|
"repository": {
|
|
@@ -182,8 +182,8 @@
|
|
|
182
182
|
"wrongstackApiVersion": "0.1.10",
|
|
183
183
|
"dependencies": {
|
|
184
184
|
"zod": "4.4.3",
|
|
185
|
-
"@wrongstack/kanban": "0.
|
|
186
|
-
"@wrongstack/persistence": "0.
|
|
185
|
+
"@wrongstack/kanban": "0.309.0",
|
|
186
|
+
"@wrongstack/persistence": "0.309.0"
|
|
187
187
|
},
|
|
188
188
|
"devDependencies": {
|
|
189
189
|
"@types/node": "^26.2.0",
|