packages/builtin-skills/src/acceptance/references/project-adapter.md
.agents/acceptance/)This skill is project-agnostic. Everything specific to the project under test — how
to start and stop it, which ports and services it needs, how auth works, which
surfaces it has, and how to jump straight into app state — lives in a per-project
adapter at .agents/acceptance/PROJECT.md. The skill reads it; it never guesses the
project's commands.
A repository that verifies itself often has more than commands to share: an
approval gate before touching the environment, a teardown discipline, a publish
target, a report directory convention. Those live beside the adapter in
.agents/acceptance/PROCESS.md. When that file exists it owns the run process,
and this skill supplies the acceptance contract — plan, evidence, report,
round. Read both before executing; where they disagree about how to run, the
project layer wins, and where they disagree about what a valid round is, this
skill wins.
<repo>/.agents/acceptance/ # committed — the adapter and project logs are team assets
├── PROJECT.md # the adapter: commands, ports, services, auth, surfaces
├── PROCESS.md # optional: the project's run process (gate, teardown, publish)
├── common-mistakes.md # PROJECT-layer living log (writable)
├── probe-mock-patterns.md # PROJECT-layer living log (writable)
├── references/ # optional: project-owned how-tos
└── scripts/ # optional: project env / probe / capture scripts
.agents/acceptance/ is committed (the adapter and the project living logs are
shared, versioned team assets). The report output directory .records/ is
gitignored — reports are per-run artifacts, published to LobeHub Acceptance,
not committed.
PROJECT.md always has these six sections, in this order. Sections the skill refers
to by number (PROJECT.md §2, §3, …), so keep the numbering.
goto <route>
quick-navigation, plus the routes worth jumping to. These are the project's
equivalent of a state-introspection helper; the skill uses them instead of
hand-rolling store-eval snippets.PROJECT.md may reference project scripts under .agents/acceptance/scripts/ or
anywhere in the repo.
# PROJECT.md — acceptance adapter for <project name>
## 1. Project summary
<One paragraph: what the product is. Then the repo layout that matters for testing —
which directory/package is the server, the web app, the desktop shell, the CLI.>
## 2. Environment
- **Start dev server:** `<command>` (base URL: `<url>`, port: `<port>`)
- **Stop dev server:** `<command>` (must stop only what this run started)
- **Required services:** <db / cache / queue / object store — with the start command
for each, or "none">
- **Already-running detection:** `<health-check command>` — how to tell the server is
up before starting another one.
- **Env / port resolution:** `<command or file>` — the source of truth for ports and
URLs. Do NOT hard-code a port table; read it here.
## 3. Auth
- **Test account(s):** <how to obtain — seeded, fixture, or a real login>
- **Seeding command:** `<command>` (or "n/a")
- **Per-surface status check:**
- CLI: `<command>` — signed-in when <...>
- Web: `<command>` — signed-in when <...>
- Electron: `<command>` — signed-in when <...>
## 4. Surfaces
<For each surface that applies. Delete the ones that don't.>
### CLI
- Invocation: `<how the CLI is run — from source or built binary>`
- Auth: <see §3 CLI>
- Standalone install: `<command>` or "covered by root install"
### Web
- Launch: `<dev server command>` (from §2)
- Base URL: `<url>`
- agent-browser session: `<session name>`
### Electron
- Launch: `<start command>` — CDP port `<port>`
- Stop: `<command>`
- Login persistence: <how login survives across runs>
## 5. Project probes & quick navigation
- Auth probe: `<command>` → `{ isSignedIn, userId }`
- Route probe: `<command>` → current route
- Operations probe: `<command>` → running operations
- Quick navigation: `<command> goto <route>`
- Routes worth jumping to: <list>
## 6. Known constraints
- <e.g. "agent runs require the queue service (§2) up, or the run dies before any
real work">
- <e.g. "the desktop and CLI packages are standalone — install inside each">
- <e.g. "OS-capture surfaces are macOS-only">
When .agents/acceptance/PROJECT.md is absent, build it before doing anything else:
package.json scripts, README, CI workflows (.github/workflows/**),
Makefile / Justfile, docker-compose*.yml / compose.yaml, .env.example,
and any existing test/dev docs. Note the dev-server command, the services it
needs, the ports, the auth story, and which surfaces exist.PROJECT.md from the fixed skeleton above, filling every section from
what you found. Where a value is uncertain, mark it explicitly as a guess rather
than inventing a command..agents/acceptance/PROJECT.md. Create
.agents/acceptance/ if it does not exist.lh acceptance install only places the skill files; it does no repo exploration.
The adapter draft needs a model, so the first verification run is what bootstraps
PROJECT.md.
Treat the adapter like a living log: when observed reality diverges from it during a
run (a port moved, a start command changed, a service is now required), fix
PROJECT.md in place during the run rather than working around it silently. The
next run should not rediscover the same divergence.
The skill's references/common-mistakes.md and references/probe-mock-patterns.md
are the generic layer — product-independent, and read-only in a consumer repo:
the installed copy is materialized from the skill source, so an edit there is lost
on the next update. Change it by PR to the skill source. The project's own
.agents/acceptance/common-mistakes.md and .agents/acceptance/probe-mock-patterns.md are
the project layer — writable, and the only place a run records project-specific
learnings. At runtime the agent reads both layers and writes only the project layer.
When a project-layer entry turns out to be product-independent, genericize it (drop
every project-specific noun) and PR it to the generic layer upstream.
Confidentiality runs one way. Anything naming a project's packages, routes, schemas, env vars, service names, or business logic stays in the project layer; only a rule that reads correctly with every project noun removed may be promoted.