Release docs sync for **paperclip v2026.824.1** (cumulative window
`v2026.824.0 → v2026.824.1`, 4 commits / 12 files). This patch release
repairs the onboarding background-service flow end to end.
## Change manifest
| Watcher | Parent files | Kind | Docs target |
|---|---|---|---|
| cli-commands | `cli/src/commands/onboard.ts`,
`cli/src/onboard-service.ts` | modified |
`docs/reference/cli/setup-commands.md` |
**`docs/reference/cli/setup-commands.md`** (`onboard` section) — once
the background service is installed, onboarding now hands you off to the
running instance: it waits for the port the service actually bound
(fallback port if the configured one is busy), prints the dashboard URL,
and opens it in your browser on interactive terminals. Headless runs
print the URL; the new **`PAPERCLIP_NO_BROWSER=1`** opts out of the
browser launch. If the service doesn't come up, onboarding points at
`paperclipai service logs` instead of claiming success.
`paperclip_version` bumped to `v2026.824.1`.
**`docs/reference/changelog.md`** — new `v2026.824.1` docs-changelog
entry.
Not doc-worthy this window: `run.ts` runtime-info plumbing, the
`paperclipai doctor` diagnostic-message refinements, and the test files
— no new or now-wrong surface in our docs.
## Verification
- `docs:build` ✓ · `sync:check` ✓ · full `docs:test` (6/6) ✓
- **verify-edit** against `v2026.824.1`: **47 claims verified, 0
unverified, 0 suspicious**. `PAPERCLIP_NO_BROWSER` and `paperclipai
service logs` both confirmed in parent code at the tag.
- **Tag-accuracy (Phase 5.7):** self-contained release — `nightly`
carries no doc drafts (only `.sync-state.json` differs from `main`), so
there are no post-tag leaks to quarantine.
- **Screenshots:** window touched only `cli/**`, no `ui/src/**` —
nothing stale.
## ⚠ Drift
Investigated against `v2026.824.1`. The two previously high-confidence
CLI findings (`paperclipai binary`, `paperclipai into`) were **scanner
false positives** — the drift scanner was reading `paperclipai <word>`
out of `seo_description` frontmatter prose. Fixed in this PR
(`scripts/sync/check-drift.mjs` now skips the YAML frontmatter block);
both disappear.
Remaining (5, medium, `Verify:` — **confirmed correct, no action
needed**):
- `POST /api/companies/import/transfers` ·
`docs/reference/api/companies.md:433`
- `PUT /api/companies/import/transfers/{transferId}/parts/{partIndex}` ·
:434
- `GET /api/companies/import/transfers/{transferId}` · :435
- `POST /api/companies/import/transfers/{transferId}/preview` · :436
- `POST /api/companies/import/transfers/{transferId}/apply` · :437
These routes **exist** at `v2026.824.1`
(`server/src/routes/companies.ts` lines 696/762/825/944/958), registered
via the `COMPANY_IMPORT_TRANSFERS_ROUTE_PATH` constant from
`@paperclipai/shared`. The scanner only matches string-literal paths, so
constant/template-literal registration reads as a false negative — a
known medium-tier limitation. The docs are accurate; nothing to change.
(A follow-up could teach the resolver to follow cross-package path
constants.)
## Checklist
- [x] Cumulative diff from last release tag
- [x] Edits verified against the release tag
- [x] Build + link + SEO + crawlable gates pass
- [x] Drift investigated; false positives fixed at the scanner, false
negatives confirmed correct
- [x] Docs-changelog entry added
- [ ] After merge: tag `docs/v2026.824.1`, realign `nightly`, verify
`docs.paperclip.ing` serves the release
---------
Co-authored-by: Claude Opus 4.8 <[email protected]>
Ports the drift-checker fix to `main` (same change already merged to
`nightly` in #61). `check-drift.mjs` is byte-identical across branches,
so this cherry-pick applies cleanly.
## Problem
The drift checker printed the parent's **live** SHA in its header but
keyed its file cache by the moving name `drift-master` with no
invalidation — reusing days-old file contents while claiming to check
today's commit, silently hiding real drift.
## Fix
- Resolve the ref to a full commit SHA before any reads; cache key =
`drift-<sha>`, never `drift-master`.
- Fail closed if the ref can't be resolved.
- Mode-aware ref from `.sync-state.json` (release → `base_release_sha`,
nightly → `last_seen_parent_sha`) before falling back to the default
branch. `main` is release-mode, so its checks now pin to the release SHA
instead of moving `master`.
- Testable cache path (`PAPERCLIP_SYNC_CACHE_DIR` + fixture SHA stub);
+2 regression tests. `npm run sync:test`: 37 passed, 0 failed.
## Triage note
Running the fixed checker on `main`'s released docs against the release
tag `v2026.707.0` returns **0 drift** — released docs are correct about
the shipped product; this is a tooling fix only, no doc content changes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 <[email protected]>
Back-fills documentation for the human multi-user collaboration surface
(company members, invites, roles, permissions, offboarding). These
features are already shipped and live; this fills doc gaps and fixes one
live permission-key drift. Branched off `main` (not `nightly`) because
it's editorial back-fill of released features, intended to ship
independently of the nightly sync cadence.
## Tier 1 — correctness
- **Fix live permission drift** in `administration/company.md`: the
grant list and Owner/Admin role descriptions were missing
`environments:manage` and `tasks:manage_active_checkouts` (both present
in `packages/shared/src/constants.ts` `PERMISSION_KEYS`;
`environments:manage` is an Owner/Admin default in
`server/src/services/company-member-roles.ts`).
- **New** `administration/roles-and-permissions.md`: canonical 8-key
catalog (what each gates), role→default-grant matrix, additive
precedence rule, `instance_admin` layer, and current limitations.
- `maintenance/follow-ups.md`: note to teach the drift checker the
permission catalog so this can't silently drift again. (Sync tooling
itself untouched.)
## Tier 2 — how-tos
- `how-to/add-a-human-teammate.md` — invite → join request → approve →
set role/grants (UI + CLI).
- `how-to/offboard-a-member.md` — suspend vs archive, work reassignment,
membership-status-gates-access, instance-level cleanup.
- `how-to/enable-multi-user-login.md` — `local_trusted → authenticated`,
board-claim handoff, then invite people.
## Tier 3 — concept
- `guides/org/members-and-access.md` — shared human+agent principal
model, roles vs grants, human roles ≠ agent org chart, instance admin,
the member profile page, and the "left a project ≠ lost access"
clarification.
## Verification
- All 5 new pages registered in `site/content.json` (valid JSON, +5
pages).
- `sync:lint-links` and `sync:verify-nav` clean for these changes. The
single link the linter reports pre-exists on `main` in a skills file
untouched here; the 2 nav orphans are the intentional CLI redirect
anchors.
- All content verified against `paperclipai/paperclip@master` source
(permission keys, role defaults, CLI syntax, deployment modes).
## Follow-up after merge
Back-merge `main → nightly` so the next release merge stays clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Two follow-ups to the server/src env-var scan widening:
1. verify-edit.mjs had its own copy of shouldFetchEnvSource with the same
narrow server allowlist — apply the identical server/src/**/*.ts widening
so the verify phase stops emitting unverified env-var false positives.
2. Both scripts now also scan all non-test packages/adapters/<name>/src/**/*.ts.
Adapter packages read env vars directly in their server/index modules —
e.g. SANDBOX_INSTALL_COMMAND (packages/adapters/{pi,claude,gemini,cursor}-local/src/...)
and per-runtime API-key fallbacks — which the old allowlist never fetched.
Verified against parent v2026.618.0:
- check-drift: 0 drift (65 env vars checked).
- verify-edit docs/reference/adapters/sandbox-providers.md: 6/6 claims verified
(SANDBOX_INSTALL_COMMAND, previously unverified, now resolves).
- sync:test 33/33.
Selection grows to ~452 files, still well under the 700 cap.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The env-var drift checker only fetched a narrow allowlist of server files
(config.ts, a few auth/service files), so env vars read elsewhere in
server/src showed up as env-var-missing false positives every run.
Verified against parent v2026.618.0 that the 5 recurring false positives are
real, read env vars the old scan never looked at:
- TRUST_PROXY server/src/app.ts:167 (parseTrustProxyEnv(process.env.TRUST_PROXY))
- OTEL_EXPORTER_OTLP_ENDPOINT server/src/instrumentation.ts:29
- OTEL_EXPORTER_OTLP_PROTOCOL server/src/instrumentation.ts:69
- OTEL_SERVICE_NAME server/src/instrumentation.ts:144
- OTEL_SERVICE_VERSION server/src/instrumentation.ts:145
Fix: replace the three narrow server/src rules in shouldFetchEnvSource with a
single rule covering every non-test server/src/**/*.ts file (tests already
excluded above). Selection grows 130 → 326 files, well under the 700 cap.
Result: check-drift against both v2026.618.0 and master now reports 0 drift
(was 5 env-var-missing), with identical coverage (65 env vars, 235 routes,
57 CLI commands, 7 paths). sync:test 33/33 pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The wet-run found POST /api/companies/{companyId}/logo documented in
docs/reference/api/companies.md but absent from the current parent
server/src/routes/companies.ts. The cumulative-diff path is blind to
this — it sees what's new, not what's vanished. Drift is independent
of the diff window: it can exist regardless of when the last sync ran.
scripts/sync/check-drift.mjs (712 lines):
- Four drift classes:
- parent-path-missing (high confidence): doc references to
cli/src/..., packages/..., server/src/... paths that 404 in parent.
- cli-command-missing/ambiguous (high/medium): documented
`paperclipai <subcommand>` not found in parent cli source.
- env-var-missing (high): table rows in environment-variables.md
that don't appear in .env.example or watched config files.
- rest-route-missing (medium): ## METHOD /api/... headers in
docs/reference/api/*.md not registered in matching routes/*.ts.
Normalisation handles {id} ↔ :id and prefix-stripping for
relative-mounted routers.
- Cached gh contents under /tmp/paperclip-sync/drift-* (per-ref).
- Same fixture-loader pattern as compare-window.mjs for hermetic
unit tests via PAPERCLIP_SYNC_FIXTURE_DIR.
- Never auto-resolves — always surfaces for human review.
SKILL.md changes:
- New Phase 1.5: runs check-drift against parent default branch
HEAD, independent of the diff window. Drift records form a new
manifest tier (not auto-merge, not pr, not context-only).
- Phase 4 dry-run summary includes drift counts.
- Phase 7 PR bodies get a "⚠ Drift" section.
Tests: 4 new (12/12 total passing). Live run against parent master
caught the motivating logo-route case plus 40 other genuine drift
candidates that should be triaged separately (env vars in untracked
packages, the goals-and-projects → goals.ts+projects.ts file-split
mismatch, etc.).
sync:check now chains lint-links + verify-nav + check-drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>