When you need this
Skip this page entirely if your repo isn’t a workspace of multiple packages — leavepackages: []
and everything works exactly as described elsewhere in these docs.
Read on if the repo shipflow runs in (or any repo listed under repos: in polyrepo) is itself an
npm/pnpm/yarn workspace, an Nx or Turborepo monorepo, a Lerna repo, a Go multi-module repo, or a
.NET solution with several projects — one work item can need changes in more than one package.
The core idea
Packages never get their own branch or PR. Onlyrepos causes that fan-out. packages only
changes three things: feature-context/feature-plan ground and assign tasks per package,
feature-tests runs each touched package’s own test command, and feature-verify grades AC
evidence per package — all within the one diff and one PR the repo already has.
Configuring packages
In shipflow.config.md:
name (used in grounding, plan, and verify output — not branches, since there
are none per package), a path relative to the repo root, and an optional tests override for
when packages use different frameworks or need a workspace-scoped command
(pnpm --filter <name> test, nx test <name>, turbo run test --filter=<name>).
Worked example
SayAB#1234 is “show the user’s subscription tier in account settings,” in a pnpm-workspace
monorepo with packages/web and packages/api.
1
Context
feature-context normalizes two ACs (AC1: API returns tier, AC2: settings page displays it)
and, since packages is non-empty, takes a first pass at which packages are likely touched —
api for AC1, web for AC2. A first read, not a commitment, exactly like polyrepo’s repo
grounding but for packages within the one repo.2
Plan
feature-plan commits to the touched set and tags every task with its package:Unlike polyrepo’s repo table, there’s no “gets a PR” column — packages never get one.
3
Implement
One branch,
feature/1234-subscription-tier, for the whole repo. Tasks tagged api are
made in packages/api; tasks tagged web in packages/web — same branch throughout.4
Tests
Runs per touched package:
pnpm --filter api test for the API change, pnpm --filter web test for the UI change — both on the same branch, reported separately.5
Verify
Aggregates per package within the one diff: AC1 is MET only if
packages/api’s code +
test satisfy it; AC2 only if packages/web’s do. If api’s change lands but web’s doesn’t,
the item is NOT READY — same aggregation rule as polyrepo, just without a second branch.6
PR
Opens exactly one PR for the repo. Its AC checklist may note
AC1 — packages/api, AC2 — packages/web for the reviewer’s benefit, but there is only ever one PR regardless of how many
packages were touched.What changes vs. a single package
Combining with polyrepo
If a polyreporepos[] entry is itself a monorepo, set packages on that entry instead of at the
top level:
platform still gets exactly one branch and one PR (per the polyrepo rule); its two packages are
graded separately within that one PR (per the monorepo rule). The two mechanisms compose without
special-casing — repo-level fan-out and package-level grounding are independent.