Skip to main content

figurant — synthetic HR and identity data for testing identity governance

A reproducible generator of organisations that look like real ones: an org tree, people with Dutch names and plausible ages, employments and registrations over a history, accounts on several systems, and an answer key so a consuming system can be scored rather than eyeballed.

It is an exporter, not a connector. It writes files that resemble what a source system holds; it never reads from or writes into a live directory or HR system, and it has no code path that can be pointed at real data. No organisation it produces is recognisable as a real one, and no national identifier is produced in any mode.

pip install -e .
figurant --scenario examples/acme-small.toml --out ./set

That is a 400-person installer with its answer key, from a declaration you can read in one screen. Three ship to start from: examples/acme.toml (the full one), examples/acme-small.toml (the same organisation, smaller and faster) and examples/loop.toml (four weeks of one organisation, for the simulation loop).

Nothing is on by default. A set is clean until a declaration asks for a fault, a malformed value or a policy breach — so a clean set is the control that proves a consumer is not reporting problems that are not there.

The sixty-second version

# 1. Generate, and serve it where a consuming system can reach it
figurant --simulation examples/loop.toml --run ./run --reference 2026-10-12 --step 0
(cd run/current && python3 -m http.server 8080)   # GET /json/index.json

# 2. Import it. Then say next, and import the same URL again
figurant --simulation examples/loop.toml --run ./run --reference 2026-10-12 --next

# 3. Reconcile backwards instead of reloading
figurant --simulation examples/loop.toml --run ./run --reference 2026-10-12 --revert

--reference is the anchor every step counts back from, and it is required rather than defaulted: nothing in the package reads the clock, so running the loop in a later week is --reference "$(date -I)" at the call site and the whole loop shifts with it — the same people, the same units, every event date moved.

run/current/ is the same path at every step, so a consuming system is pointed at it once and never reconfigured, and run/feed/ holds what changed since the last step — in both directions, so a revert is a reconciliation rather than a reload. Next week the same declaration, anchored seven days later, replays the same situations against the same organisation. See the loop.

What you get

Sixteen tables — the organisation tree, people, employments over a history, teams, and the access layer of systems, accounts, resources and assignments — written as CSV, JSON pages, NDJSON, Parquet or a WireMock stub. Beside them, in set/key/, a separate answer key: every planted fault with the value the data held before, every malformed value and what it replaced, which personnel numbers belong to one human, and the right answer for every copy of every attribute rather than only the wrong ones. Full tables and formats in the output.

Where to go

you want to… read
start from nothing, write your own declaration, and share it so a colleague gets the same people getting started
see a real set and what each part of it is for the walkthrough
decide which organisation comes out declaring an organisation
feed a system the same set over and over, with changes the loop
ask for the situation you came to test scripting a case
know what the files hold, and score a tool against the key the output
look up an option, a fault family or a dirt kind the reference
know what every entity and field of the export holds the schema
point a product's collector at a set, field by field the consumer mapping
load a set into a database importing
know what this tool will not do, and what to do instead for a consuming product
work on the tool itself development

The walkthrough is the place to start if you have not seen a set before: it goes through one, defect by defect, and says what each is a test of.

What it is built against

docs/requirements.md holds every requirement, each with how to verify it and — where one was settled by measurement — the number that settled it. tests/TRACEABILITY.md records which requirement each test covers, and tools/check_requirements.py fails when one is covered by nothing.

The case mapping records which set carries which scorable case, because the cases live across sets rather than within one: a clean set is the control, so the faults are in another.

Three more records exist because a claim nobody measured is a claim: platforms (the same set on Windows and Linux, hash for hash), importing (PostgreSQL accepting 46,290 rows with every foreign key in place) and the mutation score (what the suite detects when faults are injected into the generator on purpose).

Metadata

Release files for figurant 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for figurant 0.1.1
File Size Uploaded Provenance
figurant-0.1.1.tar.gz 1.1 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for figurant 0.1.1
File Interpreter ABI Platform
figurant-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.9 MB

Release files / figurant-0.1.1.tar.gz

Download URL figurant-0.1.1.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
8c99e08ec3857523d004f90fc59e9f45e4c110b12693fa10208fc8ff538d3b41
BLAKE2b-256 checksum
How to use checksums
ab27a3763a01ee1cff9c73fdda3ebbbed7b31c2a43b27cbbeb159b03b2f7b551
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / figurant-0.1.1-py3-none-any.whl

Download URL figurant-0.1.1-py3-none-any.whl
Size 845.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4107d921e8a6d3fbe4c2f339636921e0085e3a373455eaefdb46f5e2a716bf4f
BLAKE2b-256 checksum
How to use checksums
4a4714e54a0e1c0d56d684f0c00c36954b2d2331e1343de4b9fc35ddf27a369a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for figurant 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page