AGENTS.md
September 12, 2026 · View on GitHub
Standards for anyone — human or coding agent — working in this repository: the workspace map, the Definition of Done, and the conventions that keep changes consistent.
What this is (and isn't)
This is the repo-root contributor/agent standards doc — how to find your
way around the B4.run monorepo, what "done" means for a change, and the rules
that keep the codebase consistent. It's the canonical entrypoint; see
Cross-links for how it relates to CONTRIBUTING.md and
CONTRIBUTORS.md.
This is not the runtime workspace/AGENTS.md capability. B4.run ships a
built-in capability
(packages/core/src/capabilities/built-in/agents-md.ts) that auto-injects the
contents of an app's <appRoot>/workspace/AGENTS.md into that agent's
system prompt as its persistent "# Memory" — re-read every turn, updated by
the agent itself via writeFile. That's an end-user B4.run app feature,
documented at b4.run/docs/memory. The
name collision is real: this file (repo root, for contributors) and that file
(inside a generated app's workspace/, for the agent at runtime) share a
filename but nothing else. If you're looking for the runtime feature, this
isn't it.
Workspace map
Every packages/* directory is a pnpm workspace member (verify: pnpm -r list --depth -1). One-line purpose is each package's own README.md first line.
Core framework
| Package | Purpose |
|---|---|
@b4run/sdk | The author-facing TypeScript SDK — agent(), defineMiddleware(), allow()/reject(), and the type primitives the CLI consumes. |
@b4run/core | Filesystem-based route discovery, app config loading, state-field resolution, and typegen primitives that the B4.run CLI builds on. |
@b4run/cli | The b4 CLI — local HMR dev runtime, route execution, validation, typegen, and the build step that produces LangSmith deployment artifacts. |
@b4run/langgraph | LangGraph runtime adapters and route module contracts (graphAdapter, workflowAdapter, defineEntry) used by the CLI. |
@b4run/langchain | LangChain backend adapters — materializes chain routes and provider-aware agent routes (tool conversion, streaming, retry). |
Capabilities & integrations
| Package | Purpose |
|---|---|
@b4run/ag-ui | AG-UI protocol translation for B4.run's local runtime — maps runtime stream chunks to AG-UI events and back, so CopilotKit and other AG-UI clients can drive B4.run agents. |
@b4run/permissions | Permission and access-control primitives for B4.run agents — gating tool and resource access at runtime. |
@b4run/workspace | Filesystem-backed workspace utilities for B4.run agents — reading, writing, and managing files in an agent's working directory. |
@b4run/sandbox | Reference sandbox providers for B4.run workspace execution — a Docker-backed SandboxProvider that redirects the workspace filesystem and shell tools into a per-thread isolated environment. |
@b4run/vite-plugin | Vite plugin for B4.run's typegen pipeline (extracts tool types and generates route ambient declarations). |
Storage & memory
| Package | Purpose |
|---|---|
@b4run/memory | Deterministic long-term memory storage and recall for B4.run's typed memory.ts capability — the storage/ranking layer under @b4run/core. |
@b4run/memory-pgvector | Postgres + pgvector backend for B4.run's typed long-term memory store, for deployments where SQLite is too local (multiple instances, shared DB, HNSW retrieval at scale). |
@b4run/sqlite-storage | SQLite-backed storage adapter for B4.run — durable persistence for agent state and runtime data. |
@b4run/postgres-storage | Postgres backend for B4.run's durable runtime state — checkpointer, Agent Protocol threads store, and permissions store over one pg pool, for deployments where the .b4/ files are too local (multiple instances, shared DB, ephemeral filesystem). |
Testing & evals
| Package | Purpose |
|---|---|
@b4run/testing | Testing utilities for B4.run apps — helpers for exercising routes, tools, and agent behavior in unit and scenario tests. |
@b4run/evals | Evaluation harness for B4.run agents — running and scoring agent behavior against datasets and scenarios. |
Scaffolding & tooling
| Package | Purpose |
|---|---|
create-b4-app | Scaffold a new B4.run app — generates a working application from the supported starter templates with B4.run's canonical layout wired for local development. |
@b4run/devkit | Internal scaffold templates and dev-time tooling shared between @b4run/cli and create-b4-app. |
@b4run/config-typescript | Shared TypeScript compiler configurations (base, library, node, nextjs) for B4.run workspace packages. |
@b4run/config-biome | Shared Biome lint/format configuration used by B4.run workspace packages. |
Apps
| Package | Purpose |
|---|---|
@b4run/web (apps/web) | The documentation website (b4.run) and its content/nav. |
Examples (examples/*, pnpm workspace members; consume B4.run via workspace:* and are typechecked in CI)
| Package | Purpose |
|---|---|
@b4-example/chat-server / @b4-example/chat-web (examples/chat) | Foundational agent-harness primitives (filesystem + bash) end-to-end, plus planning, skills, subagents, workspace, and HITL permissions, with a disposable smoke-test web client. |
@b4-example/memory (examples/memory/server) | Long-term memory with a backend-switchable store — zero-setup SQLite by default, Postgres + pgvector via DATABASE_URL, hybrid keyword + vector recall via OPENAI_API_KEY. |
@b4-example/research-server / @b4-example/research-web (examples/research) | The flagship deep-research assistant example — routes, tools, subagents, memory, planning, offloading, HITL permissions, and an optional Docker sandbox. |
Note: examples/chat/package.json and examples/research/package.json are
orchestration-only (private: true, one level above server/web) and are
not themselves pnpm workspace members — the actual members are the
server/web subdirectories, matched by the examples/*/* glob in
pnpm-workspace.yaml.
Charts (Helm charts under charts/, not pnpm workspace members)
| Chart | Purpose |
|---|---|
charts/b4-app | Runs a built B4.run app image on Kubernetes as a Deployment + Service, with optional Ingress, HorizontalPodAutoscaler, and PodDisruptionBudget, with an application-owned ServiceAccount in the chart release namespace. Sandbox access is bound cross-namespace to the b4-sandbox-infra orchestrator Role. |
charts/b4-sandbox-infra | Cluster-side infrastructure for the B4.run kubernetesSandbox provider — namespace, least-privilege RBAC, default-deny egress, quotas/limits, Pod Security Standards, and a PVC reaper. |
test/ and scripts/ are repo-level (verification lanes and workspace
scripts respectively) — not workspace packages.
Definition of Done
The required validate job in .github/workflows/ci.yml aggregates four
independent lanes for code and release-bearing changes and succeeds only when all
four succeed. Failure, cancellation, or an unexpected skipped lane blocks it.
A pull request changing only regular, non-executable Markdown files under
docs/superpowers/runbooks/ uses the narrow prose path. The existing scope job
checks the exact merge-base diff, both sides of file modes, and whitespace before
emitting that result. validate still runs and requires successful classification
and all four heavy lanes to be deliberately skipped. Mixed changes, other paths,
missing or malformed results, and failed classification cannot pass this route.
All pushes to main retain full validation; generated-metadata scope remains a
separate exception for its existing infrastructure jobs.
The source-validate lane runs these gates in order after installation:
pnpm test:release-integrity— early content pins and recovery-policy checkspnpm lintpnpm check:build-cachepnpm buildpnpm typecheckpnpm testpnpm check:release-inventorynode scripts/check-docs.mjs
The release-controller lane installs dependencies, runs the early integrity
checks, and runs the complete pnpm test:release-controller suite from an unbuilt
checkout. The pack-smoke lane runs pnpm pack:check and
pnpm verify:typescript-tooling-pack. The harness-verify lane runs
pnpm verify:harness:self-test and the framework, runtime, and smoke harnesses.
These gates remain part of repository validation.
On pull requests, a separate changesets job also runs
node scripts/check-changesets.mjs to require a changeset for user-facing
package changes.
Run pnpm ci:validate locally to run the validation commands sequentially.
The script in the root package.json runs release-integrity → lint → build-cache →
build → typecheck → source-test → release-inventory → release-controller-test →
docs-check → pack-check → TypeScript-tooling-pack → harness sequence, plus
the local-only test:sync-chart-appversion release-script unit test, which is
not a separate CI step. The former publish, upload, and backfill unit-test
commands were removed with their legacy release owners; their replacement
coverage is part of test:release-controller.
Gated lanes — these run as separate CI jobs behind env flags or dedicated
infrastructure, not part of validate, and aren't required for most PRs:
sandbox-docker (B4_TEST_DOCKER=1), pgvector-docker
(B4_TEST_PGVECTOR=1), postgres-storage-docker (B4_TEST_PGSTORAGE=1,
Testcontainers postgres:16), sandbox-k8s (B4_TEST_K8S=1, kind + Calico),
sandbox-k8s-e2e / sandbox-docker-e2e (B4_TEST_SMOKE_E2E=1, full-arc
deployed-app smoke), chart-validate (Helm lint + kubeconform), and
chart-apply-smoke (kind install smoke).
Release-bearing changes must also leave the separate copilotkit-examples-e2e
and real vercel-native production-boundary jobs green. The CopilotKit examples
exercise the v2 integration surface, and the Vercel job creates, verifies, and
removes real preview resources through the pinned Vercel CLI; neither lane is a
substitute for the other or optional release cleanup.
Conventions
- Changesets are a fixed group, patch on 0.x. All publishable packages
release together (
.changeset/config.json'sfixedgroup). On a 0.x train aminorbump takes every package to1.0.0— usepatchunless you intend a real 1.0 release. exactOptionalPropertyTypes: true. Never assign{ x: undefined }to an optional field; use a conditional spread (...(x !== undefined ? { x } : {})) instead, or the type checker will reject it.- Never run bare
biome check --write. It mass-reformats the whole workspace. Usepnpm lint(orpnpm lint:fixto auto-fix), or scope Biome to the files you changed. - Import specifiers:
src/uses.js,test/uses.ts. This is NodeNext ESM — source files import siblingsrc/*.tsmodules with a.jsextension; test files import with.ts. Follow the existing pattern in the package you're editing. - Examples/docs/scaffolds use gpt-5-family models only (canonical default
gpt-5-mini; nogpt-4o, though it stays in the provider registry, validation tests, and recorded fixtures). This is a project convention, not currently enforced byscripts/check-docs.mjs— check it by eye when touching examples. - Branch per PR; pin before dispatching parallel/subagent work. In a multi-worktree setup, a subagent's commits can land on a detached HEAD tracking the wrong branch if the feature branch isn't checked out first.
- Limit simultaneous full CI submissions. Prepare independent changes locally in parallel, but normally keep at most two maintainer-managed PRs with full CI active at once, accounting for validation already running on main. Wait for active runs before pushing a follow-up head. Do not cancel release runs or add a repository-wide serialization gate; this is submission guidance. During performance work, submit one performance PR at a time so its impact is clear.
- Build before running anything against
dist/. Packages compilesrc/*.tsto a gitignoreddist/, and consumers import the built output — a stale or skeweddist/(from a branch switch or a per-package filtered build) produces false negatives in ad-hoc scripts. Runpnpm buildfirst; seeCONTRIBUTING.md's "Build before running anything againstdist/". - Banned doc phrases.
scripts/check-docs.mjsgrepsREADME.md,CONTRIBUTING.md,CONTRIBUTORS.md,SECURITY.md,CODE_OF_CONDUCT.md,apps/web/app,apps/web/content,docs/(excludingdocs/superpowers/), andpackages/for stale or overstated wording — e.g. the retiredb4.rundomain, provider-prefixed model ids (openai:gpt...), the oldagent.bindTools/.b4/generated/auto-bound/auto-registeredphrasing, and claims like "byte-identical" or "speaks the LangSmith protocol natively" that overstate local/prod parity. This file (AGENTS.md) isn't in that scanned set, but keep it honest anyway — see theforbiddenContentlist inscripts/check-docs.mjsfor the exact patterns. - Always run commands from the repo root. Turbo and workspace-package resolution assume it.
- Every final-workflow-reachable release script is content-pinned. The
audited SHA256 and exact command line for each repository script reachable
from the final release-owner workflows are recorded in
scripts/release/test/fixtures/release-script-hashes.json. Editing a reachable script, adding an unpinned entrypoint, or retaining a stale pin failspnpm test:release-controlleruntil the reviewed fixture is regenerated in the same commit. The pin file also has a reviewed digest snapshot inscripts/release/test/workflow-contracts.test.mjs; intentional pin changes must update that snapshot too. Run that focused test file alongsidepnpm test:release-integritybefore the full controller suite to catch mismatched snapshots early. Reachability is re-derived from workflowrun:steps, package-script expansion, and actionwith:inputs, and then closed transitively over each entrypoint's repository-local module loads — staticimport/export ... from, dynamicimport()with a literal specifier, and thenew URL("./sibling.mjs", import.meta.url)form the release CLI hands to its injected loader. A load whose specifier cannot be resolved statically fails the check rather than being skipped; the reviewed exceptions live inREVIEWED_DYNAMIC_IMPORT_SEAMS. Files a pinned module reads off disk instead of importing are declared inRELEASE_DATA_FILESand anchored to a reader. This is deliberately limited to release ownership; ordinary CI-only scripts are not pinned. SeeCONTRIBUTORS.md's "Release Integrity Coverage" for the boundary.
Where things live
- Docs site content:
apps/web/content/docs/*.mdx(nav registered inapps/web/app/components/docs/nav.ts). - Specs, plans, audits, runbooks:
docs/superpowers/. - CI:
.github/workflows/ci.yml. - Changeset config (fixed group, patch-on-0.x):
.changeset/config.json.
Cross-links
CONTRIBUTING.md— the public PR path: setup, issues, PRs, CLA/DCO, code of conduct.CONTRIBUTORS.md— internal monorepo guide: local setup, the--mode internalscaffold path, and verification lanes. Its per-package responsibilities point back at the workspace map above.README.md— project overview and quickstart.