Skip to content

History of arrays and matrices; int into a float field - #157

Merged
luisleo526 merged 18 commits into
mainfrom
cg/array-history
Oct 1, 2026
Merged

luisleo526 merged 18 commits into
mainfrom
cg/array-history

Conversation

@luisleo526

Copy link
Copy Markdown
Contributor

Array and matrix history; an int given to a float field

Codegen emitted C++ that did not compile for the history of an array or a
matrix ((a[1]).size(), array.size(a[1]), (m[1]).get(0, 0)), and for an
int given to a float field of a user-defined type (Cell.new(v = bar_index)).
This branch lowers the first the way TradingView reads it, refuses the
spellings TradingView refuses, and keeps every form that compiled before.

Based on main after the object-history change (#156) merged.

What TradingView reads

Synthetic probes, compiled and run on TradingView, BINANCE:ETHUSDT.P 15,
2025-04-01 to 2025-04-08; ten tapes and their probes are in
tests/fixtures/array_history_tv (README: sha256 of every probe and tape).

  • a[k] of an array or a matrix is a read-only copy of the collection as the
    variable left it at the end of its scope's execution k executions back:
    the bar k bars back for a top-level variable, its block's previous run for
    a block's local. A var array's history is one element shorter than the
    array it grows; a var matrix's holds the previous bar's value.
  • A change to the copy, to a slice of it, or through a variable or parameter
    bound to it stops the run (RE10051); a method on it before the variable
    has a history stops the run (RE10052 for an array, RE10053 for a matrix).
  • for v in a[1] iterates the array the variable holds now; a[0] is the
    array itself.
  • Two sibling blocks that declare the same name keep a history each.
  • Refused at compile time: a method straight after the history
    (a[1].size(): CE10011); the history of an object's array, matrix or map
    field (h.xs[1], (h.xs)[1]: CE10290); an array where a number, a
    condition, a string or an element is expected (CE10123: operators, nz,
    math.*, value slots of array functions such as c.push(a[1]),
    array.new<float>(2, a[1]), log.info's message, label.new's text,
    str.tostring of colors; CE10173: a scalar variable or field; CE10101: an
    if or while condition; CE10122: array.from, str.format of colors;
    CE10009: a bare statement at the top level).

What changes

  • An array or matrix variable keeps its own member; _PFCollectionHistory
    beside it keeps the copies of one declaration. Each execution of the
    declaration opens a slot and the bar's end closes it with a copy; a
    sibling block's declaration of the same name first closes the other
    block's history. The members' names (_pf_collection_hist_<name>) are the
    emitter's: a script variable spelled so is escaped.
  • CollectionHistoryChecker gives every read one outcome:
    • supported, for a top-level variable or a block's: a built-in reads or
      changes it, na(), a for...in loop, a variable or a function argument
      that only reads it. A matrix function's new matrix
      (matrix.copy(mi[1])) has the variable's element type;
    • refused, with TradingView's code, for what TradingView refuses;
    • otherwise the lowering it had before (an element of the current array,
      or a parameter's current array, with a warning), wherever that compiled,
      and refused by name where it did not, but for the two gaps under "Not in
      this branch". Which uses compiled before was measured, not assumed:
      every use of an array or matrix history and every array function, in
      every scope and for every element type, was transpiled and compiled
      with the previous build, and TradingView's compiler checked each use.
      Whether the earlier lowering compiled often turns on how an array
      function's value is consumed (a method on the new array, a function
      returning it, a variable holding it), so the verdict follows the
      consumer.
    • A read in a body the codegen emits is decided like any other read. The
      codegen emits every method and every function that some call names,
      including a call inside a function nothing calls. A function that no
      call names is never emitted, so its reads keep the earlier lowering.
  • Cell.new(v = bar_index) converts the int to a double, and an int na to
    na; an expression of int literals keeps its spelling. c.v := iv converts
    the same way: it used to compile but stored an int na as -2147483648,
    where TradingView's field is na (uassign_float: 112 of 336 exits
    differed). A bool converts to 1 or 0 and is never na. TradingView refuses
    a bool there: CE10123 in a constructor, CE10173 in an assignment.

Verification

  • Full pytest with the paired engine (headers, Eigen, generated include,
    built runtime, corpus): 4,977 passed, 33 skipped, 0 failed. The skips are
    pre-lane reference commits absent from the test checkout and empty
    parameter sets, as before.
  • Corpus compile sweep: 314 passed. Gate fixtures: parity OK over 277.
  • Tapes replayed exit for exit: ahist_ref, ahist_mtx, ahist_field,
    ahist_loop, ahist_more, ahist_sibling, uctor_float,
    uassign_float. The runtime stops with RE10051 / RE10052 / RE10053 where
    TradingView stops.
  • Before this branch, none of the history probes compiled. Under the
    branch's first version (one shared history per name), ahist_sibling
    differed on 336 of 336 exits.
  • 1,384 real-world strategy sources transpile to the same C++ as before,
    byte for byte, except two whose .clear() lines change order between
    runs of the same build; in fresh processes they are identical.
  • The probe battery has 7,177 synthetic probes: 6,511 cover every array or
    matrix history use and every array function, in every scope and for
    every element type, and 666 were written by two independent reviews. Each
    probe was transpiled and compiled with this branch and with a7c6473:
    • No probe that compiled before fails to compile now.
    • No probe that compiled before is refused unless TradingView rejects it.
      240 are refused now, and TradingView's compiler rejected each of their
      uses when probed (CE10123, CE10122, CE10173, CE10101). The uses are:
      • an array as an operator's operand (60);
      • an array as the value of a push or an includes (52);
      • an array as a condition (3), as a float variable (2), or as an
        argument of nz or math.abs (2);
      • str.tostring or str.format of an array of colors (121).
    • 2,907 compile and 4,208 are refused by name. Of these, 762 did not
      compile before and compile now.
    • 61 do not compile. All come from the reviews, and none compiled before:
      • 36 also fail without the history read (matrix.sum, na arrays,
        arrays of epochs, an object array's searches, overloads by element
        type, and others);
      • 5 are the float-field gap below;
      • 20 are the two history gaps below.
    • One review probe crashes the transpiler on both builds:
      b.concat(id2 = a), which has no history read; the keyword argument is
      dropped.
    • The 20 battery probes that failed on both builds (a call in a function
      nothing calls, which types a live untyped helper) are now refused by
      name.

Not in this branch

  • The history of a function's parameter or local, of a call's result and of
    a selection is not kept (TradingView keeps one per call); such reads keep
    the lowering they had where it compiled, and are refused otherwise.
  • Two kinds of history read keep the C++ of the previous build, which does
    not compile:
    • An element function's value of a string array's history, read where the
      earlier lowering is kept (in a function, a method, a loop or a block
      var), for example f() => str.length(array.first(s[1])). That value
      is a character of the current array's string and reaches the C++ as a
      number. Most string consumers do not take it: the str.* functions
      other than str.tostring / str.format, ==, a typed parameter, a
      push, a label's text. A dedicated battery found 650 of 1,200 such
      probes failing; none of them compiled before.
    • The history of a variable or a call that the analyzer does not type as
      an array or a matrix: a method's or matrix.row's new array, a
      selection of arrays, a tuple's element, an array of drawings.
  • An int from matrix.rows() / columns() / elements_count() or
    strategy.wintrades given to a float field does not compile, as before:
    the codegen types those reads as doubles.
  • str.tostring of an array (any array, history or not) is not lowered.
  • PineForge holds no na array: a variable bound to a history before the
    variable has one holds an empty array where TradingView's is na (a method
    on it stops TradingView's run), and one the script also tests with na()
    is refused.
  • matrix.sum(m1, m2) and other matrix results used without a declared type
    do not compile, history or not.

🤖 Generated with Claude Code

luisleo526 and others added 18 commits October 2, 2026 00:17
Cell.new(v = bar_index) into a float field did not compile: the record is
built with a designated initializer, where C++ refuses to narrow a
non-constant int or int64_t into a double. TradingView holds the number,
an integer na as na (tests/fixtures/array_history_tv uctor_float, whose
tape replays 336 of 336). The value is now converted where the field is a
double; a double, an integer literal and a bare na keep their spelling.

The fixture directory also holds this lane's TradingView evidence for the
history of arrays and matrices.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(a[1]).size(), array.size(a[1]) and (m[1]).get(0, 0) did not compile:
a[1] lowered to the current array's element 1 and m[1] to a
Series<double>. TradingView reads a[k] as a read-only copy of the
collection as the variable left it at the end of the bar k bars back (its
block's previous run, for a block's local), not the array the variable
holds now: a var array's history is one element shorter than the array it
keeps growing (tests/fixtures/array_history_tv, eight tapes).

Such a variable keeps its own std::vector or matrix member, so every other
operation keeps its C++; _PFCollectionHistory beside it keeps the copies,
a slot opened at each execution of the declaration and closed with a copy
at the bar's end. The analyzer annotates every read with its use: a
built-in reads it; one that changes it stops the run with TradingView's
RE10051 text; na() asks whether a copy exists; a for...in loop iterates the
variable's current array, as TradingView's does; a variable bound to it
or a function given it holds a copy, refused where that name is changed. A
method on a na history stops the run (RE10052, RE10053). An object's array
or matrix field read through the object's history kept the lowering it
compiled to; its tape replays.

Refused by name, located, in the analyzer: what TradingView refuses (the
history of an object's array, matrix or map field, h.xs[1] and (h.xs)[1]:
CE10290; a method straight after the history, now cited CE10011; an array
where a number or a condition is expected: CE10123, CE10173, CE10101,
CE10122, CE10009), and what PineForge does not keep, none of which
compiled (function scope, a call's or a selection's history, request
payloads, a block's var, a loop's local). test_collection_scope_isolation
read slot[0] as an element of array.from, which TradingView refuses
(CE10122); it now reads slot.get(0) and pins the refusal.

The ahist_ref probe drops its array-or-na field, which PineForge cannot
hold (a na array never compiled), and its tape is re-exported.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…rrowing

The int-to-double conversion of a user-defined record's float field bound
its value to `_pf_v`, the name the int narrowing's lambda binds, and
test_e2e_security_epoch_int64's scan of narrowed epochs read
`auto _pf_v = (...); if constexpr (std::is_floating_point_v<...>)` as
one. It binds `_pf_w`.

GCC only warns at the narrowing the pre-lane build emitted, and compiles
it, reading an int na as -2147483648; test_the_pre_lane_build_did_not_
compile_it now compiles with -Werror=narrowing, under which Clang and GCC
both refuse the pre-lane C++ and accept this build's.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
d1920c6 refused, by name, every array or matrix history read it did not
lower, and some of them compiled before: str.tostring(a[1]) anywhere,
na(a[1]) in a function, a request payload, a loop or a block's var,
array.size(x[1]) of an array parameter, a variable bound to the history
that only na() or str.tostring() read, and anything in a function nothing
calls (the codegen emits none). TradingView accepts all of them.

CollectionHistoryChecker.decide now gives every read one of three
outcomes. Supported, as before, for a top-level variable or a block's.
Refused, with TradingView's code, for what TradingView refuses
(pine-facade, 2026-10-01): an array in a value slot of an array function
(c.push(a[1]), a.includes(a[1]), array.new<float>(2, a[1]),
matrix.new(..., a[1]): CE10123), nz() of a bound history, log.info's
message, label.new's text, str.tostring of colors (CE10123), str.format
of colors (CE10122), a scalar field (CE10173). Otherwise the lowering it
had -- an element of the current array, or a parameter's current array,
with a warning -- wherever that compiled, and refused by name where it did
not. Which uses compiled before was measured: 5,286 synthetic probes, every
use in every scope for every element type and offset, transpiled and
compiled with a7c6473 and with this build, each shape compiled on
TradingView. None that compiled before is refused or fails to compile now;
29 fail to compile on both builds for reasons history does not touch (a
call in a dead function typing a live untyped helper, matrix.sum chains).

The checker also:
- keeps a history per declaration: two sibling blocks declaring the same
  name shared one, closed at the bar's end with whatever the member held,
  so the first block read the second block's array (ahist_sibling, a new
  TradingView tape: 336 of 336 exits differed; now none do). A
  declaration first closes the other declarations' histories;
- refuses a change through a slice of the history (TradingView stops the
  run there, RE10051) and a binding read both as an array and through na(),
  which PineForge, holding no na array, cannot keep (the C++ did not
  compile);
- walks a name's uses in its own scope, once per name: a script variable
  bound to the history was checked against every same-named variable of
  the script, and a diamond of helpers passing it on was walked once per
  call path;
- keeps xs[k] := v (TradingView refuses it, CE10009/CE10013) as the
  element assignment it compiled to.

The checker is built when the visit first meets an array or matrix
history, so no other script pays for it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
`for i = 0 to 1` / `pb = a[1]` / `r += pb.size()` declared the loop's
C++ local `double pb` from the expression type inference, which read a
history subscript as a number: `std::vector<double>` did not convert and
`pb.size()` did not compile. A block's local is a member, typed where the
members are registered, so only C++ locals (a loop's body, a while body)
were wrong. `_infer_type` gives a supported history read its collection's
C++ type.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The uses of a name bound to an array's history were found by walking the
rest of the script for each binding, and a function's result by walking
the whole script for its calls: 4,000 bindings took 57 s to transpile.
The checker now indexes, when it is built, every statement's place in its
list, each list's declarations, every identifier by name and every call
by callee, and a name's reads are the indexed identifiers of its scope
(the rest of its list, a nested list or loop that redeclares the name
hiding it, and for the top level the functions and methods that do not
bind the name): 7 s, where the same script binding array.copy(a) takes
4 s. Every one of the 5,286 probes of the use matrix transpiles to the
same outcome, C++ and message as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
`Cell.new(1 + 2)` and `Cell.new(5 * 2)` initialized the float field with
the int expression, a constant C++ narrows, and compiled; 991ab7e wrapped
it in the run-time conversion. Such an expression (`_pure_int_literal_
value`) keeps its spelling when a double holds it exactly; one past 2**53
is still converted.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…function

The independent review of c805757 found reads the checker kept on their
earlier lowering that never compiled -- `array.sum(a[1])` in a function, a
loop or a block's var, and the same reached through a selection's arm, an
if's value, a function's result or a tuple's element -- and an earlier
lowering it refused although it compiled: `array.size(array.copy(a[1]))`.

A probe of every array function on an element of the current array, in a
function, a loop and a block's var, for every element type, and on a
parameter's current array, in a function and a method (1,225 probes, on
a7c6473 and this build), gives the tables: a number element took no array
function, but `array.copy`, whose vector of the element's size compiled
where a namespace call or a loop's local took it; a `std::string` element
took many (size, get, clear, pop, ...); a parameter's array took all but
the ones returning a new array, and a string parameter's element-typed reads
did not compile. `array.copy`'s verdict follows its direct consumer. A
tuple element of a function's result follows the name each tuple
declaration binds at its index.

Also:
- a later declaration's history member is `_pf_collection_hist_<n>_<name>`:
  `x`'s second declaration and a variable `x_1` both named theirs
  `_pf_collection_hist_x_1`, a duplicate member;
- a method or function of the same name for another type no longer speaks
  for the collection's: `(a[1]).sz()` beside `method sz(Cell this)` was
  refused with that method's "has no fields".

Over 6,511 probes no form that compiled on a7c6473 is refused or fails to
compile; 33 fail on both builds for reasons history does not touch.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
`c.v := iv`, iv an int that is na on some bars, compiled (a plain C++
assignment converts the int) but stored the int na sentinel,
-2147483648, where TradingView's field is na: a new TradingView tape,
uassign_float (BINANCE:ETHUSDT.P 15), reads `na` on every third bar's
close, and 112 of its 336 exits differed. A `:=` to a float field
converts an int as the constructor does (991ab7e), an int na to na; a
double, a literal and an int variable stored as a double keep their
spelling. None of the 1,384 real-world sources' C++ changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A second independent review found that whether the earlier lowering of
an array function on a history compiled turns on how its value is used,
where the tables keyed on the function alone:

- a parameter's `array.sum(array.abs(x[1]))`, `array.size(array.copy(
  x[1]))`, `str.length(array.get(x[1], 0))` on a string array and the
  like compiled before, and 752eff6 refused them;
- `f() => array.copy(a[1])` returned to its caller, a copy rendered or
  called a method on, a string element's `array.pop` or `array.get`
  returned by a function, and a string element's slice or `concat`
  argument did not compile before, and 752eff6 kept them;
- an overloaded method given the history no longer compiled (its number
  overload took the element before);
- `matrix.sum(m[1], m)` reached a result that never compiles.

The tags now carry the consumer: an array function's new array is
`:receiver` (a method on it), `:result` (a function returns it),
`:render` or `:member` (a variable of the top level or a block holds
it); a value is `:result` or `:bound`. Only the combinations the earlier
build failed on are refused: `array.copy` of a number element keeps its
earlier lowering for a namespace call's or a function's argument and a
local; a string parameter's element read refuses a variable or a
function's result taking it. An overloaded method given the history keeps
the earlier lowering; `matrix.sum` of a history is refused by name. The
reads of a name are indexed under each statement list holding them, so
3,000 sibling blocks binding one name take 2.5 s, not 7.2 s.

Over the use matrix (5,286 probes), the per-function batteries (1,225)
and both reviews' probes (666), on a7c6473 and this build: no form that
compiled before is refused (but 14 TradingView rejects, CE10123 / CE10173
/ CE10101), and every probe that does not compile fails on a7c6473 too.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…emits

The checker kept the earlier lowering for every read in a callable it
thought dead, on the premise that the codegen emits no function nothing
calls from the top level. It does emit them: every method, called or not,
and every function a call names, the call sitting in an uncalled function
included (the analyzer visits every body and registers each function it
sees called). An uncalled method's `(a[1]).size()` and `g() =>
(a[1]).size()` called only from an uncalled `f` kept the element lowering
and did not compile, on a7c6473 as here.

A function is dead now only when no call anywhere names it, the codegen's
own rule; methods never are. A read in such a body is decided as any other
(both shapes are refused by name). A read in a function no call names is
still kept, except where its call hands it to an emitted function's
untyped parameter, which then takes the earlier lowering's element: the
use matrix's 20 shapes that failed on both builds (`sizeOf(v) =>
v.size()` given `x[1]` from an uncalled function) are refused by name; a
string element passed on to `na(v)` or `str.tostring(v)` compiled there
and still does. Over all 718 dead-function probes no form that compiled
on a7c6473 is refused, and none fails to compile.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… block

The uses of a script variable bound to an array's history skipped every
read in a function or a method that declared the name anywhere: `pb =
a[1]` at the top level, then `f() => pb.push(1.0)` followed by a block
declaring its own `pb`, hid the push, so the binding kept the earlier
lowering and the C++ did not compile (as on a7c6473). A read in a callable
is now the script variable's unless a parameter or a declaration before it,
in its own statement list or an enclosing one of that body, binds the name
-- the block scoping `_declaration_of` already used -- and the push is
refused as TradingView stops there (RE10051). No other probe's outcome,
C++ or message changes (7,177 transpiled before and after).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…scaped

An array's history member, `_pf_collection_hist_<name>` (a later
declaration's `_pf_collection_hist_<n>_<name>`), was outside the
emitter's reserved spellings: a script variable `_pf_collection_hist_x`
beside an array `x` whose history the script reads became a second member
of that name, an internal AssertionError ("duplicate generated
script-state member") where a7c6473's C++ did not compile either. The
pattern joins `_CPP_TEMPORARY_PATTERN`, so `_safe_name` escapes the
script's spelling (`pf_safe__pf_collection_hist_x`) and the script
compiles.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The int-to-double conversion of a float field (`Cell.new(v = ...)`,
`c.v := ...`) tested is_na() on whatever integer it took, a bool too:
the paired engine's na.hpp leaves bool out of its integer is_na template,
so is_na(false) resolves to is_na(double) and a false stayed 0.0, but
any is_na of a bool that tests the integer sentinel would read a false
as na. A bool now converts straight to 1 or 0, as on a7c6473 (TradingView
refuses a bool there: CE10123 in a constructor, CE10173 in an
assignment). A trace over six bars pins `Cell.new(even)` and `d.v :=
even` at 1 and 0, never na. No real-world source's C++ uses the
conversion.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Review cosmetics, the trivial ones:
- HISTORICAL_CHANGE_MESSAGE, NA_ARRAY_MESSAGE and NA_MATRIX_MESSAGE were
  unused, their texts repeated in the C++ templates; the templates now
  take them (the emitted C++ is byte-identical);
- a refusal of an array function's result named it "array function's
  result"; it names the call (`array.slice(a[1]) is an array, which
  TradingView refuses for operator + (CE10123)`);
- a test keeps ARRAY_CHANGING_METHODS / MATRIX_CHANGING_METHODS equal to
  the codegen's COLLECTION_MUTATING_METHODS on each namespace.

The third copy of the matrix-method lowering (`_matrix_history_method_expr`
beside visit_call's two) stays: folding them is not a cosmetic change.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
`c = matrix.copy(m[1])`, `matrix.transpose(m[1])` and
`matrix.submatrix(m[1], ...)` of a matrix<int>, <string>, <bool> or
<color> declared `c` a matrix of floats: the receiver lookup that types a
matrix function's new matrix saw no variable behind the history read,
and the namespace form at the top level, in a block or in a loop did not
compile (the method form, a `var` and a matrix<float> did). The read is
now the variable's, whose copy has its type. A battery of the three
functions on five element types, two forms and six scopes compiles but
for a function's local (refused by name, as before); a7c6473 compiled
none of them (a matrix history was a Series<double> there). Found by the
full-battery compile at HEAD: three review probes now compile, no other
probe's C++ changes, and no real-world source's C++ does.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The full-battery compile at HEAD (7,177 probes) found two classes of
history read whose C++ does not compile, as on a7c6473: an element
function's value of a string array's history that the earlier lowering
reads (a character of the current array's string, held as a number,
which most string consumers do not take: str.length, ==, a typed
parameter, a push), and the history of a variable or a call the analyzer
does not type as an array or a matrix (a method's or matrix.row's new
array, a selection of arrays, a tuple's element, an array of drawings),
which the checker never sees. The array history row and the test
module's docstring name both instead of claiming that every read the
earlier lowering could not compile is refused, and the row notes that a
matrix function's new matrix takes the history's type.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@luisleo526
luisleo526 merged commit 67892cd into main Oct 1, 2026
9 checks passed
@luisleo526
luisleo526 deleted the cg/array-history branch October 1, 2026 16:57
luisleo526 added a commit that referenced this pull request Oct 2, 2026
* docs: changelog and version scoping for 1.0.1

1.0.1 pairs with engine v1.0.1, which changes only documentation since
v1.0.0. The changelog section covers #156 and #157, the changes since
1.0.0 that a user can observe:

- C++ that did not compile now compiles: the history of user-defined
  objects and drawings (#156) and of arrays and matrices (#157), and a
  non-constant int given to a float field (#157);
- one value that came out silently wrong: an int na assigned to a float
  field was stored as -2147483648 and is na now (#157);
- new compile-time refusals with TradingView's codes (CE10010, CE10011,
  CE10101, CE10122, CE10123, CE10173, CE10187, CE10290, CE10009), and the
  forms refused by name;
- the "not covered" limits of both pull requests, the migration step
  (regenerate C++ and relink) and the pairing (1.0.1 supports only engine
  v1.0.1). The Python and JSON contract and the report keys do not change.

The README, CONTRIBUTING, AGENTS.md / CLAUDE.md, docs/PUBLIC_CONTRACT.md
and docs/pine-cap-activation.md name 1.0.1 where they named 1.0.0 as the
current release or pair, as the README's release-lane note asks (the
release section, the baseline paragraph, the engine src/source link, the
@pf-trace note, the clone command and its output, the timing note, the
explicit-attachment section, a 1.0.1 row in the pairing table). Lines
that say what changed in 1.0.0 stay, and no line calls a version the
latest.

Checked on this tree's code (67892cd) against v1.0.0, CPython 3.14.6 on
an Apple M4 Max: the engine corpus's 325 sources and the 277 gate fixtures
transpile to byte-identical C++ (13 refusals, identical messages); the
largest transpilation takes 0.048 s (0.049 s on v1.0.0); the quick-start
SMA cross transpiles to the same C++. The tutorial run with that C++
against engine 6b45f510 (Linux arm64, GCC 13) prints the README's 9 trades,
+738.20, and 13 trades with the old sizing declared.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* docs: the 1.0.1 code was graded before it merged, with no tier change

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFVRQ4gcJCLbjfYqGtmy4k

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
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