d0ebdf5210
Supersede 'broker is part of the strategy'. A strategy outputs a time-ordered table of position events (event_ts, action[buy/sell/close], position_id, instrument_id, volume; open time = opening event's event_ts, so no open_ts; unsigned volume, direction in action). Brokers become downstream swappable plugins: a deterministic frictionless sim-optimal broker yields synthetic pip-equity for neutral comparison/optimization; realistic broker plugins add currency friction/constraints for viability/deploy. Stays within C7 (scalar columns). Updates CLAUDE.md invariant 7, the walking-skeleton line, provenance, and the day-in-the-life doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
98 lines
5.7 KiB
Markdown
98 lines
5.7 KiB
Markdown
# aura — project rules
|
|
|
|
aura is a "game engine for traders": a Rust framework **and** a playground to
|
|
author trading nodes, backtest them deterministically and massively in parallel,
|
|
compose them fractally, validate them (sweep / Monte-Carlo / walk-forward), and
|
|
freeze a validated strategy into a standalone bot with a broker connection.
|
|
|
|
This file is the project sittenkodex. It imports the universal discipline from
|
|
`~/dev/skills/templates/CLAUDE.md.fragment` and adds aura's domain invariants.
|
|
The full architecture lives in the design ledger (`docs/design/`) and the specs
|
|
(`docs/specs/`), not here.
|
|
|
|
## Roles
|
|
|
|
I am the **orchestrator**, not the implementer. The skills-plugin agents are my
|
|
workers: I plan, design, decide, and integrate; they implement, refactor, test,
|
|
and diagnose. Trivial mechanical edits I may do directly; anything needing broad
|
|
reading or judgement goes to an agent. Agent reports describe intent, not
|
|
outcome — I verify the diff and the test output myself before committing.
|
|
|
|
## Commit discipline and main-branch sanctity
|
|
|
|
- **Only the orchestrator commits.** No skill agent runs `git commit`; agents
|
|
leave their output as unstaged working-tree changes for me to inspect and shape
|
|
into commits.
|
|
- **main HEAD is sacrosanct.** No `git reset`/`git revert` on main. main moves
|
|
forward only via my commits. Wrong agent output is discarded with
|
|
`git checkout -- <paths>`/`git stash`; a bad landing is fixed forward, never
|
|
rewound.
|
|
- When a commit closes a Gitea issue, reference it in the body: `closes #N`
|
|
(or `refs #N` for non-final work).
|
|
|
|
## Design rationale ≠ implementation effort
|
|
|
|
Design choices are justified by substance — semantics, structural fit, what the
|
|
design permits vs forbids, compositional clarity, future-proofing. Implementation
|
|
effort ("approach A touches 250 sites, B touches 1") is an observation about the
|
|
current code, not a rationale. Effort is at most a named tiebreaker after
|
|
substantive reasons tie.
|
|
|
|
## Bug fixes — TDD, always
|
|
|
|
Bug fixes are RED-first and autonomous: the failing test exists in the working
|
|
tree before any fix. The `debug` skill is mandatory for any observable
|
|
misbehaviour (failing test, panic, wrong output).
|
|
|
|
## Domain invariants (load-bearing — never silently violate)
|
|
|
|
These are the contracts the whole design rests on. A change that breaks one is a
|
|
design decision, not a refactor, and belongs in the ledger.
|
|
|
|
1. **Determinism.** A backtest is a deterministic, synchronous, non-concurrent
|
|
event loop that reaches a unique state after each input tick. Same input →
|
|
same run, reproducibly. Two backtests are fully disjoint → concurrently
|
|
executable without locking. Parallelism is *across* sims, never within one.
|
|
2. **Causality / no look-ahead.** A node sees only the past. Look-ahead is made
|
|
structurally impossible (read-only input windows that end at the cursor;
|
|
resamplers emit a bar only once it is complete), not merely discouraged.
|
|
3. **One merge, at ingestion only.** Heterogeneous timestamped sources are
|
|
k-way-merged into a single chronological cycle stream at the ingestion
|
|
boundary. There is no merge / as-of join inside the graph.
|
|
4. **The four scalar base types, streamed as SoA.** Only `i64`, `f64`, `bool`,
|
|
`timestamp` are streamed, as columnar Structure-of-Arrays. Composite streams
|
|
(e.g. OHLCV) are bundles of base columns. Non-scalars (String, Records,
|
|
tables, calendars) exist as metadata beside the hot path, never in it.
|
|
5. **Acyclic dataflow.** The graph is a DAG; the only feedback path is an
|
|
explicit delay/state node (the RTL "register"). The "cycle" of the research
|
|
workflow is not a dataflow cycle.
|
|
6. **Record-then-replay determinism boundary.** Anything non-deterministic,
|
|
external, or slow (LLM news agents, web sources) is materialized into a
|
|
recorded, timestamped stream *before* it enters the engine. The sim never
|
|
makes a live external call mid-replay. (See `~/.claude/CLAUDE.md` for the
|
|
IONOS consent rule: external LLM calls happen at the recording/live-source
|
|
edge, with explicit per-session consent, never inside a backtest.)
|
|
7. **Strategy result is a broker-independent position table.** A strategy
|
|
outputs not an equity curve but a time-ordered table of position events
|
|
(`event_ts, action[buy/sell/close], position_id, instrument_id, volume`; a
|
|
position's open time is its opening event's `event_ts`); the set of open
|
|
positions at t is its state. Brokers are downstream, swappable plugins that
|
|
turn this table into an equity curve — never part of the strategy. Neutral
|
|
evaluation uses a deterministic, frictionless sim-optimal broker producing
|
|
synthetic equity in **pips**; realistic broker plugins add real
|
|
friction/constraints in currency for viability and deploy.
|
|
8. **Deploy artifacts are frozen.** Hot-reload (cdylib) is an authoring-loop
|
|
tool only. The live bot is a statically-linked, versioned, frozen artifact —
|
|
never hot-swapped (audit trail: this bot = this commit).
|
|
9. **Engine / project separation.** This repo is the reusable *engine*. Research
|
|
projects are separate external repos that depend on it. Project-specific
|
|
signals live in a project's `nodes/`; cross-project-reusable nodes in shared
|
|
crates; universal blocks in `aura-std` (shipped here). Reuse is cargo-native;
|
|
the hot-reload unit is always the project-side `cdylib`. No user/project
|
|
signals in this repo (only `examples/` fixtures for the engine's own tests);
|
|
no multi-project manager or node registry inside aura.
|
|
10. **Authoring surface.** Nodes are authored in native Rust via Claude Code +
|
|
the skills pipeline. aura ships no embedded coding-LLM. IONOS LLMs are used
|
|
only as a runtime data source (news bias), with per-session consent, never
|
|
in the code path.
|