proofseal 0.0.2 → 0.1.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 +21 -0
- package/NOTICE +13 -0
- package/README.md +204 -7
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +440 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.js +58 -0
- package/dist/config.js.map +1 -0
- package/dist/core/canonical.d.ts +16 -0
- package/dist/core/canonical.js +29 -0
- package/dist/core/canonical.js.map +1 -0
- package/dist/core/hash.d.ts +32 -0
- package/dist/core/hash.js +81 -0
- package/dist/core/hash.js.map +1 -0
- package/dist/core/marker-lint.d.ts +5 -0
- package/dist/core/marker-lint.js +55 -0
- package/dist/core/marker-lint.js.map +1 -0
- package/dist/core/paths.d.ts +10 -0
- package/dist/core/paths.js +13 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/harness/quantize.d.ts +38 -0
- package/dist/harness/quantize.js +76 -0
- package/dist/harness/quantize.js.map +1 -0
- package/dist/harness/run.d.ts +61 -0
- package/dist/harness/run.js +137 -0
- package/dist/harness/run.js.map +1 -0
- package/dist/history/gitinfo.d.ts +16 -0
- package/dist/history/gitinfo.js +69 -0
- package/dist/history/gitinfo.js.map +1 -0
- package/dist/history/jsonl.d.ts +28 -0
- package/dist/history/jsonl.js +71 -0
- package/dist/history/jsonl.js.map +1 -0
- package/dist/history/queries.d.ts +43 -0
- package/dist/history/queries.js +86 -0
- package/dist/history/queries.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/derive.d.ts +28 -0
- package/dist/keys/derive.js +59 -0
- package/dist/keys/derive.js.map +1 -0
- package/dist/manifest/schema.d.ts +1068 -0
- package/dist/manifest/schema.js +102 -0
- package/dist/manifest/schema.js.map +1 -0
- package/dist/manifest/seal.d.ts +41 -0
- package/dist/manifest/seal.js +185 -0
- package/dist/manifest/seal.js.map +1 -0
- package/dist/manifest/verify.d.ts +102 -0
- package/dist/manifest/verify.js +246 -0
- package/dist/manifest/verify.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +138 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +43 -13
- package/bin.js +0 -19
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify — the stranger command. Integrity-seal triple-check (recompute
|
|
3
|
+
* hash, re-derive pubkey from embedded commit+salt, verify the seal) plus
|
|
4
|
+
* per-claim pass/drift/regressed/missing classification and the 0/1/2
|
|
5
|
+
* exit-code contract (D7, ported from ruflo verify.mjs / issue #1880).
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { join, resolve } from 'node:path';
|
|
10
|
+
import { canonicalize } from '../core/canonical.js';
|
|
11
|
+
import { normalizeClaimPath } from '../core/paths.js';
|
|
12
|
+
import { sha256Hex, fileSha256, fileSha256CrlfNormalized, markerPresent as markerPresentIn, } from '../core/hash.js';
|
|
13
|
+
import { deriveKey, verifyBytes } from '../keys/derive.js';
|
|
14
|
+
import { runHarness } from '../harness/run.js';
|
|
15
|
+
import { loadConfig, DEFAULT_MANIFEST_PATH } from '../config.js';
|
|
16
|
+
export const THREAT_MODEL_NOTE = 'commit-bound tamper-evidence, not third-party authentication';
|
|
17
|
+
/** Detail attached to a regressed file-hash claim caused by git autocrlf. */
|
|
18
|
+
export const CRLF_DETAIL = 'content identical after line-ending normalization — likely git autocrlf; pin with .gitattributes (* text=auto eol=lf)';
|
|
19
|
+
/** Named precondition hint for an uncommitted reference vector (premortem #5). */
|
|
20
|
+
export const REFERENCE_VECTOR_HINT = 'reference vector not found — did you commit the seal outputs? (run `proofseal seal` then commit the listed files)';
|
|
21
|
+
/** Build-output path pattern: a missing file here usually means "not built". */
|
|
22
|
+
const BUILD_OUTPUT_RE = /(^|\/)(dist|build|out)\//;
|
|
23
|
+
/** Map a VerifyResult onto the pinned v1 JSON schema. */
|
|
24
|
+
export function toVerifyJson(r) {
|
|
25
|
+
return {
|
|
26
|
+
ok: r.ok,
|
|
27
|
+
signature: {
|
|
28
|
+
valid: r.signature.manifestHashOk && r.signature.publicKeyReproducible && r.signature.signatureValid,
|
|
29
|
+
publicKey: r.signature.publicKey,
|
|
30
|
+
publicKeyReproducible: r.signature.publicKeyReproducible,
|
|
31
|
+
},
|
|
32
|
+
summary: { totalClaims: r.results.length, ...r.summary },
|
|
33
|
+
results: r.results.map((c) => ({
|
|
34
|
+
id: c.id,
|
|
35
|
+
type: c.type,
|
|
36
|
+
status: c.status,
|
|
37
|
+
file: c.file ?? '',
|
|
38
|
+
detail: c.detail ?? '',
|
|
39
|
+
})),
|
|
40
|
+
precondition: r.precondition ? { reason: r.precondition, hint: r.hint ?? '' } : null,
|
|
41
|
+
...(r.platformWarning ? { platformWarning: r.platformWarning } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Integrity-seal triple-check (ADR §5.4). */
|
|
45
|
+
export function checkSignature(witness) {
|
|
46
|
+
const recomputed = sha256Hex(canonicalize(witness.manifest));
|
|
47
|
+
const manifestHashOk = recomputed === witness.integrity.manifestHash;
|
|
48
|
+
const key = deriveKey(witness.manifest.gitCommit, witness.manifest.salt);
|
|
49
|
+
const publicKeyReproducible = key.publicKeyHex === witness.integrity.publicKey;
|
|
50
|
+
const signatureValid = verifyBytes(witness.integrity.publicKey, Buffer.from(witness.integrity.manifestHash, 'hex'), witness.integrity.signature);
|
|
51
|
+
return { manifestHashOk, publicKeyReproducible, signatureValid, publicKey: witness.integrity.publicKey };
|
|
52
|
+
}
|
|
53
|
+
/** Classify a file-backed (file-hash | marker) claim against the live tree. */
|
|
54
|
+
export function classifyFileClaim(root, claim) {
|
|
55
|
+
if (claim.type === 'harness') {
|
|
56
|
+
throw new Error('classifyFileClaim called with a harness claim');
|
|
57
|
+
}
|
|
58
|
+
// Windows insurance: tolerate manifests sealed with backslash paths.
|
|
59
|
+
const file = normalizeClaimPath(claim.file);
|
|
60
|
+
const base = { id: claim.id, type: claim.type, desc: claim.desc, file };
|
|
61
|
+
const abs = join(root, file);
|
|
62
|
+
if (!existsSync(abs)) {
|
|
63
|
+
return { ...base, status: 'missing', sha256Match: false, markerPresent: false };
|
|
64
|
+
}
|
|
65
|
+
const localSha256 = fileSha256(abs);
|
|
66
|
+
const sha256Match = localSha256 === claim.sha256;
|
|
67
|
+
if (claim.type === 'file-hash') {
|
|
68
|
+
// The hash IS the expectation: mismatch = regressed (no drift slot).
|
|
69
|
+
if (sha256Match)
|
|
70
|
+
return { ...base, status: 'pass', sha256Match, localSha256 };
|
|
71
|
+
// CRLF-aware detail (premortem #7): bytes are the contract, so the
|
|
72
|
+
// classification STAYS regressed — but when the CRLF→LF-normalized
|
|
73
|
+
// content matches the sealed hash, the detail names git autocrlf.
|
|
74
|
+
const crlfDetail = fileSha256CrlfNormalized(abs) === claim.sha256 ? CRLF_DETAIL : undefined;
|
|
75
|
+
return { ...base, status: 'regressed', sha256Match, localSha256, ...(crlfDetail ? { detail: crlfDetail } : {}) };
|
|
76
|
+
}
|
|
77
|
+
// Whitespace-normalized (premortem #7): re-indents/line-wraps of the
|
|
78
|
+
// marker's surroundings are drift, not a false regression.
|
|
79
|
+
const markerPresent = markerPresentIn(readFileSync(abs, 'utf8'), claim.marker);
|
|
80
|
+
const status = sha256Match && markerPresent ? 'pass' : markerPresent ? 'drift' : 'regressed';
|
|
81
|
+
return { ...base, status, sha256Match, markerPresent, localSha256 };
|
|
82
|
+
}
|
|
83
|
+
async function classifyHarnessClaim(root, claim) {
|
|
84
|
+
if (claim.type !== 'harness')
|
|
85
|
+
throw new Error('expected harness claim');
|
|
86
|
+
const base = { id: claim.id, type: claim.type, desc: claim.desc };
|
|
87
|
+
const result = await runHarness({
|
|
88
|
+
name: claim.harness,
|
|
89
|
+
cmd: claim.cmd,
|
|
90
|
+
cwd: root,
|
|
91
|
+
seed: claim.seed,
|
|
92
|
+
quantizeDecimals: claim.quantizeDecimals,
|
|
93
|
+
exclude: claim.exclude,
|
|
94
|
+
expectedSha256: claim.expectedSha256,
|
|
95
|
+
referenceVector: claim.referenceVector ? normalizeClaimPath(claim.referenceVector) : undefined,
|
|
96
|
+
tolerance: claim.tolerance,
|
|
97
|
+
});
|
|
98
|
+
const status = result.status === 'error' || result.status === 'missing' ? 'missing' : result.status;
|
|
99
|
+
return {
|
|
100
|
+
...base,
|
|
101
|
+
status,
|
|
102
|
+
hashMatch: result.hashMatch,
|
|
103
|
+
toleranceMatch: result.toleranceMatch,
|
|
104
|
+
detail: result.commandNotFound
|
|
105
|
+
? `precondition-suspect: harness command not found (${claim.cmd}) — is the environment set up?`
|
|
106
|
+
: result.error,
|
|
107
|
+
...(result.commandNotFound ? { preconditionSuspect: true } : {}),
|
|
108
|
+
...(result.referenceVectorMissing ? { referenceVectorMissing: true } : {}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function summarize(results) {
|
|
112
|
+
return {
|
|
113
|
+
pass: results.filter((r) => r.status === 'pass').length,
|
|
114
|
+
drift: results.filter((r) => r.status === 'drift').length,
|
|
115
|
+
regressed: results.filter((r) => r.status === 'regressed').length,
|
|
116
|
+
missing: results.filter((r) => r.status === 'missing').length,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const EMPTY_SIG = {
|
|
120
|
+
manifestHashOk: false,
|
|
121
|
+
publicKeyReproducible: false,
|
|
122
|
+
signatureValid: false,
|
|
123
|
+
publicKey: '',
|
|
124
|
+
};
|
|
125
|
+
function precondition(reason, hint, summary, signature, results) {
|
|
126
|
+
return {
|
|
127
|
+
ok: false,
|
|
128
|
+
exitCode: 2,
|
|
129
|
+
precondition: reason,
|
|
130
|
+
hint,
|
|
131
|
+
signature: signature ?? EMPTY_SIG,
|
|
132
|
+
summary: summary ?? { pass: 0, drift: 0, regressed: 0, missing: 0 },
|
|
133
|
+
results: results ?? [],
|
|
134
|
+
note: THREAT_MODEL_NOTE,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function resolveManifestPath(opts) {
|
|
138
|
+
const root = resolve(opts.root ?? process.cwd());
|
|
139
|
+
if (opts.manifestPath)
|
|
140
|
+
return { root, manifestPath: resolve(opts.manifestPath) };
|
|
141
|
+
try {
|
|
142
|
+
const cfg = loadConfig(root);
|
|
143
|
+
return { root, manifestPath: cfg.manifestPath };
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return { root, manifestPath: join(root, DEFAULT_MANIFEST_PATH) };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Verify a sealed manifest against the live tree. Never throws on bad repos. */
|
|
150
|
+
export async function verify(opts = {}) {
|
|
151
|
+
const { root, manifestPath } = resolveManifestPath(opts);
|
|
152
|
+
if (!existsSync(manifestPath)) {
|
|
153
|
+
return precondition('manifest-not-found', `no sealed manifest at ${manifestPath} — run \`proofseal seal\` first`);
|
|
154
|
+
}
|
|
155
|
+
let witness;
|
|
156
|
+
try {
|
|
157
|
+
witness = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
158
|
+
if (!witness?.manifest || !witness?.integrity)
|
|
159
|
+
throw new Error('not a proofseal witness document');
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
return precondition('manifest-unparseable', `could not parse ${manifestPath}: ${e.message}`);
|
|
163
|
+
}
|
|
164
|
+
const signature = checkSignature(witness);
|
|
165
|
+
// Platform honesty (premortem #3): warn — never fail — when the verifying
|
|
166
|
+
// OS differs from the (sealed) sealing OS. Manifests sealed before the
|
|
167
|
+
// platform field existed are tolerated silently.
|
|
168
|
+
const currentPlatform = opts.currentPlatform ?? process.platform;
|
|
169
|
+
const sealedOs = witness.manifest.platform?.os;
|
|
170
|
+
const platformWarning = sealedOs && sealedOs !== currentPlatform
|
|
171
|
+
? `sealed on ${sealedOs}, verifying on ${currentPlatform} — file-hash mismatches on built/binary artifacts may be platform drift, not tampering`
|
|
172
|
+
: undefined;
|
|
173
|
+
const results = [];
|
|
174
|
+
for (const claim of witness.manifest.claims) {
|
|
175
|
+
if (claim.type === 'harness') {
|
|
176
|
+
if (opts.runHarnesses === false)
|
|
177
|
+
continue;
|
|
178
|
+
results.push(await classifyHarnessClaim(root, claim));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
results.push(classifyFileClaim(root, claim));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Per-claim precondition awareness (premortem #5): a MISSING file claim
|
|
185
|
+
// whose path is a build output (dist/, build/, out/) looks like "you did
|
|
186
|
+
// not build" — but ONLY when the build-output directory itself is absent.
|
|
187
|
+
// If dist/ exists and one sealed file inside it is gone, that is a real
|
|
188
|
+
// MISSING (deleted artifact), not an unbuilt checkout (bench finding
|
|
189
|
+
// 2026-06-12: the directory-blind heuristic misclassified 3/45 deletions).
|
|
190
|
+
for (const r of results) {
|
|
191
|
+
if (r.status === 'missing' && r.file && !r.preconditionSuspect) {
|
|
192
|
+
const m = r.file.match(BUILD_OUTPUT_RE);
|
|
193
|
+
if (m) {
|
|
194
|
+
const buildDir = r.file.slice(0, r.file.indexOf(m[2]) + m[2].length);
|
|
195
|
+
if (!existsSync(join(root, buildDir))) {
|
|
196
|
+
r.preconditionSuspect = true;
|
|
197
|
+
r.detail = r.detail ?? `precondition-suspect: build output ${r.file} is absent — was the project built?`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const summary = summarize(results);
|
|
203
|
+
// Named precondition (premortem #5): a harness hash mismatch cannot be
|
|
204
|
+
// classified as drift-vs-regressed without its committed reference vector.
|
|
205
|
+
// The overwhelmingly likely cause is seal outputs that were never
|
|
206
|
+
// committed — surface that by name instead of crying "regressed".
|
|
207
|
+
if (results.some((r) => r.referenceVectorMissing)) {
|
|
208
|
+
return {
|
|
209
|
+
...precondition('reference-vector-not-found', REFERENCE_VECTOR_HINT, summary, signature, results),
|
|
210
|
+
...(platformWarning ? { platformWarning } : {}),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Exit-2 heuristics (issue #1880, relaxed per premortem round 2):
|
|
214
|
+
// (a) EVERY failing claim is precondition-suspect (missing build output
|
|
215
|
+
// and/or harness command not found) ⇒ environment, not regression;
|
|
216
|
+
// (b) legacy net: every claim missing AND the manifest references a
|
|
217
|
+
// build-output path ⇒ source-only checkout.
|
|
218
|
+
const failing = results.filter((r) => r.status === 'regressed' || r.status === 'missing');
|
|
219
|
+
const allFailingSuspect = failing.length > 0 && failing.every((r) => r.preconditionSuspect);
|
|
220
|
+
const fileClaims = witness.manifest.claims.filter((c) => c.type !== 'harness');
|
|
221
|
+
const allMissing = results.length > 0 && summary.missing === results.length;
|
|
222
|
+
const referencesBuildOutput = fileClaims.some((c) => BUILD_OUTPUT_RE.test(normalizeClaimPath(c.file)));
|
|
223
|
+
if (allFailingSuspect || (allMissing && referencesBuildOutput)) {
|
|
224
|
+
const onlyCommandsMissing = allFailingSuspect && failing.every((r) => r.detail?.includes('harness command not found'));
|
|
225
|
+
const reason = onlyCommandsMissing ? 'harness-command-not-found' : 'dist-not-built';
|
|
226
|
+
const hint = onlyCommandsMissing
|
|
227
|
+
? 'install the harness command(s) listed in the claim details, then re-run verify'
|
|
228
|
+
: 'run npm ci && npm run build';
|
|
229
|
+
return {
|
|
230
|
+
...precondition(reason, hint, summary, signature, results),
|
|
231
|
+
...(platformWarning ? { platformWarning } : {}),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const sigOk = signature.manifestHashOk && signature.publicKeyReproducible && signature.signatureValid;
|
|
235
|
+
const ok = sigOk && summary.regressed === 0 && summary.missing === 0;
|
|
236
|
+
return {
|
|
237
|
+
ok,
|
|
238
|
+
exitCode: ok ? 0 : 1,
|
|
239
|
+
signature,
|
|
240
|
+
summary,
|
|
241
|
+
results,
|
|
242
|
+
note: THREAT_MODEL_NOTE,
|
|
243
|
+
...(platformWarning ? { platformWarning } : {}),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/manifest/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startMcpServer(): Promise<void>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProofSeal MCP stdio server (ADR-0001 §4.2) — thin wrappers over the
|
|
3
|
+
* library API. Every tool is fail-open: a broken repo returns
|
|
4
|
+
* {ok:false, warn:true, error, hint} instead of killing the agent session.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { seal } from '../manifest/seal.js';
|
|
10
|
+
import { verify, toVerifyJson, classifyFileClaim } from '../manifest/verify.js';
|
|
11
|
+
import { loadHistory } from '../history/jsonl.js';
|
|
12
|
+
import { fixTimeline, findRegressionIntroductions } from '../history/queries.js';
|
|
13
|
+
import { enrichRegressionsWithGit } from '../history/gitinfo.js';
|
|
14
|
+
import { runHarness } from '../harness/run.js';
|
|
15
|
+
import { loadConfig } from '../config.js';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
/** Contract §6: structuredContent is primary; JSON mirrored into content[0].text. */
|
|
18
|
+
function asText(data) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
21
|
+
structuredContent: data,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Fail-open wrapper (RuView rvagent convention). */
|
|
25
|
+
async function failOpen(hint, fn) {
|
|
26
|
+
try {
|
|
27
|
+
return asText(await fn());
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
return asText({ ok: false, warn: true, error: e.message, hint });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Client-disconnect hygiene: when the MCP client goes away mid-write, the
|
|
35
|
+
* stdio transport surfaces `write EPIPE` (and stdin sees EOF). A vanished
|
|
36
|
+
* client is a normal shutdown, not an error — exit 0 quietly. Anything that
|
|
37
|
+
* is NOT an EPIPE still crashes loudly (stack to stderr, exit 1) so real
|
|
38
|
+
* bugs are never swallowed.
|
|
39
|
+
*/
|
|
40
|
+
function installStdioShutdownHandlers() {
|
|
41
|
+
const isEpipe = (err) => err?.code === 'EPIPE';
|
|
42
|
+
process.stdout.on('error', (err) => {
|
|
43
|
+
if (isEpipe(err))
|
|
44
|
+
process.exit(0);
|
|
45
|
+
throw err; // escalates to the uncaughtException guard below
|
|
46
|
+
});
|
|
47
|
+
process.stdin.on('error', (err) => {
|
|
48
|
+
if (isEpipe(err) || err.code === 'EOF')
|
|
49
|
+
process.exit(0);
|
|
50
|
+
throw err;
|
|
51
|
+
});
|
|
52
|
+
// stdin EOF = client closed the session: drain queued stdout, then exit 0.
|
|
53
|
+
process.stdin.on('end', () => {
|
|
54
|
+
process.stdout.write('', () => process.exit(0));
|
|
55
|
+
});
|
|
56
|
+
// Narrow guard: ONLY EPIPE exits quietly. Every other uncaught error keeps
|
|
57
|
+
// the default fatal semantics (stack trace on stderr, nonzero exit).
|
|
58
|
+
process.on('uncaughtException', (err) => {
|
|
59
|
+
if (isEpipe(err))
|
|
60
|
+
process.exit(0);
|
|
61
|
+
console.error(err);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export async function startMcpServer() {
|
|
66
|
+
installStdioShutdownHandlers();
|
|
67
|
+
const server = new McpServer({ name: 'proofseal', version: '0.1.0' });
|
|
68
|
+
server.tool('verify_claims', 'Verify the sealed ProofSeal manifest against the live tree: integrity-seal triple-check plus per-claim pass/drift/regressed/missing classification. Use when raw Bash (sha256sum, grep) is wrong because it cannot detect manifest tampering or distinguish benign drift from a real regression.', { root: z.string().optional(), manifest: z.string().optional() }, async ({ root, manifest }) => failOpen('run `proofseal init` then `proofseal seal` in the repo', async () => {
|
|
69
|
+
const r = await verify({ root, manifestPath: manifest });
|
|
70
|
+
// verify() never throws on broken repos — surface preconditions in the
|
|
71
|
+
// fail-open shape so agent sessions get {ok:false, warn:true, error, hint}.
|
|
72
|
+
if (r.precondition) {
|
|
73
|
+
return { ok: false, warn: true, error: r.precondition, hint: r.hint ?? '', detail: toVerifyJson(r) };
|
|
74
|
+
}
|
|
75
|
+
return toVerifyJson(r);
|
|
76
|
+
}));
|
|
77
|
+
server.tool('seal_manifest', 'Refresh all claims against the tree, derive the commit-bound key, seal the manifest, and append a history snapshot. Use when manually editing proofs/manifest.json is wrong because hand-edited manifests always break the seal — resealing is the only legal mutation.', { root: z.string().optional() }, async ({ root }) => failOpen('ensure the repo has proofseal.json (run `proofseal init`) and is a git checkout', async () => {
|
|
78
|
+
const r = await seal({ root });
|
|
79
|
+
return { ok: r.ok, summary: r.summary, manifestPath: r.manifestPath, manifestHash: r.witness.integrity.manifestHash, warnings: r.warnings, filesWritten: r.filesWritten };
|
|
80
|
+
}));
|
|
81
|
+
server.tool('check_drift', 'Diff the live tree against the latest sealed manifest WITHOUT resealing: reports per-claim pass/drift/regressed/missing only. Use when seal_manifest is wrong because you only want to inspect drift, not mint a new sealed snapshot.', { root: z.string().optional(), manifest: z.string().optional() }, async ({ root, manifest }) => failOpen('seal a manifest first with `proofseal seal`', () => {
|
|
82
|
+
const cfg = loadConfig(root ?? process.cwd());
|
|
83
|
+
const path = manifest ?? cfg.manifestPath;
|
|
84
|
+
const witness = JSON.parse(readFileSync(path, 'utf8'));
|
|
85
|
+
const results = witness.manifest.claims
|
|
86
|
+
.filter((c) => c.type !== 'harness')
|
|
87
|
+
.map((c) => classifyFileClaim(cfg.root, c));
|
|
88
|
+
return {
|
|
89
|
+
ok: true,
|
|
90
|
+
summary: {
|
|
91
|
+
pass: results.filter((r) => r.status === 'pass').length,
|
|
92
|
+
drift: results.filter((r) => r.status === 'drift').length,
|
|
93
|
+
regressed: results.filter((r) => r.status === 'regressed').length,
|
|
94
|
+
missing: results.filter((r) => r.status === 'missing').length,
|
|
95
|
+
},
|
|
96
|
+
results,
|
|
97
|
+
};
|
|
98
|
+
}));
|
|
99
|
+
server.tool('claim_history', 'Status timeline (pass/regressed/absent) for one claim across every sealed snapshot. Use when `git log` is wrong because it shows commits, not whether a specific verified claim held at each seal point.', { id: z.string(), root: z.string().optional() }, async ({ id, root }) => failOpen('no history yet — run `proofseal seal` at least once', () => {
|
|
100
|
+
const cfg = loadConfig(root ?? process.cwd());
|
|
101
|
+
return { ok: true, id, timeline: fixTimeline(loadHistory(cfg.historyPath), id) };
|
|
102
|
+
}));
|
|
103
|
+
server.tool('find_regression', 'Bisect the JSONL history: for every currently-regressed claim, locate the last-pass snapshot and the snapshot where the regression appeared. Use when `git bisect` is wrong because it needs a runnable predicate per commit; this answers from already-recorded seal snapshots instantly.', { root: z.string().optional() }, async ({ root }) => failOpen('no history yet — run `proofseal seal` at least once', () => {
|
|
104
|
+
const cfg = loadConfig(root ?? process.cwd());
|
|
105
|
+
// Same query code as `proofseal history --bisect`: entries are ordered
|
|
106
|
+
// by issuedAt, and each regression carries reachability/range-width
|
|
107
|
+
// info when git can resolve the recorded SHAs (best-effort).
|
|
108
|
+
return {
|
|
109
|
+
ok: true,
|
|
110
|
+
regressions: enrichRegressionsWithGit(cfg.root, findRegressionIntroductions(loadHistory(cfg.historyPath))),
|
|
111
|
+
};
|
|
112
|
+
}));
|
|
113
|
+
server.tool('run_harness', 'Run a deterministic harness (seeded via PROOFSEAL_SEED), quantize numeric output (round-half-even), hash it, and compare against the committed expectation with an rtol/atol tolerance fallback. Use when plain Bash execution is wrong because raw float output hashes diverge across CPU microarchitectures.', { name: z.string(), root: z.string().optional() }, async ({ name, root }) => failOpen('declare the harness claim in proofseal.json and run `proofseal harness run --update` first', async () => {
|
|
114
|
+
const cfg = loadConfig(root ?? process.cwd());
|
|
115
|
+
const def = cfg.config.claims.find((c) => c.type === 'harness' && (c.harness === name || c.id === name));
|
|
116
|
+
if (!def)
|
|
117
|
+
throw new Error(`no harness claim named '${name}'`);
|
|
118
|
+
const result = await runHarness({
|
|
119
|
+
name,
|
|
120
|
+
cmd: def.cmd,
|
|
121
|
+
cwd: cfg.root,
|
|
122
|
+
seed: def.seed,
|
|
123
|
+
quantizeDecimals: def.quantizeDecimals,
|
|
124
|
+
exclude: def.exclude,
|
|
125
|
+
expectedSha256: def.expectedSha256,
|
|
126
|
+
referenceVector: def.referenceVector,
|
|
127
|
+
tolerance: def.tolerance,
|
|
128
|
+
});
|
|
129
|
+
const { values: _v, quantized: _q, ...compact } = result;
|
|
130
|
+
return { ok: result.status === 'pass' || result.status === 'drift', result: compact };
|
|
131
|
+
}));
|
|
132
|
+
server.tool('list_claims', 'List the claims declared in proofseal.json (id, type, target). Use when reading proofseal.json with a file tool is wrong because this validates the schema and resolves defaults.', { root: z.string().optional() }, async ({ root }) => failOpen('run `proofseal init` to create proofseal.json', () => {
|
|
133
|
+
const cfg = loadConfig(root ?? process.cwd());
|
|
134
|
+
return { ok: true, claims: cfg.config.claims };
|
|
135
|
+
}));
|
|
136
|
+
await server.connect(new StdioServerTransport());
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proofseal",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Witness-chained, tamper-evident claim verification for any git repo — commit-bound integrity seals, zero key management.",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"author": "rudycelekli",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "git+https://github.com/rudycelekli/proofseal.git"
|
|
10
11
|
},
|
|
11
|
-
"homepage": "https://github.com/rudycelekli/proofseal#readme",
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/rudycelekli/proofseal/issues"
|
|
14
14
|
},
|
|
15
|
+
"homepage": "https://github.com/rudycelekli/proofseal#readme",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=20"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"proofseal": "dist/cli/index.js"
|
|
21
|
+
},
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"types": "dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"NOTICE",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc",
|
|
37
|
+
"pretest": "npm run build",
|
|
38
|
+
"test": "node --test \"tests/unit/**/*.test.mjs\"",
|
|
39
|
+
"test:integration": "node --test \"tests/integration/**/*.test.{mjs,js}\"",
|
|
40
|
+
"smoke:tarball": "node scripts/tarball-smoke.mjs"
|
|
41
|
+
},
|
|
15
42
|
"keywords": [
|
|
16
|
-
"readme",
|
|
17
43
|
"verification",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
44
|
+
"tamper-evidence",
|
|
45
|
+
"integrity-seal",
|
|
46
|
+
"witness",
|
|
47
|
+
"claims",
|
|
48
|
+
"provenance"
|
|
21
49
|
],
|
|
22
|
-
"
|
|
23
|
-
"
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
52
|
+
"commander": "^12.1.0",
|
|
53
|
+
"zod": "^3.23.8"
|
|
24
54
|
},
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^20.14.0",
|
|
57
|
+
"typescript": "^5.5.0"
|
|
58
|
+
}
|
|
29
59
|
}
|
package/bin.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
const lines = [
|
|
5
|
-
"",
|
|
6
|
-
" ProofSeal",
|
|
7
|
-
" ---------",
|
|
8
|
-
" Seals the claims in your README (file hashes, markers, test harnesses)",
|
|
9
|
-
" and verifies them in CI: pass / drift / regressed / missing.",
|
|
10
|
-
"",
|
|
11
|
-
" Status: v0.1.0 is in private beta. This package is a placeholder.",
|
|
12
|
-
"",
|
|
13
|
-
" Watch or star https://github.com/rudycelekli/proofseal and subscribe",
|
|
14
|
-
" to the \"Notify me\" issue there to hear about the release.",
|
|
15
|
-
"",
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
process.stdout.write(lines.join("\n") + "\n");
|
|
19
|
-
process.exit(0);
|