Skip to content

feat(core): Stage-1 world-substrate kernel (F1.0–F1.9) + G3 second substrate + F2 foundation — experimental, unexported#1078

Merged
zachshallbetter merged 22 commits into
mainfrom
feat/world-kernel
Jul 20, 2026
Merged

feat(core): Stage-1 world-substrate kernel (F1.0–F1.9) + G3 second substrate + F2 foundation — experimental, unexported#1078
zachshallbetter merged 22 commits into
mainfrom
feat/world-kernel

Conversation

@zachshallbetter

@zachshallbetter zachshallbetter commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Purpose

Stage‑1 implementation (F1.0–F1.9) of the world‑substrate kernel experiment, plus the G3 second‑substrate generalization and the F2 foundation (ProjectionContract + property classification). Every surface is internal and unexported; the frozen public API is untouched. No release. Stage‑2 implementation has not begun.

Scientific motivation

After F1.1 falsified direct FieldPattern hosting, Stage 1 became a sequence of falsifiable experiments rather than a build‑out. The central question:

Which elements of K remain necessary after representation, execution, opportunity derivation, and episode detection have been exercised experimentally?

Each milestone answers one part, and each was allowed to return a negative or partial result. F1.5 did exactly that, and the result was kept rather than engineered away.

G3 then addressed a distinct problem: after Stage 1, DynamicsContract had been validated against exactly one substrate — the field runtime it was extracted from. A contract with one implementation is indistinguishable from a description of that implementation. A field‑fitted outcome was a permitted (and pre‑declared) result.

Architectural changes

World  →  DynamicsContract  →  ExecutionSubstrate  →  Transition evidence  →  Ω_sys  →  Episode detection
  • The kernel holds opaque State threaded through initialize/advance; it never holds a substrate instance.
  • DynamicsContract carries executionKind (closed union) · capabilities · a determinism declaration (not a boolean) · typed DynamicsResult · a typed evidence channel whose unresolvedInterpretations record, never assert, interpretation.
  • The field is one substrate behind that boundary, declared opaque-native.
  • A static guard enforces the kernel imports no field code and exposes no any/Function escape hatch.

Evidence produced

Milestone Artifact Commit
F1.0 Eight‑field WorldVersionEnvelope, explicit‑fail, no silent migration a1a69858
F1.2 Generic field‑free World c2f8cb1c
F1.3 DynamicsContract boundary + consistency validator 6c117a1b
F1.4 Transition‑level raw‑vs‑substrate equivalence harness fec2a008
F1.5 Declarative‑dynamics experiment (minimal typed expression IR) b214a7e9
F1.6 Ω_sys opportunity derivation 007a258e
F1.7 Parameterized candidate‑episode detection bebb6fce
F1.8 Kernel ablation harness (executed, not asserted) 4fcdf74d

Findings

  • Dynamics is non-substitutable. Declarative‑only substitution covers 8/11 corpus laws; 3 remain opaque (hidden mutable state, host/callback, nonlinear time). Dynamics = Declarative Region + Opaque Execution Region. The IR was not expanded to force success.
  • DynamicsContract is execution-boundary-only — deliberately not promoted to an eighth primitive. One kernel drives an opaque-native and an interpreted substrate unchanged.
  • Ω_sys is derived-complete — reconstructed from state, operations, capability, authority, projection, reachability, history; all five lower inputs necessary; contains no belief/interpretation (asserted by test).
  • Episodes are derived-conditional — findings are relative to a declared contract; coupling vs shared cause is structural, surviving the most permissive thresholds.
  • The contract generalizes (G3.3): generalized-with-refinement. Across 18 dimensions compared against a second substrate, no dimension was field‑biased. The second substrate adopted executionKind, determinism, capabilities, evidence shape, failure taxonomy, snapshot fidelity, replay, restore, lifecycle and ordering unchanged; four dimensions are substrate‑specific values carried by the generic type parameters.
  • One missing general concept, found only by the second substrate. capabilities.declareTransitionLaw could be claimed truthfully while the contract offered no accessor for the law. Added describeTransitionLaw() with capability‑iff‑accessor consistency rules; opaque-native stays barred from declaring a law. The rule immediately caught a pre‑existing F1.3 fixture that claimed the capability without being able to produce a law.
  • One over‑generalization, recorded and kept. DynamicsExecutionContext.now was read by neither substrate. It was not removed — two substrates do not justify deleting a concept, and removal would erase the finding.
  • Projection is not observation (F2). A projection is subtractive with respect to power: it can hide, withhold and understate, but can never manufacture capability or silently grant permission — overstatements are reported, which is what makes them non‑silent. exposed / hidden / unavailable stay three distinct states. A projection changes Ω_sys over an identical snapshot without changing world state.
  • Empirical claims cannot be settled internally (F2). Enforced in code: an empirical property never returns satisfied — only unresolved, insufficient-evidence, or a deferral referencing an external study — and an explicit true verdict is not honoured. Likewise, one observed execution is not a model check; 500 runs still yield insufficient-evidence.
  • Rejected reductions: Relations → transitions (latent + typed semantics lost) · Operations → observed transitions (latent ops unrecoverable) · Projection → observation (materially changes Ω_sys) · Invariants → dynamics guards (no guard point in an opaque substrate) · Capability ⊕ Authority → one flag (loses the diagnosis).

Limitations

  • F1.5's corpus is representative laws modeled on the engine's force categories, not the exact 36 shipped forces.
  • F1.4 equivalence is conditional (injected RNG/clock, dt, ordering, environment, geometry) and covers only the observable projection — velocity/accumulated force are lossy and were not compared; snapshot fidelity is partial-observable, non‑restorable.
  • One real substrate plus one synthetic substrate characterized; JS plane only (native ports deferred by R4).
  • The G3 second substrate is behaviourally but not organizationally independent. It is a faithful core‑local port of the shipped @fundamental-engine/dom QualityGovernorcore cannot import dom and core's exports map is closed, so the shipped class is unreachable and no suitable core‑local substrate existed. It is a genuine second implementation; it is not evidence that an unrelated third‑party system would adapt as cleanly.
  • F2 is a foundation, not a runtime. Projections are applied and checked, but nothing executes through a projection. Property classification recognizes whether sufficient evidence was supplied; it does not discharge model‑checkable properties.
  • Episode boundary justification is analytic/empirical, not runtime‑decidable.
  • K₀ fold is representational and untested at scale.

Repository impact

Adds packages/core/src/world/** (envelope, world, dynamics, kernel, adapters, equivalence, experiments, opportunity, episodes, ablation, substrates, cross‑substrate, projection, properties) + tests, and [Unreleased] CHANGELOG entries. Nothing exported from the package entry. Existing field goldens unchanged; no accepted F1.3–F1.7 behavior was altered to make a later ablation pass.

Testing and gates

typecheck (core)   clean
check:api          ✓ 20 frozen entries intact (13 values, 4 types, 2 elements, [data-body])
check:docs         ✓ 193/193 documented (100%)
core test suite    1039 / 1039 pass, 0 fail
check:links        PASS — 155 markdown files

Merge dependencies

Based on main; #1077 is NOT required to merge first. Verified by running check-doc-links on this branch standalone — it introduces no reference depending on files added by #1077. Merging #1077 first is recommended (so CHANGELOG prose references resolve in‑repo) but is not a blocker.

Reviewer merge order: #1077 → this PR → CompInt #1. Does not touch #1034 or #1027.

Release impact

None. FIELD_VERSION remains 0.9.4; no package.json version change, no tag, no publish. All notes retained under ## [Unreleased] (8 entries). Stage 2 has not begun.

First code of the world-substrate kernel experiment (M1.5 ratified 2026-07-19).
Adds packages/core/src/world/envelope.ts — the eight-field WorldVersionEnvelope
(M1.5-07) with explicit-fail compatibility (assertCompatibleEnvelope throws
IncompatibleWorldVersion naming the field; no silent migration; migration tooling
deferred to F4.4). Not exported from the package entry, so the frozen public
surface is unchanged (check:api: 20 entries intact). 5 tests green via node --test;
core typecheck clean. Per docs/planning/world-substrate/F1-execution-spec.md.

Native Swift/Kotlin ports deferred to the F1/F2 review (R4); JS is the reference.
…dRuntime substrate

A' architecture (per the ratified redefinition of F1.1): the kernel sits ABOVE the
field runtime, not around it.

- world.ts / dynamics.ts / kernel.ts: a field-free generic World declaration, a
  DynamicsContract abstraction for lawful evolution, and hostWorld() which executes
  a contract WITHOUT understanding it and holds no substrate reference.
- adapters/field-runtime.ts: the one-way bridge. worldFromCompiledPattern maps a
  CompiledPattern -> generic World (identity/tokens/params/relations/invariants/
  projections preserved; evolution declared OMITTED). fieldRuntimeDynamics wraps a
  headless field as an OPAQUE substrate (declarative:false; no declarative-equivalence
  claim) behind the contract.

Realizes the settled assumptions: World generic; DynamicsContract = lawful evolution;
FieldRuntime = first substrate; kernel never understands forces or retains a
FieldPattern; the opaque field wrapper is labeled opaque. Not exported (frozen surface
unchanged).
- kernel.test.ts: structural equivalence (CompiledPattern -> World faithful; evolution
  omitted), the kernel executing an OPAQUE field-runtime contract, and the same kernel
  executing a NON-field contract identically (substrate-agnostic).
- architecture.test.ts: the no-escape-hatch guard -- world.ts/dynamics.ts/kernel.ts/
  envelope.ts import nothing field-specific (comment-stripped scan); the adapter is the
  only field bridge.

Full core suite: 940/940 green; typecheck clean; check:api 20 intact.
… results + evidence)

Enrich the contract to the full F1.3 boundary before F1.4 equivalence work.

- DynamicsContract<State,Input,Output,Evidence>: identity · executionKind (closed
  union) · conservative capabilities · determinism DECLARATION (not a boolean) ·
  initialize/advance/snapshot?/restore? returning a typed DynamicsResult. Removed
  the "declarative: boolean" flag (executionKind + capabilities + determinism carry
  those claims separately).
- Typed evidence channel: declaredInputs / substrateResponses / checkedInvariants /
  executionTrace / unresolvedInterpretations — the last RECORDS interpretation as
  unresolved, never asserts it. EvidenceRecord requires a source. Typed failure
  taxonomy (10 codes); exceptions reserved for programmer errors.
- kernel.ts: hostWorld now threads opaque State via initialize/advance and reads via
  snapshot; holds no substrate instance.
- adapter: field substrate declares executionKind opaque-native,
  conditionally-deterministic, snapshot-only (no restore/replay), inspectInternalState
  false, declareTransitionLaw false — advertises only what the runtime supports.
- validateDynamicsContract rejects contradictory declarations; tests cover the
  negatives + field-contract self-consistency. Architecture guard extended: no any,
  no Function, World holds no contract instance, no capability over-claim.

Scope: contract boundary only (no Force IR, opportunity, episodes, projections,
migration, or exports). check:api 20 intact; 943/943 core green; typecheck clean.
The interim F1.1c label is retired (see PLAN.md v2.1).
…evel, honest coverage)

The raw field path is the authority; the adapter is under test and must not define
the baseline.

- adapters/field-runtime.ts: construction inputs (host geometry, RNG stream, clock,
  body placement) move into a fixture-owned FieldConstruction (default preserves
  prior behavior) so the raw baseline and the adapted path are built from identical
  controlled inputs — including an injected deterministic clock (now).
- equivalence.ts: runRawPath (direct createField+addBody+tick, the authority) vs
  runAdaptedPath (field behind DynamicsContract + hostWorld); both normalized to a
  FieldSemanticStep trace. compareTraces checks EVERY transition (exact for discrete,
  declared tolerance for floats). Honest structural coverage (represented /
  substrate-owned / observable-only / lossy / unavailable; velocity=lossy, lifecycle
  callbacks=unavailable), snapshot fidelity partial-observable (non-restorable),
  and recorded determinism conditions. A pass is CONDITIONAL, never unconditional.
- equivalence.test.ts: positive raw≡adapted; coverage/fidelity honesty; negative
  fixtures (construction divergence + mutated-trace: step-count, body-count,
  ordering, out-of-tolerance); and a fixture where final-state-only false-passes
  while per-transition catches the divergence.

Scope: characterization + measurement only (no force IR, restore/replay, opportunity,
episodes, exports, or field refactoring). check:api 20 intact; 948/948 core green;
typecheck clean; field goldens unchanged. Establishes observable-execution
preservation under declared conditions — NOT that the kernel understands field laws.
Bounded scientific experiment: can force laws be represented as DATA?

- world/experiments/declarative-dynamics.ts: a minimal typed expression IR (closed
  op union: const/var/add/sub/mul/div/min/max/neg/clamp/ifGte) + interpreter. NO
  callbacks, eval, Function, script strings, or execution escape hatch.
- Representative force corpus (modeled on real force categories): distance/relation/
  environment/threshold/composition/parameterized/linear-time = declarative-expression;
  explicitly-surfaced state = declarative-stateful; nonlinear-time (unsupported-input),
  closure-captured state (hidden-mutable-state), host/callback (callback-dependence)
  = opaque-only with recorded reasons.
- Result: partial-with-opaque-extensions. Non-trivial laws are representable, but the
  system is not fully declarative; the IR was NOT expanded to force success (stop
  conditions respected). Corroborates that Dynamics is not reducible to declarative
  data and the opaque-native DynamicsContract substrate is justified (feeds F1.8).

check:api 20 intact; typecheck clean; targeted 5/5 green. Not exported.
…ived only)

evaluateOpportunity(context, operation) over (participant, operation, state,
projection, history) returns per-predicate results: domainValid/capable/permitted/
enabled/reachable/exposed/signaled/reversible + recoveryPaths + failedPredicates +
evidence (retains the world/version envelope; reconstructible).

- Runtime-derived ONLY: no belief/perceived/interpretation/expectation/confidence/
  experience/strategy (a test asserts none of those keys exist).
- Capability (Capable=can) and authority (Permitted=may) are separate; every
  permission requires an authoritySource (empty/'unknown' => not permitted).
- No aggregate boolean without predicate-level evidence; failedPredicates names
  which predicate failed and why.
- Ten negative fixtures (capable-not-permitted, permitted-not-capable, enabled-
  unreachable, reachable-not-exposed, exposed-not-signaled, irreversible-no-recovery,
  projection-changes-result, history-changes-result, unknown-authority-source,
  unsupported-operation).

Field-free; not exported. check:api 20 intact; typecheck clean; 12/12 targeted green.
…onal findings)

detectEpisodes(trace, contract, worldParticipants) under the ratified detection
contract <boundary, timescale, coupling predicate, recurrence window, influence
threshold>. Conditional findings only: 'given these parameters, this trace satisfies
the candidate-episode rule.'

- Returns candidate episodes, episode participants, supporting transition pairs,
  boundary used, coupling/reciprocity/recurrence basis, determinacy, alternate
  segmentations (reported, not errors), failure reasons, evidence.
- Coupling vs shared cause is structural: a coupling event is a directed from->to
  perturbation; a common source C->A, C->B with no A<->B link is NOT a coupled
  episode. Reciprocal, mediated (A->M->B->A), and recurrent (>=2 same-direction)
  bases, all under the recurrence window.
- Preserves world-participant vs episode-participant (latent authority holder is a
  world participant, not an episode participant).
- 8 preregistered adversarial cases + 6 additional, all green (15/15).

Field-free; not exported. check:api 20 intact; typecheck clean.
Runs the four ratified ablation forms (removal/collapse/substitution/reconstruction)
against the current kernel by EXECUTING the real F1.5-F1.7 derivations with ablated
inputs. Each record: hypothesis, transformation, fixture, expected distinguishing
case, observed, failed capability / preserved behavior, evidence, classification,
K/K0 implication.

Results:
- Dynamics: non-substitutable (declarative-only covers 8/11; 3 opaque laws remain).
- DynamicsContract: execution-boundary-only; NOT promoted to a kernel primitive.
- Omega_sys: derived-complete; all five lower inputs necessary (each removal changes
  the derivation).
- Interaction episode: derived-conditional; coupling vs shared cause is STRUCTURAL
  (shared cause yields 0 episodes even at zero thresholds).
- Relations: collapsible-with-loss (observed edges reconstruct; latent + typed
  relation semantics do not) -> not eliminable.
- Operations: non-substitutable (latent, never-invoked operations unrecoverable).
- Capability/Authority: collapsible-with-loss; kept distinct as typed constraints,
  neither a kernel element.
- Projection: non-substitutable; materially changes Omega_sys over identical state.
- Invariants: necessary kernel-side component; cannot be guards inside an opaque
  substrate (inspectInternalState=false, declareTransitionLaw=false).
- Entities/identity: representation-dependent (attribution lost when anonymized).

Includes a negative fixture proving the harness does not report loss where none
occurs. check:api 20 intact; typecheck clean; 12/12 targeted green.
@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fundamental-engine Ready Ready Preview Jul 20, 2026 3:11am

Request Review

@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fundamental-engine Ready Ready Preview Jul 20, 2026 12:17am

Request Review

…ontract

Tests whether DynamicsContract is genuinely substrate-neutral by adapting a second,
non-field substrate. The contract was NOT changed to make it fit.

Part A - selection. Chosen: the quality-governor rule set. Rationale: real discrete
state transitions with asymmetric hysteresis, a transition law that is a DECLARED
TABLE, fully surfaced state, and exact determinism (no clock, no RNG) - maximum
contrast with the field at minimum unrelated work. Provenance: a faithful core-local
port of the SHIPPED @fundamental-engine/dom QualityGovernor. It is a port, not the
shipped module, because core must never import dom (dependency direction) and core's
package exports map is closed, so the class is unreachable from core; adapting it in
dom would have required exporting kernel types (new public surface). Limitation
recorded. Rejected alternatives: semantic/states.ts (data + type guard, no real
transitions), the conformance runner (field-coupled), FrameScheduler (field-coupled),
site live-data (network I/O, non-deterministic offline).

Part B - adapter. executionKind 'interpreted'; determinism 'deterministic' with zero
uncontrolled inputs; capabilities snapshot+restore+replay+inspectInternalState+
declareTransitionLaw+deterministicReplay all true - each of which the field substrate
honestly cannot claim. Failures projected through the generic taxonomy with the native
cause retained internally; no native type leaks into World; World still holds opaque
State, never a substrate instance.

Part C - equivalence. Raw substrate is the baseline authority, driven directly. Every
transition compared (tier, streaks, change events, failures). Controls recorded
explicitly; clock/randomness/queue/environment/retry/external-response/host-geometry
declared NOT-APPLICABLE rather than silently claimed. Negative fixtures: altered
operation order, changed input, skipped transition, changed failure, reordered event,
and a final-state-only false-pass caught per-transition.

check:api 20 intact; typecheck clean; 8/8 targeted; full suite 1000/1000.
…n-law refinement

Compares FieldRuntime and the quality-governor substrate against the same DynamicsContract
across 18 dimensions, with every row read off the live contracts rather than from prose.

Outcome: generalized-with-refinement.

- No dimension classified field-biased or second-substrate-biased. The second substrate
  adopted executionKind, determinism, capabilities, evidence shape, failure taxonomy,
  snapshot fidelity, replay, restore, lifecycle and ordering unchanged.
- Nine dimensions supported-by-both; four are substrate-specific values carried by the
  generic type parameters (state/input/output model, environment and host dependence).
- One missing general concept, visible only once a second substrate existed:
  capabilities.declareTransitionLaw could be claimed truthfully while the contract offered
  no way to obtain the law. Added an optional describeTransitionLaw() returning the law as
  data, plus two consistency rules (capability iff accessor). opaque-native remains barred
  from declaring a law at all.
- One unnecessary generalization recorded, not removed: DynamicsExecutionContext.now was
  unused by both substrates. Kept and documented rather than silently dropped.

The F1.3 counter fixture claimed declareTransitionLaw without being able to produce a law;
the new rule caught it and the fixture was corrected. The field adapter is unaffected and
still validates clean with the capability false and no accessor — pinned by a migration test.

Also adds the outstanding second-adapter architecture guards: the generic contract imports no
substrate, the new files introduce no any/Function/eval/callback escape hatch, the native
governor type never reaches World, and failures project through the generic taxonomy while
retaining native causes internally.

Experimental and internal; no public surface added. check:api 20 frozen entries intact;
core suite 1012/1012.
Two internal, experimental foundations. Neither begins the Stage-2 runtime.

ProjectionContract (world/projection/projection.ts)

Projection is modelled as a presentation of a world, kept distinct from observation,
snapshot, evidence, capability, authority and operation availability using separate
concepts rather than one overloaded object.

The load-bearing rule is that a projection is subtractive with respect to power. It may
hide, withhold and understate; project() can never manufacture a capability or silently
grant permission. Where a definition claims more than the source holds, the surface still
reflects the source and the excess is reported as an anomaly — an overstatement is
reported, which is exactly what makes it non-silent.

Three operation states stay genuinely distinct: exposed, hidden (exists in the world, not
offered here) and unavailable (not in the world's vocabulary at all). Collapsing hidden
into unavailable would let a projection misrepresent the world. Observation access and
operation exposure are independent in both directions.

A projection can change Omega_sys without changing world state — demonstrated by driving
the F1.6 evaluator from two surfaces over one identical snapshot. Projection-relative
invariants are evaluated against the surface only; a claim reading hidden state is
unevaluable-outside-surface rather than being satisfied or refuted by reaching into the
world. Signaling raises an unresolved empirical obligation instead of asserting that
anyone perceived anything.

Nine required fixtures, each written to fail if the distinction it guards were collapsed.

Property classification (world/properties/properties.ts)

The Stage-2 three-class vocabulary — mechanically-decidable, model-checkable,
empirically-testable — with per-class evaluation authority, required evidence, status,
reason and provenance.

Two limits are enforced in code rather than described in prose:

- An empirical claim can never be marked satisfied internally. The validator may only
  return unresolved, insufficient-evidence, or a deferral carrying an external study
  reference. An explicit mechanical verdict of true is not honoured for an empirical
  claim, and a belief-laden statement classed as mechanical is refused as not-applicable.
- One observed execution is not a model check. 500 runs still yield insufficient-evidence,
  a bounded check holds only within its stated bound, and only exhaustive exploration
  earns satisfied.

Five negative fixtures cover each required case, including the two projection-relative
ones: a claim cannot reach past the surface into hidden state, and evidence the surface
withholds cannot discharge a claim.

Guards extended to both new modules: field-free, substrate-free, and no any/Function/eval
or callback escape hatch.

typecheck clean; check:api 20 frozen entries intact; check:docs 100%; core suite 1039/1039.
@zachshallbetter zachshallbetter changed the title feat(core): Stage-1 world-substrate kernel (F1.0–F1.8) — experimental, unexported feat(core): Stage-1 world-substrate kernel (F1.0–F1.9) + G3 second substrate + F2 foundation — experimental, unexported Jul 20, 2026
… (no adapters yet)

Two conformance-corpus substrates written from their own domain semantics, with the APIs
their own domains would give them, and NO knowledge of DynamicsContract.

Committed deliberately BEFORE their adapters exist. The corpus protocol is substrate-first,
adapt-second: the commit boundary is what makes it checkable that a substrate was not shaped
to fit the contract it is about to be measured against. Neither file may be edited to make
its adapter cleaner — if an adapter is awkward, the awkwardness is the finding.

FSM (the control): declared states, declared transition table, data guards, accepting
states, and an outcome per event that distinguishes transitioned / no-transition /
guard-blocked / unknown-event / accepted. An accepting state is DONE, not merely idle.

Planner (the falsification candidate): weighted graph, frontier, explored set, one
expansion per step, plan extracted at the end. It is the first corpus substrate that
FINISHES — the frontier empties or the goal is found — and its transition law is only
partially declarable: expansion order and edge costs are a table, while the euclidean
heuristic is computed in code and cannot be written down as rules.

Substrate-level tests only, on domain terms. 8/8.
…urn ledger, termination

Adapts the two corpus substrates committed in 00c8db0 and measures what they cost the
contract. Results against the pre-registration (d90b3bd on the docs branch):

P1 FALSIFIED. The FSM was the control, pre-registered at churn 0 on the reasoning that an
FSM is the most contract-shaped substrate imaginable. It required one change: an FSM has
accepting states, so it is the first corpus substrate that FINISHES, and the contract had
no generic way to say so. The falsification is the stronger result — it means termination
is a general property of lawful evolution, not a search idiosyncrasy, and that neither
prior substrate could have revealed it because neither ever finishes.

P2 CONFIRMED but already paid for. The planner terminates too, so it needed the same
concept the FSM had already bought, and cost 0. Its predicted secondary finding also held:
its law is partially declarable (expansion table declarative, euclidean heuristic computed),
which makes it the first substrate to exercise executionKind 'hybrid' — declared in F1.3
and never used until now.

A change considered and REJECTED. Adding TransitionLawDescription.completeness so the
planner could publish its declarable half is a substrate convenience, not a missing general
concept: declareTransitionLaw:false already answers truthfully — this substrate cannot
declare THE law. Recorded in the ledger as a rejection so it is auditable.

The termination concept: Transition.lifecycle ('continuing' | 'terminal'), optional, absent
read as continuing so no existing substrate migrates. Deliberately does NOT split
finished-with-result from finished-without — both corpus substrates exhibit that, but the
evidence only forces "must the kernel keep going?".

KernelHost gained lastLifecycle, because the kernel was discarding the field and the whole
justification for the concept was that a kernel must learn to stop without reading
substrate-specific output. It is a host reading rather than a field on advance's result:
folding it into the result is the better long-term design but would change the shape every
call site destructures, including the F1.4 equivalence harness that is the raw-vs-adapted
authority. That trade is documented at the definition.

Also adds a substrate-agnostic conformance battery (drives any contract through the generic
surface only — capabilities and declarations, never substrate identity) and a churn ledger
with the pre-registered weights. Ledger: 4 adapted, 4 pending, total churn 3, zero
substrate conveniences accepted, converging on the last adapted substrate. Pending entries
are asserted never to count as evidence of generality.

Guards added: each substrate is verified to import nothing from the contract, kernel or
world — substrate-first only means anything if the substrate is substrate-unaware.

typecheck clean; check:api 20 frozen entries intact; check:docs 100%; suite 1065/1065,
including the F1.4 equivalence tests (no regression).
…ment taxonomy

Formalizes the experimental protocol the corpus converged on, as testable data rather than
prose. The protocol is now the contribution; the abstractions are what it produced.

Three-way refinement taxonomy replaces the earlier binary. structural / representational /
convenience. The old missing-general-concept vs substrate-convenience split had no room for
"the concept existed, this expresses it better", so a representational change had to be
misfiled as one of its neighbours — precisely the ambiguity that lets a contract drift.
Current counts: 3 structural, 0 representational, 0 conveniences accepted.

Discovery registry (D-001, D-002) gives permanent identifiers to concepts the contract was
missing. A discovery must name the substrate that forced it, argue why the PRIOR contract
was incoherent rather than merely improvable, and state why no existing substrate could
have revealed it. It also records what was deliberately NOT generalized at the same time,
so the restraint is auditable alongside the change. Tests assert identifiers are dense and
ordered (a removed entry would show as a gap), that a discovery contains only structural
changes, and that the discovery ledger and the corpus ledger cannot drift apart.

Notably: neither discovery came from FieldRuntime. The substrate the contract was extracted
from has discovered nothing, which is what you would expect and is now asserted.

Prediction registry and accuracy. Contract stability and predictive power are different
things: a contract nobody changes might be right, or might be untested. Two hazards are
designed against explicitly. partially-confirmed is only available to predictions that
declared two or more independent components in advance, each graded separately, and it is
rejected if all components held (that is confirmed) or none did (that is falsified) —
otherwise the grade becomes a way for a wrong prediction to feel half-right. And partial
credit is NOT counted in the accuracy figure; a partial is not most of a hit.

Current record: 8 registered, 3 graded — 1 confirmed, 1 partially confirmed, 1 falsified.
Accuracy 1/3, surprise rate 1/3. The surprise rate is tracked deliberately: a program with
no falsifications is not being tested.

The accuracy number is not independent evidence — the same author writes the predictions,
grades them, and writes the contract. The real guarantee is commit order, and every graded
prediction must name the commit that registered it. Stated at the definition, not in a
footnote.

Projection evidence profile grades each projection claim as experimentally-grounded,
fixture-supported, or architectural-hypothesis. The middle grade is the one that matters: a
test I wrote passing against an API I designed is a consistency check, not evidence, and it
cannot falsify the design it was written from. Result: 2 grounded (both resting on the F1.6
Ω_sys evaluator, built independently and before ProjectionContract existed, so it could have
failed to show a difference), 2 fixture-supported, 4 architectural hypotheses. Grounded
fraction 0.25 — projection is carrying more weight than its evidence supports, which is now
asserted rather than admitted.

Every ungrounded claim must name the experiment that would ground it, and every hypothesis
must reference a registered prediction. P-005 through P-008 pre-register the projection
phase before it starts, including the untested case the current fixtures never cover:
projecting a projection, where a second layer might launder what the first withheld.

typecheck clean; check:api 20 frozen entries intact; suite 1083/1083.
…nd dimension

Two additions to the protocol, both aimed at things the existing registries could not record.

Negative results registry (N-001..N-005). A negative result is a hypothesis that survived
pre-registration and adaptation and was then disproven — distinct from a rejected
convenience, and distinct from a regraded prediction. The gap this fills: when a prediction
is regraded, the intuition behind it disappears from the record. N-001 preserves the belief
the FSM falsification destroyed (termination is specific to search substrates), which
otherwise survived only as a false component inside P-002.

Entries are permanent: never deleted, never renumbered, never rewritten into a prediction
update. A superseded entry must name its successor rather than vanish. Identifiers are
asserted dense so a deletion shows as a gap. A falsified entry must name what disproved it
and why, and a test asserts hypotheses are not retroactively strawmanned into something
obviously wrong.

Three entries (N-003 CompiledPattern is a complete world declaration, N-004 field dynamics
is fully declarative, N-005 context.now is needed) are reconstructed from Stage-1 findings
that predate the registry. They are flagged reconstructed: an entry recorded after the fact
is weaker evidence of protocol discipline than one recorded when the belief was abandoned,
and the ledger counts them separately rather than presenting them as equivalent.

Evidence provenance is now a first-class dimension alongside maturity. The two were
conflated: two claims can both be fixture-supported while differing entirely in what backs
them — one exercising a mechanism built earlier for another purpose that could have behaved
otherwise, the other exercising an API introduced in the same commit as its test. The first
can fail; the second is a tautology with assertions.

Five provenance levels with independence ratings that are properties of the SOURCE, not of
the author's confidence: emerged-from-prior-mechanism and revealed-by-independent-substrate
(high), independent-adversarial-test (medium), fixture-against-same-implementation (low),
architectural-argument (none).

A consistency rule enforces that maturity never outruns provenance — experimentally-grounded
requires high or medium independence, so a claim cannot be graded grounded on the strength
of a fixture written against its own implementation. The rule also catches the opposite
error: grading something a hypothesis when an independent substrate actually revealed it
understates what is known.

Applied to both registries. Projection: 2 high, 0 medium, 2 low, 4 none — the two grounded
claims rest on the Ω_sys evaluator built before ProjectionContract existed, and there is as
yet NO independent adversarial test anywhere in the projection evidence, which is precisely
what the next phase must supply. Discoveries: both D-001 and D-002 are
revealed-by-independent-substrate, and a test asserts no discovery may rest on an
architectural argument.

typecheck clean; check:api 20 frozen entries intact; suite 1095/1095.
… the research program

A debugger for computational interaction: every visible statement is reproducible from
recorded evidence, and a reviewer never has to trust the UI.

Architecture. The key constraint turned out to be the right topology rather than an
obstacle: the app CANNOT import the runtime, because core's exports map is closed and core
must stay DOM-free. So the runtime emits a normalized evidence log and the Observatory
renders it —

  living system → instrumentation adapter → normalized evidence log → Observatory

— which makes "the Observatory derives nothing" a structural property rather than a matter
of discipline. There is no code path by which the UI could compute a finding.

Evidence model reuses existing runtime types (OpportunityResult, DetectionResult,
AblationRecord, ProjectionResult, DynamicsEvidence) rather than restating them. Two new
types appear only where several sources had to be represented uniformly: the evidence node
and the recorded transition. Each node carries an origin naming the runtime function that
produced it, and derivedFrom edges make the DAG walkable in both directions.

Replay is deterministic because nothing is recomputed — the cursor indexes an immutable
array the runtime already produced. It cannot modify runtime state because it holds no
runtime reference. Pause, play, scrub, step, jump-to-evidence, bookmark.

Six replay panes (World, Projection, Opportunity, Episodes, Evidence, Timeline) and a
research mode (Corpus, Discoveries, Predictions, Projection lab, Ablation, Cross-version).
All four adapted substrates are captured through one generic path; recordRun does not
mention any substrate by name, and a test asserts it.

What the instrument refuses to do is the substance of the work, and every refusal is
enforced by a test rather than a comment:

- registry sections must deep-equal the live registries, so the UI cannot show a discovery
  the runtime does not hold;
- pending substrates get no fabricated run and render as pending;
- a substrate that cannot declare its transition law shows no law, not an empty one;
- an ablation the harness never executed is marked unsupported WITH THE REASON — two of the
  four requested ablations are currently unsupported, and the viewer says so;
- alternate episode groupings are all retained, none overwrites another, every result is
  labelled conditional;
- inferred state is structurally zero — the category exists only so its emptiness is visible;
- cross-version comparison with one revision loaded shows nothing rather than inventing a
  baseline.

Two guards walk source rather than data: the capture layer must contain no hardcoded
discovery, prediction, negative-result or ablation-classification literal, and the app's own
source is walked for the same literals plus any call to a runtime derivation.

The bundle is a generated capture and is gitignored. A stale committed capture could display
findings that no longer match the live registries, which is exactly the failure mode this
system exists to prevent.

Verified in a browser, not assumed: all twelve views render, the Ω_sys derivation graph shows
each predicate with its basis and authority source, the negative case (delete → unavailable)
lists every failed predicate with its reason, and the inspector resolves citations to
provenance. One real bug found and fixed that way — the transport bar's `hidden` attribute
lost to `display:flex`.

typecheck clean; check:api 20 frozen entries intact; check:links ok; suite 1112/1112.
The existing guards prove the Observatory cannot invent evidence or call a runtime
derivation. They prove nothing about what happens to MEANING between the bundle and a
reviewer's understanding. A renderer can compute nothing and still mislead.

Two instrument effects in the shipped build, found by looking rather than by testing:

1. The Projection pane treated the first recorded projection as an unlabelled baseline for
   its "vs" column, which made one surface read as canonical.
2. The Episodes pane defaulted to segmentation index 0 — precisely the failure of making a
   conditional boundary appear canonical.

Neither is a runtime derivation. Both are mine. Both are now declared transformations with
stated mitigations, and the baseline is named in the column header.

Transformation ledger (T-OBS-001..011 + 5 refusals). Every transformation between normalized
evidence and visible output is named, classified lossless / lossy-disclosed / interpretive,
and required to state its information loss, evidential basis, risk and mitigation. The
target is not zero transformations — a visualization necessarily transforms — but explicit,
bounded, inspectable transformation. Current: 4 lossless, 2 lossy-disclosed, 5 interpretive.

Refusals are recorded so they stay auditable: severity-ranking failed predicates (the
runtime assigns no severity), hiding unavailable operations by default (absence would read
as nonexistence), inferring causality between a discovery and the prediction preceding it
(the registries record chronology, not causation), collapsing disagreeing provenance, and
rendering a view over insufficient evidence.

Semantic model + representation invariants. Views no longer render straight from the bundle;
they build an inspectable semantic model declaring what will be shown and which
transformations produced it. Invariants are asserted against the MODEL, so "the instrument
preserves meaning" is a test rather than a claim. The distinctions that must never collapse:
hidden, unavailable, absent, unknown, unsupported, missing. Eight rules, each with a positive
case and a case proving the defect is caught — including a renderer that maps hidden onto
unavailable, a bare conditional grouping, and a hypothesis dressed with grounded emphasis.

Adversarial calibration fixtures, explicitly labelled as instrument-calibration inputs and
not as evidence about FCI: an operation hidden under one projection and absent from the
world under another; two claims at identical maturity with different independence; two
equally defensible segmentations; a claim with no evidence at all.

Instrument evidence log — the second trace. Records what the instrument loaded, selected,
filtered, refused. Ids are I- prefixed so an instrument event can never be mistaken for
subject evidence, and a test asserts no collision. A reviewer's path through the instrument
is an episode OF THE INSTRUMENT.

Instrument predictions (P-OBS-001..004) live in their own registry, NOT the FCI one. Mixing
claims about a user interface into the theory's accuracy metric would contaminate it. All
four are pending; none may be reported as confirmed.

Fidelity measurement: trace completeness, transformation disclosure, semantic distinction
preservation, replay fidelity, revision fidelity (a foreign schema is refused rather than
reinterpreted with present-day semantics). Interpretation error is deliberately NOT computed
— it requires structured review tasks, and presuming it zero would be exactly the unearned
claim this program exists to prevent. It renders as "not measured", with "not measured is
not zero" stated in the UI.

Refusal instead of a plausible drawing: constructibility() declines to build a view over an
architectural hypothesis and reports the reason, the available evidence and its independence,
what would ground it, and which registered prediction tests it.

The core UI guard is now scoped to shipped UI — the calibration tests legitimately name ids
to prove instrument events cannot collide with subject evidence.

Verified in a browser. typecheck clean; check:api 20 frozen entries intact; core suite
1112/1112; instrument calibration 27/27.
zachshallbetter added a commit that referenced this pull request Jul 20, 2026
….1, M1.5 records, F1.1 audit, F1.9 synthesis (#1077)

## Purpose

Consolidated **documentation** for the Stage‑1 world‑substrate program:
FCI ↔ Fundamental alignment, the program plan (`PLAN.md` v2.1), the M1.5
semantic freeze, the F1.1 audit, execution spec v2, and the F1.9 Stage‑1
synthesis. Docs only — no runtime code, no API change, no release.

Combines three previously separate branches preserving their original
commit sequence (17 commits): `docs/fci-alignment`,
`plan/world-substrate`, `docs/m1.5-semantic-freeze`.

## Scientific motivation

Stage 1 opened with a kernel hypothesis `K = ⟨Entities, State,
Relations, Operations, Dynamics, Projection, Invariants⟩` and a concrete
test: host an existing `FieldPattern` inside it. **That premise was
falsified.** The documentation exists to record *why* the architecture
changed and to freeze the semantics that made the subsequent experiments
interpretable — participant admission, boundary validity,
authority/capability, the causal ladder, kernel roles, the version
envelope, and the ablation methodology. Without a ratified semantic
freeze, an ablation result means nothing.

## Architectural changes

The kernel moved **above** the runtime rather than around it:

```
World  →  DynamicsContract  →  ExecutionSubstrate      (FieldRuntime is the first substrate)
```

`PLAN.md` v2.1 reframes Stage 1 around this. The original F1.1
acceptance criterion is marked **superseded, not deleted**; execution
spec v1 is retained as evidence of the pre‑finding hypothesis.

## Evidence produced

- `F1.1-integration-audit.md` — a file/line‑grounded audit of the real
`CompiledPattern` → `createField` path.
- `m1.5/` — 8 ratified decision records, each with Decision /
Alternatives / Reason / Consequences / Falsification / Open questions /
Ratification.
- `F1.9-stage1-findings.md` — the 14‑section synthesis, with §13 stating
the limits of the evidence explicitly.

## Findings

- **F1.1 falsification (preserved):** `CompiledPattern` is
authoring/runtime configuration, **not** a world declaration — lawful
evolution exists only as executable force code; live state is
closure‑scattered; snapshots are lossy. Direct hosting would have
required delegation, so it was rejected rather than faked.
- **K vs K₀:** `K₀ = ⟨X, Θ, Π, V⟩` is supported as a
**representational** reduction. Entities/Relations/Operations fold into
`X` as typed structures — nothing is derived away.
- **Two pre‑registered open questions resolved** (tested domain):
Projection **is** kernel (it materially changes derivations, so it does
not collapse into observation); Invariants **cannot** be guards inside
an opaque substrate.

## Limitations

Describes **experimental, unexported** work. The public substrate is
**not shipped**; Stage 2 has not begun. Evidence limits are enumerated
in §13 of the findings report (representative force corpus rather than
all 36 forces; conditional equivalence; one real substrate; JS plane
only; analytic boundary justification; `K₀` fold untested at scale). No
empirical or human‑subject validation is claimed anywhere.

## Repository impact

`docs/canonical/` (+1 doc, 2 edits), `docs/planning/world-substrate/`
(program, plan, m1.5, audit, specs, synthesis),
`docs/research/README.md`, and two `apps/site` copy pointers. **No
`CHANGELOG.md` change** — all changelog entries live on the code branch,
so there is no overlap with #1078.

## Testing and gates

```
check-doc-links   PASS
check:docs        PASS
check:readme      PASS
```

## Merge dependencies

**None.** Based on `main`, independently mergeable. *(Verified:
`docs/m1.5-semantic-freeze` already contained `plan/world-substrate`'s
five commits at identical SHAs, so there were no duplicate plan commits
to reconcile.)*

Reviewer merge order: **this PR → #1078 → CompInt #1.** Does not touch
#1034 or #1027.

## Release impact

**None.** No version bump, no tag, no publish, no `[Unreleased]`
promotion; no `package.json` or `version.ts` touched.
@zachshallbetter
zachshallbetter merged commit 21b3968 into main Jul 20, 2026
16 checks passed
@zachshallbetter
zachshallbetter deleted the feat/world-kernel branch July 20, 2026 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant