Repository navigation
Add the run option series_origin_ms: declare where the reference series starts - #766
Conversation
…es starts The source host takes the metadata key series_origin_ms (a positive epoch ms: the open time of the first bar of the series the reference ran on) and sets the two switches it already has, chart_ema_na_warmup and security_range_start_na_warmup with the origin as the range start. A value that is not finite or not positive changes nothing; a raw key set afterwards wins for its own context. A run that does not declare the key is unchanged. The hub's --syminfo document takes the same key as a positive JSON integer (anything else is syminfo_unreadable, reason value_type), applies it through strategy_set_syminfo_metadata after the lot grid and before mintick, and records it in applied_runtime.syminfo with the first fed bar, the offset, and a warning field when the origin is later than the first fed bar. The documentation states the security effect, the wrong-origin limit and that the key has no defined meaning in a live run. Tests: test_series_origin_tailh_tape (private tape, guarded placeholder when absent) compares a plain chart ta.ema(close, 12) probe with TradingView's exit comments over 336 exits; test_series_origin_host (public, synthetic feeds) covers the undeclared seed, the declared na-then-SMA seed written from its definition, invalid values changing nothing, the request.security start and last-writer order with the raw chart_ema_na_warmup key; tests/test_series_origin_run_json.py covers the hub's typed key, its echo and the malformed values. Registered in the private-fixture form with the manifest, inventory, count and line pins, recounted on the current main. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Main moved on since this change was based on it. One file conflicts: tests/private_fixture_reads.evidence cites lines of tests/CMakeLists.txt, and this change adds eight lines to that file above the cited block, so every cited line moves by eight: the cited tokens now sit on lines 3467, 3487, 3451 and 3463, and the else branch on lines 3493 to 3509. The numbers are re-read from the merged file, and the wording of the row is main's. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…oved The change adds lines to docker/run_json.py, src/source/pine_strategy_host.cpp, include/pineforge/pineforge.h and include/pineforge/source/pine_strategy_host.hpp, which moves every citation below its hunks in the pages that cite those files. Each cited number of such a file is mapped through the lines that the merge added (the line mapping of `git diff` of main against the merged tree) and the page text is rewritten in place: 220 citations move, none of them cited a line that the merge itself changed, and scripts/check_doc_anchors.py reports every anchor resolved to its symbol (2346 of 2346). Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The option is public surface of the next release (the source host's metadata key and the --syminfo document of docker/run_json.py); the release notes name it with what it changes and what it leaves alone. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… more in the memory page scripts/check_doc_anchors.py scans a fixed set of pages and does not scan docker/README.md, so the earlier re-anchoring left its eleven citations of docker/run_json.py at the numbers they had before this change added lines to that file. Each is mapped through the lines the change added (the line mapping of `git diff` of main against this head), as the other pages were; none cited a line the change itself edited. docs/pages/memory-management.md cites two run_json.py lines in one row and only the first had moved; the second moves by the same amount (both numbers were already off on main, which this commit does not change). Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…tate its value rules as the README does docker/README.md introduced the option with "In the next release", which reads wrong once it is released; the changelog carries the scope, so the phrase goes. The changelog sentence on malformed values said that any other value fails with syminfo_unreadable; the README is narrower and exact: 0, a negative number, a float, a string, a boolean, NaN or Infinity fail, an absent or null value applies nothing, and the source host ignores a value that is not finite or not positive. The changelog now says that. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
| if offset < 0: | ||
| expected["series_origin_warning"] = "origin_after_first_bar" | ||
| assert run_json.series_origin_echo(applied, FIRST) == expected | ||
| assert applied == si # pure helper does not modify the validated snapshot |
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 4 changed function(s) (4 not verified).
Formal verification. PR-changed functions: 0/4 verified (0 proven, 0 may-equivalent, 0 distinguished) · 4 not verified (2 vacuous, 1 unsupported, 1 error).
Not verified on this run: \_main (vacuous: never exercised), \_selected\_run (vacuous: never exercised), apply\_syminfo (error), set\_syminfo\_metadata (unsupported).
Graphify review — findings
Adds a series_origin_ms run option that declares the open time of the first bar of the series the reference ran on. Declaring it turns on TradingView-style EMA warmup (na for the first length - 1 inputs, then an SMA seed, including the EMAs inside ta.macd, ta.kc and ta.tsi) and starts request.security at the first whole bucket opening at or after the origin. Runs that don't declare it keep the same report and fingerprint. apply_syminfo in docker/run_json.py accepts it from the --syminfo document only as a positive JSON integer, sends it through strategy_set_syminfo_metadata, and fails with syminfo_unreadable for zero, negatives, floats, strings, booleans, NaN or Infinity. The range of accepted integers is not bounded before the value reaches the setter call. series_origin_echo adds the first fed bar and offset to applied_runtime.syminfo, plus an origin_after_first_bar warning when the origin is later than that bar. The README and changelog document the option, and the docker/run_json.py line references in the README are renumbered.
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 — 5005 functions depend on the 2225 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
_make_state()— 1 callers, 11 callees - worse:
_make_state()— 1 callers, 10 callees - new:
read_tape()— 1 callers, 6 callees
Verification — 5005 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: 4792 function(s) in the blast radius were not formally verified this run
Docs that may be stale (advisory)
docs/pages/native-engine.md§ Selected exposure and current execution (lines 541-737): references changed symbolsapplydocs/pine-adapter-kernel-notes.md§ 4. Other orphaned fill / bracket / margin notes (lines 819-1024): references changed symbolsapplytests/mutations/README.md§ Dormant-book mutation patches (lines 1-110): references changed symbolsapply
Formal verification
Could not verify: Could not verify \_main.
The verifier did not have enough to check \_main, 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 261 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly TypeError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify \_selected\_run.
The verifier did not have enough to check \_selected\_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: not verifiable: all 117 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly ModuleNotFoundError — names the real obstacle, not a sampling gap)
Verification did not run: Verification did not run for apply\_syminfo.
The verification could not execute (an environment/toolchain issue, not a statement about the code).
Guarantee: No guarantee, the check itself did not complete.
Note: Detail: harness produced no verdict (rc=120):
Could not verify: Could not verify set\_syminfo\_metadata.
The verifier did not have enough to check set\_syminfo\_metadata, 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
· 1 grounded finding(s) anchored inline below; 2 more finding(s) on lines outside this diff (see the check run).
| bool entry_seen = false, exit_seen = false; | ||
| }; | ||
|
|
||
| std::map<std::int64_t, TapeExit> read_tape() { |
There was a problem hiding this comment.
read_tape()
fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.
Summary
Adds the run option
series_origin_ms: the open time, in epoch milliseconds, of the first bar of the series the reference (TradingView) ran on, which may differ from the feed start or the report window. Declaring it makes the engine start the reference series' indicators the way TradingView does at the start of its series.series_origin_ms(a positive epoch time in milliseconds) and sets the two switches it already has:chart_ema_na_warmupandsecurity_range_start_na_warmup(with the origin as the range start).ta.ema, and the EMAs insideta.macd,ta.kcandta.tsi, then answernafor the firstlength - 1inputs and start from an SMA seed;request.securitystarts at the first whole bucket that opens at or after the origin. A value that is not finite or not positive changes nothing; a raw key set afterwards wins for its own context.--syminfodocument ofdocker/run_json.pytakes the same key as a positive JSON integer (0, a negative number, a float, a string, a boolean,NaNorInfinityfails withsyminfo_unreadable, reasonvalue_type; absent ornullapplies nothing), applies it throughstrategy_set_syminfo_metadataafter the lot grid and before the mintick, and records it inapplied_runtime.syminfowith the first fed bar, the offset and a warning field when the origin is later than the first fed bar.docker/README.mdstates the security effect, the wrong-origin limit and the live-run limit;CHANGELOG.mdhas a bullet for the option.Tests
test_series_origin_host(public, synthetic feeds): the undeclared seed, the declared na-then-SMA seed written from its definition, invalid values changing nothing, therequest.securitystart, and the last-writer order with the rawchart_ema_na_warmupkey.tests/test_series_origin_run_json.py: the hub's typed key, its echo and the malformed values.test_series_origin_tailh_tape(private tape, a guarded placeholder when it is absent): a plain chartta.ema(close, 12)probe compared with TradingView's exit comments over 336 exits.Merge with main, and the documentation citations
This branch carries one plain merge of main. The one conflict is the line-pinned citation row of
tests/private_fixture_reads.evidence: this change adds eight lines totests/CMakeLists.txtabove the cited block, so every cited line moved by eight and was re-read from the merged file. The change also adds lines todocker/run_json.py,src/source/pine_strategy_host.cpp,include/pineforge/pineforge.hand the host header, which moved citations in the documentation: 220 anchors of the pages thatscripts/check_doc_anchors.pyscans, 11 indocker/README.md(which that script does not scan) and one indocs/pages/memory-management.md. Each was mapped through the lines the change added; none cited a line the change itself edited. The checker reports all 2,346 anchors resolved.Not run
test_series_origin_tailh_tapeneeds the private tape; it skips without it, as in CI.scripts/test_ci_verify.py, which holds the registered-row count pin (380; the rows file agrees).ci/cr150-source-reading.*,scripts/ci_verify.pycomments,tests/heap_census_report.mdand sample strings of five test files) were not moved; no test reads those lines.🤖 Generated with Claude Code