evidential-protocol 2.0.0 → 3.0.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.
Files changed (49) hide show
  1. package/dist/attestation.d.ts +80 -0
  2. package/dist/attestation.d.ts.map +1 -0
  3. package/dist/attestation.js +115 -0
  4. package/dist/attestation.js.map +1 -0
  5. package/dist/audit-ledger.d.ts +96 -0
  6. package/dist/audit-ledger.d.ts.map +1 -0
  7. package/dist/audit-ledger.js +152 -0
  8. package/dist/audit-ledger.js.map +1 -0
  9. package/dist/dormant.d.ts +59 -0
  10. package/dist/dormant.d.ts.map +1 -0
  11. package/dist/dormant.js +256 -0
  12. package/dist/dormant.js.map +1 -0
  13. package/dist/ergative.d.ts +75 -0
  14. package/dist/ergative.d.ts.map +1 -0
  15. package/dist/ergative.js +203 -0
  16. package/dist/ergative.js.map +1 -0
  17. package/dist/fingerprint.d.ts +126 -0
  18. package/dist/fingerprint.d.ts.map +1 -0
  19. package/dist/fingerprint.js +315 -0
  20. package/dist/fingerprint.js.map +1 -0
  21. package/dist/index.d.ts +14 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +24 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/provenance.d.ts +101 -0
  26. package/dist/provenance.d.ts.map +1 -0
  27. package/dist/provenance.js +197 -0
  28. package/dist/provenance.js.map +1 -0
  29. package/dist/purity.d.ts +85 -0
  30. package/dist/purity.d.ts.map +1 -0
  31. package/dist/purity.js +124 -0
  32. package/dist/purity.js.map +1 -0
  33. package/dist/resilience.d.ts +63 -0
  34. package/dist/resilience.d.ts.map +1 -0
  35. package/dist/resilience.js +241 -0
  36. package/dist/resilience.js.map +1 -0
  37. package/dist/scoring.d.ts +87 -0
  38. package/dist/scoring.d.ts.map +1 -0
  39. package/dist/scoring.js +202 -0
  40. package/dist/scoring.js.map +1 -0
  41. package/dist/self-describing.d.ts +71 -0
  42. package/dist/self-describing.d.ts.map +1 -0
  43. package/dist/self-describing.js +153 -0
  44. package/dist/self-describing.js.map +1 -0
  45. package/dist/tests/kusunda.test.d.ts +2 -0
  46. package/dist/tests/kusunda.test.d.ts.map +1 -0
  47. package/dist/tests/kusunda.test.js +342 -0
  48. package/dist/tests/kusunda.test.js.map +1 -0
  49. package/package.json +49 -3
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Content Attestation (Kusunda isolate identity + Coldstar integration)
3
+ *
4
+ * Proves content is original, not derived. Designed to work with
5
+ * Coldstar's air-gapped signing flow: content is hashed here, the hash
6
+ * is signed on the cold device, and the signature is attached back.
7
+ */
8
+ /** A complete attestation record for a piece of content. */
9
+ export interface ContentAttestation {
10
+ /** SHA-256 hash of the content. */
11
+ content_hash: string;
12
+ /** Hash algorithm used. */
13
+ algorithm: "sha256";
14
+ /** Identifier of the entity that produced the content. */
15
+ producer: string;
16
+ /** ISO 8601 timestamp of attestation creation. */
17
+ timestamp: string;
18
+ /** Cryptographic signature (added after external signing). */
19
+ signature?: string;
20
+ /** Blockchain target for on-chain anchoring. */
21
+ chain?: "solana-devnet" | "solana-mainnet";
22
+ /** On-chain transaction hash after anchoring. */
23
+ tx_hash?: string;
24
+ /** Hash of the associated claims array, if any. */
25
+ claims_hash?: string;
26
+ }
27
+ /**
28
+ * Builds unsigned content attestations. The signing step is deliberately
29
+ * decoupled so it can happen on an air-gapped Coldstar device.
30
+ */
31
+ export declare class AttestationBuilder {
32
+ private readonly producer;
33
+ constructor(producer: string);
34
+ /** Compute the SHA-256 hash of arbitrary content. Returns hex string. */
35
+ hashContent(content: string): string;
36
+ /**
37
+ * Hash an array of claims (claim text + evidence class pairs).
38
+ * The claims are JSON-serialised in a deterministic order before hashing.
39
+ */
40
+ hashClaims(claims: Array<{
41
+ claim: string;
42
+ evidence_class: string;
43
+ }>): string;
44
+ /**
45
+ * Build an unsigned `ContentAttestation`.
46
+ *
47
+ * @param content - The raw content to attest.
48
+ * @param claims - Optional claims to bind into the attestation via hash.
49
+ */
50
+ build(content: string, claims?: Array<{
51
+ claim: string;
52
+ evidence_class: string;
53
+ }>): ContentAttestation;
54
+ /**
55
+ * Attach a signature to an attestation. Returns a new object;
56
+ * the original is not mutated.
57
+ */
58
+ sign(attestation: ContentAttestation, signature: string): ContentAttestation;
59
+ /**
60
+ * Verify that an attestation's `content_hash` matches the given content.
61
+ * Does NOT verify the cryptographic signature — that requires the
62
+ * signer's public key which lives on-chain or in the Coldstar vault.
63
+ */
64
+ verify(attestation: ContentAttestation, content: string): boolean;
65
+ }
66
+ /**
67
+ * Produce a canonical string representation of an attestation suitable
68
+ * for external signing (e.g. on a Coldstar air-gapped device).
69
+ *
70
+ * Format: deterministic, line-delimited, no optional fields unless present.
71
+ */
72
+ export declare function formatForSigning(attestation: ContentAttestation): string;
73
+ /**
74
+ * Format an attestation as compact data suitable for a Solana memo
75
+ * instruction. Memo programs accept arbitrary UTF-8 up to ~566 bytes.
76
+ *
77
+ * Format: pipe-delimited, minimal field names.
78
+ */
79
+ export declare function attestationToMemo(attestation: ContentAttestation): string;
80
+ //# sourceMappingURL=attestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestation.d.ts","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,2BAA2B;IAC3B,SAAS,EAAE,QAAQ,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAAC;IAC3C,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,EAAE,MAAM;IAI5B,yEAAyE;IACzE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIpC;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,MAAM;IAO5E;;;;;OAKG;IACH,KAAK,CACH,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,GACxD,kBAAkB;IAerB;;;OAGG;IACH,IAAI,CAAC,WAAW,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,GAAG,kBAAkB;IAI5E;;;;OAIG;IACH,MAAM,CAAC,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;CAIlE;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,kBAAkB,GAAG,MAAM,CAiBxE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,kBAAkB,GAAG,MAAM,CAiBzE"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Content Attestation (Kusunda isolate identity + Coldstar integration)
3
+ *
4
+ * Proves content is original, not derived. Designed to work with
5
+ * Coldstar's air-gapped signing flow: content is hashed here, the hash
6
+ * is signed on the cold device, and the signature is attached back.
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ // ---------------------------------------------------------------------------
10
+ // AttestationBuilder
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Builds unsigned content attestations. The signing step is deliberately
14
+ * decoupled so it can happen on an air-gapped Coldstar device.
15
+ */
16
+ export class AttestationBuilder {
17
+ producer;
18
+ constructor(producer) {
19
+ this.producer = producer;
20
+ }
21
+ /** Compute the SHA-256 hash of arbitrary content. Returns hex string. */
22
+ hashContent(content) {
23
+ return createHash("sha256").update(content, "utf-8").digest("hex");
24
+ }
25
+ /**
26
+ * Hash an array of claims (claim text + evidence class pairs).
27
+ * The claims are JSON-serialised in a deterministic order before hashing.
28
+ */
29
+ hashClaims(claims) {
30
+ // Sort by claim text for deterministic ordering.
31
+ const sorted = [...claims].sort((a, b) => a.claim.localeCompare(b.claim));
32
+ const canonical = JSON.stringify(sorted);
33
+ return createHash("sha256").update(canonical, "utf-8").digest("hex");
34
+ }
35
+ /**
36
+ * Build an unsigned `ContentAttestation`.
37
+ *
38
+ * @param content - The raw content to attest.
39
+ * @param claims - Optional claims to bind into the attestation via hash.
40
+ */
41
+ build(content, claims) {
42
+ const attestation = {
43
+ content_hash: this.hashContent(content),
44
+ algorithm: "sha256",
45
+ producer: this.producer,
46
+ timestamp: new Date().toISOString(),
47
+ };
48
+ if (claims && claims.length > 0) {
49
+ attestation.claims_hash = this.hashClaims(claims);
50
+ }
51
+ return attestation;
52
+ }
53
+ /**
54
+ * Attach a signature to an attestation. Returns a new object;
55
+ * the original is not mutated.
56
+ */
57
+ sign(attestation, signature) {
58
+ return { ...attestation, signature };
59
+ }
60
+ /**
61
+ * Verify that an attestation's `content_hash` matches the given content.
62
+ * Does NOT verify the cryptographic signature — that requires the
63
+ * signer's public key which lives on-chain or in the Coldstar vault.
64
+ */
65
+ verify(attestation, content) {
66
+ const expected = this.hashContent(content);
67
+ return attestation.content_hash === expected;
68
+ }
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Standalone utilities
72
+ // ---------------------------------------------------------------------------
73
+ /**
74
+ * Produce a canonical string representation of an attestation suitable
75
+ * for external signing (e.g. on a Coldstar air-gapped device).
76
+ *
77
+ * Format: deterministic, line-delimited, no optional fields unless present.
78
+ */
79
+ export function formatForSigning(attestation) {
80
+ const lines = [
81
+ `ep-attest:v1`,
82
+ `hash:${attestation.algorithm}:${attestation.content_hash}`,
83
+ `producer:${attestation.producer}`,
84
+ `ts:${attestation.timestamp}`,
85
+ ];
86
+ if (attestation.claims_hash) {
87
+ lines.push(`claims:${attestation.claims_hash}`);
88
+ }
89
+ if (attestation.chain) {
90
+ lines.push(`chain:${attestation.chain}`);
91
+ }
92
+ return lines.join("\n");
93
+ }
94
+ /**
95
+ * Format an attestation as compact data suitable for a Solana memo
96
+ * instruction. Memo programs accept arbitrary UTF-8 up to ~566 bytes.
97
+ *
98
+ * Format: pipe-delimited, minimal field names.
99
+ */
100
+ export function attestationToMemo(attestation) {
101
+ const parts = [
102
+ "EP1",
103
+ attestation.content_hash,
104
+ attestation.producer,
105
+ attestation.timestamp,
106
+ ];
107
+ if (attestation.claims_hash) {
108
+ parts.push(`c:${attestation.claims_hash}`);
109
+ }
110
+ if (attestation.signature) {
111
+ parts.push(`s:${attestation.signature}`);
112
+ }
113
+ return parts.join("|");
114
+ }
115
+ //# sourceMappingURL=attestation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attestation.js","sourceRoot":"","sources":["../src/attestation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * EP-2: Bilateral Audit Ledger (Kusunda dual-person marking)
3
+ *
4
+ * Every action records WHO called and WHAT was affected in a single
5
+ * fused record. Provides query, cross-reference, and hot-spot analysis.
6
+ */
7
+ import type { EvidenceClass } from "./types.js";
8
+ /** Allowed actions in the audit ledger. */
9
+ export type AuditAction = "read" | "write" | "delete" | "invoke";
10
+ /** A single bilateral audit record. */
11
+ export interface AuditEntry {
12
+ /** Unique entry identifier. */
13
+ id: string;
14
+ /** Agent identity that initiated the action. */
15
+ caller: string;
16
+ /** Resource identifier that was affected. */
17
+ target: string;
18
+ /** What kind of action was performed. */
19
+ action: AuditAction;
20
+ /** MCP tool name used for the action. */
21
+ tool: string;
22
+ /** Evidence class of the action's output. */
23
+ evidence_class: EvidenceClass;
24
+ /** ISO 8601 timestamp of when the action occurred. */
25
+ timestamp: string;
26
+ /** Duration of the action in milliseconds. */
27
+ duration_ms: number;
28
+ /** Whether the action completed successfully. */
29
+ success: boolean;
30
+ }
31
+ /** Serialized form of the audit ledger for persistence. */
32
+ export interface AuditLedgerSnapshot {
33
+ version: "1.0";
34
+ entries: AuditEntry[];
35
+ created_at: string;
36
+ }
37
+ /**
38
+ * In-memory bilateral audit ledger.
39
+ *
40
+ * Records every caller-target interaction and supports multidimensional
41
+ * querying: by caller, target, time range, tool, and cross-references.
42
+ */
43
+ export declare class AuditLedger {
44
+ private entries;
45
+ private byCallerIndex;
46
+ private byTargetIndex;
47
+ private byToolIndex;
48
+ /** Total number of entries in the ledger. */
49
+ get size(): number;
50
+ /**
51
+ * Record a new audit entry.
52
+ *
53
+ * @returns The created AuditEntry with generated id and timestamp.
54
+ */
55
+ record(params: {
56
+ caller: string;
57
+ target: string;
58
+ action: AuditAction;
59
+ tool: string;
60
+ evidence_class: EvidenceClass;
61
+ duration_ms: number;
62
+ success: boolean;
63
+ timestamp?: string;
64
+ }): AuditEntry;
65
+ /** Append a pre-built entry (used by fromJSON). */
66
+ private append;
67
+ /** Query all entries by caller identity. */
68
+ queryCaller(name: string): AuditEntry[];
69
+ /** Query all entries by target resource. */
70
+ queryTarget(resource: string): AuditEntry[];
71
+ /** Query entries within a time range (inclusive). */
72
+ queryTimeRange(from: Date, to: Date): AuditEntry[];
73
+ /** Query all entries by tool name. */
74
+ queryTool(toolName: string): AuditEntry[];
75
+ /**
76
+ * Get the N most-touched resources (by total interaction count).
77
+ * Returns [target, count] pairs sorted descending.
78
+ */
79
+ getHotTargets(n: number): Array<[string, number]>;
80
+ /**
81
+ * Get the N most-active callers (by total interaction count).
82
+ * Returns [caller, count] pairs sorted descending.
83
+ */
84
+ getActiveCallers(n: number): Array<[string, number]>;
85
+ /**
86
+ * Cross-reference: all interactions between a specific caller and target.
87
+ */
88
+ crossReference(caller: string, target: string): AuditEntry[];
89
+ /** Serialize the ledger to a JSON-safe snapshot. */
90
+ toJSON(): AuditLedgerSnapshot;
91
+ /** Restore a ledger from a serialized snapshot. */
92
+ static fromJSON(snapshot: AuditLedgerSnapshot): AuditLedger;
93
+ private indexPush;
94
+ private topN;
95
+ }
96
+ //# sourceMappingURL=audit-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-ledger.d.ts","sourceRoot":"","sources":["../src/audit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEjE,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,EAAE,WAAW,CAAC;IACpB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,cAAc,EAAE,aAAa,CAAC;IAC9B,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AASD;;;;;GAKG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,WAAW,CAA+B;IAElD,6CAA6C;IAC7C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,WAAW,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,aAAa,CAAC;QAC9B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,UAAU;IAwBd,mDAAmD;IACnD,OAAO,CAAC,MAAM;IAQd,4CAA4C;IAC5C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE;IAMvC,4CAA4C;IAC5C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAM3C,qDAAqD;IACrD,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,UAAU,EAAE;IASlD,sCAAsC;IACtC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAMzC;;;OAGG;IACH,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAIjD;;;OAGG;IACH,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAIpD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;IAU5D,oDAAoD;IACpD,MAAM,IAAI,mBAAmB;IAQ7B,mDAAmD;IACnD,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,WAAW;IAU3D,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,IAAI;CAWb"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * EP-2: Bilateral Audit Ledger (Kusunda dual-person marking)
3
+ *
4
+ * Every action records WHO called and WHAT was affected in a single
5
+ * fused record. Provides query, cross-reference, and hot-spot analysis.
6
+ */
7
+ /** Generate a compact unique ID. */
8
+ function generateId() {
9
+ const ts = Date.now().toString(36);
10
+ const rand = Math.random().toString(36).slice(2, 8);
11
+ return `aud_${ts}_${rand}`;
12
+ }
13
+ /**
14
+ * In-memory bilateral audit ledger.
15
+ *
16
+ * Records every caller-target interaction and supports multidimensional
17
+ * querying: by caller, target, time range, tool, and cross-references.
18
+ */
19
+ export class AuditLedger {
20
+ entries = [];
21
+ byCallerIndex = new Map();
22
+ byTargetIndex = new Map();
23
+ byToolIndex = new Map();
24
+ /** Total number of entries in the ledger. */
25
+ get size() {
26
+ return this.entries.length;
27
+ }
28
+ /**
29
+ * Record a new audit entry.
30
+ *
31
+ * @returns The created AuditEntry with generated id and timestamp.
32
+ */
33
+ record(params) {
34
+ const entry = {
35
+ id: generateId(),
36
+ caller: params.caller,
37
+ target: params.target,
38
+ action: params.action,
39
+ tool: params.tool,
40
+ evidence_class: params.evidence_class,
41
+ timestamp: params.timestamp ?? new Date().toISOString(),
42
+ duration_ms: params.duration_ms,
43
+ success: params.success,
44
+ };
45
+ const idx = this.entries.length;
46
+ this.entries.push(entry);
47
+ // Update indexes
48
+ this.indexPush(this.byCallerIndex, entry.caller, idx);
49
+ this.indexPush(this.byTargetIndex, entry.target, idx);
50
+ this.indexPush(this.byToolIndex, entry.tool, idx);
51
+ return entry;
52
+ }
53
+ /** Append a pre-built entry (used by fromJSON). */
54
+ append(entry) {
55
+ const idx = this.entries.length;
56
+ this.entries.push(entry);
57
+ this.indexPush(this.byCallerIndex, entry.caller, idx);
58
+ this.indexPush(this.byTargetIndex, entry.target, idx);
59
+ this.indexPush(this.byToolIndex, entry.tool, idx);
60
+ }
61
+ /** Query all entries by caller identity. */
62
+ queryCaller(name) {
63
+ const indices = this.byCallerIndex.get(name);
64
+ if (!indices)
65
+ return [];
66
+ return indices.map((i) => this.entries[i]);
67
+ }
68
+ /** Query all entries by target resource. */
69
+ queryTarget(resource) {
70
+ const indices = this.byTargetIndex.get(resource);
71
+ if (!indices)
72
+ return [];
73
+ return indices.map((i) => this.entries[i]);
74
+ }
75
+ /** Query entries within a time range (inclusive). */
76
+ queryTimeRange(from, to) {
77
+ const fromMs = from.getTime();
78
+ const toMs = to.getTime();
79
+ return this.entries.filter((e) => {
80
+ const ts = new Date(e.timestamp).getTime();
81
+ return ts >= fromMs && ts <= toMs;
82
+ });
83
+ }
84
+ /** Query all entries by tool name. */
85
+ queryTool(toolName) {
86
+ const indices = this.byToolIndex.get(toolName);
87
+ if (!indices)
88
+ return [];
89
+ return indices.map((i) => this.entries[i]);
90
+ }
91
+ /**
92
+ * Get the N most-touched resources (by total interaction count).
93
+ * Returns [target, count] pairs sorted descending.
94
+ */
95
+ getHotTargets(n) {
96
+ return this.topN(this.byTargetIndex, n);
97
+ }
98
+ /**
99
+ * Get the N most-active callers (by total interaction count).
100
+ * Returns [caller, count] pairs sorted descending.
101
+ */
102
+ getActiveCallers(n) {
103
+ return this.topN(this.byCallerIndex, n);
104
+ }
105
+ /**
106
+ * Cross-reference: all interactions between a specific caller and target.
107
+ */
108
+ crossReference(caller, target) {
109
+ const callerIndices = this.byCallerIndex.get(caller);
110
+ if (!callerIndices)
111
+ return [];
112
+ const targetSet = new Set(this.byTargetIndex.get(target) ?? []);
113
+ return callerIndices
114
+ .filter((i) => targetSet.has(i))
115
+ .map((i) => this.entries[i]);
116
+ }
117
+ /** Serialize the ledger to a JSON-safe snapshot. */
118
+ toJSON() {
119
+ return {
120
+ version: "1.0",
121
+ entries: [...this.entries],
122
+ created_at: new Date().toISOString(),
123
+ };
124
+ }
125
+ /** Restore a ledger from a serialized snapshot. */
126
+ static fromJSON(snapshot) {
127
+ const ledger = new AuditLedger();
128
+ for (const entry of snapshot.entries) {
129
+ ledger.append(entry);
130
+ }
131
+ return ledger;
132
+ }
133
+ // ---- Internal helpers ----
134
+ indexPush(index, key, value) {
135
+ const arr = index.get(key);
136
+ if (arr) {
137
+ arr.push(value);
138
+ }
139
+ else {
140
+ index.set(key, [value]);
141
+ }
142
+ }
143
+ topN(index, n) {
144
+ const pairs = [];
145
+ for (const [key, indices] of index) {
146
+ pairs.push([key, indices.length]);
147
+ }
148
+ pairs.sort((a, b) => b[1] - a[1]);
149
+ return pairs.slice(0, n);
150
+ }
151
+ }
152
+ //# sourceMappingURL=audit-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-ledger.js","sourceRoot":"","sources":["../src/audit-ledger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoCH,oCAAoC;AACpC,SAAS,UAAU;IACjB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IACd,OAAO,GAAiB,EAAE,CAAC;IAC3B,aAAa,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,aAAa,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAElD,6CAA6C;IAC7C,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MASN;QACC,MAAM,KAAK,GAAe;YACxB,EAAE,EAAE,UAAU,EAAE;YAChB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACvD,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;QAEF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzB,iBAAiB;QACjB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAElD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mDAAmD;IAC3C,MAAM,CAAC,KAAiB;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,4CAA4C;IAC5C,WAAW,CAAC,IAAY;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,4CAA4C;IAC5C,WAAW,CAAC,QAAgB;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,qDAAqD;IACrD,cAAc,CAAC,IAAU,EAAE,EAAQ;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YAC3C,OAAO,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,IAAI,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sCAAsC;IACtC,SAAS,CAAC,QAAgB;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,CAAS;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,CAAS;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,MAAc,EAAE,MAAc;QAC3C,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa;YAAE,OAAO,EAAE,CAAC;QAE9B,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,aAAa;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,oDAAoD;IACpD,MAAM;QACJ,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;IACJ,CAAC;IAED,mDAAmD;IACnD,MAAM,CAAC,QAAQ,CAAC,QAA6B;QAC3C,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,6BAA6B;IAErB,SAAS,CACf,KAA4B,EAC5B,GAAW,EACX,KAAa;QAEb,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,GAAG,EAAE,CAAC;YACR,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,IAAI,CACV,KAA4B,EAC5B,CAAS;QAET,MAAM,KAAK,GAA4B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Dormant Asset Scanner — Kusunda Rediscovery
3
+ *
4
+ * Language isolates like Kusunda were "rediscovered" after being
5
+ * presumed extinct. This module scores repositories and digital
6
+ * assets for hidden value — dormant projects that deserve revival
7
+ * vs. those ready for the archive.
8
+ */
9
+ /** Profile describing a repository or digital asset. */
10
+ export interface AssetProfile {
11
+ id: string;
12
+ name: string;
13
+ path: string;
14
+ last_commit?: string;
15
+ last_publish?: string;
16
+ has_readme: boolean;
17
+ has_tests: boolean;
18
+ has_ci: boolean;
19
+ language?: string;
20
+ dependencies_count: number;
21
+ publishable: boolean;
22
+ published: boolean;
23
+ }
24
+ /** Computed dormancy and value scores for an asset. */
25
+ export interface DormantScore {
26
+ asset_id: string;
27
+ dormancy_score: number;
28
+ value_score: number;
29
+ recommendation: "publish" | "archive" | "revive" | "maintain" | "investigate";
30
+ reasons: string[];
31
+ }
32
+ /**
33
+ * Scans a collection of asset profiles and scores them on two axes:
34
+ * dormancy (how inactive) and value (how potentially useful).
35
+ */
36
+ export declare class DormantScanner {
37
+ private assets;
38
+ /** Register an asset for scanning. */
39
+ addAsset(profile: AssetProfile): void;
40
+ /** Score a single asset by ID. */
41
+ score(assetId: string): DormantScore;
42
+ /** Score all registered assets. */
43
+ scoreAll(): DormantScore[];
44
+ /** Return unpublished assets with value_score > 0.5. */
45
+ getPublishable(): DormantScore[];
46
+ /** Return dormant assets worth reviving (high value despite dormancy). */
47
+ getRevivable(): DormantScore[];
48
+ /** Return truly dead assets recommended for archival. */
49
+ getArchivable(): DormantScore[];
50
+ /** Generate a Markdown summary report of all assets. */
51
+ generateReport(): string;
52
+ /** Compute dormancy and value scores for a single asset. */
53
+ private computeScore;
54
+ /** Determine the recommendation based on dormancy/value quadrant. */
55
+ private recommend;
56
+ /** Calculate days between a date string and now. */
57
+ private daysSince;
58
+ }
59
+ //# sourceMappingURL=dormant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dormant.d.ts","sourceRoot":"","sources":["../src/dormant.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,uDAAuD;AACvD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC;IAC9E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAWD;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAwC;IAEtD,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIrC,kCAAkC;IAClC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY;IAcpC,mCAAmC;IACnC,QAAQ,IAAI,YAAY,EAAE;IAI1B,wDAAwD;IACxD,cAAc,IAAI,YAAY,EAAE;IAShC,0EAA0E;IAC1E,YAAY,IAAI,YAAY,EAAE;IAI9B,yDAAyD;IACzD,aAAa,IAAI,YAAY,EAAE;IAI/B,wDAAwD;IACxD,cAAc,IAAI,MAAM;IA2FxB,4DAA4D;IAC5D,OAAO,CAAC,YAAY;IA6FpB,qEAAqE;IACrE,OAAO,CAAC,SAAS;IA6BjB,oDAAoD;IACpD,OAAO,CAAC,SAAS;CAKlB"}