Skip to content

1.7.0 release prep: CHANGELOG 1.7.0 — 2026-10-25, stale 'unreleased' pointers, macOS build fix (::sig*set macros) - #500

Merged
luisleo526 merged 3 commits into
mainfrom
docs/changelog-1.7.0
Oct 24, 2026
Merged

luisleo526 merged 3 commits into
mainfrom
docs/changelog-1.7.0

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Docs-only (CHANGELOG.md only) for the 1.7.0 tag, on main 91353de (#499). Names the section ## 1.7.0 — 2026-10-25 (was ## Unreleased); states the closed-trade read cache by entry point (no sink: up to 20,447,232 B; sink installed, incl. the release image's docker/run_json.py default unjailed profile: fixed 39,936 B, closed-trade loops over 128 trades re-read from scratch); the Known-limits slowdown line with measured figures: hungpixi through the release image's docker/run_json.py default profile did not finish within 1800 s (stopped at the cap) vs 74.18 s on 1.6.3 on the same box; through scripts/run_strategy.py without a sink (hosted case runner, verifier, sweep) 107.2 s (mean of three); peak RSS scripts/run_strategy.py default path, hl2-01, 100,000 bars, n=3: 144.9 MiB on 1.6.3 vs 125.7 MiB on 1.7.0. src/, include/, tests/ unchanged.

Checks on this head: preflight rj-20261024t211651-b7d846, docs rj-20261024t211655-191c85. REV-CX GO (numbers vs SM-CX's rows), SM-CX checked every figure. VERSION untouched (release.yml writes it).

--- commit message ---
CHANGELOG: say which entry points run with a report sink, and what that costs on the release image

The closed-trade cache bullet said how big the ledger read cache is with and without a report
sink but not which entry points install one. It now names them, from the tree: a handle has no
sink until its host calls strategy_set_report_sink_v1 or strategy_set_report_sink_fd_v1; the C
API used directly, C++ hosts including the Pine host, the runner/ command line,
scripts/run_strategy.py without PINEFORGE_REPORT_SINK=1 and docker/run_json.py --profile jailed
without --report-sink-fd keep the 65,536-row cache (20,447,232 bytes); docker/run_json.py in its
default unjailed profile (it installs a temporary sink on every handle), the jailed profile with
--report-sink-fd, run_strategy.py with PINEFORGE_REPORT_SINK=1 and any host that installs a sink
get the 128-row cache (39,936 bytes), and a closed-trade loop over more than 128 rows re-reads
the colliding rows from scratch files on every pass (every row from 256 closed trades on). The
App's jailed host is stated as not known.

The "Costs that remain" slowdown bullet gains the measurements that go with it, each taken on
one 16 vCPU machine: the six-script figures were measured through scripts/run_strategy.py,
which installs no sink unless PINEFORGE_REPORT_SINK=1 (it was not), so the large cache was in
effect; hungpixi (24,238 closed trades) through the release image's default docker/run_json.py
took 74.18 s on 1.6.3 and did not finish within 1800 s on 1.7.0 (the run was stopped at that
limit); through scripts/run_strategy.py without a sink it takes 107.2 s (mean of three runs);
peak RSS of the default run_strategy.py path (hl2-01, 100,000 bars, n=3) is 144.9 MiB on 1.6.3
and 125.7 MiB on 1.7.0. No statement is made that the run_json.py results are identical: the
1.7.0 run produced none.

Replaced sentences (all four are in the closed-trade cache bullet of CHANGELOG.md on main
91353de, the 1.7.0 line squash of #499, and are replaced here):

  • "Without a report sink the cache holds at most TradeLedger::kDefaultCacheRows = 65,536 rows
    of TradeLedger::kLedgerEntryBytes = 312 bytes, 20,447,232 bytes, and is allocated at the
    smaller of that budget ... 20,447,232 bytes above 32,768." is now the sentence beginning
    "A run with no report sink holds at most".
  • "With a report sink installed the budget is TradeLedger::kSinkCacheRows = 128 rows,
    39,936 bytes, a fixed bound ... so that the sink run's working memory stays flat." is now
    the sentence beginning "A run with a report sink installed holds at most".
  • "Above the budget the cache is direct-mapped, so rows that share a slot evict each other ...
    with a report sink, 2 x (N - 128) rows per pass below 256 closed trades, and every row from
    256 on." keeps both formulas and now says "with no sink" and "with a sink".
  • "The budget has no user control in this release: NativeExecutionConsumer::begin_ready sets
    it at every run begin ... and nothing in the C API or the environment changes either
    figure." is now "The two figures cannot be changed by a user in this release: ... installing
    a sink or not is the only choice." (the environment variable PINEFORGE_REPORT_SINK does choose
    whether run_strategy.py installs a sink, so the old sentence overstated).

One more sentence of main's text is reworded in the same bullet: "The six are not a sample of
all scripts, and the results are identical in every measured case." now ends "identical in
every one of those six measured cases", because the run_json.py hungpixi run added below has no
1.7.0 result to compare. The not-affected sentence names the hosted case runner, the verifier
and the sweep, and states that the corpus-parity canary pass sets PINEFORGE_REPORT_SINK=1
(scripts/check_corpus_parity.sh, line 316).

The heading of the 1.7.0 section is renamed: the line "## Unreleased" is replaced by
"## 1.7.0 — 2026-10-25" (same form as "## 1.6.1 — 2026-10-18"). VERSION is not touched here.

Only CHANGELOG.md changes; no citation moves.

Co-Authored-By: Claude Sonnet 5.5 [email protected]

🤖 Generated with Claude Code

luisleo526 and others added 3 commits October 25, 2026 05:16
…at costs on the release image

The closed-trade cache bullet said how big the ledger read cache is with and without a report
sink but not which entry points install one. It now names them, from the tree: a handle has no
sink until its host calls strategy_set_report_sink_v1 or strategy_set_report_sink_fd_v1; the C
API used directly, C++ hosts including the Pine host, the runner/ command line,
scripts/run_strategy.py without PINEFORGE_REPORT_SINK=1 and docker/run_json.py --profile jailed
without --report-sink-fd keep the 65,536-row cache (20,447,232 bytes); docker/run_json.py in its
default unjailed profile (it installs a temporary sink on every handle), the jailed profile with
--report-sink-fd, run_strategy.py with PINEFORGE_REPORT_SINK=1 and any host that installs a sink
get the 128-row cache (39,936 bytes), and a closed-trade loop over more than 128 rows re-reads
the colliding rows from scratch files on every pass (every row from 256 closed trades on). The
App's jailed host is stated as not known.

The "Costs that remain" slowdown bullet gains the measurements that go with it, each taken on
one 16 vCPU machine: the six-script figures were measured through scripts/run_strategy.py,
which installs no sink unless PINEFORGE_REPORT_SINK=1 (it was not), so the large cache was in
effect; hungpixi (24,238 closed trades) through the release image's default docker/run_json.py
took 74.18 s on 1.6.3 and did not finish within 1800 s on 1.7.0 (the run was stopped at that
limit); through scripts/run_strategy.py without a sink it takes 107.2 s (mean of three runs);
peak RSS of the default run_strategy.py path (hl2-01, 100,000 bars, n=3) is 144.9 MiB on 1.6.3
and 125.7 MiB on 1.7.0. No statement is made that the run_json.py results are identical: the
1.7.0 run produced none.

Replaced sentences (all four are in the closed-trade cache bullet of CHANGELOG.md on main
91353de, the 1.7.0 line squash of #499, and are replaced here):
- "Without a report sink the cache holds at most `TradeLedger::kDefaultCacheRows` = 65,536 rows
  of `TradeLedger::kLedgerEntryBytes` = 312 bytes, 20,447,232 bytes, and is allocated at the
  smaller of that budget ... 20,447,232 bytes above 32,768." is now the sentence beginning
  "A run with no report sink holds at most".
- "With a report sink installed the budget is `TradeLedger::kSinkCacheRows` = 128 rows,
  39,936 bytes, a fixed bound ... so that the sink run's working memory stays flat." is now
  the sentence beginning "A run with a report sink installed holds at most".
- "Above the budget the cache is direct-mapped, so rows that share a slot evict each other ...
  with a report sink, 2 x (N - 128) rows per pass below 256 closed trades, and every row from
  256 on." keeps both formulas and now says "with no sink" and "with a sink".
- "The budget has no user control in this release: `NativeExecutionConsumer::begin_ready` sets
  it at every run begin ... and nothing in the C API or the environment changes either
  figure." is now "The two figures cannot be changed by a user in this release: ... installing
  a sink or not is the only choice." (the environment variable PINEFORGE_REPORT_SINK does choose
  whether run_strategy.py installs a sink, so the old sentence overstated).

One more sentence of main's text is reworded in the same bullet: "The six are not a sample of
all scripts, and the results are identical in every measured case." now ends "identical in
every one of those six measured cases", because the run_json.py hungpixi run added below has no
1.7.0 result to compare. The not-affected sentence names the hosted case runner, the verifier
and the sweep, and states that the corpus-parity canary pass sets PINEFORGE_REPORT_SINK=1
(scripts/check_corpus_parity.sh, line 316).

The heading of the 1.7.0 section is renamed: the line "## Unreleased" is replaced by
"## 1.7.0 — 2026-10-25" (same form as "## 1.6.1 — 2026-10-18"). VERSION is not touched here.

Only CHANGELOG.md changes; no citation moves.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…on carries its release heading

The CHANGELOG heading "## Unreleased" became "## 1.7.0 — 2026-10-25" in the previous commit. Three
public statements still said the change was unreleased or pointed at the old heading. Each is
changed by words only; no line is added or removed, so no file:line citation moves.

Replaced text (sentence or line as it stands on the previous commit):
- docs/pages/public-contract.md, "From 1.6.2 (unreleased), the image declares selected-window
  contract" is now "From 1.6.2, the image declares selected-window contract" (the 1.6.2 and 1.6.3
  sources already declared revision 1.3, as README.md:61 and docs/pages/report-schema.md say).
- docs/pages/public-contract.md, "[CHANGELOG.md](../../CHANGELOG.md), under *Unreleased*,
  inventories this change." is now "[CHANGELOG.md](../../CHANGELOG.md), under *1.7.0*, inventories
  this change." (the heading it points at no longer exists).
- docker/README.md, "From 1.6.2 (unreleased), the engine/codegen image's `run_json.py --so
  <strategy.so> --capabilities-json` probe declares revision `1.3`" is now "From 1.6.2, the
  engine/codegen image's `run_json.py --so <strategy.so> --capabilities-json` probe declares
  revision `1.3`".

Left as they are, from `git grep -in unreleased` over the tree minus CHANGELOG.md and docs/build.sh:
the schema field `"unreleased": true` of the run-failure catalog diff (docker/run_failure_codes_diff.json,
docs/pages/run-failure-codes.md, scripts/gen_run_failure_catalog_diff.py), the README.md:715 note on
the documentation version label, and the "unreleased epoch" comments in tests/ that record why
pinned hashes moved; none of them says that this release is unreleased.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…pe operator

On macOS signal.h defines sigemptyset, sigaddset, sigdelset, sigismember and sigfillset as
function-like macros (MacOSX.sdk usr/include/signal.h:122-126, for example
`#define sigemptyset(set) (*(set) = 0, 0)`). A call written `::sigemptyset(&mask)` expands to
`::(*(&mask) = 0, 0)`, which clang rejects with "expected unqualified-id", so src/c_abi.cpp and
src/scratch_arena.cpp did not compile there (found by the release.yml dry run of the prebuilt
macos-universal job and by the macos-26 Debug and Release legs of ci-post). Linux declares them as
functions, so the `::` form compiled everywhere else and pull request CI never builds macOS.

The `::` is dropped on every call of the five names in src/, include/ and tests/: 14 call sites in
10 files, each an in-line edit of one token (12 lines changed, no line added or removed, so no
file:line citation moves). The unqualified name finds the function on Linux and the macro on macOS.

  src/c_abi.cpp:368, src/scratch_arena.cpp:369,
  tests/report_sink_failure_fixture.hpp:78, tests/test_command_scratch_arena_bounded.cpp:647,
  tests/test_o1bk_production_backing.cpp:716, tests/test_p2_report_abort_security_diag.cpp:16 (two
  calls), tests/test_report_scratch_arena.cpp:467, tests/test_run_sigterm_abort.cpp:23 and :24,
  tests/test_scratch_arena.cpp:1156 and :1183, tests/test_scratch_arena_jailed_seals.cpp:114.

Class check, over src/, include/ and tests/: a grep for a global-scope `::name` of the other macros
macOS headers define (FD_SET, FD_ZERO, FD_ISSET, FD_CLR, htons, ntohs, htonl, ntohl, major, minor,
makedev, the W* wait macros, errno, isnan, isinf, isfinite, getc, putc, getchar, putchar, feof,
ferror, clearerr, stdin, stdout, stderr, the ctype functions, S_IS*, CMSG_*, memcpy, memmove,
memset, strcpy, snprintf, sprintf, bzero, timeradd and its relatives, setjmp, longjmp, assert,
offsetof, NULL, va_*) finds none. The only other global-scope names that
the macOS SDK could define as macros are ::dirfd (a statement-expression macro in dirent.h, but
only when the deployment target is older than macOS 10.8) and ::fileno (not a macro in the SDK
read here); both are left unchanged and are named in the report to the supervisor.

Only source and test files change; no documentation text is replaced.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@luisleo526 luisleo526 changed the title CHANGELOG: 1.7.0 — 2026-10-25 (ledger cache by entry point, measured known limits) 1.7.0 release prep: CHANGELOG 1.7.0 — 2026-10-25, stale 'unreleased' pointers, macOS build fix (::sig*set macros) Oct 24, 2026
@luisleo526
luisleo526 merged commit b250ceb into main Oct 24, 2026
23 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant