niklas‑stephan.de

/data Workspace Conventions

Last updated 05/11/2026 · migrated-from-outline

id: data-workspace-conventions title: /data Workspace Conventions importance: high tags: migrated-from-outline updated: 2026-10-31 content: folder layout, naming, pnpm only, how to apply compose changes. outline: /doc/data-workspace-conventions-fjRCXrBtEI

.

Layout

The /data workspace has three main subfolders:

Folder Purpose
docker/ Docker Compose projects
maintenance/ Global scripts (diagnostics, ops) — standalone executable scripts, plus one-off task scratch (see below)
sources/ Storage for binary, read-only data
scripts/, tests/ host helpers / check suites (handtrixxx.com)

ThinkPad (no /data): everything lives under /home/handtrixxx/code/ — kb/ (memory repo clone), tasks/ (planning docs), project dirs, scripts/.

Rules

  • New docker projects go in docker/<project-name>/ with a compose.yml in the project root.
  • Name new project directories in lowercase kebab-case (e.g. my-service).
  • Never rename existing project directories — bind mounts depend on their paths.
  • Keep project state in subdirectories of the project folder (e.g. data/, configuration/, models/).
  • sources/ is read-only: never modify or delete files there.
  • Each server has its own /data workspace: check the local docker/ directory before assuming a project exists on a given server.

Working-file convention (decided 2026-10-25)

Three layers, so scratch does not accumulate:

  1. Durable knowledge → Outline collection KB (kb new / kb update, see memory-system). Planning/research write-ups → ThinkPad code/tasks/<task-kebab>.md (and link them from the memory). Planning/research write-ups → ThinkPad code/tasks/<task-kebab>.md (and link it from the memory).
  2. Project code → one canonical git repo per project (Gitea for kb, GitHub for alexandria/webtop/etc.). No loose clones or non-git snapshots of a project on other hosts: the metis clone /data/sources/alexandria/ and the non-git snapshot /data/maintenance/alexandria-rust/ were deleted 2026-10-25 for this reason. Dev happens on the ThinkPad; servers only build/deploy.
  3. Throwaway scratch → per-task folder /data/maintenance/<task-kebab>/ on servers (or code/tasks/agent-spike/ style on ThinkPad), containing only what a later session needs (Dockerfile, compose draft, notes); logs (build*.log), screenshots, *.tmp and one-off test scripts get pruned when the task is done.

Housekeeping 2026-10-25: ThinkPad _tmp_views/ (screenshots/askpass shims) and tmp-warmtest.py pruned; opencloud-eu-desktop-arm64/, tv-debloat/, cleanyourtv/ are finished one-offs kept as-is.

JavaScript / Node.js tooling

  • Always use **pnpm**, never **npm** (and not yarn) for JS/Node projects under /data. Use pnpm install, pnpm add <pkg>, pnpm run <script>, etc. Do not generate or commit package-lock.json — the lockfile is pnpm-lock.yaml.
  • pnpm store location: set globally to /data/code/.pnpm-store/v11 via pnpm config set store-dir /data/code/.pnpm-store/v11 --global (lives in ~/.config/pnpm/config.yaml). Rationale: the default store lives in $HOME, but /data is a separate ZFS dataset, and pnpm hard-links packages from the store into node_modules — which can’t cross a filesystem boundary. With the store on the same dataset as the projects, installs are warning-free and hard-linked (no copies). If you ever move the store, re-run the pnpm config set command with the new path; existing project node_modules get their links rebuilt once (content is reused, not re-downloaded).
  • Note: in pnpm v12, a project-level .npmrc does not set store-dir — it must be set globally or in the project’s pnpm-workspace.yaml.

Next.js applications

When scaffolding or working on a Next.js app under /data, standardize on:

  • Node.js 26.x (latest)
  • TypeScript 7.x (latest — TS 7 is the Go-based rewrite, tsgo; verify the current minor via pnpm view typescript version)
  • oxlint as the linter (latest; pnpm add -D oxlint), replacing ESLint

Always install at their latest versions rather than pinning stale ones. Set a .nvmrc/engines field to Node 26 and add a lint script (e.g. "lint": "oxlint"). Verify the exact current minor with pnpm view <pkg> version before committing, since these move fast.

General gotcha for any non-repo dir under /data: /data is a separate ZFS mount from /, so git in a directory with no .git above it reports “not a repository / stopped at filesystem boundary” — expected, not an error. And regardless of git: if packages appear to revert after pnpm add, the real cause is usually that pnpm exec <cmd> re-syncs node_modules against a stale lockfile. Fix pattern: edit package.json explicitly, run one pnpm install, and verify the new versions appear in pnpm-lock.yaml before trusting them.

Node version manager on Metis: nvm. Installed to ~/.nvm (v0.40.3) via the official script; it appended its source lines to ~/.bashrc. Node 26 is installed and set as the default alias (nvm install 26 → v26.10.0). The system Node at /usr/bin/node (a nodejs deb, v22) is untouched — nvm only takes effect in shells that source it. Important for agents/one-liners: a fresh non-interactive shell won’t have nvm on PATH, so load it first in the same command:

export NVM_DIR="$HOME/.nvm"; [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"; nvm use 26 >/dev/null; <your node/pnpm command>

Applying changes

Apply compose changes with:

docker compose up -d   # in the project directory

Source: Wiki.js