diff --git a/documentation/solid-2.0/04-stores.md b/documentation/solid-2.0/04-stores.md
index 19b859ad98..09effefcec 100644
--- a/documentation/solid-2.0/04-stores.md
+++ b/documentation/solid-2.0/04-stores.md
@@ -167,6 +167,8 @@ setStore(s => {
This pairs naturally with `createProjection`, where returning a value from the derive function uses reconciliation automatically (keyed by `options.key`, default `"id"`).
+Don't keep mutating an object after handing it to a store. A later in-place change to that object isn't observed, and assigning or reconciling the same object again doesn't pick it up either, because the store sees the same reference. Pass a fresh object instead (a new response, or a copy such as `{ ...next }`). This mostly affects test fixtures and caches that reuse one response object.
+
### Shallow stores (`shallow: true`)
By default stores track at property level all the way down — that is the model, and it is the right choice for almost all state. `shallow: true` is a **specialized performance opt-in** for one identifiable workload shape, not a general recommendation: reach for it when profiling shows ingestion cost on data whose records change wholesale.
diff --git a/documentation/solid-2.0/07-dom.md b/documentation/solid-2.0/07-dom.md
index 34d471747f..836f198a7b 100644
--- a/documentation/solid-2.0/07-dom.md
+++ b/documentation/solid-2.0/07-dom.md
@@ -93,6 +93,8 @@ let el;
(el = node), autofocus]} />; // assigned
```
+A ref runs before the element is inserted into the page. At that point `el.isConnected` is `false`, and `el.ownerDocument` is the inert document of the template the element was cloned from, so `el.ownerDocument.defaultView` is `null`. Don't reach the window or document through the element inside a ref: use the global `window`/`document`, or do work that needs the attached element (measuring, reading computed styles) in `onSettled`.
+
#### Two-phase directive factories (owned setup, unowned application)
The recommended directive pattern is **two-phase**, similar in spirit to “split effects” (compute phase vs apply phase):
diff --git a/documentation/solid-2.0/MIGRATION.md b/documentation/solid-2.0/MIGRATION.md
index af0b280069..9f214499eb 100644
--- a/documentation/solid-2.0/MIGRATION.md
+++ b/documentation/solid-2.0/MIGRATION.md
@@ -1009,6 +1009,8 @@ const value = createMemo(async function* () {
});
```
+Cleanup is not immediate. When the owner is disposed, or a re-run replaces the stream, Solid calls the generator's `return()`, but a generator waiting at an `await` can't finish until that `await` settles. The source stays subscribed until it produces another value or ends. If the memo only forwards values, return the iterable itself (`createMemo(() => observable$)`): Solid closes it right away. A source that isn't an async iterable (a callback subscription, an Observable) needs an adapter (see #4182, which also tracks prompt cleanup for generators).
+
**Solid → External (`observable`):** There's no drop-in replacement. `observable()` produced a standard Observable that external libraries could subscribe to. In 2.0, use `createEffect` to push signal changes to an external subscriber:
```js
diff --git a/packages/solid/CHEATSHEET.md b/packages/solid/CHEATSHEET.md
index f596d7f020..5bbfc7c0c8 100644
--- a/packages/solid/CHEATSHEET.md
+++ b/packages/solid/CHEATSHEET.md
@@ -33,6 +33,7 @@ import {
createOptimisticStore,
isPending,
latest,
+ createDeferred,
refresh,
affects,
untrack,
@@ -225,6 +226,11 @@ const user = createMemo(() => fetchUser(id()));
// Peek at the in-flight value during a transition
latest(id);
+// A memo that may lag but never leads (React's useDeferredValue): after its
+// first answer, a refetch keeps the last value on screen instead of holding
+// the change; isPending(() => rows()) reports the refetch.
+const rows = createDeferred(() => fetchRows(period()));
+
// Force recompute of a derived read after a server write.
// Action: call from handlers/effects/actions, not pure reads.
// A bare refresh() re-asks the SAME question — it is quiet (isPending stays
@@ -441,6 +447,8 @@ hydrate(() => , document.getElementById("root")!);
```
+A ref runs before the element is attached: `el.isConnected` is `false` and `el.ownerDocument.defaultView` is `null`. Use the global `window`/`document`, or do layout-dependent work in `onSettled`.
+
Two-phase directive (recommended):
```ts
diff --git a/packages/solid/skills/reactivity-diagnostics/SKILL.md b/packages/solid/skills/reactivity-diagnostics/SKILL.md
index e1e211d4d7..77d70355f5 100644
--- a/packages/solid/skills/reactivity-diagnostics/SKILL.md
+++ b/packages/solid/skills/reactivity-diagnostics/SKILL.md
@@ -173,7 +173,8 @@ return a cleanup function from the callback instead.
### SETTLED_CLEANUP_UNOWNED
`onSettled` returned a cleanup while running in an unowned scope, so the
-cleanup cannot be honored. Call the setup helper from an owned scope (the
+cleanup cannot be honored. Throws in dev; in production the cleanup is
+dropped. Call the setup helper from an owned scope (the
component body), not from an event handler, tracked effect, or another
`onSettled`.