# equinoxbusinesslaw — v8 substrate feedback

> Running log of friction hit while building **inside** the v8 conventions.
> **This is feedback about the substrate, not about this project** — it gets
> compiled into `/srv/.logs/planning/server-evolution-2026.md` or the ops queue
> (`/srv/.logs/ideas.md`) once the build settles.
>
> Scope discipline: only entries where the *server framework, standards library,
> or gateway* caused the friction. Bugs in this project's own code belong in
> `handoff.md`, not here.
>
> Each entry: what happened, what it cost, and a candidate fix.
> (Pattern proven 2026-07-30; it is what turns one project's
> pain into a standards fix for every later project. Delete this file if the
> project never hits substrate friction.)

---

## 2026-09-02 — Scaffolder does not know a WordPress project's instance is `wp-content/`

**What happened.** `new-workspace.sh equinoxbusinesslaw` created an empty `main/` and
printed "Put code in main/ ; point docker-compose.yml's build context at ./main". For a
gateway-managed WordPress project neither is true: the gateway bind-mounts `wp-content/`
at a fixed path and runs the container with `docker run`, not the compose file. The
same thing happened on the previous WordPress migration to the shape (2026-08-10), which
also removed `main/` by hand and wrote the declared-override paragraph into `agents.md`.

**What it cost.** A few minutes here, but the `main/` folder is a trap for the next
session: an agent following the scaffolder's own "Next:" text would put a theme in
`main/` and nothing would serve it.

**Candidate fix.** `new-workspace.sh` can read `.project.json` (`"type": "wordpress"`)
and, for that type, skip `main/`, emit the declared-override paragraph into the
generated `agents.md` Layout section, and change the "Next:" hint to "code lives in
`wp-content/` (themes, plugins); the gateway mounts it". When T3.1 absorbs the scaffolder
into `create-project`, the type is known at creation time, so this becomes free.

## 2026-09-02 — Gateway-generated `CLAUDE.md` always blocks the `CLAUDE.md -> agents.md` symlink

**What happened.** `create-project --type wordpress` writes a real `CLAUDE.md` (site URL,
container commands, DB name, file layout). The scaffolder correctly refuses to replace a
real file, so every WordPress project migrated to the shape needs a manual merge into
`agents.md` followed by `rm CLAUDE.md && ln -s agents.md CLAUDE.md`.

**What it cost.** A manual step on every WordPress project, and a window where a project
has both a stale `CLAUDE.md` and a fresh `agents.md` that disagree.

**Candidate fix.** Have `create-project` write the operational block into `agents.md`
and create `CLAUDE.md` as the symlink from day one (the v8 shape), so the scaffolder
never meets a real `CLAUDE.md` on a gateway-created project. Until then, the scaffolder
could offer `--absorb-claude-md` that appends the real file's content under an
"## Operational (imported)" heading in `agents.md` and swaps in the symlink.
