@mikeargento/bitgraph-mcp 0.5.1 → 0.6.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/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/__tests__/carrier.test.d.ts +2 -0
- package/dist/__tests__/carrier.test.d.ts.map +1 -0
- package/dist/__tests__/carrier.test.js +243 -0
- package/dist/__tests__/carrier.test.js.map +1 -0
- package/dist/__tests__/encoding.test.js +1 -1
- package/dist/__tests__/encoding.test.js.map +1 -1
- package/dist/__tests__/format.test.js +6 -6
- package/dist/__tests__/format.test.js.map +1 -1
- package/dist/__tests__/scan.test.js +1 -1
- package/dist/__tests__/scan.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +8 -7
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/api.js +1 -1
- package/dist/api.js.map +1 -1
- package/dist/carrier-io.d.ts +52 -0
- package/dist/carrier-io.d.ts.map +1 -0
- package/dist/carrier-io.js +91 -0
- package/dist/carrier-io.js.map +1 -0
- package/dist/encoding.js +1 -1
- package/dist/encoding.js.map +1 -1
- package/dist/format.d.ts +17 -3
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +36 -15
- package/dist/format.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/scan.d.ts +4 -0
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +44 -1
- package/dist/scan.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +151 -29
- package/dist/server.js.map +1 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +2 -2
- package/dist/task.js.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +13 -5
- package/src/__tests__/carrier.test.ts +271 -0
- package/src/__tests__/encoding.test.ts +1 -1
- package/src/__tests__/format.test.ts +6 -6
- package/src/__tests__/scan.test.ts +1 -1
- package/src/__tests__/tools.test.ts +8 -7
- package/src/api.ts +1 -1
- package/src/carrier-io.ts +120 -0
- package/src/encoding.ts +1 -1
- package/src/format.ts +56 -19
- package/src/index.ts +1 -1
- package/src/scan.ts +48 -1
- package/src/server.ts +169 -34
- package/src/task.ts +2 -2
- package/src/types.ts +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -24,4 +24,4 @@ BitGraph itself lives at [bitgraph.ing](https://bitgraph.ing). The protocol, thi
|
|
|
24
24
|
|
|
25
25
|
## License
|
|
26
26
|
|
|
27
|
-
MIT. Copyright (c) 2024-2026
|
|
27
|
+
MIT. Copyright (c) 2024-2026 Argento Computing Inc. The BitGraph protocol is patent pending; this client is licensed for use, the protocol implementation it talks to is not.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carrier.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/carrier.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
|
+
/**
|
|
3
|
+
* BitGraphed files through the MCP tools, end to end: a real client over an
|
|
4
|
+
* in-memory transport, a mock bitgraph.ing, and REAL carriers built from the
|
|
5
|
+
* verify package's fixture material (real proofs, real anchors, real block
|
|
6
|
+
* headers; nothing minted, no network). The two rules under test:
|
|
7
|
+
*
|
|
8
|
+
* 1. The lookups use the digest of the COMMITTED bytes inside, never the
|
|
9
|
+
* envelope's, and the carried proof is judged offline (verdict, window).
|
|
10
|
+
* 2. bitgraph_record NEVER mints carrier bytes: the envelope is not the
|
|
11
|
+
* recorded thing. The fake pipelines fail the test if a carrier reaches
|
|
12
|
+
* them.
|
|
13
|
+
*/
|
|
14
|
+
import { test, before, after } from "node:test";
|
|
15
|
+
import { strict as assert } from "node:assert";
|
|
16
|
+
import { createHash } from "node:crypto";
|
|
17
|
+
import { createServer } from "node:http";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { writeFile, mkdtemp } from "node:fs/promises";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
24
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
25
|
+
import { buildCarrier, } from "@mikeargento/bitgraph-verify";
|
|
26
|
+
import { buildServer } from "../server.js";
|
|
27
|
+
import { toUrlSafeB64 } from "../encoding.js";
|
|
28
|
+
import { sniffC2paBytes, scanFile } from "../scan.js";
|
|
29
|
+
const fixtures = fileURLToPath(new URL("../../../verify/src/__tests__/fixtures/carrier/", import.meta.url));
|
|
30
|
+
const readJson = (name) => JSON.parse(readFileSync(join(fixtures, name), "utf-8"));
|
|
31
|
+
let mock;
|
|
32
|
+
let completePath = ""; // demo2: floor + ceiling inside
|
|
33
|
+
let undevPath = ""; // demo1: floor inside, ceiling unfetched
|
|
34
|
+
let corruptPath = ""; // demo2 carrier with a broken payload byte
|
|
35
|
+
let plainPath = ""; // an ordinary file that should still mint
|
|
36
|
+
let c2paPath = ""; // an ordinary file carrying a synthetic C2PA marker
|
|
37
|
+
let innerDigest2 = ""; // standard b64 of demo2's committed bytes
|
|
38
|
+
let innerDigest1 = "";
|
|
39
|
+
const EPOCH = createHash("sha256").update("carrier-epoch").digest("base64");
|
|
40
|
+
before(async () => {
|
|
41
|
+
const root = await mkdtemp(join(tmpdir(), "bitgraph-mcp-carrier-"));
|
|
42
|
+
const demo2 = new Uint8Array(readFileSync(join(fixtures, "demo2.txt")));
|
|
43
|
+
const demo1 = new Uint8Array(readFileSync(join(fixtures, "demo1.txt")));
|
|
44
|
+
innerDigest2 = createHash("sha256").update(demo2).digest("base64");
|
|
45
|
+
innerDigest1 = createHash("sha256").update(demo1).digest("base64");
|
|
46
|
+
const complete = {
|
|
47
|
+
carrier: "bitgraph-carrier/1",
|
|
48
|
+
proof: readJson("demo2.proof.json"),
|
|
49
|
+
floor: { status: "present", anchor: readJson("floor2.anchor.json"), witness: readJson("floor2.witness.json") },
|
|
50
|
+
ceiling: { status: "present", basis: "counter-order", anchor: readJson("ceiling2.anchor.json"), witness: readJson("ceiling2.witness.json") },
|
|
51
|
+
};
|
|
52
|
+
const undeveloped = {
|
|
53
|
+
carrier: "bitgraph-carrier/1",
|
|
54
|
+
proof: readJson("demo1.proof.json"),
|
|
55
|
+
floor: { status: "present", anchor: readJson("floor1.anchor.json"), witness: readJson("floor1.witness.json") },
|
|
56
|
+
ceiling: { status: "unfetched" },
|
|
57
|
+
};
|
|
58
|
+
completePath = join(root, "photo.bitgraph.txt");
|
|
59
|
+
await writeFile(completePath, buildCarrier(demo2, complete));
|
|
60
|
+
undevPath = join(root, "doc.bitgraph.txt");
|
|
61
|
+
await writeFile(undevPath, buildCarrier(demo1, undeveloped));
|
|
62
|
+
// Corrupt: the frame intact (tail magic still matches), one byte of the
|
|
63
|
+
// JSON payload broken, so the block is found but does not parse.
|
|
64
|
+
const corrupt = Buffer.from(buildCarrier(demo2, complete));
|
|
65
|
+
corrupt[demo2.length + 12] = 0x58; // the payload's first byte, "{" -> "X"
|
|
66
|
+
corruptPath = join(root, "broken.bitgraph.txt");
|
|
67
|
+
await writeFile(corruptPath, corrupt);
|
|
68
|
+
plainPath = join(root, "fresh.txt");
|
|
69
|
+
await writeFile(plainPath, "fresh bytes that should mint");
|
|
70
|
+
// A JUMBF description box shape: "jumd", a 16-byte type, a toggle, the "c2pa" label.
|
|
71
|
+
const c2pa = Buffer.concat([
|
|
72
|
+
Buffer.from("leading bytes "),
|
|
73
|
+
Buffer.from("jumd"),
|
|
74
|
+
Buffer.alloc(17, 3),
|
|
75
|
+
Buffer.from("c2pa\0and the rest of the file"),
|
|
76
|
+
]);
|
|
77
|
+
c2paPath = join(root, "credentialed.bin");
|
|
78
|
+
await writeFile(c2paPath, c2pa);
|
|
79
|
+
mock = createServer((req, res) => {
|
|
80
|
+
let raw = "";
|
|
81
|
+
req.on("data", (d) => (raw += d));
|
|
82
|
+
req.on("end", () => {
|
|
83
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
84
|
+
const body = raw.length > 0 ? JSON.parse(raw) : null;
|
|
85
|
+
const send = (status, payload) => {
|
|
86
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
87
|
+
res.end(JSON.stringify(payload));
|
|
88
|
+
};
|
|
89
|
+
if (url.pathname === "/api/proofs/batch") {
|
|
90
|
+
const digests = body.digests;
|
|
91
|
+
const results = {};
|
|
92
|
+
for (const d of digests) {
|
|
93
|
+
// Only demo2's COMMITTED bytes are in this ledger; the envelope digests never are.
|
|
94
|
+
results[d] =
|
|
95
|
+
d === toUrlSafeB64(innerDigest2)
|
|
96
|
+
? { proofs: [{ proof: { artifact: { digestB64: innerDigest2 }, commit: { counter: "2874", epochId: EPOCH } } }] }
|
|
97
|
+
: { proofs: [] };
|
|
98
|
+
}
|
|
99
|
+
send(200, { results });
|
|
100
|
+
}
|
|
101
|
+
else if (url.pathname.startsWith("/api/proofs/digest/")) {
|
|
102
|
+
const digest = decodeURIComponent(url.pathname.split("/").pop() ?? "");
|
|
103
|
+
if (digest === toUrlSafeB64(innerDigest2)) {
|
|
104
|
+
send(200, {
|
|
105
|
+
proofs: [{ proof: { artifact: { digestB64: innerDigest2 }, commit: { counter: "2874", epochId: EPOCH } } }],
|
|
106
|
+
positions: [{ counter: "2874", epoch: toUrlSafeB64(EPOCH), lowerTime: null, upperTime: null }],
|
|
107
|
+
causalWindow: null,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
send(200, { proofs: [] });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
send(404, { error: `unexpected ${url.pathname}` });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
await new Promise((resolve) => mock.listen(0, "127.0.0.1", resolve));
|
|
120
|
+
const address = mock.address();
|
|
121
|
+
if (address === null || typeof address === "string")
|
|
122
|
+
throw new Error("no port");
|
|
123
|
+
process.env["BITGRAPH_API_URL"] = `http://127.0.0.1:${address.port}`;
|
|
124
|
+
process.env["BITGRAPH_API_KEY"] = "test-key-123";
|
|
125
|
+
});
|
|
126
|
+
after(() => {
|
|
127
|
+
mock.close();
|
|
128
|
+
delete process.env["BITGRAPH_API_URL"];
|
|
129
|
+
delete process.env["BITGRAPH_API_KEY"];
|
|
130
|
+
});
|
|
131
|
+
/** The pipelines fail the test when carrier bytes reach them. */
|
|
132
|
+
const fusedNames = [];
|
|
133
|
+
const guardFuseFile = async (file) => {
|
|
134
|
+
assert.ok(!file.name.includes(".bitgraph."), `a BitGraphed file reached the mint: ${file.name}`);
|
|
135
|
+
fusedNames.push(file.name);
|
|
136
|
+
const artifactDigestB64 = createHash("sha256").update("fused:" + file.digestB64).digest("base64");
|
|
137
|
+
return {
|
|
138
|
+
proof: { version: "bitgraph/1", artifact: { digestB64: artifactDigestB64 }, commit: { counter: "500", epochId: EPOCH } },
|
|
139
|
+
frame: { type: "bitgraph-fuse/1" },
|
|
140
|
+
placement: file.placement,
|
|
141
|
+
artifactDigestB64,
|
|
142
|
+
originDigestB64: file.digestB64,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const guardFuseSet = async (files) => {
|
|
146
|
+
for (const f of files)
|
|
147
|
+
assert.ok(!f.name.includes(".bitgraph."), `a BitGraphed file reached the set mint: ${f.name}`);
|
|
148
|
+
throw new Error("no set expected in these tests");
|
|
149
|
+
};
|
|
150
|
+
async function connectedClient() {
|
|
151
|
+
const server = buildServer({ fuseSet: guardFuseSet, fuseFile: guardFuseFile });
|
|
152
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
153
|
+
const client = new Client({ name: "test-client", version: "0.0.0" });
|
|
154
|
+
await Promise.all([client.connect(clientTransport), server.connect(serverTransport)]);
|
|
155
|
+
return client;
|
|
156
|
+
}
|
|
157
|
+
const textOf = (result) => result.content[0].text;
|
|
158
|
+
const structuredOf = (result) => result.structuredContent;
|
|
159
|
+
test("check: a BitGraphed file is judged offline and looked up by its committed bytes", async () => {
|
|
160
|
+
const client = await connectedClient();
|
|
161
|
+
const result = await client.callTool({ name: "bitgraph_check", arguments: { paths: [completePath, undevPath, corruptPath, c2paPath] } });
|
|
162
|
+
const text = textOf(result);
|
|
163
|
+
const { results } = structuredOf(result);
|
|
164
|
+
const complete = results.find((r) => r["input"] === completePath);
|
|
165
|
+
assert.equal(complete["on_record"], true);
|
|
166
|
+
assert.equal(complete["digest"], toUrlSafeB64(innerDigest2), "the lookup digest is the committed bytes', not the envelope's");
|
|
167
|
+
const view = complete["carrier"];
|
|
168
|
+
assert.equal(view.verdict, "TRUE");
|
|
169
|
+
assert.ok(view.not_before.block > 0 && view.not_after.block > view.not_before.block);
|
|
170
|
+
const undev = results.find((r) => r["input"] === undevPath);
|
|
171
|
+
assert.equal(undev["on_record"], false);
|
|
172
|
+
const undevView = undev["carrier"];
|
|
173
|
+
assert.equal(undevView.verdict, "TRUE");
|
|
174
|
+
assert.equal(undevView.not_after, null);
|
|
175
|
+
assert.equal(undevView.ceiling, "unfetched");
|
|
176
|
+
assert.ok(text.includes("not in this ledger"), "a foreign carrier is stated, not called unrecorded");
|
|
177
|
+
assert.ok(text.includes("NOT FETCHED"), "an absent ceiling is stated in those words");
|
|
178
|
+
const corrupt = results.find((r) => r["input"] === corruptPath);
|
|
179
|
+
assert.equal(corrupt["on_record"], false);
|
|
180
|
+
assert.ok(String(corrupt["note"]).includes("unreadable"), "a corrupt block is a stated condition");
|
|
181
|
+
assert.ok(text.includes("not judged"), "a corrupt carrier is not judged, not 'not on record'");
|
|
182
|
+
const credentialed = results.find((r) => r["input"] === c2paPath);
|
|
183
|
+
assert.equal(credentialed["c2pa"], true);
|
|
184
|
+
assert.ok(text.includes("Content Credentials (C2PA) detected"));
|
|
185
|
+
});
|
|
186
|
+
test("record: carrier bytes never mint; the plain file still does", async () => {
|
|
187
|
+
fusedNames.length = 0;
|
|
188
|
+
const client = await connectedClient();
|
|
189
|
+
const result = await client.callTool({ name: "bitgraph_record", arguments: { paths: [completePath, undevPath, plainPath] } });
|
|
190
|
+
const text = textOf(result);
|
|
191
|
+
const { summary, results } = structuredOf(result);
|
|
192
|
+
assert.deepEqual(fusedNames, ["fresh.txt"], "exactly the plain file reached the mint");
|
|
193
|
+
assert.equal(summary["fused"], 1);
|
|
194
|
+
assert.equal(summary["on_record"], 1, "the ledger-confirmed carrier reports as on record");
|
|
195
|
+
assert.equal(summary["carried"], 1, "the foreign carrier reports as carried, nothing minted");
|
|
196
|
+
assert.equal(summary["not_fused"], 0);
|
|
197
|
+
const onRecord = results.find((r) => r["outcome"] === "on record");
|
|
198
|
+
assert.equal(onRecord["digest"], toUrlSafeB64(innerDigest2));
|
|
199
|
+
assert.equal(onRecord["carrier"].verdict, "TRUE");
|
|
200
|
+
const carried = results.find((r) => r["outcome"] === "carried");
|
|
201
|
+
assert.equal(carried["digest"], toUrlSafeB64(innerDigest1));
|
|
202
|
+
assert.ok(text.includes("nothing minted"), "the markdown states the envelope rule");
|
|
203
|
+
});
|
|
204
|
+
test("record: a corrupt carrier is refused loudly and never minted", async () => {
|
|
205
|
+
fusedNames.length = 0;
|
|
206
|
+
const client = await connectedClient();
|
|
207
|
+
const result = await client.callTool({ name: "bitgraph_record", arguments: { paths: [corruptPath] } });
|
|
208
|
+
assert.equal(result.isError, true);
|
|
209
|
+
assert.deepEqual(fusedNames, [], "nothing reached the mint");
|
|
210
|
+
assert.ok(textOf(result).includes("unreadable"), "the reason names the corrupt block");
|
|
211
|
+
});
|
|
212
|
+
test("get_proof: a path to a foreign BitGraphed file answers offline from the proof inside", async () => {
|
|
213
|
+
const client = await connectedClient();
|
|
214
|
+
const result = await client.callTool({ name: "bitgraph_get_proof", arguments: { path: undevPath } });
|
|
215
|
+
const text = textOf(result);
|
|
216
|
+
assert.ok(text.includes("Judged offline from the proof this BitGraphed file carries"), text);
|
|
217
|
+
assert.ok(text.includes("carried proof TRUE"));
|
|
218
|
+
assert.ok(text.includes("NOT FETCHED"));
|
|
219
|
+
});
|
|
220
|
+
test("get_proof: a ledger-known BitGraphed file uses the ledger and states the carried verdict", async () => {
|
|
221
|
+
const client = await connectedClient();
|
|
222
|
+
const result = await client.callTool({ name: "bitgraph_get_proof", arguments: { path: completePath } });
|
|
223
|
+
const text = textOf(result);
|
|
224
|
+
assert.ok(text.includes("#2874"), text);
|
|
225
|
+
assert.ok(text.includes("carries its own proof (carried proof TRUE"), text);
|
|
226
|
+
});
|
|
227
|
+
test("c2pa sniff: the pair must be jumd then c2pa, near, in that order", async () => {
|
|
228
|
+
assert.equal(sniffC2paBytes(Buffer.concat([Buffer.from("jumd"), Buffer.alloc(17), Buffer.from("c2pa")])), true);
|
|
229
|
+
assert.equal(sniffC2paBytes(Buffer.from("c2pa then jumd the wrong way round")), false);
|
|
230
|
+
assert.equal(sniffC2paBytes(Buffer.from("jumd alone")), false);
|
|
231
|
+
assert.equal(sniffC2paBytes(Buffer.concat([Buffer.from("jumd"), Buffer.alloc(200), Buffer.from("c2pa")])), false, "too far apart");
|
|
232
|
+
// Streaming: the pair split across a 64 KiB read boundary is still seen.
|
|
233
|
+
const size = 64 * 1024;
|
|
234
|
+
const split = Buffer.alloc(size + 40);
|
|
235
|
+
Buffer.from("jumd").copy(split, size - 2);
|
|
236
|
+
Buffer.from("c2pa").copy(split, size + 19);
|
|
237
|
+
const root = await mkdtemp(join(tmpdir(), "bitgraph-mcp-c2pa-"));
|
|
238
|
+
const p = join(root, "split.bin");
|
|
239
|
+
await writeFile(p, split);
|
|
240
|
+
const scanned = await scanFile(p);
|
|
241
|
+
assert.equal(scanned.c2pa, true, "a pair straddling the chunk boundary is detected");
|
|
242
|
+
});
|
|
243
|
+
//# sourceMappingURL=carrier.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carrier.test.js","sourceRoot":"","sources":["../../src/__tests__/carrier.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026
|
|
1
|
+
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
2
|
import { test } from "node:test";
|
|
3
3
|
import { strict as assert } from "node:assert";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.test.js","sourceRoot":"","sources":["../../src/__tests__/encoding.test.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"encoding.test.js","sourceRoot":"","sources":["../../src/__tests__/encoding.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026
|
|
1
|
+
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
2
|
import { test } from "node:test";
|
|
3
3
|
import { strict as assert } from "node:assert";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -31,7 +31,7 @@ test("record markdown mentions again=true only when something was already on rec
|
|
|
31
31
|
{ ...base, path: "/b", outcome: "on record", artifact_digest: null, placement: null, member: null, member_count: null },
|
|
32
32
|
]);
|
|
33
33
|
assert.ok(mixed.includes("again=true"));
|
|
34
|
-
assert.ok(mixed.startsWith("1 fused, 1 already on record
|
|
34
|
+
assert.ok(mixed.startsWith("1 fused, 1 already on record."));
|
|
35
35
|
});
|
|
36
36
|
test("record markdown names the set once and its members by row", () => {
|
|
37
37
|
const set = {
|
|
@@ -47,14 +47,14 @@ test("record markdown names the set once and its members by row", () => {
|
|
|
47
47
|
};
|
|
48
48
|
const row = { digest: toUrlSafeB64(DIGEST), counter: "1386", epoch: toUrlSafeB64(EPOCH), total_positions: 1, proof_url: "https://bitgraph.ing/proof/x", artifact_digest: "ZnVzZWQ", outcome: "fused", member_count: 2 };
|
|
49
49
|
const md = renderRecordMarkdown([{ ...row, path: "/a.png", placement: "trailer/1", member: 2 }, { ...row, path: "/b.txt", placement: "container/2", member: 1 }], set);
|
|
50
|
-
assert.ok(md.startsWith("2 files BitGraphed as one set at #1386 (set of 2), 0 already on record
|
|
50
|
+
assert.ok(md.startsWith("2 files BitGraphed as one set at #1386 (set of 2), 0 already on record."), md);
|
|
51
51
|
assert.ok(md.includes("- #1386 · set of 2 · https://bitgraph.ing/proof/c2V0?counter=1386"), md);
|
|
52
52
|
assert.ok(md.includes("- fused · /a.png (2 of 2, trailer/1)"), md);
|
|
53
53
|
assert.ok(md.includes("- fused · /b.txt (1 of 2, container/2)"), md);
|
|
54
54
|
const waiting = renderRecordMarkdown([{ ...row, path: "/a.png", placement: "trailer/1", member: 1 }], { ...set, set: "set/2", index: { written: 0, pending: 2 } });
|
|
55
|
-
assert.ok(waiting.includes("
|
|
55
|
+
assert.ok(waiting.includes("The set proof beside the originals is the record either way."), waiting);
|
|
56
56
|
});
|
|
57
|
-
test("proof markdown states the
|
|
57
|
+
test("proof markdown states the floor in time and the ceiling in position", () => {
|
|
58
58
|
const detail = {
|
|
59
59
|
proofs: [{ proof: { artifact: { digestB64: DIGEST }, commit: { counter: "42", epochId: EPOCH } } }],
|
|
60
60
|
positions: [{ counter: "42", epoch: toUrlSafeB64(EPOCH), lowerTime: null, upperTime: null }],
|
|
@@ -64,7 +64,7 @@ test("proof markdown states the window as between lower and upper", () => {
|
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
const md = renderProofMarkdown(detail, "https://bitgraph.ing");
|
|
67
|
-
assert.ok(md.includes("BitGraphed
|
|
67
|
+
assert.ok(md.includes("BitGraphed after 2026-07-01T00:00:00.000Z (Ethereum block 100), and before the anchoring of block 101 (that block mined 2026-07-01T00:00:12.000Z)."), md);
|
|
68
68
|
assert.ok(md.includes("# BitGraph #42"));
|
|
69
69
|
});
|
|
70
70
|
test("capJson elides large attestation reports before truncating", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.test.js","sourceRoot":"","sources":["../../src/__tests__/format.test.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"format.test.js","sourceRoot":"","sources":["../../src/__tests__/format.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026
|
|
1
|
+
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
2
|
/**
|
|
3
3
|
* The scan's two promises: the digest is the file's own, and a state
|
|
4
4
|
* finished with the placement's suffix for a slot is the hash of the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.test.js","sourceRoot":"","sources":["../../src/__tests__/scan.test.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"scan.test.js","sourceRoot":"","sources":["../../src/__tests__/scan.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Copyright (c) 2024-2026
|
|
1
|
+
// Copyright (c) 2024-2026 Argento Computing Inc. Licensed under the MIT License. See LICENSE.
|
|
2
2
|
/**
|
|
3
3
|
* End-to-end tool tests: a real MCP client drives the real server over an
|
|
4
4
|
* in-memory transport, against a mock bitgraph.ing that asserts the exact
|
|
@@ -240,7 +240,7 @@ test("record makes ONE set of the fresh files and leaves on-record ones alone",
|
|
|
240
240
|
const batchBody = batch.body;
|
|
241
241
|
assert.ok(batchBody.digests.every((d) => !d.includes("+") && !d.includes("=")), "check uses url-safe digests");
|
|
242
242
|
const structured = result.structuredContent;
|
|
243
|
-
assert.deepEqual(structured.summary, { files: 3, directories: 0, fused: 2, on_record: 1, not_fused: 0 });
|
|
243
|
+
assert.deepEqual(structured.summary, { files: 3, directories: 0, fused: 2, on_record: 1, carried: 0, not_fused: 0 });
|
|
244
244
|
assert.ok(structured.set, "the set is reported");
|
|
245
245
|
assert.equal(structured.set?.count, 2);
|
|
246
246
|
assert.ok(structured.set?.proof_url.includes("/proof/") && structured.set?.proof_url.includes("counter="), "the set's proof page is pinned to its position");
|
|
@@ -283,7 +283,7 @@ test("a single file is fused on its own, with its Frame; again=true fuses an on-
|
|
|
283
283
|
assert.ok(row?.artifact_digest && structured.frames[row.artifact_digest], "the Frame rides in the structured result under the fused digest");
|
|
284
284
|
assert.ok(row?.proof_url?.includes(encodeURIComponent(row.artifact_digest ?? "")), "a single file's proof page is its own");
|
|
285
285
|
const text = textOf(result);
|
|
286
|
-
assert.ok(text.startsWith("1 fused, 0 already on record
|
|
286
|
+
assert.ok(text.startsWith("1 fused, 0 already on record."), text);
|
|
287
287
|
assert.ok(text.includes("its Frame is in the structured result"), text);
|
|
288
288
|
});
|
|
289
289
|
test("a directory is its regular files, hidden entries and links left out", async () => {
|
|
@@ -296,7 +296,7 @@ test("a directory is its regular files, hidden entries and links left out", asyn
|
|
|
296
296
|
assert.ok(!result.isError, JSON.stringify(result.content));
|
|
297
297
|
assert.deepEqual(setCalls[0]?.names, ["a1.txt", "a2.txt"]);
|
|
298
298
|
const structured = result.structuredContent;
|
|
299
|
-
assert.deepEqual(structured.summary, { files: 2, directories: 1, fused: 2, on_record: 0, not_fused: 0 });
|
|
299
|
+
assert.deepEqual(structured.summary, { files: 2, directories: 1, fused: 2, on_record: 0, carried: 0, not_fused: 0 });
|
|
300
300
|
assert.equal(structured.set?.count, 2);
|
|
301
301
|
});
|
|
302
302
|
test("the same bytes under two paths are one file, fused once and reported twice", async () => {
|
|
@@ -357,7 +357,7 @@ test("evidence the site cannot index waits, blocks a new set, and is sent first
|
|
|
357
357
|
const s1 = first.structuredContent;
|
|
358
358
|
assert.deepEqual(s1.set?.index, { written: 0, pending: BIG });
|
|
359
359
|
assert.equal(pendingIndexCount(), BIG);
|
|
360
|
-
assert.ok(textOf(first).includes("
|
|
360
|
+
assert.ok(textOf(first).includes("The set proof beside the originals is the record either way."), textOf(first).slice(0, 400));
|
|
361
361
|
// Still down: nothing new is made, so the members cannot be made again by mistake.
|
|
362
362
|
requests.length = 0;
|
|
363
363
|
setCalls.length = 0;
|
|
@@ -394,7 +394,7 @@ test("a set failure labels every attempted file 'not fused', never 'on record'",
|
|
|
394
394
|
const structured = result.structuredContent;
|
|
395
395
|
assert.equal(structured.set, null);
|
|
396
396
|
assert.ok(structured.results.every((r) => r.outcome === "not fused" && r.proof_url === null));
|
|
397
|
-
assert.deepEqual(structured.summary, { files: 2, directories: 0, fused: 0, on_record: 0, not_fused: 2 });
|
|
397
|
+
assert.deepEqual(structured.summary, { files: 2, directories: 0, fused: 0, on_record: 0, carried: 0, not_fused: 2 });
|
|
398
398
|
}
|
|
399
399
|
finally {
|
|
400
400
|
fuseMode = "ok";
|
|
@@ -459,7 +459,8 @@ test("get_proof by number resolves through search and renders the window", async
|
|
|
459
459
|
assert.ok(!result.isError, JSON.stringify(result.content));
|
|
460
460
|
const text = textOf(result);
|
|
461
461
|
assert.ok(text.includes("# BitGraph #10"));
|
|
462
|
-
assert.ok(text.includes("BitGraphed
|
|
462
|
+
assert.ok(text.includes("BitGraphed after 2026-07-01T00:00:00.000Z"));
|
|
463
|
+
assert.ok(text.includes("before the anchoring of block 2"), "the ceiling is stated in position, never as the block's mine time");
|
|
463
464
|
assert.ok(text.includes("Causal positions (2)"));
|
|
464
465
|
assert.ok(text.includes("/proof/"), "includes the proof page url");
|
|
465
466
|
});
|