§1 — One Pages site per repository, and one is already taken
This is the constraint that shapes everything else. GitHub gives a
repository exactly one Pages site with one source. Measured on the two repositories at
hand:
Repository
Pages
Source
Build type
Simon-McIntosh/reckon
none
—
—
Simon-McIntosh/imas-codex
active, built
main at /
legacy
A workflow using actions/deploy-pages requires the build type to be
workflow. Switching it on a repository serving legacy from a
branch replaces that site. So a naive generated workflow would silently
take over a repository's existing documentation — the exact failure the lead asked to be
guarded against, and it is live on the first repository anyone would test with.
The measured case also shows the way out. Because that repository
already serves main at the root, files under docs/ are already
reachable — verified: a plan HTML file returns 200 at
simon-mcintosh.github.io/imas-codex/docs/plans/… while the site root returns
404 for want of an index. So for a repository already publishing from a branch root,
reckon needs no workflow at all: committing the build output under a subpath makes
the SPA live, alongside whatever else that site serves.
§2 — Detect, then choose a strategy per case
Onboarding must read the repository's actual Pages configuration and pick a
non-destructive strategy, refusing rather than guessing when it cannot tell:
Existing Pages state
Strategy
None
reckon may own the site; generate a deploying workflow
Legacy, branch root
No workflow — commit the build under a subpath; it is already served
Legacy, /docs folder
Build into a subdirectory of docs/ so the existing site keeps its root
Legacy, gh-pages branch
Commit the build to a subpath of that branch, never its root
Actions-based
Refuse and report — the existing artifact must absorb reckon's output; merging two deploys is the repository owner's call
Cannot be determined
Refuse and report, never assume the site is free
Refusal is the default, not the exception. The cost asymmetry is
extreme: failing to onboard costs one command and a message, while taking over a live
documentation site is a visible outage someone else has to notice and diagnose.
§3 — Publication is opt-in, declared in the repository
The locked guard on the parent plan is that private information stays private and a fork
of an upstream repository counts as personal. Measured, a visibility predicate cannot
express that: Simon-McIntosh/imas-codex reports
isPrivate: false, isFork: true, visibility: PUBLIC,
so "publish unless private" would publish a personal fork and report itself correct.
So onboarding never enables publication as a side effect. Registering a project,
copying UI assets and adding a badge are local acts; publishing is a separate, explicit
opt-in recorded in the repository being onboarded. A repository that never opts in has no
publish job, so there is nothing for a central list to get wrong.
One fact worth recording plainly rather than leaving implicit. A public
fork's committed plans are already world-readable through the ordinary repository view —
verified, the blob route returns 200 — independently of any Pages site or reckon feature.
Declining to publish a reckon site does not make that content private, and anyone reasoning
about disclosure should know the two are separate questions.
§4 — The badge, and what it must not do
Onboarding adds a badge to the repository README linking to that repository's plans,
with a compass mark — the instrument that tells you where you are and which way you are
pointed, which is what a plan does and what the name already implies.
Constraints that matter more than the artwork. The mark ships as an
inline SVG or a committed asset in the repository, never a third-party badge service:
a remote badge endpoint makes every README render a request to someone else's
infrastructure and rots when that service changes. The badge is idempotent — running
onboarding twice must not produce two badges, which means detecting its own prior
insertion rather than appending blindly. And it degrades honestly: if the repository has
not opted into publication there is no site to link, so the badge is not added at all
rather than pointing at a 404.
Done when onboarding a repository with no Pages site produces a
registered project, a deploying workflow, and exactly one badge resolving to a live plan
index; running it a second time changes nothing; onboarding the measured legacy-root
repository produces no workflow, a subpath build and a badge to that subpath, with its
existing site still serving; and onboarding a repository with Actions-based Pages refuses
with a message naming the conflict. Each case asserted by a test against a recorded Pages
configuration rather than against live GitHub.
§ Decisions
Does onboarding extend reckon sync or become its own command?
Locked by the lead 2026-08-24. sync already registers the project, copies UI assets and writes CI behind --generate-ci, so onboarding is the same act plus Pages detection and a badge; extending keeps one entry point and one mental model rather than two commands that overlap heavily. The risk this accepts must be handled explicitly: sync is ALSO the routine refresh-assets-after-a-reckon-update command, so every onboarding-only side effect is flag-gated and idempotent, and a second run changes nothing. That idempotence is already a stated done-when for the badge and now applies to the whole onboarding path.
How does onboarding learn a repository's Pages configuration?
Locked by the lead 2026-08-24. The failure mode is replacing someone's live documentation site, so the safety-critical fact is read from the authority rather than trusted from a declaration - and it refuses when unauthenticated or when the answer is ambiguous, so the destructive path is never taken on a guess. A local declaration moves that fact into a human answer, and the operator least likely to know the Pages configuration is exactly the one onboarding an unfamiliar repository. Accepted cost: onboarding needs network and a token and behaves differently offline, which is why the per-case strategies are tested against RECORDED Pages configurations rather than live GitHub.
§ Followups
Detect the existing Pages publisher before writing any workflow
Build the detection and the per-case strategy table first, because the destructive path is the default one: a generated deploy-pages workflow replaces a legacy branch-served site. Then the badge, idempotent and with a locally committed compass mark rather than a third-party endpoint. Publication stays a separate explicit opt-in so onboarding never enables it as a side effect. Every case asserted against a recorded Pages configuration rather than live GitHub.