hardening: CodeOfPolicies ABI canary, module vintage stamps, loud jit/GPU/tune failures - and overrides announce themselves - #3687
Merged
Conversation
… jit/GPU/tune failures - and active overrides announce themselves Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H3CQmhA327qR2RyKZCKvj6
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens daslang against stale-binary / ABI-drift failure modes by adding an ABI canary for CodeOfPolicies, introducing per-dynamic-module “vintage” stamps, and making previously silent JIT/GPU/tune downgrade paths emit loud, self-diagnosing output (including a new “overrides announce themselves” review rule).
Changes:
- Add
CodeOfPolicies::abi_stamp+ verification atparseDaScript/compileDaScript, with a dedicated C++ test. - Add dynamic-module ABI “vintage” export via
REGISTER_DYN_MODULEand warn on mismatch/missing stamp at load time; expose pending module-load failures to das viadescribe_pending_dynamic_modules. - Make tuning/JIT/GPU rails failures and override knobs explicit in logs, docs, checklists, and tests (including tune mint suppression via
tune_suppress_mint).
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests-cpp/small/test_policies_canary.cpp | New doctest coverage for the CodeOfPolicies ABI canary predicate. |
| src/builtin/module_builtin_fio.cpp | Warn on dyn-module vintage mismatch; add das-visible describe_pending_dynamic_modules binding. |
| src/ast/ast_parse.cpp | Enforce the CodeOfPolicies ABI stamp at parse/compile entry points. |
| include/daScript/ast/ast.h | Introduce abi_stamp + versioned stamp computation and das_abi_vintage(); export per-module vintage symbol. |
| doc/source/stdlib/handmade/function-fio-describe_pending_dynamic_modules-0x4bb5b7686cbfbdfb.rst | Handmade stdlib doc stub for the new fio function. |
| doc/reflections/das2rst.das | Ensure describe_pending_dynamic_modules is grouped in das2rst output. |
| modules/dasLLVM/daslib/llvm_jit_run.das | Make “dll mode requested but static build” and “0 functions jitted” cases loud errors. |
| modules/dasLLVM/daslib/llvm_tune.das | Add tune_suppress_mint and explicit override announcements for tune policy/noise rails. |
| modules/dasLLVM/tests/llvm_tune_scope.das | Add a new test arm proving tune_suppress_mint prevents minting and keeps fallback stamps. |
| modules/dasLLVM/tests/llvm_tune_scope_client_suppress.das | New client fixture that suppresses mint from a library [init]. |
| skills/llvm_tune.md | Document the new runtime mint-suppression seam and its precedence rules. |
| modules/dasLLVM/CODEREVIEW.md | Add the “active overrides announce themselves” checklist rule for dasLLVM. |
| modules/dasLLAMA/dasllama/dasllama_gpu_tier.das | Add gpu_want_any and moe_gpu_backend_registered to disambiguate rail intent and backend absence. |
| modules/dasLLAMA/tests/test_gpu_tier.das | Extend tests for the new GPU-tier intent/registration predicates. |
| modules/dasLLAMA/dasllama/dasllama_image.das | Emit a loud error when GPU rails are requested but no backend module registered; include dlopen failure details. |
| modules/dasLLAMA/benchmarks/lcpp_bench.das | Refuse GPU-flagged benchmark rows when the GPU tier resolved CPU; stamp execution state into config output. |
| modules/dasLLAMA/harness/tuner_noise.das | Tag noise-gate output when DAS_TUNE_NOISE_CV recalibrates; fix Windows stderr redirection. |
| modules/dasLLAMA/harness/dasllama_tuner.das | Detect noise-gate refusal and make the final rc!=0 line self-diagnosing; announce noise overrides up front. |
| modules/dasLLAMA/dasllama/dasllama_math_gen.das | Wire DASLLAMA_ALLOW_UNTUNED=1 to tune_suppress_mint and log the active override. |
| modules/dasLLAMA/dasllama/dasllama_env.das | Update DASLLAMA_ALLOW_UNTUNED docstring to include mint suppression behavior. |
| modules/dasLLAMA/performance/profile_common.das | Clarify allow-untuned behavior in tune summary docs. |
| modules/dasLLAMA/ENVIRONMENT.md | Regenerate env docs reflecting allow-untuned mint suppression. |
| modules/dasLLAMA/BRINGUP.md | Update bring-up guidance to note allow-untuned also suppresses auto-mint. |
| modules/dasLLAMA/CODEREVIEW.md | Add the “active overrides announce themselves” checklist rule for dasLLAMA. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…s, Context::setup canary, the shared gpu_want_arms_tier predicate, metal-world guards, noise-refusal escapes honesty, both checklists rewritten per their own self-review Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H3CQmhA327qR2RyKZCKvj6
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.
The hardening landing from the jit-infra fallout arc (follow-up to #3683): the stale-binary failure class gets code teeth, the remaining silent failures get loud, and the tune mint gets its dev-run escape. Plus a new review rule, applied to both checklists and implemented across the diff: an active override announces itself in the run's output.
1. CodeOfPolicies ABI canary (the night's root cause)
CodeOfPoliciesnow leads with anabi_stampfield whose default initializer —(DAS_POLICIES_VERSION << 24) | (sizeof(CodeOfPolicies) << 8)— compiles into whatever binary CONSTRUCTS the struct (the host exe), whileparseDaScript/compileDaScriptcheck it against libDaScript's own headers. A stale daslang.exe over a fresh DLL now dies withFATAL: CodeOfPolicies ABI stamp mismatch ... relink the hostinstead of silently reading every policy field (includingjit_enabled) at shifted offsets.aot == false.static constexprmember (NSDMI is complete-class context), one source of truth.checkCodeOfPoliciesStamp, covered bytests-cpp/small/test_policies_canary.cpp) + the fatal wrapper.2. Module-vintage stamps
DAS_BUILD_IDonly changes at releases, so a shared module rebuilt against DIFFERENT headers of the SAME version passes the existing gate and is silently, subtly wrong.REGISTER_DYN_MODULEnow also exportsvintage_dyn_<name>returningdas_abi_vintage()— an FNV fold ofDAS_BUILD_IDplus the sizeof of the core ABI surface (Module, Context, SimNode, Program, TypeDecl, ..., CodeOfPolicies, daScriptEnvironment). The loader compares and WARNS (never refuses) on mismatch or absence.Field-verified: loading a same-version pre-vintage module (
D:/Work/daScript/modules/dasAudiobuilt from the main tree) into this binary prints the warning — and then the process AVs inside the drifted module, which is exactly the disease class; the log now names the culprit right before the crash. An old-VERSION module (DASPKG dasVulkan, 0.6.3) still hits the layer-1 build-id refusal unchanged.3. Loud-failure trio
run_jitending with ZERO functions to jit now logs a LOG_ERROR (the WHOLE program runs interpreted) instead of silently skipping the pipeline; the dll-mode-on-static-build downgrade is upgraded from a quiet warning to an error naming the stale-stub possibility.lcpp_benchrefuses (panics) any row whereDASLLAMA_GPU*rails were requested but the GPU tier resolved CPU, distinguishing "no backend module registered" from "registered but did not arm" — and stamps the exec state (exe-native/jit/INTERPRETED) into the config line so a dead jit can never hide behind a normal-looking header.load_model_cachedlogs a LOG_ERROR when GPU rails are wanted but no backend module ever registered — therequire ?vulkanguard previously swallowed a failed shared_module load with zero diagnostics. The message includes the exact dlopen failures via a new das-visible builtindescribe_pending_dynamic_modules(registered in das2rst groups, handmade doc included). New SPI predicatesgpu_want_any/moe_gpu_backend_registeredcarry asserts intest_gpu_tier.das.4. Tune remnants
tune_suppress_mint(reason)is a new runtime seam in llvm_tune — a library[init]can suppress theauto/restartmint so untuned scopes keep fallback stamps (--tunestill wins). dasLLAMA wiresDASLLAMA_ALLOW_UNTUNED=1to it: the dev-run escape now skips the minutes-long mint instead of only bypassing the measurement gate. Scope-test arm 13 proves it (no FAKE TUNER, fallback RESULT, no sidecar).rc=1at the log tail.dasllama_tunernow detects the refusal in the relayed output and closes withREFUSED for noise+ the full escape ladder (DAS_TUNE_NOISE_CVrecalibrates /DAS_TUNE_NOISE_OVERRIDE=1mints anyway, stamped /DASLLAMA_ALLOW_UNTUNED=1skips minting).engine_sha()'s2>/dev/nullunder cmd.exe redirected to a literal file path and leakedThe system cannot find the path specified.into every tuner run — now2>NULon windows.5. The override-announce rule
New CODEREVIEW.md entry in BOTH dasLLVM and dasLLAMA: a knob that changes what a run measures, mints, or emits beyond its defaults prints one line naming itself when set, silent when unset. Implemented for the current family:
DAS_TUNE_POLICY— announced at policy resolution (once per app compile).DAS_TUNE_NOISE_CV— noise-gate threshold lines carry(DAS_TUNE_NOISE_CV); tuner banner prints the recalibrated gate (new querytune_noise_threshold_overridden).DAS_TUNE_NOISE_OVERRIDE— announced in the tuner banner when set, not only when it fires.DASLLAMA_ALLOW_UNTUNED— unconditional LOG_WARNING at[init]when set.Validation
tests/suite green (two apparent fs/lsp reds were artifacts of a relative-dasroot .in the runner invocation, both pass with a proper root); JIT smoke clean.llvm_tune_scopeall 13 arms green under-jit;test_gpu_tiergreen.nolint:PERF030indasllama_gpu_tier.dasthat the sweep surfaced. Format clean;--ast-verify -compile-onlyclean on every changed.das.ENVIRONMENT.mdregenerated from the widenedallow_untuneddeclaration.Notes for review: the
NOISE GATEstring-scan indasllama_tuner.run_halfis a display affordance over the relayed child stream (the structured alternative would be a new@tuneevent; deliberately not taken here).LLVM_JIT_CODEGEN_VERSIONis unbumped on purpose — no IR generation, target-machine, or ABI change in this diff.🤖 Generated with Claude Code
https://claude.ai/code/session_01H3CQmhA327qR2RyKZCKvj6