Project memory for AI coding agents. Keep terse and concrete.
Both C++ unit tests and full corpus verification must pass.
# 1. Build and run unit tests (ctest)
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=Release \
-DPINEFORGE_BUILD_TESTS=ON \
-DPINEFORGE_BUILD_CORPUS_STRATEGIES=ON
cmake --build build -j$(nproc 2>/dev/null || echo 4)
ctest --test-dir build --output-on-failure
# 2. Run full validation corpus sweep (against TV exported trades)
./scripts/run_corpus.shStale-test-binary trap:
cmake --build build --target pineforgerebuilds ONLY the static lib. Test executables are separate targets that statically link it, andctestdoes not rebuild anything — after a lib-only build, ctest runs STALE test binaries and can falsely pass. Always run a fullcmake --build build(all targets) beforectestwhen runtime values changed. Before trusting any result,build/lib/libpineforge.amust be newer than every working-tree file insrc/,include/, andCMakeLists.txt(uncommitted edits count) — else the conclusion is a stale-build artifact.
If scripts/run_corpus.sh reports any parity drift or failures, investigate the underlying cause. No regressions are allowed unless a resolved bug was previously masking a divergence.
scripts/derive_corpus_feeds.py(ensure_derived()) is a cheap no-op whencorpus/data/derived/is fresh, but a REBUILD is not concurrent-safe: it writes through a fixed*.csv.newtmp then renames, so two processes materializing simultaneously race and can corrupt the derived feeds. Run it once to freshness BEFORE fanning out parallel consumers.- Never run
scripts/run_corpus.shwhile any external harness that linksbuild/lib/libpineforge.aor readscorpus/data/derived/is running: run_corpus.sh re-materializes the derived feeds and rebuilds the lib (--target corpus_strategieslinkspineforge), clobbering both under the concurrent run. External sweeps may run in parallel with each other over disjoint work sets, but never overlapped with run_corpus.sh.
- Configure CMake:
cmake -B build -S . -DPINEFORGE_BUILD_TESTS=ON -DPINEFORGE_BUILD_CORPUS_STRATEGIES=ON - Compile:
cmake --build build -j4 - Clean:
rm -rf build
- Run all unit tests:
ctest --test-dir build --output-on-failure - Run single test executable:
./build/bin/test_integration
CI runs python3 scripts/check_c_abi_runtime.py after build+test. It pins the
exact set of PF_API symbols implemented in src/c_abi.cpp against the
hardcoded EXPECTED_RUNTIME frozenset in that script. Adding (or removing) a
runtime export WITHOUT updating that list fails ALL CI matrix jobs at the
"C ABI runtime source check" step, even though build and ctest are green.
Checklist when touching runtime exports — update ALL of these together:
src/c_abi.cpp— the implementation (and its file-header symbol comment).include/pineforge/pineforge.h— thePF_APIdeclaration (+ doxygen).scripts/check_c_abi_runtime.py— add the symbol toEXPECTED_RUNTIME.- Python ctypes harnesses if consumers must call it
(
scripts/run_strategy.py,tutorial/run*.py,docker/run_json.py,benchmarks/throughput/grid_search_repro.py). - README symbol table if it enumerates exports.
Before pushing: python3 scripts/check_c_abi_runtime.py (must exit 0).
Per-strategy symbols (strategy_create, run_backtest, …) are NOT in this list —
they are codegen-emitted; the checker enforces exactly that split.
- Modern C++17. Use of
<cstdint>fixed-width types. - Follow existing patterns for trade accessors and order management.
- Keep helper functions inline or in clean namespaces.
- Do not add external dependencies without explicit user request.