feat(typecheck): infer for-each loop variable types from List T (WO28 #13) - #30
Merged
Merged
Conversation
…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
force-pushed
the
wip/wo28-13-foreach-inference
branch
from
September 24, 2026 03:29
6b01591 to
c906a02
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WO28 item #13.
for_each_binding:for each word in wordswherewords: List Textbindsword: Text(accepted_for_each_binding_v0); non-list/unprovable shapes stay unchecked, fail-closed.list_len(...)types asUInt;test_expectationaccepts on matching return types (mismatches stay unchecked).place_type_factno longer snake-normalizes whole condition expressions to bound names (if piece != ""now accepted via inferredBool).9b5d6b79— needs independent final review.Local evidence (Linux): wordfreq full-type-check is
recognized_core_body_types_checked_v0with 0 unchecked/blocking;hum runof 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.