B2.1 · dive 1 — the export list
Six functions, and a wall.
A system exports functions over identities and exports nothing else — the sentence from the Part II preface, now gated. R1 inspects the store module's actual surface; R5 proves the surface refuses kinds it never declared.
Source: content/bcs2.1.md, quoting bcs_rung_2_1_check.out; the substrate
modules are committed at lib/echo_data/bcs/.
The transcript
bcs_rung_2_1_check.out · verbatim · this dive reads R1 and R5boot: two stores under one_for_one; native codec self-check passed at each init R1 surface ok -- exports: six domain functions plus OTP callbacks, nothing else -- no table, no pid, no internals R2 existence ok -- existence restored, data not: fresh table after kill -- durability is a different chapter's job R4 radius ok -- sibling untouched (one_for_one): ord_store pid stable, row intact through prt_store's crash R3 checkpoint ok -- recovered through the boundary, not the heap: re-put from a read-back row R5 gate ok -- prt_store refuses an ORD name with {:error, :namespace} -- admitted kinds are per-boundary PASS 5/5
R1 — the boundary is the export list
content/bcs2.1.md · WhatR1 inspects the store module's actual surface and finds exports: six domain
functions plus OTP callbacks, nothing else — start_link/1, put/3,
get/2, page_desc/2, record_entity/2, placement/1, and
the behaviour's own callbacks; no table reference escapes, no pid is handed out, no internal record leaks
its shape.
What a system never exports is the more important half: the table
(protection: :private in the substrate's own gate record) and anything whose shape would
couple a caller to a representation. For agents, R1's surface is the whole callable world: what the
export list does not say, an agent may not call. The export list is the boundary contract — adding an
export is an architecture change with R1 as its gate, not a convenience landing in a diff;
Property Stores on ETS (B2.2) performs that review once, on stage.
R5 — the boundary declares its kinds
content/bcs2.1.md · What · lib/echo_data/bcs.exR5 offers the portfolio store an ORD name and is refused with
{:error, :namespace} — admitted namespaces are a per-boundary property, checked at every
ingress, exactly as Chapter 1.2 placed clause three. One system, one table, one declared kind set; the
silent join has no door here. The committed gate, verbatim:
def gate(id, ns) when is_binary(id) and is_binary(ns) do
case BrandedId.parse(id) do
{:ok, ^ns, snow} -> {:ok, snow}
{:ok, _other, _snow} -> {:error, :namespace}
:error -> {:error, :invalid}
end
end
No second parser: classification beyond the namespace collapses to :invalid,
exactly as EchoData.BrandedId.parse/1 reports it.
gate/2 on
prt_store, whose declared kind set is PRT. Select a presented kind; the
readout names the verdict.Static verdicts — PRT → {:ok, snowflake} ·
ORD → {:error, :namespace} (the rung's own crime, R5's recorded refusal)
· AST → {:error, :namespace} · TXN →
{:error, :namespace} · a non-id shape → {:error, :invalid}.
References
sources · relatedSources
- Erlang/OTP — the supervisor behaviourthe behaviour whose callbacks R1 admits beside the six exports
- Erlang/OTP — the ets moduleprotection levels — :private; the table behind the wall
Related
- B2.1 — A System Is an OTP Applicationthe module hub; the full rung in context
- B2 — The Elixir BCS Corethe chapter landing; the Part II arc
- BCS — the course homethe law, the id anatomy, the chapter map
- Functional Programming in Elixirthe umbrella where echo_data lives