A public draft · open to suggestions · not open source

Should the map's positions be computed, not welded?

Today every category on the OuterTalk map sits on a rail that a formula fixes. A proposal asked whether positions should come from the data instead — from what posts cite and what they say. Six independent checks and two adversarial passes went at it. Three of its ten claims were wrong, one of them about the wall between money and meaning. This page keeps the corrections and the numbers.

Try the app on TestFlight → Read the corrections iPhone · free · Credits ✦ are play money
Planning only — nothing here is decided or built Measured against production, 27–28 September 2026 Contracts on Base Sepolia testnet only
First, the words

Welded today. Computed was the proposal.

Five terms carry this page. They are defined here once.

The OuterTalk map is a graph: 42 top-level categories, each on its own rail — one spoke of a spiral — with concepts and posts hung beneath. (It is a DAG, a directed acyclic graph: every edge points one way and nothing loops back.) Today the position of every rail is welded: a pure function of lineage — which category, which slot — written in one file that imports nothing. No data moves it.

The proposal was to compute positions instead. Build a graph from what posts cite and what they say, take its Laplacian, and let the layout fall out of the eigenvectors. (The Laplacian is L = D − A: the degree matrix minus the adjacency matrix. Its eigenvectors are the graph's natural modes; its eigenvalues say how fast each mode varies.) Then a category would be something the corpus produces, not something we draw.

One rule sits under all of it: the wall. Money may set how bright a thing is, and never where it is or whether it is true. The rules for that are on the concept-token page. Every claim below was checked against it.

TODAY · WELDED decided

Position is lineage

src/utils/spiralMath.ts declares the invariant at line 7 and imports nothing. railPoint(m, i) is a pure function of rail and slot. Unbuyable by construction: there is no input a buyer could reach.

THE PROPOSAL · COMPUTED open

Position is a function of the edge set

Whatever produces the edges produces the map. What can be computed can be manufactured. Whether that trade is worth taking is decision 30, below — a values call, not an engineering one.

E0 · first, the three corrections

Three of the ten claims did not survive

The proposal was pitched in conversation before it was checked. Six lenses and two adversarial passes went at it. These three are wrong. The third is the one that matters, and it says the opposite of what was pitched.

C1overstated

The Laplacian is only the kinetic term open · D28

“The graph Laplacian IS the discrete Schrödinger operator.”

L = D − A is the discrete analogue of −∇² — the kinetic term only. A discrete Schrödinger operator is H = L + V, where V is a diagonal potential: one number per node. The two coincide only when V = 0: the free particle. Everything that makes hydrogen hydrogen — the shells, the lobes in the video, the n/l/m structure — comes from the Coulomb potential. That is V, not L.

A bare Laplacian gives you clustering, not orbitals. The operator section below supplies the missing term, which makes the claim true instead of deleting it.

C2wrong

The eigenvalue count is not the category count open · D29

“The eigenvalue count gives the natural number of categories.”

The multiplicity of eigenvalue zero counts connected components — the separate pieces of a graph — and nothing else. Two lenses ran it on live data. The meaning graph has 112 connected components over 143 nodes. The post-to-post graph has 15 edges over 114 posts: an average degree of 0.26, far below the percolation threshold of 1. Run today, “the eigenvalue answer to how many rails” is about 100, not 42.

On a truly empty graph it is worse, and worth stating as the honest limit: A = 0 gives L = 0, every vector is an eigenvector, and the layout is not bad but undefined. ARPACK returns different answers across runs and BLAS builds.

C3backwards

Emergent position weakens the wall open · D30

“Emergent position strengthens the WALL.”

Backwards, and unanimously so — all six lenses, independently. Today position is unbuyable by construction: src/utils/spiralMath.ts:7 declares the invariant and the file imports nothing. railPoint(m, i) is a pure function of lineage, so there is no input path a buyer could touch. Position is not a hardened attack surface. It is not a surface at all.

Emergent position is a function of the edge set. Manufacturing edges is the entire link-farm threat model that Lantern, the ranking engine, already lists against rank (its Part B6). So this converts position from an axiom you verify by reading one 80-line file into a sybil-resistance property defended forever. (A sybil is one person behind many accounts.) It may still be the right trade. It is a downgrade, and it has to be taken deliberately, not sold as an upgrade.

Correction 3 · the attack surface, before and after

TODAY · WELDED · position is a function of lineage lineage category · slot m, i railPoint(m, i) pure · imports nothing x, y position on the map src/utils/spiralMath.ts:7 declares the invariant 80 lines · no input for a buyer money no path exists · verifiable by reading one 80-line file EMERGENT · position becomes a function of the edge set edges manufacturable A → L eigenvectors solved, not declared x, y position on the map a sybil ring manufactures edges 14 humans have ever acted here same threat model as rank · B6 sybil ring links money buys accounts
An axiom becomes a defence. Today the only thing that reaches position is lineage, and you can confirm it by reading one file. Under emergent layout, whatever makes edges makes the map — and a ring of bought accounts makes edges. That is the link-farm threat model Lantern already lists against rank, now applied to geometry. A ranking failure is per-query and recoverable; a poisoned layout is the map everyone sees until the next recompute.
C3′the counter

Money already ranks who is on the map deployed · Base Sepolia

One caveat the adversary added, and it is fair. docs/dag-spiral-design.md already uses POSITION in two incompatible senses: §2, welded and unbuyable; §3 and §13, a locked-net capital score. And the deployed CategoryRegistry.getScore = TVL + volume30d (TVL is total value locked; the registry is one of seven contracts on the Base Sepolia testnet, none on mainnet) already decides which categories are in the visible 42. Money already ranks who is on the map.

Against that baseline, spectral position is an alternative to an already-scheduled capital-driven position, and the safer of the two. Correction 3 stands; the comparison is not against a perfect present.

E1 · the reference

The same atom, built twice

The reference is a 13:52 C++ build of a hydrogen atom, done twice. The first version puts electrons on tracks. The second derives the shape from the equation and lets it arrive on its own.

Left: position assigned · Right: position sampled

POSITION ASSIGNED · r = n · orbitDistance POSITION SAMPLED · sampleR(n, l, gen) angle += 0.05 n = 1, 2, 3 · one electron per track n = 2, l = 1, m = 0 · 2,000 samples · 4096-bin CDF
Assigned on the left, sampled on the right. The left electron moves because a line of code adds 0.05 to its angle. The right-hand cloud was made the way the video makes it: a 4096-bin CDF built once, then 2,000 points drawn from it by inverse-transform sampling — offline, and pasted here as static SVG. The shape is the n = 2, l = 1, m = 0 orbital, and nobody drew it. The video does the same for 100,000 points and the n = 4, l = 3, m = 1 shapes.
V1assigned

Electrons on imposed rails

struct Particle { vec2 pos; int charge; }, position as r = n * orbitDistance; angle += 0.05. It gets the energies right — −13.6, −11.51 and −3.39 eV are on screen. Then it is crossed out.

V2sampled

The shape arrives on its own

The hydrogen equation derived by hand — ψ(r,θ,φ) = R(r)·Y(θ,φ), the substitution ρ = 2r/na₀, reduction to the associated Laguerre equation — then implemented as sampleR(int n, int l, mt19937& gen), which builds a 4096-bin CDF once and inverse-transform-samples it for each of 100,000 points. (A CDF is a cumulative distribution function; inverse-transform sampling turns one uniform random number into one draw from it.) The n = 4, l = 3, m = 1 shapes are emergent: nobody placed a lobe.

→the lesson

Precompute, then sample decided

The transferable lesson is the precompute/sample split, not the physics. The CDF is built once and offline; sampling is cheap and per-frame. That is exactly Lantern's slow clock and fast clock, and it is the part of the video that maps onto OuterTalk without any analogy at all.

⚠two deflations

Both raised by the adversary, both fair

“Your current DAG is the Bohr model” was the most flattering sentence in the session and it does not survive examination. The φ/ρ spiral is a closed-form a-priori law, which is structurally the Schrödinger side of the video, not the Bohr side. The real axis of difference is not imposed-versus-emergent. It is law-derived versus data-derived. The video's second atom is still law-derived; it fits no corpus. OuterTalk would be proposing something the video never did.

Sampling 100,000 points from a closed-form |ψ|² and laying out a 100,000-node graph look identical on screen and are nothing alike computationally. The first is independent sampling from a known function — embarrassingly parallel, O(N), zero data coupling. The second is an optimisation over an N×N coupled system. “Rendering 100k points is easy” is correct. “Therefore the layout is easy” does not follow, and it is precisely where the comparable projects got stuck.

E2 · the operator, at exactly the right strength

Adding the term that was missing

The correction does not delete the idea. It supplies the piece that makes it literally true — and names where any editorial thumb would live.

// the correct sentence
L = D − A · the discrete analogue of −∇² · the kinetic term only
H = L + V · a discrete Schrödinger operator · V is a diagonal potential
V = 0 ⇒ H = L · the free particle · the only case where the two coincide

// the proposed V · makes the claim literally true
H = L_sym + γ · diag(p)
L_sym = I − D^(−1/2) A D^(−1/2) · over a text-similarity graph · meaning-only, capital-free
p = personhood-gated human attention · replies, community notes, endorsements (comment_votes), activated citations
· negative potential is a well: attention digs a well in meaning-space, nearby posts fall toward it
γ = the corpus gate, as a dial · γ = 0 is pure semantic layout and works today at 114 posts
· γ → large is pure attention layout and needs the corpus Part D gates on
Vgovernance

Naming V is a governance decision open · D38

V is a per-node scalar — exactly the shape of a thing money could buy. So naming V is a governance decision, not a rendering detail. The wall survives here because p is built only from human actions and never from a balance: money still sets brightness only. The personhood gate that p depends on is in design.

Setting γ = 0 at launch converts “not ready, hold it” into “ready, with the second term at zero” — a far better place to stand.

One operator · one eigenbasis · three physics

L one eigenbasis heat wave quantum HEAT u̇ = −Lu e^(−λt) decay WAVE ü = −Lu cos(√λ · t) oscillation · ω = √λ SCHRÖDINGER iψ̇ = Hψ · H = L + V e^(−iλt) phase ONLY THE TIME FACTOR DIFFERS · V = 0 GIVES H = L
This is the honest core of the correspondence, and it is exactly true. The same L generates three dynamics that differ only in the time factor. The wave line is the one that justifies the vocabulary: on ü = −Lu the eigenvectors are standing modes and ω = √λ, so “a category is a standing wave of the corpus” is a statement about the wave equation, not a flourish. λ is the squared frequency. Pick that convention and never mix it with the looser one.
!required

You cannot hear the shape of a drum

Kac asked in 1966 whether one can hear the shape of a drum. Gordon, Webb and Wolpert answered no in 1992, and isospectral non-isomorphic graphs — different graphs with identical eigenvalues — are common. The spectrum is a real property of the corpus but does not identify it. Never write that the spectrum is what the corpus is.

★the unlock

You do not need citations to compute a position open · D37

You need a graph with a spectrum, and there are 679 text units already. The vector extension, 0.8.0, is available and not installed. Embed title + body + poll options; build a mutual k-nearest-neighbour graph (k ≈ 8, Zelnik-Manor local scaling) — mutual, because plain kNN mints hub nodes and hubs are what produce a hairball — then union in the minimum spanning tree.

The MST union is not an optimisation. It is what guarantees one connected component, hence exactly one zero eigenvalue, which is the precondition for every other claim here. Without it you reproduce the 112-component collapse with a different edge source. Embedding the whole corpus is cheap enough that cost is not a reason to wait.

E3 · what is true, and is the best of it

A category is a standing wave of the corpus

Four things survived every lens. The first is mathematics; the other three are design that follows from it.

T1exact

Eigenvalues are frequencies, literally

On the graph wave equation ü = −Lu, solutions are u_k(t) = φ_k · cos(√λ_k · t). The Laplacian eigenvectors are the graph Fourier modes and the eigenvalues are the graph frequencies — standard graph signal processing, not analogy. Low-λ modes vary slowly across the graph; high-λ modes alternate between neighbours; the λ = 0 eigenvector is the constant vector, DC. So “a category is a standing wave of the corpus” is a mathematical statement about the wave equation on the citation graph. It is the single most honest bridge to the vibration-and-frequency interest, and it is the best sentence available.

Convention — pick one and never mix: ω = √λ, so λ is the squared frequency. Some sources loosely call λ itself “the graph frequency”. Both cannot appear in one document. In the same spirit, decision 31 drops the word “exact” from the superposition correspondence: signed eigenvector coefficients interfere; a non-negative PageRank vector, like Lantern's, does not.

T2design

Keep the 42 as names, lose them as places open · D40

The most valuable idea in the session, and it survives every lens. The registry holds the names; the spectrum may report a different number of resonances without renaming anything.

Best rendering of it: keep the 42 rails as a faint drawn overlay, give each post a spectral position, and tint it by its rail. Then “cluster 7 straddles rails 3 and 19” becomes a displayed finding about the world instead of a schema change. That is the most interesting screen in the product, it answers what the proposal's Claim 4 was reaching for, and it never touches the on-chain binding.

T3design

Spectral for the global frame, force for the local fill the plan

Spectral layout (Hall 1970; Koren 2003) has a unique global optimum and no local minima. But Laplacian eigenvectors localise on degree-heterogeneous graphs: one eigenvector gets spent separating a single hub and the rest collapses to a blob. The corpus is already heavy-tailed — 3 of 42 categories hold 116 of 182 tag edges. This is exactly what UMAP does, spectral init then local refinement, and it maps onto the two clocks: slow global solve on the server, fast local relaxation on the client.

T4design

Sparsify before the Laplacian, not after open · D41

The Serrano–Boguñá–Vespignani disparity filter, as a required spec step. It keeps only the edges that are statistically significant for the node they leave. It is the difference between this map and Obsidian's hairball.

E4 · the scale barrier

More posts will not fix this

This is the most important finding in Part E, and it changes the shape of the gate.

Use the Kesten–Stigum threshold: the point below which community structure in a sparse stochastic block model cannot be detected by any method (Decelle, Krzakala, Moore and Zdeborová, 2011). A stochastic block model is a random graph with planted communities. Reparametrise by ρ = 1 − f / f_random, where f is the fraction of a node's edges that leave its own category and f_random is what that fraction would be by chance. The required average degree collapses to a single expression.

c* = 1 / ρ² · ρ = 1 − f / f_random · c* contains no n

// in the sparse regime this is an information-theoretic barrier
// below threshold, no corpus size helps: 100,000 posts at 1.5 citations each is exactly as undetectable as 114 posts at 1.5
// the gate is citations per post, not posts
In-category shareRequired citations per post
40 %6.7
30 %12.5
20 %30.7
10 %164

c* = 1 / ρ² at 42 categories · against the measured 0.26

plan on ≈ 10 per post, sustained OuterTalk today · 0.26 citations per post · 15 edges over 114 posts the gap, on a log scale 164 · at 10 % 30.7 12.5 6.7 10 % 20 % 30 % 40 % 50 % 60 % 0.1 1 10 100 share of a post's citations that stay in its own category required citations per post · log
Blue is what the method requires; rose is what exists. Both axes are real: the curve is c* = 1/ρ² evaluated exactly at 42 categories, and 0.26 is 15 post-to-post edges over 114 posts, counted in production on 27 September 2026. The gap is about a decade and a half on a log scale, and adding posts at the same rate moves the rose line nowhere.
≈10the number

Plan on about ten per post, sustained open · D42

Today's measured value is 0.26. At 114 posts, clearing the bar means 399 citation edges; at 2,000 posts, about 7,000; at 2,000 posts with a realistic 20 % in-category share, about 31,000. A post-count gate is the wrong instrument: it would pass while the method still cannot work.

!inference

Two caveats, both marked as inference

Kesten–Stigum assumes equal blocks and Poisson degrees. OuterTalk's blocks are wildly unequal, which is strictly harder — so the realistic terminal state is “3 to 6 subjects emerge and 36 stay noise”, not “42 emerge”. And the plain Laplacian does not achieve the KS threshold on sparse graphs (the non-backtracking operator does), so with D − A the real requirement is higher still.

The precondition · and the measurement

WHAT THE METHOD NEEDS · one piece WHAT IS THERE · 112 pieces over 143 nodes 34 nodes drawn · 1 piece · mult(0) = 1 143 nodes · 112 pieces · mult(0) = 112
The multiplicity of eigenvalue zero equals the number of pieces. One piece is the precondition for every other claim on this page. There are 112, so the method run today reports about a hundred categories. The right-hand drawing uses the fewest edges that 112 pieces over 143 nodes allow — 31 — and the real shapes may differ; the counts do not. On a graph with no edges at all, L = 0, every vector is an eigenvector, and the layout is not bad but undefined.
→build order

The only work on the critical path is the link channel open · Part D

Part D already names the two defects that block it. Polls cannot cite at all — src/pages/CreatePost.tsx:1238/1393/1452 — and 102 of 114 posts are polls. Editing a post wipes its links: create_post_atomic assigns links = p_links with no COALESCE. Fix those and the question of whether the spiral should be computed becomes answerable with data instead of with physics.

E5 · address versus coordinate

The one-way door that is live in the code

Claim 10 of the proposal was “never store a post's position”. Verified: correct as a principle, and already fully satisfied. Every positional-looking column in production was enumerated. There is no stored layout coordinate anywhere. Every lat/lng is real geography. category_slot_scores.slot is a foreign key to categories.id. categories.depth is tree depth, and every row is 0. So there was nothing to reverse and no deadline; the urgency was misdirected.

The word “position” was hiding three objects, and the rule is true for exactly one of them.

ObjectWhat it isRule
ADDRESSPermanent slot identity — what a token binds to. On the concept-token page this is Rule 8: “an address is earned at lighting”.Must be stored, and immutable.
LAYOUT COORDINATEAn embedding under one projection, in one epoch.Never authored. Cache only.
GEOGRAPHYposts.lat/lng and friends.Stored. Source of truth. Derived from nothing.
BUGlive today

A 43rd category re-spaces all 42 rails open · D32

src/components/SpiralDAG.tsx:65 sorts top-level rows by id. Line 77 uses the array index as the rail m. Line 68 sets railCount = Math.max(42, tops.length) and feeds it to theta0(m, railCount).

Therefore adding a 43rd top-level category re-spaces all 42 existing rails, and inserting a category into one of the ~60 gaps in the id sequence (42 rows spread over ids 1–102) silently re-addresses every rail after it. That is exactly the MOVE that §13A forbids, in the code today. The rail index is an array position, not an address.

SpiralDAG.tsx:68 · railCount = Math.max(42, tops.length)

BEFORE · railCount = 42 AFTER · railCount = 43 one top-level row inserted SpiralDAG.tsx:68 42 rails · θ = 360° / 42 43 rails · θ = 360° / 43 · all 42 moved dashed = where each rail was
One row in, every rail moves. The angle of rail m is m / railCount of a turn. Change the count and every angle changes. Nothing about the 42 categories changed; only a loop bound did. The binding meant to prevent this is populated on 1 of 42 rows.
1/42the binding

The mapping the docs describe does not exist open · D34

categories.blockchain_category_id is populated on 1 of 42 rows (History = 1), while docs/category-rule.md:5 states the 42 are “mapped to on-chain CategoryRegistry IDs (1–42)” and “locked”. That mapping does not exist in the database. The doc is wrong and should be corrected whatever else is decided. (The registry it names is one of seven contracts on the Base Sepolia testnet; none is on mainnet.)

FKcascade

The schema's answer to NO DELETE is “cascade the ledger” open · D33

category_slot_scores, category_slot_holdings and category_slot_events all carry ON DELETE CASCADE to categories. So the schema's answer to NO DELETE / NO MOVE is currently “delete and cascade the ledger”. Free to fix today: 0 holdings, 0 events, 42 score rows.

…honestly

Why this is not an emergency open · D35

This is only a door once something persists a rail, and nothing does: the spiralDag flag is false, the card's onClick is empty, holdings are zero. A one-sentence note in docs/category-rule.md forbidding top-level inserts and deletes until the address is stored is free, is sufficient for now, and no app code writes that table.

6epochs

If a coordinate is ever cached, six things move between epochs open · D39

The spec must name all six. Sign (v and −v are both unit eigenvectors). Ordering (near-equal λ swap). Degeneracy (inside an eigenspace of multiplicity k the basis is defined only up to O(k), which no per-vector sign rule can fix). Node-set change. Solver nondeterminism. Scale (unit-norm eigenvectors shrink as 1/√n, so the drawing collapses as the corpus grows).

The first three die to one orthogonal Procrustes alignment against an anchor set — the rotation that best maps one point set onto another: M = XᵀY, take its SVD, R = VUᵀ, apply before storing. Do not constrain det(R) = +1, because reflections are exactly the sign flips being absorbed. Anchors = the 42 category nodes. This is about 30 lines and it is the highest-value implementation detail here: without it the galaxy reshuffles on every recompute, and the failure is invisible in a screenshot because it only appears at the second epoch, weeks in.

The epoch lock · why the second recompute is the one that breaks

EPOCH 1 EPOCH 2 · raw EPOCH 2 · aligned recompute sign · order · basis R = VUᵀ Procrustes gold = anchors · the 42 category nodes same modes · flipped and turned dashed = where epoch 1 drew them det(R) = −1 allowed a reflection is a sign flip
Same corpus, same modes, different signs. A recompute is free to hand back −v for v, to swap two near-equal modes, or to rotate inside a degenerate eigenspace. Each is the same layout to the solver and a different map to a person. One rotation fitted against the 42 category nodes — reflections allowed — undoes all three before anything is stored. The first epoch never shows the problem; the second always does.
E6 · the runtime, honestly

What it would run on

Six findings about the machine, each with its status.

R1drawing

C++ is not needed for drawing open · D43

100k instanced point sprites at 60 fps is routine WebGL2 from TypeScript: one VBO, one draw call. C++ compiled to wasm is justified only for the eigensolver, and only above roughly 50k nodes. At the 500-post corpus trigger, JS Lanczos is microseconds. Taking the C++ decision now buys a permanent renderer/web-app split for zero present benefit.

R2threads

Threads are dead on iOS here decided

SharedArrayBuffer and pthreads need cross-origin isolation, which a capacitor:// origin does not get without changing the web origin. Build single-threaded and never pass -pthread.

R3webgl2

WebGL2 is already load-bearing and is not a risk built

mapbox-gl 3.12 has zero WebGL1 paths, and the Ark renders on device today. Lenses that flagged WebGL2 as a new risk were wrong. A separate question several lenses raised: IPHONEOS_DEPLOYMENT_TARGET, currently 14.0.

R4webgpu

WebGPU should be struck from roadmap language open · D44

Two lenses gave directly contradictory answers about WKWebView, which is itself the finding: nobody should be writing that sentence.

R5one field

One field, two projection matrices, one of them borrowed open · D45

That is Claim 9 of the proposal, restated honestly. The mechanism is Mapbox's CustomLayerInterface, which draws into the map's own WebGL context with the camera already synced. Worth a half-day spike before anything else; if it works, the unified field is nearly free and Mapbox stays.

R6dots

Draw countable dots, not a smooth cloud, and never a centroid the plan

The HCI evidence is genuinely on this side: discrete-outcome dot displays beat continuous densities for lay readers on mobile, and showing a summary statistic makes people ignore the spread entirely. This is the one piece of the hydrogen aesthetic with real evidence behind it — and it is the opposite of what a naive |ψ|² render would do.

E7 · a product decision, not an implementation note

A living map, or a memorable place. Not both. open · D46

The founder asked for a spiral where everything affects everything. That is precisely the property that makes the map re-seat itself on every recompute. Procrustes alignment is the machinery for suppressing what was asked for.

§13A's NO MOVE and “everything affects everything” are in direct tension. The resolution on offer — NO MOVE governs the address, the coordinate is a rendering of it — is a real resolution, but it is a choice, and it means the thing that moves is never the thing people navigate by.

E8 · next

The afternoon that answers this

0.26

citations per post today

Against about 10 required. The gate is this number, not the post count.

112

pieces where the method needs one

143 nodes. The MST union is what would make it one.

1 image unbuilt

a throwaway script

Embed the 114 posts by text similarity. Draw them once. Look.

Before any of the above: a throwaway script that embeds the 114 posts by text similarity and produces one image. No migration, no flag, no deploy, nothing to unship. If that image shows structure, the programme is worth planning. If it is a blob, the whole of Part E is answered for the cost of an afternoon — and the answer is that the corpus, not the renderer, is the subject.

Everything else in Part E is downstream of that picture.

What exists today

The honest ledger

Measured against production on 27–28 September 2026. Nothing on this page is built unless this table says so.

ThingStateDetail
Posts114102 of them are polls, and polls cannot cite at all (CreatePost.tsx:1238/1393/1452).
Post-to-post citation edges15 · 0.26 per postCounted 27 September 2026. The percolation threshold is 1. The gate is about 10.
Meaning graph143 nodes · 112 piecesThe method needs one piece.
Text units to embed679Titles, bodies, poll options. vector 0.8.0 is available and not installed.
Tag edges1823 of 42 categories hold 116 of them. Already heavy-tailed.
People who have ever acted14The baseline any sybil defence would be measured against.
Top-level categories42 rows · ids 1–102About 60 gaps in the id sequence. categories.depth is 0 on every row. Zero child concepts exist.
blockchain_category_id1 of 42 rowsHistory = 1. The 1–42 binding the category rule describes does not exist in the database.
category_slot_scores / holdings / events42 · 0 · 0All three cascade on delete.
Stored layout coordinatenoneEvery lat/lng is geography. Nothing persists a rail.
spiralDag flagfalseThe card's onClick is empty.
Rail indexarray positionSpiralDAG.tsx:65/68/77. A 43rd top-level row re-spaces all 42 rails.
Spectral layout · H = L + V · epoch lock · rail overlayunbuiltEverything above the ledger is a specification.
Guard runnerunbuiltSix guards exist. None executes until a runner does.
Renderermapbox-gl 3.12 · WebGL2Zero WebGL1 paths. IPHONEOS_DEPLOYMENT_TARGET 14.0.
On-chain registry7 contracts · Base Sepolia testnetCategoryRegistry.getScore = TVL + volume30d decides the visible 42. No mainnet deploy exists.
Proof of personhoodin designThe gate that p in the operator depends on.
E9 · decisions 28 – 46 · continuing Part C's numbering

Every one of these is open

Part E marks none of them decided. Each carries the panel's recommendation where it made one. Numbered so you can refer to one.

Corrections to adopt before any of this is repeated to anyone
D28
openCorrect Claim 1 in all writing: “the graph Laplacian is the kinetic term of the discrete Schrödinger operator; the diagonal potential V is where our values enter” — never “the Laplacian is the Schrödinger operator”?Recommend yes.
D29
openDrop Claim 4 (eigenvalue count gives the category count) entirely, on the evidence that the method run on today's graph returns ~100 and never 42?Recommend yes.
D30
openAccept in writing that emergent position is a downgrade to the wall — position stops being provably unbuyable and becomes defended by the same machinery as ranking?No recommendation: a values call, not an engineering one. It must be answered explicitly, because the proposal as pitched said the opposite.
D31
openDrop “exact” from the superposition correspondence everywhere; the honest version is that signed eigenvector coefficients interfere and a non-negative PageRank vector does not?Recommend yes.
Free now, expensive later — free because the tables are empty
D32
openAdd categories.slot_no (smallint, UNIQUE, immutable by trigger), backfill from today's id order, and read the rail from slot_no − 1 instead of the forEach index?Recommend yes.
D33
openChange the three category_slot_* foreign keys from ON DELETE CASCADE to ON DELETE RESTRICT?Recommend yes — 0 holdings, 0 events.
D34
openCorrect docs/category-rule.md:5, which claims an on-chain 1–42 binding that exists on 1 of 42 rows — and either backfill blockchain_category_id to match slot_no or drop the column?Recommend yes.
D35
openInterim, free, and sufficient until 32 lands: one sentence in category-rule.md forbidding top-level inserts and deletes?Recommend yes.
D36
openBuild the guard runner (a six-line GitHub Action or a pre-commit hook, about 1 hour) before writing any new guard, accepting that all six existing guards are decorative until it exists?Recommend yes — this is already Part D's item 4, and it is now blocking two parts of the plan.
Design, if and when the corpus justifies it
D37
openBuild the meaning graph from text embeddings (mutual-kNN + MST union, pgvector 0.8.0) rather than waiting for a citation graph that does not exist?Recommend yes — it is the unlock.
D38
openAdopt H = L_sym + γ·diag(p) with γ = 0 at launch, making the physics claim literally true and converting the corpus gate from a hold into a dial?Recommend yes.
D39
openRequire the Procrustes epoch-lock in the spec — no spectral coordinate may ever be stored without alignment against the previous epoch?Recommend yes.
D40
openKeep the 42 rails as a fixed rendered overlay, with spectral positions tinted by rail, so the spectrum can never change the category count?Recommend yes — best screen in the product.
D41
openMake the Serrano disparity filter a required pre-Laplacian step, not a later optimisation?Recommend yes.
D42
openWrite the spectral trigger into the gate as citations per post ≈ 10 sustained, not as a post count?Recommend yes — a post-count gate is the wrong instrument and would pass while the method still cannot work.
D43
openDefer C++ entirely for now — WebGL2 from TypeScript first, wasm for the eigensolver only above ~50k nodes?Recommend yes.
D44
openStrike WebGPU from all roadmap language?Recommend yes.
D45
openSpike Mapbox CustomLayerInterface (half a day) before committing to any second renderer?Recommend yes.
D46
openA living map or a memorable place — which?No recommendation; this is the product call underneath all of Part E.
E10 · what should not happen now

Nothing in Part E gets built this week

The week belongs to build 8 and to the governance_grades bridge index that must be dropped or extended by 30 September 2026 — two days out when this was written on the 28th, and unrelated to any of this.

The three items on the genuine critical path are already in Part D and are unchanged by Part E: the edit-wipes-links bug, polls-cannot-cite, and the guard runner. Part E's own most useful next step is the afternoon above, and it needs none of the above.

Tell us where this is wrong

This is not open source. It is open to suggestions, from people who take it seriously. If a step in the mathematics is wrong, a threshold is misapplied, or a number here does not match what you can measure, we would rather hear it now than after it is built.