@mneme-ai/core 2.31.0 → 2.33.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/agent_manifest.d.ts +1 -1
- package/dist/agent_manifest.d.ts.map +1 -1
- package/dist/agent_manifest.js +29 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/citizen_court/citizen_court.test.d.ts +2 -0
- package/dist/citizen_court/citizen_court.test.d.ts.map +1 -0
- package/dist/citizen_court/citizen_court.test.js +121 -0
- package/dist/citizen_court/citizen_court.test.js.map +1 -0
- package/dist/citizen_court/court.d.ts +48 -0
- package/dist/citizen_court/court.d.ts.map +1 -0
- package/dist/citizen_court/court.js +178 -0
- package/dist/citizen_court/court.js.map +1 -0
- package/dist/citizen_court/hsc.d.ts +11 -0
- package/dist/citizen_court/hsc.d.ts.map +1 -0
- package/dist/citizen_court/hsc.js +74 -0
- package/dist/citizen_court/hsc.js.map +1 -0
- package/dist/citizen_court/index.d.ts +13 -0
- package/dist/citizen_court/index.d.ts.map +1 -0
- package/dist/citizen_court/index.js +12 -0
- package/dist/citizen_court/index.js.map +1 -0
- package/dist/citizen_court/types.d.ts +104 -0
- package/dist/citizen_court/types.d.ts.map +1 -0
- package/dist/citizen_court/types.js +16 -0
- package/dist/citizen_court/types.js.map +1 -0
- package/dist/coercion/audit.d.ts +22 -0
- package/dist/coercion/audit.d.ts.map +1 -0
- package/dist/coercion/audit.js +169 -0
- package/dist/coercion/audit.js.map +1 -0
- package/dist/coercion/coercion.test.d.ts +2 -0
- package/dist/coercion/coercion.test.d.ts.map +1 -0
- package/dist/coercion/coercion.test.js +69 -0
- package/dist/coercion/coercion.test.js.map +1 -0
- package/dist/coercion/index.d.ts +11 -0
- package/dist/coercion/index.d.ts.map +1 -0
- package/dist/coercion/index.js +10 -0
- package/dist/coercion/index.js.map +1 -0
- package/dist/coercion/types.d.ts +53 -0
- package/dist/coercion/types.d.ts.map +1 -0
- package/dist/coercion/types.js +17 -0
- package/dist/coercion/types.js.map +1 -0
- package/dist/flywheel/controller.d.ts +51 -0
- package/dist/flywheel/controller.d.ts.map +1 -0
- package/dist/flywheel/controller.js +187 -0
- package/dist/flywheel/controller.js.map +1 -0
- package/dist/flywheel/flywheel.test.d.ts +2 -0
- package/dist/flywheel/flywheel.test.d.ts.map +1 -0
- package/dist/flywheel/flywheel.test.js +264 -0
- package/dist/flywheel/flywheel.test.js.map +1 -0
- package/dist/flywheel/fuse.d.ts +16 -0
- package/dist/flywheel/fuse.d.ts.map +1 -0
- package/dist/flywheel/fuse.js +140 -0
- package/dist/flywheel/fuse.js.map +1 -0
- package/dist/flywheel/harvest.d.ts +32 -0
- package/dist/flywheel/harvest.d.ts.map +1 -0
- package/dist/flywheel/harvest.js +327 -0
- package/dist/flywheel/harvest.js.map +1 -0
- package/dist/flywheel/index.d.ts +26 -0
- package/dist/flywheel/index.d.ts.map +1 -0
- package/dist/flywheel/index.js +19 -0
- package/dist/flywheel/index.js.map +1 -0
- package/dist/flywheel/liveness.d.ts +34 -0
- package/dist/flywheel/liveness.d.ts.map +1 -0
- package/dist/flywheel/liveness.js +63 -0
- package/dist/flywheel/liveness.js.map +1 -0
- package/dist/flywheel/personal_cheatsheet.d.ts +34 -0
- package/dist/flywheel/personal_cheatsheet.d.ts.map +1 -0
- package/dist/flywheel/personal_cheatsheet.js +95 -0
- package/dist/flywheel/personal_cheatsheet.js.map +1 -0
- package/dist/flywheel/prescribe.d.ts +20 -0
- package/dist/flywheel/prescribe.d.ts.map +1 -0
- package/dist/flywheel/prescribe.js +119 -0
- package/dist/flywheel/prescribe.js.map +1 -0
- package/dist/flywheel/reciprocity.d.ts +36 -0
- package/dist/flywheel/reciprocity.d.ts.map +1 -0
- package/dist/flywheel/reciprocity.js +113 -0
- package/dist/flywheel/reciprocity.js.map +1 -0
- package/dist/flywheel/types.d.ts +117 -0
- package/dist/flywheel/types.d.ts.map +1 -0
- package/dist/flywheel/types.js +25 -0
- package/dist/flywheel/types.js.map +1 -0
- package/dist/flywheel/vendor_bulletin.d.ts +44 -0
- package/dist/flywheel/vendor_bulletin.d.ts.map +1 -0
- package/dist/flywheel/vendor_bulletin.js +118 -0
- package/dist/flywheel/vendor_bulletin.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/dist/mnemnet/aggregate.d.ts +33 -0
- package/dist/mnemnet/aggregate.d.ts.map +1 -0
- package/dist/mnemnet/aggregate.js +184 -0
- package/dist/mnemnet/aggregate.js.map +1 -0
- package/dist/mnemnet/dp.d.ts +13 -0
- package/dist/mnemnet/dp.d.ts.map +1 -0
- package/dist/mnemnet/dp.js +32 -0
- package/dist/mnemnet/dp.js.map +1 -0
- package/dist/mnemnet/index.d.ts +12 -0
- package/dist/mnemnet/index.d.ts.map +1 -0
- package/dist/mnemnet/index.js +11 -0
- package/dist/mnemnet/index.js.map +1 -0
- package/dist/mnemnet/mnemnet.test.d.ts +2 -0
- package/dist/mnemnet/mnemnet.test.d.ts.map +1 -0
- package/dist/mnemnet/mnemnet.test.js +147 -0
- package/dist/mnemnet/mnemnet.test.js.map +1 -0
- package/dist/mnemnet/types.d.ts +77 -0
- package/dist/mnemnet/types.d.ts.map +1 -0
- package/dist/mnemnet/types.js +14 -0
- package/dist/mnemnet/types.js.map +1 -0
- package/dist/pulsecost/budget.d.ts +20 -0
- package/dist/pulsecost/budget.d.ts.map +1 -0
- package/dist/pulsecost/budget.js +108 -0
- package/dist/pulsecost/budget.js.map +1 -0
- package/dist/pulsecost/index.d.ts +6 -0
- package/dist/pulsecost/index.d.ts.map +1 -0
- package/dist/pulsecost/index.js +5 -0
- package/dist/pulsecost/index.js.map +1 -0
- package/dist/pulsecost/pulsecost.test.d.ts +2 -0
- package/dist/pulsecost/pulsecost.test.d.ts.map +1 -0
- package/dist/pulsecost/pulsecost.test.js +64 -0
- package/dist/pulsecost/pulsecost.test.js.map +1 -0
- package/dist/pulsecost/types.d.ts +53 -0
- package/dist/pulsecost/types.d.ts.map +1 -0
- package/dist/pulsecost/types.js +22 -0
- package/dist/pulsecost/types.js.map +1 -0
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +29 -0
- package/dist/truth_gate/claims.js.map +1 -1
- package/dist/truth_gate/probes.d.ts.map +1 -1
- package/dist/truth_gate/probes.js +71 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// v2.33.0 — MNEMNET discrete root tests.
|
|
2
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
3
|
+
import { mkdtempSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { laplaceSample, noisedCount, makeDeterministicRng, readConsent, setConsent, buildEnvelope, persistEnvelope, listEnvelopes, verifyEnvelope, aggregatePublicHsc, federatePush, } from "./index.js";
|
|
7
|
+
function makeRepo() { return mkdtempSync(join(tmpdir(), "mnemnet-")); }
|
|
8
|
+
function fakeVerdict(primary, reveals, winner, at = new Date().toISOString()) {
|
|
9
|
+
return {
|
|
10
|
+
id: "v-" + Math.random().toString(36).slice(2, 10),
|
|
11
|
+
primaryVendor: primary, at,
|
|
12
|
+
promptHash: "p", primaryResponseHash: "r",
|
|
13
|
+
primaryAction: "accepted",
|
|
14
|
+
reveals: reveals.map((vendor) => ({ vendor, responseHash: "x", revealDelayMs: 0 })),
|
|
15
|
+
votedMostTruthful: winner,
|
|
16
|
+
dpEpsilon: 0,
|
|
17
|
+
hmac: "deadbeef".repeat(8),
|
|
18
|
+
seq: 1,
|
|
19
|
+
bodyDigest: "x",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
describe("DP primitives", () => {
|
|
23
|
+
it("laplaceSample with seed is deterministic", () => {
|
|
24
|
+
const rng1 = makeDeterministicRng("s1");
|
|
25
|
+
const rng2 = makeDeterministicRng("s1");
|
|
26
|
+
const a = laplaceSample(1, rng1);
|
|
27
|
+
const b = laplaceSample(1, rng2);
|
|
28
|
+
expect(a).toBe(b);
|
|
29
|
+
});
|
|
30
|
+
it("noisedCount returns trueCount when ε <= 0", () => {
|
|
31
|
+
expect(noisedCount(42, 0)).toBe(42);
|
|
32
|
+
expect(noisedCount(42, -1)).toBe(42);
|
|
33
|
+
});
|
|
34
|
+
it("noisedCount with epsilon=0.5 stays close to true count on average", () => {
|
|
35
|
+
let sum = 0;
|
|
36
|
+
const N = 200;
|
|
37
|
+
const rng = makeDeterministicRng("avg");
|
|
38
|
+
for (let i = 0; i < N; i++)
|
|
39
|
+
sum += noisedCount(100, 0.5, rng);
|
|
40
|
+
const mean = sum / N;
|
|
41
|
+
// Within 20% of true count for 200 samples + ε=0.5 (scale=2).
|
|
42
|
+
expect(Math.abs(mean - 100)).toBeLessThan(20);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("Consent (default OFF)", () => {
|
|
46
|
+
let repo;
|
|
47
|
+
beforeEach(() => { repo = makeRepo(); });
|
|
48
|
+
it("default consent is opt-out", () => {
|
|
49
|
+
const c = readConsent(repo);
|
|
50
|
+
expect(c.optIn).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
it("setConsent persists across reads + assigns node id", () => {
|
|
53
|
+
const c = setConsent(repo, true, { endpoint: "https://mnemnet.ai", maxEpsilon: 0.3 });
|
|
54
|
+
expect(c.optIn).toBe(true);
|
|
55
|
+
expect(c.nodeId).toMatch(/^node-/);
|
|
56
|
+
expect(c.maxEpsilon).toBe(0.3);
|
|
57
|
+
const read = readConsent(repo);
|
|
58
|
+
expect(read.endpoint).toBe("https://mnemnet.ai");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe("Envelope build + verify", () => {
|
|
62
|
+
let repo;
|
|
63
|
+
beforeEach(() => { repo = makeRepo(); setConsent(repo, true, { maxEpsilon: 0.5 }); });
|
|
64
|
+
it("buildEnvelope with no verdicts → empty perVendor + valid HMAC", () => {
|
|
65
|
+
const env = buildEnvelope(repo, [], { deterministicSeed: "z" });
|
|
66
|
+
expect(env.perVendor.length).toBe(0);
|
|
67
|
+
expect(verifyEnvelope(env).ok).toBe(true);
|
|
68
|
+
});
|
|
69
|
+
it("buildEnvelope adds noise but keeps non-negative counts", () => {
|
|
70
|
+
const verdicts = [
|
|
71
|
+
fakeVerdict("claude", ["gpt"], "claude"),
|
|
72
|
+
fakeVerdict("claude", ["gpt"], "claude"),
|
|
73
|
+
fakeVerdict("claude", ["gpt"], "gpt"),
|
|
74
|
+
];
|
|
75
|
+
const env = buildEnvelope(repo, verdicts, { epsilon: 0.5, deterministicSeed: "seed-1" });
|
|
76
|
+
expect(env.perVendor.length).toBe(2); // claude + gpt
|
|
77
|
+
for (const v of env.perVendor) {
|
|
78
|
+
expect(v.noisedTruthful).toBeGreaterThanOrEqual(0);
|
|
79
|
+
expect(v.noisedDecisive).toBeGreaterThanOrEqual(0);
|
|
80
|
+
}
|
|
81
|
+
expect(verifyEnvelope(env).ok).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
it("epsilon clamped to consent.maxEpsilon", () => {
|
|
84
|
+
const verdicts = [fakeVerdict("a", ["b"], "a")];
|
|
85
|
+
const env = buildEnvelope(repo, verdicts, { epsilon: 100 });
|
|
86
|
+
expect(env.epsilon).toBeLessThanOrEqual(0.5);
|
|
87
|
+
});
|
|
88
|
+
it("tampered envelope fails verify", () => {
|
|
89
|
+
const env = buildEnvelope(repo, [fakeVerdict("x", ["y"], "x")], { deterministicSeed: "t" });
|
|
90
|
+
const tampered = { ...env, epsilon: 999 };
|
|
91
|
+
expect(verifyEnvelope(tampered).ok).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
it("persist + list round-trip", () => {
|
|
94
|
+
const env = buildEnvelope(repo, [fakeVerdict("p", ["q"], "p")], { deterministicSeed: "rt" });
|
|
95
|
+
persistEnvelope(repo, env);
|
|
96
|
+
const list = listEnvelopes(repo);
|
|
97
|
+
expect(list.length).toBe(1);
|
|
98
|
+
expect(list[0].envelopeId).toBe(env.envelopeId);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("Public HSC aggregation", () => {
|
|
102
|
+
let repo;
|
|
103
|
+
beforeEach(() => { repo = makeRepo(); setConsent(repo, true, { maxEpsilon: 1 }); });
|
|
104
|
+
it("aggregates envelopes from multiple nodes", () => {
|
|
105
|
+
// Two nodes worth: pretend each builds N rounds of verdicts.
|
|
106
|
+
const node1 = buildEnvelope(repo, Array.from({ length: 30 }, () => fakeVerdict("claude", ["gpt"], "claude")), { epsilon: 1, deterministicSeed: "n1" });
|
|
107
|
+
const node2 = buildEnvelope(repo, Array.from({ length: 30 }, () => fakeVerdict("claude", ["gpt"], "claude")), { epsilon: 1, deterministicSeed: "n2" });
|
|
108
|
+
// Spoof second envelope as a different node so contributingNodes=2.
|
|
109
|
+
const node2b = { ...node2, nodeId: "node-other" };
|
|
110
|
+
const hsc = aggregatePublicHsc([node1, node2b]);
|
|
111
|
+
const claude = hsc.rows.find((r) => r.vendor === "claude");
|
|
112
|
+
expect(claude.contributingNodes).toBe(2);
|
|
113
|
+
expect(claude.totalDecisive).toBeGreaterThan(0);
|
|
114
|
+
expect(claude.meanNoisedTruthfulRate).toBeGreaterThan(0);
|
|
115
|
+
});
|
|
116
|
+
it("band thresholds: unmeasured when totalDecisive < 25", () => {
|
|
117
|
+
const env = buildEnvelope(repo, Array.from({ length: 3 }, () => fakeVerdict("v", ["w"], "v")), { epsilon: 1, deterministicSeed: "u" });
|
|
118
|
+
const hsc = aggregatePublicHsc([env]);
|
|
119
|
+
const v = hsc.rows.find((r) => r.vendor === "v");
|
|
120
|
+
expect(v.band).toBe("⚪ unmeasured");
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe("Federation stub", () => {
|
|
124
|
+
let repo;
|
|
125
|
+
beforeEach(() => { repo = makeRepo(); });
|
|
126
|
+
it("refuses without consent", async () => {
|
|
127
|
+
const env = buildEnvelope(repo, [], { deterministicSeed: "x" });
|
|
128
|
+
const r = await federatePush(repo, env);
|
|
129
|
+
expect(r.ok).toBe(false);
|
|
130
|
+
expect(r.reason).toMatch(/consent/i);
|
|
131
|
+
});
|
|
132
|
+
it("refuses with consent but no endpoint", async () => {
|
|
133
|
+
setConsent(repo, true);
|
|
134
|
+
const env = buildEnvelope(repo, [], { deterministicSeed: "x" });
|
|
135
|
+
const r = await federatePush(repo, env);
|
|
136
|
+
expect(r.ok).toBe(false);
|
|
137
|
+
expect(r.reason).toMatch(/endpoint/i);
|
|
138
|
+
});
|
|
139
|
+
it("returns stub-success with consent + endpoint", async () => {
|
|
140
|
+
setConsent(repo, true, { endpoint: "https://mnemnet.ai" });
|
|
141
|
+
const env = buildEnvelope(repo, [], { deterministicSeed: "x" });
|
|
142
|
+
const r = await federatePush(repo, env);
|
|
143
|
+
expect(r.ok).toBe(true);
|
|
144
|
+
expect(r.reason).toMatch(/stub|coming/i);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=mnemnet.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemnet.test.js","sourceRoot":"","sources":["../../src/mnemnet/mnemnet.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — MNEMNET types.
|
|
3
|
+
*
|
|
4
|
+
* MNEMNET = federated AI-honesty network. Local Mneme nodes opt-in
|
|
5
|
+
* to contribute differentially-private aggregates of their CITIZEN
|
|
6
|
+
* COURT verdicts; the network publishes a Public Honesty Court HSC
|
|
7
|
+
* per vendor that no single user can game.
|
|
8
|
+
*
|
|
9
|
+
* v2.33.0 ships the LOCAL aggregator + opt-in scaffolding + push
|
|
10
|
+
* stub (no network call). The federated endpoint protocol lands
|
|
11
|
+
* v2.34.x (same pattern HGP v2.31 used).
|
|
12
|
+
*/
|
|
13
|
+
export interface MnemnetConsent {
|
|
14
|
+
/** User opt-in flag. Default OFF (CONSENT FABRIC). */
|
|
15
|
+
optIn: boolean;
|
|
16
|
+
/** ISO of latest opt-in toggle. */
|
|
17
|
+
at: string;
|
|
18
|
+
/** Endpoint to push to (default mnemnet.ai placeholder). */
|
|
19
|
+
endpoint?: string;
|
|
20
|
+
/** Cryptographic node id (HMAC pubkey hash; never reveals identity). */
|
|
21
|
+
nodeId: string;
|
|
22
|
+
/** DP epsilon ceiling per submission (default 0.5). */
|
|
23
|
+
maxEpsilon: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The unit of contribution: a DP-noised count of truthful-votes per
|
|
27
|
+
* vendor over a window. No raw verdicts EVER leave the local node.
|
|
28
|
+
*/
|
|
29
|
+
export interface DpAggregate {
|
|
30
|
+
/** Stable HMAC-signed envelope id. */
|
|
31
|
+
envelopeId: string;
|
|
32
|
+
/** Anonymous node id (per consent). */
|
|
33
|
+
nodeId: string;
|
|
34
|
+
/** Window start + end (ISO). */
|
|
35
|
+
windowStart: string;
|
|
36
|
+
windowEnd: string;
|
|
37
|
+
/** Per-vendor noised tally. */
|
|
38
|
+
perVendor: Array<{
|
|
39
|
+
vendor: string;
|
|
40
|
+
/** truthful-vote count + Laplace(1/ε) noise. */
|
|
41
|
+
noisedTruthful: number;
|
|
42
|
+
/** decisive-vote count + Laplace(1/ε) noise. */
|
|
43
|
+
noisedDecisive: number;
|
|
44
|
+
}>;
|
|
45
|
+
/** DP epsilon applied. */
|
|
46
|
+
epsilon: number;
|
|
47
|
+
/** HMAC-signed envelope. */
|
|
48
|
+
hmac: string;
|
|
49
|
+
at: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Network-side aggregation across N envelopes. Public Honesty Court.
|
|
53
|
+
* v2.33.0 computes this locally on a list of envelopes (e.g. supplied
|
|
54
|
+
* by the user as a JSON paste from peers); v2.34.x will fetch from
|
|
55
|
+
* the live endpoint.
|
|
56
|
+
*/
|
|
57
|
+
export interface PublicHscRow {
|
|
58
|
+
vendor: string;
|
|
59
|
+
/** Mean noised truthful rate across N nodes. */
|
|
60
|
+
meanNoisedTruthfulRate: number;
|
|
61
|
+
/** Number of contributing nodes. */
|
|
62
|
+
contributingNodes: number;
|
|
63
|
+
/** Sum of decisive votes (noised). */
|
|
64
|
+
totalDecisive: number;
|
|
65
|
+
/** Effective epsilon (max across envelopes). */
|
|
66
|
+
maxEpsilon: number;
|
|
67
|
+
/** Band per the SAME thresholds CITIZEN COURT HSC uses. */
|
|
68
|
+
band: "🟢 trustworthy" | "🟡 mixed" | "🔴 suspect" | "⚪ unmeasured";
|
|
69
|
+
}
|
|
70
|
+
export interface PublicHsc {
|
|
71
|
+
generatedAt: string;
|
|
72
|
+
envelopeCount: number;
|
|
73
|
+
rows: PublicHscRow[];
|
|
74
|
+
/** HMAC-signed for receivers to verify offline. */
|
|
75
|
+
hmac: string;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mnemnet/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,SAAS,EAAE,KAAK,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,gDAAgD;QAChD,cAAc,EAAE,MAAM,CAAC;QACvB,gDAAgD;QAChD,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACH,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oCAAoC;IACpC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,EAAE,gBAAgB,GAAG,UAAU,GAAG,YAAY,GAAG,cAAc,CAAC;CACrE;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — MNEMNET types.
|
|
3
|
+
*
|
|
4
|
+
* MNEMNET = federated AI-honesty network. Local Mneme nodes opt-in
|
|
5
|
+
* to contribute differentially-private aggregates of their CITIZEN
|
|
6
|
+
* COURT verdicts; the network publishes a Public Honesty Court HSC
|
|
7
|
+
* per vendor that no single user can game.
|
|
8
|
+
*
|
|
9
|
+
* v2.33.0 ships the LOCAL aggregator + opt-in scaffolding + push
|
|
10
|
+
* stub (no network call). The federated endpoint protocol lands
|
|
11
|
+
* v2.34.x (same pattern HGP v2.31 used).
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mnemnet/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — PULSECOST enforcement primitive.
|
|
3
|
+
*
|
|
4
|
+
* Given a response text + an `X-Context-Available-Tokens` budget,
|
|
5
|
+
* trim the text to fit + emit the three response headers. Token
|
|
6
|
+
* estimation is words-per-token (0.75 default). Conservative trim
|
|
7
|
+
* keeps full sentences; falls back to char-truncation if a single
|
|
8
|
+
* sentence already exceeds the budget.
|
|
9
|
+
*/
|
|
10
|
+
import type { PulseCostBudget, PulseCostResult, PulseCostSpec } from "./types.js";
|
|
11
|
+
export declare const SPEC: PulseCostSpec;
|
|
12
|
+
export declare function estimateTokens(text: string, wordsPerToken?: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Trim by sentence boundary first; if a single sentence already
|
|
15
|
+
* exceeds the budget, fall back to char-truncation at a word boundary.
|
|
16
|
+
*/
|
|
17
|
+
export declare function trimToBudget(text: string, budget: PulseCostBudget): PulseCostResult;
|
|
18
|
+
/** Convenience: pull the request header from any { headers } shape. */
|
|
19
|
+
export declare function readRequestBudget(headers: Record<string, string | string[] | undefined>, fallback?: PulseCostBudget): PulseCostBudget;
|
|
20
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/pulsecost/budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlF,eAAO,MAAM,IAAI,EAAE,aA+BlB,CAAC;AAQF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,SAAyB,GAAG,MAAM,CAI3F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,eAAe,CAqCnF;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,QAAQ,kBAAW,GAAG,eAAe,CAS9H"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — PULSECOST enforcement primitive.
|
|
3
|
+
*
|
|
4
|
+
* Given a response text + an `X-Context-Available-Tokens` budget,
|
|
5
|
+
* trim the text to fit + emit the three response headers. Token
|
|
6
|
+
* estimation is words-per-token (0.75 default). Conservative trim
|
|
7
|
+
* keeps full sentences; falls back to char-truncation if a single
|
|
8
|
+
* sentence already exceeds the budget.
|
|
9
|
+
*/
|
|
10
|
+
const SPEC_VERSION = "0.1";
|
|
11
|
+
export const SPEC = {
|
|
12
|
+
version: SPEC_VERSION,
|
|
13
|
+
headers: {
|
|
14
|
+
requestAvailable: "X-Context-Available-Tokens",
|
|
15
|
+
responseUsed: "X-Context-Used-Tokens",
|
|
16
|
+
responseTrimmed: "X-Context-Trimmed",
|
|
17
|
+
},
|
|
18
|
+
body: [
|
|
19
|
+
"# Mneme PulseCost / MCP Context-Budget Extension v" + SPEC_VERSION,
|
|
20
|
+
"",
|
|
21
|
+
"## Problem",
|
|
22
|
+
"Every MCP server emits unbounded responses. Agents have to budget context across many tool calls per turn, but no protocol mechanism lets them ask 'how big will your answer be?' or constrain it.",
|
|
23
|
+
"",
|
|
24
|
+
"## Proposal",
|
|
25
|
+
"Three optional HTTP-style headers in MCP request/response framing:",
|
|
26
|
+
"",
|
|
27
|
+
"- `X-Context-Available-Tokens: <int>` (request) — agent's budget for THIS response",
|
|
28
|
+
"- `X-Context-Used-Tokens: <int>` (response) — actual tokens the server emitted",
|
|
29
|
+
"- `X-Context-Trimmed: true|false` (response) — was the output trimmed to fit?",
|
|
30
|
+
"",
|
|
31
|
+
"Servers SHOULD honour the request header by trimming the response to fit. If they cannot trim semantically, they MAY emit the unbounded response and set `X-Context-Trimmed: false` + `X-Context-Used-Tokens` to the actual usage. Agents can then either accept the over-budget response or re-issue with a different tool / smaller scope.",
|
|
32
|
+
"",
|
|
33
|
+
"## Token estimation",
|
|
34
|
+
"MCP-CANDOR/PulseCost recommends words-per-token = 0.75 (matches GPT/Claude tokenisation within 10%). Servers MAY swap for their own model's tokenizer when known.",
|
|
35
|
+
"",
|
|
36
|
+
"## Compatibility",
|
|
37
|
+
"Headers are OPTIONAL. Clients without the spec ignore the response headers. Servers without the spec ignore the request header (no trimming, no header emission) — same behavior as today.",
|
|
38
|
+
"",
|
|
39
|
+
"## Reference implementation",
|
|
40
|
+
"Mneme v2.33.0 ships `mneme.pulsecost.budget` as the reference implementation. Call it with `{ text, availableTokens }` to receive a trimmed string + the three response headers. Any MCP server can compose this primitive into their handlers without re-implementing token math.",
|
|
41
|
+
].join("\n"),
|
|
42
|
+
};
|
|
43
|
+
const DEFAULTS = {
|
|
44
|
+
availableTokens: 8192,
|
|
45
|
+
defaultBudget: 8192,
|
|
46
|
+
wordsPerToken: 0.75,
|
|
47
|
+
};
|
|
48
|
+
export function estimateTokens(text, wordsPerToken = DEFAULTS.wordsPerToken) {
|
|
49
|
+
if (!text)
|
|
50
|
+
return 0;
|
|
51
|
+
const words = text.trim().split(/\s+/).filter(Boolean).length;
|
|
52
|
+
return Math.ceil(words / wordsPerToken);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Trim by sentence boundary first; if a single sentence already
|
|
56
|
+
* exceeds the budget, fall back to char-truncation at a word boundary.
|
|
57
|
+
*/
|
|
58
|
+
export function trimToBudget(text, budget) {
|
|
59
|
+
const originalTokens = estimateTokens(text, budget.wordsPerToken);
|
|
60
|
+
if (originalTokens <= budget.availableTokens) {
|
|
61
|
+
return {
|
|
62
|
+
output: text, usedTokens: originalTokens, originalTokens, trimmed: false,
|
|
63
|
+
headers: {
|
|
64
|
+
[SPEC.headers.responseUsed]: String(originalTokens),
|
|
65
|
+
[SPEC.headers.responseTrimmed]: "false",
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Sentence-aware trim. We split on `.` / `!` / `?` followed by space or EOS.
|
|
70
|
+
const sentences = text.split(/(?<=[.!?])\s+/);
|
|
71
|
+
const accumulated = [];
|
|
72
|
+
let runningTokens = 0;
|
|
73
|
+
for (const s of sentences) {
|
|
74
|
+
const t = estimateTokens(s, budget.wordsPerToken);
|
|
75
|
+
if (runningTokens + t > budget.availableTokens)
|
|
76
|
+
break;
|
|
77
|
+
accumulated.push(s);
|
|
78
|
+
runningTokens += t;
|
|
79
|
+
}
|
|
80
|
+
let output = accumulated.join(" ");
|
|
81
|
+
// Single sentence already too big → char-truncate at word boundary.
|
|
82
|
+
if (output.length === 0 && sentences.length > 0) {
|
|
83
|
+
const approxChars = Math.max(1, Math.floor(budget.availableTokens * 4)); // ~4 chars/token rough
|
|
84
|
+
const cut = sentences[0].slice(0, approxChars);
|
|
85
|
+
const lastSpace = cut.lastIndexOf(" ");
|
|
86
|
+
output = lastSpace > 0 ? cut.slice(0, lastSpace) + "…" : cut + "…";
|
|
87
|
+
}
|
|
88
|
+
const usedTokens = estimateTokens(output, budget.wordsPerToken);
|
|
89
|
+
return {
|
|
90
|
+
output, usedTokens, originalTokens, trimmed: true,
|
|
91
|
+
headers: {
|
|
92
|
+
[SPEC.headers.responseUsed]: String(usedTokens),
|
|
93
|
+
[SPEC.headers.responseTrimmed]: "true",
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Convenience: pull the request header from any { headers } shape. */
|
|
98
|
+
export function readRequestBudget(headers, fallback = DEFAULTS) {
|
|
99
|
+
const raw = headers[SPEC.headers.requestAvailable] ?? headers[SPEC.headers.requestAvailable.toLowerCase()];
|
|
100
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
101
|
+
const parsed = value ? parseInt(String(value), 10) : NaN;
|
|
102
|
+
return {
|
|
103
|
+
availableTokens: Number.isFinite(parsed) && parsed > 0 ? parsed : fallback.defaultBudget,
|
|
104
|
+
defaultBudget: fallback.defaultBudget,
|
|
105
|
+
wordsPerToken: fallback.wordsPerToken,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/pulsecost/budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — PULSECOST public surface (MCP context-budget extension v0.1).
|
|
3
|
+
*/
|
|
4
|
+
export type { PulseCostBudget, PulseCostResult, PulseCostSpec } from "./types.js";
|
|
5
|
+
export { SPEC, estimateTokens, trimToBudget, readRequestBudget } from "./budget.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pulsecost/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pulsecost/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pulsecost.test.d.ts","sourceRoot":"","sources":["../../src/pulsecost/pulsecost.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// v2.33.0 — PULSECOST discrete root tests.
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { SPEC, estimateTokens, trimToBudget, readRequestBudget } from "./index.js";
|
|
4
|
+
describe("PULSECOST spec", () => {
|
|
5
|
+
it("emits the 3 header names per the proposed extension", () => {
|
|
6
|
+
expect(SPEC.headers.requestAvailable).toBe("X-Context-Available-Tokens");
|
|
7
|
+
expect(SPEC.headers.responseUsed).toBe("X-Context-Used-Tokens");
|
|
8
|
+
expect(SPEC.headers.responseTrimmed).toBe("X-Context-Trimmed");
|
|
9
|
+
});
|
|
10
|
+
it("spec body mentions MCP + protocol", () => {
|
|
11
|
+
expect(SPEC.body).toMatch(/MCP/);
|
|
12
|
+
expect(SPEC.body).toMatch(/Context-Available-Tokens/);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe("estimateTokens", () => {
|
|
16
|
+
it("0 for empty string", () => { expect(estimateTokens("")).toBe(0); });
|
|
17
|
+
it("ceil(words/0.75) for words", () => {
|
|
18
|
+
// 3 words → ceil(3/0.75) = 4 tokens
|
|
19
|
+
expect(estimateTokens("one two three")).toBe(4);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
describe("trimToBudget", () => {
|
|
23
|
+
it("returns text unchanged when within budget", () => {
|
|
24
|
+
const r = trimToBudget("Hello world.", { availableTokens: 1000, defaultBudget: 1000, wordsPerToken: 0.75 });
|
|
25
|
+
expect(r.trimmed).toBe(false);
|
|
26
|
+
expect(r.output).toBe("Hello world.");
|
|
27
|
+
expect(r.headers["X-Context-Trimmed"]).toBe("false");
|
|
28
|
+
});
|
|
29
|
+
it("sentence-aware trim keeps first N sentences", () => {
|
|
30
|
+
const text = "First sentence here. Second sentence here. Third sentence here. Fourth sentence here. Fifth sentence here. Sixth sentence here. Seventh sentence here. Eighth sentence here.";
|
|
31
|
+
// 8 sentences × 3 words = 24 words = 32 tokens. Budget 12 should fit ~2-3 sentences.
|
|
32
|
+
const r = trimToBudget(text, { availableTokens: 12, defaultBudget: 100, wordsPerToken: 0.75 });
|
|
33
|
+
expect(r.trimmed).toBe(true);
|
|
34
|
+
expect(r.output.length).toBeLessThan(text.length);
|
|
35
|
+
expect(r.output).toMatch(/^First sentence here\./);
|
|
36
|
+
expect(r.headers["X-Context-Trimmed"]).toBe("true");
|
|
37
|
+
expect(parseInt(r.headers["X-Context-Used-Tokens"], 10)).toBeLessThanOrEqual(12);
|
|
38
|
+
});
|
|
39
|
+
it("falls back to char-truncation when single sentence already too large", () => {
|
|
40
|
+
const longSentence = "word ".repeat(500); // 500 words
|
|
41
|
+
const r = trimToBudget(longSentence, { availableTokens: 5, defaultBudget: 100, wordsPerToken: 0.75 });
|
|
42
|
+
expect(r.trimmed).toBe(true);
|
|
43
|
+
expect(r.output.endsWith("…")).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("readRequestBudget", () => {
|
|
47
|
+
it("uses default when header missing", () => {
|
|
48
|
+
const r = readRequestBudget({});
|
|
49
|
+
expect(r.availableTokens).toBe(8192);
|
|
50
|
+
});
|
|
51
|
+
it("parses integer header value", () => {
|
|
52
|
+
const r = readRequestBudget({ "X-Context-Available-Tokens": "2048" });
|
|
53
|
+
expect(r.availableTokens).toBe(2048);
|
|
54
|
+
});
|
|
55
|
+
it("case-insensitive fallback", () => {
|
|
56
|
+
const r = readRequestBudget({ "x-context-available-tokens": "1024" });
|
|
57
|
+
expect(r.availableTokens).toBe(1024);
|
|
58
|
+
});
|
|
59
|
+
it("invalid header falls back to default", () => {
|
|
60
|
+
const r = readRequestBudget({ "X-Context-Available-Tokens": "garbage" });
|
|
61
|
+
expect(r.availableTokens).toBe(8192);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=pulsecost.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pulsecost.test.js","sourceRoot":"","sources":["../../src/pulsecost/pulsecost.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — PULSECOST types.
|
|
3
|
+
*
|
|
4
|
+
* "Pulse Cost: Negotiated Context Budget Between AI Agents and Their
|
|
5
|
+
* Tools" (paper 5). MCP spec extension proposal:
|
|
6
|
+
*
|
|
7
|
+
* Request header : X-Context-Available-Tokens: <int>
|
|
8
|
+
* Response header: X-Context-Used-Tokens: <int>
|
|
9
|
+
* Response header: X-Context-Trimmed: true|false
|
|
10
|
+
*
|
|
11
|
+
* The tool agrees to fit its response within the available budget;
|
|
12
|
+
* the agent can budget intelligently across many tool calls per turn.
|
|
13
|
+
* Today every MCP server emits unbounded responses → agents waste
|
|
14
|
+
* context on duplicated capability dumps.
|
|
15
|
+
*
|
|
16
|
+
* v2.33.0 ships the local enforcement primitive + spec markdown +
|
|
17
|
+
* a `mneme.pulsecost.budget` MCP tool that demonstrates the protocol.
|
|
18
|
+
* The header convention is proposed (not yet ratified) in the MCP
|
|
19
|
+
* spec — we ship a reference implementation to prove it works.
|
|
20
|
+
*/
|
|
21
|
+
export interface PulseCostBudget {
|
|
22
|
+
/** Total tokens the agent is willing to receive. */
|
|
23
|
+
availableTokens: number;
|
|
24
|
+
/** Conservative fallback when caller doesn't supply the header. */
|
|
25
|
+
defaultBudget: number;
|
|
26
|
+
/** Words-per-token ratio (rough; 0.75 is the common rule of thumb). */
|
|
27
|
+
wordsPerToken: number;
|
|
28
|
+
}
|
|
29
|
+
export interface PulseCostResult {
|
|
30
|
+
/** The trimmed output. */
|
|
31
|
+
output: string;
|
|
32
|
+
/** Estimated token count of the output. */
|
|
33
|
+
usedTokens: number;
|
|
34
|
+
/** Original (untrimmed) token estimate. */
|
|
35
|
+
originalTokens: number;
|
|
36
|
+
/** Was the output trimmed? */
|
|
37
|
+
trimmed: boolean;
|
|
38
|
+
/** Response headers the caller should emit alongside the output. */
|
|
39
|
+
headers: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
export interface PulseCostSpec {
|
|
42
|
+
/** Spec version. */
|
|
43
|
+
version: "0.1";
|
|
44
|
+
/** Human-readable spec body (markdown). */
|
|
45
|
+
body: string;
|
|
46
|
+
/** Header names. */
|
|
47
|
+
headers: {
|
|
48
|
+
requestAvailable: string;
|
|
49
|
+
responseUsed: string;
|
|
50
|
+
responseTrimmed: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/pulsecost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,oBAAoB;IACpB,OAAO,EAAE,KAAK,CAAC;IACf,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,OAAO,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.33.0 — PULSECOST types.
|
|
3
|
+
*
|
|
4
|
+
* "Pulse Cost: Negotiated Context Budget Between AI Agents and Their
|
|
5
|
+
* Tools" (paper 5). MCP spec extension proposal:
|
|
6
|
+
*
|
|
7
|
+
* Request header : X-Context-Available-Tokens: <int>
|
|
8
|
+
* Response header: X-Context-Used-Tokens: <int>
|
|
9
|
+
* Response header: X-Context-Trimmed: true|false
|
|
10
|
+
*
|
|
11
|
+
* The tool agrees to fit its response within the available budget;
|
|
12
|
+
* the agent can budget intelligently across many tool calls per turn.
|
|
13
|
+
* Today every MCP server emits unbounded responses → agents waste
|
|
14
|
+
* context on duplicated capability dumps.
|
|
15
|
+
*
|
|
16
|
+
* v2.33.0 ships the local enforcement primitive + spec markdown +
|
|
17
|
+
* a `mneme.pulsecost.budget` MCP tool that demonstrates the protocol.
|
|
18
|
+
* The header convention is proposed (not yet ratified) in the MCP
|
|
19
|
+
* spec — we ship a reference implementation to prove it works.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pulsecost/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../src/truth_gate/claims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"claims.d.ts","sourceRoot":"","sources":["../../src/truth_gate/claims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,KAAK,CA8K9C,CAAC"}
|
|
@@ -167,5 +167,34 @@ export const CLAIM_CATALOG = [
|
|
|
167
167
|
probeId: "probe.hgp.federation_default_off",
|
|
168
168
|
severity: "block",
|
|
169
169
|
},
|
|
170
|
+
// ── v2.32.0 FLYWHEEL claim ─────────────────────────────────────────
|
|
171
|
+
{
|
|
172
|
+
id: "claim.flywheel.health_known",
|
|
173
|
+
source: "v2.32.0 release notes",
|
|
174
|
+
text: "FLYWHEEL self-audit health is a known non-negative number on first install (or improves to ≥ 0 after first run)",
|
|
175
|
+
kind: "numeric",
|
|
176
|
+
asserted: { value: 0, op: ">=", unit: "score" },
|
|
177
|
+
probeId: "probe.flywheel.health",
|
|
178
|
+
severity: "info",
|
|
179
|
+
},
|
|
180
|
+
// ── v2.33.0 CITIZEN COURT + MNEMNET claims ────────────────────────
|
|
181
|
+
{
|
|
182
|
+
id: "claim.citizen_court.verdict_count_known",
|
|
183
|
+
source: "v2.33.0 release notes",
|
|
184
|
+
text: "CITIZEN COURT verdict ledger reports a non-negative count (zero on fresh install is honest)",
|
|
185
|
+
kind: "numeric",
|
|
186
|
+
asserted: { value: 0, op: ">=", unit: "verdicts" },
|
|
187
|
+
probeId: "probe.citizen_court.verdict_count",
|
|
188
|
+
severity: "info",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
id: "claim.mnemnet.federation_default_off",
|
|
192
|
+
source: "v2.33.0 release notes",
|
|
193
|
+
text: "MNEMNET federation is opt-in / private-by-default (CONSENT FABRIC)",
|
|
194
|
+
kind: "numeric",
|
|
195
|
+
asserted: { value: 0, op: "=", unit: "boolean" },
|
|
196
|
+
probeId: "probe.mnemnet.federation_default_off",
|
|
197
|
+
severity: "block",
|
|
198
|
+
},
|
|
170
199
|
];
|
|
171
200
|
//# sourceMappingURL=claims.js.map
|