Repository navigation
codegen 1.11.1: merge the release train into main - #371
Conversation
Tests only. A function-local string that is read with history and joined with its own current value by + (issue #354) must keep its string type: the current slot is a std::string, so the emitted C++ must not wrap it in std::to_string. tests/test_string_local_history_concat.py compiles, runs and compares the result of the neutral source from the issue, the same shape under the built-in spellings second and hour, a string-annotated local, a reassigned local, two call sites with different arguments, a chart-level pair and swapped operands. It also keeps the translation-time refusal of the nine price-field names read with history in a requested helper, the emission of an explicit string conversion and of a numeric na operand, and the analyzer refusal of a string plus an integer. The expected values are literals computed by hand from closes 10, 20, 30 and opens 1, 2, 3. tests/test_builtin_named_locals_compile.py now requires the neutral control of each string-history row to compile; before, it accepted a compile failure that matched the renamed row's failure. Two older modules compare a complete emission with the emission of an older codegen: tests/test_generated_member_names.py and tests/test_helper_builtin_named_locals.py. For their string rows the older emission holds the join that did not compile, so they now repair that one site in the older text with a helper of the new module (it requires exactly one such site) and compare everything else unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…a concatenation A function-local string that is read with history (aa[1]) is a string series, but the scalar local-type map has no entry for it, so the type query for the bare name returned the double fallback. In a + whose other operand was a string the bare name was then wrapped in std::to_string, which does not accept a std::string, and the generated C++ did not compile (issue #354). The binary + lowering now asks for the series element type when the query returns double for a bare function-local that reads its own series slot and whose series holds strings; every other operand is typed as before. The general type query and the translation-time refusal of price-field names are unchanged. The changelog drops the exception that named this shape and adds a bullet for the fix. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Tests only. A record that a script keeps in a top-level var and builds from a stable var array, and a plain var-to-var array alias, hold the source as it stands at the end of the bar in which they were bound: live during that bar, a separate array after it, and every holder keeps its own array. tests/test_array_retained_alias.py compiles, runs and compares nine scripts with the sizes observed on TradingView as literals: a record built on the first bar from an empty source that is pushed after the construction, the same with two pushes, a record built on a later bar, the same with one more push after the construction, a record built on every bar (a guard that passes without the change), pushes made through the field after the first bar, a plain var alias, two records built from one array, and one record with two array fields given the same array. The driver reuses one strategy for two runs, which covers the run reset. It also keeps the neighbours that must not change (a record whose source is not pushed again, a record built from an array literal), the usual array reads on a plain alias (size, get, a loop, last), the compile error for a copy of such a record made in the creation bar and in a later bar, the checkpoint round trip of the binding in the generated trait and in a generated strategy, and emission guards for the shapes the change leaves alone (array copy, array history, a nested record, varip, intrabar recalculation, a rebound source, an alias chain). tests/test_e2e_udt_array_fields.py: the row for a record held directly by a var now expects the new binding instead of the copy taken at construction; its other two rows keep the vector storage. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A record that a script keeps in a top-level var and builds from a stable var array took a copy of the array at construction, and so did a plain var-to-var alias. TradingView shows the array as it stands at the end of the bar in which the binding was made: live during that bar, a separate array after it, whatever the source does later. Each holder has its own array: two records built from one source, and two fields of one record given the same array, do not share it. pineforge_codegen/codegen/retained_alias.py selects the bindings whose lifetime is proved (a direct top-level var holder, stable primitive var arrays, a constructor outside callable bodies, no rebinding of the field) and emits a binding handle for them and one manager per source array. Each creation takes a binding of its own from the manager, which reads the live source; the manager closes every binding opened in the bar after the last authored statement of the bar, giving each its own copy of the source. A creation on a later bar makes a new binding and leaves the earlier ones as they are. The handle has a checkpoint specialization that keeps the binding, its pending or owned state and the owned contents. A copy() of a record with such a field keeps its existing compile error: TradingView does not share the array between a record and its copy, and no observation shows what the copy holds. Scripts with requested evaluations, collection history, array copy or slice, an array or object subscript, nested records, varip holders or intrabar recalculation keep their previous lowering, and so does every script that selects nothing: their C++ does not change. The changelog describes the change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Brings in the pull request that landed on main after this branch was cut (the reservation of the numbered tuple element bindings, and the string-history refusal rows pinned against the pinned reference). Two files conflict. CHANGELOG.md: the bullet about a local spelled like a built-in variable keeps main's text without its clause saying that a string local read with history and used in a concatenation still does not compile (this branch fixes that), and the new bullet for the fix stays after it. tests/test_builtin_named_locals_compile.py: the docstring keeps main's price-field exception and no longer says that the string-with-history shapes do not compile; the loop of test_string_history_compile_outcome_matches_neutral_control is main's loop over the census of names, with this branch's assertion that the neutral control compiles kept before it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e emissions The nine rows of test_price_named_string_library_local_history_keeps_the_base_outcome compare the whole C++ of a script whose library function joins a string local with its previous value against the older reference commit. The reference wrapped the current value in std::to_string (issue #354), which does not compile; with the fix merged, the new emission joins the strings. The reference text gets the same one-site repair that the two other modules of the fix use (it requires exactly one such site), and everything else is still compared unchanged. Rows that compare a refusal are not touched. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Tests only. The rows that compare the translation of scripts the retained array change must not touch with the translation of the base took their reference from a commit that main does not contain (that pull request was merged as a squash), so on this branch and on main the comparison never ran and the rows fell back to pinned tokens. One token named the unescaped identifier source where the emitter writes pf_safe_source, and another asserted the absence of a field the script never had, so neither could be relied on. The reference is now main's commit a156a7d (the base this change sits on), and it is required: a commit that is missing or is not an ancestor fails the row with the "required byte oracle commit ... is missing" text that the other byte-oracle tests of the repository use. Every neighbour row and every row for a shape the change leaves alone now compares the whole translation unit with the base, and keeps the check that no retained helper appears. New rows, test_unresolved_callable_types_keep_base_emission in tests/test_array_retained_alias.py: a record whose array field is assigned through the receiver of a method (self.stamps := ...), and an array copy and an array slice made through an array parameter of a method, each in a script that also builds a record from a stable var array. The expectation of each is the base translation with no retained helper. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ved holder The plan that selects a record type for the retained lowering excludes a type whose array field is assigned (holder.field := value). It resolved the holder with the types known at planning time, before the parameters of methods and functions are known, so a holder that is a parameter (self in a method, for example) came back unresolved and the exclusion was skipped. The type was then selected, and the emitter later reached the assignment with a value that is not a proven source and stopped with a bare AssertionError, which transpile does not turn into a diagnostic, on a script that the base translator compiled. An assignment to a member that is an array field of a candidate type, through a holder whose type is not resolved, now removes that type from the selection: it keeps the base lowering. The same holds for the method form of copy() and slice() whose receiver is unresolved and is a name bound by a parameter, a loop or a tuple assignment, as it already did for a receiver known to be an array. The emitter's invariant for a retained field without a proven source now raises the existing CodegenInvariantError, which transpile reports as the located internal-error diagnostic, instead of a bare AssertionError. Scripts that select nothing, and the shapes that were selected before and have a resolved holder and receiver, are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…variable in v6 (#361) Pine v6 has no implicit conversion of a number to bool, so `if ta.change(t)` with a float t, or `if ta.change(strategy.position_size)`, does not compile on TradingView. The generator translated both and ran them with the Pine v5 meaning (a non-zero number is true). The condition refusal of if and while now also proves the numeric type of ta.* calls and of built-in member variables, following the overload that the argument types select: ta.change of a bool stays a bool condition, and an argument of unknown type never causes a refusal. Pine v5 library definitions keep their behavior. Tests: both reported forms, while conditions, arithmetic over such a call, numeric built-in members, overloaded calls with numeric and bool sources, controls that must stay accepted, a v5 library control, and complete-C++ comparisons for scripts that are accepted. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…same name plainly (#359) A var or varip declared inside one block and a plain variable of the same name declared in a sibling block were emitted as one class member. The plain declaration of the other block overwrote the member, so the var read whatever that block wrote last and lost its first value, with no diagnostic. The code generator now selects such a persistent declaration for a member name of its own, through the renamer that already separates declarations whose types differ. Two var declarations (which the analyzer already separates), two plain declarations of one type, a name declared directly at the top level, and collisions inside a single block keep their output. Tests: the reported script against its control, the blocks in either order, varip, three blocks, for, while and switch siblings, history reads, shadowing binders, and complete-C++ comparisons for scripts without such a pair. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Remove five unused members from 48 public metrics fixtures while preserving the remaining bytes and parsed content.
…able (#360) A function or method parameter named like a built-in series (close, high, hl2, ...) lost its [n] history operator: f(close) => close[1] was emitted as the current value, and the script ran with no diagnostic and gave different trades from TradingView. The pass that gives callable locals spelled like built-in variables a private name now covers parameters too, so such a parameter takes the same path as a parameter with any other name. Keyword arguments keep binding to the authored spelling, including for overloads and methods, and diagnostics show the authored spelling. A string parameter named like a price field that is read with history inside a requested helper keeps its earlier refusal. A method call with an unknown keyword argument keeps its earlier error. A function call that binds no argument to such a history parameter (an unknown or misspelled keyword) is now refused like any other history parameter, with the existing error about the per-callsite type; before, it compiled and read the chart's series. Tests: the smallest form, the trades form with its control and the swapped argument form; neighbouring forms (method, keyword call, forwarding, hl2, two call sites); controls that were already right; complete-C++ comparisons for scripts without such a parameter. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Describe recorded fixture semantics and dated evidence without operational attribution. Preserve the documented technical rules and examples.
…#362) A float setting of a built-in indicator that is an expression on an input (the multiplier of ta.bb, ta.bbw, ta.kc, ta.kcw and the ta.vwap bands, the factor of ta.supertrend, the arguments of ta.sar, the offset and sigma of ta.alma) was converted to an integer before it reached the indicator: a multiplier of 1.5 became 1 and a SAR maximum of 0.2 became 0. The code generator rebuilds the indicator from the input and cast every runtime constructor argument whose lowered expression is float-typed (a math call, a division, a timeframe helper) to an integer, whatever the slot was. That cast now follows the declared type of the constructor slot: a float slot receives the value as a double (an integer na stays missing). Every other slot, and every argument the cast never applied to, is rendered exactly as before. The ta.vwap bands needed one more step. The slot lookup goes by the Pine function name, and the two band classes (the anchored form and the form with the anchor omitted and stdev_mult given by keyword) have no entry under it, so their multiplier slot was never placed and kept the integer cast. Both classes are now placed from the anchored-band table, which names stdev_mult as the multiplier. Tests: the reported scripts against their controls with input overrides, the other float settings of the same indicators, the ta.vwap multiplier in both forms on the chart and in a requested context, the forms that keep their refusals, integer lengths, and complete-C++ comparisons against the previous commit for scripts whose float settings are plain inputs or literals. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Member of the 1.11.1 codegen train (#361 group A), reviewed and tested on its exact head.
Member of the 1.11.1 codegen train (#359), reviewed and tested on its exact head.
Member of the 1.11.1 codegen train (#360), reviewed and tested on its exact head.
Member of the 1.11.1 codegen train (fixture metadata), reviewed on its exact head.
Describe the declared symbol fact as per-run metadata and name the measured instrument types directly.
Member of the 1.11.1 codegen train (#362), reviewed and tested on its exact head.
Member of the 1.11.1 codegen train (public guidance wording), reviewed on its exact head.
… change The only conflict is CHANGELOG.md: this change and the numeric condition entry both add their bullet at the top of the unreleased list. Both bullets are kept, the condition entry first. No other file needed a resolution. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The only conflict is CHANGELOG.md. This change edits the first bullet of the built-in-named locals entry (it drops the clause saying that a string local read with history and used in a concatenation still does not compile) and adds its own bullet after it; the train branch adds the built-in-named parameter bullet after the original entry. The result keeps this change's edited bullet and its new bullet, then the train's parameter bullet. No other file needed a resolution. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Member of the 1.11.1 codegen train (retained array alias), reviewed and tested on its exact head.
Member of the 1.11.1 codegen train (#354 string local history), reviewed and lab-tested on its exact merge head.
There was a problem hiding this comment.
Graphify reviewed this change.
No issues found by static checks — no coupling regressions or blocking issues in the code graph. That is not the same as safe to merge: see what was not checked.
Not checked: tests were not run; formal verification proved 0 of 35 changed function(s) (1 sampled, not proven, 34 not verified).
Formal verification. PR-changed functions: 1/35 verified (0 proven, 1 may-equivalent, 0 distinguished) · 34 not verified (3 vacuous, 21 unsupported, 10 over cap).
Not verified on this run: \_rewrite\_function\_syntax\_method\_call (unsupported), \_visit\_FuncCall (unsupported), \_visit\_IfStmt (unsupported), \_visit\_WhileStmt (unsupported), separate\_builtin\_callable\_locals (vacuous: never exercised), \_declared\_names (unsupported), rename\_declarations (unsupported), \_declarations (vacuous: never exercised), block\_declarations (vacuous: never exercised), \_block\_locals\_needing\_names (unsupported), and 14 more; 10 changed function(s) beyond the cap and 0 skipped when the time budget ran out.
Graphify review — findings
Fixes a batch of Pine compile/codegen issues, mostly around built-in-named locals and parameters, var storage, and float indicator settings (#354, #359, #360, #361, #362). The diff is truncated, so this covers the changelog and docs, not the full code changes. - Refusals: Pine v6 now rejects an if/while condition whose numeric value comes from a ta.* call or a built-in variable like strategy.position_size, as TradingView does. Bool overloads and Pine v5 libraries are unaffected. - Built-in-named locals: a parameter spelled like a built-in (close, high) keeps its [n] history. A function-local string read with history keeps its string type in concatenations, so the emitted C++ no longer calls std::to_string on a string. - var storage: a var in one block no longer shares storage with a same-named plain variable in a sibling block. Retained record fields and plain var array aliases built from stable var arrays now keep their own copy of the array as it stood at the end of the creation bar. - Float settings: float settings computed from an input keep their fraction in ta.bb/bbw/kc/kcw, ta.vwap bands, ta.supertrend, ta.sar and ta.alma. Integer slots keep their narrowing and preserve na. Generated C++ changes, so affected strategies need to be regenerated and relinked.
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 6212 functions depend on the 2154 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
Analyzer— 107 callers, 15 callees - worse:
CodeGen— 68 callers, 14 callees - worse:
parse_library_module()— 15 callers, 11 callees - worse:
bind_method_call()— 6 callers, 4 callees - worse:
separate_builtin_callable_locals()— 2 callers, 6 callees - worse:
_assert_keeps_the_base_outcome()— 3 callers, 4 callees - new:
test_builtin_parameter_inventory_registers_scoped_history()— 0 callers, 6 callees
Verification — 6212 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 5334 function(s) in the blast radius were not formally verified this run
Cross-repo impact
Cross-repo impact
This change impacts 2 symbol(s) across 1 peer repo(s) — blast radius over derived cross-repo edges:
- pineforge-4pass/pineforge-hpo —
python/pineforge_hpo/transpile.py(via import_moniker, heuristic),tests/python/test_transpile.py(via import_moniker, heuristic)
1 peer repo(s) in this group are not yet indexed — cross-repo impact may be incomplete.
Cross-repo linkage is derived (SCIP-moniker matches are sound; name/contract matches are heuristic) and ADVISORY — it never affects this check's conclusion.
Test selection
Test selection
515 of 515 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety (
noncode-change,uncovered-code) — the selection is not trustworthy on its own (see below). CI should run the whole suite.
tests/test_action_pins.py— full-run-safetytests/test_allow_entry_in_qualifier.py— impact, full-run-safetytests/test_allow_entry_in_request_const.py— impact, full-run-safetytests/test_analyzer.py— impact, full-run-safetytests/test_analyzer_matrix_inference.py— impact, full-run-safetytests/test_analyzer_ta_return_types.py— impact, full-run-safetytests/test_anchor_tf_change.py— impact, full-run-safetytests/test_anchor_time.py— impact, full-run-safetytests/test_anchor_vwap.py— impact, full-run-safetytests/test_array_bounds_insert_fill_slice.py— impact, full-run-safetytests/test_array_checked_access.py— impact, full-run-safetytests/test_array_empty_aggregates.py— impact, full-run-safetytests/test_array_history.py— impact, full-run-safetytests/test_array_missing_integer_index.py— impact, full-run-safetytests/test_array_new_color_fill_and_na_size.py— impact, full-run-safetytests/test_array_new_defaults_and_order.py— impact, full-run-safetytests/test_array_reference_semantics.py— impact, full-run-safetytests/test_array_retained_alias.py— impact, changed-test, full-run-safetytests/test_array_slice_view.py— impact, full-run-safetytests/test_array_terminal_returns.py— impact, full-run-safetytests/test_arrseg_coded_run_stops.py— impact, full-run-safetytests/test_arrseg_review_fixes.py— impact, full-run-safetytests/test_binop_operand_order.py— impact, full-run-safetytests/test_block_shadow_primitive_types.py— impact, full-run-safetytests/test_block_var_plain_siblings.py— impact, changed-test, full-run-safetytests/test_bool_na_refusal.py— impact, full-run-safetytests/test_bool_na_refusals_2.py— impact, full-run-safetytests/test_bool_na_values.py— impact, full-run-safetytests/test_bool_string_inference.py— impact, full-run-safetytests/test_builtin_name_shadow.py— impact, full-run-safetytests/test_builtin_named_locals_compile.py— impact, changed-test, full-run-safetytests/test_builtin_named_locals_price_refusal.py— impact, changed-test, full-run-safetytests/test_builtin_named_locals_receipt.py— impact, full-run-safetytests/test_builtin_named_locals_scope.py— impact, changed-test, full-run-safetytests/test_builtin_named_parameters.py— impact, changed-test, full-run-safetytests/test_builtin_named_parameters_reference.py— impact, changed-test, full-run-safetytests/test_calc_on_order_fills_codegen.py— impact, full-run-safetytests/test_calendar_lambda_locals.py— impact, full-run-safetytests/test_call_argument_order.py— impact, full-run-safetytests/test_callable_local_histories.py— impact, full-run-safetytests/test_callable_series_param_types.py— impact, full-run-safetytests/test_callable_string_series_type.py— impact, full-run-safetytests/test_callable_ta_forwarded_length.py— impact, full-run-safetytests/test_callable_var_first_reach.py— impact, full-run-safetytests/test_checked_settings.py— impact, full-run-safetytests/test_ci_engine_main_touched.py— full-run-safetytests/test_closed_trade_fold.py— impact, full-run-safetytests/test_closed_trade_fold_emission.py— impact, full-run-safetytests/test_closed_trade_text_equals.py— impact, full-run-safetytests/test_coded_run_stops.py— impact, full-run-safety- … and 465 more
non-code file(s) changed (
CHANGELOG.md,docs/reference/known-codegen-quirks.md,docs/reference/support-contracts.md,tests/fixtures/bar_magnifier/mi-fx-eth-15/metrics.json,tests/fixtures/bar_magnifier/w9mag-fx-eth-15-off/metrics.json…) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
CHANGELOG.md,docs/reference/known-codegen-quirks.md,docs/reference/support-contracts.md,pineforge_codegen/codegen/emit_top.py,pineforge_codegen/codegen/retained_alias.py) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Docs that may be stale (advisory)
AGENTS.md§ Layout (lines 65-80): references changed symbolsreferenceAGENTS.md§ Emission invariant (lines 185-223): references changed symbolsreferenceAGENTS.md§ Conventions (lines 224-240): references changed symbolsreferenceCLAUDE.md§ Layout (lines 65-80): references changed symbolsreferenceCLAUDE.md§ Emission invariant (lines 185-223): references changed symbolsreferenceCLAUDE.md§ Conventions (lines 224-240): references changed symbolsreferenceREADME.md§ How it works (lines 516-542): references changed symbols__init__docs/PUBLIC_CONTRACT.md§ Optional generated settings extension (lines 350-412): references changed symbolsmemberdocs/PUBLIC_CONTRACT.md§ Input manifest and override keys (lines 632-753): references changed symbolsmemberdocs/reference/file-map.md§ File map (lines 1-186): references changed symbolsmember
…and 2 more.
Formal verification
Could not verify: Could not verify \_rewrite\_function\_syntax\_method\_call.
The verifier did not have enough to check \_rewrite\_function\_syntax\_method\_call, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_FuncCall.
The verifier did not have enough to check \_visit\_FuncCall, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_IfStmt.
The verifier did not have enough to check \_visit\_IfStmt, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_visit\_WhileStmt.
The verifier did not have enough to check \_visit\_WhileStmt, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
No difference found (not proven): No behavior difference found in \_builtin\_callable\_local\_names (not a proof).
The verifier ran both versions of \_builtin\_callable\_local\_names on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify separate\_builtin\_callable\_locals.
The verifier did not have enough to check separate\_builtin\_callable\_locals, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 80 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly AttributeError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify \_declared\_names.
The verifier did not have enough to check \_declared\_names, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `node` is annotated `ASTNode` — outside the synthesizable primitive/collection set
Could not verify: Could not verify rename\_declarations.
The verifier did not have enough to check rename\_declarations, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_declarations.
The verifier did not have enough to check \_declarations, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 250 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous
Could not verify: Could not verify block\_declarations.
The verifier did not have enough to check block\_declarations, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 17 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous
Could not verify: Could not verify \_block\_locals\_needing\_names.
The verifier did not have enough to check \_block\_locals\_needing\_names, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_collect\_ta\_runtime\_resets.
The verifier did not have enough to check \_collect\_ta\_runtime\_resets, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_generate\_cpp.
The verifier did not have enough to check \_generate\_cpp, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_lower\_reset\_expr\_via\_visitor.
The verifier did not have enough to check \_lower\_reset\_expr\_via\_visitor, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_runtime\_ctor\_arg\_for\_reset.
The verifier did not have enough to check \_runtime\_ctor\_arg\_for\_reset, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_ta\_run\_ctor\_args.
The verifier did not have enough to check \_ta\_run\_ctor\_args, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_emit\_handle\_checkpoint\_traits.
The verifier did not have enough to check \_emit\_handle\_checkpoint\_traits, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_emit\_includes.
The verifier did not have enough to check \_emit\_includes, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_emit\_on\_bar.
The verifier did not have enough to check \_emit\_on\_bar, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_emit\_script\_state\_hooks.
The verifier did not have enough to check \_emit\_script\_state\_hooks, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_security\_derived\_argument\_history.
The verifier did not have enough to check \_security\_derived\_argument\_history, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_lazy\_edge\_hoist\_block\_reason.
The verifier did not have enough to check \_lazy\_edge\_hoist\_block\_reason, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_ta\_arg\_takes\_plan.
The verifier did not have enough to check \_ta\_arg\_takes\_plan, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_ta\_ctor\_param.
The verifier did not have enough to check \_ta\_ctor\_param, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
Could not verify: Could not verify \_ta\_dynamic\_ctor\_arg.
The verifier did not have enough to check \_ta\_dynamic\_ctor\_arg, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
· 3 grounded finding(s) anchored inline below; 4 more finding(s) on lines outside this diff (see the check run).
| ) | ||
|
|
||
|
|
||
| def separate_builtin_callable_locals(program, bindings) -> bool: |
There was a problem hiding this comment.
separate_builtin_callable_locals()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
|
|
||
|
|
||
| def _assert_keeps_the_base_outcome(source, reference, tmp_path, libraries=None): | ||
| def _assert_keeps_the_base_outcome(source, reference, tmp_path, libraries=None, |
There was a problem hiding this comment.
_assert_keeps_the_base_outcome()
high coupling complexity (Ca·Ce = 12).
Grounded coupling-delta finding (deterministic), not an LLM guess.
|
|
||
| @pytest.mark.parametrize("name", _LOCAL_NAMES) | ||
| @pytest.mark.parametrize("method", [False, True], ids=["function", "method"]) | ||
| def test_builtin_parameter_inventory_registers_scoped_history(name, method): |
There was a problem hiding this comment.
test_builtin_parameter_inventory_registers_scoped_history()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
…able tests/test_numeric_condition_calls.py carried an autouse fixture that set PINEFORGE_REQUIRE_NATIVE=1 for every test of the file. That overrides the rule of tests/_compile.py: without an engine checkout the native tests skip, and only an environment that sets PINEFORGE_REQUIRE_NATIVE=1 itself fails on missing inputs. In an environment without the engine (the hosted test job) the native tests of the file therefore failed with "PINEFORGE_ENGINE_INCLUDE not set or invalid" instead of skipping. The fixture and its comment are removed; nothing else changes. With the engine set and PINEFORGE_REQUIRE_NATIVE=1 in the environment every test of the file runs as before. Refs #361. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Let the numeric condition tests skip when no engine checkout is available
Merges the codegen 1.11.1 train branch
train/codegen-1.11.1(head 8e88b43, tree 94129fb5) intomain.The branch is
main(a156a7d) plus eight reviewed member pull requests, each merged into the train branch:Nothing else is on the branch: every line it changes over
maincomes from one of these members.Merge method: one squash commit.
Before merge, this pull request carries:
main);🤖 Generated with Claude Code