This project lives in more than one repository, and which one you are looking at changes what you may do with it. This is the map.
private/brink ─────────── the workshop. Where work happens.
│ Agent config, playtest databases, drafts.
│ Never published as-is.
│
├── tree copy ────► public/brink ──── the game. MIT, issues, stars.
│ (scripts/publish.sh) Standalone: NOT a GitHub fork,
│ so it stays discoverable and
│ owns its own issue tracker.
│
└── push offer/* ─► <you>/dmcp ────► shawnrushefsky/dmcp
a real GitHub upstream. Receives PRs.
fork. Exists only
to carry offer/*
branches and open
pull requests.
Four repositories, two routes out, and they do not touch each other.
The public repo starts from a single squashed commit. It is not a branch of
this one and never will be — git push public main cannot work and is not meant
to.
That is a deliberate trade. It gives up the commit history, which in this repository is unusually good documentation: most messages carry the playtest that prompted the change, what was measured, and why a test was reversed rather than loosened. What it buys is that nothing in the private history can ever leak, which matters because a great deal of it predates anyone thinking about publication. A scrub can miss something. An absent history cannot.
Practically: publishing copies a tree and makes a commit. History accumulates in the public repo from its first release forward, so the archaeology starts there.
Two independent reasons, either of which is sufficient:
- The history is wrong. The
offer/*branches are cut fromupstream/mainand carry DMCP's own history. Pushing them into a repo whose root is a squashed commit would either drag all of DMCP's history in beside the squash, or be unmergeable. - GitHub will not allow the pull request. Pull requests are only possible
between repositories in the same fork network. A standalone repo — however
much history it shares — cannot target
shawnrushefsky/dmcp. It has to be an actual GitHub fork.
So generic work travels private → your fork of DMCP → PR, and the public repo is not on that path. See IMPROVEMENTS-TO-DMCP.md for what is on those branches and why each one is generic.
Short on purpose. A long exclude list means the published tree drifts from the one that is actually tested, and then a release breaks in a way no test saw.
Everything else git tracks is published, including CLAUDE.md and the design
brief — both are good documentation and both have been scrubbed of anything
machine-specific.
src/__tests__/publishHygiene.test.ts fails CI if a private machine name, a home
directory, an account name, a raw LAN address, or the name of an unrelated
project appears anywhere in the tracked tree. src/gm/__tests__/repoCredentialHygiene.test.ts
does the same for credentials.
This is deliberately not a step in the publish script. A hostname committed on a Tuesday is published on the Thursday, and nobody re-reads a checklist — but everybody notices a red build. When that test was first written it immediately found six files a careful manual sweep had missed, including one written ten minutes earlier by the person doing the sweeping.
Every forbidden pattern carries the reason it is forbidden, so the failure explains itself and a future contributor has something to argue with other than a bare list of words.
# The public repo: create it EMPTY on GitHub -- no README, no licence, no
# .gitignore -- so the first publish is the first commit.
git clone git@github.com:<you>/brink-public.git ../brink-public
# The DMCP fork: use GitHub's fork button on shawnrushefsky/dmcp. It has to be
# a real fork or pull requests are impossible.
git remote add dmcp-fork git@github.com:<you>/dmcp.git./scripts/publish.sh ../brink-public "release: what changed" --dry-run # look first
./scripts/publish.sh ../brink-public "release: what changed"
cd ../brink-public && git log -1 --stat && git pushThe script refuses to run on a dirty tree, and runs the full suite, lint and
typecheck before copying anything. It uses git archive, so only tracked files
can reach the public tree, and rsync --delete, so a file removed here is
removed there.
git fetch upstream
git checkout -b offer/<topic> upstream/main
# ... generic mechanism only. No geopolitical content in code, tests or
# comments -- use neutral fixtures ("grain", "treasury", "population").
git push dmcp-fork offer/<topic>
# then open the PR from <you>/dmcp against shawnrushefsky/dmcpBefore pushing, check the branch really is clean:
git diff upstream/main...offer/<topic> | grep -icE "defcon|prestige|flashpoint|crisis|seat"Zero is the only acceptable answer, and all four existing offer/* branches
return it.
