Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull-request-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Describe key implementation decisions.

- [ ] Change preserves deterministic behavior
- [ ] Tests confirm reproducibility
- [ ] No hidden state introduced
- [ ] No hidden State introduced

## Performance Impact

Expand Down
18 changes: 16 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,34 @@ This changelog starts from the clean Core package baseline.

## [Unreleased]

### Removed

- `StrategyState.pop_queued_intents` (unused; Execution Control uses per-order queue helpers).
- `fold_event_stream_entries` and root export (use `process_event_entry` in order).
- Unused telemetry models in `core/events/events.py`.
- Unused `combine_candidate_intents` helper.
- Root exports for Execution Control apply detail types and `apply_execution_control_plan` (internal Execution Control apply stage).

### Added

- Deterministic `run_core_step` and `run_core_wakeup_step` architecture.
- CoreWakeupStep final-state Strategy evaluation: reduce all entries, then `CoreWakeupStrategyEvaluator` once.
- CoreWakeupStep final Strategy evaluation: reduce all entries, then `CoreWakeupStrategyEvaluator` once.
- Canonical Event input models and `EventStreamEntry`/`ProcessingPosition`.
- Intent candidate record pipeline with dominance/reconciliation.
- Intent Pipeline candidate records with dominance/reconciliation.
- Risk Engine (policy-only) admission and Execution Control plan/apply integration.
- `CoreStepResult.dispatchable_intents` and `ControlSchedulingObligation` outputs.
- Core-only quickstart example and focused semantics test coverage.
- Root export of `PolicyIntentEvaluator` and documentation of extension points vs convenience implementations.
- Pipeline integration tests for `RiskEngine` as `policy_evaluator` in `run_core_step`.
- `FillEvent` reducer and Pipeline tests.
- Runnable Risk Engine example at `examples/core_step_with_risk_engine.py`.
- Extension-point docs under `docs/` and U3 candidate list at `docs/roadmap/dead-code-cleanup-candidates.md`.

### Changed

- Package metadata, exports, and docs reset for standalone Core library identity.
- Pydantic models established as contract source of truth across public API docs.
- README clarifies internally wired Pipeline vs externally supplied extension points.

### Removed

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ python -m build
- Register canonical category handling in `core/domain/event_model.py`.
- Update canonical reduction behavior in `core/domain/processing.py`.

### CoreStep/CoreWakeupStep pipeline
### CoreStep/CoreWakeupStep Pipeline

- Update `core/domain/processing_step.py` for deterministic flow changes.
- Keep reconciliation/policy/apply transitions explicit and side-effect-safe.
Expand Down
247 changes: 151 additions & 96 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Include:
This policy covers the Core package in this repository, including:

- canonical Event and Intent contracts
- deterministic CoreStep/CoreWakeupStep decision pipeline
- deterministic CoreStep/CoreWakeupStep decision Pipeline
- package integrity and dependency usage in `tradingchassis_core`

## Secrets and Credentials Policy
Expand Down
34 changes: 29 additions & 5 deletions docs/code-map/core-pipeline-map.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Core Pipeline Map

This map captures the only supported deterministic decision pipeline for
This map captures the only supported deterministic decision Pipeline for
TradingChassis Core.

## Step-by-step flow
Expand All @@ -17,7 +17,7 @@ TradingChassis Core.
in the current slice—see `../flows/control-time-and-scheduling.md`).
9. Runtime can dispatch later and inject further canonical Events (including
`ControlTimeEvent` when an obligation is realized); Core does not perform
external dispatch or mutate queues outside this pipeline.
external dispatch or mutate Queues outside this Pipeline.

## Core APIs

Expand All @@ -29,7 +29,7 @@ TradingChassis Core.
## Determinism notes

- Processing Order monotonicity is enforced by `ProcessingPosition`.
- Core logic is side-effect-safe apart from deterministic state mutation.
- Core logic is side-effect-safe apart from deterministic State mutation.
- Runtime adapters and external dispatch concerns are outside Core.


Expand All @@ -44,12 +44,36 @@ Wakeup flow:

1. Runtime supplies an ordered batch of `EventStreamEntry` values.
2. `run_core_wakeup_reduction` calls `process_event_entry` for each entry in order.
3. `CoreWakeupStrategyEvaluator.evaluate` runs **once** on the fully reduced state
3. `CoreWakeupStrategyEvaluator.evaluate` runs **once** on the fully reduced State
(`CoreWakeupStrategyContext` carries all entries).
4. `run_core_wakeup_decision` snapshots queued intents once, combines generated + queued
once, applies dominance/reconciliation once, Policy Admission once, and
ExecutionControl plan/apply once.
Execution Control plan/apply once.
5. `CoreStepResult.dispatchable_intents` is returned; Runtime dispatches later.

`run_core_step` remains single-entry: one reduction, one step-level Strategy evaluation,
one decision pass.

## Internally wired vs externally supplied

### Internally wired

- Steps 1–3, 5, and 8 in the flow above (reduction, candidates, `CoreStepResult`)
- Policy admission **machinery** when `CorePolicyAdmissionContext` is provided
- Execution Control plan/apply **machinery** when apply context is provided

### Externally supplied extension points

- **Strategy** — `CoreStepStrategyEvaluator` or `CoreWakeupStrategyEvaluator`
- **Policy** — `PolicyIntentEvaluator` via `CorePolicyAdmissionContext`
- **Execution Control instance** — `ExecutionControl` via `CoreExecutionControlApplyContext`
- **Configuration** — optional `CoreConfiguration`
- **Event bus** — `StrategyState(event_bus=...)`; `NullEventBus` for standalone use

### Convenience implementations

- Risk Engine (`RiskEngine`) — optional built-in `PolicyIntentEvaluator` (`examples/core_step_with_risk_engine.py`)
- `ExecutionControl` — default queue/rate/inflight behavior (instance still supplied by caller)
- `NullEventBus` — no-op bus for tests and examples

See `../reference/public-api.md` and `../how-to/use-policy-evaluator.md`.
9 changes: 5 additions & 4 deletions docs/code-map/repository-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ High-level map for the standalone Core package.

- `tradingchassis_core/__init__.py`: public package boundary exports
- `tradingchassis_core/core/domain/`: canonical contracts and deterministic
pipeline orchestration
Pipeline orchestration
- `tradingchassis_core/core/risk/`: policy-only Risk Engine evaluator/config
- `tradingchassis_core/core/execution_control/`: Execution Control primitives
- `tradingchassis_core/core/events/`: internal Event bus/sink utilities
- `tradingchassis_core/core/events/`: Event bus/sink utilities (`NullEventBus`; `LoggingEventSink` for Runtime)

## Tests and examples

- `tests/semantics/`: focused contract and deterministic behavior tests
- `examples/core_step_quickstart.py`: public-import quickstart
- `examples/core_step_quickstart.py`: minimal inline-policy quickstart
- `examples/core_step_with_risk_engine.py`: Risk Engine policy quickstart

## Top-level package docs and metadata

Expand All @@ -30,7 +31,7 @@ Core owns:

- canonical Events and Processing Order contracts
- deterministic reduction and step decisions
- Intent candidate, Risk Engine (policy), Execution Control outputs
- Intent candidate records, Risk Engine (policy), Execution Control outputs

Core does not own:

Expand Down
18 changes: 9 additions & 9 deletions docs/flows/control-time-and-scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ to Execution Control deferral.
- **ControlSchedulingObligation** — Non-canonical Core output: a structured hint
that a **time-dependent** recheck may be useful. It is **not** part of the
canonical Event Stream and does not mutate `StrategyState`.
- **ControlTimeEvent** — Canonical **control** category Event. It becomes part of
- **Control-Time Event** (`ControlTimeEvent`) — Canonical **control** category Event. It becomes part of the
deterministic history only after the **Runtime** injects it as
`EventStreamEntry` input (same ingestion path as other canonical Events).
- **Inflight** — Core-side **intent-operation** gating: a sendability / operation
- **Inflight** — Core-side **Intent-operation** gating: a sendability / operation
slot (for example keyed by `client_order_id`) is occupied because an earlier
intent operation is still awaiting **canonical execution feedback**. This is
Intent operation is still awaiting **canonical execution feedback**. This is
not the same as venue-side “order ownership”; Core models sendability for the
decision pipeline.
- **Rate-limit deferral** — Execution control blocks dispatch because the
decision Pipeline.
- **Rate-limit deferral** — Execution Control blocks dispatch because the
configured **token / time budget** for orders or cancels is not yet available at
the apply clock (`now_ts_ns_local` in `CoreExecutionControlApplyContext`).
- **Inflight deferral** — Dispatch is blocked because **inflight** gating applies,
Expand All @@ -33,11 +33,11 @@ to Execution Control deferral.
**Not in scope for the current contract:** inflight timeout, wall-clock recovery,
or “synthetic” obligations for inflight-only waits.

**Not implied:** every queued intent produces a scheduling obligation or a future
**Not implied:** every queued Intent produces a scheduling obligation or a future
`ControlTimeEvent`. Obligations are for **rate-limit** rechecks in the current
Core slice.

## Clean Core pipeline (unchanged)
## Clean Core Pipeline (unchanged)

1. `EventStreamEntry`
2. `process_event_entry` / `process_canonical_event`
Expand All @@ -55,9 +55,9 @@ they are selected only in the mutable **apply** stage (`apply_execution_control_

## Runtime ownership

- Runtimes **must not** mutate Core queues (`StrategyState.queued_intents`, etc.)
- Runtimes **must not** mutate Core Queues (`StrategyState.queued_intents`, etc.)
directly outside the normal Core step / Execution Control apply path.
- Queue flush / sendability decisions remain **ExecutionControl-owned** inside
- Queue flush / sendability decisions remain **Execution Control-owned** inside
Core when `CoreExecutionControlApplyContext` is supplied to `run_core_step` /
wakeup APIs.

Expand Down
4 changes: 2 additions & 2 deletions docs/how-to/update-core-step-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Recommended workflow:

Guardrails:

- No Runtime dispatch logic in Core pipeline code.
- No Runtime dispatch logic in Core Pipeline code.
- No legacy compatibility contract restoration.
- Keep deterministic behavior and public API coherence.

Expand All @@ -30,6 +30,6 @@ When updating wakeup behavior:

1. Keep `run_core_wakeup_reduction` as reduction-only (no per-entry Strategy calls).
2. Use `CoreWakeupStrategyEvaluator` and `wakeup_strategy_evaluator=` for batch evaluation.
3. Preserve one Policy Admission and one ExecutionControl apply per wakeup in
3. Preserve one Policy Admission and one Execution Control apply per wakeup in
`run_core_wakeup_decision`.
4. Add tests in `tests/semantics/test_core_wakeup_final_state.py`.
4 changes: 3 additions & 1 deletion docs/how-to/update-policy-and-execution-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ The Risk Engine (policy) and Execution Control are separate deterministic phases
- Core integration:
`core/domain/policy_risk_decision.py` and `run_core_step` policy phase
- Built-in policy-only evaluator:
`core/risk/risk_engine.py`
`core/risk/risk_engine.py` (public Risk Engine class `RiskEngine`; internal `RiskPolicy` / `ExecutionConstraintsPolicy`)
- User guide:
`use-policy-evaluator.md`

When updating Risk Engine policy behavior:

Expand Down
54 changes: 54 additions & 0 deletions docs/how-to/use-policy-evaluator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# How to use a policy evaluator

Core policy admission is optional. When you pass `CorePolicyAdmissionContext`, Core
calls your evaluator for each **generated** candidate intent (queued candidates
passthrough unchanged).

## Extension point: `PolicyIntentEvaluator`

Root export: `tradingchassis_core.PolicyIntentEvaluator`

Implement:

```python
def evaluate_policy_intent(
self,
*,
intent: OrderIntent,
state: StrategyState,
now_ts_ns_local: int,
) -> tuple[bool, str | None]:
...
```

Pass the instance via `CorePolicyAdmissionContext(policy_evaluator=..., now_ts_ns_local=...)`.

Any object satisfying this contract works. Core does not require `RiskEngine`.

## Convenience implementation: Risk Engine (`RiskEngine`)

The built-in **Risk Engine** (`RiskEngine`) implements `PolicyIntentEvaluator` with
policy gates (trading enabled, max loss, normalization, hard limits). Configure
with `RiskConfig`.

Runnable example:

```bash
cd core
python examples/core_step_with_risk_engine.py
```

Minimal quickstart (`examples/core_step_quickstart.py`) uses an inline allow-all
policy to stay small. That does not mean the Risk Engine is unused.

## Execution Control apply

Policy admission alone does not mutate queues or produce dispatchables. Also pass
`CoreExecutionControlApplyContext` with a supplied `ExecutionControl` instance and
set `activate_dispatchable_outputs=True` when you want `CoreStepResult.dispatchable_intents`.

See also:

- `reference/public-api.md`
- `code-map/core-pipeline-map.md`
- `update-policy-and-execution-control.md`
14 changes: 12 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ This documentation set describes the standalone clean Core package baseline.
- `reference/public-api.md`: supported root exports and package boundary
- `reference/events-reference.md`: canonical Events and Intent contracts
- `flows/control-time-and-scheduling.md`: rate-limit vs inflight deferral and obligations
- `code-map/core-pipeline-map.md`: deterministic pipeline walkthrough
- `code-map/core-pipeline-map.md`: deterministic Pipeline walkthrough
- `code-map/repository-map.md`: package layout and ownership map
- `how-to/add-canonical-event.md`: extending canonical Event contracts
- `how-to/update-core-step-pipeline.md`: changing CoreStep/CoreWakeupStep behavior
- `how-to/update-policy-and-execution-control.md`: changing Risk Engine / Execution Control behavior
- `how-to/use-policy-evaluator.md`: `PolicyIntentEvaluator`, `RiskEngine`, and examples
- `roadmap/dead-code-cleanup-candidates.md`: U3 removal candidates (audit before delete)

## Package Purpose

Expand All @@ -38,7 +40,15 @@ canonical contracts, State reduction, and step-level decision outputs.
Pydantic contract models in `tradingchassis_core/core/domain/types.py` are the
source of truth for canonical Event/Intent schemas.

## Extension points (summary)

- **Supplied by Runtime/tests:** Strategy evaluators, `PolicyIntentEvaluator`, `ExecutionControl`, `CoreConfiguration`, `EventBus`
- **Convenience:** `RiskEngine`, `NullEventBus`
- **Wired inside Core:** reduction, candidate reconciliation, policy/EC mechanisms, `CoreStepResult`

Examples: `examples/core_step_quickstart.py` (inline policy), `examples/core_step_with_risk_engine.py` (Risk Engine).

## Out of Scope

- Runtime orchestration and Order lifecycle ownership
- Venue Adapters, Backtesting/Live I/O, external dispatch
- Venue Adapters, Backtesting and Live I/O, external dispatch
2 changes: 1 addition & 1 deletion docs/reference/events-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ contracts. Pydantic models are the schema source of truth.

## Canonical Event Models

- `MarketEvent`: book/trade market data input for state reduction
- `MarketEvent`: book/trade market data input for State reduction
- `ControlTimeEvent`: canonical **control** wakeup; becomes stream history only
after Runtime injection. Reducer updates monotone time (and processing cursor
when positioned). Scheduling **obligations** are a separate non-canonical output;
Expand Down
Loading
Loading