Onboard a Project to TellBoB
Onboard a Project to TellBoB
Section titled “Onboard a Project to TellBoB”Get a task done. Give a project a TellBoB intake front-door — invited reporters get a shared link that turns freeform reports into approved, BoB-convention GitHub issues. Onboarding is a config change plus a deploy: no code changes, ever (#1099). (Back to docs home.)
TellBoB is the multi-tenant intake Worker at apps/intake/ (see its
README for architecture). Each tenant is one
entry in apps/intake/config/projects.json.
Live deployment (#1364): https://tellbob-intake.paul-bb4.workers.dev,
serving tenants bigbrain and oos. Committed config stores token
SHA-256 digests only; plaintext reporter links live with the operator at
~/.claude/secrets/tellbob-reporter-links.md (see the README’s “Live
deployment” section for bindings and secrets).
Onboard
Section titled “Onboard”1. Add the config entry
Section titled “1. Add the config entry”In apps/intake/config/projects.json, add one entry under projects — the
key is the URL slug reporters will visit:
"my-project": { "name": "My Project", "repo": "owner/my-project", "tokens": [ { "label": "alice", "token_sha256": "<sha-256 hex of `openssl rand -hex 16`>" } ], "areas": ["frontend", "api"], "context": "One paragraph grounding the drafting model in what this project is."}Real tenants commit only the SHA-256 digest of each reporter secret
(token_sha256); the plaintext value goes in the reporter’s link and never
in the repo. Issue each reporter their token per the
token lifecycle runbook. R2
attachment prefixes (pending/my-project/…, projects/my-project/…) derive
from the slug automatically — nothing to provision.
2. Create the project’s Access application (#1511)
Section titled “2. Create the project’s Access application (#1511)”Each onboarded project is gated by its own Cloudflare Access application,
scoped to tellbob.iwpi.com/<slug> — identity (email OTP) in front of the
token layer; see the README’s
“Access gating”
section for the layering. Declare it, then converge:
-
In
apps/intake/config/access.json, add the slug underprojectswith the emails allowed to reach the form:"my-project": {"allowed_emails": ["reporter@example.com"]} -
Apply (idempotent; needs an operator-local
CLOUDFLARE_API_TOKENwith Access: Apps and Policies — Edit on the account):Terminal window cd apps/intake && npm run access:apply
Reporters must be on both lists to file: their email on the Access allow-list (gets them to the form), and a named token row (attributes their reports). Adding either later is a config edit + apply/deploy.
3. Preconditions — GitHub App installation and labels
Section titled “3. Preconditions — GitHub App installation and labels”Two preconditions must hold before the tenant goes live:
- GitHub App installed on the target repo. Issue filing uses a repo-scoped
installation token from the TellBoB GitHub App — if the App isn’t installed
on
owner/my-project, filing 502s. Install it (App settings → Install App → add the repo); creating the App in the first place is the GitHub App runbook. - Standard BoB label set on the target repo. Filed issues carry
type/priority/area labels plus
approved; the repo must have the standard set (scripts/bootstrap-labels.sh ensure --repo owner/my-projectif not).
Run the onboarding check — it verifies the config entry, the label set, and the Access gating entry (exit 4 if missing), and states the App precondition:
apps/intake/scripts/onboard-check.sh my-projectExpected output: onboarding preconditions pass for 'my-project'. A label
gap exits 3 and prints the exact bootstrap-labels.sh ensure remediation.
4. Deploy and verify
Section titled “4. Deploy and verify”cd apps/intake && npm test && npm run deployVerify end to end — the App-installation verification step: run the
filing smoke test from the
GitHub App runbook’s Verify section
against the new slug. A 201 with an issue URL (labels + approved + the
reporter footer on the created issue) proves the whole path; a 502 with
nothing created means the App isn’t installed on that repo.
Then send reporters their links: https://<worker-host>/my-project?t=<token>.
Offboard
Section titled “Offboard”Offboarding reverses the same declarative unit:
- Revoke every token for the project (set
"revoked": true— keep the rows; they are the attribution history for issues already filed). Deploy. This alone kills access while preserving everything else. - Remove the config entry once the tenant is confirmed dead (a grace period with revoked-but-present entries costs nothing). Deploy. The slug now 404s before token handling.
- R2 prefix retention stance: attachments under
projects/my-project/issues/…are retained — they are linked from filed GitHub issues, which outlive the tenant; deleting them would break issue history. (Served links stop resolving once the config entry is gone — retention is for the record, not for serving.) Anything still underpending/my-project/…needs no action: the 7-day lifecycle rule expires it. Only scrubprojects/<slug>/explicitly (wrangler r2 object delete) if the offboarding is a data-removal request, and note it on the issues that linked the files.
Related
Section titled “Related”- Token lifecycle runbook — issue / rotate / revoke reporter tokens
- GitHub App runbook — create/install the App, secrets, rotation
apps/intake/README.md— config shape, architecture, filing contract