@ceccec/millennium-solutions 9.7.6 → 9.8.3

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 (59) hide show
  1. package/README.md +299 -107
  2. package/dist/data/baked/answer_gate.json +1 -0
  3. package/dist/data/baked/answer_verify_arith.json +1 -0
  4. package/dist/data/baked/answer_verify_arxiv.json +1 -0
  5. package/dist/data/baked/anti_fake.json +1 -0
  6. package/dist/data/baked/api_gates.json +1 -0
  7. package/dist/data/baked/apis_guru_cross.json +1 -0
  8. package/dist/data/baked/apis_guru_gaps.json +1 -0
  9. package/dist/data/baked/apis_theorems.json +1 -0
  10. package/dist/data/baked/coils.json +1 -0
  11. package/dist/data/baked/constants_check.json +1 -0
  12. package/dist/data/baked/contradictions.json +1 -0
  13. package/dist/data/baked/discover.json +1 -0
  14. package/dist/data/baked/discoveries.json +1 -0
  15. package/dist/data/baked/entanglements.json +1 -0
  16. package/dist/data/baked/evidence.json +1 -0
  17. package/dist/data/baked/hexbit_route.json +1 -0
  18. package/dist/data/baked/index.json +41 -0
  19. package/dist/data/baked/leads.json +1 -0
  20. package/dist/data/baked/leaks.json +1 -0
  21. package/dist/data/baked/memory_check.json +1 -0
  22. package/dist/data/baked/memory_derive.json +1 -0
  23. package/dist/data/baked/metrics_face.json +1 -0
  24. package/dist/data/baked/package_gates.json +1 -0
  25. package/dist/data/baked/prefix_check.json +1 -0
  26. package/dist/data/baked/prose_check.json +1 -0
  27. package/dist/data/baked/qpu_court_local.json +1 -0
  28. package/dist/data/baked/qpu_families.json +1 -0
  29. package/dist/data/baked/recompute.json +1 -0
  30. package/dist/data/baked/session_report.json +1 -0
  31. package/dist/data/baked/theorem_only.json +1 -0
  32. package/dist/data/baked/trinity.json +1 -0
  33. package/dist/data/discovered.json +149408 -0
  34. package/dist/data/formulas.jsonld +470143 -0
  35. package/dist/mcp.bin.d.ts +2 -0
  36. package/dist/mcp.bin.js +80 -0
  37. package/dist/src/0/index.d.ts +1 -0
  38. package/dist/src/0/index.js +7 -8
  39. package/dist/src/face/index.d.ts +41 -0
  40. package/dist/src/face/index.js +32 -0
  41. package/dist/src/factor/index.d.ts +58 -0
  42. package/dist/src/factor/index.js +209 -0
  43. package/dist/src/factor/verify.d.ts +18 -0
  44. package/dist/src/factor/verify.js +28 -0
  45. package/dist/src/handle/index.d.ts +9 -0
  46. package/dist/src/handle/index.js +10 -0
  47. package/dist/src/mcp/index.d.ts +4199 -0
  48. package/dist/src/mcp/index.js +249 -0
  49. package/dist/src/mcp/serve.d.ts +100 -0
  50. package/dist/src/mcp/serve.js +282 -0
  51. package/dist/src/mcp/suites.d.ts +1 -0
  52. package/dist/src/mcp/suites.js +14 -0
  53. package/dist/src/mirror/index.d.ts +18 -0
  54. package/dist/src/mirror/index.js +37 -0
  55. package/dist/src/policy/index.d.ts +8 -0
  56. package/dist/src/policy/index.js +23 -0
  57. package/dist/src/the/rosetta/index.d.ts +3 -0
  58. package/dist/src/the/rosetta/index.js +25 -0
  59. package/package.json +55 -8
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from 'node:readline';
3
+ import { readFileSync, existsSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, join } from 'node:path';
6
+ import { run, served, withLedger, withFormulas, withBake } from './src/mcp/serve.js';
7
+ const here = dirname(fileURLToPath(import.meta.url));
8
+ for (const p of [join(here, 'data', 'discovered.json'), join(here, '..', 'src', 'proof', 'discovered.json')]) {
9
+ if (!existsSync(p))
10
+ continue;
11
+ try {
12
+ withLedger(JSON.parse(readFileSync(p, 'utf8')));
13
+ break;
14
+ }
15
+ catch { }
16
+ }
17
+ for (const p of [join(here, 'data', 'formulas.jsonld'), join(here, '..', 'public', 'formulas.jsonld')]) {
18
+ if (!existsSync(p))
19
+ continue;
20
+ try {
21
+ const j = JSON.parse(readFileSync(p, 'utf8'));
22
+ const rows = (j.itemListElement ?? []).map((e) => {
23
+ const i = (e.item ?? e);
24
+ return { name: i.name, statement: i.description, key: i.identifier, source: i.source, wing: i.wing, proof: i.proof };
25
+ }).filter((r) => r.name);
26
+ if (rows.length) {
27
+ withFormulas(rows);
28
+ break;
29
+ }
30
+ }
31
+ catch { }
32
+ }
33
+ for (const dir of [join(here, 'data', 'baked')]) {
34
+ const idx = join(dir, 'index.json');
35
+ if (!existsSync(idx))
36
+ continue;
37
+ try {
38
+ const j = JSON.parse(readFileSync(idx, 'utf8'));
39
+ const answers = {};
40
+ for (const n of j.baked) {
41
+ const p = join(dir, n + '.json');
42
+ if (existsSync(p))
43
+ answers[n] = JSON.parse(readFileSync(p, 'utf8')).answer;
44
+ }
45
+ withBake({ stamp: j.stamp, answers, notBaked: j.notBaked });
46
+ break;
47
+ }
48
+ catch { }
49
+ }
50
+ const send = (m) => process.stdout.write(JSON.stringify(m) + '\n');
51
+ const rl = createInterface({ input: process.stdin });
52
+ rl.on('line', (line) => {
53
+ if (!line.trim())
54
+ return;
55
+ let id = null;
56
+ try {
57
+ const req = JSON.parse(line);
58
+ id = req.id ?? null;
59
+ const ok = (result) => send({ jsonrpc: '2.0', id, result });
60
+ if (req.method === 'initialize') {
61
+ return ok({ protocolVersion: '2024-11-05', capabilities: { tools: {} },
62
+ serverInfo: { name: 'millennium-solutions (self-sufficient entry)', version: 'from the published package' } });
63
+ }
64
+ if (req.method === 'tools/list') {
65
+ return ok({ tools: [
66
+ { name: 'list_tools', description: 'What this entry serves, and what each tool it does not serve needs instead.', inputSchema: { type: 'object', properties: { name: { type: 'string' } } } },
67
+ { name: 'call_tool', description: 'Call one of the served tools.', inputSchema: { type: 'object', properties: { name: { type: 'string', enum: served() }, arguments: { type: 'object' } }, required: ['name'] } },
68
+ ] });
69
+ }
70
+ if (req.method === 'tools/call') {
71
+ return ok({ content: [{ type: 'text', text: run(String(req.params?.name ?? ''), req.params?.arguments ?? {}) }] });
72
+ }
73
+ if (req.method?.startsWith('notifications/'))
74
+ return;
75
+ send({ jsonrpc: '2.0', id, error: { code: -32601, message: `method not found: ${String(req.method)}` } });
76
+ }
77
+ catch (e) {
78
+ send({ jsonrpc: '2.0', id, error: { code: -32603, message: e instanceof Error ? e.message : String(e) } });
79
+ }
80
+ });
@@ -1,3 +1,4 @@
1
+ export declare const SEEDS: readonly number[];
1
2
  export declare function toUuid(seed: string): string;
2
3
  export declare function strictUuidna(value: unknown): string;
3
4
  export declare function merge(a: string, b: string): string;
@@ -1,7 +1,7 @@
1
1
  const BYTE_MASK = 0xff;
2
- const MASK_32 = 0xffffffffn;
3
2
  function mul32(a, b) {
4
- return Number((BigInt(a >>> 0) * BigInt(b >>> 0)) & MASK_32);
3
+ const al = a & 0xffff, ah = a >>> 16, bl = b & 0xffff, bh = b >>> 16;
4
+ return (al * bl + ((ah * bl + al * bh) & 0xffff) * 0x10000) >>> 0;
5
5
  }
6
6
  function hash32(input, seed) {
7
7
  let h = (0x811c9dc5 ^ seed) >>> 0;
@@ -18,13 +18,9 @@ const HEX_BYTE = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2
18
18
  function hexByte(value) {
19
19
  return HEX_BYTE[value & BYTE_MASK];
20
20
  }
21
+ export const SEEDS = [0, 0x9e3779b9, 0x243f6a88, 0xb7e15162];
21
22
  function bytesFromSeed(seed) {
22
- const words = [
23
- hash32(seed, 0),
24
- hash32(seed, 0x9e3779b9),
25
- hash32(seed, 0x243f6a88),
26
- hash32(seed, 0xb7e15162),
27
- ];
23
+ const words = SEEDS.map((s) => hash32(seed, s));
28
24
  return words.flatMap((word) => [
29
25
  (word >>> (8 * 3)) & BYTE_MASK,
30
26
  (word >>> 16) & BYTE_MASK,
@@ -33,10 +29,13 @@ function bytesFromSeed(seed) {
33
29
  ]);
34
30
  }
35
31
  const _uuidCache = new Map();
32
+ const CACHE_LIMIT = 1 << 14;
36
33
  export function toUuid(seed) {
37
34
  const cached = _uuidCache.get(seed);
38
35
  if (cached !== undefined)
39
36
  return cached;
37
+ if (_uuidCache.size >= CACHE_LIMIT)
38
+ _uuidCache.clear();
40
39
  const bytes = bytesFromSeed(seed);
41
40
  bytes[6] = (bytes[6] & 0x0f) | 0x80;
42
41
  bytes[8] = (bytes[8] & 0x3f) | 0x80;
@@ -0,0 +1,41 @@
1
+ export type Metric = {
2
+ key: string;
3
+ claim: string;
4
+ value: string;
5
+ command: string;
6
+ receipt: string;
7
+ };
8
+ export type Face = {
9
+ repo: string;
10
+ definition: string;
11
+ protocol?: unknown;
12
+ generatedFrom?: string;
13
+ specWitness?: {
14
+ seed: string;
15
+ receipt: string;
16
+ };
17
+ rows: Metric[];
18
+ root: string;
19
+ };
20
+ export declare const PROTOCOL: {
21
+ readonly id: 'millennium-solutions/metric-face/2';
22
+ readonly covers: readonly ['key', 'claim', 'value', 'command'];
23
+ readonly chained: false;
24
+ readonly receipt: 'toUuid(key + LF + claim + LF + value + LF + command)';
25
+ readonly merge: "toUuid(utf8(a + ':' + b)) — COLON U+003A";
26
+ readonly address: string;
27
+ readonly specWitness: 'see the specWitness field on the face itself: the verbatim seed of row 0 and its receipt';
28
+ readonly root: string;
29
+ readonly orderInvariant: true;
30
+ };
31
+ export declare const protocolId: (p: unknown) => string;
32
+ export declare const receiptOf: (key: string, claim: string, value: string, command?: string) => string;
33
+ export declare const rootOf: (rows: Metric[]) => string;
34
+ export type Verdict = 'intact' | 'altered' | 'different-convention';
35
+ export declare function checkFace(f: Face): {
36
+ verdict: Verdict;
37
+ ok: boolean;
38
+ altered: string[];
39
+ root: string;
40
+ failingGates: string[];
41
+ };
@@ -0,0 +1,32 @@
1
+ import { toUuid, merkleFold } from '../0/index.js';
2
+ export const PROTOCOL = {
3
+ id: 'millennium-solutions/metric-face/2',
4
+ covers: ['key', 'claim', 'value', 'command'],
5
+ chained: false,
6
+ receipt: 'toUuid(key + LF + claim + LF + value + LF + command)',
7
+ merge: "toUuid(utf8(a + ':' + b)) — COLON U+003A",
8
+ address: 'uuidv8 shaped per RFC 9562 §5.8 (version nibble 8, variant 10x) over FNV-1a — NOT SHA-2: '
9
+ + 'four 32-bit FNV-1a passes over the UTF-16 code units, each starting at the FNV OFFSET BASIS 0x811c9dc5 '
10
+ + 'XOR the pass seed — seeds 0, 0x9e3779b9, 0x243f6a88, 0xb7e15162, so h begins at (0x811c9dc5 ^ seed) and '
11
+ + 'NOT at the seed itself, which is the one line an implementer cannot guess. '
12
+ + 'with an xor-shift-13 per code unit and a two-round murmur finalizer (0x85ebca6b, 0xc2b2ae35, then >>> 16), '
13
+ + 'concatenated big-endian to 16 octets. Non-cryptographic: integrity against accident, not against an '
14
+ + 'adversary.',
15
+ specWitness: 'see the specWitness field on the face itself: the verbatim seed of row 0 and its receipt',
16
+ root: 'merkleFold: leaves sorted lexicographically, then pairwise merge up the tree; an odd element '
17
+ + "carries up unchanged; zero rows fold to toUuid('empty-mind')",
18
+ orderInvariant: true,
19
+ };
20
+ export const protocolId = (p) => typeof p === 'string' ? p : (p && typeof p === 'object' && 'id' in p ? String(p.id) : '(none declared)');
21
+ export const receiptOf = (key, claim, value, command = '') => toUuid(key + '\n' + claim + '\n' + value + '\n' + command);
22
+ export const rootOf = (rows) => merkleFold(rows.map((r) => r.receipt));
23
+ export function checkFace(f) {
24
+ const altered = f.rows.filter((r) => receiptOf(r.key, r.claim, r.value, r.command) !== r.receipt).map((r) => r.key);
25
+ const root = rootOf(f.rows);
26
+ const rootMatches = root === f.root;
27
+ const wholesale = f.rows.length > 1 && altered.length === f.rows.length && !rootMatches;
28
+ const stated = f.protocol !== undefined && protocolId(f.protocol) !== PROTOCOL.id;
29
+ const verdict = altered.length === 0 && rootMatches ? 'intact'
30
+ : (wholesale || stated) ? 'different-convention' : 'altered';
31
+ return { verdict, ok: verdict === 'intact', altered, root, failingGates: f.rows.filter((r) => r.value === 'FAIL').map((r) => r.key) };
32
+ }
@@ -0,0 +1,58 @@
1
+ export declare const TRIAL_BOUND = 1000000n;
2
+ export declare const RHO_BUDGET = 500000;
3
+ export type Factorisation = {
4
+ status: 'FACTORED';
5
+ factors: string[];
6
+ primality: 'every factor proved prime by trial division or by the deterministic test';
7
+ } | {
8
+ status: 'PARTIAL';
9
+ factors: string[];
10
+ cofactor: string;
11
+ cofactorDigits: number;
12
+ cofactorPrimality: 'probable prime by Miller–Rabin, not proved' | 'composite (a witness was found)' | 'composite (split into open pieces, each above the trial bound)';
13
+ blocking: string;
14
+ } | {
15
+ status: 'REFUSED';
16
+ why: string;
17
+ };
18
+ export declare const millerRabin: (n: bigint) => 'PRIME' | 'COMPOSITE';
19
+ export declare const parseInteger: (input: string) => string | null;
20
+ export declare const factor: (input: string) => Factorisation;
21
+ export declare const rho: (n: bigint, budget?: number) => bigint | null;
22
+ export declare const RAYS: readonly number[];
23
+ export declare const renderDigits: (n: bigint, k: number) => number[];
24
+ export declare const parseDigits: (ds: readonly number[], k: number) => bigint;
25
+ export declare const mirrorDigits: (digits: string) => string | null;
26
+ export type WitnessState = {
27
+ coin: 'integer' | 'mirror';
28
+ ray: number;
29
+ radix: number;
30
+ digits: number;
31
+ roundTrip: boolean;
32
+ };
33
+ export type Witness = {
34
+ register: {
35
+ coins: 2;
36
+ rays: 7;
37
+ faces: 14;
38
+ source: 'qpu.lean — the served register, faces = coins × rays';
39
+ };
40
+ coins: {
41
+ integer: Factorisation & {
42
+ n: string;
43
+ };
44
+ mirror: (Factorisation & {
45
+ n: string;
46
+ }) | {
47
+ status: 'UNDEFINED';
48
+ why: string;
49
+ };
50
+ };
51
+ states: WitnessState[];
52
+ agree: boolean;
53
+ failures: string[];
54
+ };
55
+ export declare const factorWitnessed: (input: string) => (Factorisation & {
56
+ n?: string;
57
+ witness?: Witness;
58
+ });
@@ -0,0 +1,209 @@
1
+ export const TRIAL_BOUND = 1000000n;
2
+ export const RHO_BUDGET = 500_000;
3
+ const DETERMINISTIC_LIMIT = 3317044064679887385961981n;
4
+ const modPow = (base, exp, mod) => {
5
+ let result = 1n;
6
+ let b = base % mod;
7
+ let e = exp;
8
+ while (e > 0n) {
9
+ if (e & 1n)
10
+ result = (result * b) % mod;
11
+ b = (b * b) % mod;
12
+ e >>= 1n;
13
+ }
14
+ return result;
15
+ };
16
+ const BASES = [2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n];
17
+ export const millerRabin = (n) => {
18
+ if (n < 2n)
19
+ return 'COMPOSITE';
20
+ for (const p of BASES) {
21
+ if (n === p)
22
+ return 'PRIME';
23
+ if (n % p === 0n)
24
+ return 'COMPOSITE';
25
+ }
26
+ let d = n - 1n;
27
+ let r = 0;
28
+ while ((d & 1n) === 0n) {
29
+ d >>= 1n;
30
+ r++;
31
+ }
32
+ for (const a of BASES) {
33
+ let x = modPow(a, d, n);
34
+ if (x === 1n || x === n - 1n)
35
+ continue;
36
+ let composite = true;
37
+ for (let i = 1; i < r; i++) {
38
+ x = (x * x) % n;
39
+ if (x === n - 1n) {
40
+ composite = false;
41
+ break;
42
+ }
43
+ }
44
+ if (composite)
45
+ return 'COMPOSITE';
46
+ }
47
+ return 'PRIME';
48
+ };
49
+ export const parseInteger = (input) => {
50
+ const t = input.trim().replace(/_/g, '');
51
+ if (/^0b[01]+$/i.test(t))
52
+ return BigInt(t).toString();
53
+ if (/^0x[0-9a-f]+$/i.test(t))
54
+ return BigInt(t).toString();
55
+ if (/^\d+$/.test(t))
56
+ return t;
57
+ return null;
58
+ };
59
+ export const factor = (input) => {
60
+ const digits = parseInteger(input);
61
+ if (digits === null)
62
+ return { status: 'REFUSED', why: 'the input is not a non-negative integer in decimal, 0b binary or 0x hex' };
63
+ let n = BigInt(digits);
64
+ if (n < 2n)
65
+ return { status: 'REFUSED', why: `${n} has no factorisation to give` };
66
+ const found = [];
67
+ const divide = (d) => { while (n % d === 0n) {
68
+ found.push(d.toString());
69
+ n /= d;
70
+ } };
71
+ divide(2n);
72
+ let d = 3n;
73
+ for (; d <= TRIAL_BOUND && d * d <= n; d += 2n)
74
+ divide(d);
75
+ if (n === 1n)
76
+ return { status: 'FACTORED', factors: found, primality: 'every factor proved prime by trial division or by the deterministic test' };
77
+ if (d * d > n)
78
+ return { status: 'FACTORED', factors: [...found, n.toString()], primality: 'every factor proved prime by trial division or by the deterministic test' };
79
+ const primes = [];
80
+ const open = [];
81
+ splitWithRho(n, primes, open);
82
+ const all = [...found, ...primes.map((p) => p.toString())];
83
+ if (open.length === 0)
84
+ return { status: 'FACTORED', factors: all, primality: 'every factor proved prime by trial division or by the deterministic test' };
85
+ const cofactor = open.reduce((acc, v) => acc * v, 1n);
86
+ const cofactorPrimality = open.length > 1
87
+ ? 'composite (split into open pieces, each above the trial bound)'
88
+ : millerRabin(cofactor) === 'COMPOSITE' ? 'composite (a witness was found)' : 'probable prime by Miller–Rabin, not proved';
89
+ return { status: 'PARTIAL', factors: all, cofactor: cofactor.toString(), cofactorDigits: cofactor.toString().length, cofactorPrimality,
90
+ blocking: `the cofactor has no factor below ${TRIAL_BOUND} and Pollard rho did not split it within ${RHO_BUDGET} steps; no method in this tree factors it` };
91
+ };
92
+ export const rho = (n, budget = RHO_BUDGET) => {
93
+ if (n % 2n === 0n)
94
+ return 2n;
95
+ const gcd = (a, b) => { while (b) {
96
+ [a, b] = [b, a % b];
97
+ } return a; };
98
+ const diff = (a, b) => (a > b ? a - b : b - a);
99
+ let steps = 0;
100
+ for (let c = 1n; c < 20n; c++) {
101
+ const f = (v) => (v * v + c) % n;
102
+ let y = 2n, x = y, ys = y, g = 1n, q = 1n, r = 1;
103
+ const m = 128;
104
+ while (g === 1n) {
105
+ x = y;
106
+ for (let i = 0; i < r; i++)
107
+ y = f(y);
108
+ let k = 0;
109
+ while (k < r && g === 1n) {
110
+ ys = y;
111
+ for (let i = 0; i < Math.min(m, r - k); i++) {
112
+ y = f(y);
113
+ q = (q * diff(x, y)) % n;
114
+ }
115
+ g = gcd(q, n);
116
+ k += m;
117
+ }
118
+ steps += r;
119
+ r *= 2;
120
+ if (steps > budget)
121
+ return null;
122
+ }
123
+ if (g === n) {
124
+ g = 1n;
125
+ while (g === 1n) {
126
+ ys = f(ys);
127
+ g = gcd(diff(x, ys), n);
128
+ }
129
+ }
130
+ if (g !== n)
131
+ return g;
132
+ }
133
+ return null;
134
+ };
135
+ const splitWithRho = (m, primes, open) => {
136
+ if (m === 1n)
137
+ return;
138
+ const verdict = millerRabin(m);
139
+ if (m < DETERMINISTIC_LIMIT && verdict === 'PRIME') {
140
+ primes.push(m);
141
+ return;
142
+ }
143
+ const d = verdict === 'COMPOSITE' || m >= DETERMINISTIC_LIMIT ? rho(m) : null;
144
+ if (d === null || d === 1n || d === m) {
145
+ open.push(m);
146
+ return;
147
+ }
148
+ splitWithRho(d, primes, open);
149
+ splitWithRho(m / d, primes, open);
150
+ };
151
+ export const RAYS = [1, 2, 3, 4, 5, 6, 7];
152
+ const GLYPHS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
153
+ export const renderDigits = (n, k) => {
154
+ const b = 1n << BigInt(k), out = [];
155
+ let m = n;
156
+ if (m === 0n)
157
+ return [0];
158
+ while (m > 0n) {
159
+ out.unshift(Number(m % b));
160
+ m /= b;
161
+ }
162
+ return out;
163
+ };
164
+ export const parseDigits = (ds, k) => ds.reduce((acc, d) => (acc << BigInt(k)) + BigInt(d), 0n);
165
+ export const mirrorDigits = (digits) => /0/.test(digits) ? null : digits.split('').map((c) => String(10 - Number(c))).join('');
166
+ export const factorWitnessed = (input) => {
167
+ const digits = parseInteger(input);
168
+ const base = factor(input);
169
+ if (digits === null || base.status === 'REFUSED')
170
+ return base;
171
+ const n = BigInt(digits);
172
+ const m = mirrorDigits(digits);
173
+ const states = [];
174
+ const failures = [];
175
+ const coinsOf = m === null ? [['integer', n]] : [['integer', n], ['mirror', BigInt(m)]];
176
+ for (const [coin, v] of coinsOf)
177
+ for (const k of RAYS) {
178
+ const ds = renderDigits(v, k);
179
+ const ok = parseDigits(ds, k) === v && ds.every((d) => d >= 0 && d < (1 << k));
180
+ states.push({ coin, ray: k, radix: 1 << k, digits: ds.length, roundTrip: ok });
181
+ if (!ok)
182
+ failures.push(`${coin} does not survive radix ${1 << k}`);
183
+ }
184
+ const check = (label, r, v) => {
185
+ if (r.status === 'FACTORED') {
186
+ const prod = r.factors.reduce((acc, x) => acc * BigInt(x), 1n);
187
+ if (prod.toString() !== v)
188
+ failures.push(`${label}: the factors do not multiply back`);
189
+ }
190
+ else if (r.status === 'PARTIAL')
191
+ failures.push(`${label}: ${r.cofactorDigits}-digit cofactor left open — ${r.cofactorPrimality}`);
192
+ else
193
+ failures.push(`${label}: ${r.why}`);
194
+ };
195
+ check('integer', base, digits);
196
+ const mirrorFact = m === null
197
+ ? { status: 'UNDEFINED', why: 'a digit is 0, and 10 − 0 is not a digit: the mirror coin is undefined, which is stated rather than counted' }
198
+ : { n: m, ...factor(m) };
199
+ if (mirrorFact.status !== 'UNDEFINED')
200
+ check('mirror', mirrorFact, m);
201
+ return {
202
+ ...base, n: digits,
203
+ witness: {
204
+ register: { coins: 2, rays: 7, faces: 14, source: 'qpu.lean — the served register, faces = coins × rays' },
205
+ coins: { integer: { n: digits, ...base }, mirror: mirrorFact },
206
+ states, agree: failures.length === 0, failures,
207
+ },
208
+ };
209
+ };
@@ -0,0 +1,18 @@
1
+ export type Verification = {
2
+ status: 'VERIFIED';
3
+ n: string;
4
+ factors: string[];
5
+ primality: string;
6
+ why: string;
7
+ } | {
8
+ status: 'PROBABLE';
9
+ n: string;
10
+ factors: string[];
11
+ primality: string;
12
+ why: string;
13
+ } | {
14
+ status: 'REFUSED';
15
+ n: string;
16
+ why: string;
17
+ };
18
+ export declare const verifyFactors: (nIn: string, factorsIn: string[]) => Verification;
@@ -0,0 +1,28 @@
1
+ import { millerRabin, parseInteger } from './index.js';
2
+ const DETERMINISTIC_LIMIT = 3317044064679887385961981n;
3
+ export const verifyFactors = (nIn, factorsIn) => {
4
+ const n = parseInteger(nIn) ?? nIn;
5
+ if (!/^\d+$/.test(n))
6
+ return { status: 'REFUSED', n, why: 'the integer is not a non-negative integer in decimal, 0b binary or 0x hex' };
7
+ if (factorsIn.length === 0)
8
+ return { status: 'REFUSED', n, why: 'no factors were given' };
9
+ const factors = factorsIn.map((f) => parseInteger(f) ?? f);
10
+ if (!factors.every((f) => /^\d+$/.test(f)))
11
+ return { status: 'REFUSED', n, why: 'a factor is not a non-negative integer in decimal, 0b binary or 0x hex' };
12
+ const values = factors.map((f) => BigInt(f));
13
+ if (values.some((v) => v < 2n))
14
+ return { status: 'REFUSED', n, why: 'a factor is below 2, which proves nothing about a factorisation' };
15
+ const product = values.reduce((acc, v) => acc * v, 1n);
16
+ if (product !== BigInt(n))
17
+ return { status: 'REFUSED', n, why: 'the factors do not multiply to the integer' };
18
+ const unproved = values.filter((v) => v >= DETERMINISTIC_LIMIT);
19
+ const bad = values.filter((v) => millerRabin(v) === 'COMPOSITE');
20
+ if (bad.length)
21
+ return { status: 'REFUSED', n, why: `${bad.length} factor(s) are composite, by a witness the test found, so they are not prime factors` };
22
+ const primality = unproved.length === 0
23
+ ? 'every factor proved prime by the deterministic test'
24
+ : `${values.length - unproved.length} factor(s) proved prime; ${unproved.length} factor(s) above 3.3e24 only probably prime`;
25
+ if (unproved.length === 0)
26
+ return { status: 'VERIFIED', n, factors, primality, why: 'the product holds and every factor is proved prime' };
27
+ return { status: 'PROBABLE', n, factors, primality, why: 'the product holds; some factor passed a probabilistic test, which is not a proof' };
28
+ };
@@ -0,0 +1,9 @@
1
+ export declare const HANDLE_HEX = 4;
2
+ export declare const HANDLE_OFFSET = 0;
3
+ export declare const handleOf: (uuid: string) => string;
4
+ export declare const handle: (message: string) => string;
5
+ export declare const carries: (h: string, message: string) => boolean;
6
+ export declare const resolve: (h: string, message: string) => {
7
+ uuid: string;
8
+ carries: boolean;
9
+ };
@@ -0,0 +1,10 @@
1
+ import { toUuid } from '../0/index.js';
2
+ export const HANDLE_HEX = 4;
3
+ export const HANDLE_OFFSET = 0;
4
+ export const handleOf = (uuid) => uuid.replace(/-/g, '').slice(HANDLE_OFFSET, HANDLE_OFFSET + HANDLE_HEX);
5
+ export const handle = (message) => handleOf(toUuid(message));
6
+ export const carries = (h, message) => handle(message) === h.toLowerCase();
7
+ export const resolve = (h, message) => {
8
+ const uuid = toUuid(message);
9
+ return { uuid, carries: handleOf(uuid) === h.toLowerCase() };
10
+ };