Files
hq/02-DECISIONS/0014-no-npm-workspace.md
T
jschoubben 333356cff3 Order the records the way the system is learned
Jochen asked whether the order made sense. It did not -- it followed when
things happened to be decided, which after consolidation is fictional anyway
since record 5 alone folds decisions taken across a week.

Concretely wrong before: the domain statement sat at 8, after five engineering
rules; the constitution was scattered across 5, 12 and 17; the tiers landed at
15, 16, 21 and 22 with process records in between.

Now it walks: what the mesh is (1-3), its tiers from the bottom up (4-8), what
runs on them and how it gets there (9-10), how it is built (11-16), how it is
checked (17-18), how we work (19-23).

Two things made this safe rather than free. It is a permutation, not a
compaction, so the renames go through temporary names -- otherwise two files
want one slot and one is lost. And the reference rewrite is a single
simultaneous pass, because almost every number moved into a slot another number
was vacating; replacing one at a time would have cascaded and pointed things at
the wrong record while still resolving.

Verified: 284 [ADR NNNN](path) links across the repository, all with matching
text and target.

The ordering principle is now stated in 19 rather than left implicit -- the
repository already said "the numbering is the flow" about its folders, and
there was no reason for the records to be the exception.
2026-08-28 23:30:42 +02:00

66 lines
3.1 KiB
Markdown

---
status: accepted
date: 2026-06-04
deciders: jochen
reconstructed: true
---
# 14. No workspace — each module is a standalone package consuming published dependencies
> Reconstructed after the fact from the evidence cited below.
## Context
Modules depend on each other, above all on the shared library every module builds against.
A workspace was the obvious way to express that: sibling packages, resolved locally, one
install at the root.
It produced a divergence that is worth stating precisely, because it is not obvious. In
development, a workspace member importing a sibling resolves to that sibling's **local source**.
In the pipeline, each module is built alone, from a clone, without its siblings present — so
the same import resolves to the **published version**. The two environments were therefore
building different code from identical source, and the failure appeared only in the pipeline,
in a module that had not been touched.
## Considered options
1. **Keep the workspace and make the pipeline replicate it** — clone every module, build the
graph. Rejected: it makes every build a whole-repository build, which is the cost the
per-module pipeline exists to avoid, and it does not extend to modules in their own
repositories.
2. **Keep the workspace and pin siblings to published versions.** Rejected as the worst of
both: the workspace's local resolution silently overrides the pin, so the divergence
remains while looking solved.
3. **No workspace. Every module is standalone and consumes published dependencies.** Chosen.
## Decision
There is no workspace. Each module is an independent package that declares its dependencies
and consumes them from the private registry, including the mesh's own shared library.
A cross-package change is therefore two steps: publish the producer, then consume it. The
pipeline does the first on push and resolves the levels so that a module always builds against
its dependencies' freshly published versions.
## Consequences
- Development and the pipeline resolve imports identically. The divergence is gone by
construction rather than by discipline.
- A module in its own repository is not a special case. It builds exactly as a module in the
monorepo does — which is what makes [ADR 0015](0015-applications-live-in-their-own-repository.md)
cheap.
- A cross-package change costs a publish-and-consume round trip. This is the real price, paid
on every shared-library change.
- There is no repository-wide install and no repository-wide build. Anything that assumed one
broke, and one thing that assumed one has stayed broken: the end-to-end pipeline harness has
not built since this decision landed. See
[`04-ISSUES/005`](../04-ISSUES/005-pipeline-test-harness-unbuildable/00-report.md).
## References
- `fix(noxflow): kill npm workspace, restore encryption inside PgAdminRepo` (#240),
2026-06-04. The reason is recorded in the root package manifest, which still carries the
note explaining why no workspace exists.
- The divergence it fixed is named there: workspace members importing each other resolved to
local unbuilt source in the pipeline.