VibeVM
Contents
On this page
en
Publisher
org.vibevm.core
Version
1.0.0latest
Audiences
user
Reading time
8 min
Rendered
Read aloud
never

PROP-034: Transitive inclusion links and the static boot-link graph

01Status: IMPLEMENTED under renamed terms (requirements authored 2026-07-14 at the owner's request; verified against the tree 2026-07-25 by the spec-actualization campaign). static-transitive is live on LinkType, and dedup + topological ordering + tie-break emission run in bootgen — this repository's own STATIC.md is the §3 redbook closure in the flesh. PROP-035 §12 and PROP-038 absorbed the graph as their emission layer; read the TERMINOLOGY-RENAME note below before the body. Extends PROP-009 (the loading model).

02Scope note (2026-08-23, PROP-050 §3): the boot-link graph this document defines is now built over the consumer root's effective set E(R) — the visibility layer (access / friendship / exclude / override, PROP-050) decides which nodes exist before any link mode is read; a static-transitive edge propagates strength across visible edges only.

03Terminology (2026-07-16): the inline / static / dynamic link types this document describes were renamed — read inline as static (the verbatim STATIC.md lane), static as dynamic (the default, a by-reference read), and the old dynamic as a dynamic entry carrying a when; inline-transitive is now static-transitive. See PROP-009 §2.4. The body below predates the rename and keeps the old names.

04Related: PROP-009 §2.4 (the direct inline / static / dynamic link types this PROP makes transitive), PROP-028 (families / collections — the motivating consumer), PROP-003 / PROP-017 (version unification — one node per resolved package), vibevm/vibespecs/design/loading-and-boot-model.xml (the static/dynamic-linking metaphor this PROP completes).

05Supersedes: backlog B1 (transitive-inline / transitive-static) — promoted to this PROP.

1. Motivation — the boot closure must link like a static linker

06PROP-009 §2.4 gives each direct dependency edge an inclusion type — inline (verbatim into INLINE.md, the priority lane), static (a path in INDEX.md), or dynamic (a conditional INCLUDE). Two gaps make a growing dependency set fragile, and a collection like redbook un-loadable the way its consumer wants:

07Gap 1 — inclusion does not propagate transitively. A consumer sets link only on its own direct edges.

  • 08A dependency's transitive closure takes its type from each member's own [boot_snippet] suggested link, or the static default — bootgen resolves declared_link.or(suggested_link), and a transitive dependency's declared_link reads back as None.
  • So a collection (e.g. redbook, PROP-028) cannot say "load my whole closure inline."
  • The only workaround — each member self-suggesting inline — is wrong: it forces inline on every consumer of that member, not just the one collection that wanted it.
  • Inclusion strength is a property of how a consumer pulls a subtree, and today that cannot be expressed.

09Gap 2 — the boot closure is not resolved as a static link graph. A dependency closure is a graph, and assembling a boot from it is exactly static linking.

10Three linker invariants are currently only informally met by PROP-009's "ordered list" and are load-bearing:

  • 11Each package linked exactly once. A package reachable through several dependency paths must appear once in INLINE.md / INDEX.md, never N times. Double-inclusion wastes context, and for inline it duplicates verbatim text and its anchors (a duplicate-anchor hazard).
  • Dependency order (topological). A package must be emitted before every package that requires it, so that when a dependent's boot text is read, everything it builds on is already in context. A package needed by another (or several) comes earlier in the sequence.
  • Deterministic and acyclic. The walk must be deterministic (stable output across runs) and reject cycles loudly at generate time — the agent-side read stays recursion-free (PROP-009 §2), so all graph work, including cycle detection, happens once in vibe.

12Without these pinned, adding the whole redbook, delegation-first, and future collections risks a boot that double-includes packages and orders a dependent before its dependency — the failure the owner names as "we might never load cleanly."

2. Decisions

2.2 Effective inclusion mode — the precedence lattice

17A package can be reached by several edges and several transitive closures carrying different modes.

18Its effective inclusion mode is the join of every mode that reaches it, under the lattice:

19inline ⊐ static ⊐ dynamic

20Resolution, for each package in the closure:

  1. 21Collect every mode reaching it:
  2. (a) a direct edge to it contributes that edge's mode;
  3. (b) a transitive link contributes its mode to every package in the closure reached through it;
  4. (c) the package's own [boot_snippet] suggested link;
  5. (d) the static default when nothing else applies.
  6. The effective mode is the strongest (left-most) of those.

22Consequences, all deliberate:

  • 23Inline wins, monotonically. If any path pulls a package inline (a direct inline, or an inline-transitive ancestor, or a self-suggested inline), it is inline. Adding a stronger link never demotes a package — a package's priority can only rise, never silently fall, as the graph grows.
  • dynamic is overridden by any unconditional need. If one path needs a package dynamic (context-gated) but another needs it static/inline unconditionally, it loads unconditionally — the when gate cannot hide a package something else requires outright.
  • A direct link never demotes a package an ancestor pulled inline-transitive (inline is sticky, per the monotonicity above). A consumer that truly needs a subtree not inline must not sit under an inline-transitive edge to it.

24The lattice makes the effective mode a deterministic function of the graph, independent of walk order.

2.4 Emission — a dependency-ordered priority lane and index

27From the sorted, deduplicated, mode-assigned node list:

  • 28inline nodes → concatenated verbatim into INLINE.md, in topological order — a dependency's boot text precedes its dependents' within the priority lane. This is the static-linked inline lane: inline content, but resolved, deduplicated, and dependency-ordered by the linker rather than pasted in discovery order.
  • static nodes → [[entry]] kind = "static" in INDEX.md, in topological order.
  • dynamic nodes → [[entry]] kind = "dynamic" with their when, in topological order.

29Both lanes are dependency-ordered: a reader (human or agent) always meets a package before anything that builds on it, and never meets the same package twice.

2.5 Boot budget note

  • 30inline-transitive over a large collection puts that collection's whole boot closure into INLINE.md, read first and in full every session.
  • That is the point when priority must be guaranteed by position (critical practices that must never be missed) — and a real cost when the closure is large.
  • Choose inline-transitive for closures whose every member is boot-critical; keep static-transitive (still deduplicated and dependency-ordered, but read on demand from INDEX.md) as the default for large practice sets where INDEX-lane resolution is acceptable.

3. redbook as inline-transitive — the motivating case

31vibevm pulls flow:org.vibevm.world/redbook as inline-transitive. The effect, under §2:

  • 32Every practice redbook collects, plus their transitive deps, resolves to effective mode inline.
  • The graph is deduplicated: a practice several members share (e.g. git-practices, or a common dependency) appears once.
  • The graph is topologically ordered: a practice needed by another (or by redbook itself) is emitted earlier in INLINE.md.
  • The whole tested edition is thus in the priority lane, verbatim, dependency-ordered, once each — the practices are guaranteed to load, which is the safety the owner is buying (over static, which trusts agent-side INDEX resolution).

33The per-member [boot_snippet].link = "inline" self-suggestions used as the B1 interim (e.g. on the git-practices members) become unnecessary once the consumer declares inline-transitive, and can be dropped — the inclusion strength moves back to the consumer where §2.1 puts it.

4. Compatibility and migration

  • 34The direct inline / static / dynamic types and their semantics are unchanged; the transitive variants are purely additive to the link enum.
  • §2.3's dedup + topological order pins what PROP-009 §2 left as an "ordered list": existing manifests keep working and simply gain guaranteed single-inclusion and dependency order. Any boot that silently relied on a non-topological order is a latent bug this surfaces.
  • Manifest schema (vibe-core): the link field accepts the new variants; unknown link values remain a manifest error.
  • Implementation lands in vibe-workspace boot resolution (bootgen): mode propagation (§2.2), dedup, topological sort with the deterministic tie-break, and cycle rejection.

5. Open questions

  1. 35dynamic-transitive. Semantics of gating a whole closure behind one when (does the gate distribute to every member, or gate the subtree as a unit?) — reserved until a use case appears.
  2. when inside a transitive-inline closure. A member carrying its own when OS-gate that is pulled inline-transitive: does inline (unconditional, verbatim) or the gate win? Provisional: an explicit member when keeps the member dynamic (the gate is more specific than the ancestor's blanket inline); confirm against a real case.
  3. Explicit demotion. Whether to add a link = "static-here" escape that lets a consumer pull a package static even under an ancestor's inline-transitive (breaking the monotonicity of §2.2). Deferred — no demotion use case today, and monotonic priority is the safer default.

6. Version history

  • 362026-07-14 — drafted (owner-requested). Promotes backlog B1. Defines the transitive inline-transitive / static-transitive links (§2.1), the effective-mode precedence lattice (§2.2), and the static boot-link graph — dedup + topological order + cycle rejection (§2.3) — with dependency-ordered emission into the INLINE.md priority lane and INDEX.md (§2.4). redbook is the motivating inline-transitive consumer (§3). Implementation (manifest schema + bootgen resolution) is the next milestone.

For an agent

This page has a machine mirror. The citation carries the version rather than latest, so what an agent quotes does not move under it.

spec://org.vibevm.core/vibevm@1.0.0/modules/vibe-workspace/PROP-034-transitive-links-boot-graph

.md.xmlllms.txt