Merge pull request '[E01-S01-T02] ADR: Node/TypeScript' (#407) from feature/189 into main
CI / Stage 6 — PostgreSQL integration tests (E00-S05-T01) (push) Successful in 1m8s
CI / Stage 4 — Unit tests (E00-S05-T01) (push) Successful in 1m35s
CI / Stage 7 — Build the admin and server applications (E00-S05-T01) (push) Successful in 1m12s
CI / Stage 5 — Architecture tests (E00-S05-T01) (push) Successful in 3m10s
CI / Stage 2 — Typecheck (E00-S05-T01) (push) Successful in 1m22s
CI / Stage 3 — Formatting/lint policy (E00-S05-T01) (push) Successful in 47s
CI / Stage 1 — Frozen lockfile install (E00-S05-T01) (push) Successful in 45s
CI / Stage 6 — PostgreSQL integration tests (E00-S05-T01) (push) Successful in 1m8s
CI / Stage 4 — Unit tests (E00-S05-T01) (push) Successful in 1m35s
CI / Stage 7 — Build the admin and server applications (E00-S05-T01) (push) Successful in 1m12s
CI / Stage 5 — Architecture tests (E00-S05-T01) (push) Successful in 3m10s
CI / Stage 2 — Typecheck (E00-S05-T01) (push) Successful in 1m22s
CI / Stage 3 — Formatting/lint policy (E00-S05-T01) (push) Successful in 47s
CI / Stage 1 — Frozen lockfile install (E00-S05-T01) (push) Successful in 45s
This commit was merged in pull request #407.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# ADR-002: Node.js 24 LTS runtime
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-08-31
|
||||
- Deciders: platform stream
|
||||
- References: ADR index (section 70), Technology stack wiki (sections 5.2, 6, 7, 8), ADR-001
|
||||
|
||||
## Context
|
||||
|
||||
EPPP is a greenfield personal blogging platform (ADR-001) whose runtime is a
|
||||
single modular-monolith application plus an optional worker, deployed as one
|
||||
or more containers of one image. The whole platform — public server, admin
|
||||
API, rendering pipeline, extension runtime, core services and background
|
||||
jobs — executes on one runtime, so the runtime choice is a platform-wide,
|
||||
hard-to-reverse decision with security, tooling and operational reach.
|
||||
|
||||
The workspace is a pnpm monorepo (pnpm 11.23.0) whose root manifest already
|
||||
declares `engines.node: ">=24.0.0 <25.0.0"` with `engineStrict: true`, and
|
||||
the CI pipeline installs and runs on Node 24 (E00-S01-T08). The technology
|
||||
stack wiki classifies Node.js as support class A — a fixed upstream EOL date
|
||||
— and pins the golden compatibility tuple to Node 24.19.0 LTS (Krypton), with
|
||||
`node:24.19.0-bookworm-slim` as the application container base image.
|
||||
|
||||
## Decision
|
||||
|
||||
EPPP runs on the **Node.js 24 LTS** runtime line, exact-pinned to Node 24.19.0
|
||||
LTS (Krypton) in the golden compatibility tuple and the container image. The
|
||||
workspace root manifest restricts the engine to 24.x
|
||||
(`engines.node: ">=24.0.0 <25.0.0"`), pnpm enforces it at install time
|
||||
(`engineStrict: true`), and CI installs and runs on Node 24. The runtime is a
|
||||
class A dependency: its upstream EOL (2028-04-30) drives the upgrade
|
||||
schedule, and a move to a later major line (for example Node 26) is only
|
||||
evaluated once that line is LTS and the compatibility suite passes, and then
|
||||
only as a deliberate, ADR-recorded change. The decision text — **Node.js 24
|
||||
LTS runtime** — matches the ADR index entry (ADR-002, section 70).
|
||||
|
||||
## Alternatives
|
||||
|
||||
- **Node 22 LTS (Jod)** — rejected: it is the previous LTS line and reaches
|
||||
EOL before Node 24 (2027-04-30), shortening the runway for a platform whose
|
||||
v1.1 boundary contracts (ADR-027 to ADR-032) extend past that date.
|
||||
- **Node 26 (current, non-LTS at decision time)** — rejected: not LTS when
|
||||
the decision was made; running a non-LTS line contradicts the class A
|
||||
support posture (fixed EOL, security patching on an LTS cadence).
|
||||
- **Node 24 with no exact pin (floating latest 24.x)** — rejected: a floating
|
||||
minor would break the reproducibility of the golden compatibility tuple and
|
||||
the container image; the line is pinned and minors move deliberately.
|
||||
- **Node 24 LTS, exact-pinned 24.19.0** — chosen: an LTS major with a fixed
|
||||
EOL, exact-pinned in the image and tuple, engine-restricted in the
|
||||
manifest, and enforced in CI.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Positive: an LTS line with a fixed upstream EOL (2028-04-30) gives a
|
||||
predictable security-patching and upgrade horizon; the exact pin makes
|
||||
builds and containers reproducible; the engine restriction rejects
|
||||
unsupported Node versions at install time instead of failing at runtime.
|
||||
- Negative: Node 24 API and behaviour become the platform floor — anything
|
||||
needing a newer Node feature waits for the deliberate, ADR-recorded major
|
||||
upgrade; minor upgrades inside 24.x still need the weekly dependency sweep
|
||||
and full CI.
|
||||
- Neutral: the runtime is shared by every module, so a future extraction
|
||||
(ADR-001) keeps running on the same Node line until that module's runtime
|
||||
needs diverge.
|
||||
|
||||
## Operational impact
|
||||
|
||||
- Application and worker containers run `node:24.19.0-bookworm-slim`; release
|
||||
automation records the immutable image digest in the SBOM/release manifest.
|
||||
- The supported runtime is enforced at install (`engineStrict: true` fails
|
||||
installs on unsupported Node) and at test time (the node-engine suite
|
||||
asserts the current runtime satisfies the 24.x range).
|
||||
- CI installs and runs every stage on Node 24, so the committed pipeline is
|
||||
the operational proof that the platform runs on the chosen line.
|
||||
- Node 24 is patched on the LTS cadence; security-emergency updates go
|
||||
through the focused lane (immediate, full CI), and the EOL date is the
|
||||
deadline for the next major-line ADR.
|
||||
|
||||
## Revisit trigger
|
||||
|
||||
- Revisit when Node 26 becomes LTS and passes the compatibility suite, per
|
||||
the LTS strategy — the decision to move majors is a new ADR, not a patch.
|
||||
- Revisit on a security-emergency or patch-lane event that forces a minor
|
||||
upgrade outside the weekly sweep, or if upstream announces a change to the
|
||||
Node 24 support horizon.
|
||||
- Revisit if a module's runtime needs (ADR-001 extraction) diverge from the
|
||||
shared Node line and a second runtime enters the platform.
|
||||
@@ -0,0 +1,86 @@
|
||||
# ADR-003: TypeScript 6.0.3 language decision
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-08-31
|
||||
- Deciders: platform stream
|
||||
- References: ADR index (section 70), Technology stack wiki (sections 5.2, 6, 7, 8), ADR-001
|
||||
|
||||
## Context
|
||||
|
||||
EPPP is a modular monolith (ADR-001) written in TypeScript across every
|
||||
module boundary: `apps/`, `packages/` and `extensions/` are all compiled from
|
||||
strict TypeScript against a shared base tsconfig (E00-S01-T10). The language
|
||||
version is therefore a platform-wide decision: it fixes the type-system
|
||||
features, the compiler behaviour and the toolchain (editor, build, CI
|
||||
typecheck) every module sees.
|
||||
|
||||
The workspace already pins TypeScript exactly: the root manifest declares
|
||||
`devDependencies.typescript: "6.0.3"` (a bare MAJOR.MINOR.PATCH, no semver
|
||||
range), the committed lockfile resolves exactly one `typescript@6.0.3`, and
|
||||
every workspace package resolves `Version 6.0.3` (E00-S01-T09). The
|
||||
technology stack wiki classifies TypeScript as support class C — rolling,
|
||||
exact-pinned, tested and upgraded deliberately — and pins 6.0.3 in the golden
|
||||
compatibility tuple. TypeScript 7.0 reached GA in 2026-07 without a stable
|
||||
programmatic API before 7.1, making 6.0 the bridge release.
|
||||
|
||||
## Decision
|
||||
|
||||
EPPP uses **TypeScript 6.0.3** as its language and compiler, exact-pinned in
|
||||
the root manifest and the lockfile so every workspace package and every CI
|
||||
typecheck runs the identical compiler. 6.0.3 is the baseline; a formal review
|
||||
happens after TS 7.1 is stable (per the technology stack LTS strategy), and
|
||||
any move to the 7.x line is a deliberate, ADR-recorded change. The decision
|
||||
text — **TypeScript 6.0.3 pending TS7.1 ecosystem review** — matches the ADR
|
||||
index entry (ADR-003, section 70).
|
||||
|
||||
## Alternatives
|
||||
|
||||
- **TypeScript 7.0 at GA (2026-07)** — rejected: it shipped without a stable
|
||||
programmatic API before 7.1, which would put the compiler toolchain on an
|
||||
unstable surface; 6.0 is the documented bridge.
|
||||
- **TypeScript 6.x floating (caret/range)** — rejected: a range could resolve
|
||||
to a different compiler than the one the golden tuple was tested with; the
|
||||
exact pin is what makes typecheck deterministic across modules and CI.
|
||||
- **TypeScript 5.x (previous major)** — rejected: it predates the 6.0 type
|
||||
system and ecosystem position the platform was bootstrapped on; staying on
|
||||
an older major only delays the bridge.
|
||||
- **TypeScript 6.0.3 exact-pinned** — chosen: the bridge release, exact-pinned
|
||||
and CI-verified, with a formal re-review once TS 7.1 stabilises the
|
||||
programmatic API.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Positive: one exact compiler version across apps, packages and extensions
|
||||
makes typecheck results reproducible locally and in CI; the 6.0 bridge is a
|
||||
known-good stepping stone to the 7.x line; strict mode across the workspace
|
||||
stays uniform.
|
||||
- Negative: the language feature set is fixed at 6.0.3 until the reviewed
|
||||
upgrade; any tooling that needs the 7.x programmatic API waits for the TS
|
||||
7.1 formal review.
|
||||
- Neutral: upgrades inside the pinned major remain controlled by the
|
||||
dependency sweep; the language choice is invisible to the deployed runtime
|
||||
(TypeScript compiles away) but is enforced at build and typecheck time.
|
||||
|
||||
## Operational impact
|
||||
|
||||
- `pnpm install --frozen-lockfile` resolves exactly `typescript@6.0.3`; the
|
||||
lockfile contains one resolved TypeScript entry, so no package can drift
|
||||
onto another version.
|
||||
- Every workspace `build`/`typecheck` script invokes the pinned compiler
|
||||
(`pnpm exec tsc`), and the typescript-pin suite asserts each package
|
||||
resolves `Version 6.0.3`.
|
||||
- CI stage 2 (typecheck) runs `pnpm typecheck` across the workspace, so the
|
||||
language pin is continuously verified on every pull request.
|
||||
- A TypeScript upgrade is a class C lane change: patch/minor through the
|
||||
sweep with full CI; the 7.x major is a programme item with its own ADR.
|
||||
|
||||
## Revisit trigger
|
||||
|
||||
- Revisit after TypeScript 7.1 is stable: the formal review (per the LTS
|
||||
strategy) decides whether the platform moves to the 7.x line, recorded as a
|
||||
new ADR.
|
||||
- Revisit if a workspace package needs a type-system feature or toolchain
|
||||
capability that 6.0.3 cannot provide, or if the ecosystem (editors, tools,
|
||||
type packages) leaves the 6.0 bridge unsupported.
|
||||
- Revisit if a module boundary contract (ADR-027 to ADR-032) becomes
|
||||
unrepresentable in the pinned type system.
|
||||
Reference in New Issue
Block a user