From 7928a86ef95ed0c934ff8a9c70f002a21d85c3ec Mon Sep 17 00:00:00 2001 From: luisleo526 Date: Fri, 9 Oct 2026 19:25:37 +0800 Subject: [PATCH 1/2] docs: record the native attempt-report fix under 1.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the Unreleased heading to "1.5.0 — Unreleased" and add one bullet for #361: a batch run call's report belongs to its own attempt, a call that does not begin a run gets the empty report and a failure status instead of OK or an earlier payload, a started-then-failed run and the explicit stream snapshot keep their reports, and the engine-owned gate covers the C, native-module and generated wrappers with no change to emitted source. The recorded-outputs entry is unchanged byte for byte. CHANGELOG.md only: no source, version, date, tag or patch-line change. Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f699648..3f7dee95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ README's *Releases* section and on the GitHub releases page. From 1.0.0 the version number follows semantic versioning over the surfaces the [public contract](docs/pages/public-contract.md) lists. -## Unreleased +## 1.5.0 — Unreleased - **Recorded outputs.** A module can record what it computes on each bar besides its trades: doubles in named slots per bar, doubles kept once per @@ -31,6 +31,22 @@ version number follows semantic versioning over the surfaces the symbol are unchanged, and `PF_ABI_VERSION` stays 4. The new members enter `engine_script_run_v19` without an epoch; a C++ object compiled against an earlier v19 header is rebuilt with the library. +- **A run's report belongs to the call that began it ([#361]).** A batch run + call returns the report of its own attempt. A call that does not begin a run + (a begin outside `Ready`, a refused bar array or run option, a calendar or + timezone refusal, a begin over a live stream) now gets the empty report + (every array `NULL`, every count 0) instead of the rows the handle kept from + an earlier call, and `strategy_native_run_v1` answers it + `PF_NATIVE_E_RUN_FAILED`, never `PF_NATIVE_OK`; the reason stays in + `strategy_get_last_error`. A run that began and then failed still publishes + its partial report, and `strategy_stream_fill_report`, the explicit stream + snapshot, still returns a live stream's rows, even after a batch call was + refused over the stream. The gate is the engine's own report reader, + `BacktestEngine::fill_report`, so the C and native-module entry points and + the generated `run_backtest` / `run_backtest_full` wrappers all obey it, with + no change to emitted source. + +[#361]: https://github.com/pineforge-4pass/pineforge-engine/pull/361 ## 1.4.0 — 2026-10-08 From 0c055fc68953d96a79e932c2982d570b846c322f Mon Sep 17 00:00:00 2001 From: luisleo526 Date: Fri, 9 Oct 2026 19:49:21 +0800 Subject: [PATCH 2/2] docs: scope the batch report promise to engine pre-begin refusals A call that reaches the engine answers its own attempt's report. The empty report and PF_NATIVE_E_RUN_FAILED now cover only calls the engine refuses before it begins a run. The C entry's PF_NATIVE_E_HANDLE and PF_NATIVE_E_ARGUMENT checks and native-module argument preflight still return before the engine runs and leave caller output untouched, as native_c_api.h and native_module.hpp already state. Changelog wording only: no source, header or test change. Co-Authored-By: Claude Haiku 5.5 --- CHANGELOG.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f7dee95..b3ee7fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,15 +31,18 @@ version number follows semantic versioning over the surfaces the symbol are unchanged, and `PF_ABI_VERSION` stays 4. The new members enter `engine_script_run_v19` without an epoch; a C++ object compiled against an earlier v19 header is rebuilt with the library. -- **A run's report belongs to the call that began it ([#361]).** A batch run - call returns the report of its own attempt. A call that does not begin a run - (a begin outside `Ready`, a refused bar array or run option, a calendar or - timezone refusal, a begin over a live stream) now gets the empty report - (every array `NULL`, every count 0) instead of the rows the handle kept from - an earlier call, and `strategy_native_run_v1` answers it - `PF_NATIVE_E_RUN_FAILED`, never `PF_NATIVE_OK`; the reason stays in - `strategy_get_last_error`. A run that began and then failed still publishes - its partial report, and `strategy_stream_fill_report`, the explicit stream +- **A run's report belongs to the call that began it ([#361]).** Once a call + reaches the engine, its batch report belongs to that call's attempt. A call + the engine refuses before it begins a run (a begin outside `Ready`, a refused + bar array or run option, a calendar or timezone refusal, a begin over a live + stream) now gets the empty report (every array `NULL`, every count 0) instead + of the rows the handle kept from an earlier call, and + `strategy_native_run_v1` answers it `PF_NATIVE_E_RUN_FAILED`, never + `PF_NATIVE_OK`; the reason stays in `strategy_get_last_error`. The C entry's + `PF_NATIVE_E_HANDLE` and `PF_NATIVE_E_ARGUMENT` checks, and native-module + argument preflight, still return before the engine runs and leave caller + output untouched. A run that began and then failed still publishes its + partial report, and `strategy_stream_fill_report`, the explicit stream snapshot, still returns a live stream's rows, even after a batch call was refused over the stream. The gate is the engine's own report reader, `BacktestEngine::fill_report`, so the C and native-module entry points and