How it's built

Realistic on purpose. Proven every time.

Sample data is easy to make and hard to make well. These are the ideas, the tools, and the decisions behind a church that behaves like a real one.

The big ideas

Six ideas carry the whole project.

  1. 1

    Three datasets, one Cast

    A hand-designed Cast is the same everywhere, and a generated Crowd adds size. Tests name the Cast. The Crowd is never named.

  2. 2

    Knowledge lives in data, not code

    Targets, stories, church setup, and rules live in versioned data files. When we learn something, we change a file and rebuild. We never start over.

  3. 3

    Store the people, generate the timeline

    Files hold who people are. What they did is generated at install, counting back from install day, so history is always current.

  4. 4

    Realism is measured

    We copy the shapes and ratios of real churches, never their size or setup, and grade our data against them on every build.

  5. 5

    Fast, without skipping the rules

    The loader copies rows in bulk instead of saving one at a time. It then sets the values Rock's own save logic would have set.

  6. 6

    Proven against Rock itself

    Every package is loaded into a clean Rock and checked by Rock's own tools before it can ship.

The pipeline

From plain files to a living church.

  1. Data files

    The Cast, the church setup, and the target patterns, in plain JSON.

  2. Builder

    Turns the files into one package per dataset, for one exact Rock.

  3. Verify

    Loads each package into a clean Rock and checks it. No pass, no publish.

  4. Loader

    Loads a package into a fresh Rock database in seconds.

  5. Rock

    A church with years of history, ready to explore.

Measured realism

Patterns from real churches. Never their people.

Real churches have weekly, monthly, and erratic givers, Easter peaks, and summer dips. To learn those patterns, we ran summary queries on real churches' Rock databases, only where each church gave us permission.

The queries return only totals and percentages, such as the share of givers who give monthly. They never return a name, an Id, or any record about a person, and they're read-only, so they change nothing. No personal data was ever taken.

We keep only the patterns, never a church's size, setup, or people. Then we grade the generated data with the same queries. Today, 91% of measured values fall within tolerance, and anything we skip on purpose is written down with the reason.

We never name or describe the churches that helped, and their totals never leave the machine that ran the queries.

91% of measured values within tolerance

Trust

Rock checks our work.

The loader is fast because it copies data in bulk around Rock's business logic. So the proof has to come from Rock itself. Before any package is published, the verify tool does four things.

A clean Rock

It builds a database made only by Rock's own migrations and start-up steps, then loads the package into a copy.

Rock's own columns

It checks every table, column, and Guid the loader writes against that exact Rock release.

Rule checks

It runs rules such as "every person is in a family" and "nothing is dated in the future," and confirms every Cast story shows what it should.

Rock Cleanup

It runs Rock's own Rock Cleanup job. If Rock finds anything in the sample data to fix, the package fails.

Decisions worth reading

A dozen choices, and why we made them.

Every choice is written down in the decision log, with its reason. These are a few that shape the church most.

Decision 1

Sample data installs into a fresh database only.

Decision 6

Store who people are; generate what they did at install time, counting back from install day. Ages and grades never drift.

Decision 7

Calibration copies shapes and ratios from real churches, never their size or local setup.

Decision 12

Every person, church, and organization is fictional, including employers and businesses.

Decision 15

Every Cast household has a story and a test purpose.

Decision 26

Check gifts come with scanned check images that match the gift exactly: the writer, the date, the amount, and the check number.

Decision 28

New people's photos are AI-generated, fictional faces. No new face may resemble a real or famous person.

Decision 41

A dataset ships as a package of data, never SQL.

Decision 52

Each package is for one exact Rock. The loader refuses a database that doesn't match.

Decision 66

A package is published only with a passing receipt from the verify tool.

Decision 72

A connected request adds the person to the team as Pending, as Rock ships it. The team leader makes them active as part of onboarding.

Decision 76

Every team at every campus has volunteers and serving history on install, before any connection request.

The photos

Made to look like one church.

Every portrait, group photo, and building view is AI-generated and fictional. Portraits look like casual profile pictures, and family members look related.

Group photos are made from each member's own portrait, so the same faces appear on Sunday and in small group. Twelve empty building views keep every new photo in the same rooms, with the same furniture and the same light.

Read the details

It's all in the repository.