Skip to content

Fix fill recalculation, declared quantity steps, and intraday request grids - #727

Merged
luisleo526 merged 27 commits into
mainfrom
fix-fill-recalc-qty-step-grid
Nov 3, 2026
Merged

luisleo526 merged 27 commits into
mainfrom
fix-fill-recalc-qty-step-grid

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Fixes #723
Fixes #708
Fixes #722
Fixes #720

Part of #716: the engine now floors order quantities to a declared quantity step (qty_step, or mincontract when no qty_step is declared), which covers items 1 and 2 for runs that declare it; runs that declare neither key are unchanged, and the issue stays open until the callers supply the step.

This change corrects entry handling during fill recalculation, uses an explicitly declared minimum contract as the quantity step, and aligns requested bars with the session grid.

Entry replacement and the pyramiding cap

With fill recalculation enabled and a flat book, a later same-id entry now replaces an earlier held priced entry. Previously the earlier held entry could be submitted afterwards and replace the later market entry. TradingView captures of the reproduction keep the later market entry with orders processed both at the next open and on close.

The engine call logs for two seeded random scenarios show the same priced-entry then market-entry shape on the two divergence bars, with identical calls before and after the fix. The logged position is the script's view; which order wins is shown by the trade comparison. There is no TradingView tape of those random scenarios. Their eight pinned runs move; the other runs retain their recorded values.

A settled opening also occupies its pyramiding slot while its applied notification is still queued. This prevents an explicit close followed by a reversing same-id entry from admitting a second lot past a cap of one. A 150-resting-limit test covers the large-book case. Its helper matches sell limits at the adapter's half-tick matching threshold; the order's own price is unchanged. A real-bars TradingView script of the same order shape refuses the repeated short lot. That capture is not a tape of the seeded transcript and is not a class-wide claim. The reported behavior is present in the released 1.9.1 engine.

Declared quantity step

When a symbol declares a minimum contract and no separate quantity step, the declared minimum contract supplies the step. The default path with neither declaration remains unchanged. The public test names the floor's one-millionth-of-a-step epsilon limit. Stop-limit chronology is outside this quantity-step change.

This reaches library callers that set mincontract alone and preserves explicit qty_step precedence. Nothing is inferred from the symbol name.

The default-metadata path and the other order-quantity cases in #716 remain open.

Requested-bar session grid

TradingView-checked: BINANCE:BTCUSDT 24x7 at 75m over 2025-04-01..04 (a bar opens at 00:00 UTC each day; the last bar of a day is 23:45-00:00). Session symbols, late-open anchoring, other time zones / DST and widths of a day or more are engine expectations, not TradingView-measured.

The reviewed source candidate matched twelve BTC TradingView rows at 205 joined and equal trades each, and both explicit-session equity rows at 40 joined and equal trades each. These are member evidence for those cases; the combined candidate also passed full verification.

The capped final time_close and DST characterization are engine expectations without a TradingView tape. An empty after-close bucket completes immediately and has no feed-level completion row. The default-session case remains open in the caller-metadata work. The open-label-only mutation survives by construction; the prefix-key mutation produces two completions and fails the existing one-completion assertion. The two default-session rows are deferred intact, with no skip or xfail introduced.

Native-live report compatibility

Native-live modules built with an earlier version are still accepted and use the standard report path (no live accumulator) until they are rebuilt.

Documentation sentences removed by this change

Stale references to intraday_grid_clock_ms are replaced with intraday_bucket, the requested-bar grid implementation. Source references are refreshed throughout, including the native example batch test registration.

Validation

All eight verification steps passed on Linux x86-64: preflight, Release, Debug, sanitizers, kernel, documentation, corpus parity and subset. The ABI layout probe passed in Release, Debug and sanitizers. On aarch64, the quantity-step tape/API tests passed three of three and the layout/report integration tests passed three of three, with zero skips. The full-population parity sweep completed; the required parity carry verdict follows publication.

luisleo526 and others added 27 commits November 3, 2026 21:24
…d in a flat fill-recalculation book

With calc_on_order_fills on and a flat book, a priced entry is held until the
end of the script evaluation. A later entry with the same id is accepted
first, and the held older one is then submitted after it and replaces it, so
the market entry is lost and a limit the feed never reaches stands in its
place. TradingView keeps the later market entry (two short trades, quantity 1
then quantity 2) for the equivalent script, with orders processed at the next
open and on close.

test_coof_reused_id_reentry runs both process_orders_on_close settings over a
constructed feed with expectations derived by hand in the header: the two rows
matched by TradingView captures, two hand-derived controls with the old id
still open, and three metamorphic controls (market call only, fill
recalculation off, different ids).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
submit_or_replace already removes an earlier same-id request from the queued
coof requests, bracket legs and delayed market orders when a later one is
accepted. The entries a flat calc_on_order_fills evaluation holds until its
end were not in that list, so the end-of-evaluation flush submitted the older
priced call after the newer one and the core replaced the newer instruction
with it.

Remove a held row of the same id when the accepted request is a later opening
and the row is an opening entry issued before it, with no paired reversal
parent and no retained parent topology (those keep their own submission rules).
The erase runs only after the core accepted the later request.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…imit, correct the capture wording

Header: say which controls are premise checks (market call only, fill
recalculation off: they pass with and without the cleanup by construction) and
which can fail (different ids, and the two rows with the old id still open).
Say that the guard keeping a held entry issued after the accepted one is
defensive and unexercised, with the reason: with fill recalculation on, an
entry the core accepts while an evaluation holds rows is a later call of that
evaluation, and the queues released ahead of the held rows hold no entry.

Rows with the old id still open: assert what is pending at bar 25, derived
from the engine's cap rule (nothing with next-open fills; with close fills the
priced add rests over the cap as the one pending limit at 191). No capture
shows TradingView's pending orders for these rows; the header says so.

Capture wording: with process_orders_on_close on, the capture lists the second
trade on bars 20 and 30, the bars whose closes it fills at.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The cleanup added for a held same-id entry ran for any accepted opening, which
includes strategy.order. Narrow it to an accepted entry replacing a held
earlier entry of the same id, the shape the change is for. An accepted
strategy.order call leaves a held entry alone, as before the cleanup existed.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…l open

The rows with the old id still open asserted what is pending at bar 25. That
value comes from the engine's own cap rule and no TradingView capture shows it,
so checking it only restates the engine. Keep printing the count and say in the
header that it is engine behaviour, not a TradingView claim. The trade, lot and
size checks of those rows stay, and the pending-zero check of the rows with the
old id closed stays.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…defect

test_adapter_quiet_bar pins values harvested from the base tree. Eight runs of
two seeded random scenarios (Random02 and Random20, each with magnifier off and
on and with recording off and on) move with the held-entry cleanup, because
both scenarios contain the shape the cleanup changes: with calc_on_order_fills
on and a flat book, one evaluation issues a priced entry and then a market
entry of the same id (Random02 at bar 24: a cancel, a stop entry at 105.50,
then a market entry; Random20 at bar 54: a short stop entry at 93.25, then a
market short). The base tree filled the held priced entry and lost the later
market call; TradingView keeps the later call for this shape. After the change
Random02 fills the market entry at the next open (103.5 instead of 105.5) and
Random20 fills it at the bar's close (94 instead of 93.25 one bar later).

The values come from the repository's own harvest (this test compiled with
-DPINEFORGE_QUIET_BAR_HARVEST, run once on this tree); the pinned file was
compared with the harvest row by row: only these eight rows differ, each with
one changed trade (Random20 also fewer source callbacks: 67 to 65 and 70 to 67),
and the other 268 runs of the 276 are byte-equal to the base tree. The rows were
replaced by a program from the harvest output, not edited by hand.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
TradingView floors an order quantity to the symbol's quantity step
(syminfo.mincontract). The engine floors only when the caller declares the key
qty_step and ignores a declared mincontract, so a full-equity order keeps its
unrounded quantity and, at one bar of the measured tape, no position opens at
all.

test_qty_step_mincontract_tapes runs the limit-only control of the #707
reporter (BINANCE:BTCUSDT 60, 2024-01-01 .. 2024-03-01, 29 trades, tape sha256
prefix e0085eab) against the tape's own quantities and exit times:

- Q1 declares mincontract = 0.00001 alone: expected to fail until the fix;
- Q2 declares qty_step = 0.00001 alone, Q3 and Q4 declare conflicting values in
  both orders: the explicit qty_step wins. These pass on the current main.

Every expected quantity is the tape's decimal text, compared exactly; the step
is a declared parameter, never inferred from the symbol or the tape. The tape
is a private fixture: registered in the guarded private-fixture form (a SKIP
placeholder when absent), listed in tests/private_fixture_rows.txt and in the
removed-path inventory, with the count pins and the line pin updated. The
public bars file is committed.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…eclared

set_syminfo_metadata now takes a finite mincontract > 0 as the quantity step
while the handle holds no qty_step key. An explicit qty_step (including zero or
an invalid value) wins in either setter order. The metadata is per handle, and
a handle that declares neither key is unchanged: nothing is inferred from the
symbol.

The patch is SM-CX's candidate (src/engine_consumer.cpp, 17 lines); the rows
of test_qty_step_mincontract_tapes decide it: Q1 turns green, Q2 to Q4 stay
green.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
test_syminfo_mincontract_qty_step covers the declared-step contract with
literals only: a mincontract alone sets the quantity step on a fresh handle,
an explicit qty_step wins in either setter order (including zero and invalid
values), an invalid mincontract never sets or clears a grid, a handle without a
key keeps the zero-grid quantity bits, the mincontract getter returns the
supplied value, and the metadata lives per handle.

test_qty_step_qna_rows runs the entry with quantity na and 100 percent of
equity sizing for the 59 signal rows whose next bar opens above the signal
close, against TradingView's own placed / declined decision and quantity for
each. Its rows are a private fixture read at run time (a SKIP placeholder when
absent, listed in tests/private_fixture_rows.txt and the removed-path
inventory, count and line pins updated); no tape value is embedded in a public
file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…'s limit

A declared qty_step, or a finite mincontract > 0 while no qty_step is
declared, sets the order quantity grid: stated at strategy_set_syminfo_metadata
(pineforge.h) and at the two engine.hpp declarations of the step. The public
unit test's comment now calls its rows the documented floor rule and names the
limit: the engine floor adds a +1e-6-step epsilon, and quantities near a step
boundary beyond the 29 trades and 59 rows of the private tests are not covered.
Comments only; no line count of engine.hpp changes.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…l recalculation

With calc_on_order_fills = true, an explicit strategy.close followed by a
reversing strategy.entry (pyramiding = 1) lets a repeated entry of the
same id add a second lot on the same tick: the first lot's fill is still
queued as an applied notification when the repeat is evaluated, so the slot
count does not see it.

test_coof_close_entry_pyramiding_slot builds a constructed feed (one long,
then a close and a reversing short, then a repeated short request of 3, then
close-all) and derives the expected result by hand in its header: two closed
trades, short quantity 2, at most one short lot, final position 0. Controls:
fill recalculation off, and no explicit close, keep their trade lists; an
input mutant with pyramiding = 2 must differ from the one-slot result.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ulation

accepted_entries_in_cycle skipped an entry's own id and never counted a
pending limit entry, so a synchronous fill whose applied notification was
still queued did not occupy a slot. With calc_on_order_fills = true, an
explicit close followed by a reversing entry then admitted a repeated entry
of the same id as a second lot (pyramiding = 1).

An opening placement that is already settled, meaning its handle is in its
cohort's opened list or the host reports an open lot whose origin is the
placement's incarnation, now occupies a slot even for the same id or a
limit order; an unfilled replacement has no physical origin and does not.
place_entry also no longer skips the cap for a priced entry under
process_orders_on_close while fill recalculation is active.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The two rows that reuse a closed id (explicit close, then the same id entered
twice on one bar) fail identically on main and with the slot fix, so they do
not belong in this test: the fix does not act on them. They stay as an open
question outside the registered tests until the engine behaviour for that
shape is settled. No other check in the file changes.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
test_coof_pyramiding_slot_large_book repeats the settled-reversal scenario of
test_coof_close_entry_pyramiding_slot with 150 pending same-side sell limits
of other ids in the book and pyramiding counts of 1, 2 and 200. The slot count
is derived by hand in the header (each pending limit counts 0, the settled
short counts 1), and the trade list with the pending limits equals the one
without them. It checks results at a large book; it does not assert a bound on
the cost of the open-lot visit, which no counter exposes.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ing-slot fix

kTranscriptDigests[16] (reversals, seed 1780393, magnifier off, margin off,
pyramiding 1, process_orders_on_close off, calc_on_order_fills on) moves with
the change that counts a settled opening against the pyramiding cap during fill
recalculation: after the reversal fill the repeated same-id entry is refused
where it was accepted before. The new value comes from the repository's own
generator (the harvest build of test_adapter_live_state_equivalence, run once
on this tree; the harvested table was compared with the committed table row by
row: only row 16 differs, 108 rows both sides). The row's comment changes with
it: 176 trades, 668 commands, 627 rows placed became 179 trades, 667 commands,
632 rows placed.

The seed-1780393 transcript runs on synthetic bars. The bar-127 side was checked
against TradingView on a real-bars source of the same order shape (an explicit
close plus a same-id short at pyramiding 1, BTCUSDT 60-minute, 2024-01-01 to
2024-03-01): TradingView refuses the second short lot, as this change does. It
is not a TradingView tape of the transcript itself, and it is not claimed
class-wide.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The probe counted the book's resting limits by comparing each row's limit price
with the level the call gave, exactly. The host stores that sell limit half a
tick lower (measured on a CLOUD build: 999.995 for a call at 1000 with a mintick
of 0.01; why is not established here), so the helper counted 0 and the two
assertions on the working-rest count failed in all 16 cases while every trade,
size and lot check passed. The count now identifies a rest by its label and the
limit kind and matches the level within one mintick. The expected counts are
unchanged: 150 resting limits at the probe and on bar 25 (a build with a dump of
the host's rows reported 150 working rows, each labelled rest<k>, before this
change).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…er threshold

The previous commit matched the resting limits within one mintick because the
stored level (999.995 for a call at 1000, mintick 0.01) was measured but not
explained. It is the adapter's trigger rule: source_trigger_threshold hands the
core a limit trigger at the grid level plus (upward ? -0.5 : 0.5) times the
tick, upward for a sell limit (src/source/pine_adapter.cpp, the function that
starts at "double source_trigger_threshold"). The helper now expects exactly that
level (the call's level minus half a mintick, to rounding) instead of any level
within a tick, so it can still see a one-tick error in the stored level. The
mintick is a named constant used for the probe's syminfo and the expected level.
The comment says the probe places only sells.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…frames

Adds the measured TradingView rows that a fix of the requested-bar grid
(intraday_bucket_open_ms and the paths that divide the continuous clock) must
turn green, and the regression rows that must stay green:

- test_requested_bar_grid_tapes: BTCUSDT 60, 2024-01-01 .. 2024-03-01. Requested
  300 / 420 / 600 with a bar_index payload, 300 / 420 with an open payload and
  the raw requested open time and index of the 300 trace tape; the dividing
  widths 120 / 180 / 240 / 360 / 480 and open 120 as regression rows. Every
  expected value is read from the TradingView tape (quantity, exit time, raw
  ro / ri), never from engine output; a row fails unless all 205 entries join
  and are equal. The tapes are private fixtures: registered in the guarded
  private-fixture form (a SKIP placeholder when absent), listed in
  tests/private_fixture_rows.txt, pins updated in scripts/ci_verify.py and its
  test. The public bars file is committed.
- test_requested_bar_grid_private_tapes: the equity-session rows, lab-only
  (PINEFORGE_LAB_ONLY_TESTS, default OFF). The feed and tapes come from
  environment variables and an absent input is a failure, never a skip.

The rows are expected to fail on the current main for the non-dividing widths
and to pass for the dividing ones; they were written before the fix.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Use one session-day bucket key, open and capped end throughout intraday
aggregation, timeframe changes and the empty-session close path. Retain
the observed first input stamp before relabeling for late-open prefixes.
Preserve one completion for the existing pre-open-prefix control.

Keep legacy daylight-saving offset resolution. Characterize its known
session-less transition edge as an engine expectation, not a TradingView
measurement. No instant-exact offset change or new refusal is introduced.
Clamp outside-session bucket ends to the existing open after applying the
session-day end cap, preserving the bucket key and open. Pin the valid final
session bucket, the Pine time_close consumer and UTC dividing-width behaviour
as engine expectations; these rows are not TradingView measurements.
Keep the two explicit-session tape rows and their strict comparisons in the
shipping target. Retain the unchanged default-context cases separately for
the caller-metadata work. Count actual rows and failures and omit the deferred
rows from the runtime summary; no skip or expected-failure path is added.
Reconcile the quantity-step and requested-bar inventories in their reviewed
insertion order: 379 rows, 2704 directories, 10235 files and 12939 paths.
Locate all evidence citations by their unchanged CMake content. Keep every
other key, comment and product line unchanged.

Rebuild both scientific arrays with their repository harvest mains on the
combined semantic tree. All 108 equivalence and 276 quiet-bar values match
the member commits; against main only equivalence row 16 and the eight
documented seeded runs differ. No digest was guessed or edited by hand.

Re-anchor the documentation to the combined source, including the renamed
intraday bucket helper and the manually selected adapter references. The
standalone grid-member citation refresh is a separate metadata-only input
commit; the final citations here derive from this tree's actual content.
The sized-runner CI change intentionally supersedes three earlier routing
descriptions; no test or checker is changed by this empty naming commit.

- 482b000 introduced the statement that both native-live sanitizer profiles
  use fixed bare scale-set names directly in runs-on. docs/ci.md:75-77 now
  separates the direct bare-scalar jobs from the native profile matrix;
  docs/ci.md:1636 identifies its exact matrix.runner values. The two live
  profiles no longer share one literal runs-on value.
- c85a40b introduced the statement that live-sanitizers and live-tsan both
  build on gke-16cpu-32gb-amd64. docs/ci.md:627 now records their measured
  disk tiers: live-sanitizers uses -256gb and live-tsan uses -128gb, selected
  by the explicit matrix include rows. The old unsuffixed shared-label
  statement no longer describes those jobs.
- f85ce18 introduced the broad 'GKE preflight and proof legs with fixed
  labels' summary. docs/ci.md:1632 now states the current disk-qualified
  Debug and arm64 routing, while the preflight remains tiered by the main
  classifier (docs/ci.md:9). The old undifferentiated summary is superseded
  by these explicit workload mappings rather than a routing exemption.

This records the real documentation intent of the measured-disk change.
The workflow labels, their preflight checks and their assertions are kept.
…er the grid and pyramiding changes

The source gate matches each site by file, symbol, lexical scope, class, spelling
and occurrence. Three reviewed identities no longer matched because the text of
an enclosing scope changed; the statements themselves did not. Each was read by
content on this tree:

- src/session_time.cpp, entry U0757, symbol "days": the assign is the local
  `const int64_t days = osec / 86400 - (...)` inside the civil-span branch of
  compute_tf_close_ms. That function's signature changed (the open stamp
  parameter is now the bar stamp, and the symbol time zone and session were
  added). It is a single integer, not a container: nothing grows, the entry's
  state (unreviewed) and container are unchanged.
- src/source/pine_adapter.cpp, entry U0912, symbol "pending": the assign is the
  counter `std::size_t pending = 0` inside place_entry's pyramiding guard. The
  guard's condition gained `&& !coof_recalc_active_`. A counter, not the
  vector of the entry; state (pending-flat-memory) unchanged.
- src/source/pine_adapter.cpp, entry U0939, symbol "result": the assign is
  `const auto result = require_host().cancel(handle)` in the same guard's
  over-cap branch, under the same changed condition. A local, not the vector of
  the entry; state (unreviewed) unchanged.

The inventory file is the gate's own `--emit-site-inventory` output for this
tree; it differs from the committed file in exactly these three scope strings
(3 hunks). No entry, state, bound, pin or scan scope changed, and nothing is
loosened: the open counts stay 1538 entries, 0 bounded, 184 pending, 1354
unreviewed.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
TimeframeAggregator now retains observed_first_ms_. Its one by-value
BacktestEngine::script_tf_agg_ member adds eight aligned bytes to the host.
The measured Host size is 107952; Adapter remains 89488 and Scratch 672.
Refresh only the two Host size pins.

PF_STREAM_ENGINE_LAYOUT_VERSION is the live accumulator's exact C++ layout
contract, independently of PF_ABI_VERSION. Advance it from 2 to 3 with the
matching-module expectation. The runner compares that stamp before reading
BacktestEngine directly; older stamp-2 modules remain accepted through
strategy_stream_fill_report and avoid the current-layout accumulator.

Add a stamped-2 fixture and report control by reusing the existing opaque
fixture and authenticated report assertions without changing their source
or golden. The old-macro RED and current-macro GREEN control execution and
the new-head full verification remain required; source delivery is not a
runtime verdict. Existing test deadlines are unchanged.
The new old-layout module shifted the runner CMake declarations. Point
the sentence at the add_test(NAME test_native_example_batch declaration
at line169, rather than a property-list occurrence or an offset guess.
Only this citation changes; sentence wording and document line count stay.

Replaced sentence:
- Update the three places that pin the paths: `native_market_example` runner/CMakeLists.txt:54, `NATIVE_EXAMPLES` check_native_include_independence.py:49, the tests at `test_native_example_batch` runner/CMakeLists.txt:156.

Replacement sentence:
- Update the three places that pin the paths: `native_market_example` runner/CMakeLists.txt:54, `NATIVE_EXAMPLES` check_native_include_independence.py:49, the tests at `test_native_example_batch` runner/CMakeLists.txt:169.
The embedded timeframe aggregator gained an eight-byte observation timestamp,
which shifts the host's later adapter member from offset 6424 to 6432 on Linux
x86_64 with libstdc++. Match the measured offset while retaining the real
subobject-address check. The host size pins already include the same growth;
offsets within the adapter and retired scratch object remain unchanged.
@luisleo526 luisleo526 changed the title Fix fill recalculation entries, quantity steps, and requested-bar grids Fix fill recalculation, declared quantity steps, and intraday request grids Nov 3, 2026

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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; no formal proof of the changed code.


Graphify review — findings

Adds the W15 kernel-calibration rulings to the kernel/adapter boundary ADR and re-pins every pine_adapter.cpp line reference it cites, since the adapter grew by about 49 lines. Narrows the priced-entry carve-out under process_orders_on_close in place_entry, so it no longer applies while a calc_on_order_fills recalculation is active (coof_recalc_active_) and same-direction pyramiding entries are gated normally there. Widens compute_tf_close_ms to take the symbol's timezone and session next to the bar time, so timeframe close follows the session calendar, and the rulings table that records the resulting intraday-grid behavior has to stay one row per ruling.

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 — 4946 functions depend on the 2952 functions this change touches.

Health — this change adds coupling hotspots:

  • new: intraday_bucket() — 5 callers, 5 callees
  • worse: compute_tf_close_ms() — 2 callers, 8 callees
  • new: check_reentry_trades() — 3 callers, 4 callees
  • new: read_rows() — 1 callers, 8 callees
  • new: read_tape() — 1 callers, 8 callees
  • new: run_row() — 1 callers, 8 callees
  • new: read_tape() — 1 callers, 8 callees
  • new: check_closed_incarnation() — 1 callers, 7 callees
  • …and 6 more — each is listed as a finding

Verification — 4946 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: 4664 function(s) in the blast radius were not formally verified this run

· 14 grounded finding(s) anchored inline below.

Comment thread src/session_time.cpp
}

static int64_t compute_tf_close_ms(int64_t open_ms,
static int64_t compute_tf_close_ms(int64_t bar_ms,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — compute_tf_close_ms()

fans out to 8 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

Comment thread src/timeframe.cpp
/// 13:45/14:45 after the open, under the same key. With the supplied 13:30
/// observation, the prefix through 14:44 shares 13:30/14:45 and completes
/// once. Strict origin anchoring without prefix folding would split it.
IntradayBucket intraday_bucket(int64_t ms, int64_t bucket_sec,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — intraday_bucket()

high coupling complexity (Ca·Ce = 25).

Grounded coupling-delta finding (deterministic), not an LLM guess.


// Metamorphic controls (a), (b) and (c): row 1's trades, the old short of 1
// and then the bar-20 market short of 2 (id "reused", or "B" in (c)).
void check_reentry_trades(const SlotProbe& p, bool on_close, const char* successor_id) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — check_reentry_trades()

high coupling complexity (Ca·Ce = 12).

Grounded coupling-delta finding (deterministic), not an LLM guess.

}

// Rows 1 and 2.
void check_closed_incarnation(bool on_close, bool close_old) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — check_closed_incarnation()

fans out to 7 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

bool entry_seen = false, exit_seen = false;
};

std::map<Key, TapeTrade> read_tape() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — read_tape()

fans out to 6 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

bool entry_seen = false, exit_seen = false;
};

std::map<Key, TapeTrade> read_tape(const char* slug) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — read_tape()

fans out to 8 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

return text.str();
}

void run_row(const Row& row, const std::vector<Bar>& bars) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — run_row()

fans out to 6 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

return group.finish();
}

int metadata_getter() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — metadata_getter()

fans out to 6 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

return group.finish();
}

int handle_lifetime() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — handle_lifetime()

fans out to 7 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.


} // namespace

int main() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regression — main()

fans out to 6 callees (efferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

@luisleo526
luisleo526 merged commit 9fa1ac5 into main Nov 3, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment