diff --git a/docs/evidence/decision-buy-denial-foundation-20260908.json b/docs/evidence/decision-buy-denial-foundation-20260908.json new file mode 100644 index 0000000..4a056a8 --- /dev/null +++ b/docs/evidence/decision-buy-denial-foundation-20260908.json @@ -0,0 +1,16 @@ +{ + "date": "2026-09-08", + "host": "192.168.31.177", + "candidateCommit": "7d293f0", + "unitTestsPassed": 451, + "integrationTestsPassed": 122, + "ignoredManualBenchmarks": 8, + "failed": 0, + "backtestRunnerCargoCheck": "passed", + "covered": ["top-up rejection", "sell permission preserved", "decision context restored", "existing pending order not rewritten", "next-open target direction determined by actual price"], + "deployed": false, + "factorCompilerConnected": false, + "paperLivePlanConnected": false, + "orderAmendmentAcceptanceComplete": false, + "realStrategyAcceptanceComplete": false +} diff --git a/docs/factor-decision-phase-contract.md b/docs/factor-decision-phase-contract.md new file mode 100644 index 0000000..1efb8be --- /dev/null +++ b/docs/factor-decision-phase-contract.md @@ -0,0 +1,36 @@ +# Factor Decision Phases + +Status: broker foundation implemented; factor compiler, evaluator and runtime-plan integration are not complete. Do not advertise this as a fully working stock-pool buy-condition feature. + +## Separate Contracts + +| Phase | Meaning | Must Not Do | +|---|---|---| +| Selection | Build and rank the candidate universe at the strategy decision clock | Pretend this also guards every later top-up | +| Buy permission | Decide whether this decision may create new buy exposure for a symbol | Convert a denied buy into a sell or silently drop a holding from a full target snapshot | +| Exit/reduction | Produce the explicitly configured exit or partial target | Normalize remaining targets upward without an explicit strategy rule | +| Execution risk | Apply actual execution-date price, ST, suspension, lifecycle, liquidity and cost constraints | Substitute decision-date risk facts for next-open execution facts | +| Existing orders | Continue the already submitted order under its execution risk and lifetime contract | Implicitly cancel or rewrite it merely because a later decision has a new buy denial | + +## Broker Primitive + +`StrategyDecision.buy_denials` is a symbol-to-reason map sampled by the strategy layer, not a factor evaluator. Merged decisions retain denials. The broker installs it only while processing that decision and restores the prior context afterward; it is never shared through DataSet caches. + +New positive buy quantities and target-buy planning respect the map after standard market/risk checks. Sells remain permitted. The actual execution price determines whether a value/portfolio target requires buying: a target below the signal-day holding value can become a buy after a lower next open, so signal-day direction alone is insufficient. + +Existing resting orders are not automatically canceled by this primitive. Cancellation and exposure-increasing order amendment need an explicit policy and further integration tests. + +## Required Integration + +1. Split selection and buy-role output in the stock-pool compiler instead of folding both into `stock_filter`. +2. Evaluate buy expressions at the declared decision clock using typed field availability, units and frozen data identity. Missing data must retain its own diagnostic, not silently become a false trading signal. +3. Populate denials for every symbol a decision can buy, including portfolio targets, retained-target reentry and top-ups. Do not infer execution direction from signal-day value. +4. Preserve/consume constraints in Paper/Live strategy-plan conversion. No consumer may silently discard a nonempty denial map. +5. Define and test pending-order amendment behavior separately; validate source-date and execution-date risk independently. +6. Verify same-bundle baseline parity when no buy constraint is configured, then test explicit buy failures across share, value, target and algorithmic orders. + +## Current Evidence + +On 177, broker tests verify blocked target top-ups, permitted sells, context restoration, existing pending-order preservation, and a next-open target direction flip. Full `fidc-core` tests passed: 451 unit tests and 122 integration tests, with 8 manual benchmarks ignored. The backtest runner compiles against the changed API. + +The candidate is not deployed. The current OmniQuant compiler still needs the above integration, and no production readiness claim follows from these low-level tests.