33 Commits
Author SHA1 Message Date
d627632874 Release docs for paperclip v2026.1106.0 (#172)
Docs for parent release `v2026.1106.0` (`d69631b0`), up from
`v2026.1023.0` (`1b4c8038`): 515 parent commits.

## How this branch was built

The tag is 914 commits behind what `nightly` has drafted, so this branch
isn't cut from `nightly` HEAD. It starts at nightly commit `1952052`
(parent `043f2514`), 19 commits before the tag, then adds:

- the `main` hotfix (#160)
- the sync tooling from `nightly`
- docs for those 19 commits

Later nightly drafts stay on `nightly`, so no pages had to be removed.
No `nightly-draft/*` PRs are open.

## What changed

- **Runner by default:** new Claude, Codex, OpenCode and Pi agents start
on Paperclip Runner on supported hosts, with **Legacy runner** and
**Upgrade runner**.
- **Workspaces:** cleanup of finished workspaces, optional Git
expiration, and restore points for unsaved work. Restore points are off
by default.
- **New pages:** Prompt injection prevention, Google Workspace, GitHub
Copilot, Speko, Braintrust, Daytona, Ditto and Unikraft.
- **Breaking and upgrade notes:** the run history limit, Sentry run
failures off by default and the DSN variables, the Docker start command
for custom images, `--yes` on `instructions-file:delete`, and slower
migrations on large instances.
- **Also covered:** project repositories as skill sources, roster bulk
edit, Artifacts V1 (experimental, off by default), composer dismissal,
`expectedStatusVersion`, `unexecuted_review_stage`, and plugin workspace
providers.
- **Changelog:** a v2026.1106.0 entry in `reference/changelog.md`.

## Older text corrected

These were wrong at the tag, and most are also wrong on the live site:

- which permissions let an agent read a peer's configuration or change
instructions (`api/agents.md`)
- `decideNowCount`, which doesn't exist; the field is `deskBadgeCount`
- `file-resources` routes, which are board-only
- the **Create project** dialog fields, a CEO rule the code doesn't
enforce, and where a terminated agent's reports appear
- `instructions-file:put` and `:delete` examples that always failed
(`cli/agent.md`)
- a curl example that returned `422` (`api/cases.md`)
- Google Workspace **Reconnect** instructions, which claimed it reopens
the service picker
- the `permissionKey` table, which listed 8 of 21 keys
- drafting text at the end of `api/agents.md`

## ⚠ Please check these

- **Product behaviour that may be a parent bug.** The docs now describe
the tag's code, which you may prefer to fix upstream:
- The project **Environment** dropdown saves a choice, but runs ignore
it (`experimental/environments.md`).
- `environments:manage` is granted by roles but no environment route
checks it.
- `suggest-changes` is documented as agent-only, because only agents
have a consent path. Company skill policy decides skill edits.
- **Reader-visible mismatches in the parent UI.** The docs follow the
code. Upstream copy still mentions a "Built-in agents tab", says Copilot
"awaits qualification", and tells people to "Reconnect Google Workspace
to change access".

## ⚠ Post-tag leaks removed

Nothing to remove from an already-drafted page: post-tag surfaces such
as 1Password, Vercel, Supabase deploy, custom gateway onboarding and
Artifacts V1 as default never came onto this branch. Authors left out
post-tag hunks of the next nightly draft, and the reasons are in the run
notes.

## ⚠ Drift

None. Zero findings at the tag, from a full parent snapshot.

## ⚠ Verification Failures

The tag-accuracy gate reports one leak and nine review entries. None is
a real failure:

- **Leak:** `reference/cli/service.md`, `paperclipai payload and`. This
is a false positive; it's prose from a real message at
`cli/src/commands/service.ts:184`.
- **Review, 8 new connector pages:** the gate can't confirm new pages.
Reviewers confirmed each surface exists at the tag.
- **Review, `local_tools`:** an example value from the tag's Runner
README.

Not provable from code, and kept deliberately:

- `sandbox-providers.md` uses `sandbox.yaml`. The tag's README says
`install.yaml`, which returned 404 when checked. The upstream fix is
post-tag.
- The Google Workspace row about older OAuth brokers rests on release
notes and a design doc. The broker isn't in this repo.
- External claims about provider behaviour (for example Braintrust,
Daytona, Unikraft and Google scopes).

## ↻ Renames detected

None. The rename helper wasn't run: the 19-commit delta adds no new
adapter, skill, or plugin directories that it would check.

## Verification

All checks read a checkout pinned to the tag.

- **First round:** authors, a release-notes audit, an audit of
corrections stranded on `nightly`, an audit of 321 lines the last
realign dropped from `main` (about 130 checked directly in code), and
six fresh verifiers.
- **Second round:** seven new verifiers re-checked every changed area,
tracing behaviour rather than matching labels, and fixed about 50 more
defects. That volume means more may remain.
- **Limits of that second round:**
- Each verifier reported what it only string-matched. That includes
parts of Artifacts V1, the **Upgrade runner** notice, Copilot run
behaviour, and some Plugin SDK contract text.
  - The second-round fixes themselves weren't reviewed by a third round.
- **Gates:** `docs:build`, `docs:test` and `sync:check` pass.
- **Nothing was run against a live instance.** All of this comes from
reading code.

## Screenshots

**196 of 278 screenshots are stale and none were recaptured.** The list
is in `SCREENSHOTS_PENDING.md`. Some visibly differ from the text, such
as the removed **Run with provider trace** button and the old roster
tabs.

## After merge

1. Keep the PR title as is: `tag-docs-release.yml` reads the version
from it.
2. Confirm the `docs/v2026.1106.0` tag exists.
3. Run `node scripts/sync/realign-nightly.mjs release/v2026.1106.0
--push`, then audit for dropped lines and duplicated paragraphs, and set
`nightly` state back to `branch_mode: nightly`.
4. Check that `docs.paperclip.ing` serves the release: a new page, a new
claim, and the changelog's top entry.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Dotta <[email protected]>
Co-authored-by: ClaudeCoder <[email protected]>
2026-11-07 13:02:42 +01:00
0ea1994fa7 Release docs for paperclip v2026.1023.0 (#156)
## Summary

Release docs for Paperclip **v2026.1023.0** (parent tag commit
`1b4c8038`).

- **Window:** `v2026.1012.0` → `v2026.1023.0`. The tag was cut from
parent `master` at 2026-10-12, so the cumulative window is the
merge-base `22a3ea34` → `1b4c8038`. That's 200 commits and 2,501 files,
with no compare truncation.
- **Branch:** cut from `nightly` (`1b81e21`). Nightly had drafted
against parent master up to `043f2514` (Oct 22), which is 496 commits
past the tag. Most of nightly's #151–#155 work is post-tag.
- **Review:** six reviewers checked all 161 changed pages hunk by hunk
against a local checkout of the tag, using post-tag history
(`1b4c8038..043f2514`) to date each claim. The tag-accuracy gate was
then re-run on the result.

**Headline doc changes:**
- **New pages (21):**
  - [Custom model providers](docs/connectors/custom-model-providers.md)
  - [Decision Models API](docs/reference/api/decision-models.md)
  - [Cases](docs/experimental/cases.md)
  - [External agents: OpenAI Dot](docs/experimental/external-agents.md)
  - [Agent cryptographic identity](docs/guides/org/agent-identity.md)
- [Agent complaints and
suggestions](docs/administration/agent-commentary.md)
  - [Runtime Commands](docs/reference/cli/runtime.md)
- 14 connector guides: Bitly, Calendly, Context7, Enterpret, Exa,
Firecrawl, Gauge, GSC Wizard, Make, Parallel Search, Superagent, Tavily,
Telem.AI and Windsor.ai
- **Updated pages:**
  - Private tasks and projects, with sharing and inherited privacy.
- Costs: estimated, unpriced and subscription spend, the Overview
breakdowns, provider cost reports, and the Decisions view.
  - Operators get default company editing permissions (#15377).
  - Agent setup checks and your primary agent.
  - Slack: automatic setup and **Require at-mention**.
  - The simplified dedicated GitHub App setup.
  - Cursor and Pi on Paperclip Runner, and the **Harness** label.
  - Expanded assistant MCP tools and the `paperclip:configure` scope.
  - CSV and HTML artifact previews.
  - The plugin agent lifecycle contract.
- Server-host AI sign-in, and new Linear, Airtable and Hugging Face
methods.
- A changelog entry, and 102 pages stamped `paperclip_version:
v2026.1023.0`.

### ⚠ Post-tag leaks removed

These document parent `master` features that are **not in
v2026.1023.0**. They stay on `nightly` for a later release.

- **Pages removed (7):**
  - `connectors/github-copilot.md` (92b23813)
  - `connectors/google-workspace.md` (23b2ceb0)
  - `connectors/braintrust.md` (92cfd701)
  - `connectors/daytona.md` (0b62c736)
  - `connectors/ditto.md` (a1e2173c)
  - `connectors/speko.md` (22d05644)
  - `connectors/prompt-injection-prevention.md` (2c96f767)

Their nav entries and catalog rows are already removed, and no page
links to them.
- **Reverted to `main`:**
  - 54 pages whose nightly changes were all post-tag. That includes:
- The Google per-app "no longer listed" notes and Gmail archive
(23b2ceb0, e4ce9890).
- The skills guide and the company-skill-policy API (repository packages
and auto-updates: a9830414, 473c80d1, df4ee06e).
    - The Cases API (handoffs and workflows: 505e1a55, 0a5f1546).
- The companies API (observability and prompt injection: ac9459ba,
2c96f767).
- `deploy/docker.md`, the claude-code and hermes adapters, and
`cli/agent.md` / `cli/service.md` (`--runner`, managed-shim guard).
  - The rest only changed Sources-link SHAs or had nightly-only wording.
- **Sections trimmed:**
- The Runner-default rollout, its upgrade notice and `runner` fields
(adb69e8f, 8193abb9, 39e44a9d, 734c2653).
  - Grok Bot and Muse (b8ffeb97, e6dcc6b0).
  - Task workspaces and plugin project storage (f329b24e, 8b4ab65b).
  - Task Retry and recovery status lines (d33b40a5).
- The commentary read API, `commentary:view`, and Pipelines removal
(e6dcd1e8, e5927e1d, 90777488).
  - Scoped and async budget enforcement (30b753f6).
- Plugin WebSocket routes, agent detail tabs, resource-lifecycle
delivery and Runner tasks (42715d45, db65a086, 33cc567f).
- Slack managed Cloud setup and DM at-mention changes (f0e12c85,
df06df23).
- Review-bot queued-comment, reconnect and naming changes (3b8324a2,
52459590, 7eea9d82).
  - OpenRouter attribution headers (9179d8dc).
  - Agent, project and routine search (7b9334cd).
  - Artifacts upload (762d680d).
- Env-var rows: `NATIVE_HARNESS_BACKUP_*`, `WORKSPACE_COMPACTION_*`,
`GIT_CACHE_*`/`GIT_BASE_*`, `SKILL_VERSION_RETENTION_*`, `NATIVE_MCP_*`
and `SENTRY_RUN_FAILURES`.
  - `/api/liveness` (a0651c96).
- Source links pinned to post-tag commits now point at the tag commit.

### ⚠ Drift

Checked against the tag (`check-drift --against 1b4c8038`). There are 33
candidates, the same set as the last nightly runs:
- **High:** `PAPERCLIP_WORKSPACE_GIT_SCAN_*`,
`PAPERCLIP_WORKSPACE_GIT_SNAPSHOT_TIMEOUT_MS`, `PAPERCLIP_RUNNER_API_*`,
`PAPERCLIP_MCP_AUTHORIZATION_ORIGIN` and `PAPERCLIP_CLOUD_CONNECTOR_*`
are known false positives. They're read through helpers or `env.`
receivers the checker doesn't scan.
- **High:** `PAPERCLIP_ID_CONNECTOR_*` is documented as retired, which
is intentional.
- Verify: `agent-avatars` (`:file` param), `companies/import/transfers*`
(constant route path), `chats/{agentRef}` (`router[method]` loop), and
`mcp/requests/{id}` plus the Dot pairing routes (array registration in
`public-mcp.ts`). These are known false positives.

### ⚠ Verification Failures / review notes

- **Tag-accuracy gate false positives:**
- `cli/runtime.md`: `--sha256` is a `.requiredOption` in
`cli/src/commands/runtime.ts`. `SSL_CERT_FILE`, `SSL_CERT_DIR` and
`NODE_EXTRA_CA_CERTS` are passed through by key list in
`buildPiSetupEnvironment`.
- `plugins/sdk.md`: `ENVIRONMENT_ACQUISITION_PROVIDER_STATES` is an SDK
export.
- `skills.md`: `PAPERCLIP_HELPER_STATE_DIR` is read in the skill's
upload script.
- `adapters/cursor-local.md`: the `acpx*` fields are validated in
`paperclip-runner-permissions.ts`.
- **New pages the gate can't auto-confirm:** each was confirmed by hand
at the tag, against the app definitions, routes and UI.
- **Claims kept on weaker evidence (commit message or UI string, not
code) — please eyeball:**
  - "a new bot starts in mentions-only mode" (github-setup).
  - "Mentions work in issue and PR descriptions" (review-bot setup).
  - Airtable's "HTTPS or localhost" sign-in note.
  - The "37 tools" figure on assistant-connections.
  - Reservation semantics on the costs guide.

### Screenshots

142 of 278 screenshots depend on UI files changed in this window (see
`SCREENSHOTS_PENDING.md`). They were last captured against v2026.1012.0
(#150), and a recapture is still pending.

### Checks

`docs:build` and `sync:check` pass: no broken links, and the only
orphans are the four pre-existing ones (`you-com`, `hosted-beta` and the
two intentional CLI redirect pages). All eight `docs:test` suites pass.

### After merge

1. Confirm the `docs/v2026.1023.0` tag was created.
2. Run `node scripts/sync/realign-nightly.mjs release/v2026.1023.0
--push`.
3. Re-apply this branch's decisions on `nightly`.
4. Flip `nightly`'s state back to `branch_mode: nightly`.
5. Verify docs.paperclip.ing serves the changelog entry and new pages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Dotta <[email protected]>
Co-authored-by: ClaudeCoder <[email protected]>
2026-10-24 13:01:34 +02:00
39633c2217 docs: connectors catalog, operator-first third revision (#124)
Connector catalog, setup guides, and shared access documentation,
followed by a final code-accuracy repair pass. This PR does not change
application behavior.

## Final accuracy pass

Checked against shipped Paperclip `v2026.916.0`, commit
`dffc2b3ca1b9e88fa21cb17493083e682dffd1ca`, rather than the dirty local
checkout or the earlier canary baseline.

- Corrects connector/method-specific identity choices, human audiences,
and managed GitHub versus PAT scope and verification.
- Explains that **Always allow** covers different arguments for the same
agent/action/connection, with project scope when present; uses actual
button labels and removes the test-panel control from review
instructions.
- Qualifies new-action quarantine, including safe-default read
exceptions. Removes unconditional approval guarantees.
- Separates provider channel/repository reach from Paperclip sender
authorization.
- Completes sandbox sign-in and model credential-selection instructions
from the current UI implementation.
- Repairs Notion's hub summary, removes incomplete optional
Notion/Sentry client-registration procedures, and corrects Linear's
provider-versus-Paperclip attribution.
- Removes unsupported Postman tier claims, contradictory Cloudinary/Mem0
verification assertions, API-equivalence claims, and overbroad
successful-test assurances.
- Retains Supabase's required project reference: both released method
definitions explicitly require it. An earlier review suggested
otherwise; release code is authoritative here.
- Updates the release baseline and removes draft commit chronology from
the public introduction.

## Availability and remaining runtime gates

- **Google:** Verification is pending. Per the product-owner
clarification, authorization can continue where Google offers an
Advanced option; this is not available for every account and does not
override Workspace policy or other Google prerequisites. Notices on the
hub and all Google guides now distinguish an unverified-app warning from
blocked authorization.
- **Slack is available but not yet fully functional; follow-up fixes are
planned.** For agent tools, the released OAuth endpoint/scope defaults
differ from Slack's documented MCP contract. The page now warns against
treating that route as production-ready and removes the misleading
bot-scope walkthrough. Chat-channel bot setup remains separate.
Engineering must reconcile the integration and run OAuth plus one read
before removing this warning. Source:
https://docs.slack.dev/ai/slack-mcp-server/
- No credentialed connector run was performed in this pass. Code
consistency, provider documentation, UI rendering, and successful live
execution are separate evidence levels. No claim of runtime
certification for all connectors.

## Validation

- Root build: 253 crawlable documentation pages.
- Full `docs:test`: all eight suites passed locally, including
root/subpath routes, sitemap history, fingerprints, navigation, skill
source blocks, crawlable links, doc-link resolution, and SEO metadata.
- Internal-link lint: 258 Markdown files; no broken internal links.
- Latest cleanup: full build, all eight docs:test suites, internal-link
lint and diff whitespace checks passed; 1,878 link-resolution checks.
- Fixed the Calendar MCP reference URL; browser-checked the five
inconclusive external destinations (Miro article loads; Asana, Google
Cloud, OpenAI and xAI reach sign-in/console screens). Authenticated
destinations were not tested beyond those screens.
- Replaced the Sandbox providers editorial TODO with a scope note and
removed the CLI overview's unfinished-guide announcement.
- Browser client navigation: 687 checks passed using installed Chrome.
Initial launch lacked the downloaded Playwright browser; rerun used
`DOCS_CHROMIUM_PATH` without changing the tests.
- Nine representative connector/shared pages at 1440px and 390px: HTTP
200, one article H1, no page-level horizontal overflow. Mobile
screenshot inspected; approval page opened in the Codex browser.
- Navigation audit reports three existing non-connector orphan files;
this patch does not alter those files or their navigation.

The previous revision's provider-page expansion, Google shared setup
guide, navigation additions, and accidental node_modules-symlink cleanup
remain in this PR. Internal review ledgers remain outside the
publication branch. No merge or production deployment authorized.

---------

Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: Michael Nguyen <[email protected]>
2026-09-16 22:19:14 -10:00
Aron PrinsandClaude Opus 4.8 27d7a5ab4c Release docs for paperclip v2026.831.1 (#120)
Syncs docs to parent release **v2026.831.1** (cumulative from
`v2026.824.1`, via merge-base `664052f`). Authored fresh against the
release tag; every claim verified at the tag.

## What changed

**New**
- **Kimi Code adapter** (`kimi_local`) — new reference page, wired into
the adapters overview, nav, and anchor-map source mapping.

**Reference**
- **Env vars** — `PAPERCLIP_WORKSPACE_REAPER_COOLDOWN_DAYS`, opt-in
`SENTRY_DSN`, and the operator controls `PAPERCLIP_HIDDEN_SETTINGS` /
`PAPERCLIP_SETTING_DEFAULTS`.
- **Instance Settings** — new "operator controls for hosted deployments"
section (hide surfaces / override defaults).
- **Node.js floor → 24.11.0** across installation, setup,
local-development, plugin dev, Modal, and the getting-started/terminal
guides.
- **Grok adapter** — `permissionMode` no longer defaults to `dontAsk`;
when unset no flag is passed, and `--always-approve` is the unattended
policy.
- **CLI `agent`** — Kimi skills install path (`~/.kimi-code/skills`) +
`KIMI_CODE_HOME`.

**Guides**
- **Onboarding** — rebuilt around a single-card wizard that opens on
creating your agent; the mission step is gone, the goal is set
afterward.
- **Settings unification** — Invites folded into a Members tab, one
shared settings nav, and the company brand color + per-company
attachment size limit removed (also reflected in the Companies and Cases
APIs).
- **Governance behavior** — silent-run detection and stranded-task
recovery no longer act on their own; agent thought text is excluded from
automatic comments; invalid agent credentials now return `401`.

**Changelog** — entry added for v2026.831.1.

## Gates

- `docs:build`, SEO metadata, crawlable-links, sitemap-lastmod
(194/194), lint-links, verify-nav — all pass.
- **Edit verification:** every new high-confidence claim verified at the
tag.
- **Tag-accuracy gate:** 31 files checked, **0 post-tag leaks**, 30
clean, 1 review (below).

## ⚠ Drift (Verify before acting — not auto-resolved)

Medium-confidence REST-route drift in `docs/reference/api/companies.md`
— the import-transfer routes may no longer exist at these paths (likely
a false negative from prefix/dynamic registration; confirm before
editing):

- `POST /api/companies/import/transfers`
- `PUT /api/companies/import/transfers/{transferId}/parts/{partIndex}`
- `GET /api/companies/import/transfers/{transferId}`
- `POST /api/companies/import/transfers/{transferId}/preview`
- `POST /api/companies/import/transfers/{transferId}/apply`

## ⚠ Review

- `docs/reference/adapters/kimi-local.md` — new page; the only flagged
claim is the `secret-id` JSON **example placeholder** (not a real
identifier). Authored directly from the adapter's config surface at the
tag.

## Screenshots (deferred)

288 of 342 registered screenshots are stale (org-wide rename +
settings/onboarding rewrites), tracked in `SCREENSHOTS_PENDING.md`.
Recapture is a follow-up pass — **the merged pages describe the new
onboarding/settings UI while screenshots still show the old flow until
then.**

---------

Co-authored-by: Claude Opus 4.8 <[email protected]>
2026-09-02 13:06:00 +02:00
Aron PrinsandClaude Opus 5 c593c23233 seo: date sitemap entries by body changes, not frontmatter sweeps (#118)
Follow-up to #117. That PR got `<lastmod>` publishing at all; this one
makes the dates worth resubmitting.

## The problem

**190 of 193 pages read `2026-08-25`** — the date of #115, which added
`seo_title`/`seo_description` to all 192 pages. Here is everything it
changed in a representative file:

```diff
+---
+seo_title: "Key Concepts: Companies, Agents, Tasks"
+seo_description: The seven ideas behind Paperclip — company, agent, task...
+---
+
 # Key Concepts
```

Not a word of prose. `lastmod` is meant to carry the date a page's
**content** last changed, so resubmitting this hands Search Console the
"whole site changed at once" signal that `dropUniformLastmod` and the
shallow-checkout guard both exist to prevent. It cleared
`dropUniformLastmod` only because 3 pages happened to differ.

## The fix

Walk each file's history and report the newest commit that changed the
**rendered body** — comparing `parseFrontmatter().body` across
consecutive commits, so frontmatter-only commits are skipped. Reusing
the build's own parser means the body compared is exactly the body the
site renders.

| | Before | After |
|---|---|---|
| Distinct dates | **2** | **31** |
| Largest single-date cluster | 190 pages | 54 pages |
| Range | 2 days | 2026-04-17 → 2026-08-27 |

Top of the new distribution:

| Date | Pages |
|---|---|
| 2026-08-18 | 54 |
| 2026-06-04 | 21 |
| 2026-08-25 | 17 |
| 2026-07-08 | 16 |
| 2026-07-20 | 15 |
| 2026-04-22 | 12 |

Spot-checked both directions:

- `key-concepts.md` — last touched by the frontmatter sweep, now dates
to **2026-07-08**, the commit that changed "Claude Local" to "Claude
Code" in the body.
- `day-to-day/issues.md` — **keeps 2026-08-25**, because release commit
`6c4519a` that day added a real "Who may resolve a card" section. Its
frontmatter-only `paperclip_version` bump in the same release was
correctly skipped.

## Two supporting fixes

**Concurrency.** ~600 git round-trips in series cost 40s. Resolving them
in parallel: **11s**.

**A race the concurrency exposed** — and the reason this is worth
reading closely. `hasTrustworthyGitHistory()` memoised its *resolved
value*, so once all 192 pages asked at once, every one of them passed
the guard before the first resolved:

```
Could not deepen the shallow checkout: fatal: Unable to create '.git/shallow.lock': File exists.
Still shallow: omitting sitemap <lastmod> rather than dating every page alike.
   × 192
```

192 concurrent `git fetch --unshallow` calls fighting over the lock, and
**a sitemap with no dates at all**. This only reproduces on a shallow
clone — which is to say only on Cloudflare Pages, never locally or in
`docs-test`. Fixed by memoising the promise (single-flight).

## Verification

| Scenario | Result |
|---|---|
| Full clone | 193 dates, 31 distinct, 11s |
| `git clone --depth 1` (reproduces CF) | one unshallow, **193 dates, 31
distinct** |
| Shallow + unreachable remote | no dates, exit 0 |
| `npm run docs:test` (6 suites) | pass |
| `npm run sync:test` | 39 pass, 0 fail (+1 new) |

New unit test covers the `--follow --name-status` rename parsing — 55
docs files have been renamed, and reading the wrong field silently drops
their pre-rename history.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-08-29 10:55:32 +02:00
Aron PrinsandClaude Opus 4.8 5457a4ff38 Release docs for paperclip v2026.824.1 (#116)
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]>
2026-08-27 12:55:02 +02:00
Aron PrinsandClaude Opus 4.8 8a858777f2 sync-docs: tag-accuracy gate + release-channel-aware skill (#111)
Makes /sync-docs correct under the canary→nightly→beta→stable channel model. Adds the release-mode tag-accuracy gate (scripts/sync/check-tag-accuracy.mjs) that verifies every changed page against the stable tag and flags post-tag leaks; stable-CalVer guard + channel glossary, tag-scoped drift/verify, and Phase 5.7 in the skill; realign fix that keeps nightly's drafts; a release-channels watcher; the analysis/plan doc; and a hermetic test (sync:test 38/38).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-08-25 11:48:38 +02:00
631a6a0c53 Release docs for paperclip v2026.817.0 (content + screenshot overhaul) (#95)
Ships the v2026.817.0 docs to live: the doc content that was authored
and verified
earlier, plus a full screenshot overhaul.

The content half (`cdf81e2` and the nightly commits behind it) has
already been
reviewed. **The screenshots are the part that needs eyes** — `f24d734`,
342 PNGs.

## Screenshots

Everything was recaptured against the release commit
`213dabab4f8e1f3bb1803a2924c0fea1289fcd4c`
(`upstream/candidate/release-2026.817.0`). The previous shots were 375
parent-commits stale (v2026.720.0), with 228 of 310 entries flagged
pending. All
342 registry entries now carry that SHA.

> ⚠️ Worth knowing: the release commit is **not** an ancestor of the
parent's
> `master`, and local `master` was four days *older* than it. Capturing
against
> `master` would have both missed release UI and leaked 93 post-tag
commits' worth
> of UI into the release docs.

### New coverage (34 entries)

Three guides shipped with **no images at all** despite being 115–136
lines. They
now have them:

| Guide | Shots |
|---|---|
| `guides/day-to-day/decisions.md` | queue, an agent-proposed decision
with its options, triage strip, filter panel, named queue, Decided
curtain, empty state |
| `experimental/status-cards.md` | board, New card dialog, and all four
drawer tabs |
| `experimental/task-chat.md` | thread, composer mode picker, side pane
|
| `reference/api/secrets.md` | the board-side Proposals tab |

Chat-Style Tasks is captured in a **separate pass**:
`enableTaskChatRedesign` is
instance-wide, so leaving it on would have turned every classic
issue/task/work-mode
shot into the redesigned chat.

## Two defects that were already live

Both were shipping in the docs before this PR:

1. **`issues/detail-chat.png` and the `tasks/*` shots were mostly plugin
debug
output.** The Kitchen Sink example plugin mounts a panel into the issue
page
that dumps the raw issue JSON, and the seed installed it. Those guides
were
illustrating a debug panel instead of the task page. The seed no longer
   installs it.
2. **The seeded task thread was a monologue** — four board-user messages
in a row,
because the board actor cannot post agent comments. It is now a real
two-sided
   exchange.

## Targets repointed because the UI moved

| Target | Why |
|---|---|
| `activity/*` | `Activity.tsx` deleted; `/activity` renders
`pages/audit/CompanyActivity.tsx` |
| `experimental/cloud-upstream` | `CloudUpstream.tsx` deleted; the route
now redirects to `/company/export` |
| `settings/*`, `plugins/*`, `adapters/*` | `/instance/settings/*` are
legacy redirects now |
| `dashboard/stale-tasks-panel` | panel removed from `Dashboard.tsx` —
target dropped |

Plus eight targets with **silent selector drift**. A failed interaction
step falls
back to "whatever state was reached", so these had been quietly
producing wrong
images — a plain inbox where the doc promised a mode picker, a whole
dashboard
where it promised one panel. Full table in
`docs/user-guides/screenshots/SCREENSHOTS_PLAN_v2026.817.0.md` §C2.

## Pipeline

Decisions, status-card summaries and secret proposals are all
**agent-authored**,
and the board actor the seed runs as is refused by every one of them
(`"Agent run context required"`, `"Secret proposals require a verified
run-bound
agent token"`). Rather than insert rows behind the API,
`seed-new-surfaces.mjs`
borrows the two doors a real run already has — a board-minted agent API
key, and a
locally signed agent JWT — so every write goes through the production
code path.

Also:
- `capture.mjs` records a real `captured_against` on a detached checkout
instead of
the literal string `"HEAD"` (which is what every pre-2026.817 entry
recorded), and
  gains a `scrollTo` step for content below the fold.
- `run.mjs` gains `--serve` for iterating on the seed, the task-chat
phase, and a
keeper that holds the demo board's issue statuses steady — the demo
`process`
agents finish runs without declaring a disposition, so the stalled-work
sweep
re-blocks issues every few minutes over a capture that runs far longer.

## Reviewing

Light and dark both captured at 1440×900 @2x. The new surfaces are the
ones to
scrutinise; the rest is a like-for-like refresh.

### One leftover

Dropping `dashboard/stale-tasks-panel` leaves
`{light,dark}/dashboard/stale-tasks-panel.png`
tracked but unused — they need deleting by hand.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
Co-authored-by: Dotta <[email protected]>
Co-authored-by: ClaudeCoder <[email protected]>
2026-08-18 12:43:56 +02:00
8121a9c947 Release docs for paperclip v2026.720.0 (#67)
Ships the docs for **paperclip v2026.720.0** to `docs.paperclip.ing`.

Window: `v2026.707.0...v2026.720.0` — 196 commits, 1,523 changed files,
0 truncated leaves.

Most of this release was already drafted on `nightly` over the past
cycle (Cases, Folders, Decision Training, Attention, Built-in Agents,
company skill policy, inbox agent policy, `costStatus`, the ACP engine
graduation and `acpx_local` retirement, and
`PAPERCLIP_TOOL_ACTION_SIGNING_SECRET`). This PR adds the surfaces
nightly had **not** yet covered, then stamps the release version across
everything touched this cycle.

## New pages

**`docs/reference/api/tool-gateway.md`** — the MCP Tool Gateway, the
headline experimental feature. Covers applications and connections,
catalog entries and risk levels, profiles/entries/bindings, the
tool-access policy and its decision outcomes, named MCP gateways and
their tokens, the audit feed, and the Smoke Lab. Documents the five
`tools:*` permission keys and the viewer/membership rules on routes that
don't use a permission key. Flags both experimental gates (`enableApps`,
and `enableSmokeLab` separately).

**`docs/reference/api/summary-slots.md`** — the built-in Summarizer and
summary slots. Covers slot addressing (`scopeKind` / `scopeId` /
`slotKey`), generation, revisions, and the `enableSummaries` gate.
Cross-references Built-in Agents rather than duplicating it.

## Updated

**`docs/guides/org/skills.md`** — Skill Studio (the three-pane authoring
workspace, saved inputs, test runs and their unavailability reasons, run
templates, version history), nested skill folders and the My Skills
view, importing skills straight from a project, and company skill forks.
Cross-references the existing Folders and Company Skill Policy API pages
instead of restating them.

## Release stamping

`paperclip_version: v2026.720.0` applied to all 26 pages touched this
cycle — bumped on 10 that already had frontmatter, added to 13 that had
none (including the API pages nightly authored, which were intentionally
versionless until they merged to `main`).

## ↻ Renames detected

`detect-renames.mjs` reports no directory renames. It flags one
`removed_dirs_no_match`:

- `packages/adapters/acpx-local` — **already reconciled on nightly.**
The adapter was retired upstream (ACP became a capability of each
harness adapter rather than a standalone adapter).
`docs/reference/adapters/acpx-local.md` is now a retired stub that
points at Claude Code / Codex / Gemini CLI and documents the automatic
migration. No action needed.

## Screenshots — full overhaul recommended

**248 of 298** registry entries are stale. This release landed a
design-system convergence (single-source design tokens, retuned theme,
broad Card/Badge adoption, a multiplicative radius ladder, unified list
surfaces, Lucide task-status glyphs), so nearly every captured surface
moved. This is an overhaul cycle, not a targeted refresh:

```sh
npm run screenshots:refresh:all
```

Full per-entry breakdown in `SCREENSHOTS_PENDING.md`. Captures go to
their own PR for review — nothing is auto-pushed.

## Verification

- **Drift:** clean — 0 records against `903bd15` (8 parent paths, 57 CLI
commands, 66 env vars, 389 REST routes, 18 permission keys, 4 roles).
- **Claim verification:** `verify-edit.mjs` against `v2026.720.0` — **0
unverified, 0 suspicious** across all three authored files.
- **Reconciliation:** no disappeared manifest entries.
- **`npm run docs:build`:** passes — 169 markdown files, sitemap and
robots generated.
- **`npm run sync:check`:** links clean (172 files), nav clean,
screenshots indexed, drift clean.
- **Nav orphans:** `docs/reference/cli/commands.md` and
`docs/reference/cli/control-plane-commands.md` — intentional redirect
anchors, expected.

`.sync-state.json` bumped to `base_release_tag: v2026.720.0` /
`base_release_sha: 903bd157…`, which also repoints the drift checker's
pinned ref (the previous `f12bb27…` no longer resolves upstream).

No open `nightly-draft/*` PRs to fold in.

## Checklist

- [ ] Tool Gateway page reads correctly for an operator enabling
`enableApps` for the first time
- [ ] Summary Slots experimental gating is accurate
- [ ] Skill Studio guide matches what you see in the running UI
- [ ] Decide whether to run the screenshot overhaul before or after
merging this
- [ ] **After squash-merging: run `node scripts/sync/realign-nightly.mjs
release/v2026.720.0 --push` before the next nightly sync.** The squash
severs `main`↔`nightly` ancestry; the realign (shipped in this PR)
prevents add/add conflicts at the next nightly run.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: DevRel Gemini <[email protected]>
Co-authored-by: Paperclip <[email protected]>
2026-07-20 19:59:18 +02:00
Aron PrinsandClaude Opus 4.8 55de2cbb81 fix(sync): pin drift check to an immutable SHA, key cache by SHA (#62)
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]>
2026-07-15 13:36:41 +02:00
Aron Prins 7e25158fca Release docs for paperclip v2026.707.0 (#49)
Promotes v2026.707.0 docs from nightly: Custom sandbox images + Ramp skill (new), Work Timeline (#48) and Secret scopes (#47) content, screenshot capture targets, environments nav reconcile, sync-state bump to v2026.707.0, and accuracy fixes from adversarial verification. 0 drift.
2026-07-08 11:11:32 +02:00
Aron PrinsandClaude Opus 4.8 1bba6f6601 docs(access): document members, roles, permissions, invites & offboarding (#38)
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]>
2026-07-01 18:11:25 +02:00
Aron PrinsandClaude Sonnet 4.6 e46c6631e0 fix(sync): teach verify-edit to resolve hermes-local/hermes-gateway → packages/adapters/hermes
The hermes adapter package was consolidated under packages/adapters/hermes/
in v2026.626.0, but the doc files keep the hermes-local.md and
hermes-gateway.md names. verify-edit.mjs derives the source path from the
doc basename, so it was searching packages/adapters/hermes-local and
packages/adapters/hermes-gateway (non-existent) and flagging all claims as
unverified — false positives.

Fix: add an adapter_doc_sources map to anchor-map.json that overrides the
source-path lookup for these two docs, and update fetchAdapterFiles() to
read and apply that map before falling back to the default
packages/adapters/${adapter} pattern.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-27 10:01:22 +02:00
DottaandPaperclip 5b4b489154 [codex] Add Skills docs hierarchy (#34)
## Summary

- Add generated reference pages for bundled and optional skills.
- Add Skills index pages and hierarchy-aware sidebar/breadcrumb
navigation.
- Add verification scripts for hierarchical Skills routes and static
docs routes.

## Verification

- `npm run sync:verify-nav`
- `npm run docs:test:static-routes`
- `npm run docs:build`
- QA in PAP-11775 also verified browser rendering for hierarchy, bundled
`task-planning`, and optional `last30days` pages with screenshots.

## Issues

- PAP-11770
- PAP-11783

---------

Co-authored-by: Paperclip <[email protected]>
2026-06-24 08:32:10 -05:00
Aron PrinsandClaude Opus 4.8 4ed3a26ff8 sync: bring verify-edit in line + scan adapter package sources
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]>
2026-06-19 09:48:43 +02:00
Aron PrinsandClaude Opus 4.8 c8e3aaf1f1 sync: widen drift checker env-var scan to all of server/src
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]>
2026-06-19 09:39:24 +02:00
Aron PrinsandClaude Opus 4.8 1a28b59fbf anchor-map: add skills-catalog watcher
Closes the gap this run surfaced: packages/skills-catalog/** was unwatched, so
new bundled catalog skills (e.g. the wireframe product skill) weren't auto-detected.

Watches catalog/**/SKILL.md + generated/catalog.json, routes to docs/reference/skills.md
and docs/guides/org/skills.md (PR tier), distinct from the agent-skills watcher which
covers the server-forced bundled skills under skills/**.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-03 10:42:23 +02:00
Aron Prins 17e046db5f Harden screenshot runner environment 2026-05-30 17:52:14 +02:00
Aron PrinsandClaude Opus 4.8 e4be96d643 Add screenshot-coverage gate to sync:check
New scripts/sync/verify-screenshots.mjs asserts that every screenshot
referenced in a guide page is (a) a CAPTURE_TARGET in routes.mjs and (b)
indexed in registry.json with a non-empty depends_on. It exits non-zero
otherwise, so a doc image added without a capture target fails loudly instead
of silently going stale. Wired into `npm run sync:check`, which the /sync-docs
skill runs every sync.

Currently: 112 referenced screenshots, all tracked and indexed.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-05-30 14:42:14 +02:00
Aron Prins 52542db923 Fix sync verification edge cases 2026-05-13 21:46:12 +02:00
Aron PrinsandClaude Opus 4.7 f68cbbd29a Wire detect-renames, frontmatter, and verify-edit into SKILL
Closes the design loop for the three helpers shipped in the
preceding commits and addresses the batched-exhaustiveness gap.

SKILL.md (+43 net):

- Phase 3: new substep runs detect-renames.mjs and routes detected
  renames to the EXISTING doc page with change_kind: renamed (not a
  new page). removed_dirs_no_match surfaces as a Reconcile-style
  flag. added_dirs_genuinely_new flow through unchanged.
- Phase 5: new bold paragraph stating --batched mode is exhaustive
  per window — no subsampling. Wet-run subsampling was scope-control
  for testing, not skill design. Also: paperclip_version frontmatter
  is now live (builder strips and surfaces it); added a new final
  voice-rule bullet requiring concrete identifiers (flags, env vars,
  routes, field names) be copied verbatim from parent code.
- New Phase 5.5: run verify-edit.mjs on every touched file. Auto-merge
  edits roll back on any high-confidence unverified claim. PR-tier
  edits get a Verification Failed callout; batched-release PRs never
  auto-merge when any verification fails. Suspicious claims log but
  never block.
- Phase 7 PR body template: three structured sections — Drift,
  Verification Failures, Renames detected. Each omitted if empty,
  never silently dropped.
- Helper-script index added near top.

anchor-map.json:

- adapters watcher detect rewritten to reference detect-renames.mjs
  as the canonical rename check (no more inline heuristic prose).
- agent-skills, plugin-sdk, server-adapters: parenthetical pointers
  added to detect-renames where renames apply.
- Other watchers unchanged (rename signal doesn't cleanly apply).

Follow-ups flagged but not done in this commit:
- Special-cases "Renames on parent" still describes the manual
  fix-anchor-map workflow; would benefit from a one-line distinction
  between watcher-path renames (manual) vs single-dir renames within
  a watcher (automatic).
- file-path drift kind and verify-edit's file-path kind overlap —
  worth deduping a future pass so one missing file doesn't appear
  under both Drift and Verification Failures.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 13:57:26 +02:00
Aron PrinsandClaude Opus 4.7 c071db51e4 Add post-edit code verification helper
Drift detection catches the coarse case (doc references X, parent
doesn't have X). Verification is finer-grained: doc claims specific
properties (flag names, env vars, route paths, schema field names,
config values) and we check each individual claim against parent
code, post-edit.

scripts/sync/verify-edit.mjs (1266 lines):
- Takes a doc file + parent ref. Extracts claims by kind:
  cli-command, cli-flag, env-var, rest-route,
  adapter-config-field, adapter-config-value, file-path.
- Uses structural cues (Config sections, code fences, tables) to
  avoid extracting from natural prose — guard against
  false-positives on phrasing like "use the `model` field".
- Per-claim verification:
  - cli-* → grep parent cli/src/** for command/flag literals
  - env-var → check .env.example, server/src/config.ts, packages/**/env.ts
  - rest-route → grep matching routes/<surface>.ts with {id}↔:id normalization
  - adapter-* → grep packages/adapters/<name>/** for literal field/value
  - file-path → gh contents API existence check
- Three output buckets: verified, unverified (with Levenshtein-≤3
  fuzzy "did you mean" suggestion), suspicious.
- Cached gh fetches under /tmp/paperclip-sync/verify-<ref-sha>/.
- Same fixture-loader pattern as compare-window/check-drift.

Tests: 6 new (CLI pass/fail, adapter field typo with suggest,
REST route normalization, env var pass, prose-guard
false-positive). 26/26 total passing.

Live test against test/sync-docs-catchup-run:cursor-cloud.md →
20/20 claims verified. The catchup agent's worry that adapter docs
might invent field names didn't materialize on cursor-cloud (every
config field is present in packages/adapters/cursor-cloud/**) — but
the tool would have caught it. acpx-local hasn't been verified yet;
worth running before the next merge decision.

Wired as sync:verify-edit. SKILL.md update to follow.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 13:54:46 +02:00
Aron PrinsandClaude Opus 4.7 16b910db88 Add directory-rename detection helper
GitHub's compare API marks individual file renames via status='renamed'
when git's similarity heuristic catches them, but DIRECTORY renames
(common case: packages/adapters/foo-local → foo-cloud) appear as a
bunch of add/remove pairs. Without aggregation, the adapters watcher
would treat the addition as a genuinely-new adapter and create a
duplicate doc page.

scripts/sync/detect-renames.mjs (252 lines):
- Input: a compare-window.mjs JSON file (or stdin).
- Detects directory renames under hard-coded watched prefixes:
  packages/adapters/, packages/plugins/sandbox-providers/,
  server/src/adapters/, skills/.
- Aggregates added/removed files into depth-2 dirs, requires ALL
  files in a candidate dir to share the add/remove status (mixed
  with 'modified' = the dir is alive, not a rename).
- Three matching signals, ranked by reliability:
  - file-content-overlap (≥50% suffix-path intersection) → high
  - shared-prefix (≥3 chars; ≥50% of longer leaf → high)
  - levenshtein (≤30% of shorter leaf) → medium
- Greedy 1:1 assignment when multiple pairs compete.
- Reports: renames, added_dirs_genuinely_new, removed_dirs_no_match.

Wired as sync:detect-renames in package.json.

Tests: 5 new (pure rename, shared-prefix, genuine new dir, genuine
removal, multi-candidate tiebreak). 20/20 total passing.

Live run on v2026.318.0...v2026.512.0: 0 renames detected
(correct — no dirs got renamed in that window; cursor-cloud is a
genuinely new sibling of cursor-local, not a rename). 7 dirs flagged
as genuinely new and verified.

A follow-up commit will wire this into the SKILL Phase 3 manifest
build so the adapter watcher consults it before creating doc pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 13:46:52 +02:00
Aron PrinsandClaude Opus 4.7 1922822817 Add YAML frontmatter support to the docs build pipeline
The SKILL says to add `paperclip_version: <tag>` frontmatter in
release mode but `site/build-release.mjs` didn't strip YAML —
`---` blocks would render as horizontal rules in the SPA. The
catchup wet run correctly refused to add the frontmatter for
this reason.

Now the build pipeline is frontmatter-aware:

- site/build-release.mjs: exported parseFrontmatter() (~30 line
  inline regex parser, no deps), copyMarkdownIntoRelease() that
  strips YAML on copy, frontmatter attached to each page in
  releaseNav before writing content.json. Guarded main() so test.mjs
  can import the module without triggering a build.
- site/app.js: stripFrontmatter() safety net in renderMarkdown plus
  a small "Documenting Paperclip <version>" footer block inside
  appendPageFeedback() that renders when page.frontmatter
  .paperclip_version is present.
- scripts/sync/test.mjs: 3 new cases (well-formed, none,
  malformed). 15/15 passing.

Parser intentionally minimal — scalar key:value lines only.
Swap in js-yaml later if frontmatter usage outgrows that.

Manual test: temporarily added frontmatter to claude-local.md,
built, confirmed YAML stripped from rendered body and version
recorded in content.json. Edit reverted.

A follow-up SKILL.md update will switch the release-mode voice
rule from "skip the frontmatter" to "add paperclip_version".

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 13:41:57 +02:00
Aron PrinsandClaude Opus 4.7 ca78d442f6 Fix anchor-map glob bugs: adapters/sandbox-providers + agent-skills
Two same-class glob bugs caught by the latest dry-run validation:

1. adapters watcher: parent_paths used `packages/adapters/*` and
   `packages/plugins/sandbox-providers/*` — single-segment globs.
   Real adapter files live deeper (packages/adapters/<name>/src/...).
   Result: 123 adapter files in the 318→512 diff window, ZERO
   watcher hits. The cursor-cloud doc only got written in the prior
   wet run because reviewers eyeballed it. Fix: `**` recursive globs.

   Hit count: 0 → 181.

2. agent-skills watcher: parent_paths used `skills/paperclip/**`,
   expecting a literal `paperclip/` segment. Real skill bundles are
   named `skills/paperclip-create-agent/`, `skills/diagnose-why-...`,
   etc. The `skills/**/SKILL.md` fallback caught 11 files but missed
   reference/script/fixture files in bundles.

   Hit count: 11 → 19 (the 19 is all skills/ files in this window).

Detect rules updated to match the broader globs.

A similar trap exists in the schemas glob (`packages/**/schema/*.ts`
misses nested schema dirs). Deferred — current hit count (37) is
healthy for the typical flat-schema case.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 12:06:48 +02:00
Aron PrinsandClaude Opus 4.7 72f56f64ad Add drift detection — catches docs referencing removed parent surfaces
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]>
2026-05-13 11:55:47 +02:00
Aron PrinsandClaude Opus 4.7 0dded0ef75 Implement cumulative-diff bisection as a helper script
The wet-run hit the GitHub compare API's 300-file/250-commit cap on
the first call against the 318→512 window. The SKILL had the
algorithm in prose — that's load-bearing now, so it gets a real
implementation.

scripts/sync/compare-window.mjs (392 lines):
- Recursive midpoint SHA bisection. Truncation detected by
  files.length===300 OR total_commits>commits.length.
- SHA enumeration via compare's .commits[].sha (up to 250); falls
  back to paginated /commits for windows exceeding that.
- Leaf responses cached under /tmp/paperclip-sync/<a..b>.json so
  re-runs within a day are cheap.
- Status-merge rules when unioning: added+removed → drop;
  added+modified → modified; modified+removed → removed;
  renamed wins over modified.
- CLI: node scripts/sync/compare-window.mjs <A> <B> [--json] [--repo]
- Fixture-driven testability via PAPERCLIP_SYNC_FIXTURE_DIR env var
  so unit tests stay hermetic without HTTP mocks.

Test coverage (3 new unit + 1 live integration in test.mjs):
- No-truncation case (1 leaf, no recursion).
- Single split (2 leaves, status-merge verified).
- Status merge cancellation (added+removed → drop).
- Live: real 318→512 window returns 1,726 unique files across 22
  leaves with truncated_leaves=0 and the three sentinel files
  present.

SKILL.md Phase 2: replace the algorithm prose with a one-line
helper invocation. Status-merge rules stay in SKILL as contract.

8/8 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 11:40:41 +02:00
Aron PrinsandClaude Opus 4.7 b477fa79c9 Split plugin-sdk watcher into plugin-sdk + agent-skills
The wet-run found the plugin-sdk watcher's docs_paths
(docs/reference/skills.md, docs/how-to/write-a-company-skill.md)
target agent skill bundles, not the plugin SDK. Separate concerns.

- plugin-sdk now targets docs/reference/plugins/sdk.md (to be created
  by the skill on first hit) and docs/administration/plugins.md.
- New agent-skills watcher targets the skills/ surface in parent and
  routes to docs/reference/skills.md + docs/how-to/write-a-company-skill.md.

Watcher count: 11 → 12.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 11:40:41 +02:00
Aron PrinsandClaude Opus 4.7 5647ca941f Apply Tier 3 dry-run fixes: parent default branch, dead globs, bisection, watchers
A design-validation dry-run against the real 318→512 release gap
surfaced seven issues that would break or misbehave at runtime.
All addressed:

1. Parent default branch is `master`, not `main` (verified via
   gh api ... -q .default_branch). Resolved dynamically at runtime:
   new Preconditions step 5 calls the API once and stores the result
   as <parent-default>; all subsequent references use that variable.
   Resilient to future parent renames.

2. Two dead globs in anchor-map.json:
   - env-vars: `server/src/env.ts` → replaced with `server/src/config.ts`
   - schemas: dropped `server/src/db/schema/**` (dir doesn't exist;
     coverage already provided by `packages/**/schema/*.ts`).

3. Truncation fallback was insufficient. The 318→512 gap had 5 of 6
   tag-to-tag windows still hitting the 300-file cap. Rewrote Phase 2
   to use recursive midpoint bisection by commit SHA: detect via
   files.length==300 OR total_commits>commits.length, split at median
   SHA, recurse until every leaf is within caps. Also corrected the
   commits cap (250, not ~300) and added explicit status-merge rules
   for unioning leaf file lists (added+removed → drop, etc.).

4. Adapter watcher would over-trigger on renames within the *-local
   family. Extended detect rule to check for correlated add/remove
   of similarly-named dirs (rename heuristic) before assuming a new
   adapter — uses compare's status:'renamed' signal.

5. Four new watchers for previously unwatched busy surfaces:
   - web-ui (ui/src/**) — invalidates screenshots and end-user flows
   - server-services (server/src/services/**) — user-visible behaviour
   - server-adapters (server/src/adapters/**) — distinct from packages/
   - db-migrations (packages/db/migrations/**) — context-only

6. auto_merge_safety.max_lines_changed 20→50. The current gap shows
   real-world .env.example additions land in batches (a feature ships
   with 10–20 related env vars + comments) and were being needlessly
   demoted to PR tier.

7. New Preconditions step 6: preflight every concrete (non-glob)
   watcher path via gh api .../contents and warn on 404. Would have
   caught the server/src/env.ts dead glob immediately.

Watcher count: 7 → 11.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 10:50:08 +02:00
Aron PrinsandClaude Opus 4.7 e09564a34d Add sync:test — unit tests for helper scripts
Self-contained test runner (no framework). Creates tmpdir fixtures
per test and asserts script behaviour via subprocess invocation.

Covers:
- lint-links: positive + 9 skip-case patterns (external URLs, schemes,
  anchors, absolute SPA routes, template placeholders).
- verify-nav: dangling + orphan classification, screenshots-dir exclusion,
  --strict mode.
- backfill-screenshots: idempotency (preserves entries with non-empty
  depends_on, scaffolds the rest).

4/4 passing on the current source. No source-script bugs found.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 10:47:45 +02:00
Aron PrinsandClaude Opus 4.7 c29d44a92e Add sync helper scripts and address deferred gotchas
Closes the five deferred items from the prior gotcha audit:

A. Link checker — scripts/sync/lint-links.mjs walks docs/**/*.md and
   verifies every relative markdown/image link resolves to an existing
   file. Skips external URLs, absolute SPA routes (/...), URI schemes
   (mailto:, agent://, etc.), and template placeholders. Found 3 real
   pre-existing broken links to missing screenshots — not fixed in
   this commit, but the tool will now block any new ones.

B. Nav verification — scripts/sync/verify-nav.mjs cross-checks
   site/content.json against the docs filesystem. Dangling entries
   (in nav but missing on disk) are errors; orphans (on disk but not
   in nav) are warnings. Found 1 real orphan (require-board-approval-
   before-spend.md from c0ff148 — never registered in content.json)
   that the user should triage separately.

C. Screenshot registry backfill — scripts/sync/backfill-screenshots.mjs
   scaffolds entries for every PNG under docs/user-guides/screenshots/.
   Run once; registry.json now ships with 274 scaffolded entries
   (137 light + 137 dark). Each has placeholder `depends_on: []` and
   a `_todo` field; humans fill in parent-repo path anchors over time
   to activate staleness detection per-entry. Re-runs preserve any
   entry with non-empty depends_on.

D. content.json edit serialisation — SKILL Phase 5 now requires
   subagents to return a structured `nav_addition` object alongside
   page content rather than editing site/content.json directly. The
   orchestrator merges all nav_additions on the main thread after
   subagents finish. Prevents the parallel-write race where two
   subagents creating new pages clobber each other's nav entries.

E. gh compare truncation — SKILL Phase 2 now explicitly documents
   the GitHub compare endpoint's ~300-file/~300-commit cap and the
   window-splitting fallback (walk intermediate release tags for
   release mode; binary-split commit list for nightly mode).

Also wires the scripts into package.json (sync:lint-links,
sync:verify-nav, sync:check, sync:backfill-screenshots) and into
SKILL Phase 7 (sync:check runs before commit; dangling/broken-link
failures abort the run).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 10:37:42 +02:00
Aron PrinsandClaude Opus 4.7 28af20be39 Fix correctness gotchas in /sync-docs design
Several issues found while reviewing the skill — most stemming from
the incremental-diff model that the first cut used. The fix is a
shift to cumulative diffs (always from the last release tag) plus
explicit reconciliation handling.

Changes:

- Cumulative diff window for BOTH modes. Nightly was using
  yesterday's SHA as the diff base; now it uses base_release_tag
  like release mode does. This makes reverts auto-cancel in the
  manifest (they're net-zero across the cumulative window) instead
  of needing message-regex filtering.

- Remove skip_patterns from anchor-map.json. They were dangerous:
  filtering ^revert by message would HIDE the undo signal when a
  previously-processed commit got reverted. The proper filter is
  surface impact via watcher path globs + cumulative-diff cancellation.

- Add Phase 3.5 (Reconciliation) to the SKILL. Catches the remaining
  case: a doc edit was committed in a prior run for a feature that
  has since been reverted. The manifest_hash + last_applied_manifest_hash
  comparison surfaces "disappeared" entries as ⚠ Reconcile flags for
  manual review — the skill never auto-undoes prose edits.

- auto_merge_safety: add explicit forbid_kinds: [removed, renamed].
  A 1-line rename is still a breaking change and was previously
  guarded only by SKILL prose.

- Rename state fields for clarity. synced_to/synced_sha were
  ambiguous between branches. New schema: branch_mode,
  base_release_tag, base_release_sha, last_seen_parent_sha,
  last_applied_manifest_hash. base_release_tag is the diff base
  and only bumps on a successful release merge — the invariant
  that makes cumulative diffs stable.

- Release mode is now self-sufficient (doesn't require nightly
  drafts to exist). Fixes the chicken-and-egg for the first run
  catching up multiple releases.

- PENDING.md is regenerated each run, not appended, so it never
  carries stale entries from reverted commits.

- New special-cases entries for parent renames, nightly-with-open-PRs
  at release time, and quarantine race conditions.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 10:30:12 +02:00
Aron PrinsandClaude Opus 4.7 02dbbf83a7 Add sync engine config: anchor map, state file, screenshot registry
Scaffolds the data layer for the /sync-docs skill:

- scripts/sync/anchor-map.json — declares which parent-repo paths each
  watcher tracks, where they route in our docs, and whether changes
  are auto-merge (mechanical, schema-bound) or PR tier (judgment calls).
- scripts/sync/state.example.json — template for .sync-state.json.
- .sync-state.json — per-branch sync state, seeded for an initial
  release-mode run from v2026.318.0.
- docs/user-guides/screenshots/registry.json — screenshot dependency
  tracking so the skill can flag stale captures.

The skill itself follows in the next commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-13 10:18:48 +02:00