Repository navigation
Fix engine execution cases and selected-capacity admission for 1.12.0 - #822
luisleo526 wants to merge 58 commits into
Conversation
Exercise the version-only reset before tagging, preserving tagged behavior. Add refusal controls for parent count, extra paths, version direction, catalog bytes, existing tags and inherited release stamp constraints.
Require each release phase to use its own exact-commit CI evidence. Keep the bump untagged until its checks finish, then authenticate and tag that same commit. Validate the two-file transition and preserve catalog assets.
Record advisory verification and complete workflow attempt history, bind the decision to received response bytes, and refuse changed run metadata before admission. Keep release receipts on refusal and honor declared catalog paths. docs/ci.md: replaces the release-bump exemption sentence introduced by 72d9fd5 (#486).
Use timezone-aware UTC and keep exact output assertions aligned with each test input. Preserve every release safety condition and mutation control.
Cover authenticated advisory creators and first-attempt actor refusals. Reject malformed advisory states before logging them, retain sanitized unexpected-exception receipts, and distinguish invalid triggering actors from changed attempt metadata. Keep parity as the only required status.
Carry both strict admission forms in the hosted release workflow, retaining caller identity, artifact custody and exact-commit release evidence.
Keep historical matrix inputs independent from the phased release workflow and require both phase and dry-run boundaries on downstream publishing jobs.
Choose the expected guard and message from the complete dispatch declaration, while retaining strict workflow acceptance and both dry-run boundaries.
…hosted jobs WorkflowPinTests reads the #768 matrix rebuild of release.yml for its hosted-matrix contracts. That rebuild keeps the shipped two-phase release job, a combination the validator correctly refuses, and its single prebuilt job has no tag-phase guard. Four checks therefore failed. They now read the shipped workflow: - test_two_release_phases_stop_before_publication_until_tag_phase pins the exact job-level tag-phase if: of prebuilt-x86, prebuilt-arm and upload, and the closed job list. The notify-hub, gate, step-condition and writer pins are unchanged. - test_prebuilt_requires_release_success_without_failure_bypasses holds the release-success pin for the release job, both build jobs and the publishing upload job: needs: release on each build job, upload's exact needs: [release, prebuilt-x86, prebuilt-arm], no always(), !cancelled() or continue-on-error: outside comments, and no release_bump_workflow_findings. - test_prebuilt_failure_bypass_mutations_are_refused, both subtests, inserts each bypass into each build job and into upload and requires the same refusal. Each of those jobs first passes with the shipped "no continue-on-error" comment in it, so the pin is still shown to read keys, not words. The validator compares every split job header, so the pin now scans the build jobs and upload before the release job, and a refusal names its job and bypass. The other WorkflowPinTests tests keep reading the matrix rebuild. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Scripts that read their closed trades again and again (strategy.closedtrades accessors in a loop) were about 1.9 to 2.0 times slower than on 1.10.0 on histories of 15,500 and 39,456 closed trades. Two things made them slow: every cache hit rewrote the rank of the other entries of its set, and four-way sets spread consecutive trades over four times the pages their rows need. The cache now follows the number of closed trades. While the ledger holds at most as many rows as the cache has entries (215,070 by default), row n owns slot n: one way, one probe per lookup, and only the pages the rows reach are committed (25,000 closed trades hold 98 pages, 7.8 MB, where four-way sets held 391 pages, 31.2 MB). With more rows the four-way sets apply as before. An append that takes the ledger past the cache's rows, or a rewind back to them, drops every cached row and keeps the allocated pages. In a set, a hit on the most recent entry changes nothing and a hit on any other entry ages only the entries more recent than it, so a full set replaces the entry touched longest ago, as the documentation says. A miss is probed and counted once. Every value a script reads is unchanged: the reports of a 15,500-trade script are identical field by field. Measured on an aarch64 build host, one pinned core, engine time against 1.10.0 built with the same compiler: a script that scans 15,500 closed trades again and again takes 1.03 of the 1.10.0 time (five rounds; main before this change 1.92); a script that only opens and closes trades is unchanged by this change (1.10 on 150,000 bars, as on main). With 250,000 closed trades, above the cache's rows, a script that scans all of them every 6,000 bars takes 40 s, against 27 s on main before this change and 138 s on 1.10.0 (two rounds). Timings on x86-64 were not measured. Tests: the placement oracle in tests/ledger_default_cache_rows.hpp now takes the number of rows the ledger holds, and nine tests that compared resident bytes or entry counts with it state both placements; three new tests pin the least-recently-used rule, the single probe of a miss and the placement change. Documentation: docs/pages/memory-management.md and the header comment describe the placement by row count. Two sentences of the memory page leave in the ledger read cache row: the sentence that began "Storage is private: a global ordinal chooses one four-way set" (introduced by ba14721) is rewritten to state the placement for both populations, and "Page growth preserves entries through the 64/128/256 boundaries." (introduced by 69cddc9) now says that growth preserves entries through every page boundary, every 256 rows within the cache's rows. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Preserve phase-aware release admission while incorporating the current main toolchain contract. Keep both Eigen flag constants and the mode parameter, and update the planned-phase fixture to the typed PATH flag. Co-Authored-By: Codex <[email protected]>
Retain the tagged VERSION and catalog baseline before exact-head validation. Co-Authored-By: Codex <[email protected]>
Complete the selected-capacity production entry and add pineforge-selected-admit, a small command-line program that checks a caller's capacity bounds on the Source and the selected inputs of a run before the first writer consumes them. Production entry: the five selected-capacity observers are bound through the native materializer, and actual Source records and CSV bytes are accounted with the existing reserve primitive. Input-sensitive tests cover the field limits, the exact failure arguments, the byte accounting and the production binding. Helper: it reads a versioned request descriptor (tools/selected_admit/ DESCRIPTOR-V1.md specifies the request, the result and the manifest), takes custody of each input by descriptor number, size and digest, parses it with the existing selected-capacity reader, calls the product entry, and answers with one result document and an exit status. The Source stage forwards each record only after it is admitted, and refuses a forward descriptor that is the same file as its stdout or stderr (exit 41); the Selected stage counts the selected pass and retains nothing. The helper and its manifest (size, sha256, build identity, schema digests, stages) install to bin/ and share/pineforge/. The sha256 of the spec is compiled into the manifest, so a change to the spec changes the manifest. The spec also lists what the Source stage holds in memory (the record window and the reader's copy of one field, each up to the record cap, a chunk and the process base) with one measured figure, and what the helper reads from the environment and the file system: GLIBCXX_TUNABLES at start, and, for a calendar zone that is not UTC-like, TZ and, per libc, TZDIR and the zone file under the zone database root. Tests: descriptor, custody, stage and manifest tests, the Source-stage parity test, an import-list test and a calendar test. The import-list test reads the undefined symbols of the built helper with nm and fails if it imports one of its list of 41 process, thread, session, socket, descriptor-duplication, signalling, system-call or library-loading functions, other than dlopen (one RTLD_NOLOAD lookup of the engine's own image) and recvmsg (the run-quota endpoint). The two allowed names are pinned in the test, a glibc fortified or internal spelling of a forbidden name counts as the name, an nm line that cannot be parsed stops it, and a listing without pread, poll and __cxa_begin_catch, which the helper builds measured so far import, is rejected as empty, truncated or unrelated; having them proves neither completeness nor which file nm read. The calendar test runs the Selected stage with New York four-hour script bars across the two clock changes of 2024: the open of the date's own season is admitted, the open of the other season is refused with the neighbouring bar opens that civil-time arithmetic gives, and a zone database root that holds no zone makes the zone unsupported. Inventory: the allocation-site inventory gets the three new Source-stage groups and five site rows, the unreviewed ceiling goes from 1410 to 1413 and the exact-union pin to 1356 + 57 + 184, the five selected limit routes of the ownership manifest are corrected, and the CMakeLists.txt line citations in five documents are re-anchored (three citations that named a neighbouring line now name the line they describe). Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The capture counter starts after the ledger cache has been populated, so resident cache-page growth must not be required in its working-heap peak. Restore the symmetric fixed-window comparison while retaining the exact row-count-dependent cache residency assertions and all output oracles.
Retain the row-count-derived page-growth upper envelope, since Release can allocate cache pages during capture. Do not require that growth in the measured peak when pages are already resident. Keep the exact cache residency, scratch-window, output and profile checks unchanged.
…utral names The registration file of the helper's unit tests, the fence around its script tests in tests/CMakeLists.txt, and the CTest label of all seven tests carried a name derived from a work card. They are now selected-admit-helper and selected_admit_helper. The registrations are otherwise unchanged, and nothing else in the tree named the old file or label. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The private-fixture reads check reads the add_test arguments of tests/CMakeLists.txt and refuses a variable that starts with _pf_ unless it saw that variable set in the files it reads. The manifest test took its expected stages from _pf_sa_stages_json, which the root CMakeLists.txt sets, so the check stopped on it and test_private_fixture_reads and its controls failed in every build that runs the full suite. The pull request always carries tools/selected_admit/stage_source.cpp, so the root sets that variable to ["source","selected"]; the test now gets exactly that text, and it still compares it with the stages in the built helper's manifest. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…rule CMakeLists.txt takes the sha256 of tools/selected_admit/DESCRIPTOR-V1.md into the selected-admit helper's manifest at configure time, so a change to that page changes a build output. The docs-only rule called every Markdown file outside its excluded trees documentation, and test_no_cmake_file_reads_documentation (the docs-only-tests stage of preflight) failed on exactly this page: Lists differ: ['tools/selected_admit/DESCRIPTOR-V1.md'] != []. The page joins PROOF_READS, the list of documentation inputs that proof jobs read, so a change to it runs every proof leg. The pinned list in the rule's test, the scan test that now requires the page among the CMake reads it must see, and the sentence in docs/ci.md that counts the excluded files are updated with it. A new test replays the page in real git histories: an edit, a rename away, a rename onto its path and a deletion all run the proof legs, and another Markdown page of the same directory stays documentation. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… pin it with a calendar test The spec page said that a bare name "that is also a valid POSIX rule" is accepted as a POSIX rule when no usable zone file is found for it. What the helper applies is its own check (tz_posix_spec_accepted in src/native_calendar.cpp), not whatever a C library calls valid, so the page now names that check in both places where it states the exception. The calendar test pinned that a named zone is refused when the zone database root is missing, but nothing pinned the other half of the sentence. The new row runs the bare name EST5EDT under a missing root: the session opens of a mid-winter and a mid-summer date are admitted, the other season's open is refused as unaligned with the true grid neighbours, and the named zone America/New_York under the same root is the control (refused where the C library reads the root, admitted where it does not). Only mid-season dates are used, because the rule set a bare POSIX name without an explicit rule follows near a transition is the C library's default. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
With process_orders_on_close and the default FIFO close rule, a strategy.close() of the open position followed, in the same execution, by a reversing strategy.entry() with an explicit quantity and named strategy.exit() calls for that entry reserved the exit quantity from a basis reduced by the close of the OLD position: the pending close was subtracted from the sum of the entry's book basis and the new entry's own units. A percentage exit was then sized from too little, or from nothing (it then fell back to the old position's size), an absolute-quantity exit lost its quantity, and a part of the new position could be left without an exit and stay open past its stop. The close is now subtracted from the book part of the basis only, floored at zero, before the new entry's units are added. Wherever the close does not exceed the book part the basis is unchanged. tests/test_adapter_named_exit_after_reversing_close.cpp runs twenty scenarios, each with and without the strategy.close(). Fourteen use process_orders_on_close (long and short reversals with the old position larger, smaller and equal; absolute-quantity and limit-only exits; a default-quantity entry). It checks every exit quantity against values derived from the entry's inputs, requires the old position's trade to carry the close's exit id, and compares the close run with the control field by field. Ten of those fourteen fail without the change. Six scenarios run without process_orders_on_close (the old position larger, smaller and equal, long and short, with next-bar fills): they compare the close run with the control field by field and assert the totals, times, prices and positions; they pass with and without the change, so the trades there are unchanged. The split of a reversal's exits between the take-profit and the stop is not asserted without process_orders_on_close. Not changed: reversals under the same id, close_entries_rule ANY, a same-side re-entry under another id and a partial close before a reversal; their exit sizing is separate work. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Without process_orders_on_close, a strategy.entry with an explicit quantity that reverses an open position is parked in the same-bar command queue until the end of the script execution. The pending-parent scan of strategy.exit looked only at the live and the pending entry lists, so the parked entry was not counted: the exit's basis was zero and its percentage fell back to the size of the position being replaced. With qty_percent below 100 and sizes that differ, the take-profit took a share of the old position (an old position of 4 reversed into 2 closed the whole 2 at the limit and left no stop; 2 reversed into 4 gave 1 and 3 instead of 2 and 2), and a take-profit given as an absolute quantity never fired, so the stop closed the whole position. The scan now also counts a parked entry that reverses the open position, so the percentage is taken from the new entry. Flat starts, same-side adds and default-quantity reversals are unchanged. tests/test_adapter_named_exit_after_reversing_close.cpp now asserts the exit split of its six next-bar scenarios (the four with different sizes fail without the change) and adds four next-bar scenarios with an absolute-quantity take-profit (they fail without the change as well). Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
With margin_long and margin_short both 0, a strategy that declares default_qty_type = strategy.percent_of_equity with a value above 100 sized its default-quantity entries from the full declared percentage: 150 percent bought 150 percent of equity. For an entry from flat, without commission, TradingView sizes such an order at no more than 100 percent of equity when margins are off, for long and for short entries. With margin 1 it keeps the declared percentage and with margin 100 it refuses the order; both already behaved that way here and do not change. default_percent_of_equity() returns the declared percentage capped at 100 when the default quantity is a percent of equity and both margins are 0, and the declared value otherwise. default_sizing_cash() (both branches) and pooc_fee_units() take their money from it, so the money is capped before any commission is taken out of it. CASH and FIXED defaults, explicit quantities, typed per-order quantities and configurations with a non-zero margin are unchanged. tests/test_percent_equity_cap_margins_off.cpp runs twelve entries (long and short; margin 0 at 80, 100, 150 and 1000 percent; margin 1 and margin 100 at 150 percent) against a reference function; the four runs at 150 and 1000 percent with margins off fail without the change. Rows for a cash commission per order, a cash commission per contract, and a percentage commission under process_orders_on_close with a fractional quantity grid run each of long and short at 100 and at 150 percent: the two runs must give the same trades and the quantity must equal a reference function (these rows have no TradingView tape; the expectation follows the sizing rule stated in the code). Reverting either commission line fails those rows. Three pairs of runs (a same-side add followed by a close, a same-side add and a close in one bar, a reversal and a close on a fine quantity grid) at 100 and at 150 percent must give identical trades. tests/test_value_invalid_sizing_margin_source.cpp: the row that overflows a declared percentage of the largest double now runs at margin 100, because with both margins at 0 that declared percentage is capped at 100 and its product stays finite. Not covered: a configuration with only one margin at 0; entries that are not from flat (adds and reversals above 100 percent); commission paths against a TradingView tape; the branches that key on a declared value of exactly 100 (see the pairs above) beyond those three scripts. Refs #805. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Test strategy.risk.max_drawdown at closing fills, as TradingView does
The train now holds the changes merged into it so far, among them the fill-time drawdown rule (#804). The only textual conflict was the unreleased section of the changelog, where both lines are kept; the adapter, the host, the state hash and the test registrations merged without edits. Refs #805. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ranch Brings the train branch (train/engine-1.11.1) into this branch, so that the branch can be merged into the train branch as a member change. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The train now holds the changes merged into it so far, among them the fill-time drawdown rule (#804). The only textual conflict was the unreleased section of the changelog, where all three lines are kept; the adapter and the test registrations merged without edits. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
ci: split release bump and tag admission
Three changes of this series alter which exits and orders survive a reversing entry: an exit placed with a same-side entry on the bar where the position is closed is kept when the position goes flat, an entry placed after a partial close now closes the rest and opens the new position, and an exit placed while its entry id holds lots is cancelled when an entry of the same id reverses those lots. The frozen digests of the live-state equivalence test (10 of 108 configurations) and of the quiet-bar battery (16 of 276 rows) move with them; no other row moves. Each moved value is replaced by the harvest of the tree that holds all the changes, compiled with the harvest macros of the two tests; the harvest of the tree before the series reproduces every old value. The data files carry one comment block per cause with the old and new value of every moved row and the TradingView tape of that cause. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Size a reversal's exits from the new entry, as TradingView does
Candidate: add the selected-capacity admission helper
…gain The train now also holds the reversal exit sizing change (#803) and the changes merged with it. The only textual conflict was the unreleased section of the changelog, where every line is kept; the adapter and the test registrations merged without edits. Refs #805. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The class series (the ANY basis and same-side exits, the partial close then reversing entry, the same-id reversal and the re-pin of the frozen digests) now holds the engine 1.11.1 train, with the reversal exit sizing change and the other changes merged into it. The only textual conflict was the unreleased section of the changelog, where every line is kept; the adapter, its header and the test registrations merged without edits. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Cap a percent default quantity at 100 percent of equity with margins off
…ay which rows are controls An entry placed after closes on the same bar is a reversal only when those closes leave part of the position open. The units of the closes are summed and compared with the held position; the compare now allows the quantity epsilon that the neighbouring compare of the process-orders-on-close path already allows, so closes of 0.1 and 0.7 on a position of 0.8, which sum one unit in the last place below 0.8 in doubles, count as covering it. The notes of the class tests now say which rows are controls that pass on the base and carry no tape of their own, and only the row that reproduces a TradingView tape cites it. The changelog names the two observation fields that read 0 for an entry placed after a partial close, and the quiet-bar note lists the counts that move with the re-pin. No pinned value changes. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The train now also holds the percent default quantity cap (#805). The merge had no textual conflict: the changelog, the adapter, its header and the test registrations merged without edits. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…artial closes do not The pending order of a reversing entry placed after closes on the same bar reports created_after_position_close_in_bar as 1 exactly when the units of those closes reach the held position, and as 0 when they leave part of it open. The rows read that field on the pending entry before it fills, for closes of 0.1 and 0.7 on a position of 0.8, closes of 1 and 2 on 3 and two percentage closes of 50 on 3, and for two controls that leave part of the position open (closes of 0.1 and 0.6 on 0.8, and one close of 0.25 on 0.8). The first row needs the quantity epsilon of the cover compare, because 0.1 and 0.7 sum one unit in the last place below 0.8 in doubles. The other two need the loop to add every close of the bar, not only the first. Each expectation is derived from one rule, written in the test. Refs #803. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Fix the remaining reversal and exit-sizing cases (#803)
Update the CMake registration anchor to the actual final train token location; preserve the evidence row, predicate and reason.
docs: re-anchor execution documentation and fixture evidence
There was a problem hiding this comment.
Graphify reviewed this change.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 3 advisory finding(s) below merit a look before merge.
Not checked: tests were not run; no formal proof of the changed code.
Graphify review — findings
Splits the release workflow into a bump phase, which gates the dispatch SHA, pushes only the two-file VERSION and reset-diff commit to main, and stops, and a tag phase, dispatched with dispatch_sha, which tags and publishes that exact commit. The gate step now requires authenticated parity and exact-SHA full CI before the tag phase proceeds, so publication depends on that check holding for the bump commit and on one tag run owning the release. ci_release_gate.py plan now computes the version and previous tag in place of the inline release_version.py next call, and the gate writes a receipt artifact that dry runs also keep. In the tag phase, catalog stamping diffs from HEAD^, and a retry reuses an existing tag at the same SHA instead of writing VERSION or creating a new commit.
Worth a look
- Manifest path can escape the install root —
cmake/PineForgeSelectedAdmitManifest.cmake:114· Escalate · medium- unverified hypothesis — survived the adversarial refute pass; needs human review
- Tag phase can publish before the bump commit's CI succeeds —
.github/workflows/release.yml· Escalate · medium- unverified hypothesis — survived the adversarial refute pass; needs human review
- Concurrent tag-phase runs can race to create the same release —
.github/workflows/release.yml:369· Escalate · medium- unverified hypothesis — survived the adversarial refute pass; needs human review
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 — 6369 functions depend on the 6043 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
ci_workflow_findings()— 93 callers, 25 callees - worse:
admit_rule_findings()— 9 callers, 9 callees - worse:
_job_block()— 22 callers, 3 callees - worse:
build_diff()— 8 callers, 8 callees - worse:
do_check()— 3 callers, 17 callees - worse:
native_run_spec_digest()— 17 callers, 3 callees - new:
parse()— 6 callers, 8 callees - worse:
_holds_credentials()— 6 callers, 7 callees - …and 36 more — each is listed as a finding
Verification — 6369 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: 6235 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
1420 of 1420 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety (
noncode-change,uncovered-code) — the selection is not trustworthy on its own (see below). CI should run the whole suite.
benchmarks/tests/test_aggregate.py— full-run-safetybenchmarks/tests/test_check_provenance.py— full-run-safetybenchmarks/tests/test_compare.py— full-run-safetybenchmarks/tests/test_public_names.py— full-run-safetybenchmarks/tests/test_run_all.py— full-run-safetybenchmarks/tests/test_run_strategy_feeds.py— full-run-safetydocker/pineforge_sink_finalize_test.py— full-run-safetydocker/pineforge_sink_replay_rq_test.py— full-run-safetydocker/pineforge_sink_replay_test.py— full-run-safetydocker/pineforge_sink_to_json_test.py— full-run-safetydocker/quota_columns_test.py— full-run-safetydocker/quota_convert_test.py— full-run-safetydocker/quota_finalize_test.py— full-run-safetydocker/replay_rq_engine_test.py— full-run-safetydocker/run_json_artifact_window_test.py— full-run-safetydocker/run_json_bin_test.py— full-run-safetydocker/run_json_bounded_transport_test.py— full-run-safetydocker/run_json_bulk_equity_fuzz_test.py— full-run-safetydocker/run_json_bulk_equity_test.py— full-run-safetydocker/run_json_codes_test.py— full-run-safetydocker/run_json_converter_metadata_test.py— full-run-safetydocker/run_json_converter_session_test.py— full-run-safetydocker/run_json_diagnostics_test.py— full-run-safetydocker/run_json_equity_scan_test.py— full-run-safetydocker/run_json_fused_test.py— full-run-safetydocker/run_json_harnesses_test.py— full-run-safetydocker/run_json_metrics_only_test.py— full-run-safetydocker/run_json_misc2_test.py— full-run-safetydocker/run_json_misc_test.py— full-run-safetydocker/run_json_pfbar_test.py— full-run-safetydocker/run_json_provenance_test.py— full-run-safetydocker/run_json_quota_supervisor_test.py— full-run-safetydocker/run_json_replay_test.py— full-run-safetydocker/run_json_selected_sink_test.py— full-run-safetydocker/run_json_sink_lexical_test.py— full-run-safetydocker/run_json_sink_summary_test.py— full-run-safetydocker/run_json_sink_test.py— full-run-safetydocker/run_json_sink_vectors_test.py— full-run-safetydocker/run_json_spool_work_test.py— full-run-safetydocker/run_json_stringio_test.py— full-run-safetydocker/run_json_symbol_feeds_test.py— full-run-safetydocker/run_json_syminfo_test.py— full-run-safetydocker/run_json_trade_scan_test.py— full-run-safetydocker/run_json_window_budget_test.py— full-run-safetydocker/run_json_wrapper_work_test.py— full-run-safetyinclude/pineforge/native_run_spec.hpp— full-run-safetyscripts/derive_corpus_feeds_self_test.py— full-run-safetyscripts/fingerprint_self_test.py— full-run-safetyscripts/run_corpus_self_test.py— full-run-safetyscripts/test_abi_receipt_skips.py— full-run-safety- … and 1370 more
non-code file(s) changed (
.github/workflows/release.yml,CHANGELOG.md,CMakeLists.txt,ci/cr150-source-bounds.yaml,ci/cr150-source-sites.json…) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
.github/workflows/release.yml,CHANGELOG.md,docs/adr/0001-kernel-adapter-boundary.md,docs/ci.md,docs/design/arena-bound.md…) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Docs that may be stale (advisory)
AGENTS.md§ What this repo is (lines 5-11): references changed symbolssourceAGENTS.md§ Build (lines 12-25): references changed symbolsreceiptAGENTS.md§ Layout (lines 26-41): references changed symbolssourceAGENTS.md§ What CI runs, per trigger (lines 46-70): references changed symbolsdiagnosticAGENTS.md§ Local-only tests (no CI job runs them) (lines 71-82): references changed symbolsselectedAGENTS.md§ Conventions (lines 103-116): references changed symbolssourceAGENTS.md§ Safety rules (lines 117-127): references changed symbolssourceCLAUDE.md§ What this repo is (lines 5-11): references changed symbolssourceCLAUDE.md§ Build (lines 12-25): references changed symbolsreceiptCLAUDE.md§ Layout (lines 26-41): references changed symbolssource
…and 10 more.
· 20 grounded finding(s) anchored inline below; 12 more finding(s) on lines outside this diff (see the check run); 12 additional anchorable finding(s) not shown (cap).
|
|
||
| def _release_split_toolchain_reader_is_pinned(workflow: str, body: str) -> bool: | ||
| """Admit only the reviewed OIDC reader; scan all other raw credential inputs.""" | ||
| def _release_split_current_toolchain_reader_is_pinned(workflow: str, body: str) -> bool: |
There was a problem hiding this comment.
_release_split_current_toolchain_reader_is_pinned()
fans out to 9 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return not _holds_credentials(workflow, token_only_body, strict=True) | ||
|
|
||
|
|
||
| def _release_split_contract_findings(workflow: str, mode: str) -> list[str]: |
There was a problem hiding this comment.
_release_split_contract_findings()
fans out to 11 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return findings | ||
|
|
||
|
|
||
| def release_bump_workflow_findings(workflow: str) -> list[str]: |
There was a problem hiding this comment.
release_bump_workflow_findings()
fans out to 10 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| _fields(run, ("created_at", "updated_at", "run_started_at", "html_url"))) | ||
|
|
||
|
|
||
| def _observe_run(api: API, repo: str, run: dict, record: dict) -> None: |
There was a problem hiding this comment.
_observe_run()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| validation["outcome"] = "pending" | ||
|
|
||
|
|
||
| def _revalidate_runs(api: _GateReads) -> None: |
There was a problem hiding this comment.
_revalidate_runs()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
|
|
||
| } // namespace | ||
|
|
||
| int main() { |
There was a problem hiding this comment.
main()
fans out to 11 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| CHECK(got.open_at_end == expected.open_at_end); | ||
| } | ||
|
|
||
| void check_exits(const Scenario& spec, const std::vector<Bar>& bars, const Observed& got) { |
There was a problem hiding this comment.
check_exits()
fans out to 7 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| CHECK(old_rows == 1); | ||
| } | ||
|
|
||
| void check_exits(const Scenario& spec, const std::vector<Bar>& bars, const Observed& got) { |
There was a problem hiding this comment.
check_exits()
fans out to 7 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| got.final_units, got.error.c_str()); | ||
| } | ||
|
|
||
| void run_case(const Scenario& spec) { |
There was a problem hiding this comment.
run_case()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| std::vector<std::uint64_t> lengths; | ||
| }; | ||
|
|
||
| Parsed parse(Memory& memory, const std::string& digest, std::uint64_t cap, |
There was a problem hiding this comment.
parse()
fans out to 8 callees (efferent coupling); 6 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
Revert the split release admission change from the 1.11.1 train
| # Retain the decoy outside the install location; delete no file. | ||
| configure_decoy.rename(root / "retained-configure-decoy") | ||
| self.run_command(["cmake", "--install", str(build)]) | ||
| binary = check_install(configure_prefix, chosen_sha, True) |
| configure() | ||
| build_all() | ||
| self.run_command(["cmake", "--install", str(build)]) | ||
| binary = check_install(configure_prefix, chosen_sha, False) |
| import subprocess | ||
| import sys | ||
| import tempfile | ||
| import unittest |
| while position < len(data): | ||
| count = os.write(input_write, data[position:position + 4096]) | ||
| position += count | ||
| except BrokenPipeError: |
| position += count | ||
| except BrokenPipeError: | ||
| pass | ||
| except BaseException as error: |
| total += len(chunk) | ||
| if total >= len(HEADER): | ||
| resume.set() | ||
| except BaseException as error: |
| self.assertGreater(count, 0) | ||
| written[0] += count | ||
| pending = pending[count:] | ||
| except BaseException as error: |
| if not chunk: | ||
| break | ||
| forwarded.append(chunk) | ||
| except BaseException as error: |
|
Superseded by #824, which carries the same final tree as one commit on main. |
Include #797, #804, #817, #801, #816 and #820: closed-trade cache placement, fill-time drawdown halt and flatten, reversal exit sizing and its class cases, selected-capacity admission, and the percent default quantity cap.
Document the intentional replacement of these earlier descriptions:
update_risk_state(bar.close)once per script bar at the close mark description is obsolete afterstrategy.risk.max_drawdown(value, strategy.percent_of_equity): no halt in a strategy that only reverses, and an early halt in a strategy that enters from flat #804. The cell now describes the fill-time peak, closing-fill threshold, halt latch and immediate flatten. Preserve MG10-a and MG10-b as HISTORICAL, measured on engine f5e929d, before thestrategy.risk.max_drawdown(value, strategy.percent_of_equity): no halt in a strategy that only reverses, and an early halt in a strategy that enters from flat #804 change, with their values, claim status and grade unchanged.Re-anchor the remaining documentation citations and move the private-fixture registration evidence anchor from line 3470 to the actual token at line 3476. Preserve its row, predicate and reason; no new parity result or closed surface is claimed.
Closes #803, closes #804, closes #805.
Supersedes #808.
🤖 Generated with Claude Code