docs(ledger): C24 enforcement shift — invariant 9 moves from structural to resolver-seam
A cycle-0091 design analysis (adversarially verified) of "does invariant 9 survive lifting blueprints onto the data plane?" records a load-bearing finding in the C24 entry. Pre-C24 a blueprint referencing another project's node was a compile error (topology was in-process Rust — structurally impossible). Post-C24 it is a type-id string refused only by the injected resolver's closed set (UnknownNodeType). The anti-NIH rationale survives (logic stays cargo+Gitea-only; the format distributes topology-as-content, never logic, C17) and std_vocabulary stays a compiled-in dispatch table, not a registry — but enforcement of the engine/project boundary degrades from compiler-guaranteed to resolver-seam discipline. Two consequences recorded: #160 becomes the data-plane face of that boundary (no longer droppable; its own drift still fails safe), and the injected per-project resolver is the genuinely new, deferred invariant-9 surface (a project can express a marketplace one layer above the engine contract) — a World/C21-layer charter point. Invariant 8 (frozen) is reframed alongside: runtime topology generation (research plane) + frozen deploy artifact + deterministic-once-instantiated (C1). refs #160
This commit is contained in:
@@ -1883,6 +1883,30 @@ non-printable; equality could only be defined over the serialized *data*, of whi
|
||||
a drift hazard against the very form #158 content-addresses). The loader stays lenient
|
||||
(a trailing newline on input still parses, Tier-1 robustness).
|
||||
|
||||
**Enforcement shift — invariant 9 on the data plane (2026-06-30, cycle-0091 analysis,
|
||||
adversarially verified).** Lifting topology onto the data plane relocates *where* the
|
||||
engine/project boundary (invariant 9, no bespoke node registry/marketplace) is enforced,
|
||||
without changing what it forbids. **Pre-C24** a blueprint referencing another project's
|
||||
node was a **compile error** — topology was in-process Rust, so cross-boundary node
|
||||
resolution was *structurally impossible*, compiler-guaranteed for free. **Post-C24** that
|
||||
same reference is a **type-id string in a serialized blueprint**, refused only by the
|
||||
injected resolver's closed set (`UnknownNodeType`). The anti-NIH rationale survives intact
|
||||
(node *logic* stays cargo+Gitea-only; the format distributes **topology-as-content**, never
|
||||
logic — C17), and `std_vocabulary` stays a compiled-in dispatch table, not a registry — but
|
||||
its enforcement **degrades from compiler-guaranteed to resolver-seam discipline**. Two
|
||||
consequences: (1) **#160** (the guard that the closed vocabulary stays honest) is no longer
|
||||
droppable hygiene — it guards the data-plane face of the boundary (its own drift direction
|
||||
still fails *safe*, `UnknownNodeType`). (2) The **injected per-project resolver** (C16) is
|
||||
the genuinely new, *deferred* invariant-9 surface: nothing structurally stops a project
|
||||
resolver from accepting arbitrary type-ids, or a project from layering a blueprint
|
||||
*marketplace* (store + type-discovery API) **on top of** the format — one layer *above* the
|
||||
engine contract. Invariant 9 holds **at the engine**; the project/ecosystem boundary (what
|
||||
an injected resolver may resolve, where closed-set discipline draws the line) is a
|
||||
**World/C21-layer charter point**, not an engine fix. Invariant 8 (frozen) is likewise
|
||||
reframed by C24/C21: from "topology baked at build time" to "the World may *generate*
|
||||
topology at runtime (research plane), the chosen blueprint is frozen into the deploy
|
||||
artifact, and any run is deterministic once instantiated" (C1).
|
||||
|
||||
---
|
||||
|
||||
## Open architectural threads not yet resolved
|
||||
|
||||
Reference in New Issue
Block a user