→ Is .me a Category?

From Pointer Semantics to Categorical Structure.

By Sui Gn. Originally published on Medium (CodeX), Jul 26, 2026: Is .me a Category? ⓘ

Builds on What Is the Mathematical Structure of a Space in .me?. Every formula on this page, in one glossary: The Equations: Is .me a Category?. Notation: R_{t,γ} is the resolution relation R fixed at time t under context γ.

Four formal corrections close this out, all of them about typing Trace correctly — a fitting last step, since getting types right has been the through line of every revision in this series.

Separating Syntax, Structure, and Manifestation

Trace must return a morphism, not a category

Writing Trace_t^{(n)} : P̂ ⇀ C_t was a type error of exactly the kind this series has been hunting down elsewhere: C_t is a category, not a set of routes an ordinary function can return an element of. What Trace actually needs to produce is a morphism of C_t, typed by its source and target:

Trace^{(n)}_t : P̂ ⇀ Mor(C_t)
Mor(C_t) = ∐_{p, q ∈ P̂} Hom_{C_t}(p, q)

or, written out concretely for a given input:

Trace^{(n)}_t(x) = c : p → q,   c ∈ Hom_{C_t}(p, q),   x ∈ ↓p

The dependent condition x ∈ ↓p matters, and it’s the same subtlety Exec’s earlier fix already surfaced: the input x is not generally the morphism’s source object. In the running example from axiom A4, the traversed morphism is c : profile.cards.primary → wallet, but the input being resolved is x = profile.cards.primary.income — an extension of the source, x ∈ ↓p, not the source itself. Trace returns the typed morphism together with the guarantee that the actual input lives in its domain cone.

The pointer-free case needs its own object, not a bare identity

Trace^{(n)}_t(x) = id was informal in the same way — a category has no identity without an object to anchor it; every identity is id_p : p → p for some specific p. For a pointer-free resolution, the natural anchor is the path itself:

Trace^{(n)}_t(x) = id_x : x → x

which composes correctly with everything already established: F_t(id_x) = id_{↓x}, so F_t(id_x)(x) = x, and therefore:

Exec_{t,γ}(id_x, x) = R_{t,γ}(x)

— resolving a path with no pointer involved is exactly the special case where the structural layer contributes nothing and contextual resolution acts directly on the input. When a pointer is found — including one discovered at a prefix of x rather than at x itself — Trace instead returns c : p → q with x = p.s for some suffix s, and the same formula applies uniformly across both cases.

Two different partialities, not one

Saying R_{t,γ} was “where the only real partiality in the whole system lives” directly contradicted having just defined Trace^{(n)}_t as partial. The fix is to name two distinct kinds of partiality rather than pick one:

R_{t,γ} : P̂ ⇀ M      — semantic partiality: a syntactically valid position may simply manifest nothing
Trace^{(n)}_t           — operational partiality: a fuel-bounded evaluation may not complete a finite trace

R_{t,γ} is where semantic partiality lives — a well-formed path can be entirely valid and still resolve to ⊥, for reasons unrelated to any pointer at all (nothing was ever written there, or the observer lacks the authority to see it). Trace_t^{(n)} may additionally be operationally partial, for a different reason entirely: because a bounded, finite evaluation procedure — src/core-index.ts: resolveIndexPointerPath’s fuel-limited loop, or the unbounded-but-still-finite-stack outer recursion through self.readPath — need not complete before it must stop. These are not competing claims about where “the” partiality is; they’re two separate sources of it, at two different layers.

ConeSubst(P̂) is a deliberately restricted category, not the category of all cone maps

Left unstated, “category of cone substitutions” invites a reader to imagine something much larger — every possible function between principal cones, which would generally be neither thin nor chaotic. That was never what was being defined. ConeSubst(P̂) is not the category of all cone maps; it is the deliberately restricted category containing exactly the canonical prefix-replacement map between each pair of principal cones — one specific morphism per ordered pair, π_{p,q}(p.s) = q.s, and nothing else. Its chaotic structure — every hom-set a singleton, every morphism invertible — is a direct consequence of that restriction, not an incidental property of “substitutions between cones” in general.

Faithfulness is a per-hom-set property, not a property of one walked route

F_t collapsing a single walked route “faithfully when no other route could have produced the same relocation” read as a claim about one execution, when faithfulness is inherently a statement about an entire hom-set. The precise version: on a hom-set Hom_{C_t}(p, q), F_t is injective exactly when that hom-set contains at most one route. Route information is preserved exactly for source–target pairs that admit at most one formal chain — and lost exactly for the pairs that admit more than one, regardless of which particular chain any single evaluation happened to walk.

The fully typed pipeline

H_t  ──fold_LWW──▶  G_t  ──FreeCat──▶  C_t

For a concrete evaluation of a path x:

Trace^{(n)}_t(x) = c : p → q,   x ∈ ↓p      (or  id_x : x → x  when no pointer is involved)
F_t(c) : ↓p → ↓q
F_t(c)(x) ∈ ↓q
RuntimeEval^{(n)}_{t,γ}(x) = R_{t,γ}( F_t(Trace^{(n)}_t(x))(x) ),   when the trace is defined

with the pointer-free case collapsing cleanly to RuntimeEval^{(n)}_{t,γ}(x) = R_{t,γ}(x), and the axiom-A4 case instantiating as c : profile.cards.primary → wallet, x = profile.cards.primary.income, F_t(c)(x) = wallet.income, resolved through secret-branch decryption to 1000.

Verdict

Six typed stages, each carrying exactly what the next one needs and nothing it doesn’t:

history → active graph → available routes → typed traversed route → canonical relocation → contextual manifestation

H_t records every declaration ever made. G_t folds that into what’s currently active. C_t = FreeCat(G_t) holds every formally possible route those active edges permit — a space of possibilities, unconcerned with any particular execution. Trace_t^{(n)}(x) picks out one typed morphism of C_t — a genuine chain, or the identity at x when no pointer was needed — that a specific, fuel-bounded evaluation actually produced, and may itself be undefined when that evaluation fails to complete. F_t sends that morphism to its canonical net relocation in the deliberately restricted, chaotic category ConeSubst(P̂), faithfully wherever the corresponding hom-set of C_t had nowhere else to collapse from, and lossily wherever it did. R_{t,γ} takes the resulting path and decides, under a specific observer and mode, whether it manifests a value, a family, a history, or nothing — its own partiality, semantic rather than operational, answering a different question than Trace’s ever did.

.me is not a category because pointers happen to compose. It is an event log, folded into an active graph, generating a free category of formally possible routes, from which a fuel-bounded evaluator extracts one typed, possibly-undefined trace per read, which a deliberately restricted structural functor reduces to a canonical relocation exactly as far as that route’s hom-set permits, over which a separately, semantically partial contextual resolution finally decides what — if anything — the resulting position manifests.

Source code: neurons-me/.me. Documentation: neurons-me.github.io.

See also