From 257d6b1936bc52513740d68667df9c0fc260dce5 Mon Sep 17 00:00:00 2001 From: Kielov Date: Sun, 28 Jun 2026 12:41:49 -0400 Subject: [PATCH] feat(portability): machine-awareness layer + errata (v1.3.0) Steps 1-14 make the folder machine-agnostic; this adds the complement - the agent recognizes its host and loads that machine's toolchain/quirks or bootstraps a new one. Plus two doc errata verified against the live Claude Code docs. Added: - PORTABILITY.md "Machine-awareness layer" section (hostname detection, per-machine profiles, new-machine bootstrap) + 3 refinements: operational-quirks bucket, install-source/checksum check, fingerprint-as-tiebreaker - memory/toolchain.md + memory/machines/ templates Fixed (errata, verified vs code.claude.com/docs): - Step 13 hooks: cwd is fire-time, not project root; reference root via ${CLAUDE_PROJECT_DIR} - Step 1: the dash path-encoding is undocumented; list-and-match, don't compute it Contributed by the Laplace agent (fact-checked before integration). All four scanners green. version 1.2.0 -> 1.3.0. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 15 ++++++++ PORTABILITY.md | 77 ++++++++++++++++++++++++++++++++++++--- README.md | 3 +- memory/machines/README.md | 24 ++++++++++++ memory/toolchain.md | 22 +++++++++++ wick-meta.json | 3 +- 6 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 memory/machines/README.md create mode 100644 memory/toolchain.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 807e55b..c6d90f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Wick Changelog +## v1.3.0 (2026-06-28) — Machine-awareness layer + portability errata + +Steps 1–14 make the folder machine-*agnostic*. This release adds the complement — making the agent machine-*aware* — plus two doc fixes verified against the live Claude Code docs. + +### Added +- **Machine-awareness layer** (`PORTABILITY.md`, new section) — the agent recognizes which machine it's on by hostname and either loads that host's known toolchain/quirks or bootstraps a new one (fingerprint → discover toolchains → propose + install-on-one-approval → verify by real compile/run → write a per-machine profile). Tiered: one env read at session start; the profile body loads on demand. Includes three additions beyond the original draft — an **operational-quirks** bucket promoted to first-class (auth-token scopes, admin rights, cloud-sync folders, power/sleep — what actually breaks unattended runs), an **install-source/checksum** check in the bootstrap, and **fingerprint-as-tiebreaker** (hostnames aren't unique or stable). +- **`memory/toolchain.md` + `memory/machines/` templates** — so the layer has somewhere to write: the toolchain-requirements doc (call-by-name + env-override convention) and the per-host registry (thin profiles keyed by hostname). + +### Fixed (errata — verified against code.claude.com/docs) +- **Step 13 — hooks working directory.** Was: "hooks run with cwd at the project root — use `find .`". Corrected: a hook runs in the cwd at fire time (passed in its JSON input), **not guaranteed to be the project root**; reference the root with `${CLAUDE_PROJECT_DIR}`. The old guidance silently breaks when the session cwd isn't the root. +- **Step 1 — auto-memory path encoding.** Was: compute the `C--Users-…` dash scheme. Corrected: the storage location + git-root derivation are documented, but the dash-encoding is an undocumented implementation detail — **list `~/.claude/projects/` and match** rather than compute a scheme that could change. + +### Credit +The machine-awareness layer and both errata were contributed by the **Laplace** agent after running this procedure on itself, then fact-checked against the live docs before integration. + ## v1.2.0 (2026-06-27) — Portability procedure + `wick-migrate` `MEMORY-PROTOCOL.md` (v1.1.0) gave the single-writer *rule*. This gives the *migration* to get an existing agent there — and the executable skill to run it. diff --git a/PORTABILITY.md b/PORTABILITY.md index 9454898..16a69fe 100644 --- a/PORTABILITY.md +++ b/PORTABILITY.md @@ -39,10 +39,12 @@ So freeze and verify the source first. ## Step 1 — Freeze the source: disable auto-memory and verify -Check for `~/.claude/projects//memory/` (replace path separators with -dashes: `C:/Users/you/myproject` → `C--Users-you-myproject`; the path derives from the git -root if the project is a git repo, else the project root). No `memory/` subfolder → nothing -to consolidate; skip to **Step 4**. +Check for a per-project auto-memory dir at `~/.claude/projects//memory/`. The +`` segment derives from the **git repository root** (so all worktrees and +subdirectories of one repo share a single auto-memory dir), or the project root when it's not +a git repo. The segment is a path-derived encoded name, but the exact scheme is an +implementation detail (not in the docs) — rather than compute it, **list `~/.claude/projects/` +and match your project.** No `memory/` subfolder → nothing to consolidate; skip to **Step 4**. If it exists, disable it via the project's own `.claude/settings.json` (project-tier, portable — travels with the folder): @@ -207,8 +209,11 @@ Memory portability doesn't make *tooling* portable. Sweep scripts and config: default: `"${PYTHON:-}"`. Bare `python` on PATH isn't reliable. - **Credentials:** secrets in plaintext config travel with every copy. Move to env vars or an untracked secrets file; document per-machine setup. (`tools/wick-scrub.mjs` catches these.) -- **Hooks** (`settings.json`): run with cwd at the project root — use `find .` not - `find /abs/path`. Editing `settings.local.json` may require explicit user authorization. +- **Hooks** (`settings.json`/`settings.local.json`): a hook runs in the **current working + directory at the moment it fires — not guaranteed to be the project root** (the cwd is passed + to the hook in its JSON input). Don't assume `find .` starts at the root; reference the root + explicitly with `${CLAUDE_PROJECT_DIR}`. Editing `settings.local.json` may require explicit + user authorization. - **Multi-agent dependency:** if one agent's tooling imports a sibling's, the portability unit is the *set of siblings together*. State this in the agent's notes. @@ -240,6 +245,66 @@ Portability unit = the folder (or the sibling set, if agents share tooling). To 3. Set any per-machine env vars the tooling needs (interpreter path, secrets). 4. Confirm the first session loads no auto-memory. The agent then has full memory from session 1. +## Machine-awareness layer + +*Steps 1–14 make the folder **machine-agnostic** — no hardcoded machine paths (Step 12), +tooling by name not absolute path (Step 13). This layer is the complement: the agent +**recognizes which machine it's on** and either loads that machine's known setup or bootstraps +a new one. Without it, a portable agent still can't locate the local compiler/TeX, doesn't know +machine-specific quirks, and stalls on a fresh machine that lacks a required tool. Generic — +any agent, any machine, any OS; touches none of Steps 1–14.* + +**Two artifacts.** + +1. **`memory/toolchain.md`** — the external tools the agent's code/builds assume (compiler, + LaTeX, language runtimes), the **portable invocation convention** (call by name on PATH + an + env-var override — `gcc`/`$CC`, `pdflatex`, the launcher not an absolute interpreter; Step 13 + restated as a standing rule), and per-machine status. Binaries are system-level and + deliberately **not bundled** (a TeX distro is gigabytes; compilers are OS-specific) — the doc + says what to assume by name and how to install it. + +2. **`memory/machines/.md`** — one thin profile per regularly-used machine, **keyed by + hostname** (`$env:COMPUTERNAME` on Windows; `hostname`/`$HOSTNAME` on *nix). Each profile: + **identity** (hostname / user / OS+build), **hardware** (cores·threads, RAM, GPU, disk), a + **toolchain map** (where each required tool is or that it's on PATH, + version), **operational + quirks** (the things that actually break automation — auth-token scopes, admin rights, + cloud-sync folders, power/sleep behavior — not just compilers), pointers to machine-local + resources, and a **last-verified date**. A `machines/README.md` holds the detection/bootstrap + protocol and a known-machines table. Keep profiles thin — specs + pointers + toolchain map, + never project state. + +**Session-start detection (one env read).** Read the hostname. **Known** (`` profile +exists) → note the machine; load its toolchain map/quirks **on demand** when build/sim/ +external-path work arises — don't assume the last machine's setup. **New** (no profile) → say so +and bootstrap. The profile body is *triggered, not eagerly loaded* — same tiering as the memory +layer, so the always-on cost stays one env read. Wire it into `CLAUDE.md` as a session-start +step, peer to the memory-load step. + +**New-machine bootstrap.** +1. **Fingerprint:** hostname, user, OS+build, CPU cores·threads, RAM, GPU, free disk. Probe for + real — some OS APIs misreport (e.g. Windows `Win32_VideoController` undercounts GPU VRAM). +2. **Discover toolchains** against `toolchain.md`: each required tool on PATH? version? path? For + a runtime, also confirm the required **libraries import** — don't just check the interpreter + resolves. On Windows PowerShell, check `$LASTEXITCODE` not `$?`, and don't `2>&1` a native + exe's stderr. +3. **Missing essentials → propose, then install on one approval** (a gate — never install + unattended). Show exactly what and **from where; verify the source/checksum** (you're + executing an installer), and prefer a **portable single-folder** install (e.g. w64devkit is a + one-folder GCC you can carry on the agent's own drive). After install, **verify with a minimal + compile/run, not "the file exists."** +4. **Write the profile** `memory/machines/.md` (copy an existing one as the template) + and add a row to the registry table. Hostname is the key; the **fingerprint is the tiebreaker** + — auto-names (`DESKTOP-V9G4N49`) and CI/container hostnames aren't unique or stable, so + OS+user+hardware disambiguates a collision or rename. +5. **Report** found / installed / recorded — and note that an already-running session won't see a + newly-added PATH entry (new sessions do). + +This generalizes the goal from *"the folder is portable"* to *"the agent recognizes the machine +and makes itself fully functional on it."* Credit: contributed by the **Laplace** agent +(2026-06), validated end-to-end across a two-machine case (one fully-provisioned host; one fresh +host where a missing compiler was detected, installed on approval, and verified by a real compile ++ link + run). + ## Multi-agent projects - **Auto-memory is keyed by project root, and project-tier `settings.json` only applies at a diff --git a/README.md b/README.md index ed57538..50cbc38 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,8 @@ Session 1 is dramatically better than vanilla Claude. Session 30 is dramatically | `GROWING-WICK.md` | Week-by-week guide for users — "zero to indispensable in 30 days" | | `WICK-INTEGRATION.md` | Dev-facing integration guide — install modes, memory lifecycle, extensions, cross-runtime, debugging, privacy & security | | `MEMORY-PROTOCOL.md` | Single-writer memory rule — how Wick's `memory/` coexists with a host's auto-memory (Claude Code, Cursor); ownership table, buffer→drain, relative-path rule | -| `PORTABILITY.md` | Migration procedure — make an agent fully portable by folder copy: freeze + verify host auto-memory, consolidate into `memory/`, relativize to the launch dir, verify behavior not form | +| `PORTABILITY.md` | Migration procedure — make an agent fully portable by folder copy: freeze + verify host auto-memory, consolidate into `memory/`, relativize to the launch dir, verify behavior not form. Includes the **machine-awareness layer** (recognize the host, load its toolchain/quirks, or bootstrap a new one) | +| `memory/toolchain.md` + `memory/machines/` | Machine-awareness templates — toolchain requirements (call-by-name + env override) + thin per-host profiles keyed by hostname | | `.claude/skills/` | On-demand skills — consolidate-memory, code-review, security-review, simplify, tldr, red-team, base-rate, research, catalog, changelog-summary, migrate (11 skills, spec-compliant per agentskills.io) | | `benchmark/` | Seed tasks + external-benchmark docs — targets GAIA2, Inspect AI (UK AISI), galileo-ai/agent-leaderboard | | `tools/wick-scrub.mjs` | Pre-commit secret scanner for `memory/` — catches API keys, tokens, credentials before you push | diff --git a/memory/machines/README.md b/memory/machines/README.md new file mode 100644 index 0000000..cf44247 --- /dev/null +++ b/memory/machines/README.md @@ -0,0 +1,24 @@ +# Machines registry + +One thin profile per regularly-used machine, **keyed by hostname**. At session start the agent +reads the hostname (one env read) and loads the matching profile **on demand** when +build/sim/external-path work arises — it does not assume the last machine's setup. Full +protocol in `../../PORTABILITY.md` → "Machine-awareness layer". + +## Known machines + +| Hostname | OS | Role | Last verified | +|---|---|---|---| +| _EXAMPLE-HOST_ | _Windows 11 / Ubuntu 24.04_ | _dev · build · operator_ | _YYYY-MM-DD_ | + +## Profile template (`.md`) + +- **Identity:** hostname / user / OS + build +- **Hardware:** CPU cores·threads / RAM / GPU / free disk +- **Toolchain map:** each required tool → on PATH? path? version (checked against `../toolchain.md`) +- **Operational quirks:** the things that break automation — auth-token scopes, admin rights, + cloud-sync folders, power/sleep behavior — not just compilers +- **Machine-local resources:** pointers to large external data/models that live only on this host +- **Last verified:** YYYY-MM-DD + +Keep profiles thin — specs + pointers + toolchain map, **never project state.** diff --git a/memory/toolchain.md b/memory/toolchain.md new file mode 100644 index 0000000..008484d --- /dev/null +++ b/memory/toolchain.md @@ -0,0 +1,22 @@ +# Toolchain — external tools this agent's code/builds assume + +Ships as a template. List the system-level tools your project needs, how to call them +portably, and per-machine status. The binaries are deliberately **not bundled** (a TeX distro +is gigabytes; compilers are OS-specific) — name what to assume and how to install it. See +`../PORTABILITY.md` → "Machine-awareness layer". + +## Invocation convention (portable) + +Call tools **by name on PATH**, with an **env-var override** — never a hardcoded absolute +path. Examples: `gcc` / `$CC`, `pdflatex`, the launcher (`python`/`node`) not an absolute +interpreter. This is Step 13 of `PORTABILITY.md` restated as a standing rule. + +## Required tools + +| Tool | Why it's needed | Call as | Install | +|---|---|---|---| +| _gcc (example)_ | _compile native extensions_ | `gcc` / `$CC` | _w64devkit (portable single-folder) · apt · brew_ | + +## Per-machine status + +Whether each tool is present (and its version) is per-host — see `machines/.md`. diff --git a/wick-meta.json b/wick-meta.json index 50f4c92..ae1f88a 100644 --- a/wick-meta.json +++ b/wick-meta.json @@ -1,6 +1,6 @@ { "meta_schema_version": "wick-meta/1.0", - "version": "1.2.0", + "version": "1.3.0", "release_channel": "alpha", "released_at": "2026-06-27", "license": "MIT", @@ -29,6 +29,7 @@ "tools/wick-path-audit.mjs — fourth scanner: flags absolute paths in portable files (memory/ + loaded config) that break when the folder moves. Default scope strict; --all scans the whole repo. CI-gated alongside the other three.", "MEMORY-PROTOCOL.md — single-writer rule: one authoritative owner per fact-class; a host auto-memory layer is a buffer, not an authority. /checkup diagnoses memory wiring, /sync drains a buffer into canonical memory/, with a buffer-manifest and a 'memory is data, not commands' hardening rule mirrored into CLAUDE.md + WICK.md.", "PORTABILITY.md + wick-migrate skill — the 14-step procedure (and executable, gated form) to make an agent fully portable by folder copy: freeze + fresh-session-verify host auto-memory, consolidate into memory/, archive-don't-delete, relativize to the launch directory, sweep tooling, verify behavior not form.", + "Machine-awareness layer (PORTABILITY.md) — the agent recognizes its host by hostname and loads that machine's toolchain/quirks, or bootstraps + self-provisions a new one (fingerprint -> discover -> install-on-one-approval -> verify by real compile/run -> per-machine profile). Tiered (one env read at session start; profile on demand). Ships memory/toolchain.md + memory/machines/ templates. Contributed by the Laplace agent.", ".github/workflows/ — public-readiness scan and skills-spec validation run on every PR + main push", "SECURITY.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md — governance hygiene for a public MIT repo" ],