Commits
Links to pdsls.dev with the record AT URI so you can inspect
the raw lexicon record on the user's PDS.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Two strata records can share the same graph (same connected component)
but have different analyses. The lexmin hash conflated them. Now the ID
is the record rkey (e.g. 3mlrokf4gho2i), so each strata record is
distinct. Also simplifies getIsland — direct URI lookup instead of
scanning all records.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
resolveVertexMeta was doing 14 sequential D1 queries (cards+citations,
chunked at 50). Now builds all statements upfront and runs them in a
single db.batch() call. Also removed ensureContrailReady from getIslands
entirely — it only needs D1.
940ms → 320ms cold, 200ms warm.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Canvas height 200px → 320px (was cramming 301 nodes vertically)
- Remove hardcoded width/height HTML attrs — constructor sizes via
getBoundingClientRect + devicePixelRatio
- Repulsion force 300 → 500 for better spread
- Warmup ticks 120 → 200 for settled layout
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Explore page fetches ?summary=true — skips vertexMeta (244KB saved)
and trims edges to source/target/connectionType. Full data loads
on demand when viewing an island detail. Also skips contrail init
in summary mode for faster cold starts.
523KB → 216KB, 1.2s → 230ms cold, 90ms warm.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Landing page only needs a json_extract query, not contrail schema
init. Cold start went from ~450ms to ~170ms.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Landing page only needs id, lexmin, title — extract those via
json_extract instead of pulling the full record (117KB each).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Lexicon: connections field now holds objects {uri, source, target,
connectionType, note} instead of bare AT URIs. The graph renders
straight from the record — no chunked D1 queries needed.
Backfilled both existing records via PDS putRecord.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Lexicon: add connections field (array of AT URIs)
- getIslands: reconstruct island from stored connections in chunks of 50
- Backfill existing records with 341 connection URIs each
- Landing page loads summaries, frontend fetches full data via API
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Island interface: vertices, edges, vertexMeta now optional
- Card renderer shows title preview for summaries, graph for full data
- summarizeIsland checks title before vertices
- Fixed landing page to query D1 directly instead of internal fetch
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Dockerfile COPY paths relative to container/ build context
- Landing page now uses getIslands (lightweight) instead of listStrataIslands
- Removed listStrataIslands (dead code)
- wrangler.jsonc with container + DO + migrations config
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- GET /xrpc/org.latha.strata.getIsland?id=<id>
- Accepts stable ID (sha256 of lexmin) or AT URI
- Returns full island with vertices, edges, metadata, and strata analysis
- Falls back to deriving island from seed if no strata record exists
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- deriveIsland is now POST (procedure) — takes optional seed in body
- getIslands is a lightweight GET query — returns summaries from
records_strata without deriving islands on every request
- Added org.latha.strata.getIslands lexicon
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Container reads vault via ob sync, carry via git pull
- deriveIsland: with seed → single island, without → all islands
- analyze: cross-references island against vault+carry
- Lexicon methods: org.latha.strata.deriveIsland, org.latha.strata.analyze
- StrataContainer Durable Object manages container lifecycle
- carry-vault pushed to github.com/codegod100/carry-vault (private)
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Removed island_cache table and rebuildIslandCache cron
- Removed legacy PUT endpoints (putSummary, putAnalysis)
- Landing page and getIslands now query records_strata via listStrataIslands()
- Each strata record derives its island from lexmin on demand
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- strata-analyze.py now creates org.latha.strata records on PDS
instead of pushing to API endpoints
- Added deriveIsland() with BFS traversal (recursive CTE OOMs in D1)
- New xrpc endpoints:
- GET /xrpc/org.latha.strata.getRecord?uri=<at-uri>
- GET /xrpc/org.latha.strata.listRecords
- GET /xrpc/org.latha.strata.getIslands
- Frontend supports AT URI as strata page ID
- Lexicon updated: added title field, relaxed source.uri format
- Migrated all /api/ routes to /xrpc/ namespace
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
LLM was paraphrasing/abbreviating titles which broke linking.
Added explicit instruction to use EXACT titles from island data.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Links now point to semble.so/url/<encoded-uri> instead of raw URLs
- Excludes at:// titles from link map
- Added substring matching: short names from titles (before delimiters/
parens) are linked if they appear in relationship text
- Fixes most "leads to" etc being unlinked
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
LLM now produces a [Title] section — a single sentence capturing
the core argument rather than a fragmented topic list. Uploaded
as the island summary via PUT /api/strata/islands/:id/summary.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Cards and collections stored as at:// URIs were showing as raw
URIs with type "unknown". Now resolveVertexMeta also queries
records_card and records_collection by AT URI to get titles
and descriptions. Added card/collection type colors to force graph.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Removed DiscourseGraphRenderer class, types, CSS, and rendering.
The discourse_graph data is still computed and stored in strata
analysis — just not rendered on the page for now.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
semble.so/url/<encoded-source-url> instead of profile/<did>.
Also: discourse graph now pan/zoom with fixed viewport.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Nodes as rounded-rect cards with type badge + short title
- Canvas width scales with max nodes per layer (min 90px spacing)
- Canvas height scales with active layer count
- Hover tooltip shows full title
- Edges connect bottom/top of cards with bezier curves
- Legend moved to bottom-right
- Faded edges (44 alpha) by default, bright on hover
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Layered graph modeled on Discourse Graphs (discoursegraphs.com):
4 node types — QUE (question), CLM (claim), EVD (evidence),
SRC (source) — arranged in horizontal layers top to bottom.
Edges typed as supports/opposes/informs/addresses with color
coding and curved bezier paths.
Computation: LLM classifies vertices and identifies discourse
relations during strata analysis. Data uploaded via API as
discourse_graph field in strata JSON.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Semble has no dedicated connection record page, so edges now link
to the connection author profile: semble.so/profile/<did>
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Edge rows are now <a> links to semble.so/at/<record-uri>.
Removed vertex list — only edges shown. Removed "Strata" h2.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Layout: summary + graph at top, synthesis below, then themes,
relationships, tensions, open questions, and full node/edge lists
at the bottom.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
On rebuild, compute the new lexmin-hash ID for each old island
and carry forward its summary and strata data to the new row.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Shape: 16 hex chars (e.g. "a3f2c8b91e4d7a05"). Stable when
vertices are added, opaque, short enough for URLs and DB keys.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Island ID is now the alphabetically smallest URI in the connected
component, not a hash of all vertices. This keeps the ID stable when
new vertices are added to the island.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Strata analysis now runs on cloudy (local machine) via
scripts/strata-analyze.py, not in a Cloudflare Container. The script
fetches islands from the API, asks letta to produce structured prose
with semantic arrows (→, ←, ↔, ⇏), then uploads the results to
Cloudflare via PUT /api/strata/islands/:id/analysis.
The strata page renders prose with styled arrows showing relationships
between vertices — no canvas graph. Island cards link directly to the
strata page and show "View Strata" when analysis exists.
- Removed: AnalysisContainer durable object, container analysis endpoint,
CarryGraph class, apiPost helper, POST /api/strata/analyze
- Added: PUT /api/strata/islands/:id/analysis endpoint, strata column
in island_cache, scripts/strata-analyze.py, D1 migration
- Frontend: strata page shows prose with arrows, themes, tensions,
open questions, synthesis
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Each island card on explore page now has a Strata button that
navigates to the island detail page
- org.latha.strata records now include island graph data (vertices
+ edges) so the record page can render the full constellation
- CarryGraph class renders the island network overlaid with carry
cross-reference nodes: network nodes are circles, carry nodes are
diamonds, carry links are dashed lines
- Legend in the graph canvas shows node types
- CSS for carry graph canvas, island card footer with Strata button
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Replace preemptive card analysis with island detection (connected
components from network.cosmik.connection records). Each island is
a cluster of linked URLs — the explore page shows islands as cards.
- Worker: detectIslands() BFS for connected components, /api/strata/islands
endpoint, Strata analyze creates org.latha.strata record in D1 and
returns at-uri, removed analyzeNewCards cron
- Container: analysis accepts island (vertices + edges) instead of
single source, cross-references entire cluster against vault + carry
- Frontend: island cards on explore page, Strata button runs analysis
and navigates to /strata?uri= record page, removed modal approach
- CSS: island-card, island-detail, strata-record styles
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Cloudflare Workers + Containers + Contrail appview that cross-references
Semble cards against local vault and carry data, producing org.latha.strata
synthesis records as stigmergic signals for the network.
- Worker (Hono) with Contrail indexing, connection graph, citation pipeline
- Container analysis engine: reads R2 vault+carry, extracts themes, finds
connections, detects tensions, generates open questions, synthesizes prose
- org.latha.strata lexicon with sourceRef, structuredAnalysis, carryCrossRef
- R2 sync endpoints and CLI script for vault + carry upload
- Frontend SPA with Strata analysis modal on cards and resources
- Per-DID container instances via Durable Objects (10m idle sleep)
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Two strata records can share the same graph (same connected component)
but have different analyses. The lexmin hash conflated them. Now the ID
is the record rkey (e.g. 3mlrokf4gho2i), so each strata record is
distinct. Also simplifies getIsland — direct URI lookup instead of
scanning all records.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
resolveVertexMeta was doing 14 sequential D1 queries (cards+citations,
chunked at 50). Now builds all statements upfront and runs them in a
single db.batch() call. Also removed ensureContrailReady from getIslands
entirely — it only needs D1.
940ms → 320ms cold, 200ms warm.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Canvas height 200px → 320px (was cramming 301 nodes vertically)
- Remove hardcoded width/height HTML attrs — constructor sizes via
getBoundingClientRect + devicePixelRatio
- Repulsion force 300 → 500 for better spread
- Warmup ticks 120 → 200 for settled layout
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Explore page fetches ?summary=true — skips vertexMeta (244KB saved)
and trims edges to source/target/connectionType. Full data loads
on demand when viewing an island detail. Also skips contrail init
in summary mode for faster cold starts.
523KB → 216KB, 1.2s → 230ms cold, 90ms warm.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Lexicon: connections field now holds objects {uri, source, target,
connectionType, note} instead of bare AT URIs. The graph renders
straight from the record — no chunked D1 queries needed.
Backfilled both existing records via PDS putRecord.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Lexicon: add connections field (array of AT URIs)
- getIslands: reconstruct island from stored connections in chunks of 50
- Backfill existing records with 341 connection URIs each
- Landing page loads summaries, frontend fetches full data via API
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Island interface: vertices, edges, vertexMeta now optional
- Card renderer shows title preview for summaries, graph for full data
- summarizeIsland checks title before vertices
- Fixed landing page to query D1 directly instead of internal fetch
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Dockerfile COPY paths relative to container/ build context
- Landing page now uses getIslands (lightweight) instead of listStrataIslands
- Removed listStrataIslands (dead code)
- wrangler.jsonc with container + DO + migrations config
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- GET /xrpc/org.latha.strata.getIsland?id=<id>
- Accepts stable ID (sha256 of lexmin) or AT URI
- Returns full island with vertices, edges, metadata, and strata analysis
- Falls back to deriving island from seed if no strata record exists
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- deriveIsland is now POST (procedure) — takes optional seed in body
- getIslands is a lightweight GET query — returns summaries from
records_strata without deriving islands on every request
- Added org.latha.strata.getIslands lexicon
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Container reads vault via ob sync, carry via git pull
- deriveIsland: with seed → single island, without → all islands
- analyze: cross-references island against vault+carry
- Lexicon methods: org.latha.strata.deriveIsland, org.latha.strata.analyze
- StrataContainer Durable Object manages container lifecycle
- carry-vault pushed to github.com/codegod100/carry-vault (private)
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Removed island_cache table and rebuildIslandCache cron
- Removed legacy PUT endpoints (putSummary, putAnalysis)
- Landing page and getIslands now query records_strata via listStrataIslands()
- Each strata record derives its island from lexmin on demand
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- strata-analyze.py now creates org.latha.strata records on PDS
instead of pushing to API endpoints
- Added deriveIsland() with BFS traversal (recursive CTE OOMs in D1)
- New xrpc endpoints:
- GET /xrpc/org.latha.strata.getRecord?uri=<at-uri>
- GET /xrpc/org.latha.strata.listRecords
- GET /xrpc/org.latha.strata.getIslands
- Frontend supports AT URI as strata page ID
- Lexicon updated: added title field, relaxed source.uri format
- Migrated all /api/ routes to /xrpc/ namespace
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Links now point to semble.so/url/<encoded-uri> instead of raw URLs
- Excludes at:// titles from link map
- Added substring matching: short names from titles (before delimiters/
parens) are linked if they appear in relationship text
- Fixes most "leads to" etc being unlinked
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Cards and collections stored as at:// URIs were showing as raw
URIs with type "unknown". Now resolveVertexMeta also queries
records_card and records_collection by AT URI to get titles
and descriptions. Added card/collection type colors to force graph.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Nodes as rounded-rect cards with type badge + short title
- Canvas width scales with max nodes per layer (min 90px spacing)
- Canvas height scales with active layer count
- Hover tooltip shows full title
- Edges connect bottom/top of cards with bezier curves
- Legend moved to bottom-right
- Faded edges (44 alpha) by default, bright on hover
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Layered graph modeled on Discourse Graphs (discoursegraphs.com):
4 node types — QUE (question), CLM (claim), EVD (evidence),
SRC (source) — arranged in horizontal layers top to bottom.
Edges typed as supports/opposes/informs/addresses with color
coding and curved bezier paths.
Computation: LLM classifies vertices and identifies discourse
relations during strata analysis. Data uploaded via API as
discourse_graph field in strata JSON.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Strata analysis now runs on cloudy (local machine) via
scripts/strata-analyze.py, not in a Cloudflare Container. The script
fetches islands from the API, asks letta to produce structured prose
with semantic arrows (→, ←, ↔, ⇏), then uploads the results to
Cloudflare via PUT /api/strata/islands/:id/analysis.
The strata page renders prose with styled arrows showing relationships
between vertices — no canvas graph. Island cards link directly to the
strata page and show "View Strata" when analysis exists.
- Removed: AnalysisContainer durable object, container analysis endpoint,
CarryGraph class, apiPost helper, POST /api/strata/analyze
- Added: PUT /api/strata/islands/:id/analysis endpoint, strata column
in island_cache, scripts/strata-analyze.py, D1 migration
- Frontend: strata page shows prose with arrows, themes, tensions,
open questions, synthesis
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Each island card on explore page now has a Strata button that
navigates to the island detail page
- org.latha.strata records now include island graph data (vertices
+ edges) so the record page can render the full constellation
- CarryGraph class renders the island network overlaid with carry
cross-reference nodes: network nodes are circles, carry nodes are
diamonds, carry links are dashed lines
- Legend in the graph canvas shows node types
- CSS for carry graph canvas, island card footer with Strata button
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Replace preemptive card analysis with island detection (connected
components from network.cosmik.connection records). Each island is
a cluster of linked URLs — the explore page shows islands as cards.
- Worker: detectIslands() BFS for connected components, /api/strata/islands
endpoint, Strata analyze creates org.latha.strata record in D1 and
returns at-uri, removed analyzeNewCards cron
- Container: analysis accepts island (vertices + edges) instead of
single source, cross-references entire cluster against vault + carry
- Frontend: island cards on explore page, Strata button runs analysis
and navigates to /strata?uri= record page, removed modal approach
- CSS: island-card, island-detail, strata-record styles
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Cloudflare Workers + Containers + Contrail appview that cross-references
Semble cards against local vault and carry data, producing org.latha.strata
synthesis records as stigmergic signals for the network.
- Worker (Hono) with Contrail indexing, connection graph, citation pipeline
- Container analysis engine: reads R2 vault+carry, extracts themes, finds
connections, detects tensions, generates open questions, synthesizes prose
- org.latha.strata lexicon with sourceRef, structuredAnalysis, carryCrossRef
- R2 sync endpoints and CLI script for vault + carry upload
- Frontend SPA with Strata analysis modal on cards and resources
- Per-DID container instances via Durable Objects (10m idle sleep)
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>