Observed
(<- x str (Pure b"raw-bytes")) binds x = b"raw-bytes" and continues silently — the declared str type is never checked. Minimal repro (against main 678c184):
(require doeff-hy.macros [defk <-])
(import doeff [Pure run])
(defk check-it []
{:pre [True] :post [(: % bytes)]}
(<- x str (Pure b"raw-bytes")) ;; declared str, receives bytes
x)
(print (run (check-it))) ;; prints b'raw-bytes' — no error
Why it matters
- The documented contract ("
(<- x str (Ask ...)) — yield, bind, assert isinstance") promises a runtime check, and defk's :pre/:post contracts ARE strictly enforced (the macro even rejects object as too broad) — so the silent no-op on the bind annotation is an inconsistent gap in the contract system.
- Real bug it hid today (proboscis-ema ISSUE-TRD-176 Phase 0c):
(<- api-key str (GetSecret ...)) silently bound the GSM payload bytes; the type error only surfaced deep inside the lighter SDK on the first real-testnet run (startswith first arg must be bytes...). An enforced bind annotation would have failed loudly at the boundary in L0 tests.
Expected
Either enforce the 3-arg bind annotation with the same isinstance machinery as :pre/:post (preferred), or reject the 3-arg form at macro-expansion time so the annotation cannot masquerade as a check.
Observed
(<- x str (Pure b"raw-bytes"))bindsx = b"raw-bytes"and continues silently — the declaredstrtype is never checked. Minimal repro (against main 678c184):Why it matters
(<- x str (Ask ...))— yield, bind, assert isinstance") promises a runtime check, anddefk's:pre/:postcontracts ARE strictly enforced (the macro even rejectsobjectas too broad) — so the silent no-op on the bind annotation is an inconsistent gap in the contract system.(<- api-key str (GetSecret ...))silently bound the GSM payload bytes; the type error only surfaced deep inside the lighter SDK on the first real-testnet run (startswith first arg must be bytes...). An enforced bind annotation would have failed loudly at the boundary in L0 tests.Expected
Either enforce the 3-arg bind annotation with the same isinstance machinery as
:pre/:post(preferred), or reject the 3-arg form at macro-expansion time so the annotation cannot masquerade as a check.