Skip to content

complete value ownership: typed invalid values across source, config and derived state (selected-window contract revision 1.3) - #388

Merged
luisleo526 merged 55 commits into
mainfrom
lv/en132
Oct 14, 2026
Merged

luisleo526 merged 55 commits into
mainfrom
lv/en132

Conversation

@luisleo526

@luisleo526 luisleo526 commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

This lands EN-132: complete value ownership for the selected-window contract
revision 1.3. Every actionable value that reaches settlement or the report is
now produced through a typed failure — strategy_value_invalid,
engine_command_value_invalid, report_result_invalid,
report_post_execution_failed — instead of becoming a non-finite number or a
generic refusal. The engine image declares contract revision 1.3 through
--capabilities-json (capabilities.selected_window_contract_revisions =
["1.3"] for a supported runtime, [] otherwise); the wire version, phase
version and fingerprint/schema version are unchanged.

What it covers (each with user effect): source doors (strategy_entry,
exit, order, cancel, risk.*, declaration/margins) admit text, levels
and quantities through typed codes; the derived engine arithmetic (sizing,
margin, fee/commission, slippage, relative-price, risk thresholds/equity,
settlement) fails closed as engine_command_value_invalid; the native
settlement guards refuse an invalid closed row; the report producer emits
report_result_invalid and post-boundary report_post_execution_failed
instead of writing a non-finite document. An ownership manifest plus a
source-only checker and its controls pin the producer set, and an independent
D4 route pins the report schema.

Deliberate decisions, kept and named: D6 rows 17 (relative_price.level
native arming overflow → typed NonrepresentableQuantity refusal), 21 and 22
(settlement row guards → engine_invariant) are KEEPs with their user effect
unchanged. Policy decision: the pinned signal-time rejection
wins; G1's throw is narrowed; row-7 is re-scoped.
commission_type unknown
int → Percent, and the generated legacy strategy_set_override export losing a
carried reason, are stated gaps with their own cards.

Proof: the release/debug/kernel CI profiles and the eight-step lab remote
set on the final tree; a spot box that runs the three Release builds + Debug,
the fixture-absence calibration, the named GREEN sets, the RED fail-before
population, 157 curated mutants / 163 pairings each killing its named test,
and the tripwire corpus zero-count; and an overlay release with the private
fixtures whose stale settlement control is reconciled to the coded failure
(overlay job rj-20261014t051458-76684e, GREEN). Four release-profile failures
found by the box were triaged to five EN-132 defects, fixed, and re-proven; the
base-check release job on engine main passed, confirming they were EN-132's.

Not claimed: that every word-composition or census gap is closed; the
uncovered obligations (four F/M mutant rows and the G-PRICE equivalent mutant)
are named in the mutant report.

Stated proof gaps

Eight changed Python cases in tests/test_run_json_post_execution.py are observed green on both engine main and this head and carry no advance preservation/control declaration, so they contribute no fail-before evidence. They are proof gaps, not blocks: correctness for the behaviours they exercise rests on the GREEN rows, the sweep and parity. Each is listed for follow-up:

  • test_engine_resource_and_unclassified_lines[out_of_memory-resource-after-boundary-ordinary|selected] (:324): an engine out_of_memory after the boundary becomes reason resource.
  • test_engine_resource_and_unclassified_lines[engine_unclassified_error-exception-after-boundary-ordinary|selected] (:324): an engine engine_unclassified_error after the boundary becomes reason exception.
  • test_missing_observer_acknowledgement_stops_before_report_access[ordinary|selected] (:346): a missing observer acknowledgement stops before report access.
  • test_results_digest_request_is_refused_before_execution[ordinary|selected] (:473): a results-digest request is refused before execution.

Mutant matrix

163 mutant pairings, run in four shards with the fixtures and source-layer options on:

  • 160 killed by an assertion in the paired test. Every kill was read against the patch it answers; none was unrelated.
  • 2 detected by an error rather than an assertion, listed apart and not counted as kills:
    • quantity_defined_fallback_becomes_error in test_value_admission_arith: the test process aborted. Attribution rests on the baseline passing and the restored tree passing.
    • 06-stream-half-report-to-stdout in test_encoder_failure_after_report_chunks[exception-selected]: the test body's JSON decode of the child output raised.
  • 1 survivor, d6_13_slippage_evaluation_order, closed in this PR. The new row d6_13_current_slippage_bits in tests/test_value_invalid_fee_slip_settle.cpp passes on this head and fails under the mutant at line 377.

All 163 restored trees pass. All 10 settlement pairings are killed. Two follow-ups make the error-detected tests fail by an assertion before the 1.6.0 final.

🤖 Generated with Claude Code

luisleo526 and others added 30 commits October 13, 2026 10:55
…y (EN-132 L0)

Header-only base every EN-132 lane branches from: the source-side
strategy_value_invalid throw with the closed `field` vocabulary
(src/source/pine_value_admission.hpp) and the generic kernel-side
engine_command_value_invalid throw with the stage vocabulary
(src/engine_value_invalid.hpp). No call site yet, no behaviour change.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ipwire build (EN-132 L0b)

engine_command_value_invalid_or_count: throws in a normal build; with
-DPINEFORGE_VALUE_TRIPWIRE it prints one counting line and returns so the
old branch after the call runs unchanged. Header only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… three guards (EN-134)

The pre-commit guard of a closed settlement row checked only pnl and commission;
entry_price, exit_price, qty, pnl_pct, max_runup and max_drawdown reached the
report unchecked, and the end-of-range open-position rows had no guard at all.

- engine_orders.cpp / engine_internal.hpp: internal::closed_row_all_finite over
  the eight doubles of a Trade, generic (no Pine logic, no new status or code).
- engine_execution.cpp: the staged commit guard and the two guards of the
  fused one-lot settlement (projection and prepare) use it; the status stays
  InvalidAccounting, rendered engine_invariant as before.
- native_execution_consumer.cpp: a non-finite end-of-range row throws
  std::logic_error before it is appended (rendered engine_invariant by the
  existing classifier; traced in the lane notes).
- tests: test_native_settlement_row_finite drives 14 fault rows and 9 finite
  controls through the public C ABI (staged two-lot closes and range-end
  rows). The fused one-lot close is covered by the guard change but not yet by
  a row; a follow-up adds it. The kernel's std::max(0, x) excursion floors are
  deliberately unchanged.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… and summary values fail as report_result_invalid (EN-133)

json.dump ran with allow_nan=True and the trades list and summary carried raw
float() values, so a non-finite number became a bare NaN/Infinity token that a
strict JSON parser rejects.

- _validate_report_result: after the report dictionary is built (selected and
  ordinary run), the eight doubles of every trade and the five summary doubles
  must be finite, else RunFailure report_result_invalid with an engine-literal
  field (trades.<leaf> / summary.<leaf>) and reason nonfinite.
- allow_nan=False at the report writers and the printed capabilities and
  validation-only documents. A value that still reaches a writer fails while the
  document is in memory (report_post_execution_failed, serialization, behind the
  acknowledged phase boundary). The failure-line writer keeps its default: its
  args are not universally sanitized.
- Metrics, equity curve and recorded outputs keep _num (non-finite -> null).
- tests/test_run_json_nonfinite_report.py: all 13 leaves on both paths, the
  writer backstop, finite-output byte identity against the frozen base producer,
  null controls; the native-host process rows skip unless a host library is
  supplied. One sentence in report-schema.md.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…e parity (EN-134)

Comment only. L6 condition 3: the guard is an invariant of the kernel's own
Trade row, which is why it may live in the kernel.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…nd its self-test (EN-132 P0)

driver.py takes a Pine probe through the installed transpiler, the
entrypoint's compiler flags and the real run_json.py, and compares the
outcome with an expect.json pinned before execution. Seeds: a valid run, a
legitimate na limit, and a positive-infinity limit (red until the door
producer lands). README documents the schema; the self-test includes
deliberately wrong expectations that must FAIL.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…eplay of retained rows (EN-132 S1a)

strategy_value_invalid at each door, after the capture return and the legacy
gate, and again for every retained pre-roll row at replay (the replay bypasses
the wrappers). Invalid UTF-8 in id/comment/oca/from_entry texts and
+/-Infinity price levels and tick offsets are S; NaN stays absent (ruling D1);
quantity and percent arguments keep their documented defaults. Two arguments
stay unadmitted because existing tests pin infinity behaviour (exit.stop_price,
exit.trail_points) and infinite order.qty because the CANCEL path defines it;
all three are stated gaps.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…esult_invalid (EN-133)

Without --run-phase-fd there is no execution boundary, so the strict
json.dump(allow_nan=False) refusal on the ordinary report used to surface as
harness_internal_error. It now fails with report_result_invalid, field
"report.document", reason "nonfinite", for the encoder's exact refusal
messages only. With an acknowledged boundary it stays
report_post_execution_failed{phase: serialization}; other ValueErrors, and the
capabilities and --validate-window-only documents, keep harness_internal_error.
The old unphased pin is renamed and corrected, with a circular-document control.
One sentence in report-schema.md.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…N-132 S1b)

An infinite max_drawdown, max_intraday_loss or max_position_size now fails the
run with strategy_value_invalid (risk.max_drawdown, risk.max_intraday_loss,
risk.max_position_size; reason nonfinite) instead of reaching the adapter.
The check sits in the three host setters, so it applies live in every
evaluation including discarded pre-roll ones (D2), in the three retained-row
replay dispatches, and as a release-active check of the start/end risk
snapshots before their direct restore. NaN stays the existing absent limit
(D1); the three int setters cannot carry NaN/Inf and are unchanged.

Adds a host test, 22 risk probes under tests/ownership/probes/risk, and the
CMake registration.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…se 1)

An infinite default_qty_value, margin_long or margin_short in the source
configuration now fails the run with strategy_value_invalid
(strategy.default_qty_value / strategy.margin_long / strategy.margin_short,
reason nonfinite) before the configuration is stored or any caller override is
merged. Finite values, including non-positive margins, keep their definitions.
NaN stays admitted behind one constant, kDeclarationNanIsInvalid (D3-a): the
codegen never emits NaN for na, omitted or computed arguments, so a NaN here
has no script origin.

Adds a host test over the real configure path and eleven declaration probes
(six are compile-refusal coverage only; the paired native rows are the
producer witnesses), and the CMake registration. The caller-override door
(D3-b) is not part of this commit.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ts (EN-132 S3)

A finite raw level, tick or trail-point count whose normalization overflows to
an infinity now fails the run with strategy_value_invalid (reason
numeric_overflow, field = the door's own literal) instead of installing a
non-finite boundary. The checks cover the entry/order limit and stop decimal
grid, the trigger threshold (quotient, integral-inverse product, grid product,
half-tick addition and the candidate quotients), the percent-default entry
stop's directional snap, and the immediate exit trail-point tolerance.

checked_mul/div/add (pine_checked_arith.hpp) return no value only for finite
operands with a non-finite result; non-finite inputs keep their ordinary IEEE
value for the existing absence policy. Evaluation order is unchanged, and
derived prices, quantity floors and every call without a field keep the
original expressions. Raw sites only: effective exit levels and state-dependent
sums are not attributed to the script.

Adds a host test over the real command doors (overflow rows plus bit-identity
controls) and 28 arithmetic probes, and the CMake registration.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…t the fused one-lot route (EN-134, round b)

The finite-row settlement guard now also covers two adapter-side writers:
the terminal-quote presentation rebuild (the rebuilt mark and the quote
price must be finite before any presented row is overwritten) and the
TV-split amendment of committed rows (every replacement row is validated
before the committed rows or their tallies change). Either failure is
std::logic_error and ends the run engine_invariant. These are settlement
safety guards (an invariant), not Pine parity.

Adds one-lot fused-route rows (NaN, +/-Infinity runup and drawdown, pnl_pct
overflow, finite controls) to the native settlement test, and a source-layer
build of the same test for the terminal-quote and amendment rows.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…e (EN-132 S2, D3-b)

apply_overrides now rejects +/-Infinity in StrategyOverrides::default_qty_value
with the existing setting_rejected{entrypoint: strategy_set_override,
reason: number_out_of_finite_range}, before any member is merged, so both the
direct setter and begin's opaque overrides leave the prior configuration
installed. NaN still means "leave the declared value"; finite values,
including zero, negative and the extremes, merge as before.

The generated legacy strategy_set_override export catches invalid_argument and
re-renders it with the fixed reason unparseable_value, so that path ends with
that reason; preserving the carried reason there is a codegen change and is
not part of this commit.

The two D3-b acceptance pins in test_value_admission_decl are rewritten to the
ruled behaviour; new rows cover both paths, NaN, finite values and the begin
failure record.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A run.json that names the five selected-window flags now runs the Selected
route: the driver transpiles through transpile_with_request_inventory, binds
the inventory with the entrypoint's own binder, passes the bound inventory and
a run-phase descriptor to the real run_json.py, and collects the phase
records over an AF_UNIX socketpair under the phase transport v1 bounds. A
partial or duplicated selected request is refused, never run as ordinary.
expect.json gains an optional phase_final member compared with the last
record; the ordinary route is unchanged.

The self-test covers the selected argument construction, the phase-record
collection against a stub child, and a wrong phase_final failing its row.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Local lane base only; not part of any PR.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The std::isfinite(price) test beside the predicate is implied by it (the
rebuilt mark carries the quote price as exit_price), so no mutant can kill it
alone. It stays as the explicit statement of the invariant. Comment only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…d_value_invalid (EN-132 G3)

After the door admitted the arguments, a finite configured value that
overflows to an infinity in the engine's own arithmetic now fails the run with
engine_command_value_invalid instead of silently dropping a leg or disabling a
risk limit:
- relative_price.level (numeric_overflow): the exit's entry price +/- ticks *
  tick limit, stop and trail levels, and the same three constructions when the
  relative exits are materialized.
- risk.threshold (numeric_overflow, nonfinite when the equity base is already
  non-finite): the drawdown and intraday-loss thresholds in the Pine adapter
  (three sites) and in the native consumer; risk.equity (nonfinite): a
  non-finite marked equity in the native risk evaluation.
Every site goes through engine_command_value_invalid_or_count, so the
tripwire build counts instead of throwing. An infinite configured limit stays
the risk setter's S error; the invalid-source-level placeholder (row 16) and
the filled-order counter (row 20) are unchanged. The native arming refusal
(row 17) is already a typed engine_invariant failure and is left as it is.

Adds two host tests (native C ABI and scripted source host) with test-only
fixtures behind PINEFORGE_VALUE_INVALID_FIXTURES, ten probes, and the CMake
registration; intraday_loss_breached loses noexcept because it can now throw.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…(EN-132 X)

New tests/test_run_json_post_execution.py forces a failure through main() with
the real run-phase descriptor at each place after the engine acknowledged the
end of execution: native report extraction, a trade accessor after the library
returns, the report builder's summary read and validation read, the encoder
after report chunks, and the report buffer write. Each of MemoryError, OSError
and a generic exception must end report_post_execution_failed with phase
result_assembly or serialization and reason resource, io or exception, in
ordinary and Selected mode, and each row asserts the fault really fired.

Controls: an engine out_of_memory or engine_unclassified_error line becomes the
same code only after the boundary; strategy, setting, declaration, argument,
invariant and deadline-literal engine lines keep their code and args in both
states; a missing observer acknowledgement stops before any report access; an
exception during execution keeps its harness classification; a typed
RunFailure and a phase-transport error after the boundary keep their own
codes; failure- and report-looking lines on stdout or stderr decide neither
the outcome nor the phase; a results-digest request is refused before
execution (there is no digest producer in this tree).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…lid (EN-132 G2)

After the door admitted the arguments, an invalid value the engine derives for
a fee or a slippage fill now fails the run with engine_command_value_invalid
instead of being skipped or refused with a generic code:
- fee.commission: the modeled commission result (numeric_overflow), an invalid
  per-allocation cost or pinned ticket (nonfinite), the ticket and allocation
  sums (numeric_overflow), on the fused one-lot path and the staged chain, and
  the Pine adapter's opening fee and grossed unit.
- slippage.fill_price: a non-finite current fill price in the native consumer
  (nonfinite) and a non-finite derived sizing or recalculation fill price in
  the Pine adapter (numeric_overflow), only when the basis it came from is
  finite. The shared apply_slippage helper is untouched, so the defined
  rejection of a non-finite candidate price (row 12) stays.
Every site goes through engine_command_value_invalid_or_count, so the
tripwire build counts and runs the old branch. The position-cycle, entry and
stream-action counter exhaustion throws become coded engine_invariant
failures (same rendering, now explicit). The two functions of the finite-row
settlement guard are not touched; the settlement.row producers follow the
integration of EN-134.

The sites are not reachable from public input, so the test drives them through
injection hooks compiled only under PINEFORGE_VALUE_INVALID_FIXTURES, an
opt-in CMake option that is OFF in every profile; nine probes cover what is
reachable from a script.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ts (EN-134)

scripts/check_run_failure_codes.py refuses an uncoded throw in src/source
unless a row of scripts/run_failure_throw_allowlist.txt admits it. The
terminal-quote and amended-trade guards of the previous commit throw
std::logic_error (the classifier renders engine_invariant), so each gets a row
naming it an engine invariant. Found by the first spot-box run of the slice:
ci_verify stopped at this source guard.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…alid (EN-132 G1)

After the door admitted the arguments, a non-finite or overflowing value the
engine derives while sizing an order or computing margin now fails the run
with engine_command_value_invalid instead of becoming a silent no-order, a
refusal or a skipped liquidation:
- sizing.quantity / sizing.basis: a non-finite derived unit count, divisor,
  cash or denominator, a non-finite equity basis, and non-finite execution
  terms units (D6 rows 1, 3, 4, 5, 7, 9);
- margin.required / margin.maintenance / margin.restore: a non-finite
  required margin, held, mark, point value or fx, unit margin, equity or
  required amount, and a restore multiplication that overflows or a
  non-finite override (D6 rows 10 and the margin sizing rows).
Finite negative and zero results keep their defined outcomes. Every site goes
through engine_command_value_invalid_or_count, so the tripwire build counts
and runs the old branch; the generic kernel diff carries no Pine wording, no
origin tag and no durable state.

Two things to settle at integration, both recorded in the lane notes: the
non-finite execution-terms units case (row 5) conflicts with the existing pin
a_t5_terms_rejections_retain_attempted_terms in test_native_execution_terms.cpp,
which expects a completed run with InvalidTerms; and the C transport's NaN
units sentinel for an invalid enum reaches the same producer for unresolved
requests.

Adds two ownership tests (native and source companion; the source companion
uses a test-only injection point behind
PINEFORGE_VALUE_INVALID_SIZING_MARGIN_FIXTURES) and the probes.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…-132 S1a)

The first compile of test_value_admission_doors on a spot box refused two
reads of signed_position_size(), which the host exposes to derived classes
only. The test host re-exports it with a using-declaration. Test file only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…N-132 G1)

The first compile of test_value_invalid_sizing_margin_source on a spot box
refused the one-argument call. The public signature is
strategy_stream_end(pf_strategy_t, int finalize_partial_input_bar); the other
tests pass 0. Test file only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
… private hook (EN-134)

The terminal-quote row overrode PineStrategyHost::present_report, which is
private, and called the base implementation from the override; the real
compiler refused it (found on a spot box). The row now runs the same selected
window twice, once without a terminal quote, reads the unpresented row through
the public report surface and pins its fields, and compares the presented row
against it with the exit time normalized, plus the exact contract values
(quote close, pnl and pnl_pct 12, commission 0, equity 10012). The
presentation counter is gone: a run in which the product presentation did not
run would still fail the projected-row rows. Test file only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The placeholder-withdrawal row read the armed child's request and handle from
ArmedEvent members that do not exist in this tree; the real compiler refused it
(found on a spot box). An armed event carries a definition that holds the
request and the handle, and a cancelled event carries a definition too, so the
row now reads the label and the limit trigger from the armed definition,
matches the cancelled event on the same handle, requires it to come after the
arming in ordinal order, and counts exactly one of each. Test file only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ur does (EN-132 G1)

The first real build of test_value_invalid_sizing_margin failed two row-5 KEEP
controls: the finite negative and zero host-units cases were read from a
current-execution preview of a cohort-owned close, which current execution
refuses before it resolves terms, so neither outcome field was ever set. The
controls now preview an independent HostSized open request, as
a_t14_preview_outcome_table_without_mutation does, with the same two pinned
outcomes (InvalidTerms for finite negative units, NoEffect for zero), the
unchanged-hash and unchanged-history checks, an explicit no-refusal check and a
cancel afterwards. No product change: the diagnosis found no finite case that
moved. Test file only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ests (EN-132 G3)

The first real run of the two g3 tests failed six checks in three scenarios; the
lane's diagnosis (read from the code) found all three to be wrong tests, with no
product producer to move:
- row 18, pre-close intraday threshold: the scenario lowered the limit to zero
  before the queued applied notification was delivered (it is delivered after
  the calculation callback ends), so the threshold line was never reached; the
  scenario now keeps the finite limit set until the notification runs;
- row 16, placeholder withdrawal: the placeholder arms a Limit at zero, not at
  1.0; the row now pins that and the arming-then-cancelled relation by handle;
- row 19, finite zero and negative equity: the run reports no equity curve in
  that mode, so the check reads the report fields the mode does carry.
Probe notes follow the tests. No product change.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…(EN-132 G1)

A non-finite HostSized units value in the native execution terms keeps its
defined outcome: a completed run with an InvalidTerms rejection, at the
execution and at the preview site. This is test-pinned
(tests/test_native_execution_terms.cpp:702) and the C host's NaN units sentinel
for an invalid shape or grid enum (src/native_c_host.cpp:2604-2641) is a
contract hosts rely on. ENGINE-TOP and L6 ruled row 5 KEEP (13:10), so the two
nested sizing.quantity producers added by the previous G1 commit are removed;
both branches are byte-identical to the base again. Finite negative units keep
InvalidTerms and finite zero keeps NoEffect. Rows 1, 3, 4, 7, 9 and 10 stay
engine_command_value_invalid as ruled.

The test drops the six row-5 fault cases and the row-5 producer mutants, and
pins the kept NaN-units outcome from the existing neighbour's expectation.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
luisleo526 and others added 23 commits October 13, 2026 13:42
…tlement.row rows (EN-132 G2)

ENGINE-TOP and L6 ruled the non-finite closed-row and marked-row failure KEEP
engine_invariant: EN-134 decides that branch, it is already a typed failure,
and EN-134's own rows pin the code and message. The two deferred rows of this
test (d6_21_settlement_pnl, d6_22_settlement_excursion) expected the
engine_command_value_invalid settlement.row code that was never to be
produced; they are removed (no mutant existed for either). The three
settlement probes now pin the kept outcome (engine_invariant, empty args)
instead of the G code, with the EN-134 test as their native boundary control.
The release notes say: rows 21/22 kept engine_invariant (EN-134).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ed evidence line (EN-134)

The first full ci_verify run of this slice on a spot box found two things the
lane tests could not:
- test_native_fused_settlement failed (its randomized book compares the fused
  and the staged transcripts and found them different at the same step for
  dozens of seeds), on the Release and the Debug build alike; it passes on the
  base. Cause: the all-field settlement guard had also been put into
  OneLot::project, the fused route's PREVIEW, but the staged route has no
  full-row check before its commit stage, so a row with a finite pnl and
  commission but another non-finite figure failed one step earlier on the
  fused route. The preview goes back to its money-only check; the full-row
  guard stays in OneLot::prepare and in prepare_native_settlement_commit, the
  two commit-stage sites, so the fused and the staged route fail at the same
  step again. With this change all 34 settlement rows and the fused test pass
  on a Release build (checked on the box).
- tests/private_fixture_reads.evidence pins the line of a registration in
  tests/CMakeLists.txt; the one added test source moves it by one line (3252).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Engine main moved while the EN-132 slice lanes were built on 9da4c98: EN-133
landed as a squash (#384), the CI time limits were removed (#378), the API docs
gained the favicon (#355), and the corpus regeneration pin moved to codegen
1.5.0. Three files conflicted and are resolved:

- tests/test_run_json_nonfinite_report.py takes main's version whole (the frozen
  producer is read from engine main 7da487a, not from a lane commit).
- tests/CMakeLists.txt keeps both sides' registrations; the EN-133 test is
  registered once.
- tests/private_fixture_reads.evidence is recomputed from the resolved file: the
  pinned registration line is now 3268 (and its add_test at 3288).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…nce test

Lane m (round 1 + round 2). Adds the revision-3 value-ownership contract as
data plus a source-only checker that reconstructs producers independently and
compares them, with negative controls and an independent D4 reconstruction.

- tests/ownership/manifest.v1.json: the contract (vocabulary, sinks,
  admission routes, descriptors, catalog and canonical schema) with a closed
  kept_branches section recording the L6 D6 KEEPs (rows 17, 21, 22) and their
  function/literal anchors.
- scripts/check_selected_window_ownership.py: reads source only (stdlib, -I
  safe), discovers S/G/R/X producers and rejects any divergence from the
  manifest; a settlement or native-arming G producer that contradicts a KEEP
  is rejected irrespective of the manifest; unknown syntax fails closed.
- tests/ownership/test_manifest_checker.py: negative controls (renames,
  omissions, duplicates, same-count swaps, catalog/registry drift, kept-branch
  anchor removal and producer gain) on temp copies, plus the route-two D4
  reconstruction by evaluating the real report builders.
- wiring: ci_preflight.py, ci_verify.py and tests/CMakeLists.txt register the
  checker and the controls.

Round 2 adds the kept_branches decision set and the no-settlement /
no-native-arming G guard. Source-trace only; no checker, test or build was
executed by the lane (the supervisor's box runs them).

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Lane f, the last slice. Flips the one declared selected-window contract
revision from the prerelease parity literal to the complete-ownership literal
and updates its pinned tests and docs. Merges last, after lanes r, m and bx.

- docker/selected_window_report.py: CONTRACT_REVISIONS = ("1.3",) - the single
  place the revision is written; the capability record reads it, so the
  --capabilities-json probe now advertises ["1.3"] for a supported runtime and
  [] otherwise. No feature switch, environment knob or second constant; the
  wire version (1), phase version (1) and fingerprint/schema version (2) are
  unchanged.
- tests/test_run_json_selected_window.py: the pinned assertions inverted to
  the complete revision (never the parity literal), the "no revision literal
  in a request/report/phase/fingerprint" checks extended, and a guard test
  that rejects the old or any stray revision tuple by mutating the source.
- README.md, docker/README.md, docs/pages/report-schema.md: state that the
  1.6.0 image declares revision 1.3 - complete value ownership through
  strategy_value_invalid, engine_command_value_invalid,
  report_result_invalid and report_post_execution_failed.

The receipt checks (check_capability_revisions with value_ownership.status
complete, and check_stable_complete) confirm a release receipt pairs exactly
["1.3"] with a complete status; amendment 6 requires that pairing before the
pin ships. Source-trace only here; the integration box runs the capability
tests.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Merge lv/en132-m (620deea) into lv/en132-r on top of the engine-main merge
5b1f003. Adds the revision-3 ownership manifest, the source-only checker, its
negative controls and the independent D4 reconstruction, and registers them in
ci_preflight.py, ci_verify.py and tests/CMakeLists.txt. The merge was clean (no
conflict, no resolution needed).

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Merge lv/en132-f (e207130) as the final slice, so the capability flip tops the
integration tree: CONTRACT_REVISIONS ("1.3",) with its pinned tests (the parity
literals inverted, a stray-revision guard) and the three docs stating complete
value ownership. Clean merge.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Bring the integration tree onto current engine main before the integration box
and the verification run. Clean merge; #383's benchmarks changes land with no
conflict.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Bring the integration tree onto current main: #386 moves the futures and forex
captures to the private fixtures and adjusts the pins and floors.

One conflict, tests/private_fixture_reads.evidence, resolved by RECOMPUTING the
pinned lines on the merged tree, not by choosing a side: registration
tests/CMakeLists.txt:3267, add_test :3287, the counts :3235/:3263 and the else
branch :3293-3294. tests/CMakeLists.txt itself auto-merged (both sides' rows
kept). scripts/check_private_fixture_reads.py passes on the merged tree (rc 0).

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The release box failed four ctest rows; the triage named each cause, and the
base-check lab remote release job passed on engine main (exit 0), so all four
are EN-132's, not environmental and not pre-existing on main.

- tests/test_value_admission_arith.cpp: the S3 control now asserts the
  downstream engine code and the exact relative_price payload G3's guard
  produces, instead of expecting no failure.
- src/source/pine_adapter.cpp: narrow G1's pre-rejection throw at both row-7
  placement sites so a finite explicit requirement overflow falls through to
  the pinned signal-time rejection-and-continuation; nonfinite placement
  inputs and equity still fault.
- tests/test_value_invalid_sizing_margin_source.cpp: re-scope the row-7
  witness to default-sized placement overflow and nonfinite pointvalue, and add
  keep_finite_explicit_placement_overflow() pinning the rejection-and-
  continuation for finite explicit overflow.
- tests/ownership/test_manifest_checker.py: expect the checker's 'stale'
  diagnostic (its set-difference convention) for the removed-registry-row
  negative.
- scripts/test_private_fixture_reads.py: copy the nested ownership driver into
  TamperTree so the two new registrations resolve.

L6 default ruling 10-14 06:5x: the pinned signal-time rejection wins; G1's
throw is narrowed; row-7 is re-scoped.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Bring the integration tree (with the four release-failure fixes) onto current
main: #387 makes run_all.sh record the busy count as unknown on a host without
ps and label the figures quiet-unverified. Clean merge, no conflict.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The fifth release-box row aborted: lane G2 turned an infinite modeled
percentage fee into a coded engine failure (src/engine_execution.cpp:43) while
the old control still expected a returned execution::Status::InvalidAccounting,
so the coded exception terminated the process. The control now catches the
coded failure and asserts engine_command_value_invalid with
fee.commission / fee / numeric_overflow; the tripwire build
(PINEFORGE_VALUE_TRIPWIRE) keeps the returned-status expectation, and the
unchanged-book checks and the explicit quoted-fee control are kept. Per
TRIAGE5.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The EN-132 integration moved lines in the source, so the documentation
anchor checker failed on six documents. Every failing citation is re-anchored
to the real line of the symbol it names — citation digits only; document
prose, paths, symbol claims and content pins are unchanged, and the line
counts are preserved.

- docs/design/native-feature-parity.md — 294 citations
- docs/adr/0001-kernel-adapter-boundary.md — 80
- docs/pages/pine-to-native.md — 10
- docs/native-refactor-progress.md — 10
- docs/pages/native-engine.md — 8
- docs/pages/contributing-llm.md — 1

scripts/check_doc_anchors.py: 1742 anchors, ok 1742, bad 0 — every
documentation anchor resolves to its symbol.

Keep every existing file.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
The EN-132 mutant matrix left g2/d6_13_slippage_evaluation_order alive
against test_value_invalid_fee_slip_settle: it rewrites the current
execution fill price from on_grid + ticks * tick into
(on_grid / tick + ticks) * tick. Both forms are the same in real
arithmetic; the test held only the both-infinite overflow row, so the
regrouped form passed.

Add the row d6_13_current_slippage_bits. A current execution at price
100.0, price_tick 0.1, slippage_ticks 1 (no price grid, so the grid snap
is the identity) must fill at the head's ADD form, 100.1 (hex
0x1.9066666666666p+6); the DIVIDE form gives 100.10000000000001
(0x1.9066666666667p+6). The row asserts the engine's own trade entry
price against that literal, not a value recomputed from either formula.
The inputs were found by static binary64 arithmetic (find_inputs.py,
prove_kill.py); no test was built or run locally.

Test-only change, nothing under src/.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@luisleo526
luisleo526 merged commit 868aa65 into main Oct 14, 2026
20 checks passed
luisleo526 added a commit that referenced this pull request Oct 14, 2026
* docs: the 1.6.0-rc.1 changelog entry

The changelog section for the first candidate of 1.6.0, tag v1.6.0-rc.1 on
commit 04607c1: the selected-window contract
revision 1.3 and the typed failures behind it (#388), finite trade and summary
doubles in every report writer (#384, #388), the favicon of the API
documentation (#355), the removed CI time limits and command-line options (#378),
and the tests, CI and benchmarks changes since 1.5.0 (#375, #376, #377, #382,
#383, #385, #386, #387).

The entry is inserted above the 1.5.0 section; no existing line changes. The
date is the UTC date of the tag.

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

* README: link the apex pineforge.dev, not the www host

The README header link pointed at https://www.pineforge.dev. The product site
lives at the apex, https://pineforge.dev; the www host is being redirected to
it, and search indexes both forms today. One link changed, nothing else.

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

* CHANGELOG: add the selected-window mode and typed failures to the 1.5.0 notes

Two things that are in the v1.5.0 tag were missing from its notes: the opt-in
selected-window mode with retained pre-roll bars (#363, already in
v1.5.0-rc.1) and the typed failures that docker/run_json.py raises for
exceptions from the selected-window helper modules (_typed_failure).

The new subsection "Additions to the 1.5.0 notes" only states what the code
and the #363 text say, with the same "development-only parity candidate"
limits (contract revision 1.3-parity, no claim of complete value-ownership
coverage, cannot be promoted to stable). It adds lines and changes none.

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

---------

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 17, 2026
… not 'complete' (#400)

docs/pages/report-schema.md said that revision 1.3 means "complete value
ownership with" the four value-failure codes. That sentence came in with
868aa65 (#388). No completeness proof has been run (EN-115), so the
published API docs claimed more than the evidence supports. The sentence now
says "covering value ownership through", the wording of the 1.6.0 notes
(CHANGELOG, README.md, docker/README.md, #399). It replaces the #388 phrase
"meaning complete value ownership with".

Docs only; no code, test or harness change.

Co-authored-by: CORE-TOP <[email protected]>
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
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