Skip to content

Pine adapter: admission fill half, close-first entries, point order, exit tombstones and pyramiding records - #335

Merged
luisleo526 merged 1 commit into
mainfrom
px/admission-fill-n34
Oct 4, 2026
Merged

luisleo526 merged 1 commit into
mainfrom
px/admission-fill-n34

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

TradingView admits an order in two halves: rules 2 and 5 at the signal close,
then one price-scale check at the fill. This change turns the fill half on and
adds the TradingView behaviours that the fixtures under
tests/fixtures/admission_rules pin. Each rule has its own internal switch in
MarginRuleSwitches. All switches are on, and only tests change one.

  • unified_placement: the placement half, split out of fill_price_recheck. A
    reversal that rule 5 refuses stays placed, marked signal_price_refused. It
    drops at its fill, and the script's later close of the held id stays an
    ordinary close.
  • fill_price_recheck, now on: the whole order drops iff
    sig10(sig10(E_signal) / (Q m)) is under the slipped tick-built fill quote.
    The tie band is removed. Inside the unified scope, the explicit market
    long's money check on the unslipped next-bar quote is never reached.
  • close_first_admission: an entry the script placed on the same bar behind its
    own strategy.close() or strategy.close_all() of the position it
    opposes is checked by rule 2 only.
    • It fills flat with its frozen quantity.
    • The fact is recorded once, at the close or close_all call, and stamped on
      the entry at its entry() call.
  • point_fills_before_margin: at the open, the queued orders execute first,
    then the exits the open reaches, then the margin check on what is left. Two
    kinds of order fill before that check:
    • a protective strategy.exit stop or limit that the opening print reaches
      and whose entry holds units of the position; an exit armed for an entry
      that holds nothing fills nothing there. from_entry_units, the units an
      exit's entry holds, is shared with the process_orders_on_close bracket
      ranking in flush_pending_bracket_legs, whose inert exit also needs an
      entry with no working order; each site keeps its own test;
    • a close the script placed ahead of its opposite entry.
      Two shapes keep the earlier order:
    • A process_orders_on_close short's call sized at the previous close,
      while the open does not re-size it, is a queued order, so it executes
      before a stop the open gaps through (TradingView's tape of
      axealgo-tp-sl-toolkit-axealgo on OANDA:XAUUSD: the call of 1, then the
      stop's 1.62). A call the open re-sizes is the open's own check, after the
      exits; no tape decides that shape yet.
    • A partial exit fills first only when what it leaves is margined; a
      remainder still short keeps the call at the open first. No tape decides
      that case yet.
      test_point_order_open_call pins both shapes, each with a control.
  • exit_child_tombstones: a partial exit child that filled is never revived for
    the entry incarnation it filled under.
  • pyramiding_ledger_records: under pyramiding above one, the cap counts the
    open close-ledger records, one per entry fill not yet booked, not the
    physical lots. An exit armed for one opening books that opening first.

Every rule runs only on a power-of-ten lot grid, which every tape and every
population member uses. The unified admission also leaves out
calc_on_order_fills, the bar magnifier, stops that reverse, default-sized
stops, a resting book and same-open pairs; those keep the earlier rules. New
durable state is folded into the source-adapter hash only while it is set.

Three rules are left out, because nothing tells them apart from the current
behaviour. Decision counters ran over every ctest fixture and 198 replayed
population scripts and found no divergence:

  • the commission-0 POOC unit: 23,510 calls;
  • the whole-book add at the signal close: 413 calls;
  • the lagged follow-up on whole-share grids: 1 call.
    docs/pine-adapter-kernel-notes.md section 1.8 names the TradingView control
    each one needs.

Fixtures:

  • tests/fixtures/admission_rules: 73 TradingView tapes in four groups,
    gap_admission, point_order_and_book, stop_priority and explicit_short.
    • The engine reproduces all 73, and 56 of the 59 NYSE:F tapes book the same
      trades as a backtest and as a stream; the other three cross a holiday
      that a stream takes as an in-session gap.
    • Each of the six rules above loses tapes when turned off alone.
  • test_qty_step_lot_grid_case, the hosted lot-grid case, still books every
    recorded row exactly, with and without the 1e-05 grid.
  • The explicit-short twin control in test_taro_price_gap_admission_l4d is
    re-pinned on TradingView's own tape of it (explicit_short/offset0-fill).
    TradingView fills that order, so its literal check moves to the -.00032
    offset, where the order is declined.
  • The margin_call_rules, margin_ledger_rules and forward-replay lists drop the
    entries the fill half now reproduces.
  • test_integer_flat_budget_tie_l4d asserts the one row it moves. On a 0.01
    lot grid, rule 2 drops a default long from flat one ulp under the cost, as
    TradingView's margin_ledger_rules tape eth-flat-m100-ulp-under does.

The witness tables move on hash fields only. Every closed trade of every
run-pass is identical, field for field, to the parent commit's.

The margin-rules notes said the unified admission ships off; it now ships
on, so these sentences of docs/pine-adapter-kernel-notes.md are replaced:

  • "Two narrowings keep the scraped population's orders on the earlier rules"
  • "Outside that scope the engine's earlier admission rules run unchanged."
  • "The tree ships this unified admission off"
  • "gates it whole, its fill half and the placement half's reach"
  • "With it on, the scraped population lost orders"
  • "keeps the earlier scopes: an explicit quantity from flat"
  • "With the shipped switches the engine reproduces 170"
  • "The tests list 3 single-position and 104 ledger tapes"
  • "The fill re-check, and with it the unified admission"
  • "On the scraped population it dropped reversals and openings"
  • "The tapes pin the check only at a one-tick"

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

Measurement

Full population against the active baseline: 7,989 probes, all measured, 6 up, 0 down, all strong → excellent:

  • the unified placement rule: an NYSE:F 1D probe;
  • exit tombstones: an NYSE:F 15m probe;
  • the pyramiding count over open records: a grid bot on ETH 15m (hard lane), a grid bot on ETHUSDT.P 1D, and one script on both XAUUSD 15m and NSE:NIFTY 15m.

Disclosure: the NSE:NIFTY 15m rise rests on the trade count alone. Its exact TradingView rows are unchanged (668 → 668), and its unmatched pairs go from 1 to 2: a same-bar reversal and an opposite add are filled in the other order. That ordering is filed as a pin item; no tape decides it today.

At trade level, against the base: 184 probes match TradingView better, 1 is mixed (+6 / −1 exact rows), 1 is the NIFTY case above, and 0 are worse. In all, 2,547 exact rows are gained and 1 is lost. The witness tables move no trade. CI profiles are posted as pineforge/verify; the sweep is posted as pineforge/parity.

🤖 Generated with Claude Code

…r, exit tombstones, pyramiding records

TradingView admits an order in two halves: rules 2 and 5 at the signal close,
then one price-scale check at the fill. This change turns the fill half on and
adds the TradingView behaviours that the fixtures under
tests/fixtures/admission_rules pin. Each rule has its own internal switch in
MarginRuleSwitches. All switches are on, and only tests change one.

- unified_placement: the placement half, split out of fill_price_recheck. A
  reversal that rule 5 refuses stays placed, marked signal_price_refused. It
  drops at its fill, and the script's later close of the held id stays an
  ordinary close.
- fill_price_recheck, now on: the whole order drops iff
  sig10(sig10(E_signal) / (Q m)) is under the slipped tick-built fill quote.
  The tie band is removed. Inside the unified scope, the explicit market
  long's money check on the unslipped next-bar quote is never reached.
- close_first_admission: an entry the script placed on the same bar behind its
  own strategy.close(<held id>) or strategy.close_all() of the position it
  opposes is checked by rule 2 only.
  - It fills flat with its frozen quantity.
  - The fact is recorded once, at the close or close_all call, and stamped on
    the entry at its entry() call.
- point_fills_before_margin: at the open, the queued orders execute first,
  then the exits the open reaches, then the margin check on what is left. Two
  kinds of order fill before that check:
  - a protective strategy.exit stop or limit that the opening print reaches
    and whose entry holds units of the position; an exit armed for an entry
    that holds nothing fills nothing there. from_entry_units, the units an
    exit's entry holds, is shared with the process_orders_on_close bracket
    ranking in flush_pending_bracket_legs, whose inert exit also needs an
    entry with no working order; each site keeps its own test;
  - a close the script placed ahead of its opposite entry.
  Two shapes keep the earlier order:
  - A process_orders_on_close short's call sized at the previous close,
    while the open does not re-size it, is a queued order, so it executes
    before a stop the open gaps through (TradingView's tape of
    axealgo-tp-sl-toolkit-axealgo on OANDA:XAUUSD: the call of 1, then the
    stop's 1.62). A call the open re-sizes is the open's own check, after the
    exits; no tape decides that shape yet.
  - A partial exit fills first only when what it leaves is margined; a
    remainder still short keeps the call at the open first. No tape decides
    that case yet.
  test_point_order_open_call pins both shapes, each with a control.
- exit_child_tombstones: a partial exit child that filled is never revived for
  the entry incarnation it filled under.
- pyramiding_ledger_records: under pyramiding above one, the cap counts the
  open close-ledger records, one per entry fill not yet booked, not the
  physical lots. An exit armed for one opening books that opening first.

Every rule runs only on a power-of-ten lot grid, which every tape and every
population member uses. The unified admission also leaves out
calc_on_order_fills, the bar magnifier, stops that reverse, default-sized
stops, a resting book and same-open pairs; those keep the earlier rules. New
durable state is folded into the source-adapter hash only while it is set.

Three rules are left out, because nothing tells them apart from the current
behaviour. Decision counters ran over every ctest fixture and 198 replayed
population scripts and found no divergence:
- the commission-0 POOC unit: 23,510 calls;
- the whole-book add at the signal close: 413 calls;
- the lagged follow-up on whole-share grids: 1 call.
docs/pine-adapter-kernel-notes.md section 1.8 names the TradingView control
each one needs.

Fixtures:
- tests/fixtures/admission_rules: 73 TradingView tapes in four groups,
  gap_admission, point_order_and_book, stop_priority and explicit_short.
  - The engine reproduces all 73, and 56 of the 59 NYSE:F tapes book the same
    trades as a backtest and as a stream; the other three cross a holiday
    that a stream takes as an in-session gap.
  - Each of the six rules above loses tapes when turned off alone.
- test_qty_step_lot_grid_case, the hosted lot-grid case, still books every
  recorded row exactly, with and without the 1e-05 grid.
- The explicit-short twin control in test_taro_price_gap_admission_l4d is
  re-pinned on TradingView's own tape of it (explicit_short/offset0-fill).
  TradingView fills that order, so its literal check moves to the -.00032
  offset, where the order is declined.
- The margin_call_rules, margin_ledger_rules and forward-replay lists drop the
  entries the fill half now reproduces.
- test_integer_flat_budget_tie_l4d asserts the one row it moves. On a 0.01
  lot grid, rule 2 drops a default long from flat one ulp under the cost, as
  TradingView's margin_ledger_rules tape eth-flat-m100-ulp-under does.

The witness tables move on hash fields only. Every closed trade of every
run-pass is identical, field for field, to the parent commit's.

The margin-rules notes said the unified admission ships off; it now ships
on, so these sentences of docs/pine-adapter-kernel-notes.md are replaced:
- "Two narrowings keep the scraped population's orders on the earlier rules"
- "Outside that scope the engine's earlier admission rules run unchanged."
- "The tree ships this unified admission off"
- "gates it whole, its fill half and the placement half's reach"
- "With it on, the scraped population lost orders"
- "keeps the earlier scopes: an explicit quantity from flat"
- "With the shipped switches the engine reproduces 170"
- "The tests list 3 single-position and 104 ledger tapes"
- "The fill re-check, and with it the unified admission"
- "On the scraped population it dropped reversals and openings"
- "The tapes pin the check only at a one-tick"

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@luisleo526
luisleo526 force-pushed the px/admission-fill-n34 branch from ed36a01 to 075469d Compare October 4, 2026 15:41
@luisleo526
luisleo526 marked this pull request as ready for review October 4, 2026 16:51
@luisleo526
luisleo526 merged commit 6b77f06 into main Oct 4, 2026
17 checks passed
@luisleo526
luisleo526 deleted the px/admission-fill-n34 branch October 4, 2026 21:14
luisleo526 added a commit that referenced this pull request Oct 4, 2026
On a gathered chart (a script timeframe above the input timeframe),
pin K5 keeps every entry row of the run, so the sweep at each bar open
(erase_retired_rows) walked a table that grows with the run,
re-finding each row and binary-searching the askable origins before
reading the row's own pin: the per-bar cost rose with every entry
placed. The sweep now reads the rows straight off the table's storage,
in the same incarnation order (PlacementTable::visit_rows), and tests
a row's own pin before the searches. It keeps and erases exactly the
rows it did.

Alongside, each value-identical: decimal_grid_exponent forms its
nineteen powers once, by the same expressions; gain_loss_regime and
slipped_long_margin_scope read the configuration before the run;
on_bar_open takes the point-order scan only under the point order; the
narrow-scope margin and admission helpers stay out of line (two) or
out of line and cold (six), and thirteen of their scope tests are
hinted rare.

The recovery is for gathered charts. With the script timeframe equal to
the input timeframe the table stays small, the sweep is cheap anyway,
and the cost the margin, sizing and admission rules added since
14b05c9 remains (native example batch median +5.7 %); the next
commit takes it.

No decision, order of operations, hashed field or floating-point value
moves: against the admission change (#335) the witness harvests (every
pinned state hash), a per-trade dump of all 21 Trade fields (%.17g,
every run pass), the no-hash digests and the tape suites are
byte-identical, and release ctest passes with the receipt rows. Doc
citation digits re-anchored.

Timing, measured on the admission change (#335) before its final rebase
(same library):
Xeon 8375C, CPU 2, 61 rotating blocks x 3 independent builds per tree
x 5 runs, paired block bootstrap; every 95% interval within 0.21
points, * = it covers 0.

  percent vs                native  ta-sma  bracket    udt    vcp
  batch median, gathered (1 m input, 3 m script)
    14b05c9                +0.05*  -0.05*   -1.95   -0.38  -0.29
    #335 (parent)           -4.31   -2.56    -2.98   -3.63  -2.07
  batch median, ungathered (1 m input, 1 m script)
    14b05c9                +5.70   -0.33    +0.07*  +4.19  +2.09
    #335 (parent)           -1.06   -3.01    -1.24   -1.00  -2.25
  stream p95, gathered
    14b05c9                +0.89   -0.18    -0.90   +2.77  +3.41

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 4, 2026
…on; no sort or copy for a lone command

The margin and admission scopes are asked several times a bar, and on a
run outside them -- no power-of-ten lot step, a commission, pyramiding
above one -- the configuration alone answers. Those conjuncts are now
formed when the configuration is set (set_configuration and
set_staged_configuration, the only writers of config_ and staged_), so
such a bar answers each scope with one read instead of a call; inside a
scope its own tests run as before, and the rule switches are still read
at every ask. The unified admission at resolve_terms moves out of line
unchanged, and the realized-money fold returns at once when nothing was
booked since the last one.

Alongside, on the same per-bar path: the same-bar command flush no longer
stable-sorts a one-command queue (std::stable_sort still took a
temporary buffer and moved the command, its whole placement snapshot
included, through it and back) and keeps the queue's storage for the
next bar; cancel_bracket_siblings and apply_fx_opening_margin_slice
decide before copying the filled row; close_all records the close-first
fact from the point and position it has already read; on_bar_open forms
the opening print only under the point order; the retired-row sweep's
visitors are inlined.

No decision, order of operations, hashed field or floating-point
value moves. Against the previous commit: the whole-suite dump
(every closed and range-end trade with all 21 Trade fields at %.17g,
every recorded per-bar, broker and stream state hash) is
byte-identical on 659 of 663 process files (4 of them matched by
content: their name hashes a temp-path argument), and the other 4
differ by run, not by tree (a timing-calibrated row, a stack-address
row, two concurrent writers identical when run alone, twice in each
tree); the 30 witness harvests (no re-pin) and 176 tape and witness
executables are byte-identical; release ci_verify 859/859 with the
receipt rows; corpus 312/312, moved 0. The seven new members are
functions of the folded configuration and are waived as such. Doc
citation digits re-anchored.

Timing (Xeon 8375C, CPU 2; 4 independent builds per tree resampled as a
random effect, blocks paired; percent against 14b05c9, 95% CI; largest
build-to-build A/A 0.11 % / 0.27 % on the whole-batch median):

                        whole-batch median  stream mean per call  stream p95
script timeframe = input timeframe (81 blocks)
  native example        -1.5 [-1.5,-1.4]    -2.8 [-2.8,-2.7]      -2.1 [-2.2,-2.1]
  ta-sma-dual-cross     -1.9 [-2.0,-1.9]    -0.5 [-0.5,-0.4]      +0.4 [+0.4,+0.5]
  bracket-aurora        +0.2 [+0.1,+0.2]    -0.7 [-0.8,-0.7]      +1.0 [+1.0,+1.1]
  udt-regime-stack      +0.4 [+0.4,+0.5]    -0.8 [-0.9,-0.8]      +0.4 [+0.3,+0.5]
  composite-vcp         +2.6 [+2.5,+2.6]    +1.6 [+1.5,+1.6]      +2.2 [+2.1,+2.3]
1-minute input under a 3-minute script (41 blocks)
  native example        -5.2 [-5.3,-5.0]    -4.4 [-4.5,-4.3]      -5.0 [-5.1,-4.9]
  ta-sma-dual-cross     -2.2 [-2.3,-2.1]    -1.2 [-1.3,-1.1]      +0.2 [+0.1,+0.5]
  bracket-aurora        -3.6 [-3.7,-3.5]    -3.3 [-3.4,-3.2]      -5.8 [-5.9,-5.7]
  udt-regime-stack      -2.6 [-2.8,-2.5]    -2.3 [-2.4,-2.2]      -0.4 [-0.7,-0.1]
  composite-vcp †       -0.4 [-0.5,-0.2]    +0.4 [+0.3,+0.4]      +2.0 [+2.0,+2.2]

† Not a property of this commit: this row moves with the size of the
process environment. setenv("TZ") (src/timezone.cpp) costs one heap
trim and re-grow per run, about 85 us over 5,003 bars, and the row
reads -0.3 to -0.6 with some environment sizes and +1.5 (+1.9 against
the previous commit) with others. Whole-batch differences under
0.5 % read as at par.

In the same runs the previous commit stood at +5.6, -0.3, +0.1, +4.2,
+2.0 (script timeframe = input timeframe) and -0.2, -0.1, -2.0, -0.4,
-0.1 (3-minute script) on the whole-batch median, and the admission
change (#335) at +6.7, +2.9, +1.4, +5.2, +4.4 and +4.5, +2.6, +1.1,
+3.4, +2.0. composite-vcp's remaining gap is the session clock in
src/session_time.cpp (time() with a session argument every bar), which
this commit does not touch.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 4, 2026
…ssion rules (#336)

* Pine adapter: the retired-row sweep reads the placement rows in place

On a gathered chart (a script timeframe above the input timeframe),
pin K5 keeps every entry row of the run, so the sweep at each bar open
(erase_retired_rows) walked a table that grows with the run,
re-finding each row and binary-searching the askable origins before
reading the row's own pin: the per-bar cost rose with every entry
placed. The sweep now reads the rows straight off the table's storage,
in the same incarnation order (PlacementTable::visit_rows), and tests
a row's own pin before the searches. It keeps and erases exactly the
rows it did.

Alongside, each value-identical: decimal_grid_exponent forms its
nineteen powers once, by the same expressions; gain_loss_regime and
slipped_long_margin_scope read the configuration before the run;
on_bar_open takes the point-order scan only under the point order; the
narrow-scope margin and admission helpers stay out of line (two) or
out of line and cold (six), and thirteen of their scope tests are
hinted rare.

The recovery is for gathered charts. With the script timeframe equal to
the input timeframe the table stays small, the sweep is cheap anyway,
and the cost the margin, sizing and admission rules added since
14b05c9 remains (native example batch median +5.7 %); the next
commit takes it.

No decision, order of operations, hashed field or floating-point value
moves: against the admission change (#335) the witness harvests (every
pinned state hash), a per-trade dump of all 21 Trade fields (%.17g,
every run pass), the no-hash digests and the tape suites are
byte-identical, and release ctest passes with the receipt rows. Doc
citation digits re-anchored.

Timing, measured on the admission change (#335) before its final rebase
(same library):
Xeon 8375C, CPU 2, 61 rotating blocks x 3 independent builds per tree
x 5 runs, paired block bootstrap; every 95% interval within 0.21
points, * = it covers 0.

  percent vs                native  ta-sma  bracket    udt    vcp
  batch median, gathered (1 m input, 3 m script)
    14b05c9                +0.05*  -0.05*   -1.95   -0.38  -0.29
    #335 (parent)           -4.31   -2.56    -2.98   -3.63  -2.07
  batch median, ungathered (1 m input, 1 m script)
    14b05c9                +5.70   -0.33    +0.07*  +4.19  +2.09
    #335 (parent)           -1.06   -3.01    -1.24   -1.00  -2.25
  stream p95, gathered
    14b05c9                +0.89   -0.18    -0.90   +2.77  +3.41

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

* Pine adapter: margin and admission scopes answer from the configuration; no sort or copy for a lone command

The margin and admission scopes are asked several times a bar, and on a
run outside them -- no power-of-ten lot step, a commission, pyramiding
above one -- the configuration alone answers. Those conjuncts are now
formed when the configuration is set (set_configuration and
set_staged_configuration, the only writers of config_ and staged_), so
such a bar answers each scope with one read instead of a call; inside a
scope its own tests run as before, and the rule switches are still read
at every ask. The unified admission at resolve_terms moves out of line
unchanged, and the realized-money fold returns at once when nothing was
booked since the last one.

Alongside, on the same per-bar path: the same-bar command flush no longer
stable-sorts a one-command queue (std::stable_sort still took a
temporary buffer and moved the command, its whole placement snapshot
included, through it and back) and keeps the queue's storage for the
next bar; cancel_bracket_siblings and apply_fx_opening_margin_slice
decide before copying the filled row; close_all records the close-first
fact from the point and position it has already read; on_bar_open forms
the opening print only under the point order; the retired-row sweep's
visitors are inlined.

No decision, order of operations, hashed field or floating-point
value moves. Against the previous commit: the whole-suite dump
(every closed and range-end trade with all 21 Trade fields at %.17g,
every recorded per-bar, broker and stream state hash) is
byte-identical on 659 of 663 process files (4 of them matched by
content: their name hashes a temp-path argument), and the other 4
differ by run, not by tree (a timing-calibrated row, a stack-address
row, two concurrent writers identical when run alone, twice in each
tree); the 30 witness harvests (no re-pin) and 176 tape and witness
executables are byte-identical; release ci_verify 859/859 with the
receipt rows; corpus 312/312, moved 0. The seven new members are
functions of the folded configuration and are waived as such. Doc
citation digits re-anchored.

Timing (Xeon 8375C, CPU 2; 4 independent builds per tree resampled as a
random effect, blocks paired; percent against 14b05c9, 95% CI; largest
build-to-build A/A 0.11 % / 0.27 % on the whole-batch median):

                        whole-batch median  stream mean per call  stream p95
script timeframe = input timeframe (81 blocks)
  native example        -1.5 [-1.5,-1.4]    -2.8 [-2.8,-2.7]      -2.1 [-2.2,-2.1]
  ta-sma-dual-cross     -1.9 [-2.0,-1.9]    -0.5 [-0.5,-0.4]      +0.4 [+0.4,+0.5]
  bracket-aurora        +0.2 [+0.1,+0.2]    -0.7 [-0.8,-0.7]      +1.0 [+1.0,+1.1]
  udt-regime-stack      +0.4 [+0.4,+0.5]    -0.8 [-0.9,-0.8]      +0.4 [+0.3,+0.5]
  composite-vcp         +2.6 [+2.5,+2.6]    +1.6 [+1.5,+1.6]      +2.2 [+2.1,+2.3]
1-minute input under a 3-minute script (41 blocks)
  native example        -5.2 [-5.3,-5.0]    -4.4 [-4.5,-4.3]      -5.0 [-5.1,-4.9]
  ta-sma-dual-cross     -2.2 [-2.3,-2.1]    -1.2 [-1.3,-1.1]      +0.2 [+0.1,+0.5]
  bracket-aurora        -3.6 [-3.7,-3.5]    -3.3 [-3.4,-3.2]      -5.8 [-5.9,-5.7]
  udt-regime-stack      -2.6 [-2.8,-2.5]    -2.3 [-2.4,-2.2]      -0.4 [-0.7,-0.1]
  composite-vcp †       -0.4 [-0.5,-0.2]    +0.4 [+0.3,+0.4]      +2.0 [+2.0,+2.2]

† Not a property of this commit: this row moves with the size of the
process environment. setenv("TZ") (src/timezone.cpp) costs one heap
trim and re-grow per run, about 85 us over 5,003 bars, and the row
reads -0.3 to -0.6 with some environment sizes and +1.5 (+1.9 against
the previous commit) with others. Whole-batch differences under
0.5 % read as at par.

In the same runs the previous commit stood at +5.6, -0.3, +0.1, +4.2,
+2.0 (script timeframe = input timeframe) and -0.2, -0.1, -2.0, -0.4,
-0.1 (3-minute script) on the whole-batch median, and the admission
change (#335) at +6.7, +2.9, +1.4, +5.2, +4.4 and +4.5, +2.6, +1.1,
+3.4, +2.0. composite-vcp's remaining gap is the session clock in
src/session_time.cpp (time() with a session argument every bar), which
this commit does not touch.

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

* Tests: run the lookup-index and live-state scaling rows serially in Release

Under a parallel ctest the lookup-index scaling row once read 6.15
against its 5.0 bound, and 4.08 when run alone; the live-state scaling
row failed the same way under load. RUN_SERIAL keeps other rows off the
box while these two time their legs, in Release, where their ratios
gate. A whole Release suite at -j 28 read 3.99-4.01 with it and
3.82-4.83 without, for about a minute more wall time. No source or
behaviour change.

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 5, 2026
* docs: release notes and version scoping for v1.2.0

CHANGELOG: the Unreleased section becomes 1.2.0 (2026-10-05), a minor
release that adds the compiled execution-capabilities extension to the C
ABI (PF_CAPABILITIES_API_VERSION, strategy_capabilities_api_version,
strategy_capabilities_receipt). One bullet per change since v1.1.0 with
its PR (#328, #330, #331, #332, #333, #334, #335, #336, #337, #338 and the
session-clock change, written #VCP until its PR number exists), the
recipe additions under State hashes (#328, #330, #335; domain tags and
epoch unchanged), Report keys (docker/run_json.py is byte-identical to
v1.1.0's, so no key changes) and Migration.

Version scoping: README, install and public-contract pages name v1.2.0
and codegen 1.2.0; "since the next release" and "fixed on main" in the
capabilities guide and the runner guide become 1.2.0 and 1.1.0 (#325).
Lines that state what an earlier release shipped stay.

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

* docs: 1.2.0's grades from the facts tokens, #339, and codegen's license

- CHANGELOG: the session-clock change is #339 (merged as 52292db), in place
  of the #VCP token of 3082fbd; the "What a script author sees" bullet of
  3082fbd now states release 1.2.0's grades (registry baseline
  pineforge-parity-baseline-20261005-engine-52292db9: 7,970 excellent / 19
  strong of 7,989, none below strong) instead of the main scoreboard at
  6b77f06.
- README: the release sentence names 1.2.0 and renders releases[1.2.0], and
  the main scoreboard renders the same baseline, from pineforge-release
  facts/facts.json at 0c2f6838 (the facts export for the 1.2.0 release).
- README, LEGAL.md, docs/pages/index.md: pineforge-codegen is under the
  PineForge Source License 1.1 from its release 1.2.0; releases up to 1.1.0
  keep the PolyForm Noncommercial terms they shipped with.

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

---------

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