The v0.1 Pragmas (Normative)

The header of osmol.py documents five deliberate simplifications, the v0.1 pragmas. They are not implementation trivia. For v0.1 they are normative: they define what the language actually does today, and every successor implementation must either honor each pragma or consciously supersede it through the RFC process. A successor that silently diverges from a pragma is not more correct than the reference interpreter; it is nonconforming.

This chapter promotes each pragma to its proper status: statement, rationale, required behavior, and how to test for it.

Pragma 1, Circles derive from bonds

Statement (from the header): a sender's membrane audience family/team matches any party the sender bonds with trust high; others is the rest.

Rationale. v0.1 has no social-graph model; the only relationship signal in the language is bond. Deriving audience classes from trust-high bonds gives membranes real semantics with zero new syntax.

Required behavior. When evaluating a membrane rule selector -> family: … or -> team: … in twin A against receiver B, the rule matches iff A declares bond b { trust high } for B. -> others matches iff A does not bond B trust-high. -> all matches everyone; a bare name matches that twin exactly. Separately, the receiver's class for a sender (which selects θ) derives from the receiver's own bonds: trust-high sender ⇒ family, otherwise others.

Test hint. Remove bond raj { trust high } from maya in dinner.osmol: the eta(*) -> family: exact rule stops matching, the -> others: coarse(30m) rule takes over, and raj's threshold class for maya flips to others.

Pragma 2, Wall-clock time is not simulated

Statement: deadlines raise urgency (U = 1.3) and drive escalation notes, but quiet hours are stored only.

Rationale. A clock in the settle loop would make traces depend on when you run them, and that is fatal for golden-file testing. So v0.1 collapses time to one bit: has a deadline, or not.

Required behavior. Any by clause on a gap sets U = 1.3; no deadline means U = 1.0. No gradual promotion, no lateness detection. quiet ranges parse and store but are never consulted. Sync-tagged gaps still open at equilibrium print the sync will be scheduled note rather than booking anything.

Test hint. Delete by 19:00 from raj's eta gap: the t2 flow's pressure drops from 1.30 to 1.00, and nothing else changes.

Pragma 3, owe auto-supplies status

Statement: owe X(args) auto-emits hold status(args.X) = in-progress on the ower.

Rationale. Spec §3: commitments generate structural gaps automatically; an unmet owe implies the counterparty's seek for its status. Structural demand needs structural supply, or the implied gap could never close.

Required behavior. Parsing owe review(atlas) to raj by fri in maya's twin emits hold status(atlas.review) = in-progress (argument path first, then the fact name), unless she already holds that fact explicitly.

Test hint. This is why t3 exists in the canonical trace: raj's seek status(atlas.review) drinks from a holding maya never wrote.

Pragma 4, decide requires human judgment

Statement: the engine cannot choose. Resolutions are injected via --resolve twin:fact=value.

Rationale. This one is different from the other four. It is no simplification at all but a permanent feature of the runtime contract (dissertation Chapter 3): human judgment is an input type, not a solver capability, in every habitat, always. No future implementation may supersede it.

Required behavior. An unresolved decide does not block settlement. The mesh settles around it: every other gap that can close will close, the engine declares equilibrium for what remains, and the open gap plus the waiting decide are reported in the footer as awaiting human judgment ... machines do not choose venues. We verified this against the interpreter: the dinner mesh without --resolve reaches equilibrium after 2 flows with the venue gap still open. A resolution must name one of the enumerated options, deletes the decide, and emits the corresponding hold.

Test hint. Run the dinner mesh without --resolve: maya's venue gap survives to the footer and raj's decide prints as awaiting judgment. See Resolving Decides.

Pragma 5, Placement

Statement: express → human lane (verbatim, delivered first); escalate-tagged gaps → ledger; everything else → silent. Interrupts exist but demand a passed escalate deadline, which needs wall-clock: unused.

Required behavior. The human lane delivers before any flow, untransformed, provenance-labeled. A delta absorbed into a gap declared else escalate appends to the receiver's ledger; all other deltas are silent. No flow ever places as interrupt in v0.1, and every trace footer truthfully prints interruptions: 0.

Test hint. The canonical trace's [ledger] on t1 and [silent] on t2/t3 are exactly this pragma.

The constant tables

These values are normative for v0.1; changing any of them is a semantics change and therefore edition-visible.

ConstantValues
Trust weight Thigh 1.0 · medium 0.6 · low 0.3 · no bond ⇒ medium
Cast weight Mexact 1.0 · coarse(g) 0.7 (any grain) · category 0.5 · existence 0.3 · deny 0
Default θfamily 0.3 · team 0.4 · others 0.8
Urgency U1.3 with any deadline, else 1.0
Relevance R1.0 (exact fact-name match is the only relevance)
Attention cost C0.0 (no interrupts are ever spent)

Not implemented in v0.1

Equally normative is knowing what the reference interpreter does not do:

  • roledecl (assume/yield role): parses nowhere; semantic addressing waits for the mesh's role registry. See the wire roadmap.
  • stake: unparsed; the anti-spam economics need a reputation ledger and, ultimately, Theorem 5.
  • when conditions on membrane rules: parsed and stored, never evaluated. The Rust checker takes these up in osmol-core Stage 3.
  • Number trust levels (trust 0.8): the grammar allows them; the engine knows only the three words.
  • Lexicographic tie-break: the spec-level rule orders equal-pressure flows by (sender, receiver, fact); v0.1 uses iteration order, and the two visibly disagree even on the shipped corpus. In the canonical dinner trace, the equal-pressure t1/t2 flows fire in scan order, where the lexicographic rule would fire maya's eta before raj's venue (see the honesty note in the pressure chapter). The Rust solver must implement the real rule; reconciling the golden trace with it is an open, RFC-shaped decision.

Each absence is a rung on the build ladder, not a hole in the language. The pragmas are the honest boundary line between the two, and the reference interpreter's header is where that line is signed.