Skip to content

nightly reds: daslang-live loads live_host, pinvoke panic leak, Windows 64 KB pipe, LINT030 argument order, CRLF/tsan/fast-math lanes - #3993

Merged
borisbat merged 12 commits into
masterfrom
bbatkin/nightly-fixes-2026-09-10
Sep 10, 2026
Merged

nightly reds: daslang-live loads live_host, pinvoke panic leak, Windows 64 KB pipe, LINT030 argument order, CRLF/tsan/fast-math lanes#3993
borisbat merged 12 commits into
masterfrom
bbatkin/nightly-fixes-2026-09-10

Conversation

@borisbat

Copy link
Copy Markdown
Collaborator

Behavior change: a Windows spawn_process child gets a 64 KB stdout pipe (was the 4 KB default), and daslang-live loads the LiveHost shared module before reading its exports - rebuild daslang-live and the modules.

Why. Four nightly workflows were red. The dasImgui lane lost every playwright test since the lazy module scan (daslang-live read the LiveHost exports before anything loaded the module, so live mode never turned on); the ASan lane leaked 87 bytes per caught pinvoke panic; the Windows AOT host read an empty child output in every module_cache test; the Windows lanes throttled a chatty watchdog child to 16 KB/s; the tsan lane tripped on libdbus's own lock order; the extended checks read CRLF checkouts as changed bytes; the fastmath lane compared float printing against a fast-math fmt.

What changes.

  • daslang-live asks the deferred-module loader for live_host before the dlsym; tests/live_host/test_host_ready.das spawns it on a port nothing answers on and polls /status; the folder's gate in tests/.das_test asks for dasHV too.
  • The pinvoke family (pinvoke_named, pinvoke_impl2_core, pinvoke_impl3) and the [extern] binder's refusal move their message to the stack and free the string before throw_error_at (src/builtin/ARCHITECTURE.md sec.4).
  • spawn_process on Windows creates the child's pipe at the POSIX 64 KB (sec.5).
  • The order a call's arguments are evaluated in is not defined: LINT030 (daslib/lint.das, ships off) flags a sibling argument reading what a nested call writes by reference; the module_cache tests sequence every child run and arm the rule per file.
  • The dasllama image-stamp gate folds CRLF before hashing; the tree-sitter artifacts get eol=lf.
  • .github/tsan_suppressions.txt names libdbus's module as the frame of its create/close lock-order report.
  • test_float2string.cpp and both vecmath backend arms pin precise math and #error otherwise.
  • The watchdog and process tests scale their startup deadlines threefold on a Debug host, capped at five minutes.
  • Four stale nolint markers go; the builtin module's page stops telling readers to require builtin.

Observable behavior.

  • dasImgui nightly: 45 of 81 tests red -> green; a playwright host is ready in under a second.
  • Windows AOT host, tests/module_cache: 11 red cells -> 40 passed, 7 host skips.
  • Windows watchdog chatty arm: 96 s (fails at 120 on a 4-core runner) -> 9 s Release, 56 s Debug.
  • ASan lane: LeakSanitizer: 87 byte(s) -> clean.
  • tsan lane test_tray_menu_over_private_bus: child exit 66 -> 0.
  • extended checks Windows: two red gates -> green on the same checkout; linux/darwin doc-verify: 1 red page -> green.
  • fastmath lane: 4 failed ctest entries -> pass.
  • whole-tree lint: 4 stale nolints -> 0 issues.

Where to look. daslib/lint.das (the LINT030 frame stack) and src/builtin/module_builtin_fio.cpp (the pipe size) are the two places that change runtime shape; the rest is tests, gates and docs.

Validation, claims, ledger

Validation

  • Preflight on the tip: the fast tier and the docs, tests-cpp, tests-interp, tests-jit, tests-aot and utils-tests lanes all green; the lint lane run again after the last document edits.
  • Windows: a worktree on zen2 (D:\Work\das-nightly, Release Ninja; das-nightly-dbg, Debug) - test_aot.exe on tests/module_cache 40 passed / 7 skipped; tests/watchdog/test_watchdog.das 46 Release and 46 Debug, tests/fio/test_process.das 6 and 6; the chatty arm 96 s -> 9 s; the image-stamp gate reproduced the Windows hash by converting the dasllama folder to CRLF and read OK after the fold.
  • Linux tsan: the daslinux VM (Debian arm64, -DDAS_USE_SANITIZER=tsan) reproduced the exit 66 with the libdbus lock-order report, then 12 passed with no report under the suppressions file.
  • Mac: tests/live_host 86, tests/module_cache 61, tests/debug_agent 54, tests/module_tests 47, tests/lint 84, tests/watchdog 47, tests/fio/test_process 6; ctest float2string|double2string|vecmath 4/4; doc-verify green on module-builtin.rst and lint.rst; utils/lint and dasllama gates OK.
  • The live_host regression test fails at 50 s on the old daslang-live and passes at 0.8 s on the new one.
  • vecmath_scalar, vecmath_native, float2string and double2string run for real on every non-fastmath lane through ctest -L small; on the fastmath lane their TUs are now precise-math while the library stays fast-math. Proof the pin takes under -ffast-math: clang++ -ffast-math -D_TARGET_SIMD_SCALAR=1 -DEXPECT_SCALAR=1 -Iinclude tests-cpp/big/vecmath_backend/test_vecmath_backend.cpp stops at the #error, and with -fno-fast-math appended (the CMake line's effect) both arms build and pass.
  • modules/dasLLAMA changes are two dropped nolint markers and the stamp gate's CRLF fold; the module's --suite model-free / --suite stocked runs were not made for them - the gate itself ran (REVIEW.das dasllama: OK on the LF tree, and OK on the same folder converted to CRLF).
  • Two codex rounds. The first's two LINT030 findings (a writer nested in an expression, a call inside a lambda argument leaking its reads) are fixed and pinned in the fixture. The second, on the reworked tip, found one thing: the live-host test's fixed port and unconditional /shutdown could end an unrelated host - it now probes for a port nothing answers on and shuts down only a child that reported ready.
  • The fixture's negatives each answer to a control: with the by-reference-to-the-outer-call exclusion forced false the fixture fails on take_ref(out, fill(out)); the nolint marker case and the by-value-parameter case stay silent on the tip. The CRLF case in utils/internal/review-md/test_walkers.das fails with the gate's line-end fold reverted (the stamp finding fires on the CRLF copy) and passes with it.
  • What the doc pages tell a reader to type exists and works: lint.rst's LINT030 section names options _lint = "LINT030" and LINT030 = true in .lint_config - utils/lint/main.das on the page's own example fires LINT030: argument 2 reads x while the call bump(...) in argument 1 writes it by reference under the first spelling and stays silent on the sequenced form, and the .lint_config re-enable is the CODE = true directive daslib/lint_config.das erases the default-off seed on; module-builtin.rst says nothing needs a require, and doc-verify compiles the page's example with none - utils/internal/doc-verify/main.das --page reference/language/lint and --page stdlib/handmade/module-builtin both green.

Claims - stated, not tested

  • The CI Windows Debug runner is slower than the Debug tree the guards were measured on (zen2); the threefold scale is sized from the CI logs (a JIT child reached codegen at 59 s against a 60 s deadline), not from a run on that runner.
  • The 64 KB pipe matches POSIX; a 1 MB pipe passed the lines in 4 s but pushed the string-heap gauge past the chatty arm's 2 MB bar, since one drain is what the heap holds between collects. No assertion tells the 4 KB pipe from the 64 KB one - the chatty arm's deadline is the only witness, and it widens on a Debug host.
  • Four guards in the rule are defensive and no fixture reaches them: a call with no resolved function, a mention outside any argument slot, a by-value non-const parameter whose argument is a bare variable (the compiler wraps those in a ref-to-value node), and the visitor's own noLint flag.

Not done

  • LINT030 ships off: a tree sweep with it armed found about 90 library sites on the shape (daslib/faker.das twin draws, the dasLLAMA gemm emitter parts and kv accessors, array_data_ptr beside length in dasLLVM, the spirv emitter) - a sweep of its own.
  • The whole-tree lint's fast pass and the Windows Debug nightly re-prove themselves on the next cron.
  • tests/module_cache/REVIEW.md asks every test there to carry options _lint = "LINT030"; no REVIEW.das gate checks it yet - eight files comply today, the gate is a follow-up.
  • No CI row compiles the rule fixtures under utils/lint/tests (utils/lint/REVIEW.das checks that each rule id has one; the linter skips the folder; nothing runs their expect counts) - true of every fixture there, LINT030's included. A row of its own.

borisbat and others added 11 commits September 10, 2026 07:48
…veHost shared module's lifecycle exports before any require names it, and the lazy module scan now defers that module, so live mode never turned on and no HTTP API started - every dasImgui playwright test waited out its ready budget since the lazy-load merge; the host asks the deferred-module loader for live_host before the dlsym, and tests/live_host/test_host_ready.das spawns the daslang-live beside dastest's own daslang on a lifecycle fixture, polls /status and ends it over /shutdown, red on the old binary at 50 s and green at 0.8 s; pinvoke_named and pinvoke_impl2_core composed their message in a string alive across throw_error_at, whose longjmp unwinds nothing, and the new by-name ambiguity test's recover made the ASan lane report the 87 bytes - throw_pinvoke_error moves the text to a stack buffer and releases the string first, src/builtin/ARCHITECTURE.md sec.4 says why; the dasLLAMA image layout stamp hashed source text as checked out, so the Windows lane read every line one byte longer and asked for a re-stamp no other platform could match - the gate folds CRLF before hashing, proven by hashing the folder converted to CRLF against the committed stamp; the tree-sitter generate gate compares bytes against a CRLF checkout on Windows - the four generated artifacts join .gitattributes as eol=lf like dasClangBind's; the fast-math lane's float2string compare reads fmt's printing through a fast-math TU and the vecmath backend rows pin IEEE NaN, tie and out-of-range answers, so those three targets pin precise math the way test_isnan_fastmath_region.cpp does and #error when built otherwise; the four stale nolint markers the whole-tree lint reported go; and the builtin module's handmade page stops telling the reader to `require builtin`, a spelling that resolves to a sibling file, so doc-verify's one red page compiles - the generator writes the implicit-module sentence for a module registered with no require line

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e tsan lane's tray child exits 66 on libdbus's own lock order - dbus_bus_get_private takes the library's two global locks one way and dbus_connection_close the other, both on the main thread, a lock-order report on internals the tray neither holds nor can reorder - so .github/tsan_suppressions.txt names the dlopened library's module as the frame (proved in the daslinux VM under a -DDAS_USE_SANITIZER=tsan build: the report, then twelve passes and no report); the Windows AOT host ran every module_cache child and read nothing back because report_child(t, phase, run_child(cmd, out), out, marker) nests the run beside the out it writes in one argument list, an evaluation order the AOT C++ leaves to the compiler and MSVC and clang-cl take right to left while the interpreter, the JIT and the Linux compilers go left to right - run_child_reported and run_driver_reported make the run a statement of its own at all 62 sites, tests/module_cache/ARCHITECTURE.md says why, and test_aot.exe on zen2 passes the folder; and the watchdog's chatty-child arm moved twenty thousand lines in 96 s on a 64-core Windows box because spawn_process asked CreatePipe for the default 4 KB while the supervisor drains every 250 ms, 16 KB a second - the pipe is created at the POSIX 64 KB (a 1 MB pipe passed the lines in 4 s and failed the string-heap bar, since one drain is what the heap sees between collects), src/builtin/ARCHITECTURE.md sec.5 carries the mechanism, and the arm reads 9 s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n their clocks: every deadline in tests/watchdog/test_watchdog.das and tests/fio/test_process.das goes through guard(), which triples it on a Debug host - shared_module_extension() names one - and caps it at five minutes; the deadlines guard a child's startup or exit, and a Debug daslang compiles what a child requires several times slower (a Debug box took 12 s to a ready file with a 15 s deadline, 30 s to a tray with a 30 s one), so a slow runner read the clock as a red; both files pass on a Release Mac (6, 47) and on a Debug Windows tree (6, 46)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ite that depends on it is the defect: LINT030 (daslib/lint.das) reads a variable mentioned in one argument beside a nested call in another that writes it through a mutable by-reference parameter, off the ordinary walk - one frame per call, its slot advanced per argument, every read recorded into the slot at the frame's own closure depth, the mentions flowing into the parent's slot on the way out, a variable the outer call itself takes by reference not counted since the callee sees its final state whatever the order - and fires on the outer call; it ships default-off beside LINT029, because the tree's library code carries the shape where a callee takes `var` to hand out a pointer or advance a builder (faker's twin draws, the gemm emitter parts, the kv accessors, array_data_ptr beside length - about ninety sites, a sweep of their own); the fixture holds five shapes and four that stay silent, the module_cache tests arm the rule per file and test_default_cache_path.das takes its nineteen sites through run_reported, and CLAUDE.md's fails-silently list, the language skill's calling section, lint.rst and ARCHITECTURE_LINT.md carry the fact - the interpreter and the JIT go left to right, the AOT C++ goes the compiler's way

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…popped off the frame stack attributes what it writes by reference to the parent's slot, so a writer nested in an expression (`pair(1 + bump(x), x)`) is found where the argument-root check missed it, mentions and writes cross into the parent only from the same closure depth so a call inside a block argument's body stays inside it, and the frame stack clears at function entry with the visitor's other stacks; the fixture pins the nested writer and the block-body call; the module_cache tests sequence the four sites where a message string read the output a sibling run wrote and arm the rule in the two child-spawning files that lacked it, and tests/README.md lists the live_host readiness test; the [extern] binder's refusal message crosses the panic jump the way the pinvoke family's does now, and src/builtin/ARCHITECTURE.md sec.4 names every site

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…AUDE.md carries the argument-order shape once, in the fails-silently list, with the sequenced form and the arming spelling, and the idiom-table row goes; src/builtin/ARCHITECTURE.md sec.5 states the chatty child's rate in the present tense and sec.4 names the FMT_THROW stash's file; src/builtin/REVIEW.md binds a C++ edit under a `// src/builtin/ARCHITECTURE.md sec.N` comment to the section it cites, since C++ carries no [arch] annotation; tests/module_cache/ARCHITECTURE.md keeps the fact - a nested run reads its output empty on a Windows AOT host - and the duty moves to tests/module_cache/REVIEW.md as a rule: a child runs as a statement of its own and the file carries `options _lint = "LINT030"`; the dasllama image-stamp section says CRLF folds to LF before the hash, and the gate's read_lf drops the comment that restated it

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… its guards decide - a block handed to a nested call in a sibling argument runs while that argument is evaluated, so its read of the written variable is reported, where a block the outer call itself takes stays silent; the outer call taking the written variable by reference is silent, since the callee sees its final state whatever the order, and the fixture fails with that exclusion forced off; a by-value parameter's write and a nolint-marked site stay silent; tests/.das_test admits tests/live_host only where dasHV is built too, since test_host_ready.das polls the host over its client and a DAS_HV_DISABLED build would fail the folder's compile instead of skipping it; and the review-md walker test writes the dasllama image closure with CRLF line ends and asks the gate to keep the stamp, red with the fold reverted

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nswers on and posts /shutdown only to a child that reported ready - a fixed port with an unconditional shutdown could end an unrelated daslang-live when the test's own child failed to start; closing the handle ends a child that never became ready, and a span every port of which has a host skips the test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…hat the 4 KB pipe permits - its capacity four drains a second - instead of four pipes' worth between two drains; CLAUDE.md's idiom table drops the argument-order row, the fails-silently bullet being the one place the shape lives

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…skill, CLAUDE.md, lint.rst and the LINT030 fixture say the order is not defined and differs between tiers, and stop there - naming which tier goes which way invites reliance on an order the sentence calls undefined, and a host compiler's direction is not a claim a daslang probe can verify

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t citation - this folder's ARCHITECTURE.md or src/ast's, which seven comments here cite - to the section it names

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 10, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It spans core runtime behavior changes (process I/O, panic/throw paths), lint engine additions, and multiple cross-platform CI/test gates that warrant final human verification.

Pull request overview

This PR addresses multiple “nightly red” CI failures by adjusting runtime behavior (module loading, error throwing, Windows process piping), adding/arming a new lint rule (LINT030), and updating tests/docs/gates to lock in the fixed behaviors across platforms and build modes.

Changes:

  • Ensure daslang-live loads the live_host shared module before resolving its exports, with a new tests/live_host regression test and updated .das_test gating.
  • Fix ASan-reported leaks on caught panics by moving pinvoke / dasbind throw messages to stack buffers before Context::throw_error_at longjmps.
  • Improve Windows child-process stdout/stderr throughput (64 KB pipe), add LINT030 (“argument order”) to daslib/lint, and normalize CRLF-sensitive gates / fast-math-sensitive C++ tests.
File summaries
File Description
utils/lint/tests/lint030_argument_order.das New fixture covering LINT030 positives/negatives.
utils/internal/review-md/test_walkers.das Adds CRLF fixture for dasLLAMA stamp gate.
utils/daslang-live/main.cpp Forces deferred loader to load live_host before dlsym/export reads.
tests/watchdog/test_watchdog.das Adds Debug-scaled time guards for child lifecycle deadlines.
tests/README.md Documents the new tests/live_host/test_host_ready.das.
tests/module_cache/test_require_module_now.das Sequences child-run + output checks to avoid argument-order hazards (LINT030).
tests/module_cache/test_module_groups.das Adds reported wrapper to keep child runs as statements (LINT030-safe).
tests/module_cache/test_macro_dep_invalidate.das Arms LINT030 and avoids order-dependent child-run patterns.
tests/module_cache/test_generic_instance_origin.das Arms LINT030 for module_cache child-run sequencing.
tests/module_cache/test_descriptor_manifest.das Uses run_child_reported to avoid nested run_child(..., out) argument hazards.
tests/module_cache/test_deferred_modules.das Uses run_child_reported throughout to avoid empty-output ordering on Windows AOT.
tests/module_cache/test_default_cache_path.das Adds run_reported wrapper and sequences run/output checks safely.
tests/module_cache/REVIEW.md Updates folder rules: require LINT030 + child runs must be standalone statements.
tests/module_cache/ARCHITECTURE.md Documents why run_child_reported exists (argument evaluation order).
tests/module_cache/_mc_common.das Adds run_child_reported helper.
tests/live_host/test_host_ready.das New regression test verifying /status comes up and /shutdown exits cleanly.
tests/live_host/_fixture_host_ready.das Minimal live-host fixture script for daslang-live.
tests/fio/test_process.das Adds Debug-scaled time guards for child lifecycle deadlines.
tests/.das_test Gates tests/live_host on both live_host and dashv.
tests-cpp/small/test_float2string.cpp Hard-fails compilation under fast-math to keep fmt-based byte compares valid.
tests-cpp/CMakeLists.txt Pins test_float2string.cpp to precise-math compile flags.
tests-cpp/big/vecmath_backend/test_vecmath_backend.cpp Hard-fails compilation under fast-math for IEEE-asserting backend rows.
tests-cpp/big/vecmath_backend/CMakeLists.txt Pins both vecmath backend executables to precise-math compile flags.
src/builtin/REVIEW.md Adds rule: C++ comments citing ARCHITECTURE sections must update those sections in the same diff.
src/builtin/REVIEW.das Removes stale STYLE030 nolint on review_nttp require.
src/builtin/module_builtin_fio.cpp Windows spawn_process pipe sized to 64 KB (CreatePipe size param).
src/builtin/module_builtin_debugger.cpp Avoids heap-owning locals across throw_error_at longjmp for pinvoke errors.
src/builtin/module_builtin_dasbind.cpp Avoids heap-owning locals across throw_error_at for binder refusal message.
src/builtin/ARCHITECTURE.md Documents sec.4 (panic-jump message discipline) and sec.5 (pipe sizing rationale).
skills/daslang/references/functions.md Documents unspecified argument evaluation order.
modules/dasLLAMA/tests/test_arch_registry.das Removes stale STYLE029 nolint marker.
modules/dasLLAMA/REVIEW.das Normalizes CRLF->LF before hashing/stamping.
modules/dasLLAMA/dasllama/dasllama_asr.das Removes stale STYLE029 nolint marker.
modules/dasLLAMA/ARCHITECTURE_IMAGE.md Documents CRLF folding in the image-layout stamp closure.
examples/daslive/hello_stdio/main.das Removes stale STYLE030 nolint marker.
doc/source/stdlib/handmade/module-builtin.rst Corrects docs: builtin module doesn’t need require builtin.
doc/source/reference/language/lint.rst Adds LINT030 documentation section.
doc/reflections/gen_module_examples.py Adjusts generated module docs to omit “require” guidance when not applicable (builtin).
daslib/lint.das Implements LINT030 (argument order dependency detection).
daslib/lint_config.das Adds LINT030 to the default-disabled seed list.
daslib/ARCHITECTURE_LINT.md Documents LINT030 implementation approach and why it ships default-off.
CLAUDE.md Adds “argument order undefined” to the “fails silently” list + LINT030 mention.
.github/tsan_suppressions.txt Adds suppression for libdbus lock-order report.
.gitattributes Forces LF for tree-sitter generated artifacts to avoid CRLF hash diffs.
Review details
  • Files reviewed: 44/44 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread doc/source/reference/language/lint.rst Outdated
…and what the page's own pair returns - 11 or 10 - instead of naming the call by its argument values; and it says which block reads count: one the outer call takes runs after every argument, one handed to a nested call in a sibling argument runs while that argument is evaluated

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 10, 2026 15:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The runtime behavior changes are consistent with the documented architecture rationale and the new/updated tests and gates directly cover the previously failing scenarios.

Review details
  • Files reviewed: 44/44 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@borisbat
borisbat merged commit b926170 into master Sep 10, 2026
34 checks passed
@borisbat
borisbat deleted the bbatkin/nightly-fixes-2026-09-10 branch September 10, 2026 15:42
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.

2 participants