@ceccec/millennium-solutions 9.3.3 → 9.3.5
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/README.md +29 -15
- package/dist/mod.core.d.ts +9 -0
- package/dist/mod.core.js +9 -0
- package/dist/src/0/index.d.ts +47 -0
- package/dist/src/0/index.js +189 -0
- package/dist/src/0/ledger.d.ts +1 -0
- package/dist/src/0/ledger.js +25 -0
- package/dist/src/0/trinity-matrix.d.ts +1 -0
- package/dist/src/0/trinity-matrix.js +16 -0
- package/dist/src/5/aspects.d.ts +1 -0
- package/dist/src/5/aspects.js +22 -0
- package/dist/src/5/reflection.d.ts +1 -0
- package/dist/src/5/reflection.js +25 -0
- package/dist/src/7/rosetta.d.ts +1 -0
- package/dist/src/7/rosetta.js +24 -0
- package/dist/src/9/enumeration.d.ts +1 -0
- package/dist/src/9/enumeration.js +14 -0
- package/dist/src/honesty/index.d.ts +16 -0
- package/dist/src/honesty/index.js +69 -0
- package/package.json +27 -10
- package/.zenodo.json +0 -51
- package/ABSTRACT.md +0 -155
- package/ACCOUNTING.md +0 -27
- package/AXIOMS.md +0 -574
- package/CHALLENGES.md +0 -2595
- package/DEPLOY.md +0 -39
- package/DEVELOP.md +0 -34
- package/HEART.md +0 -112
- package/PHYSICS-SCALES.md +0 -80
- package/PRIOR-ART.md +0 -151
- package/PROOF-OF-CONCEPT.md +0 -81
- package/REALISATIONS.md +0 -87
- package/RESEARCH.md +0 -188
- package/RULES.md +0 -57
- package/SEQUENCE-DECODE.md +0 -196
- package/SIGNATURE.md +0 -34
- package/THEOREMS.md +0 -97
- package/WHITEPAPER.md +0 -40
- package/WORKFLOWS.md +0 -47
- package/boundaries.md +0 -23
- package/captain.md +0 -85
- package/compare.md +0 -42
- package/compute.md +0 -543
- package/cryptography.md +0 -55
- package/dashboard.md +0 -50
- package/examples.md +0 -47
- package/folds.md +0 -65
- package/forensic.md +0 -67
- package/guide.md +0 -126
- package/harness.md +0 -20
- package/index.md +0 -217
- package/mod.core.ts +0 -10
- package/nature.md +0 -58
- package/organism.md +0 -30
- package/paper.md +0 -8789
- package/proofs.md +0 -26
- package/quantum.md +0 -40
- package/rights.md +0 -39
- package/solutions.md +0 -28
- package/speedup.md +0 -41
- package/src/0/chacha.ts +0 -3
- package/src/0/crypt.ts +0 -4
- package/src/0/csp.ts +0 -10
- package/src/0/entanglement.ts +0 -31
- package/src/0/fusion.ts +0 -28
- package/src/0/holographic.ts +0 -57
- package/src/0/impossible.ts +0 -30
- package/src/0/imprint.ts +0 -160
- package/src/0/index.ts +0 -263
- package/src/0/ledger.ts +0 -25
- package/src/0/legible.ts +0 -29
- package/src/0/limit.ts +0 -29
- package/src/0/merkle-proof.ts +0 -3
- package/src/0/null-token.ts +0 -24
- package/src/0/sha256.ts +0 -3
- package/src/0/singularity.ts +0 -20
- package/src/0/stream.ts +0 -47
- package/src/0/trinities.ts +0 -37
- package/src/0/trinity-matrix.ts +0 -20
- package/src/0/version-matrix.ts +0 -70
- package/src/1/acceptance.ts +0 -26
- package/src/1/index.ts +0 -80
- package/src/1/paradox.ts +0 -28
- package/src/1/vortex.lean +0 -6
- package/src/2/frequency-scales.ts +0 -28
- package/src/2/iching.ts +0 -34
- package/src/2/index.ts +0 -78
- package/src/2/primes-vortex.ts +0 -12
- package/src/2/quantum.ts +0 -48
- package/src/2/string-scale.ts +0 -14
- package/src/2/vortex.lean +0 -10
- package/src/3/index.ts +0 -63
- package/src/3/pi-bbp.ts +0 -13
- package/src/3/trinity.ts +0 -39
- package/src/3/vortex.lean +0 -7
- package/src/4/git.ts +0 -30
- package/src/4/index.ts +0 -63
- package/src/4/vortex.lean +0 -6
- package/src/5/aspects.ts +0 -27
- package/src/5/center.ts +0 -35
- package/src/5/development.ts +0 -45
- package/src/5/diamond.ts +0 -35
- package/src/5/folds.ts +0 -12
- package/src/5/index.ts +0 -63
- package/src/5/reflection.lean +0 -14
- package/src/5/reflection.ts +0 -14
- package/src/5/vortex.lean +0 -10
- package/src/6/dna.ts +0 -27
- package/src/6/index.ts +0 -63
- package/src/6/vortex.lean +0 -7
- package/src/7/cross.ts +0 -31
- package/src/7/glagolitic.ts +0 -51
- package/src/7/index.ts +0 -67
- package/src/7/language-lens.ts +0 -41
- package/src/7/lens.ts +0 -41
- package/src/7/locale.ts +0 -105
- package/src/7/rbac.ts +0 -31
- package/src/7/rosetta-clay.ts +0 -15
- package/src/7/rosetta.lean +0 -11
- package/src/7/rosetta.ts +0 -11
- package/src/7/string-dimensions.ts +0 -14
- package/src/7/vortex.lean +0 -6
- package/src/8/infinite.ts +0 -26
- package/src/8/merkaba/field.ts +0 -27
- package/src/8/merkaba/geometry.ts +0 -16
- package/src/8/merkaba/touch.ts +0 -26
- package/src/8/nucleus/magic.lean +0 -15
- package/src/8/nucleus/proton-mass-fit.ts +0 -9
- package/src/8/nucleus/proton-mass.lean +0 -10
- package/src/8/nucleus/shell-model-magic.ts +0 -10
- package/src/8/vortex.lean +0 -7
- package/src/9/access.ts +0 -34
- package/src/9/aura-funding.ts +0 -25
- package/src/9/coins.ts +0 -25
- package/src/9/enumeration.ts +0 -13
- package/src/9/funding.ts +0 -85
- package/src/9/security.ts +0 -36
- package/src/9/society.ts +0 -32
- package/src/9/vortex.lean +0 -11
- package/src/api/gates.ts +0 -122
- package/src/api/index.ts +0 -447
- package/src/api/lanes.ts +0 -81
- package/src/claims/index.ts +0 -81
- package/src/demand/queries.json +0 -1764
- package/src/face/index.ts +0 -100
- package/src/from/the/heart/index.ts +0 -11
- package/src/honesty/boundaries.ts +0 -29
- package/src/honesty/index.ts +0 -63
- package/src/html/index.ts +0 -10
- package/src/latex/index.ts +0 -474
- package/src/millennium/index.ts +0 -53
- package/src/play/the/game/index.ts +0 -12
- package/src/proof/README.md +0 -118
- package/src/proof/address.lean +0 -168
- package/src/proof/coin.lean +0 -152
- package/src/proof/covered.json +0 -9
- package/src/proof/demand.lean +0 -160
- package/src/proof/demand2.lean +0 -219
- package/src/proof/demand3.lean +0 -209
- package/src/proof/discovered.json +0 -19530
- package/src/proof/elementary.lean +0 -495
- package/src/proof/energy.lean +0 -329
- package/src/proof/families.lean +0 -740
- package/src/proof/fixtures/axiom-control.lean +0 -39
- package/src/proof/flow.lean +0 -78
- package/src/proof/fnv.lean +0 -127
- package/src/proof/generated-theorems.json +0 -207
- package/src/proof/generated.lean +0 -101
- package/src/proof/imagined.lean +0 -492
- package/src/proof/index.lean +0 -156
- package/src/proof/index.ts +0 -916
- package/src/proof/involution.lean +0 -90
- package/src/proof/ledgerclaims.lean +0 -84
- package/src/proof/light.lean +0 -168
- package/src/proof/mechanical.lean +0 -563
- package/src/proof/merkaba.lean +0 -89
- package/src/proof/merkle.lean +0 -132
- package/src/proof/nim.lean +0 -332
- package/src/proof/novelty.json +0 -751
- package/src/proof/phenomena.lean +0 -90
- package/src/proof/priorart.lean +0 -190
- package/src/proof/quantum.lean +0 -159
- package/src/proof/reach.lean +0 -121
- package/src/proof/recovered.lean +0 -56
- package/src/proof/reversal.lean +0 -402
- package/src/proof/revoked.json +0 -317
- package/src/proof/rights.lean +0 -155
- package/src/proof/sequences.lean +0 -284
- package/src/proof/speed.lean +0 -158
- package/src/proof/split.lean +0 -209
- package/src/proof/theorems.lean +0 -67
- package/src/proof/trial-all.json +0 -16532
- package/src/proof/z9.lean +0 -126
- package/src/proof/z9plus.lean +0 -345
- package/src/proofs.lisp +0 -170
- package/src/prove/emit.ts +0 -115
- package/src/prove/index.ts +0 -143
- package/src/prove/translate.ts +0 -638
- package/src/publication/index.ts +0 -362
- package/src/quantum/field.ts +0 -73
- package/src/quantum/tree.ts +0 -79
- package/src/receipts/1431b4c4-7950-8d7b-88d1-b633219692f8.json +0 -7
- package/src/receipts/171e09c0-4cfd-8ce0-a6ed-cd33d5553da3.json +0 -7
- package/src/receipts/1a1f16c9-3491-8050-b221-e2a362439be4.json +0 -12
- package/src/receipts/1da15f83-83a6-8d04-b1ac-334c2dd6abb3.json +0 -7
- package/src/receipts/375a57ed-ef99-855e-8f34-b77d08010f3c.json +0 -6
- package/src/receipts/3dcbbf9e-0e49-8ba7-921e-17e478dbafaf.json +0 -6
- package/src/receipts/43a24136-5ad9-81ef-97c9-17be1c05bb5f.json +0 -11
- package/src/receipts/4991be51-74ba-8f66-9534-e6dba52fb569.json +0 -10
- package/src/receipts/52375d8f-232b-8c01-9d82-a824ffa7b2b7.json +0 -6
- package/src/receipts/593b546a-36b4-8553-941a-0e03b7053a64.json +0 -7
- package/src/receipts/7f75c989-96c9-8a24-8d0d-7e690861ccb4.json +0 -6
- package/src/receipts/80f80b59-81d8-866d-9a14-f469729d3dc8.json +0 -6
- package/src/receipts/85ac8585-9dc1-8964-9848-ae0f49cc82fb.json +0 -7
- package/src/receipts/85db092e-f2c0-88e5-bf75-61c4a65d84e7.json +0 -7
- package/src/receipts/95bacad3-9e56-8741-b0f8-def2c6ecb050.json +0 -7
- package/src/receipts/a1d33966-7bbd-84ca-902b-49e315af60e0.json +0 -6
- package/src/receipts/b20ced61-24ad-8123-adee-56031ab734dd.json +0 -11
- package/src/receipts/ba0447cd-f489-841a-a70f-a39b18ec2946.json +0 -11
- package/src/receipts/bcddbe66-06cf-8f31-a261-98b836938947.json +0 -7
- package/src/receipts/c1bac0d8-d906-8196-a4f0-3d8270b2e944.json +0 -6
- package/src/receipts/ce851ea3-3cf8-8646-a5d6-c0c6281210fe.json +0 -10
- package/src/receipts/cf43a122-c880-8d86-9e25-6f22f92d6b0a.json +0 -7
- package/src/receipts/daad8cd4-d4db-8dca-9c97-9a838cbce528.json +0 -7
- package/src/receipts/dc8bdb82-599f-8020-9eb2-cb016b408ec1.json +0 -6
- package/src/receipts/df77c265-d1a8-8354-8a9e-769fa5c676e2.json +0 -6
- package/src/receipts/e96686da-a411-8838-a5c8-ee7472bce048.json +0 -10
- package/src/receipts/f073c46f-7b67-83d0-aca5-db11fac4b5ec.json +0 -7
- package/src/receipts/f946d99d-a1c2-89f7-9426-a367c5b04191.json +0 -6
- package/src/receipts/fc069e45-115d-8983-ad25-fb9f735da84b.json +0 -6
- package/src/the/abstract/index.ts +0 -21
- package/src/the/abundance/index.ts +0 -20
- package/src/the/apple/earth/index.ts +0 -23
- package/src/the/apple/earth/navigation/index.ts +0 -28
- package/src/the/apple/earth/truth/index.ts +0 -19
- package/src/the/apple/index.ts +0 -27
- package/src/the/cancer/index.ts +0 -26
- package/src/the/clown/index.ts +0 -25
- package/src/the/creation/index.ts +0 -16
- package/src/the/crystal/index.ts +0 -23
- package/src/the/domain/index.ts +0 -16
- package/src/the/game/index.ts +0 -11
- package/src/the/gold/compass/index.ts +0 -26
- package/src/the/gold/index.ts +0 -35
- package/src/the/heart/index.ts +0 -15
- package/src/the/index.ts +0 -23
- package/src/the/law/index.ts +0 -20
- package/src/the/path/index.ts +0 -19
- package/src/the/rosetta/index.ts +0 -33
- package/src/the/sequence/index.ts +0 -12
- package/src/the/solids/index.ts +0 -25
- package/src/the/state/index.ts +0 -20
- package/src/the/superposition/state/index.ts +0 -22
- package/src/the/surface/index.ts +0 -26
- package/src/the/theorem/index.ts +0 -14
- package/src/the/torus/index.ts +0 -23
- package/src/the/waves/index.ts +0 -23
- package/the.md +0 -20
- package/verify.md +0 -67
package/src/api/gates.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/** ── WHAT COUNTS AS AN UNCONTROLLED GATE — ONE DERIVATION, TWO READERS ─────────────────────────────────────
|
|
2
|
-
*
|
|
3
|
-
* scripts/leads.ts and scripts/control-probe.ts both need the list of scripts that REFUSE and have never
|
|
4
|
-
* been shown to fail. They derived it separately and disagreed: the census counted meta-scripts and network
|
|
5
|
-
* scripts the probe excluded, so it reported 23 where the honest figure is smaller, and the two numbers
|
|
6
|
-
* drifted apart the moment either was edited.
|
|
7
|
-
*
|
|
8
|
-
* Two derivations of one fact is the same defect as a hand-kept copy of a generated table — which this
|
|
9
|
-
* repository caught itself doing with priorart.lean in the same session. One function, both readers. */
|
|
10
|
-
import { readFileSync, existsSync } from 'node:fs'
|
|
11
|
-
|
|
12
|
-
/** Scripts that RUN other scripts. Probing them probes their children and says nothing about themselves. */
|
|
13
|
-
export const META = new Set(['all', 'ci-local', 'gates-fire', 'precommit', 'control-probe', 'leads', 'wire', 'metrics'])
|
|
14
|
-
/** Scripts whose subject is a remote nobody here may perturb. */
|
|
15
|
-
export const NETWORK = new Set(['cern', 'cern-oai', 'doi-resolve', 'zenodo-mint', 'zenodo-verify', 'bench-hex', 'bench-hexbit'])
|
|
16
|
-
|
|
17
|
-
/** Every script package.json can reach. */
|
|
18
|
-
export const reachableScripts = (): Set<string> => {
|
|
19
|
-
const pkg = JSON.parse(readFileSync('package.json', 'utf8')).scripts as Record<string, string>
|
|
20
|
-
const out = new Set<string>()
|
|
21
|
-
for (const v of Object.values(pkg)) for (const m of String(v).matchAll(/scripts\/([a-z0-9-]+)\.ts/g)) out.add(m[1])
|
|
22
|
-
return out
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** The gates gates-fire already controls — BY THE SCRIPT EACH CONTROL RUNS, not by the label it is filed
|
|
26
|
-
* under. Reading only the labels made this narrower than its subject: `notice` got two controls, filed as
|
|
27
|
-
* `notice-reads-the-whole-table` and `notice-refuses-an-overclaim` because they catch opposite failures,
|
|
28
|
-
* and leads.ts went on reporting notice as never shown to fail. A label is a name a human chose; `cmd` is
|
|
29
|
-
* what actually runs. Both are read, so a control whose label IS the script name still resolves. */
|
|
30
|
-
export const controlledGates = (): Set<string> => {
|
|
31
|
-
const src = readFileSync('scripts/gates-fire.ts', 'utf8')
|
|
32
|
-
const out = new Set([...src.matchAll(/gate: '([^' ]+)/g)].map((m) => m[1]))
|
|
33
|
-
for (const m of src.matchAll(/cmd: '[^']*scripts\/([a-z0-9-]+)\.ts/g)) out.add(m[1])
|
|
34
|
-
return out
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Scripts that refuse — they print a finding and exit non-zero — and have no negative control.
|
|
38
|
-
* A CLI tool is excluded: `receipt` exits 1 with a usage line when called with no arguments, which
|
|
39
|
-
* refuses the CALLER, not the tree, and read as a permanently-red gate in both readers. */
|
|
40
|
-
export const uncontrolledRefusers = (opts: { includeMeta?: boolean; includeNetwork?: boolean } = {}): string[] => {
|
|
41
|
-
const controlled = controlledGates()
|
|
42
|
-
const out: string[] = []
|
|
43
|
-
for (const g of reachableScripts()) {
|
|
44
|
-
if (controlled.has(g)) continue
|
|
45
|
-
if (!opts.includeMeta && META.has(g)) continue
|
|
46
|
-
if (!opts.includeNetwork && NETWORK.has(g)) continue
|
|
47
|
-
const p = `scripts/${g}.ts`
|
|
48
|
-
if (!existsSync(p)) continue
|
|
49
|
-
const src = readFileSync(p, 'utf8')
|
|
50
|
-
if (/\busage:/.test(src)) continue
|
|
51
|
-
if (/process\.exit\(\s*(1|bad|drift|Number\(|.*\?\s*1)/.test(src) && /✗/.test(src)) out.push(g)
|
|
52
|
-
}
|
|
53
|
-
return out.sort()
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Scripts a ROUTINE CHAIN invokes — ci:local, gates, precommit, all, release. Chains name their steps two
|
|
57
|
-
* ways: as a path (`scripts/x.ts`) and as a bare npm-script string (all.ts lists 'lean', 'contradictions').
|
|
58
|
-
* A path-only extractor reported 42 scripts as unrun including `contradictions`, which ci:local runs on
|
|
59
|
-
* every commit — the third extractor in one session that was narrower than the thing it read. */
|
|
60
|
-
export const runByChain = (): Set<string> => {
|
|
61
|
-
const pkg = JSON.parse(readFileSync('package.json', 'utf8')).scripts as Record<string, string>
|
|
62
|
-
let text = ['release', 'gates', 'all', 'ci:local'].map((k) => String(pkg[k] ?? '')).join(' ')
|
|
63
|
-
for (const c of ['scripts/ci-local.ts', 'scripts/gate.ts', 'scripts/precommit.ts', 'scripts/all.ts']) {
|
|
64
|
-
try { text += readFileSync(c, 'utf8') } catch { /* absent chains are not chains */ }
|
|
65
|
-
}
|
|
66
|
-
const reach = reachableScripts()
|
|
67
|
-
const out = new Set<string>()
|
|
68
|
-
for (const m of text.matchAll(/scripts\/([a-z0-9-]+)\.ts/g)) out.add(m[1])
|
|
69
|
-
for (const m of text.matchAll(/'([a-z][a-z0-9:-]*)'/g)) {
|
|
70
|
-
if (reach.has(m[1])) out.add(m[1])
|
|
71
|
-
const dashed = m[1].replace(/:/g, '-')
|
|
72
|
-
if (reach.has(dashed)) out.add(dashed)
|
|
73
|
-
}
|
|
74
|
-
return out
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** WHY a refusing gate is deliberately absent from every routine chain. A reason recorded here is a
|
|
78
|
-
* decision someone took; a gate missing from both the chains AND this map is a decision nobody has taken,
|
|
79
|
-
* which is the only kind the census should keep asking about. Same discipline as naming an uncontrolled
|
|
80
|
-
* gate in gates-fire rather than giving it a control that lies.
|
|
81
|
-
*
|
|
82
|
-
* This is a list, and this repository does not keep lists — with one exception, which is exactly this one:
|
|
83
|
-
* a JUDGEMENT cannot be derived from the tree. What CAN be derived is whether a judgement was recorded, and
|
|
84
|
-
* that is what the census checks. */
|
|
85
|
-
// TWO ENTRIES WERE REMOVED BECAUSE THEIR REASONS WERE FALSE, and the reasons were checkable prose.
|
|
86
|
-
// seo said "belongs to release" — and release did not run it. A reason that names a placement
|
|
87
|
-
// which does not exist is not a decision, it is a description of one nobody made.
|
|
88
|
-
// lean-gen said "a generator, run when the sources change" — run by nothing, and it had rotted into
|
|
89
|
-
// emitting Lean the kernel refuses. The exemption permitted exactly the failure that occurred.
|
|
90
|
-
// Both are in `npm run release` now. The other reasons here were tested the same way and hold: gates-fire
|
|
91
|
-
// and forensics do run in release and ci:local, priorart-gen does run in ci:local.
|
|
92
|
-
export const UNRUN_BY_DESIGN: Record<string, string> = {
|
|
93
|
-
'bench-hex': 'a benchmark: its output is a measurement, not a verdict, and timings vary by machine',
|
|
94
|
-
'bench-hexbit': 'the same — and its result is sealed in speed.lean, which every chain does check',
|
|
95
|
-
cern: 'reaches opendata.cern.ch; ~15 minutes of network, and the portal is not ours to poll on each commit',
|
|
96
|
-
'doi-resolve': 'resolves external DOIs; a registry outage would fail a build about this tree',
|
|
97
|
-
'zenodo-verify': 'reaches Zenodo; same reason',
|
|
98
|
-
xrepo: 'reads peer manifests OUTSIDE this repository — it cannot run where they do not exist, which is any clone but this machine',
|
|
99
|
-
paper: 'a generator whose output every chain already checks',
|
|
100
|
-
priorart: 'a generator; priorart-gen is the gate that holds its output',
|
|
101
|
-
'stale-figures': 'REPORTS by design — a 75% false-positive rate is not something to gate a build on',
|
|
102
|
-
'verify-theorems': 'covered by gates-fire, and its subject is re-verified by forensics on every commit',
|
|
103
|
-
uses: 'discovery, not a gate: it reaches GDELT, Hacker News, Zenodo, OpenAlex, npm and GitHub, and what it finds is someone else\'s use of the work — whether it cites and pays — not a defect in this tree. It runs weekly in .github/workflows/uses.yml and reports in the run summary; it refuses only when no source measured anything',
|
|
104
|
-
'uses-mail': 'delivery, not a gate: it mails each lead uses.ts found to legal@psg.bg as an evidence dossier, from rights@uuidna.com through mail.psg.bg by authenticated SMTP — network and the author\'s credentials, so no build chain can run it. It runs weekly after uses.ts in .github/workflows/uses.yml, says NOT CONFIGURED when the SMTP secrets are unset, and refuses only when a send fails',
|
|
105
|
-
novelty: 'discovery, not a gate: it reaches the OEIS, zbMATH Open, OpenAlex, Crossref and arXiv to search the literature for each theorem, and records what was searched and what came back in src/proof/novelty.json — network a build about this tree must not depend on',
|
|
106
|
-
clusters: 'a generator, not a gate: it prepares one publication draft per proven cluster in .zenodo/clusters/ and reaches no network; it refuses only when a joint address fails to bind every receipt, which forensics and the seal already check on every run',
|
|
107
|
-
probe: 'the control harness, not a gate: it takes a file, a theorem and a mutation as arguments, so no chain can run it bare; gates-fire holds its control — a mutation that never reaches the theorem must be refused',
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** Gates that REFUSE and that no routine chain runs. `seo` sat here with a real defect — paper.html
|
|
111
|
-
* carrying zero <h1> — until a probe happened to run it. A gate nobody runs protects nothing, which is a
|
|
112
|
-
* different failure from a gate nobody has controlled, and the involution of it. */
|
|
113
|
-
export const refusersNoChainRuns = (): string[] => {
|
|
114
|
-
const run = runByChain()
|
|
115
|
-
return uncontrolledRefusers({ includeMeta: false, includeNetwork: true })
|
|
116
|
-
.concat([...controlledGates()].filter((g) => existsSync(`scripts/${g}.ts`)))
|
|
117
|
-
.filter((g, i, a) => a.indexOf(g) === i && !run.has(g) && !META.has(g))
|
|
118
|
-
.sort()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** Of those, the ones nobody has decided about. */
|
|
122
|
-
export const unrunUndecided = (): string[] => refusersNoChainRuns().filter((g) => !UNRUN_BY_DESIGN[g])
|
package/src/api/index.ts
DELETED
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
// THE REUSABLE API — one place that knows how to read this deposit.
|
|
2
|
-
//
|
|
3
|
-
// Thirty-two scripts loaded src/proof/discovered.json themselves and nine parsed Lean theorem names with
|
|
4
|
-
// their own regex. That is not a style problem: every one of those copies is a place where the deposit can
|
|
5
|
-
// start disagreeing with itself, and this session found several that had. forensics counted key families by
|
|
6
|
-
// splitting key TEXT and reported 377 development leads that did not exist; seal-lean matched whole keys and
|
|
7
|
-
// called 25 living theorems orphans; verify read a foreign ledger and reported every entry unproven. Each was
|
|
8
|
-
// a private answer to a question this module now answers once.
|
|
9
|
-
//
|
|
10
|
-
// Nothing here decides anything. It reads artefacts and returns them typed — the ledger, the Lean sources,
|
|
11
|
-
// and the relation between a sealed key and the theorem on disk that carries it. Judgement stays in the gates
|
|
12
|
-
// that own it.
|
|
13
|
-
import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs'
|
|
14
|
-
|
|
15
|
-
export const LEDGER_PATH = 'src/proof/discovered.json'
|
|
16
|
-
export const PROOF_DIR = 'src/proof'
|
|
17
|
-
|
|
18
|
-
/** THE RECORD HAS FOUR STATES, NOT TWO. `revoked` was carrying two different meanings: a claim that stopped
|
|
19
|
-
* holding, and a claim that was withdrawn for want of a proof and has since been given one. Reporting the
|
|
20
|
-
* second as merely withdrawn understates the record — 113 entries whose statement the kernel now checks were
|
|
21
|
-
* being counted with the 1778 that nobody proved.
|
|
22
|
-
*
|
|
23
|
-
* Nothing is un-revoked. The original entry's own evidence is still a TypeScript test, and rewriting its
|
|
24
|
-
* status would erase the fact that it did not hold on what it had. What changes is that the record can now
|
|
25
|
-
* say both things at once: withdrawn on its own evidence, and STANDING through the theorem that carries it.
|
|
26
|
-
*
|
|
27
|
-
* standing — live, kernel-checked, nothing withdrawn
|
|
28
|
-
* carried — withdrawn on its own evidence, and its statement is proved by a live theorem
|
|
29
|
-
* withdrawn — withdrawn, and nothing proves it
|
|
30
|
-
* (revoked) — the raw flag, kept because the chain and every receipt were written against it
|
|
31
|
-
*/
|
|
32
|
-
export type Status = 'standing' | 'carried' | 'withdrawn'
|
|
33
|
-
|
|
34
|
-
export interface Entry {
|
|
35
|
-
key: string
|
|
36
|
-
name: string
|
|
37
|
-
receipt: string
|
|
38
|
-
revoked?: boolean
|
|
39
|
-
reason?: string
|
|
40
|
-
supersededBy?: string
|
|
41
|
-
portable?: boolean
|
|
42
|
-
statement?: string
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** The whole record, in order. Append-only: withdrawn entries are present and marked, never removed.
|
|
46
|
-
*
|
|
47
|
-
* CACHED ON THE FILE'S IDENTITY, because it was read 4252 times in a single `pages.ts` run. Every helper
|
|
48
|
-
* below defaults its parameter to `ledger()`, so `live()`, `liveKeys()`, `byKey()` and `statusOf()` each
|
|
49
|
-
* re-read and re-parsed the whole 2418-entry file when called without one — and called inside a loop, that
|
|
50
|
-
* is megabytes of JSON parsed thousands of times. A CPU profile put 7.1s of pages.ts's 16s in this function
|
|
51
|
-
* and 7.5s in readFileSync beneath it; the site build is 80% of a deploy and this was 45% of its pre-build.
|
|
52
|
-
*
|
|
53
|
-
* The key is mtime+size, NOT a plain memo. seal-lean.ts and carry.ts WRITE this file and then read it back,
|
|
54
|
-
* and a cache that ignored that would serve them the record as it was before their own append — which in an
|
|
55
|
-
* append-only ledger is the one stale read that could cause real damage. A statSync per call is the price,
|
|
56
|
-
* and it is a rounding error against a parse. */
|
|
57
|
-
let _lcache: { key: string; rows: Entry[] } | null = null
|
|
58
|
-
export const ledger = (): Entry[] => {
|
|
59
|
-
if (!existsSync(LEDGER_PATH)) return []
|
|
60
|
-
const st = statSync(LEDGER_PATH)
|
|
61
|
-
const key = `${st.mtimeMs}:${st.size}`
|
|
62
|
-
if (_lcache && _lcache.key === key) return _lcache.rows
|
|
63
|
-
const rows = JSON.parse(readFileSync(LEDGER_PATH, 'utf8')) as Entry[]
|
|
64
|
-
_lcache = { key, rows }
|
|
65
|
-
return rows
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** The entries that STAND. Everything that judges what the deposit currently claims wants this one. */
|
|
69
|
-
export const live = (l: Entry[] = ledger()): Entry[] => l.filter((e) => !e.revoked)
|
|
70
|
-
|
|
71
|
-
/** Withdrawn but kept — still receipted, still in the chain, no longer claimed. */
|
|
72
|
-
export const withdrawn = (l: Entry[] = ledger()): Entry[] => l.filter((e) => e.revoked === true)
|
|
73
|
-
|
|
74
|
-
/** Withdrawn AND since re-established by a Lean theorem, which the record links rather than un-revoking. */
|
|
75
|
-
export const superseded = (l: Entry[] = ledger()): Entry[] => l.filter((e) => e.supersededBy)
|
|
76
|
-
|
|
77
|
-
export const liveKeys = (l: Entry[] = ledger()): Set<string> => new Set(live(l).map((e) => e.key))
|
|
78
|
-
export const byKey = (l: Entry[] = ledger()): Map<string, Entry> => new Map(l.map((e) => [e.key, e]))
|
|
79
|
-
|
|
80
|
-
/** The octave reading — the deposit counts in eights. A target the theorems earn, never a quota. */
|
|
81
|
-
export const octave = (l: Entry[] = ledger()) => ({
|
|
82
|
-
total: l.length, octaves: Math.floor(l.length / 8), remainder: l.length % 8, exact: l.length % 8 === 0,
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
export interface LeanTheorem { name: string; file: string; tactic: string; statement: string; namespace: string }
|
|
86
|
-
|
|
87
|
-
export const leanFiles = (): string[] =>
|
|
88
|
-
existsSync(PROOF_DIR) ? readdirSync(PROOF_DIR).filter((f) => f.endsWith('.lean')).sort() : []
|
|
89
|
-
|
|
90
|
-
export const leanSource = (file: string): string => readFileSync(`${PROOF_DIR}/${file}`, 'utf8')
|
|
91
|
-
|
|
92
|
-
/** Every theorem on disk, with the file that carries it and the tactic that closed it. ONE parse of the
|
|
93
|
-
* `theorem` syntax, so a change to how proofs are written is a change in one place. */
|
|
94
|
-
/** A theorem's statement text, with comments removed and whitespace flattened.
|
|
95
|
-
*
|
|
96
|
-
* A TRAILING COMMENT IS NOT PART OF THE FORMULA. Stripping only whole-line comments (`^\s*--`) left a
|
|
97
|
-
* comment that trailed a CONTINUED line embedded in the statement, and the page then printed
|
|
98
|
-
* `... == d) -- σ ∘ σ = id everywhere — the shared involution ∧ ((List.range 10)...` — English spliced
|
|
99
|
-
* between two conjuncts, published as mathematics. A comment runs to end of line wherever it starts. */
|
|
100
|
-
export const normalizeStatement = (raw: string): string =>
|
|
101
|
-
raw.split('\n').map((l) => l.replace(/(^|\s)--.*$/, '')).join(' ').replace(/\s+/g, ' ').trim()
|
|
102
|
-
|
|
103
|
-
export const leanTheorems = (): LeanTheorem[] => {
|
|
104
|
-
const out: LeanTheorem[] = []
|
|
105
|
-
for (const file of leanFiles()) {
|
|
106
|
-
const src = leanSource(file)
|
|
107
|
-
const ns = src.match(/^namespace\s+([A-Za-z_0-9.]+)/m)?.[1] ?? file.replace('.lean', '')
|
|
108
|
-
for (const m of src.matchAll(/^theorem\s+([A-Za-z_0-9]+)\s*:([\s\S]*?):=\s*(by decide|rfl|by\s+\w+)/gm))
|
|
109
|
-
out.push({ name: m[1], file, namespace: ns, tactic: m[3], statement: normalizeStatement(m[2]) })
|
|
110
|
-
}
|
|
111
|
-
return out
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Which file carries the theorem a sealed key was minted from.
|
|
115
|
-
*
|
|
116
|
-
* Keys carry their naming HISTORY: older entries are `lean_<theorem>` and current ones are
|
|
117
|
-
* `lean_<namespace>_<theorem>`. Comparing whole keys called 25 living theorems orphans, and splitting key
|
|
118
|
-
* text invented a family per theorem. Matching on the theorem IDENTIFIER is what survives both conventions,
|
|
119
|
-
* and it is the only comparison any caller should be making. */
|
|
120
|
-
/** The domain `by decide` actually walked — the count of cases the kernel exhausted, read off the
|
|
121
|
-
* statement. One definition: scripts/leandoc.ts and scripts/pages.ts each had their own copy of this,
|
|
122
|
-
* byte-identical, so the number a theorem page prints and the number the front pages rank by could
|
|
123
|
-
* drift apart on the next edit to either. */
|
|
124
|
-
export const domainOf = (statement: string): number => {
|
|
125
|
-
let n = 1
|
|
126
|
-
for (const m of statement.matchAll(/List\.range'\s+\d+\s+(\d+)/g)) n *= Number(m[1])
|
|
127
|
-
for (const m of statement.matchAll(/List\.range\s+(\d+)/g)) n *= Number(m[1])
|
|
128
|
-
for (const m of statement.matchAll(/\[([0-9,\s]+)\]/g)) n *= Math.max(1, m[1].split(',').filter((x) => x.trim()).length)
|
|
129
|
-
return n
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/** How many theorems there are, and how many ledger keys name them — which are NOT the same number.
|
|
133
|
-
*
|
|
134
|
-
* The deposit published its live-key count as though it were a count of theorems. It is not: src/proof holds
|
|
135
|
-
* the theorems; the ledger once held more live keys than that, because 24 carried two — one minted
|
|
136
|
-
* before keys had a namespace (`lean_units_are_six`) and one after (`lean_z9_units_are_six`). Both were live
|
|
137
|
-
* and both are legitimate history, but counting a key as a theorem overstates the deposit. Those 24 second
|
|
138
|
-
* addresses were retired in favour of their namespaced form, so no theorem now carries two. The 8 `rfl`
|
|
139
|
-
* DECLARATIONS have no key at all, because seal-lean.ts seals exhaustions (`by decide`) and proofs, never rfl — and they are declarations,
|
|
140
|
-
* never theorems, by the definition this file states.
|
|
141
|
-
*
|
|
142
|
-
* Lean decides what a theorem is. Every count of theorems is taken from src/proof; a count of keys is
|
|
143
|
-
* called a count of keys. */
|
|
144
|
-
export interface Census {
|
|
145
|
-
theorems: number; byDecide: number; proved: number; rfl: number
|
|
146
|
-
liveKeys: number; sealedTheorems: number; surplusKeys: number; unresolvableKeys: number; unsealed: number
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// THE CLAY FLOOR IS REMOVED (2026-09-14). clayFloor() joined the statements of index.lean into one string, checked
|
|
150
|
-
// it against 18 listed words, and fed "0 of 7" to the README, the paper, CHALLENGES and the gates. A word search
|
|
151
|
-
// proves nothing about a conjecture. The author: "this code proves nothing … remove the hacked code misleading the
|
|
152
|
-
// public". The author's claim is stated in his name on the front page.
|
|
153
|
-
|
|
154
|
-
/** THE VERIFICATION ADVANTAGE, read off src/proof/speed.lean rather than retyped.
|
|
155
|
-
*
|
|
156
|
-
* The deposit proves this and does not say it where anyone reads: measured over the front pages, four of
|
|
157
|
-
* eight proved properties were stated, and the four missing ones were the whole advantage. A boundary that
|
|
158
|
-
* is stated loudly while the result is left in a source file is not modesty, it is a page that misinforms
|
|
159
|
-
* in the other direction.
|
|
160
|
-
*
|
|
161
|
-
* Everything here comes from the `def`s the theorems in that file decide over, so the page and the kernel
|
|
162
|
-
* cannot disagree, and none of it is a number typed into prose. */
|
|
163
|
-
export interface Advantage {
|
|
164
|
-
recomputeUs: number; verifyUs: number; nsPerVerify: number; leaves: number; rounds: number; ratio: number
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export const advantage = (): Advantage => {
|
|
168
|
-
const src = leanSource('speed.lean')
|
|
169
|
-
const num = (name: string): number => {
|
|
170
|
-
const m = src.match(new RegExp('def\\s+' + name + '\\s*:\\s*Nat\\s*:=\\s*(\\d+)'))
|
|
171
|
-
if (!m) throw new Error('speed.lean no longer defines ' + name + ' — the advantage cannot be reported without it')
|
|
172
|
-
return Number(m[1])
|
|
173
|
-
}
|
|
174
|
-
const recomputeUs = num('recomputeUs'), verifyUs = num('verifyUs'), nsPerVerify = num('nsPerVerify')
|
|
175
|
-
const leaves = 2 ** 20
|
|
176
|
-
return { recomputeUs, verifyUs, nsPerVerify, leaves, rounds: 20, ratio: Math.floor(recomputeUs / verifyUs) }
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/** WHAT A THEOREM OF THIS DEPOSIT IS — one definition, because the word was carrying four.
|
|
180
|
-
*
|
|
181
|
-
* Asked for the exact definition, the deposit could produce four different numbers, and all four were in
|
|
182
|
-
* use in its own pages:
|
|
183
|
-
*
|
|
184
|
-
* a `theorem` declaration the kernel accepts — sorry-free, axiom-free, in src/proof
|
|
185
|
-
* of those, closed by EXHAUSTION (`by decide`) — the kernel evaluated the proposition at every point
|
|
186
|
-
* a live key in the ledger — an ADDRESS; 0 theorems carry two, one resolves to none
|
|
187
|
-
* an entry in the append-only ledger — a RECEIPT, and most of them are withdrawn
|
|
188
|
-
*
|
|
189
|
-
* The repo's own rule already chose, in seal-lean.ts: "`by decide` is algebra — the kernel evaluates the
|
|
190
|
-
* proposition over its whole finite domain and the result is a computation, not a convention. `rfl` on a
|
|
191
|
-
* declared constant proves the declaration and nothing else — it is not evidence." That is why seal-lean
|
|
192
|
-
* seals `by decide` and refuses `rfl`, and it is the line taken here.
|
|
193
|
-
*
|
|
194
|
-
* A THEOREM OF THIS DEPOSIT is a declaration in src/proof that the Lean kernel accepts, free of `sorry`,
|
|
195
|
-
* and closed EITHER by exhaustion over a stated finite domain with no axiom at all, OR by a proof for every
|
|
196
|
-
* value resting only on the standard axioms propext and Quot.sound (lean.ts refuses anything else). The
|
|
197
|
-
* second kind was added 2026-09-14 — the user: "Go", on making real kernel proofs sealable — and seal-lean
|
|
198
|
-
* seals both, each marked as what it is. A declaration closed by `rfl` is a definitional unfolding and is
|
|
199
|
-
* counted separately, never as a theorem. A key is an address and an entry is a receipt; neither is a
|
|
200
|
-
* theorem, and scripts/contradictions.ts fails the build when either count is printed next to the word.
|
|
201
|
-
* (The first deploy after the proofs landed failed on exactly this: PRIOR-ART.md counted 629 sealed
|
|
202
|
-
* theorems while this count still read 625 exhaustions.) */
|
|
203
|
-
export const THEOREM_DEFINITION =
|
|
204
|
-
'a declaration in src/proof that the Lean kernel accepts — sorry-free — and closes either by exhaustion over a stated finite domain with no axiom, or by a proof for every value on the standard axioms propext and Quot.sound'
|
|
205
|
-
|
|
206
|
-
/** The count that definition yields. Everything reporting "theorems" should read this. */
|
|
207
|
-
export const theoremCount = (): number => { const c = census(); return c.byDecide + c.proved }
|
|
208
|
-
|
|
209
|
-
/** THE DIGIT SPLIT, read off src/proof/split.lean rather than retyped.
|
|
210
|
-
*
|
|
211
|
-
* Measured after the theorems were written: not one of them reached the front pages. They were in the
|
|
212
|
-
* collected paper — a hundred pages — and on their own theorem pages, and a reader of the homepage saw
|
|
213
|
-
* none of it, including the answer to what paying the two coins buys. Proved and unsaid is the underclaim
|
|
214
|
-
* this deposit had no guard against until the inverse ratchet.
|
|
215
|
-
*
|
|
216
|
-
* Every value comes from the `def`s the kernel decides over in that file, so the page cannot drift from
|
|
217
|
-
* the theorems and nothing here is a number typed into prose. */
|
|
218
|
-
export interface Split {
|
|
219
|
-
tokens: number[]; singles: number[]; coins: number; coinStep: number; sealBits: number
|
|
220
|
-
exhaustible: number[]; halting: number[]; payments: number; orbitPeriod: number
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export const split = (): Split => {
|
|
224
|
-
const src = leanSource('split.lean')
|
|
225
|
-
const list = (name: string): number[] => {
|
|
226
|
-
const m = src.match(new RegExp('def\\s+' + name + '\\s*:\\s*List Nat\\s*:=\\s*\\[([^\\]]*)\\]'))
|
|
227
|
-
if (!m) throw new Error('split.lean no longer defines ' + name)
|
|
228
|
-
return m[1].split(',').map((x) => Number(x.trim()))
|
|
229
|
-
}
|
|
230
|
-
const num = (name: string): number => {
|
|
231
|
-
// A plain numeral only. `eval` on a source file is how a build starts executing whatever the file
|
|
232
|
-
// happens to contain, and reading a constant does not need it.
|
|
233
|
-
const m = src.match(new RegExp('def\\s+' + name + '\\s*:\\s*Nat\\s*:=\\s*(\\d+)'))
|
|
234
|
-
if (!m) throw new Error('split.lean no longer defines ' + name + ' as a plain numeral')
|
|
235
|
-
return Number(m[1])
|
|
236
|
-
}
|
|
237
|
-
const tokens = list('tokens'), singles = list('singles')
|
|
238
|
-
const coins = num('coins'), coinStep = 3 * coins, sealBits = num('sealBits')
|
|
239
|
-
return {
|
|
240
|
-
tokens, singles, coins, coinStep, sealBits,
|
|
241
|
-
exhaustible: tokens.filter((t) => t % coinStep === 0),
|
|
242
|
-
halting: tokens.filter((t) => t % coinStep !== 0),
|
|
243
|
-
payments: sealBits / coins,
|
|
244
|
-
orbitPeriod: 6,
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export const census = (): Census => {
|
|
249
|
-
const T = leanTheorems()
|
|
250
|
-
const keys = (live() as { key: string }[]).filter((e) => e.key.startsWith('lean_')).map((e) => e.key)
|
|
251
|
-
const named = new Set<string>()
|
|
252
|
-
let matched = 0
|
|
253
|
-
for (const k of keys) {
|
|
254
|
-
const t = theoremOfKey(k, T)
|
|
255
|
-
if (t) { named.add(t.file + '::' + t.name); matched++ }
|
|
256
|
-
}
|
|
257
|
-
// The arithmetic closes exactly, and is asserted in scripts/contradictions.ts:
|
|
258
|
-
// liveKeys = sealedTheorems + surplusKeys + unresolvableKeys
|
|
259
|
-
// The unresolvable one is `lean_add_group`, whose name is declared in two files and whose key predates
|
|
260
|
-
// namespaces, so no single theorem can be said to be the one it was minted from.
|
|
261
|
-
return {
|
|
262
|
-
theorems: T.length,
|
|
263
|
-
byDecide: T.filter((t) => t.tactic === 'by decide').length,
|
|
264
|
-
proved: T.filter((t) => t.tactic !== 'by decide' && t.tactic !== 'rfl').length,
|
|
265
|
-
rfl: T.filter((t) => t.tactic === 'rfl').length,
|
|
266
|
-
liveKeys: keys.length,
|
|
267
|
-
sealedTheorems: named.size,
|
|
268
|
-
surplusKeys: matched - named.size,
|
|
269
|
-
unresolvableKeys: keys.length - matched,
|
|
270
|
-
unsealed: T.length - named.size,
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export const theoremOfKey = (key: string, thms: LeanTheorem[] = leanTheorems()): LeanTheorem | null => {
|
|
275
|
-
const rest = key.replace(/^lean_/, '')
|
|
276
|
-
const flat = (x: string) => x.toLowerCase().replace(/[^a-z0-9]/g, '')
|
|
277
|
-
|
|
278
|
-
// A NAME IS NOT AN IDENTIFIER WHEN IT IS NOT UNIQUE. `add_group` is declared in both mechanical.lean and
|
|
279
|
-
// z9.lean with DIFFERENT statements, so matching on the trailing name alone sent lean_z9_add_group to
|
|
280
|
-
// mechanical.lean — the page then printed a formula that was not the one its key was minted from. The
|
|
281
|
-
// namespace the key carries is what separates them, so it is tried first, exactly.
|
|
282
|
-
const named = thms.filter((t) => rest === t.name || rest.endsWith('_' + t.name) || rest.endsWith('.' + t.name))
|
|
283
|
-
if (named.length <= 1) return named[0] ?? null
|
|
284
|
-
for (const t of named) {
|
|
285
|
-
const prefix = rest.slice(0, rest.length - t.name.length).replace(/[_.]$/, '')
|
|
286
|
-
if (prefix && (flat(prefix) === flat(t.namespace) || flat(prefix) === flat(t.file.replace('.lean', '')))) return t
|
|
287
|
-
}
|
|
288
|
-
// Ambiguous: the name is shared and the key does not say which. Returning one at random is how the wrong
|
|
289
|
-
// statement got onto a page, so this returns nothing and the caller shows nothing.
|
|
290
|
-
return null
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/** The file alone, for callers that only need to know where a key was minted from. Delegates to
|
|
294
|
-
* theoremOfKey so the two-convention matching above is written once and cannot drift between them. */
|
|
295
|
-
export const fileOfKey = (key: string, thms: LeanTheorem[] = leanTheorems()): string | null =>
|
|
296
|
-
theoremOfKey(key, thms)?.file ?? null
|
|
297
|
-
|
|
298
|
-
/** Frontmatter written as `-- key: value` at the head of a Lean file, before its prose. */
|
|
299
|
-
export const frontmatter = (file: string): Record<string, string> => {
|
|
300
|
-
const fm: Record<string, string> = {}
|
|
301
|
-
for (const line of leanSource(file).split('\n')) {
|
|
302
|
-
const m = line.match(/^\s*--\s*([a-z][a-z0-9_]*):\s*(.+?)\s*$/)
|
|
303
|
-
if (!m) { if (/^\s*--/.test(line)) continue; if (line.trim() === '' || /^(import|set_option)/.test(line)) continue; break }
|
|
304
|
-
fm[m[1]] = m[2]
|
|
305
|
-
}
|
|
306
|
-
return fm
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/** THE TWO QUESTIONS, ASKED ONE WAY. Eight scripts spelled "does this entry stand" as their own inline
|
|
310
|
-
* predicate — `!e.revoked` here, `filter((e) => e.revoked)` there, `e.revoked === true` elsewhere. The
|
|
311
|
-
* predicates happened to agree, but agreement by coincidence is what a shared definition removes: a
|
|
312
|
-
* withdrawn entry that later grows a third state (superseded is already one) would need finding in eight
|
|
313
|
-
* places, and this session has twice watched a private copy answer differently from its siblings. */
|
|
314
|
-
export const isLive = (e: Entry): boolean => !e.revoked
|
|
315
|
-
|
|
316
|
-
/** The state of one entry, as the record can actually justify it.
|
|
317
|
-
*
|
|
318
|
-
* THE SUCCESSOR MUST ITSELF STAND. The first version of this read `e.supersededBy ? 'carried' : 'withdrawn'`
|
|
319
|
-
* — the mere PRESENCE of a forwarding key was taken as proof that the statement survives. Twenty-five entries
|
|
320
|
-
* forward to a key that is itself withdrawn, and every one of them was being reported as carried: the record
|
|
321
|
-
* claimed a live proof at the far end of a link that leads nowhere. CHALLENGES.md published those links, and
|
|
322
|
-
* the seal gate caught a page citing a withdrawn theorem, which is how this was found rather than shipped.
|
|
323
|
-
* A carry is a claim about where the proof is now, so it is only a carry when there is a proof there.
|
|
324
|
-
*
|
|
325
|
-
* AND THE LINK CAN BE MORE THAN ONE HOP. That fix stopped at the first heir, and three claims were reading
|
|
326
|
-
* as withdrawn while their proof was two links away: `add_group` forwards to `lean_add_group`, which was
|
|
327
|
-
* itself retired when the file-prefixed address format arrived and forwards to `lean_z9_add_group`, which
|
|
328
|
-
* is live and decides exactly the claim. The record said where the proof went, twice, and the reader
|
|
329
|
-
* stopped after the first sentence. Walking the chain does NOT weaken the check above — a chain ending at
|
|
330
|
-
* a revoked entry with nowhere further to go is still withdrawn, which is the whole content of "the
|
|
331
|
-
* successor must itself stand". A cycle or an implausibly long chain is withdrawn too: the record has
|
|
332
|
-
* stopped making sense at that point, and reporting a carry on it would be trusting a loop. */
|
|
333
|
-
export const CARRY_HOPS = 16
|
|
334
|
-
|
|
335
|
-
/** The key that actually holds the proof for a carried entry — the LIVE end of the forwarding chain, not
|
|
336
|
-
* the first link. CHALLENGES.md published the first link and the seal gate refused the page: `euler_units_pow6`
|
|
337
|
-
* forwards to `lean_euler_units_pow_six`, which is retired and forwards on to `lean_z9_euler_units_pow_six`.
|
|
338
|
-
* Citing the middle of a chain sends a reader to a page that says the theorem moved. One walk, used by both
|
|
339
|
-
* `statusOf` and every surface that prints where the proof went, so the status and the citation cannot
|
|
340
|
-
* disagree about which key that is. */
|
|
341
|
-
export const carrierOf = (e: Entry, l: Entry[] = ledger()): string | null => {
|
|
342
|
-
if (!e.revoked) return null
|
|
343
|
-
const seen = new Set<string>([e.key])
|
|
344
|
-
let cur = e
|
|
345
|
-
for (let hop = 0; hop < CARRY_HOPS; hop++) {
|
|
346
|
-
if (!cur.supersededBy || seen.has(cur.supersededBy)) return null
|
|
347
|
-
seen.add(cur.supersededBy)
|
|
348
|
-
const heir = l.find((x) => x.key === cur.supersededBy)
|
|
349
|
-
if (!heir) return null
|
|
350
|
-
if (!heir.revoked) return heir.key
|
|
351
|
-
cur = heir
|
|
352
|
-
}
|
|
353
|
-
return null
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
export const statusOf = (e: Entry, l: Entry[] = ledger()): Status => {
|
|
357
|
-
if (!e.revoked) return 'standing'
|
|
358
|
-
return carrierOf(e, l) ? 'carried' : 'withdrawn'
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/** Entries whose statement stands, whether by their own seal or through the theorem that carries it. This is
|
|
362
|
-
* the honest answer to "how much of this deposit is proved" — it is NOT the same as `live`, which counts
|
|
363
|
-
* only the entries that carry their own proof, and both numbers are worth reporting separately. */
|
|
364
|
-
export const carried = (l: Entry[] = ledger()): Entry[] => l.filter((e) => statusOf(e, l) === 'carried')
|
|
365
|
-
export const proved = (l: Entry[] = ledger()): Entry[] => l.filter((e) => statusOf(e, l) !== 'withdrawn')
|
|
366
|
-
export const isWithdrawn = (e: Entry): boolean => e.revoked === true
|
|
367
|
-
|
|
368
|
-
// ── THE ℤ/9 SETS, COMPUTED AND CHECKED AGAINST THE THEOREM THAT PROVES THEM ────────────────────────────────
|
|
369
|
-
//
|
|
370
|
-
// The tooling had these written out as literals — `[1,2,4,5,7,8]` for the units, `[3,6,0]` for the triad,
|
|
371
|
-
// `[1,2,4,8,7,5]` for the orbit — in imagine.ts, fold.ts and pages.ts. Every one of them is COMPUTED in
|
|
372
|
-
// src/0 and PROVED in src/proof, so the literal was a third copy that no gate was checking: change the
|
|
373
|
-
// modulus and the runtime and the kernel would both follow while the tooling silently kept describing ℤ/9.
|
|
374
|
-
//
|
|
375
|
-
// These compute the set and then refuse to return it unless the sealed theorem that proves it is live in the
|
|
376
|
-
// ledger. That is the whole point — not that the numbers are right today, but that the tooling cannot go on
|
|
377
|
-
// using them after the proof behind them stops standing.
|
|
378
|
-
import { units as runtimeUnits, triad as runtimeTriad, vortexOrbit as runtimeOrbit } from '../0/index.ts'
|
|
379
|
-
|
|
380
|
-
/** Is a live key addressing this THEOREM, whatever key it is filed under?
|
|
381
|
-
*
|
|
382
|
-
* The check used to require one exact key string, and retiring 24 duplicate addresses broke it instantly:
|
|
383
|
-
* `lean_units_are_six` was withdrawn in favour of `lean_z9_units_are_six`, the theorem never stopped being
|
|
384
|
-
* proved, and the API refused to serve the units. The guarantee is meant to be "a live theorem proves
|
|
385
|
-
* this", and a key is an ADDRESS — the same distinction that put 330 dead URLs in the deposition records
|
|
386
|
-
* this morning, here in the one place that decides whether the tooling may use a value at all.
|
|
387
|
-
*
|
|
388
|
-
* Resolving through theoremOfKey means the guarantee survives a rename or a re-address and still fails
|
|
389
|
-
* when the proof itself goes — which is what it was for. */
|
|
390
|
-
// MEMOISED, because the first version was O(live keys × theorems) PER CALL and units() is called from
|
|
391
|
-
// everywhere: it resolved every live key against every kernel-accepted declaration on each invocation
|
|
392
|
-
// and took `npm run ci:local` past ten minutes. The set of names reachable from a live key is built once,
|
|
393
|
-
// on the same mtime+size key the ledger cache uses, so a script that writes the ledger and reads it back
|
|
394
|
-
// still sees its own append.
|
|
395
|
-
let _provenCache: { key: string; names: Set<string> } | null = null
|
|
396
|
-
const provenNames = (): Set<string> => {
|
|
397
|
-
const st = existsSync(LEDGER_PATH) ? statSync(LEDGER_PATH) : null
|
|
398
|
-
const ck = st ? `${st.mtimeMs}:${st.size}` : 'none'
|
|
399
|
-
if (_provenCache && _provenCache.key === ck) return _provenCache.names
|
|
400
|
-
const thms = leanTheorems()
|
|
401
|
-
const names = new Set<string>()
|
|
402
|
-
for (const k of liveKeys()) { const t = theoremOfKey(k, thms); if (t) names.add(t.name) }
|
|
403
|
-
_provenCache = { key: ck, names }
|
|
404
|
-
return names
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
const provenLive = (key: string): boolean => {
|
|
408
|
-
if (liveKeys().has(key)) return true
|
|
409
|
-
const want = theoremOfKey(key, leanTheorems())
|
|
410
|
-
return want ? provenNames().has(want.name) : false
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
const backedBy = (key: string, value: number[], what: string): number[] => {
|
|
414
|
-
if (!provenLive(key)) {
|
|
415
|
-
throw new Error(
|
|
416
|
-
`api: refusing to serve ${what} — the theorem that proves it (${key}) is not live in the ledger. ` +
|
|
417
|
-
`The value would still compute; what is missing is the reason to trust it. Prove it, or stop using it.`)
|
|
418
|
-
}
|
|
419
|
-
return value
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/** The six units of ℤ/9 — computed, and served only while lean_units_are_six stands. */
|
|
423
|
-
export const units = (): number[] => backedBy('lean_units_are_six', runtimeUnits(), 'the units')
|
|
424
|
-
|
|
425
|
-
/** The triad {3,6,9} — the non-units, the merkaba's axis. */
|
|
426
|
-
export const triad = (): number[] => backedBy('lean_units_are_six', runtimeTriad(), 'the triad')
|
|
427
|
-
|
|
428
|
-
/** The doubling orbit 1,2,4,8,7,5 — six turns before it returns to where it began. */
|
|
429
|
-
export const orbit = (): number[] =>
|
|
430
|
-
backedBy('lean_millenniumfloor_riemann_reflection_and_heart', runtimeOrbit(), 'the doubling orbit')
|
|
431
|
-
|
|
432
|
-
/** THE MOD-3 CLASSES — the merkaba's axis and its two tetrahedra, computed from the partition rather than
|
|
433
|
-
* typed. These were the literals I missed when I claimed the tooling held no hardcoded ℤ/9 sets: the claim
|
|
434
|
-
* was scoped to the three patterns I had grepped for, which is how a check confirms what it was told to look
|
|
435
|
-
* for and nothing else. Backed by the theorem that proves the classes partition the ring 3+3+3. */
|
|
436
|
-
export const tetA = (): number[] =>
|
|
437
|
-
backedBy('lean_merkaba_the_three_classes_partition_z9',
|
|
438
|
-
Array.from({ length: 9 }, (_, d) => d).filter((d) => d % 3 === 1), 'the first tetrahedron')
|
|
439
|
-
|
|
440
|
-
export const tetB = (): number[] =>
|
|
441
|
-
backedBy('lean_merkaba_the_three_classes_partition_z9',
|
|
442
|
-
Array.from({ length: 9 }, (_, d) => d).filter((d) => d % 3 === 2), 'the second tetrahedron')
|
|
443
|
-
|
|
444
|
-
/** The axis {3,6,0} — the same partition's third class, and the triad by another name. */
|
|
445
|
-
export const axis = (): number[] =>
|
|
446
|
-
backedBy('lean_merkaba_the_three_classes_partition_z9',
|
|
447
|
-
Array.from({ length: 9 }, (_, d) => d).filter((d) => d % 3 === 0), 'the axis')
|
package/src/api/lanes.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/** ── HOW MANY JOBS THIS MACHINE CAN ACTUALLY HOLD, WHICH IS NOT HOW MANY CORES IT HAS ─────────────────────
|
|
2
|
-
*
|
|
3
|
-
* `availableParallelism()` answers "how many things can run at once" and says nothing about whether they
|
|
4
|
-
* FIT. On this host that gap is not academic — measured, one `lean` process elaborating families.lean
|
|
5
|
-
* peaks at about 2.9 GB, so ten lanes is 29 GB of demand on a 32 GB machine from a single session. The
|
|
6
|
-
* machine does not refuse; it swaps, and the run gets slower while every core reads as busy.
|
|
7
|
-
*
|
|
8
|
-
* A peer session on uuidna reported a window where this host sat at 88% system time against 9% user with
|
|
9
|
-
* swap climbing — ten times more kernel than work, a machine moving pages rather than computing — and
|
|
10
|
-
* named the cause as a capacity function that is honest per process and blind to its neighbours. I could
|
|
11
|
-
* not verify that recording: the host has rebooted since and currently shows no swap in use at all. What I
|
|
12
|
-
* could verify is the arithmetic, and the arithmetic is worse than the framing, because cores were never
|
|
13
|
-
* the binding constraint. Memory is.
|
|
14
|
-
*
|
|
15
|
-
* So a lane budget is the smallest of three numbers, and the third is the neighbour term:
|
|
16
|
-
*
|
|
17
|
-
* cores what can run at once
|
|
18
|
-
* memory / perJob what fits, from memory that is actually reclaimable
|
|
19
|
-
* minus neighbours jobs of this kind already running, whoever started them
|
|
20
|
-
*
|
|
21
|
-
* THE NEIGHBOUR TERM NEEDS NO AGREEMENT BETWEEN SESSIONS. A shared budget would have to be negotiated,
|
|
22
|
-
* which means a protocol, which means every repo adopting it before any repo benefits. Yielding to jobs
|
|
23
|
-
* that are already running is unilateral: if each session does it alone, the sum is bounded anyway.
|
|
24
|
-
*/
|
|
25
|
-
import { availableParallelism, totalmem } from 'node:os'
|
|
26
|
-
import { execFileSync } from 'node:child_process'
|
|
27
|
-
|
|
28
|
-
/** Memory a checker may actually take: free plus the pages the OS can reclaim without swapping. `freemem()`
|
|
29
|
-
* counts only the free list and reports a few gigabytes on a machine with twenty reclaimable — budgeting
|
|
30
|
-
* from it would refuse lanes the machine can easily afford. */
|
|
31
|
-
export const reclaimableMB = (): number => {
|
|
32
|
-
try {
|
|
33
|
-
const out = String(execFileSync('vm_stat', [], { stdio: 'pipe' }))
|
|
34
|
-
const page = Number(out.match(/page size of (\d+)/)?.[1] ?? 4096)
|
|
35
|
-
const pages = (k: string) => Number(out.match(new RegExp(`Pages ${k}:\\s+(\\d+)`))?.[1] ?? 0)
|
|
36
|
-
const usable = pages('free') + pages('inactive') + pages('speculative') + pages('purgeable')
|
|
37
|
-
if (usable > 0) return (usable * page) / (1024 * 1024)
|
|
38
|
-
} catch { /* not macOS, or vm_stat unavailable — fall through */ }
|
|
39
|
-
return (totalmem() / (1024 * 1024)) / 2 // half of physical: a guess, and named as one
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Jobs of this kind already running, whoever started them — or NULL when it could not be measured.
|
|
43
|
-
*
|
|
44
|
-
* The first version ran `pgrep -c`, counted the output, and caught every failure as zero. macOS pgrep has
|
|
45
|
-
* no `-c` flag — that is Linux — so it printed a usage error to stderr, threw, and the catch reported "no
|
|
46
|
-
* neighbours" on every call. The term never fired once, and nothing said so: a check that cannot run,
|
|
47
|
-
* answering all-clear. Three answers, not two, is the rule that catches this — none, some, and unknown are
|
|
48
|
-
* different, and only the first two are a measurement. */
|
|
49
|
-
export const neighbours = (procName: string): number | null => {
|
|
50
|
-
try {
|
|
51
|
-
const out = String(execFileSync('pgrep', ['-x', procName], { stdio: ['ignore', 'pipe', 'ignore'] }))
|
|
52
|
-
return out.split('\n').filter((l) => l.trim().length).length
|
|
53
|
-
} catch (e: any) {
|
|
54
|
-
// pgrep exits 1 with NO output when nothing matched: that is a real measurement of zero.
|
|
55
|
-
if (e?.status === 1 && !String(e?.stdout ?? '').trim()) return 0
|
|
56
|
-
return null // anything else — missing pgrep, wrong flag, no permission — is UNKNOWN, not zero
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export type Budget = { lanes: number; cores: number; byMemory: number; running: number | null; perJobMB: number; why: string }
|
|
61
|
-
|
|
62
|
-
/** The lane count, with every term it was derived from, so a caller can print WHY rather than a bare number. */
|
|
63
|
-
export const laneBudget = (opts: { perJobMB: number; procName: string; envLanes?: string }): Budget => {
|
|
64
|
-
const cores = availableParallelism?.() ?? 4
|
|
65
|
-
const forced = Number(opts.envLanes ?? '')
|
|
66
|
-
const perJobMB = Math.max(1, opts.perJobMB)
|
|
67
|
-
const byMemory = Math.max(1, Math.floor(reclaimableMB() / perJobMB))
|
|
68
|
-
const running = neighbours(opts.procName)
|
|
69
|
-
// UNKNOWN IS NOT ZERO. When the neighbour count cannot be measured the budget halves rather than assuming
|
|
70
|
-
// the machine is empty — the failure that matters here is claiming capacity somebody else is already using.
|
|
71
|
-
const base = Math.min(cores, byMemory)
|
|
72
|
-
const lanes = forced > 0 ? forced
|
|
73
|
-
: running === null ? Math.max(1, Math.floor(base / 2))
|
|
74
|
-
: Math.max(1, base - running)
|
|
75
|
-
const why = forced > 0
|
|
76
|
-
? `forced to ${forced} by the environment`
|
|
77
|
-
: running === null
|
|
78
|
-
? `min(cores ${cores}, memory ${byMemory} at ~${perJobMB}MB each) halved — the neighbour count could NOT be measured on this host`
|
|
79
|
-
: `min(cores ${cores}, memory ${byMemory} at ~${perJobMB}MB each) minus ${running} already running`
|
|
80
|
-
return { lanes, cores, byMemory, running, perJobMB, why }
|
|
81
|
-
}
|