@atrib/sdk 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 +216 -0
- package/README.md +525 -0
- package/dist/attest.d.ts +106 -0
- package/dist/attest.d.ts.map +1 -0
- package/dist/attest.js +64 -0
- package/dist/attest.js.map +1 -0
- package/dist/attribution.d.ts +81 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +133 -0
- package/dist/attribution.js.map +1 -0
- package/dist/client.d.ts +18 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +244 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +113 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +91 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +32 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +175 -0
- package/dist/daemon.js.map +1 -0
- package/dist/evidence-envelope.d.ts +98 -0
- package/dist/evidence-envelope.d.ts.map +1 -0
- package/dist/evidence-envelope.js +108 -0
- package/dist/evidence-envelope.js.map +1 -0
- package/dist/evidence.d.ts +76 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +20 -0
- package/dist/evidence.js.map +1 -0
- package/dist/hashes.d.ts +26 -0
- package/dist/hashes.d.ts.map +1 -0
- package/dist/hashes.js +33 -0
- package/dist/hashes.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/recall.d.ts +122 -0
- package/dist/recall.d.ts.map +1 -0
- package/dist/recall.js +29 -0
- package/dist/recall.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.d.ts","sourceRoot":"","sources":["../src/attest.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAA;AAElE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,sBAAsB,EAAE,MAAM,CAAA;IAC9B,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,0EAA0E;AAC1E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,WAAW,GAAG,SAAS,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,iEAAiE;IACjE,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAA;IACtD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,GAAG,EAAE,QAAQ,GAAG,YAAY,GAAG,MAAM,CAAA;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,0BAA0B,CAAA;IAChD;;;;OAIG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAA;CACrC;AAOD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,gBAAgB,CAAC,EAAE,MAAM,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCzB;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,QAAQ,GAAG,YAAY,EAC5B,aAAa,EAAE,MAAM,EAAE,GACtB,YAAY,CAmBd"}
|
package/dist/attest.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
const REF_EVENT_TYPE = {
|
|
3
|
+
annotates: 'annotation',
|
|
4
|
+
revises: 'revision',
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Map AttestInput to the EmitInput argument shape shared by the daemon's
|
|
8
|
+
* `emit` tool and `emitInProcess`. Throws TypeError on contradictory input
|
|
9
|
+
* (the only throw path of the write verb — operational failures degrade).
|
|
10
|
+
*/
|
|
11
|
+
export function buildEmitArgs(input, defaultContextId) {
|
|
12
|
+
const ref = input.ref;
|
|
13
|
+
let eventType = input.event_type;
|
|
14
|
+
if (ref) {
|
|
15
|
+
const derived = REF_EVENT_TYPE[ref.kind];
|
|
16
|
+
if (derived === undefined) {
|
|
17
|
+
throw new TypeError(`atrib: unknown attest ref kind: ${String(ref.kind)}`);
|
|
18
|
+
}
|
|
19
|
+
if (eventType !== undefined && eventType !== derived && !eventType.endsWith(`/${derived}`)) {
|
|
20
|
+
throw new TypeError(`atrib: attest ref kind '${ref.kind}' requires event_type '${derived}', got '${eventType}'`);
|
|
21
|
+
}
|
|
22
|
+
eventType = eventType ?? derived;
|
|
23
|
+
}
|
|
24
|
+
const contextId = input.context_id ?? defaultContextId;
|
|
25
|
+
return {
|
|
26
|
+
event_type: eventType ?? 'observation',
|
|
27
|
+
content: input.content,
|
|
28
|
+
...(contextId !== undefined ? { context_id: contextId } : {}),
|
|
29
|
+
...(ref?.kind === 'annotates' ? { annotates: ref.record_hash } : {}),
|
|
30
|
+
...(ref?.kind === 'revises' ? { revises: ref.record_hash } : {}),
|
|
31
|
+
...(input.informed_by !== undefined ? { informed_by: input.informed_by } : {}),
|
|
32
|
+
...(input.allow_unresolved_informed_by !== undefined
|
|
33
|
+
? { allow_unresolved_informed_by: input.allow_unresolved_informed_by }
|
|
34
|
+
: {}),
|
|
35
|
+
...(input.chain_root !== undefined ? { chain_root: input.chain_root } : {}),
|
|
36
|
+
...(input.provenance_token !== undefined
|
|
37
|
+
? { provenance_token: input.provenance_token }
|
|
38
|
+
: {}),
|
|
39
|
+
...(input.tool_name !== undefined ? { tool_name: input.tool_name } : {}),
|
|
40
|
+
...(input.args_hash !== undefined ? { args_hash: input.args_hash } : {}),
|
|
41
|
+
...(input.result_hash !== undefined ? { result_hash: input.result_hash } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function attestResultFromEmitOutput(output, via, extraWarnings) {
|
|
45
|
+
const warnings = [
|
|
46
|
+
...extraWarnings,
|
|
47
|
+
...(Array.isArray(output.warnings) ? output.warnings.map(String) : []),
|
|
48
|
+
];
|
|
49
|
+
const receiptId = typeof output.receipt_id === 'string' ? output.receipt_id : undefined;
|
|
50
|
+
return {
|
|
51
|
+
record_hash: typeof output.record_hash === 'string' && output.record_hash !== ''
|
|
52
|
+
? output.record_hash
|
|
53
|
+
: null,
|
|
54
|
+
context_id: typeof output.context_id === 'string' ? output.context_id : null,
|
|
55
|
+
log_index: typeof output.log_index === 'number' ? output.log_index : null,
|
|
56
|
+
inclusion_proof: Array.isArray(output.inclusion_proof)
|
|
57
|
+
? output.inclusion_proof
|
|
58
|
+
: null,
|
|
59
|
+
...(receiptId !== undefined ? { receipt_id: receiptId } : {}),
|
|
60
|
+
via,
|
|
61
|
+
warnings,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=attest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.js","sourceRoot":"","sources":["../src/attest.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAiGtC,MAAM,cAAc,GAAsC;IACxD,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE,UAAU;CACpB,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,gBAAyB;IAEzB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAA;IACrB,IAAI,SAAS,GAAG,KAAK,CAAC,UAAU,CAAA;IAChC,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAAC,mCAAmC,MAAM,CAAE,GAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC3F,CAAC;QACD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,CAAC;YAC3F,MAAM,IAAI,SAAS,CACjB,2BAA2B,GAAG,CAAC,IAAI,0BAA0B,OAAO,WAAW,SAAS,GAAG,CAC5F,CAAA;QACH,CAAC;QACD,SAAS,GAAG,SAAS,IAAI,OAAO,CAAA;IAClC,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,IAAI,gBAAgB,CAAA;IACtD,OAAO;QACL,UAAU,EAAE,SAAS,IAAI,aAAa;QACtC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,GAAG,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,GAAG,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,GAAG,CAAC,KAAK,CAAC,4BAA4B,KAAK,SAAS;YAClD,CAAC,CAAC,EAAE,4BAA4B,EAAE,KAAK,CAAC,4BAA4B,EAAE;YACtE,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/E,CAAA;AACH,CAAC;AAYD,MAAM,UAAU,0BAA0B,CACxC,MAAsB,EACtB,GAA4B,EAC5B,aAAuB;IAEvB,MAAM,QAAQ,GAAG;QACf,GAAG,aAAa;QAChB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAA;IACD,MAAM,SAAS,GAAG,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAA;IACvF,OAAO;QACL,WAAW,EAAE,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,KAAK,EAAE;YAC9E,CAAC,CAAC,MAAM,CAAC,WAAW;YACpB,CAAC,CAAC,IAAI;QACR,UAAU,EAAE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;QAC5E,SAAS,EAAE,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;QACzE,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC;YACpD,CAAC,CAAE,MAAM,CAAC,eAAkD;YAC5D,CAAC,CAAC,IAAI;QACR,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG;QACH,QAAQ;KACT,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dev.atrib/attribution` extension receipts (accepted as D141; extension
|
|
3
|
+
* spec at docs/extensions/dev.atrib-attribution/v0.1.md, conformance at
|
|
4
|
+
* spec/conformance/mcp-extension/).
|
|
5
|
+
*
|
|
6
|
+
* Behind an opt-in flag, the daemon client parses attestation receipts
|
|
7
|
+
* from tool results' `_meta["dev.atrib/attribution"]`: the propagation
|
|
8
|
+
* token, a receipt block naming the record the server already signed
|
|
9
|
+
* locally, and optionally the full signed record for immediate Tier-3
|
|
10
|
+
* re-verification. `log_submission` is a queue status, never an awaited
|
|
11
|
+
* proof — submission stays non-blocking per §5.3.5.
|
|
12
|
+
*
|
|
13
|
+
* Receipts are advisory extension data: trust derives only from verifying
|
|
14
|
+
* signed records and inclusion proofs, never from the receipt itself.
|
|
15
|
+
*/
|
|
16
|
+
import { ATTRIBUTION_EXTENSION_ID, type AtribRecord, type AttributionLogSubmissionStatus, type AttributionReceiptVerification } from '@atrib/mcp';
|
|
17
|
+
/**
|
|
18
|
+
* Alias of `@atrib/mcp`'s `ATTRIBUTION_EXTENSION_ID` — one identifier, one
|
|
19
|
+
* source of truth (the SEP-2133 extension id is frozen).
|
|
20
|
+
*/
|
|
21
|
+
export declare const ATTRIBUTION_EXTENSION_KEY: typeof ATTRIBUTION_EXTENSION_ID;
|
|
22
|
+
export type { AttributionLogSubmissionStatus };
|
|
23
|
+
export interface AttributionReceipt {
|
|
24
|
+
record_hash?: string;
|
|
25
|
+
creator_key?: string;
|
|
26
|
+
context_id?: string;
|
|
27
|
+
event_type?: string;
|
|
28
|
+
chain_root?: string;
|
|
29
|
+
/** Queue status; unknown future values pass through as strings. */
|
|
30
|
+
log_submission?: AttributionLogSubmissionStatus | string;
|
|
31
|
+
}
|
|
32
|
+
export interface AttributionReceiptBlock {
|
|
33
|
+
/** §1.5.2 propagation token for the record the server just signed. */
|
|
34
|
+
token?: string;
|
|
35
|
+
receipt?: AttributionReceipt;
|
|
36
|
+
/** Full signed record; present only when the client accepted 'record'. */
|
|
37
|
+
record?: AtribRecord;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The receipt surface the daemon client attaches to attest/recall results:
|
|
41
|
+
* the leniently parsed block plus the outcome of running `@atrib/mcp`'s
|
|
42
|
+
* `verifyAttributionReceipt` over the RAW `_meta` block (structural +
|
|
43
|
+
* internal-consistency check per extension spec §6.2). Verification is
|
|
44
|
+
* advisory like the receipt itself: an invalid receipt is discarded from
|
|
45
|
+
* trust, never from the tool result.
|
|
46
|
+
*/
|
|
47
|
+
export interface VerifiedAttributionReceipt {
|
|
48
|
+
block: AttributionReceiptBlock;
|
|
49
|
+
verification: AttributionReceiptVerification;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Extract the extension block from a tool result's `_meta`. Lenient parse
|
|
53
|
+
* per the extension's degradation posture: anything malformed yields null,
|
|
54
|
+
* never a throw.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseAttributionReceiptBlock(meta: unknown): AttributionReceiptBlock | null;
|
|
57
|
+
/** Outcome of checking a receipt against its attached signed record. */
|
|
58
|
+
export interface AttributionReceiptConsistency {
|
|
59
|
+
/** True iff every receipt claim matches the attached record. */
|
|
60
|
+
receipt_valid: boolean;
|
|
61
|
+
/** Receipt fields whose claims contradict the attached record. */
|
|
62
|
+
mismatched_fields: string[];
|
|
63
|
+
/** recordHashRef of the attached record (when a record is available). */
|
|
64
|
+
attached_record_hash?: string;
|
|
65
|
+
/** The receipt's claimed record_hash (when present). */
|
|
66
|
+
claimed_record_hash?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check a receipt block's claims against the signed record they name
|
|
70
|
+
* (the attached `block.record`, or a caller-retrieved record). Receipts
|
|
71
|
+
* are advisory: a mismatch NEVER invalidates the tool result — it means
|
|
72
|
+
* the receipt must not be trusted or cited (conformance:
|
|
73
|
+
* spec/conformance/mcp-extension/cases/receipt--*.json).
|
|
74
|
+
*
|
|
75
|
+
* Compared claims: `receipt.record_hash` vs the record's canonical hash,
|
|
76
|
+
* `token` vs encodeToken(record), and `creator_key` / `context_id` /
|
|
77
|
+
* `chain_root` / `event_type` (short name or URI, normalized) vs the
|
|
78
|
+
* record's fields. Absent receipt fields are not mismatches.
|
|
79
|
+
*/
|
|
80
|
+
export declare function checkAttributionReceiptConsistency(block: AttributionReceiptBlock, record?: AtribRecord): AttributionReceiptConsistency;
|
|
81
|
+
//# sourceMappingURL=attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,wBAAwB,EAGxB,KAAK,WAAW,EAChB,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACpC,MAAM,YAAY,CAAA;AAGnB;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,OAAO,wBAAmD,CAAA;AAElG,YAAY,EAAE,8BAA8B,EAAE,CAAA;AAE9C,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,cAAc,CAAC,EAAE,8BAA8B,GAAG,MAAM,CAAA;CACzD;AAED,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,0EAA0E;IAC1E,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,uBAAuB,CAAA;IAC9B,YAAY,EAAE,8BAA8B,CAAA;CAC7C;AAWD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CA6B1F;AAED,wEAAwE;AACxE,MAAM,WAAW,6BAA6B;IAC5C,gEAAgE;IAChE,aAAa,EAAE,OAAO,CAAA;IACtB,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,uBAAuB,EAC9B,MAAM,CAAC,EAAE,WAAW,GACnB,6BAA6B,CAgD/B"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* `dev.atrib/attribution` extension receipts (accepted as D141; extension
|
|
4
|
+
* spec at docs/extensions/dev.atrib-attribution/v0.1.md, conformance at
|
|
5
|
+
* spec/conformance/mcp-extension/).
|
|
6
|
+
*
|
|
7
|
+
* Behind an opt-in flag, the daemon client parses attestation receipts
|
|
8
|
+
* from tool results' `_meta["dev.atrib/attribution"]`: the propagation
|
|
9
|
+
* token, a receipt block naming the record the server already signed
|
|
10
|
+
* locally, and optionally the full signed record for immediate Tier-3
|
|
11
|
+
* re-verification. `log_submission` is a queue status, never an awaited
|
|
12
|
+
* proof — submission stays non-blocking per §5.3.5.
|
|
13
|
+
*
|
|
14
|
+
* Receipts are advisory extension data: trust derives only from verifying
|
|
15
|
+
* signed records and inclusion proofs, never from the receipt itself.
|
|
16
|
+
*/
|
|
17
|
+
import { ATTRIBUTION_EXTENSION_ID, encodeToken, normalizeEventType, } from '@atrib/mcp';
|
|
18
|
+
import { recordHashRef } from './hashes.js';
|
|
19
|
+
/**
|
|
20
|
+
* Alias of `@atrib/mcp`'s `ATTRIBUTION_EXTENSION_ID` — one identifier, one
|
|
21
|
+
* source of truth (the SEP-2133 extension id is frozen).
|
|
22
|
+
*/
|
|
23
|
+
export const ATTRIBUTION_EXTENSION_KEY = ATTRIBUTION_EXTENSION_ID;
|
|
24
|
+
const RECEIPT_STRING_FIELDS = [
|
|
25
|
+
'record_hash',
|
|
26
|
+
'creator_key',
|
|
27
|
+
'context_id',
|
|
28
|
+
'event_type',
|
|
29
|
+
'chain_root',
|
|
30
|
+
'log_submission',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Extract the extension block from a tool result's `_meta`. Lenient parse
|
|
34
|
+
* per the extension's degradation posture: anything malformed yields null,
|
|
35
|
+
* never a throw.
|
|
36
|
+
*/
|
|
37
|
+
export function parseAttributionReceiptBlock(meta) {
|
|
38
|
+
if (typeof meta !== 'object' || meta === null)
|
|
39
|
+
return null;
|
|
40
|
+
const raw = meta[ATTRIBUTION_EXTENSION_KEY];
|
|
41
|
+
if (typeof raw !== 'object' || raw === null)
|
|
42
|
+
return null;
|
|
43
|
+
const block = raw;
|
|
44
|
+
const out = {};
|
|
45
|
+
if (typeof block['token'] === 'string')
|
|
46
|
+
out.token = block['token'];
|
|
47
|
+
const rawReceipt = block['receipt'];
|
|
48
|
+
if (typeof rawReceipt === 'object' && rawReceipt !== null && !Array.isArray(rawReceipt)) {
|
|
49
|
+
const receipt = {};
|
|
50
|
+
let kept = 0;
|
|
51
|
+
for (const field of RECEIPT_STRING_FIELDS) {
|
|
52
|
+
const value = rawReceipt[field];
|
|
53
|
+
if (typeof value === 'string') {
|
|
54
|
+
receipt[field] = value;
|
|
55
|
+
kept += 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// A receipt where every field was wrong-typed conveys nothing; treat
|
|
59
|
+
// it as absent rather than surfacing an empty object.
|
|
60
|
+
if (kept > 0)
|
|
61
|
+
out.receipt = receipt;
|
|
62
|
+
}
|
|
63
|
+
const rawRecord = block['record'];
|
|
64
|
+
if (typeof rawRecord === 'object' && rawRecord !== null && !Array.isArray(rawRecord)) {
|
|
65
|
+
out.record = rawRecord;
|
|
66
|
+
}
|
|
67
|
+
return out.token !== undefined || out.receipt !== undefined || out.record !== undefined
|
|
68
|
+
? out
|
|
69
|
+
: null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check a receipt block's claims against the signed record they name
|
|
73
|
+
* (the attached `block.record`, or a caller-retrieved record). Receipts
|
|
74
|
+
* are advisory: a mismatch NEVER invalidates the tool result — it means
|
|
75
|
+
* the receipt must not be trusted or cited (conformance:
|
|
76
|
+
* spec/conformance/mcp-extension/cases/receipt--*.json).
|
|
77
|
+
*
|
|
78
|
+
* Compared claims: `receipt.record_hash` vs the record's canonical hash,
|
|
79
|
+
* `token` vs encodeToken(record), and `creator_key` / `context_id` /
|
|
80
|
+
* `chain_root` / `event_type` (short name or URI, normalized) vs the
|
|
81
|
+
* record's fields. Absent receipt fields are not mismatches.
|
|
82
|
+
*/
|
|
83
|
+
export function checkAttributionReceiptConsistency(block, record) {
|
|
84
|
+
const attached = record ?? block.record;
|
|
85
|
+
const receipt = block.receipt;
|
|
86
|
+
const claimed = receipt?.record_hash;
|
|
87
|
+
if (!attached) {
|
|
88
|
+
return {
|
|
89
|
+
receipt_valid: false,
|
|
90
|
+
mismatched_fields: ['record'],
|
|
91
|
+
...(claimed !== undefined ? { claimed_record_hash: claimed } : {}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const mismatched = [];
|
|
95
|
+
let attachedHash;
|
|
96
|
+
let token;
|
|
97
|
+
try {
|
|
98
|
+
attachedHash = recordHashRef(attached);
|
|
99
|
+
token = encodeToken(attached);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// A record that cannot be canonicalized/hashed cannot back a receipt.
|
|
103
|
+
return {
|
|
104
|
+
receipt_valid: false,
|
|
105
|
+
mismatched_fields: ['record'],
|
|
106
|
+
...(claimed !== undefined ? { claimed_record_hash: claimed } : {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (claimed !== undefined && claimed !== attachedHash)
|
|
110
|
+
mismatched.push('record_hash');
|
|
111
|
+
if (block.token !== undefined && block.token !== token)
|
|
112
|
+
mismatched.push('token');
|
|
113
|
+
if (receipt?.creator_key !== undefined && receipt.creator_key !== attached.creator_key) {
|
|
114
|
+
mismatched.push('creator_key');
|
|
115
|
+
}
|
|
116
|
+
if (receipt?.context_id !== undefined && receipt.context_id !== attached.context_id) {
|
|
117
|
+
mismatched.push('context_id');
|
|
118
|
+
}
|
|
119
|
+
if (receipt?.chain_root !== undefined && receipt.chain_root !== attached.chain_root) {
|
|
120
|
+
mismatched.push('chain_root');
|
|
121
|
+
}
|
|
122
|
+
if (receipt?.event_type !== undefined &&
|
|
123
|
+
normalizeEventType(receipt.event_type) !== normalizeEventType(attached.event_type)) {
|
|
124
|
+
mismatched.push('event_type');
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
receipt_valid: mismatched.length === 0,
|
|
128
|
+
mismatched_fields: mismatched,
|
|
129
|
+
attached_record_hash: attachedHash,
|
|
130
|
+
...(claimed !== undefined ? { claimed_record_hash: claimed } : {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribution.js","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AttestInput, type AttestResult } from './attest.js';
|
|
2
|
+
import { type AtribClientConfig } from './config.js';
|
|
3
|
+
import { type RecallOutcome, type RecallQuery } from './recall.js';
|
|
4
|
+
export interface AtribClient {
|
|
5
|
+
/** Single write verb. Never throws on operational failure (§5.8). */
|
|
6
|
+
attest(input: AttestInput): Promise<AttestResult>;
|
|
7
|
+
/** Single read verb. Never throws on operational failure (§5.8). */
|
|
8
|
+
recall<T = unknown>(query: RecallQuery): Promise<RecallOutcome<T>>;
|
|
9
|
+
/**
|
|
10
|
+
* Await all in-flight anchor fan-out legs (D138). For tests and shutdown
|
|
11
|
+
* hooks only — the attest path itself never awaits anchoring (§5.3.5).
|
|
12
|
+
*/
|
|
13
|
+
flushAnchors(): Promise<void>;
|
|
14
|
+
/** Close the daemon transport (if one was opened). */
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function createAtribClient(config?: AtribClientConfig): AtribClient;
|
|
18
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA0BA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAsC,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAExF,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAA;AAEpB,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACjD,oEAAoE;IACpE,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAA;IAClE;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B,sDAAsD;IACtD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AA8BD,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,iBAAsB,GAAG,WAAW,CAqO7E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* createAtribClient(): the consolidated client over attest/recall.
|
|
4
|
+
*
|
|
5
|
+
* Daemon-first per D120/the SDK brief: writes and reads prefer the local
|
|
6
|
+
* primitives runtime over MCP Streamable HTTP (one host-owned process,
|
|
7
|
+
* one key owner, one mirror), falling back to in-process engines.
|
|
8
|
+
* `@atrib/emit` is a hard dependency (the write fallback must always
|
|
9
|
+
* work); `@atrib/recall` and `@atrib/verify-mcp` are OPTIONAL peer
|
|
10
|
+
* dependencies loaded lazily, mirroring the P047 pattern — when absent,
|
|
11
|
+
* the corresponding recall shapes degrade to a typed unavailable outcome
|
|
12
|
+
* per §5.8 rather than failing to import.
|
|
13
|
+
*
|
|
14
|
+
* Operational failures never throw (§5.8); they degrade into `warnings`
|
|
15
|
+
* on the result. The only throw paths are contradictory inputs
|
|
16
|
+
* (programmer error).
|
|
17
|
+
*/
|
|
18
|
+
import { emitInProcess, resolveKey } from '@atrib/emit';
|
|
19
|
+
import { createAnchorFanout, readMirrorTail, resolveEnvContextId, } from '@atrib/mcp';
|
|
20
|
+
import { attestResultFromEmitOutput, buildEmitArgs, } from './attest.js';
|
|
21
|
+
import { recordHashRef } from './hashes.js';
|
|
22
|
+
import { DEFAULT_PRODUCER, resolveAnchorSet } from './config.js';
|
|
23
|
+
import { DaemonClient } from './daemon.js';
|
|
24
|
+
import { SHAPE_TO_TOOL, shapeOf, toToolArgs, } from './recall.js';
|
|
25
|
+
let recallModulePromise = null;
|
|
26
|
+
function loadRecallModule() {
|
|
27
|
+
recallModulePromise ??= import('@atrib/recall').then((mod) => mod, () => null);
|
|
28
|
+
return recallModulePromise;
|
|
29
|
+
}
|
|
30
|
+
let verifyModulePromise = null;
|
|
31
|
+
function loadVerifyModule() {
|
|
32
|
+
verifyModulePromise ??= import('@atrib/verify-mcp').then((mod) => mod, () => null);
|
|
33
|
+
return verifyModulePromise;
|
|
34
|
+
}
|
|
35
|
+
export function createAtribClient(config = {}) {
|
|
36
|
+
const daemonMode = config.daemon?.mode ?? 'prefer';
|
|
37
|
+
const daemon = daemonMode === 'off'
|
|
38
|
+
? null
|
|
39
|
+
: new DaemonClient(config.daemon, {
|
|
40
|
+
attributionReceipts: config.attributionReceipts === true,
|
|
41
|
+
});
|
|
42
|
+
const producer = config.producer ?? DEFAULT_PRODUCER;
|
|
43
|
+
const anchorSet = resolveAnchorSet(config.anchors, config.allowSingleAnchor);
|
|
44
|
+
const anchorWarnings = anchorSet.warnings;
|
|
45
|
+
const logEndpoint = anchorSet.primaryLogEndpoint;
|
|
46
|
+
// One D138 anchor fan-out per client, built lazily on the first
|
|
47
|
+
// in-process attest. The daemon attest path never consults it: the
|
|
48
|
+
// daemon owns its own anchors.
|
|
49
|
+
let fanout = null;
|
|
50
|
+
const getFanout = () => {
|
|
51
|
+
fanout ??= createAnchorFanout({ config: anchorSet.config });
|
|
52
|
+
return fanout;
|
|
53
|
+
};
|
|
54
|
+
// Lazily resolve the in-process signing key once. `config.key === null`
|
|
55
|
+
// is an explicit pass-through request; undefined defers to resolveKey().
|
|
56
|
+
let keyPromise = null;
|
|
57
|
+
const resolveClientKey = () => {
|
|
58
|
+
if (Object.prototype.hasOwnProperty.call(config, 'key')) {
|
|
59
|
+
return Promise.resolve(config.key ?? null);
|
|
60
|
+
}
|
|
61
|
+
keyPromise ??= resolveKey().catch((error) => {
|
|
62
|
+
console.warn(`atrib: key resolution failed: ${String(error)}`);
|
|
63
|
+
return null;
|
|
64
|
+
});
|
|
65
|
+
return keyPromise;
|
|
66
|
+
};
|
|
67
|
+
const defaultContextId = () => config.contextId ?? resolveEnvContextId();
|
|
68
|
+
async function attest(input) {
|
|
69
|
+
// Throws TypeError on contradictory input — the only throw path.
|
|
70
|
+
const args = buildEmitArgs(input, defaultContextId());
|
|
71
|
+
const warnings = [...anchorWarnings];
|
|
72
|
+
if (daemon) {
|
|
73
|
+
const outcome = await daemon.callTool('emit', args);
|
|
74
|
+
const attribution = outcome.ok ? outcome.attribution : undefined;
|
|
75
|
+
const emitOutput = outcome.ok && typeof outcome.value === 'object' && outcome.value !== null
|
|
76
|
+
? outcome.value
|
|
77
|
+
: null;
|
|
78
|
+
// A structurally-garbage daemon result (no record_hash string) is a
|
|
79
|
+
// daemon FAILURE, not a silent all-null success — fall through so
|
|
80
|
+
// the in-process path can still sign.
|
|
81
|
+
if (emitOutput !== null && typeof emitOutput.record_hash === 'string') {
|
|
82
|
+
const result = attestResultFromEmitOutput(emitOutput, 'daemon', warnings);
|
|
83
|
+
return attribution !== undefined
|
|
84
|
+
? { ...result, attribution_receipt: attribution }
|
|
85
|
+
: result;
|
|
86
|
+
}
|
|
87
|
+
const reason = outcome.ok
|
|
88
|
+
? 'daemon returned an emit result without a record_hash'
|
|
89
|
+
: outcome.reason;
|
|
90
|
+
warnings.push(`atrib: daemon attest failed: ${reason}`);
|
|
91
|
+
if (daemonMode === 'require') {
|
|
92
|
+
return {
|
|
93
|
+
record_hash: null,
|
|
94
|
+
context_id: null,
|
|
95
|
+
log_index: null,
|
|
96
|
+
inclusion_proof: null,
|
|
97
|
+
via: 'none',
|
|
98
|
+
warnings,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const key = await resolveClientKey();
|
|
103
|
+
if (key === null) {
|
|
104
|
+
warnings.push('atrib: no signing key available; operating in pass-through mode (§5.8), no record emitted');
|
|
105
|
+
return {
|
|
106
|
+
record_hash: null,
|
|
107
|
+
context_id: null,
|
|
108
|
+
log_index: null,
|
|
109
|
+
inclusion_proof: null,
|
|
110
|
+
via: 'none',
|
|
111
|
+
warnings,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const output = await emitInProcess(args, {
|
|
116
|
+
key,
|
|
117
|
+
producer,
|
|
118
|
+
...(logEndpoint !== undefined ? { logEndpoint } : {}),
|
|
119
|
+
});
|
|
120
|
+
const result = attestResultFromEmitOutput(output, 'in-process', warnings);
|
|
121
|
+
await fanOutToAnchors(result);
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
// emitInProcess throws only on input-shape validation; surface it as
|
|
126
|
+
// the caller's programmer error.
|
|
127
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* D138 anchor fan-out for the in-process path. Reads the freshly signed
|
|
132
|
+
* record back from the local mirror (§5.9) and hands it to every
|
|
133
|
+
* configured anchor. Fire-and-forget per §5.3.5: the fan-out ticket's
|
|
134
|
+
* outcomes are NEVER awaited here — only submission handoff is. The
|
|
135
|
+
* primary atrib-log anchor may receive the record twice (once via
|
|
136
|
+
* emitInProcess's own §2.6.1 queue, once via the fan-out); duplicate
|
|
137
|
+
* submission is idempotent-safe per §2.6.1 step 6 (the log returns the
|
|
138
|
+
* existing proof bundle for an already-committed record_hash).
|
|
139
|
+
* §5.8-safe: every failure degrades into a warning on the result.
|
|
140
|
+
*/
|
|
141
|
+
async function fanOutToAnchors(result) {
|
|
142
|
+
if (result.record_hash === null)
|
|
143
|
+
return;
|
|
144
|
+
try {
|
|
145
|
+
const fan = getFanout();
|
|
146
|
+
const posture = {
|
|
147
|
+
effective_anchor_count: fan.posture.effective_anchor_count,
|
|
148
|
+
used_default_set: fan.posture.used_default_set,
|
|
149
|
+
warned: fan.posture.warn,
|
|
150
|
+
};
|
|
151
|
+
result.anchor_posture = posture;
|
|
152
|
+
// The freshly-written mirror tail is the expected match: emitInProcess
|
|
153
|
+
// mirrors the signed record before returning.
|
|
154
|
+
const mirrorPath = process.env['ATRIB_MIRROR_FILE'];
|
|
155
|
+
const record = mirrorPath !== undefined && mirrorPath !== ''
|
|
156
|
+
? await readMirrorTail({
|
|
157
|
+
path: mirrorPath,
|
|
158
|
+
...(result.context_id !== null ? { contextId: result.context_id } : {}),
|
|
159
|
+
})
|
|
160
|
+
: null;
|
|
161
|
+
if (record === null || recordHashRef(record) !== result.record_hash) {
|
|
162
|
+
result.warnings.push('atrib: anchor fan-out skipped — signed record not found at the mirror tail (ATRIB_MIRROR_FILE)');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
fan.submitToAnchors(record);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
result.warnings.push(`atrib: anchor fan-out failed: ${String(error)}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function recall(query) {
|
|
172
|
+
const shape = shapeOf(query);
|
|
173
|
+
const tool = SHAPE_TO_TOOL[shape];
|
|
174
|
+
if (tool === undefined) {
|
|
175
|
+
throw new TypeError(`atrib: unknown recall shape: ${String(shape)}`);
|
|
176
|
+
}
|
|
177
|
+
const args = toToolArgs(query);
|
|
178
|
+
if (shape === 'session_chain' || shape === 'orphans') {
|
|
179
|
+
if (args['context_id'] === undefined) {
|
|
180
|
+
const contextId = defaultContextId();
|
|
181
|
+
if (contextId !== undefined)
|
|
182
|
+
args['context_id'] = contextId;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const warnings = [];
|
|
186
|
+
if (daemon) {
|
|
187
|
+
const outcome = await daemon.callTool(tool, args);
|
|
188
|
+
if (outcome.ok) {
|
|
189
|
+
const result = {
|
|
190
|
+
shape,
|
|
191
|
+
via: 'daemon',
|
|
192
|
+
data: outcome.value,
|
|
193
|
+
warnings,
|
|
194
|
+
};
|
|
195
|
+
return outcome.attribution !== undefined
|
|
196
|
+
? { ...result, attribution_receipt: outcome.attribution }
|
|
197
|
+
: result;
|
|
198
|
+
}
|
|
199
|
+
warnings.push(`atrib: daemon recall (${tool}) failed: ${outcome.reason}`);
|
|
200
|
+
if (daemonMode === 'require') {
|
|
201
|
+
return { shape, via: 'none', data: null, warnings };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
if (shape === 'history') {
|
|
206
|
+
const mod = await loadRecallModule();
|
|
207
|
+
if (mod === null) {
|
|
208
|
+
warnings.push("atrib: in-process history fallback unavailable — install the optional peer '@atrib/recall'");
|
|
209
|
+
return { shape, via: 'none', data: null, warnings };
|
|
210
|
+
}
|
|
211
|
+
const data = await mod.recall(args);
|
|
212
|
+
return { shape, via: 'in-process', data: data, warnings };
|
|
213
|
+
}
|
|
214
|
+
if (shape === 'verify') {
|
|
215
|
+
const mod = await loadVerifyModule();
|
|
216
|
+
if (mod === null) {
|
|
217
|
+
warnings.push("atrib: in-process verify fallback unavailable — install the optional peer '@atrib/verify-mcp'");
|
|
218
|
+
return { shape, via: 'none', data: null, warnings };
|
|
219
|
+
}
|
|
220
|
+
const data = await mod.handleAtribVerify(args);
|
|
221
|
+
return { shape, via: 'in-process', data: data, warnings };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
warnings.push(`atrib: in-process recall (${shape}) failed: ${String(error)}`);
|
|
226
|
+
return { shape, via: 'none', data: null, warnings };
|
|
227
|
+
}
|
|
228
|
+
warnings.push(`atrib: recall shape '${shape}' has no in-process fallback in @atrib/sdk v0; start the primitives runtime or use the ${tool} tool directly`);
|
|
229
|
+
return { shape, via: 'none', data: null, warnings };
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
attest,
|
|
233
|
+
recall,
|
|
234
|
+
flushAnchors: async () => {
|
|
235
|
+
if (fanout)
|
|
236
|
+
await fanout.flush();
|
|
237
|
+
},
|
|
238
|
+
close: async () => {
|
|
239
|
+
if (daemon)
|
|
240
|
+
await daemon.close();
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|