Development guide#
Level: Expert
You will: contribute code and documentation while preserving deterministic
outputs, contracts, tests, and release quality.
Before you start: a repository checkout and basic Git and Poetry skills.
Services: None for the quality gate.
FraudTwin is a small Python package with a deliberately deterministic core. Keep domain rules in src/fraudtwin/domain, use cases and orchestration in the simulation/application modules, and integrations at the edges. Changes should make generated data easier to explain, not merely more complex.
Set up the repository#
Requirements are Python 3.12 and Poetry 2.x:
poetry install
poetry run fraudtwin config validate configs/minimal.yaml
Generated runs belong in the ignored ./runs directory. Do not commit generated data, credentials, or local environment files.
Quality gate#
Run the same checks used by CI before opening a pull request:
poetry check --strict
poetry run ruff check .
poetry run ruff format --check .
poetry run mypy src
poetry run pytest
poetry build
git diff --check
The repository’s checks run only on pull requests targeting main; a merged
commit does not rerun the test suite. Protect main with a GitHub ruleset that
requires those pull-request checks and disallows direct pushes. GitHub Actions
cannot enforce that restriction by itself.
Version policy is read-only: every PR must raise the version above main and
keep pyproject.toml, src/fraudtwin/__init__.py, and CHANGELOG.md in sync.
The workflow never commits or pushes version bumps on your behalf.
To publish, push a vX.Y.Z tag from the merged release commit. The tag must
match the versions in pyproject.toml, src/fraudtwin/__init__.py, and the
top CHANGELOG.md heading. Ordinary pushes and commit messages never publish a
release.
Focused tests#
Use the narrowest test while iterating, then run the full suite:
Area |
Test command |
|---|---|
Entities and behavior |
|
Card lifecycle |
|
Pix lifecycle and ledger |
|
Fraud scenarios |
|
Workflow cases and labels |
|
Data quality |
|
Point-in-time datasets |
|
Replay and backtesting |
|
Baseline ML and prediction adapter |
|
Graph exports |
|
Difficulty |
|
Camouflage |
|
Campaign dynamics |
|
Observability |
|
For a generated-run smoke test:
CONFIG=configs/minimal.yaml
RUN_ID=RUN-...
RUNS_DIR=./runs
poetry run fraudtwin config validate "$CONFIG"
poetry run fraudtwin generate "$CONFIG" --output-dir "$RUNS_DIR"
poetry run fraudtwin validate-ledger \
--run-id "$RUN_ID" \
--output-dir "$RUNS_DIR"
Scale tests must use at most 1,000 logical events per fixture. Validate scale behavior with small deterministic runs and simulated interruption/resume; do not execute the billion profile in the test suite.
Working on a feature#
Read the relevant module and its nearest tests before editing implementation code.
Preserve deterministic seeds, stable schemas, and causal timestamps.
Add or update focused tests for invariants, not only happy-path output.
Update the relevant page under
docs/, the root README when the user path changes, andCHANGELOG.mdfor release-facing behavior.Run the quality gate and inspect
git diff --checkbefore handing off.
Documentation conventions#
Write for a reader who has not seen the repository before. Lead with what a command enables, show the smallest working example, and explain any important constraint immediately after it. Keep release history in CHANGELOG.md; the README and docs/ should teach people how to use the current system.
Every non-tutorial guide begins with a reader contract containing Level,
You will, Before you start, and Services. Use the level routes for
navigation and keep one canonical explanation per topic. Prefer feature names
in public prose; reserve internal version or compatibility identifiers for
schemas, manifests, release history, and legacy command paths. End a guide with
Next and Related links so the reader always has a sensible continuation.
Next#
Run the quality gate, then review Release evidence for release-facing changes.