Two conformant runtimes must agree on every verdict — so
they must agree on the arithmetic the verdicts are built
from. box-and-box pins a single numeric domain:
IEEE-754 binary64 (double); one canonical rounding util
round(x, dp = 3) (and
roundDelta = round(x, 6) for evolution
deltas), defined as
Math.round(x · 10^dp) / 10^dp — half-toward
+∞ at the .5 boundary; one comparison tolerance
EPS = 1e-9 via
approxEq. Fields are EXACT (compared
with ===: n, κ,
phase, ledger balances) or TOLERANCE (compared
with approxEq: β, utility,
scores). Non-finite inputs pass through
round unchanged — fail-closed, never NaN
laundering. The full normative statement lives in the
kernel README §Numerics and the exported
box-and-box/numerics module; the laws below
are stated over this domain.
feasible ▸ permitted ▸ best — the rule that composes the rest, and the annihilation that makes a veto absolute.
B1▸veto ⇒ score 0̲✓
infeasible(o) ⇒ gatedScore(o) = 0̲
(−∞)
B2▸select ranks within feasible✓
select = argmax utility over the feasible
set only
B3▸conservativity: one feasible ⇒ chosen✓
|feasible| = 1 ⇒ that option chosen (even
vs. utility 999)
what can happen, the monoid of values, and the 0̲ that infeasibility collapses to.
L1▸combine associative✓
combine(combine(a,b),c) =
combine(a,combine(b,c))
L2▸combine identity V0✓
combine(a, V0) = a
L3▸commutative families (n,κ,β,σ,deny)✓
combine(a,b) = combine(b,a) on
each field
L4▸β idempotent under min✓
combine(a,a).β = a.β (β merges by
min)
L5▸σ idempotent under ∪✓
combine(a,a).σ = a.σ (σ merges by
∪)
L6▸κ idempotent under ∨✓
combine(a,a).κ = a.κ (κ merges by
∨)
L7▸promote β-monotone✓
promote(a, ev).β ≥ a.β
L8▸reconcile antitone + idempotent✓
reconcile(a,T).σ ⊆ a.σ, and
reconcile is idempotent
L9▸deliberate κ→false + idempotent✓
deliberate(a).κ = false, and
deliberate is idempotent
L10▸chain refuses a backward phase✓
phaseIdx(a) > phaseIdx(b) ⇒ chain(a,b)
errors
L11▸chain associative where defined✓
chain assoc. on forward-ordered
triples
L12▸promote distributes over combine on β✓
promote(combine(a,b)).β = combine(promote
a, promote b).β
L13▸consume gate (β_min)✓
consume(a).ok ⟺ a.β ≥ β_min
L14▸deny_default idempotent under ∧✓
combine(a,a).denyDefault =
a.denyDefault
(merges by ∧)
obligation, prohibition, conflict, and contrary-to-duty repair — and how a permit composes into the verdict.
D1▸join commutative + associative✓
join(a,b) = join(b,a),
join associative
D2▸join identity OPTIONAL + idempotent✓
join(a, OPTIONAL) = a,
join(a,a) = a
D3▸O ⊔ F = CONFLICT✓
join(OBLIGATORY, FORBIDDEN) =
CONFLICT
D4▸join monotone (a ⊑ a⊔b)✓
rank(a ⊔ b) ≥ rank(a) and
≥ rank(b)
D5▸CONFLICT absorbs✓
join(CONFLICT, a) = CONFLICT
D6▸resolve idempotent + clears conflict (distinct prio)✓
resolve with distinct priorities
clears CONFLICT; resolve idempotent
D7▸factual detachment (in force iff condition)✓
detach(duty).inForce ⟺ condition
holds
D8▸CTD partiality (repair iff violated)✓
repair present ⟺ primary duty
violated
D9▸comply: O⇒¬F (ought is permitted)✓
comply(O,done)=ok;
comply(F,done)≠ok;
comply(O,¬done)≠ok
DB1▸forbidden excluded from decision✓
forbidden option (utility 99) is never
chosen; safe option wins
DB2▸obligation forces over higher score✓
obligatory(utility 1) chosen over
non-obligatory(utility 99)
DB3▸alethic precedence ⇒ CTD escalation✓
obligatory option infeasible ⇒ decision
null + CTD escalation
how the feasible, permitted options are ranked — in a semiring, so preferences never resurrect a vetoed one.
H1▸⊕ commutative monoid✓
⊕ commutative, associative, identity
0̲
H2▸⊗ monoid✓
⊗ associative, identity 1̲
H3▸left distributivity✓
a ⊗ (b ⊕ c) = (a ⊗ b) ⊕ (a ⊗ c)
H4▸right distributivity✓
(a ⊕ b) ⊗ c = (a ⊗ c) ⊕ (b ⊗ c)
H5▸0̲ annihilates ⊗✓
0̲ ⊗ a = 0̲
H6▸⊕ idempotence (dioid only)✓
a ⊕ a = a under the tropical dioid
H7▸⊗ monotone in order✓
a ≤ b ⇒ a ⊗ c ≤ b ⊗ c
H8▸reinforce η-contraction✓
|reinforce(u,t,e) − t| = (1−e)·|u −
t|
H9▸rollout γ-contraction✓
‖Bu − Bv‖ = γ·‖u − v‖
H10▸dominate idempotent + Pareto✓
dominate idempotent; no Pareto-dominated
survivor
H11▸anneal ε→0 idempotent✓
anneal drives ε → 0, and is a
fixpoint there
H12▸softmax shift-invariant✓
softmax(u, T) = softmax(u + c, T)
H13▸T→0 collapses to argmax✓
softmax(u, 0⁺) → argmax
safety as an invariant over the whole trajectory; liveness as a horizon obligation.
T1▸G,F idempotent (GGφ≡Gφ)✓
GGφ ≡ Gφ, FFφ ≡ Fφ
T2▸duality (¬Gφ≡F¬φ, ¬Fφ≡G¬φ)✓
¬Gφ ≡ F¬φ, ¬Fφ ≡ G¬φ
T3▸∧,∨ commutative + idempotent✓
∧, ∨ commutative and idempotent
T4▸progression faithful (monitor ≡ direct)✓
monitor verdict = direct trace
semantics
T5▸safety finite-witness / liveness never-early✓
safety emits a 'vio' witness at the breach
step; liveness never commits false
early
T6▸G/∧ and F/∨ distribute✓
G(a ∧ b) ≡ Ga ∧ Gb,
F(a ∨ b) ≡ Fa ∨ Fb
T7▸until fixpoint (φUψ≡ψ∨(φ∧X(φUψ)))✓
φUψ ≡ ψ ∨ (φ ∧ X(φUψ))
T8▸lasso GF/FG + G/F vs unrolling✓
GF = some loop state; FG = every loop
state; G/F = unrolled prefix
TB1▸safety shield prunes a violating step✓
residual rejects a violating next step,
accepts a holding one
TB2▸unmet liveness ⇒ escalation at horizon✓
missed liveness at horizon ⇒ escalate
(repair/replan)
TB3▸safety violation ⇒ unsafe verdict✓
supervise returns safe=false at the exact
violatedAt index
a closed, double-entry budget; affine use; and pricing the kernel’s own deliberation.
C1▸conservation under transfer (Σ invariant)✓
total balance invariant under any
transfer
C2▸no overdraft; balances stay ≥ 0✓
over-transfer ⇒ INFEASIBLE; all balances ≥
0
C3▸independent transactions commute (CRDT)✓
disjoint transfers commute
C4▸linearity — spending depletes (not idempotent)✓
spend twice removes two units
C5▸reusability — using `!` does not deplete (idempotent)✓
using a reusable (`!`) skill twice leaves
the balance unchanged
C6▸flow monotonicity — depletion only decreases✓
available tokens only decrease over a
run
C7▸capacity conservation (stability + plasticity)✓
total capacity invariant under
allocate/forget
C8▸no free reclaim — forgetting releases the knowledge✓
forget releases capacity AND the associated
knowledge
C9▸irreversible sink is absorbing — sink monotone, allocation of unspent budget still feasible✓
kind[res]='irreversible' ⟹ sink(res)
non-decreasing ∧ transfer(SINK → ·) =
INFEASIBLE
C10▸a declared cap bounds cumulative consumption of an irreversible resource✓
sink(res) ≤ cap[res], always
C11▸the authority fields (kind, cap) are frozen — a declared cap cannot be rewritten✓
kind and cap are frozen at construction and
on every clone; writing one throws
L.cap.hb = 100 walked past C10 and
L.kind.hb = 'depletable' walked
past C9. The two fields that decide what the
rules are are now sealed, and the seal
survives cloning. Balances are deliberately
not sealed and that boundary is
declared rather than enforced — a Ledger is a
value, not a capability handle, and making
balances unforgeable needs an opaque
write-mediated object.
CB1▸exhaustion ⇒ infeasible (the alethic 0̲ gate)✓
feasible ⟺ balance ≥ cost
CB2▸cost composes additively along a pipeline (semiring)✓
three staged spends = one lump spend of the
sum
|>.
CB3▸Type-II repair pricing (value ≥ cost ∧ affordable)✓
repair invoked ⟺ value ≥ cost ∧ affordable;
charges cost
CB4▸irreversible exhaustion is not recoverable from the sink✓
exhausted ∧ irreversible ⟹ no transfer out
of SINK re-opens the CB1 gate
CB5▸the alethic gate agrees with the primitive✓
feasible(L, acct, cost) ⟺ charge(L, acct,
cost) ≠ INFEASIBLE
feasible said
GO on a spend transfer was already
committed to refusing. C1, C2, C9 and C10 all
still held — no law compared them. A decision
layer answering yes over a primitive answering
no is worse than either answer alone, because
the caller has committed by the time it finds
out. Both now consult one admissibility
predicate, and this law is what keeps them
pointed at it.
CB6▸a preflighted path never returns INFEASIBLE dressed as a ledger✓
use(·).L ≠ INFEASIBLE ∧ repair(·).L ≠
INFEASIBLE
use and repair ran
their own affordability check and then called
spend, so an irreversible resource
at its cap produced
{ok: true, L: INFEASIBLE} — a
Symbol handed to a caller expecting a ledger.
The general form is the lesson: a new invariant
is not finished when the primitive that states
it enforces it. Every other path deciding the
same question has to be found and pointed at the
same predicate.
knowledge (S5) vs. belief (KD45); a known-unknown that must route to deliberation.
E1▸factivity T (Kφ → φ)✓
Kφ → φ
E2▸distribution K (K(φ→ψ)∧Kφ → Kψ)✓
K(φ→ψ) ∧ Kφ → Kψ
E3▸positive introspection (Kφ → KKφ)✓
Kφ → KKφ
E4▸negative introspection (¬Kφ → K¬Kφ)✓
¬Kφ → K¬Kφ
E5▸belief consistency D (¬(Bφ ∧ B¬φ))✓
¬(Bφ ∧ B¬φ)
E6▸knowledge ⇒ belief (Kφ → Bφ)✓
Kφ → Bφ
E7▸learning monotonicity (announce preserves K)✓
public announcement of a truth preserves
prior K
E8▸common knowledge (Cφ → Eφ)✓
Cφ → Eφ
EB1▸threshold gate monotone; K = belief@1✓
belief gate monotone in threshold;
knowledge = belief at threshold 1
EB2▸known-unknown ⇒ deliberate (κ)✓
knowsItDoesntKnow ⇒ route =
deliberate
EB3▸pooled knowledge dominates individual✓
individual knowledge ⊆ distributed
knowledge
which coalitions can actually ensure an outcome — ought-implies-can, made checkable.
S1▸unit: [C]⊤ and ¬[C]⊥✓
[C]⊤ holds; [C]⊥ never holds
S2▸coalition monotonicity (C ⊆ C′ ⇒ [C]φ → [C′]φ)✓
C ⊆ C′ ⇒ [C]φ → [C′]φ
S3▸outcome monotonicity (φ⊨ψ ⇒ [C]φ → [C]ψ)✓
φ ⊨ ψ ⇒ [C]φ → [C]ψ
S4▸superadditivity (disjoint C₁,C₂ cooperate)✓
[C₁]φ₁ ∧ [C₂]φ₂ ⇒ [C₁∪C₂](φ₁ ∧ φ₂)
for disjoint C₁,C₂
S5▸regularity (¬([C]φ ∧ [N∖C]¬φ))✓
¬([C]φ ∧ [N∖C]¬φ)
S6▸maintenance is a greatest fixpoint (□)✓
canMaintain = greatest fixpoint (□)
S7▸reachability is a least fixpoint (◊)✓
canReach = least fixpoint (◊)
S8▸grand-coalition determinacy ([Σ]φ ↔ ∃ successor φ)✓
[Σ]φ ⟺ ∃ successor satisfying φ
SB1▸single-agent collapse → temporal reachability✓
1-agent canReach = BFS reachability
SB2▸ought-implies-can (¬ability ⇒ escalate)✓
oblige ⇒ discharge if canEnsure, else
escalate
SB3▸coordination needs ability ∧ common knowledge✓
executable ⟺ canEnsure ∧
commonKnowledge
rules that change rules, with an entrenched core that no amendment can weaken.
R1▸success (enact adds, repeal removes)✓
enact adds a rule; repeal removes it
R2▸consistency (no surviving dominated conflict)✓
arbitration leaves no dominated O/F
conflict standing
R3▸minimal change (enact∘repeal = id)✓
enact then repeal returns the exact
original rule-set
R4▸entrenchment (no weakening the core)✓
entrenched 'safe' rule cannot be repealed
or weakened, only strengthened
R5▸lex superior (priority wins)✓
higher-priority rule overrides lower
R6▸lex posterior (recency breaks ties)✓
equal priority ⇒ more recent rule
wins
R7▸arbitration idempotent✓
arbitration is idempotent
R8▸reflective stability (fixpoint)✓
stabilize reaches a fixpoint
RB1▸cannot self-permit the forbidden✓
an obligation out-prioritizing an
entrenched prohibition is rejected
RB2▸revision propagates to govern✓
enacting a prohibition flips the live
verdict (A chosen → A vetoed)
RB3▸entrenched safety survives in supervise✓
entrenched temporal floor can't be repealed
and still enforces
Where the laws bend — by design
A governance algebra has to know the difference between regimes. So the harness also checks, on every run, that certain properties fail exactly where they should. These aren’t bugs — they’re the distinctions that make the kernel honest.
the measured, priced, certified self-revision bridge — a join across reflexive × axiological × resource: may this policy change, did it measurably improve, is it worth paying for.
EV1▸digest is key-order independent✓
digest(canon(x)) is invariant under JSON
key reordering
EV2▸chain verifies & detects tamper✓
verify(chain) holds; mutating any record
breaks verify
EV3▸refuse to weaken the entrenched floor✓
a change weakening an entrenched floor is
rejected, even at large positive Δ
EV4▸a regressing change is never accepted✓
regresses(before, after) ⇒ decision ≠
accept
EV5▸priced accept ⇒ affordable ∧ worthwhile ∧ charged✓
accept ⇒ affordable ∧ worthwhile ∧ ledger
charged
EV6▸certificate soundness✓
predicted / observed / verified / priced
agree with the recorded decision
the lego layer — two brick operators, &
(parallel coalition) and |> (sequential
pipeline), over one shared floor 0̲.
A brick of bricks is a brick.
CA1▸& associative✓
(a & b) & c = a & (b & c)
CA2▸& commutative✓
a & b = b & a (capability lattice)
CA3▸& idempotent✓
a & a = a (value carrier)
CA4▸&none identity✓
a & none = none & a = a
&.
CP1▸|> associative where feasible✓
(a |> b) |> c = a |> (b |> c)
CP2▸id identity✓
a |> id = id |> a = a
|>.
CP3▸|> non-commutative (backward ⇒ 0̲)✓
forward a |> b survives; backward b |>
a ⇒ 0̲
CP4▸infeasible hand-off ⇒ 0̲✓
feeds_into(a) ∩ accepts_from(b) = ∅ ⇒ a |>
b = 0̲
CX1▸0̲ absorbs both operators✓
a & 0̲ = 0̲ & a = a |> 0̲ = 0̲ |>
a = 0̲
CX2▸quantity semiring✓
confidence = ∏ · cost = Σ · latency =
max
CX3▸conservative cost (uncertified ⇒ 0̲)✓
an uncertified child ⇒ composite = 0̲
CX4▸cost-class lattice (worst wins)✓
certified composite costClass = join (worst)
of children
CX5▸closure (a brick of bricks is a brick)✓
compose(brick, brick) is itself a brick
CX6▸fail-closed (a malformed child ⇒ 0̲ or a valid brick, never an exception)✓
compose(partial|garbage, b) never throws; result isZero or isBrick
CX7▸a malformed semantic value cannot normalize to LIVE — unknown floors to 0̲, not to V0✓
unreadable(v) ⇒ isZero(Brick(value=v))
CX6 could not see it.
A malformed value — a string, a number, an array, an error sentinel — floored to
V0(), the benign identity value: feasible, acyclic, no conflict. So
"I cannot interpret this value" became "the harmless
value" and stayed LIVE. CX6 asks for
"0̲ or a valid Brick, never an exception", and
V0() is a valid Brick — so a fuzzer aimed at crashes was fully satisfied
by the laundering. Directive 1 says FAIL-CLOSED and the code had read it as
DO-NOT-THROW; not throwing is necessary and is not sufficient. A partial object
is still fine — its fields are readable and the rest take documented defaults. The line
is between "incomplete" and "not a Value at all".
AC-COMM▸&'s OWN floor is commutative (the anchor: a brick of bricks is a brick)✓
isZero(a&b) === isZero(b&a)
& itself. Listed here because the page counted the anchor in its total without ever showing it.
Contract declaration — missing ≠ universal
Added 2026-08-22. Until that day Brick() defaulted an absent contract
field to '*' and typeMatch() waved through null on
either side, so an assembly that declared no interface at all received the most permissive
one in the algebra and every hand-off passed a check with nothing left to check —
fail-open, in a runtime whose whole claim is that it refuses. Found by outside review.
These five were written against the unfixed code first, and four came back red. The
fifth, CD2, was green from the start on purpose: an explicit '*'
must keep composing, or "missing ≠ universal" collapses into "refuse everything" and the
distinction carries nothing. The identity laws survive for the same reason —
none() and idBrick() declare the wildcard rather than
being handed it by an absence.
CD1▸an UNDECLARED feeds_into is not a wildcard✓
isZero(undeclared |> narrow)
contract-undeclared, kept distinct from
contract-mismatch: a mismatch is a fact about the parts, an absence
is the lack of one, and an operator needs to be told which it hit.
CD2▸an EXPLICIT '*' IS a wildcard and still composes✓
!isZero(star |> narrow)
'*' is a claim — made by a holder who can
be held to it. This law is why the fix is "missing ≠ universal" rather than
"refuse more".
CD3▸& does not launder undeclaredness into a declared interface✓
undeclared(a.feeds_into) ⇒ undeclared((a&b).feeds_into)
CD4▸identity is preserved DELIBERATELY, and its domain is stated✓
declared(a) ⇒ id|>a ≡ a ≡ a|>id ∧ undeclared(a) ⇒ isZero(id|>a)
CP2's domain, and a narrowing left implicit is a law nobody can check —
so the narrowing is itself stated. idBrick() declaring '*'
is load-bearing, not incidental.
CD6▸& does not launder a DECLARED-but-incompatible member✓
isZero(a|>c) ⇒ isZero((a&b)|>c)
& used to union both contract ends while |>
asked only for a non-empty intersection, so a coalition handed off on behalf of
a member that could not have handed off itself — and identically on the input
side. Three semantics were sound; Option U was ruled on outside review:
outputs join, inputs meet, and a hand-off is a SUBSET test
(OUT(a) ⊆ IN(b)), not an intersection. Meet-everywhere was rejected
for hiding real outputs; routed hand-off was rejected as a default until a route
witness exists to earn the permissiveness. This law was xfail for the few hours
between opening it and the ruling landing.
CD7▸ANY is directional; an UNBOUND var is unknown and refuses; the identity is distinguished, not var-typed✓
isZero(ANY |> narrow) ∧ isZero(VAR α |> narrow) ∧ id.identity = '|>'
'*' was doing duty as both "any possible output" and
"whatever came in, unchanged", and under intersection matching nothing
ever forced the difference. The subset rule asks immediately: an ANY output
is not safe into a narrow consumer, while a VAR α passthrough is. The
identity is neither: it is a distinguished element of |>, branded
rather than typed, and short-circuited before the contract check runs.
This law previously required the opposite — it asserted
!isZero(VAR α |> narrow), that a free variable on an ordinary
brick must compose with a narrow consumer — and went green for as long as it
existed. That is not polymorphism; it is universal compatibility wearing a Greek
letter, and CD8 caught it laundering forbidden hand-offs in 11 of 64
endpoint pairs. A law can encode a defect as a requirement. Contract ends are now tagged
undeclared | any | types | var, all four serialisable, so a contract
can appear in a receipt, a hash or a replayed world instead of vanishing at the
JSON boundary as raw undefined did.
CD8▸inserting the identity cannot change feasibility✓
zero(a|>b) = zero((a|>id)|>b) = zero(a|>(id|>b))
CD4 proved id preserved the value
and never asked whether it preserved feasibility — and it did not:
x emitting U into d accepting T is
correctly refused, while x |> id |> d composed. Measured at
11 of 64 endpoint pairs where a direct 0̲ became LIVE.
The cause was α implemented as an endpoint matcher rather than a binding.
The fix is not a stricter matcher — a var OUTPUT is genuinely unknown until bound, so
making it directional would break the identity law instead of the soundness. Instead
id became a distinguished element: a |> ID = a by
construction, returning the operand itself, so it never reaches the check.
CD9▸& projects the same contract either way round✓
contract(a & b) = contract(b & a)
& is this algebra's parallel operator and is proved commutative — but its
projected interface was not. meetIn returned "the other
operand" when it met a variable, so two differently named free variables gave
(a&b) accepting β and (b&a) accepting
α. No verdict differed at the time, because a var matched everything
anyway — a latent bug held harmless by a second bug, which is exactly why
nothing caught it. Both operators now treat an unbound var as absorbing, so the
projection is order-independent by construction rather than by luck.
CD10▸a malformed contract end normalizes to UNDECLARED, never to a declared one✓
malformed(t) ⇒ kind(norm(t)) = 'undeclared'
norm() used to filter: it took input it could not read, dropped the parts
it did not understand, and returned the residue as a well-formed declaration.
For an output endpoint that residue was usually the empty set — and under a subset rule
∅ ⊆ X holds for every X, so the least readable input in the
algebra produced the most permissive endpoint in it.
{kind:'types', values:[1,2,3]}, a bare 42,
[null] and {} all composed into a narrow consumer. Only an
explicitly supplied empty set still means "emits nothing", because
that is a claim somebody made.
CD11▸normalization cannot widen admissibility✓
malformed(t) ⇒ ∀c. isZero(brick(feeds_into=t) |> c)
CD10, stated separately because CD10 could be
satisfied by a normaliser that returned some other declared-but-narrow endpoint. What has
to hold is the admissibility bound: whatever a malformed end becomes, it may not
compose with a consumer a correct reading would have refused. This is the general
principle behind all four of these laws —
unknown or malformed evidence may never be canonicalised into a stronger claim than
the input justified — and it is the same meta-error as the original
missing → * that CD1–CD3 closed. The carrier
changed; the mistake moved.
CD12▸identity privilege is UNFORGEABLE: no ordinary brick acquires it by declaring a field✓
ordinary(x) ⇒ (a |> x) ≠ a ∧ (x |> b) ≠ b
identity:'|>' field on Brick() was not, because a field is data and
data is written by whoever holds the pen. An uncertified brick with a contract matching
nothing declared the privilege and both operators short-circuited past every floor they have —
and it survived a JSON round-trip, the boundary this carrier exists to cross. The old code
compared the NAME 'id' and a comment correctly called that forgeable, then replaced
a forgeable name with a forgeable FIELD: the same thing wearing a schema.
Serialisability and authenticity are different requirements. The identities are now
singleton TERMS recognised by reference, serialised as a bare tag
({"kind":"pipe_identity"}) carrying nothing else, and
decodeTerm() is the only door from data back to the privilege — a tag with a payload
decodes to an ordinary brick.
VX1▸a present-but-invalid scalar floors the brick to 0̲; an ABSENT one still defaults✓
invalid(v[k]) ⇒ isZero(Brick(value=v)) · absent(k) ⇒ default
normValue() drew its line at "is this an object at all", so a brick could
carry {beta:'high'} — present, explicitly asserted, not a number — stay LIVE, and
hand beta = NaN downstream where the floor never fired because no
beta_min had been required. A default is justified by ABSENCE and by nothing
else. Spreading ...v over defaults did the opposite: the default was there to
fill a hole and instead sat quietly beside a wrong answer.
VX2▸pi is a declared PHASE or null — never an uninterpretable string✓
v.pi ∈ PHASES ∪ {null}
{pi:'not-a-phase'} stayed LIVE and could leave a composite carrying a phase
phaseIdx has no index for — which is the input the |> phase floor
reads. A carrier the floor cannot interpret is a floor that cannot fire.
VX3▸beta is finite and in [0,1]✓
0 ≤ v.beta ≤ 1 ∧ finite(v.beta)
[0,1] quantity under min. NaN,
±Infinity, -0.1, 1.1 and the string '0.5'
all passed. Math.min(NaN, x) is NaN, so one bad operand poisons every
composite it touches without any of them being refused.
VX4▸kappa and denyDefault are real booleans, not truthy stand-ins✓
typeof v.kappa = 'boolean' ∧ typeof v.denyDefault = 'boolean'
kappa:'false' is a non-empty string and therefore truthy — it asserts the
opposite of what it appears to say, and κ is the cyclicity flag that routes
to deliberation. denyDefault is the deny-by-default switch. Neither may be
satisfied by coercion.
VX5▸normalization never manufactures NaN or Infinity in a LIVE brick✓
live(b) ⇒ finite(b.value.n) ∧ finite(b.value.beta)
NaN reaching a floor with no predicate that could test it. Whatever
survives normalisation has to be arithmetically usable, and it has to stay so under
composition.
CD13▸the identity does not bypass canonicalization✓
isZero(Brick(x)) ⇒ isZero(x |> ID) ∧ isZero(ID |> x) ∧ isZero(x & &none)
CD12 stopped ordinary
data from BEING the identity and left open what the real identity does to an operand that was
never canonicalised. ensure() accepted anything brick-shaped — a shape test,
not a validity test — so a raw object with value.beta = 'high' passed through and
the identity handed it straight back: Brick(raw) was 0̲ and
raw |> ID was LIVE. Mutating a legitimate brick after construction did the same.
The root cause was an identity law stated too strongly. a |> ID === a —
return the very same object — is a JavaScript reference property, not the algebra's; the law is
canon(a |> ID) ≡ canon(a), and insisting on the reference form is what created a
privileged path around the normaliser. Operands are now canonicalised at ingress, and the zero
test runs after that rather than before — a mutated brick's stale
annihilated flag used to pass the check that ran first.
CD14▸identity terms are transitively immutable✓
∀ o reachable from ID or &none · Object.isFrozen(o)
ensure() returns the units by reference and justified it — 'they are provably unchanged' — but nobody had done the proof. Object.freeze is shallow: it blocked replacing id.cost and permitted writing through it, permanently and process-wide. A caller could push onto &none.value.authority and collect the result under the other operator. The deep freeze also caught a bug in itself — the first draft used isFrozen as its visited marker, so it stopped at TYPES(), which is frozen with a live values array.
CD15▸a unit has algebraic meaning only under its own operator✓
composeAnd(ID, x) = composePipe(&none, x) = 0̲
&none output type is the empty set, and the empty set is a subset of everything, so the hand-off check passes vacuously.
CD16▸no unit contributes value, authority or cost under the other operator✓
cost(x ⊕ foreign-unit).certified ≠ true ∧ authority(x ⊕ foreign-unit) = ∅
CD17▸a counterfeit unit refuses and names the transport fault✓
kind(x) ∈ {pipe_identity, and_identity} ∧ x ≠ singleton ⇒ 0̲
decodeTerm(encodeTerm(t)) === t holds, but nothing stopped a caller writing postMessage(idBrick()) instead of postMessage(encodeTerm(idBrick())). The copy that lands on the far side carries the canonical tag and not the reference. It must not compose as an ordinary brick — it arrives holding a free certificate — and it must not fail silently either: the defect is at the call site and the refusal says so. Measured across a real worker_threads realm boundary, not a same-realm clone.
QX1▸a malformed or absent q cannot become Q0 on an ordinary brick✓
malformed(q) ∨ absent(q) ⇒ isZero(Brick(…))
ANY
(CD1–CD5); malformed Value → V0() (CX7, VX1–VX5); malformed q →
Q0(), here. q:'nope', q:42, q:[] and a wholly
absent q all became {confidence:1, cost:0, latency:0} — so unreadable
measurement evidence read as perfect confidence, zero cost, zero latency, the most
favourable point in the lattice, handed out for saying nothing.
QX2▸confidence is finite and in [0,1]✓
0 ≤ q.confidence ≤ 1 ∧ finite
confidence:'high' composed to NaN; confidence:2 stayed
LIVE. Confidence is the ⊗ component of the CC2 semiring — it multiplies down a pipeline, so one
out-of-domain operand contaminates every composite downstream of it.
QX3▸cost is finite and ≥ 0✓
q.cost ≥ 0 ∧ finite
cost:'free' composed to the
string 'free0', because + on a string concatenates. The
runtime and the public page both describe cost as adding; nothing checked that the operands
were numbers.
QX4▸latency is finite and ≥ 0✓
q.latency ≥ 0 ∧ finite
latency:'fast' composed to NaN under max, and
latency:-5 passed unchallenged. Found again independently by the mutation
dimension of the metamorphic gate, which is how the ordering defect behind CD13 surfaced.
QX5▸only an identity TERM may carry Q0 without measurement evidence✓
q ≡ Q0 ⇒ term ∈ {id, &none}
Q0 is the true identity of the CC2 semiring — 1 for a product, 0 for a sum, 0 for a
max — and it is the correct measured quantity for id and &none,
which cost nothing. It is wrong for an ordinary brick that merely arrived without measurements,
because there every component is a maximal CLAIM rather than a neutral value. The identities
keep it by supplying it explicitly and passing the same validation as everyone else — they are
not exempt, they qualify.
QX6▸utility is a finite number✓
finite(utility) ∨ absent(utility)
typeof NaN === 'number', so a NaN utility passed every check and silently poisoned
any ranking it entered. An absent utility still defaults to 0 — the additive identity and
the least favourable value, so defaulting it claims nothing — while an explicit
null is an assertion, and utility is a number.
AD1▸the carrier is closed✓
admitted(a) ∧ admitted(b) ⇒ isZero(a ⊕ b) ∨ admitted(a ⊕ b)
LIVE was doing duty for two different things — structurally valid (the constructor could read every field) and admitted (the shared floor lets it through). An uncertified brick is structurally perfect and unadmitted. Stated as closure it stops being a matter of taste: the anchor law is a brick of bricks is a brick, and u |> ID took a non-carrier element and returned a non-carrier element out of a composition. The algebra was not closed.
AD2▸the identity preserves an admitted element✓
admitted(a) ⇒ value(a ⊕ e) = value(a) ∧ contract(a ⊕ e) = contract(a) ∧ cost(a ⊕ e) = cost(a)
a ⊗ e = a says nothing about objects that are not elements — so restricting them costs no law and buys closure back. CD4b's genuine improvement survives intact: undeclared is not a floor condition, so an undeclared brick still passes through the identity unchanged and still refuses at its next real hand-off.
AD3▸the identity does not admit an unadmitted element✓
¬admitted(x) ⇒ isZero(x ⊕ e), agreeing with isZero(x ⊕ anything)
u |> f was 0̲ and u |> ID returned u, LIVE, because the identity short-circuits before the floor — so the single route applying no floor was the element whose entire job is to change nothing. The property is agreement, not uncertified floors: whatever real composition decides about an operand, every identity route must decide the same.
AD4▸a declared floor requirement is enforced, not merely carried✓
requirement ∈ floor(a) ∪ floor(b) ⇒ enforced on a ⊕ b, and inherited by the composite
floor had been on every brick since the first draft: stored, unioned into every composite, threaded through the whole algebra — and never once read. floored() took a requirements argument that neither operator passed. A requirement propagated but not applied is worse than an absent one: in a receipt it reads exactly like a satisfied one.
AD5▸an unrecognised floor token refuses✓
token ∉ recognised ⇒ 0̲
floor: ['signed-by-treasury'] from a runtime that has never heard of it must not have the demand quietly dropped.
CERT1▸certified:true is not self-authenticating✓
¬wellFormed(cert) ⇒ isZero(Brick(…))
an object asserting certified:true — {verdict:{certified:true,costClass:'poly'}} composed LIVE, allow, free. No issuer, no subject, no analyzer, no policy.
CERT2▸an admitted certificate binds its subject and may not out-permit its own verdict✓
wellFormed(c) ⇒ binds(subject, analyzer) ∧ strictness(c.policy) ≥ strictness(decisionOf(c.verdict))
certified must also be a real boolean: !! made the string 'false', the empty array and the empty object all read as certified.
CERT3▸composition never upgrades evidence✓
authenticated(a ⊕ b) ⇔ authenticated(a) ∧ authenticated(b)
CERT4▸authentication is unforgeable by data and does not serialise✓
isAttested is WeakSet membership; ¬isAttested(clone(c)) ∧ 'authenticated' ∉ verdict
CERT5▸a certified verdict of unknown cost certifies nothing✓
certified ∧ costClass = unknown ⇒ 0̲
certified === false and nothing tested the class, so the one combination that names its own ignorance was the one that passed. Every real class still composes, tower included — escalate is not annihilate.
CERT6▸composition never weakens resource policy✓
decision(a ∘ b) ≥ max(decision a, decision b, decisionOf(result))
costClass alone, so every stricter policy an operand carried was discarded on the way in: a certificate reading certified, poly, ANNIHILATE composed to certified, poly, ALLOW. That is policy laundering, and it contradicts the one-directional coherence rule the validator already enforces on a single certificate. Enforcing it per-leaf and dropping it per-composition made the rule true of every certificate and false of the algebra it was written to protect. Strictness now only accumulates, on allow < budget_check < escalate < annihilate.
CERT7▸an annihilate decision cannot enter the admitted carrier✓
policy.resourceDecision = annihilate ⇒ 0̲
escalate and budget_check deliberately do not floor — they are live-with-an-obligation, and the composite carries them up at full strength rather than downgrading them. The brick itself stays structurally valid and unadmitted, the same shape as uncertified: policy is a floor condition, not a canonicalisation one.
CERT8▸an attested certificate is transitively immutable at attestation✓
attest(c) ⇒ ∀ o reachable from c · Object.isFrozen(o)
hash-A, then set subject.hash = 'hash-B', and isAttested still said true — the certificate changed what it claimed to authenticate and the authentication survived. This is the attestation form of the shallow-frozen identity defect (CD14), one layer up. Freezing happens before branding, so there is no window in which an attested certificate is writable.
CERT9▸attestation binds a verifier to an exact subject, and the brick must be that subject✓
verifyAndAttest(c, H) requires c.subject.hash = H; floor authenticated requires brick.artifact.hash = c.subject.hash
artifact), and absence is fail-closed: a brick that claims no identity cannot satisfy an authenticated floor.
CERT10▸a composite subject is a canonical composition identity, not a deduplicated leaf set✓
subject(a |> b) = pipe(A,B) ≠ and(A,B) = subject(a & b)
subject(a|>b) and subject(a&b) were both {parts:['A','B']}, and A|>A and A|>A|>A were both {parts:['A']}. A cost certificate whose subject cannot tell those apart is binding a bag of participants, not a composition — and those programs need not cost the same. What the identity may normalise is decided by which equations the suite actually proves: & flattens (CA1 associativity passes) but does not commute (CA2 is lattice-only; CP7 is the open counterexample) and does not dedupe (CA3 is lattice-only; cost and quantities accrue); |> does not flatten at all, because CP5/CP6 are declared-open.
CERT11▸a subject may never be empty✓
valid(subject) ⇔ isStr(kind) ∧ isStr(hash)
{kind:'weave-composite', parts:[]} was accepted and produced an admitted, authenticated brick — a certificate over the empty set — while the code four lines away said a certificate that names no subject certifies no subject. Two shapes for one obligation is how the empty one slipped through; there is now one.
CERT12▸attestation is a capability, not a free export✓
createAttestationAuthority() succeeds once per module instance; isAttested stays free
attest(cert) and said honestly that it was unforgeable by data but not by code. Once the same brand carries WORLD revisions and authority delegations, any module with package access may declare a fact authenticated is not a boundary at all. The authority is minted once, at bootstrap, and handed to whichever component actually verifies. The limit is stated rather than implied, and the noun matters: this is module-instance-order security, not realm — measured, two ESM instances in one realm mint two authorities with independent stores. Within one instance, code that runs before your bootstrap takes the authority instead. Reading is never a privilege, so isAttested remains a free export: asking whether a fact is authenticated must not require the power to make it so.
CERT13▸the canonical subject encoding is injective, and subject equality is the complete subject✓
leaf ["leaf",kind,hash] · pipe ["pipe",L,R] · and ["and",T…]
subject(A |> B) and a leaf whose hash was pipe(A,B) were equal, and unAnd() parsed leaf strings as composite syntax so leaf("and(A,B)") & C collided with (A&B)&C. Untrusted input that looks like grammar being read as grammar — the same meta-error removed elsewhere, committed in the fix for the previous one. A canonical form built by concatenating untrusted strings is not canonical, it is a template. The term is now structured and serialised injectively, flattening reads a structured term from a private map rather than parsing a string, and leaf identity includes kind — {weave-ir, H} and {world-revision, H} both entered a term as bare H.
CERT14▸attestation alone does not authenticate a brick; attestation plus exact subject binding does✓
authenticatedFor(b) ⇔ isAttested(b.cost) ∧ sameSubject(b.artifact, b.cost.subject)
isAttested(brick.cost) answers was this certificate object verified; it does not answer was it verified for this brick. The runtime asked the first and branded composites on it. Two things were conflated: the authentication property — an objective relation between an artifact and its evidence — and the authenticated floor, a contextual requirement that the relation exist. The floor decides whether authentication is required; it must not decide what authentication means. The property is now computed always, and the floor merely consults it.
CERT15▸an authenticated composite requires every operand authenticated for its own artifact✓
authenticated(a ∘ b) ⇔ authenticatedFor(a) ∧ authenticatedFor(b)
pipe(A,B). Neither brick had to ask for an authenticated floor, because the branding step never consulted the binding.
CERT16▸a composite artifact is derived from operand artifacts, never from the certificate✓
artifact(a ∘ b) = composeIdentity(op, a.artifact, b.artifact)
{...cost.subject} — the evidence manufacturing the identity of the thing it was supposedly evidence for, which makes any misbinding self-ratifying. The principle is the one this whole layer now rests on: evidence may authenticate an independently identified subject; evidence must never define the subject that makes the evidence appear valid. Both identities are computed by the same rule over different inputs, so they coincide exactly when each operand's certificate was bound to its own artifact, and diverge visibly when one was not. An operand declaring no artifact yields a composite with none, rather than borrowing one.
CERT17▸a canonical subject survives canonicalisation, JSON and structured clone✓
composite subject = {kind, hash, term} with hash = canonicalJSON(term), checked
Brick() erased it when canonicalising an artifact into a fresh {kind, hash}. The certificate kept its term by reference and the artifact did not. A canonical identity is not canonical if reconstructing the same value erases information needed to extend that identity. The term is now durable data on the subject, and a term that disagrees with the hash it ships beside is refused — so a caller may hand one in and have it understood, and cannot lie about it.
CERT18▸exact binding is inductive at arbitrary depth, in every association✓
artifact(compose*(A…N)) = subject(compose*(A…N)) for all depths and shapes
A & B bound correctly and (A & B) & C did not, because the two identities stopped being the same derivation once one side lost its structure. The law tested the base case and never the induction step, so it was green over a real closure failure. Depth and shape — left, right, balanced — are now swept rather than exemplified.
CERT19▸the authenticated carrier is closed at arbitrary depth✓
authenticatedFor(a) ∧ … ∧ authenticatedFor(n) ⇒ authenticatedFor(compose*(a…n))
CERT20▸presented evidence is bound evidence: binding is not part of authentication✓
presentedFor(b) ⇔ artifact ∧ sameSubject(b.artifact, b.cost.subject); authenticatedFor(b) ⇔ presentedFor(b) ∧ isAttested(b.cost)
floor: ['bound'] turns the baseline rule into a positive requirement.
CERT21▸misbound evidence refuses at the baseline floor, attested or not✓
artifact ∧ ¬sameSubject(artifact, cost.subject) ⇒ 0̲
A attached to an artifact X is not an unauthenticated certificate for X — it is the wrong certificate. It was admitted at the default floor, so the runtime held an object whose evidence explicitly named something else, and two of them composed into one. That is not a downgrade, it is an internally inconsistent admitted object. Evidence presented for a subject must first actually name that subject; authentication decides whether to trust the evidence, not whether it is about the thing carrying it. Misbinding is a floor condition rather than a canonicalisation one, so the brick is structurally valid and unadmitted — the same shape as uncertified.
CERT22▸subject equality is substitutive under composition✓
sameSubject(x,y) ⇒ composeIdentity(op,x,z) = composeIdentity(op,y,z), for every op and z
term was merely optional on every subject and equality compared kind+hash, so {kind,hash,term} and {kind,hash} were the same subject — and composing each with the same operand produced different identities, one LIVE and one 0̲. An equality relation under which x = y but compose(x,z) ≠ compose(y,z) is not the equality of the carrier; it is a coincidence of two selected fields. The repair is to remove the second representation rather than widen the comparison: subjects are a discriminated union on kind, a composite must carry its term, and anything else must not. Two subjects are equal only if replacing one with the other cannot change any future canonical identity.
CERT23▸a recursively canonical object enforces its invariants recursively✓
isTerm(['leaf', k, h]) ⇒ k, h non-empty ∧ k ≠ 'weave-composite'
typeof === 'string', so ['leaf','',''] was a well-formed node. A term containing it attested, was admitted, and cleared an authenticated floor while binding neither a namespace nor a digest at that position. An invariant enforced at the root of a tree is enforced on one node.
CERT24▸a runtime owns its attestation store✓
isAttested(c, rtA) ⇏ isAttested(c, rtB)
createComposeRuntime({verify}) mints a runtime that owns its store, so two tenants, worlds or verifiers
in one process share no authentication state: a certificate attested by one is merely presented to the
other. The module-level operators keep a default store, which is exactly the previous behaviour for anything that
never asks for isolation. A verifier is mandatory — an authority that checks nothing relabels rather than
authenticates.
CERT25▸the subject discriminator agrees with the term discriminator✓
kind = 'weave-composite' ⇒ term root ∈ {and, pipe}
kind:'weave-composite' while carrying a leaf term. It was a distinct subject at ingress and then evaporated at the identity layer: F ≠ A, yet F & C === A & C. A discriminator that the two halves of an object can disagree about is not discriminating.
CERT26▸every admitted composite subject is in the runtime's algebraic normal form✓
canonicalTerm(t) ⇔ wellFormedTerm(t) ∧ root ≠ leaf ∧ t = normalize(t)
wellFormedTerm proves a grammar. It does not prove the tree is the runtime's representative of its algebraic class — and the runtime itself only ever produces flat and, because CA1 is a passing law. So ['and',['and',A,B],C] was admitted beside ['and',A,B,C] with a different hash. Validity is not canonicality. Only proved equations are normalised: & flattens (CA1); & order and duplicates are untouched (CA2/CA3 are lattice-only, CP7 open); |> association is preserved exactly, because normalising it would assert an equation CP5/CP6 currently falsify. Noncanonical terms are refused, not repaired — a supplied term is an identity assertion, and a default may not overwrite a claim.
CERT27▸algebraically equivalent & assemblies have exactly one admissible representation✓
left-, right- and balanced-associated & trees over the same leaves mint one identity
|> deliberately staying distinct by association.
CERT28▸verification cannot change the claim being authenticated✓
snapshot ▸ validate ▸ freeze ▸ compare ▸ verify(it) ▸ brand(it)
verify, and only then freeze and brand. A verifier that writes to what it is checking moves the claim after the claim has been approved — verify(c){ c.subject.hash='B'; return true } made “verify this exact certificate for A” finish by authenticating B, which then cleared an authenticated floor and admitted. Freezing earlier is not enough on its own, because Object.freeze leaves an accessor an accessor; the certificate is therefore copied into inert data first, and validation, comparison, the verifier, the brand and the return value all see that one frozen snapshot. The structure verified must be the structure branded.
CERT29▸subject validation is total under the declared budget✓
∀ admissible term, depth ≤ 4096 · nodes ≤ 100000 ⇒ a verdict, never an exception
|> association is preserved while CP5/CP6 are open, term depth is something a caller controls. Every walk over it recursed — wellFormedTerm, normalizeTerm, deepFreeze, and JSON.stringify in C++ — so past some engine-specific depth a hostile certificate produced a RangeError instead of 0̲. A limit the implementation discovers is not a limit the protocol declared. Every walk is now iterative and the ceiling is three stated numbers.
CERT30▸an over-budget subject refuses by name, never by exception✓
over-budget ⇒ 0̲ with a named reason, and refusing costs less than accepting
O(1) from the node itself: counting to a hundred thousand before declining to count to a hundred thousand is still doing the work.
CERT31▸a canonical hash is computed from what the term contains, never from what it volunteers✓
canonTerm walks the structure; only leaf STRINGS reach JSON.stringify
canonTerm was JSON.stringify, which asks a value how it would like to be serialised — it calls toJSON(). Array.isArray is true of an Array subclass, so a leaf could contain A and hash as X. Since sameSubject is kind+hash, a certificate about A attested against an expectation of X and the brick carrying it admitted. The doctrine the runtime states everywhere else — a supplied term is an identity assertion, checked against its bytes — was being enforced against bytes the asserter chose. Terms are now also copied, not adopted, so what a brick stores cannot tell a later reader a different story.
CERT32▸the canonical serialiser is byte-identical to the JSON.stringify that minted every existing hash✓
∀ plain term t · canonTerm(t) === JSON.stringify(t)
TREE1▸a one-leaf composition tree returns a canonical Brick or 0̲, never the caller's input✓
composeTree(leaf) = ensure(leaf) through the shared floor
if (!node || node.op == null) return node — the caller's object, unexamined, out of a function that promises a composed brick. composeTree({id:'raw', cost:{nonsense:true}}) returned that object with no Value, no contract and no certificate; composeTree(42) returned 42. The correct identity operation on a single leaf is the one the algebra already defines, a |> ID, so the leaf takes exactly that path.
TREE2▸composeTree has no weaker ingress boundary than composeAnd/composePipe✓
isZero(composeTree(x)) = isZero(x & none) = isZero(x |> ID)
ensure itself, and here). Scoped to ordinary operands: the units have their own rule about which operator they mean something under (CD15/CD16).
CD5▸an explicit null/undefined field is an ABSENCE, not a declaration✓
isZero({feeds_into: null} |> narrow)
null is how a contract arrives from JSON when the field was never
filled in — reading it as universal would reinstate the defect through the
serialisation boundary.
CERT33▸the byte budget is canonical serialised UTF-8 bytes, not source string units✓
canonBytes(s) === TextEncoder().encode(JSON.stringify(s)).length
s.length. Those differ by six for a control character: 750,000 U+0000 is 750,000 source units and 4,500,055 canonical bytes, so a subject a third over the ceiling was admitted. A budget must name the quantity it bounds, and the quantity that matters is the one that gets stored, hashed and shipped. The length is computed without building the escaped string, because allocating 4 MiB to discover that 4 MiB is too much is the mistake the ceiling exists to prevent.
CERT34▸the hostile-data boundary is total: ingest yields a named 0̲ or a Brick, never an exception✓
∀ hostile v · ingest(v) is a Brick, and 0̲ ⇒ it says why
cost getter, a Proxy that traps getPrototypeOf, a term element with a throwing Symbol.toPrimitive each made an ordinary public call throw. The answer taken is that the boundary is declared and one function owns it — Brick/composeAnd/composePipe/composeTree are trusted construction over values you already own; ingest is the door for anything off a wire, and it snapshots to inert data first. An ingested brick is also deeply frozen, so the evidence a verdict was reached about cannot be rewritten afterwards.
CERT35▸refusing is not more expensive than accepting✓
|refusal message| is bounded regardless of the size of what was refused
malformedCert built its message with JSON.stringify(c.subject).slice(0, 200) — serialise the whole subject, keep 200 characters. Refusing a 100,100-leaf term therefore cost a full serialisation of the term: the check was O(1) and the sentence about the check was O(n). That is the same exhaustion the budget exists to refuse, reached through the one path everything hostile is guaranteed to take.
TREE3▸the fold's work is bounded: a shared child is priced per path, and an exponential DAG refuses by name✓
folds ≤ maxFoldNodes, and composeTree(x & x) === composeAnd(x, x)
& is idempotent on the capability lattice and is not idempotent on cost or quantities, so x & x is not x and memoising would change the arithmetic silently. A DAG is a tree that happens to share storage, and the budget prices it as the tree it denotes.
TREE4▸the operator is validated before the descent: an invalid root buys no subwork✓
unknown op ⇒ refuses having read zero children
CERT36▸an inert snapshot has no semantic prototype: every field is own data✓
getPrototypeOf(snapshot) === null ∧ every semantic field is an own property
{} inherits Object.prototype, which has an accessor named __proto__. JSON.parse treats that key as ordinary data and produces it as an own property — but copying it out with dst[k] = v runs the inherited setter and re-points the destination's prototype. So a certificate could arrive with no own subject at all, inherit a valid one, validate, attest — and then be rewritten through a prototype deepFreeze never walked, because getOwnPropertyNames does not see inherited properties. That is CERT8/CERT28 a third time, reached through inheritance rather than through mutability. Objects now get a null prototype and every field is installed with defineProperty, which never consults a setter — special-casing the name __proto__ would have fixed the witness and left the general defect in place. A field genuinely named __proto__ survives as ordinary own data, which is what a JSON document means by it.
CERT37▸descriptor-only ingress really is descriptor-only: no caller code runs during a snapshot✓
array indices come from the length descriptor; elements are read only via getOwnPropertyDescriptor
Array.from(src, …) iterates the source, so an accessor installed on an element ran once per snapshot. The outer catch kept the never-throw contract — which is why this was invisible — but a getter that performs a side effect and returns normally defeated the stronger property the boundary exists for. Never-throwing and never-executing are different guarantees, and only the second is what "inert" means.
CERT38▸the state WORLD requires is reachable by one call: ingested ∧ authenticated ∧ immutable✓
ingestAndVerify(raw) → a frozen brick whose exact certificate is branded in this runtime
ingest and verifyAndAttest are both copying boundaries: whichever runs second undoes the other. A rule whose required state has no construction path is not a rule. The sequence now happens inside the runtime, where the brand is applied after the last copy. It is deliberately not a field: an ingested: true boolean would be exactly the caller-asserted authority CERT1 removed, so the property is earned by which function produced the object and read as authenticatedFor(b) ∧ isFrozen(b).
CERT39▸the hostile boundary takes bytes, because reflection over an object is executable✓
ingestJSON(text) executes no caller code; adopt(obj) is named as the weaker route
Object.getOwnPropertyNames and getOwnPropertyDescriptor are Proxy traps, so a valid brick behind a counting Proxy produced a live, authenticated, frozen result — the strongest state this runtime can hand to WORLD — while executing eight trap invocations of caller JavaScript. There is no portable way to inspect an arbitrary JavaScript object while guaranteeing its traps do not run: an API that has already received an object graph has crossed the line too late. So the guarantee moved rather than being patched. ingestJSON(text) parses bytes with a parser the runtime owns, which makes "no caller code executes" a fact about the input language instead of a hope about the input value; adopt(obj) keeps the object route under a name that no longer borrows the word "ingest". WORLD consumes only the first.
CERT40▸an own undefined is not absence: the boundary never erases present evidence✓
own undefined ⇒ 0̲ by name, on every carrier
undefined because JSON has none and JSON.stringify drops such a key. Wrong in both directions: in an array, JSON.stringify emits null and keeps the slot, so the two carriers disagreed — and far worse, dropping it turned floor: [undefined] (present, invalid, refuses) into floor: [] (no requirement, admitted). The hostile boundary made the object less constrained than the input asked for. floor is the worst carrier for that to happen on, because an erased requirement is indistinguishable in a receipt from a satisfied one. Sixth carrier, same rule: absence may take a documented default; present-and-malformed may not be repaired into a stronger claim.
WIRE0▸the WORLD door is the same function however the caller got hold of it✓
rt.f(x), const {f} = rt; f(x), and [x].map(rt.f) agree — for every ingress name
ingestJSONAndVerify was a method calling this.adoptAndVerify. Modules are strict, so a detached reference had this === undefined and threw a TypeError. Three things made that worse than an ordinary binding bug. It threw on the success path only — bad input still refused politely, so the failure appeared only once the caller got everything right. It broke the contract this runtime states most loudly, that the boundary never throws whatever it is handed (CERT34) — and the contract was true of the function while being false of the name. And of the ingress routes it was the only one written as a method, so the single door WORLD is specified to consume was the single door that broke under the idiom every consumer reaches for on a frozen namespace object.
WIRE1▸the byte budget bounds bytes, not source units✓
utf8Len(text) > maxBytes ⇒ 0̲, for every UTF-8 width class
text.length counts UTF-16 code units. Measured: 6,000,376 UTF-8 bytes went through a 4,194,304 ceiling live, authenticated and frozen, because U+0800 is one source unit and three bytes. This is CERT33's error — source units are not bytes — reappearing one boundary further out, in the function written to be the boundary. A budget must name the quantity it bounds; naming it is not enough, the check has to read it. The length is now counted without allocating the encoding, because a 4 MiB budget check must not build a 12 MiB buffer to decide it is over budget.
WIRE2▸a frame is not bytes until it is copied: no caller code participates in the bound✓
the bound is read through %TypedArray%.prototype getters, never off the argument
ingestFrame(bytes: Uint8Array) as the narrower door. Measured before it was written, that reintroduces CERT39 one layer down: a Proxy over a Uint8Array passes instanceof and fires its traps, and a subclass whose byteLength getter lies both runs caller code and gets an oversized frame parsed. bytes.byteLength > MAX is exactly getOwnPropertyDescriptor(o, k) — a property read the caller animates. A typed array is still an object, so "the boundary takes bytes" is only true of an API that never asks the object anything. The bound is read through brand-checked intrinsics captured at module load, which a subclass cannot override and a Proxy has no internal slot to satisfy; a view onto a SharedArrayBuffer is refused because its contents can change between the check and the decode; and the bytes are copied before anything inspects them.
WIRE3▸duplicate member names refuse: a peer must be able to agree what was authenticated✓
a repeated object member ⇒ 0̲ by name, on every text route
artifact twice, hash "B" then hash "A", came out live and authenticated carrying "A". Nothing about that is a fact two runtimes share, and a signature over it means nothing. RFC 7493 (I-JSON) forbids it, and RFC 8785 (JCS) builds on I-JSON precisely so that hashing has repeatable bytes — which is what RevisionRef will need. The check is a scan of the text, because by the time JSON.parse has returned the duplicate is gone and the survivor is whichever one the engine felt like keeping.
WIRE4▸a retained string is encodable: no lone surrogate reaches an identity✓
surrogates and noncharacters ⇒ 0̲, in values and in member names, on every route
TextEncoder silently replaces it with U+FFFD, so a hash this runtime authenticated is one it cannot transmit — the corruption happens on the way out of the process, not at some hypothetical foreign peer. Measured live and authenticated with U+D800 in the artifact hash. WIRE1 does not subsume this, and the ordering is the point: a strict UTF-8 decode rejects the raw form (bytes ED A0 80) and accepts "A\ud800", which is well-formed UTF-8 on the wire and only becomes a lone surrogate after JSON string-escape processing. Frame well-formedness and value well-formedness are two checks.
WIRE5▸the frame route yields the admissible state, and nothing weaker does✓
ingestFrameAndVerify ⇒ authenticated ∧ frozen; ingestFrame ⇒ frozen ∧ ¬authenticated
WIRE6▸owning a frame invokes no caller behaviour — the frame at return is the frame at call✓
the copy performs no SpeciesConstructor, no constructor read, no property access on the source
WIRE1/WIRE2 fixed the reads and left the copy as ArrayBuffer.prototype.slice — which is not an inert memmove. Its first steps run SpeciesConstructor(O, %ArrayBuffer%), reading O.constructor and then constructor[@@species] off an ordinary caller-supplied buffer, and the specification notes those steps may have side effects before the source data is copied. The captured pristine intrinsic called the caller's getter faithfully. Measured: a constructor getter that rewrites "hash":"A" to "hash":"B" in place produced artifact.hash B, authenticatedFor true — from a frame that held A when the call began. WIRE2 stayed green throughout, because it counted invocations of the getters it had replaced and never asked what the copy did. Capturing a function guarantees nothing if the function's own algorithm is specified to consult its operand. The copy is now %TypedArray%.prototype.set into a runtime-allocated buffer — internal slots and a memmove — and the element type is brand-checked through the intrinsic @@toStringTag, because set converts between element types.
WIRE7▸the boundary does not fetch its dependencies from the ambient realm at call time✓
replacing TextDecoder / Uint8Array / ArrayBuffer / JSON / Reflect.apply after import changes nothing
Reflect.apply 4×, TextDecoder 2×, Uint8Array 1×. Two threats were being conflated, and only one is WIRE's to answer. Hostile bytes in a trusted realm is WIRE's job: the frame must not be able to execute anything, and everything the boundary depends on is captured at module load. Hostile code sharing the realm is not, and no amount of capturing fixes it — ordinary ECMAScript primordials are mutable and reachable, which is exactly what SES/Hardened JavaScript lockdown() exists for. The declared contract: WIRE protects a trusted runtime against hostile input; it does not contain hostile code already executing in the same unhardened realm. If you need mutually hostile code in one process, give it a hardened realm, a worker, or a process — not a stricter parser. Capturing still earns its place inside that scope: it makes the boundary immune to accidental post-import patching, which is the failure that actually happens.
Declared open — 3 laws that do not hold
These run on every build, print FALSIFIED in red, and are
expected to. They are not skipped, not pending, not hidden. Three of them
(CP5, CP6, CP7) trace to one root cause — the
Value.pi carrier. CD6 is a separate defect in the contract
algebra, added 2026-08-22, and it is the one blocked on a ruling rather than on a fix.
The suite exits
process.exit((total === 0 && xpass === 0) ? 0 : 1), so
the build fails if one of them starts passing without being promoted into a
real suite. A fixed defect quietly left in the exception list would be worse than the defect.
The counterexamples below come from a live run; the trial index is wherever the generator
happened to find one and differs run to run.
CP5▸the |> floor is ASSOCIATION-INVARIANT✗ FALSIFIED
isZero((a|>b)|>c) === isZero(a|>(b|>c))
CP6▸NO backward execution step survives |>, in either association✗ FALSIFIED
a pipeline containing a backward phase step must floor to 0̲
CP7▸&-operand order does not change a downstream |> floor✗ FALSIFIED
isZero((a&b)|>c) === isZero((b&a)|>c)
& is commutative — AC-COMM above proves its own floor is — but the merge sets its phase by first-non-null, so (A&B) and (B&A) exit at different phases and chain differently. Reproduce it in your browser.