Commits
When a carry or vault note has no https:// URL, the analysis now calls
the Letta API (url-discoverer agent with tavily_search tool) to find
the canonical URL. This ensures all connection records have valid
https:// targets.
- Created url-discoverer agent (agent-36607e8a) on Letta Cloud
- Container calls Letta API for notes lacking URLs during analysis
- Secrets: LETTA_API_KEY, LETTA_AGENT_ID in Cloudflare
- Fixed async/await for findFilesystemTouchpoints (was returning Promise)
- Health endpoint shows lettaKeySet and lettaAgentId
Test: 14 connections found for single-vertex island, all with https://
targets discovered via Letta web search.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
carry:// and vault:// URI schemes are not valid connection targets.
The graph only deals with https:// URLs.
- Filesystem touchpoints: extract the https:// URL from each carry/vault
note and use it as the target. Notes without URLs are skipped.
- D1 carry touchpoints: use the carry record url field (not atUri) as
the target for entities and reasonings. Citations already used url.
- Deleted 41 garbage connection records from PDS (carry://, vault://,
and at:// targets).
- Removed temporary cleanupConnections endpoint.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Container now syncs both vault (ob sync) and carry (git pull) on startup:
- Fixed obsidian-cli → obsidian-headless (correct npm package name)
- Fixed ob sync path syntax (--path flag, not positional arg)
- Container writes auth token + vault config to ~/.config/obsidian-headless/
- Secrets: OBSIDIAN_AUTH_TOKEN, OBSIDIAN_ENCRYPTION_KEY, OBSIDIAN_ENCRYPTION_SALT
- Container health endpoint shows vaultFiles, carryFiles, token status
- Sync endpoint returns vault/carry log output for debugging
Result: 654 vault files + 42 carry files synced in container.
Analysis now finds 279 touchpoints (vault + carry) against island vertices.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
The strata analysis now cross-references island vertices against:
1. Carry data from filesystem (synced via git clone from GitHub)
2. Structured carry records from D1 (entities, citations, reasonings)
When semantic matches are found, new network.cosmik.connection records
are created on PDS linking island vertices to carry records.
Key changes:
- Container syncs carry vault from GitHub (CARRY_GITHUB_TOKEN secret)
- Analysis reads vault/carry markdown from filesystem
- findCarryTouchpoints matches carry records to island vertices
- findFilesystemTouchpoints matches vault/carry notes to vertices
- Worker creates connection records on PDS via createRecord
- Frontend sends vertex metadata (titles) with analyze request
- Added containerHealth and syncContainer endpoints
Test: 20 carry touchpoints found for AI island, matching citations
(Knowledge Synthesis, PROV-K), entities (Jacky Alciné, Dawn Foster),
and connections (Khayame-Vickers, Matt Akamatsu-Discourse Graphs).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Analysis now cross-references island vertices against carry data
(entities, citations, reasonings) from D1. When semantic matches are
found, new network.cosmik.connection records are created on PDS linking
the island vertex to the carry record.
Flow:
1. Worker reads carry records from D1 (records_entity, records_citation,
records_reasoning)
2. Passes carryData to container alongside island
3. Container matches carry records against island vertices by keyword
overlap (URL match, title overlap, takeaway overlap)
4. Returns newConnections array
5. Worker creates connection records on PDS via createRecord
6. New connection URIs added to highlights
No carry touchpoints found yet — carry data needs to be published to
AT Protocol first (entities, citations, reasonings) for contrail to
ingest into D1.
Removed carryRefs from frontend (replaced by real connection records).
Removed filesystem-based vault/carry reading from analysis.ts.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
The old analysis.connections field contained fabricated connections
including Japanese text from a Bluesky post. Removed connections from
the PDS record and added cleanup to updateRecord to delete stale
fields. Restored unicode edge icons (the Japanese was in the data,
not the icons). Fixed pdsls.dev link (no encodeURIComponent).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Unicode arrows/symbols (U+2295, U+26D4, etc.) render as CJK in some
fonts. Replaced with ASCII equivalents. Edge title max-width 200px
was too short — now 60% of container.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Highlights section shows only hot edges with star badges
- Edges section shows all edges without hot styling (no duplication)
- recordUri now pulled from getRecord response onto island object
- pdsls.dev link uses actual recordUri
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Also persisted analysis highlights to D1/PDS for island 3mlrokf4gho2i.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Node --experimental-strip-types requires .ts extensions in imports,
not .js. Also adds better error reporting in callContainer.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Remove the separate connections/relationships layer from strata analysis.
All edges are now network.cosmik.connection records. The analysis flags
existing edges as "hot" (semantically significant) via a highlights array
of AT URIs. Frontend renders hot edges with a star badge and accent border.
Lexicon changes:
- Remove #connection def and token defs (supports, contradicts, etc.)
- Remove connections from structuredAnalysis
- Add highlights (at-uri[]) to structuredAnalysis
Analysis changes:
- Replace findConnections with findHotEdges — scores edges by
vault/carry overlap and connection type, returns top AT URIs
- Remove validateConnections (no longer needed)
- Remove Connection interface
Worker changes:
- Replace relationships flattening with highlights passthrough
Frontend changes:
- Remove Relationships section
- Hot edges get .hot-edge class, star badge, accent border
- Edges header shows "N hot" count
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Was dropped in the edit-paradigm rewrite. Now rendered as editable
items with entity linking (Semble pages) and arrow styling.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Inline editing on all analysis fields (title, synthesis, themes,
tensions, questions). Theme tags are editable chips with add/remove.
Regenerate button re-runs analysis with diff highlighting (purple glow
on changed fields). Save to PDS button writes updated record via
com.atproto.repo.putRecord. Editable = human, generatable = machine,
symbiotic loop.
Also adds PUT /xrpc/org.latha.strata.updateRecord endpoint and
PDS_APP_PASSWORD worker secret for PDS writes.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
pdsls.dev/at://did:plc:.../org.latha.strata/rkey#record
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
pdsls.dev links are /{handle}/{collection}/{rkey}, not /{at-uri}.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
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>
When a carry or vault note has no https:// URL, the analysis now calls
the Letta API (url-discoverer agent with tavily_search tool) to find
the canonical URL. This ensures all connection records have valid
https:// targets.
- Created url-discoverer agent (agent-36607e8a) on Letta Cloud
- Container calls Letta API for notes lacking URLs during analysis
- Secrets: LETTA_API_KEY, LETTA_AGENT_ID in Cloudflare
- Fixed async/await for findFilesystemTouchpoints (was returning Promise)
- Health endpoint shows lettaKeySet and lettaAgentId
Test: 14 connections found for single-vertex island, all with https://
targets discovered via Letta web search.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
carry:// and vault:// URI schemes are not valid connection targets.
The graph only deals with https:// URLs.
- Filesystem touchpoints: extract the https:// URL from each carry/vault
note and use it as the target. Notes without URLs are skipped.
- D1 carry touchpoints: use the carry record url field (not atUri) as
the target for entities and reasonings. Citations already used url.
- Deleted 41 garbage connection records from PDS (carry://, vault://,
and at:// targets).
- Removed temporary cleanupConnections endpoint.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Container now syncs both vault (ob sync) and carry (git pull) on startup:
- Fixed obsidian-cli → obsidian-headless (correct npm package name)
- Fixed ob sync path syntax (--path flag, not positional arg)
- Container writes auth token + vault config to ~/.config/obsidian-headless/
- Secrets: OBSIDIAN_AUTH_TOKEN, OBSIDIAN_ENCRYPTION_KEY, OBSIDIAN_ENCRYPTION_SALT
- Container health endpoint shows vaultFiles, carryFiles, token status
- Sync endpoint returns vault/carry log output for debugging
Result: 654 vault files + 42 carry files synced in container.
Analysis now finds 279 touchpoints (vault + carry) against island vertices.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
The strata analysis now cross-references island vertices against:
1. Carry data from filesystem (synced via git clone from GitHub)
2. Structured carry records from D1 (entities, citations, reasonings)
When semantic matches are found, new network.cosmik.connection records
are created on PDS linking island vertices to carry records.
Key changes:
- Container syncs carry vault from GitHub (CARRY_GITHUB_TOKEN secret)
- Analysis reads vault/carry markdown from filesystem
- findCarryTouchpoints matches carry records to island vertices
- findFilesystemTouchpoints matches vault/carry notes to vertices
- Worker creates connection records on PDS via createRecord
- Frontend sends vertex metadata (titles) with analyze request
- Added containerHealth and syncContainer endpoints
Test: 20 carry touchpoints found for AI island, matching citations
(Knowledge Synthesis, PROV-K), entities (Jacky Alciné, Dawn Foster),
and connections (Khayame-Vickers, Matt Akamatsu-Discourse Graphs).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Analysis now cross-references island vertices against carry data
(entities, citations, reasonings) from D1. When semantic matches are
found, new network.cosmik.connection records are created on PDS linking
the island vertex to the carry record.
Flow:
1. Worker reads carry records from D1 (records_entity, records_citation,
records_reasoning)
2. Passes carryData to container alongside island
3. Container matches carry records against island vertices by keyword
overlap (URL match, title overlap, takeaway overlap)
4. Returns newConnections array
5. Worker creates connection records on PDS via createRecord
6. New connection URIs added to highlights
No carry touchpoints found yet — carry data needs to be published to
AT Protocol first (entities, citations, reasonings) for contrail to
ingest into D1.
Removed carryRefs from frontend (replaced by real connection records).
Removed filesystem-based vault/carry reading from analysis.ts.
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
The old analysis.connections field contained fabricated connections
including Japanese text from a Bluesky post. Removed connections from
the PDS record and added cleanup to updateRecord to delete stale
fields. Restored unicode edge icons (the Japanese was in the data,
not the icons). Fixed pdsls.dev link (no encodeURIComponent).
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
- Highlights section shows only hot edges with star badges
- Edges section shows all edges without hot styling (no duplication)
- recordUri now pulled from getRecord response onto island object
- pdsls.dev link uses actual recordUri
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Remove the separate connections/relationships layer from strata analysis.
All edges are now network.cosmik.connection records. The analysis flags
existing edges as "hot" (semantically significant) via a highlights array
of AT URIs. Frontend renders hot edges with a star badge and accent border.
Lexicon changes:
- Remove #connection def and token defs (supports, contradicts, etc.)
- Remove connections from structuredAnalysis
- Add highlights (at-uri[]) to structuredAnalysis
Analysis changes:
- Replace findConnections with findHotEdges — scores edges by
vault/carry overlap and connection type, returns top AT URIs
- Remove validateConnections (no longer needed)
- Remove Connection interface
Worker changes:
- Replace relationships flattening with highlights passthrough
Frontend changes:
- Remove Relationships section
- Hot edges get .hot-edge class, star badge, accent border
- Edges header shows "N hot" count
👾 Generated with [Letta Code](https://letta.com)
Co-Authored-By: Letta Code <noreply@letta.com>
Inline editing on all analysis fields (title, synthesis, themes,
tensions, questions). Theme tags are editable chips with add/remove.
Regenerate button re-runs analysis with diff highlighting (purple glow
on changed fields). Save to PDS button writes updated record via
com.atproto.repo.putRecord. Editable = human, generatable = machine,
symbiotic loop.
Also adds PUT /xrpc/org.latha.strata.updateRecord endpoint and
PDS_APP_PASSWORD worker secret for PDS writes.
👾 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>