From 1fba3d9f957c8b4c76111ab0f1a96740d2d090ba Mon Sep 17 00:00:00 2001 From: implementer Date: Mon, 31 Aug 2026 00:26:34 +0000 Subject: [PATCH 1/2] docs(adr): record Node.js 24 LTS runtime decision as ADR-002 --- docs/adr/ADR-002-node-24-lts-runtime.md | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/adr/ADR-002-node-24-lts-runtime.md diff --git a/docs/adr/ADR-002-node-24-lts-runtime.md b/docs/adr/ADR-002-node-24-lts-runtime.md new file mode 100644 index 0000000..082237e --- /dev/null +++ b/docs/adr/ADR-002-node-24-lts-runtime.md @@ -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. -- 2.54.0 From ee0c09439811f40607e72d1e281d6137918c64ab Mon Sep 17 00:00:00 2001 From: implementer Date: Mon, 31 Aug 2026 00:26:35 +0000 Subject: [PATCH 2/2] docs(adr): record TypeScript 6.0.3 language decision as ADR-003 --- docs/adr/ADR-003-typescript-6-0-3.md | 86 ++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/adr/ADR-003-typescript-6-0-3.md diff --git a/docs/adr/ADR-003-typescript-6-0-3.md b/docs/adr/ADR-003-typescript-6-0-3.md new file mode 100644 index 0000000..6c53000 --- /dev/null +++ b/docs/adr/ADR-003-typescript-6-0-3.md @@ -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. -- 2.54.0