Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
77 changes: 71 additions & 6 deletions PORTABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<path-encoded-folder>/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/<project>/memory/`. The
`<project>` 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):
Expand Down Expand Up @@ -207,8 +209,11 @@ Memory portability doesn't make *tooling* portable. Sweep scripts and config:
default: `"${PYTHON:-<current absolute>}"`. 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.

Expand Down Expand Up @@ -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/<hostname>.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** (`<hostname>` 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/<hostname>.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
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
24 changes: 24 additions & 0 deletions memory/machines/README.md
Original file line number Diff line number Diff line change
@@ -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 (`<hostname>.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.**
22 changes: 22 additions & 0 deletions memory/toolchain.md
Original file line number Diff line number Diff line change
@@ -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/<hostname>.md`.
3 changes: 2 additions & 1 deletion wick-meta.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
],
Expand Down
Loading