dsh-research-report 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/CHANGELOG.md +18 -0
- package/LICENSE +201 -0
- package/README.es.md +155 -0
- package/README.hi.md +155 -0
- package/README.md +155 -0
- package/README.pt.md +155 -0
- package/README.zh.md +155 -0
- package/THIRD_PARTY_NOTICES.md +21 -0
- package/cordis.patch.yml +24 -0
- package/lib/index.js +2143 -0
- package/lib/types/assemble.d.ts +123 -0
- package/lib/types/assemble.d.ts.map +1 -0
- package/lib/types/assemble.js +239 -0
- package/lib/types/assemble.js.map +1 -0
- package/lib/types/config.d.ts +48 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +60 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/gather.d.ts +119 -0
- package/lib/types/gather.d.ts.map +1 -0
- package/lib/types/gather.js +165 -0
- package/lib/types/gather.js.map +1 -0
- package/lib/types/index.d.ts +51 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +71 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/ledger.d.ts +159 -0
- package/lib/types/ledger.d.ts.map +1 -0
- package/lib/types/ledger.js +276 -0
- package/lib/types/ledger.js.map +1 -0
- package/lib/types/provider-local.d.ts +137 -0
- package/lib/types/provider-local.d.ts.map +1 -0
- package/lib/types/provider-local.js +418 -0
- package/lib/types/provider-local.js.map +1 -0
- package/lib/types/service.d.ts +302 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/service.js +31 -0
- package/lib/types/service.js.map +1 -0
- package/lib/types/tools/evidence-add.d.ts +36 -0
- package/lib/types/tools/evidence-add.d.ts.map +1 -0
- package/lib/types/tools/evidence-add.js +107 -0
- package/lib/types/tools/evidence-add.js.map +1 -0
- package/lib/types/tools/ledger-query.d.ts +42 -0
- package/lib/types/tools/ledger-query.d.ts.map +1 -0
- package/lib/types/tools/ledger-query.js +154 -0
- package/lib/types/tools/ledger-query.js.map +1 -0
- package/lib/types/tools/research-report.d.ts +67 -0
- package/lib/types/tools/research-report.d.ts.map +1 -0
- package/lib/types/tools/research-report.js +345 -0
- package/lib/types/tools/research-report.js.map +1 -0
- package/lib/types/verify.d.ts +128 -0
- package/lib/types/verify.d.ts.map +1 -0
- package/lib/types/verify.js +208 -0
- package/lib/types/verify.js.map +1 -0
- package/lib/types/version.d.ts +7 -0
- package/lib/types/version.d.ts.map +1 -0
- package/lib/types/version.js +7 -0
- package/lib/types/version.js.map +1 -0
- package/package.json +147 -0
- package/src/assemble.ts +302 -0
- package/src/config.ts +97 -0
- package/src/gather.ts +239 -0
- package/src/index.ts +139 -0
- package/src/ledger.ts +344 -0
- package/src/provider-local.ts +489 -0
- package/src/service.ts +322 -0
- package/src/tools/evidence-add.ts +132 -0
- package/src/tools/ledger-query.ts +191 -0
- package/src/tools/research-report.ts +424 -0
- package/src/verify.ts +285 -0
- package/src/version.ts +7 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The evidence ledger: a content-addressed snapshot store with JSONL journals.
|
|
3
|
+
*
|
|
4
|
+
* Layout under the configured `ledgerRoot`:
|
|
5
|
+
* - `objects/<sha256>` — one immutable snapshot per content hash (same content
|
|
6
|
+
* is stored exactly once; an "update" is a new object, history is never
|
|
7
|
+
* rewritten).
|
|
8
|
+
* - `index.jsonl` — evidence registrations: id → hash, origin, capturedAt,
|
|
9
|
+
* title, bytes. Append-only.
|
|
10
|
+
* - `claims.jsonl` — claim registrations: id → text, evidenceIds, optional
|
|
11
|
+
* dataset bridge fields. Append-only.
|
|
12
|
+
* - `verdicts.jsonl` — verification verdicts; the latest line per claim wins.
|
|
13
|
+
*
|
|
14
|
+
* Tamper detection is the point of the design: every content read recomputes
|
|
15
|
+
* the SHA-256 of the object file and compares it against the indexed hash —
|
|
16
|
+
* a mismatch surfaces as `tampered`, a deleted object as `missing`.
|
|
17
|
+
*
|
|
18
|
+
* This module is pure Node (zero DSH imports) so it stays testable in
|
|
19
|
+
* isolation; policy (size caps, fetch) lives in the provider.
|
|
20
|
+
*
|
|
21
|
+
* @module dsh-research-report/ledger
|
|
22
|
+
*/
|
|
23
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
24
|
+
import { appendFile, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
25
|
+
import path from 'node:path';
|
|
26
|
+
/** SHA-256 hex of one UTF-8 string. */
|
|
27
|
+
export function sha256Of(content) {
|
|
28
|
+
return createHash('sha256').update(content, 'utf8').digest('hex');
|
|
29
|
+
}
|
|
30
|
+
/** A loud ledger failure (audit state must never degrade silently). */
|
|
31
|
+
export class LedgerError extends Error {
|
|
32
|
+
/** The machine-routable failure code. */
|
|
33
|
+
code;
|
|
34
|
+
constructor(code, message) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'LedgerError';
|
|
37
|
+
this.code = code;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Read one JSONL journal; a corrupt line fails loud with file and line number. */
|
|
41
|
+
async function readJournal(file) {
|
|
42
|
+
let text;
|
|
43
|
+
try {
|
|
44
|
+
text = await readFile(file, 'utf8');
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// A not-yet-created journal is an empty journal; anything else is loud.
|
|
48
|
+
if (error.code === 'ENOENT')
|
|
49
|
+
return [];
|
|
50
|
+
throw new LedgerError('IO', `cannot read journal ${file}: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
const lines = [];
|
|
53
|
+
const rows = text.split('\n');
|
|
54
|
+
for (let index = 0; index < rows.length; index++) {
|
|
55
|
+
const row = rows[index];
|
|
56
|
+
if (row.trim() === '')
|
|
57
|
+
continue;
|
|
58
|
+
try {
|
|
59
|
+
lines.push(JSON.parse(row));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw new LedgerError('JOURNAL_CORRUPT', `corrupt JSONL at ${file}:${index + 1}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return lines;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The content-addressed evidence ledger. Writes are serialized through an
|
|
69
|
+
* internal promise queue so concurrent tool calls cannot interleave journals.
|
|
70
|
+
*/
|
|
71
|
+
export class EvidenceLedger {
|
|
72
|
+
/** Absolute ledger root directory. */
|
|
73
|
+
root;
|
|
74
|
+
/** Write serialization chain (never rejects — each link absorbs the previous error). */
|
|
75
|
+
queue = Promise.resolve();
|
|
76
|
+
/**
|
|
77
|
+
* @param root - absolute ledger root directory.
|
|
78
|
+
*/
|
|
79
|
+
constructor(root) {
|
|
80
|
+
this.root = root;
|
|
81
|
+
}
|
|
82
|
+
get objectsDir() {
|
|
83
|
+
return path.join(this.root, 'objects');
|
|
84
|
+
}
|
|
85
|
+
get indexFile() {
|
|
86
|
+
return path.join(this.root, 'index.jsonl');
|
|
87
|
+
}
|
|
88
|
+
get claimsFile() {
|
|
89
|
+
return path.join(this.root, 'claims.jsonl');
|
|
90
|
+
}
|
|
91
|
+
get verdictsFile() {
|
|
92
|
+
return path.join(this.root, 'verdicts.jsonl');
|
|
93
|
+
}
|
|
94
|
+
/** Run `work` after all previously queued writes settle. */
|
|
95
|
+
enqueue(work) {
|
|
96
|
+
const run = this.queue.then(work);
|
|
97
|
+
this.queue = run.then(() => undefined, () => undefined);
|
|
98
|
+
return run;
|
|
99
|
+
}
|
|
100
|
+
/** Ensure the directory layout exists. */
|
|
101
|
+
async ensureLayout() {
|
|
102
|
+
await mkdir(this.objectsDir, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
/** Write one snapshot object atomically (tmp + rename); no-op when present. */
|
|
105
|
+
async writeObject(hash, content) {
|
|
106
|
+
const target = path.join(this.objectsDir, hash);
|
|
107
|
+
try {
|
|
108
|
+
await readFile(target);
|
|
109
|
+
return; // object exists — content-addressed storage is immutable
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (error.code !== 'ENOENT') {
|
|
113
|
+
throw new LedgerError('IO', `cannot stat object ${hash}: ${error.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const temporary = path.join(this.objectsDir, `.${hash}.tmp-${process.pid}-${randomBytes(4).toString('hex')}`);
|
|
117
|
+
await writeFile(temporary, content, 'utf8');
|
|
118
|
+
try {
|
|
119
|
+
await rename(temporary, target);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
// A concurrent writer may have won the rename; the object is identical
|
|
123
|
+
// either way (same hash ⇒ same content), so only non-exists errors matter.
|
|
124
|
+
try {
|
|
125
|
+
await readFile(target);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
throw new LedgerError('IO', `cannot commit object ${hash}: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Register one evidence snapshot. Same content dedupes to the stored object;
|
|
134
|
+
* a caller-chosen id that already exists with DIFFERENT content is refused
|
|
135
|
+
* loudly (history is never rewritten).
|
|
136
|
+
* @param input - id (optional), title, origin, content, capturedAt.
|
|
137
|
+
* @returns the record plus whether this call created it.
|
|
138
|
+
*/
|
|
139
|
+
async putEvidence(input) {
|
|
140
|
+
return this.enqueue(async () => {
|
|
141
|
+
await this.ensureLayout();
|
|
142
|
+
const hash = sha256Of(input.content);
|
|
143
|
+
const id = input.id ?? `ev-${hash.slice(0, 12)}`;
|
|
144
|
+
const index = await readJournal(this.indexFile);
|
|
145
|
+
const existing = index.find(line => line.id === id);
|
|
146
|
+
if (existing !== undefined) {
|
|
147
|
+
if (existing.hash !== hash) {
|
|
148
|
+
throw new LedgerError('ID_CONFLICT', `evidence id "${id}" is already registered with different content (indexed ${existing.hash}, new ${hash}); choose a new id — snapshots are immutable`);
|
|
149
|
+
}
|
|
150
|
+
return { record: existing, created: false };
|
|
151
|
+
}
|
|
152
|
+
await this.writeObject(hash, input.content);
|
|
153
|
+
const record = {
|
|
154
|
+
id,
|
|
155
|
+
hash,
|
|
156
|
+
title: input.title,
|
|
157
|
+
origin: input.origin,
|
|
158
|
+
capturedAt: input.capturedAt,
|
|
159
|
+
bytes: Buffer.byteLength(input.content, 'utf8'),
|
|
160
|
+
};
|
|
161
|
+
await appendFile(this.indexFile, `${JSON.stringify(record)}\n`, 'utf8');
|
|
162
|
+
return { record, created: true };
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Register claims (id → text, evidenceIds). Re-registering a claim id with
|
|
167
|
+
* a different text or different bindings is refused loudly.
|
|
168
|
+
* @param claims - the registrations to append.
|
|
169
|
+
* @param registeredAt - ISO-8601 registration time.
|
|
170
|
+
* @returns the durable claim lines (existing lines for idempotent repeats).
|
|
171
|
+
*/
|
|
172
|
+
async registerClaims(claims, registeredAt) {
|
|
173
|
+
return this.enqueue(async () => {
|
|
174
|
+
await this.ensureLayout();
|
|
175
|
+
const journal = await readJournal(this.claimsFile);
|
|
176
|
+
const out = [];
|
|
177
|
+
for (const claim of claims) {
|
|
178
|
+
const existing = journal.find(line => line.id === claim.id);
|
|
179
|
+
if (existing !== undefined) {
|
|
180
|
+
const same = existing.text === claim.text
|
|
181
|
+
&& JSON.stringify(existing.evidenceIds) === JSON.stringify(claim.evidenceIds)
|
|
182
|
+
&& existing.dataset === claim.dataset;
|
|
183
|
+
if (!same) {
|
|
184
|
+
throw new LedgerError('ID_CONFLICT', `claim id "${claim.id}" is already registered with different text or bindings; choose a new claim id — registrations are immutable`);
|
|
185
|
+
}
|
|
186
|
+
out.push(existing);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const line = { ...claim, registeredAt };
|
|
190
|
+
await appendFile(this.claimsFile, `${JSON.stringify(line)}\n`, 'utf8');
|
|
191
|
+
journal.push(line);
|
|
192
|
+
out.push(line);
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Append one verdict (latest per claim wins on read).
|
|
199
|
+
* @param verdict - claimId, status, optional note.
|
|
200
|
+
* @param at - ISO-8601 write time.
|
|
201
|
+
*/
|
|
202
|
+
async recordVerdict(verdict, at) {
|
|
203
|
+
await this.enqueue(async () => {
|
|
204
|
+
await this.ensureLayout();
|
|
205
|
+
const line = { ...verdict, at };
|
|
206
|
+
await appendFile(this.verdictsFile, `${JSON.stringify(line)}\n`, 'utf8');
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Read the evidence index.
|
|
211
|
+
* @returns every registration in append order.
|
|
212
|
+
*/
|
|
213
|
+
async listEvidence() {
|
|
214
|
+
return readJournal(this.indexFile);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Read one evidence registration.
|
|
218
|
+
* @param id - the ledger id.
|
|
219
|
+
* @returns the record, or undefined when unknown.
|
|
220
|
+
*/
|
|
221
|
+
async getEvidence(id) {
|
|
222
|
+
const index = await this.listEvidence();
|
|
223
|
+
return index.find(line => line.id === id);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Read every claim registration.
|
|
227
|
+
* @returns every claim in append order.
|
|
228
|
+
*/
|
|
229
|
+
async listClaims() {
|
|
230
|
+
return readJournal(this.claimsFile);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Read one claim registration.
|
|
234
|
+
* @param id - the claim id.
|
|
235
|
+
* @returns the claim line, or undefined when unknown.
|
|
236
|
+
*/
|
|
237
|
+
async getClaim(id) {
|
|
238
|
+
const claims = await this.listClaims();
|
|
239
|
+
return claims.find(line => line.id === id);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Fold the verdict journal to the latest verdict per claim.
|
|
243
|
+
* @returns claimId → latest stored verdict.
|
|
244
|
+
*/
|
|
245
|
+
async latestVerdicts() {
|
|
246
|
+
const journal = await readJournal(this.verdictsFile);
|
|
247
|
+
const latest = new Map();
|
|
248
|
+
for (const line of journal)
|
|
249
|
+
latest.set(line.claimId, line);
|
|
250
|
+
return latest;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Read one snapshot and recompute its hash — the tamper-detection path.
|
|
254
|
+
* @param id - the ledger id.
|
|
255
|
+
* @returns content plus integrity (`ok` | `tampered` | `missing`), or
|
|
256
|
+
* undefined when the id is unknown.
|
|
257
|
+
*/
|
|
258
|
+
async readContent(id) {
|
|
259
|
+
const record = await this.getEvidence(id);
|
|
260
|
+
if (record === undefined)
|
|
261
|
+
return undefined;
|
|
262
|
+
let content;
|
|
263
|
+
try {
|
|
264
|
+
content = await readFile(path.join(this.objectsDir, record.hash), 'utf8');
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
// A deleted object degrades to the `missing` integrity state, never an
|
|
268
|
+
// unhandled failure; anything else is loud.
|
|
269
|
+
if (error.code === 'ENOENT')
|
|
270
|
+
return { content: '', integrity: 'missing' };
|
|
271
|
+
throw new LedgerError('IO', `cannot read object ${record.hash}: ${error.message}`);
|
|
272
|
+
}
|
|
273
|
+
return { content, integrity: sha256Of(content) === record.hash ? 'ok' : 'tampered' };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local Provider of the research-report seam: assembles the filesystem
|
|
3
|
+
* evidence ledger, the byte-level verifier, the optional numeric bridge, and
|
|
4
|
+
* the sealing renderer into the `ctx.researchReport` service implementation.
|
|
5
|
+
* @module dsh-research-report/provider-local
|
|
6
|
+
*/
|
|
7
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
8
|
+
import type { Session } from '@deepseek-ai/dsh-session';
|
|
9
|
+
import type { ResolvedConfig } from './config.js';
|
|
10
|
+
import type { GatherOutcome } from './gather.js';
|
|
11
|
+
import { ResearchReportService } from './service.js';
|
|
12
|
+
import type { AddEvidenceInput, AssembleContext, AssembleReportRequest, AssembleReportResult, ClaimVerdict, ClaimView, EvidenceIntegrity, EvidenceRecord, EvidenceView, LedgerSummary } from './service.js';
|
|
13
|
+
/** A loud provider failure with a machine-routable code. */
|
|
14
|
+
export declare class ResearchReportError extends Error {
|
|
15
|
+
/** The machine-routable failure code. */
|
|
16
|
+
readonly code: 'EVIDENCE_TOO_LARGE' | 'CLAIM_UNKNOWN' | 'LEDGER';
|
|
17
|
+
constructor(code: ResearchReportError['code'], message: string);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The local `ctx.researchReport` implementation. Everything durable lives in
|
|
21
|
+
* the filesystem ledger; the service adds policy (caps), verification, and
|
|
22
|
+
* sealing on top.
|
|
23
|
+
*/
|
|
24
|
+
export declare class LocalResearchReportService extends ResearchReportService {
|
|
25
|
+
/** The content-addressed ledger. */
|
|
26
|
+
private readonly ledger;
|
|
27
|
+
/** The resolved plugin config. */
|
|
28
|
+
private readonly config;
|
|
29
|
+
/** Absolute workspace root for local capture and path display. */
|
|
30
|
+
private readonly workspaceRoot;
|
|
31
|
+
/**
|
|
32
|
+
* @param ctx - the plugin context.
|
|
33
|
+
* @param config - the resolved plugin config.
|
|
34
|
+
* @param workspaceRoot - absolute workspace root (the harness cwd).
|
|
35
|
+
*/
|
|
36
|
+
constructor(ctx: Context, config: ResolvedConfig, workspaceRoot: string);
|
|
37
|
+
/** The web seam, resolved at call time (HMR-safe; may be absent). */
|
|
38
|
+
private get web();
|
|
39
|
+
/** The optional numeric bridge, resolved at call time (never injected). */
|
|
40
|
+
private get dataQuality();
|
|
41
|
+
/** Capture dependencies for the gather/capture paths. */
|
|
42
|
+
private get captureDeps();
|
|
43
|
+
/**
|
|
44
|
+
* Register one evidence snapshot. Over-size content is refused loudly;
|
|
45
|
+
* same-content registrations dedupe.
|
|
46
|
+
* @param input - the snapshot and its provenance.
|
|
47
|
+
* @param session - the owning session (audit event), when known.
|
|
48
|
+
* @returns the durable record and whether this call created it.
|
|
49
|
+
*/
|
|
50
|
+
addEvidence(input: AddEvidenceInput, session?: Session): Promise<{
|
|
51
|
+
record: EvidenceRecord;
|
|
52
|
+
deduplicated: boolean;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Capture one origin (URL via ctx.web, workspace path via fs) and register
|
|
56
|
+
* it. Provider-internal helper for the tools layer.
|
|
57
|
+
* @param origin - URL or workspace path.
|
|
58
|
+
* @param title - display title (defaults to the origin).
|
|
59
|
+
* @param signal - caller cancellation.
|
|
60
|
+
* @param session - the owning session (audit event), when known.
|
|
61
|
+
* @returns the durable record and whether this call created it.
|
|
62
|
+
*/
|
|
63
|
+
captureAndRegister(origin: string, title: string | undefined, signal?: AbortSignal, session?: Session): Promise<{
|
|
64
|
+
record: EvidenceRecord;
|
|
65
|
+
deduplicated: boolean;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Run one topic gather: search + snapshot capture + registration. Never
|
|
69
|
+
* auto-assembles; uncaptured sources land in the gap list.
|
|
70
|
+
* @param topic - the research topic.
|
|
71
|
+
* @param depth - quick | standard | deep.
|
|
72
|
+
* @param signal - caller cancellation.
|
|
73
|
+
* @param session - the owning session (audit events), when known.
|
|
74
|
+
* @returns candidates plus gaps.
|
|
75
|
+
*/
|
|
76
|
+
gather(topic: string, depth: 'quick' | 'standard' | 'deep', signal?: AbortSignal, session?: Session): Promise<GatherOutcome>;
|
|
77
|
+
/**
|
|
78
|
+
* Verify one registered claim against its bound snapshots: integrity first
|
|
79
|
+
* (tampered/missing ⇒ contradicted), then the byte-level check, then the
|
|
80
|
+
* optional numeric bridge. The verdict is written back to the ledger.
|
|
81
|
+
* @param claimId - the claim to verify.
|
|
82
|
+
* @param session - the owning session (audit event), when known.
|
|
83
|
+
* @returns the fresh verdict.
|
|
84
|
+
*/
|
|
85
|
+
verifyClaim(claimId: string, session?: Session): Promise<ClaimVerdict>;
|
|
86
|
+
/** Compute the verdict for one claim registration (no writeback). */
|
|
87
|
+
private verifyRegistration;
|
|
88
|
+
/**
|
|
89
|
+
* Assemble and seal one report: validate (loud), register evidence and
|
|
90
|
+
* claims (idempotent; conflicts throw), verify every claim, render
|
|
91
|
+
* `report.md` with visible markers for unverified/contradicted claims, write
|
|
92
|
+
* `manifest.json`, and seal the versioned directory with the manifest hash.
|
|
93
|
+
* @param request - the frozen assemble request.
|
|
94
|
+
* @param context - optional assemble context (owning session for events).
|
|
95
|
+
* @returns the sealed directory, the seal hash, and the per-claim verdicts.
|
|
96
|
+
*/
|
|
97
|
+
assemble(request: AssembleReportRequest, context?: AssembleContext): Promise<AssembleReportResult>;
|
|
98
|
+
/** Allocate the next versioned report directory for one topic (UTC clock). */
|
|
99
|
+
private freshReportDir;
|
|
100
|
+
/**
|
|
101
|
+
* Read one evidence item (re-hashed on read).
|
|
102
|
+
* @param evidenceId - the ledger id.
|
|
103
|
+
* @returns the view, or undefined when unknown.
|
|
104
|
+
*/
|
|
105
|
+
getEvidence(evidenceId: string): Promise<EvidenceView | undefined>;
|
|
106
|
+
/**
|
|
107
|
+
* Read one snapshot's bytes (re-hashed on read).
|
|
108
|
+
* @param evidenceId - the ledger id.
|
|
109
|
+
* @returns content plus integrity, or undefined when unknown.
|
|
110
|
+
*/
|
|
111
|
+
readEvidenceContent(evidenceId: string): Promise<{
|
|
112
|
+
content: string;
|
|
113
|
+
integrity: EvidenceIntegrity;
|
|
114
|
+
} | undefined>;
|
|
115
|
+
/**
|
|
116
|
+
* Read one claim with its latest verdict.
|
|
117
|
+
* @param claimId - the claim id.
|
|
118
|
+
* @returns the view, or undefined when unknown.
|
|
119
|
+
*/
|
|
120
|
+
getClaim(claimId: string): Promise<ClaimView | undefined>;
|
|
121
|
+
/**
|
|
122
|
+
* List every registered evidence item (re-hashed on read).
|
|
123
|
+
* @returns all evidence views in registration order.
|
|
124
|
+
*/
|
|
125
|
+
listEvidence(): Promise<EvidenceView[]>;
|
|
126
|
+
/**
|
|
127
|
+
* List every registered claim with its latest verdict.
|
|
128
|
+
* @returns all claim views in registration order.
|
|
129
|
+
*/
|
|
130
|
+
listClaims(): Promise<ClaimView[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Aggregate ledger counts (evidence re-hashed for the tamper count).
|
|
133
|
+
* @returns the summary.
|
|
134
|
+
*/
|
|
135
|
+
summarize(): Promise<LedgerSummary>;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=provider-local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-local.d.ts","sourceRoot":"","sources":["../../src/provider-local.ts"],"names":[],"mappings":"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"}
|