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
28 changes: 28 additions & 0 deletions .changeset/agents-md-worktree-staleness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
---

Two additions to AGENTS.md's multi-agent discipline. Deliberately empty
frontmatter: documentation, this releases nothing.

**#9 — refresh a long-lived worktree's build state after merging `main`.** Four
distinct stale artefacts each fail *as if your change broke something*, naming
other people's exports, other packages' files, or config you never touched:
`packages/spec/dist` (makes `check:api-surface` report someone else's exports as
breaking, and `check:i18n-coverage` reject a valid example config), `node_modules`
(a package cannot resolve a dependency it plainly declares), `packages/runtime/
.objectstack/` (fixture rows accumulating across runs), and `.cache/objectui-*`
(dozens of lint errors in files you have never opened). None is CI-visible — CI
checks out fresh — so the cost lands entirely on whoever is debugging. Also notes
that `OS_SKIP_DTS=1` leaves no `.d.ts`, which makes `gen:api-surface` impossible
rather than merely slow.

**#10 — a clean merge is not a working merge.** Git conflicts on overlapping
lines; nothing warns when two changes are individually fine and jointly wrong.
Both examples are real and recent: a test pinning a response body's exact shape
landed while that shape was being changed elsewhere, and a domain file was deleted
while another agent's guard still declared it. The first merged clean and failed
CI; the second was caught only because the guard existed. Hence: pull `main` and
re-run before opening a PR, and again before merging.

Written from one branch's lifetime — every row is a failure that cost a debugging
round, so the list is what was actually hit rather than what might happen.
31 changes: 31 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,37 @@ own worktree, operate defensively:
up your own instance on a random high port (`pnpm dev -- --fresh -p <random>`)
and **shut it down yourself when the task is done**
(`kill $(lsof -ti tcp:<port>)`). Don't leave orphan servers behind.
9. **After pulling `main` into a long-lived worktree, refresh its build state
before you trust a single test or gate.** A worktree that has been open across
several merges accumulates artefacts that are stale relative to the source, and
every one of them fails **as if your change broke something** — naming other
people's exports, other packages' files, or config you never touched:

| stale artefact | how it presents | why it lies |
|---|---|---|
| `packages/spec/dist` | `check:api-surface` reports *other people's* exports as "N breaking (removed/narrowed)"; `check:i18n-coverage` rejects an example config for a value the spec allows | both read the built `.d.ts`, not `src/` |
| `node_modules` | a package fails to resolve a dependency it plainly declares (`Cannot find package 'hono'`) | the merge moved `pnpm-lock.yaml` |
| `packages/runtime/.objectstack/` | `datasource-autoconnect` sees each row 6× | gitignored fixture state accumulating across runs |
| `.cache/objectui-*` | `pnpm lint` reports dozens of errors in files you have never opened | a full objectui checkout left by `build-console.sh`, linted as if it were ours |

So after any `git merge origin/main`:
`pnpm install --frozen-lockfile && pnpm build && rm -rf packages/runtime/.objectstack`
(add `rm -rf .cache` if you have run the console build). Note `OS_SKIP_DTS=1`
keeps a build fast but leaves no `.d.ts`, so `gen:api-surface` cannot run at
all under it — that one needs a real build.

None of this is CI-visible: CI checks out fresh and installs clean. It costs
only *your* time, which is exactly why it is worth recognising in one step
rather than re-diagnosing per gate.
10. **A clean merge is not a working merge.** Git conflicts on overlapping lines;
nothing warns you when two changes are individually fine and jointly wrong.
Real examples from one branch's lifetime: a test asserting a response body's
exact shape landed while that shape was being changed elsewhere (merged clean,
failed CI); a domain file was deleted while another agent's guard still
declared it. **Before opening a PR, and again before merging, pull `main` and
re-run the suite** — the second CI round is where these surface, and the guards
in `scripts/check-*.mjs` exist largely because this class of breakage is
invisible to `git merge`.

---

Expand Down
Loading