Skip to content

feat(typecheck): infer for-each loop variable types from List T (WO28 #13) - #30

Merged
undergroundrap merged 2 commits into
mainfrom
wip/wo28-13-foreach-inference
Sep 24, 2026
Merged

undergroundrap merged 2 commits into
mainfrom
wip/wo28-13-foreach-inference

Conversation

@undergroundrap

Copy link
Copy Markdown
Owner

WO28 item #13.

  • for_each_binding: for each word in words where words: List Text binds word: Text (accepted_for_each_binding_v0); non-list/unprovable shapes stay unchecked, fail-closed.
  • Adjacent completions the acceptance command required: list_len(...) types as UInt; test_expectation accepts on matching return types (mismatches stay unchecked).
  • Collateral fix: place_type_fact no longer snake-normalizes whole condition expressions to bound names (if piece != "" now accepted via inferred Bool).
  • Session AG flipped back to the byte-exact stdout success check (exit 0, 13 bytes, no CR); digest pin recomputed 9b5d6b79 — needs independent final review.
  • Friction ledger feat: text_split primitive (WO27 Part 1a) #13 marked RESOLVED.
  • 5 new focused tests; root suite 507 passed; clippy/fmt/hygiene/readiness clean.

Local evidence (Linux): wordfreq full-type-check is recognized_core_body_types_checked_v0 with 0 unchecked/blocking; hum run of the APP entry reaches the platform boundary (native_path_input_unavailable_on_non_windows_v0, exit 2) — the type gate is open. Final proof of the done-condition (exit 0, 13 bytes, no CR) rests with Windows CI.

No new language surface; existing semantics only. Ocean merges.

…13)

for_each_binding types the loop variable from the iterated expression:
for each word in words where words: List Text binds word: Text
(accepted_for_each_binding_v0). Non-list and unprovable shapes fail closed
into the existing unchecked path (iterator_type_checking_not_implemented).

Two adjacent completions the acceptance command required to open the
full-type gate for wordfreq's actual code: list_len(...) call expressions
type as UInt in return position, and test_expectation accepts when the
callee's declared return type matches the returns literal shape
(accepted_test_expectation_v0; mismatches stay unchecked, fail-closed).
No new language surface: all three follow the existing semantic rules.

Collateral fix: place_type_fact no longer snake-normalizes a whole
condition expression to a bound name. if piece != "" with piece: Text was
rejected (the normalized text collided with the bound name and returned
Text before condition inference could return Bool); it is now accepted via
the inferred Bool. Plain-name fallback is unchanged.

Tests: five focused unit tests (positive + fail-closed for for-each
binding, the condition-name guard, matching/mismatched expectations).
Root suite: 507 passed. clippy/fmt/hygiene/readiness clean.

Session AG: flipped back to the byte-exact stdout success check
(exit 0, exactly 13 bytes, three 0x0A, no 0x0D) per the WO28 #13
done-condition; the typed-denial misuse assertion returns
(WordfreqError.read caused by FileReadError.denied). Digest pin recomputed
(9b5d6b79); changed body needs independent final review.

Friction ledger #13 marked RESOLVED.

Local evidence (Linux): hum full-type-check on wordfreq.hum is
recognized_core_body_types_checked_v0 with 0 unchecked/blocking; hum run
of the APP entry reaches the platform boundary
(native_path_input_unavailable_on_non_windows_v0, exit 2) -- the type gate
is open. Final proof of the done-condition rests with Windows CI.
#17

Windows CI diagnosis (run 35941546472): WO28 #13 works — the type gate
opens and the wordfreq app entry executes — but files_read_text fails
closed on hosted runners (WordfreqError.read <- FileReadError.unavailable)
because the locality policy admits only ATA/SATA/NVMe drives
(crates/windows-drive-locality/src/lib.rs) while Azure runner disks are
virtual/SCSI. Session AG re-pinned to the observed behavior: exit 1,
empty stdout, stderr contains WordfreqError.read and
FileReadError.unavailable, no panic. Every failure message carries stderr.

Ledger entry #17 records the locality finding; WO28 #13's done-condition
is rewritten honestly: app entry executes end-to-end through the type
gate, byte-exact success read blocked on hosted runners pending decision
0029. Locality crate untouched (security policy).
@undergroundrap
undergroundrap force-pushed the wip/wo28-13-foreach-inference branch from 6b01591 to c906a02 Compare September 24, 2026 03:29
@undergroundrap
undergroundrap merged commit e35e16c into main Sep 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant