skynet-graph 1.2.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 (213) hide show
  1. package/CONTRIBUTING.md +22 -0
  2. package/LICENSE +661 -0
  3. package/README.md +245 -0
  4. package/bin/sg +20 -0
  5. package/concepts/README.md +23 -0
  6. package/concepts/_substrate/Claim/Confidence/Trusted.json +6 -0
  7. package/concepts/_substrate/Claim/Confidence.json +10 -0
  8. package/concepts/_substrate/Claim/Freshness/Stale.json +7 -0
  9. package/concepts/_substrate/Claim/Freshness.json +5 -0
  10. package/concepts/_substrate/Claim/Verification/Refuted.json +6 -0
  11. package/concepts/_substrate/Claim/Verification.json +6 -0
  12. package/concepts/_substrate/Claim.json +4 -0
  13. package/concepts/_substrate/Frontier/InBeam.json +6 -0
  14. package/concepts/_substrate/Frontier/Stuck.json +6 -0
  15. package/concepts/_substrate/Frontier.json +5 -0
  16. package/concepts/_substrate/Intake/ToTask.json +22 -0
  17. package/concepts/_substrate/Intake/Typed.json +10 -0
  18. package/concepts/_substrate/Intake.json +27 -0
  19. package/concepts/_substrate/Task/Answer.json +12 -0
  20. package/concepts/_substrate/Task/Complexity/Atomic.json +5 -0
  21. package/concepts/_substrate/Task/Complexity/Compound/Expansion.json +7 -0
  22. package/concepts/_substrate/Task/Complexity/Compound.json +6 -0
  23. package/concepts/_substrate/Task/Complexity.json +6 -0
  24. package/concepts/_substrate/Task/EvalComplexity.json +13 -0
  25. package/concepts/_substrate/Task/ReportUp.json +6 -0
  26. package/concepts/_substrate/Task/Rollup.json +10 -0
  27. package/concepts/_substrate/Task.json +5 -0
  28. package/concepts/clinical/Diagnosis/Medication.json +6 -0
  29. package/concepts/clinical/Diagnosis.json +15 -0
  30. package/concepts/clinical/Observation/LabValue/OutOfRange.json +6 -0
  31. package/concepts/clinical/Observation/LabValue.json +5 -0
  32. package/concepts/clinical/Observation.json +6 -0
  33. package/concepts/common/Document/pathBasket.json +6 -0
  34. package/concepts/common/Document.json +3 -0
  35. package/concepts/common/Edge/Distance.json +13 -0
  36. package/concepts/common/Edge/Stay/LongStay.json +8 -0
  37. package/concepts/common/Edge/Stay.json +8 -0
  38. package/concepts/common/Edge/Travel/LongTravel.json +16 -0
  39. package/concepts/common/Edge/Travel/ShortTravel.json +11 -0
  40. package/concepts/common/Edge/Travel/targetNode.json +7 -0
  41. package/concepts/common/Edge/Travel.json +7 -0
  42. package/concepts/common/Edge.json +3 -0
  43. package/concepts/common/Vertice.json +3 -0
  44. package/concepts/supply/Fulfillment.json +10 -0
  45. package/concepts/supply/Inventory/Reorder.json +7 -0
  46. package/concepts/supply/Inventory.json +5 -0
  47. package/concepts/supply/Procurement/SupplierConfirm.json +6 -0
  48. package/concepts/supply/Procurement.json +8 -0
  49. package/concepts/supply/Transport.json +5 -0
  50. package/doc/API.md +556 -0
  51. package/doc/CAPABILITIES.md +373 -0
  52. package/doc/MODELISATION.md +511 -0
  53. package/doc/architecture.md +267 -0
  54. package/doc/concept-as-graph.md +379 -0
  55. package/doc/concept-learning.md +168 -0
  56. package/doc/creative-loop-map.md +202 -0
  57. package/doc/original-2016-doc.md +148 -0
  58. package/doc/usage.md +501 -0
  59. package/lib/authoring/abstract.js +401 -0
  60. package/lib/authoring/abstraction.js +190 -0
  61. package/lib/authoring/adapt.js +393 -0
  62. package/lib/authoring/ancestry.js +216 -0
  63. package/lib/authoring/author.js +147 -0
  64. package/lib/authoring/bounded-merge.js +57 -0
  65. package/lib/authoring/canon.js +158 -0
  66. package/lib/authoring/clock.js +123 -0
  67. package/lib/authoring/combinator.js +92 -0
  68. package/lib/authoring/compete.js +76 -0
  69. package/lib/authoring/compose-hotspot.js +314 -0
  70. package/lib/authoring/compress.js +279 -0
  71. package/lib/authoring/concept-net.js +254 -0
  72. package/lib/authoring/concepts.js +66 -0
  73. package/lib/authoring/context-project.js +277 -0
  74. package/lib/authoring/contract.js +476 -0
  75. package/lib/authoring/corpus-pack.js +125 -0
  76. package/lib/authoring/cost-probe.js +86 -0
  77. package/lib/authoring/crystallize.js +555 -0
  78. package/lib/authoring/dag-decompose.js +256 -0
  79. package/lib/authoring/dataset-adapter.js +253 -0
  80. package/lib/authoring/debug-provider.js +92 -0
  81. package/lib/authoring/decompose.js +343 -0
  82. package/lib/authoring/emittability.js +236 -0
  83. package/lib/authoring/equilibrium.js +160 -0
  84. package/lib/authoring/extract.js +153 -0
  85. package/lib/authoring/forest.js +55 -0
  86. package/lib/authoring/forge-fallback.js +116 -0
  87. package/lib/authoring/givens.js +121 -0
  88. package/lib/authoring/glossary.js +177 -0
  89. package/lib/authoring/grammar-graph.js +191 -0
  90. package/lib/authoring/granularity.js +80 -0
  91. package/lib/authoring/graph-net.js +108 -0
  92. package/lib/authoring/ground.js +148 -0
  93. package/lib/authoring/higher-order.js +85 -0
  94. package/lib/authoring/hotspot.js +132 -0
  95. package/lib/authoring/hysteresis.js +85 -0
  96. package/lib/authoring/index.js +106 -0
  97. package/lib/authoring/lattice-morphism.js +61 -0
  98. package/lib/authoring/lattice-pack.js +148 -0
  99. package/lib/authoring/leaf-io.js +77 -0
  100. package/lib/authoring/library.js +156 -0
  101. package/lib/authoring/lifecycle.js +92 -0
  102. package/lib/authoring/loop.js +193 -0
  103. package/lib/authoring/master-loop.js +132 -0
  104. package/lib/authoring/mdl.js +209 -0
  105. package/lib/authoring/memo-stability.js +122 -0
  106. package/lib/authoring/method-explorer.js +138 -0
  107. package/lib/authoring/method-pack.js +181 -0
  108. package/lib/authoring/method.js +202 -0
  109. package/lib/authoring/mine.js +510 -0
  110. package/lib/authoring/mount.js +119 -0
  111. package/lib/authoring/negotiate.js +100 -0
  112. package/lib/authoring/parametric.js +139 -0
  113. package/lib/authoring/reaggregate.js +75 -0
  114. package/lib/authoring/rebalance.js +157 -0
  115. package/lib/authoring/recall.js +135 -0
  116. package/lib/authoring/registry.js +350 -0
  117. package/lib/authoring/relearn.js +147 -0
  118. package/lib/authoring/retention.js +89 -0
  119. package/lib/authoring/segment-proxy.js +114 -0
  120. package/lib/authoring/serve-leaf.js +64 -0
  121. package/lib/authoring/slot-aware-serve.js +77 -0
  122. package/lib/authoring/sound-invoke.js +59 -0
  123. package/lib/authoring/split-serve.js +74 -0
  124. package/lib/authoring/ste.js +239 -0
  125. package/lib/authoring/stock.js +101 -0
  126. package/lib/authoring/store.js +94 -0
  127. package/lib/authoring/supervise.js +138 -0
  128. package/lib/authoring/support.js +131 -0
  129. package/lib/authoring/task-mirror.js +51 -0
  130. package/lib/authoring/typed-loop.js +160 -0
  131. package/lib/authoring/validate.js +569 -0
  132. package/lib/authoring/widen.js +88 -0
  133. package/lib/combos/appliance.js +189 -0
  134. package/lib/combos/critique.js +377 -0
  135. package/lib/combos/defaults.js +86 -0
  136. package/lib/combos/durable-runner.js +115 -0
  137. package/lib/combos/forge.js +209 -0
  138. package/lib/combos/index.js +86 -0
  139. package/lib/combos/learning-library.js +253 -0
  140. package/lib/combos/mixture-serve.js +193 -0
  141. package/lib/combos/plan-loop.js +192 -0
  142. package/lib/combos/proxy-cache.js +272 -0
  143. package/lib/combos/self-mod.js +94 -0
  144. package/lib/durable/audit.js +102 -0
  145. package/lib/durable/checkpoint-store.js +550 -0
  146. package/lib/durable/fold.js +62 -0
  147. package/lib/durable/interpreter.js +242 -0
  148. package/lib/durable/xlate.js +185 -0
  149. package/lib/graph/Graph.js +2486 -0
  150. package/lib/graph/expr.js +307 -0
  151. package/lib/graph/index.js +26 -0
  152. package/lib/graph/log.js +134 -0
  153. package/lib/graph/objects/Concept.js +382 -0
  154. package/lib/graph/objects/Entity.js +503 -0
  155. package/lib/graph/objects/Node.js +57 -0
  156. package/lib/graph/objects/PathMap.js +557 -0
  157. package/lib/graph/objects/Segment.js +100 -0
  158. package/lib/graph/tasks/stabilize.js +59 -0
  159. package/lib/graph/tasks/taskflow.js +247 -0
  160. package/lib/index.js +122 -0
  161. package/lib/load.js +132 -0
  162. package/lib/providers/backends.js +117 -0
  163. package/lib/providers/borderline.js +129 -0
  164. package/lib/providers/cache.js +226 -0
  165. package/lib/providers/canonicalize.js +198 -0
  166. package/lib/providers/constat.js +107 -0
  167. package/lib/providers/geo.js +53 -0
  168. package/lib/providers/index.js +116 -0
  169. package/lib/providers/intake.js +263 -0
  170. package/lib/providers/llm-local.js +88 -0
  171. package/lib/providers/llm.js +236 -0
  172. package/lib/providers/local-host.js +197 -0
  173. package/lib/providers/merge-consistency.js +162 -0
  174. package/lib/providers/nogood.js +149 -0
  175. package/lib/providers/reason-loop.js +223 -0
  176. package/lib/providers/semiring.js +285 -0
  177. package/lib/providers/solver-fork.js +163 -0
  178. package/lib/providers/stats.js +228 -0
  179. package/lib/providers/verify.js +120 -0
  180. package/lib/runtime/index.js +135 -0
  181. package/lib/runtime/invoke-pool.js +92 -0
  182. package/lib/runtime/protocol.js +210 -0
  183. package/lib/runtime/transport-socket.js +77 -0
  184. package/lib/runtime/worker-entry.js +31 -0
  185. package/lib/sg/cli.js +601 -0
  186. package/lib/sg/log-sinks.js +214 -0
  187. package/lib/sg/mcp.js +395 -0
  188. package/lib/sg/proxy-run.js +66 -0
  189. package/lib/sg/serve-demo.js +185 -0
  190. package/lib/sg/serve.js +205 -0
  191. package/lib/sg/trace.js +118 -0
  192. package/lib/studio/protocol.js +45 -0
  193. package/lib/studio/public/app.js +310 -0
  194. package/lib/studio/public/components/ConceptEditor.js +43 -0
  195. package/lib/studio/public/components/ConceptTree.js +43 -0
  196. package/lib/studio/public/components/CorpusPanel.js +68 -0
  197. package/lib/studio/public/components/ForkTree.js +36 -0
  198. package/lib/studio/public/components/GrammarGraph.js +99 -0
  199. package/lib/studio/public/components/GraphCanvas.js +156 -0
  200. package/lib/studio/public/components/Inspector.js +48 -0
  201. package/lib/studio/public/components/LearningPanel.js +85 -0
  202. package/lib/studio/public/components/PromptConsole.js +46 -0
  203. package/lib/studio/public/components/ProviderTrace.js +39 -0
  204. package/lib/studio/public/components/SessionSplit.js +47 -0
  205. package/lib/studio/public/components/TilingOverlay.js +40 -0
  206. package/lib/studio/public/components/Timeline.js +57 -0
  207. package/lib/studio/public/index.html +26 -0
  208. package/lib/studio/public/styles.css +185 -0
  209. package/lib/studio/public/ws.js +58 -0
  210. package/lib/studio/server.js +130 -0
  211. package/lib/studio/session.js +397 -0
  212. package/lib/studio/studio.js +149 -0
  213. package/package.json +42 -0
@@ -0,0 +1,379 @@
1
+ # Concept-as-graph — the target system (Use 2)
2
+
3
+ > **Audience:** a reader who knows the substrate (Use 1 — a rule-driven graph that stabilizes typed-fact concepts
4
+ > to a fixpoint, with JTMS retraction and git-like revisions; see [architecture.md](architecture.md)) and wants
5
+ > the high-level goal built on top of it. Everything here is **host-side and ZERO-CORE** — it does not touch
6
+ > `lib/graph/`, and it is **additive**: Use 1 needs none of it. The canonical, specialist-confronted design and
7
+ > the build LOGs are kept in the project's local R&D notes. This doc is the durable summary.
8
+
9
+ ## 0. The thesis, in one paragraph
10
+
11
+ A hard problem blows up an LLM's context window. The fix here: a learned **concept-graph is a method** — a
12
+ reusable sub-graph that goes from a parameterized state **A** to a parameterized state **B**. To its *user* it is
13
+ a single black box with a **typed contract**; to its *author* it is a body of productions. A supervisor goes from
14
+ a human formulation to executed cases by **composing / forging / refining** methods, and **the bounded context is
15
+ the abstraction barrier** — you carry the *contract*, not the *body*, opening a box only to refine it. Bounded
16
+ throughout by **K1**: only recurrent, typed, canonicalizable structure amortizes; genuinely novel reasoning stays
17
+ in the model.
18
+
19
+ ![the two uses](img/two-uses.svg)
20
+
21
+ ## 1. The core object — a two-faced method
22
+
23
+ ![a concept-graph is a two-faced method](img/concept-as-graph.svg)
24
+
25
+ A concept-graph is a **two-faced** object (formally an HRG non-terminal — Habel 1992; Drewes-Kreowski-Habel 1997):
26
+
27
+ - **Outer face — a method with a defeasible typed contract.** A *separation triple* (O'Hearn-Reynolds-Yang 2001):
28
+ a **read-footprint**, a **write-footprint**, a **precondition** over the reads, a **postcondition** over the
29
+ writes, and an **effect** tag. This is the black box a caller composes on. It is **defeasible**: for a *learned*
30
+ method the post is an induced hypothesis — sound on observed cases, possibly wrong on the next — so the contract
31
+ gives **eventual soundness** (assume-at-compose, **assert-at-runtime**, retract-and-blame), not static soundness.
32
+ - **Inner face — productions.** The concrete ways to realize A → B: `for` / `while` / `map` / `fold`. The grammar
33
+ over these productions is decidable; their *execution* over runtime-sized data is a fuel-bounded executor
34
+ (Turing-complete, totalized by a step budget). **Two regimes, never one badge.**
35
+
36
+ **A concept-graph is a method LIBRARY, not a single path.** The inner face holds an **ensemble of alternative
37
+ qualified subpaths** — the known methods for the *one* abstract problem A → B (a derivation forest). Its slots are
38
+ the **under-qualified tentacles** of those subpaths (under-qualified = abstract = a slot). Mount semantics:
39
+ dispatch the method, **unify the typed params** against the slots' `require`s, and the engine tries to complete
40
+ **at least one path**; if none completes, the frontier's unresolved `require`s surface as **hints** ("need a sort
41
+ X in role Y"); once the problem is solved exactly **one path stays active** — the others collapse locally or
42
+ remain as trace. This is the engine's *native* path semantics (the original travel domain: candidate routes,
43
+ `getPaths`/`PathMap`, pareto selection), not a new mechanism. The currently-built artifact
44
+ (`crystallizeStructural`'s one-template-per-signature + `mountTemplate`'s single imposed path) is the **degenerate
45
+ single-path case** of this object — a stage to generalize, not the definition.
46
+
47
+ ### Naming — the `concept-*` family (settled 2026-07-03)
48
+
49
+ The system uses several concept NATURES; the family name is a hyphenated term of art, identical in EN and FR
50
+ (searchable, and consistent with "concept-as-graph"). Two orthogonal axes — never encode both in one name:
51
+
52
+ | Name (EN = FR) | Body | Lives as |
53
+ |---|---|---|
54
+ | **concept-rule** (concept-règle) | the atomic authored unit: `require`/`ensure`/`provider`/`applyMutations` | `Concept.js`, the JSONC trees |
55
+ | **concept-sort** (concept-sorte) | a node of the isa lattice (kind / category / facet); its `childConcepts` edges are the subsumption; the synonym RING lives on its key | the material of selectional restrictions |
56
+ | **concept-method** (concept-méthode) | **the concept-as-graph of this document**: a derivation forest of qualified subpaths + role-typed slots, mounted parametrically zero-fire | `method.js`, crystallize, §1 above |
57
+ | **concept-meta** (concept-méta) | the reactive concepts that drive learning at the stabilize fixpoint | `RegistryMerge`, `Relearn` |
58
+
59
+ The **epistemic status is a QUALIFIER, never part of the type name**: *axiom* (authored) vs *learned/defeasible*
60
+ `{source, confiance}` — it applies uniformly to every nature (a learned isa edge, a learned ring alias, a
61
+ crystallized method). Likewise **"abstract" is a DEGREE, not a nature** (under-qualified = abstract = a slot):
62
+ a concept-method's abstraction is *measured* as open-slots/total-slots; a fully instantiated method is the same
63
+ object at degree 0.
64
+
65
+ Internal vocabulary (the figures' language): **role slot** (slot rôlé, `<stepKind>#<i>` — an antiUnify hole) ·
66
+ **qualification segment** (the parallel edge that types a slot) · **affinity segment** (a digram-mined AB·BC→AC
67
+ edge) · **mount** (monture — params placed into slots, zero-fire) · **restriction** (the per-slot isa cut).
68
+ Export unit: a **method-pack** (`.sgc`) = one concept-method + the transitive closure of its dependencies (the
69
+ concept-methods it uses, its sorts, the rings they require) + its contract (`post`/`postSlots`) + provenance,
70
+ versioned by the registry — concept-methods compose, so they ship with their dependencies.
71
+
72
+ ### Parameterization — typed named slots
73
+ A method is parameterized by other sub-graphs (the loop *body*, a predicate, an accumulator). This is
74
+ **higher-order in power, first-order in mechanics**: we never *infer* a body (undecidable — Huet 1975), the engine
75
+ *supplies* it by name → substitution. Four invariants keep it decidable and are **checked** by a lint
76
+ (`lib/authoring/method.js#lintMethod`): every slot is **(a) named (b) K1-typed (c) bound-by-ref, never solved-for
77
+ (d) tentacle-fixed**. The role of a slot — a **param** (typed, part of the contract + memo key) vs a **`coll`**
78
+ (the cases iterated over, *excluded* from the key) — is assigned by the method, not intrinsic to a field. Building
79
+ blocks: `applySubgraphArg` / `mapTemplate` (apply a sub-graph param, fan a body per element with fresh ids),
80
+ `selectCluster` (case-parameterized selection by typed gates).
81
+
82
+ The frontier itself is **declared, not inferred**, and **reified** as a first-class `FrontierSignature` on the
83
+ crystallized schema (`schema.frontier`, a sibling of `schema.contract` — it serializes with the tree and round-trips
84
+ through rollback): `{ params:[{name, sort, field, role, requiredFacts}], summaryFacts, appConditions }`. A param's
85
+ **`sort ∈ node-ref | method-ref | predicate-ref`** makes an endpoint and a *behavioral* param (a sub-method body, a
86
+ stop predicate) the **same** relativize/instantiate hole differing only by `sort` — so the library becomes an algebra
87
+ of combinators, dispatch is keyed on the canonical interface, and an untyped behavioral param is rejected at author
88
+ time (`lintFrontier`, reusing the lint above). `summaryFacts` (the sound post the abstraction barrier carries) and
89
+ `appConditions` (the parent NACs) are the index's discriminants.
90
+
91
+ ## 2. Bounded context = the abstraction barrier
92
+
93
+ Composing abstract method-faces means **carrying the typed contract, not the body** — so the method library and
94
+ the bounded-context engine are *the same mechanism*. This is **by discipline, not automatic**: a bounded
95
+ projection at every join (`bounded-merge.js#boundedProject` crosses only the declared separator alphabet Σ_sep,
96
+ not the whole child), digests-not-bodies in the supervisor's context, and it is **only as strong as the
97
+ contracts** — an incomplete contract forces opening the box, and the bound is gone. The one principled bridge from
98
+ human prose into a typed goal (domain-recognize → decompose to start/goal → snap to vocabulary → out-of-vocab
99
+ gate) is the system's **soundness boundary** (still open — see §8).
100
+
101
+ ## 3. Forge · reuse · compose — tools-from-tools
102
+
103
+ The library grows by a **wake/sleep** loop (DreamCoder, Ellis 2021; EBG, Mitchell 1986):
104
+
105
+ - **WAKE** — the supervisor selects + composes existing methods (path-search / HTN, gated by the typed contracts).
106
+ 0 model calls in-vocabulary; +1 bridge call per genuine gap.
107
+ - **SLEEP** — real **case traces** → **anti-unification / LGG** (Plotkin 1970; Stitch, Bowers 2023) → a typed
108
+ parameterized method → the library. Admission is **MDL-gated in model-call currency** (`abstraction.evaluate`
109
+ scores model calls, not `applies`), **memo-surface-preserving** (`memo-stability.js`, fail-closed), and
110
+ **non-overlap / priority-ordered** (a distilled method's pre must be disjoint from incumbents, or it creates a
111
+ critical pair that breaks composition-confluence — Plump 1993).
112
+ - **The multiplier — tools-from-tools.** The human capacity is to forge a composite tool (a non-terminal that
113
+ isn't a primitive), then compose tools into bigger tools. That recursion lets a **K1-bounded** library punch
114
+ above its ceiling: few typed composites → a huge combinatorial space, no single combination novel.
115
+ - **The micro-task floor.** Everything decomposes until each leaf is **either a cached/typed method OR a micro-task
116
+ a small fast LLM does easily**. A *missing* contract is not a failure — drop a small-LLM micro-task in its place.
117
+ So contract coverage is a **cost/coverage gradient**, not a soundness cliff (the runtime assert still guards).
118
+
119
+ The abstractivation tooling (`abstract.js`): `relativize` / `instantiate` (created ids → holes, frontier refs
120
+ bound at the call site), `antiUnify` (the Plotkin LGG soundness check), `emitMethodAsSubgraph` (serialize a
121
+ derived sub-graph into a re-mountable parameterized method via the engine-native `Graph#getMutationFromPath` — the
122
+ generalization of travel-path mounting). This is what makes cross-problem **structural** transfer sound + non-zero
123
+ (it was zero with a flat cache — the absolute ids didn't transfer).
124
+
125
+ The crystallizer's frontier is **declared, not inferred** (`mine.js#declaredCtx` reads each endpoint off its declared
126
+ field rather than scanning the literal-id surface gated on `knownIds`) — fixing the `$`-ref-endpoint and k-ary cases
127
+ the scan missed, and reifying the `FrontierSignature` (§1). Declaring re-opens an id-space hazard the `knownIds` scan
128
+ closed by construction, so a **soundness gate** refuses any method whose parameterized form would leak a learning id at
129
+ replay: an **un-holed** segment endpoint (an endpoint the declaration missed), a **base-prefix phantom** (an external
130
+ id colliding with `<base>_…` that `relativize` mis-folds into the base id-space — `hasHoles` cannot see it), or two
131
+ endpoints that **collapse** to one hole by value-coincidence. Each refusal was adversarial-review-reproduced; together
132
+ they restore *every created segment endpoint is base-derived or a bound, distinct frontier hole*.
133
+
134
+ ## 4. Build / execute — the graph designs the method, a durable engine runs it
135
+
136
+ ![build / execute separation](img/build-execute.svg)
137
+
138
+ - **The graph BUILDS + TESTS the method** (the belief-view: decidable, traceable, defeasible). In-graph
139
+ "execution" is *validation* of the algorithm on cases — concepts advanced by the one stabilization loop.
140
+ - **A separate durable WORKFLOW ENGINE EXECUTES** a compiled translation of the validated method (durable,
141
+ crash-resumable, at scale). This is the **belief / durable boundary**: the belief-view is a reactive view over
142
+ case *progress*; durable effects + exactly-once + crash-resume live in the executor underneath.
143
+
144
+ The durable executor (`lib/durable/`, ZERO-CORE, two backends — in-memory + `node:sqlite`):
145
+
146
+ | Piece | Role |
147
+ |---|---|
148
+ | **`checkpoint-store.js`** (Layer A) | the durable **marking** — tokens(runId, recordId, placeId, status, …) walked through a workflow-net; the content-addressed **memo** (key = FactsDigest, the durable sibling of `cache.js`); the createdRefs rollback set. Crash-safety = lease-expiry + `rollbackInflight`, with a **fencing token** (a monotonic persisted leaseId) so a re-claimed lease can't be corrupted by a zombie worker. |
149
+ | **`xlate.js`** (C-xlate) | `compileMethod(spec) → net` — a method spec → a workflow-net `{select, task, map, join, fold}`; `validateNet` is a structural lint. |
150
+ | **`interpreter.js`** (Layer B) | `runFlow(store, runId, net, …)` drains case records as tokens: typed `select` routing (via `expr.js`), content-memoized `task` micro-tasks, `map` fan-out, the fold-back **JOIN** (the cardinality fan-in), per-case determinism, fuel-bounded termination. |
151
+ | **`fold.js`** | the JOIN's monoid algebra (via `semiring.js`) — a commutative monoid fold is **order-independent** (non-deterministic throughput, deterministic belief); `concat`/`merge` are element-index-sorted. |
152
+ | **`audit.js`** (C-audit) | read-only inspection — the **derivation forest** per record, the verdict (done/failed/pending), the **blame** traceable to the exact step, run totals. The audit trail no surface-similarity store can give. |
153
+
154
+ **Soundness in the executor:** a **map ∘ reduce** equals the open-the-box computation; the JOIN is crash-resumable
155
+ at every cut; a failed shard **fail-fasts** its group (never a silent partial fold); a per-step **contract guard**
156
+ asserts the post *before* commit (a wrong learned post is quarantined, never committed downstream). Measured: a
157
+ recurrent 24-case stream costs **6 model calls vs 24** for retrieve-and-adapt, **12/12 correct on a mid-stream
158
+ drift vs 0/12** (stale), replaying across a process restart at **0 calls**.
159
+
160
+ ## 5. Soundness under composition — C-contract & the un-learn moat
161
+
162
+ `lib/authoring/contract.js` is the defeasible separation-triple checker — the "central hole" of the conception,
163
+ built behind a specialist confrontation (theory / engine / adversary):
164
+
165
+ - **Assume at compose-time.** `checkCompose(M1, M2)` checks `post(M1) ⊨ pre(M2)` over every shared fact, by
166
+ **per-key abstract-domain entailment** (interval + finite-domain — Cousot-Cousot 1977; **not** atom-by-atom, so
167
+ `x>3 ∧ x<5 ⊨ x==4` and `x≥5 ⊭ x≥7` are both decided right). It **never false-accepts**: anything out of the
168
+ monadic, ground fragment (disjunction, two-key relations, non-ground footprints, an under-determined post) →
169
+ **`escalate`** (open the box / a micro-LLM), never a silent pass.
170
+ - **Assert at runtime.** `assertPost` is the runtime monitor — in the executor (assert-before-commit) and in the
171
+ belief-view (the post realized as an `ensure`). Plus the gates the entailment structurally can't do: **G1**
172
+ frame-completeness (the keys the body *actually touched* ⊆ the declared write), **G2** the effect-tag (an
173
+ `external` post must be confirmed by a ground-truth oracle, not the internal fact), **G3** footprint-cycle
174
+ rejection (Tarjan-SCC — no JTMS oscillation).
175
+ - **Retract + blame + revise = the moat.** On a violation the **JTMS retracts** the method (belief-view) or the
176
+ executor **quarantines** the token (blame reason), and `reviseOnBlame` **specializes the precondition** with the
177
+ counterexample's discriminating atom (CEGIS — not method removal). `satisfies` then excludes the failing case
178
+ from selection while still admitting the valid ones. **This is principled UN-learning** — the differentiator no
179
+ prose memory / RAG / skill-library has: a stale skill in a vector store stays retrievable; here the typed
180
+ premise is *in* the belief, so when it falls the derivation retracts and the library narrows the method's claim.
181
+
182
+ The whole loop — **assume-compose / assert-settle / retract-blame / revise** — spans the build, execute, **and**
183
+ belief layers, on the real engine (`examples/poc/contract-compose.js`, `durable-contract.js`, `contract-unlearn.js`).
184
+
185
+ ## 6. The supervisor control loop & the library
186
+
187
+ `authoring/master-loop.js` — a standing controller that climbs a **value-of-computation ladder** per problem and
188
+ takes the first arm that resolves at acceptable cost:
189
+
190
+ ```
191
+ MATCH exact cache hit on the K1 signature → 0 model calls
192
+ RETRIEVE fuzzy recall → typed VERIFY → 0 (full) or partial cost
193
+ FORGE fork + LLM + crystallize into the library → full cost; warms the library
194
+ ESCALATE a method deopted K times → always re-forge / LLM → full cost, never cached (the floor)
195
+ ```
196
+
197
+ | Module | Role |
198
+ |---|---|
199
+ | **`recall.js`** | FUZZY-RECALL → TYPED-VERIFY. Recall orders (embedding/similarity); verify admits (`full`/`partial`/`reject`). A high-similarity but structurally-different method is **rejected**, never falsely replayed — *fuzziness in recall, exactness in truth*. |
200
+ | **`mount.js`** | the 3-regime MOUNT policy: **instance** (fork-per-case, the safe default) / **inline** (`addConcept`, read-only frontier only) / **frozen** (warm-cache replay + deopt-guard) / **escalate** (the K1 floor), with hysteresis + a well-founded deopt-rank (termination). |
201
+ | **`../providers/cache.js`** | the derivation cache — content-addressed memo over a provider, keyed on the canonical justification of a cast (the fast/episodic half of CLS; the durable sibling lives in the executor's memo). |
202
+ | **`crystallize.js` · `mine.js` · `abstraction.js` · `memo-stability.js`** | FORGE → library (§3): mine producer→consumer chains, compose, MDL-gate, install fail-closed. |
203
+ | **`reaggregate.js`** | defeasible RE-AGGREGATION — a cleaner-on-retract un-pushes a contribution + re-folds, so a derived *summary* (not just the belief) updates on drift. |
204
+ | **`library.js`** | the **O(1) dispatch index** (consume `libraryKey`): given a target `FrontierSignature` (the abstract mechanism), a bucket lookup → refine by application-conditions over the call-site → **ranked** candidates (weighted). A *lookup*, **never a corpus search** (HRG-parsing is NP-complete — Lange-Welzl 1987). This is the structuring↔concept-DLL juncture. |
205
+ | **`combinator.js`** | the dispatch→**MOUNT** bridge: a higher-order concept fills its behavioral hole with a dispatched fragment via require-resolution + `applySubgraphArg` — so a concept **reuses another's** learned method when their signatures match (recombination at 0 calls). The re-fire guard is a distinct durable fact, **not** the self-flag (the `_name` marker uncasts on de-apply). |
206
+ | **`adapt.js`** | `adaptOrForge` — the retrieve-or-forge drive *over* the dispatch: RETRIEVE (a template for this signature = a hit, 0 calls) / FORGE-or-ADAPT (the model builds it, reusing dispatched neighbours = structural reuse + content forge) / VERIFIER-GATE (a sound contract) / index-back (**amortise**: the next encounter hits). The structure-mapping realization of the ladder above. |
207
+
208
+ **The two grammars are one, in two levels.** The supervisor's abstract mechanism is the *structuring* grammar (abstract
209
+ productions with non-terminal holes); the library is the *concept-DLL* grammar (learned terminals). They are not rivals
210
+ to reconcile (that implies a costly translator) but **two levels of one graph-grammar**; their juncture is a
211
+ **K1-canonical interface alphabet** — the `FrontierSignature` + app-conditions, a *snapped separator* (the impedance is
212
+ at the entrance: a prose scaffold needs C0; a typed scaffold couples cleanly). Formally this is **structure-mapping**
213
+ (Gentner 1983: the abstract mechanism = the relational structure, library methods = source domains, a dispatch = the
214
+ analogy) and **conceptual blending** (`antiUnify` = generalize-and-rebind). The result is **combinational + exploratory
215
+ creativity** (Boden 1990) over a learned grammar — *verifier-gated search*, with the genuinely-novel primitive deferred
216
+ to the model (K1) and a slow *transformational* loop alongside (crystallization invents new non-terminals).
217
+
218
+ **Persistence & portability** (`store.js` · `method-pack.js`): the warm library survives a restart (a write-through
219
+ `store` re-loads + replays at 0 calls) and **ships between deployments** as a `.sgc` **method package** (the sibling
220
+ of the authored-grammar `corpus-pack`). The version gate covers **both** replay paths (a stale-version method never
221
+ replays verbatim); the typed verify re-gates on the receiver, so a structurally-foreign method is rejected.
222
+
223
+ ## 7. The two decidability regimes (keep them honest)
224
+
225
+ 1. **A decidable method GRAMMAR** above (composition / parameterization — first-order named slots, a well-founded
226
+ mount-rank). **2. A fuel-bounded EXECUTOR** at the case layer (while / fold over runtime-sized data =
227
+ Turing-complete, totalized by a step budget; exhaustion is a *cutoff*, not a fixpoint). Determinism of
228
+ *triggering* gives **confluence**, not termination, not decidability of plan-existence (recursive-HTN
229
+ plan-existence is undecidable — Erol-Hendler-Nau 1996). Never one badge for both regimes.
230
+
231
+ ## 8. Status & honest lines
232
+
233
+ > **Update (2026-07-13).** The blocks below are dated status snapshots and stand as written. Since
234
+ > then the bounded-context thesis has shipped as a product combo: **C7 `createPlanLoop`** (decompose
235
+ > → bounded projection per leaf → serve → rebalance → verified reassembly), on the standalone bricks
236
+ > `dag-decompose`, `context-project` (the `stratComplete` stratified rendering), `givens` and
237
+ > `leaf-io` — measured cross-domain at N=200/domain; and **C9 `createCriticalMind`** (the external
238
+ > critical mind) is promoted to the library + MCP surface. The consolidated per-capability numbers
239
+ > and limits live in **[CAPABILITIES.md](CAPABILITIES.md)** (the zoom: F2; the critical mind: F5).
240
+
241
+ **Built + measured (2026-07-01, ZERO-CORE throughout, 759 tests at the time — the full repo suite is
242
+ 1350 today):** the middle spine (Bricks 1–3:
243
+ applySubgraphArg / lintMethod / selectCluster), the abstractivation slice (F6), the durable executor (Layer A +
244
+ B + the fold-back JOIN + fail-fast / fold-survivors / nested-fold + C-fail retry/escalate + audit), C-xlate,
245
+ C-contract (the checker · the §11.6 composition-soundness probe · the executor guard · the belief-view un-learn loop
246
+ · the **standing autonomous** revise loop, `relearn.js`), **C0 prose-intake** (the soundness front-door, `intake.js`),
247
+ the crystallization **structural miner** + the **declared-frontier** crystallizer with its reified `FrontierSignature`
248
+ (§1, §3), the supervisor loop + recall / mount / cache / reaggregate, and the **creative loop** (library **dispatch** +
249
+ combinator **mount** + `adaptOrForge`, §6), persistence + `.sgc` packs. The §11 stream gate **passes** on a live local
250
+ model (call-elision + wall-clock + durability + drift-soundness).
251
+
252
+ **The Construct → Method flex programme (built 2026-06-30, ZERO-CORE; each gated by an adversarial soundness review):**
253
+ the K1 ceiling read as a *gradient* — a loose, multi-path `Construct` crystallizes its **recurrent + typed**
254
+ fraction into an exact `Method`. **(§6.2) interface-only dispatch** — a loosened recall reaches a structurally-matching
255
+ in-bucket donor that the exact gate dropped, re-forges the differing content, and verifies the *adapted* method's own
256
+ contract (never replays the donor). **(§6.1) multi-path `Construct`** — a competition (propose N decompositions → pareto
257
+ `Select`) whose **clean-dominance survivor crystallizes** (a tie → flat-skip, a winner that flips → `signatureDetermined`
258
+ refuses): residency = isolated forks (the co-resident OR-forest = ATMS multi-context = FILED, justified — its one
259
+ case is the non-local frontier G1 already forbids). **(§6.4) the bidirectional patch** — the symmetric **widen**
260
+ (S-boundary climb) of the built narrow un-learn loop: ≥k verified positives generalise a method's pre to the LGG
261
+ (`widenOnVerified`, additive enum-union, methodId-gated), `recordWiden` demotes FROZEN→INSTANCE before the gate-relax,
262
+ and a reactive `Widen` loop (`widen.js`) drives it autonomously. **(§6.3) the ancestry oracle** — behind the now-sound
263
+ **E7/Σ_sep gate** (the bag-intersection separator horizon, not the lossy scalar treewidth / size-1 articulation cuts):
264
+ **(a)** monotone-safe digest-key enlargement gated by `separatorGate`; **(b)** content→param **promotion** — a leaf that
265
+ is a function of a below-horizon ancestor (`value(f)=N(s).g`, GOLEM ij-determinacy) is rebound to it, gated by a
266
+ **mandatory held-out strict-`===`** + an **exact relational post** (not the over-approximating band — the silent-
267
+ unsoundness spine the review found). Measured live (qwen3-8b): a real decomposition's structured-echo content promotes
268
+ (exact post), its novel content forges — the canon barrier read on the ancestry axis.
269
+
270
+ **The §6.1 / §6.2 deeper live measures (2026-07-01, qwen3-8b temp 0, deterministic).** **§6.2** — a real structural
271
+ forge reusing a surfaced donor skeleton generates **5.68× fewer completion tokens** (125→22) than a fresh whole-method
272
+ forge, the §6.2 gate holding (the "token win, not a call-count win" the layer promised). **§6.1** — the SELECTION-K1
273
+ fraction on real output (hardened by an adversarial review, verdict SOUND-WITH-CORRECTION): **winner-determinacy 2/3,
274
+ crystallizable 1/3** at Σ={taskClass} — the two axes kept separate (a determined-but-Pareto-tied winner is soundly
275
+ refused by the tie-gate, not a latency; an undetermined split can be a canon-granularity artefact). The fraction is a
276
+ property of the (workload, Σ) pair, and Regime-1 dispatch is *defeasible* (leans on the un-learn loop) — the honest
277
+ ceiling exhibited, not a defended scalar.
278
+
279
+ **Bounded subgraph extraction + embedded inference (2026-07-01, ZERO-CORE).** The fork-perf measure settled the scale
280
+ question: the fork deep-copy is O(working-graph) and **library-independent** (the conceptMap is passed by reference), so
281
+ forks don't dominate from a distilled mass; the real lever is the **multi-process ship** — `extractSubgraph`/`mergeSlice`
282
+ (`lib/authoring/extract.js`) = program slicing at the fork boundary (a k-hop ball + a **frozen frontier** = `contract.js`
283
+ G1 + an ATMS environment + a single-writer disjoint merge), ship-able to a worker process (27–245× cheaper than the whole
284
+ graph, cross-process proven). And the library can now run its **small functional model(s) in-process** —
285
+ `makeLocalAsk` (`lib/providers/llm-local.js`, node-llama-cpp/GGUF, proven on an RTX 5090), whose **grammar-constrained
286
+ decoding** enforces the canonicalization barrier at the *decode* level (a small model *cannot* emit a malformed typed
287
+ fact) — the self-contained-appliance endpoint and the signature-stability lever.
288
+
289
+ **Signature-stability screen (2026-07-01, ZERO-CORE) — the roadmap's 2-phase-minimum make-or-break, run + a decisive
290
+ finding.** *Does constrained decoding keep a small model's typed signature paraphrase-stable?* — instrumented live behind
291
+ an adversarial confront (formal + SOTA). Built the tracked paraphrase-stability profiler (`lib/authoring/emittability.js`,
292
+ the roadmap's Grammar-P1 instrument): unbiased-Simpson within-task collision + the pooled **V-measure homogeneity** that
293
+ catches the correctness-fatal COLLISION mode a naive within-task metric misses + a Fleiss-κ **vacuousness alarm** +
294
+ per-field marginals + a format-netting cross-arm compare. Four arms on vibethinker-3b (temp 0, deterministic) **INVERT the
295
+ roadmap's convergence #3**: grammar-constrained decoding is a signature-stability **hazard**, not its enabler. Format
296
+ closure is obtainable from a strong closed-vocab PROMPT alone (typedRate 1.00 on the 3B); once format is already closed the
297
+ grammar **distorts** the semantic choice (Park et al. 2024, Grammar-Aligned Decoding — κ 0.61 grammar vs 0.92 prompt-only,
298
+ flipping `severity`/`bugClass` across paraphrases the prompt-only arm keeps stable). ⇒ constrained decoding is **demoted to
299
+ format INSURANCE** (for unreliable prompt-compliance) with a measured distortion cost; the signature-stability lever is the
300
+ strong prompt + the (unchanged) Σ_sep / canon-vocabulary keystone. The screen passes on *stability IS achievable on a small
301
+ model* — via the prompt. The confront earned its keep: the naive arm-pair (grammar-vs-weak-free-text) reads "huge win" and
302
+ would have shipped "constrained decoding fixes stability"; the mechanism-isolating arm showed the win is pure format and the
303
+ semantics are hurt.
304
+
305
+ **⇒ The target-system ROADMAP** (kept in the project's local R&D trail) composes five grounded strategy axes
306
+ (compositional distillation · grammar/vocabulary design · small-LLM controller · evaluation · embedded inference) into a
307
+ staged plan whose spine is: one shared front gate (*does the real workload compose/recur?* — currently it does NOT, per
308
+ `hotspot.js`), the **interface-alphabet registry (Σ_sep) as keystone**, and **constrained decoding** as the cross-axis
309
+ enabler. The 2-phase minimum: the controller request/response bridge + the compose-gate + signature-stability-via-
310
+ constrained-decoding — because everything downstream is worthless if paraphrases fragment the key.
311
+
312
+ **STAGE-0 compositional gate (2026-07-01, ZERO-CORE) — the compress.js decision made honest.** The composed roadmap's ONE
313
+ shared front kill-gate (*does the workload COMPOSE?*) now has a cheap instrument: `lib/authoring/compose-hotspot.js`, the
314
+ depth-≥2 analog of `hotspot.js`. RE-PAIR over dispatch sequences → {compose-candidate · **already-flat-covered** (the
315
+ off-ramp: a composite spanning only ONE whole-task, which whole-task memo already serves) · unstable · too-rare} + a Minton
316
+ call-utility (`savedCalls ≈ distinctTasks−1`). The load-bearing condition (self-confronted): a persisted depth-≥2 method
317
+ pays ONLY when a sub-composite recurs across **distinct** whole-tasks. Result: it finds + quantifies shared sub-composites
318
+ (incl. a depth-3 via the RE-PAIR hierarchy) on a compositional workload, but on the EXISTING whole-task-chain workloads
319
+ returns **no candidate** → sharpening `hotspot.js`'s depth-1 finding: the current workloads compose neither at depth 1 nor
320
+ cross-task. The depth-≥2 hold/replay substrate already exists (`adapt.js#blendMethods`→`indexMethod`→`combinator.js#dispatchConcept`;
321
+ `synthesizeByBlend` to depth-3 at 0 calls) — so `compress.js` is now the ONLY missing half, and it is GATED behind this
322
+ detector run on a REAL compositional trace.
323
+
324
+ **Still genuinely open (gated):** the **compositional distillation ENGINE** `compress.js` (the corpus-wide DreamCoder/Stitch
325
+ abstraction sleep — the genuinely-missing operator that mints a recurring composite into one persisted method; **now gated
326
+ behind `compose-hotspot.js` returning a candidate on a real trace**, no longer a blind build); a **real-model streaming
327
+ `adaptOrForge`** measurement (calls × correct-under-drift); §6.3(b)
328
+ **mapping-φ** promotion; the **EAGER in-core `SubGraph`/`ZoomSegment` object** (FILED, justified). Whole-graph COW is
329
+ **deprioritized** (the deep-copy is cheap + library-independent — the multi-process extraction is the built lever instead).
330
+
331
+ **Hold these lines.** *Eventual*, not static, soundness for learned methods — via a load-bearing runtime monitor
332
+ over a **sound-but-incomplete** compose gate (deciding fragment-membership is undecidable — Rice; so "compose
333
+ without opening the box" is never an unconditional claim). A reactive **belief-view atop a durable executor** (not
334
+ itself one). Bounded by **K1**: amortization of recurrent typed methods, **not** capability extension — the win is
335
+ LLM-call/token **elision + drift-robustness + auditability**, not CPU speed. Bounded context is by **discipline**
336
+ (the fold-digest window), as strong as the contracts.
337
+
338
+ ## 9. Formal foundations — the reference frame (a super-seed)
339
+
340
+ Not a glossary: a **generative composite of ~9 formal systems**, each seeding one layer of the design, cross-checked by
341
+ two adversarial SOTA passes (2026-07-01). Every piece skynet already has maps to a named formal object; exactly ONE
342
+ operator is missing and exactly ONE thing is open research. Use this as the compass — it says *how* to build each layer;
343
+ the STAGE-0 gate (§8, `compose-hotspot`) says *when* it is warranted. **(2026-07-01) the gate is now interleave-robust**
344
+ — a PROVENANCE data-flow-edge tally replaces the positional contiguous tally (the flat screen is UNSOUND on the
345
+ stabilize fixpoint's non-deterministic emission order: it both fabricates spurious cross-lane composites and misses real
346
+ ones — proven live). The antiUnify certification + MDL selection remain compress.js's front half, still FILED. See the
347
+ composed-roadmap graft **G-0**.
348
+
349
+ | layer | formal home | status in skynet |
350
+ |---|---|---|
351
+ | **engine** (cast→fixpoint, synchronized phases, membrane=frontier) | **P-system / membrane computing** (Păun 1998/2000) — a *confluent/deterministic* one (so the non-deterministic power results do NOT transfer) | built (`Graph`, taskflow, `extractSubgraph`) |
352
+ | **representation** (slot = typed sub-path, FrontierSignature = interface) | **hyperedge-replacement grammar (HRG)** — slot = nonterminal hyperedge, frontier = tentacles, `blendMethods` = a production, `synthesizeByBlend` = μ-descent generation | **already an HRG, un-named** (`abstract.js`, `adapt.js`, `combinator.js`) |
353
+ | **pairwise detector** | **anti-unification / Plotkin LGG** — 1st-order = **unique ∧ polynomial** (the crux; leaving 1st order forfeits both) | built (`abstract.js#antiUnify`) |
354
+ | **the MISSING operator** (`compress.js`) | **corpus-MDL compression sleep** — Stitch (Bowers et al. POPL 2023) / SUBDUE (Cook & Holder JAIR 1994) branch-and-bound over `antiUnify` (the *structural* generalization of RE-PAIR, which is the 1-D special case) | **to build, gated on the STAGE-0 structural detector** |
355
+ | **forge** (under objective pressure) | **type-directed synthesis** — SyGuS (Alur 2013), Synquid (Polikarpova 2016), Myth (2015) — the **C-contract IS the refinement-type spec** | built (`adaptOrForge`, `crystallizeStructural`) |
356
+ | **higher-order contract** (loop-in-loop) | parametric-in-argument-contract skeleton — **higher-order frame rule** (Birkedal 2005 / Iris), **effect polymorphism** (Lucassen & Gifford 1988), refinement-on-arrow | **SOUND (static) · CONSERVATIVE**; adopt verbatim |
357
+ | **defeasible revision** (collapse→blame→re-qualify/forge) | **blame calculus** (Wadler-Findler 2009) + **higher-order contracts** (Findler-Felleisen 2002) + **CEGIS** (Solar-Lezama) | **OPEN — the genuine research contribution** (retractable argument-contract, uncovered by classical results) |
358
+ | **retention / library selection** | **Chemical Organization Theory** (Dittrich & Speroni 2007) on AlChemy (Fontana-Buss 1994) — crystallize iff **closed ∧ self-maintaining**; closure ≈ the typed barrier; the organization **lattice** ≈ defeasance/drift | to wire onto `crystallize`/`method-pack` |
359
+ | **LLM role** | **propose + name + document** (LILO/AutoDoc, ICLR 2024) — never own compression or soundness | to discipline |
360
+ | **diagnostic** | **canalization / attractors** (Kauffman 1969) — typed-fact discipline = canalization ⇒ drift-robustness; `divergent` = limit cycle (caveat: 2025 coherence-gap — a crystallized method may be *less* robust than re-deriving) | lens (metrics) |
361
+ | **vocabulary topology** (granularity / degeneracy / flexibility) | **Information Bottleneck** (Zaslavsky et al. 2018 — a frontier/diagnostic, NOT a generator) · granularity = **MDL-compressivity** of the solved-trace corpus (Stitch) · **Locatello 2019** impossibility (the typed-canon bias must be injected) · degeneracy at search (babble e-graph) + the library RETAINED as a version-space of theories pruned by utility not MDL (Mitchell; Lakatos-patch on incipient collapse) · **CLS** core=slow-protected not frozen (McClelland 1995) · learn-the-form (Kemp-Tenenbaum 2008) via Kirby compress↔expressify | the STAGE-1 Σ_sep registry, ELEVATED (see the graft G-1) |
362
+
363
+ **The five decisions it seeds.** (1) `compress.js` = **first-order antiUnify + a Stitch/SUBDUE MDL sleep**, NOT RE-PAIR;
364
+ the flat `compose-hotspot` is a cheap 1-D SCREEN, the real detector is structural. (2) The higher-order contract = the
365
+ **parametric skeleton (adopt verbatim) + defeasible revision** (the collapse/blame/CEGIS-supervisor loop) — *that* is the
366
+ novelty; do NOT claim to solve precise higher-order inference (nobody has). (3) **Retention = a COT organization gate**
367
+ (closed ∧ self-maintaining) on crystallization. (4) The **LLM proposes + names/documents**, never owns compression or
368
+ correctness. (5) The **vocabulary is a multi-granular, redundant, flexible topology** (COT organizations = "languages";
369
+ untranslatables = organization-relative concepts; multiple co-resident organizations = the re-opened membrane multi-context).
370
+
371
+ **The guardrails (hold these).** • **Stay first-order** at the detector/contract level — E-AU / higher-order-AU /
372
+ full-graph RLGG forfeit uniqueness, polynomial cost, AND contract decidability (graph-motif detection is NP-hard). Put
373
+ redundancy/equivalence (e-graphs) at the *vocabulary* level, first-order at the *compression/contract* level. • **The
374
+ frame is a MAP, not a green light** — its seductive coherence must not override the STAGE-0 gate: on the current workloads
375
+ nothing composes, so `compress.js` stays FILED until a real trace shows candidates. • **No spontaneous emergence** — these
376
+ frameworks are selectionless at the object level; skynet is goal-directed: it **forges under objective pressure + retains
377
+ per a COT closure test**, purposive construction filtered by a self-closing stability criterion. • **Soundness ⊕
378
+ flexibility** — a FROZEN typed core (signature stability) + a FLEXIBLE, redundant, multi-granular interior (the learning
379
+ substrate); the granularity split between them is the load-bearing design variable.
@@ -0,0 +1,168 @@
1
+ # Learned concepts — training a population at the fixpoint
2
+
3
+ > **Status: optional / shelved advanced track.** This subsystem (a tiny gate×update NN trained at the
4
+ > fixpoint) is a premature, narrow accelerator — a solution looking for a deployed hot-spot, and it does
5
+ > **not** replace an LLM. The mainline Use-2 path is [concept-as-graph.md](concept-as-graph.md) (methods +
6
+ > contracts + the durable executor); this stays shelved until a proven recurrent + structured + high-volume
7
+ > sub-task justifies it. The work is real, tested, and de-risked — revisit it then. Documented here for completeness.
8
+
9
+ > **Audience:** a fresh reader (AI or human) who knows what the engine is (a rule-driven graph that
10
+ > stabilizes typed-fact concepts to a fixpoint — see [architecture.md](architecture.md)) and wants to
11
+ > understand the **learning** subsystem under `lib/authoring/`. Everything here is **host-side and
12
+ > ZERO-CORE** — it does not touch `lib/graph/`. The full R&D trail (with the per-step measurements
13
+ > "F1…F9") is kept in the project's local R&D notes; this doc is the durable summary.
14
+
15
+ ## 1. The question
16
+
17
+ Concepts are normally **hand-authored** declarative rules. Authoring and maintaining a good concept
18
+ corpus is the dominant cost (see the README's "Concept strategy is WIP"). The open bet of this
19
+ subsystem: can a concept be **learned** — a small neural net instead of a hand-written rule — and can
20
+ a *population* of such concepts be **trained, grown, and distilled** so the system improves **without
21
+ human iteration**?
22
+
23
+ The project's two-level model already names the object (see the HANDOFF preamble): a concept is a
24
+ **local neighbourhood operator**, provably the same thing as an **MPNN layer** on a restricted
25
+ fragment, with a **hard cast = a quantized activation**. So a *population of concepts run to a
26
+ fixpoint* **is a quantized, equilibrium Graph Neural Network**. Training it is therefore a known
27
+ (if subtle) problem — and that is exactly what this subsystem does.
28
+
29
+ ## 2. The pieces (and how they compose)
30
+
31
+ ```
32
+ equilibrium.js the MATH: gradient through a fixpoint (DEQ / implicit differentiation)
33
+
34
+ concept-net.js the SUBSTRATE: a population of gate×update concept-units, trained with equilibrium
35
+ │ ├── train / grad / loss learn the population at its fixpoint
36
+ │ ├── evolve grow the FORM by success (utility/MDL gate)
37
+ │ ├── bakePopulation BRIDGE: a frozen population → real engine concepts
38
+ │ └── unrollPopulation serve a CYCLIC population on the engine (unrolled)
39
+
40
+ lifecycle.js the KNOB: plasticity p∈[0,1] — plastic=train/explore, frozen=serve/deterministic
41
+ llm.js / ste.js plasticity wired into real providers (LLM temperature / NN exploration noise)
42
+ ```
43
+
44
+ ### 2.1 `equilibrium.js` — gradient through a fixpoint (DEQ)
45
+
46
+ The engine's stabilization is a **Picard iteration** `z_{t+1} = F(z_t, θ)` driven to a fixpoint
47
+ `z* = F(z*, θ)`, where `θ` are the learnable weights inside concept-nets. To train `θ` we need
48
+ `dL/dθ` **without differentiating through the iteration** (which would be deep, memory-hungry, and
49
+ unstable). The trick (Almeida/Pineda 1987; Deep Equilibrium Models, Bai-Kolter-Koltun 2019) is to
50
+ differentiate the **fixpoint condition** itself:
51
+
52
+ ```
53
+ solve the adjoint (I − J_z)^T u = ∇_z L at z* (J_z = ∂F/∂z, one sweep)
54
+ then dL/dθ = J_θ^T u (J_θ = ∂F/∂θ, one sweep)
55
+ ```
56
+
57
+ - Well-posed iff the iteration **contracts** (spectral radius `ρ(J_z) < 1`) — the same condition that
58
+ makes the forward fixpoint exist and be unique. As `ρ → 1` everything slows (forward sweeps, the
59
+ Neumann backward depth, the gradient norm all scale `~1/(1−ρ)`). The engine's **apply-cap is the
60
+ exact analogue of the Neumann truncation depth**.
61
+ - The **hard cast** (a step function) is handled by a **straight-through estimator (STE)**: hard
62
+ forward, smooth (sigmoid-derivative) backward — consistent with the canonicalization barrier (a
63
+ discrete cast at inference, continuous only during offline training).
64
+ - API: `solveFixpoint` (Picard), `implicitGrad` (the adjoint solve — `direct` or `neumann:K`),
65
+ `spectralRadius` (the regime instrument), `numJac` (finite-difference Jacobians of one sweep).
66
+
67
+ Proven on a minimal **genuinely-cyclic** 2-fact model (a DAG would make implicit==unrolled, vacuous):
68
+ the implicit gradient matches finite-difference to `<1e-4`; **training converges** (loss `0.047→8e-9`);
69
+ the cycle is load-bearing (a fixed-depth unroll can't represent the fixpoint map); the `ρ→1` regime is
70
+ mapped (19 forward sweeps at ρ=0.3 → 419 at ρ=0.95). This module is a **differentiable mirror** of the
71
+ stabilization — the real engine stays discrete; a trained net is baked back via the bridge.
72
+
73
+ ### 2.2 `concept-net.js` — a population of concept-units
74
+
75
+ A **concept-unit** is exactly the shape you'd sketch: a NN that decides **whether to cast** (the gate)
76
+ × a NN that **generates the value** it writes (the update):
77
+
78
+ ```
79
+ contribution of unit i to its target fact = gate_i(ctx) · update_i(ctx)
80
+ gate_i = σ(W^g_i·ctx + b^g_i) cast decision (hard = step at inference, STE backward)
81
+ update_i = σ(W^u_i·ctx + b^u_i) the value cast
82
+ ctx = z[ unit_i.inputs ] the facts the unit reads — the WIRING / the FORM
83
+ ```
84
+
85
+ Many units may target the same fact (their contributions **sum** — a mixture); one-unit-per-fact is the
86
+ special case (a ring/chain). The population is run to a fixpoint and trained end-to-end with §2.1.
87
+ Builders: `ringPopulation` (a cycle), `chainPopulation` (a DAG), `widePopulation` (K parallel units →
88
+ a readout). `train` / `grad` / `loss` do the learning.
89
+
90
+ Measured: the population gradient matches finite-difference; **training scales** across 2→6 units
91
+ without collapse (loss → `1e-10…1e-19`); a hard-cast (STE) population trains; a small population can
92
+ **distil** a bigger one's input→output map (3 units reproduce a 6-unit map).
93
+
94
+ ### 2.3 `lifecycle.js` (+ `llm.js` / `ste.js`) — the plasticity knob
95
+
96
+ Every concept carries one scalar, its **plasticity `p ∈ [0,1]`** — the unified creativity/learning
97
+ knob. `p=1` plastic (learning on / high creativity), `p=0` frozen (deterministic, memo-perfect spine),
98
+ `{plastic, probationary, frozen}` is just the banding of `p`. The **same** `p` modulates very different
99
+ providers: an `LLM::complete` concept's **temperature** (`llm.js`) and an STE mini-NN concept's
100
+ **exploration noise** (`ste.js`). Consolidation is Complementary-Learning-Systems annealing: a concept
101
+ is born plastic and `p` decays toward 0 as its reliability is proven. **Discipline (K1):** plasticity
102
+ *modulates a provider*; it is **never** a fact that gates applicability (a continuous gate would churn
103
+ the memo). This is the train↔serve switch: **plastic = train, frozen = serve.**
104
+
105
+ ### 2.4 The bridge — `bakePopulation` / `unrollPopulation` (train offline, serve in the engine)
106
+
107
+ A frozen, trained population is **baked back into real engine concepts**: each unit becomes a concept
108
+ `{ require, provider }` whose provider does the hard gate × update with the frozen weights, writes its
109
+ target fact + its self-flag, and the `require` keys on the producer unit's self-flag — so the
110
+ population **cascades in stabilization** to a terminal state. This is the frozen *serve* regime made
111
+ concrete (the multi-unit analogue of `ste.js#createNet`).
112
+
113
+ - **Acyclic** populations cascade directly (verified: a frozen `chain(3)` reproduces its mirror
114
+ fixpoint through real stabilization to `<1e-9`).
115
+ - **Cyclic** populations can't be baked directly — the `require` graph would be a producer cycle with
116
+ **no entry point** (it deadlocks), and the engine won't natively iterate a value-feedback loop. So
117
+ `unrollPopulation(pop, N)` **unrolls** the fixpoint to depth `N` (Picard) into an acyclic DAG of `N`
118
+ weight-tied stages, which bakes normally. The depth-`N` readout → the true fixpoint as `N` grows
119
+ (`~ρ^N`); verified on the real engine (a `ring(3)` unrolled to N=6 reproduces the fixpoint to `<1e-9`).
120
+
121
+ ### 2.5 `evolve` — the form grows by success
122
+
123
+ `evolve` grows a population one unit at a time and keeps a larger form **only while the added unit earns
124
+ its keep** — loss must improve past a `margin` (a utility/MDL gate, the continuous cousin of
125
+ `abstraction.js`). Growth stops at the parsimonious size that fits the task (too few underfit, the right
126
+ size fits, more don't pay for themselves). Verified: a teacher needing more capacity makes a 1-unit form
127
+ underfit → it grows → then a utility gate stops it; a 1-unit-sufficient task stays at 1 (Occam).
128
+
129
+ ## 3. Honest limits (read before relying on this)
130
+
131
+ - **It is a *mirror*, plus a serving bridge.** Training happens in the differentiable mirror; the real
132
+ engine is discrete. The bridge serves a frozen result; the engine does not train.
133
+ - **Topology matters (finding #24).** A *chain* of gate×update units **collapses in depth** — each fact
134
+ squashes into `[0,1]`, so the next sigmoid runs near-linear and depth adds no expressivity (deep-GNN
135
+ over-smoothing). Use **width**, not depth, for capacity.
136
+ - **Cyclic serving is *unrolled*** (finding #25), N× the concepts — not an engine-internal feedback loop.
137
+ - **STE depth/variance** is only validated at moderate depth; deep stacks of hard casts are unmeasured.
138
+ - **Heterogeneous concepts** — an `LLM::complete` or a deterministic rule is **not differentiable**, so
139
+ it stays frozen / off-gradient. The gradient only reaches the NN-backed units. This is a *Mixture of
140
+ Reasoners*, not a uniform net.
141
+ - **Distillation** is shown on a scalar-input toy; capacity/generalisation at scale is open.
142
+
143
+ ## 4. File map · demos · tests
144
+
145
+ | File | Role |
146
+ |---|---|
147
+ | `lib/authoring/equilibrium.js` | DEQ: `solveFixpoint`, `implicitGrad`, `spectralRadius`, `numJac` |
148
+ | `lib/authoring/concept-net.js` | the population: `make/ring/chain/wide/unrollPopulation`, `train`, `grad`, `loss`, `evolve`, `bakePopulation` |
149
+ | `lib/authoring/lifecycle.js` | the plasticity ledger `p∈[0,1]` (CLS annealing) |
150
+ | `lib/providers/llm.js`, `lib/authoring/ste.js` | plasticity wired into a real provider (temperature / noise) |
151
+ | `examples/poc/equilibrium.js` | DEQ convergence + the ρ→1 regime + STE, narrated |
152
+ | `examples/poc/concept-population.js` | a population: train → scale 2→6 → evolve form → distil |
153
+ | `examples/poc/concept-bridge.js` | a frozen population served in the real engine |
154
+ | `examples/poc/plasticity.js` | one knob p → LLM temperature + NN noise, annealing plastic→frozen |
155
+ | `tests/unit/equilibrium*.test.js`, `tests/unit/concept-net*.test.js`, `tests/integration/concept-net-*.test.js` | the proofs |
156
+
157
+ Run a demo: `node examples/poc/concept-population.js` (or `concept-bridge.js`, `equilibrium.js`,
158
+ `plasticity.js`). Run the proofs: `npm test`.
159
+
160
+ ## 5. Where this sits in the roadmap
161
+
162
+ This realizes the `#12`/`#13` line (grammar induction / crystallization) on its *continuous* side: the
163
+ discrete crystallization tools (`mine` → `abstraction` MDL gate → `crystallize`/`consolidate`) distil a
164
+ recurring sub-derivation into one typed production; this subsystem learns and serves concepts as trained
165
+ NN populations. They share the **memo-stability discipline** (a learned output must not leak onto a
166
+ snapped gate/memo surface — `memo-stability.js`). The open frontier: an engine-internal feedback loop
167
+ (no unroll), deeper/heterogeneous topologies, a self-training loop (the population observes episodes and
168
+ trains itself), and non-toy distillation.