@mikeargento/bitgraph-mcp 0.1.2 → 0.3.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/README.md +7 -5
- package/dist/__tests__/format.test.js +4 -4
- package/dist/__tests__/format.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +45 -58
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/format.d.ts +11 -4
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +17 -12
- package/dist/format.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/server.d.ts +22 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +114 -87
- package/dist/server.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/format.test.ts +4 -4
- package/src/__tests__/tools.test.ts +50 -67
- package/src/format.ts +29 -17
- package/src/server.ts +131 -109
package/dist/server.js
CHANGED
|
@@ -2,18 +2,70 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @mikeargento/bitgraph-mcp: tool definitions.
|
|
4
4
|
*
|
|
5
|
-
* Three gestures, the same three the website has:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Three gestures, the same three the website has: make a BitGraph of a file,
|
|
6
|
+
* check whether bytes are on record, fetch a proof. Making a BitGraph builds a
|
|
7
|
+
* fused artifact from the file in memory, on this machine, and commits its
|
|
8
|
+
* digest under a slot allocated for it; only SHA-256 digests and slot records
|
|
9
|
+
* ever leave the machine. File contents are never uploaded.
|
|
8
10
|
*/
|
|
9
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
12
|
import { z } from "zod";
|
|
11
|
-
import {
|
|
13
|
+
import { readFile } from "node:fs/promises";
|
|
14
|
+
import { fuse, builderFor, placementForBytes, fusedNamesFor } from "@mikeargento/bitgraph";
|
|
15
|
+
import { ApiError, batchCheck, configFromEnv, getProofDetail, search, } from "./api.js";
|
|
12
16
|
import { fromUrlSafeB64, looksLikeDigest, mapConcurrent, sha256FileB64, toUrlSafeB64, } from "./encoding.js";
|
|
13
17
|
import { capJson, positionOf, proofUrl, renderCheckMarkdown, renderProofMarkdown, renderRecordMarkdown, } from "./format.js";
|
|
14
|
-
export const SERVER_VERSION = "0.
|
|
18
|
+
export const SERVER_VERSION = "0.2.0";
|
|
15
19
|
const HASH_CONCURRENCY = 4;
|
|
16
20
|
const MAX_FILES = 500;
|
|
21
|
+
/** Files above this are refused: the fused artifact is built in memory. */
|
|
22
|
+
const MAX_FUSE_BYTES = 256 * 1024 * 1024;
|
|
23
|
+
/**
|
|
24
|
+
* The default pipeline, the same one the site's drop and the bitgraph-fuse
|
|
25
|
+
* command run: choose the placement from the bytes, allocate a slot, derive
|
|
26
|
+
* the commitment, build the fused bytes, hash them, commit under that exact
|
|
27
|
+
* slot, verify the returned proof against the bytes.
|
|
28
|
+
*/
|
|
29
|
+
async function fuseFileDefault(bytes, name, config) {
|
|
30
|
+
const placement = placementForBytes(bytes);
|
|
31
|
+
const { fusedName } = fusedNamesFor(name, placement);
|
|
32
|
+
const r = await fuse(builderFor(placement, bytes), {
|
|
33
|
+
placement,
|
|
34
|
+
original: bytes,
|
|
35
|
+
fusedFile: fusedName,
|
|
36
|
+
keepFused: false,
|
|
37
|
+
transport: { baseUrl: config.baseUrl, ...(config.apiKey ? { apiKey: config.apiKey } : {}) },
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
proof: r.proof,
|
|
41
|
+
frame: r.frame,
|
|
42
|
+
placement,
|
|
43
|
+
artifactDigestB64: r.artifactDigestB64,
|
|
44
|
+
originDigestB64: r.originDigestB64 ?? "",
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Read the given paths whole (bounded concurrency). Throws before any network call. */
|
|
48
|
+
async function readPaths(paths) {
|
|
49
|
+
const failures = [];
|
|
50
|
+
const out = await mapConcurrent(paths, HASH_CONCURRENCY, async (p) => {
|
|
51
|
+
try {
|
|
52
|
+
const buf = await readFile(p);
|
|
53
|
+
if (buf.length > MAX_FUSE_BYTES)
|
|
54
|
+
throw new Error(`larger than ${MAX_FUSE_BYTES / (1024 * 1024)} MB; the fused artifact is built in memory`);
|
|
55
|
+
const bytes = new Uint8Array(buf);
|
|
56
|
+
const digestB64 = await sha256FileB64(p);
|
|
57
|
+
return { bytes, digestB64 };
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
failures.push(`${p}: ${err instanceof Error ? err.message : String(err)}`);
|
|
61
|
+
return { bytes: new Uint8Array(0), digestB64: "" };
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
if (failures.length > 0) {
|
|
65
|
+
throw new Error(`Could not read ${failures.length} file(s); nothing was BitGraphed.\n${failures.join("\n")}\nUse absolute paths to existing regular files under ${MAX_FUSE_BYTES / (1024 * 1024)} MB.`);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
17
69
|
const responseFormatSchema = z
|
|
18
70
|
.enum(["markdown", "json"])
|
|
19
71
|
.default("markdown")
|
|
@@ -51,38 +103,31 @@ async function hashPaths(paths) {
|
|
|
51
103
|
}
|
|
52
104
|
return digests;
|
|
53
105
|
}
|
|
54
|
-
export function buildServer() {
|
|
106
|
+
export function buildServer(deps = {}) {
|
|
107
|
+
const fuseFile = deps.fuseFile ?? fuseFileDefault;
|
|
55
108
|
const server = new McpServer({
|
|
56
109
|
name: "bitgraph-mcp-server",
|
|
57
110
|
version: SERVER_VERSION,
|
|
58
111
|
});
|
|
59
112
|
server.registerTool("bitgraph_record", {
|
|
60
|
-
title: "
|
|
61
|
-
description: "
|
|
62
|
-
"
|
|
63
|
-
"Files whose bytes are already on record are NOT
|
|
64
|
-
"Pass again=true to deliberately
|
|
65
|
-
"
|
|
66
|
-
"Returns one outcome per file: '
|
|
113
|
+
title: "Make a BitGraph",
|
|
114
|
+
description: "Make a BitGraph of one or more files. For each file, on this machine: hash it (the origin), allocate an unused slot in the BitGraph ledger (bitgraph.ing) before any artifact exists, build a new fused artifact from the file in memory with a registered placement (a 48-byte trailer for formats that ignore trailing bytes such as JPEG, PNG, TIFF, WebP; a small tar container otherwise), hash it, and commit that digest under the same slot. " +
|
|
115
|
+
"The file is never modified and never uploaded; only digests and slot records leave the machine. The fused bytes are not kept: the original plus the proof rebuilds them, and the Frame for each file is returned in the structured result. " +
|
|
116
|
+
"Files whose bytes are already on record, as a recording or as the origin of a fused artifact, are NOT BitGraphed again by default; they come back as 'on record' with their earliest position. " +
|
|
117
|
+
"Pass again=true to deliberately make a new fused artifact from a file already on record. " +
|
|
118
|
+
"BitGraphs are permanent: the ledger has 10-year retention and no deletes, so only BitGraph files the user asked to. " +
|
|
119
|
+
"Returns one outcome per file: 'fused' (a new fused artifact, with its placement, position and proof page URL), 'on record', or 'not fused' (with the error). " +
|
|
67
120
|
"Use bitgraph_check instead when the user only wants to know whether a file is on record.",
|
|
68
121
|
inputSchema: {
|
|
69
122
|
paths: z
|
|
70
123
|
.array(z.string().min(1))
|
|
71
124
|
.min(1)
|
|
72
125
|
.max(MAX_FILES)
|
|
73
|
-
.describe(`File paths to
|
|
74
|
-
attribution: z
|
|
75
|
-
.object({
|
|
76
|
-
name: z.string().max(200).optional().describe("Submitter's name (self-attributed)."),
|
|
77
|
-
title: z.string().max(200).optional(),
|
|
78
|
-
message: z.string().max(2000).optional(),
|
|
79
|
-
})
|
|
80
|
-
.optional()
|
|
81
|
-
.describe("Optional self-attributed submitter's note, stored in the signed proof. Rendered as a note, never as verified identity."),
|
|
126
|
+
.describe(`File paths to BitGraph (absolute paths preferred), up to ${MAX_FILES}.`),
|
|
82
127
|
again: z
|
|
83
128
|
.boolean()
|
|
84
129
|
.default(false)
|
|
85
|
-
.describe("false (default): files already on record are returned as-is, nothing minted. true:
|
|
130
|
+
.describe("false (default): files already on record are returned as-is, nothing minted. true: make a new fused artifact from every file even if its bytes are already on record. Outcomes are per unique file content: two paths with identical bytes yield one artifact."),
|
|
86
131
|
response_format: responseFormatSchema,
|
|
87
132
|
},
|
|
88
133
|
annotations: {
|
|
@@ -91,16 +136,16 @@ export function buildServer() {
|
|
|
91
136
|
idempotentHint: false,
|
|
92
137
|
openWorldHint: true,
|
|
93
138
|
},
|
|
94
|
-
}, async ({ paths,
|
|
139
|
+
}, async ({ paths, again, response_format }) => {
|
|
95
140
|
const config = configFromEnv();
|
|
96
141
|
try {
|
|
97
|
-
const
|
|
98
|
-
// Unique
|
|
142
|
+
const read = await readPaths(paths);
|
|
143
|
+
// Unique by content, first path wins for the artifact's name; extra paths listed too.
|
|
99
144
|
const byDigest = new Map();
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
byDigest.set(
|
|
145
|
+
read.forEach((r, i) => {
|
|
146
|
+
const entry = byDigest.get(r.digestB64) ?? { bytes: r.bytes, paths: [] };
|
|
147
|
+
entry.paths.push(paths[i]);
|
|
148
|
+
byDigest.set(r.digestB64, entry);
|
|
104
149
|
});
|
|
105
150
|
const unique = [...byDigest.keys()];
|
|
106
151
|
const checked = await batchCheck(config, unique.map(toUrlSafeB64));
|
|
@@ -111,57 +156,48 @@ export function buildServer() {
|
|
|
111
156
|
existing.set(d, entry.proofs);
|
|
112
157
|
}
|
|
113
158
|
const toMint = again ? unique : unique.filter((d) => !existing.has(d));
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
159
|
+
const fused = new Map();
|
|
160
|
+
const failed = new Map();
|
|
161
|
+
for (const d of toMint) {
|
|
162
|
+
const entry = byDigest.get(d);
|
|
163
|
+
const name = entry.paths[0].split(/[\\/]/).pop() ?? "file";
|
|
117
164
|
try {
|
|
118
|
-
|
|
119
|
-
// A 200 with fewer proofs than digests is still a partial failure;
|
|
120
|
-
// never let it reach the success path looking complete.
|
|
121
|
-
if (minted.length < toMint.length) {
|
|
122
|
-
partial = new PartialCommitError(minted, toMint.length, new Error("commit returned fewer proofs than digests sent"));
|
|
123
|
-
}
|
|
165
|
+
fused.set(d, await fuseFile(entry.bytes, name, config));
|
|
124
166
|
}
|
|
125
167
|
catch (err) {
|
|
126
|
-
|
|
127
|
-
minted = err.minted;
|
|
128
|
-
partial = err;
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
throw err;
|
|
132
|
-
}
|
|
168
|
+
failed.set(d, err instanceof Error ? err.message : String(err));
|
|
133
169
|
}
|
|
134
170
|
}
|
|
135
|
-
const mintedByDigest = new Map();
|
|
136
|
-
for (const p of minted) {
|
|
137
|
-
const d = p.artifact?.digestB64;
|
|
138
|
-
if (d !== undefined)
|
|
139
|
-
mintedByDigest.set(d, p);
|
|
140
|
-
}
|
|
141
171
|
const outcomes = [];
|
|
142
|
-
|
|
143
|
-
|
|
172
|
+
const frames = {};
|
|
173
|
+
for (const [digest, entry] of byDigest) {
|
|
174
|
+
const made = fused.get(digest);
|
|
144
175
|
const prior = existing.get(digest);
|
|
145
|
-
for (const path of
|
|
146
|
-
if (
|
|
147
|
-
const { counter, epoch } = positionOf(
|
|
176
|
+
for (const path of entry.paths) {
|
|
177
|
+
if (made) {
|
|
178
|
+
const { counter, epoch } = positionOf(made.proof);
|
|
179
|
+
frames[toUrlSafeB64(made.artifactDigestB64)] = made.frame;
|
|
148
180
|
outcomes.push({
|
|
149
181
|
path,
|
|
150
182
|
digest: toUrlSafeB64(digest),
|
|
151
|
-
outcome: "
|
|
183
|
+
outcome: "fused",
|
|
184
|
+
artifact_digest: toUrlSafeB64(made.artifactDigestB64),
|
|
185
|
+
placement: made.placement,
|
|
152
186
|
counter,
|
|
153
187
|
epoch,
|
|
154
188
|
total_positions: (prior?.length ?? 0) + 1,
|
|
155
|
-
proof_url: proofUrl(config.baseUrl,
|
|
189
|
+
proof_url: proofUrl(config.baseUrl, made.artifactDigestB64, counter ?? undefined, made.proof.commit?.epochId),
|
|
156
190
|
});
|
|
157
191
|
}
|
|
158
|
-
else if (prior) {
|
|
192
|
+
else if (prior && !failed.has(digest)) {
|
|
159
193
|
const first = prior[0]?.proof;
|
|
160
194
|
const { counter, epoch } = first ? positionOf(first) : { counter: null, epoch: null };
|
|
161
195
|
outcomes.push({
|
|
162
196
|
path,
|
|
163
197
|
digest: toUrlSafeB64(digest),
|
|
164
198
|
outcome: "on record",
|
|
199
|
+
artifact_digest: null,
|
|
200
|
+
placement: null,
|
|
165
201
|
counter,
|
|
166
202
|
epoch,
|
|
167
203
|
total_positions: prior.length,
|
|
@@ -169,50 +205,41 @@ export function buildServer() {
|
|
|
169
205
|
});
|
|
170
206
|
}
|
|
171
207
|
else {
|
|
172
|
-
// Neither minted nor previously on record: lost to a partial
|
|
173
|
-
// failure. The honest outcome is "not recorded", never a claim.
|
|
174
208
|
outcomes.push({
|
|
175
209
|
path,
|
|
176
210
|
digest: toUrlSafeB64(digest),
|
|
177
|
-
outcome: "not
|
|
211
|
+
outcome: "not fused",
|
|
212
|
+
artifact_digest: null,
|
|
213
|
+
placement: null,
|
|
178
214
|
counter: null,
|
|
179
215
|
epoch: null,
|
|
180
|
-
total_positions: 0,
|
|
216
|
+
total_positions: prior?.length ?? 0,
|
|
181
217
|
proof_url: null,
|
|
218
|
+
error: failed.get(digest) ?? "not attempted",
|
|
182
219
|
});
|
|
183
220
|
}
|
|
184
221
|
}
|
|
185
222
|
}
|
|
186
223
|
const structured = {
|
|
187
224
|
results: outcomes,
|
|
225
|
+
frames,
|
|
188
226
|
summary: {
|
|
189
|
-
|
|
227
|
+
fused: outcomes.filter((o) => o.outcome === "fused").length,
|
|
190
228
|
on_record: outcomes.filter((o) => o.outcome === "on record").length,
|
|
191
|
-
|
|
229
|
+
not_fused: outcomes.filter((o) => o.outcome === "not fused").length,
|
|
192
230
|
},
|
|
193
231
|
};
|
|
194
|
-
if (
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
: `Re-run bitgraph_record with the same paths: already-recorded files will come back as 'on record' and only the missing ones will mint.`;
|
|
232
|
+
if (failed.size > 0) {
|
|
233
|
+
const guidance = again
|
|
234
|
+
? "A file marked 'not fused' MAY still have been BitGraphed if the failure was a timeout: run bitgraph_check on it first, then re-run bitgraph_record with again=true for only the files still missing."
|
|
235
|
+
: "Re-run bitgraph_record with the same paths: files already on record come back as 'on record' and only the missing ones are BitGraphed.";
|
|
199
236
|
return {
|
|
200
237
|
isError: true,
|
|
201
|
-
content: [
|
|
202
|
-
{
|
|
203
|
-
type: "text",
|
|
204
|
-
text: `${errorText(partial.cause2)}\n` +
|
|
205
|
-
`${minted.length} of ${toMint.length} digests were recorded before the failure (those recordings are permanent); ${unrecorded} were not. ` +
|
|
206
|
-
`${retryGuidance}\n\n` +
|
|
207
|
-
renderRecordMarkdown(outcomes),
|
|
208
|
-
},
|
|
209
|
-
],
|
|
238
|
+
content: [{ type: "text", text: `${fused.size} of ${toMint.length} files were BitGraphed; ${failed.size} failed. ${guidance}\n\n${renderRecordMarkdown(outcomes)}` }],
|
|
210
239
|
structuredContent: structured,
|
|
211
240
|
};
|
|
212
241
|
}
|
|
213
|
-
const text = response_format === "json"
|
|
214
|
-
? capJson(structured).text
|
|
215
|
-
: renderRecordMarkdown(outcomes);
|
|
242
|
+
const text = response_format === "json" ? capJson(structured).text : renderRecordMarkdown(outcomes);
|
|
216
243
|
return ok(text, structured);
|
|
217
244
|
}
|
|
218
245
|
catch (err) {
|
|
@@ -223,8 +250,8 @@ export function buildServer() {
|
|
|
223
250
|
title: "Check for BitGraphs",
|
|
224
251
|
description: "Check whether files or digests are on record in the BitGraph ledger, without recording anything. " +
|
|
225
252
|
"Accepts file paths (hashed locally; only digests are sent) and/or raw SHA-256 digests in standard or URL-safe base64. " +
|
|
226
|
-
"Returns, per item: on record or
|
|
227
|
-
"Read-only. Use bitgraph_record to
|
|
253
|
+
"Returns, per item: on_record (the bytes are on record, as an exact recording or as the original a new file was made from), every position by counter, and the proof page URL. " +
|
|
254
|
+
"Read-only. Use bitgraph_record to BitGraph files that turn out not to be on record.",
|
|
228
255
|
inputSchema: {
|
|
229
256
|
paths: z
|
|
230
257
|
.array(z.string().min(1))
|
|
@@ -271,8 +298,8 @@ export function buildServer() {
|
|
|
271
298
|
input: input.label,
|
|
272
299
|
digest: toUrlSafeB64(input.standardDigest),
|
|
273
300
|
// A fused descendant that names these bytes as origin is not a recording of them.
|
|
274
|
-
|
|
275
|
-
|
|
301
|
+
// The original and the new file made from it find the same proof.
|
|
302
|
+
on_record: proofs.length > 0,
|
|
276
303
|
positions,
|
|
277
304
|
proof_url: proofs.length > 0 ? proofUrl(config.baseUrl, input.standardDigest) : null,
|
|
278
305
|
};
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikeargento/bitgraph-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "MCP server for BitGraph. Take a BitGraph of a file, check whether bytes are on record, and fetch proofs from any MCP client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://bitgraph.ing",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
|
-
"zod": "^3.25.0"
|
|
41
|
+
"zod": "^3.25.0",
|
|
42
|
+
"@mikeargento/bitgraph": "^1.3.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@types/node": "^20.0.0",
|
|
@@ -30,14 +30,14 @@ test("record markdown mentions again=true only when something was already on rec
|
|
|
30
30
|
total_positions: 1,
|
|
31
31
|
proof_url: "https://bitgraph.ing/proof/x",
|
|
32
32
|
};
|
|
33
|
-
const fresh = renderRecordMarkdown([{ ...base, path: "/a", outcome: "
|
|
33
|
+
const fresh = renderRecordMarkdown([{ ...base, path: "/a", outcome: "fused", artifact_digest: "ZnVzZWQ", placement: "container/1" }]);
|
|
34
34
|
assert.ok(!fresh.includes("again=true"));
|
|
35
35
|
const mixed = renderRecordMarkdown([
|
|
36
|
-
{ ...base, path: "/a", outcome: "
|
|
37
|
-
{ ...base, path: "/b", outcome: "on record" },
|
|
36
|
+
{ ...base, path: "/a", outcome: "fused", artifact_digest: "ZnVzZWQ", placement: "container/1" },
|
|
37
|
+
{ ...base, path: "/b", outcome: "on record", artifact_digest: null, placement: null },
|
|
38
38
|
]);
|
|
39
39
|
assert.ok(mixed.includes("again=true"));
|
|
40
|
-
assert.ok(mixed.startsWith("1
|
|
40
|
+
assert.ok(mixed.startsWith("1 fused, 1 already on record."));
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test("proof markdown states the window as between lower and upper", () => {
|
|
@@ -15,7 +15,7 @@ import { tmpdir } from "node:os";
|
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
17
17
|
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
18
|
-
import { buildServer } from "../server.js";
|
|
18
|
+
import { buildServer, type FusedSummary } from "../server.js";
|
|
19
19
|
import { toUrlSafeB64 } from "../encoding.js";
|
|
20
20
|
|
|
21
21
|
interface Recorded {
|
|
@@ -32,7 +32,6 @@ let fileB = "";
|
|
|
32
32
|
let fileC = "";
|
|
33
33
|
let digestA = ""; // standard b64 of fileA bytes
|
|
34
34
|
let digestB = "";
|
|
35
|
-
let commitMode: "ok" | "429" | "short" = "ok";
|
|
36
35
|
const EPOCH = createHash("sha256").update("test-epoch").digest("base64");
|
|
37
36
|
let mintCounter = 100;
|
|
38
37
|
|
|
@@ -90,17 +89,8 @@ before(async () => {
|
|
|
90
89
|
}
|
|
91
90
|
send(200, { results });
|
|
92
91
|
} else if (url.pathname === "/api/commit") {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
res.end(JSON.stringify({ error: "Rate limit exceeded: per-client proof rate limit exceeded" }));
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const digests = (body as { digests: Array<{ digestB64: string }> }).digests;
|
|
99
|
-
if (commitMode === "short") {
|
|
100
|
-
send(200, digests.slice(1).map((d) => proofFor(d.digestB64)));
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
send(200, digests.map((d) => proofFor(d.digestB64)));
|
|
92
|
+
// Ordinary recording is no longer what the record tool does; nothing here should call it.
|
|
93
|
+
send(500, { error: "unexpected /api/commit" });
|
|
104
94
|
} else if (url.pathname.startsWith("/api/proofs/digest/")) {
|
|
105
95
|
const digest = decodeURIComponent(url.pathname.split("/").pop() ?? "");
|
|
106
96
|
if (digest === toUrlSafeB64(digestA)) {
|
|
@@ -143,8 +133,24 @@ after(() => {
|
|
|
143
133
|
delete process.env["BITGRAPH_API_KEY"];
|
|
144
134
|
});
|
|
145
135
|
|
|
136
|
+
/** A stand-in for the fuse pipeline: no slot, no enclave; records what it was asked to fuse. */
|
|
137
|
+
const fusedCalls: Array<{ name: string; digestB64: string }> = [];
|
|
138
|
+
let fuseMode: "ok" | "fail" = "ok";
|
|
139
|
+
async function fakeFuse(bytes: Uint8Array, name: string): Promise<FusedSummary> {
|
|
140
|
+
const digestB64 = createHash("sha256").update(bytes).digest("base64");
|
|
141
|
+
fusedCalls.push({ name, digestB64 });
|
|
142
|
+
if (fuseMode === "fail") throw new Error("the boundary is restarting");
|
|
143
|
+
const artifactDigestB64 = createHash("sha256").update("fused:" + digestB64).digest("base64");
|
|
144
|
+
return {
|
|
145
|
+
proof: proofFor(artifactDigestB64) as unknown as FusedSummary["proof"],
|
|
146
|
+
frame: { type: "bitgraph-fuse/1" },
|
|
147
|
+
placement: "container/1",
|
|
148
|
+
artifactDigestB64,
|
|
149
|
+
originDigestB64: digestB64,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
146
152
|
async function connectedClient(): Promise<Client> {
|
|
147
|
-
const server = buildServer();
|
|
153
|
+
const server = buildServer({ fuseFile: fakeFuse });
|
|
148
154
|
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
149
155
|
const client = new Client({ name: "test-client", version: "0.0.0" });
|
|
150
156
|
await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]);
|
|
@@ -158,56 +164,53 @@ test("lists the three tools", async () => {
|
|
|
158
164
|
assert.deepEqual(names, ["bitgraph_check", "bitgraph_get_proof", "bitgraph_record"]);
|
|
159
165
|
});
|
|
160
166
|
|
|
161
|
-
test("record dedups on-record files and
|
|
167
|
+
test("record dedups on-record files and fuses only fresh ones", async () => {
|
|
162
168
|
const client = await connectedClient();
|
|
163
169
|
requests.length = 0;
|
|
170
|
+
fusedCalls.length = 0;
|
|
164
171
|
const result = await client.callTool({
|
|
165
172
|
name: "bitgraph_record",
|
|
166
173
|
arguments: { paths: [fileA, fileB] },
|
|
167
174
|
});
|
|
168
175
|
assert.ok(!result.isError, JSON.stringify(result.content));
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const commitBody = commit.body as { digests: Array<{ digestB64: string; hashAlg: string }>; chainId: string };
|
|
173
|
-
assert.equal(commitBody.chainId, "bitgraph:main");
|
|
174
|
-
assert.deepEqual(commitBody.digests, [{ digestB64: digestB, hashAlg: "sha256" }], "only fileB minted, standard b64");
|
|
175
|
-
assert.equal(commit.headers["authorization"], "Bearer test-key-123", "api key forwarded");
|
|
176
|
-
|
|
176
|
+
assert.equal(requests.filter((r) => r.path === "/api/commit").length, 0, "nothing is committed as bytes-only");
|
|
177
|
+
assert.deepEqual(fusedCalls.map((c) => c.digestB64), [digestB], "only fileB fused; fileA was on record");
|
|
178
|
+
assert.equal(fusedCalls[0]?.name, "b.txt", "the artifact is named after the file");
|
|
177
179
|
const batch = requests.find((r) => r.path === "/api/proofs/batch");
|
|
178
|
-
if (!batch) throw new Error("no batch check preceded the
|
|
180
|
+
if (!batch) throw new Error("no batch check preceded the fuse");
|
|
179
181
|
const batchBody = batch.body as { digests: string[] };
|
|
180
182
|
assert.ok(batchBody.digests.every((d) => !d.includes("+") && !d.includes("=")), "check uses url-safe digests");
|
|
181
|
-
|
|
182
183
|
const structured = result.structuredContent as {
|
|
183
|
-
results: Array<{ path: string; outcome: string; counter: string | null }>;
|
|
184
|
-
|
|
184
|
+
results: Array<{ path: string; outcome: string; counter: string | null; placement: string | null; artifact_digest: string | null }>;
|
|
185
|
+
frames: Record<string, unknown>;
|
|
186
|
+
summary: { fused: number; on_record: number; not_fused: number };
|
|
185
187
|
};
|
|
186
|
-
assert.equal(structured.summary.
|
|
188
|
+
assert.equal(structured.summary.fused, 1);
|
|
187
189
|
assert.equal(structured.summary.on_record, 1);
|
|
190
|
+
assert.equal(structured.summary.not_fused, 0);
|
|
188
191
|
const a = structured.results.find((r) => r.path === fileA);
|
|
189
192
|
const b = structured.results.find((r) => r.path === fileB);
|
|
190
193
|
assert.equal(a?.outcome, "on record");
|
|
191
194
|
assert.equal(a?.counter, "10", "on-record outcome reports the EARLIEST position");
|
|
192
|
-
assert.equal(b?.outcome, "
|
|
195
|
+
assert.equal(b?.outcome, "fused");
|
|
196
|
+
assert.equal(b?.placement, "container/1");
|
|
197
|
+
assert.ok(b?.artifact_digest && structured.frames[b.artifact_digest], "the Frame rides in the structured result under the fused digest");
|
|
193
198
|
});
|
|
194
199
|
|
|
195
|
-
test("record with again=true
|
|
200
|
+
test("record with again=true fuses even on-record files", async () => {
|
|
196
201
|
const client = await connectedClient();
|
|
197
|
-
|
|
202
|
+
fusedCalls.length = 0;
|
|
198
203
|
const result = await client.callTool({
|
|
199
204
|
name: "bitgraph_record",
|
|
200
205
|
arguments: { paths: [fileA], again: true },
|
|
201
206
|
});
|
|
202
207
|
assert.ok(!result.isError, JSON.stringify(result.content));
|
|
203
|
-
|
|
204
|
-
const commitBody = commit?.body as { digests: Array<{ digestB64: string }> };
|
|
205
|
-
assert.deepEqual(commitBody.digests.map((d) => d.digestB64), [digestA]);
|
|
208
|
+
assert.deepEqual(fusedCalls.map((c) => c.digestB64), [digestA]);
|
|
206
209
|
const structured = result.structuredContent as {
|
|
207
210
|
results: Array<{ outcome: string; total_positions: number }>;
|
|
208
211
|
};
|
|
209
|
-
assert.equal(structured.results[0]?.outcome, "
|
|
210
|
-
assert.equal(structured.results[0]?.total_positions, 3, "two prior positions plus the new
|
|
212
|
+
assert.equal(structured.results[0]?.outcome, "fused");
|
|
213
|
+
assert.equal(structured.results[0]?.total_positions, 3, "two prior positions plus the new artifact");
|
|
211
214
|
});
|
|
212
215
|
|
|
213
216
|
test("check reports positions without ever committing", async () => {
|
|
@@ -274,49 +277,29 @@ test("get_proof requires exactly one selector", async () => {
|
|
|
274
277
|
assert.ok(result.isError);
|
|
275
278
|
});
|
|
276
279
|
|
|
277
|
-
test("
|
|
280
|
+
test("a fuse failure labels the file 'not fused', never 'on record'", async () => {
|
|
278
281
|
const client = await connectedClient();
|
|
279
|
-
|
|
282
|
+
fuseMode = "fail";
|
|
280
283
|
try {
|
|
281
284
|
const result = await client.callTool({
|
|
282
285
|
name: "bitgraph_record",
|
|
283
286
|
arguments: { paths: [fileC] },
|
|
284
287
|
});
|
|
285
|
-
assert.ok(result.isError, "
|
|
288
|
+
assert.ok(result.isError, "a failure must be an error result");
|
|
286
289
|
const text = (result.content as Array<{ text: string }>)[0]?.text ?? "";
|
|
287
|
-
assert.ok(text.includes("Retry after 30 seconds"), text);
|
|
288
290
|
assert.ok(text.includes("0 of 1"), text);
|
|
291
|
+
assert.ok(text.includes("the boundary is restarting"), text);
|
|
289
292
|
const structured = result.structuredContent as {
|
|
290
|
-
results: Array<{ outcome: string; proof_url: string | null;
|
|
291
|
-
summary: {
|
|
293
|
+
results: Array<{ outcome: string; proof_url: string | null; error?: string }>;
|
|
294
|
+
summary: { fused: number; on_record: number; not_fused: number };
|
|
292
295
|
};
|
|
293
|
-
assert.equal(structured.results[0]?.outcome, "not
|
|
296
|
+
assert.equal(structured.results[0]?.outcome, "not fused");
|
|
294
297
|
assert.equal(structured.results[0]?.proof_url, null);
|
|
295
|
-
assert.equal(structured.summary.
|
|
296
|
-
assert.equal(structured.summary.
|
|
298
|
+
assert.equal(structured.summary.not_fused, 1);
|
|
299
|
+
assert.equal(structured.summary.fused, 0);
|
|
297
300
|
assert.equal(structured.summary.on_record, 0);
|
|
298
301
|
} finally {
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
test("a 200 with fewer proofs than digests is treated as a partial failure", async () => {
|
|
304
|
-
const client = await connectedClient();
|
|
305
|
-
commitMode = "short";
|
|
306
|
-
try {
|
|
307
|
-
const result = await client.callTool({
|
|
308
|
-
name: "bitgraph_record",
|
|
309
|
-
arguments: { paths: [fileC] },
|
|
310
|
-
});
|
|
311
|
-
assert.ok(result.isError, "shortfall must not reach the success path");
|
|
312
|
-
const structured = result.structuredContent as {
|
|
313
|
-
results: Array<{ outcome: string }>;
|
|
314
|
-
};
|
|
315
|
-
assert.equal(structured.results[0]?.outcome, "not recorded");
|
|
316
|
-
const text = (result.content as Array<{ text: string }>)[0]?.text ?? "";
|
|
317
|
-
assert.ok(text.includes("fewer proofs than digests"), text);
|
|
318
|
-
} finally {
|
|
319
|
-
commitMode = "ok";
|
|
302
|
+
fuseMode = "ok";
|
|
320
303
|
}
|
|
321
304
|
});
|
|
322
305
|
|
|
@@ -330,5 +313,5 @@ test("record surfaces unreadable paths before any network call", async () => {
|
|
|
330
313
|
assert.ok(result.isError);
|
|
331
314
|
assert.equal(requests.length, 0, "no API call happened; nothing was minted");
|
|
332
315
|
const text = (result.content as Array<{ text: string }>)[0]?.text ?? "";
|
|
333
|
-
assert.ok(text.includes("nothing was
|
|
316
|
+
assert.ok(text.includes("nothing was BitGraphed"));
|
|
334
317
|
});
|