@mneme-ai/core 2.21.0 → 2.21.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.
@@ -0,0 +1,148 @@
1
+ /**
2
+ * v2.21.1 — STILLNESS PROTOCOL.
3
+ *
4
+ * "AI that decides when NOT to respond."
5
+ *
6
+ * Every AI vendor trains for "answer fast + be helpful." None train for
7
+ * "the right response right now is silence." This module is the gate
8
+ * the user installs in front of their AI agents to enforce structural
9
+ * silence under their own configured policy.
10
+ *
11
+ * Four production-grade primitives:
12
+ *
13
+ * 1. SILENCE BUDGET — per-user daily cap on AI utterances. When the
14
+ * budget is exhausted, AI literally cannot respond. Refreshes
15
+ * atomically at local midnight; the counter survives process
16
+ * restarts (.mneme/stillness/budget.json).
17
+ *
18
+ * 2. SILENCE RULES — declarative user-defined rules:
19
+ * match: { keywordsAll | keywordsAny | regex }
20
+ * when: { hours: "23:00-07:00", "afterNFailuresPerHour": N }
21
+ * action: silent | delay-hours-N | speak
22
+ * Rules evaluate in order; first match wins.
23
+ *
24
+ * 3. COOL-OFF RECEIPTS — HMAC-signed records of every declined
25
+ * response. The user reviews them later. Receipts capture:
26
+ * ts, prompt-hash (not the prompt itself), reason, reviewable-at.
27
+ *
28
+ * 4. CADENCE STATE INFERENCE — record inter-keystroke intervals from
29
+ * the IDE/editor hook; compute coefficient-of-variation (CV) of
30
+ * recent intervals; classify state:
31
+ * steady (0.2 <= CV <= 0.6) → ok
32
+ * agitated (CV > 0.8) → suggest SILENT
33
+ * robotic (CV < 0.15) → suggest SILENT (probable bot pasting)
34
+ * sparse (< 3 samples / minute) → ok (no signal)
35
+ *
36
+ * The gate composes all four: gate(prompt) returns SPEAK | SILENT |
37
+ * DELAY-N + a signed receipt the user reviews later.
38
+ *
39
+ * No vendor lock-in. No cloud. No new daemon — runs in-process.
40
+ */
41
+ export interface BudgetState {
42
+ v: 1;
43
+ /** Total utterances allowed in the rolling refresh window. */
44
+ maxUtterances: number;
45
+ /** "day" (UTC midnight) | "hour" (each hour boundary). */
46
+ refresh: "day" | "hour";
47
+ /** Counter consumed in current window. */
48
+ consumed: number;
49
+ /** Window start (ISO). */
50
+ windowStart: string;
51
+ }
52
+ export declare function getBudget(repoRoot: string, now?: Date): BudgetState;
53
+ export interface SetBudgetOptions {
54
+ maxUtterances?: number;
55
+ refresh?: BudgetState["refresh"];
56
+ /** Reset counter to zero. */
57
+ reset?: boolean;
58
+ }
59
+ export declare function setBudget(repoRoot: string, opts: SetBudgetOptions): BudgetState;
60
+ /** Atomic-ish increment + check. Returns true when consumption succeeded
61
+ * (budget had room) or false when budget was exhausted. */
62
+ export declare function consumeBudget(repoRoot: string, n?: number): {
63
+ ok: boolean;
64
+ remaining: number;
65
+ state: BudgetState;
66
+ };
67
+ export interface SilenceRule {
68
+ v: 1;
69
+ id: string;
70
+ /** Plain-English rationale (shown in receipts). */
71
+ rationale: string;
72
+ /** Matchers — ALL must hit for the rule to fire. */
73
+ match: {
74
+ keywordsAll?: string[];
75
+ keywordsAny?: string[];
76
+ regex?: string;
77
+ };
78
+ /** Optional time-window gate. "23:00-07:00" means active during those
79
+ * hours (UTC); rule only fires in this window. */
80
+ hoursWindow?: string;
81
+ /** What to do when the rule fires. */
82
+ action: "silent" | {
83
+ delayHours: number;
84
+ };
85
+ }
86
+ export declare function addRule(repoRoot: string, rule: Omit<SilenceRule, "v" | "id">): SilenceRule;
87
+ export declare function listRules(repoRoot: string): SilenceRule[];
88
+ export declare function removeRule(repoRoot: string, ruleId: string): boolean;
89
+ export interface Receipt {
90
+ v: 1;
91
+ ts: string;
92
+ decision: "silent" | "delay" | "speak";
93
+ reason: string;
94
+ /** sha256 of the prompt (not the prompt itself — preserves privacy). */
95
+ promptSha: string;
96
+ /** When the user CAN re-ask (set when decision is "delay"). */
97
+ reviewableAt?: string;
98
+ /** Which rule fired (when applicable). */
99
+ ruleId?: string;
100
+ sig: string;
101
+ }
102
+ export declare function listReceipts(repoRoot: string, sinceMs?: number): Receipt[];
103
+ export declare function verifyReceipt(repoRoot: string, r: Receipt): boolean;
104
+ export interface CadenceSample {
105
+ ts: string;
106
+ /** Inter-keystroke interval in ms. */
107
+ intervalMs: number;
108
+ }
109
+ export type CadenceState = "steady" | "agitated" | "robotic" | "sparse";
110
+ export interface CadenceVerdict {
111
+ state: CadenceState;
112
+ /** Coefficient of variation of recent intervals. */
113
+ cv: number;
114
+ /** Number of samples used. */
115
+ samples: number;
116
+ /** Should the gate suggest SILENT given this verdict? */
117
+ shouldSilence: boolean;
118
+ }
119
+ export declare function recordCadence(repoRoot: string, intervalsMs: number[]): void;
120
+ /** Read the most recent N cadence samples + compute the verdict.
121
+ * Uses Coefficient-of-Variation (CV = stddev / mean) as the state
122
+ * signal — robust to per-user typing speed differences. */
123
+ export declare function inferCadenceState(repoRoot: string, lastN?: number): CadenceVerdict;
124
+ export interface GateOptions {
125
+ prompt: string;
126
+ /** Skip budget check (useful for diagnostic / preview calls). */
127
+ skipBudget?: boolean;
128
+ /** Skip cadence inference. */
129
+ skipCadence?: boolean;
130
+ /** Override "now" — test injection. */
131
+ now?: Date;
132
+ }
133
+ export interface GateDecision {
134
+ decision: "speak" | "silent" | "delay";
135
+ reason: string;
136
+ receipt: Receipt;
137
+ /** When decision = delay, the ISO of when the AI may try again. */
138
+ reviewableAt?: string;
139
+ /** Budget remaining if decision = speak (so caller can show it). */
140
+ remainingBudget?: number;
141
+ }
142
+ /** Headline verb. Composes the four primitives into a single SPEAK |
143
+ * SILENT | DELAY decision with a signed receipt. */
144
+ export declare function gate(repoRoot: string, opts: GateOptions): GateDecision;
145
+ export declare function formatBudget(b: BudgetState): string;
146
+ export declare function formatDecision(d: GateDecision): string;
147
+ export declare function formatVerdict(v: CadenceVerdict): string;
148
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stillness/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,365 @@
1
+ /**
2
+ * v2.21.1 — STILLNESS PROTOCOL.
3
+ *
4
+ * "AI that decides when NOT to respond."
5
+ *
6
+ * Every AI vendor trains for "answer fast + be helpful." None train for
7
+ * "the right response right now is silence." This module is the gate
8
+ * the user installs in front of their AI agents to enforce structural
9
+ * silence under their own configured policy.
10
+ *
11
+ * Four production-grade primitives:
12
+ *
13
+ * 1. SILENCE BUDGET — per-user daily cap on AI utterances. When the
14
+ * budget is exhausted, AI literally cannot respond. Refreshes
15
+ * atomically at local midnight; the counter survives process
16
+ * restarts (.mneme/stillness/budget.json).
17
+ *
18
+ * 2. SILENCE RULES — declarative user-defined rules:
19
+ * match: { keywordsAll | keywordsAny | regex }
20
+ * when: { hours: "23:00-07:00", "afterNFailuresPerHour": N }
21
+ * action: silent | delay-hours-N | speak
22
+ * Rules evaluate in order; first match wins.
23
+ *
24
+ * 3. COOL-OFF RECEIPTS — HMAC-signed records of every declined
25
+ * response. The user reviews them later. Receipts capture:
26
+ * ts, prompt-hash (not the prompt itself), reason, reviewable-at.
27
+ *
28
+ * 4. CADENCE STATE INFERENCE — record inter-keystroke intervals from
29
+ * the IDE/editor hook; compute coefficient-of-variation (CV) of
30
+ * recent intervals; classify state:
31
+ * steady (0.2 <= CV <= 0.6) → ok
32
+ * agitated (CV > 0.8) → suggest SILENT
33
+ * robotic (CV < 0.15) → suggest SILENT (probable bot pasting)
34
+ * sparse (< 3 samples / minute) → ok (no signal)
35
+ *
36
+ * The gate composes all four: gate(prompt) returns SPEAK | SILENT |
37
+ * DELAY-N + a signed receipt the user reviews later.
38
+ *
39
+ * No vendor lock-in. No cloud. No new daemon — runs in-process.
40
+ */
41
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from "node:fs";
42
+ import { join } from "node:path";
43
+ import { createHmac, createHash, randomBytes } from "node:crypto";
44
+ const DIR = ".mneme/stillness";
45
+ const BUDGET = "budget.json";
46
+ const RULES = "rules.jsonl";
47
+ const RECEIPTS = "receipts.jsonl";
48
+ const CADENCE = "cadence.jsonl";
49
+ const KEY = "stillness.key";
50
+ // ─── STORAGE ────────────────────────────────────────────────────────────
51
+ function ensureDir(repoRoot) {
52
+ const d = join(repoRoot, DIR);
53
+ if (!existsSync(d))
54
+ mkdirSync(d, { recursive: true });
55
+ return d;
56
+ }
57
+ function ensureKey(repoRoot) {
58
+ const d = ensureDir(repoRoot);
59
+ const p = join(d, KEY);
60
+ if (existsSync(p))
61
+ return readFileSync(p, "utf8").trim();
62
+ const k = randomBytes(32).toString("base64url");
63
+ writeFileSync(p, k, "utf8");
64
+ return k;
65
+ }
66
+ function sign(payload, key) {
67
+ return createHmac("sha256", key).update(payload).digest("base64url").slice(0, 22);
68
+ }
69
+ const DEFAULT_MAX_UTTERANCES = 200;
70
+ const DEFAULT_REFRESH = "day";
71
+ function budgetPath(repoRoot) { return join(ensureDir(repoRoot), BUDGET); }
72
+ function currentWindowStart(refresh, now = new Date()) {
73
+ if (refresh === "hour") {
74
+ const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours()));
75
+ return d.toISOString();
76
+ }
77
+ // day boundary at UTC midnight.
78
+ const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
79
+ return d.toISOString();
80
+ }
81
+ export function getBudget(repoRoot, now = new Date()) {
82
+ const p = budgetPath(repoRoot);
83
+ let state;
84
+ if (!existsSync(p)) {
85
+ state = { v: 1, maxUtterances: DEFAULT_MAX_UTTERANCES, refresh: DEFAULT_REFRESH, consumed: 0, windowStart: currentWindowStart(DEFAULT_REFRESH, now) };
86
+ writeFileSync(p, JSON.stringify(state, null, 2), "utf8");
87
+ return state;
88
+ }
89
+ try {
90
+ state = JSON.parse(readFileSync(p, "utf8"));
91
+ }
92
+ catch {
93
+ state = { v: 1, maxUtterances: DEFAULT_MAX_UTTERANCES, refresh: DEFAULT_REFRESH, consumed: 0, windowStart: currentWindowStart(DEFAULT_REFRESH, now) };
94
+ }
95
+ // Auto-refresh at window boundary.
96
+ const expected = currentWindowStart(state.refresh, now);
97
+ if (state.windowStart !== expected) {
98
+ state.windowStart = expected;
99
+ state.consumed = 0;
100
+ writeFileSync(p, JSON.stringify(state, null, 2), "utf8");
101
+ }
102
+ return state;
103
+ }
104
+ export function setBudget(repoRoot, opts) {
105
+ const state = getBudget(repoRoot);
106
+ if (typeof opts.maxUtterances === "number")
107
+ state.maxUtterances = Math.max(0, opts.maxUtterances);
108
+ if (opts.refresh)
109
+ state.refresh = opts.refresh;
110
+ if (opts.reset) {
111
+ state.consumed = 0;
112
+ state.windowStart = currentWindowStart(state.refresh);
113
+ }
114
+ writeFileSync(budgetPath(repoRoot), JSON.stringify(state, null, 2), "utf8");
115
+ return state;
116
+ }
117
+ /** Atomic-ish increment + check. Returns true when consumption succeeded
118
+ * (budget had room) or false when budget was exhausted. */
119
+ export function consumeBudget(repoRoot, n = 1) {
120
+ const state = getBudget(repoRoot);
121
+ const room = state.maxUtterances - state.consumed;
122
+ if (room < n)
123
+ return { ok: false, remaining: Math.max(0, room), state };
124
+ state.consumed += n;
125
+ writeFileSync(budgetPath(repoRoot), JSON.stringify(state, null, 2), "utf8");
126
+ return { ok: true, remaining: state.maxUtterances - state.consumed, state };
127
+ }
128
+ function rulesPath(repoRoot) { return join(ensureDir(repoRoot), RULES); }
129
+ export function addRule(repoRoot, rule) {
130
+ const full = { v: 1, id: "rule_" + randomBytes(4).toString("hex"), ...rule };
131
+ appendFileSync(rulesPath(repoRoot), JSON.stringify(full) + "\n", "utf8");
132
+ return full;
133
+ }
134
+ export function listRules(repoRoot) {
135
+ const p = rulesPath(repoRoot);
136
+ if (!existsSync(p))
137
+ return [];
138
+ try {
139
+ return readFileSync(p, "utf8").trim().split("\n").map((l) => { try {
140
+ return JSON.parse(l);
141
+ }
142
+ catch {
143
+ return null;
144
+ } }).filter((r) => !!r);
145
+ }
146
+ catch {
147
+ return [];
148
+ }
149
+ }
150
+ export function removeRule(repoRoot, ruleId) {
151
+ const rules = listRules(repoRoot).filter((r) => r.id !== ruleId);
152
+ writeFileSync(rulesPath(repoRoot), rules.map((r) => JSON.stringify(r)).join("\n") + (rules.length > 0 ? "\n" : ""), "utf8");
153
+ return true;
154
+ }
155
+ function isInHoursWindow(window, now = new Date()) {
156
+ const m = /^(\d{1,2}):(\d{2})-(\d{1,2}):(\d{2})$/.exec(window);
157
+ if (!m)
158
+ return true;
159
+ const hh1 = parseInt(m[1], 10), mm1 = parseInt(m[2], 10);
160
+ const hh2 = parseInt(m[3], 10), mm2 = parseInt(m[4], 10);
161
+ const nowMin = now.getUTCHours() * 60 + now.getUTCMinutes();
162
+ const a = hh1 * 60 + mm1;
163
+ const b = hh2 * 60 + mm2;
164
+ if (a < b)
165
+ return nowMin >= a && nowMin <= b;
166
+ // Wraps midnight: e.g. 23:00-07:00.
167
+ return nowMin >= a || nowMin <= b;
168
+ }
169
+ function ruleMatches(rule, prompt, now = new Date()) {
170
+ if (rule.hoursWindow && !isInHoursWindow(rule.hoursWindow, now))
171
+ return false;
172
+ const lower = prompt.toLowerCase();
173
+ if (rule.match.keywordsAll) {
174
+ for (const k of rule.match.keywordsAll)
175
+ if (!lower.includes(k.toLowerCase()))
176
+ return false;
177
+ }
178
+ if (rule.match.keywordsAny) {
179
+ let any = false;
180
+ for (const k of rule.match.keywordsAny)
181
+ if (lower.includes(k.toLowerCase())) {
182
+ any = true;
183
+ break;
184
+ }
185
+ if (!any)
186
+ return false;
187
+ }
188
+ if (rule.match.regex) {
189
+ try {
190
+ const re = new RegExp(rule.match.regex, "i");
191
+ if (!re.test(prompt))
192
+ return false;
193
+ }
194
+ catch {
195
+ return false;
196
+ }
197
+ }
198
+ // If none of the matchers were configured, the rule is vacuous → no match.
199
+ if (!rule.match.keywordsAll && !rule.match.keywordsAny && !rule.match.regex)
200
+ return false;
201
+ return true;
202
+ }
203
+ function receiptsPath(repoRoot) { return join(ensureDir(repoRoot), RECEIPTS); }
204
+ function writeReceipt(repoRoot, rec) {
205
+ const key = ensureKey(repoRoot);
206
+ const canonical = `${rec.v}|${rec.ts}|${rec.decision}|${rec.reason}|${rec.promptSha}|${rec.reviewableAt ?? ""}|${rec.ruleId ?? ""}`;
207
+ const sig = sign(canonical, key);
208
+ const full = { ...rec, sig };
209
+ appendFileSync(receiptsPath(repoRoot), JSON.stringify(full) + "\n", "utf8");
210
+ return full;
211
+ }
212
+ export function listReceipts(repoRoot, sinceMs) {
213
+ const p = receiptsPath(repoRoot);
214
+ if (!existsSync(p))
215
+ return [];
216
+ try {
217
+ const all = readFileSync(p, "utf8").trim().split("\n").map((l) => { try {
218
+ return JSON.parse(l);
219
+ }
220
+ catch {
221
+ return null;
222
+ } }).filter((r) => !!r);
223
+ if (!sinceMs)
224
+ return all;
225
+ return all.filter((r) => new Date(r.ts).getTime() >= sinceMs);
226
+ }
227
+ catch {
228
+ return [];
229
+ }
230
+ }
231
+ export function verifyReceipt(repoRoot, r) {
232
+ const key = ensureKey(repoRoot);
233
+ const canonical = `${r.v}|${r.ts}|${r.decision}|${r.reason}|${r.promptSha}|${r.reviewableAt ?? ""}|${r.ruleId ?? ""}`;
234
+ return sign(canonical, key) === r.sig;
235
+ }
236
+ function cadencePath(repoRoot) { return join(ensureDir(repoRoot), CADENCE); }
237
+ export function recordCadence(repoRoot, intervalsMs) {
238
+ const dir = ensureDir(repoRoot);
239
+ const ts = new Date().toISOString();
240
+ for (const interval of intervalsMs) {
241
+ if (!Number.isFinite(interval) || interval < 0)
242
+ continue;
243
+ appendFileSync(join(dir, CADENCE), JSON.stringify({ ts, intervalMs: interval }) + "\n", "utf8");
244
+ }
245
+ }
246
+ /** Read the most recent N cadence samples + compute the verdict.
247
+ * Uses Coefficient-of-Variation (CV = stddev / mean) as the state
248
+ * signal — robust to per-user typing speed differences. */
249
+ export function inferCadenceState(repoRoot, lastN = 50) {
250
+ const p = cadencePath(repoRoot);
251
+ if (!existsSync(p))
252
+ return { state: "sparse", cv: 0, samples: 0, shouldSilence: false };
253
+ let samples = [];
254
+ try {
255
+ samples = readFileSync(p, "utf8").trim().split("\n").map((l) => { try {
256
+ return JSON.parse(l);
257
+ }
258
+ catch {
259
+ return null;
260
+ } }).filter((s) => !!s);
261
+ }
262
+ catch {
263
+ return { state: "sparse", cv: 0, samples: 0, shouldSilence: false };
264
+ }
265
+ const recent = samples.slice(-lastN);
266
+ if (recent.length < 3)
267
+ return { state: "sparse", cv: 0, samples: recent.length, shouldSilence: false };
268
+ const intervals = recent.map((r) => r.intervalMs);
269
+ const mean = intervals.reduce((s, v) => s + v, 0) / intervals.length;
270
+ if (mean <= 0)
271
+ return { state: "sparse", cv: 0, samples: recent.length, shouldSilence: false };
272
+ const variance = intervals.reduce((s, v) => s + (v - mean) ** 2, 0) / intervals.length;
273
+ const stddev = Math.sqrt(variance);
274
+ const cv = stddev / mean;
275
+ let state = "steady";
276
+ let shouldSilence = false;
277
+ if (cv > 0.8) {
278
+ state = "agitated";
279
+ shouldSilence = true;
280
+ }
281
+ else if (cv < 0.15) {
282
+ state = "robotic";
283
+ shouldSilence = true;
284
+ }
285
+ return { state, cv: Number(cv.toFixed(3)), samples: recent.length, shouldSilence };
286
+ }
287
+ /** Headline verb. Composes the four primitives into a single SPEAK |
288
+ * SILENT | DELAY decision with a signed receipt. */
289
+ export function gate(repoRoot, opts) {
290
+ const now = opts.now ?? new Date();
291
+ const ts = now.toISOString();
292
+ const promptSha = createHash("sha256").update(opts.prompt).digest("hex").slice(0, 32);
293
+ // Phase 1 — rules.
294
+ for (const rule of listRules(repoRoot)) {
295
+ if (!ruleMatches(rule, opts.prompt, now))
296
+ continue;
297
+ if (rule.action === "silent") {
298
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "silent", reason: rule.rationale, promptSha, ruleId: rule.id });
299
+ return { decision: "silent", reason: rule.rationale, receipt };
300
+ }
301
+ if (typeof rule.action === "object" && "delayHours" in rule.action) {
302
+ const reviewableAt = new Date(now.getTime() + rule.action.delayHours * 3600 * 1000).toISOString();
303
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "delay", reason: rule.rationale, promptSha, reviewableAt, ruleId: rule.id });
304
+ return { decision: "delay", reason: rule.rationale, receipt, reviewableAt };
305
+ }
306
+ }
307
+ // Phase 2 — cadence state.
308
+ if (!opts.skipCadence) {
309
+ const cad = inferCadenceState(repoRoot);
310
+ if (cad.shouldSilence) {
311
+ const reason = `cadence state = ${cad.state} (CV ${cad.cv}). Suggesting silence.`;
312
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "silent", reason, promptSha });
313
+ return { decision: "silent", reason, receipt };
314
+ }
315
+ }
316
+ // Phase 3 — budget.
317
+ if (!opts.skipBudget) {
318
+ const r = consumeBudget(repoRoot, 1);
319
+ if (!r.ok) {
320
+ const reason = `budget exhausted (${r.state.consumed}/${r.state.maxUtterances} consumed; refreshes ${r.state.refresh === "day" ? "at UTC midnight" : "hourly"}).`;
321
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "silent", reason, promptSha });
322
+ return { decision: "silent", reason, receipt };
323
+ }
324
+ // SPEAK + record + return.
325
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "speak", reason: "all gates passed", promptSha });
326
+ return { decision: "speak", reason: "all gates passed", receipt, remainingBudget: r.remaining };
327
+ }
328
+ const receipt = writeReceipt(repoRoot, { v: 1, ts, decision: "speak", reason: "budget bypassed", promptSha });
329
+ return { decision: "speak", reason: "budget bypassed", receipt };
330
+ }
331
+ // ─── FORMATTERS ────────────────────────────────────────────────────────
332
+ export function formatBudget(b) {
333
+ const remaining = b.maxUtterances - b.consumed;
334
+ return [
335
+ `🤐 STILLNESS BUDGET`,
336
+ ``,
337
+ ` Max: ${b.maxUtterances} utterance(s) per ${b.refresh}`,
338
+ ` Consumed: ${b.consumed}`,
339
+ ` Remaining: ${remaining}`,
340
+ ` Window: ${b.windowStart} (refreshes at next ${b.refresh} boundary)`,
341
+ ].join("\n");
342
+ }
343
+ export function formatDecision(d) {
344
+ const badge = d.decision === "speak" ? "🗣 SPEAK"
345
+ : d.decision === "silent" ? "🤐 SILENT"
346
+ : "⏳ DELAY";
347
+ const lines = [`🤐 STILLNESS — ${badge}`, ``, ` Reason: ${d.reason}`];
348
+ if (d.reviewableAt)
349
+ lines.push(` Reviewable at: ${d.reviewableAt}`);
350
+ if (d.remainingBudget !== undefined)
351
+ lines.push(` Budget remaining: ${d.remainingBudget}`);
352
+ lines.push(` Receipt: ${d.receipt.sig.slice(0, 16)}… (${d.receipt.ts})`);
353
+ return lines.join("\n");
354
+ }
355
+ export function formatVerdict(v) {
356
+ return [
357
+ `🤐 STILLNESS CADENCE VERDICT`,
358
+ ``,
359
+ ` State: ${v.state}`,
360
+ ` CV: ${v.cv}`,
361
+ ` Samples: ${v.samples}`,
362
+ ` Should silence: ${v.shouldSilence ? "yes" : "no"}`,
363
+ ].join("\n");
364
+ }
365
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stillness/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stillness.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stillness.test.d.ts","sourceRoot":"","sources":["../../src/stillness/stillness.test.ts"],"names":[],"mappings":""}