B1.2 · dive 1 of 4 — the typed property
A discriminant carried twice.
The namespace lives in the value — the first three bytes — and in the type, wherever the runtime can hold one. What systems may rely on: a wrong-kind identity cannot cross a declared boundary silently.
The evidence stack runs the whole gauntlet: one compiler error, a 400 issued before any handler runs, and a store-side {:error, :namespace} — the silent join retired at compile time, at the schema, and at the store, in that order.
The evidence stack
committed outputs, quoted verbatimThree layers, three committed proofs — compile time first, then the schema, then the store. The deliberate negative test in the cross-runtime article is one compiler error:
typecheck_negative.ts(13,13): error TS2345: Argument of type 'BrandedId<"USR">' is not assignable to parameter of type 'BrandedId<"CRS">'.
inject: valid/malformed/ns/miss : 200 / 400 / 400 / 404 ← the third column: a valid USR id on a CRS route, refused before the handler
The third column is the one to stare at: a structurally valid USR
id on a route that requires CRS is a 400 issued by the schema compiler — the handler never
runs. The fourth column is the only question a gated route leaves to the handler: known or unknown, 200
or 404. And beneath both sits the store:
G3 typed ok -- rejects 4/4 as :invalid; GRD id on BRL store -> {:error, :namespace}; raising twin -> NamespaceError
The boundary gate, run by hand
inputs per content/vectors.json · content/docs/One-Contract-Three-Runtimes.mdA declared boundary that requires CRS. Every input below is from a
committed source — the article's seed literal, the canonical vector, and two reject vectors. A pure
function replays the gate: parse first, then namespace match; the readout names the verdict and the
layer that issued it.
200 / 400 / 400 / 404 for valid / malformed / wrong-namespace / unknown
(content/docs/One-Contract-Three-Runtimes.md). Select an id to replay the gate against a
CRS boundary.The wrong-namespace refusal and the malformed refusal share a status — 400 — but not a meaning: one is a parse failure, the other a type failure over a perfectly well-formed id. The gate taxonomy keeps the two refusals distinct; dive 4 reads the full vocabulary.
Carriage in Elixir
content/bcs1.2.md · HowThe discriminant lives in binary pattern matching: a function head of
<<ns::binary-size(3), _::binary-size(11)>> with the is_branded
guard makes the function-clause system do the type system's work. The ~b sigil moves
literal validation to compile time — an invalid id in source fails the build, not the request. The store
behind it refuses what the pattern admits but the registry forbids: a GRD id on the
BRL store earns {:error, :namespace}.
Carriage in Go
content/bcs1.2.md · HowNominal where Go can hold it, constructor-enforced where it cannot: one defined type per
registered namespace — type PrtID string, type AstID string — minted only by
parsing constructors, so a PrtID does not assign where an AstID is required,
and the conversion that would defeat it is explicit, greppable, and reviewable. Weaker than a TS brand,
and stated so; the load-bearing gate in Go remains the channel edge of the owner goroutine, where every
inbound id meets Parse before any map is touched.
What it retires
content/bcs1.2.mdThe silent join — the wrong-table id that survives until an analyst notices. With the discriminant carried twice, it dies at compile time, at the schema, and at the store, in that order; each layer that misses it leaves one more layer in front of the data. No runtime carries all three layers, and none needs to: the value carries the namespace everywhere, and each runtime holds it in the strongest type it has.
References
sources · relatedSources
- Erlang/OTP — the ets modulethe private table behind the substrate's store gate, where G3 ran
- King — Announcing Snowflake (2010)the bare 64-bit id the brand wraps — sortable, but typeless without the namespace
Related
- B1.2 — the module hubthe contract sheet, all four properties
- B1 — Ideas Behindthe chapter landing
- BCS — the course homethe law, the id anatomy, the chapter map
- Functional Programming in Elixirthe umbrella where echo_data — the production identity library — lives