Skip to content

Commit 2b8e82f

Browse files
committed
spec(bridge): review fixes — BR-B1 admission authority, BR-D2 three tolerances
Two normative wording fixes from #297 review: * BR-B1 was internally inconsistent: "nothing that changes which sites are found" contradicted BR-L1's routing, which legitimately admits, suppresses, and redirects sites (unresolved skip, self-subscribe drop, released-capture mitigation, returned_fresh provenance, token-vs-region path choice). Restated: the bridge does not independently solve for violations after routing; its only authority to admit/suppress/redirect is the CLOSED routing behavior of BR-L1 (+ the lowering-time admission rules BR-L6-L9) and the advisory side paths of BR-V1 — over admitted inputs the analyses own every verdict. * BR-D2's "skipped, never coerced" overclaimed: the same sentence then described DI field coercions. Restated as three distinct tolerances — malformed entries skipped whole; accepted entries subject to the existing field-specific coercions; line degrading via _as_int only on the paths that use it (OD-3) — so the tolerant door's contract matches what #294 is actually deciding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MdYFKUaygHz1T9H1qJ7BqK
1 parent 4c2821c commit 2b8e82f

1 file changed

Lines changed: 21 additions & 13 deletions

File tree

‎spec/Bridge.md‎

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ the core owns. Concretely: ownership/borrow/lifetime verdicts come from
3737
`check_module` (the composed core driver in `ownlang/__main__.py`); DI verdicts
3838
from `ownlang/di.py`'s five finders; effect verdicts from
3939
`ownlang/effects.py`; protocol verdicts from `ownlang/obligations.py`; the MOS
40-
fixpoint from `ownlang/ownership.py:solve`. The bridge's own logic is routing,
41-
identity, synthesis of *presentation* (messages, severity tiers, evidence
42-
slices) — and nothing that changes which sites are found.
40+
fixpoint from `ownlang/ownership.py:solve`. The bridge does **not**
41+
independently solve for violations after routing: its only authority to
42+
*admit, suppress, or redirect* sites is the **closed** routing behavior of
43+
BR-L1 (plus the lowering-time admission rules BR-L6–L9) and the advisory side
44+
paths of BR-V1; over the inputs it admits, the analyses own every verdict.
45+
Beyond that, the bridge's own logic is identity and the synthesis of
46+
*presentation* (messages, severity tiers, evidence slices).
4347

4448
**BR-B2 (no verdict repair).** The bridge must not repair a wrong analysis
4549
verdict by replacing its code or its primary anchor. It may *skip* a closed list
@@ -70,16 +74,20 @@ names rejected** — the name is the identity verdicts map back by) →
7074

7175
**BR-D2 (the tolerant door).** `check_facts(facts)` (and `to_module`/`to_own`)
7276
accept a dict directly, without `load()` — the path tests and embedders use.
73-
On this door the bridge **re-validates tolerantly**: malformed optional-block
74-
entries are **skipped, never coerced** (`_effect_findings`, `_protocol_findings`
75-
skip a malformed entry; `_di_findings` string-coerces only identity fields and
76-
requires `disposable` to be the JSON boolean `true`); `line` degrades to `0`
77-
via `_as_int` where the tolerant helpers are used; a **duplicate protocol name
78-
resolves first-wins** (deterministically) instead of raising. The two doors are
79-
deliberate: strict for external input, tolerant for already-shaped input — but
80-
their *divergences* are part of this contract and enumerated in §9 (OD-1,
81-
OD-2, OD-3). A port must implement the strict door exactly; whether it exposes
82-
the tolerant door at all is #259's decision recorded against OD-1.
77+
On this door the bridge re-validates with **three distinct tolerances**, none
78+
of them a blanket rule: (1) a **malformed optional-block entry is skipped as a
79+
whole**, never patched into shape (`_effect_findings` and `_protocol_findings`
80+
drop a malformed entry — a `deps: "a"` must not become `("a",)` and mint a
81+
spurious verdict); (2) an **accepted** entry's fields go through the existing
82+
**field-specific coercions** (`_di_findings` `str()`-coerces identity/location
83+
fields and admits `disposable` only as the JSON boolean `true`); (3) `line`
84+
**degrades to `0`** via `_as_int` on the paths that use the tolerant helper
85+
(not all paths do — OD-3). A **duplicate protocol name resolves first-wins**
86+
(deterministically) instead of raising. The two doors are deliberate: strict
87+
for external input, tolerant for already-shaped input — but their
88+
*divergences* are part of this contract and enumerated in §9 (OD-1, OD-2,
89+
OD-3). A port must implement the strict door exactly; whether it exposes the
90+
tolerant door at all is #259's decision recorded against OD-1.
8391

8492
**BR-D3 (`sig` asymmetry — normative, not a bug).** A present-but-non-string
8593
`sig` on a `functions[]` **record** is rejected at the strict door; a malformed

0 commit comments

Comments
 (0)