This guide assumes you are working from the AtlantisV2 repository root.
Install The Docs App
The Astro docs app is isolated in docs-site/.
cd docs-site
pnpm install
pnpm build
pnpm dev
The Python core remains at repository root under src/atlantis_core.
Verify The Core
From the repository root:
python -m pytest
ruff check .
ruff format --check .
These are the default checks before claiming a framework slice is done.
Build The Smallest Market Snapshot
Adapters do not write features or patterns directly. They normalize raw venue payloads to EventEnvelope.
from datetime import UTC, datetime
from atlantis_core.market import EventEnvelope, EventKind
from atlantis_core.temporal import ReferenceTime
reference_time = ReferenceTime(datetime(2026, 4, 24, 9, 15, tzinfo=UTC))
event = EventEnvelope(
event_id="delta:BTCUSD:2026-04-24T09:14:59Z",
event_type=EventKind.PRICE_TICK,
source="delta_market_data",
source_sequence="42",
instrument_ref="DELTA:BTCUSD",
event_ts=datetime(2026, 4, 24, 9, 14, 59, tzinfo=UTC),
ingest_ts=datetime(2026, 4, 24, 9, 14, 59, 25000, tzinfo=UTC),
reference_time=reference_time,
payload={"price": 65000.0},
schema_version="delta_quote_v1",
trace_id="delta-trace-1",
)
SnapshotBuilder owns dedupe, ordering, freshness, invalid payload handling, and future-event filtering. The adapter does not.
Move From Snapshot To Thesis
The implemented spine follows this sequence:
MarketSnapshot
-> FeatureKernel.compute()
-> PatternRegistry.match()
-> ScoringEngine.score()
-> SignalIntentEngine.from_hypothesis()
-> PermissionEngine.decide()
-> LifecycleEngine.admit()
Each step returns a typed object with lineage and reason fields. Nothing returns a broker order.
Open And Track Expression
After permission admits a signal intent, an expression adapter may produce an ExposureExpression.
result = lifecycle.open_expression(
position_intent=position_intent,
expression_result=expression_result,
)
An opened exposure can receive marks and closes:
marked = lifecycle.mark_exposure(open_exposure=exposure, mark_event=mark_event)
closed = lifecycle.close_exposure(open_exposure=marked.open_exposure, close_event=close_event)
Marks create MarkRecord. State changes create LifecycleTransition. Closes create OutcomeRecord.
The Contract Rule
When in doubt, ask:
- Is this deterministic as of
ReferenceTime? - Is this instrument-agnostic?
- Does missing or stale data remain explicit?
- Does this belong in Core, or should an adapter own it?
- Is there a test or parity fixture proving the behavior?
If the answer is unclear, the next slice should be smaller.