Skip to content

cr150: freeze the four 1.7.0 contracts (P00: report sink ABI + writer, TradeLedger, metric accumulator/point source, bar views) - #413

Draft
luisleo526 wants to merge 85 commits into
mainfrom
core/cr150-p00-contracts
Draft

luisleo526 wants to merge 85 commits into
mainfrom
core/cr150-p00-contracts

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

CR-150 lane P00, per DESIGN rev 6 (sha256 68bda6e3…) sections 2.2, 3.3, 3.4 and 3.7. Declarations and doc comments only; no existing call path changes.

  • include/pineforge/report_sink.h (C ABI) and report_sink_writer.hpp: the sink and its line writer. S1 receipt-query behaviour as ruled.
  • include/pineforge/trade_ledger.hpp: the ledger API. T1 adds clear/reserve/at/empty and vector-style invalidation.
  • include/pineforge/metrics_stream.hpp: the accumulator and point source.
  • include/pineforge/native_bar_views.hpp: the views header.
  • docs/design/cr150-contracts.md: maps each declaration to its DESIGN section.
  • tests/test_cr150_contract_headers{.cpp,_c.c}: a compile-only test with static_asserts on the frozen facts.
  • Remaining OPEN items S2, M1, V1, V2 are listed in the map, not invented.

Gating read (Fable): accepted, with the docs and the S1/T1 fixes applied. Lab: rj-20261018t093110-9b52e1 (preflight, release, debug, docs) green on a6abb14.

Not to merge before the 1.6.2-rc.1 cut (1.6.2 is EN-115 only).

🤖 Generated with Claude Code

Rewords the source citations of the contract map introduced by d0fd21c
("feat(cr150): declare bar views and document reader inventory") so each
range carries the backticked symbol or content hash check_doc_anchors.py
requires. The sentences d0fd21c wrote are replaced in place, not dropped.
Refresh citation prose from d0fd21c and 131852f, including All DESIGN line numbers below refer to that revision, to identify the final rev 6 text and correct its DESIGN line ranges.

Update only citation numbers in the contract headers and compile-witness comments; declarations, assertions, source anchors and CMake registration remain unchanged.
Apply CORE-TOP's 10-18 16:04 rev 6 amendment. Resolve S1 and T1 wording from 57857a5, c0c879c and 9f01fbc; the four other OPEN items remain unchanged.

Add declaration-only ledger clear/reserve/at/empty contracts and receipt-query initialization/return rules; extend only compile-time checks for the new method types.
Apply the CORE-TOP rev 6 amendment recorded at 10-18 19:24: adopt the V1/V2 proposal with all nine required changes and the eager-at-configure component-digest ruling.

Supersede OPEN/forward-only prose from d0fd21c, 54acd1c, 9f01fbc and a6abb14. Refresh the scope wording from 57857a5 and extend the source inventory from 131852f with projection validation.

Freeze declarations and contracts only: pending staging and active query on the private consumer, explicit feed context/accessor, four-operation provider, and static assertions. Existing execution paths and CMake line pins are unchanged.
* feat(cr150): resolve contract OPEN items V1 and V2

Apply the CORE-TOP rev 6 amendment recorded at 10-18 19:24: adopt the V1/V2 proposal with all nine required changes and the eager-at-configure component-digest ruling.

Supersede OPEN/forward-only prose from d0fd21c, 54acd1c, 9f01fbc and a6abb14. Refresh the scope wording from 57857a5 and extend the source inventory from 131852f with projection validation.

Freeze declarations and contracts only: pending staging and active query on the private consumer, explicit feed context/accessor, four-operation provider, and static assertions. Existing execution paths and CMake line pins are unchanged.

* test(cr150): add L15a view binding red witness

* feat(cr150): implement L15a pending bar view bindings

Implement the frozen ee3083d V1/V2 contract and the 19:24 eager-component ruling. Preserve v3 layouts, owned fallbacks and digest bytes; add no borrowed production export or concrete lower provider.

Update read-inventory claims introduced by d0fd21c and amended by a6abb14 and ee3083d; other documentation edits only carry source coordinates. Reword the EntryExitGuard explanation introduced by 47184e5 to include unconditional outer-run binding detachment.

Red witness committed first as 100a605. Builds, compilation, tests and source guards were not run on this Mac, per CORE-TOP brief; lab verification remains pending.

* fix(cr150): list L15a kernel sources on separate lines

Round 3 item 1, lab rj-20261018t115236-b4aba1: repair the shared source line introduced by 2539102 so the detached-comment reader sees separate translation units. Carry every affected root-CMake documentation coordinate by one line; tests/CMakeLists.txt and its private_fixture_reads.evidence pin stay unchanged, following the line-pin discipline of P00 fix4 (25e4491).

The documentation source claims came from 47184e5 and 868aa65; only their coordinates change. No builds, tests or guards executed on the Mac.

* docs(cr150): carry all L15a source citations to the new tree

Round 3 item 2, lab rj-20261018t115236-b4aba1: carry 302 source-coordinate spans from ee3083d to the unchanged 2539102 engine sources, including all 288 anchors listed in lab-doc-anchors.log and 14 additional affected references. Handle basenames, full paths and shorthand lists while retaining the backticked claims and the intended occurrence of repeated symbols. Preserve citations already moved in Round 2.

Doc source-claim provenance: 47184e5, 65c69b0, f48b7c8 and 868aa65. Only citation coordinates change; no policy, numeric assertion, frozen declaration or engine behavior is reworded. Repair source drift introduced by 2539102.

No builds, compilation, tests or guards executed here. CORE-TOP must rerun the two failed preflight stages and required verification on the lab.

* test(cr150): keep FX index pins and expect the L15a tail

Round 4, lab rj-20261018t124444-007ef1: update only NativeFxCurveVersions.test_new_paths_append_without_reindexing_existing_pins. Retain FX at FILES[12:14], the identity pin at 11 and both uniqueness checks; expect the seven L15a paths in FILES[14:].

Comparison with core/cr150-p00-contracts (ee3083d) confirms its full 14-entry FILES prefix is already unchanged, so do not reorder or rewrite the guard list. Follow the FX append precedent from e7cdf05 without preserving its stale newest-tail assertion. No build, compilation, test or guard executed here.
* test(cr150): pin L8a ledger and retaining native behavior

Red-first witness: the static assertion requires BacktestEngine closed rows to be TradeLedger; the P00 base still stores std::vector<Trade>. Runtime cases cover the frozen API, global windows, ownership, tail rewrites, native reports and handle reuse. Expected failure is source-derived; no compile or test was run under the CORE-TOP Mac restriction.

* feat(cr150): implement the retaining TradeLedger container

Implement the frozen P00 ledger in engine_orders.cpp, swap the closed-row owner, and adapt digest/sort signatures without changing their folds or ordering. Keep production retention unchanged: no seal call is installed. Explicitly select kernel-recorded equity in the new native report witness. The out-of-row engine_execution.cpp reserve_effects vector caller and frozen oracle compatibility remain reported OPEN; no local compile or test was run.

* test(cr150): adapt non-frozen helpers to TradeLedger

Keep live helper references on the ledger and preserve snapshot copies through iterator ranges. Replace front reads with resident iteration and update the closed-row digest probe type. Keep numeric assertion literals, fixture values, oracle sources and hash pins unchanged. This is a mechanical caller migration under SCOPE-RULING-1818; no local compilation or tests were run.

* test(cr150): adapt frozen oracle carriers through snapshots

Add a test-only vector snapshot accessor to OraclePineNativeHost and map trades_ only around the two affected non-frozen carrier includes. Refresh same-size snapshots in place to preserve row references across repeated reads. Leave frozen oracle bytes, pins and P00 declarations unchanged. No build, compilation, test or guard was run.

* fix(cr150): reserve settlement effects through TradeLedger

Add the CORE-TOP-approved TradeLedger overload immediately after the vector helper. Guard the logical end and reserve the resident count through the frozen API. Preserve both existing call sites, the vector helper and P00 declarations. No build, compilation, test or guard was run.

* docs(cr150): refresh every L8a source citation

Repair the source citations shifted by the L8a header/include and allocation-overload edits. Search docs for all 70 changed-file basenames, covering 516 mentions in 18 documentation files, rather than only the 140 lab findings.

Keep exact declaration/occurrence targets for ambiguous symbols, preserve the existing comment hash while shifting its range, and name the trail-peak carry sites explicitly. Identify archived deleted-source coordinates as historical records instead of shifting them onto unrelated live code. Preserve document line counts.

Doc-revert/source-line attribution: the edited documentation lines were introduced or last re-anchored by the following commits; the prose sources of the rewritten passages are named as well:
- 51a1989
- d093560
- 06d4107
- 44b17c1
- 868aa65
- 925f1c9
- a744bee
- f48b7c8
- 0411892
- 47184e5
- 0d76a09
- 65c69b0
- b16e11f
- caa65e4
- b97c409
- 3372b5d
- b2a578c

These include L14-A/Doxygen (51a1989), L11 archived notes (44b17c1, 06d4107), Q6 trail-peak discussion (b16e11f, caa65e4, 868aa65), and the archival paragraph's V19-A/DOCS-ENGINE history (3372b5d, b2a578c). No behavior ruling is reverted.

No source/header/test or pin changes in this commit. No build, compilation, tests, documentation guards, preflight, parity or corpus command was run under the CORE-TOP Mac restriction.
…er (L1) (#414)

* test(cr150): add red pf_bar file and csv2bin contract proofs

* feat(cr150): add durable streaming csv2bin converter

* test(cr150): gate corpus identity on materialized fixtures

* fix(cr150): report unexpected csv2bin faults as JSON

* test(cr150): pin amended chart refusal contract

* fix(cr150): apply amended chart timeframe and timestamp refusals
…, trailer, SHA-256, reader) (#416)

* test(cr150): pin L6a sink wire format before implementation

Add the P00-only runtime witness, 1,000,000 checked-in Python repr samples and all 2,098 binary64 powers of two, UTF-8 cases, writer artifacts and strict-reader refusals. Expected red on a6abb14: undefined report_sink formatting and LineWriter implementations; pf_sink is also absent. Compilation and execution are reserved for CORE-TOP lab per the lane brief; no observed red diagnostic is claimed.

* feat(cr150): add dependency-free streaming SHA-256 for L6a

Implement the FIPS 180-4 block schedule, streaming updates, copy-on-finalize digest and lowercase hex encoding. Extend the already-red format unit with NIST vectors and every two-part split of the short messages. Lab compilation and execution remain pending per the executor brief.

* feat(cr150): implement isolated P00 report sink writer

Add Python repr-compatible binary64 rendering, byte-validating UTF-8 escaping, the seven fixed descriptors, E/T serialization and SHA-counted trailers. Buffer checked writes in 64 KiB and latch validation or I/O failure before publication. Keep P00 declarations unchanged. S2 uses internal WriterError and cached repeated finalization, with runtime error-code mapping reserved for L6b-1. No build or tests were run on this machine.

* feat(cr150): add strict streaming report sink reference reader

Validate fixed ordered v1 descriptors, typed records, exact Python f64 lexemes, bounded UTF-8 JSON lines and the final counts/SHA receipt. Yield immutable typed rows in one pass and expose completion only after EOF. Extend the format witness with an exact 1 MiB boundary, zero/nonzero descriptor shapes, finalization lifecycle and malformed-stream cases. Execution is deferred to CORE-TOP lab as required.

* test(cr150): isolate the L6a reader proof from host settings

Keep Python assertions enabled regardless of PYTHONOPTIMIZE, suppress bytecode artifacts and retry an interrupted child wait. This only strengthens the pending lab witness; no build or test was executed here.

* fix(cr150): wire L6a sink sources and format unit into CMake

Apply CORE-TOP wave1 and the Fable gating read: add report_sink_writer.cpp and sha256.cpp to PINEFORGE_KERNEL_SOURCES, one per line, and append the format unit inventory/registration after the pinned test lines.

Mechanically re-anchor only shifted top-level CMake citations. Preserve the prose and claims recorded by 47184e5 and 868aa65; no sentence is reworded. Keep all C++/Python bodies, P00 declarations, fixture evidence and other lines unchanged.

No configuration, compilation, tests or guards run in this fix round per the executor brief. Commit hooks are disabled for this invocation to honor that instruction; lab proof remains with CORE-TOP.
* test(cr150): add L15a view binding red witness

* feat(cr150): implement L15a pending bar view bindings

Implement the frozen ee3083d V1/V2 contract and the 19:24 eager-component ruling. Preserve v3 layouts, owned fallbacks and digest bytes; add no borrowed production export or concrete lower provider.

Update read-inventory claims introduced by d0fd21c and amended by a6abb14 and ee3083d; other documentation edits only carry source coordinates. Reword the EntryExitGuard explanation introduced by 47184e5 to include unconditional outer-run binding detachment.

Red witness committed first as 100a605. Builds, compilation, tests and source guards were not run on this Mac, per CORE-TOP brief; lab verification remains pending.

* fix(cr150): list L15a kernel sources on separate lines

Round 3 item 1, lab rj-20261018t115236-b4aba1: repair the shared source line introduced by 2539102 so the detached-comment reader sees separate translation units. Carry every affected root-CMake documentation coordinate by one line; tests/CMakeLists.txt and its private_fixture_reads.evidence pin stay unchanged, following the line-pin discipline of P00 fix4 (25e4491).

The documentation source claims came from 47184e5 and 868aa65; only their coordinates change. No builds, tests or guards executed on the Mac.

* docs(cr150): carry all L15a source citations to the new tree

Round 3 item 2, lab rj-20261018t115236-b4aba1: carry 302 source-coordinate spans from ee3083d to the unchanged 2539102 engine sources, including all 288 anchors listed in lab-doc-anchors.log and 14 additional affected references. Handle basenames, full paths and shorthand lists while retaining the backticked claims and the intended occurrence of repeated symbols. Preserve citations already moved in Round 2.

Doc source-claim provenance: 47184e5, 65c69b0, f48b7c8 and 868aa65. Only citation coordinates change; no policy, numeric assertion, frozen declaration or engine behavior is reworded. Repair source drift introduced by 2539102.

No builds, compilation, tests or guards executed here. CORE-TOP must rerun the two failed preflight stages and required verification on the lab.

* test(cr150): keep FX index pins and expect the L15a tail

Round 4, lab rj-20261018t124444-007ef1: update only NativeFxCurveVersions.test_new_paths_append_without_reindexing_existing_pins. Retain FX at FILES[12:14], the identity pin at 11 and both uniqueness checks; expect the seven L15a paths in FILES[14:].

Comparison with core/cr150-p00-contracts (ee3083d) confirms its full 14-entry FILES prefix is already unchanged, so do not reorder or rewrite the guard list. Follow the FX append precedent from e7cdf05 without preserving its stale newest-tail assertion. No build, compilation, test or guard executed here.

* test(cr150): add L16 lower-path provider red witness

* feat(cr150): stream magnifier lower paths through bounded providers

Implement L16 on the L15a side channel: preserve the vector reference, decide whole-input fallback before generation, cache count, and publish monotone overlapping segments with separate look-ahead. Route kernel preflight and delivery plus scheduler reads through the bound provider. Keep metadata and count-first digests identical. Update the guard reader inventory and route requirements for these callers.

Add synthetic path, execution/report/hash, preflight-boundary and provider heap witnesses. No compilation, test, guard or corpus command was executed on this machine; CORE-TOP owns the lab proof.

* docs(cr150): refresh source coordinates shifted by L16

Carry 306 affected published source-coordinate spans from ddc9c94 to 411e48e, including shorthand lists and the relocated scheduler next_open. Preserve the existing claims and content pins; no policy or numeric assertion is reworded. Refresh only coordinates shifted by this lane.

Doc source-claim provenance: ae868d6, 2539102, 9f01fbc, 47184e5, 65c69b0, f48b7c8 and 868aa65. This repairs source drift introduced by 411e48e; it does not revert those claims. No doc guard or other verification was executed here; CORE-TOP must run check_doc_anchors in the lab.

* test(cr150): pin lower-provider hash after input release

Strengthen the L16 execution differential by releasing the borrowed input after the public run exit, then querying the retained continuation hash. This exercises the eager component digest and provider detachment rather than relying on live caller storage. Lab execution remains pending under the no-run instruction.
* test(cr150-l8b): pin sealed trade percent prefix identity

Add the standalone PINEFORGE_TEST_TRADE_PERCENT_PREFIX proof in the lane-owned metric source. It covers every sealed/resident split, left-fold rounding, pnl-based filters, zero guards, mutable tails and reset.

Red by source inspection against a6abb14: fold_trade_percent_prefix and reset_trade_percent_prefix do not exist. No build, compilation or tests were run on CORE-TOP as instructed; the lab must record the first compiler diagnostic.

* feat(cr150-l8b): seed percent averages from sealed trade rows

Keep all/winning/losing percentage sums and counts at the sealed prefix. Continue each original left fold over resident rows, preserving pnl filters, signed loss percentages and existing win/loss guards. Add protected fold/reset operations for L8c; do not install streaming or change P00 declarations.

OPEN for supervisor: hash coverage for trade_percent_prefix_ needs an out-of-row hash/waiver change; the member remains inside a broker-state region so the guard can report it. L8c must wire fold-before-retire and new-run reset. No build, compilation or tests were run on this machine.

* fix(cr150-l8b): waive derived trade percent prefix state

DESIGN rev 6 section 3.4 requires the same left folds over sealed rows followed by the resident tail, while retaining the existing closed-row digest hash. The six prefix values are reconstructible from those immutable already-hashed rows and add no independent decision state.

Add an explicit reasoned waiver for trade_percent_prefix_ rather than new seal-dependent hash bytes. Addresses the coverage failure in lab rj-20261018t125021-5a52a9. No build, test, guard or verification command was run here.

* test(cr150-l8b): register trade percent prefix unit

Apply the L8B FIXES from core-cr150-read-wave1. Move the unit introduced by 826e74d out of engine_metrics.cpp into tests/test_trade_percent_prefix.cpp, preserving its body and assertions, removing only the compile-mode wrapper and adding standalone includes.

Append the TEST_SOURCES entry and pineforge_add_unit_test call after all existing test CMake lines, preserving the private-fixture evidence pins. Existing metric definitions and published source anchors retain their line numbers. No build, test, guard or verification command was run here.
* test(cr150-l7b): add point-source equity metrics witness

* feat(cr150-l7b): stream equity metrics from array points

* docs(cr150-l7b): record lane handoff

* docs(cr150-l7b): clarify handoff diff scope

* chore(cr150-l7b): move handoff artifacts out of engine

* fix(cr150-l7b): define ordinary point-source metrics entry
* test(metrics): add isolated CR-150 trade accumulator red test

Reuse the L0 fixed/random trade fixtures and unchanged reference. Exercise copy snapshots and repeatable finish without sink dependencies. The base declares the accumulator but provides no method definitions; CORE-TOP must record its link failure on the lab because this lane cannot compile or execute locally.

* refactor(metrics): fold trade stats through the P00 accumulator

Keep the existing per-row arithmetic and final formulas in one implementation, deep-copy prefix state, and make finish a const read. Route the array entry point through the fold and refresh the shifted documentation anchors. No broker state or P00 declarations change. Lab compilation, byte comparisons and repository verification remain pending under the no-local-execution brief.
* test: specify CR-150 heap census and unique-id controls

* test: add live CR-150 heap census and lane inventory

* fix: attribute heap growth using demangled allocation frames

* fix: select the run chart and map probe feed tapes
Comment thread tests/test_heap_census.py Fixed
Each CR-150 lane registers its tests in tests/cr150.d/<lane>.cmake, included in sorted order; scripts/check_cr150_cmake_d.py enforces the lane-file rules (R1). Lab rj-20261019t001911-c8ee68, all four steps passed on e721eec.
CR-150 lane L19c. Lab rj-20261019t012637-885007, all four steps passed (preflight, release, debug, docs) on bd478b2, which contains the integration head 5be8c54.
CR-150 lane L19d. Lab rj-20261019t012720-0c0042, all four steps passed on ee44580 (contains 5be8c54). Merged onto 437bc33 without a re-proof: no code file shared with L19c, and the trial merge was clean; covered by the batch integration proof.
CR-150 lane L8d. Lab rj-20261019t012726-30ae5e, all four steps passed on ca06099 (contains 5be8c54). Merged onto ace7189 without a re-proof: no code file shared with L19c or L19d (design docs only), and the trial merge was clean; covered by the batch integration proof.
CR-150 lane L19a. Lab rj-20261019t022649-4b1196, all four steps passed on 2c7ef14 (contains the integration head 5e167bd).
luisleo526 and others added 10 commits October 20, 2026 11:13
…224095) (#455)

Lab proof commit, never pushed. Its tree equals the lane head; its single parent is the integration head 9224095 (L2 #429 merged), as the GitHub squash will write it.

CR-150 lane: see the lane REPORT.md for design, tests and wiring.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Integration moved with L8c #455; this merge brings the lane up to it before its proof.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Integration moved with L8c #455; this merge brings the lane up to it before its proof.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Integration moved with L8c #455; this merge brings the lane up to it before its proof.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Digits only, no prose changed: every citation into a file this lane or L8c changed was recomputed from the final tree.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…t only the resident ones (behaviour fix, witness test)

L19l-A's disk-resident cohort table made the reversal cancellation loop (on_applied, full close) visit resident rows only, while a spilled cohort with no exposure can still own queued exits; cancellation is an action over the id, so spilling an eligible row suppressed it and changed command events, pending requests, hashes and later trades. The loop now snapshots the same two exemptions as the base (the applied snapshot's source id and any live entry opening on the new side) and streams every logical id in lexicographic order through the new DiskResidentIdTable::for_each_sorted_id, without restoring facts or building a history-sized vector. tests/test_adapter_reversal_storage.cpp runs a live reversal fixture with capacity release and cohort eviction on and off against the retained-storage run, comparing every trade field, recorded and callback hashes and the final hash.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* cr150 l19lb: executor result for CR-150 lane l19lb (supervisor commit)

Edit-only Codex executor output committed by the supervisor on integration b3c3923. Design, tests, wiring and the compile audit are in the lane's REPORT.md. Not yet proven on the lab; the four-step proof and any parity sweep follow on a squash proof commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19lc: executor result for CR-150 lane l19lc (supervisor commit)

Edit-only Codex executor output committed by the supervisor on integration b3c3923. Design, tests, wiring and the compile audit are in the lane's REPORT.md. Not yet proven on the lab; the four-step proof and any parity sweep follow on a squash proof commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l9c: executor result for CR-150 lane l9c (supervisor commit)

Edit-only Codex executor output committed by the supervisor on integration b3c3923. Design, tests, wiring and the compile audit are in the lane's REPORT.md. Not yet proven on the lab; the four-step proof and any parity sweep follow on a squash proof commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19l: executor result for CR-150 lane l19l (supervisor commit)

Edit-only Codex executor output committed by the supervisor on integration b3c3923. Design, tests, wiring and the compile audit are in the lane's REPORT.md. Not yet proven on the lab; the four-step proof and any parity sweep follow on a squash proof commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l9c: portable report sink (named temp file, per-reader offsets), sink canary line, keep-sink switch (fix round 1)

The temporary report sink is a named mode-0600 file unlinked at close, so every
SinkReader opens its own descriptor on Linux and Darwin (no /proc/self/fd or
/dev/fd branch). run_strategy.py prints
`sink_canary: probe=<id> bytes=<n> records=<n> trades=<n> ok` per probe and
PINEFORGE_KEEP_REPORT_SINK keeps the sink file of the named probes (or all).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19m: exit-phase store on disk, release empty cohort maps and rosters (executor result)

The closed-trade exit phase byte vector (one byte per closed-trade index) moves
to a ScratchFile-backed ExitPhaseStore with one fixed 4 KiB page. The cohort
live_units_by_origin map (104 B per distinct entry id) and the opened roster
vector (24 B per id) are released as soon as they are empty. Written on the old
base; merged onto the L19l head in the next commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19n: kernel calendar memo and certified-cycle ring reserve their span buffers once (executor result)

The session-day memo (64 direct-mapped slots) and the certified-cycle ring (4
entries) were already fixed-size; what grew was the heap each slot owned, one
span buffer per new day until the table filled. Every slot's buffer is now
reserved once to a proven per-day bound (session_day_span_bound) and only
assign()ed afterwards, so live heap is constant. Table geometry, slot function
and eviction rule are unchanged. Two new source-free tests compare against the
memo-free calendar.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l9c: per-run canary log for full and subset sweeps, canary also checks the E records against the engine receipt (fix round 2)

scripts/run_corpus.sh and scripts/check_corpus_parity.sh keep the sink_canary:/sink_kept: lines of every probe, passing or failing, in one PINEFORGE_CANARY_LOG (unset: no log I/O, behaviour unchanged). New scripts/check_sink_canary_log.py requires exactly one well-formed ok canary per probe of the sweep's own list. run_strategy.py reads the engine's receipt count_e from the live handle and the canary compares the E records a fresh strict read decodes against it; the line gains `equity=<n>` before the verdict. The DESIGN 3.11 wording for the named temporary sink is in the design folder, outside this tree.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19l+l19m: round-2 fixes: exit-phase store and kernel roster store removed, coded throws, portable fault injection, comments restored, citations refreshed

The exit-phase byte vector returns to its base form (its windowing is L8c's); KernelRosterStore is removed (cohort_exists is a range check plus the map); the two uncoded throws in pine_adapter.cpp now carry run-failure codes (report_sink_failed for a corrupt scratch cohort record, engine_invariant for a fixture backend selected after use); the fixture lifecycle is explicit and tested; the Pine prefix of 18 literals in id_pair_store.hpp (kernel-residuals check) is removed; fault injection opens the file by path instead of /dev/fd; the orphan fixture and a stale process comment are removed; the four deleted comment sentences of the base are restored; two witnesses (live settlement capacity release, part C typed failure) are added; 426 doc citations across seven documents are refreshed (digits only).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: re-anchor file:line citations after merging integration 5022017

Digits only, no prose changed: every citation into a file this lane or L8c changed was recomputed from the final tree.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cr150 l19l: reversal cancels exits of every known cohort id again, not only the resident ones (behaviour fix, witness test)

L19l-A's disk-resident cohort table made the reversal cancellation loop (on_applied, full close) visit resident rows only, while a spilled cohort with no exposure can still own queued exits; cancellation is an action over the id, so spilling an eligible row suppressed it and changed command events, pending requests, hashes and later trades. The loop now snapshots the same two exemptions as the base (the applied snapshot's source id and any live entry opening on the new side) and streams every logical id in lexicographic order through the new DiskResidentIdTable::for_each_sorted_id, without restoring facts or building a history-sized vector. tests/test_adapter_reversal_storage.cpp runs a live reversal fixture with capacity release and cohort eviction on and off against the retained-storage run, comparing every trade field, recorded and callback hashes and the final hash.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Comment thread scripts/run_strategy.py
raise IndexError("sink row index out of range")


class _SinkReport(dict):
Comment thread scripts/run_strategy.py
docker_dir = str(REPO_ROOT / "docker")
if docker_dir not in sys.path:
sys.path.insert(0, docker_dir)
import run_json

sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "tests"))

from test_run_json_sink import * # noqa: F401,F403,E402
Comment thread docker/run_json.py
if not self.keep:
try:
os.unlink(self.path)
except FileNotFoundError:
luisleo526 and others added 19 commits October 20, 2026 15:03
…d counts the sink canaries (CX-CANARY-WIRE)

check_corpus_parity.sh --subset now factors the parallel run into run_subset_probes() and, after pass 1 (sink off, judged exactly as before), re-runs the same probes with PINEFORGE_REPORT_SINK=1, a canary log ($BUILD_DIR/sink_canary.log unless the caller set PINEFORGE_CANARY_LOG), the first five probe ids kept in $BUILD_DIR/sink-kept, re-judges byte identity with the same pins, and requires exactly one ok canary per probe from check_sink_canary_log.py. It prints the canary count against the probe count and one sink_kept line (sha256, bytes) per kept sink through a new `kept` subcommand. PINEFORGE_SUBSET_SINK=0 skips pass 2. Tests: tests/test_corpus_subset_sink.py (registered in cr150.d/core-cr150-canary.cmake) and extensions of test_run_strategy_sink.py.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Integration moved with batch-A #457; the lane was built on the batch-A head, whose tree equals the integration tree, so the merged tree equals the lane head (the add/add conflicts are the same files on both sides of the squash).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… head

The sink-on corpus subset pass and its canary log counter go in before the
freeze (CORE-TOP 23:27).

Co-Authored-By: Claude Code <noreply@anthropic.com>
… a SyntaxError (introduced by fcd2b52)

fcd2b52 (CX-CANARY-WIRE) added tests/test_corpus_subset_sink.py with a
trailing comma after the iterable of four comprehensions ("for probe in
probes,"), which Python rejects, so the file never imported and the CTest row
test_corpus_subset_sink_cr150 failed in the release and debug steps of the
four-step on a41b26b.

The four places: the json.dumps dict comprehension that writes the fixture
pins, and the three set comprehensions in
test_subset_defaults_to_two_passes_and_reports_exact_artifacts,
test_first_identity_failure_stops_before_any_sink_run and
test_explicit_opt_out_keeps_the_first_pass_sink_off. Only the commas are
removed; no assertion, fixture or expected value changes.
…ratch_tables_v1, scratch_capacity_exceeded and scratch_io_failed

Route (ii) of CR-221 (CORE-TOP 10-21 00:44): an in-memory backend for the nine
scratch regions the sink-OFF tables use, so a run inside a jail that forbids
file creation and growth (RLIMIT_FSIZE 0, no writable directory) does not
touch a file. This commit is the FOUNDATION only; the three backends are
separate lanes and refuse a nonempty owner until they land.

- detail/scratch_slab.hpp: ONE aligned allocation per run, zeroed before
  publication, nine fixed regions laid out by compute_layout with the
  SINKBOUND formulas (Q(K), D_j, I_j, Coh, Rank, Roots, 4096-byte pages,
  checked 64-bit arithmetic, V <= 27); checked read_at/write_at, read-only
  can_extend/require_extend, zero/reset without reallocation.
- detail/scratch_tables.hpp: ScratchTableBackend {disk_scratch, bounded_memory},
  ScratchManifest (eleven uint64 fields), ScratchTableConfig and the three
  binder entry points (bodies are stubs that refuse a nonempty owner).
- detail/scratch_errors.hpp: ScratchCapacityError (closed resource argument)
  and ScratchIoError moved to the shared header; IdPairStoreError recoded.
- pineforge.h / engine.hpp / c_abi.cpp: pf_scratch_tables_v1 and
  strategy_set_scratch_tables_v1 (105 public declarations, 85 runtime
  implementations); the configuration is read once per run in
  NativeExecutionConsumer::prepare_public_begin, before the first cache
  mutation and independent of the report sink.
- docker/run_failure_codes.json and the generated vocabulary, registry, diff and
  docs: scratch_capacity_exceeded and scratch_io_failed (resource, retryable
  false, since 1.7.0).
- tests: test_scratch_slab_layout.cpp, test_scratch_tables_abi.cpp (hand-derived
  layouts), cr150.d/core-cr150-ramfound.cmake; four existing fault-injection
  tests now expect scratch_io_failed.

Executed verification: none yet; the commit is proven only by the lab remote
four-step on this exact commit.
…d profile, HPO example, scratch-tables docs

Part of CR-221 route (ii) in engine 1.7.0. Builds on the foundation commit
d91c96d.

- include/pineforge/detail/scratch_defaults.hpp: default_scratch_manifest, the
  P0 policy tier (a policy choice, not a measured bound): 4,096 keys per store,
  256-byte ids, rank 27 keys, roots 2 x input bars (65,536 for a stream
  without a declared bar count), q reserved zero.
- docker/run_json.py: a jailed profile read once at startup that calls
  strategy_set_scratch_tables_v1 with the bounded-memory backend on every
  fresh handle, creates NO report sink, and refuses with a typed
  incompatibility when the symbol is missing (never a silent disk fallback);
  the unjailed profile is unchanged.
- benchmarks/throughput/grid_search_repro.py: the HPO example sets the manifest
  on every new trial handle.
- docs/pages/scratch-tables.md: the two backends, the setter, the default tier
  (hand arithmetic), the typed errors, what is not covered, the SIGXFSZ rule
  (the host owns the signal) and the honest memory statement.
- tests: test_scratch_defaults.cpp, test_run_json_jailed_profile.py,
  test_scratch_tables_docs.py.

Needs one foundation-owned change applied in the foundation fix round: the
all-zero manifest resolution to the default tier in the begin snapshot.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit that integrates it.
…emory backend for erased_minima_ and consumed_partial_exit_cycles_

Part of CR-221 route (ii) in engine 1.7.0 (CORE-TOP 10-21 00:44): a run in a jail
that forbids file creation and growth must not touch a file for the sink-OFF
tables. Builds on the foundation commit d91c96d (fixed scratch slab, nine
regions, typed capacity error).

- PlacementTable drops sequence_index_ (the q store, data and index): the
  stale minima it kept are redundant with erased_minima_ (every row is folded
  into e before it is erased), so command_sequence_for now scans the retained
  rows and combines the e minima, keeping the known / pair-known flags, the
  exact-pair preference and the explicit UINT64_MAX fallback exactly as before.
  No hash leaf moves (the placement leaf folds live rows and the erased
  count/digest, not q).
- IdPairStore gets a bounded-memory form bound to one data slice and one
  fixed Q(K) index slice of the slab: same Header 40 B / Slot 16 B records via
  copy, same full-key equality, live flag and resurrection rules, same
  iteration order; no growth, no rehash, no replacement index, no file.
  The disk form is unchanged. Capacity tickets are read-only and run before the
  failing operation's first mutation (erase preflights both minima keys before
  taking the row; the retirement workset, replace/refold and the consumed
  cycle reservation in the precommit path), raising scratch_capacity_exceeded
  with the erased_data / erased_index / consumed_data / consumed_index resource.
- tests: test_id_pair_store_ram.cpp, test_placement_q_removed.cpp,
  test_adapter_idpair_ram.cpp and a changed test_adapter_auxiliary_disk.cpp
  (the q fixtures become the scan).

Needs two foundation-owned changes that are applied in the foundation fix
round, not here: the K_q = B_q = 0 layout contract and the precommit ordering
in PineStrategyHost::validate_execution_precommit.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit that integrates it.
…t rejected d91c96d

The lab preflight of d91c96d (rj-20261020t173420-4985ab) failed in eight
stages. Each cause is fixed at its source, no guard is loosened:

- native_execution_consumer.cpp reopened `namespace pineforge` after its first
  closing brace, which the epoch version guards (check_native_cpp_versions.py,
  check_aggregate_cpp_versions.py) reject: the helper moves into the single
  block, body unchanged.
- pf_scratch_table_backend_e is ruled C-only in check_native_c_api_surface.py
  (a scratch storage setup enumeration, outside the native run-spec inventory).
- tests/ownership/manifest.v1.json gets the rows for scratch_capacity_exceeded
  and scratch_io_failed, and the negative controls of its test omit each one.
- The installed header scratch_tables.hpp no longer names a source-layer type
  (kernel-residuals rule on the `pine` vocabulary): the three binder
  declarations and the source/native forward declarations move to the
  non-installed src/scratch_table_binders.hpp, same names and signatures.
- Two docs and one inventory sentence state 85 runtime exports (digits only);
  scripts/test_ci_verify.py counts become 105/85, matching
  scripts/check_c_abi_runtime.py.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit.
…und through WorkingRequestCore::bind_scratch_slab

Part of CR-221 route (ii) in engine 1.7.0. Builds on the foundation commit
d91c96d.

PUBLIC API CHANGE to the installed header include/pineforge/native_order.hpp,
made under CORE-TOP's ruling of 10-21 02:02 (L6 informed and upheld it): the
header changes by exactly three added lines and no removed or changed line, a
forward declaration of pineforge::detail::ScratchSlab and ONE public member
function on WorkingRequestCore, bind_scratch_slab(const std::shared_ptr<
::pineforge::detail::ScratchSlab>&), beside set_successor_roots_directory. No
detail include, no friend, no data member, no inline body, no change to any
existing signature (reserve_successor_root() keeps its no-argument form).
Reason: the jailed scratch backend, CR-224 / CR-221 route (ii): the successor
roots must live in the run's pre-sized slab instead of a created file.
Layout evidence: test_successor_roots_ram.cpp compares sizeof and alignof of
WorkingRequestCore with a mirror of its data members. No header-freeze pin
exists for this header (no whole-file digest or declaration-count pin found; see
the lane report), so none changes.

- SuccessorRootIndex (src/native_order.cpp only) gets a bounded-memory form on
  the Roots region: the 64-row inline tail stays; a full tail flushes into the
  region by write_at and prefix reads use read_at; append stays noexcept and
  consumes an already validated slot; the disk form is unchanged.
- The ticket is read-only and runs before the tail-room early return and
  before any flush write: the whole logical root population against R (so
  R < 64 is enforced) and the full prefix extent; a rootless submit and a
  kept-handle replacement are not charged (a plain field on the helper, set by
  reserve_plan / the direct path just before the unchanged no-argument call).
  Raises scratch_capacity_exceeded(successor_roots).
- The disk form's create / unlink / CLOEXEC / write / offset errors now carry
  scratch_io_failed instead of an uncoded system_error.
- tests: test_successor_roots_ram.cpp, test_native_roots_ram_run.cpp,
  tests/cr150.d/core-cr150-ramroots.cmake.

The foundation call site moves to the member in the foundation fix round.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit that integrates it.
…ble and the exit-rank table

Part of CR-221 route (ii) in engine 1.7.0 (CORE-TOP 10-21 00:44). Builds on the
foundation commit d91c96d (fixed scratch slab, nine regions, typed capacity
error).

- DiskIdTable / DiskResidentIdTable / ScratchFile route their byte I/O (packed
  Links reads and writes, key reads, value get/set, node append) to the Coh and
  Rank regions of the slab when one is bound; with no slab they are byte for
  byte the disk behaviour. Record layouts, packed AVL nodes, residency and
  pinning, spill-before-erase, the sorted and insertion-order iteration and the
  hash folds are unchanged.
- Read-only capacity tickets run before the failing operation's first
  mutation: DiskIdTable::insert after its duplicate search and before the first
  write, DiskResidentIdTable::emplace before its spill, PineExecutionAdapter::
  cohort_for before the kernel cohort handle is opened, note_exit_rank_key
  before the insert and the digest writes (the 27-key cutoff stays: a 28th key
  is ignored, not a capacity failure). Raises scratch_capacity_exceeded with
  the cohort or exit_rank resource.
- tests: test_disk_id_table_ram.cpp, test_adapter_tree_ram.cpp,
  tests/cr150.d/core-cr150-ramtree.cmake.

The rank ticket before PineStrategyHost's first precommit_held_units_ assignment
needs one hunk in the foundation-owned pine_strategy_host.cpp; it is applied in
the foundation fix round, not here.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit that integrates it.
…ackend lanes asked for

- scratch_slab.hpp compute_layout refuses a nonzero K_q or B_q (resource=layout):
  the q store was removed by the id-pair lane, so the q regions are reserved
  zero; the nine descriptors, the enum values, the manifest field order and the
  C struct stay unchanged. The foundation's worked layouts and ABI test use
  K_q = B_q = 0 (hand-derived), and a nonzero q is refused in a new case.
- PineStrategyHost::validate_execution_precommit calls the adapter's validation
  first and assigns precommit_held_units_ after it, so the adapters' read-only
  capacity tickets can throw before the first host mutation.
- prepare_public_begin resolves an all-zero bounded-memory manifest to the
  default P0 tier (batch: by the run's bar count; stream: the fixed tier, since
  a stream's warmup count is not its lifetime); scratch_defaults.hpp is the
  host lane's header, copied byte for byte.
- The successor-root binding moves to the member
  WorkingRequestCore::bind_scratch_slab (CORE-TOP ruling 10-21 02:02); the free
  roots binder declaration and stub are removed. This commit does not compile
  without the roots lane's member; the integration merge supplies it.

Executed verification: none yet; proven only by the lab remote four-step on the
integrated commit.
# Conflicts:
#	docs/adr/0001-kernel-adapter-boundary.md
#	docs/design/native-feature-parity.md
# Conflicts:
#	docs/adr/0001-kernel-adapter-boundary.md
#	docs/design/native-feature-parity.md
#	docs/native-refactor-progress.md
#	docs/pages/native-engine.md
#	include/pineforge/source/pine_adapter.hpp
#	src/source/pine_adapter.cpp
…tion order, doc anchors, roots test fixture

The lab preflight of the integration d1fbc16 (rj-20261020t190008-5ff372)
failed in three stages. Causes fixed at their sources, no guard loosened:

- check_run_failure_codes: the cohort restore_record corruption throw in
  pine_adapter.cpp now goes through a noreturn helper
  detail::raise_scratch_io_error (scratch_errors.hpp) that throws the same
  ScratchIoError (system_error with errno, scratch_io_failed), so the
  scanner's coded-throw rule is met; the pine_adapter.hpp bare-rethrow
  allowlist row is tightened from 2 to 1 (the q store removal deleted
  PlacementTable::try_emplace's catch; the remaining one is
  OriginRoster::push_back).
- verifier-tests: the 16-shard failure was the same guard aborting the driver
  before the stage under test; the 105/85 export counts were already correct.
- The adapter header declares the two scratch binders in namespace
  pineforge::detail before its qualified friend declarations (the private
  src/scratch_table_binders.hpp is not included from an installed header).
- doc-anchors: 301 bad file:line citations re-derived, digits only, after the
  source edits (native-engine.md 3, pine-to-native.md 82, ADR-0001 22,
  native-feature-parity.md 186, native-refactor-progress.md 11).
- test_successor_roots_ram.cpp: the neighbour fixture no longer sets K_q/B_q
  (the q regions are reserved zero and the layout refuses a nonzero q); the
  atomicity assertions are unchanged.

Executed verification: none yet; proven only by the lab remote four-step on the
exact commit.
…paths

Four-step 2 (rj-20261020t194625-6a7bd1) failed release ctest on two tests.
Source reading showed both fixtures encoded wrong premises; production
behaviour is unchanged and correct.

- tests/test_run_json_jailed_profile.py: every monkeypatch.setenv() in a
  create callback performs its own environ.get() for cleanup bookkeeping,
  so four callbacks produced the four extra PINEFORGE_RUN_JSON_PROFILE
  reads the one-read assertion counted. The callback now assigns
  os.environ directly (the initial setenv still owns cleanup), keeping the
  exact one-read assertion intact.
- tests/test_adapter_tree_ram.cpp: the first failing condition was
  ranks.checked, not bytes: execute_current() latches the capacity failure
  and throws before the checked flag is set. The fixture now asserts the
  thrown code and resource, then runs every existing state assertion. The
  byte-cap sizing itself is correct (61 bytes admitted, 62 required).

Edit-only round: no production file changed, no build or test run locally.
lab verification remains owed on the resubmitted four-step.
…re it corrupts the record

Four-step 3 (rj-20261020t205342-f04bf9) failed one ctest row,
test_adapter_tree_ram, at the corrupt-record witness. The fixture assumed the
first source_hash() spills the sole cohort row; the sorted range pins that
first row, so the row stayed resident and the later restore never read the
corrupted slab bytes (io stayed false).

- tests/test_adapter_tree_ram.cpp: after the first hash the fixture runs a
  missing-id strategy_close, which spills the unpinned row through the real
  find() path and asserts one more orphan spill. Because that close records a
  dropped close, a clean control host runs the same commands and supplies the
  reference hash; no digest is typed in.

Edit-only round: no production file changed, no build or test run locally.
lab verification remains owed on the resubmitted four-step.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CR-150 route (ii): jailed preallocated scratch slab (integration)
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