Phase 0 · 0.A–0.C — monorepo scaffold + strict TS/lint/test spine#1
Conversation
…e lint/format/test spine (Phase 0 · 0.A–0.C)
The project's first code: the foundation Phase 1 builds on — types and tooling, not
features. `pnpm install && pnpm turbo run lint typecheck test build` is green and
`format:check` is clean from a fresh checkout.
0.A — Turborepo + pnpm workspace skeleton: private root package.json (pnpm@9.12.3
pinned via packageManager), .nvmrc, .npmrc (auto-install-peers), pnpm-workspace.yaml
(packages/* + apps/*), turbo.json (build/lint/typecheck/test + globalDependencies so a
root-config change busts caches). Directory skeleton from project-structure.md:
packages/{shared,llm,core,db,ui} + apps/{desktop,vscode-extension,cli}; only shared is
built out — the rest are README-only placeholders (no package.json) per the
no-over-scaffolding rule, so pnpm/Turborepo ignore them until their phase.
0.B — strict tsconfig.base.json: strict + noUncheckedIndexedAccess +
exactOptionalPropertyTypes + noImplicitOverride + verbatimModuleSyntax + isolatedModules
+ moduleResolution bundler. @relavium/shared extends it with a build/typecheck split
(tsconfig.build.json emits dist, excludes tests; tsconfig.json type-checks everything).
Strictness verified load-bearing (a removed flag yields TS18048).
0.C — root spine: ESLint flat config (typescript-eslint typed rules; no-explicit-any
and no-floating-promises as errors; the seam fence via built-in no-restricted-imports
is 0.F), Prettier (docs/ + markdown governed by documentation-style.md, not Prettier),
and a workspace-aware Vitest config with V8 coverage. Lint gate verified load-bearing
(an any and a floating promise both error).
@relavium/shared is a real, buildable package exporting SCHEMA_VERSION; the full Zod
schema set lands in 0.E. All added dependencies are devDependencies (the
tech-stack-pinned toolchain) — no runtime dependency added, so no ADR required.
Refs: docs/roadmap/phases/phase-0-foundations.md (0.A, 0.B, 0.C)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…slint TS-family scoping, lint ^build, format:check task, coverage)
Acts on a three-pass review of the scaffold after adversarially re-verifying every
finding against the real toolchain (one report was stale; one "HIGH" was a false
positive — corrected below). All fixes proven green: lint/typecheck/test/build +
format:check + coverage, with live .tsx/.js ESLint probes.
- ESLint (the real bug): type-aware rules (recommendedTypeChecked) + projectService +
the no-explicit-any / no-floating-promises errors were scoped to `**/*.ts`, so
.tsx/.mts/.cts got type-aware rules with NO project and ESLint hard-crashed (exit 2)
the moment such a file was linted — packages/ui (.tsx) would have failed lint entirely
at 0.H. Now the typed config is scoped to `**/*.{ts,tsx,mts,cts}` with projectService;
`disableTypeChecked` covers `**/*.{js,jsx,mjs,cjs}` (no crash on JS); config files are
ignored at any depth via `**/*.config.*` (a bare `*.config.*` matched only the repo
root, so a nested per-package vitest/tsup config would crash type-aware lint). Proven:
a .tsx inside a tsconfig reports BOTH non-negotiable errors with no crash; a nested
config is ignored; a .js does not crash. (The review's "no-explicit-any silently
downgrades to warn on .tsx" was FALSE — recommendedTypeChecked already pins it to
error; the real failure mode was the crash.)
- turbo.json: `lint` now `dependsOn: ["^build"]` — type-aware lint resolves a
dependency's types via its built dist/*.d.ts, so without this the first cross-package
@relavium/* import at 0.D would lint against absent/stale types on a clean checkout.
Added .nvmrc + pnpm-workspace.yaml to globalDependencies. Added a `//#format:check`
root task so `pnpm turbo run format:check` resolves and caches (Prettier is repo-global
→ a root task, not per-workspace, is the correct design).
- tsconfig: noEmit:true in packages/shared/tsconfig.json + noEmit:false in
tsconfig.build.json (emit is a config property now, not reliant on the --noEmit flag);
build excludes *.spec.ts as well as *.test.ts. Vitest include pinned to `**/*.test.ts`
(Vitest's default also matches *.spec.ts, which the build did not exclude — a dist-leak
path).
- Added a root `coverage` script (`vitest run --coverage`) so 0.C's "branch coverage
reported" acceptance has an invokable command (was configured but never run).
- .npmrc: keep strict-peer-dependencies=false locally (Phase-1 surface packages pull
React/Tauri/provider-SDK peers not all present at once → a hard local `true` would
break fresh installs); peer drift is caught by a CI-only strict gate (0.G). Documented.
Refs: docs/roadmap/phases/phase-0-foundations.md (0.A, 0.B, 0.C)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reviewer's GuideSets up the initial monorepo/tooling spine (Turborepo + pnpm workspace) with strict shared TypeScript config, a root ESLint/Prettier/Vitest configuration, and a minimal but fully buildable @relavium/shared package, plus roadmap/docs updates to reflect Phase 0.A–0.C as landed and green. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR establishes the monorepo scaffolding: Node/pnpm and Prettier configs, pnpm workspace/catalog, strict TypeScript baseline, root package.json with Turbo scripts, ESLint flat config with TS overrides, Vitest workspace config with V8 coverage, and bootstraps ChangesMonorepo Scaffold and Shared Package
Sequence Diagram — Tooling flow: sequenceDiagram
participant RootPackage as package.json
participant Turbo as turbo.json
participant ESLint as eslint.config.mjs
participant Vitest as vitest.config.ts
RootPackage->>Turbo: run scripts (build/lint/test)
Turbo->>ESLint: execute lint task using eslint.config.mjs
Turbo->>Vitest: execute test task using vitest.config.ts (coverage)
ESLint->>ESLint: apply TypeScript-specific overrides for .ts/.tsx
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request scaffolds the Relavium monorepo using Turborepo and pnpm, establishing root configurations for ESLint, Prettier, TypeScript, and Vitest, alongside a buildable @relavium/shared package and placeholders for future packages and applications. Feedback on these changes highlights several key improvement opportunities: first, updating moduleResolution and module to NodeNext in the base TypeScript configuration to enforce explicit file extensions and prevent runtime ESM resolution crashes; second, explicitly declaring typescript and eslint in @relavium/shared's devDependencies to ensure robust script execution in a strict pnpm workspace; and third, scoping globals.node in the ESLint configuration more narrowly to prevent unsafe Node-specific globals from leaking into frontend packages.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| "module": "ESNext", | ||
| "moduleResolution": "bundler", |
There was a problem hiding this comment.
Using "moduleResolution": "bundler" allows extensionless relative imports (e.g., import { foo } from './utils') and directory index imports to compile without errors.
However, since @relavium/shared (and other packages like @relavium/core or apps/cli) are compiled directly with tsc to ESM and executed in Node.js (which strictly requires explicit file extensions for relative imports in ESM mode), any extensionless imports will compile successfully but crash at runtime with ERR_MODULE_NOT_FOUND.
To enforce strict ESM import path compliance at compile time and prevent runtime resolution crashes, consider using "moduleResolution": "NodeNext" and "module": "NodeNext" instead. If "bundler" is required for frontend/Tauri packages, consider overriding it in those specific packages' tsconfig.json files.
| "module": "ESNext", | |
| "moduleResolution": "bundler", | |
| "module": "NodeNext", | |
| "moduleResolution": "NodeNext", |
| "devDependencies": { | ||
| "vitest": "^3.0.0" | ||
| } |
There was a problem hiding this comment.
The package scripts invoke tsc and eslint directly, but these packages are not declared in devDependencies.
In a strict pnpm workspace, relying on root-hoisted binaries can be fragile and may fail if hoisting is restricted or if the package is built/linted in isolation. It is a best practice to explicitly declare typescript and eslint in the package's own devDependencies to ensure they are always available in the package's local .bin path.
"devDependencies": {
"eslint": "^9.17.0",
"typescript": "^5.7.2",
"vitest": "^3.0.0"
}| globals: { | ||
| ...globals.node, | ||
| }, |
There was a problem hiding this comment.
Applying globals.node globally to all files in the TS family (**/*.{ts,tsx,mts,cts}) is unsafe for frontend packages like packages/ui (React components) and apps/desktop (Tauri frontend). It allows Node-specific globals (like process or Buffer) to be used in browser/UI code without lint errors, which will cause runtime crashes in the browser.
Consider scoping Node.js globals to Node-specific packages/files, or adding globals.browser for .tsx files and frontend packages.
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
packages/shared/tsconfig.json,outDiris configured butnoEmit: trueprevents output; consider either removingoutDirfrom the typecheck config or splitting emit/no-emit concerns more clearly betweentsconfig.build.jsonandtsconfig.jsonto avoid confusion. - You currently declare
vitestboth at the repo root and inpackages/shared; if all packages will rely on the same runner version, consider centralizingvitestat the workspace root (or using a workspace protocol reference) to reduce version-drift risk.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `packages/shared/tsconfig.json`, `outDir` is configured but `noEmit: true` prevents output; consider either removing `outDir` from the typecheck config or splitting emit/no-emit concerns more clearly between `tsconfig.build.json` and `tsconfig.json` to avoid confusion.
- You currently declare `vitest` both at the repo root and in `packages/shared`; if all packages will rely on the same runner version, consider centralizing `vitest` at the workspace root (or using a workspace protocol reference) to reduce version-drift risk.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
…globals cleanup, tsconfig emit split, pnpm catalog Each finding was reproduced/refuted against the real toolchain before acting. - moduleResolution (real, the important one): the base used `bundler`, which lets an extensionless relative import (`import './x'`) typecheck clean — but `@relavium/shared` is compiled with `tsc` and consumed as real ESM, so that would crash with ERR_MODULE_NOT_FOUND in Node. Switched the base to `module`/`moduleResolution`: `NodeNext`, which rejects it at compile time (TS2835, "Did you mean './x.js'?"). Proven: an extensionless import now errors; the existing code (already using `./x.js`) builds clean. Vite-bundled surfaces (packages/ui, apps/desktop frontend, apps/portal) override back to `bundler` in their own tsconfig at 0.H+. - ESLint globals (partly real, wrong mechanism): the review feared blanket `globals.node` lets Node globals into browser code "without lint errors". But type-aware linting disables `no-undef` for TS (verified: resolves to [0]), so `globals.node` was inert and misleading; the real platform boundary is each package's tsconfig `types`/`lib` (`process` already errors TS2591 under shared's `types: []`). Removed the blanket `globals.node` (and the now-unused `globals` dep) and documented per-surface globals. - tsconfig emit/typecheck split (real, minor): moved `rootDir`/`outDir` to tsconfig.build.json so tsconfig.json is purely the typecheck config (`noEmit` only). - dep hygiene (real, minor): adopted a pnpm `catalog` as the single source of truth for dev-tool versions (no cross-package drift), and `@relavium/shared` now declares the tools its scripts invoke (typescript, eslint, vitest) so per-package isolation holds — verified `pnpm --filter @relavium/shared run typecheck/lint` work standalone. Gate green: lint/typecheck/test/build + format:check + coverage (100% branch). Refs: PR #1 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ings Phase 0 — Foundations is done: all workstreams 0.A–0.I merged (PR #1–#3), achieving milestone M0. Reflect that across the roadmap and entry docs: - phase-0-foundations.md: status -> Complete; 0.F–0.I marked done; the 0.M3/M0 milestone done; exit criterion #7 lists better-sqlite3 (ADR-0021). - current.md: Where-we-are / What-is-active / next-steps now point at Phase 1 (@relavium/llm seam + @relavium/core engine); M1 is the next checkpoint. - roadmap/README.md milestone spine: M0 done; root README + CLAUDE.md status updated. Adds docs/roadmap/deferred-tasks.md: every confirmed-but-deferred finding from the 97-agent comprehensive review, as discrete checkable tasks (decisions, schema/test depth, tooling, docs, packaging) so none get lost. None blocked M0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.U is the proof the engine works end-to-end before any surface exists. It composes the already-landed pieces behind the @relavium/llm seam (1.K FallbackChain, 1.N run loop + RunEventBus, 1.O AgentRunner, 1.P node handlers, 1.Q human gate, 1.R checkpoint/resume, 1.S node retry, 1.T ToolRegistry) on the in-memory ExecutionHost reference — zero platform imports, no live network/keys, deterministic. No engine code and no new ADR: the harness uses only already-exported @relavium/core symbols. A scenario suite (the seed the Phase-2 CLI regression harness 2.K grows from): - happy-path — the literal 3-node input -> agent(+tool call) -> output: live token streaming, per-attempt cost (attributed to the model), a gap-free sequenceNumber stream that validates against the canonical RunEventSchema. - flagship — input -> agent -> human_gate -> output: in ONE run across a process boundary, the agent's forced provider error -> node retry (ADR-0040) -> failover to the second chain entry (1.K), per-attempt cost attributed to the fallback model; then a pause at the gate (the durable mid-run checkpoint persisted to the SQLite-shaped store); then a FRESH engine resumes via resumeFromCheckpoint, runs output to run:completed, and reproduces the final output with sequenceNumber continuing gap-free. The agent is NOT re-run on resume (its output is restored). - determinism — a re-run yields an identical event signature + final output (the no-wall-clock/no-RNG ban the risk table binds to the harness). Design decision (maintainer-approved): the resume demonstration uses a human gate as the durable suspend point, because the Phase-1 engine resumes ONLY from a gate/budget pause — a gate-less interrupted run is reconciled to run:failed (ADR-0036; verified by the resume-model review + an adversarial refutation). The literal 3-node topology is preserved by the happy-path member; the flagship adds the gate. Recorded as the §1.U "Harness shape" clarification in the phase plan (no new ADR — composes decided mechanisms). Exit criterion #1 annotated to point resume at the gated flagship. Per-attempt cost is asserted as distinct cost:updated events (not only the terminal cumulative); all LLM cost is incurred pre-gate, so the plain-human-gate cost-restore deferral (deferred-tasks.md) is off this path. 1.U / M2 will be marked Done only after this PR merges (roadmap-done-after-merge). Full gate (format/lint/typecheck/test/build) green — core 683 tests; Leakwatch clean. Refs: §1.U, M2, ADR-0036, ADR-0040, ADR-0003 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…che) A multi-dimensional Sonnet review (7 dimensions, adversarial refute-by-default verify) surfaced 18 findings; 16 confirmed, 2 refuted. Fixed 15 (skipped 1 — see end). No product behavior changed: test strengthening, code/doc comments, a CI cache step. Test hardening (the meaningful ones): - checkpoint.test.ts: the new node:completed cost-restore test was tautological for the Math.max reconciliation (a bare assignment would pass). Added two interaction tests over BOTH durable cost sources — incl. one (budget:paused 900 → node:completed 800 → 900) that gives Math.max teeth (a bare-assign would yield 800 and fail it). Clarified that the pre-existing "cost tallies" test exercises the fold's cost:updated arm (a defensive branch; cost:updated is streamed, not persisted — the production path is node:completed). - m2-harness: tightened the under-constrained cost-count asserts to exact counts (happy-path === 2 tool+answer turns; flagship === 1 successful fallback — a double-charge or missing tool-turn cost would now fail); replaced the tautological node:retrying `.retryable === true` with the classified `.error.code === 'provider_unavailable'`; added a direct assertion that the checkpointed `work` node is NOT re-dispatched on resume; collapsed nodeOutput's double array scan to a single find. Docs / comments (accuracy): - checkpoint.ts: the budget:paused comment called cost-event persistence "the deferred general fix" — it landed; rewrote it + the CheckpointState JSDoc to describe both durable sources + the Math.max reconciliation. - phase-1: exit criterion #1 no longer self-contradicts ("3-node" now names only the happy-path member; resume rides the gated flagship); added 1.AB to the §1.U composing-list (the harness needs the ExpressionSandbox). Same 1.AB addition in the harness header. - CLAUDE.md: the status blurb was one giant **…** span with nested **…** that GFM can't render; scoped the bold to "Status:" so the inner emphases render. - spec.ts: documented the toolLoop test's scope (asserts the call→result→continuation FLOW; the provider tool_result WIRE shape is asserted by the per-adapter unit tests). - vitest.config.ts: corrected the stale "coverage not yet wired into CI / tracked in deferred-tasks" comments (it is now the advisory ci.yml job). CI: - The coverage job now restores the .turbo cache (like `ci`), so its build is a warm hit rather than a cold rebuild. Skipped: the nit that commit 15a5b0e used a bare `test:` type without a scope — it is already pushed; a history rewrite on a shared branch is unwarranted for a nit (future commits scope). Full gate (format/lint/typecheck/test/build) green; `pnpm coverage` EXIT 0 (floor holds); Leakwatch clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ects (review HIGH #1/#2) A multi-dimensional adversarial review of P1+P2 confirmed two HIGH defects on the production (store-injected) de-inline path that the prior reviews missed: - I3 BYTE LEAK (HIGH #1): deInlineMedia's rewrite only handled the canonical {type:'media'} part, so a non-canonical byte carrier in an opaque z.unknown() run-event position — a base64 data: URI string, a loose {kind:'base64'} source, a raw binary buffer — passed THROUGH and persisted/delivered (the with-store branch had no re-scan; the run-event positions have no byte backstop). Fix: deInlineMedia now HARD-FAILS on every non-canonical carrier (data: URI / loose base64 / raw buffer) and on an unknown source kind / unknown modality — it can only ever emit handles + text, never pass bytes. - TERMINAL NOT TOTAL (HIGH #2): #emitDurable only rescued the media_store_unavailable throw on a terminal; a store.put rejection (disk full) or any other de-inline throw on a media-bearing terminal escaped the catch-less #loop → no terminal, consumer hang, unhandled rejection. Fix: the terminal catch now strips the best-effort media payload on ANY de-inline failure (re-throws only for non-terminal drafts), so the run always settles. - url MEDIUM: add containsDurableUnsafeMedia (the byte scan + a url media part), used by the de-inline fast-path + the no-store guard, so a url-only payload is never silently passed through (it now hard-fails pending the D9 re-host). Regression tests: non-canonical carriers + url-only hard-fail (no leak/put); a data: URI node output fails the run with no bytes persisted even WITH a store; a rejecting store.put yields exactly one terminal (no hang); decodeBase64 + containsDurableUnsafeMedia direct unit tests; the ADR-0042 §2 reconcile media-free backstop. Also fixes the stale #emitDurable ordering comment. Refs: ADR-0042, ADR-0043 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…xt pickup 2.C PR #44 merged: durable local run history via @relavium/db (the SQLite RunStore writer + read API + ADR-0050 at-rest posture) is live. - phase-2-cli.md: §2.H header ✅ Done (PR #44); status line records 2.H Done (ADR-0050); the "Remaining build order" queue drops the completed 2.H row, renumbers (2.C is now #1), and the gate-closing backbone is 2.C → 2.E → 2.G → 2.I → 2.L (2.K + 2.H done). - current.md: 2.H ✅ Done; "Next pickup: 2.C" (provider/keys). - CLAUDE.md + README.md: Phase-2 status sentence records durable run history landed. Next pickup is 2.C (provider/keys) — independent, unblocks 2.R + 2.M + live runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xt pickup 2.E PR #45 merged. Provider/key commands (the `relavium provider` registry + API keys in the OS keychain via @napi-rs/keyring, resolved keychain → RELAVIUM_<PROVIDER>_API_KEY env var → error) are shipped. No new ADR (secrets.enc deferred past v1.0; @napi-rs/keyring pre-authorized by ADR-0019). - phase-2-cli.md: 2.C heading + status header + Remaining-build-order status line all marked ✅ Done (PR #45); the build-order table drops the 2.C row, renumbers (2.E now #1), and flips 2.C → ✓ in the MCP/chat blocker cells; the gate-closing backbone shrinks to `2.E → 2.G → 2.I → 2.L` (2.C joins 2.K + 2.H as done). - current.md: 2.C added to the Landed list (behind ADR-0019 + ADR-0006); next pickup → 2.E; date bump. - CLAUDE.md + README.md: status paragraphs updated (2.C landed; next pickup 2.E). Refs: phase-2-cli.md 2.C, ADR-0019, ADR-0006 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xt pickup 2.G PR #46 merged. The ink streaming TUI is shipped — the third RunRenderer over the one event bus (live per-node status + spinners, the active node's streaming tokens, a running cost footer, a persistent final summary), with cooperative Ctrl-C cancel (the native-AbortController + persistent-SIGINT + abort→cancelled chain). Behind ADR-0047 (ink ^6.8.0 + React 19, confined to apps/cli); no new ADR. - phase-2-cli.md: 2.E heading + status header + Remaining-build-order status line all marked ✅ Done (PR #46); the build-order table drops the 2.E row, renumbers (2.G now #1), and flips 2.E → ✓ in the 2.G + chat blocker cells; the gate-closing backbone shrinks to `2.G → 2.I → 2.L` (2.E joins 2.K + 2.H + 2.C as done). - current.md: 2.E added to the Landed list (behind ADR-0047); next pickup → 2.G; date bump (2026-06-24). - CLAUDE.md + README.md: status paragraphs updated (2.E landed; next pickup 2.G). Refs: phase-2-cli.md 2.E, ADR-0047 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xt pickup 2.I 2.G (interactive human-gate prompt + `relavium gate` cross-process resume) merged via PR #47, fully closing 2.K's deferred gate-resume half. Flip the status surfaces: - phase-2-cli.md: §2.G heading → Done; status header + Remaining-build-order status line → add 2.G; the build-order table drops the 2.G row and renumbers (2.I now #1, 2.L #2, 2.S #3, …); the gate-closing backbone shrinks to `2.I → 2.L`; the §2.K deferred gate-resume note → landed. - current.md: 2.G added to Landed; next pickup → 2.I. - CLAUDE.md + README.md: 2.G landed; next pickup 2.I. The structural views (dependency matrix, ordered waves, Mermaid graphs) are the from-scratch plan, not a live tracker, so they keep 2.G as a graph node unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nstall path Two defects in the 2.L packaging (ADR-0051), each of which would block or spoil the first publish; both surfaced after the tag-triggered Release CLI run. 1. `relavium --version` reported the hardcoded `0.0.0` sentinel, never the package version — it was never wired to package.json (the program.ts comment deferred it to "packaging (2.L)"). tsup now injects the manifest version at build time via a `__RELAVIUM_CLI_VERSION__` esbuild `define`; program.ts reads it behind a `typeof` guard and falls back to `0.0.0-dev` on a source run (tsx/vitest, no define). Bundled `relavium --version` → `0.1.0`; source → `0.0.0-dev`. 2. The cross-OS install-smoke failed on ubuntu/macOS/Windows: `npm install -g artifact/relavium-X.tgz` — a slash-bearing arg without `./` — is read by npm as a GitHub `owner/repo` shorthand and git-cloned (`Permission denied (publickey)`), never as the local tarball. Prefix with `./` so npm classifies it as a file spec (verified via npm-package-arg: bare → git, `./` → file). The publish job is gated on green smoke, so nothing was published. Also assert `relavium --version == package.json` in the smoke matrix so a version-wiring regression is caught before publish — the old smoke only ran `--help`, which is why #1 slipped. Refs: ADR-0051 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eck off discharged deferrals PR #52 (2.S — media host-wiring) merged 2026-06-25. Post-merge follow-up (deliberately held per the done-after-merge convention): - current.md: 2.S added to the Landed list (✅ PR #52, behind ADR-0042–0046, no new ADR; read_media deferred to 2.M); next pickup flipped 2.S → 2.R. - phase-2-cli.md: top status line, the 2.S section Status banner, the acceptance/outcome row, the remaining-build-order Status line + Next/Lane table (2.R now #1, 2.S moved to a ✅ row), the "four additive lanes" → three, and the 2.S-timing judgement-call prose all reflect 2.S Done + 2.R next. - CLAUDE.md: status paragraph — 2.S landed (PR #52), next pickup 2.R. - deferred-tasks.md: checked off the D-items 2.S discharged — durable fail-cost (node:failed/run:failed/ run:cancelled), D15 (catalog load-check wired on run/gate), D17 (media_cost_estimate threaded), D8 (resolveForEgress injected), the CAS-orphan sweep, and the clean-terminal reclaim-retry — each with PR #52; preamble updated. Still-open 2.S-created deferrals (save_to resumer-cwd, host-GC CLI-locality, media_gc_grace_days threading) left unchecked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lands Phase 0 workstreams 0.A / 0.B / 0.C — the project's first code: the monorepo + toolchain foundation Phase 1 builds on. Types and tooling, not features.
What's here
package.json(pnpm@9.12.3pinned),.nvmrc,.npmrc,pnpm-workspace.yaml,turbo.json(build/lint/typecheck/test +globalDependencies). Directory skeleton perproject-structure.md; only@relavium/sharedis built out, the rest are README-only placeholders.tsconfig.base.json(strict+noUncheckedIndexedAccess+exactOptionalPropertyTypes+noImplicitOverride+verbatimModuleSyntax+isolatedModules+moduleResolution: bundler);@relavium/sharedhas a build/typecheck split. Strictness verified load-bearing.no-explicit-any+no-floating-promisesas errors, scoped to the TS family withprojectService;disableTypeCheckedfor JS), Prettier (thedocs/house style is governed separately), and a workspace-aware Vitest with V8 coverage.Hardening pass (2nd commit)
After a three-pass review + adversarial re-verification of every finding against the real toolchain:
.tsx/.mts/.ctsno longer crash type-aware lint (the unscoped typed config would have failedpackages/uilint entirely at 0.H); JS getsdisableTypeChecked; config files ignored at any depth.lintnowdependsOn: ["^build"](cross-package type-aware lint at 0.D);.nvmrc+pnpm-workspace.yamladded toglobalDependencies; a//#format:checkturbo root task.noEmithardening +*.spec.tsbuild-leak exclude; Vitestincludepinned to**/*.test.ts; a rootcoveragescript (closes 0.C's "branch coverage reported").Verification (green from a fresh checkout)
pnpm install && pnpm turbo run lint typecheck test build✅ ·pnpm format:check✅ ·pnpm coverage✅ (V8 branch coverage). The lint + strictness gates are proven load-bearing (any, a floating promise, andnoUncheckedIndexedAccessall error;.tsxreports both non-negotiables with no crash).Scope
In: 0.A, 0.B, 0.C. Still open before M0: 0.D/0.E (Zod schemas — critical path), 0.F (seam fence), 0.G (CI), 0.H (docs), 0.I (
@relavium/db).🤖 Generated with Claude Code
Summary by Sourcery
Scaffold the initial monorepo toolchain and shared package, establishing strict TypeScript, linting, formatting, and testing foundations for future phases.
New Features:
@relavium/sharedpackage as the dependency root, exposing a versioned schema scaffold and package-level build/test scripts.Enhancements:
Documentation:
Tests:
@relavium/sharedaligned with the project’s testing conventions.Summary by CodeRabbit
Chores
Documentation
Tests