---
title: "Cohomology explanation"
description: "Cohomology explanation - URL: https://chatgpt.com/c/6a80c2b6-9b30-83ea-92f6-6ae7f97b2473 - Created: 2026-08-15T19:49:20.936Z --- What’s cohomology Cohomology is a mathematical tool for detecting a…"
doc_version: 1
last_updated: 2026-10-17
canonical_url: "http://parc.yolo.scapegoat.dev/note/transcripts/2026/08/15/chatgpt-transcript-cohomology-explanation"
---

# Cohomology explanation

Cohomology explanation - URL: https://chatgpt.com/c/6a80c2b6-9b30-83ea-92f6-6ae7f97b2473 - Created: 2026-08-15T19:49:20.936Z --- > What’s cohomology Cohomology is a mathematical tool for detecting a…

## Content

# Cohomology explanation

- URL: https://chatgpt.com/c/6a80c2b6-9b30-83ea-92f6-6ae7f97b2473
- Created: 2026-08-15T19:49:20.936Z

---

> What’s cohomology

**Cohomology** is a mathematical tool for detecting and describing the “holes” and global structure of a space.

A rough intuition:

- A **0-dimensional hole** relates to disconnected pieces.
- A **1-dimensional hole** is like the hole in a circle.
- A **2-dimensional hole** is like the enclosed cavity inside a hollow sphere.

For example, a circle has one important 1-dimensional hole, while a solid disk doesn’t.

More formally, cohomology assigns groups (or vector spaces) to a space:

$$
H^0(X),\ H^1(X),\ H^2(X),\ldots
$$

These groups encode information about the space that survives stretching and bending, as long as you don’t tear or glue it.

Cohomology is closely related to **homology**, but it has extra algebraic structure: cohomology classes can be multiplied using the **cup product**. That extra structure often lets cohomology distinguish spaces that homology alone cannot.

If you want, I can explain cohomology **visually/intuitively**, starting from circles, spheres, and tori, without assuming abstract algebra.


---

> Cohomilogy of REST APIs or like, if certain parameters are enough to cover some kind of information or ensure some transactional invariant

There isn’t a standard “cohomology of REST APIs” in ordinary software engineering, but there is a mathematically precise way to use cohomological ideas for exactly the kind of question you’re describing: whether locally supplied data can be glued into a globally consistent state, and whether an invariant can be satisfied across overlapping pieces.

```json
{"system1_search_query":[{"q":"site:arxiv.org sheaf cohomology distributed systems consistency data integration"},{"q":"site:arxiv.org sheaf data consistency databases cohomology"},{"q":"site:ncatlab.org cohomology obstruction gluing local global sheaf"},{"q":"site:arxiv.org cohomology obstruction consistency distributed database"}],"response_length":"medium"}
```

<details><summary>💭 Thinking</summary>

**Searched 3 websites**

**Modeling API consistency**

I’m distinguishing two ideas: global sections can represent globally consistent parameter assignments, while higher cohomology may capture obstruction patterns. For parameter sufficiency itself, functional dependencies, schema constraints, refinement types, or formal verification are usually more direct.

**Modeled API consistency**

</details>

Yes. What you’re describing has a real mathematical analogue, but **sheaf theory / sheaf cohomology** is the more relevant formulation than ordinary topological cohomology.

A useful translation is:

> **API parameters give local information; can those local pieces be combined into a global state satisfying all system invariants?**

That is almost exactly the local-to-global problem sheaves were designed to formalize. Recent work explicitly uses sheaves this way for distributed computation and constraint-satisfaction problems. citeturn210946search1turn210946academia73

### REST API example

Suppose an order system has:

```text
POST /reserve
  orderId, sku, quantity

POST /charge
  orderId, amount, currency

POST /ship
  orderId, address
```

and globally you require

$$
\text{chargedAmount} = \text{orderTotal}
$$

$$
\text{reservedQuantity} \geq \text{orderedQuantity}
$$

$$
\text{shipped} \Rightarrow \text{paid}
$$

Each endpoint sees only part of the total state:

$$
U_R = \{\text{order},\text{inventory}\}
$$

$$
U_C = \{\text{order},\text{payment}\}
$$

$$
U_S = \{\text{order},\text{shipping}\}
$$

Think of each endpoint as producing a **local section**:

$$
s_R\in F(U_R),\quad
s_C\in F(U_C),\quad
s_S\in F(U_S).
$$

Where endpoints overlap—for example both `/reserve` and `/charge` know `orderId`, `orderVersion`, and perhaps `orderTotal`—you have restriction maps:

$$
F(U_R)\rightarrow F(U_R\cap U_C)
$$

and

$$
F(U_C)\rightarrow F(U_R\cap U_C).
$$

You ask whether they agree:

$$
s_R|_{U_R\cap U_C}
=
s_C|_{U_R\cap U_C}.
$$

Do this for all the overlaps.

The key question then becomes:

$$
\boxed{\text{Do these locally valid API states correspond to one globally valid system state?}}
$$

A **global section**

$$
s\in F(X)
$$

is precisely such a globally consistent assignment. This local-to-global interpretation is standard sheaf language. citeturn210946search11turn210946search12

And this is where cohomology becomes interesting. In suitable formulations, nontrivial cohomological classes can represent **obstructions** to obtaining a global solution from locally consistent information. This has been developed explicitly for distributed systems and constraint satisfaction. citeturn210946search10turn210946academia73

So you could imagine an API architecture having something analogous to

$$
H^0 \quad\text{= globally consistent configurations}
$$

while higher cohomological information detects certain global obstructions or degrees of inconsistency. The exact interpretation depends on how you construct the sheaf/presheaf; one shouldn't simply say “$H^1$ = API bugs” in general. In specific computational sheaf constructions, however, $H^1$ can encode independent global-consistency obstructions. citeturn210946search16

### But for “are these parameters enough?”, there is a simpler tool

If your question is specifically:

> Given parameters $P=\{p_1,\ldots,p_n\}$, are they sufficient to determine/verify invariant $I$?

then **functional dependencies, constraint satisfaction, information flow, or logic** are usually more direct than cohomology.

For example, suppose:

```text
/charge(orderId, amount)
```

must guarantee

$$
amount = price \times quantity.
$$

If you know

$$
orderId\rightarrow(price,quantity)
$$

because `orderId` uniquely determines the immutable order state, then

$$
\{orderId,amount\}
$$

contains enough information to verify the invariant.

But if prices are versioned,

$$
orderId\nrightarrow price,
$$

while

$$
(orderId,version)\rightarrow(price,quantity),
$$

then your parameter set is insufficient. You need something like

```text
orderId
orderVersion
amount
```

to establish the invariant without ambiguity.

That problem can be phrased as computing the **closure** of the supplied information:

$$
P^+
$$

under all known dependencies and asking

$$
\operatorname{Vars}(I)\subseteq P^+.
$$

That is probably the cleanest formal notion of **parameter sufficiency**.

Then sheaf/cohomological machinery becomes valuable when the problem gets distributed:

$$
\boxed{
\text{parameter sufficiency locally}
\quad+\quad
\text{compatibility across endpoints}
\quad+\quad
\text{existence of a global invariant-satisfying state}
}
$$

In other words, I think your intuition is pointing toward a potentially useful abstraction:

$$
\textbf{API surface}
\rightarrow
\textbf{cover of system state}
\rightarrow
\textbf{local constraints}
\rightarrow
\textbf{global sections / obstructions}.
$$

There is even research showing that database JOIN/data-merging problems can have genuine topological obstruction formulations, so this isn't merely a metaphor. citeturn210946academia71

If you're thinking about this as an **API design/static-analysis technique**, I can formalize a small “cohomology of an API” model—endpoints as a cover, parameters as observable coordinates, invariants as constraints, and a computable test for whether the API surface is sufficient to enforce them.


---

> Motivate and apply presheaf / sheaf to the following software I’ve been building so I can start to understand what they are and what cohomology is and bridge software engineering with some “multidimensional topological-esque shapes” intuitions I see in my head but I’m a software developer just getting into abstract maths but I know there is something there to look at more closely. Feel free to clone the repo and look more closely, you can also download the markdown of any page on parc.yolo by appending .md
>
> https://parc.yolo.scapegoat.dev/note/research/software-architecture-garden/sessionstream/readme

I’ll ground this in your actual architecture rather than give you a generic category-theory lecture. I’m going to inspect the SessionStream notes and the linked repo, then map concrete software objects in it to presheaves, sheaves, Čech-style overlap data, and eventually cohomological “obstructions.”

```json
{"open":[{"ref_id":"https://parc.yolo.scapegoat.dev/note/research/software-architecture-garden/sessionstream/readme.md"},{"ref_id":"https://parc.yolo.scapegoat.dev/note/research/software-architecture-garden/sessionstream/readme"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 1 website**

</details>

```unknown
git clone --depth 1 https://github.com/go-go-golems/sessionstream.git /mnt/data/sessionstream
```

```json
{"paths":["GitHub"],"query":"repository"}
```

<details><summary>💭 Thinking</summary>

**Cloned the sessionstream repository**

</details>

```python3
{"path":"/GitHub/link_694554034b848191ab0db5a14b130105/get_repo","args":{"repository_full_name":"go-go-golems/sessionstream"}}
```

<details><summary>💭 Thinking</summary>

**Inspected Sessionstream repository structure, projections, hydration, hub, and WebSocket schema**

</details>

One useful thing already jumps out: your notes are naturally written in “local-to-global” language even though they don’t call it that. `SessionId` partitions state into scopes, projections expose partial views, snapshots represent prefix cuts, and reconnect correctness asks whether separately obtained observations fit one coherent history. That is exactly the terrain where sheaf language becomes more than decoration.

```python3
{"path":"/GitHub/link_694554034b848191ab0db5a14b130105/fetch_file","args":{"repository_full_name":"go-go-golems/sessionstream","path":"pkg/sessionstream/hub.go","ref":"main","start_line":1,"end_line":360}}
```

<details><summary>💭 Thinking</summary>

**Inspected SessionStream Hub implementation and hydration SQLite interfaces**

</details>

```json
{"system1_search_query":[{"q":"site:stacks.math.columbia.edu sheaf presheaf definition restriction maps sections open subsets"},{"q":"site:stacks.math.columbia.edu Cech cohomology sheaf cover definition"},{"q":"site:arxiv.org sheaf distributed systems consistency local global obstruction cohomology"},{"q":"site:arxiv.org cellular sheaves data fusion distributed systems consistency"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 2 websites**

</details>

```python3
{"path":"/GitHub/link_694554034b848191ab0db5a14b130105/fetch_file","args":{"repository_full_name":"go-go-golems/sessionstream","path":"pkg/sessionstream/transport/ws/server.go","ref":"main","start_line":1,"end_line":360}}
```

<details><summary>💭 Thinking</summary>

**Fetched WebSocket subscription handling and SQLite snapshot store implementation**

**Building the analogy**

I’m framing SessionStream as a space of observation contexts: vertices represent views, edges overlaps, and higher simplices multi-way consistency. A presheaf assigns data to each context; restriction maps compare views, while cohomology detects global gluing obstructions.

**Built the analogy**

**Expanding the model**

I’m noting that time alone forms a simple chain, so richer structure comes from combining time with projections, replicas, clients, and storage views. Their overlaps create squares, triangles, and higher-dimensional simplices where consistency can be studied.

</details>

```json
{"click":[{"ref_id":"turn861691view1","id":1}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searching the web**

</details>

The most useful distinction for your codebase is this: **a presheaf is “all the ways I can look at or forget part of a system”; a sheaf adds a law saying compatible partial views can be assembled into one coherent whole.** Your snapshot/hydration path already contains an operational version of that gluing law, while your open atomicity/cut obligations are examples of places where the gluing law is not yet guaranteed.

```python3
{"path":"/GitHub/link_694554034b848191ab0db5a14b130105/fetch_file","args":{"repository_full_name":"go-go-golems/sessionstream","path":"pkg/sessionstream/schema.go","ref":"main","start_line":1,"end_line":300}}
```

<details><summary>💭 Thinking</summary>

**Inspected local schema typing**

</details>

```json
{"open":[{"ref_id":"turn233951academia24"},{"ref_id":"turn233951academia26"},{"ref_id":"turn233951academia27"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 1 website**

</details>

Yes. There is a fairly precise mathematical object hiding behind the intuition you’re describing.

I inspected the Architecture Garden entry and the current `sessionstream` source through GitHub. Your system is an unusually good teaching example because it already revolves around **partial views of one underlying execution**: canonical events, projection state, materialized entities, snapshot cuts, projection cursors, live UI batches, and client-visible state. The Garden entry also explicitly identifies the hard parts as consistent cuts, atomic projection progress, deterministic replay, retry identity, and snapshot-plus-suffix completeness. citeturn861691view1

The bridge I would use is:

$$
\boxed{
\text{software contexts}
\longrightarrow
\text{presheaf}
\longrightarrow
\text{compatible local views}
\longrightarrow
\text{sheaf}
\longrightarrow
\text{global sections}
\longrightarrow
\text{cohomological obstructions}
}
$$

The important point is that **the “space” need not be physical space**.

---

## Start with the software meaning of a presheaf

Forget topology for a minute.

Suppose there is some complete system state $X$, but no component sees all of it.

One component sees:

$$
U=\{\text{SessionId},\text{event log},\text{event cursor}\}
$$

another sees:

$$
V=\{\text{SessionId},\text{timeline entities},\text{projection cursor}\}
$$

and another sees:

$$
W=\{\text{SessionId},\text{snapshot ordinal},\text{snapshot entities}\}.
$$

For every such context $U$, define

$$
\mathcal F(U)
=
\{\text{all locally valid states observable in context }U\}.
$$

Now suppose $V$ contains more information than some smaller context $A$. There is an obvious operation

$$
\rho^V_A:\mathcal F(V)\to\mathcal F(A)
$$

which means:

> **forget everything except what $A$ can see.**

That is a **restriction map**.

Mathematically, that is essentially the definition of a presheaf: assign some object $\mathcal F(U)$ to every context, and whenever $V\subseteq U$, provide a compatible restriction map $\mathcal F(U)\to\mathcal F(V)$. Equivalently, a presheaf is a contravariant functor from your category of contexts. citeturn233951search0turn233951search2

In software terms:

| Mathematics | Software intuition |
|---|---|
| base space / site / poset | your collection of information contexts |
| region $U$ | what some subsystem/request/transaction can observe |
| $\mathcal F(U)$ | valid states/values/traces over that context |
| section $s\in\mathcal F(U)$ | one concrete locally valid observation |
| restriction $s|_V$ | forget fields, project a view, truncate history |
| cover $U_1,\ldots,U_n$ | components/endpoints that collectively see the system |
| overlap $U_i\cap U_j$ | information both components know |
| global section | one coherent end-to-end system state/execution |
| sheaf condition | compatible partial states uniquely assemble |
| cohomology | algebraic information about failures/ambiguities of local-to-global assembly |

That table is probably the most useful Rosetta stone for you.

---

# What changes when a presheaf becomes a sheaf?

A presheaf merely says:

> I have partial views and know how to forget information.

A **sheaf** adds a very strong integration law.

Suppose

$$
U=U_1\cup U_2\cup\cdots\cup U_k
$$

and you have locally valid states

$$
s_i\in\mathcal F(U_i).
$$

Whenever two pieces overlap, require that they agree:

$$
s_i|_{U_i\cap U_j}
=
s_j|_{U_i\cap U_j}.
$$

The sheaf condition says that if all those local pieces agree on their overlaps, then there exists a **unique**

$$
s\in\mathcal F(U)
$$

whose restrictions are exactly those pieces.

That's the formal gluing axiom. citeturn233951search9

As a software developer, I would initially read:

$$
\boxed{\text{sheaf} \approx \text{lossless, unambiguous composition of compatible partial information}}
$$

This is close to a lossless JOIN intuition.

If API A tells you about `(orderId, amount)`, API B tells you about `(orderId, currency)`, and API C tells you about `(orderId, account)`, restriction means projecting down to the fields they share.

The sheaf question is:

> If all three agree wherever their data overlaps, is there exactly one globally coherent transaction they describe?

Sometimes yes.

Sometimes there are several possible global states.

Sometimes there are none.

Those distinctions are mathematically meaningful.

---

# This gives a precise formulation of your original “are these API parameters enough?” question

Let $X$ denote all semantic information that matters to an operation, and let $P\subseteq X$ denote the parameters an API call actually supplies.

There is a restriction:

$$
r_P:\mathcal F(X)\to\mathcal F(P).
$$

If the request contains payload $p\in\mathcal F(P)$, look at its **fiber**

$$
r_P^{-1}(p)
=
\{s\in\mathcal F(X)\mid s|_P=p\}.
$$

This is a very useful API-design object.

If

$$
r_P^{-1}(p)=\varnothing,
$$

the request is inconsistent: there is no possible global state corresponding to it.

If

$$
|r_P^{-1}(p)|=1,
$$

the supplied parameters uniquely determine the relevant global state.

If it contains many possibilities, the API has left something underdetermined.

And if you're interested only in invariant $I$, rather than the entire global state, then you need something slightly weaker:

$$
I(s_1)=I(s_2)
\qquad
\forall s_1,s_2\in r_P^{-1}(p).
$$

In words:

> **The parameters are sufficient to decide invariant $I$ exactly when every possible global completion of those parameters gives the same answer for $I$.**

That's already an interesting formal method for API design, before we touch cohomology.

---

# Now apply this directly to `sessionstream`

Your core types make the partial-view structure unusually visible.

An `Event` currently contains `Name`, `Payload`, `SessionId`, and `Ordinal`; a `Session` contains its identity and metadata. fileciteturn2file0L2

Meanwhile a timeline projection sees

$$
(\text{event},\text{session},\text{TimelineView})
$$

and emits `TimelineEntity` values; a UI projection sees the same sort of pre-event context and emits `UIEvent`s. fileciteturn3file0L2

And hydration introduces another family of views:

$$
\text{Snapshot}
=
(\text{SessionId},\text{SnapshotOrdinal},\text{Entities}).
$$

The store separately exposes event cursors, projection cursors, snapshots, event replay, and materialized state. fileciteturn7file0L2

So don't imagine one state object.

Imagine a family of overlapping coordinate charts on an execution.

---

## A useful “space” for SessionStream

I would define an observation context roughly as

$$
C=(s,n,K),
$$

where

- $s$ is a session,
- $n$ is an event-prefix/cut coordinate,
- $K$ says which kinds of information are visible.

For example $K$ might contain some subset of

$$
\{
E,T,S,U,C
\}
$$

where

$$
E=\text{canonical event history},
$$

$$
T=\text{timeline/materialization},
$$

$$
S=\text{snapshot},
$$

$$
U=\text{live UI stream},
$$

$$
C=\text{client-observed state}.
$$

Then there are two very natural kinds of restriction maps.

You can **forget an observation dimension**:

$$
(s,n,\{E,T,S\})
\rightarrow
(s,n,\{T,S\}),
$$

or you can **move backward in time**:

$$
(s,n,K)\rightarrow(s,m,K),
\qquad m\le n.
$$

That gives you something richer than a line.

You have approximately

$$
\text{session}
\times
\text{event time}
\times
\text{observer/context}.
$$

This is where the “multidimensional shape” intuition starts becoming legitimate.

---

# The topological-looking shape is the pattern of overlaps

Here's a toy architecture complex, not a claim that this is the uniquely correct model:

```text
             Timeline
             T
            / \
           /   \
          E     S
   Event  |     |  Snapshot
          |     |
          U-----C
       Live UI  Client
```

Think of the vertices as information contexts.

An edge means:

> These two contexts have some common semantic information whose agreement matters.

For example:

$$
E\leftrightarrow T
$$

shares session/prefix/projection-progress information.

$$
T\leftrightarrow S
$$

shares materialized entities and their cut.

$$
S\leftrightarrow C
$$

shares the snapshot delivered to the client.

$$
E\leftrightarrow U
$$

shares the canonical event ordinal associated with projected UI output.

$$
U\leftrightarrow C
$$

shares live observations.

Now the shape has a loop.

That loop is already a 1-dimensional topological feature.

If three contexts can be jointly observed/validated, you add a filled triangle. Four-way joint contexts produce tetrahedron-like simplices, and so forth.

So:

> **Dimension here means order of simultaneous compatibility, not physical dimension.**

A vertex represents one local context.

An edge represents pairwise compatibility.

A triangle represents a genuine three-way compatibility witness.

A tetrahedron represents four-way compatibility.

That is probably close to the multidimensional object you've been intuiting.

There is contemporary distributed-systems work doing essentially this: representing local knowledge/indistinguishability with cellular structures, attaching sheaf data to them, and characterizing valid distributed solutions as global sections. citeturn701652view0

---

# You already implemented something very close to sheaf gluing

The strongest example is your **snapshot-before-live** protocol.

Your Garden note describes a snapshot at ordinal $n$ as a representation of the prefix

$$
e_1e_2\cdots e_n
$$

with live delivery supplying the suffix strictly after the cut. Reconnect correctness therefore has the form

$$
\operatorname{fold}
(S_n,e_{n+1}\cdots e_m)
=
S_m.
$$

citeturn861691view1

Your current WebSocket implementation registers the subscription as hydrating *before* loading the snapshot, buffers concurrent UI batches, sends the snapshot, drains the buffered data relative to its `SnapshotOrdinal`, then transitions to live delivery. fileciteturn9file0L2

Conceptually you have two local sections:

$$
s_{\mathrm{past}}
\in
\mathcal F(U_{\mathrm{snapshot}})
$$

and

$$
s_{\mathrm{future}}
\in
\mathcal F(U_{\mathrm{live}}).
$$

Their common boundary information is the cut $n$.

The gluing conditions include:

$$
\text{same SessionId},
$$

$$
\operatorname{ordinal}(\text{live batch})>n,
$$

correct suffix ordering, and no event being silently neither represented by the snapshot nor delivered in the suffix.

If those conditions hold, you form

$$
s_{\mathrm{client}}
=
s_{\mathrm{past}}
\cup
s_{\mathrm{future}}.
$$

That is almost the sheaf axiom written as a network protocol.

The hydration buffer is acting as your **gluing mechanism**.

Its overflow/error path is also conceptually revealing: instead of pretending there is a valid global section, you explicitly fail the attempted construction.

---

# And some of your open correctness obligations are failures to guarantee gluing

This is where the abstraction starts paying rent.

## Atomic projection progress

Current `projectAndApply` does roughly:

```text
AppendEvent
    ↓
read View
    ↓
UIProjection
TimelineProjection
    ↓
Apply entities
    ↓
AdvanceProjectionCursor
    ↓
fanout UI
```

Those operations are separate persistence/effect boundaries in the current implementation. fileciteturn6file0L2

Your Garden note already calls out the desired invariant: a projection checkpoint at $n$ should mean that every event through $n$ has the promised materialization, and no later state is being claimed as part of that prefix. citeturn861691view1

The sheaf reading is:

$$
\mathcal F(E)
=
\text{event-store facts},
$$

$$
\mathcal F(T)
=
\text{materialization facts},
$$

$$
\mathcal F(P)
=
\text{projection-progress facts}.
$$

Each might contain a perfectly valid local observation.

But consider:

```text
event log:          n
materialization:    n
projection cursor:  n-1
```

Perhaps `Apply` committed and `AdvanceProjectionCursor` failed.

Locally, none of those values is malformed.

But they don't form the **global committed section** your stronger transactional semantics wants.

That is exactly a local-to-global consistency problem.

A SQL transaction spanning `Apply + cursor advance`, or a recovery protocol representing the intermediate state explicitly, changes the topology of what the software can jointly witness: you create a stronger context in which those facts are observed/committed together.

---

# The consistent-snapshot problem is an even cleaner example

Your SQLite `Snapshot` currently obtains the snapshot cursor and then queries the entity rows separately. fileciteturn10file0L2

The Garden entry therefore states the desired law

$$
\operatorname{LastEventOrdinal}(x)
\le
\operatorname{SnapshotOrdinal}
$$

for every returned entity, and notes that a read transaction should bind the cut and entity set into one coherent database snapshot if concurrent mutation is allowed. citeturn861691view1

Think about the two local sections:

$$
s_C=\text{“snapshot cut is }n\text{”}
$$

and

$$
s_E=\text{“these are the entity rows”}.
$$

Suppose a concurrent update occurs between the two reads and you get:

$$
\text{SnapshotOrdinal}=42
$$

while one entity says

$$
\text{LastEventOrdinal}=43.
$$

Both reads were locally legitimate.

There is simply **no global section representing “the state at cut 42”** that restricts to both observations.

That's almost the cleanest possible software-engineering example of what “doesn't glue” means.

---

# Retry identity exposes a different presheaf problem: missing coordinates

Your `Event` currently contains:

$$
(\text{Name},\text{Payload},\text{SessionId},\text{Ordinal})
$$

but no independent stable logical event identifier. fileciteturn2file0L2

The Garden analysis consequently identifies stable redelivery identity as incomplete: reuse of the same `(SessionId, Ordinal)` is idempotent in the event store, but a redelivery that acquires a fresh ordinal can look like a new event. citeturn861691view1

The sheaf interpretation is subtle and useful:

> This isn't primarily “nontrivial cohomology.” Your coordinate system is under-specified.

Two contexts:

```text
first delivery
retry delivery
```

may correspond to the same semantic event, but nothing in the common restriction forces them to be identified.

You probably need another coordinate such as

$$
\text{EventId}
$$

or

$$
(\text{producer},\text{stable message id})
$$

if logical redelivery identity is part of the invariant.

This is an important lesson:

> **Not every local-to-global problem is a cohomology problem. Sometimes your presheaf simply forgot a coordinate.**

---

# Deterministic replay has the same flavor

Your projection interface gets an event, session and `TimelineView`. fileciteturn3file0L2

But ordinary Go code implementing that interface could additionally consult clocks, randomness, network state, mutable globals, or other implicit inputs.

Your Garden entry explicitly identifies this: deterministic replay requires every relevant input to be represented—initial view, metadata, schema version, event prefix, and any otherwise hidden dependencies. citeturn861691view1

Suppose you believed the global section was indexed by

$$
(\text{events},\text{initial state}).
$$

But the projector secretly uses `time.Now()`.

You haven't discovered a mysterious topological hole.

You've discovered that the actual base has another coordinate:

$$
\text{wall-clock observation}.
$$

Either include it,

or, much better for event sourcing, turn the relevant observation into canonical event data.

This is a nice way to use presheaf thinking during architecture reviews:

> **If two supposedly identical local sections restrict differently downstream, ask what hidden coordinate you forgot.**

---

# Now we can finally talk about cohomology

For ordinary sheaf cohomology you normally want algebraic values—abelian groups, vector spaces, modules, etc.—rather than arbitrary Go objects.

Given a cover

$$
\mathcal U=\{U_i\},
$$

Čech cohomology constructs objects in dimensions:

$$
C^0
=
\prod_i\mathcal F(U_i),
$$

$$
C^1
=
\prod_{i,j}\mathcal F(U_i\cap U_j),
$$

$$
C^2
=
\prod_{i,j,k}
\mathcal F(U_i\cap U_j\cap U_k),
$$

and so on. citeturn121511search1turn121511search3

For a 0-cochain

$$
s=(s_i),
$$

the coboundary tells you the disagreements on overlaps:

$$
(\delta s)_{ij}
=
s_j|_{U_i\cap U_j}
-
s_i|_{U_i\cap U_j}.
$$

If

$$
\delta s=0,
$$

all local pieces agree.

So $H^0$ is the first familiar thing:

$$
H^0
\approx
\text{compatible global sections}.
$$

Indeed, ordinary sheaf notation identifies $H^0(U,\mathcal F)$ with global sections over $U$. citeturn233951search0

Then the magical-looking expression is

$$
H^1
=
\frac{\ker\delta_1}{\operatorname{im}\delta_0}.
$$

Read it as:

> **patterns of overlap discrepancy which satisfy all local higher-order consistency conditions, modulo discrepancies that can be explained away just by changing the local descriptions.**

That's where the “holes” intuition comes from.

---

# A software engineer's $H^1$ example

Take our toy SessionStream loop:

```text
EventStore → Timeline → Snapshot → Client → LiveUI → EventStore
```

Suppose every component has its own revision coordinate $x_i\in\mathbb Z$.

On every edge, record the claimed offset:

$$
r_{ij}=x_j-x_i.
$$

The collection of local coordinates $x_i$ is a **0-cochain**.

The edge offsets $r_{ij}$ are a **1-cochain**.

If those offsets actually come from globally meaningful local coordinates, then going around a loop must give

$$
r_{ET}
+r_{TS}
+r_{SC}
+r_{CU}
+r_{UE}
=
0.
$$

Because everything telescopes:

$$
(x_T-x_E)
+(x_S-x_T)
+(x_C-x_S)
+(x_U-x_C)
+(x_E-x_U)
=0.
$$

Now imagine your contracts instead imply

$$
r_{ET}
+r_{TS}
+r_{SC}
+r_{CU}
+r_{UE}
=1.
$$

Every individual edge contract might appear reasonable.

But globally you've accumulated an unremovable off-by-one around the loop.

There is no assignment of local coordinates $x_i$ that realizes all those edge relations simultaneously.

That persistent circulation is the kind of object $H^1$ captures.

For a simple cycle graph with constant coefficients, there's one independent 1-dimensional hole, corresponding precisely to one independent circulation around that loop.

---

## This is surprisingly relevant to your ordinal vocabulary

Your Garden entry repeatedly warns that these are not automatically identical notions:

```text
event-store cursor
projection checkpoint
snapshot cut
live suffix coordinate
entity last-event ordinal
```

citeturn861691view1

Suppose one adapter interprets its cursor as:

> last included event

and another interprets its cursor as:

> next event to consume.

They're shifted by one.

Locally every implementation may look correct.

After composing enough adapters, you may return to the original semantic coordinate shifted by $+1$.

That's an almost literal “holonomy around an architecture loop” intuition.

The fix might be a bug fix.

But sometimes the math tells you something deeper:

> You tried to pretend five different coordinate systems were the same coordinate.

Then the right solution is to type them separately and make the transformations explicit.

Which is remarkably close to the vocabulary discipline already present in your notes.

---

# Here is the topological intuition I think you're reaching for

Imagine that components only know pairwise overlaps:

```text
A ----- B
|       |
|       |
D ----- C
```

The boundary forms a loop.

There is no context anywhere in the system that sees all four things jointly.

So locally you can walk around checking:

```text
A agrees with B
B agrees with C
C agrees with D
D agrees with A
```

while still lacking one globally coherent witness.

The inside of the square is missing.

Now add a transaction/coordinator/context that jointly observes enough facts to validate the entire combination.

Mathematically, you've done something like **filling the hole with a higher-dimensional cell**.

That is why transactional boundaries and higher-order invariants fit your geometric intuition surprisingly well:

$$
\boxed{
\text{pairwise contracts form edges;}
\quad
\text{joint atomic contracts create faces.}
}
$$

This should not be interpreted too literally as “database transactions are 2-cells.” But as a modeling discipline, it is powerful.

A “hole” becomes:

> **a boundary of local compatibility for which your architecture provides no higher-order global witness.**

---

# The important caveat about cohomology

Your actual constraints include things like

$$
\text{LastEventOrdinal}\le\text{SnapshotOrdinal},
$$

idempotence, tombstones, ordering, uniqueness, cancellation, schema validity, and temporal behavior.

Those aren't naturally all linear equations in abelian groups.

So I would **not** begin by trying to calculate $H^1(\text{SessionStream})$.

Begin with a **set-valued presheaf of valid configurations**.

This is essentially a constraint-satisfaction perspective:

$$
\mathcal F(U)
=
\{\text{assignments on }U\text{ satisfying all constraints visible in }U\}.
$$

Global correctness becomes existence of a global section.

There is research making exactly this connection: CSPs can be represented as global-section problems for presheaves, with Čech-cohomological methods used to detect certain global obstructions that ordinary propagation of local consistency misses. citeturn818658view1

Then linearize particular diagnostics when useful.

For example:

$$
\text{cursor offsets},
\quad
\text{parities},
\quad
\text{counts},
\quad
\text{conservation laws},
\quad
\text{version deltas}
$$

can naturally live in $\mathbb Z$, $\mathbb F_2$, or vector spaces.

That's where actual matrix-computable cohomology becomes attractive.

And one should keep the logical direction straight: in many sheaf-theoretic obstruction constructions, a nonzero cohomology class witnesses impossibility, but vanishing need not prove that everything is globally consistent. Abramsky et al.'s contextuality construction explicitly has that sufficient-but-not-necessary character. citeturn818658view2

---

# What I would build inside `sessionstream` as a first experiment

Not production machinery. A research instrument alongside your existing formal/spec work.

1. **Define an architecture complex.** Start with cells corresponding to `EventStore`, `TimelineProjection`, `Snapshot`, `UIFanout`, and `Client`. Define explicitly what information each cell can observe and which overlaps exist. Then introduce session and ordinal/cut as coordinates.

2. **Define a set-valued presheaf first.** A section might contain facts such as `EventCursor`, `ProjectionCursor`, `SnapshotOrdinal`, maximum entity `LastEventOrdinal`, event-prefix digest, materialization digest, live batch ordinals, and a client reconstruction digest. Restriction just discards facts not visible to the smaller context.

3. **Feed real traces into it and test gluing.** Your observer/refinement work already thinks in terms of recorded traces and executable laws. Turn a recorded session into local sections and ask whether the sections agree on every overlap and whether a global execution witness exists. This would make “doesn't glue” an actual diagnostic rather than just category-theory language. Your Garden entry already treats transition traces and refinement evidence as first-class verification artifacts. citeturn861691view1

4. **Only then add a small cellular/Čech cohomology experiment.** Start with something intentionally linear, such as revision-offset consistency. Construct the incidence/coboundary matrices for your architecture complex and calculate $H^0$ and $H^1$. If a cycle carries an irreducible cursor offset, emit both the offending cohomology class and the architectural loop supporting it.

The particularly interesting combination with SessionStream is:

$$
\text{runtime trace}
\rightarrow
\text{local sections}
\rightarrow
\text{restriction checks}
\rightarrow
\text{global-section search}
\rightarrow
\text{cohomological diagnostic}.
$$

That could genuinely become a useful research tool rather than mathematics painted onto software.

---

## The deepest conceptual shift

You initially encounter topology as:

> circle has a hole, sphere has a cavity, torus has loops.

Sheaf theory changes what the “points” can mean.

Your points can be **information contexts**.

Your edges can mean **these contexts overlap**.

Your triangles can mean **three observations can be jointly reconciled**.

Your sections are **possible values living over those contexts**.

Then topology stops being about whether your software “looks like a doughnut.”

It becomes about the **shape of who knows what together**.

And cohomology starts asking whether information can circulate through that shape and return with a discrepancy that no local correction can eliminate.

For `sessionstream`, I would summarize the picture as:

$$
\boxed{
\begin{array}{c}
\text{event history is your temporal coordinate}\\
\text{projections/transports/stores are overlapping observers}\\
\text{restriction means forgetting/truncating information}\\
\text{snapshot + suffix is a gluing problem}\\
\text{transactional correctness is global-section correctness}\\
\text{missing parameters are missing coordinates}\\
\text{higher-order incompatibilities can sometimes become cohomological obstructions}
\end{array}
}
$$

The most important thing is that **sheaves are already useful before cohomology**. I would spend some time getting comfortable with “context → sections → restrictions → compatible family → global section.” Once that feels natural in SessionStream, the definition

$$
H^1=\ker\delta_1/\operatorname{im}\delta_0
$$

stops looking like arbitrary algebra and starts looking like a way of measuring the architectural loops that local reasoning can't eliminate.


---

> Use the attached book which I’m currently working through (I’m at the limits part of chapter 3) as a source of pedagogy, definitions, exercises, and write my “custom version” that is grounded in sessionstream in particular, software engineering at large, to make a custom textbook for me to work through all this theory and be able to study my mental intuitions. 
>
> As markdown and pdf

<details><summary>💭 Thinking</summary>

**Planning the textbook**

I’m checking the EPUB and repository materials first, then I’ll shape the Markdown textbook and PDF around the requested three-part progression, keeping the explanation practical and source-grounded.

**Planned the textbook**

</details>

I’ll extract the book’s pedagogy and definitions, ground them in `sessionstream` and broader software engineering, then produce a self-contained textbook with exercises in Markdown and PDF.

```unknown
bash -lc cat /home/oai/skills/pdfs/SKILL.md
```

<details><summary>💭 Thinking</summary>

**Inspected PDF and EPUB resources, extracted topology content, and reviewed repository structure**

</details>

```json
{"open":[{"ref_id":"https://github.com/go-go-golems/sessionstream/archive/refs/heads/main.zip"}],"response_length":"short"}
```

<details><summary>💭 Thinking</summary>

**Searching the web**

</details>

```json
{"open":[{"ref_id":"https://parc.yolo.scapegoat.dev/note/research/software-architecture-garden/sessionstream/readme.md"},{"ref_id":"https://parc.yolo.scapegoat.dev/note/research/software-architecture-garden/sessionstream/readme"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 1 website**

**Fetched Sessionstream repository tree, documentation, and source files**

**Gathering source material**

I’m combining the provided book’s core concepts with the repository’s architecture, models, tests, and examples. I’ll keep the result original, practical, visual, and organized for learning rather than copying the source.

**Gathered source material**

**Structuring the curriculum**

I’m organizing the material around categories, functors, natural transformations, presheaves, sheaves, sites, logic, simplicial shapes, cohomology, and applied architecture, with optional adjunctions and tooling appendices.

**Structured the curriculum**

</details>

```unknown
bash -lc python - <<'PY'
from bs4 import BeautifulSoup
from pathlib import Path
for f in ['content.opf','Text/Copyright.html','Text/Title.html','Text/Preface2.html']:
    p=Path('/mnt/data/topoi_epub/OEBPS')/f
    print('\n---',f,'---')
    s=BeautifulSoup(p.read_text(errors='ignore'),'xml' if f.endswith('.opf') else 'html.parser')
    print(' '.join(s.get_text(' ',strip=True).split())[:5000])
PY
```

<details><summary>💭 Thinking</summary>

**Extracted textbook metadata for citation**

**Designing the textbook**

I’m turning the outline into a coherent progression: software interfaces first, then categorical structure, local-to-global semantics, sheaves, cohomology, applied session-stream case studies, and practical tooling.

**Designed the textbook**

</details>

```unknown
bash -lc which dot || true; which pandoc || true; which xelatex || true; which latexmk || true; fc-list | head -10
```

I’ll preserve Goldblatt’s dependency order through categories, limits, topoi, functors, sheaves, and adjunctions, then add a separate cohomology extension; your current checkpoint is §3.11.

<details><summary>💭 Thinking</summary>

**Checked document-generation tools for PDF creation**

</details>

```json
{"search_query":[{"q":"site:stacks.math.columbia.edu presheaf sheaf definition restriction maps sheaf condition"},{"q":"site:stacks.math.columbia.edu Cech cohomology definition sheaf cohomology"},{"q":"cellular sheaves network systems Ghrist Hansen paper pdf"},{"q":"sheaf theory distributed systems global sections cohomology primary paper"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 10 websites**

**Reviewed SessionStream semantics, consumer implementation, and trace files**

</details>

```unknown
bash -lc set -euo pipefail
WORK=/mnt/data/sessionstream_textbook_work
ASSETS=$WORK/assets
rm -rf "$WORK"
mkdir -p "$ASSETS"

cat > "$ASSETS/core_flow.dot" <<'DOT'
digraph G {
  graph [rankdir=LR, bgcolor="white", pad=0.2, nodesep=0.45, ranksep=0.65];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=11];
  edge [fontname="DejaVu Sans", fontsize=9];
  command [label="Typed command"];
  hub [label="Session Hub"];
  handler [label="Command handler"];
  event [label="Canonical event\n(SessionId, Ordinal)"];
  store [label="Event store"];
  ui [label="UI projection"];
  timeline [label="Timeline projection"];
  live [label="Live UI suffix"];
  material [label="Materialized entities"];
  snapshot [label="Snapshot at cut n"];
  client [label="Client state"];
  command -> hub -> handler -> event;
  event -> store;
  event -> ui -> live -> client;
  event -> timeline -> material -> snapshot -> client;
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/core_flow.dot" -o "$ASSETS/core_flow.png"

cat > "$ASSETS/composition.dot" <<'DOT'
digraph G {
  graph [rankdir=LR, bgcolor="white", pad=0.2];
  node [shape=circle, fontname="DejaVu Sans", fontsize=12, width=0.65, fixedsize=true];
  edge [fontname="DejaVu Sans", fontsize=11];
  A [label="S0"];
  B [label="S1"];
  C [label="S2"];
  A -> B [label=" f "];
  B -> C [label=" g "];
  A -> C [label=" g o f ", minlen=2];
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/composition.dot" -o "$ASSETS/composition.png"

cat > "$ASSETS/limit_cone.dot" <<'DOT'
digraph G {
  graph [rankdir=TB, bgcolor="white", pad=0.2, nodesep=0.7, ranksep=0.55];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=11];
  edge [fontname="DejaVu Sans", fontsize=10];
  cprime [label="Any cone apex c'"];
  c [label="Limit apex L"];
  d1 [label="D(1)"];
  d2 [label="D(2)"];
  d3 [label="D(3)"];
  cprime -> c [label=" unique u ", style=dashed];
  c -> d1 [label="lambda1"];
  c -> d2 [label="lambda2"];
  c -> d3 [label="lambda3"];
  cprime -> d1 [label="f1", constraint=false];
  cprime -> d2 [label="f2", constraint=false];
  cprime -> d3 [label="f3", constraint=false];
  {rank=same; d1; d2; d3;}
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/limit_cone.dot" -o "$ASSETS/limit_cone.png"

cat > "$ASSETS/pullback.dot" <<'DOT'
digraph G {
  graph [bgcolor="white", pad=0.25, nodesep=0.75, ranksep=0.75];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=10];
  edge [fontname="DejaVu Sans", fontsize=9];
  PB [label="Authorized subscription\n(principal, session, cut)"];
  A [label="Authorized sessions\n(principal, SessionId)"];
  B [label="Subscription request\n(SessionId, sinceCut)"];
  S [label="Session identifiers"];
  PB -> A [label="forget cut"];
  PB -> B [label="forget principal"];
  A -> S [label="SessionId"];
  B -> S [label="SessionId"];
  {rank=same; A; B;}
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/pullback.dot" -o "$ASSETS/pullback.png"

cat > "$ASSETS/naturality.dot" <<'DOT'
digraph G {
  graph [bgcolor="white", pad=0.25, nodesep=0.9, ranksep=0.8];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=10];
  edge [fontname="DejaVu Sans", fontsize=9];
  Fa [label="F(A)\nold representation"];
  Fb [label="F(B)\nold representation"];
  Ga [label="G(A)\nnew representation"];
  Gb [label="G(B)\nnew representation"];
  Fa -> Fb [label="F(f)"];
  Ga -> Gb [label="G(f)"];
  Fa -> Ga [label="eta_A"];
  Fb -> Gb [label="eta_B"];
  {rank=same; Fa; Fb;}
  {rank=same; Ga; Gb;}
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/naturality.dot" -o "$ASSETS/naturality.png"

cat > "$ASSETS/presheaf.dot" <<'DOT'
digraph G {
  graph [rankdir=TB, bgcolor="white", pad=0.25, nodesep=0.55, ranksep=0.65];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=10];
  edge [fontname="DejaVu Sans", fontsize=9];
  X [label="Full execution context X\nF(X): complete valid executions"];
  E [label="Event-log context E\nF(E)"];
  T [label="Timeline context T\nF(T)"];
  W [label="WebSocket context W\nF(W)"];
  ET [label="Shared event/timeline facts\nF(E intersect T)"];
  TW [label="Shared timeline/client facts\nF(T intersect W)"];
  X -> E [label="restrict / forget"];
  X -> T [label="restrict / forget"];
  X -> W [label="restrict / forget"];
  E -> ET [label="restrict"];
  T -> ET [label="restrict"];
  T -> TW [label="restrict"];
  W -> TW [label="restrict"];
  {rank=same; E; T; W;}
  {rank=same; ET; TW;}
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/presheaf.dot" -o "$ASSETS/presheaf.png"

cat > "$ASSETS/sheaf_gluing.dot" <<'DOT'
digraph G {
  graph [rankdir=LR, bgcolor="white", pad=0.25, nodesep=0.6, ranksep=0.7];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=10];
  edge [fontname="DejaVu Sans", fontsize=9];
  P [label="Past section\nSnapshot S_n"];
  O [label="Overlap / boundary\nSessionId and cut n"];
  F [label="Future section\nordered batches > n"];
  G [label="Glued client execution\nS_n + suffix"];
  P -> O [label="exposes boundary"];
  F -> O [label="starts after boundary", dir=back];
  P -> G [label="glue"];
  F -> G [label="glue"];
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/sheaf_gluing.dot" -o "$ASSETS/sheaf_gluing.png"

cat > "$ASSETS/cochain.dot" <<'DOT'
digraph G {
  graph [rankdir=LR, bgcolor="white", pad=0.25, nodesep=0.8];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=11];
  edge [fontname="DejaVu Sans", fontsize=10];
  C0 [label="C^0\nlocal labels on vertices"];
  C1 [label="C^1\ndiscrepancies on edges"];
  C2 [label="C^2\ncirculation on faces"];
  C0 -> C1 [label="delta^0"];
  C1 -> C2 [label="delta^1"];
  Z [shape=plaintext, label="delta^1 delta^0 = 0"];
  C1 -> Z [style=invis];
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/cochain.dot" -o "$ASSETS/cochain.png"

cat > "$ASSETS/research_pipeline.dot" <<'DOT'
digraph G {
  graph [rankdir=LR, bgcolor="white", pad=0.25, nodesep=0.45, ranksep=0.65];
  node [shape=box, style="rounded", fontname="DejaVu Sans", fontsize=10];
  edge [fontname="DejaVu Sans", fontsize=9];
  trace [label="Runtime trace"];
  sections [label="Local sections\nper context"];
  overlaps [label="Restriction and\noverlap checks"];
  global [label="Global-section\nsearch"];
  linear [label="Linearized\ncochain complex"];
  diag [label="Counterexample or\ncohomology diagnostic"];
  trace -> sections -> overlaps -> global;
  overlaps -> linear -> diag;
  global -> diag;
}
DOT

dot -Tpng -Gdpi=180 "$ASSETS/research_pipeline.dot" -o "$ASSETS/research_pipeline.png"

python - <<'PY'
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
import numpy as np
out=Path('/mnt/data/sessionstream_textbook_work/assets')

# Dimensions of simplices
fig, ax = plt.subplots(figsize=(10,2.7))
ax.axis('off')
# 0 simplex
ax.scatter([0.5],[0.5],s=80)
ax.text(0.5,0.15,'0-simplex: context',ha='center')
# 1 simplex
ax.plot([2.0,3.0],[0.5,0.5],marker='o')
ax.text(2.5,0.15,'1-simplex: overlap',ha='center')
# 2 simplex
tri=np.array([[4.5,0.25],[5.6,0.25],[5.05,1.15]])
ax.add_patch(Polygon(tri,closed=True,alpha=0.2))
ax.plot(*np.vstack([tri,tri[0]]).T,marker='o')
ax.text(5.05,-0.05,'2-simplex: joint witness',ha='center')
# 3 simplex projection
pts=np.array([[7.0,0.25],[8.2,0.25],[7.6,1.15],[7.6,0.62]])
for i,j in [(0,1),(0,2),(1,2),(0,3),(1,3),(2,3)]:
    ax.plot([pts[i,0],pts[j,0]],[pts[i,1],pts[j,1]],marker='o')
ax.text(7.6,-0.05,'3-simplex: four-way witness',ha='center')
ax.set_xlim(0,8.8); ax.set_ylim(-0.2,1.5)
fig.tight_layout()
fig.savefig(out/'simplex_dimensions.png',dpi=180,bbox_inches='tight')
plt.close(fig)

# Cycle versus filled cycle
fig, ax = plt.subplots(figsize=(8,3.5))
ax.axis('equal'); ax.axis('off')
for cx, filled, label in [(0,False,'cycle: one 1-dimensional hole'),(3.3,True,'filled face: hole removed')]:
    theta=np.linspace(0,2*np.pi,5)[:-1]+np.pi/4
    pts=np.c_[cx+np.cos(theta), np.sin(theta)]
    if filled:
        ax.add_patch(Polygon(pts,closed=True,alpha=0.2))
    ax.plot(*np.vstack([pts,pts[0]]).T,marker='o')
    ax.text(cx,-1.45,label,ha='center')
ax.set_xlim(-1.5,4.8); ax.set_ylim(-1.7,1.5)
fig.tight_layout()
fig.savefig(out/'cycle_vs_filled.png',dpi=180,bbox_inches='tight')
plt.close(fig)

# SessionStream architecture complex
fig, ax = plt.subplots(figsize=(7,5))
ax.axis('equal'); ax.axis('off')
labels=['Event log E','Timeline T','Snapshot S','Client C','Live UI U']
theta=np.linspace(np.pi/2, np.pi/2+2*np.pi, len(labels), endpoint=False)
pts=np.c_[np.cos(theta),np.sin(theta)]
for i in range(len(labels)):
    j=(i+1)%len(labels)
    ax.plot([pts[i,0],pts[j,0]],[pts[i,1],pts[j,1]],marker='o')
for (x,y),lab in zip(pts,labels):
    ax.text(x*1.28,y*1.28,lab,ha='center',va='center')
ax.text(0,0.18,'pairwise contracts',ha='center')
ax.text(0,-0.12,'without a joint witness',ha='center')
ax.set_xlim(-1.7,1.7); ax.set_ylim(-1.5,1.6)
fig.tight_layout()
fig.savefig(out/'architecture_cycle.png',dpi=180,bbox_inches='tight')
plt.close(fig)
PY

ls -lh "$ASSETS"/*.png
```

The opening four chapters are drafted, with limits built around execution tuples, pullbacks, and reconstruction. Later, snapshot gluing and ordinal cycles lead concretely into sheaves and $H^1$.

<details><summary>💭 Thinking</summary>

**Drafted SessionStream chapters and conceptual diagrams on categorical abstractions**

</details>

```json
{"open":[{"ref_id":"turn587443search0"}],"response_length":"long"}
```

<details><summary>💭 Thinking</summary>

**Searched 1 website**

</details>

```unknown
bash -lc cat > /mnt/data/sessionstream_textbook_work/14-nerve-shapes.md <<'EOF'
# Nerves and Multidimensional Architecture Shapes

> **Supplemental chapter:** Goldblatt develops sheaves categorically but does not center the combinatorial geometry used here. The aim is to make the "multidimensional topological-esque shape" intuition explicit and disciplined.

## 14.1 Dimension is joint compatibility, not physical space

A **0-simplex** is a vertex. A **1-simplex** is an edge. A **2-simplex** is a filled triangle. A **3-simplex** is a tetrahedron. In general, an \(n\)-simplex has \(n+1\) vertices.

![Simplices encode increasingly high-order joint contexts.](assets/simplex_dimensions.png){#fig:simplex-dimensions width=96%}

For a software architecture:

- a vertex can represent one observation context,
- an edge can represent a nontrivial pairwise overlap,
- a filled triangle can represent a genuine three-way joint context,
- a tetrahedron can represent a four-way joint witness.

The word **filled** is essential. Three pairwise edges do not automatically imply a triangle. Pairwise compatibility may exist without a context in which all three views coexist.

## 14.2 Abstract simplicial complexes

An **abstract simplicial complex** \(K\) on a vertex set \(V\) is a collection of finite nonempty subsets of \(V\) such that if \(\sigma\in K\) and \(\tau\subseteq\sigma\) is nonempty, then \(\tau\in K\).

The subsets \(\sigma\) are simplices. Their dimension is

\[
\dim\sigma=|\sigma|-1.
\]

Downward closure says that a joint context includes all of its smaller faces. If four subsystem views can be observed jointly, then every triple and pair among them can also be regarded as jointly observable by restriction.

## 14.3 The nerve of a cover

Given a cover \(\{U_i\}_{i\in I}\), its **nerve** has:

- one vertex for each \(U_i\),
- an edge \(\{i,j\}\) when \(U_i\cap U_j\) is nonempty or semantically meaningful,
- a triangle \(\{i,j,k\}\) when the triple overlap is meaningful,
- and so on.

The nerve records the shape of overlaps while forgetting the internal details of each patch.

For software, "nonempty" should be replaced only with a precisely stated criterion, such as:

- shared fields,
- shared semantic identifiers,
- a common transaction snapshot,
- a common trace witness,
- a pullback object with allowed sections.

Two services mentioning `SessionId` do not automatically have a useful overlap if they assign it different semantics.

## 14.4 A SessionStream architecture nerve

Consider contexts:

\[
E=\text{event log},
\quad
T=\text{timeline},
\quad
S=\text{snapshot},
\quad
C=\text{client},
\quad
U=\text{live UI}.
\]

One possible overlap graph is a cycle:

![A cycle of pairwise contracts can exist without any higher-order context witnessing the whole loop.](assets/architecture_cycle.png){#fig:architecture-cycle width=58%}

Edges could mean:

- \(E-T\): event identity and projection progress,
- \(T-S\): materialized entities and snapshot cut,
- \(S-C\): transmitted snapshot and reconstructed client base,
- \(C-U\): delivered live observations,
- \(U-E\): UI batches tied to canonical event ordinals.

This graph is a modeling proposal, not a fact extracted automatically from package imports. Each edge needs a defined overlap space and restriction maps.

## 14.5 Cycles are opportunities, not automatically defects

A cycle creates the possibility of circulation. Data can be transformed around the loop and return changed. But a cycle alone is not a bug.

Examples of lawful cycles:

- unit conversions that compose to identity,
- schema adapters with a coherent round trip,
- replicated coordinate frames with consistent transition maps.

Examples of problematic cycles:

- mixed "last included" and "next expected" cursor conventions,
- version conversions whose composite increments a revision,
- time-zone conversions that apply daylight rules inconsistently,
- duplicated normalization performed on only one path.

Cohomology will distinguish exact changes of local coordinates from persistent circulation around cycles.

## 14.6 Filling a hole

Compare a cycle with a filled face:

![A one-dimensional cycle has a potential circulation class; adding a two-dimensional face imposes a higher-order compatibility condition.](assets/cycle_vs_filled.png){#fig:cycle-filled width=74%}

A filled triangle represents more than pairwise APIs. It represents a context or law that jointly witnesses all three views and constrains circulation around the boundary.

A database transaction that reads cursor and rows together can sometimes be modeled as adding a joint context. A coordinated protocol among three services can add a triangle. But the analogy must be earned by specifying the face stalk and its restriction maps.

## 14.7 The Čech nerve

For a cover \(\{U_i\to U\}\), the Čech nerve contains repeated fiber products:

\[
U_i,
\quad
U_i\times_UU_j,
\quad
U_i\times_UU_j\times_UU_k,
\quad\ldots
\]

These are the actual overlap objects used by descent and Čech cohomology. The abstract nerve records only which overlaps exist; the Čech nerve retains their data.

Software reading: the graph of "who overlaps whom" is only the skeleton. A useful analysis also records the shared schema, trace fields, coordinate transformations, or validation relations on each overlap.

## 14.8 Products of dimensions

SessionStream has several independent axes:

\[
\text{session}
\times
\text{event cut}
\times
\text{observer kind}
\times
\text{schema version}.
\]

A section may vary along all four. Restriction can move backward in time, narrow observer capabilities, select one session, or downgrade schema.

The resulting base need not be a simple graph. It can be a product poset, a cubical complex, or a category with nontrivial arrows. Graphs are useful for first computations because they expose cycles, but they may omit higher-order overlap structure.

## 14.9 Building an architecture complex

A practical construction process:

1. Choose a single invariant family, such as ordinal coherence.
2. Create one vertex for each context that owns a coordinate.
3. Add an edge only when two contexts have an explicit comparison map.
4. Add a face only when a joint context or law constrains all boundary comparisons.
5. Label every cell with the data observable there.
6. Validate that face inclusion corresponds to lawful restriction.
7. Record which cells are absent and why.

Do not build the complex from a package dependency graph. Dependencies are not automatically information overlaps.

## 14.10 Homotopy intuition, carefully

Topology studies features preserved under continuous deformation. In combinatorial complexes, the first intuition is:

- connected components are 0-dimensional global separation,
- loops are 1-dimensional holes,
- enclosed voids are 2-dimensional holes.

For architecture complexes, these features concern the overlap shape, not physical deployment. A loop says there is a closed chain of comparisons not filled by higher-order witness cells. Whether this matters depends on the sheaf placed over the shape.

The same complex can have different cohomology for different sheaves. Topology is the base; sheaf data are the semantics.

## Exercises

1. **[S]** Build the nerve of three API contexts with all pairwise overlaps but no triple-overlap transaction. List its simplices.
2. Add a joint transaction context and explain which simplex is added.
3. Give two different meanings for an edge between event-store and snapshot contexts. Which one supports ordinal comparison?
4. **[S]** Explain why a service dependency graph is not automatically the nerve of an information cover.
5. Draw a product-like base with axes `{event cut 0,1,2}` and `{event, timeline, snapshot}`. Identify squares that could be filled by naturality laws.
6. Architecture lab: construct a simplicial complex for one end-to-end request. Mark every missing triangle where only pairwise tests exist.
7. Research exercise: decide whether a WebSocket hydration transaction should be represented by a triangle, a square, or a temporal cell complex. Justify the choice.
8. Explain why a nontrivial loop may be harmless for the constant sheaf but problematic for a sheaf with nontrivial coordinate changes, or vice versa.
EOF

cat > /mnt/data/sessionstream_textbook_work/15-cellular-sheaves.md <<'EOF'
# Cellular Sheaves on Architecture Complexes

> **Supplemental chapter:** This chapter follows the applied cellular-sheaf convention used by Hansen and Ghrist: vector spaces are attached to cells, with linear maps from a face to an incident coface.

## 15.1 Why cellular sheaves

Ordinary sheaves on open sets are conceptually fundamental, but finite software models often begin as graphs, simplicial complexes, or cell complexes. A cellular sheaf turns that finite shape into a linear data structure.

It assigns:

- a vector space of possible local data to every cell,
- a linear compatibility map from each face to each incident higher-dimensional cell.

This makes global consistency a system of linear equations.

## 15.2 Cell complexes and face posets

A finite regular cell complex \(X\) has cells of dimensions \(0,1,2,\ldots\). Write

\[
\sigma\le\tau
\]

when \(\sigma\) is a face of \(\tau\).

The face relation is a poset and therefore a category. A cellular sheaf over a field \(\Bbbk\) is a functor

\[
\mathcal F:P_X\to\mathbf{Vect}_{\Bbbk}.
\]

For every incidence \(\sigma\le\tau\), it provides a linear map

\[
\mathcal F_{\sigma\le\tau}:
\mathcal F(\sigma)\to\mathcal F(\tau),
\]

with identity and composition laws.

This direction differs from the open-set presheaf notation because a cell is being used as a compact encoding of its open star. Keep the convention explicit.

## 15.3 Stalks as local data spaces

The vector space \(\mathcal F(\sigma)\) is called the stalk over cell \(\sigma\).

For a graph model of SessionStream:

- a vertex stalk may contain a subsystem's local coordinate vector,
- an edge stalk may contain the shared comparison space,
- the two endpoint-to-edge maps translate each local coordinate into that common space.

Example edge \(e=(v,w)\):

\[
\rho_{v e}:\mathcal F(v)\to\mathcal F(e),
\qquad
\rho_{w e}:\mathcal F(w)\to\mathcal F(e).
\]

Endpoint values \(x_v,x_w\) agree along the edge when

\[
\rho_{v e}(x_v)=\rho_{w e}(x_w).
\]

## 15.4 Constant sheaf

The constant cellular sheaf with stalk \(\Bbbk\) assigns \(\Bbbk\) to every cell and identity maps to every incidence.

On a connected graph, a global section assigns the same scalar to every vertex. Thus \(H^0\) will have dimension one.

For an architecture graph, a constant sheaf asks whether all components can share one common coordinate without transformations. This is appropriate only after units and conventions have already been normalized.

## 15.5 A coordinate-change sheaf

Suppose one subsystem stores the last included ordinal \(n\), while another stores the next expected ordinal \(n+1\).

Let both vertex stalks be \(\mathbb R\), and let the shared edge stalk also be \(\mathbb R\). Purely linear maps cannot express addition of 1, because

\[
x\mapsto x+1
\]

is affine, not linear.

There are three options:

1. normalize coordinates before constructing the sheaf;
2. use affine spaces and affine maps;
3. homogenize by adding a constant coordinate:

\[
\begin{bmatrix}x\\1\end{bmatrix}
\mapsto
\begin{bmatrix}1&1\\0&1\end{bmatrix}
\begin{bmatrix}x\\1\end{bmatrix}.
\]

This example shows that choosing vector-space coefficients is itself a modeling decision.

## 15.6 Global sections on a graph

A global section is a compatible assignment \(x_v\in\mathcal F(v)\) to vertices, together with consistent cell data, such that every edge comparison agrees.

For a graph, after eliminating edge values, compatibility is

\[
\rho_{v e}(x_v)-\rho_{w e}(x_w)=0
\]

for every oriented edge \(e=(v,w)\).

Collecting all equations gives a linear map

\[
\delta^0:C^0(X;\mathcal F)	o C^1(X;\mathcal F).
\]

Global sections are

\[
\ker\delta^0.
\]

## 15.7 SessionStream stalk design

For an ordinal-coherence model, possible vertex stalks are:

\[
\mathcal F(E)=\mathbb R^2
\]

for event cursor and stable stream coordinate,

\[
\mathcal F(T)=\mathbb R^2
\]

for projection cursor and maximum materialized ordinal,

\[
\mathcal F(S)=\mathbb R^2
\]

for snapshot cut and maximum entity ordinal,

\[
\mathcal F(C)=\mathbb R^2
\]

for last reconstructed and next expected ordinal.

An edge stalk should contain only the comparison coordinates actually shared. Restriction maps can project, rename, convert units, or apply a linearized schema mapping.

A one-dimensional stalk everywhere is simpler but may falsely identify distinct meanings.

## 15.8 Local residuals

Given a 0-cochain \(x\), the edge residual

\[
(\delta^0x)_e
=
\rho_{v e}(x_v)-\rho_{w e}(x_w)
\]

measures disagreement in the common edge coordinate.

This produces a useful diagnostic even before computing cohomology:

- zero residual: the pair agrees,
- nonzero residual: the pair violates its overlap contract,
- large norm: large disagreement in a weighted model.

A sheaf Laplacian can distribute and localize disagreement, but raw residuals are already actionable.

## 15.9 Higher-dimensional cells

A 2-cell has a stalk and maps from boundary edges into it. These maps encode a joint compatibility space beyond pairwise agreement.

For a transaction spanning event append, entity apply, and cursor advance, a face stalk might represent the atomic commit coordinate. Boundary edge data map into that coordinate. The face compatibility law can reject a circulation that pairwise edges alone cannot eliminate.

Again, adding a face to the drawing is not enough. The face stalk and maps must express the actual atomic witness.

## 15.10 Sheaf morphisms

A morphism \(\phi:\mathcal F\to\mathcal G\) assigns a linear map

\[
\phi_\sigma:\mathcal F(\sigma)\to\mathcal G(\sigma)
\]

for every cell, commuting with all restriction maps.

Examples:

- map detailed cursor vectors to a one-dimensional freshness score,
- map concrete trace coordinates to abstract model coordinates,
- forget payload digests while retaining ordinals.

A sheaf morphism induces maps on cohomology. Therefore diagnostics can be compared across levels of abstraction when the abstraction is natural.

## 15.11 Weighted sheaves and confidence

With inner products on stalks, one can weight coordinates by trust, cost, or variance. The sheaf Laplacian then supports least-squares reconciliation and harmonic extension.

For software telemetry:

- durable database facts may receive high weight,
- lossy observer records lower weight,
- advisory client cursors lower weight than server commits.

Weights do not change truth into certainty. They define an optimization geometry for approximate consistency.

## 15.12 Modeling workflow

Start with a finite graph and one scalar invariant. Then proceed:

1. choose vertex meanings,
2. choose edge comparison spaces,
3. write restriction matrices,
4. generate observed 0-cochains,
5. compute edge residuals,
6. inspect the kernel dimension,
7. add faces only when a real higher-order witness exists,
8. expand stalks only when one scalar collapses distinct semantics.

This incremental method prevents an impressive but uninterpretable matrix model.

## Exercises

1. **[S]** Define the constant sheaf on a connected three-vertex path and compute its global sections.
2. Build a graph sheaf with vertex stalks \(\mathbb R\), edge stalks \(\mathbb R\), and one edge map multiplying by 1000 to convert seconds to milliseconds. Write the compatibility equation.
3. Explain why `nextExpected = lastIncluded + 1` requires affine rather than purely linear data.
4. **[S]** Design stalks and restriction maps for comparing snapshot cut with maximum entity ordinal.
5. Compute residuals for a four-vertex architecture assignment of your choice.
6. Implementation lab: represent stalk dimensions and restriction matrices for a graph sheaf. Assemble \(\delta^0\).
7. Architecture lab: propose a 2-cell for atomic projection progress. Identify what runtime evidence inhabits the face stalk.
8. Explain why a scalar "revision" stalk may hide the distinction between event cursor, projection checkpoint, and snapshot cut.
EOF

cat > /mnt/data/sessionstream_textbook_work/16-cohomology.md <<'EOF'
# Cohomology as Persistent Disagreement

> **Supplemental chapter:** This chapter uses finite cellular and Čech-style cohomology. General sheaf cohomology is broader and is commonly defined as the derived functors of global sections. For software experiments, finite cochain complexes are the practical starting point.

## 16.1 From compatibility equations to a complex

For a cellular sheaf \(\mathcal F\) on a finite cell complex \(X\), define the degree-\(k\) cochains

\[
C^k(X;\mathcal F)
=
\bigoplus_{\dim\sigma=k}\mathcal F(\sigma).
\]

A 0-cochain assigns local values to vertices. A 1-cochain assigns discrepancy-like values to edges. A 2-cochain assigns values to faces.

Signed incidence numbers and restriction maps define coboundary maps

\[
\delta^k:C^k\to C^{k+1}
\]

satisfying

\[
\delta^{k+1}\circ\delta^k=0.
\]

![Cohomology studies what is closed under the next compatibility check but not generated by a lower-dimensional correction.](assets/cochain.png){#fig:cochain width=76%}

## 16.2 Why \(\delta^2=0\)

The equation

\[
\delta^{k+1}\delta^k=0
\]

is the algebraic form of "the boundary of a boundary is zero." Contributions from adjacent faces cancel with opposite signs.

In software language, a discrepancy produced solely by changing local coordinate choices cannot itself create net higher-order circulation. If it does, either the matrices are wrong or the model's composition laws fail.

## 16.3 Cocyles, coboundaries, and cohomology

A **\(k\)-cocycle** is a cochain \(z\in C^k\) with

\[
\delta^k z=0.
\]

A **\(k\)-coboundary** is a cochain of the form

\[
z=\delta^{k-1}x.
\]

Every coboundary is a cocycle because \(\delta^2=0\).

The \(k\)-th cohomology group or vector space is

\[
H^k(X;\mathcal F)
=
\frac{\ker\delta^k}{\operatorname{im}\delta^{k-1}}.
\]

It identifies cocycles that differ only by a lower-dimensional change of coordinates.

## 16.4 Degree zero

There is no incoming coboundary map to \(C^0\), so

\[
H^0(X;\mathcal F)=\ker\delta^0.
\]

For a cellular sheaf, this is the space of global sections.

Thus \(H^0\) answers:

- which assignments are globally compatible?
- how many degrees of freedom do globally compatible assignments have?

For the constant \(\mathbb R\)-sheaf on a connected graph,

\[
H^0\cong\mathbb R,
\]

representing one common scalar value. With \(c\) connected components,

\[
\dim H^0=c.
\]

Separate session components therefore naturally create independent global values.

## 16.5 Degree one on a cycle

Take a four-vertex cycle with the constant \(\mathbb R\)-sheaf. Then

\[
C^0\cong\mathbb R^4,
\qquad
C^1\cong\mathbb R^4.
\]

Choose an orientation around the cycle. The coboundary is the incidence matrix

\[
\delta^0=
\begin{bmatrix}
-1&1&0&0\\
0&-1&1&0\\
0&0&-1&1\\
1&0&0&-1
\end{bmatrix}.
\]

Its rank is 3. There are no 2-cells, so \(\delta^1=0\). Hence

\[
\dim H^1
=
\dim C^1-\operatorname{rank}\delta^0
=4-3=1.
\]

One independent circulation survives around the loop.

## 16.6 Exact edge differences

Suppose vertex values \(x_v\) are local coordinate choices. Their induced edge differences are

\[
r=\delta^0x.
\]

Such a residual is **exact**. Summing its signed entries around any cycle gives zero because differences telescope.

If an observed edge relation \(r\) has nonzero cycle sum, then no vertex assignment \(x\) can explain it:

\[
r\notin\operatorname{im}\delta^0.
\]

On a graph, every 1-cochain is a cocycle, so \(r\) determines a nonzero class in \(H^1\).

This is the cleanest software reading of first cohomology:

> a closed pattern of pairwise transformations that cannot be removed by independently relabeling local coordinates.

## 16.7 SessionStream ordinal-offset example

Consider a cycle of coordinate systems:

\[
E\to T\to S\to C_{next}\to E.
\]

Let edge offsets mean "target coordinate minus source coordinate."

Healthy conversions might be:

\[
r_{ET}=0,
\quad
r_{TS}=0,
\quad
r_{SC}=1,
\quad
r_{CE}=-1.
\]

The cycle sum is zero.

Now suppose the final adapter incorrectly treats `nextExpected` as `lastIncluded`, giving

\[
r_{CE}=0.
\]

Then

\[
r_{ET}+r_{TS}+r_{SC}+r_{CE}=1.
\]

No choice of local origin values can make every edge contract true simultaneously. The offset cochain represents a nonzero \(H^1\) class on the architecture cycle.

This does not prove a runtime bug occurred. It proves that the declared coordinate conversions are globally inconsistent in the model.

## 16.8 Filling the cycle with a face

Add a 2-cell representing a joint witness for all boundary comparisons. Then

\[
\delta^1:C^1\to C^2
\]

computes the signed circulation around the face.

The erroneous offset cochain with sum 1 is no longer a cocycle:

\[
\delta^1r\ne0.
\]

The inconsistency is detected locally by the face law rather than surviving as a cohomology class.

For the constant sheaf on a filled square or triangle,

\[
H^1=0.
\]

This is the precise content behind the intuition that adding a genuine higher-order compatibility witness "fills the hole."

## 16.9 What nonzero \(H^1\) does not mean

Nonzero \(H^1\) does not automatically mean:

- the program is incorrect,
- no global sections exist,
- every local family fails to glue,
- or the architecture has a transaction bug.

For the constant sheaf on a circle, global constant sections exist even though \(H^1\ne0\). The nonzero group says the coefficient system and base support an independent 1-dimensional cohomology class.

To turn a concrete consistency problem into an obstruction, formulate an affine equation

\[
\delta^0x=r.
\]

If \(r\) is closed but its class \([r]\in H^1\) is nonzero, the equation has no solution. The class of the specific residual is the obstruction.

## 16.10 Čech cohomology

For an abelian presheaf and a cover \(\mathcal U=\{U_i\}\), Čech cochains use multiple intersections:

\[
\check C^0=\prod_i\mathcal F(U_i),
\]

\[
\check C^1=\prod_{i,j}\mathcal F(U_i\cap U_j),
\]

\[
\check C^2=\prod_{i,j,k}\mathcal F(U_i\cap U_j\cap U_k),
\]

with alternating restriction sums as coboundaries.

The sheaf condition identifies global sections with \(\check H^0\) for every cover. Higher Čech cohomology can measure obstruction patterns for that cover.

Čech cohomology and derived sheaf cohomology agree under useful hypotheses but not in complete generality. This book's finite architecture computations should be described as cellular or cover-relative Čech computations unless a stronger theorem is established.

## 16.11 Higher degrees

\(H^2\) can detect 2-dimensional obstruction classes, such as incompatibilities among face-level gluing data around a void. In software terms, these may correspond to failures of compatibility among multiple joint transactions or adapter cocycles.

Do not assign canned bug meanings by degree. Degree reflects the dimension of the compatibility structure, while semantics come from stalks and restriction maps.

## 16.12 Laplacians and approximate consistency

With inner products, define the degree-\(k\) sheaf Laplacian

\[
L^k
=
\delta^{k-1}\delta^{k-1*}
+
\delta^{k*}\delta^k.
\]

For finite-dimensional real cellular sheaves,

\[
\ker L^k\cong H^k(X;\mathcal F).
\]

At degree zero,

\[
L^0=\delta^{0*}\delta^0.
\]

Minimizing

\[
\|\delta^0x-r\|^2
\]

finds the best approximate local coordinate assignment for observed edge relations. Residual energy localizes disagreement even when exact gluing is impossible.

## 16.13 Computation by matrices

For a finite complex over a field:

1. order cells by dimension,
2. choose bases for every stalk,
3. assemble block coboundary matrices,
4. verify \(\delta^{k+1}\delta^k=0\),
5. compute ranks and nullspaces,
6. calculate

\[
\dim H^k
=
\dim C^k
-
\operatorname{rank}\delta^k
-
\operatorname{rank}\delta^{k-1}.
\]

For exact discrete diagnostics, finite fields such as \(\mathbb F_2\) avoid floating-point rank ambiguity. For signed offsets and least squares, \(\mathbb Q\) or \(\mathbb R\) may be more natural.

## Exercises

1. **[S]** Compute \(H^0\) and \(H^1\) of a three-vertex path with the constant \(\mathbb R\)-sheaf.
2. Compute \(H^0\) and \(H^1\) of a triangle graph without its face.
3. Add the triangle face and recompute.
4. **[S]** Prove that an edge-offset assignment is exact on a connected graph iff its signed sum around every cycle is zero.
5. Construct a SessionStream cursor-offset cochain with zero pairwise residuals on a spanning tree but nonzero circulation on one extra edge.
6. Explain why a nonzero \(H^1\) group alone is not a counterexample to existence of global sections.
7. Implementation lab: assemble the incidence matrix of a graph and compute \(\beta_0\) and \(\beta_1\) over \(\mathbb F_2\).
8. Implementation lab: solve \(\min_x\|\delta^0x-r\|^2\) for noisy cursor-offset measurements and identify the largest residual edge.
9. Architecture lab: decide whether your chosen 2-cell has enough semantics to justify \(\delta^1\). If not, remove it.
10. Research exercise: compare a set-valued global-section search with a linearized cohomology test. Give an example where the linear test misses a nonlinear obstruction.
EOF

wc -w /mnt/data/sessionstream_textbook_work/14-nerve-shapes.md /mnt/data/sessionstream_textbook_work/15-cellular-sheaves.md /mnt/data/sessionstream_textbook_work/16-cohomology.md
```

<details><summary>💭 Thinking</summary>

**Created chapter on nerve complexes and compatibility shapes**

</details>

```unknown
bash -lc cat > /mnt/data/sessionstream_textbook_work/17-sessionstream-case-studies.md <<'EOF'
# SessionStream Case Studies

> **Repository basis:** The examples in this chapter are grounded in the public SessionStream repository and its Architecture Garden entry. The code snapshot inspected for this companion was `main` at commit `d62dca9f5efa2e3094d6c62e5ead5ed0c88fd35c` from August 13, 2026. The Garden analysis was modified August 15, 2026. Treat this chapter as a model of that snapshot, not as a permanent claim about later revisions.

## 17.1 The core semantic separation

SessionStream's central types distinguish:

\[
\text{Command}
\to
\text{Canonical Event}
\to
\begin{cases}
\text{UI Event}\\
\text{Timeline Entity}
\end{cases}
\to
\begin{cases}
\text{Live Fanout}\\
\text{Snapshot}
\end{cases}
\]

This separation is mathematically productive because each arrow can have different information-loss and consistency properties.

- A command expresses intent, not occurrence.
- A canonical event records an admitted occurrence.
- A UI event is a live projection, not durable truth.
- A timeline entity is materialized query state, not the original event.
- A snapshot is a cut-indexed collection of entities.
- A projection cursor records interpreter progress, not automatically event-store progress.

The first architecture rule is therefore type discipline: do not identify objects merely because they carry similar fields.

## 17.2 Schema registry as a typed admission subobject

The schema registry binds symbolic names to protobuf prototypes for commands, events, UI events, and timeline entities. Duplicate names and payload-type mismatches are rejected.

Categorical model:

- all name/message pairs form an ambient object \(A\),
- valid admitted registrations form a subobject \(V\hookrightarrow A\),
- lookup and instantiation are arrows from the registry state,
- encoding and decoding should commute with the chosen schema interpretation.

Questions:

1. Is the name-to-descriptor map monic?
2. Is every admitted wire payload in the image of a registered schema?
3. Does decode after encode retract to the original typed value?
4. Is schema evolution natural with respect to projections and replay?

The registry solves a naming and type-admission problem. It does not prove that an event's business claim is true.

## 17.3 Canonical events as a coproduct

Named event alternatives can be modeled as a tagged coproduct:

\[
E=E_1+\cdots+E_k.
\]

A projector out of \(E\) is determined by its branch behavior. String names plus `proto.Message` implement a dynamically extensible approximation to this sum.

The mathematical tension is useful:

- the architecture wants distinguishable injections,
- the transport uses a generic envelope,
- the registry restores the tag-to-type relation dynamically.

A future generated closed sum would move more evidence to compile time. The current design retains runtime extensibility.

## 17.4 Per-session ordinal assignment

The local path serializes ordinal allocation with a mutex. The bus consumer uses an `OrdinalAssigner` that maintains per-session current values and may derive a larger ordinal from stream metadata.

The intended order object for each session is a chain:

\[
0<1<2<\cdots.
\]

The global order is closer to a disjoint union or product of chains, not one total order across all sessions.

### Correctness questions

- Are ordinals strictly monotone per session?
- Can two logically identical redeliveries receive different ordinals?
- Does every materialization apply events in ordinal order?
- Is a numeric ordinal faithful to the authoritative bus order?

Ordinal allocation alone does not serialize projection and application. A lock can protect the coordinate assignment while later effects race.

## 17.5 Case study: per-session serial application

Suppose two concurrent local publishes for one session receive ordinals \(n\) and \(n+1\). If the ordinal lock is released before `projectAndApply`, scheduling can apply \(n+1\) first.

This is primarily a transition-system and linearizability problem.

A desired law is observational equivalence:

\[
\operatorname{observe}(\operatorname{concurrentApply}(H_s))
=
\operatorname{observe}(\operatorname{fold}(H_s)).
\]

Useful categorical views:

- the event-prefix category defines the required arrow order,
- replay should be a functor from prefixes to states,
- concurrent execution should refine that functor,
- a per-session sequencer can supply one canonical composite.

Cohomology is not the first tool. There is no need to invent a hole when a two-event schedule already gives a concrete counterexample.

### Executable test

Use barriers to force:

1. event \(n\) obtains its ordinal and pauses,
2. event \(n+1\) obtains its ordinal and applies,
3. event \(n\) resumes,
4. inspect materialized state and entity ordinals.

The abstraction map should compare the observed trace with the permitted serial histories.

## 17.6 Case study: atomic projection progress

The current core pipeline conceptually performs:

1. append event if an event store exists,
2. load the pre-event view,
3. run UI and timeline projections,
4. apply timeline entities,
5. advance the named projection cursor,
6. fan out UI events.

These steps have different durability and failure semantics.

Define local contexts:

- \(E\): event appended,
- \(M\): materialization applied,
- \(P\): projection cursor advanced,
- \(U\): UI fanout attempted.

A durable timeline commit may require the joint section

\[
(E_n,M_n,P_n).
\]

UI fanout should usually remain outside this durable transaction because client delivery is a separate effect.

### Three valid designs

**Atomic transaction:** append, apply, and cursor advance commit together.

**Explicit recovery machine:** intermediate states such as `(event appended, projection pending)` are durable and replayable.

**Idempotent recomputation:** cursor advancement lags safely because materialization is deterministic and duplicate application is controlled.

The sheaf model must include whichever intermediate states are valid. Declaring only the final tuple and then observing partial commits creates false non-gluability.

### Geometry

Pairwise edges among event, materialization, and cursor contexts may not enforce a three-way atomic law. A face stalk representing the transaction commit can supply a higher-order witness. That is a legitimate "filled triangle" only if the database or protocol actually produces one joint commit record.

## 17.7 Case study: consistent snapshot cuts

A `Snapshot` contains a session ID, a `SnapshotOrdinal`, and entities carrying `CreatedOrdinal` and `LastEventOrdinal`.

The core invariant is

\[
\forall x\in\operatorname{Entities}(S),
\quad
\operatorname{LastEventOrdinal}(x)
\le
\operatorname{SnapshotOrdinal}(S).
\]

If the snapshot cut and entity rows are read under different database epochs, a concurrent update can produce a header from cut \(n\) and an entity from \(n+1\).

### Presheaf diagnosis

- one local section reports the cut,
- another reports entity versions,
- the claimed cover says they describe one snapshot,
- but there is no global section satisfying the cut predicate.

### Repair

A database read transaction gives one larger context from which both local sections are restrictions. The transaction does not prove every snapshot invariant, but it supplies the coherent epoch needed to state them.

### Test

Use a controlled concurrent writer between cursor and row reads. The test should fail for the split-read implementation and pass when both reads share one database snapshot.

## 17.8 Case study: stable retry identity

Current event identity includes name, payload, session, and assigned ordinal. Store-level idempotence can recognize an identical event at the same `(SessionId, Ordinal)` and reject a conflict at that coordinate.

A bus redelivery that receives a fresh ordinal does not necessarily retain logical identity.

This is best diagnosed as a missing coordinate:

\[
\text{EventId}
\quad\text{or}\quad
\text{stable stream coordinate}.
\]

Once present, delivery attempts can be quotiented by logical identity. Without it, a coequalizer for retries cannot be defined faithfully.

### Property

\[
\operatorname{accept}(e);
\operatorname{accept}(e)
\simeq
\operatorname{accept}(e).
\]

The equivalence must specify which observations ignore duplicate delivery attempts and which diagnostic traces retain them.

## 17.9 Case study: deterministic replay

Both UI and timeline projectors receive a canonical event, session metadata, and a pre-event timeline view. The interface does not prohibit a projector from reading time, randomness, network state, or mutable globals.

### Functoriality requirement

A deterministic projector should extend to a functor from event histories to materialized states. Composition requires batch and stepwise processing to agree.

### Hidden-coordinate audit

For every projector, record:

| Input | Explicit in replay? | Stability contract |
|---|---:|---|
| event payload | yes | canonical schema |
| prior timeline view | yes | cut-indexed |
| session metadata | partially | version must be fixed |
| wall clock | usually no | prohibit or event-source |
| randomness | usually no | seed or event-source |
| network lookup | no | snapshot or canonical event |
| schema version | ambient | pin per replay |

If any uncontrolled input remains, weaken the deterministic replay theorem or expand the source object.

## 17.10 Case study: snapshot-before-live hydration

The WebSocket adapter registers a subscription in a hydrating state, loads a snapshot, buffers concurrent UI batches, sends the snapshot, flushes batches newer than the cut in order, then marks the subscription live.

This is the strongest direct sheaf example in the repository.

### Cover

\[
\{U_{snapshot},U_{registered\ future}\}
\to
U_{client\ subscription}.
\]

### Matching data

- session identity,
- snapshot cut,
- event ordinals of buffered batches,
- registration boundary,
- subscription lifecycle state.

### Amalgamation

The client-visible history formed from snapshot plus ordered suffix.

### Explicit non-gluing outcomes

- authorization denial,
- snapshot load failure,
- buffer overflow,
- connection closure,
- protocol decode failure.

These should remain explicit outcomes rather than silently incomplete histories.

## 17.11 Case study: observer traces

Transport observers are delivered through a bounded best-effort dispatcher, separate from socket critical paths. Records may be dropped under backpressure, while accepted records are delivered in order and drained during shutdown subject to context bounds.

A diagnostic observer is therefore not an authority sheaf for runtime truth. Its section sets should include loss metadata or interval uncertainty.

A useful model is a presheaf of trace intervals:

\[
\mathcal O(I)
=
\{\text{observer records known for interval }I,
\text{ plus drop bounds}\}.
\]

Restriction trims the interval and preserves relevant drop evidence. A morphism maps concrete traces to an abstract transition trace.

Do not infer "no event occurred" from "no observer record exists" when records are lossy.

## 17.12 Which mathematical tool fits which obligation?

| Obligation | First tool | Secondary tool |
|---|---|---|
| Per-session apply order | transition system, linearizability | functorial replay |
| Stable retry identity | type/coordinate design, quotient | coequalizer |
| Consistent snapshot cut | transaction, pullback, subobject | sheaf cover |
| Atomic projection progress | transaction or recovery automaton | face-level cellular model |
| Deterministic replay | purity, explicit inputs | functor/naturality |
| Snapshot plus suffix | presheaf and sheaf gluing | trace refinement |
| Observer delivery | bounded queue state machine | trace presheaf |
| Cursor convention cycles | typed coordinates | cellular \(H^1\) |
| Parameter sufficiency | fibers and factorization | adjoint quantifiers |

This table is a guardrail against using cohomology as a universal metaphor.

## 17.13 A concrete architecture cochain

Create vertices:

\[
E,T,S,C
\]

for event cursor, timeline checkpoint, snapshot cut, and client's next expected ordinal. Normalize all but \(C\) to "last included." Let \(C\) remain "next expected."

The correct edge transformations have offsets:

\[
E\to T:0,
\quad
T\to S:0,
\quad
S\to C:+1,
\quad
C\to E:-1.
\]

Store these offsets as an affine 1-cochain. A code review that replaces the final `-1` conversion with identity produces cycle sum \(+1\), a concrete non-exact class.

This model can be generated from typed conversion declarations. It is more reliable than inferring offsets from variable names.

## 17.14 Research-grade evidence ladder

For each law, build evidence in increasing strength:

1. vocabulary and type distinctions,
2. executable unit examples,
3. property-based tests,
4. deterministic schedule tests,
5. finite-state model exploration,
6. linear sheaf diagnostics where applicable,
7. mechanized proofs of a pure kernel,
8. runtime refinement traces connecting implementation to kernel.

No single layer substitutes for all others. The categorical model helps keep abstraction maps and composition laws explicit across the ladder.

## Exercises

1. **[S]** Classify each SessionStream case study as primarily a missing-coordinate, local-to-global, temporal-order, or linear-cycle problem.
2. Draw the event/materialization/cursor triangle. State what data must inhabit a genuine transaction face.
3. Formalize the snapshot invariant as a subobject and its database read as a candidate section.
4. **[S]** Explain why stable retry identity should be solved before computing cohomology on retry traces.
5. Write the naturality square for rebuilding a timeline before versus after a schema migration.
6. Implementation lab: create a deterministic schedule that applies ordinal \(n+1\) before \(n\) and assert the desired serial observation.
7. Implementation lab: emit typed cursor-conversion declarations and compute signed cycle sums.
8. Architecture lab: model observer traces without treating missing records as negative evidence.
9. Design a failure section for hydration overflow. Decide whether it belongs to the same sheaf or to an enlarged outcome sheaf.
10. **[S]** Explain why UI fanout should not automatically be part of the atomic durable projection face.
EOF

cat > /mnt/data/sessionstream_textbook_work/18-analyzer-study-program.md <<'EOF'
# Building a Local-to-Global Analyzer

> **Capstone chapter:** The objective is not to build a universal category-theory framework. It is to build a small instrument that makes one model explicit, checks its laws, and produces counterexamples.

## 18.1 Scope the first analyzer narrowly

Choose one invariant family:

> Every cursor-like coordinate in the snapshot-and-live path is connected by explicit conversions, and every architecture cycle has zero net conversion offset.

This scope is intentionally linear. It avoids payload semantics, arbitrary set-valued sections, and temporal liveness.

Inputs:

- contexts as vertices,
- pairwise comparison contracts as edges,
- optional joint witnesses as faces,
- stalk dimensions,
- restriction matrices or affine transforms,
- observed local values or edge relations.

Outputs:

- malformed model errors,
- residuals on edges and faces,
- dimensions of \(H^0\) and \(H^1\),
- representative nontrivial cycles,
- least-squares repaired assignments when exact gluing fails.

![A practical workflow moves from runtime traces to local sections, overlap checks, global-section search, and only then cohomological diagnostics.](assets/research_pipeline.png){#fig:research-pipeline width=94%}

## 18.2 Data model

A minimal YAML-like source format could be:

```yaml
field: rational
cells:
  - id: event
    dim: 0
    stalk: [lastIncluded]
  - id: timeline
    dim: 0
    stalk: [lastApplied]
  - id: snapshot
    dim: 0
    stalk: [snapshotCut]
  - id: client
    dim: 0
    stalk: [nextExpected]
  - id: event_timeline
    dim: 1
    stalk: [normalizedCut]
  - id: timeline_snapshot
    dim: 1
    stalk: [normalizedCut]
  - id: snapshot_client
    dim: 1
    stalk: [homogeneousCut, constant]
incidences:
  - from: event
    to: event_timeline
    matrix: [[1]]
  - from: timeline
    to: event_timeline
    matrix: [[1]]
```

For affine transforms, either store an offset separately or homogenize coordinates.

Do not allow an incidence without a semantic label. A matrix alone is not documentation.

## 18.3 Stage 1: validate the category and restrictions

Before linear algebra, check:

- every incidence points from a face to a coface,
- stalk dimensions match matrix dimensions,
- identity maps are identities,
- composed restriction maps agree on every chain of cells,
- every face boundary has consistent orientations,
- \(\delta^{k+1}\delta^k=0\).

The final check catches both incidence-sign errors and nonfunctorial restriction maps.

## 18.4 Stage 2: set-valued matching checker

Some SessionStream invariants are not linear. Implement a separate finite checker:

```go
type ContextID string

type Section struct {
    Values map[string]string
}

type Restrict func(Section) (Section, error)

type Cover struct {
    Target  ContextID
    Members []ContextID
}
```

For each cover:

1. enumerate or load local sections,
2. restrict every pair to its overlap,
3. retain matching families,
4. search candidate global sections,
5. count extensions.

Classify each family:

- zero extensions: obstruction or missing data,
- one extension: unique gluing,
- multiple extensions: underdetermination.

For large spaces, compile constraints to SAT/SMT rather than enumerate.

## 18.5 Stage 3: assemble cellular coboundaries

For a graph sheaf, choose an orientation for every edge \(e=(v,w)\). The block row of \(\delta^0\) is

\[
\begin{bmatrix}
\cdots & -\rho_{v e} & \cdots & \rho_{w e} & \cdots
\end{bmatrix}.
\]

For higher cells, use signed incidences and the face-to-coface restriction matrices.

Verify dimensions and \(\delta^1\delta^0=0\) before computing ranks.

## 18.6 A small \(\mathbb F_2\) rank routine

The following code is enough to compute ordinary Betti numbers of a finite complex over \(\mathbb F_2\). A general sheaf analyzer replaces scalar entries with assembled block matrices.

```go
package cohomology

// Matrix entries are interpreted modulo 2.
type Matrix [][]uint8

func cloneMatrix(a Matrix) Matrix {
    out := make(Matrix, len(a))
    for i := range a {
        out[i] = append([]uint8(nil), a[i]...)
    }
    return out
}

func RankF2(a Matrix) int {
    m := cloneMatrix(a)
    if len(m) == 0 {
        return 0
    }
    rows, cols := len(m), len(m[0])
    rank := 0

    for col := 0; col < cols && rank < rows; col++ {
        pivot := -1
        for row := rank; row < rows; row++ {
            if m[row][col]&1 == 1 {
                pivot = row
                break
            }
        }
        if pivot < 0 {
            continue
        }
        m[rank], m[pivot] = m[pivot], m[rank]

        for row := 0; row < rows; row++ {
            if row == rank || m[row][col]&1 == 0 {
                continue
            }
            for j := col; j < cols; j++ {
                m[row][j] ^= m[rank][j]
            }
        }
        rank++
    }
    return rank
}

// d0 has shape n1 x n0 and d1 has shape n2 x n1.
func Betti01(n0, n1 int, d0, d1 Matrix) (beta0, beta1 int) {
    r0 := RankF2(d0)
    r1 := RankF2(d1)
    beta0 = n0 - r0
    beta1 = (n1 - r1) - r0
    return beta0, beta1
}
```

Tests should include:

- a path: \((\beta_0,\beta_1)=(1,0)\),
- a cycle: \((1,1)\),
- a filled cycle: \((1,0)\),
- two disconnected paths: \((2,0)\).

## 18.7 Rational and real coefficients

Ordinal offsets are signed integers, so \(\mathbb F_2\) loses direction and magnitude. Use:

- exact rational arithmetic for conversion equations,
- integer normal forms for integral structure,
- floating-point SVD for noisy telemetry,
- finite fields for parity-like constraints.

With floating point, report singular values and tolerance. Never report a rank without the tolerance used.

## 18.8 Trace ingestion

A runtime trace adapter should produce local sections rather than directly produce matrices.

Example pipeline:

1. parse typed transport and pipeline records,
2. group by `SessionId`, connection, and event ordinal,
3. map records to context-local facts,
4. preserve uncertainty and dropped-record counts,
5. restrict to the analysis window,
6. build observed 0- or 1-cochains,
7. run exact and approximate checks.

The adapter should be a presheaf morphism: restricting a time window before abstraction should agree with abstracting and then restricting.

## 18.9 Diagnostics

A useful diagnostic should say more than "H1 nonzero."

Example:

```text
coordinate cycle is not exact
cycle: event -> timeline -> snapshot -> client -> event
signed offset sum: +1
edges:
  event -> timeline: 0
  timeline -> snapshot: 0
  snapshot -> client: +1
  client -> event: 0   expected -1 under declared conventions
suggested checks:
  - nextExpected vs lastIncluded conversion
  - missing affine offset declaration
  - inconsistent ordinal type alias
```

For set-valued gluing:

```text
matching family has no global extension
cover: snapshot + buffered-live
session: s-42
snapshot cut: 100
accepted live ordinal: 101
classification: neither represented nor delivered
first blocking transition: hydration buffer overflow without reconnect outcome
```

The mathematical object should lead to an engineering witness.

## 18.10 Analyzer architecture

Keep layers separate:

- `model`: cells, contexts, covers, restrictions,
- `validate`: category and presheaf laws,
- `sections`: matching and global-extension search,
- `linear`: matrices, ranks, nullspaces, Laplacians,
- `trace`: SessionStream-specific adapters,
- `report`: human-readable witnesses,
- `fixtures`: small known complexes and mutated contracts.

Do not make the core package depend on SessionStream types. SessionStream should be one adapter and one library of models.

## 18.11 Mutation suite

Seed deliberate faults:

1. replace `nextExpected = lastIncluded + 1` with identity,
2. swap two ordinal applications,
3. omit one buffered batch,
4. duplicate one batch across snapshot and suffix,
5. read cursor and entity rows from different epochs,
6. advance a projection cursor after failed materialization,
7. give a redelivery a new logical identity,
8. drop an observer record without incrementing loss metadata,
9. make a schema migration path-dependent,
10. break one restriction-composition law.

Each mutation should be caught by the layer designed for it. A cohomology test should not be praised for catching a failure that a simple type or schedule test should own.

## 18.12 Twelve-week study plan

### Weeks 1-2: arrows and universal properties

Read Goldblatt Chapters 2-3 through limits. Work companion Chapters 1-5. Implement products, equalizers, and pullback examples as tests.

### Weeks 3-4: histories, functors, naturality

Work Chapters 6-8. Build a pure chat reducer and test fold composition, migration naturality, and cross-session commutation.

### Week 5: adjunctions and parameter fibers

Work Chapter 9. Build a finite parameter-sufficiency enumerator.

### Weeks 6-7: presheaves and sheaves

Read Goldblatt Chapter 14. Work Chapters 10-12. Implement a finite context poset, restrictions, matching families, and global extension counts.

### Week 8: local truth and topoi

Read selected Goldblatt Chapters 4-8 and companion Chapter 13. Rewrite three booleans as context-specific predicates.

### Weeks 9-10: complexes and cohomology

Work Chapters 14-16. Implement incidence matrices, \(H^0\), \(H^1\), and affine cycle checks.

### Week 11: SessionStream models

Work Chapter 17. Encode snapshot hydration and cursor conventions. Add at least five mutations.

### Week 12: capstone report

Build one trace adapter, run it against deterministic tests, and write a short report separating:

- proved model laws,
- executable evidence,
- unverified refinement assumptions,
- and open correctness obligations.

## 18.13 Capstone options

### A. Hydration sheaf checker

Model snapshot and live suffix sections, enumerate matching families, and produce a minimal missing-or-duplicate ordinal witness.

### B. Cursor coordinate cohomology

Generate an architecture graph from typed cursor converters, assemble an affine cochain, and report nonzero cycle sums.

### C. Projection-commit descent model

Represent append, apply, cursor advance, and recovery states as a finite site. Determine which declared covers satisfy unique gluing.

### D. Runtime refinement trace

Map concrete observer-dispatch records to a proved abstract kernel and check naturality under trace restriction.

## 18.14 Final discipline

When the analyzer reports a result, ask four questions:

1. Is the base shape faithful to the architecture?
2. Are the stalks rich enough to express the invariant?
3. Are the restriction maps implemented and composed correctly?
4. Does the coefficient system preserve the nonlinear semantics that matter?

A cohomology calculation is exact about the model you built. The difficult scientific work is demonstrating that the model is the right abstraction of the software.

## Exercises

1. **[S]** Implement the path, cycle, and filled-cycle tests for `Betti01`.
2. Design a JSON schema for cells, stalks, incidences, and covers.
3. Add a check that \(\delta^1\delta^0=0\) and return the first nonzero matrix entry as a witness.
4. **[S]** Explain why runtime traces should first become local sections rather than being treated directly as cochains.
5. Implement a finite global-extension counter for map-valued sections.
6. Add affine homogeneous coordinates to the graph-sheaf matrix assembler.
7. Write one mutation that should be caught by a presheaf-law check and one caught only by a cycle check.
8. Capstone: complete one project in Section 18.13 and document every abstraction assumption.
EOF

wc -w /mnt/data/sessionstream_textbook_work/17-sessionstream-case-studies.md /mnt/data/sessionstream_textbook_work/18-analyzer-study-program.md
```

<details><summary>💭 Thinking</summary>

**Developed SessionStream topological case studies**

**Preparing appendices**

I’m adding notation, a Goldblatt reading map, selected solutions, a glossary, and implementation labs so the textbook supports both mathematical study and SessionStream engineering practice.

**Prepared appendices**

</details>

```unknown
bash -lc ls -la /mnt/data/sessionstream_textbook_work && echo '--- chapters' && find /mnt/data/sessionstream_textbook_work -maxdepth 1 -type f -printf '%f %s bytes
' | sort && echo '--- assets' && find /mnt/data/sessionstream_textbook_work/assets -maxdepth 1 -type f -printf '%f %s bytes
' | sort | sed -n '1,80p'
```

<details><summary>💭 Thinking</summary>

**Inspected textbook assets, chapter structures, guidelines, definitions, and Markdown characters**

</details>

```unknown
bash -lc cat > /mnt/data/sessionstream_textbook_work/19-selected-solutions.md <<'EOF'
\appendix

# Selected Solutions and Substantial Hints

These solutions correspond only to exercises marked **[S]**. They are written to expose the proof pattern rather than merely state the result. For diagram exercises, redraw the diagram and verify every domain and codomain before reading the argument.

## Chapter 1

### Exercise 1: a category of protobuf schemas

Choose a fixed universe of protobuf message descriptors. An object is a concrete message schema, including its field numbers, types, oneof structure, and any validation rules regarded as part of the contract.

An arrow

\[
 m:A\to B
\]

is a total migration function from valid values of schema \(A\) to valid values of schema \(B\). "Total" means every valid \(A\)-value has an image. "Validation-preserving" means \(m(a)\) satisfies the declared validity predicate of \(B\) whenever \(a\) satisfies that of \(A\).

The identity on \(A\) is the identity migration \(1_A(a)=a\). Composition is ordinary function composition. Totality and validation preservation are closed under composition, so the category laws follow from the category of sets and functions.

Arrow equality must be semantic rather than source-code identity:

\[
 m=n
 \quad\Longleftrightarrow\quad
 \forall a\in\operatorname{Valid}(A),\;m(a)=n(a).
\]

Two Go functions with different implementations but identical outputs on every valid input are the same arrow in this category. If error values, warnings, telemetry, or provenance are semantically relevant, they must be included in the codomain; otherwise the category deliberately forgets them.

### Exercise 6: why the empty trace is an identity

Let traces compose by concatenation. An identity trace \(\epsilon\) must satisfy

\[
 \epsilon w=w,
 \qquad
 w\epsilon=w
\]

for every trace word \(w\). This is not merely an optimization saying that running no operations happens to leave state unchanged. The identity laws are required for composition to form a category or monoid at all.

Without an explicit empty trace, there would be no identity arrow for an execution state, so a supposedly compositional trace algebra would fail one of the category axioms. Treating \(\epsilon\) as a first-class trace also supports induction on trace length and gives the base case of fold laws.

## Chapter 2

### Exercise 2: cancellation in the one-object addition category

Create one object \(*\). Let each natural number \(n\) be an arrow \(*\to *\), with composition defined by addition:

\[
 m\circ n=m+n.
\]

The identity is \(0\). An arrow \(k\) is monic exactly when

\[
 k\circ m=k\circ n\Longrightarrow m=n.
\]

Under the definition of composition, this becomes

\[
 k+m=k+n\Longrightarrow m=n,
\]

which is left cancellation for addition. Since addition of natural numbers is commutative, the same arrows are also epic, expressing right cancellation. This example shows that monic and epic are cancellation properties of composition, not definitions involving injective or surjective functions.

## Chapter 3

### Exercise 1: composites of monics

Let

\[
 A\xrightarrow{f}B\xrightarrow{g}C
\]

with \(f\) and \(g\) monic. Suppose arrows \(u,v:X\to A\) satisfy

\[
 (g\circ f)\circ u=(g\circ f)\circ v.
\]

Associativity gives

\[
 g\circ(f\circ u)=g\circ(f\circ v).
\]

Since \(g\) is monic,

\[
 f\circ u=f\circ v.
\]

Since \(f\) is monic, \(u=v\). Therefore \(g\circ f\) is monic. Notice the proof uses only composition, associativity, and the cancellation definition.

### Exercise 5: a decoder as a retraction

Let

\[
 E:V\to B
\]

encode valid values into byte strings, and

\[
 D:B\to V_\bot
\]

decode arbitrary bytes into either a valid value or failure. Restricted to the valid encoded image, one may have

\[
 D\circ E=1_V.
\]

Thus \(D\) is a retraction of \(E\), and \(E\) is a section of \(D\), after choosing a codomain that represents failure appropriately.

An isomorphism would also require

\[
 E\circ D=1_B.
\]

That generally fails. Invalid byte strings may decode to failure, multiple byte strings may decode to the same semantic value, and canonical encoding may replace a noncanonical representation with a canonical one. Hence the round trip is exact on valid values without establishing a bijection between all bytes and values.

## Chapter 4

### Exercise 1: uniqueness of terminal objects

Let \(T\) and \(T'\) both be terminal. Since \(T'\) is terminal, there is a unique arrow

\[
 f:T\to T'.
\]

Since \(T\) is terminal, there is a unique arrow

\[
 g:T'\to T.
\]

Now \(g\circ f:T\to T\). The identity \(1_T:T\to T\) is another arrow with the same domain and codomain. Terminality of \(T\) says there is exactly one such arrow, so

\[
 g\circ f=1_T.
\]

Similarly,

\[
 f\circ g=1_{T'}.
\]

Therefore \(f\) and \(g\) are inverse isomorphisms. They are unique because each was forced by terminality. Thus terminal objects are unique up to unique isomorphism, not necessarily literal equality.

### Exercise 4: encoding a cut inequality as an equalizer

Let \(O\) be the set of observation records containing two natural numbers:

\[
 O=\{(e,s,\ldots)\mid e=\texttt{LastEventOrdinal},\;s=\texttt{SnapshotOrdinal}\}.
\]

The desired subset is

\[
 V=\{o\in O\mid e(o)\le s(o)\}.
\]

An equalizer selects points where two arrows are equal, whereas \(e\le s\) is an inequality. Encode the inequality as equality by defining, for example,

\[
 a,b:O\to\mathbb N
\]

with

\[
 a(o)=e(o),
 \qquad
 b(o)=\min(e(o),s(o)).
\]

Then

\[
 a(o)=b(o)
 \quad\Longleftrightarrow\quad
 e(o)\le s(o).
\]

The inclusion \(V\hookrightarrow O\) is therefore the equalizer of \(a\) and \(b\) in \(\mathbf{Set}\). Other encodings are possible, such as arrows into the two-element truth-value set. The modeling lesson is that an equalizer requires an explicitly selected notion of observable equality.

## Chapter 5

### Exercise 1: product as a limit

Let \(J\) be the discrete category with two objects \(0,1\). A diagram \(D:J\to\mathcal C\) merely chooses objects \(A=D(0)\) and \(B=D(1)\); there are no nonidentity compatibility conditions.

A cone with apex \(X\) is therefore exactly a pair of arrows

\[
 f:X\to A,
 \qquad
 g:X\to B.
\]

A limiting cone is an object \(P\) with projections \(\pi_A:P\to A\), \(\pi_B:P\to B\) such that every pair \((f,g)\) factors through a unique \(u:X\to P\):

\[
 \pi_A\circ u=f,
 \qquad
 \pi_B\circ u=g.
\]

This is precisely the universal property of the binary product \(A\times B\). Hence the product is the limit of the two-object discrete diagram.

### Exercise 4: authorized subscription pullback

Let

\[
 A=\{(p,s)\mid p\text{ is authorized for session }s\},
\]

\[
 R=\{(s,n)\mid \text{a request subscribes to }s\text{ since cut }n\},
\]

and let \(S\) be the set of session identifiers. Define

\[
 f:A\to S,\quad f(p,s)=s,
\]

\[
 g:R\to S,\quad g(s,n)=s.
\]

The pullback is

\[
 P=A\times_S R
 =\{((p,s),(s',n))\mid s=s'\}.
\]

It can be represented more compactly as valid triples \((p,s,n)\). The projections are

\[
 \pi_A(p,s,n)=(p,s),
 \qquad
 \pi_R(p,s,n)=(s,n),
\]

and they commute because \(f\pi_A=g\pi_R=s\).

For any set \(X\) with arrows \(a:X\to A\) and \(r:X\to R\) satisfying \(f a=g r\), define

\[
 u(x)=(a(x),r(x)).
\]

The matching equation ensures \(u(x)\in P\). Its projections are \(a\) and \(r\). Any other mediator with those projections must have the same ordered-pair value at every \(x\), so \(u\) is unique. This proves the universal property.

### Exercise 10: transaction contexts and sheaf laws

A read transaction can make several facts jointly observable at one database snapshot. In a context model, this may justify adding a larger context \(U\) whose restrictions expose the cursor view, entity view, and projection-progress view. It can also justify declaring those smaller contexts to cover \(U\).

That does not prove a sheaf law. One still must specify:

1. the sections permitted over every context,
2. the restriction maps,
3. the covers under consideration,
4. what compatibility on overlaps means,
5. existence of a glued section for every matching family,
6. uniqueness of that glued section.

A transaction supplies an implementation mechanism for one class of joint witness. It may still return semantically invalid rows, omit hidden state, expose ambiguous completions, or fail to support other covers. Sheafhood is a property of the entire indexed data model, not a synonym for atomicity.

## Chapter 6

### Exercise 1: the fold concatenation law

Let \(\operatorname{fold}(x,w)\) apply the events of word \(w\) to initial state \(x\). Prove

\[
 \operatorname{fold}(x,uv)
 =
 \operatorname{fold}(\operatorname{fold}(x,u),v)
\]

by induction on \(v\).

Base case: \(v=\epsilon\). Then

\[
 \operatorname{fold}(x,u\epsilon)
 =\operatorname{fold}(x,u)
 =\operatorname{fold}(\operatorname{fold}(x,u),\epsilon).
\]

Inductive step: suppose the law holds for \(v\), and append event \(e\). Using the recursive definition of fold,

\[
 \begin{aligned}
 \operatorname{fold}(x,u(ve))
 &=\operatorname{step}(\operatorname{fold}(x,uv),e)\\
 &=\operatorname{step}(\operatorname{fold}(\operatorname{fold}(x,u),v),e)\\
 &=\operatorname{fold}(\operatorname{fold}(x,u),ve).
 \end{aligned}
\]

Thus the law holds for all event words.

### Exercise 5: payload equality is not delivery identity

Two distinct legitimate events may have equal payloads. Two token-delta events could both contain the string `"the"`; two inventory adjustments could both contain `+1`; two users could submit identical prompts. Quotienting by payload equality would incorrectly identify different causal occurrences.

Retry identity must instead use a stable logical event identity, or a declared idempotency key tied to the producer operation. Payload equality can be one field in a conflict check, but it cannot generally determine whether two deliveries represent one logical event or two events with equal content.

## Chapter 7

### Exercise 1: a deterministic fold as a functor

Let \(\mathcal H\) be the one-object category whose arrows are event words, identity is the empty word, and composition is concatenation. Let \(\mathcal T\) be the one-object category whose arrows are endofunctions on state set \(X\), identity is \(1_X\), and composition is function composition.

Define \(F:\mathcal H\to\mathcal T\) by assigning to event word \(w\) the state transformer

\[
 F(w)(x)=\operatorname{fold}(x,w).
\]

Identity preservation follows from

\[
 F(\epsilon)(x)=\operatorname{fold}(x,\epsilon)=x.
\]

Composition preservation follows from the fold concatenation law. With the convention that \(uv\) means first \(u\), then \(v\),

\[
 F(uv)(x)
 =\operatorname{fold}(x,uv)
 =F(v)(F(u)(x)),
\]

so

\[
 F(uv)=F(v)\circ F(u).
\]

The apparent order depends on the chosen convention for word composition; once that convention is fixed, the functor law is exact.

### Exercise 5: why presheaves reverse inclusions

Suppose \(V\subseteq U\). A section over \(U\) contains enough information to be observed on the smaller context \(V\), so there is a restriction function

\[
 \rho^U_V:\mathcal F(U)\to\mathcal F(V).
\]

The inclusion arrow points from \(V\) to \(U\), while the data map points from \(\mathcal F(U)\) to \(\mathcal F(V)\). Hence the assignment reverses arrows. Formally, it is a covariant functor from the opposite category:

\[
 \mathcal F:\mathcal C^{op}\to\mathbf{Set}.
\]

This reversal is not arbitrary. More context can be forgotten to produce less context; a local observation cannot generally be extended to a larger context without additional choices.

## Chapter 8

### Exercise 1: migration naturality square

Let \(S_o\) and \(S_n\) be old and new snapshot state spaces. Let

\[
 T_o(e):S_o\to S_o,
 \qquad
 T_n(Me):S_n\to S_n
\]

be transition functions for an old event \(e\) and its migrated event \(Me\). Let \(\mu:S_o\to S_n\) migrate snapshots. The naturality/refinement square is

\[
 \begin{CD}
 S_o @>{T_o(e)}>> S_o\\
 @V{\mu}VV @VV{\mu}V\\
 S_n @>{T_n(Me)}>> S_n.
 \end{CD}
\]

Commutation means

\[
 \mu\circ T_o(e)=T_n(Me)\circ\mu.
\]

Migrating after one old transition must equal migrating first and applying the corresponding new transition. For traces, prove the analogous statement by induction.

### Exercise 4: naturality of a presheaf transformation

Let \(\eta:\mathcal F\Rightarrow\mathcal G\) be a natural transformation of presheaves. For every inclusion or refinement arrow \(V\subseteq U\), naturality says

\[
 \rho^{\mathcal G,U}_V\circ\eta_U
 =
 \eta_V\circ\rho^{\mathcal F,U}_V.
\]

In restriction notation,

\[
 \eta_U(s)|_V=\eta_V(s|_V).
\]

Transforming a broad observation and then narrowing it must equal narrowing first and transforming locally.

## Chapter 9

### Exercise 1: factorization through parameters

Let \(p:X\to P\) expose parameters and \(I:X\to Y\) be an invariant-valued function.

First suppose \(I\) factors through \(p\), so \(I=\bar I\circ p\) for some \(\bar I:P\to Y\). If \(p(x)=p(x')\), then

\[
 I(x)=\bar I(p(x))=\bar I(p(x'))=I(x').
\]

Thus \(I\) is constant on each fiber of \(p\).

Conversely, suppose \(I\) is constant on each fiber. Define \(\bar I\) on the image of \(p\) by

\[
 \bar I(q)=I(x)
 \quad\text{for any }x\text{ with }p(x)=q.
\]

Fiber constancy makes this well-defined. If \(p\) is surjective, this defines \(\bar I:P\to Y\). If not, choose arbitrary values outside \(\operatorname{im}p\), or more precisely factor through \(\operatorname{im}p\). Then \(I=\bar I\circ p\).

So parameters decide the invariant precisely when the invariant cannot distinguish two global states with the same parameters.

### Exercise 4: the free-monoid adjunction in event sourcing

For a set \(E\) of event symbols, the free monoid \(E^*\) contains finite event histories, with concatenation and empty history. The forgetful functor \(U:\mathbf{Mon}\to\mathbf{Set}\) forgets multiplication.

The adjunction

\[
 \mathbf{Mon}(E^*,M)
 \cong
 \mathbf{Set}(E,U(M))
\]

says that assigning a semantic action to each primitive event uniquely extends to a monoid homomorphism on complete histories.

In event-sourcing terms, choose a monoid \(M\) of state transformations or effects. A function assigning each event type its transition transformer determines one and only one fold homomorphism on event words. The universal property explains why a reducer is specified by its behavior on generators, provided composition is deterministic and respects concatenation.

## Chapter 10

### Exercise 1: a cursor-observation presheaf

Let the base poset be the powerset of

\[
 K=\{E,P,S,C\}
\]

ordered by inclusion, where the letters denote event, projection, snapshot, and client coordinate systems. For a context \(U\subseteq K\), define

\[
 \mathcal F(U)
 =
 \{x:U\to\mathbb N\mid x\text{ satisfies all cursor relations visible within }U\}.
\]

For \(V\subseteq U\), define restriction by ordinary function restriction:

\[
 \rho^U_V(x)=x|_V.
\]

Identity holds because \(x|_U=x\). Composition holds because

\[
 (x|_V)|_W=x|_W
 \qquad(W\subseteq V\subseteq U).
\]

This is a presheaf only if every valid section over \(U\) restricts to a valid section over \(V\). That condition forces "visible relations" to be hereditary under forgetting.

### Exercise 4: payload-redaction naturality

Let \(R_U:\mathcal T(U)\to\mathcal R(U)\) redact payloads from traces observed in context \(U\). For every refinement \(V\subseteq U\), require

\[
 \rho^{\mathcal R,U}_V\circ R_U
 =
 R_V\circ\rho^{\mathcal T,U}_V.
\]

Equivalently,

\[
 R_U(t)|_V=R_V(t|_V).
\]

If redaction depends on facts that disappear under restriction, this square may fail. The failure identifies either a nonlocal redaction policy or a context model that omitted policy inputs.

## Chapter 11

### Exercise 1: variable assignments form a sheaf

Fix a set of variables \(X\) and value set \(V\). For \(U\subseteq X\), let

\[
 \mathcal F(U)=V^U
\]

be assignments of values to variables in \(U\). Restrictions are ordinary function restrictions.

Let \(U=\bigcup_i U_i\), and let assignments \(s_i:U_i\to V\) agree on every overlap:

\[
 s_i|_{U_i\cap U_j}=s_j|_{U_i\cap U_j}.
\]

Define \(s:U\to V\) by selecting any \(i\) with \(x\in U_i\) and setting \(s(x)=s_i(x)\). This is well-defined because if \(x\in U_i\cap U_j\), compatibility gives \(s_i(x)=s_j(x)\). Clearly \(s|_{U_i}=s_i\).

For uniqueness, any other assignment \(t\) with the same restrictions satisfies, for every \(x\in U\),

\[
 t(x)=t|_{U_i}(x)=s_i(x)=s(x)
\]

for some \(i\) containing \(x\). Hence \(t=s\).

### Exercise 4: two-patch sheaf condition as an equalizer

For a cover \(U=U_1\cup U_2\), form the two arrows

\[
 \mathcal F(U_1)\times\mathcal F(U_2)
 \rightrightarrows
 \mathcal F(U_1\cap U_2)
\]

where

\[
 d_0(s_1,s_2)=s_1|_{U_1\cap U_2},
\]

\[
 d_1(s_1,s_2)=s_2|_{U_1\cap U_2}.
\]

The equalizer consists exactly of matching pairs. The restriction map

\[
 r:\mathcal F(U)\to\mathcal F(U_1)\times\mathcal F(U_2),
 \qquad
 r(s)=(s|_{U_1},s|_{U_2})
\]

always lands in that equalizer. The sheaf condition says \(r\) is an isomorphism onto it: every matching pair has one and only one global antecedent.

### Exercise 10: pairwise checks need valid overlaps

A statement such as "A agrees with B" is meaningful only after specifying a common context and two restriction maps into it. Informal pairwise checks may compare differently normalized values, values read at different epochs, or values whose apparent shared field names have different semantics.

Even correctly defined pairwise overlaps do not automatically provide a global section unless the chosen cover and presheaf satisfy descent. Pairwise compatibility is input to the sheaf theorem, not a replacement for it. The sheaf condition additionally demands one global section and its uniqueness.

For higher-order covers, pairwise intersections must themselves compose coherently on triple intersections. Without those maps and laws, "all pairs agree" may conceal path-dependent comparison.

## Chapter 12

### Exercise 1: coverage axioms in software language

A software coverage relation should obey three structural principles.

**Identity.** A context covers itself. Observing the complete declared context is sufficient evidence for that same context.

**Base change.** If contexts \(U_i\) cover \(U\), then after narrowing along any map \(V\to U\), the corresponding pullback or restricted contexts cover \(V\). Coverage remains valid when the question is refined.

**Transitivity.** If \(U_i\) cover \(U\), and each \(U_i\) is in turn covered by contexts \(V_{ij}\), then the combined \(V_{ij}\) cover \(U\). Coverage evidence may be refined in stages.

These axioms concern the declared notion of coverage. They do not by themselves say that any particular presheaf glues over those covers.

### Exercise 4: transaction stability under entity-kind refinement

Suppose one transaction reads a session cut and all entity rows represented at that same database snapshot. This gives a joint context \(U\). Now refine to a particular entity kind \(K\). The pullback/refined context is obtained by applying a predicate such as `kind = K` within the same transaction snapshot.

Because the transaction's database snapshot is fixed, both the cut and the selected entity rows remain observations of the same epoch. The original coverage witness therefore restricts to a coverage witness for the narrowed context. This is a concrete base-change argument.

If the kind filter caused a fresh query outside the transaction, the property could fail: refinement would no longer preserve the common epoch. Thus pullback stability is an implementation obligation, not just a diagram label.

## Chapter 13

### Exercise 1: valid snapshots as a subobject

Let \(R\) be the set of all records with the syntactic snapshot shape:

\[
 r=(\text{SessionId},\text{SnapshotOrdinal},\text{Entities}).
\]

Define predicate \(P(r)\) to require, for example:

- nonempty `SessionId`,
- every entity belongs to that session,
- every entity satisfies its registered schema,
- every `LastEventOrdinal` is at most `SnapshotOrdinal`,
- entity keys are unique,
- tombstone policy is respected.

Then

\[
 V=\{r\in R\mid P(r)\}
\]

with inclusion \(m:V\hookrightarrow R\) is a subobject of \(R\) in \(\mathbf{Set}\). Different implementations of the same inclusion represent the same subobject when they differ by an isomorphism over \(R\).

In a topos, this subobject has a classifying map \(\chi_m:R\to\Omega\). The truth value \(\chi_m(r)\) need not be a global Boolean when validity is contextual.

### Exercise 4: absence of observation versus observed negation

`not observed(P)` says the available evidence does not establish \(P\). `observed(not P)` says the available evidence positively establishes a contradictory condition.

A missing transport record could mean the event did not occur, the observer dropped a record, the observation window ended too early, or the observer lacked authority. None of those alone establishes that the event did not occur.

This distinction is central to constructive and local semantics. Information may grow under refinement: a later or broader context may establish \(P\) without contradicting the earlier context's lack of evidence. Treating absence as falsity would make truth nonmonotone and unsound under partial observation.

## Chapter 14

### Exercise 1: nerve of three pairwise-overlapping APIs

Let the cover consist of contexts \(U_0,U_1,U_2\). Assume each pair has a declared nonempty overlap, but there is no valid triple-overlap context.

The nerve has:

- vertices \([0],[1],[2]\),
- edges \([0,1],[0,2],[1,2]\),
- no 2-simplex \([0,1,2]\).

Geometrically this is the boundary of a triangle, homotopy-equivalent to a circle. The missing filled triangle records the absence of a three-way joint witness. It does not by itself prove inconsistency; it identifies where a one-dimensional obstruction could live for suitable coefficient data.

### Exercise 4: why a dependency graph is not automatically a nerve

A dependency graph records calls, imports, deployments, or ownership relationships. A nerve records intersections of a chosen cover: an edge exists because two contexts have a meaningful common refinement, and a higher simplex exists because all listed contexts share a jointly valid overlap.

Services can depend on each other while sharing no jointly comparable information. Conversely, two independent services may overlap semantically through a shared database record. A nerve therefore requires explicit contexts, covers, and overlap witnesses. Reusing the service graph without this interpretation confuses communication topology with information topology.

## Chapter 15

### Exercise 1: constant sheaf on a path

Let the path have vertices \(v_0,v_1,v_2\) and edges \(e_{01},e_{12}\). Assign stalk \(\mathbb R\) to every vertex and edge. Every restriction map from a vertex to an incident edge is the identity.

A global section is a tuple

\[
 (x_0,x_1,x_2;y_{01},y_{12})
\]

such that

\[
 x_0=y_{01}=x_1,
 \qquad
 x_1=y_{12}=x_2.
\]

Therefore every global section is determined by one scalar \(a\):

\[
 x_0=x_1=x_2=y_{01}=y_{12}=a.
\]

The space of global sections is isomorphic to \(\mathbb R\). In the vertex-only cochain representation, \(H^0=\ker\delta^0\) is the set of constant triples \((a,a,a)\).

### Exercise 4: comparing snapshot cut and entity ordinals

One simple linear design uses two vertex stalks:

\[
 \mathcal F(S)=\mathbb R
 \quad\text{for snapshot cut }n,
\]

\[
 \mathcal F(E)=\mathbb R
 \quad\text{for maximum entity ordinal }m.
\]

Let the comparison edge have stalk \(\mathbb R\), with identity restrictions from both vertices. Global sections enforce \(n=m\). That models exact completeness, not the weaker invariant \(m\le n\).

To model the inequality, use a set-valued sheaf instead:

\[
 \mathcal F(SE)=\{(m,n)\in\mathbb N^2\mid m\le n\},
\]

with restrictions to the two coordinates, or introduce a nonnegative slack variable \(d\) and linear equation

\[
 n-m=d,
 \qquad d\ge0.
\]

The latter requires an ordered cone or constraint system in addition to vector-space linear algebra. The exercise illustrates why stalk semantics must match the invariant rather than forcing every condition into equality over \(\mathbb R\).

## Chapter 16

### Exercise 1: cohomology of a three-vertex path

Orient the path \(v_0\to v_1\to v_2\). For the constant \(\mathbb R\)-sheaf,

\[
 C^0\cong\mathbb R^3,
 \qquad
 C^1\cong\mathbb R^2,
\]

and

\[
 \delta^0=
 \begin{bmatrix}
 -1&1&0\\
 0&-1&1
 \end{bmatrix}.
\]

The kernel consists of \((a,a,a)\), so

\[
 H^0\cong\mathbb R.
\]

The matrix has rank 2. Since the graph has no 2-cells, \(\delta^1=0\), and

\[
 \dim H^1
 =\dim C^1-\operatorname{rank}\delta^0
 =2-2=0.
\]

Thus \(H^1=0\). A path has no independent circulation.

### Exercise 4: exact offsets and cycle sums

Let \(G\) be connected, orient every edge, and let \(r\) assign a scalar to each oriented edge.

If \(r=\delta^0x\), then for edge \(u\to v\),

\[
 r_{uv}=x_v-x_u.
\]

Summing around any directed cycle telescopes to zero. Hence exact assignments have zero signed cycle sum.

Conversely, suppose every cycle sum is zero. Choose a root vertex \(v_0\) and set \(x_{v_0}=0\). For any vertex \(v\), choose a path from \(v_0\) to \(v\) and define \(x_v\) as the signed sum of \(r\) along that path. This is path-independent: two paths form a closed walk, decomposable into cycles, and the difference of their sums is therefore zero.

For any oriented edge \(u\to v\), compare a root-to-\(u\) path followed by that edge with a root-to-\(v\) path. Path independence gives

\[
 x_v=x_u+r_{uv},
\]

so \(r_{uv}=x_v-x_u\). Therefore \(r=\delta^0x\). Connectivity is used to define every \(x_v\); for a disconnected graph, apply the construction separately to each component.

## Chapter 17

### Exercise 1: classify the case studies

The classifications are "primarily" rather than exclusively:

| Case study | Primary diagnosis | Reason |
|---|---|---|
| Snapshot cut read separately from entity rows | local-to-global / consistent-cut | Locally valid reads may have no common epoch section. |
| Materialization applied but projection cursor not advanced | local-to-global / atomic-commit | Durable facts fail to glue to the promised committed state. |
| Retry receives a new ordinal with no stable logical ID | missing coordinate | The model cannot identify two deliveries as one event. |
| Projector consults wall clock or mutable global | missing coordinate | Replay input omits a causal dependency. |
| Snapshot plus buffered/live handoff omits or duplicates an ordinal | temporal-order and gluing | Prefix and suffix fail to reconstruct one history. |
| `lastIncluded` confused with `nextExpected` around adapters | linear-cycle | Declared affine conversions have nonzero circulation. |
| Observer trace drops records without loss metadata | missing coordinate/evidence | Absence cannot distinguish nonoccurrence from observation loss. |
| Cross-session event interleaving changes a per-session projection | temporal-order / isolation | Independent session actions fail expected commutation. |

A mature analysis can model several diagnoses at once, but the primary classification points to the cheapest adequate tool.

### Exercise 4: solve retry identity before cohomology

Cohomology compares values along already-defined contexts and restriction maps. If the model cannot tell which deliveries represent the same logical event, then its vertices and edges are wrong before any matrix is assembled.

A redelivery with a fresh ordinal might appear as an additional event rather than another observation of the same event. Any cycle residual computed from that trace would mix identity ambiguity with coordinate inconsistency. A nonzero class could therefore be an artifact of omitted event identity.

Introduce a stable logical `EventId` or idempotency key, specify its behavior across publication and redelivery, and quotient or group traces by that identity. Only then does a cohomology calculation address residual inconsistency rather than compensate for an under-specified base.

### Exercise 10: why fanout is outside the durable atomic face

The durable projection face naturally joins event append, timeline materialization, and projection progress because together they state what has been committed and can be rebuilt after restart. UI fanout is an external effect to live connections. It may fail because a connection closes, a queue fills, or the network partitions even when the durable state is correct.

Putting fanout in the same atomic transaction is often impossible and can make durable progress depend on ephemeral clients. A better architecture commonly commits durable state first and gives fanout retry, reconnect, or hydration semantics. The resulting correctness statement is not "fanout and storage commit atomically," but something such as:

\[
 \text{durable cut }n
 \quad+\quad
 \text{reconnect from a snapshot at }n
 \quad\Longrightarrow\quad
 \text{eventual client reconstruction}.
\]

This separation must be explicit. Excluding fanout from the durable face does not excuse silent loss; it moves the obligation to a different temporal protocol.

## Chapter 18

### Exercise 1: tests for `Betti01`

Over \(\mathbb F_2\), orientation signs disappear because \(-1=1\). One possible Go test is:

```go
func TestBetti01(t *testing.T) {
    tests := []struct {
        name       string
        n0, n1     int
        d0, d1     Matrix
        want0, want1 int
    }{
        {
            name: "path",
            n0: 3,
            n1: 2,
            d0: Matrix{
                {1, 1, 0},
                {0, 1, 1},
            },
            d1:   Matrix{},
            want0: 1,
            want1: 0,
        },
        {
            name: "cycle",
            n0: 3,
            n1: 3,
            d0: Matrix{
                {1, 1, 0},
                {0, 1, 1},
                {1, 0, 1},
            },
            d1:   Matrix{},
            want0: 1,
            want1: 1,
        },
        {
            name: "filled-cycle",
            n0: 3,
            n1: 3,
            d0: Matrix{
                {1, 1, 0},
                {0, 1, 1},
                {1, 0, 1},
            },
            d1: Matrix{
                {1, 1, 1},
            },
            want0: 1,
            want1: 0,
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got0, got1 := Betti01(tt.n0, tt.n1, tt.d0, tt.d1)
            if got0 != tt.want0 || got1 != tt.want1 {
                t.Fatalf("got (%d,%d), want (%d,%d)",
                    got0, got1, tt.want0, tt.want1)
            }
        })
    }
}
```

Also test \(d_1d_0=0\). The filled triangle's face row multiplied by the incidence matrix is zero modulo 2.

### Exercise 4: traces should become local sections first

A raw trace is an implementation record: it may contain duplicated events, missing observations, serialization details, timestamps, and fields irrelevant to a chosen invariant. A cochain, by contrast, has a declared degree and lives in a specific direct sum of stalks.

The conversion therefore needs an explicit semantic stage:

\[
 \text{trace records}
 \to
 \text{context-indexed facts}
 \to
 \text{local sections}
 \to
 \text{cochains or residuals}.
\]

At the local-section stage, one can validate schema, preserve uncertainty, record observation loss, and check restriction naturality. Only then should values be linearized. Skipping this stage silently assumes that every trace field already has the meaning and coordinate system required by the cochain complex.

This separation also supports multiple analyses over the same trace. One presheaf may track cursor coordinates, another authorization evidence, and another message identity. They should not be forced into one undifferentiated vector.
EOF

```

<details><summary>💭 Thinking</summary>

**Completed textbook appendices, formatting, compilation, visual inspection, typo fixes, and PDF preflight verification**

</details>

```unknown
bash -lc set -euo pipefail
OUT=/mnt/data
WORK=/mnt/data/sessionstream_textbook_work
SRC=$OUT/local-to-global-software-sessionstream-source
rm -rf "$SRC" "$OUT/local-to-global-software-sessionstream-source.zip"
mkdir -p "$SRC/chapters" "$SRC/assets"
cp "$WORK/local-to-global-software-sessionstream.md" "$OUT/local-to-global-software-sessionstream.md"
cp "$WORK/local-to-global-software-sessionstream.pdf" "$OUT/local-to-global-software-sessionstream.pdf"
cp "$WORK/local-to-global-software-sessionstream.md" "$SRC/local-to-global-software-sessionstream.md"
cp "$WORK"/{00-frontmatter.md,01-change-of-view.md,02-categories-software.md,03-mono-epi-iso.md,04-universal-constructions.md,05-limits-colimits.md,06-event-histories.md,07-functors.md,08-naturality.md,09-adjunctions-parameters.md,10-presheaves.md,11-sheaves.md,12-sites-covers.md,13-topoi-local-truth.md,14-nerve-shapes.md,15-cellular-sheaves.md,16-cohomology.md,17-sessionstream-case-studies.md,18-analyzer-study-program.md,19-selected-solutions.md,20-notation-glossary.md,21-reading-map-sources.md} "$SRC/chapters/"
cp "$WORK/assets"/* "$SRC/assets/"
cat > "$SRC/README.md" <<'EOF'
# Local-to-Global Software source bundle

This bundle contains the editable source for:

**Local-to-Global Software: Categories, Presheaves, Sheaves, and Cohomology Through SessionStream**

## Contents

- `local-to-global-software-sessionstream.md` - combined Markdown textbook
- `chapters/` - one Markdown file per front-matter, chapter, and appendix unit
- `assets/` - rendered diagrams plus their Graphviz source where available

The combined Markdown references images with paths such as `assets/core_flow.png`, so keep the `assets` directory beside the Markdown file.

## Build the PDF

The PDF was built with Pandoc and XeLaTeX:

```bash
pandoc local-to-global-software-sessionstream.md \
  --from=markdown+tex_math_single_backslash \
  --top-level-division=chapter \
  --pdf-engine=xelatex \
  --resource-path=. \
  -o local-to-global-software-sessionstream.pdf
```

Fonts used by the source metadata are Noto Serif, Noto Sans, DejaVu Sans Mono, and Latin Modern Math. Substitute installed fonts in the YAML front matter when necessary.

## Source boundaries

The textbook is original explanatory material. It uses Robert Goldblatt's *Topoi: The Categorial Analysis of Logic* as its main pedagogical and terminological source, and the public SessionStream repository and Architecture Garden entry as the software case study. The attached Goldblatt EPUB is not redistributed in this bundle.

The SessionStream implementation was inspected at commit:

```text
d62dca9f5efa2e3094d6c62e5ead5ed0c88fd35c
```

See Appendix C in the textbook for the detailed source crosswalk and references.
EOF
cd "$OUT"
zip -qr local-to-global-software-sessionstream-source.zip local-to-global-software-sessionstream-source
ls -lh "$OUT/local-to-global-software-sessionstream.md" "$OUT/local-to-global-software-sessionstream.pdf" "$OUT/local-to-global-software-sessionstream-source.zip"
sha256sum "$OUT/local-to-global-software-sessionstream.md" "$OUT/local-to-global-software-sessionstream.pdf" "$OUT/local-to-global-software-sessionstream-source.zip"
```

<details><summary>💭 Thinking</summary>

**Created source bundle with README and ZIP**

</details>

The manuscript is now in production verification, with worked solutions, glossary/crosswalk, and an executable analyzer design added. Full-page inspection has also resolved the remaining typesetting issues.

```json
{"paths":["GitHub"],"query":"fetch"}
```

```json
{"uri":"/response/turn12","query":"\"path\":\"docs/","start_line":1,"end_line":13}
```

## Session Spaces

I created an original custom textbook aligned with the progression and terminology of Goldblatt’s *Topoi: The Categorial Analysis of Logic*, while rebuilding the explanations, examples, diagrams, and exercises around SessionStream and general software engineering.

The finished book is **135 pages and approximately 24,400 words**, with:

- 20 chapters and five appendices
- 12 original architecture and category-theory diagrams
- A detailed treatment of limits at your current point in Goldblatt
- Topoi, subobjects, categorical logic, functors, internal languages, and recursion
- Presheaves, restriction maps, matching families, sheaves, sites, local truth, and adjunctions
- A clearly separated cohomology supplement covering nerves, simplicial complexes, cochains, coboundaries, $H^0$, $H^1$, and architectural obstruction diagnostics
- SessionStream case studies involving projections, consistent-cut snapshots, snapshot-plus-suffix gluing, ordinal conventions, projection cursors, retry identity, deterministic replay, and observer traces
- Exercises at recognition, calculation, proof, design, lab, and research levels
- Selected solutions, a study plan, notebook templates, proof patterns, and a glossary

### Files

[Download the PDF textbook](sandbox:/mnt/data/Session-Spaces-Custom-Textbook.pdf)

[Download the complete Markdown](sandbox:/mnt/data/Session-Spaces-Custom-Textbook.md)

[Download the editable source bundle with chapter files, PNG diagrams, Graphviz sources, and build instructions](sandbox:/mnt/data/Session-Spaces-Custom-Textbook-Source.zip)

The standalone Markdown refers to the relative `figures/` directory, so the source bundle is the appropriate version for editing, rebuilding, or viewing the Markdown with all diagrams.

## Sitemap

- [Home](http://parc.yolo.scapegoat.dev/)
- [Home markdown mirror](http://parc.yolo.scapegoat.dev/index.md)
- [Markdown sitemap](http://parc.yolo.scapegoat.dev/sitemap.md)
