Repository navigation
Combine pull requests 781, 758, 780 and 783 with the corpus validation, trade text and RCI changes - #788
Conversation
…it text, byte-exact The report sink carries no entry comment and replaces invalid text, and the bounded text interface of the trade source had no production provider, so the text a strategy attaches to its orders could not be read back from the engine side. This adds a read-only adapter over the trade ledger and the engine report that implements the bounded, offset-based text reads of the trade source, and a separate opt-in companion output (runner option --trade-text) that writes one record per trade bound to the run and to the row, carrying entry id, exit id, entry comment and exit comment, with a closing record that carries the count and a digest. The sink format is untouched and a run without the option prints the same bytes as before. Invalid UTF-8 follows the sink's rule. No size cap is added. Documented in the report channel design page and the changelog. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A bounded drawing arena replaces its whole state with a deep copy on every create, delete and setter, whether or not a checkpoint shares it, so a script that moves a few of its live drawings per bar pays O(bound) per call and the first write after each checkpoint pays it again. The unbound arena already shares blocks of 32 records between copies and clones only the blocks a write reaches; this is the bounded twin of test_coof_drawing_checkpoint_cost. The test fills an arena to its bound (100 and 1,000), then runs the scheduler's checkpoint sequence (snapshot, restore, execute, commit) around an execution that deletes the oldest label, creates one, moves three and changes one text, all with texts that are never inline so a record copy allocates. Per execution it checks that the arena shares all but a few blocks of records with its checkpoint (the same record object through both) and that the heap blocks allocated do not depend on the bound, that the arena equals a plain model of the same operations after every execution, and that checkpointing an unwritten arena allocates the same at both bounds. The cost row is the row the change that follows must turn from red to green; the model row and the unchanged-checkpoint row are the guards that change has to keep green. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A bounded arena replaced its whole state with a deep copy on every create, delete and setter: every slot, the text of every label, the directory and the order, whether or not a script-state checkpoint still shared it. A script that moves a few of its live drawings on every bar therefore paid time proportional to the bound on every call, and the first write after each checkpoint paid it again. The slots now live in a DrawingRecordStore, the block store the unbound arena already uses: blocks of 32 that a copy of the state shares, one path copied per write that reaches a shared block. A copy of the state shares the blocks and copies only the directory and the order (an integer per occupant), the directory with room for every slot so a creation never reallocates it. Creation, deletion and every setter give the arena a state of its own when a checkpoint shares it, then change it in place. Each does every step that can allocate or throw (the state's copy, the copy of the slot's block, the directory's room, the order's growth) before its first change and only steps that cannot throw after it, so a refused allocation leaves the arena and its checkpoint as they were. The search for the lowest free slot starts at a recorded index below which every slot is occupied, so slot reuse order is unchanged and a creation no longer scans every slot. The bound, the typed overflow outcome, the stale-handle behaviour and every value a script reads are unchanged. The source allocation-bound gate (ci/cr150-source-bounds.yaml) pins every growable-container site of include/pineforge/**, so its reviewed site inventory moves with this change: the two groups for the removed whole-state copies are deleted and the OPEN ceiling drops by two; the groups for the slots (a block store filled by push_back), the directory and the state's allocation gain the new site identities. The inventory is the gate's own proposal for this tree; its differences from the previous one are exactly those sites. The gate's real-tree test pins the number of OPEN groups, so that pin moves by the same two. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Main moved to the hosted verification jobs and their documentation since this branch was cut. No file of this change is touched by those commits and no conflict arises. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… lines A bounded drawing arena's edits and checkpoints do no per-record work in the bound: they copy only the blocks of 32 records they write. They do not cost O(changes): the first write after a checkpoint still copies the slot directory and the creation order (one 8-byte integer per occupant), and deleting the oldest drawing moves the directory's entries. The test header and the CHANGELOG now say so, and the test's function is renamed to match. The source allocation-bound manifest keeps its line fields as diagnostics. The entries of drawing.hpp that the change moved (U1665, U1669, U1670, U1671, U1672) carry the first line the gate finds for them again. No identity changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The CHANGELOG entry and the cost test header of the bounded drawing change said that the first write after a checkpoint copies "one 8-byte integer per occupant". The slot directory holds two 32-bit integers per occupant (the id and the slot) and the creation order one 32-bit integer, so both now say "a directory entry and an order index per occupant". Words only: no code, no assertion and no manifest line changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Main moved by one commit since the previous merge: the hosted sanitizer builds get a dedicated data disk (two workflow files). No file of this change is touched by it and no conflict arises. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Assert open and closed short accessors preserve direction from a real fill.
Report signed quantities for open and closed short trades while preserving long, flat and bounds behavior.
The signed trade-size accessor fix intentionally removes two obsolete public statements from docs/pages/pine-to-native.md. The sentence introduced by 7328f4d is wrong after the fix because Pine's size accessor carries direction in its sign; the sentence introduced by cced2aa is the same obsolete unsigned/raw-quantity description. The replacement rows state positive long and negative short and distinguish raw magnitude fields with is_long. Name 7328f4d and cced2aa so the doc-reverts guard can verify why those historical sentences were removed.
The accessor bodies already return signed quantities; keep each expression on one source line so the existing documentation citations remain bound to the same header and implementation lines. This preserves the exact signed-size tree behavior while removing the anchor shift.
…n moved its lines The bounded drawing checkpoint test adds one source, test_drawing_bound_checkpoint_cost, to the TEST_SOURCES list near the top of tests/CMakeLists.txt, which moves every later line of that file by one. The evidence row for test_pooc_close_fill_view_tapes cites five of those lines: the line the sweep re-reads (3459, now 3460) and four in its reason text (:3443, :3455, :3479 and :3485-3501, now :3444, :3456, :3480 and :3486-3502). test_private_fixture_reads failed with "the token no longer sits on tests/CMakeLists.txt:3459", and test_private_fixture_reads_controls failed with it. Only those five numbers change; the row's text is otherwise as it was. Each new line was read from the file: 3444 is the EXISTS test of a tape, 3456 the increment of _pf_pcv_emitted, 3460 the condition that is the row's token, 3480 the registration of the test, 3486 the registration of the skipped placeholder. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Use GCC minimal debug information for instrumented Debug profiles while retaining file and line data, sanitizer flags and the full test selection. Keep the definition below the cited profile-floor table so existing documentation anchors remain valid. This is a measurement step: it lowers debug info only. The pass condition is at least 20 GB free after Verify on the worst hosted sanitizer shard. If that margin is not reached, each shard will build only its own targets next.
Update the margin-call twin assertion digest and register the pyramiding partial-drain signed-size rewrite in the twin parity inventory. Recompute the inventory hash so the guard covers both intentional assertion changes.
Build and select the existing ABI layout probe alongside the eleven existing fast executables. Update the derived membership pin, preserve prior checks, and exercise removal of the actual ABI row through the real workflow checker. Documentation replacement: the sentence "names its eleven real executables; configure refuses" now names twelve executables and explains the existing probe's Linux x86_64 GNU libstdc++ applicability.
The ABI smoke explanation adds two documentation lines. Correct both exact line-count expectations from 2060 to 2062 while retaining all substantive runner, slow-inventory and same-size negative checks.
Accept live_drawings through the existing typed limit helper and publish its English template, preserving the code identity, since value and prior limit values. Regenerate the registry and catalog diff and exercise distinct operator maxima through the real helper contract.
Bring the merged hosted release workflow and its CI documentation and checks into the candidate without rewriting the existing commits.
Bring the merged hosted release workflow and its CI documentation and checks into the candidate without rewriting the existing commits.
The merge gate now requires pineforge/parity and treats pineforge/verify as advisory, so the promotion workflow skipped every engine merge whose head carried no verify status. Admit on pineforge/parity success alone; a failed or absent parity still skips. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Retain the ABI smoke selector and its tests alongside the current engine changes.
Retain the runtime limit catalog addition alongside the current engine changes.
Takes in main since 0027d8e (89 commits). The two conflicts were additive: the runner usage text now lists both `--report-jsonl=delta-v2` and `--trade-text`, and the changelog keeps main's entries before the trade text entry. No other file of the companion channel overlaps a main change except runner/CMakeLists.txt and runner/README.md, which merged without conflict. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…site manifest, doc anchors The merge with main left four checks of the trade text companion failing. - test_trade_text_default_bytes took PINEFORGE_VERSION_FULL as the expected engine field. The report sink writes PINEFORGE_VERSION_STRING (MAJOR.MINOR.PATCH), and the full value gains a describe suffix on a tagged checkout, so the row only passed where describe was unavailable. It now takes PINEFORGE_VERSION_MMP, which is the value the sink writes in every configuration. - The allocation-bound manifest gets five unreviewed groups for the companion's source accessor and writer, its unreviewed ceiling goes from 1407 to 1412, the gate test pins 1356 + 56 + 184 open groups, and the site inventory gains the eleven concrete sites. No existing inventory record changes. - The runner's test block moves to the end of runner/CMakeLists.txt so the design doc lines that cite that file stay valid, and one main.cpp anchor follows the usage text lines to 344. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Require the complete parity-only head predicate while preserving main-copy, latest-status, pagination, tree, authorization and credential-order checks. Add Bash and jq status decisions and workflow mutation controls.
Normalize enclosing parentheses around the exact parity-success expression. Reject compound and malformed predicates, and cover parity-only, verify-only, combined-status and missing-status cases plus expression wrapping controls.
Point seven documentation citations at the matching catalog fields after the vocabulary additions shifted their lines.
…sult rules Brings the reviewed final head of the release admission contract into the branch that adds the corpus validation job variant. The incoming change makes the data-only admission entry pin the workflow_dispatch trigger and its inputs of the split release workflow, the repository context of the upload step, the main-only guard of the prebuilt build job and of its caller step, and the frozen legacy copies of the two current workflows, and it adds the negative tests for each of those pins. The merge is textually clean: the changes meet only in the two preflight files, in places that do not overlap the corpus variant rules. Nothing under .github or docs changes with it, so the two length pins of docs/ci.md stay at 2107 lines, which is the length of the merged document. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Add an end-to-end regression for the map pair limit: a committed, generated strategy library driven through the ordinary run_json command line in seven cases (finite boundary and refusal, omitted and explicit zero limit with two pair counts each, and a negative option), with an oracle that recomputes what to expect from the inputs. The row is slow-labelled, registered from its tests/cr150.d lane file with its library in the owning fence, guarded for sanitizer and coverage builds, and pinned (89 to 90) in the explicit slow-row policy. docs/ci.md: the slow-label bound paragraph and the slow-label inventory paragraph, introduced by 69cddc9 (#679), now state the size of the pinned set (90 names, including test_cr559_map_capacity_cli) instead of the retired 43 + 28 = 71 breakdown. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…tion Brings the head of the pull request that registers the rerun controller tests in the preflight plan into the branch that adds the corpus validation job variant. The two changes meet in one place: the stage inventory test of the preflight plan pins how many checks the plan holds (the whole plan, the fast tier, and the fast tier on the platforms that skip the prebuilt checks). The corpus change adds four checks and the rerun change adds one, so each of the three expectations is the sum of both additions: 71, 66 and 64. Every other hunk combines without a conflict, and no other line is edited by hand. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The census test of the corpus variant module requires every script test module to be named by a preflight row or to carry an explicit exemption, and it requires an exemption to be removed once a row names the module. The pull request that registers the rerun controller tests in the preflight plan names scripts/test_ci_rerun_preempted.py, so the combination with it fails that test until the exemption of the module is removed. This commit removes that one exemption line and changes nothing else. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…the process The checker's tests exercised the decision function and the exit codes 0 and 2, but nothing ran the script to a refusal, and nothing pinned the repository, the check name, the application and the host that the gate trusts. A script whose main returned 0 after printing a refusal, or whose constants named another repository or host, passed every test. This adds, in the checker's test module only: - a process-level test that runs the script against a local server for each refusal (the check missing, failed, pending, from another application id, from another application slug, and for another commit) and requires exit code 1, one reason line, no traceback and one request; - a test that the request names the pinned repository and the check name as literal text instead of through the script's own constants; - a test that a run without an explicit API URL asks the pinned repository on the pinned host; - a test that the four constants have their literal values. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…e tools The validator's build-and-probe stage (configure, build, library check, feed derivation, probe run and the comparison of each produced trade file's header with the recorded tape header) had no committed test; only one successful run on a real corpus checkout exercised it. A change that ignored a failed build or a failed probe, or stopped comparing headers, passed every test. This adds, in the validator's test module only, a test class that runs the stage against a tiny real Git repository whose tracked scripts are stubs, a fake cmake first on PATH and a plain corpus directory. The fake tools only decide which step fails. The tests require, for each step, the reported finding and whether it counts as an error: a failed configure or derivation is an error with its log shown; a failed build, a probe without exactly one library and a failed probe are findings; a renamed or missing header column, an undeclared trailing column and a repeated declared one are findings; the declared trailing column is accepted; the command helper returns the exit code and shows the log of a failure. They claim nothing about what a real compiler does. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The documentation of the corpus repository validation gate said that the validator measures the selected subset and that a coverage limit is a finding. The validator compares only the header of each produced trade file with the recorded tape header and never compares trades, and no code emits a coverage finding. The section also described the corpus workflow in the present tense although the workflow is added by a later corpus pull request. This rewrites the three sentences, quoted here as they were so that the documentation checker can see them named: - "The corpus workflow runs the engine's `scripts/validate_corpus_sha.py` against the proposed corpus checkout and prints the engine commit it ran." - "The validator checks recorded bytes and checkout cleanliness, builds the probes and measures the selected subset." - "A coverage limit is a finding; subset measurement does not establish full population parity." The page is two lines longer, 2109 lines, so the two length pins in the preflight tests move together. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… branch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665). It makes the preflight admit split release builds and retained smoke output, pins the identities of the split dispatch and of the legacy workflow fixtures, adds credential-withdrawal controls, and requires repository-bound uploads and main-only OIDC callers. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…anch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665), the release admission contract (130bda2) and the rerun-controller test registration (348a897). It adds the corpus record validator, the corpus gitlink result checker and the writer of the corpus file digest manifest with their tests and fixtures, lets the preflight admit the corpus validation job of the pull-request workflow, combines the preflight stage inventory with the rerun-controller test registration, and drops the census exemption of the rerun-controller tests. Its tests also cover the checker's refusals at process level and the validator's build and probe failures, and its documentation page states what those checks measure. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head is the trade text companion branch merged with main (63f3978), where the two arithmetic conflicts of the source allocation-bound gate (the ceiling and the pinned total) were resolved on the source branch itself. It adds the opt-in trade text option of the live runner. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… into the combined branch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665). It computes the simple moving average from a correctly rounded window sum, with tests that check the rounded window means, and records the new window container sites in the allocation-bound inventory. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
163abf5) into the combined branch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665). It adds an end-to-end regression for the map pair limit, driven through the ordinary command line over a committed generated strategy library in seven cases, registers it as a slow-labelled row from its tests/cr150.d lane file, and pins the explicit slow-row count (89 to 90) and the documentation that states it. docs/ci.md: the slow-label bound paragraph and the slow-label inventory paragraph, introduced by 69cddc9 (#679), now state the size of the pinned set (90 names, including test_cr559_map_capacity_cli) instead of the retired 43 + 28 = 71 breakdown. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ed branch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665). It stops the RCI oscillator from copying the price history while ranking, and puts the regression test for its workspace in the required technical-analysis unit target. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…sted state (head 000e2da) into the combined branch Plain merge of the source head into the combined branch; nothing was resolved by hand. The source head already contains main (755e665). It gives the private calculation group, the current execution frame and the margin liquidation of the native execution consumer explicit constructors with the same default values, so that constructing them in place compiles with Clang 18 and libstdc++ 13 in the default build with the tests on, and it moves nine source citations on three documentation pages by the five lines that the constructors add. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
| ' run: python3 base/scripts/check_corpus_gitlink_result.py --repo head ' | ||
| '--base "$BASE_SHA" --head "$HEAD_SHA"']: |
| 'gke-pr.yml build-debug must retain exactly its four smoke steps ' | ||
| 'and optional pinned final output collector', |
| require(stderr.read_bytes() == b"", f"{name}: unexpected stderr") | ||
| lines = stdout.read_text(encoding="utf-8").splitlines() | ||
| require(len(lines) == 1 and bool(lines[0]), f"{name}: expected one JSON line") | ||
| document = json.loads(lines[0], parse_constant=lambda value: reject(value)) |
| import sys | ||
| import tempfile | ||
| import threading | ||
| import unittest |
| import unittest | ||
|
|
||
| import ci_preflight | ||
| import test_ci_preflight as preflight_fixtures |
| import subprocess | ||
| import sys | ||
| import tempfile | ||
| import unittest |
There was a problem hiding this comment.
Graphify reviewed this change.
No issues found by static checks — no coupling regressions or blocking issues in the code graph. That is not the same as safe to merge: see what was not checked.
Not checked: tests were not run; formal verification proved 0 of 9 changed function(s) (1 sampled, not proven, 6 not verified).
Formal verification. 2 change(s) alter behavior, breaking input(s) attached. PR-changed functions: 3/9 verified (0 proven, 1 may-equivalent, 2 distinguished) · 6 not verified (2 vacuous, 4 unsupported).
Behavior changes: gke\_admit\_workflow\_findings changes behavior, here is the input that shows it.
The verifier found a concrete input on which gke\_admit\_workflow\_findings behaves differently before and after the change. If that change is intended, ship it; if not, this is your bug.
Guarantee: This difference was REPRODUCED, the verifier actually ran both versions on that input and saw them disagree. It is real, not an artifact.
Evidence: On input \{"workflow":"'a'","name":"''"\}, the old code produced \[': trigger must be exactly pull\_request\_target', ': trigger must restrict branches to main', ': trigger types are incomplete or reordered', ': run\-name must bind the PR number and head SHA', ':… but the new code produces \[': trigger must be exactly pull\_request\_target', ': trigger must restrict branches to main', ': trigger types are incomplete or reordered', ': run\-name must bind the PR number and head SHA', ':…. Paste that input straight into a regression test.
Behavior changes: release\_prebuilt\_workflow\_findings changes behavior, here is the input that shows it.
The verifier found a concrete input on which release\_prebuilt\_workflow\_findings behaves differently before and after the change. If that change is intended, ship it; if not, this is your bug.
Guarantee: This difference was REPRODUCED, the verifier actually ran both versions on that input and saw them disagree. It is real, not an artifact.
Evidence: On input \{"workflow":"'\\\\t\\\\n'"\}, the old code produced \['release\.yml prebuilt must retain needs: release before build', 'release\.yml prebuilt must retain workflow permissions: contents: write', 'release\.yml prebuilt must retain job permissions: conte… but the new code produces \['release\.yml prebuilt must retain exactly release, prebuilt and notify\-hub jobs', 'release\.yml prebuilt must retain needs: release before build', 'release\.yml prebuilt must retain workflow perm… (outputs first differ at character 37). Paste that input straight into a regression test.
Not verified on this run: args (unsupported), help (unsupported), run (unsupported), check\_commands (vacuous: never exercised), runner\_findings (vacuous: never exercised), calculate (unsupported).
Graphify review — findings
Adds an opt-in pineforge-live run --trade-text PATH companion file that writes all four trade text fields (entry/exit id and comment) per finished row, with run and row identity and a count/SHA-256 trailer. It is off by default, applies no text size cap, and leaves the primary report and sink bytes unchanged; the writer streams each field through a fixed transfer buffer, carrying partial UTF-8 bytes across transfers. The CR150 source-bounds ledger gains five unreviewed groups (ceiling 1404 → 1409) for the new text accessor and writer buffers, none of which is bounded. The ExactWindowSum window storage is also recorded in the source-site index. Drops the test_ci_rerun_preempted.py row from the "run it manually" table in AGENTS.md and CLAUDE.md, and adds a CHANGELOG entry for the new flag.
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 — 4432 functions depend on the 4146 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
ci_workflow_findings()— 88 callers, 24 callees - worse:
gke_admit_workflow_findings()— 18 callers, 14 callees - worse:
_job_values()— 33 callers, 3 callees - worse:
run()— 1 callers, 74 callees - worse:
admit_rule_findings()— 8 callers, 9 callees - worse:
release_prebuilt_workflow_findings()— 6 callers, 10 callees - worse:
_job_block()— 20 callers, 3 callees - worse:
runner_findings()— 2 callers, 28 callees - …and 9 more — each is listed as a finding
Verification — 4432 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: 4430 function(s) in the blast radius were not formally verified this run
Risky patterns (advisory)
- medium
no-stderr-to-stdoutinscripts/check_corpus_gitlink_result.py:184: error printed to stdout instead of stderr: print(f"corpus validation unreadable: {type(error).__name__}: {message}") - medium
no-stderr-to-stdoutinscripts/validate_corpus_sha.py:621: error printed to stdout instead of stderr: print(f"RESULT {('valid', 'invalid', 'error')[code]}") - medium
no-stderr-to-stdoutinscripts/write_corpus_file_digests.py:105: error printed to stdout instead of stderr: print(f"ERROR arguments: {error}") - medium
no-stderr-to-stdoutinscripts/write_corpus_file_digests.py:110: error printed to stdout instead of stderr: print(f"REFUSED {error}") - medium
no-stderr-to-stdoutinscripts/write_corpus_file_digests.py:114: error printed to stdout instead of stderr: print(f"ERROR {type(error).__name__}: {message}")
Docs that may be stale (advisory)
CONTRIBUTING.md§ The two layers, and the one rule (lines 26-59): references changed symbolsGeneratedStrategyCONTRIBUTING.md§ Development setup (lines 72-102): references changed symbolsbuild,gitCONTRIBUTING.md§ The gates (lines 123-158): references changed symbolsbuild,checkCONTRIBUTING.md§ Coverage (lines 272-286): references changed symbolsbuildCONTRIBUTING.md§ Commits and pull requests (lines 287-317): references changed symbolsgitREADME.md§ With an AI agent (MCP, Docker only) (lines 83-116): references changed symbolscommand,workREADME.md§ From source (lines 117-143): references changed symbolsbuild,gitREADME.md§ 1. PineScript, through codegen (lines 182-201): references changed symbolssharedREADME.md§ 2. C++, against the kernel (lines 202-235): references changed symbolsbuildREADME.md§ Validation scoreboard (lines 294-308): references changed symbolscheck
…and 10 more.
Formal verification
Behavior changes: gke\_admit\_workflow\_findings changes behavior, here is the input that shows it.
The verifier found a concrete input on which gke\_admit\_workflow\_findings behaves differently before and after the change. If that change is intended, ship it; if not, this is your bug.
Guarantee: This difference was REPRODUCED, the verifier actually ran both versions on that input and saw them disagree. It is real, not an artifact.
Evidence: On input \{"workflow":"'a'","name":"''"\}, the old code produced \[': trigger must be exactly pull\_request\_target', ': trigger must restrict branches to main', ': trigger types are incomplete or reordered', ': run\-name must bind the PR number and head SHA', ':… but the new code produces \[': trigger must be exactly pull\_request\_target', ': trigger must restrict branches to main', ': trigger types are incomplete or reordered', ': run\-name must bind the PR number and head SHA', ':…. Paste that input straight into a regression test.
Behavior changes: release\_prebuilt\_workflow\_findings changes behavior, here is the input that shows it.
The verifier found a concrete input on which release\_prebuilt\_workflow\_findings behaves differently before and after the change. If that change is intended, ship it; if not, this is your bug.
Guarantee: This difference was REPRODUCED, the verifier actually ran both versions on that input and saw them disagree. It is real, not an artifact.
Evidence: On input \{"workflow":"'\\\\t\\\\n'"\}, the old code produced \['release\.yml prebuilt must retain needs: release before build', 'release\.yml prebuilt must retain workflow permissions: contents: write', 'release\.yml prebuilt must retain job permissions: conte… but the new code produces \['release\.yml prebuilt must retain exactly release, prebuilt and notify\-hub jobs', 'release\.yml prebuilt must retain needs: release before build', 'release\.yml prebuilt must retain workflow perm… (outputs first differ at character 37). Paste that input straight into a regression test.
Could not verify: Could not verify args.
The verifier did not have enough to check args, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: unsupported return type: Config
Could not verify: Could not verify help.
The verifier did not have enough to check help, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: unsupported return type: void
Could not verify: Could not verify run.
The verifier did not have enough to check run, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: unsupported parameter type(s)
Could not verify: Could not verify check\_commands.
The verifier did not have enough to check check\_commands, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 90 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly NameError — names the real obstacle, not a sampling gap)
No difference found (not proven): No behavior difference found in release\_credential\_findings (not a proof).
The verifier ran both versions of release\_credential\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify runner\_findings.
The verifier did not have enough to check runner\_findings, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: non-vacuity: domain too small (only 2 distinct inputs exercised, need 3) — 'no divergence' would be near-vacuous
Could not verify: Could not verify calculate.
The verifier did not have enough to check calculate, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: unsupported: member function — receiver/self (`this`) not synthesizable from the simple-type literal pools — abstaining rather than guessing a receiver
· 9 grounded finding(s) anchored inline below; 8 more finding(s) on lines outside this diff (see the check run).
| ''' | ||
|
|
||
|
|
||
| def gke_admit_workflow_findings(workflow: str, name: str = 'gke-pr.yml') -> list[str]: |
There was a problem hiding this comment.
gke_admit_workflow_findings()
fans out to 14 callees (efferent coupling); 18 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return [step.rstrip('\n') for step in _steps(template)] | ||
|
|
||
|
|
||
| def _release_split_job_findings(job: str, body: str) -> list[str]: |
There was a problem hiding this comment.
_release_split_job_findings()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return findings | ||
|
|
||
|
|
||
| def _release_split_toolchain_reader_is_pinned(workflow: str, body: str) -> bool: |
There was a problem hiding this comment.
_release_split_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_workflow_findings(workflow: str) -> list[str]: |
There was a problem hiding this comment.
_release_split_workflow_findings()
fans out to 8 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| return findings | ||
|
|
||
|
|
||
| def release_prebuilt_workflow_findings(workflow: str) -> list[str]: |
There was a problem hiding this comment.
release_prebuilt_workflow_findings()
fans out to 10 callees (efferent coupling); 6 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| 'gke-pr.yml: admission workflow is missing']) | ||
|
|
||
|
|
||
| def main_admission_data_findings(workflows): |
There was a problem hiding this comment.
main_admission_data_findings()
6 callers depend on it (afferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| findings.append(f"records {root / FILE_DIGESTS}: {kind}: and {len(ordered) - 50} more") | ||
|
|
||
|
|
||
| def _file_census(root: Path, findings: list[str], counts: dict[str, int]) -> dict[str, str]: |
There was a problem hiding this comment.
_file_census()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| raise ValueError(message) | ||
|
|
||
|
|
||
| def main(argv: list[str] | None = None) -> int: |
There was a problem hiding this comment.
main()
fans out to 9 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
| raise ValueError(f"{root / name}: checkout is dirty ({flags.decode('ascii')})") | ||
|
|
||
|
|
||
| def write_file_digests(corpus: Path, output: Path | None = None) -> Path: |
There was a problem hiding this comment.
write_file_digests()
fans out to 7 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
…out of the combined branch Plain revert of the merge commit 3f22452 (git revert -m 1); nothing was resolved by hand and the revert had no conflict. The parity measurement of the combined branch with this change showed 40 probes whose graded tier falls against their committed TradingView tapes (every one of them calls ta.sma) and no other probe that changes; a measurement of main plus only this change gave the same 40 results. A fresh TradingView export of two of these probes agrees with the new arithmetic, so the committed tapes of the others are expected to be out of date. The change leaves this branch and returns on its own with refreshed tapes. The six other members are unchanged. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Summary
This branch combines seven source heads into one change on top of main (
755e6658), so that the build, the parity sweep and the review each run once. Every source head was merged with an ordinary merge commit: nothing was rebased, nothing was squashed inside the branch, no conflict occurred in these merges and nothing was resolved by hand. Every source head contains main (755e6658) except the trade text channel's, which contains the main before one documentation-only commit (63f3978a); the combined branch contains main. When this change merges, pull requests 781, 758, 780 and 783 are closed with a link to it.A moving average change (head
4c5c65f4, "Compute SMA from a correctly rounded window sum") was merged into this branch between the trade text channel and #783 and is taken out again by the last commit of the branch, a plain revert of that merge (git revert -m 1, no conflict). The parity measurement of the branch with it showed 40 probes whose graded tier falls against their committed TradingView tapes, every one of them callingta.sma; a measurement of main plus only that change gave the same 40 results, and no other probe changed. The change returns on its own with refreshed tapes. The tree of this branch equals the tree of the seven heads below merged on main without it.PR type: code (engine sources, tests, CI scripts and documentation).
Fixes #779
Sources
130bda2db570bd63bdec57b6b5fdd3cabacab7fc46bb21fb169091722d49d3b2f2e4f1f589148166348a89766e0ff23f88b4837bce80957f7635ef8e5930d7f8d12010d67c77a098804eb6cd295095db163abf58f1a73c7ec9160120774954fb29f4bd2d022750f8451aadd93066ffad3b54695e23956116000e2dac0e8e5e73fe53551adec7fbdf3f251af6The head listed for the corpus validation change already contains the heads listed for #781 and #758, so merging it brings both along and the separate merge of the #758 head changes nothing (it is listed because its pull request closes with this change). The merges that this branch makes of the source heads resolve no conflict by hand. The source histories themselves carry six merges that were resolved by hand in their own branches, before the heads were handed over: three in the history of the corpus validation head and three in the history of the trade text channel head. Corpus validation:
d482eb37(scripts/test_ci_preflight.py: the stage-inventory counts between the registration of the rerun-controller tests and the corpus validation job),f7519bb8(scripts/ci_preflight.pyandscripts/test_ci_preflight.py) andcecedc0e(CHANGELOG.md,ci/cr150-source-bounds.yaml,scripts/test_cr150_source_gate.pyandtests/private_fixture_reads.evidence). Trade text channel:09c9fb52(CHANGELOG.mdandrunner/main.cpp),8c17d14eand5930d7f8(both inci/cr150-source-bounds.yamlandscripts/test_cr150_source_gate.py). The head listed for #758 is that pull request's branch merged once with main; the head published on #758 is older. The head listed for #780 is the head of its branch (the construction fixes and the refreshed source citations in three documentation pages).How it was built
The merges were made in the order of the table, with the moving average change between the trade text channel and #783 (see above), except that the separate merge of the #758 head was skipped because the corpus validation head contains it. Relative to main, 52 files change. Besides the files that #781 and #758 share with the corpus validation head, three files are touched by more than one source and were merged automatically without a conflict:
docs/ci.md(the corpus validation change and #783),docs/design/native-feature-parity.md(the trade text channel and #780) andscripts/test_ci_preflight.py(#781, #758, the corpus validation change and #783). For every source, the changed lines of the files that only it touches equal the changed lines of this branch, and for every shared file the union of the sources' changed lines equals the branch's; an independent chain of the same merges in the reverse order gives the same tree.docs/ci.md: the slow-label bound paragraph and the slow-label inventory
paragraph, introduced by 69cddc9 (#679), now state the size of the pinned set
(90 names, including test_cr559_map_capacity_cli) instead of the retired
43 + 28 = 71 breakdown.
docs/ci.md: the three sentences of 42527b6 (#704) that said gke-pr.yml admits exactly two variants, that OLD is the shape without the arm job kept so earlier workflow files still pass, that NEW requires the exact arm classifier output, and that hybrids and extra jobs, outputs, needs or arm steps are refused while OLD retains its original exact rules and templates for a workflow without the arm job, are rewritten to cover the arm and the corpus variants.
What is still required before merge
CI green on this head, one parity sweep against the active baseline, one review of the combined diff that cites each source and of the revert commit, and the native and live runs of the post-merge workflow on the exact tree before the merge. The results already recorded on the individual pull requests and branches, and the parity sweep of the head that still contained the moving average change, are not repeated here and do not stand in for these.
🤖 Generated with Claude Code