Lighter PR CI: slow rows run only on push and dispatch, proof jobs start with preflight, and the merge gate is the maintainers' verification statuses (lane CI-LITE) - #288
Merged
Conversation
luisleo526
added a commit
that referenced
this pull request
Sep 26, 2026
…-rc.1 candidate) (#290) * H-MEASURE: measure the margin retentions against the kernel and TradingView AUDIT4 X14 rows G2-09 (M7), G2-10 (M8), G2-12 (M10), G2-13 (M11) and the E20 f1 probe-tail pin. tests/test_adapter_margin_schedule_differential.cpp runs the same bars and orders through the Pine adapter and through a bare kernel host whose margin hooks answer TradingView's money and slice (the twin's), so only the kernel's own scheduling, check kinds and opening gate differ; every section prints both sides and pins the measured difference: - M7: the kernel's AfterApplied point after a leveraged opening or a mid-bar add, and its BarOpen point on a carried commissioned POOC short, are points margin_check_allowed refuses. - M8: a gap-open breach is a market execution at the open, sized on the open's money; no kernel check kind books that row. - M10: the pre-open slice's own x4 parts from the kernel's AfterApplied point (and from ab9714be) on the one-contract band, the +1e-6 restore floor and the frozen signal-time units. - M11: AdmitWithHostMargin and initial_margin_fraction part both ways. - E20 f1 (ruled 2026-09-22): the probe-suppressed tail books the kernel's path liquidation and the adapter's post-script margin call. M7 is also measured against TradingView: four lab tv tapes (tests/fixtures/margin_entry_bar, BINANCE:ETHUSDT.P 15m, rangeProof covered) book the margin call of a leveraged opening ON ITS ENTRY BAR at that bar's low, as the kernel's AfterApplied point does; the adapter books it a bar late or not at all. That is a TradingView-visible divergence, pinned as recorded (not fixed here: the lane measures). Docs made true: ADR-0001 "Margin" (the pre-open slice does have a kernel point beside it) and its initial_margin_fraction row, native-engine.md's margin paragraph, pine-to-native.md and contributing-llm.md (M11), live-surface.md §3.2 (the tail's two routes; the dispatch_bar paragraph named helpers that no longer exist), design rows MG4 and MG15; two design anchors into native-engine.md re-anchored for the moved lines. No src/ or include/ change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit bafefba06cebfc6989313e91c4a97e1a815a7239) INT26 pick note: the ADR and design pages conflicted on citation digits only (int16_digit_merge: 5 blocks, no text refused). The resolution is PAR-MARGIN's 6574de6d, the same pick onto the same tree (83d1ca7f): its two design citations of native-engine.md carried through the exact line map (2941-3009 -> 2963-3031). hunkcheck: every hunk of bafefba0 carried; the two pages differ from its diff in anchor digits only. * H-MEASURE: tape the pyramiding count, the sibling stop and pending-entry trails AUDIT4 X14 rows G2-15 (M13), the M16 sibling stop (G2-18), E14's anchored-leg seed (AUDIT3 H6 tapes) and E5's pending-entry arm, each measured against the kernel on the same bars and against TradingView's own trades (lab tv, NYSE:F 15m, ws-report-v1, rangeProof covered; each fixture README names its tapes and sha256): - tests/test_pyramiding_count_differential.cpp (M13): fifteen pyramiding=2 scenarios through the adapter, a bare host with max_open_lots=2 and the tapes. TradingView checks an entry once, at its first eligible point, against the trades then open; max_open_lots books 14 of 15 as TradingView does, the adapter's per-cycle count 8 (it counts a resting entry, admits three market entries on a flat bar, keeps a slot another entry's exit drained). A default strategy.exit(from_entry) under FIFO closes the book in the adapter and one lot in TradingView (P10). All pinned as recorded divergences; the retention reason in ADR-0001 is refuted. - tests/test_zero_trail_sibling_stop.cpp (M16): the bare host with both legs is the adapter bit for bit; the Trail alone rides past the open. TradingView books the touch at the open on 16 of 16 taped trades. - tests/test_pending_entry_trail_tapes.cpp (E5, E14): a trailing exit written while its entry is pending. The quantized arm holds, 28 of 28 (E5's claim, taped); TradingView's running best starts at the activation 13 of 13 while the adopted anchored child names no best_seed and exits 1 to 24 bars later -- recorded divergences, the adoption compare leaving best_seed out. Docs: ADR-0001's max_open_lots row, design MG3 and the rulings summary, the sibling-stop and anchored-leg paragraphs (the latter no longer "an open measurement"), native-engine.md and pine-to-native.md on adoption and the sibling stop, contributing-llm.md's pyramiding row; two design anchors into native-engine.md re-anchored. No src/ or include/ change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 99d3b9506af49a3c9bdfc5bfd947c12fd9988839) INT26 pick note: the ADR, design and pine-to-native pages conflicted on citation digits only (int16_digit_merge: 5 blocks, no text refused). The two design citations of native-engine.md both sides moved are carried through the exact line map from the pre-pick tree (2963-3031 -> 2970-3038, 1642-1643 -> 1647-1648). hunkcheck: every hunk of 99d3b950 carried; the three pages differ from its diff in anchor digits only. * H-MEASURE: measure excursions, short-seed swaps, the dust sweep, ismarket AUDIT4 X14 rows E19 (the excursion model, G2-22), G2-21 (short-seed report swaps), G2-32 (the 1e-10 dust sweep) and G2-36 (session.ismarket, the CME weekend and 0000-2400 classes), each measured against the kernel on the same fills and against TradingView's own trades (lab tv, ws-report-v1, rangeProof covered; each fixture README names its tapes): - tests/test_e19_excursion_tape.cpp (E19): a corpus probe's own script re-exported (1580 trades, its excursion cells equal to the corpus tape's) and a calc_on_order_fills scratch tape. Where the host-owned model (RULING A48) and the kernel sampler differ, the kernel's number is TradingView's: entry-bar over-mask, exit-bar over-fold after an at-open exit, the COOF scratch TradingView reports as 0/0. One trade per class pinned; corpus-wide the kernel is TradingView's on 315 of the 326 identified disagreements and the host on none. Recorded divergences. - tests/test_short_seed_report_swap.cpp (G2-21): the swap relabels two rows' entry_incarnation into ab9714be's numbering, read against the kernel's own lot identities in the same run; TradingView exports no incarnation, and the Pine host books the collision tape's 13 rows. - tests/test_pine_dust_sweep_paired.cpp (G2-32): the sweep erases a dust lot inside a live book, unlike ab9714be's whole-book reset; TradingView's decimal quantities leave no remnant row, which the Pine host books and a bare host does not (four 2.8e-17-unit rows). - tests/test_session_ismarket_tape.cpp (G2-36): six tapes (ES1!, EURUSD, XAUUSD, ETH; both 2025 DST switches, Thanksgiving) flag every bar in market; the kernel's in_session matches every spelling, the generated predicate misses every Sunday open under a :23456 mask and every bar of 0000-2400. Routing session.ismarket is a codegen change, not made here. Docs: ADR-0001 (the excursion seam, the dust sweep as a quirk, the session.ismarket selection, the excursion columns being report-only), design RP1, RP5 (its "measured in §3.7 part 2" named no short-seed row) and the excursion-mode alternative, native-settlement.md's sweep paragraph ("restates" the legacy rule, it does not), pine-to-native.md and pine_v6_coverage_detail.md on session.ismarket. No src/ or include/ change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit fd3c72e2d6cc22a77b86a73d2efc36aeed7c968f) INT26 pick note: docs/native-settlement.md conflicted in text. INT25 (K-ULP4) had appended the sentences on the adapter not declaring the kernel's quantity tolerance to the paragraph this commit rewrites; the merged paragraph is this commit's measured text followed by those INT25 sentences unchanged. The ADR, design and pine-to-native pages conflicted on citation digits only (int16_digit_merge, digits carried from the pre-pick tree). hunkcheck: every hunk of fd3c72e2 carried; design and pine-to-native differ from its diff in anchor digits only. * H-MEASURE: F1(e) tape row, F1's magnified residual, request.security routes AUDIT4 X14's aggregation rows, measured on the K-IDX tree (the kernel now books lots, rows and interval_index in script-bar space): - F1(e), tests/test_aggregated_entry_bar_index_tape.cpp: TradingView's own tape of a process_orders_on_close script whose every exit reads strategy.opentrades.entry_bar_index / closedtrades.exit_bar_index (lab tv hm-f1e-ebi-pooc-eth and its magnifier-on twin, BINANCE:ETHUSDT.P 15m), replayed on the chart, the plain aggregated (corpus 1m -> 15m) and the magnified path: 26 checks, 0 failures. With the four booking sites of e362bc4b reverted in a scratch build (the kernel books input slots again, and nothing re-stamps them) it fails 10 of 24 checks: no held exit fires, A/B/C close at their timeouts, D never enters. No corpus probe runs an aggregated process_orders_on_close script that reads a bar index; this engine row is the parity witness until the supervisor adds one. - F1's magnified residual, tests/test_magnified_aggregated_tape.cpp: instrumented, the three entry-bar tests of a magnified aggregated run now compare script bars with script bars (0 of 5170 out of space, 4996 on 91d65ad6); sixteen lab tv tapes of lane F1's differential script book its 12 rows as this engine does on every path (ab9714be's 9 were its own error). The variants the magnified run books exactly are asserted at chart-bar granularity; TradingView dates a magnified fill at its chart bar's open (218 of 218), a recorded presentation divergence. - M20 / G2-23, tests/test_adapter_security_route_conditions.cpp: every condition that keeps request.security on the source evaluator, each reachable one tripped alone against a control site, and where a kernel subscription spells the same site, the evaluator's value against a bare kernel host's on every chart bar. ADR-0001's row named four classes; the predicate has sixteen conditions, now listed and measured. Docs: design §3.8 (the gate that can now see F1's regression, AG1's TradingView proof, AG2's magnified dating, the magnified residual closed), ADR-0001's subscriptions row and native-engine.md's route paragraph; one design anchor into native-engine.md re-anchored. No src/ or include/ change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 206a739d2d9a997ae0516064e668ea48979a89ca) INT26 pick note: the ADR conflicted on citation digits only (int16_digit_merge, digits carried from the pre-pick tree). hunkcheck: every hunk of 206a739d carried; the ADR differs from its diff in anchor digits only. * H-MEASURE: the G1 acid composite as a C++/C witness row AUDIT4-codex A4-ACID-COVERAGE. tests/test_native_acid_composite.cpp is one source-free strategy on NativeStrategyHost (kernel headers only) that exercises every feature of the G1 acid test and prints PASS per feature: F01 fee-reserved Sized entry, F02 anchored bracket legs on a price grid, F03 a keep_binding re-issue, F04 a trail in ticks, F05 a maintenance-only margin model and its liquidation seen through the open lots, F06 an FX step, F07 a risk limit and an opening refused with RiskLimit, F08 calc-on-fills, F09 an hourly subscription plus an auxiliary 5m->30m series that is actually delivered (44 buckets; the audit's copy wiped its own series with an empty begin-time declare and so read aux=0), F10 session-day flags, F11 a FIFO partial close across lots and an exact-sum close that leaves no dust lot (K-ULP3), F12 typed refusals, F13 magnifier counters, F14 the kernel-recorded report with per-bar hashes. The C half (tests/test_native_acid_composite_c.c, native_c_api.h only) configures through strategy_configure_native_ext_result_v1 on a handle it first refuses (GRID_REQUIRES_PRICE_TICK, stays UNCONFIGURED, then Ready, then WRONG_PHASE), runs the same commands in batch and stream, and prints the same FIELD lines: the C++ half compares the two sets in process, 915 of 915 identical, every C++-only family named by an EXCLUDED line (the four C-SURFACE-2 items ruled to 1.1.0, closes_session_day_open_ended, the protected broker fold, quote_origin_ordinal and driver_statistics). The batch/stream comparison is explicit: trades, fills, curve, series deliveries, check points and the broker half agree; the per-bar hash rows, the final hashes and the forming bar's closes_session_day are driving-mode keyed, each rule printed with its documented source. Findings printed, not asserted: under IntrabarPath::lower_tf the margin model is checked at the bar's first sample and after fills only, never per sample, contrary to native-engine.md's "re-evaluates at each delivered sample". Source-free: registered like test_native_c_api, so it runs in the kernel profile and in release. native-engine.md records the C port's measured exclusions beside the COVERAGE block. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 58e0f16275ea57148f3385d564df88ae7cc2e70c) * H-MEASURE: H12 mutation battery; the PR parity subset covers what the sweep catches AUDIT3-opus2 H12 (carried by AUDIT4 X14): measure the 30-probe pull-request subset against mutations. 44 single-line mutations (22 kernel: matching, fees, sizing, path order, sessions, timeframe aggregation; 10 adapter; 12 ta) plus 17 designed afterwards as a holdout, each built on spark and run over all 312 corpus probes, the unmutated tree 312/312 moved=0 before, between and after: the full sweep caught 39, the 30-probe subset 19. Escaped: ten ta.* arithmetic mutations, the AUTO path-order tie, an HTF aggregation low, strategy.risk.max_position_size's equality gate and the stop-limit entry (the last two with one corpus witness each, outside the 40-item scan the subset was built from). - scripts/corpus_parity_subset.txt: 24 probes appended (the original 30 untouched): the greedy cover of the escapes, one witness per ta class a generated strategy constructs, and the two holdout witnesses. The 54 catch all 39; subset-only reruns of the escaped mutations detect them. Its header no longer claims every one-witness mechanism by construction. - scripts/corpus_parity_mutation_battery.tsv: the 39 caught mutations with the probes that caught them. - scripts/test_corpus_parity_subset_cover.py, a new ci_preflight stage: fails when the subset stops witnessing a recorded mutation (it reports 20 escapes against the original 30). - docs/ci.md records the battery and the full-sweep timing it measured (19-24 s ten-wide, 113 s serial, after a 99 s build); the "30 probes" counts in docs/ci.md, CONTRIBUTING.md, README.md, check_corpus_parity.sh and the two workflows' comments now read 54, the historical timings are labelled as the first 30's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 9c0579d2b332eaebe579a9b5baa7aa8dcedb8be6) INT26 pick note: the two workflow comments this commit re-counts were rewritten on main (57c89ff5, the advisory PR subset and the maintainers' parity status). The merged comments are main's text with this commit's count: corpus-parity.yml's "PR EARLY SIGNAL" and "advisory PR subset" sentences name the 54 probes; ci.yml's rewritten comment names no count. No other hunk differs from 9c0579d2 (hunkcheck). * H-MEASURE: put N12's seeded corpus experiment on the tree AUDIT4 X14 row "N12's corpus half" (DONE-CLAIMED-ONLY: design §3.6.1 cited an uncommitted, env-gated experiment). Ruled, with its pin and a committed reproduction: - It cannot be a CTest row. Pine's strategy.risk statements reach the adapter on script bar 0, after project() built the run spec and configure_native digested it; prepare_native_begin is final and a second configure_native while Ready is refused, so no in-process test can seed the kernel's NativeRunSpec::risk for a Pine run without a source change. The pins stay the five probes' baseline rows and test_adapter_risk_relower's SW check. - scripts/check_seeded_risk_experiment.sh applies tests/fixtures/seeded_risk/n12-experiment.patch (N12's own experiment, recovered from its session record and ported; inert without PF_N12_ROUTE) to a throwaway copy, builds the runtime and the five risk probes, checks the unseeded runs still hash to the parity baseline, runs them with the kernel's rule seeded in the adapter's place and compares expected.tsv. On this tree (spark, 29 s) it reproduces every count the design states: 1502/1502 and 1464/1464 identical, 3840 of 3916, 312 of 604, 2370 of 2386 (two extra rows) on the ten TradingView-recorded columns. Exit 1 when the measurement moves, 2 when the patch no longer applies. Docs: design §3.6.1's acceptance evidence and ADR-0001's risk row cite the script; one contributing-llm.md anchor into the design re-anchored. No src/ or include/ change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit bf5a11fbb4248d3f3bfbf5fcce1c610705c12f41) INT26 pick note: the ADR conflicted on citation digits only (int16_digit_merge, digits carried from the pre-pick tree). hunkcheck: every hunk of bf5a11fb carried; the ADR differs from its diff in anchor digits only. * H-MEASURE: the ctest floors count the lane's rows -- release 672 -> 684, kernel 271 -> 272 Counted with ctest -N on this tree, configured as ci_verify's release and kernel profiles: release registers 684 rows (the twelve H-MEASURE rows on top of 672, no row skips), kernel 273 (test_native_acid_composite is the lane's one source-free row; the WebSocket row still skips on a system libcurl, so 272 run). Each row is named beside the floor it raises. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 2b494497c8707c3365218cac4ae8d9548dc3c67b) INT26 pick note: scripts/ci_verify.py's two floors conflicted with INT25's (wave G: KERNEL 277, RELEASE 678). The merged floors add this lane's rows to INT25's -- KERNEL 277 + 1 = 278, RELEASE 678 + 12 = 690 -- with both comments kept; INT26 item (iv) recounts every floor with ctest -N per profile on the integrated tree. The four floor citations in CONTRIBUTING.md and contributing-llm.md name the merged lines (ci_verify.py:247 and :371). * Gates: the residual gate rules a text by its exact words and reads Pine's dotted namespaces (R5 lane H-DOCGATES, X12) AUDIT4-opus X12 (kres K4, K5, K11) found check_kernel_residuals blind in three ways. Its own probe battery, copied and re-run on this tree's macOS kernel archive, flagged 16 of 51 probes at 21bdc2e8; it flags every Pine probe now, on all four surfaces (strings, nm, header literals, kernel literals). - A ruled name never covers a text. The bare words `Pine` (the PineMap row) and `syminfo` passed "match Pine semantics exactly" and "syminfo.tickerid must be set", and any ruled name passed any text around it. A text is now ruled by its exact words; a name by its name. - The vocabulary reads Pine's other dotted namespaces (timeframe., input., str., math., matrix., map., line., xloc., syminfo., format., currency., dayofweek., ...; the namespace must open the run, so a compiler's l_switch.table.<symbol> label stays silent), the camel-case Tv/TV spelling, bare islastbar/isfirstbar, heikinashi, renko, tradingday and the word Pine in a text. - A row whose second column says "no archive symbol" is held to it: PineMap or a matrix text in the archive or a kernel literal fails. - The key line counts the rulings the vocabulary reads (174 identifiers, 45 texts), not every first-column token (202/25 counted 27 + 22 mechanism-table names), and ci_verify.py floors both counts (ADR_RULED_IDENTIFIERS_MIN / ADR_RULED_TEXTS_MIN), passed as --min-ruled-identifiers / --min-ruled-texts. The 57 installed-header literals are ruled, not reworded (rewording a generated strategy's runtime diagnostic is the GAP-15 codegen decision): one new ADR row holds the 32 distinct dotted argument-check texts of generic_matrix.hpp, map.hpp and drawing.hpp; the PineMap row holds map.hpp's four static_assert texts in place of `Pine`; the deprecated-alias row holds its six alias texts. No source, header or object changes: scripts, tests and docs only. Mac kernel archive: 21bdc2e8's checker "146 archive hits ... against 202 ruled identifiers and 25 ruled texts: 0 findings"; this commit "146 archive hits ... 326 installed-header hits ... against 174 ruled identifiers and 45 ruled texts (floors 174/45): 0 findings ... OK". test_check_kernel_residuals: 39 -> 46 cases (ReachTests), all pass. A symbol a compiler split or cloned (GCC's `.cold` / `.part.N` / `.isra.N` / `.constprop.N`, clang's `.cold.N` / `.llvm.N`) is still one name: x86-64 GCC 13's archive prints `strategy_set_syminfo_type.cold` and six more ruled exports that way (first NTU run of this change: 7 findings, all of that shape). Doc deletions this commit names (rewritten, not dropped): - ADR residual intro, "a text by a phrase it contains" (lane F6's rule) -> "a text by its exact words"; - ADR PineMap row, "where the bare word `Pine` is read" (lane F6); - native-engine.md "What the kernel-only archive still names": the vocabulary list and "requires every match to be listed, by name" (gap lane P2's wording, pre-F6). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit d5b6583119d321e3c6d41a2dc4e1d2ccb5c86fe1) INT26 pick note: scripts/ci_verify.py conflicted where INT25 and H-MEASURE rewrote the floors this commit sits beside; its ADR ruled-count floors are inserted after the merged RELEASE_MIN_TESTS, every floor and comment of both kept. hunkcheck: every hunk of d5b65831 carried unchanged. * Gates: a published sentence leaves only when its commit names it -- the doc-revert stage (R5 lane H-DOCGATES, X13) AUDIT4-opus docs-a (f)/N7: no silent doc revert reached main between fd785928 and 91d65ad6, but nothing would have caught one. Lane B-C-SURFACE's rebase kept its own base's pages, dropping V19-D's keep_handle / keep_binding row and putting D2-C's runtime-block wording back; the integration caught it by reading. scripts/check_doc_reverts.py compares each commit with its parent, sentence by sentence (paragraphs, list items, table cells of README.md, CONTRIBUTING.md and docs/**/*.md; anchor digits and content pins normalised). A deleted sentence, or older wording restored over newer (a sentence the page held before its parent), must be named by the commit's message: the lane label or hash of the commit that introduced it, six consecutive words of it, or its table row's key. Fresh rewrites and re-anchors need no name. Range: non-merge commits since the merge base with main; with no main ref (the lab's remote hosts) it walks back from HEAD; a commit whose tree predates the gate is never judged. --base/--head/--message-file judge one replayed change. Acceptance (both run on this tree): - 597a4367's nine pages replayed onto db98990c with 597a4367's message: "17 unnamed sentence deletions or reverts ... FAIL" -- V19-D's keep_handle rows (introduced by c619f5f) and D2-C's ambient-block wording reverted to "thread-local"; - e3e20cb5 with its own message: "0 unnamed ... OK"; the same change with the message "docs: tidy" fails on the 11 PERF-P1 sentences it deleted (introduced by 36a6a7e, cherry-picked from 3bd72fb). Preflight stages doc-reverts and doc-reverts-tests (binding); CTest row test_doc_reverts (10 cases over throwaway git repositories), so the floors rise: KERNEL_MIN_TESTS 272 -> 273, RELEASE_MIN_TESTS 673 -> 674. docs/ci.md, README.md, CONTRIBUTING.md and contributing-llm.md name the gate; the floor citations re-anchored (ci_verify.py:229 -> :231, :332 -> :336). No sentence is deleted by this commit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 34ae339e3488c2ec22e6724643d65d2ecea73a48) INT26 pick note: the floors conflicted with INT25's and H-MEASURE's; each floor adds this commit's one row to the merged value (KERNEL 278 -> 279, RELEASE 690 -> 691), both comments kept, and the four floor citations name the merged lines (ci_verify.py:249 and :375). hunkcheck: every other hunk of 34ae339e carried unchanged. * Gates: a content pin accompanies a claim, never replaces it; a comma-borrowed citation claims nothing (R5 lane H-DOCGATES, X13) AUDIT4-opus docs-a N1/N2 (GAP-1, GAP-5): a backticked sha256 pin before an anchor dropped the symbol claim and was compared alone, so whatever the cited line held passed -- a wrong line (P09), a blank line (P10), a garbage hash before a real one (P11), a ruling row pinned over unrelated code (P16) -- and 44 of the tree's 92 pins held something other than what their sentence claimed. In a citation list, a citation that prose introduced after a comma ("FX curve c_abi.cpp:882, probe c_abi.cpp:882") borrowed the list's first symbol. check_doc_anchors.py: - the nearest non-pin span before a pin is still the claim and is still checked; a ruling row needs its symbol or fragment, pinned or not; - PINLINE (a pin on a single line), PINEMPTY (a pin over blank lines), PINDOUBLE (two pins before one anchor); a pinned comment-only window is COMMENTONLY unless the sentence says it cites a comment; - a citation that prose words introduce after an earlier citation's comma is NOCLAIM until it carries its own backticked symbol. Self-tests 45 -> 53: PinMustFail (P09, P10, P11, P16, the comment window, a pinned range with its claim) and BorrowedClaim. Against 21bdc2e8's checker the six must-fail cases fail and the two controls pass (anchor_selftests.before.txt in the lane scratch). The pages: on HEAD the new rules raised 64 findings (23 PINLINE, 2 PINDOUBLE, 8 COMMENTONLY, 1 SYMMISS, 30 NOCLAIM). Every pin was re-derived on this tree (claim, window, verdict, true location) and re-cited as a symbol claim at its declaration, or as a pinned range whose sentence names the comment it cites; every comma-borrowed citation now names its own symbol at its true line (e.g. design OT5: FX curve `strategy_configure_native_fx_curve_v1` c_abi.cpp:940, probe `strategy_execution_contract` c_abi.cpp:873; FP1's fill_through enforcement `protect_limit` :6103-6113 and InvalidTerms :4958-4976). The anchor gate reads 1657 anchors, 0 bad. docs/ci.md and the checker's docstring state the new rules. Doc sentences this commit deletes or rewrites as history (named for the doc-revert stage). Most of the pins it removes are B-DOCS' (d3cca9e, cherry-picked from 5c3c9ae), so the unpinned wording that returns in pine-to-native.md's `open_profit` rows and `strategy_create` row, and in design E2's margin sentence, is that commit's pins undone on purpose: - design §2.vi claim rows 2, 3, 6, 8 and 9: their plan-era anchor lists (B-DOCS' pins, 91d65ad6's re-cites) become "at 73817c1 (overtaken ...)"; row 1 is re-cited to today's Trigger/OrderIntent/Owner/Group/PointBudget; - design §2.i "Today: one static library always compiles the source layer" -> "Before L1" plus the tree's current CMake lines (the sentence 1dd5430 wrote, "sits in the *main* list", now "sat"); - design "Its callers were the adapter only (pine_adapter.cpp:2605, ...)" for the deleted admission_retention -> its history (73817c1d); - design "The dead helpers engine.hpp:1255, engine.hpp:1265, ... are the reference arithmetic" -> they are deleted; the kernel's own step is native_matching::apply_slippage; - design P6 "(`sha256` `sha256` native-engine.md:421-435)" -> the page section "Stream limitations (current)"; - design "degenerate equity metrics (engine_metrics.cpp:3)" drops its anchor (pre-L2 behaviour). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 85910410f08abac32922125b4c3b0e2a01db598e) INT26 pick note: the four pages conflicted where INT25 and H-MEASURE had moved or rewritten the rows this commit re-cites. Each merged row keeps both intents: - ADR "Margin": this commit's three claimed citations, then H-MEASURE's measured paragraph unchanged. - design rows 1-3, 5, 6, 9 and P4: this commit's re-citations (symbol claims, or "at `73817c1` (overtaken ...)"); INT25 had only moved their digits or re-hashed their pins. Rows 7 and 8 keep INT25's text (row 8 is C-SURFACE-1's current C-surface statement with its pins); this commit left row 7 alone and marked row 8's old statement overtaken. - design (a) NEUTRALITY: this commit's `PASS` claim; main rewrote the AGENTS.md section it cited (116c461b), so the pin now covers main's "A campaign PASS verdict still binds the exact engine and codegen HEADs" (AGENTS.md:139-140). - OL14 and pine-to-native's `pyramiding` row: word-level merges, INT25's and H-MEASURE's words with this commit's claims. Every other hunk of 85910410 is carried (hunkcheck); citation digits are re-anchored once on the integrated tree (INT26 item vii). * Gates: the doc lint reads native-*/v<n>, the ABI numbers, VERSION and src/include paths (R5 lane H-DOCGATES, X13) AUDIT4-opus docs-a GAP-6 (probes P19, P20, P29-P32): the lint was blind to a dead `src/` or `include/` path, to a stale `native-consumer/v8` or `native-driver/v4` domain, to "`PF_ABI_VERSION` is 3" and to "PineForge 0.13.1, the current release". - rule 3's live hash domains also read every "native-<name>/v<n>" literal the tree declares (market_driver.hpp: native-driver/v5, native-consumer/v9, native-calendar/v1); rule 7 judges a marker on one; - rule 5 reads `src/` and `include/` paths to a C/C++ file or directory; a `git show <ref>:path` object path and a file its clause calls generated are not dead; - rule 8 (new): a stated PF_ABI_VERSION / PF_NATIVE_API_VERSION must be the header's #define; a higher number is a forward reference unless stated as current, a lower one needs the marker and a history framing; - rule 9 (new): a PineForge release stated as the current one must be VERSION's. Self-tests 55 -> 67 (MustFailH: P19, P20, P29, P30, P31, P32, a marker on a native domain stated as now, a forward ABI number stated as current; MustNotFireH: live values, forward/historical numbers, git object paths, a generated header, a foreign crate's src/main.rs, a native domain as history). Against 21bdc2e8's lint the eight must-fail cases fail and the four controls pass (lint_selftests.before.txt in the lane scratch). The tree had three offenders under the new rules, all in the design record: row o (§2.ii) now says the admission journal "was" include/pineforge/market_admission.hpp + src/market_admission.cpp until N14 moved both under source/ (marked history), and §2.iii's O proposal is spelled `c_native_host.cpp` like S's, not as a tree path. The lint reads 0 offenders; docs/ci.md lists the new families. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 845b07a5a345312bfa85a71fbfd9b5aeab514724) * Tests: one random draw per statement at the fifteen sites the compiler ordered, and a lint that keeps the class out (R5 lane H-DOCGATES, X17) AUDIT4-opus perf N-2: XPLAT1's bug class (e8bc3237) came back. C++ leaves a call's argument order unspecified and a binary operator's operands unsequenced; GCC on x86-64 draws right to left, AppleClang left to right, so ten call sites in five test files (P7's and L2's fixtures, TA1's tests) built a different random battery on each compiler. The lint finds five more, in unsequenced `*` operands (test_adapter_live_state_equivalence, test_native_direct_mutation x2, test_native_handle_stable_replace x2). Each of the fifteen sites now takes one draw per statement into a named local, in the order the arguments are written (AppleClang's), so no Mac output moves: - the 15 affected test executables, Release, AppleClang 17 (arm64): stdout before vs after identical in every non-timing byte (15/15); - the same 15 in Docker xplat1-gcc13:amd64 (GCC 13, x86-64): before, the printed batteries differed from the Mac's in 7 tests (test_adapter_purge_index "14844 commands" vs 14575, test_native_settlement_carry, _fused_settlement, _in_place_reads, _precommit_hook, _quiet_point, _direct_mutation); after, x86-64 prints the Mac's bytes in all 15. Every test passes on both, before and after. So the only output that moves is x86-64's random battery, onto the one the Mac already runs; no pinned value, hash or fixture moves (nothing in these tests pins a draw-dependent count, or x86 CI would have failed before). scripts/check_rng_draw_order.py (binding preflight stages rng-draw-order and rng-draw-order-tests): a draw is a call that advances a std:: engine or a class whose members apply a PRNG step, found transitively through drawing helpers and lambdas; it reports ARG (two draw-bearing arguments of one call), OPERAND (two draw-bearing operands of an unsequenced operator) and BYVALUE (a generator parameter copied while other arguments are evaluated), and leaves the sequenced forms alone (one per statement or declarator, braced-init lists, && || ?: and the comma, C++17's << >> [] = orders, lambda bodies). 21bdc2e8's tests: 15 findings; this tree: 0; self-test 5 cases (a must-fail fixture of XPLAT1's three shapes and each kind, a must-pass fixture of every sequenced form). CONTRIBUTING.md lists the gate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 7536bf01e0a4cbfdb32141b9065891048f4366a6) * Tests: the runtime blocks' LIFO check gets a death row, and the chart-day memo a witness that reads it (R5 lane H-DOCGATES, X17) AUDIT4-opus perf N-7 and D-17: two INT23 witnesses proved nothing. 1. uninstall_runtime_ambient's debug-build LIFO check (09ced53e, INT23) had no row: a mutant deleting it survived every profile. tests/test_native_runtime_ambient_lifo.cpp holds the legal order in process (each block's writes copied back down to the thread's own) and, in a forked child, the outer block leaving first: a library built with its debug checks (PINEFORGE_LIBRARY_DEBUG_CHECKS=$<CONFIG:Debug>, from tests/CMakeLists.txt; the TU strips NDEBUG like every test) must die of SIGABRT inside the call; any other library must return, leaving the thread's own block in force with the inner block's write lost -- the silent state loss the check exists to stop. Measured on a scratch copy of this tree: Debug "ok (16 checks)", Release "ok (19 checks)", Debug with UBSan ok; with the check deleted, Debug fails 2 of 16 (the child returned). This tree's Release kernel build: "ok (19 checks)". Source-free, so it runs in the kernel profile too: KERNEL_MIN_TESTS 273 -> 274, RELEASE_MIN_TESTS 674 -> 675 (recorded below both floor lines so the pages' citations of them do not move). 2. test_chart_day_memo's `CHECK(pair.kept.holds_cache())` became vacuous with D2-C: the consumer holds the adapter's lookup index on every chart, so INT23's mutant cd5 (a memo never kept or read) passed. The new memo_witness reads the memo in place and plants keys in it (test-only: the index's day_lo / day_hi / day_key offsets come from a layout mirror of AdapterLookupIndex, held to the whole days UTC reads keep before anything is planted, so a drifting layout fails instead of writing over another member): on each UTC spelling a read keeps its whole floor day and key and a planted key answers exactly that day; on each chart timezone nothing is kept and a planted key is never answered. Mutants on a scratch copy: cd1-cd4 still fail; cd5 (never read), cd6 (kept, never read) and cd7 (a zoned chart consults the memo) now fail where the old check passed all three. No source change: tests only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit d5ead4d5893e175f431bbd9b8d25f138fe6d5706) INT26 pick note: the floors conflicted with the merged ones; each adds this commit's LIFO death row to the merged value (KERNEL 279 -> 280, RELEASE 691 -> 692), with this commit's comment kept below RELEASE_MIN_TESTS so the cited floor lines stay put. Every other hunk of d5ead4d5 carried. * Docs: the deferred-performance inventory, the witness drift and the next script-ABI epoch's schedule are written down; three comments say what the code does (R5 lane H-DOCGATES, X17) AUDIT4-opus X17 (perf N-1, N-4, N-5, N-6, N-9, N-10; K1-9; L4-10), the documentation half. Comment-only for the three C++ files: their code and literals are token-identical to HEAD's (scripts/cxxlex.py), and the Release objects of src/native_calendar.cpp (which includes native_calendar.hpp) and src/source/pine_strategy_host.cpp (which includes pine_adapter.hpp) are byte-identical before and after (sha256 ccd2c0b06f48..., c9ce59093717...). - TLS wording: pine_strategy_host.cpp said D2-C left "no thread-local access per bar"; it left no thread-local WRITE. The comment now names the readers that still reach the block through the thread's pointer once per call (the extremum rings behind ta.highest / lowest / highestbars / lowestbars / stoch / wpr / range; the day partition behind the default ta.vwap, crosses_boundary(DAY) and the session-period helpers), measured 1.000 access a bar per call by AUDIT4. - K1: native_calendar.hpp claimed every instant a held session day holds() keys to its ordinal; America/Sitka and America/Juneau in October 1867 under "2330-2300" hold 30 and 45 instants (all out of session) whose own session_day_at carries another ordinal. The comment states the guarantee where the cycles tile and names the exception. - L4: the two retired receipt-reader slots and their waivers are scheduled for the next engine_script_run epoch (slot comment, both waiver rows, and the progress page). - docs/native-refactor-progress.md "Deferred performance work": D2-B, the PERF-D3 S1a / S1b / S1c / S2 / S2e rows and the quiet-run loop, PGO, L3's compact records, checked-values handoff and chunked trades_ store, the zoned chart-day memo, and the thread-local readers that remain -- each with its measured size (lane, host, tool), the ledger ruling that deferred it, where its prototype lives (perf-d2/proto-throwaway 92e85571, perf-d3/proto-throwaway a820b7df, r5/l3 b33ea659) and what reopens it; "audit-off mode", "LTO" and "data-oriented layout" are struck until a design note defines them. - "Recorded witness drift": K24's pre-size is dormant under Window retention; PERF-L4 reads the receipts 3.09 times a bar, not once (test_adapter_quiet_bar_probe on this tree: ReceiptRead asked 40996, 81.8 % stopped at the gate, against 13248 for a once-per-bar gate); D2-C's carry counts moved 479/397 -> 489/412 at dbcca850 (bisected on macOS), and x86-64 now prints the Mac's numbers after this lane's one-draw-per-statement fix. - The page joins check_doc_anchors.py's published set, so its 28 new citations are held; the pages' anchors that the comment lines shifted are re-anchored (native-engine.md, the ADR, the design record). No sentence is deleted: the pages gain sections, and the re-anchors change digits only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 2201c1ac15ef463a8f75867651ee96c45e993f04) INT26 pick note: the ADR, design and native-engine pages conflicted on citation digits only (int16_digit_merge per line, digits carried from the pre-pick tree; one ADR citation of pine_strategy_host.cpp both sides moved taken additively, 1925 -> 1931, re-judged at INT26 item vii). hunkcheck: every hunk of 2201c1ac carried; two pages differ in anchor digits only. * Docs+Gates: every kernel seam and every kernel member the source layer writes gets an ADR-0001 row, the account of TradingView-justified comments is complete, and a gate holds the inventory (R5 lane H-DOCGATES, X10) AUDIT4-opus X10 found the ADR contradicting itself and the tree. Each sentence was re-derived on this tree: - The examples sentence claimed every C++ host includes only native_host.hpp. Three include native_toolkit.hpp or native_module.hpp (both include native_host.hpp) and the two C hosts include pineforge.h; "each including only `<pineforge/native_host.hpp>` (or `native_c_api.h`)" is rewritten to say so. - The build_close_trade_with_costs row still said "One question stays open, recorded at the site: the net basis is applied to a host-owned excursion's magnitudes too (RULING A48's hook)". R5 lane F3 closed it in 684800bf; the row now says so and scopes the net basis to the kernel's own sampled excursions. - The neutral-spellings row said map.hpp and drawing.hpp are neutral names with deprecated pine_* aliases, "already ruled: "Neutral spellings" above" -- a section that does not exist, contradicting the residual table's PineMap row (primaries with no neutral alias). The row now names both cases and cites the two residual rows. - "They do not yet account for the whole population" (the paragraph ending "until each gets a row or moves") and the Consequences bullet "Not yet fully accounted for" contradicted rule 2's "no site left unruled". Four Section B rows close the eighteen unruled lines the audit's closure grep found (the chart-day partition, the bar-time accessors, the offset sign, the grid and lot helpers); the paragraph now records the re-taken census (369 comment lines in 44 of 92 files, none unruled) and the bullet says the count is held by reading, not by a gate. Rule 2 pointed at "the section below"; the section is above. - Rule 1 now names the generated-code language runtime and its admission test, which the three category rows apply. - The subscriptions row listed four exclusions ("the sites the predicate leaves out (lower timeframe, lookahead, auxiliary, streams) keep the source evaluator"); declare_security_sites_to_kernel has fifteen and declares every site or none. The row lists them. - Fourteen new rows in "Kernel state the adapter sets" cover every seam and member the new gate finds, including the two whole-struct current_bar_ writes (E21 check e), broker_fill_event_seq_, the dead source_stream_entry_comment (scheduled for the next script-ABI epoch in docs/native-refactor-progress.md), fold_exit_trail_peak_, NativeHostCache and the rows AG1/AG2 re-date. The dust sweep is recorded OPEN for lane H-THIN (A4-DUST); the position_entry_count_ overwrite is recorded OPEN. - Design row RP5 said the short-seed swaps are "measured in §3.7 part 2"; no row there measures them, and it now says so. The second "### 3.8" (lane F9) is §3.9, and RP9's "§3.8 records the old quadratic adapter fold" now points at it. - Two engine.hpp comments were false: "Generated code reads them for Pine's bare ``hour``" (the transpiler emits pine_hour(..., syminfo_.timezone); no corpus strategy names a _bar_* accessor) and script_tf_'s writers "(both sites live in engine_run.cpp)" (the one writer is the Pine host). Comment-only, line-count preserving: all 86 library objects are byte-identical with and without the edit. scripts/check_kernel_seam_rows.py (a binding ci_preflight stage, with its must-fail suite as ci_preflight stage and CTest row test_kernel_seam_rows) fails when a kernel `virtual source_*` seam, a BacktestEngine member the source layer writes, or a Trade / PyramidEntry field written through the kernel's rows has no ADR-0001 row naming it in its first cell. Over this commit's parent it reports 43 without a row; here 0. It reads class bodies itself: check_broker_state_hash_coverage.py loses a member declared right after an inline function body (current_bar_, bar_magnifier_enabled_, trace_buffer_). KERNEL_MIN_TESTS 274 -> 275, RELEASE_MIN_TESTS 675 -> 676. Sentences deleted or rewritten, by the commit that wrote them: ca0aac5 (INT16's examples sentence), 2757095 (P2's lead-in of the mechanism table), 5691220 (L14-C's neutral-spellings row), 2dd9834 (F2's "The rows above account" paragraph and its "Not yet fully accounted for" bullet) and d3cca9e (the gates paragraph's closing sentence, now naming the seam-row gate beside the review record). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 4cbc6ab6c1d8925d2d9353fc030ab511665252f9) INT26 pick note: the merged pages keep both sides. - ADR-0001 inventory: INT25's K-ULP4 and K-ULP5 rows stay after the journal window row (its V19-FIX wording kept), then this commit's fourteen rows. - ADR `subscriptions` row: this commit's all-or-nothing predicate list, plus the one clause it left out (`declare_security_sites_to_kernel` also refuses a registry whose `sec_id`s are not dense from 0), then H-MEASURE's measured sentence on what each reachable clause changes (c77ee9f9). - ADR close-trade row: this commit's closed A48 question and H-MEASURE's report-only excursion columns (word merge). - ADR rule-2 paragraph: this commit's gate list, then INT25's C-SURFACE-1.0 transport ruling section unchanged. - design RP5: H-MEASURE's measured short-seed sentence stays; this commit's "unmeasured: §3.7 has no row for them" was true only before H-MEASURE's `tests/test_short_seed_report_swap.cpp` (37090e19). - floors: this commit's seam-row self-test adds one row to the merged values (KERNEL 280 -> 281, RELEASE 692 -> 693). check_kernel_seam_rows on the merged tree: 3 seams, 44 written members, 0 without a row. * Docs+Gates: the 1.0 C boundary -- every C++ capability the C surface does not expose, its reason and the checker row that fails when the gap closes; no page claims C/C++ parity beyond it (R5 lane H-DOCGATES, C-surface 1.0) Supervisor ruling 2026-09-26: C-SURFACE-2 moves to 1.1.0, so the 1.0 docs list every C++ capability the C surface does not expose, each with its reason and checker row, and nothing claims C/C++ parity beyond that list. docs/pages/native-engine.md "The 1.0 C boundary" replaces "What is not exposed, and why", which named the five excluded host members and said of the preview that "`strategy_native_execute_current_v1` answers the same verdicts" -- it applies the command, so it is no preview. The table has 27 rows: the five COVERAGE `[--]` members, the deprecated hash_source_extension seam, the KernelRecordedAtHostMarks exclusion (reworded: the kernel's mark is reached only by the Pine source host; a C++ host records its own points), and 21 C_V1_EXCLUSIONS rows -- the replace options, the applied event's tail, a closed row's entry comment, closed rows in place, the working request's whole definition, the open-ended session-day fact and the rest of the callback contexts, host-sized openings, the terms hook's units answer, the excursion facts' rate, the hash sink, the entry-bar mask outside on_applied, timeframe_undetected, the inherited statistics, the hook views, the command events' payloads, the command results, native_state()'s spec and failure context, trace rows and hook re-declaration, the C++ library around the host, and native_toolkit.hpp. The four C-SURFACE-2 items say 1.1.0; the rest say they have no lane. scripts/check_native_c_api_surface.py: each C_V1_EXCLUSIONS row pins its C++ declaration (a whole-word match) and one or more (C record, pattern) pairs whose pattern must stay absent; every pattern tolerates a prefix and a suffix (`\w*`), because the old draft's pins caught only the plain spelling and let strategy_closed_trade_entry_comment_v1, a keep_handle-carrying replace call, strategy_native_submit_bracket_v1 and a request_origin / request_label applied tail through. The page must cite every row exactly once and no row the checker lacks. Ten new self-tests: those four spellings, a pf_native_applied_ext_v1 beside v1, an input interval on the decision, a C++ declaration that goes, and a row missing, doubled or made up on the page. Against this commit's parent checker all ten fail (7 failures, 3 errors); here 29/29 pass. Parity claims narrowed where they went past the boundary: native-engine "`<pineforge/native_c_api.h>` is the C spelling of all of it", the reading table's state / working / events / current-point rows (partial), native_sized_units's C cell (it has one), the preview's C cell, the report mark "the host calls the kernel's report mark", the spec extension's "The one field of `NativeRunSpec` it deliberately does not carry is `identity`" (also timeframe_undetected), on_close_units "the only half this header exposes"; pine-to-native "needs no C++", the host-sized answer "A C host answers the same question through `on_close_units`", "Three rules make the C door behave like the C++ one" and the "Five members have no direct C spelling" paragraph; README's three front doors ("so they match trigger, price fills, book lots and settle identically") and "to its C++ **and** C spelling" (also index.md and contributing-llm); the ADR's C API bullet, its route-or-ruling sentence and the KernelRecordedAtHostMarks row; design §2.iii marked as the L13 plan. Header comments (comment-only, line-count preserving; all 86 library objects byte-identical with and without them): native_c_api.h's opening ("It is the C spelling of ... NativeStrategyHost"), the inspect_current_execution COVERAGE row, the spec extension's omission, on_close_units; native_host.hpp's C spellings of native_state, events, current_execution_point, resolve_execution_terms, inspect_current_execution and the two configure calls; native_order.hpp's HostSized note ("the C surface refuses HostSized under any owner but BindCohort" -- a Book-scoped WaitForApplied close is admitted too). Sentences deleted or rewritten, by the commit that wrote them: f22a34e (N8's "What is not exposed, and why" lead), d3cca9e (its five-member list and the market-only note), 69228e6 (L14-C's native_sized_units and preview C cells), 074f648 (F4's KernelRecordedAtHostMarks row reason), 2fcbb52 (F2's "Not every member of the C++ host has a C spelling"), ca0aac5 (INT16's five-member sentence on the migration page) and 4fb9db3 (L14-B's CONTRIBUTING row for a C kernel-driving export). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 77a3eacb6e24fec8d98c1d074bfaf8943cdfdb9a) INT26 pick note: this commit was written before INT25's KERNEL-EDGE (409ebad1), which made the kernel's report mark installed C++ API (`NativeStrategyHost::mark_native_report_point`, a COVERAGE `[--]` row of native_c_api.h). Its sentences "The kernel's mark is reached only by the Pine source host (it is not installed API); a C++ host records its own points instead" are false on the merged tree, so: - the ADR's KernelRecordedAtHostMarks row keeps INT25's text (a C++ host reaches the kernel producer through mark_native_report_point); - native-engine.md's report-mark paragraph keeps INT25's text and adds this commit's C half: "A C host has no call that marks one (the 1.0 C boundary table)."; - the boundary table's KernelRecordedAtHostMarks row states the C++ mark route and cites COVERAGE `[--] mark_native_report_point` beside its ENUM_TWINS exclusion (the sixth excluded NativeStrategyHost member). The C configure paragraph keeps INT25's "a second extended configure of a Ready handle is refused without changing it" and takes this commit's two omitted fields (`identity`, `timeframe_undetected`). The ADR paragraph on report ownership keeps INT25's digits and takes this commit's boundary pointer. check_native_c_api_surface: 64 members, 58 with a C spelling, 6 excluded; 21 C++ capabilities outside the 1.0 C surface, each pinned and in the boundary table. * Gates: a sanitizer build's quoted type name is judged as the name, and Eigen's assert text a debug archive carries has its own row (R5 lane H-DOCGATES, X12) The sanitizers profile's run of the X12 vocabulary (lab remote job rj-20260925t190344-64918a, NTU2, x86-64 GCC) failed test_kernel_residuals on two strings a release archive does not carry: - `'struct SymInfo'`: UBSan's type descriptor quotes a type's name. The line IS the name `SymInfo`, which is ruled, but X12 judged it as a text naming a ruled identifier. check_kernel_residuals.py now reads a quoted type name (GCC's `'struct X'`, clang's `'pineforge::X'`) as its names. - `matrix.cols() == matrix.rows()`: the eigen_assert text of Eigen's eigenvalue solvers, which src/matrix.cpp instantiates, compiled in only when NDEBUG is off. X12's dotted-namespace vocabulary reads `matrix.`. It gets an ADR-0001 row by its exact words ("not residue": Eigen's parameter, not Pine's namespace), and a row whose second column says "absent under NDEBUG" is no longer called stale when no surface carries it, so the same row holds in release, debug and sanitizers. ADR_RULED_TEXTS_MIN 45 -> 46. Five self-tests: both quoted spellings pass as the ruled name and an unruled quoted type still fails, a quoted Pine text is still a text, the debug-only text is not stale when absent and covered when present, only a marked row may be absent, and an unruled assert-shaped text still fails. Dropping the type-name rule fails the first; dropping the debug-only rule fails the release table. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 68b974f2d2921fbe79c72d1b9642ad393cc67d66) INT26 pick note: scripts/ci_verify.py conflicted beside INT25's PR-only floors and ctest bound; ADR_RULED_TEXTS_MIN takes this commit's 46 and every INT25 line stays. The residual gate on the merged tree: 174 ruled identifiers, 46 ruled texts, 0 findings. * Kernel+C: the four deprecated public spellings are removed for 1.0 (lane REL10, item 1) ADR-0001 "Deprecated public spellings" scheduled pf_equity_stats_t::sharpe_tv / sortino_tv for removal at the next PF_ABI_VERSION and exit_legs::Domain::Coof / MagnifierCoof at the namespace after lifecycle_v1. They are removed for 1.0 without either epoch: an alias shares its storage or its value with the primary spelling, so no offset, size, value, hash fold or mangled name moves. PF_ABI_VERSION stays 4 and lifecycle_v1 stays lifecycle_v1; the PF_DEPRECATED and PF_ANONYMOUS_UNION helpers leave pineforge.h with them. ADR-0001 rule 2: the kept spellings are the generic ones, named for the resampling period and the fill-recalculation pass, not for a Pine or TradingView setting. - test_removed_public_spellings (F6's deprecation row, renamed; still one row): the 1.0 spellings compile clean under -Werror in strict C99 and in C++17, and each removed spelling alone fails with the unknown-member diagnostic that names it. - Tests and the Python mirrors name the 1.0 spellings; the twin-parity guard matches the renamed CHECKs by literal signature, counts unchanged. - The JSON report keys stay sharpe_tv / sortino_tv: docker/run_json.py writes the two C fields under them (EQUITY_REPORT_KEYS), pinned by scripts/test_report_schema_keys.py, a new ci_preflight stage. - Every page that named an old spelling says what is true now; the ADR section keeps its heading and records the removal. Anchor digits follow in the lane's re-anchor commit. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 38e8ad1e0f6a022e03d91e82f31d43ea66bef652) INT26 pick note: dropping the four spellings drops their ADR residual row, which H-DOCGATES (33aaf0b9) had widened to rule each alias's six texts by their exact words; the row leaves whole, as this commit removes it, and the residual gate's ruled-count floors in scripts/ci_verify.py fall with it (ADR_RULED_IDENTIFIERS_MIN 174 -> 170, ADR_RULED_TEXTS_MIN 46 -> 40; the gate on the merged kernel archive counts 170 / 40, 0 findings). ci_preflight.py keeps H-MEASURE's subset-cover stage and adds this commit's report-schema-key stage. pine-to-native.md takes this commit's text (line 141 on its tree), digits carried. The sentences the removal retires, by the commits that wrote them: lane P2c's deprecation ruling and its page notes (329e021), lane F4's strict-C99 anonymous-union note (0a46b45), the int12 guard pass's migration sentences (9b50973) and INT16's wave-F reconciliation of the same pages (ca0aac5). * Build: a release-candidate VERSION configures, builds and installs, and every surface names it (lane REL10, item 3) VERSION may be X.Y.Z-rc.N (N >= 1). CMake's project(VERSION), the package's PineForge_VERSION, PINEFORGE_VERSION_MAJOR / _MINOR / _PATCH / _STRING and pf_version_get() stay the numeric X.Y.Z; PINEFORGE_VERSION_FULL, pf_version_string() and the package's new PineForge_VERSION_FULL carry the full version, -rc.N included. AUTO keeps git describe first (it already resolved a vX.Y.Z-rc.N tag); FILE and AUTO's no-describe fallback now keep the file's -rc.N instead of dropping it, and any other suffix fails configure. version.h.in keeps its six placeholders: codegen's test harness renders exactly those. The installed-package smoke consumer prints pf_version_string() and exits 1 unless the package, the installed header and the linked library name one version. scripts/ci_verify.py compares its print with VERSION, so the numeric print it replaced would have failed every profile on an -rc.N VERSION. test_cmake_version_source adds the candidate's archive, tag and past-the-tag cases, the final release after its candidate, and the refused prerelease spellings. No pkg-config file is added: integration-cmake.md says the CMake package is the one that ships. That page now pins 1.x: the package is SameMajorVersion, so a 0.x minimum does not find a 1.x install. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit dd6e9d843e24156e49be35ac4883f11ea2668116) INT26 pick note: clean pick. Two sentences are rewritten rather than kept: lane F2's statement of what the generated <pineforge/version.h> exposes for 0.14.0 (2fcbb52) now states the full and numeric versions, and lane FPC's smoke-consumer sentence (4c9404c) keeps its -ffp-contract=off check inside the rewritten smoke paragraph. * Release: release.yml takes an exact override, a dry run and release candidates; its version arithmetic is a tested script (lane REL10, item 4) scripts/release_version.py `next` computes current / next / tag / prerelease / previous from VERSION and the tags, and refuses anything but X.Y.Z or X.Y.Z-rc.N, a version that does not sort above VERSION, an existing tag, and a bump from a release candidate (its successor is always an exact override). `previous`, the release-notes base, orders tags by semver precedence: the YAML's `git tag --sort=-v:refname` put vX.Y.Z-rc.N above vX.Y.Z, so v1.0.1's notes would have started at a candidate. `check-install` verifies a staged install's version.h and package files before a tarball is packed. scripts/test_release_version.py holds all of it as a ci_preflight stage. release.yml: - `override` (exact version) and `dry_run` inputs beside `bump`; `override` reaches only the script, through env. - A release candidate is a GitHub prerelease, and the hub dispatch carries client_payload {version: vX.Y.Z[-rc.N], prerelease: true|false, run_id}. - The prebuilt job configures with PINEFORGE_VERSION_SOURCE=FILE and verifies the staged version; the tarball keeps its pineforge-vX.Y.Z[-rc.N]-<triple> name. - A dry run computes the version, builds, installs, verifies and packs every tarball (kept as workflow artifacts), and commits, tags, releases, uploads and dispatches nothing. - The App-token commit / tag / push step is unchanged; a dry run skips it. - The workflow publishes no container image, and its header no longer says it does: the GHCR image is the hub's. ci_preflight's workflow-lint stage now lints release.yml too (the prebuilt configure's intentional word split carries its shellcheck annotation). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 2bd8e2f3fb9307571b57167d20f892a25f53cd42) INT26 pick note: ci_preflight.py conflicted beside H-MEASURE's subset-cover stage; both stages stay and this commit's comment covers its two stages. * Docs: the public contract for 1.0 (lane REL10, item 2) docs/pages/public-contract.md states what the version number covers from 1.0.0, mirroring codegen's docs/PUBLIC_CONTRACT.md: versions and where the full X.Y.Z-rc.N appears; the C ABI (PF_ABI_VERSION 4 for 1.x, frozen layouts, append-only functions and enumerators); the native C++ API (source-compatible within 1.x, not binary-compatible); the script ABI epoch engine_script_run_v19 and the stability of its state-hash values; the 1.0 C-surface boundary (the exclusions listed in the native-engine page's "Driving the kernel from C", where lane H-DOCGATES's 1.0 table lands; C-SURFACE-2 planned for 1.1.0); and the pairing rule -- engine and codegen share one version number, the same X.Y.Z prerelease included, and the hub enforces it. Each rule names the checker or CTest row that holds it on this tree, and the parts no checker holds (a C signature kept by name, a C enumerator value against the previous release, pf_report_t against a 1.0.0 baseline, C++ source compatibility against a 1.0.0 baseline, the stream fingerprint's value) are named as such. Linked from README, docs/README, the site index, the CMake integration page and CONTRIBUTING's new release step. pineforge.h's two hash comments no longer say a fingerprint may change between builds: its recipe is the epoch's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 5f423b54fa8954c705fafde171f98ec0adf577f6) * CHANGELOG.md: the 1.0.0 entry (lane REL10, item 5) What 1.0 means -- the kernel runs without any Pine adapter, and Pine is an adapter over it -- and what a 0.x user must act on since v0.13.1, the last tag (VERSION read 0.14.0 from 439bd520 on, never tagged): C ABI 4 and the grown pf_report_t, the renamed equity fields (JSON keys unchanged), the regenerate-and-relink rule of the v19 script ABI epoch and the codegen pairing, the new state hashes, the event-retention window default, -ffp-contract=off reaching consumers, the moved pine_float_compare.hpp, the 0.x find_package pins a SameMajorVersion package no longer satisfies, and prerelease versions; then the behaviour that moves results. Read from the tags, the merged PRs #232-#288 and the public headers' diff between v0.13.1 and 1a0e7ea1, with each commit and PR cited checked against the history. README points to it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit bda36e1fe578221727afff65883823f92d0b83c5) * Kernel: a group's receipts follow its drain's queue order, so a re-price that keeps its handle inside a group no longer stops the run (R5 lane K-OCA-KEEP) Ruling (ADR-0001 rule-2 row "the order of one cause's group-effect receipts"): a drain applies a group's effect in queue order, whatever the handles' numbers, and the receipts record that order. Generic, no knob. Root cause (K-ULP5's finding 1, HIGH, pre-existing). A member's fill reaches its live siblings through WorkingRequestCore::group_recipients, which walks the book in queue order -- ascending LiveRequest::priority. A re-price with ReplaceOptions::keep_handle (R5 lane V19-D) keeps the request's incarnation and takes a fresh priority, so it moves behind younger siblings: queue order and incarnation order part. The receipt store was bisected by (cause, recipient incarnation, effect), and prepare_group_effect / apply_group_effect refused any receipt that sorted before receipts_.back(). So the second recipient of one cause -- the re-priced request, drained behind a younger sibling -- was refused CoreFailure::InvalidCause and the consumer failed the run (Contract, discriminator 1) after the member's fill was booked, staged and direct, under Cancel and Reduce. K-ULP5's probe on 2a03c658: book [inc 2 prio 2][inc 1 prio 3], recipients 2 then 1, receipt (21,2) committed, (21,1) refused. Which order is right: V19-D's contract is that a keep_handle run records the plain replace's run -- every journal event, ordinal for ordinal. The plain successor is the newest request and is drained last, i.e. in queue order. Sorting the recipients by incarnation instead would drain the re-priced request first and swap the group events' ordinals against the plain run. So the walk's order stands and the receipt store follows it: - receipts_ stays append-only in commit order (the consumer folds each once, by index, at its commit), ordered by cause alone; - receipt_lookup bisects the cause and walks that cause's receipts (a drain of k recipients makes about k*k/2 comparisons); - the order check refuses only a cause older than the newest receipt's. A completed run's receipts were already in incarnation order within each cause, and the lookup answers such a store as before, so no completed run changes and no hash value moves. receipt_cmp is gone. The other walks (waiting_children, bound_close_handles, the parent-terminal and owner-applied drains) read no receipt order; the cohort rosters and the opening rows sort by handle, which a keep_handle re-price does not change. Tests: test_native_gro…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lighter PR CI, and the merge gate described as it now works
PR CI stops waiting on the slowest rows. Every test stays in the tree, and the full set still runs on every push to main, on manual dispatch, and in the maintainers' own pre-merge verification.
What changes
slow, declared in one place (tests/CMakeLists.txt).test_ci_verify(485–986 s under sanitizers) and the native batteries (test_native_direct_mutation,test_native_match_band_precheck,test_native_match_row_reuse,test_native_command_after, …).pull_requestonly, the sanitizer, Debug and native jobs pass--exclude-label slow.workflow_dispatchtrigger run every row.ci_verify.pycounts rows with CTest's ownctest -N, with and without-LE slow, and requiresran == registered − labelled, with PR registration floors. A row that silently loses its registration still fails.preflightinstead of waiting about 9 minutes for it. The aggregatebuildcontext still requires every job.pineforge/verifyandpineforge/parity, posted from the maintainers' own verification, instead of GitHub Actions'build/sanitizers. GitHub Actions CI is advisory.promote-baseline.ymlnow confirms both statuses on the merged PR head, taking the newest status per context.docs/ci.md,AGENTS.md, the README and the workflow comments describe the new gate.Measured
Most of the remaining time is the sanitizer build itself: 29–30 min from build start to CTest on the hosted 4-core runner. The ≤25-minute target is not reachable without build changes; that is noted for later.
Verification
ci_preflightpasses locally: 32/32 stages, 143 verifier tests, 8 preflight tests.ctest -Ncounts:slowsrc/,include/orcorpus/changes, so engine behaviour and TradingView parity cannot move.Report:
exec/CI-LITE-final.mdunder the R5 evidence root.🤖 Generated with Claude Code
https://claude.ai/code/session_01LifAW9e5J6gFx7gatuxETE