docs+skill: fold live-e2e findings into onboarding docs; add onboarding-e2e skill

From the first agent-conversation e2e against a live hub:
- install.md: git handoff for tracked knowledge folders (one transport per
  folder), .bdrive//.bdriveignore git guidance, Hermes per-user hook warning,
  drop stale share--list aside
- SKILL.md: .bdriveignore is local-only on --shared mounts (root file sits
  outside the include list) — doc now matches behavior
- new project skill .claude/skills/onboarding-e2e: reusable procedure to
  re-run the conversation-level e2e (staging, instruction materialization,
  agent prompt contract, verification, pass bar)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VbiaaVM2ACxeRi8ySG9ybc
This commit is contained in:
Snow Lee
2026-07-18 21:25:35 -07:00
co-authored by Claude Fable 5
parent 66f7a98fcc
commit a6ee5aa75e
3 changed files with 98 additions and 4 deletions
+80
View File
@@ -0,0 +1,80 @@
---
name: onboarding-e2e
description: "Live end-to-end test of BearDrive's agent-first onboarding: spawn a fresh agent that role-plays a real user conversation ('keep our wiki synced…') against a running hub, following the plugin's SKILL/install instructions verbatim, and report the full transcript plus doc-vs-reality findings. Use when the plugin onboarding copy, the CLI init/login/hooks flow, or hub auth changed and you want proof the conversation still works. Args: [hub-url] [authenticated BDRIVE_HOME] [bdrive-binary]"
---
# Agent-onboarding live E2E
Tests the thing unit tests can't: that a *conversation* driven by the plugin
instructions actually onboards a user end to end against a real hub. The
deliverable is a transcript + findings, not a pass/fail bit — instruction
drift (docs promising what the binary doesn't do) is exactly what this
catches.
## Inputs (ask if not provided)
- `HUB` — a running hub URL (dev default: the local cloud hub).
- `HOME_AUTH` — a `BDRIVE_HOME` directory already signed in to that hub
(`bdrive login --status` must show an account). Browser signup can't run
headlessly; if none exists, create a synthetic user first (hub-dependent —
on a PropelAuth hub: Backend API `POST /api/backend/v1/user/` then a magic
link, or the device flow approved from an authenticated browser session).
- `BDRIVE` — path to the `bdrive` binary to test (build it from the tree
under test: `go build -o /tmp/bdrive-e2e ./cmd/bdrive`). Don't trust PATH.
## Procedure
1. **Stage a realistic repo** in a scratch dir (never inside the real repo):
```sh
A=<scratch>/agent-e2e && mkdir -p $A/repo/wiki $A/repo/src $A/plugin
# 3 markdown pages with [[wikilinks]] in wiki/, a token src/ file,
# git init + commit (the wiki MUST be git-tracked — the handoff step
# is part of the test).
```
2. **Materialize the instructions under test** — from the branch being
tested, not the working tree:
```sh
git show <branch>:plugin/commands/install.md > $A/plugin/install.md
git show <branch>:plugin/skills/beardrive/SKILL.md > $A/plugin/SKILL.md
```
3. **Spawn a fresh agent** (Task/Agent tool, general-purpose) with a prompt
that makes it role-play a real Claude Code session. The prompt must:
- confine all writes to the scratch dir;
- name the two instruction files as its ONLY operating manual and demand
it follow them faithfully, noting friction instead of papering over it;
- require `BDRIVE_HOME=$HOME_AUTH` on every bdrive call and forbid bare
`bdrive login` (no browser available);
- fix the project name (avoid collisions with earlier runs);
- open with the exact user message
`"keep our wiki synced with the team and give me a link to it"`;
- script the simulated user: consent to the sync + synced AGENTS.md, but
DECLINE one optional step (e.g. the root pointer) so the transcript
proves the consent gates are real;
- require every command's real output in the transcript — no fabrication;
- end with cleanup: `bdrive stop <repo>` so no daemon lingers;
- demand a two-part report: **TRANSCRIPT** (User/Claude turns with real
command output) and **TEST FINDINGS** (numbered: worked-as-written /
doc-vs-reality gaps with quoted instruction text / first-timer
confusion / whether the `bdrive url` payoff link served real content —
verify with an authenticated `curl` against the project API).
4. **Independently verify** the agent's headline claims before relaying:
the project exists on the hub (`/api/projects` with the token), the file
content round-trips, the daemon is stopped.
5. **Relay** the transcript verbatim and triage findings into: fix-now doc
patches, behavior bugs (file/branch them), and cosmetics.
## Pass bar
The conversation must reach the payoff (a working hub link) with no step
where the agent had to contradict the instructions silently. Any place the
agent adapted beyond the written instructions is a finding, even if the run
"worked".
## Known environment quirks
- `command -v bdrive` may find a Homebrew binary that's older than the tree
under test — always pass `BDRIVE` explicitly and watch for version skew.
- On hubs with PropelAuth + "must be in at least one org": brand-new users
are gated at PropelAuth's create-org screen unless the `user.created`
webhook can reach the hub — synthetic-user setup must account for it
(deliver the webhook by hand or pre-create the org).
+17 -3
View File
@@ -29,9 +29,9 @@ browser window is coming, then sign in:
If `$ARGUMENTS` gives a project name and/or `--shared <dir>`, use them.
Otherwise ask the user two questions (or infer from their request):
- **Create a new project or connect an existing one?** (`bdrive share --list`
isn't needed here — `bdrive init --name <name>` creates-or-joins by name;
`bdrive init --project <p-id>` connects by id.)
- **Create a new project or connect an existing one?** (`bdrive init
--name <name>` creates-or-joins by name; `bdrive init --project <p-id>`
connects by id.)
- **Sync the whole folder, or only a shared subfolder?** Hard rule:
**never sync a repo root** — inside a repo, knowledge always syncs as a
scoped subfolder via `--shared`. Whole-folder is only for a dedicated
@@ -41,6 +41,12 @@ Otherwise ask the user two questions (or infer from their request):
markdown-heavy, not source code) and propose the best candidate for
confirmation, e.g. "I found `./wiki` — sync that?".
**One transport per folder.** If the chosen folder is currently git-tracked,
BearDrive and git would both write it — the silent-revert hazard. Get consent,
then hand it off: `git rm -r --cached <dir>` and add `<dir>/` to `.gitignore`;
stage the change but let the user commit. (Full detection ladder — git,
Obsidian, symlinks — in the beardrive skill's "Connecting knowledge tooling".)
Then run it non-interactively, e.g.:
```sh
bdrive init --name <project-name> --yes # dedicated knowledge folder
@@ -49,6 +55,11 @@ bdrive init --name <project-name> --shared wiki # in a repo: only ./wiki sync
Re-running `bdrive init --yes` later is always safe: it resumes syncing
(including after the folder was renamed or moved).
After init, tell git what's what: add `.bdrive/` to `.gitignore` (per-machine
state, never committed) and COMMIT `.bdriveignore` (on a `--shared` mount the
root `.bdriveignore` is local-only to each clone, so git is how the team
shares it).
## 4. Teach agents about the shared folder (ask first — never do this silently)
Two files with different jobs (full rationale: the beardrive skill's
@@ -118,6 +129,9 @@ Tell the user which platforms got hooks (`bdrive hooks` shows the status
table). If Codex is among them, mention they must run `/hooks` inside
Codex once to trust the project's `.codex` layer. To register a platform
that wasn't detected: `bdrive hooks install --agent claude,codex,gemini,hermes`.
Heads-up before installing: Hermes hooks are PER-USER (`~/.hermes/config.yaml`,
outside the repo) — mention that when it's among the targets, and skip it
unless the user actually uses Hermes.
## 6. Verify and summarize
+1 -1
View File
@@ -37,7 +37,7 @@ Use this skill whenever the user is working with the `bdrive` CLI: initializing
Two files at the mount root control a folder's sync behavior:
- **`.bdrive/`** — the folder's settings **directory**; `config.json` inside holds the **stable mount id** (`m-xxxxxxxx`) plus `volume`, `remote`, optional `include`. Written by `bdrive init`; safe to hand-edit (a running daemon picks changes up on its next tick). It is **never synced**, holds **no credentials** (the token lives in `~/.bdrive/settings.json`), and because all state is keyed by the mount id — not the path — the folder can be **renamed or moved freely**; the daemon exits on a move and the next bdrive command at the new location resumes.
- **`.bdriveignore`** — opt-out list, gitignore-style. **Syncs like a normal file**, so all devices share the same rules. Syntax subset: `#` comments, `*` within a segment, `**` across segments, `?`, trailing `/` for directories-only, a `/` elsewhere anchors to the mount root, `!` re-includes.
- **`.bdriveignore`** — opt-out list, gitignore-style. On a whole-folder mount it **syncs like a normal file**, so all devices share the same rules; on a `--shared <dir>` mount the seeded root `.bdriveignore` sits OUTSIDE the include list and is **local-only** — commit it to git (or place ignore rules inside the shared dir) if the team should share it. Syntax subset: `#` comments, `*` within a segment, `**` across segments, `?`, trailing `/` for directories-only, a `/` elsewhere anchors to the mount root, `!` re-includes.
```jsonc
// .bdrive/config.json