# Squeak & Pharo (image-based Smalltalk) — deep dive (findings) **Date:** 2026-06-14 · **Source:** SHARD-WP-0004 **T6 (Squeak)** + **T8 (Pharo)** — combined (justified merge: both are image-based Smalltalks; Pharo is T8's "context for T6/T7," kept brief per the workplan). · **Subject:** the **image-based live-object** environment and what it teaches (and warns) about shard-wiki's page model. ## Why this dive (and why merged) Squeak (1996, the Alan Kay/Ingalls lineage) and Pharo (2008 fork, the substrate **Glamorous Toolkit** T7 runs on) are the same idea: **a persistent world of live objects, the "image," with no file/document/application boundary.** They are **not candidate shards** — they are the **anti-pattern boundary** for shard-wiki's files-canonical stance *and* the inspiration behind moldable inspection (T7). T8 (Pharo) is folded here as the workplan allows: its distinct contribution over Squeak (Tonel/Iceberg file-based code → git) is the one piece that *does* touch our concerns, covered in §3. ## 1. The image: knowledge-as-live-objects - A Smalltalk **image** is a serialized snapshot of the **entire object memory** — every object, class, tool, window, and the running program state — persisted as one binary file (`.image` + `.changes` log). You resume exactly where you left off. - **"Everything is a live object"**: code, data, UI (Morphic), the debugger, the inspector — all are objects you can open, message, and modify *in place*, while running. There is **no edit/compile/run cycle** and **no document-vs-app distinction**. - The **inspector** lets you open any object and explore/modify its state live — the direct ancestor of GT's moldable inspector (T7), but generic rather than domain-molded. This is the **purest "live" end** of the spectrum the whole batch traverses: literate source (static) → notebook captured output (snapshot) → GT/Lepiter (live results over files) → **image (everything live, nothing inherently a file).** ## 2. The boundary: image-as-store is the anti-pattern The image directly **contradicts** shard-wiki's design constraints, which is exactly why it's worth recording as a hard boundary: - **Opaque, monolithic, non-diffable.** The image is one big binary blob of entangled live state — no per-page identity, no text diff, no mergeable history, no provenance per unit. It violates *union-without-erasure granularity*, *Markdown-first*, and *git-addressable coordination*. - **No stable addressable "page."** Knowledge is an object graph in memory, not addressable documents — there is nothing to attach at page granularity without an export step. - **History is a `.changes` log**, a serial source-change stream, not a content history. **Conclusion (boundary recorded):** an image is **not a shard and not a store**. This is the generalized form of the rule already hit at Jupyter (UC-84) and GT (T7): *attach the exported files, never the live image/kernel.* The image can only participate via an **export projection** (objects/code → files), which is a **derivation-projection** (T1) that **degrades the liveness to a static snapshot**. ## 3. Pharo's twist: code-as-files (Tonel) → git (the one actionable bit) Pharo (T8) matters precisely where it **retreats from pure-image**: - **Tonel / FileTree** serialize each class/method as **plain-text files** in a directory, and **Iceberg** manages those files as a **git repository** — so Pharo code lives in git as text, diffable and mergeable, *outside* the image. - This is the **same move** as Lepiter (T7), nbstripout/Jupytext (T3), and ikiwiki source (UC-79): **the durable, attachable artifact is the file representation; the live environment is a layer above it.** It confirms our stance from the *Smalltalk* side: even the most image-centric tradition externalizes to **git-versionable text** to collaborate. So Pharo adds **no new page-model idea** beyond "image-based environments still externalize to git text" — exactly the "keep brief / fold" expectation. Its value is **confirming the boundary resolution**: attach the **Tonel/git source**, treat the image as live-only. ## 4. INTENT mapping ### Inspiration (keep) - **Live-object inspection** is the seed of moldable views (T7/UC-54): the *idea* that any unit can be opened and explained interactively. shard-wiki adopts this as **projection/ view**, not as a storage model. - **Resume-where-you-left-off** liveness names the far end of the **live↔snapshot** axis the contract must place every computed/projected view on (UC-83/84): the more live the source, the more its attached form is a **degrading snapshot**. ### Boundary (enforce — design-bug if violated) - **Image-as-store is a design-bug boundary.** Never model an image (or any monolithic live memory blob) as a shard/store; participate only via **export → files** (a degrading derivation-projection). Generalizes "attach files, not the kernel/image" (UC-84, T7). ### Confirmation (Pharo) - Even pure-image traditions externalize to **git-versionable text** (Tonel/Iceberg) to version and collaborate — reinforcing **files-canonical + git coordination** as the durable substrate; the live environment sits above it. ## 5. UC disposition (enrichment-only — no new UC) | Mechanism (findings §) | Catalog UC / thread | |------------------------|---------------------| | Live-object inspector = generic ancestor of moldable views (§1) | links UC-54, UC-47/48 (T7) | | Image = opaque monolithic non-diffable blob; not a page/store (§2) | **boundary** for UC-34/UC-35/UC-79 (granularity, identity, files-canonical) | | Image participates only via export→files = degrading derivation-projection (§2) | links UC-83, UC-84 (live→snapshot) | | Pharo Tonel/Iceberg: code-as-text in git (§3) | links UC-79, UC-76 (git-canonical text) | | `.changes` = serial source-change log, not content history (§1) | links UC-36 (history shape) | Both Squeak and Pharo are **design prior art / boundary**, not candidate shards → **no new UC**. They sharpen the **live↔snapshot** axis and harden the **image-is-not-a-store** boundary; Pharo confirms even image traditions externalize to git text. ## 6. Architecture notes for SHARD-WP-0002 - **T14 (attach binding):** record the **image-is-not-a-store** boundary explicitly — a monolithic live-memory blob is never an attach target; participation is via **export→files** only. Generalize the "attach files, not the kernel/image" rule (UC-84, GT T7) to a named boundary in the binding taxonomy. - **T16 (projection):** add the **live↔snapshot** axis to the projection model — every computed/projected view sits somewhere between "live (re-derivable on demand)" and "static snapshot," and the more live the source, the more its attached form must be a clearly- marked degrading snapshot. - **T11/T12:** the live-object inspector is the *inspiration* for the moldable view registry (T7), not a storage shape; nothing new to the page model itself. ## 7. Open questions 1. Is **live↔snapshot** an explicit, first-class metadata axis on every projection (so the union can label "this view was live / is a snapshot from time T"), or implicit per capability? (Recurs across UC-83/84, GT, Mathematica `Dynamic`, Strudel T5.) 2. Do we ever ingest a Smalltalk project by attaching its **Tonel/git** repo as an ordinary git-text shard (no Smalltalk-specific adapter needed), confirming the boundary resolution? ## 8. Sources - Squeak: `squeak.org`, the *Back to the Future* (Squeak) paper (Ingalls et al.), Morphic; image/`.changes` model. - Pharo: `pharo.org`, **Tonel** format, **Iceberg** (git integration), FileTree. - prior: `research/260614-glamorous-toolkit-deep-dive/` (moldable inspector, Lepiter, T7); `research/260614-jupyter-deep-dive/` (live→snapshot boundary, UC-84). ## 9. Traceability **No new UC** (boundary / design prior art; covers **T6 Squeak** and **T8 Pharo** in one justified-merge memo). Boundary hardened for: UC-34/UC-35/UC-79 (image-is-not-a-store); links UC-83/UC-84 (live→snapshot), UC-54/UC-47/UC-48 (live-object inspection → moldable views), UC-76/UC-79 (Pharo Tonel/git text), UC-36 (`.changes` history shape). Architecture cross-refs: SHARD-WP-0002 T14 (image-is-not-a-store boundary; export→files only), T16 (live↔snapshot projection axis).