<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Papa</title>
    <description>The latest articles on DEV Community by Papa (@papajams).</description>
    <link>https://dev.to/papajams</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3756591%2F7668ad38-c403-4b29-812f-52c067981580.png</url>
      <title>DEV Community: Papa</title>
      <link>https://dev.to/papajams</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/papajams"/>
    <language>en</language>
    <item>
      <title>Familexyz: Giving AI Agents Persistent Memory with Cognee Cloud</title>
      <dc:creator>Papa</dc:creator>
      <pubDate>Sat, 04 Jul 2026 15:23:15 +0000</pubDate>
      <link>https://dev.to/papajams/familexyz-giving-ai-agents-persistent-memory-with-cognee-cloud-1el</link>
      <guid>https://dev.to/papajams/familexyz-giving-ai-agents-persistent-memory-with-cognee-cloud-1el</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Integrating Cognee Cloud's memory layer into FamilyXYZ — a multi-agent AI platform where five philosophy-inspired agents help families strengthen their relationships across Telegram and the web — and ended up filing a PR against Cognee itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;TL;DR — 4 lessons from this integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;When the docs are unclear, read the source.&lt;/strong&gt; An "undocumented" endpoint we thought didn't exist actually did — we found it in the Cognee repo, not the docs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The default search mode isn't always right for you.&lt;/strong&gt; Switching from &lt;code&gt;GRAPH_COMPLETION&lt;/code&gt; to &lt;code&gt;CHUNKS&lt;/code&gt; cut an LLM call and seconds of latency out of every recall.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful degradation is non-negotiable.&lt;/strong&gt; A no-op fallback service meant the app kept working even with the memory layer fully disabled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixing a bug taught us more than the docs did.&lt;/strong&gt; We ended up contributing a PR (&lt;a href="https://github.com/topoteretes/cognee/pull/3863" rel="noopener noreferrer"&gt;#3863&lt;/a&gt;) after tracing inconsistent error responses through the router source.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Details below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahu9izpckbwlmp70g4vy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fahu9izpckbwlmp70g4vy.png" alt=" " width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;FamilyXYZ has five AI agents — Wisdom (Alain de Botton), Intimacy (Esther Perel &amp;amp; Gottman), Presence (Thich Nhat Hanh), Growth (James Clear &amp;amp; Carol Dweck), and Bridge (StoryCorps &amp;amp; bell hooks). Families interact with them via a Telegram bot and a web dashboard.&lt;/p&gt;

&lt;p&gt;The agents were helpful in the moment, but they had no memory. A parent could tell the Wisdom agent about a difficult conversation with their teenager on Monday, and by Wednesday the agent had no idea that conversation ever happened. For a family wellness product, this is a fundamental gap — real relationships are built on accumulated context, not single interactions.&lt;/p&gt;

&lt;p&gt;We needed persistent, per-user memory that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stored every conversation, check-in, and interaction&lt;/li&gt;
&lt;li&gt;Could be queried for relevant context before each agent response&lt;/li&gt;
&lt;li&gt;Supported enrichment (building a knowledge graph from raw text)&lt;/li&gt;
&lt;li&gt;Allowed full data deletion (GDPR-style right to be forgotten)&lt;/li&gt;
&lt;li&gt;Was optional — the app had to keep working if the memory service was down&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh2vm60nk2acy1nexlx2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh2vm60nk2acy1nexlx2o.png" alt=" " width="799" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Cognee Cloud
&lt;/h2&gt;

&lt;p&gt;We evaluated several options: raw vector databases (Pinecone, Weaviate), LLM-native memory (Mem0), and Cognee. We chose Cognee Cloud for three reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Knowledge graph, not just vectors.&lt;/strong&gt; Cognee doesn't just embed text and do similarity search — it builds an actual knowledge graph with entities and relationships. When a user says "I argued with my partner Sarah about screen time," Cognee extracts the entities (user, Sarah, screen time) and relationships (argued_with, about). This means recall can find semantically related memories even without keyword overlap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The lifecycle maps perfectly to agent memory.&lt;/strong&gt; Cognee has four operations that map cleanly to what an agent memory layer needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;remember()&lt;/code&gt; — ingest text, build the knowledge graph automatically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;recall()&lt;/code&gt; — query the graph for relevant context&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;improve()&lt;/code&gt; — run enrichment on the existing graph&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;forget()&lt;/code&gt; — delete a user's entire memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Managed cloud, no infrastructure.&lt;/strong&gt; Cognee Cloud gives us a tenant-isolated instance with a REST API. No graph database to run, no embedding pipeline to maintain, no vector index to tune.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftde26mnzxmgopbuew8nm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftde26mnzxmgopbuew8nm.png" alt=" " width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;We built a standalone workspace package (&lt;code&gt;packages/memory&lt;/code&gt;) that wraps the Cognee Cloud REST API. It exports a &lt;code&gt;MemoryService&lt;/code&gt; interface with four methods and two implementations:&lt;br&gt;
packages/memory/src/&lt;br&gt;
├── MemoryService.ts          # Interface: remember, recall, improve, forget, isEnabled&lt;br&gt;
├── CogneeMemoryService.ts    # Talks to Cognee Cloud via REST API&lt;br&gt;
├── NoopMemoryService.ts      # Silent fallback — all methods are no-ops&lt;br&gt;
└── index.ts                  # Factory: reads env vars, returns the right impl&lt;/p&gt;

&lt;p&gt;The key design decision: &lt;strong&gt;graceful degradation&lt;/strong&gt;. If &lt;code&gt;COGNEE_ENABLED&lt;/code&gt; is not &lt;code&gt;true&lt;/code&gt;, or the API key is missing, or Cognee is unreachable, the app uses &lt;code&gt;NoopMemoryService&lt;/code&gt; and continues working with its existing SQLite-backed state. The memory layer is an enhancement, not a dependency.&lt;/p&gt;
&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;Cognee Cloud uses two headers for multi-tenant auth:&lt;br&gt;
X-Api-Key: &lt;br&gt;
X-Tenant-Id: &lt;/p&gt;

&lt;p&gt;We encapsulated these in an &lt;code&gt;authHeaders()&lt;/code&gt; helper that injects both on every request.&lt;/p&gt;
&lt;h3&gt;
  
  
  Per-User Isolation
&lt;/h3&gt;

&lt;p&gt;Each user gets a dedicated Cognee dataset named &lt;code&gt;familexyz_user_&amp;lt;userId&amp;gt;&lt;/code&gt;. This gives us clean isolation — one user's memories never bleed into another's — and makes &lt;code&gt;forget()&lt;/code&gt; simple: delete the dataset, and all the user's graph data, vectors, and relational records are gone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Naming note:&lt;/strong&gt; you'll see "FamilyXYZ" (the product), &lt;code&gt;familexyz&lt;/code&gt; (the repo/package name), and &lt;code&gt;famile.xyz&lt;/code&gt; (the live domain) used throughout this post. The codebase predates the current domain, hence the mismatch — nothing to worry about if you're cross-referencing the repo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  The Four Operations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;remember()&lt;/strong&gt; — &lt;code&gt;POST /api/v1/remember&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After every Telegram conversation, check-in, or family interaction, we store the content plus metadata (which agent, what source, which family member) as a text blob. Cognee's &lt;code&gt;remember&lt;/code&gt; endpoint handles both ingestion and graph building (add + cognify combined), so we don't need a separate processing step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;enriched&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;memory.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;datasetName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// POST /api/v1/remember&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;recall()&lt;/strong&gt; — &lt;code&gt;POST /api/v1/recall&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Before an agent responds to a user message, we call &lt;code&gt;recall()&lt;/code&gt; to fetch relevant context from the user's memory graph. We use &lt;code&gt;searchType: "CHUNKS"&lt;/code&gt; with &lt;code&gt;topK: 5&lt;/code&gt; — this returns raw text snippets directly without an LLM call, which is cheaper, faster, and gives us text we can inject into the agent's prompt as context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;searchType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CHUNKS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;topK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned snippets are injected into the agent's system prompt as "Previous context from memory:" — giving the agent awareness of past conversations without any agent framework changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;improve()&lt;/strong&gt; — &lt;code&gt;POST /api/v1/improve&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Triggered from the web dashboard's "Improve Memory" button. Runs Cognee's enrichment pipeline (memify) on the user's knowledge graph in the background. This is fire-and-forget — if it fails, the existing graph is still usable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;forget()&lt;/strong&gt; — &lt;code&gt;POST /api/v1/forget&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Triggered from the dashboard's "Forget All" button. Sends &lt;code&gt;{ dataset: "familexyz_user_&amp;lt;id&amp;gt;" }&lt;/code&gt; and Cognee handles the rest: deletes relational records, graph nodes/edges, and vector embeddings. Clean slate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wiring It Into the App
&lt;/h3&gt;

&lt;p&gt;The memory service is a singleton, initialized once at boot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// agent/src/index.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initMemoryService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@familexyz/memory&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;initMemoryService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in the Telegram bot's message router, before routing to an agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMemoryService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Inject context into agent prompt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And after the agent responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`User: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userMessage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nAgent: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;agentResponse&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;conversation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wisdom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The web dashboard at &lt;code&gt;famile.xyz/memory&lt;/code&gt; exposes the full lifecycle via REST endpoints (&lt;code&gt;/api/memory/status&lt;/code&gt;, &lt;code&gt;/api/memory/recall&lt;/code&gt;, &lt;code&gt;/api/memory/remember&lt;/code&gt;, &lt;code&gt;/api/memory/forget&lt;/code&gt;, &lt;code&gt;/api/memory/improve&lt;/code&gt;) with JWT authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The docs don't always match the API
&lt;/h3&gt;

&lt;p&gt;When we first integrated, the documentation for the &lt;code&gt;forget&lt;/code&gt; endpoint was inconsistent — the OpenAPI spec listed a &lt;code&gt;forget&lt;/code&gt; tag, but the API reference page 404'd. We initially assumed the REST endpoint didn't exist and built a workaround (UUID lookup via &lt;code&gt;GET /datasets&lt;/code&gt; + &lt;code&gt;DELETE /datasets/{id}&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;After diving into the Cognee open-source repo to contribute a PR, we discovered &lt;code&gt;POST /api/v1/forget&lt;/code&gt; does exist and accepts &lt;code&gt;{ dataset: "name" }&lt;/code&gt; directly. We simplified our implementation to a single call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When the docs are unclear, read the source. Open-source projects often have better answers in the code than in the docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. CHUNKS vs GRAPH_COMPLETION matters a lot
&lt;/h3&gt;

&lt;p&gt;The default &lt;code&gt;searchType&lt;/code&gt; for &lt;code&gt;recall()&lt;/code&gt; is &lt;code&gt;GRAPH_COMPLETION&lt;/code&gt;, which calls an LLM to generate a natural language answer from the graph. This is expensive (LLM call per recall), slow (seconds of latency), and returns an answer, not raw context.&lt;/p&gt;

&lt;p&gt;For our use case — injecting context into an agent prompt — we want raw text snippets, not LLM-generated answers. Switching to &lt;code&gt;searchType: "CHUNKS"&lt;/code&gt; was a significant improvement: no LLM call, sub-second latency, and text we can directly inject.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Read the search type options carefully. The default isn't always right for your use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Graceful degradation is non-negotiable
&lt;/h3&gt;

&lt;p&gt;The memory layer is optional. The app worked for months without it. If Cognee goes down, credits run out, or the network fails, the app must keep working.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;NoopMemoryService&lt;/code&gt; pattern — where every method is a silent no-op — made this painless. The calling code doesn't know or care whether Cognee is active. It calls &lt;code&gt;recall()&lt;/code&gt;, gets an empty array, and the agent responds without memory context. Not ideal, but not broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When adding a cloud dependency to an existing app, wrap it in an interface with a no-op fallback. The integration becomes a feature enhancement, not a reliability risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Contributing back is the best documentation
&lt;/h3&gt;

&lt;p&gt;We found issue #3748 in the Cognee repo — "Inconsistent API error responses in improve, forget, and recall routers." Three routers were returning raw error dicts with non-standard HTTP status codes (420, 409) instead of the canonical &lt;code&gt;ErrorResponse&lt;/code&gt; DTO used by the other five routers.&lt;/p&gt;

&lt;p&gt;We fixed it in &lt;a href="https://github.com/topoteretes/cognee/pull/3863" rel="noopener noreferrer"&gt;PR #3863&lt;/a&gt;, and the process of reading the router source code taught us more about the API than the docs ever did. We saw exactly how each endpoint handled errors, what status codes to expect, and what the response schema looked like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; The fastest way to understand an open-source API is to fix a bug in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent framework&lt;/td&gt;
&lt;td&gt;ElizaOS (TypeScript)&lt;/td&gt;
&lt;td&gt;Existing multi-agent orchestration, already in place before this integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory layer&lt;/td&gt;
&lt;td&gt;Cognee Cloud (REST API)&lt;/td&gt;
&lt;td&gt;Managed knowledge graph — no infra to run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Hono on Node.js, PM2 on Hetzner&lt;/td&gt;
&lt;td&gt;Lightweight, fast cold starts, cheap to run on a VPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js on Netlify&lt;/td&gt;
&lt;td&gt;Simple static + serverless deploy for the dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bot&lt;/td&gt;
&lt;td&gt;Telegram Bot API&lt;/td&gt;
&lt;td&gt;Primary interaction surface for families&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;JWT (HMAC-SHA256)&lt;/td&gt;
&lt;td&gt;Stateless auth across bot and dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package manager&lt;/td&gt;
&lt;td&gt;pnpm workspaces&lt;/td&gt;
&lt;td&gt;Monorepo with shared packages like &lt;code&gt;@familexyz/memory&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The memory layer is live in production at &lt;code&gt;api.famile.xyz&lt;/code&gt;. A round-trip test confirms it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;remember&lt;/strong&gt;: Store "User checked in: mood=good, had breakfast with family" → &lt;code&gt;{"success":true}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;recall&lt;/strong&gt;: Query "What did the user do this morning?" → Returns the exact memory with metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;status&lt;/strong&gt;: &lt;code&gt;{"enabled":true,"service":"cognee"}&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Telegram bot now remembers past conversations, the web dashboard shows memory status and lets families manage their data, and the whole system degrades gracefully if Cognee is ever unavailable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Session-scoped memory&lt;/strong&gt;: Cognee supports &lt;code&gt;session_id&lt;/code&gt; for per-conversation context tracking. We could give each Telegram conversation its own session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node sets&lt;/strong&gt;: Cognee's &lt;code&gt;remember&lt;/code&gt; accepts &lt;code&gt;node_set&lt;/code&gt; tags for grouping related data. We could tag memories by agent (wisdom, intimacy, etc.) for more targeted recall.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope-aware recall&lt;/strong&gt;: Cognee's &lt;code&gt;scope&lt;/code&gt; parameter can search "graph", "session", "trace", or "all" — we're currently using the default "auto" but could be more intentional about which memory sources to query.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;FamilyXYZ is an open-source family wellness platform. The Cognee integration code is at &lt;a href="https://github.com/thisyearnofear/familexyz" rel="noopener noreferrer"&gt;github.com/thisyearnofear/familexyz&lt;/a&gt;. The Cognee PR is at &lt;a href="https://github.com/topoteretes/cognee/pull/3863" rel="noopener noreferrer"&gt;github.com/topoteretes/cognee/pull/3863&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I turned café wifi speeds into a metro map — on Aurora Serverless v2 + Vercel</title>
      <dc:creator>Papa</dc:creator>
      <pubDate>Mon, 29 Jun 2026 23:51:41 +0000</pubDate>
      <link>https://dev.to/papajams/i-turned-cafe-wifi-speeds-into-a-metro-map-on-aurora-serverless-v2-vercel-55f</link>
      <guid>https://dev.to/papajams/i-turned-cafe-wifi-speeds-into-a-metro-map-on-aurora-serverless-v2-vercel-55f</guid>
      <description>&lt;h1&gt;
  
  
  I Built Lattency: A Crowdsourced Metro Map for Café Wi-Fi Using Aurora PostgreSQL Serverless v2 and Vercel
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsslivpyfwjnqti46slnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsslivpyfwjnqti46slnx.png" alt=" " width="799" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Built for the &lt;strong&gt;H0: Hack the Zero Stack&lt;/strong&gt; hackathon (Vercel × AWS Databases).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Stack:&lt;/strong&gt; Amazon Aurora PostgreSQL Serverless v2 + PostGIS + Next.js on Vercel&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://lattency.vercel.app/" rel="noopener noreferrer"&gt;https://lattency.vercel.app/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/thisyearnofear/lattency" rel="noopener noreferrer"&gt;https://github.com/thisyearnofear/lattency&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;#H0Hackathon&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finding a café with reliable Wi-Fi (in Nairobi) is surprisingly difficult.&lt;/p&gt;

&lt;p&gt;You buy a coffee, settle in, open your laptop, and discover the network can't survive a video call. Twenty minutes later you're packing up and looking for another café.&lt;/p&gt;

&lt;p&gt;It's a problem that quietly steals hours every week.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Lattency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of reviews saying &lt;em&gt;"the Wi-Fi is good"&lt;/em&gt;, Lattency is a crowdsourced metro map where every café is a station and every line represents a Wi-Fi speed tier—not geography.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚄 &lt;strong&gt;Express&lt;/strong&gt; — &lt;strong&gt;50 Mbps and above&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🚉 &lt;strong&gt;Local&lt;/strong&gt; — &lt;strong&gt;10–49 Mbps&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🚧 &lt;strong&gt;Suspended&lt;/strong&gt; — &lt;strong&gt;Below 10 Mbps&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyone can run a speed test, submit a measurement, and within seconds the café is reclassified for everyone else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flioq9oj37c90nhcbo2xp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flioq9oj37c90nhcbo2xp.png" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The interesting part wasn't drawing the map.&lt;/p&gt;

&lt;p&gt;It was building a backend that could answer &lt;strong&gt;"What's the fastest café near me?"&lt;/strong&gt;, update itself in near real time, resist bad data, and cost almost nothing when nobody was using it.&lt;/p&gt;

&lt;p&gt;This post is about the infrastructure that makes that possible.&lt;/p&gt;




&lt;h1&gt;
  
  
  Choosing the database
&lt;/h1&gt;

&lt;p&gt;The hackathon offered three AWS database options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon DynamoDB&lt;/li&gt;
&lt;li&gt;Amazon Aurora DSQL&lt;/li&gt;
&lt;li&gt;Amazon Aurora PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Lattency, the decision came down to one requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Find cafés within a radius of the user's location.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With PostGIS, that's almost trivial.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lng&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;cafes&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ST_DWithin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;geog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ST_MakePoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="n"&gt;geography&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ST_DWithin()&lt;/code&gt; is exactly the kind of query PostGIS was built for.&lt;/p&gt;

&lt;p&gt;DynamoDB has no native geospatial radius queries, and Aurora DSQL doesn't currently support PostGIS.&lt;/p&gt;

&lt;p&gt;Once location search became a requirement, Aurora PostgreSQL wasn't simply the easiest choice—it was the only database that naturally fit the problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzy0m2ju3oboy3s7yheh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzy0m2ju3oboy3s7yheh2.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second reason was economics.&lt;/p&gt;

&lt;p&gt;Aurora PostgreSQL Serverless v2 scales all the way down to &lt;strong&gt;0 ACUs&lt;/strong&gt; when idle.&lt;/p&gt;

&lt;p&gt;A project like Lattency doesn't receive traffic around the clock. It wakes up during working hours, slows down overnight, and may eventually expand city by city.&lt;/p&gt;

&lt;p&gt;Paying only when the database is actually serving requests is exactly the pricing model I wanted.&lt;/p&gt;

&lt;p&gt;The trade-off is a cold start of roughly &lt;strong&gt;15–30 seconds&lt;/strong&gt; after long periods of inactivity.&lt;/p&gt;

&lt;p&gt;Fortunately, there are ways to hide that from users.&lt;/p&gt;




&lt;h1&gt;
  
  
  Let PostgreSQL decide the line colour
&lt;/h1&gt;

&lt;p&gt;Raw speed tests are noisy.&lt;/p&gt;

&lt;p&gt;One person on hotel Wi-Fi, a VPN, or a congested network shouldn't immediately downgrade an entire café.&lt;/p&gt;

&lt;p&gt;Instead of calculating speed tiers on every request, Lattency maintains a &lt;strong&gt;materialized view&lt;/strong&gt; that stores per-café statistics.&lt;/p&gt;

&lt;p&gt;Every new measurement refreshes that view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;REFRESH&lt;/span&gt; &lt;span class="n"&gt;MATERIALIZED&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;CONCURRENTLY&lt;/span&gt; &lt;span class="n"&gt;cafe_speed_stats&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is &lt;code&gt;CONCURRENTLY&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Without it, PostgreSQL would lock the view while rebuilding it.&lt;/p&gt;

&lt;p&gt;With it, visitors continue reading from the old version while PostgreSQL prepares the new one in the background.&lt;/p&gt;

&lt;p&gt;No downtime.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fska76hqc4nexvou6qtu7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fska76hqc4nexvou6qtu7.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As more measurements came in, I made the aggregation smarter.&lt;/p&gt;

&lt;p&gt;Once a café has enough submissions, measurements marked as outliers are ignored when calculating the median.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one accidental upload won't move a café into &lt;em&gt;Suspended&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;genuine network upgrades still appear naturally over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Outliers are excluded from the calculation—not deleted—so the underlying data remains intact.&lt;/p&gt;




&lt;h1&gt;
  
  
  Making serverless behave like a long-running app
&lt;/h1&gt;

&lt;p&gt;Connecting a serverless application to PostgreSQL introduces three practical problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Too many database connections
&lt;/h2&gt;

&lt;p&gt;Every serverless function can create its own PostgreSQL connection.&lt;/p&gt;

&lt;p&gt;That doesn't scale very well.&lt;/p&gt;

&lt;p&gt;Instead, I cache a single &lt;code&gt;pg.Pool&lt;/code&gt; on &lt;code&gt;globalThis&lt;/code&gt;, allowing warm instances to reuse existing connections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalForPg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;globalThis&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Pool&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;globalForPg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;rejectUnauthorized&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;globalForPg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping each instance to a single pooled connection dramatically reduces connection pressure.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Don't wake the database for every visitor
&lt;/h2&gt;

&lt;p&gt;Most people viewing the homepage are looking at the same information.&lt;/p&gt;

&lt;p&gt;There's no reason every request should hit Aurora.&lt;/p&gt;

&lt;p&gt;The homepage is statically rendered using Incremental Static Regeneration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;revalidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most visitors receive a cached page from Vercel's edge network.&lt;/p&gt;

&lt;p&gt;Aurora only needs to wake once every minute instead of once per visitor, reducing both cost and cold starts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprvk39wv7wqbbbrrvv6b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fprvk39wv7wqbbbrrvv6b.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Never fail because the database is sleeping
&lt;/h2&gt;

&lt;p&gt;Cold starts happen.&lt;/p&gt;

&lt;p&gt;Instead of showing an error page while Aurora wakes up, Lattency falls back to a bundled snapshot included with the application.&lt;/p&gt;

&lt;p&gt;The map still loads.&lt;/p&gt;

&lt;p&gt;Users can still explore cafés.&lt;/p&gt;

&lt;p&gt;For a hackathon demo, that's the difference between an impressive first impression and a blank screen.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Refresh after the response
&lt;/h2&gt;

&lt;p&gt;Refreshing the materialized view isn't part of the user's request.&lt;/p&gt;

&lt;p&gt;Using Next.js' &lt;code&gt;after()&lt;/code&gt; API, the response is sent immediately while the refresh runs afterwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;refreshSpeedStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users don't wait for maintenance work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1cfb6bxnif9zi0pvprqp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1cfb6bxnif9zi0pvprqp.jpg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Crowdsourced data only works if people can't game it
&lt;/h1&gt;

&lt;p&gt;Allowing anyone to contribute data is both the best feature and the biggest security problem.&lt;/p&gt;

&lt;p&gt;I wanted automatic submissions to be more trustworthy than manually typed numbers.&lt;/p&gt;

&lt;p&gt;Instead of asking contributors to copy results from another speed test, Lattency performs the test directly in the browser against a Vercel Edge region.&lt;/p&gt;

&lt;p&gt;It measures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download speed&lt;/li&gt;
&lt;li&gt;upload speed&lt;/li&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;jitter&lt;/li&gt;
&lt;li&gt;packet loss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, the server—not the client—decides whether the submission counts as an automatic test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;testMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;downloadBytes&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;downloadDurationMs&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;manual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A user can't simply claim they performed an automatic test.&lt;/p&gt;

&lt;p&gt;The evidence has to exist.&lt;/p&gt;




&lt;p&gt;To prevent spam without storing personal information, every IP address is salted and hashed before comparison.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RATE_LIMIT_SALT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The raw IP is never stored.&lt;/p&gt;

&lt;p&gt;Rate limiting becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One measurement per IP, per café, every ten minutes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Privacy is preserved while abuse becomes significantly harder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6a8smagngla072ifa3vr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6a8smagngla072ifa3vr.jpg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Adding a brand-new café is also transactional.&lt;/p&gt;

&lt;p&gt;Creating the café and inserting its first measurement happen inside the same database transaction.&lt;/p&gt;

&lt;p&gt;If either operation fails, everything rolls back.&lt;/p&gt;

&lt;p&gt;The map never ends up with empty cafés that have no measurements attached.&lt;/p&gt;




&lt;h1&gt;
  
  
  The production architecture I almost shipped
&lt;/h1&gt;

&lt;p&gt;One rabbit hole consumed far more time than I expected.&lt;/p&gt;

&lt;p&gt;RDS Proxy.&lt;/p&gt;

&lt;p&gt;Initially, I wanted every database connection to pass through an RDS Proxy instead of exposing Aurora directly.&lt;/p&gt;

&lt;p&gt;I configured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a dedicated security group&lt;/li&gt;
&lt;li&gt;Secrets Manager credentials&lt;/li&gt;
&lt;li&gt;IAM permissions&lt;/li&gt;
&lt;li&gt;the proxy itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything looked correct.&lt;/p&gt;

&lt;p&gt;Nothing connected.&lt;/p&gt;

&lt;p&gt;Eventually I realised why.&lt;/p&gt;

&lt;p&gt;RDS Proxy is intentionally private.&lt;/p&gt;

&lt;p&gt;Its endpoint lives inside the VPC.&lt;/p&gt;

&lt;p&gt;That's perfect for Lambda, ECS, and EC2.&lt;/p&gt;

&lt;p&gt;It's not designed for platforms like Vercel running outside your AWS network.&lt;/p&gt;

&lt;p&gt;Connecting to it requires additional networking such as PrivateLink or a load balancer.&lt;/p&gt;

&lt;p&gt;That lesson ended up being more valuable than the configuration itself.&lt;/p&gt;

&lt;p&gt;If I were taking Lattency to production today, I'd choose one of these architectures:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Vercel × AWS Marketplace Aurora Integration&lt;/strong&gt; — Aurora provisioned through Vercel using PrivateLink. No public database endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PrivateLink&lt;/strong&gt; — More infrastructure, but the same private networking model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Load Balancer + RDS Proxy&lt;/strong&gt; — Works without reprovisioning, although it adds cost and operational complexity.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the hackathon, opening PostgreSQL on port 5432 was the pragmatic decision.&lt;/p&gt;

&lt;p&gt;I think it's more useful to explain that trade-off honestly than pretend the demo shipped with perfect infrastructure.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I ended up with
&lt;/h1&gt;

&lt;p&gt;The metro-map interface is what people notice first.&lt;/p&gt;

&lt;p&gt;The infrastructure is what makes it believable.&lt;/p&gt;

&lt;p&gt;Lattency combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aurora PostgreSQL Serverless v2 + PostGIS&lt;/strong&gt; for fast geospatial searches and scale-to-zero pricing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Materialized views&lt;/strong&gt; for outlier-aware café classification without blocking reads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental Static Regeneration&lt;/strong&gt; so most visitors never touch the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection reuse&lt;/strong&gt; to keep PostgreSQL healthy in a serverless environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-side trust verification&lt;/strong&gt; so automatic measurements can't be trivially faked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful fallbacks&lt;/strong&gt; so the application continues working even while Aurora is waking up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same architecture could power Wi-Fi maps for any city.&lt;/p&gt;

&lt;p&gt;Nairobi just happened to be the first one.&lt;/p&gt;




&lt;p&gt;If you'd like to explore it yourself:&lt;/p&gt;

&lt;p&gt;🗺️ &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://lattency.vercel.app/" rel="noopener noreferrer"&gt;https://lattency.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/thisyearnofear/lattency" rel="noopener noreferrer"&gt;https://github.com/thisyearnofear/lattency&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear what you'd build with the same stack—or how you'd improve Lattency.&lt;/p&gt;

&lt;p&gt;Built for the &lt;strong&gt;H0: Hack the Zero Stack&lt;/strong&gt; hackathon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#H0Hackathon&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>postgres</category>
      <category>postgressql</category>
    </item>
    <item>
      <title>Cognivern - Spend OS For Agent Teams</title>
      <dc:creator>Papa</dc:creator>
      <pubDate>Mon, 08 Jun 2026 06:47:42 +0000</pubDate>
      <link>https://dev.to/papajams/cognivern-spend-os-for-agent-teams-1852</link>
      <guid>https://dev.to/papajams/cognivern-spend-os-for-agent-teams-1852</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://cognivern.vercel.app" rel="noopener noreferrer"&gt;Cognivern&lt;/a&gt;&lt;/strong&gt; is a control plane for agent operations — a SpendOS for agent teams.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ljj5r4u03j4wote2d8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ljj5r4u03j4wote2d8m.png" alt=" " width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As AI agents proliferate across development workflows, a quiet crisis is brewing: no one really controls what agents spend, on what, on behalf of whom, or why. Every agent gets what amounts to a blank check — against model APIs, against wallets, against third-party services. Cognivern exists to fix that.&lt;/p&gt;

&lt;p&gt;The platform unifies governed wallet spend and AI spend governance across IDE, CLI, and agent workflows into a single auditable control layer. The core promise is simple: &lt;strong&gt;move fast without blank checks&lt;/strong&gt;. Every spend decision can be policy-checked, privacy-preserving, efficiency-aware, and audit-ready — before it executes.&lt;/p&gt;

&lt;p&gt;This matters especially in emerging markets and for teams building on-chain infrastructure, where cost overruns from runaway agents aren't just annoying — they're existential. You don't burn budget you don't have chasing a misconfigured prompt loop.&lt;/p&gt;

&lt;p&gt;At its core, Cognivern provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy evaluation&lt;/strong&gt; — enforce who/what/when rules before any spend executes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy-native operations&lt;/strong&gt; — evaluate sensitive policy context via confidential paths using Fhenix FHE (Fully Homomorphic Encryption)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI spend governance&lt;/strong&gt; — model/runtime usage visibility and optimization alongside financial controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit trails&lt;/strong&gt; — persist decision evidence (&lt;code&gt;decisionId&lt;/code&gt;, attestation, run context) for continuous accountability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-provider AI routing&lt;/strong&gt; — ChainGPT as the primary Web3-native LLM, with Fireworks, OpenAI, Gemini, Anthropic, and others as fallbacks
The stack is TypeScript + Solidity, deployed across X Layer Testnet (execution and policy), Filecoin Calibration (audit storage), and Fhenix (confidential policy state). The frontend lives at &lt;a href="https://cognivern.vercel.app" rel="noopener noreferrer"&gt;cognivern.vercel.app&lt;/a&gt; and includes a PromptOS terminal for natural-language governance interaction.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://cognivern.vercel.app" rel="noopener noreferrer"&gt;cognivern.vercel.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 &lt;strong&gt;API:&lt;/strong&gt; &lt;a href="https://cognivern.thisyearnofear.com" rel="noopener noreferrer"&gt;cognivern.thisyearnofear.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 &lt;strong&gt;PromptOS Terminal:&lt;/strong&gt; &lt;a href="https://cognivern.vercel.app/os" rel="noopener noreferrer"&gt;cognivern.vercel.app/os&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 &lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/thisyearnofear/cognivern" rel="noopener noreferrer"&gt;github.com/thisyearnofear/cognivern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key flows you can explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submit a spend request through the dashboard and watch policy evaluation fire in real time&lt;/li&gt;
&lt;li&gt;Use the PromptOS terminal to interact with governance rules in natural language&lt;/li&gt;
&lt;li&gt;Inspect the audit log — every decision has a &lt;code&gt;decisionId&lt;/code&gt; and attestation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Try the encrypted spend path (Fhenix), where policy is evaluated over encrypted inputs — the server never sees the raw values
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;Cognivern started as a hackathon project with a clear thesis but rough edges everywhere. The core governance loop worked, but it was held together with duct tape: no proper workspace isolation, no rate limiting, brittle contract interactions, and a frontend that was functional but not something you'd confidently hand to an operator.&lt;/p&gt;

&lt;p&gt;Here's what changed during the finish-up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure hardening&lt;/strong&gt; — Added per-workspace and per-API-key rate limiters with sliding windows, deep health checks, and circuit-breaker patterns. Moved to TypeScript strict mode throughout. Built out a unified CI pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;172 tests&lt;/strong&gt; — Unit, integration, and E2E via Playwright. The project went from "it works on my machine" to something with real coverage guarantees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-workspace and policy versioning&lt;/strong&gt; — Each workspace now has independent API keys, rate limits, and a full policy version history. This was the feature that turned a demo into something a real team could adopt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fhenix Wave 5–7&lt;/strong&gt; — The FHE integration went from a proof-of-concept to a full institutional demo: encrypted policies, MEV-protected execution, selective auditor disclosure, two-phase FHE resolution with &lt;code&gt;resolveDecision&lt;/code&gt;, sealed-bid vendor selection, and a Privara confidential payroll flow. Also migrated from Helium testnet to Arbitrum Sepolia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChainGPT integration&lt;/strong&gt; — Brought in ChainGPT as the primary AI provider for Web3-native governance queries, with the Smart Contract Auditor running as runtime pre-spend defense. This felt like the missing piece — governance AI that actually understands on-chain context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operator UX&lt;/strong&gt; — PromptOS terminal integrated into the sidebar, voice input via ElevenLabs STT, self-service onboarding flow, animated workspace mode toggles, full mobile responsiveness.&lt;/p&gt;

&lt;p&gt;The project went from ~60% production-ready to ~93%. The remaining 7% is mostly production key management and a few contract audit items before mainnet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx30cvuw5p8sgsh1j8c5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx30cvuw5p8sgsh1j8c5v.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;Cognivern is a project with a lot of moving parts — Solidity contracts, TypeScript APIs, multi-chain deployment scripts, FHE integration, and a React frontend — often all in motion at the same time. Copilot was the connective tissue that kept things moving without constant context-switching tax.&lt;/p&gt;

&lt;p&gt;A few specific ways it earned its keep:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boilerplate elimination for the governance endpoints.&lt;/strong&gt; The API has 12+ endpoints with consistent patterns — request validation, policy lookup, decision logging, response shaping. Writing the first one from scratch was fine; Copilot handled the rest, often getting the full shape right on the first suggestion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solidity contract work.&lt;/strong&gt; The &lt;code&gt;ConfidentialSpendPolicy&lt;/code&gt; contract for Fhenix was genuinely novel — FHE operations aren't something most developers have pattern-matched on. Copilot's suggestions weren't always right, but they were useful scaffolding that surfaced the right questions. The back-and-forth of accepting, rejecting, and editing suggestions was faster than writing from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test generation.&lt;/strong&gt; Getting to 172 tests would have taken much longer without Copilot helping generate test cases from the function signatures and existing test patterns. It's particularly good at the "write 10 edge case tests for this validator" kind of ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;README and documentation.&lt;/strong&gt; The architecture docs, developer guide, and deployment docs are detailed. Copilot helped maintain consistent voice and structure across them, and was surprisingly good at inferring the right level of technical detail for each audience.&lt;/p&gt;

&lt;p&gt;The honest take: Copilot didn't make hard architectural decisions easier. The FHE integration design, the multi-chain deployment strategy, the policy versioning data model — those required real thinking. But it absorbed a huge amount of the mechanical work and kept me in flow during the push to get this finished.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Find me on &lt;a href="https://farcaster.xyz/papa" rel="noopener noreferrer"&gt;Farcaster&lt;/a&gt; and &lt;a href="https://palus.app/u/papajams" rel="noopener noreferrer"&gt;Lens&lt;/a&gt; — always building at the intersection of AI, emerging markets, and on-chain infrastructure.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>githubchallenge</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>DiversiFi — Finishing What Inflation Started</title>
      <dc:creator>Papa</dc:creator>
      <pubDate>Mon, 08 Jun 2026 06:34:44 +0000</pubDate>
      <link>https://dev.to/papajams/diversifi-finishing-what-inflation-started-9mb</link>
      <guid>https://dev.to/papajams/diversifi-finishing-what-inflation-started-9mb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://diversifiapp.vercel.app" rel="noopener noreferrer"&gt;DiversiFi&lt;/a&gt; is an AI-powered stablecoin diversification app built on Celo and Arbitrum. The premise is simple but personal: your stablecoins shouldn't all be pegged to the dollar.&lt;/p&gt;

&lt;p&gt;If you live in Kenya — as I do — inflation isn't an abstract macroeconomic concept. It's the gap between what you earned last year and what that money buys today. It's the reason holding savings in a local currency account quietly destroys purchasing power, and why stablecoins feel like a genuine unlock: your savings can actually compound instead of erode.&lt;/p&gt;

&lt;p&gt;But even dollar-pegged stables have their own exposure. And if you care about your continent — about African economies developing their own financial infrastructure, about emerging markets building on-chain alternatives to broken legacy rails — then a portfolio that's 100% cUSD is both financially incomplete and ideologically inconsistent.&lt;/p&gt;

&lt;p&gt;DiversiFi tries to fix both problems at once. Connect a wallet, pick a financial philosophy, deposit stablecoins into a non-custodial Safe smart account, and let an AI agent rebalance your holdings across regional stablecoins — cUSD (US), cEUR (EU), KESm (Kenya), COPm (Colombia), PHPm (Philippines), cREAL (Brazil) — based on live inflation and economic data.&lt;/p&gt;

&lt;p&gt;The agent doesn't just chase yield. It reads governance forums, World Bank inflation feeds, and economic signals to make allocation decisions that reflect both the numbers and the philosophy you've chosen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Africapitalism&lt;/strong&gt; — keep wealth circulating in African economies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Islamic Finance&lt;/strong&gt; — Sharia-compliant, no interest-bearing assets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buen Vivir&lt;/strong&gt; — LatAm philosophy balancing material wealth with community wellbeing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Diversification&lt;/strong&gt; — maximum geographic spread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom&lt;/strong&gt; — define your own allocation targets
This isn't cosmetic. Each philosophy filters which assets the agent can touch, how it weights rebalancing recommendations, and what it rules out entirely. The goal is a tool that reflects how real people in real places actually think about money — not just a generic robo-advisor with a world-map splash screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built by &lt;a href="https://farcaster.xyz/papa" rel="noopener noreferrer"&gt;@papajams&lt;/a&gt; · &lt;a href="https://palus.app/u/papajams" rel="noopener noreferrer"&gt;Lens&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://diversifiapp.vercel.app" rel="noopener noreferrer"&gt;diversifiapp.vercel.app&lt;/a&gt;&lt;br&gt;
📦 &lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/thisyearnofear/diversify" rel="noopener noreferrer"&gt;github.com/thisyearnofear/diversify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvtgoc56byz3ubkqsmwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvtgoc56byz3ubkqsmwq.png" alt=" " width="800" height="839"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl7ddx9ibvcol97dzp4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbl7ddx9ibvcol97dzp4k.png" alt=" " width="800" height="1307"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;DiversiFi started as a hackathon prototype — the kind that works well enough for a 3-minute pitch but quietly falls apart the moment you try to actually use it.&lt;/p&gt;

&lt;p&gt;The core flows were broken. The agent could recommend rebalances but couldn't reliably execute them. The permission system — the piece that makes this non-custodial and therefore trustworthy — was wired up but unenforced, which defeated the whole point. The UI showed allocation targets but gave no real-time feedback on what the agent was actually doing. And the financial strategy layer was mostly decorative; it influenced the copy, not the code.&lt;/p&gt;

&lt;p&gt;The push to actually finish it came from submitting to the &lt;a href="https://luma.com/ETHMX2026" rel="noopener noreferrer"&gt;Ethereum México x Bitso Hackathon&lt;/a&gt; — a 5-week global build sprint at the intersection of AI, stablecoins, and payments, with Bitso as a key integration partner and 20% of judging weighted on LATAM real-world impact. Having real mentors and a live demo day in front of regulators and fund managers has a way of clarifying what "done" actually means.&lt;/p&gt;

&lt;p&gt;Here's what changed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution layer fixed.&lt;/strong&gt; &lt;code&gt;_executor.ts&lt;/code&gt; now correctly bridges the vault service to the chain via Privy smart accounts, with a local dev fallback that doesn't require a full smart account setup to test against.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permission model enforced.&lt;/strong&gt; Session signer policies now actually gate what the agent can spend, on which contracts, within what time bounds. The agent cannot exceed user-defined limits. This is the difference between "non-custodial" as a marketing claim and non-custodial as an architectural guarantee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategy wired into agent behaviour.&lt;/strong&gt; Each financial philosophy now filters and weights rebalance recommendations at the &lt;code&gt;vault.service.ts&lt;/code&gt; level. Africapitalism doesn't just change the UI label — it changes which assets the agent will and won't touch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real transaction receipts.&lt;/strong&gt; Transactions now log through OpenClaw with human-readable summaries. Users can see exactly what the agent did, why, and when — not just a tx hash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bitso integration.&lt;/strong&gt; Added Bitso as a payment rail, bridging fiat on-ramps to on-chain stablecoin positions. For LATAM users this matters enormously: getting funds into the protocol shouldn't require already being crypto-native.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expanded to Arbitrum.&lt;/strong&gt; Extended beyond Celo to support Arbitrum, broadening the asset universe and giving users access to deeper liquidity pools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fee model stabilised.&lt;/strong&gt; 1% annual management + 10% performance above high-water mark + 0.10% swap spread, now calculated and settled correctly at withdrawal rather than estimated and forgotten.&lt;/p&gt;

&lt;p&gt;The project went from a prototype that made a good pitch to something I'd actually trust with a real deposit.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I used Copilot Chat throughout the finishing process — primarily for architecture and debugging, less as a code generator and more as a thinking partner when things got tangled.&lt;/p&gt;

&lt;p&gt;The most valuable moments were in the permission and execution layers, which are genuinely non-trivial. ERC-4337 smart accounts, session signer policies, Privy's secure enclave model — these interact in ways that aren't obvious, and when something breaks the error messages are often unhelpfully cryptic. Being able to paste a stack trace or policy config into Copilot Chat and get a focused hypothesis about what was failing saved real time that would otherwise have gone into reading SDK internals line by line.&lt;/p&gt;

&lt;p&gt;I also used it to pressure-test the security model. Walking through the architecture — user controls Safe, agent signs within policy, no private key on server — and asking Copilot to look for holes surfaced a few edge cases around policy expiry and fallback signing I hadn't thought through carefully enough. Having something push back on your assumptions is underrated.&lt;/p&gt;

&lt;p&gt;It's not magic. It didn't know Mento Protocol's quirks or Celo's specific bundler constraints out of the box. But as a tool for reasoning through complex, interlocking systems — rather than just autocompleting boilerplate — Copilot Chat earned its place in this build.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Find me on &lt;a href="https://farcaster.xyz/papa" rel="noopener noreferrer"&gt;Farcaster&lt;/a&gt; and &lt;a href="https://palus.app/u/papajams" rel="noopener noreferrer"&gt;Lens&lt;/a&gt; — always building at the intersection of AI, emerging markets, and on-chain infrastructure.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>WebMCP Might Be the Most Important Announcement at Google I/O 2026</title>
      <dc:creator>Papa</dc:creator>
      <pubDate>Mon, 25 May 2026 00:49:35 +0000</pubDate>
      <link>https://dev.to/papajams/webmcp-might-be-the-most-important-announcement-at-google-io-2026-1gfh</link>
      <guid>https://dev.to/papajams/webmcp-might-be-the-most-important-announcement-at-google-io-2026-1gfh</guid>
      <description>&lt;p&gt;Every few years a technology shows up that looks like a product but is actually a protocol. When that happens, the product gets forgotten and the protocol becomes infrastructure. Google I/O 2026 had one of those moments. It just didn't get treated like one.&lt;/p&gt;

&lt;p&gt;The models were impressive. Gemini 3.5 Flash is four times faster than its predecessors. Antigravity 2.0 makes agent orchestration feel like something you'd actually ship. AI Studio now deploys to Cloud Run in one click. None of it was architecturally surprising. But buried in the developer sessions was something different: WebMCP, a proposed open standard for exposing structured tools to browser-based AI agents.&lt;/p&gt;

&lt;p&gt;That one is worth sitting with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Failure Mode Everyone Already Knows
&lt;/h2&gt;

&lt;p&gt;If you have ever maintained Selenium automation for more than six months, you already understand the problem WebMCP is trying to solve.&lt;/p&gt;

&lt;p&gt;The automation works until the product team redesigns the checkout page. Then the selector breaks. You fix it. Three weeks later the login flow changes. You fix it again. You are not engineering anything — you are running a permanent rearguard action against a UI that was never designed to stay still. The automation is fragile because it is built on inference: your code is guessing at intent by reading presentation.&lt;/p&gt;

&lt;p&gt;The first generation of browser AI agents have exactly this problem, at larger scale and higher stakes. They can see buttons and forms and navigation menus, and they can click on things, but they are always one redesign away from failing. They are imitating human behavior because the web has never offered them an alternative.&lt;/p&gt;

&lt;p&gt;Imagine booking a flight through an agent today. The agent visually searches for departure fields, date pickers, seat selectors, and payment buttons. Every redesign risks breaking the workflow. Under WebMCP, the airline could expose booking itself as a structured capability: destination, dates, passenger count, seat preferences, payment authorization. The agent stops navigating the interface and starts interacting with the system underneath it.&lt;/p&gt;

&lt;p&gt;WebMCP is the alternative.&lt;/p&gt;

&lt;p&gt;The standard lets web developers expose structured tools — JavaScript functions, typed parameters, form interactions — as machine-readable capabilities. Instead of an agent inferring "this is probably a search box" by parsing the DOM, the site simply declares: here is a search function, here are its inputs, here is what it returns. Declarative for standard interactions, imperative for anything requiring runtime JavaScript. Chrome's experimental origin trial starts in Chrome 149.&lt;/p&gt;

&lt;p&gt;The immediate gain is reliability. But that is not the interesting part.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changes Under the Surface
&lt;/h2&gt;

&lt;p&gt;Websites have always been designed around visibility. If a human could see and operate something, the web had succeeded. That assumption ran so deep it was invisible — interfaces were presentation layers, and making them look right was the whole job.&lt;/p&gt;

&lt;p&gt;WebMCP introduces a different assumption: systems may not need to be visually navigable to be operationally useful. The interface stops being primarily a presentation layer and starts being a capability surface.&lt;/p&gt;

&lt;p&gt;That is a significant mutation.&lt;/p&gt;

&lt;p&gt;An airline site exposing a structured booking capability is no longer just a place you visit. It becomes a service an agent can call directly. The distinction between website and API starts to blur at the protocol level, not just for developers, but for the web itself.&lt;/p&gt;

&lt;p&gt;There is historical precedent for this shift.&lt;/p&gt;

&lt;p&gt;RSS made web content machine-readable. A feed reader did not have to scrape a blog and guess where the article title ended and the sidebar began. The site simply exposed structure directly. RSS eventually collapsed as a consumer technology, but the idea it proved — that structured syndication beats scraping — became foundational to modern content APIs.&lt;/p&gt;

&lt;p&gt;WebMCP does for actions what RSS did for content.&lt;/p&gt;

&lt;p&gt;That distinction matters enormously.&lt;/p&gt;

&lt;p&gt;Content syndication is passive. The machine reads what a human wrote. Action exposure is active — the machine performs operations on a user's behalf, with real-world consequences. The jump from "readable" to "actionable" changes the ontology of the web itself.&lt;/p&gt;

&lt;p&gt;This is what Google is quietly building toward.&lt;/p&gt;

&lt;p&gt;Antigravity 2.0 orchestrates agents. Gemini Spark acts across Gmail, Calendar, and eventually third-party tools via MCP. But agent workflows are only as reliable as the surfaces they operate on. The whole agentic stack presupposes that websites will eventually expose structured interfaces for machine consumption.&lt;/p&gt;

&lt;p&gt;WebMCP is the specification for what that looks like on the open web.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Critique You Have to Make
&lt;/h2&gt;

&lt;p&gt;Here is where most conference coverage goes soft.&lt;/p&gt;

&lt;p&gt;WebMCP only matters if adoption follows. An open standard with one browser behind it and no ecosystem buy-in is just a Chrome experiment. The history of proposed web standards is mostly a graveyard of promising ideas that died waiting for critical mass, or got implemented inconsistently enough that developers ended up writing workarounds anyway — which is to say, they ended up back at the Selenium problem.&lt;/p&gt;

&lt;p&gt;Google has enough platform leverage to push Chrome 149 to most of the world's browsers in six months. It does not have the same leverage over every site that agents will need to use. The gap between "here is a standard" and "here is a standard that Stripe and Shopify and healthcare portals have implemented correctly" is years of developer effort and business negotiation. Nothing about announcing a standard compresses that timeline.&lt;/p&gt;

&lt;p&gt;There is also a safety question the I/O coverage largely sidesteps.&lt;/p&gt;

&lt;p&gt;Structured tool exposure is a double-sided surface. Right now browser agents are limited partly for the same reason they are safe: they cannot do that much. A web where every site exposes clean, machine-actionable capabilities is a web where the blast radius of a compromised or misbehaving agent gets significantly larger.&lt;/p&gt;

&lt;p&gt;The permissions model, the consent model, the audit trail — none of that is solved by declaring "here are the actions this site supports." If anything, it sharpens the accountability question.&lt;/p&gt;

&lt;p&gt;The infrastructure is arriving faster than the trust guarantees.&lt;/p&gt;

&lt;p&gt;That is the honest summary of where agentic development actually sits right now. Not just for WebMCP — for all of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Is Still the Story
&lt;/h2&gt;

&lt;p&gt;None of those concerns make WebMCP less important. They make it more important to track carefully.&lt;/p&gt;

&lt;p&gt;The DEV community's instinct after I/O was telling. The submissions that resonated were not about model benchmarks. They were about infrastructure, about privacy, about frameworks designed for machines as much as humans. That pattern is not accidental.&lt;/p&gt;

&lt;p&gt;Developers who ship things for a living have a reliable nose for where the actual work is going to land, and right now that nose is pointing at integration — not intelligence.&lt;/p&gt;

&lt;p&gt;The capability problem is closer to solved than most people want to admit. Models reason well. Models act. What remains unsolved is making those actions reliable, auditable, and safe at scale.&lt;/p&gt;

&lt;p&gt;That is an infrastructure problem.&lt;/p&gt;

&lt;p&gt;And infrastructure problems get solved by protocols, not products.&lt;/p&gt;

&lt;p&gt;WebMCP is an early answer to the question of what reliable agent-web interaction should look like. It will probably not be the final answer. RSS wasn't either. But RSS proved the idea was viable, and everything that followed built on that proof.&lt;/p&gt;

&lt;p&gt;The original web connected documents.&lt;/p&gt;

&lt;p&gt;The next version may connect capabilities — not just for humans navigating pages, but for agents executing intent.&lt;/p&gt;

&lt;p&gt;The web was built for humans to navigate.&lt;/p&gt;

&lt;p&gt;The next version may be built for agents to operate.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Submitted for the Google I/O 2026 Writing Challenge on DEV.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>ai</category>
      <category>web</category>
      <category>techtalks</category>
    </item>
  </channel>
</rss>
