crewhaus 0.1.8 → 0.2.1
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/README.md +10 -3
- package/dist/advice-apply.d.ts +182 -0
- package/dist/advice-apply.js +286 -0
- package/dist/advise-rules.d.ts +348 -0
- package/dist/advise-rules.js +905 -0
- package/dist/alert-sink.d.ts +48 -0
- package/dist/alert-sink.js +86 -0
- package/dist/approval-gate.d.ts +127 -0
- package/dist/approval-gate.js +254 -0
- package/dist/audit-verify.d.ts +69 -0
- package/dist/audit-verify.js +97 -0
- package/dist/autodistill.d.ts +113 -0
- package/dist/autodistill.js +256 -0
- package/dist/channel-provision.d.ts +360 -0
- package/dist/channel-provision.js +881 -0
- package/dist/ci-scaffold.d.ts +31 -0
- package/dist/ci-scaffold.js +343 -0
- package/dist/compile-check.d.ts +90 -0
- package/dist/compile-check.js +285 -0
- package/dist/compliance-schedule.d.ts +35 -0
- package/dist/compliance-schedule.js +36 -0
- package/dist/context-pressure.d.ts +80 -0
- package/dist/context-pressure.js +166 -0
- package/dist/dataset-mine.d.ts +173 -0
- package/dist/dataset-mine.js +404 -0
- package/dist/datasets.d.ts +124 -0
- package/dist/datasets.js +260 -0
- package/dist/deploy-canary.d.ts +83 -0
- package/dist/deploy-canary.js +87 -0
- package/dist/doctor-checks.d.ts +33 -0
- package/dist/doctor-checks.js +92 -0
- package/dist/doctor-detect.d.ts +108 -0
- package/dist/doctor-detect.js +214 -0
- package/dist/doctor-fix.d.ts +81 -0
- package/dist/doctor-fix.js +164 -0
- package/dist/egress-triage.d.ts +121 -0
- package/dist/egress-triage.js +261 -0
- package/dist/eval-bridge.d.ts +114 -0
- package/dist/eval-bridge.js +158 -0
- package/dist/eval-coverage.d.ts +140 -0
- package/dist/eval-coverage.js +428 -0
- package/dist/eval-history.d.ts +48 -0
- package/dist/eval-history.js +157 -0
- package/dist/eval-matrix.d.ts +80 -0
- package/dist/eval-matrix.js +182 -0
- package/dist/eval-sentinel.d.ts +65 -0
- package/dist/eval-sentinel.js +132 -0
- package/dist/faq.d.ts +68 -0
- package/dist/faq.js +168 -0
- package/dist/feedback.d.ts +9 -2
- package/dist/feedback.js +17 -7
- package/dist/fewshot.d.ts +83 -0
- package/dist/fewshot.js +158 -0
- package/dist/fleet.d.ts +207 -0
- package/dist/fleet.js +488 -0
- package/dist/flywheel.d.ts +193 -0
- package/dist/flywheel.js +519 -0
- package/dist/graders-suggest.d.ts +186 -0
- package/dist/graders-suggest.js +658 -0
- package/dist/incident.d.ts +99 -0
- package/dist/incident.js +217 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +11664 -963
- package/dist/init-interactive.d.ts +105 -0
- package/dist/init-interactive.js +208 -0
- package/dist/intents.d.ts +105 -0
- package/dist/intents.js +292 -0
- package/dist/judge-calibrate.d.ts +137 -0
- package/dist/judge-calibrate.js +247 -0
- package/dist/justification-calibrate.d.ts +150 -0
- package/dist/justification-calibrate.js +262 -0
- package/dist/justification-gate.d.ts +27 -6
- package/dist/justification-gate.js +30 -6
- package/dist/knowledge-sync.d.ts +179 -0
- package/dist/knowledge-sync.js +551 -0
- package/dist/lessons.d.ts +87 -0
- package/dist/lessons.js +207 -0
- package/dist/lint.d.ts +127 -0
- package/dist/lint.js +226 -0
- package/dist/loadtest.d.ts +114 -0
- package/dist/loadtest.js +196 -0
- package/dist/marketplace-cli.d.ts +110 -0
- package/dist/marketplace-cli.js +250 -0
- package/dist/mcp-doctor.d.ts +121 -0
- package/dist/mcp-doctor.js +249 -0
- package/dist/model-scan.d.ts +116 -0
- package/dist/model-scan.js +226 -0
- package/dist/onchain-tune.d.ts +164 -0
- package/dist/onchain-tune.js +346 -0
- package/dist/permissions-suggest.d.ts +126 -0
- package/dist/permissions-suggest.js +333 -0
- package/dist/pii-tune.d.ts +107 -0
- package/dist/pii-tune.js +122 -0
- package/dist/propose.d.ts +117 -0
- package/dist/propose.js +184 -0
- package/dist/refresh-goldens.d.ts +82 -0
- package/dist/refresh-goldens.js +221 -0
- package/dist/regression-pin.d.ts +160 -0
- package/dist/regression-pin.js +281 -0
- package/dist/retention.d.ts +193 -0
- package/dist/retention.js +607 -0
- package/dist/retire.d.ts +118 -0
- package/dist/retire.js +291 -0
- package/dist/right-size.d.ts +100 -0
- package/dist/right-size.js +123 -0
- package/dist/route.d.ts +19 -0
- package/dist/route.js +90 -0
- package/dist/scaffold-evals.d.ts +138 -0
- package/dist/scaffold-evals.js +410 -0
- package/dist/scope-audit-drift.d.ts +139 -0
- package/dist/scope-audit-drift.js +260 -0
- package/dist/security-corpus.d.ts +237 -0
- package/dist/security-corpus.js +516 -0
- package/dist/security-digest.d.ts +174 -0
- package/dist/security-digest.js +656 -0
- package/dist/sessions-index.d.ts +27 -0
- package/dist/sessions-index.js +51 -0
- package/dist/slo-doctor.d.ts +67 -0
- package/dist/slo-doctor.js +119 -0
- package/dist/slo-sink.d.ts +96 -0
- package/dist/slo-sink.js +107 -0
- package/dist/spec-changelog.d.ts +102 -0
- package/dist/spec-changelog.js +237 -0
- package/dist/state-backup.d.ts +223 -0
- package/dist/state-backup.js +648 -0
- package/dist/tools-cli.d.ts +170 -0
- package/dist/tools-cli.js +300 -0
- package/dist/triage.d.ts +202 -0
- package/dist/triage.js +403 -0
- package/dist/upgrade.d.ts +57 -0
- package/dist/upgrade.js +113 -0
- package/dist/version.d.ts +6 -0
- package/dist/version.js +27 -0
- package/dist/voice-eval.d.ts +138 -0
- package/dist/voice-eval.js +309 -0
- package/dist/watch.d.ts +58 -0
- package/dist/watch.js +97 -0
- package/package.json +90 -65
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Item 14 — `crewhaus advise` rule library: the pure, side-effect-free half
|
|
3
|
+
* of the trace-mining spec advisor. Aggregates session JSONLs (including the
|
|
4
|
+
* advisor kinds runtime-core now persists — `recovery`, `tool_stats`,
|
|
5
|
+
* `permission`, `model_meta`) plus `.crewhaus/audit` records into an
|
|
6
|
+
* `AdviceContext`, then runs a library of threshold rules over it. Each rule
|
|
7
|
+
* returns typed findings whose suggestion is either a pre-validated
|
|
8
|
+
* `SpecPatch` (consumable by a future `optimize --from-advice`) or free-form
|
|
9
|
+
* advice text.
|
|
10
|
+
*
|
|
11
|
+
* Everything here is pure so it is unit-testable; all filesystem access
|
|
12
|
+
* lives in `apps/cli/src/index.ts` (mirrors `feedback.ts` / `eval-history.ts`).
|
|
13
|
+
*
|
|
14
|
+
* Old-vintage logs (written before the advisor kinds existed) build an empty
|
|
15
|
+
* context slice for each missing kind and simply produce no findings — the
|
|
16
|
+
* rules only fire where the data now exists.
|
|
17
|
+
*/
|
|
18
|
+
import type { Spec } from "@crewhaus/spec";
|
|
19
|
+
import { type SpecPatch } from "@crewhaus/spec-patch";
|
|
20
|
+
export type AdviceSeverity = "info" | "warn";
|
|
21
|
+
export type AdviceSuggestion = {
|
|
22
|
+
readonly kind: "spec-patch";
|
|
23
|
+
readonly patch: SpecPatch;
|
|
24
|
+
} | {
|
|
25
|
+
readonly kind: "advice";
|
|
26
|
+
readonly text: string;
|
|
27
|
+
};
|
|
28
|
+
export type AdviceFinding = {
|
|
29
|
+
/** `<rule>` or `<rule>:<subject>` (e.g. `repeated-tool-failures:Fetch`). */
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly severity: AdviceSeverity;
|
|
32
|
+
/** One-line human summary of what tripped. */
|
|
33
|
+
readonly summary: string;
|
|
34
|
+
/** Human-readable evidence lines (counts, rates, example subjects). */
|
|
35
|
+
readonly evidence: ReadonlyArray<string>;
|
|
36
|
+
/** The numeric aggregates the rule fired on. */
|
|
37
|
+
readonly counts: Readonly<Record<string, number>>;
|
|
38
|
+
readonly suggestion: AdviceSuggestion;
|
|
39
|
+
};
|
|
40
|
+
export type ToolCallStats = {
|
|
41
|
+
calls: number;
|
|
42
|
+
errors: number;
|
|
43
|
+
totalDurationMs: number;
|
|
44
|
+
};
|
|
45
|
+
export type AskStats = {
|
|
46
|
+
asks: number;
|
|
47
|
+
approved: number;
|
|
48
|
+
denied: number;
|
|
49
|
+
};
|
|
50
|
+
/** Item 19 — per-errorName recovery aggregate: total occurrences plus the
|
|
51
|
+
* distribution of recovery actions that error drove. */
|
|
52
|
+
export type ErrorRecoveryStats = {
|
|
53
|
+
count: number;
|
|
54
|
+
/** action (`retry`/`compact`/`continue`/`tombstone`/`fail`) → occurrences. */
|
|
55
|
+
actions: Map<string, number>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Session-derived aggregates the rules consume. Built by
|
|
59
|
+
* `buildAdviceContext` from parsed session-JSONL objects (tolerant of
|
|
60
|
+
* old-vintage logs, malformed lines, and unknown kinds) plus optional
|
|
61
|
+
* `.crewhaus/audit` records.
|
|
62
|
+
*/
|
|
63
|
+
export type AdviceContext = {
|
|
64
|
+
readonly sessionIds: ReadonlyArray<string>;
|
|
65
|
+
/** Per-tool aggregate over `tool_stats` lines. */
|
|
66
|
+
readonly toolStats: ReadonlyMap<string, ToolCallStats>;
|
|
67
|
+
/** `recovery` lines grouped by action (`retry`/`compact`/`continue`/…). */
|
|
68
|
+
readonly recoveriesByAction: ReadonlyMap<string, number>;
|
|
69
|
+
/**
|
|
70
|
+
* Item 19 — `recovery` lines grouped by `errorName`, each carrying the
|
|
71
|
+
* action distribution that error drove. The failure-taxonomy rule clusters
|
|
72
|
+
* these into draft `failure_taxonomy` entries (error class → recovery
|
|
73
|
+
* action). Old-vintage logs (no recovery lines) leave this empty.
|
|
74
|
+
*/
|
|
75
|
+
readonly recoveriesByErrorName: ReadonlyMap<string, ErrorRecoveryStats>;
|
|
76
|
+
/**
|
|
77
|
+
* `action: "continue"` recoveries — emitted exclusively for
|
|
78
|
+
* `max_output_tokens` truncations (recovery-engine's taxonomy), so this
|
|
79
|
+
* IS the truncation-pressure count.
|
|
80
|
+
*/
|
|
81
|
+
readonly truncationContinues: number;
|
|
82
|
+
/**
|
|
83
|
+
* Item 19 — synthetic `[runtime] possible loop detected` nudges mined from
|
|
84
|
+
* `user_message` lines, grouped by tool signature. `matchNamedFailure`
|
|
85
|
+
* matches error.message only, so a loop (which is NOT an error — no
|
|
86
|
+
* exception is thrown) can never be caught by a taxonomy entry; the
|
|
87
|
+
* loop-break rule turns recurring signatures into instructions-addendum
|
|
88
|
+
* advice instead.
|
|
89
|
+
*/
|
|
90
|
+
readonly loopSignatures: ReadonlyMap<string, number>;
|
|
91
|
+
/** `compaction` lines per session (any vintage — this kind predates item 14). */
|
|
92
|
+
readonly compactionsBySession: ReadonlyMap<string, number>;
|
|
93
|
+
/** Resolved permission asks per tool, from `permission` lines. */
|
|
94
|
+
readonly asksByTool: ReadonlyMap<string, AskStats>;
|
|
95
|
+
/** Stop-reason distribution over `model_meta` lines. */
|
|
96
|
+
readonly stopReasons: ReadonlyMap<string, number>;
|
|
97
|
+
readonly modelResponses: number;
|
|
98
|
+
/**
|
|
99
|
+
* Item 21 — per-tool total byte spend (tool_use input JSON + the correlated
|
|
100
|
+
* tool_result content), keyed by the PascalCase runtime tool name. The
|
|
101
|
+
* sub-agent-split rule uses the dominance of one tool's byte spend as the
|
|
102
|
+
* per-turn-token-pressure proxy (a tool that dominates context is the one
|
|
103
|
+
* to move behind its own window). Empty on old-vintage logs.
|
|
104
|
+
*/
|
|
105
|
+
readonly perToolBytes: ReadonlyMap<string, number>;
|
|
106
|
+
/** Item 21 — total observed tool byte spend across all tools (the
|
|
107
|
+
* denominator for the dominance ratio). */
|
|
108
|
+
readonly totalToolBytes: number;
|
|
109
|
+
/** `.crewhaus/audit` record kinds → counts (report context + future rules). */
|
|
110
|
+
readonly auditKindCounts: ReadonlyMap<string, number>;
|
|
111
|
+
};
|
|
112
|
+
export type SessionEvents = {
|
|
113
|
+
readonly sessionId: string;
|
|
114
|
+
readonly objects: ReadonlyArray<unknown>;
|
|
115
|
+
};
|
|
116
|
+
/** Parse a JSONL blob into objects, skipping blank/malformed lines —
|
|
117
|
+
* a session log must never abort mining over one corrupt line. */
|
|
118
|
+
export declare function parseJsonlObjects(text: string): unknown[];
|
|
119
|
+
/** The fixed prefix the runtime stamps on a loop-detection nudge (a
|
|
120
|
+
* `user_message` with `synthetic: true`). Exported so a fixture/test can
|
|
121
|
+
* build a realistic nudge without hard-coding the string twice. */
|
|
122
|
+
export declare const LOOP_NUDGE_PREFIX = "[runtime] possible loop detected:";
|
|
123
|
+
/**
|
|
124
|
+
* Item 19 — extract a loop signature (the looping tool name) from a
|
|
125
|
+
* `user_message` payload's `content` when it is a runtime loop-detection
|
|
126
|
+
* nudge, else undefined. The nudge content is the fixed string
|
|
127
|
+
* `[runtime] possible loop detected: tool "<name>" has been called …`.
|
|
128
|
+
* Returns `tool:<name>` so recurring loops on the same tool cluster; falls
|
|
129
|
+
* back to a generic `loop` signature when the tool name can't be parsed.
|
|
130
|
+
*/
|
|
131
|
+
export declare function loopSignatureOf(content: unknown): string | undefined;
|
|
132
|
+
/** Tolerantly read a session-JSONL line's payload when its `kind` matches —
|
|
133
|
+
* the canonical defensive accessor shared with `context-pressure.ts`
|
|
134
|
+
* (`doctor --context-pressure` folds the same persisted events). */
|
|
135
|
+
export declare function payloadOf(obj: unknown, kind: string): Record<string, unknown> | undefined;
|
|
136
|
+
/**
|
|
137
|
+
* Fold parsed session objects (and optional audit records) into the
|
|
138
|
+
* aggregates the rules consume. Every field access is defensive: missing
|
|
139
|
+
* payloads, wrong-typed fields, and unknown kinds are skipped, so
|
|
140
|
+
* old-vintage logs (no advisor kinds) and future kinds both pass through
|
|
141
|
+
* cleanly.
|
|
142
|
+
*/
|
|
143
|
+
export declare function buildAdviceContext(sessions: ReadonlyArray<SessionEvents>, auditObjects?: ReadonlyArray<unknown>): AdviceContext;
|
|
144
|
+
export type AdviceThresholds = {
|
|
145
|
+
/** Minimum calls before a tool's error rate is judged at all. */
|
|
146
|
+
toolFailureMinCalls: number;
|
|
147
|
+
/** Error rate (errors/calls) at/above which the failure rule fires. */
|
|
148
|
+
toolFailureRate: number;
|
|
149
|
+
/** `continue` recoveries at/above which truncation pressure fires. */
|
|
150
|
+
truncationContinues: number;
|
|
151
|
+
/** Compactions in a single session at/above which thrash fires. */
|
|
152
|
+
compactionsPerSession: number;
|
|
153
|
+
/** Resolved asks per tool at/above which churn is judged. */
|
|
154
|
+
asksPerTool: number;
|
|
155
|
+
/** Minimum model responses before stop reasons are judged at all. */
|
|
156
|
+
stopMinResponses: number;
|
|
157
|
+
/** Anomalous-stop rate at/above which the stop rule fires. */
|
|
158
|
+
stopAnomalyRate: number;
|
|
159
|
+
/** Item 19 — occurrences of one error CLASS at/above which a
|
|
160
|
+
* failure_taxonomy entry is drafted. */
|
|
161
|
+
recoveryClusterMin: number;
|
|
162
|
+
/** Item 19 — occurrences of one loop SIGNATURE at/above which loop-break
|
|
163
|
+
* instructions advice fires. */
|
|
164
|
+
loopSignatureMin: number;
|
|
165
|
+
/** Item 21 — sessions that must each compact ≥ compactionsPerSession
|
|
166
|
+
* before a sub-agent restructure is suggested (chronic, not one-off). */
|
|
167
|
+
chronicCompactionSessions: number;
|
|
168
|
+
/** Item 21 — fraction of total tool byte-spend one tool must dominate for a
|
|
169
|
+
* sub-agent split to be suggested on the dominance signal. */
|
|
170
|
+
toolByteDominance: number;
|
|
171
|
+
/** Item 21 — minimum total tool bytes before dominance is judged at all
|
|
172
|
+
* (a handful of tiny calls shouldn't trip a restructure). */
|
|
173
|
+
toolByteMinTotal: number;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Canonical rule thresholds. runtime-core's in-run digest
|
|
177
|
+
* (observability.ts DIGEST_THRESHOLDS) mirrors these — it cannot import
|
|
178
|
+
* them (apps/cli depends on runtime-core, not vice versa), so keep the two
|
|
179
|
+
* in sync when tuning.
|
|
180
|
+
*/
|
|
181
|
+
export declare const DEFAULT_ADVICE_THRESHOLDS: AdviceThresholds;
|
|
182
|
+
/** Stop reasons that are part of healthy operation; everything else
|
|
183
|
+
* (max_tokens, refusal, pause_turn, …) counts as anomalous. Mirrored by
|
|
184
|
+
* runtime-core's digest tally. */
|
|
185
|
+
export declare const CLEAN_STOP_REASONS: ReadonlySet<string>;
|
|
186
|
+
export type RuleOptions = {
|
|
187
|
+
/** The cwd spec, when one exists — enables patch suggestions. */
|
|
188
|
+
readonly spec?: Spec;
|
|
189
|
+
readonly thresholds?: Partial<AdviceThresholds>;
|
|
190
|
+
};
|
|
191
|
+
export type AdviceRule = (ctx: AdviceContext, opts?: RuleOptions) => AdviceFinding[];
|
|
192
|
+
/**
|
|
193
|
+
* Repeated tool failures: a tool with ≥ minCalls whose error rate crosses
|
|
194
|
+
* the threshold. Advice-only by design — `tool_config` is not in
|
|
195
|
+
* OPTIMIZABLE_PATHS (the whitelist is the autotune safety floor), so the
|
|
196
|
+
* suggestion points at the spec's `tool_config` block when one exists for
|
|
197
|
+
* the tool instead of emitting a patch. NOTE: `tool_stats.isError` includes
|
|
198
|
+
* permission-denied results; the churn rule covers the ask side of that.
|
|
199
|
+
*/
|
|
200
|
+
export declare const ruleRepeatedToolFailures: AdviceRule;
|
|
201
|
+
/**
|
|
202
|
+
* Truncation pressure: `continue` recoveries (always max_output_tokens) at
|
|
203
|
+
* or above the threshold. Suggests a SpecPatch bumping `agent.max_tokens`
|
|
204
|
+
* (whitelisted in OPTIMIZABLE_PATHS): double the spec's current value, or
|
|
205
|
+
* add 16384 (2× the runtime's 8192 default) when the spec doesn't set one.
|
|
206
|
+
*/
|
|
207
|
+
export declare const ruleTruncationPressure: AdviceRule;
|
|
208
|
+
/**
|
|
209
|
+
* Compaction thrash: any single session compacting ≥ threshold times.
|
|
210
|
+
* ADVICE-ONLY — no auto-applicable SpecPatch. `compaction.curate` is listed
|
|
211
|
+
* in OPTIMIZABLE_PATHS and lowers to IR (`packages/ir/src/index.ts`,
|
|
212
|
+
* `IrCompaction.curate`), but no target emitter or runtime-core path
|
|
213
|
+
* actually consumes it yet (see the IR field's doc comment). A patch that
|
|
214
|
+
* flips a runtime no-op would pass the `optimize --from-advice` eval gate
|
|
215
|
+
* trivially (inert change → equal pass rate) and get written into the
|
|
216
|
+
* user's spec while changing nothing, so this rule surfaces the finding as
|
|
217
|
+
* a warning with concrete alternatives instead of proposing `curate: true`.
|
|
218
|
+
* `compaction.threshold` is ALSO whitelisted, but the strict spec schema
|
|
219
|
+
* carries no such key today, so a threshold patch could never apply either.
|
|
220
|
+
*/
|
|
221
|
+
export declare const ruleCompactionThrash: AdviceRule;
|
|
222
|
+
/**
|
|
223
|
+
* Permission churn: a tool prompting ≥ threshold times with 100% approved
|
|
224
|
+
* outcomes. NEVER a patch — permissions are excluded from OPTIMIZABLE_PATHS
|
|
225
|
+
* by design (an optimizer must not be able to widen its own permissions);
|
|
226
|
+
* the human gets the alwaysAllow one-liner with the evidence instead.
|
|
227
|
+
*/
|
|
228
|
+
export declare const rulePermissionChurn: AdviceRule;
|
|
229
|
+
/**
|
|
230
|
+
* Stop-reason anomalies: a high rate of stops outside CLEAN_STOP_REASONS
|
|
231
|
+
* (end_turn / tool_use / stop_sequence are healthy; max_tokens, refusal,
|
|
232
|
+
* pause_turn, … are not). Advice-only — the right fix depends on which
|
|
233
|
+
* reason dominates.
|
|
234
|
+
*/
|
|
235
|
+
export declare const ruleStopReasonAnomalies: AdviceRule;
|
|
236
|
+
/** One drafted failure_taxonomy entry (shape = the spec's entry schema:
|
|
237
|
+
* `{ class, pattern, recovery, hint? }`). */
|
|
238
|
+
export type FailureTaxonomyEntry = {
|
|
239
|
+
readonly class: string;
|
|
240
|
+
readonly pattern: string;
|
|
241
|
+
readonly recovery: string;
|
|
242
|
+
readonly hint?: string;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Item 19 — specificity floor for a drafted taxonomy `pattern`. The pattern is
|
|
246
|
+
* `errorName` verbatim, matched by the recovery engine as a case-insensitive
|
|
247
|
+
* SUBSTRING of `error.message`. A very short or generic name (e.g. "Error")
|
|
248
|
+
* drafts a rule that fires on almost every failure — worse than no entry. Such
|
|
249
|
+
* clusters are surfaced as ADVICE (a human should hand-write a precise pattern)
|
|
250
|
+
* rather than drafted into a patch.
|
|
251
|
+
*/
|
|
252
|
+
export declare const TAXONOMY_MIN_PATTERN_LEN = 4;
|
|
253
|
+
/** Generic error tokens too broad to auto-draft, regardless of length. */
|
|
254
|
+
export declare const TAXONOMY_GENERIC_TOKENS: ReadonlySet<string>;
|
|
255
|
+
/** True when `errorName` is too broad to draft a taxonomy pattern for
|
|
256
|
+
* (too short, or a generic token). Case-insensitive. */
|
|
257
|
+
export declare function taxonomyPatternTooBroad(errorName: string): boolean;
|
|
258
|
+
/**
|
|
259
|
+
* Item 19 — failure-taxonomy learning. Clusters recurring `recovery` events
|
|
260
|
+
* by `errorName`; each class seen ≥ recoveryClusterMin times (and NOT already
|
|
261
|
+
* covered by the spec's taxonomy) becomes a draft `failure_taxonomy` entry
|
|
262
|
+
* whose `recovery` action is the one the runtime actually took most for that
|
|
263
|
+
* class, and whose `pattern` is a case-insensitive substring of the error
|
|
264
|
+
* name.
|
|
265
|
+
*
|
|
266
|
+
* `failure_taxonomy` IS whitelisted in OPTIMIZABLE_PATHS for every target, so
|
|
267
|
+
* the emitted patch rides the eval-gated `optimize --from-advice` apply. The
|
|
268
|
+
* patch REPLACES the whole `failure_taxonomy` array (existing entries +
|
|
269
|
+
* drafts) when the spec already has one, else ADDS the array — a whole-block
|
|
270
|
+
* edit the whitelist's prefix match allows. Budget caps aren't a field on the
|
|
271
|
+
* strict entry schema (`{ class, pattern, recovery, hint? }`), so the drafted
|
|
272
|
+
* `hint` carries the observed count + the "matches error.message" caveat and
|
|
273
|
+
* the recovery-engine's per-turn budget note.
|
|
274
|
+
*/
|
|
275
|
+
export declare const ruleFailureTaxonomy: AdviceRule;
|
|
276
|
+
/**
|
|
277
|
+
* Item 19 — loop-break learning. A `[runtime] possible loop detected` nudge
|
|
278
|
+
* is NOT an error (no exception is thrown), so `matchNamedFailure` — which
|
|
279
|
+
* matches error.message only — can never catch it; a taxonomy entry is the
|
|
280
|
+
* wrong tool. This rule instead drafts an instructions-ADDENDUM as advice
|
|
281
|
+
* text (never a patch: `agent.instructions` IS optimizable, but a
|
|
282
|
+
* mechanically-appended nudge is a prompt edit a human should own, and the
|
|
283
|
+
* optimizer already rewrites instructions on its own signal). Fires per
|
|
284
|
+
* recurring loop signature (same tool looped in ≥ loopSignatureMin sessions/
|
|
285
|
+
* turns).
|
|
286
|
+
*/
|
|
287
|
+
export declare const ruleLoopBreak: AdviceRule;
|
|
288
|
+
/**
|
|
289
|
+
* Targets whose AGENT block carries a `sub_agents:` map, so the drafted
|
|
290
|
+
* fragment (which sits under `agent:`) pastes in verbatim: cli and channel.
|
|
291
|
+
* Crew ALSO has sub_agents, but under each ROLE rather than a single `agent`
|
|
292
|
+
* block, so the paste location differs — it's excluded here rather than emit a
|
|
293
|
+
* fragment that lands in the wrong place. Any other target has no sub_agents
|
|
294
|
+
* block at all, so the rule stays silent (nowhere to paste).
|
|
295
|
+
*/
|
|
296
|
+
export declare const SUB_AGENT_TARGETS: ReadonlySet<string>;
|
|
297
|
+
/** Draft a ready-to-paste `sub_agents:` YAML fragment moving `toolName`'s
|
|
298
|
+
* concern into its own sub-agent with its own context window. Two-space
|
|
299
|
+
* indented to sit under the spec's `agent:` block (cli/channel) — the CLI
|
|
300
|
+
* prints it verbatim in the advice text. */
|
|
301
|
+
export declare function subAgentFragment(toolName: string): string;
|
|
302
|
+
/**
|
|
303
|
+
* Item 21 — suggest a sub-agent split when context pressure is chronic:
|
|
304
|
+
* either the mined sessions ROUTINELY compact (≥ chronicCompactionSessions
|
|
305
|
+
* sessions each compacting ≥ compactionsPerSession times) OR one tool/concern
|
|
306
|
+
* DOMINATES tool byte-spend (≥ toolByteDominance of ≥ toolByteMinTotal total
|
|
307
|
+
* bytes). Moving the heavy concern behind a sub-agent's own context window
|
|
308
|
+
* relieves the parent.
|
|
309
|
+
*
|
|
310
|
+
* STRICTLY suggest+scaffold — NEVER a patch: a structural change (adding a
|
|
311
|
+
* sub-agent + rewriting instructions) isn't eval-safe to auto-apply, so this
|
|
312
|
+
* emits advice text carrying a ready-to-paste `sub_agents:` fragment (the
|
|
313
|
+
* correct spec key — NOT `agents:`). Gated per target: only cli/channel/crew
|
|
314
|
+
* schemas have a `sub_agents` block; on any other target (or with no spec) the
|
|
315
|
+
* rule stays silent, since there's nowhere to paste it.
|
|
316
|
+
*/
|
|
317
|
+
export declare const ruleSubAgentSplit: AdviceRule;
|
|
318
|
+
export declare const ADVICE_RULES: ReadonlyArray<AdviceRule>;
|
|
319
|
+
/**
|
|
320
|
+
* Run every rule and rank the findings: warn before info, then by the
|
|
321
|
+
* magnitude of the primary count, then by id (deterministic output). Each
|
|
322
|
+
* emitted patch was already pre-validated by its rule via `patchOrAdvice`.
|
|
323
|
+
*/
|
|
324
|
+
export declare function runAdviceRules(ctx: AdviceContext, opts?: RuleOptions): AdviceFinding[];
|
|
325
|
+
export type SuggestionsFile = {
|
|
326
|
+
readonly generatedAt: string;
|
|
327
|
+
readonly sessionIds: ReadonlyArray<string>;
|
|
328
|
+
/** Only the findings whose suggestion is a validated SpecPatch. */
|
|
329
|
+
readonly suggestions: ReadonlyArray<{
|
|
330
|
+
readonly findingId: string;
|
|
331
|
+
readonly severity: AdviceSeverity;
|
|
332
|
+
readonly summary: string;
|
|
333
|
+
readonly patch: SpecPatch;
|
|
334
|
+
}>;
|
|
335
|
+
};
|
|
336
|
+
/** The `suggestions.json` payload — the SpecPatch list a future
|
|
337
|
+
* `optimize --from-advice` consumes. Advice-only findings are report-only. */
|
|
338
|
+
export declare function buildSuggestionsFile(findings: ReadonlyArray<AdviceFinding>, sessionIds: ReadonlyArray<string>, generatedAt: string): SuggestionsFile;
|
|
339
|
+
export declare function escapeHtml(s: string): string;
|
|
340
|
+
/** Self-contained `report.html` for `crewhaus advise` — ranked findings with
|
|
341
|
+
* evidence and the suggested patch/advice per finding. */
|
|
342
|
+
export declare function renderAdviceHtml(input: {
|
|
343
|
+
readonly findings: ReadonlyArray<AdviceFinding>;
|
|
344
|
+
readonly sessionIds: ReadonlyArray<string>;
|
|
345
|
+
readonly generatedAt: string;
|
|
346
|
+
}): string;
|
|
347
|
+
/** One line per finding for the CLI's text mode. */
|
|
348
|
+
export declare function formatFindingLines(f: AdviceFinding): string[];
|