ADR 0011: Dependency Governance & Release Pipeline
Date: 2026-07-29 Status: Implemented
Context
After the monorepo merge and Phase 1-3 refactors, the project had excellent dependency consistency (265 catalog entries, all package.json using catalog: or workspace:*), but lacked mechanical enforcement, version management tooling, and a unified release strategy.
Three interdependent decisions needed to be made:
- Whether to enforce catalog-only dependencies mechanically
- How to handle version identity across apps and packages
- What release tooling to adopt
Decision 1: Enable catalogMode: strict
Chosen: catalogMode: strict in pnpm-workspace.yaml.
Rationale:
- pnpm 10.12+ native enforcement is stronger than ESLint rules (runs at install time)
- Zero breakage — all existing deps already use
catalog:protocol - One-line change with no maintenance burden
- Prevents future version drift from
pnpm addwithout--save-catalog
Alternatives considered:
- ESLint
pnpm/json-enforce-catalog— belt-and-suspenders, but redundant with pnpm's native check - No enforcement — relying on convention alone; rejected because convention degrades over time
Decision 2: Hybrid Versioning — Unified Packages, Independent Apps
Chosen: 5 shared packages use a fixed group for synchronized versioning; 3 apps use independent versioning.
Rationale:
- Packages are tightly coupled —
@walnut/contractchanges cascade to all consumers,@walnut/utilsis consumed by both frontend and backend. A type change incontractis breaking to all package consumers, so synchronized bumping reflects reality. - Apps have independent release cycles —
apps/docscontent update does not affectapps/server;apps/adminUI change does not affectapps/docs. Independent versioning avoids spurious version bumps. private: trueremoval signals the code is publicly visible (not secret/internal). Does NOT imply intent to publish to npm.- Unified
0.0.1as a clean starting point after the repo merge (previous versions were 0.0.1, 0.0.0, 1.0.0, 1.18.0 — inconsistent artifacts of separate repos).
Alternatives considered:
- All 8 packages in Fixed Group — rejected; apps with independent release cycles get spurious version bumps (e.g., docs change triggers server version bump)
- Full Independent for all — rejected; 5 packages are tightly coupled and benefit from synchronized versioning
- Keep apps at 1.18.0 and packages at 0.0.1 — rejected; split versioning is confusing when all packages move together
Decision 3: changesets + git-cliff Pipeline
Chosen: changesets for version bumping and fixed group synchronization; git-cliff for CHANGELOG generation from conventional commits.
Rationale:
- changesets excels at multi-package version management (
fixedgroups,changeset version) - git-cliff excels at changelog rendering from git history (already in catalog at version 2.13.1)
- Separation of concerns: version management ≠ changelog formatting
auto-changeset.tsbridges conventional commits →.changeset/*.mdfiles, preserving the existing commit workflowrelease.tsorchestrates the full pipeline: generate → confirm → version → changelog → tag → push.changeset/config.jsonsets"changelog": falseto disable changesets' built-in changelog
Tool responsibilities:
| Tool | Role |
|---|---|
auto-changeset.ts | Generate .changeset/*.md from conventional commits since last tag |
changeset version | Bump versions in all package.json (sync via fixed group), consume changeset files |
git-cliff | Render CHANGELOG.md from git history with conventional commit grouping |
release.ts | Orchestrate: auto-generate → interactive bump confirm → version → changelog → tag → push |
Key configuration:
cliff.toml: conventional commit parsing with emoji-categorized groups, GitHub commit links.changeset/config.json:fixedgroup covering 5 shared packages (utils,contract,client,axios,eslint-config), apps are independent,changelog: false,access: public
Consequences
pnpm addwithout--save-catalogwill now fail — developers must usepnpm add <pkg> --save-catalogpnpm release(onmainbranch only) executes the full release pipelinepnpm changeset:autogenerates changeset files from commits (for review before release)pnpm changeloggenerates CHANGELOG.md via git-cliff- 5 shared packages are mechanically kept in sync via the
fixedgroup; 3 apps version independently — no manual version editing needed
Related
- Supersedes the versioning aspect of ADR 0008 (unified versioning confirmed, deploy separation unchanged)
- Enables ADR 0009 quality gates (changesets provide the version management foundation for CI test requirements)
- References:
docs/architecture/04-toolchain.md,scripts/version/release-workflow.md