@open-everywhere/create 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/NOTICE CHANGED
@@ -8,10 +8,40 @@ This product is licensed under the Apache License, Version 2.0 (see LICENSE).
8
8
  Built on Vercel Eve (https://github.com/vercel/eve), licensed under the
9
9
  Apache License, Version 2.0.
10
10
 
11
- @open-everywhere/core also ships a patch that modifies Vercel Eve (the file in
12
- its patches/ directory), with the oe-eve-patch command that applies it to a
13
- consumer's own installed copy. The patch is licensed under the Apache License,
14
- Version 2.0. No modified Vercel Eve files are distributed.
11
+ ---
12
+
13
+ Modifications to eve
14
+
15
+ The @open-everywhere/core package distributes patches/eve+0.54.3.patch. That
16
+ patch file is a modification of eve 0.54.3. Vercel licenses eve 0.54.3 under the
17
+ Apache License, Version 2.0. The copyright notice of eve 0.54.3 reads
18
+ "Copyright 2026 Vercel, Inc. and contributors". The Open Everywhere authors made
19
+ the changes in the patch file.
20
+
21
+ The patch modifies six files of eve 0.54.3:
22
+
23
+ dist/src/context/dynamic-tool-lifecycle.js
24
+ dist/src/execution/web-fetch/request.js
25
+ dist/src/harness/tool-loop.js
26
+ dist/src/internal/authored-package-boundary.js
27
+ dist/src/protocol/message.d.ts
28
+ dist/src/tasks/session-index.js
29
+
30
+ Open Everywhere does not ship the eve package. eve is a peer dependency, so the
31
+ consumer installs eve 0.54.3 from the registry. The patch file carries the
32
+ modified portions of eve. The oe-eve-patch command, which
33
+ @open-everywhere/core ships, applies them to the eve that the consumer
34
+ installed. The command writes no file outside the consumer's own project.
35
+
36
+ The attribution notice of eve 0.54.3 follows, as section 4(d) of the Apache
37
+ License, Version 2.0 requires. The notices for eve's bundled code-mode runtime
38
+ are not reproduced, because the patch modifies no part of that runtime.
39
+
40
+ eve
41
+ Copyright 2026 Vercel, Inc. and contributors
42
+
43
+ This product includes software developed at Vercel, Inc.
44
+ (https://vercel.com/).
15
45
 
16
46
  ---
17
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-everywhere/create",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "description": "npx scaffold and setup check for Open Everywhere — one step engine, reported by --check for an agent-led setup.",
@@ -40,14 +40,14 @@
40
40
  "test:engine": "tsx scripts/engine-test.ts",
41
41
  "test:cli": "tsx scripts/cli-check-test.ts",
42
42
  "test": "npm run test:chain",
43
- "test:chain": "npm run test:engine && npm run test:scaffold && npm run test:cli && npm run test:env-pipe && npm run test:boot-free",
43
+ "test:chain": "tsx ../../scripts/chain/run-chain.ts",
44
44
  "test:boot-free": "tsx scripts/boot-free-test.ts",
45
45
  "test:scaffold": "tsx scripts/scaffold-test.ts",
46
46
  "test:env-pipe": "tsx scripts/env-pipe-test.ts"
47
47
  },
48
48
  "dependencies": {
49
- "@open-everywhere/core": "0.1.4",
50
- "@open-everywhere/provider-slack": "0.1.4",
49
+ "@open-everywhere/core": "0.1.5",
50
+ "@open-everywhere/provider-slack": "0.1.5",
51
51
  "tsx": "^4.23.9"
52
52
  },
53
53
  "devDependencies": {
@@ -85,6 +85,9 @@ function rosterNext(detail: string): string {
85
85
  if (/npm install/.test(detail)) return "npm install";
86
86
  if (/UNREVIEWED|missing — nothing has been REVIEWED/.test(detail)) return "review the contribution in roster.config.ts, then `npx oe build --accept` and read the roster.lock.json diff";
87
87
  if (/NOT BUILT/.test(detail)) return "npm run build";
88
+ // OPE-2217: `oe build --check` also proves the overlays hold only data. `oe build` never writes an
89
+ // overlay, so it cannot clear this red.
90
+ if (/OVERLAY ·/.test(detail)) return "edit only the data in the named overlay, then `npx oe overlays normalize`";
88
91
  return "npx oe build";
89
92
  }
90
93
 
@@ -35,7 +35,8 @@ Setup is yours to drive, with the user's consent at every command. Use the
35
35
  `agent/connections/` and `agent/lib/providers.generated.ts` — `oe build` output. Never edit or
36
36
  commit them.
37
37
  - `*.generated.ts` — machine-owned overlays that the agent's own approval flows write by pull
38
- request. Never edit them by hand.
38
+ request. Never edit them by hand. `npx oe overlays check` proves each one holds only data, and
39
+ `npx oe overlays normalize` re-emits them after a data edit.
39
40
  - `scripts/ops-mcp.ts` — the ops MCP server. `scripts/env-pipe.mjs` — `npm run -s env:pipe`, which
40
41
  pipes one `.env.local` value into `vercel env add`. Always pipe it; never run it bare.
41
42
 
@@ -47,6 +48,8 @@ Setup is yours to drive, with the user's consent at every command. Use the
47
48
  `npm run dev` and `npm start` run `oe build` first too.
48
49
  - `oe build` refuses a contribution the lock has not reviewed. Decide about it in
49
50
  `roster.config.ts`, then run `npx oe build --accept`, and review the lock diff.
51
+ - `npx oe build --check` verifies the slot tree without a write, and proves the overlays hold
52
+ only data. Run it before you merge a pull request that changes an overlay.
50
53
  - `npm run typecheck` type-checks the app.
51
54
  - Deploy is a separate, explicit step. On the Vercel route that is `npx vercel deploy --prod`; a
52
55
  `git push` does NOT deploy.
@@ -60,7 +60,8 @@ without a public tunnel.
60
60
  `agent/tools/`, `agent/channels/`, `agent/hooks/`, `agent/schedules/`, `agent/skills/`,
61
61
  `agent/connections/` and `agent/lib/providers.generated.ts` are `oe build` output. They are not
62
62
  committed. The `*.generated.ts` files are machine-owned overlays that the agent's own approval flows
63
- write by pull request. Do not edit them by hand.
63
+ write by pull request. Do not edit them by hand. `npx oe build --check` (or `npx oe overlays check`)
64
+ proves they hold only data. After a data edit, run `npx oe overlays normalize`.
64
65
 
65
66
  ## Add a surface
66
67
 
@@ -1,14 +1,15 @@
1
1
  // GENERATED + MACHINE-OWNED — DO NOT HAND-EDIT.
2
2
  //
3
3
  // The credential-bindings overlay: DATA ONLY. Written exclusively by the deterministic codemod
4
- // (packages/core/agent/access/credential-bindings-codemod.ts) on a bot-PR branch; the PR merge is the approval gate.
4
+ // (@open-everywhere/core/agent/access/credential-bindings-codemod.js) on a bot-PR branch; the PR merge is the approval gate.
5
5
  //
6
6
  // The codemod re-emits this file from its own parsed content and refuses to rewrite it when the
7
- // bytes differ, so a hand-edit stops the next machine PR. Before a merge, nothing checks that the
8
- // file is still data only unless the repository runs its own check: the person who merges the PR
9
- // is the gate. Read a PR to this file as code, because it is code.
7
+ // data or the import differ, so a hand-edit there stops the next machine PR. Before a merge,
8
+ // nothing checks that the file is still data only unless the repository runs
9
+ // `npx oe build --check` or `npx oe overlays check`: the person who merges the PR is the gate.
10
+ // Read a PR to this file as code, because it is code.
10
11
  //
11
- // To change it by hand, edit only the data below and keep the layout exactly as emitted.
12
+ // To change it by hand, edit only the data below, then run `npx oe overlays normalize`.
12
13
 
13
14
  import type { CredentialBindingsFile } from "@open-everywhere/core/agent/access/credential-bindings-codemod.js";
14
15
 
@@ -1,14 +1,15 @@
1
1
  // GENERATED + MACHINE-OWNED — DO NOT HAND-EDIT.
2
2
  //
3
3
  // The grants overlay: DATA ONLY. Written exclusively by the deterministic codemod
4
- // (packages/core/agent/access/grants-codemod.ts) on a bot-PR branch; the PR merge is the approval gate.
4
+ // (@open-everywhere/core/agent/access/grants-codemod.js) on a bot-PR branch; the PR merge is the approval gate.
5
5
  //
6
6
  // The codemod re-emits this file from its own parsed content and refuses to rewrite it when the
7
- // bytes differ, so a hand-edit stops the next machine PR. Before a merge, nothing checks that the
8
- // file is still data only unless the repository runs its own check: the person who merges the PR
9
- // is the gate. Read a PR to this file as code, because it is code.
7
+ // data or the import differ, so a hand-edit there stops the next machine PR. Before a merge,
8
+ // nothing checks that the file is still data only unless the repository runs
9
+ // `npx oe build --check` or `npx oe overlays check`: the person who merges the PR is the gate.
10
+ // Read a PR to this file as code, because it is code.
10
11
  //
11
- // To change it by hand, edit only the data below and keep the layout exactly as emitted.
12
+ // To change it by hand, edit only the data below, then run `npx oe overlays normalize`.
12
13
 
13
14
  import type { GrantsFile } from "@open-everywhere/core/agent/access/grants-codemod.js";
14
15
 
@@ -3,7 +3,7 @@
3
3
  // per scope on the container ladder (org < tenant < domain < surface); an unpinned scope
4
4
  // inherits the nearest wider pin, and a scope no pin reaches at all resolves "none" — the same
5
5
  // egress posture every scope already has today. See docs/how-it-works/access-and-scoping.md in the Open Everywhere repository
6
- // (§ Network-access levels) and packages/core/agent/access/network-access.ts for the resolution
6
+ // (§ Network-access levels) and @open-everywhere/core/agent/access/network-access.js for the resolution
7
7
  // doctrine and exactly what "trusted" opens.
8
8
  //
9
9
  // LEFT EMPTY, DELIBERATELY. This ticket adds the CONFIG SHAPE — it does not widen this
@@ -1,5 +1,5 @@
1
1
  // Blob hosting — config-as-code, the org-level opt-in for PUBLISHING HTML artifacts to a
2
- // world-readable Vercel Blob URL from the post_file tool (packages/core/agent/tools/post_file.ts).
2
+ // world-readable Vercel Blob URL from the post_file tool (@open-everywhere/core/agent/tools/post_file.js).
3
3
  //
4
4
  // OFF BY DEFAULT. With `enabled:
5
5
  // false` — the shipped default — post_file NEVER hosts: an HTML artifact is attached to the
@@ -1,14 +1,15 @@
1
1
  // GENERATED + MACHINE-OWNED — DO NOT HAND-EDIT.
2
2
  //
3
3
  // The person-groups overlay: DATA ONLY. Written exclusively by the deterministic codemod
4
- // (packages/core/agent/identity/groups-codemod.ts) on a bot-PR branch; the PR merge is the approval gate.
4
+ // (@open-everywhere/core/agent/identity/groups-codemod.js) on a bot-PR branch; the PR merge is the approval gate.
5
5
  //
6
6
  // The codemod re-emits this file from its own parsed content and refuses to rewrite it when the
7
- // bytes differ, so a hand-edit stops the next machine PR. Before a merge, nothing checks that the
8
- // file is still data only unless the repository runs its own check: the person who merges the PR
9
- // is the gate. Read a PR to this file as code, because it is code.
7
+ // data or the import differ, so a hand-edit there stops the next machine PR. Before a merge,
8
+ // nothing checks that the file is still data only unless the repository runs
9
+ // `npx oe build --check` or `npx oe overlays check`: the person who merges the PR is the gate.
10
+ // Read a PR to this file as code, because it is code.
10
11
  //
11
- // To change it by hand, edit only the data below and keep the layout exactly as emitted.
12
+ // To change it by hand, edit only the data below, then run `npx oe overlays normalize`.
12
13
 
13
14
  import type { GroupsFile } from "@open-everywhere/core/agent/identity/groups-codemod.js";
14
15
 
@@ -81,7 +81,7 @@ for word: names, titles, tokens, times, the exact text to post or to schedule. "
81
81
  specified" or "the text they gave" points at nothing the worker can read. You never
82
82
  know the id of the page or channel you are on: the channel id is opaque, and a message
83
83
  id is not a page id. For a task about "this page", tell the worker to read the current
84
- page; never put an id you inferred
84
+ page (`page markdown current` on the notion-rest skill); never put an id you inferred
85
85
  into the brief. Name an id only when the person named it. Say you have handed it off, and report it done only when the worker's own report says it is done.
86
86
  That report can arrive after this turn ends.
87
87
 
@@ -175,7 +175,7 @@ applySubtreeSurfaceClaims();
175
175
  // the Neon Marketplace integration sets DATABASE_URL and nothing else, `getOperationalStore()` then
176
176
  // resolves to postgres, no client is ever registered, and the first audit append throws. The
177
177
  // scaffolded app is dead rather than degraded, and it mounts no status route to say why.
178
- // `scripts/scaffold-test.ts` reds if this returns to testing the two env names.
178
+ // The Open Everywhere repository's `packages/create/scripts/scaffold-test.ts` reds if this returns to testing the two env names.
179
179
  const operationalSelection = resolveOperationalSelection(process.env);
180
180
  const postgresSelected =
181
181
  resolveMemoryProviderId(process.env) === "postgres" ||
@@ -75,6 +75,11 @@ import "../identity/authors.js";
75
75
  // import degrades loudly (a routine that names a collector stops being creatable) rather than
76
76
  // silently widening anything.
77
77
  import "../routines/collectors.js";
78
+ // Side effect: register the deployment-wide half of the SHIPPED MANUAL (OPE-138, OPE-2215) so the
79
+ // read_docs tool serves the configuration reference, the security docs and the how-it-works pages.
80
+ // Each provider package registers its own setup runbook from register<X>Provider() instead. Drop
81
+ // this import and read_docs serves those runbooks and nothing else.
82
+ import "./register-docs.js";
78
83
 
79
84
  // The BEHAVIOUR half of config-as-code (OPE-371), registered FIRST — before registerConfig, and
80
85
  // before the boot-time cross-validations below — because a settings-sensitive gate consulted during
@@ -0,0 +1,17 @@
1
+ // Shipped-manual wiring (OPE-138) — hands core the deployment-wide half of the docs the agent can
2
+ // read about itself. SELF-REGISTERING: importing this module performs the registration, the same
3
+ // shape as agent/identity/surfaces.js (see register-config.ts, which imports both for their
4
+ // side effects, so every process that resolves config also carries the manual).
5
+ //
6
+ // This half is the UNIVERSAL manual. Each provider bundle registers its OWN setup runbook from its
7
+ // register<X>Provider(), so a de-selected bundle's docs are not in the import graph at all.
8
+ //
9
+ // The manual ships INSIDE `@open-everywhere/core` (OPE-2215), so this app serves the pages of the
10
+ // core version it installed, and an upgrade of core upgrades the manual with it. Nothing here is
11
+ // copied at scaffold time. To add your own pages, call registerDocs again with more entries. An
12
+ // entry with the same `path` as a shipped page replaces that page.
13
+
14
+ import { registerDocs } from "@open-everywhere/core/agent/adapter-api.js";
15
+ import { UNIVERSAL_DOCS } from "@open-everywhere/core/agent/docs/generated/index.js";
16
+
17
+ registerDocs(UNIVERSAL_DOCS);
@@ -1,14 +1,15 @@
1
1
  // GENERATED + MACHINE-OWNED — DO NOT HAND-EDIT.
2
2
  //
3
3
  // The agents overlay: DATA ONLY. Written exclusively by the deterministic codemod
4
- // (packages/core/agent/memory/agents-codemod.ts) on a bot-PR branch; the PR merge is the approval gate.
4
+ // (@open-everywhere/core/agent/memory/agents-codemod.js) on a bot-PR branch; the PR merge is the approval gate.
5
5
  //
6
6
  // The codemod re-emits this file from its own parsed content and refuses to rewrite it when the
7
- // bytes differ, so a hand-edit stops the next machine PR. Before a merge, nothing checks that the
8
- // file is still data only unless the repository runs its own check: the person who merges the PR
9
- // is the gate. Read a PR to this file as code, because it is code.
7
+ // data or the import differ, so a hand-edit there stops the next machine PR. Before a merge,
8
+ // nothing checks that the file is still data only unless the repository runs
9
+ // `npx oe build --check` or `npx oe overlays check`: the person who merges the PR is the gate.
10
+ // Read a PR to this file as code, because it is code.
10
11
  //
11
- // To change it by hand, edit only the data below and keep the layout exactly as emitted.
12
+ // To change it by hand, edit only the data below, then run `npx oe overlays normalize`.
12
13
 
13
14
  import type { AgentsFile } from "@open-everywhere/core/agent/memory/agents-codemod.js";
14
15
 
@@ -1,8 +1,8 @@
1
1
  // Off-Vercel sandbox backend selection — the app-side re-export of the PURE decision logic.
2
2
  //
3
- // The decision itself lives in core (`packages/core/agent/sandbox/backend-select.ts`) because
3
+ // The decision itself lives in core (`@open-everywhere/core/agent/sandbox/backend-select.js`) because
4
4
  // TWO packages need it and a rule has one home: this file wires it into `sandbox.ts`, and the
5
- // turn-end stop hook (`packages/adapters/agent/sandbox/backend-stop.ts`) reads the SAME answer
5
+ // turn-end stop hook (`@open-everywhere/adapters/agent/sandbox/backend-stop.js`) reads the SAME answer
6
6
  // through the adapter-api barrel to pick which backend owns the stop. A second parse of
7
7
  // `OE_SANDBOX_BACKEND` would let the backend that runs and the backend that stops disagree.
8
8
 
@@ -153,7 +153,7 @@ const VERCEL_CREATE_OPTIONS = vercelSandboxCreateOptions({
153
153
  // mid-session (the runtime firewall wouldn't allow it; the vendor tools additionally run with
154
154
  // autoInstall bound off). Unarmed it is {} — the definition below carries NO bootstrap /
155
155
  // revalidationKey property at all, byte-identical to the pre-capability shape. Rationale +
156
- // fail-closed matrix live in the adapter (packages/adapters/agent/browser/sandbox.ts).
156
+ // fail-closed matrix live in the adapter (@open-everywhere/adapters/agent/browser/sandbox.js).
157
157
  const AGENT_BROWSER_BAKE = agentBrowserSandboxHooks();
158
158
 
159
159
  function selfHostBackend() {
@@ -13,7 +13,7 @@
13
13
  //
14
14
  // EMPTY BY DEFAULT — with nothing declared here, nothing is checkpointed (Open Everywhere never
15
15
  // invents a threshold). This file is the seam a DB/dashboard would swap behind, same as
16
- // budgets.ts / memory/config/domains.ts. After adding a checkpoint: `npm run typecheck:all`
16
+ // budgets.ts / memory/config/domains.ts. After adding a checkpoint: `npm run typecheck`
17
17
  // (assertSpendCheckpointsValid runs at import time and throws on a malformed entry — bad scope
18
18
  // keys, unknown/typo'd fields, non-positive amounts).
19
19
  //
@@ -1,14 +1,15 @@
1
1
  // GENERATED + MACHINE-OWNED — DO NOT HAND-EDIT.
2
2
  //
3
3
  // The webhook-hooks overlay: DATA ONLY. Written exclusively by the deterministic codemod
4
- // (packages/core/agent/webhooks/hooks-codemod.ts) on a bot-PR branch; the PR merge is the approval gate.
4
+ // (@open-everywhere/core/agent/webhooks/hooks-codemod.js) on a bot-PR branch; the PR merge is the approval gate.
5
5
  //
6
6
  // The codemod re-emits this file from its own parsed content and refuses to rewrite it when the
7
- // bytes differ, so a hand-edit stops the next machine PR. Before a merge, nothing checks that the
8
- // file is still data only unless the repository runs its own check: the person who merges the PR
9
- // is the gate. Read a PR to this file as code, because it is code.
7
+ // data or the import differ, so a hand-edit there stops the next machine PR. Before a merge,
8
+ // nothing checks that the file is still data only unless the repository runs
9
+ // `npx oe build --check` or `npx oe overlays check`: the person who merges the PR is the gate.
10
+ // Read a PR to this file as code, because it is code.
10
11
  //
11
- // To change it by hand, edit only the data below and keep the layout exactly as emitted.
12
+ // To change it by hand, edit only the data below, then run `npx oe overlays normalize`.
12
13
 
13
14
  import type { HooksFile } from "@open-everywhere/core/agent/webhooks/hooks-codemod.js";
14
15
 
@@ -64,6 +64,23 @@ step 3, after the install puts the target's own copy on disk. The same text is i
64
64
  **Stop and ask the user** when the window holds a breaking change, an env change or a manual step.
65
65
  Those are decisions, not steps.
66
66
 
67
+ `--plan` also prints a **template drift** report. It compares every file the scaffold copied into
68
+ this app with the TARGET release's `@open-everywhere/create` template, and lists each one that
69
+ differs, with a one-line size of its diff. An upgrade changes only `package.json`, so a scaffolded
70
+ file stays as the old template wrote it. A stale copy can typecheck and build and still break the
71
+ deployment: the 0.1.2 `agent/lib/register-adapters.ts` registers no Postgres client on a bare
72
+ `DATABASE_URL`, so a Vercel+Neon deployment of 0.1.4 fails at its first write.
73
+
74
+ | Line | What to do |
75
+ | --- | --- |
76
+ | SYNC | a template-owned file — wiring, a script, `AGENTS.md`, `README.md`, `.env.example`, a skill. Plan to copy the target's file over this one, after you read the diff. |
77
+ | config | the app's own config-as-code. A difference is normal once the app is configured. Merge the template's change by hand only if the user wants it. |
78
+
79
+ The report never writes a file. If it says the drift check did not run, compare the files with the
80
+ target's template by hand. An installed core without the report prints none: `oe upgrade` runs the
81
+ INSTALLED core's code. So when `--plan` prints no "Template drift" heading, run
82
+ `npx oe upgrade --to <target> --plan` once more after step 3. The target's own code prints the report then.
83
+
67
84
  ## 3. Run the upgrade
68
85
 
69
86
  ```
@@ -95,10 +112,18 @@ survives `rm -rf node_modules && npm ci`.
95
112
  Never delete the marker to make `oe upgrade` say there is nothing to do. It is the only record
96
113
  that a run began taking the target and never proved the tree.
97
114
 
98
- **If it refuses with "the release notes name codemods this CLI does not hold":** the codemod ships
99
- in a newer core than the one you are running. Upgrade in ONE step to a version that holds it, or
100
- apply those migrations by hand. Do not work around the refusal — it exists because a half-applied
101
- migration that reports success is worse than a stop.
115
+ **If it refuses with "the release notes name codemods this CLI does not hold":** the running core
116
+ is 0.1.4, and it runs codemods from its own registry. When it stops after the install, the
117
+ target's own `oe` is installed now. Run `oe upgrade` again: the resume marker keeps the window, and
118
+ the target's registry applies the codemod. Apply the migration by hand only if that run refuses
119
+ too. Do not work around the refusal — it exists because a half-applied migration that reports
120
+ success is worse than a stop. A later core only WARNS with that text before the install, because
121
+ the target's own registry decides.
122
+
123
+ **If it refuses with "the installed core's registry does not hold":** the target release names a
124
+ codemod that it does not ship, and no codemod ran. Run `oe upgrade --to <a later release that holds
125
+ it>`. The resume marker keeps the refused release in that run's window, so that run applies the
126
+ codemod. Do not delete the marker to get past this refusal.
102
127
 
103
128
  ## 4. Review the diff
104
129
 
@@ -115,6 +140,18 @@ is the review surface, and it is the only one.
115
140
  Then run the app's own checks once more if anything above was fixed by hand:
116
141
  `npm run typecheck && npm run build`.
117
142
 
143
+ Then act on the template drift report. A core that carries it prints it again after the install;
144
+ if this run printed no "Template drift" heading, run `npx oe upgrade --to <target> --plan` now to get it. For
145
+ each SYNC line, read the diff against the installed template, for example
146
+ `diff node_modules/@open-everywhere/create/template/agent/lib/register-adapters.ts agent/lib/register-adapters.ts`.
147
+ Keep any edit the user made on purpose, and copy the template's file otherwise. A file under the
148
+ template's `claude/` directory lands in the app's `.claude/`, and the template's `gitignore` is the
149
+ app's `.gitignore`. Name every synced file in the pull request.
150
+
151
+ Run `npx oe build --check`. It also proves the machine-owned `*.generated.ts` overlays hold only
152
+ data. If it says an overlay has older header text, that is not a failure: run
153
+ `npx oe overlays normalize` and commit the header change with the upgrade.
154
+
118
155
  ## 5. Open a pull request
119
156
 
120
157
  Commit on a branch, never on the default branch. The body carries:
@@ -124,6 +161,7 @@ Commit on a branch, never on the default branch. The body carries:
124
161
  - what changed in `roster.lock.json`, in your own words;
125
162
  - **the env names the deployment needs before this merges**, names only;
126
163
  - the manual steps, and who does each one.
164
+ - the template files you synced, and each SYNC line you left as it is, with the reason.
127
165
 
128
166
  Then stop. The admin reviews the lock diff and merges. The merge deploys.
129
167