Skip to content

Support engine v1.0.0 and codegen 1.0.0 - #3

Open
luisleo526 wants to merge 7 commits into
mainfrom
v1/support
Open

luisleo526 wants to merge 7 commits into
mainfrom
v1/support

Conversation

@luisleo526

Copy link
Copy Markdown
Contributor

Summary

This makes pineforge-live and its test suite work with the PineForge engine v1.0.0 release and pineforge-codegen 1.0.0, and replaces the README's "Engine v1.0.0 support is pending" with what was checked.

Test results against engine v1.0.0

Setup: Linux arm64 (Ubuntu 24.04), Python 3.12.3. scripts/build_engine.sh built all 312 corpus libraries.

Tree env -u PINEFORGE_ENGINE_ROOT python -m pytest PINEFORGE_ENGINE_ROOT=<absolute path> python -m pytest
Before: 5a6b29b 950 passed, 151 skipped 22 failed, 1079 passed
After: 224c417 952 passed, 152 skipped 1104 passed, 0 failed

Where the 22 failures were: test_live_core 14, test_book 2, and one each in test_abi, test_execution_replay, test_ids, test_l1_harness, test_runtime_checkpoint and test_signal_engine[test_so_pooc].

After the fix there is one new offline test and one new engine-backed test. The engine-backed count is now 152.

End-to-end run through the CLI (same host, engine v1.0.0)

  • README demo. scripts/make_webhook_demo.py plus examples/webhook_receiver.py over loopback HTTP:
    • pineforge-live run delivered 16 actions; a second run delivered 0; check delivered 0.
    • The receiver stored 16 unique event ids.
    • pineforge-live engine-info: abi 4, version 1.0.0, exports 25/25.
  • Codegen 1.0.0. Installed with pip install pineforge-codegen==1.0.0. It transpiled the corpus SMA and ATR-bracket strategies, which were compiled with verification.probe_case.compile_strategy against the v1.0.0 build and run through the same demo.
    • Deliveries: 16 for SMA and 13 for the bracket strategy, then 0 on re-run and in check.
    • Each delivery matches the corpus library's on bar, id, action, leg, contracts and price.
    • The SMA C++ is byte-identical to the corpus copy.

Changes

Runtime

  • core/ids.py: new intent_kind.
    • v1.0.0 reports every strategy.entry in the pending-order mirror as type 1 (ENTRY), market or priced (see mirror_order_type in the engine's src/source/pine_adapter.cpp). The ABI-v4 revision before it reported a market entry as 0 (MARKET).
    • intent_kind keys an ENTRY row whose requested limit_price and stop_price are both NaN as MARKET again.
    • Result: Intent.is_market, LiveCore's settle-time MARKET_AT_OPEN legs and the open requote/withdraw path work as before, and intent keys are unchanged.
    • Both fields are read strictly: a missing field raises an error instead of defaulting.
  • core/book.py: settled_book guard.
    • v1.0.0 marks the mirror's level fields "deprecated, derived output only".
    • settled_book now raises when a MARKET key that the engine reported as ENTRY has a finite stop or limit in effective_levels. Without the guard, a priced entry misread as MARKET would be sent at the open as a market order.

Tests

Each change below records something measured against v1.0.0; the commit messages have the details.

Test v1.0.0 fact
test_ids: engine-header test engine.hpp no longer has enum class OrderType. The test now parses mirror_order_type and checks every PineOrderFamily against the unchanged codes.
test_ids: new offline test An ENTRY row with no levels gets a MARKET key; a priced one gets an ENTRY key; missing level fields raise.
test_book: flat-to-long keys An order placed while flat is stamped with the last position cycle (99, not 0). XL keeps its key through the entry fill but reads MODIFIED, because its qty goes from NaN to 1.0. A same-id re-issue after the fill is a new placement (CANCELLED + RESTING). A re-issue within the same cycle reads MODIFIED.
test_abi: abort v1.0.0 drops an abort requested before the run begins. For the full feed in a fresh process, the run begins 3–10 ms after the C call, so the single request at 3 ms was dropped in 5 of 5 runs. The test now repeats the request every 0.5 ms until the call returns.
POOC probe (order-deferred-flip-pooc-cross-bar-01) v1.0.0 fills the flip's stop entry at the cross bar's close, as TradingView's trade list does: on 2025-03-31 the short entry is 1802.93, the close of the 08:00 UTC bar. The entry never rests between bars, so it has no Pine id (?). Webhook: id: null, identity_resolved: false, as docs/webhooks.md documents; the test pins 4 such fills. L1 harness: each flip emits a close MARKET_NOW plus an unattributed entry MARKET_NOW, with still 0 MISSED, 0 incidents and 0 STOPs. Execution replay: the coordinator refuses unattributed entries by design (docs/plan-b3.md), so the replay stops at bar 2048.
test_probe fakes The fake ENTRY mirror rows now carry the level fields that real rows have.
New: test_book guard, test_live_core resting stop entry In order-dual-stop-far-only-01 (new test_so_dual_stop fixture), the resting long and short stop entries stay ENTRY and get no market leg.

Docs

  • README install. Build from the v1.0.0 tag; all 152 engine-backed tests pass.
  • README codegen. Install pineforge-codegen==1.0.0. Per codegen's rule, a codegen release pairs with the engine tag of the same version.
  • README verify. The two-input report was recorded with pre-1.0 revisions.
  • docs/webhooks.md. Documents the null-id case.
  • docs/execution.md. Documents the replay refusal.
  • CHANGELOG.md. New Unreleased entry.

Known limits (not changed here)

  1. Entries filled by process-orders-on-close on their own bar get no Pine id. The engine exposes no id for an order that never rests. Webhooks carry id: null, and the execution research track refuses such entries. Fixing this needs either an engine ABI that names the order behind an open position or a policy decision in the execution track.
  2. Same-id re-issues can change their key. v1.0.0 gives a new key to a same-id re-issue placed in a later position cycle. No driver mirrors resting exits today. An exit-mirroring driver would issue CANCEL_STALE_CYCLE by Pine id for the old key, and check_stop_transition would read the new key as a missing stop.
  3. Early abort requests are dropped. The engine drops abort requests made before a run begins. The runtime's abort_probe is best effort: a dropped request only lets that probe finish.
  4. No codegen dependency or version range exists in this repo. The README names codegen 1.0.0 as the pair of engine v1.0.0.
  5. Campaign verification was not re-run. The two-input campaign verification needs private inputs and was not repeated with v1.0.0.

The engine and codegen are unchanged.

🤖 Generated with Claude Code

luisleo526 and others added 7 commits September 29, 2026 19:44
- README Verify: the engine-backed test command used a relative
  PINEFORGE_ENGINE_ROOT; as written it fails 17 tests (strategy_path not
  found from temp configs). The absolute form passes 1101/1101 at the pin.
  Source: pytest runs from a clean clone.
- README Verify: install '.[dev,websocket]' so the WebSocket tests the
  text lists run (948 passed/153 skipped without the extra).
- README Install: no engine release has ABI v4 (v0.13.1 is
  PF_ABI_VERSION 3; a v0.13.1-built strategy is refused with "missing
  export strategy_request_abort"); the pin 399eead is v0.13.1-111 on engine
  main, in no tag. ABI v4 alone is not enough: engine main 35db01c8 runs
  the demo but fails 21 engine-backed tests. Source: pineforge.h@v0.13.1:80,
  git describe, engine-info and pytest runs.
- README Install: pineforge-engine is a C++ repository, not a Python
  package (PyPI 404); state the corpus feed size (176 MB LFS pointer).
- README: name the verified codegen revision 0fe2189f (v0.10.4-3, codegen
  main). Source: docs/verification JSON sourceCommits, git describe.
- README Verify: the two-input result is live-vs-batch equivalence, not
  TradingView parity; the image, case artifacts and review it pins are not
  public. Source: JSON, gh repo view pineforge-lab.
- README layout: add bars/, adapters/, execution/, drivers/,
  verification/ and cloudrun/; maintainer tooling ships in the repo and
  wheel and needs private repos and cloud storage. Source: wheel listing.
- docs/execution.md, docs/core.md: the README has had no L1 quickstart
  since 4fd8318; point to the Install build and l1_harness.py --help.
- docs/core.md, docs/plan-b3.md, ledger.md, cloudrun/README.md: mark the
  unpublished pineforge-workflow-live spec/ledger and private
  pineforge-lab/pineforge-workflow; redact an internal session id; note
  the ledger predates publication (repo created 2026-09-09, v0.1.0).
- docs/plan-b3.md: say that absent planned modules were never built.
- docs/two-input-verification.md: 4,190 was the probe population at the
  time (JSON selection.population).
- docs/verification JSON: redact the internal GCS bucket name from 35
  case-artifact URIs; keys, generations, sizes and SHA-256 are unchanged.
- CONTRIBUTING: the wheel also ships the maintainer verification modules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Engine v1.0.0 (2026-09-30) provides ABI v4, so "no engine release
provides ABI v4 yet" is stale. This revision (9d76f8c) was tested on
Linux arm64 against the pin and against v1.0.0 with the same OS and
Python:

- pin 399eead: build_engine.sh builds 312 corpus libraries; 950 passed
  and 151 skipped without the engine, 1101 passed with it; the README
  demo delivers 16 actions, then 0 on re-run and in check.
- v1.0.0 (5718c5dc, corpus b40aa8ec): the libraries load (abi 4,
  version 1.0.0, exports 25/25) and the demo delivers 16, then 0, but
  22 of the 151 engine-backed tests fail (1079 passed).

The README keeps the pin, says v1.0.0 support is pending, warns that
v1.0.0 libraries load without error, and names the releases whose
libraries are refused (up to v0.13.1, ABI v3 or older). Codegen 1.0.0
output includes pineforge/source/pine_strategy_host.hpp, which the
pinned engine does not have (compiling it against the pin stops with
"No such file or directory"), and codegen 1.0.0 is supported only with
engine v1.0.0; the README says so, keeps the verified pre-1.0 codegen
revision and shows how to install it (pip install of the git revision,
checked). Both pins are ancestors of the v1.0.0 tags.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Engine v1.0.0 reports every strategy.entry in the pending-order mirror as
type 1 (ENTRY), market or priced (mirror_order_type in
src/source/pine_adapter.cpp); the ABI-v4 revision before it reported a
market entry as 0 (MARKET). Intent.is_market therefore never fired, so
LiveCore asked for no MARKET_AT_OPEN legs and the open requote path had
nothing to supersede.

ids.intent_kind reads the mirror's requested limit_price/stop_price (NaN
when absent, per the engine's pending intent view) and keys an ENTRY with
neither as MARKET. The settled book and the probe's departure check both
build keys through intent_key_for, so they stay consistent, and intent
keys are the same as on the earlier engine. Both fields are read
strictly: a mirror without them raises instead of turning priced entries
into market orders.

engine.hpp no longer declares enum class OrderType, so the header test
now reads mirror_order_type and checks every Pine order family against
ORDER_TYPE_NAMES (the codes are unchanged).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Five engine-backed tests still failed after the MARKET fix. Each follows
an engine v1.0.0 behaviour change measured on the corpus fixtures; none
needs a runtime change.

- test_abi abort: v1.0.0 copies and checks the bars before the run
  begins and consumes any abort requested before then. For the full
  15m feed that takes 3-10 ms in a fresh process, so the single request
  3 ms after entering the C call was dropped (status 0, five runs of
  five). Re-request every 0.5 ms until the call returns; the next run
  still proves an idle abort does not leak.
- test_book flat-to-long: v1.0.0 stamps an order placed while flat with
  the last position cycle (99, not 0); a flat-placed exit keeps its key
  through the entry fill but reads MODIFIED there (its qty becomes the
  filled position), and a same-id re-issue is a new placement stamped
  with its own cycle, so the first re-issue after the fill re-keys
  (CANCELLED + RESTING) while a re-issue within one cycle reads MODIFIED.
- POOC probe (order-deferred-flip-pooc-cross-bar-01): v1.0.0 fills the
  flip's stop entry at the close of the cross bar, not the next open.
  That matches TradingView's trade list: on 2025-03-31 both book the
  short at the 08:00 UTC cross bar's close, 1802.93 (the corpus's older
  recorded engine trades show the next open, 1802.94). The entry never
  rests in the settled book, so no Pine id reaches the runtime ("?").
  - signals: the webhook already sends such a fill with id null and
    identity_resolved false (docs/webhooks.md); the expected list now
    applies that mapping.
  - L1 harness: each of the four POOC bars is a close plus an
    unattributed entry, both MARKET_NOW; still zero MISSED, incidents
    and STOPs.
  - execution replay: the coordinator refuses an unattributed entry by
    design (docs/plan-b3.md), and every POOC fill in the window is such
    a flip, so the replay now reports that refusal at bar 2048.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The runtime now works with the engine v1.0.0 release; replace the
"support is pending" wording with what was checked on Linux arm64
(Ubuntu 24.04, Python 3.12.3) on 2026-09-30:

- README Install: build from the engine's v1.0.0 tag (commit 5718c5dc,
  corpus b40aa8ec) instead of the unreleased 399eead pin. All 151
  engine-backed tests pass with it; the README demo delivers 16 actions,
  then 0 on re-run and in check.
- README codegen: install pineforge-codegen 1.0.0 from PyPI. Codegen's
  own pairing rule supports a 1.x release only with the engine tag of the
  same version; its output needs pine_strategy_host.hpp, which only
  v1.0.0 has. Transpiling the corpus SMA and ATR bracket strategies with
  it, compiling through verification.probe_case.compile_strategy against
  the v1.0.0 build and running the demo delivers the same actions as the
  corpus libraries (16 and 13; engine-info abi 4, version 1.0.0,
  exports 25/25).
- README Verify: the two-input report was recorded with the pre-1.0
  revisions it names, not with v1.0.0.
- docs/webhooks.md: an orders-on-close entry filled at the close of the
  bar that placed it has a null id; v1.0.0 makes a same-bar stop flip
  such a case.
- docs/execution.md: the coordinator refuses such an unattributed entry,
  so the POOC probe's replay stops at its first flip.
- CHANGELOG: Unreleased entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ids.intent_kind reads limit_price and stop_price strictly to tell a
market entry from a priced one. Two synthetic probe tests built ENTRY
mirror rows without those fields (every real pf_pending_order_v1_t row
has them), so they raised KeyError. Give each row the stop level its
book intent already carries (L1 100.0; L 105.0, S 95.0). A lenient
default would have keyed these priced entries as MARKET and broken the
departure check these tests exercise.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-ups to the v1.0.0 support.

- core/book.py: ids.intent_kind finds a market entry by the mirror row's
  limit_price/stop_price, which engine v1.0.0 marks "deprecated, derived
  output only". If a later engine left them NaN on a priced entry, the
  entry would key as MARKET and LiveCore would send it at the next open
  as a market order. settled_book already reads the handle's own levels
  for every row; it now raises when a MARKET key the engine reported as
  ENTRY has a finite stop or limit there. The docstring also records the
  v1.0.0 cycle stamping and replacement re-keying.
- tests: an offline test for that refusal, and an engine-backed test on
  the corpus probe order-dual-stop-far-only-01 (new test_so_dual_stop
  fixture): its long and short stop entries rest after bar 2076 as
  priced ENTRY intents and LiveCore asks for no MARKET_AT_OPEN leg. The
  earlier fixtures only had market entries or stop entries that fill at
  their own close.
- test_signal_engine pins the null-id count per fixture (4 POOC flips in
  the window, none elsewhere); test_execution_replay asserts the replay
  settled bars 2000-2047 and stopped at the flip bar; the abort comment
  no longer claims the order of work before the run begins.
- CHANGELOG: POOC flip null ids and replay refusal; the README no
  longer documents the pre-1.0 revision. README: 152 engine-backed tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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