§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:

RepositoryPagesSourceBuild type
Simon-McIntosh/reckonnone
Simon-McIntosh/imas-codexactive, builtmain 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 stateStrategy
Nonereckon may own the site; generate a deploying workflow
Legacy, branch rootNo workflow — commit the build under a subpath; it is already served
Legacy, /docs folderBuild into a subdirectory of docs/ so the existing site keeps its root
Legacy, gh-pages branchCommit the build to a subpath of that branch, never its root
Actions-basedRefuse and report — the existing artifact must absorb reckon's output; merging two deploys is the repository owner's call
Cannot be determinedRefuse 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.

/reckon-ship reckon:project-onboarding