@ainize/core 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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/ain-ledger.d.ts +191 -0
  4. package/dist/ain-ledger.d.ts.map +1 -0
  5. package/dist/ain-ledger.js +714 -0
  6. package/dist/ain-ledger.js.map +1 -0
  7. package/dist/browser.d.ts +15 -0
  8. package/dist/browser.d.ts.map +1 -0
  9. package/dist/browser.js +16 -0
  10. package/dist/browser.js.map +1 -0
  11. package/dist/bytes.d.ts +3 -0
  12. package/dist/bytes.d.ts.map +1 -0
  13. package/dist/bytes.js +14 -0
  14. package/dist/bytes.js.map +1 -0
  15. package/dist/canonical.d.ts +5 -0
  16. package/dist/canonical.d.ts.map +1 -0
  17. package/dist/canonical.js +70 -0
  18. package/dist/canonical.js.map +1 -0
  19. package/dist/catalog.d.ts +181 -0
  20. package/dist/catalog.d.ts.map +1 -0
  21. package/dist/catalog.js +496 -0
  22. package/dist/catalog.js.map +1 -0
  23. package/dist/config-schema.d.ts +222 -0
  24. package/dist/config-schema.d.ts.map +1 -0
  25. package/dist/config-schema.js +302 -0
  26. package/dist/config-schema.js.map +1 -0
  27. package/dist/config.d.ts +128 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +330 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/events.d.ts +14 -0
  32. package/dist/events.d.ts.map +1 -0
  33. package/dist/events.js +20 -0
  34. package/dist/events.js.map +1 -0
  35. package/dist/identity.d.ts +15 -0
  36. package/dist/identity.d.ts.map +1 -0
  37. package/dist/identity.js +59 -0
  38. package/dist/identity.js.map +1 -0
  39. package/dist/index.d.ts +17 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +17 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/ledger.d.ts +134 -0
  44. package/dist/ledger.d.ts.map +1 -0
  45. package/dist/ledger.js +2 -0
  46. package/dist/ledger.js.map +1 -0
  47. package/dist/lineage.d.ts +63 -0
  48. package/dist/lineage.d.ts.map +1 -0
  49. package/dist/lineage.js +156 -0
  50. package/dist/lineage.js.map +1 -0
  51. package/dist/local-ledger.d.ts +74 -0
  52. package/dist/local-ledger.d.ts.map +1 -0
  53. package/dist/local-ledger.js +229 -0
  54. package/dist/local-ledger.js.map +1 -0
  55. package/dist/npz.d.ts +107 -0
  56. package/dist/npz.d.ts.map +1 -0
  57. package/dist/npz.js +502 -0
  58. package/dist/npz.js.map +1 -0
  59. package/dist/ops.d.ts +65 -0
  60. package/dist/ops.d.ts.map +1 -0
  61. package/dist/ops.js +9 -0
  62. package/dist/ops.js.map +1 -0
  63. package/dist/teach-auth.d.ts +19 -0
  64. package/dist/teach-auth.d.ts.map +1 -0
  65. package/dist/teach-auth.js +33 -0
  66. package/dist/teach-auth.js.map +1 -0
  67. package/dist/types.d.ts +1096 -0
  68. package/dist/types.d.ts.map +1 -0
  69. package/dist/types.js +98 -0
  70. package/dist/types.js.map +1 -0
  71. package/dist/x402.d.ts +35 -0
  72. package/dist/x402.d.ts.map +1 -0
  73. package/dist/x402.js +84 -0
  74. package/dist/x402.js.map +1 -0
  75. package/package.json +49 -0
@@ -0,0 +1,229 @@
1
+ /**
2
+ * LocalLedger — signed record DAG stored in SQLite (node:sqlite), replicated by set reconciliation.
3
+ *
4
+ * Record hash = sha256(canonicalJson({kind, body, author, ts, parents})); sig = ecSignMessage(hash).
5
+ * `parents` = hashes of the newest records known when the record was created (causal frontier), which
6
+ * gives a partial order without needing a single writer — suited to many independent peers.
7
+ *
8
+ * Import compatibility: blocks from the reference prototype's ledger.jsonl (linear HMAC chain written by
9
+ * Python) are re-hashed with `pythonJson` so their original `hash` values are preserved and the linear
10
+ * chain can still be verified.
11
+ */
12
+ import { DatabaseSync } from 'node:sqlite';
13
+ import { mkdirSync, existsSync, readFileSync } from 'node:fs';
14
+ import { dirname } from 'node:path';
15
+ import { createHmac } from 'node:crypto';
16
+ import { canonicalJson, pythonJson, sha256Hex } from './canonical.js';
17
+ import { signMessage, verifyMessage } from './identity.js';
18
+ /** Secret used by the reference Python prototype for its HMAC "signature" mock. */
19
+ const PROTOTYPE_SECRET = 'x402-demo-facilitator';
20
+ const PROTOTYPE_AUTHOR = 'prototype:kimminhyun-ai';
21
+ export function recordHash(kind, body, author, ts, parents) {
22
+ return sha256Hex(canonicalJson({ kind, body, author, ts, parents }));
23
+ }
24
+ /**
25
+ * A record this ledger will never accept, however often it is offered — a hash that does not match its body, a
26
+ * signature that is not its author's.
27
+ *
28
+ * The distinction matters to whoever is feeding records in: a refusal is final, so a sync may pass over it, while
29
+ * anything else (a busy database, a write that threw part-way) is this node's problem and the record must be
30
+ * offered again rather than skipped for ever.
31
+ */
32
+ export class RecordRefused extends Error {
33
+ refused = true;
34
+ constructor(message) { super(message); this.name = 'RecordRefused'; }
35
+ }
36
+ /** Is this the ledger saying "never", rather than "not now"? */
37
+ export function isRecordRefusal(e) {
38
+ return !!e && typeof e === 'object' && e.refused === true;
39
+ }
40
+ export class LocalLedger {
41
+ path;
42
+ identity;
43
+ events;
44
+ network;
45
+ kind = 'local';
46
+ db;
47
+ constructor(path, identity, events = {}, network = 'local') {
48
+ this.path = path;
49
+ this.identity = identity;
50
+ this.events = events;
51
+ this.network = network;
52
+ }
53
+ async init() {
54
+ if (this.path !== ':memory:')
55
+ mkdirSync(dirname(this.path), { recursive: true });
56
+ this.db = new DatabaseSync(this.path);
57
+ this.db.exec(`
58
+ PRAGMA journal_mode = WAL;
59
+ CREATE TABLE IF NOT EXISTS records (
60
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
61
+ hash TEXT NOT NULL UNIQUE,
62
+ kind TEXT NOT NULL,
63
+ author TEXT NOT NULL,
64
+ ts REAL NOT NULL,
65
+ parents TEXT NOT NULL,
66
+ body TEXT NOT NULL,
67
+ sig TEXT NOT NULL,
68
+ legacy INTEGER NOT NULL DEFAULT 0,
69
+ received_at REAL NOT NULL
70
+ );
71
+ CREATE INDEX IF NOT EXISTS idx_records_kind ON records(kind);
72
+ CREATE INDEX IF NOT EXISTS idx_records_ts ON records(ts);
73
+ CREATE INDEX IF NOT EXISTS idx_records_recv ON records(received_at);
74
+ `);
75
+ }
76
+ async close() { this.db.close(); }
77
+ async info() {
78
+ const row = this.db.prepare('SELECT COUNT(*) AS n, MAX(seq) AS h FROM records').get();
79
+ const head = this.db.prepare('SELECT hash FROM records ORDER BY seq DESC LIMIT 1').get();
80
+ return { kind: 'local', network: this.network, records: row.n, height: row.h ?? 0, head: head?.hash };
81
+ }
82
+ frontier(limit = 4) {
83
+ const rows = this.db.prepare('SELECT hash FROM records ORDER BY seq DESC LIMIT ?').all(limit);
84
+ return rows.map((r) => r.hash);
85
+ }
86
+ async append(kind, body) {
87
+ const ts = Date.now();
88
+ const parents = this.frontier();
89
+ const hash = recordHash(kind, body, this.identity.address, ts, parents);
90
+ const sig = signMessage(hash, this.identity.privateKey);
91
+ const rec = { hash, kind, body, author: this.identity.address, ts, parents, sig };
92
+ this.insert(rec, false);
93
+ this.events.onRecord?.(rec);
94
+ return rec;
95
+ }
96
+ async ingest(record) {
97
+ if (this.has(record.hash))
98
+ return false;
99
+ if (!LocalLedger.validate(record))
100
+ throw new RecordRefused(`invalid record ${record.hash}`);
101
+ this.insert(record, record.author.startsWith('prototype:'));
102
+ this.events.onRecord?.(record);
103
+ return true;
104
+ }
105
+ static validate(record) {
106
+ if (record.author.startsWith('prototype:'))
107
+ return LocalLedger.validateLegacy(record);
108
+ const expect = recordHash(record.kind, record.body, record.author, record.ts, record.parents);
109
+ if (expect !== record.hash)
110
+ return false;
111
+ return verifyMessage(record.hash, record.sig, record.author);
112
+ }
113
+ /** Legacy prototype block: {i,t,kind,body,prev,hash,sig(HMAC)} mapped into a record. */
114
+ static validateLegacy(record) {
115
+ const legacy = record.body.__legacy;
116
+ if (!legacy)
117
+ return false;
118
+ const { __legacy, ...body } = record.body;
119
+ const raw = pythonJson({ i: legacy.i, t: legacy.t, kind: record.kind, body, prev: legacy.prev });
120
+ if (sha256Hex(raw) !== record.hash)
121
+ return false;
122
+ const sig = createHmac('sha256', PROTOTYPE_SECRET).update(record.hash).digest('hex');
123
+ return sig === record.sig;
124
+ }
125
+ has(hash) {
126
+ return !!this.db.prepare('SELECT 1 FROM records WHERE hash = ?').get(hash);
127
+ }
128
+ insert(rec, legacy) {
129
+ this.db.prepare('INSERT INTO records (hash, kind, author, ts, parents, body, sig, legacy, received_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)').run(rec.hash, rec.kind, rec.author, rec.ts, JSON.stringify(rec.parents), JSON.stringify(rec.body), rec.sig, legacy ? 1 : 0, Date.now());
130
+ }
131
+ rowToRecord(r) {
132
+ return {
133
+ hash: r.hash,
134
+ kind: r.kind,
135
+ author: r.author,
136
+ ts: r.ts,
137
+ parents: JSON.parse(r.parents),
138
+ body: JSON.parse(r.body),
139
+ sig: r.sig,
140
+ };
141
+ }
142
+ async list(opts = {}) {
143
+ const where = [];
144
+ const args = [];
145
+ if (opts.since !== undefined) {
146
+ where.push('received_at > ?');
147
+ args.push(opts.since);
148
+ }
149
+ if (opts.kind) {
150
+ where.push('kind = ?');
151
+ args.push(opts.kind);
152
+ }
153
+ const sql = `SELECT * FROM records ${where.length ? 'WHERE ' + where.join(' AND ') : ''} ORDER BY seq ASC ${opts.limit ? 'LIMIT ' + Number(opts.limit) : ''}`;
154
+ return this.db.prepare(sql).all(...args).map((r) => this.rowToRecord(r));
155
+ }
156
+ async get(hash) {
157
+ const r = this.db.prepare('SELECT * FROM records WHERE hash = ?').get(hash);
158
+ return r ? this.rowToRecord(r) : null;
159
+ }
160
+ /** Records received after `since` (peer-local receive clock) plus the cursor to continue from. */
161
+ async sync(since = 0, limit = 500) {
162
+ const rows = this.db.prepare('SELECT * FROM records WHERE received_at > ? ORDER BY received_at ASC, seq ASC LIMIT ?').all(since, limit);
163
+ const records = rows.map((r) => this.rowToRecord(r));
164
+ const cursor = rows.length ? rows[rows.length - 1].received_at : since;
165
+ return { records, cursor };
166
+ }
167
+ async hashes(since = 0) {
168
+ return this.db.prepare('SELECT hash FROM records WHERE received_at > ? ORDER BY seq').all(since).map((r) => r.hash);
169
+ }
170
+ async byKind(kind, filter) {
171
+ const recs = (await this.list({ kind }));
172
+ return filter ? recs.filter((r) => filter(r.body)) : recs;
173
+ }
174
+ anchors() { return this.byKind('anchor'); }
175
+ attestations(patchId) { return this.byKind('attest', patchId ? (b) => b.patch_id === patchId : undefined); }
176
+ settlements(patchId) { return this.byKind('settle', patchId ? (b) => b.patch_id === patchId : undefined); }
177
+ challenges(patchId) { return this.byKind('challenge', patchId ? (b) => b.patch_id === patchId : undefined); }
178
+ disputes(patchId) { return this.byKind('dispute', patchId ? (b) => b.patch_id === patchId : undefined); }
179
+ branches() { return this.byKind('branch'); }
180
+ nodes() { return this.byKind('node'); }
181
+ supersedes() { return this.byKind('supersede'); }
182
+ subscriptions() { return this.byKind('subscribe'); }
183
+ async verify() {
184
+ const errors = [];
185
+ const all = await this.list();
186
+ // legacy linear chain check
187
+ let prev = '0'.repeat(64);
188
+ for (const r of all) {
189
+ if (!LocalLedger.validate(r))
190
+ errors.push(`bad hash/sig: ${r.hash}`);
191
+ const legacy = r.body.__legacy;
192
+ if (legacy) {
193
+ if (legacy.prev !== prev)
194
+ errors.push(`legacy chain broken at ${r.hash}`);
195
+ prev = r.hash;
196
+ }
197
+ }
198
+ return { valid: errors.length === 0, checked: all.length, errors };
199
+ }
200
+ /**
201
+ * Import the reference prototype's ledger.jsonl (Python HMAC chain). Blocks become records whose
202
+ * `hash` is the original block hash; their Python-shaped bodies are normalised onto our schema by the
203
+ * caller (see node/seed.ts) — here we only preserve them verbatim so `verify()` can re-check the chain.
204
+ */
205
+ async importPrototypeLedger(file) {
206
+ if (!existsSync(file))
207
+ return 0;
208
+ let n = 0;
209
+ for (const line of readFileSync(file, 'utf8').split('\n')) {
210
+ if (!line.trim())
211
+ continue;
212
+ const blk = JSON.parse(line);
213
+ const kind = (blk.kind === 'settle' || blk.kind === 'attest' || blk.kind === 'anchor') ? blk.kind : 'anchor';
214
+ const rec = {
215
+ hash: blk.hash,
216
+ kind,
217
+ body: { ...blk.body, __legacy: { i: blk.i, t: blk.t, prev: blk.prev } },
218
+ author: PROTOTYPE_AUTHOR,
219
+ ts: Math.round(blk.t * 1000),
220
+ parents: blk.prev === '0'.repeat(64) ? [] : [blk.prev],
221
+ sig: blk.sig,
222
+ };
223
+ if (await this.ingest(rec))
224
+ n++;
225
+ }
226
+ return n;
227
+ }
228
+ }
229
+ //# sourceMappingURL=local-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-ledger.js","sourceRoot":"","sources":["../src/local-ledger.ts"],"names":[],"mappings":"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"}
package/dist/npz.d.ts ADDED
@@ -0,0 +1,107 @@
1
+ export interface NpyHeader {
2
+ descr: string;
3
+ fortranOrder: boolean;
4
+ shape: number[];
5
+ dataOffset: number;
6
+ }
7
+ export declare function parseNpyHeader(buf: Buffer): NpyHeader;
8
+ export interface NpzInfo {
9
+ members: {
10
+ name: string;
11
+ descr: string;
12
+ shape: number[];
13
+ bytes: number;
14
+ }[];
15
+ rows: number;
16
+ rowDim: number;
17
+ }
18
+ /** Inspect an .npz without loading array bodies (except headers). */
19
+ export declare function inspectNpz(path: string): NpzInfo;
20
+ /** Load the int64 address array as BigInt64Array (copy). */
21
+ export declare function readNpzAddrs(path: string): BigInt64Array;
22
+ /** Sorted, de-duplicated address set. */
23
+ export declare function addressSet(addrs: BigInt64Array): BigInt64Array;
24
+ /** |A ∩ B| for two sorted address sets (도 6 conflict test). */
25
+ export declare function intersectionCount(a: BigInt64Array, b: BigInt64Array): number;
26
+ /** Bottom-k MinHash-style sketch of an address set for cheap remote pre-checks. */
27
+ export declare function addressSketch(addrs: BigInt64Array, k?: number): number[];
28
+ /** Estimated Jaccard similarity from two bottom-k sketches. */
29
+ export declare function sketchJaccard(a: number[], b: number[]): number;
30
+ /** Read one array member of an .npz (header + raw little-endian body). Used by the teach stub to copy fixture rows. */
31
+ export declare function readNpzMember(path: string, name: string): {
32
+ header: NpyHeader;
33
+ body: Buffer;
34
+ };
35
+ export interface NpzMemberSpec {
36
+ name: string;
37
+ descr: string;
38
+ shape: number[];
39
+ body: Buffer;
40
+ }
41
+ /**
42
+ * Write a minimal .npz (ZIP_STORED members, npy v1) — enough for `inspectNpz` / `readNpzAddrs` / numpy.load.
43
+ * Only the teach stub backend uses it (a valid 1-row knowledge file when no fixture is available).
44
+ */
45
+ export declare function writeNpz(path: string, members: NpzMemberSpec[]): void;
46
+ /**
47
+ * Row-level agreement between two knowledge files (§9 step 2, and the evidence behind "these two really do
48
+ * disagree"): over the addresses both files touch, how many hold bf16-identical `after` values.
49
+ *
50
+ * bf16 is the comparison unit because that is what the table stores (patch_hook.py:98) — two files whose float32
51
+ * `after` differ in the dropped 16 bits are the same row as far as the model is concerned.
52
+ */
53
+ export declare function valuesEqualCount(pathA: string, pathB: string): {
54
+ shared: number;
55
+ equal: number;
56
+ differ: number;
57
+ dim: number;
58
+ };
59
+ /**
60
+ * Row-level report for a MERGE of two knowledge files (design §9 step 2). Where `valuesEqualCount` answers "do these
61
+ * two disagree", this answers the four numbers SC-14 puts on the screen — `{ra} only in A · {rb} only in B · {shared}
62
+ * written by both ({dis} disagree)` — plus the two facts that decide whether a merge can be done without training:
63
+ *
64
+ * - `disagree`: shared addresses whose `after` differs in bf16 (the unit the table stores).
65
+ * - `opposing`: shared addresses where BOTH files moved the row away from their own `before` and landed on different
66
+ * values. A disagreement where only one file wrote the row is a stacking order question; an opposing one cannot be
67
+ * resolved by order at all, and is the honest count behind "these two really cannot just be combined".
68
+ * - `before_differs`: shared addresses whose `before` differs — the two files disagree about what was underneath
69
+ * them, so a stand-alone union of them has no single value to write as `before` (a delta over a stack, merged with
70
+ * a file built on the bare model, is the usual cause).
71
+ */
72
+ export interface NpzCompare {
73
+ a_rows: number;
74
+ b_rows: number;
75
+ a_only: number;
76
+ b_only: number;
77
+ shared: number;
78
+ equal: number;
79
+ disagree: number;
80
+ opposing: number;
81
+ before_differs: number;
82
+ dim: number;
83
+ }
84
+ export declare function compareNpz(pathA: string, pathB: string): NpzCompare;
85
+ /** Why a union of two files cannot be written (design §9 T0). */
86
+ export type UnionRefusal = 'rows_disagree' | 'before_differs' | 'dim_mismatch';
87
+ export interface UnionResult {
88
+ rows: number;
89
+ a_rows: number;
90
+ b_rows: number;
91
+ shared: number;
92
+ pre_state_sha256: string;
93
+ dim: number;
94
+ }
95
+ /**
96
+ * **T0 “Just combine”** (design §9 step 3): the row UNION of two knowledge files, written as a new .npz — no training,
97
+ * no GPU, seconds.
98
+ *
99
+ * It is allowed only when the two files cannot contradict each other on the model: either their address sets are
100
+ * disjoint, or every shared address holds a bf16-identical `after` AND a bf16-identical `before`. Anything else throws
101
+ * — **nothing is averaged and nothing is added** (design §9 “Forbidden”, F8): a row two files disagree about has to be
102
+ * retrained (T1) or rebuilt (T2), because a value neither file measured is not knowledge.
103
+ *
104
+ * `extra` members (a job marker, `meta`) are written beside `addrs`/`before`/`after` exactly as given.
105
+ */
106
+ export declare function unionNpz(dest: string, pathA: string, pathB: string, extra?: NpzMemberSpec[]): UnionResult;
107
+ //# sourceMappingURL=npz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npz.d.ts","sourceRoot":"","sources":["../src/npz.ts"],"names":[],"mappings":"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"}