Repository navigation
metrics: typed report_result_invalid for overflow; annualised metrics under one day are null with a reason (rev 3.1, CR-202) - #450
Closed
luisleo526 wants to merge 12 commits into
Closed
luisleo526 wants to merge 12 commits into
luisleo526 wants to merge 12 commits into
Conversation
…s (CR-202) Report metrics that overflowed (buy_hold_return, cagr and every other product, ratio, sum or annualisation in engine_metrics.cpp, engine_report.cpp, runner/report.hpp and docker/run_json.py) were silently serialised as null. Revision 3 Appendix A:82-83 and :93 allow null only for a defined absence, so an overflowed value now raises the typed report_result_invalid (reason nonfinite) at the computation that produced it. - src/report_value_invalid.hpp: one finite-value guard on the existing coded-failure mechanism. - engine_metrics.cpp / engine_report.cpp / runner/report.hpp / run_json.py: checked reductions and ratios; defined-domain nulls unchanged. - tests/ownership/probes/report/buy_hold_return_overflow: the c18_3 probe, pinned in the manifest and its checker. - tests/test_metrics_overflow.cpp: native boundary and absence controls for all 87 floating metrics; Python serializer expectations updated. Not yet run on the lab: the red-first proof and the gate follow. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ix 1) The kernel guard for the monthly Sharpe and Sortino ratios carried the public keys metrics.equity.sharpe_tv / sortino_tv as string literals, which the kernel-residuals preflight check rejects (src/engine_metrics.cpp:327). The kernel now names its own fields (sharpe_monthly / sortino_monthly) and the public wire layer maps the last path segment of a report_result_invalid args.field with the existing EQUITY_REPORT_KEYS, so the wire still shows sharpe_tv / sortino_tv as revision 3 Appendix A requires. Native tests expect the native field; Python tests keep the public name on the wire, and fields outside the monthly aliases pass through unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ix 2) The first lab proof of the overflow guard failed 22 existing tests: - A settlement-row failure (engine_invariant, PF_NATIVE_E_RUN_FAILED) was turned into PF_NATIVE_E_STATE by the C wrapper when the partial report of the failed run then overflowed. strategy_native_run_v1 now keeps the earlier typed failure and its run-failed status when fill_report rethrows exactly that failure; a report overflow after a successful run still records the report_result_invalid detail (revision 3 Appendix A:87, section 2). - Fixtures whose annualised CAGR (or Calmar) really overflows binary64 now expect the typed report_result_invalid failure (Appendix A:83, A:93). The expected field is predicted from the frozen equity_stats_reference walk, never from the observed exception; finite controls keep every original assertion, and the overflow-free twin of each shortened fixture is kept. - test_metrics_overflow: the two return_sum tapes overflow earlier, in the runup percentage; their expected fields follow that trace and isolated shared-sum cases cover the helper. - test_metrics_overflow is registered after the evidence-pinned lines of tests/CMakeLists.txt (private_fixture_reads). The ownership probe files and manifest are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ix 2 docs/adr/0001-kernel-adapter-boundary.md:764 cited strategy_configure_native_ext_result_v1 at native_c_host.cpp:4066; the report-failure precedence change above it moved the definition to :4091 (check_doc_anchors, preflight stage doc-anchors). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Proof 4 stopped in the Release build: two test hosts called the private PineStrategyHost::present_report from a derived class. The tests now observe the engine's own data through the public report read (or, for the amended trade row, the two protected section helpers on a genuine derived instance) and predict the rejected metric from the frozen equity_stats_reference walk after the call. No production header, access or behaviour changes. Also: self-contained include and inline template in report_failure_checks.hpp, and include/read guards for the historical-header (R4D harvest) configurations of the quiet-bar, brackets and anchored-legs tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…d calmar (CR-202 fix 4) L6 ruled option (b): the annualised metrics cagr and calmar are a DEFINED absence (null with the named reason span_too_short_to_annualize) when the measured span is under one day; an overflow on a span of one day or more, and every non-annualised overflow, stays the typed report_result_invalid fault. - Measured span: last minus first equity-curve point time_ms (UTC epoch milliseconds, the bar clock), unsigned difference; under one day means strictly less than 86,400,000 ms. The test runs before the ratio and pow. - One policy list, docker/report_annualization.def, included by the C++ metric walk (src/metrics_annualization.hpp) and read by run_json.py, so the span and the field list exist in one place. - The reason is written outside the revision-3 digest: diagnostics.annualization in the public report, only when the rule fired and the metric is null. - docs/design/selected-window-wire-v1.3-revision-3.1.md and docs/pages/report-schema.md state the clarification. - Tests: the short-span fixtures of fix 2/3 go back to completing with null; new cases cover 7 minutes, 86,399,999 ms, exactly one day, an overflow at one day and at several days, and the non-annualised buy_hold_return overflow on a sub-day span; the wire test shows the reason only when the rule fired. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… return (CR-202 fix 4b)
Proof 6 failed two ways:
- scripts/check_selected_window_ownership.py reads build_report_dict as ONE
returned dict literal; the revision 3.1 change had turned it into
out = {...}; return out. The builder returns the literal again and merges
the diagnostics entry inside it through a small helper.
- run_json.py read docker/report_annualization.def at import, but the product
and the ownership box ship docker/*.py without data files, so every run
printed nothing. run_json.py now carries the two policy facts (86,400,000 ms;
cagr and calmar) itself, and a test pins them to the .def the native metric
walk includes.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sion 3.1 helpers (CR-202 fix 4c) tests/ownership/test_manifest_checker.py compiles only a named set of pure functions and assignments out of docker/run_json.py; build_report_dict now calls _annualization_block / _annualization_diagnostics and reads the two policy constants, so the extraction set names them. Doc citations into docker/run_json.py and tests/test_adapter_quiet_bar.cpp are refreshed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…kes (CR-202 fix 4d) test_metrics_overflow.cpp handed a ReportC to live::native_report_json, which takes the pf_report_t twin (proof 8 release build). ReportC mirrors pf_report_t member for member; the test casts like src/native_c_host.cpp does at the C boundary and a static_assert on the sizes keeps the cast honest. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…CR-202) kNeutralReportDigest folds report.metrics. The fixture is a seven-minute +8% run, so under revision 3.1 its cagr and calmar are the defined absence (span under one day) where main computed finite values; the metrics bytes move by that rule only, trades and hashes are unchanged. The new value is the lab-measured digest printed by job rj-20261019t210726-6fa3f7, applied under CORE-TOP's fixture authority of 10-20 05:48. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Brings the branch up to the release commit: VERSION and docker/run_failure_codes_diff.json (metadata of the rc.1 cut). No other file differs. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Metrics overflow: revision 3.1 (CR-202, for 1.6.2 final)
CR-202, for the 1.6.2 final. Under revision 3 there is no catch-all null for overflowing report metrics. The owner-approved clarification REVISION 3.1 (L6 ruling 10-20) adds one defined exception:
nullwith a named reason,diagnostics.annualization.<field>. The run completes.report_result_invalidfault.The pinned neutral-report digest in
tests/test_native_anchored_legs.cppis re-pinned to the lab-harvested value17583267501122239024(rj-20261019t210726-6fa3f7). The 7-minute fixture's cagr/calmar now become null by the rule; nothing else in the digest moved.Proof 10 (rj-20261019t215306-ac540a, squash tree == c901d07): preflight; release 961/961; debug 942/942; docs.
This head merges main 7bd065c (v1.6.2-rc.1): only VERSION and docker/run_failure_codes_diff.json change. The delta steps and ONE full parity sweep run on this head.
Squash body: see the commit message file of the lane.
🤖 Generated with Claude Code