pb-build-pack · git:20260901.0259d5f · 2026-09-01 · sha256 e0adbe03dbc38239
pb-build-pack git:20260901.0259d5fA
Immutable. This exact content never changes and is served at /api/v1/blob/e0adbe03dbc38239.
---
name: pb-build-pack
description: Author an agent pack (company/agency/knowledge) and import it into a guild via the registry, BYO repo, or MCP surface. Trigger for pack work - 'author a company pack', 'import a pack', 'pack init', 'ship capabilities as a pack'.
---
# pb-build-pack — author and import an agent PACK
## Goal
Package capabilities as an agent pack (one folder, one root marker), validate
it, then import it through the right surface — registry, BYO repo, or MCP
tools — and confirm with a re-sync.
Prerequisites (reference by name): `ap-tasks` if you track the work on the
board; the pack machinery itself lives in this repo, not the daemon.
## Steps
### 1. Read the committed SOP first
Read `projects/guilde/docs/PACK-SOP.md` before anything else. It is the
authoritative authoring SOP — folder layout, marker semantics, what each
doctype handler consumes. This playbook sequences the work; the SOP defines
the artifacts.
### 2. Scaffold with the authoring CLI
```
pnpm --filter @guilde/api run pack init <kind> <slug>
```
`kind` is one of `company` | `agency` | `knowledge` — the ROOT MARKER file
decides the doctype: `COMPANY.md`, `AGENCY.md`, or `KNOWLEDGE.md`. Never use
bare `pnpm pack` — that is a reserved pnpm builtin, not this CLI.
### 3. Validate BEFORE importing
```
pack validate <dir>
```
Scaffolds pass `validate` out of the box; fill in your content and re-run
until it passes. Validation is the gate between authoring and import.
### 4. Import through the right surface
- House/external registry: add the source to `PACK_REGISTRY`
(`apps/api/src/config/pack-registry.ts`) keyed by `kind` — external repos
of any kind register like the house companies.
- BYO repo onto an EXISTING guild: `connect_pack_repo` (vaults the PAT;
repo becomes a resolvable source for that guild).
- New guild from a repo: `apply_company_from_repo({repo, kind, ...})`.
- New guild from a registry source: `apply_company({sourceId, entryId})`.
- Existing guild, one operator or corpus: `install_operator` /
`apply_corpus`.
Underneath, every import path is ONE ingress primitive:
```
applyPackageToScope({ scopeId, userId, pkg, includeHandlers?, installMode? })
```
`installMode`: `append` (default, multi-instance) | `skip-existing` |
`upsert-by-slug` (re-sync). `includeHandlers` filters which doctype handlers
materialize. All three call-sites (guild-create, corpus-apply,
operator-install) route through it.
### 5. Verify with a re-sync
```
resync_pack({ guildId: '<guildId>' })
```
`resyncGuildPackage` re-fetches the source, sha-diffs against the stored
`guild.sourcePackage`, and upserts only on change (no migration; reuses
jsonb). An import that cannot survive a resync was not really installed.
## Gotchas
- Validate BEFORE importing: a bad marker file means a silent doctype
mismatch — the pack lands as the wrong kind and downstream handlers skip
it without an error you would notice.
- Re-running install upserts by slug — it does not duplicate. But
`includeHandlers` decides what materializes: a handler you filter out is
simply not imported, so check the filter matches what you expect to see.
- PATs for BYO repos are vaulted, not stored in plaintext; re-resolve
through the guild's `packSources`, never paste tokens into pack files.
- The canonical import types live in `@agstudio/agent-package-import`
(`materializeAgentPackage`, `computePackageSha`); doctype handlers in
`@guilde/core/domain/import/handlers.ts` are first-match-wins by path —
ordering matters when one path could match two handlers.
## Verify
`pack validate <dir>` passes, the MCP surface reports the pack landed
(`apply_company` response or the guild listing shows the expected
operators/corpora), and `resync_pack` reports no unexpected changes (sha
matches, upsert no-op or intended-only delta). A pack whose resync finds a
mismatch has drifted — re-import with `upsert-by-slug`.