# Emiote — Full Knowledge Corpus > AI-native design and build for founders and teams — MVPs, full products, and software modernization. Homepage: https://emiote.com/ Pricing: https://emiote.com/pricing/ Reframe Stack Review: https://emiote.com/reframe/ ReframeHub Tool Directory: https://emiote.com/reframehub/ Products: https://emiote.com/products/ Work & Case Studies: https://emiote.com/work/ Studio Journal: https://emiote.com/journal/ About: https://emiote.com/about/ Contact: https://emiote.com/contact/ Docs: https://emiote.com/docs/ MCP Server: https://emiote.com/mcp/ ## Agent Discovery & Machine Interfaces - Concise Summary: https://emiote.com/llms.txt - Full Corpus: https://emiote.com/llms-full.txt - AI Visibility & Permissions: https://emiote.com/ai.txt - Structured AI Snapshot (JSON): https://emiote.com/api/ai - Markdown Content Catalog: https://emiote.com/api/md/_catalog - Model Context Protocol (MCP) Docs: https://emiote.com/mcp.md - MCP Server Card: https://emiote.com/.well-known/mcp/server-card.json - MCP JSON-RPC Endpoint: https://emiote.com/api/mcp - RFC 9727 API Catalog: https://emiote.com/.well-known/api-catalog - OpenAPI 3.1 Specification: https://emiote.com/openapi.json - Pricing Sheet (Markdown): https://emiote.com/pricing.md - XML Sitemap: https://emiote.com/sitemap-index.xml - Robots: https://emiote.com/robots.txt ## Content Negotiation Send `Accept: text/markdown` on any public URL (`/`, `/pricing/`, `/services/`, `/products/`, `/work/`, `/reframe/`, `/reframehub/`, `/journal/`, `/about/`, `/contact/`, `/mcp/`) to receive a markdown representation of that specific route. --- # About Emiote Emiote is a **Product & Engineering Studio** founded by Dhanji Bhagat. Positioning: - We design and build software for founders and teams — AI-native. - We are a studio that ships in-house products and partners with clients on engineering. - We are **not** a software agency selling billable hours, not an AI hype shop, and not a freelance portfolio. - Business model: Two equal pillars. (1) In-house products (such as Ankik), which provide real-world testing grounds and standards. (2) Product partner work (MVPs, stack reviews, AI integrations, modernization). Founder: Dhanji Bhagat (Founder & Principal Engineer) Email: dhanji@emiote.com Booking: https://cal.com/dhanjib/15min GitHub: https://github.com/dhanji4U LinkedIn: https://www.linkedin.com/in/dhanji-bhagat-609804245/ X: https://x.com/dhanji_bhagat --- # Commercial Offers & Pricing Canonical offer sheet: https://emiote.com/pricing.md ### 1. Reframe Stack Review ($199) - Fixed price: **$199 USD** (one-time) - Turnaround: **3 business days** - Deliverable: Comprehensive software & SaaS audit classifying every tool in your stack into **Keep / Configure / Replace / Build**. - Includes: Cost reduction map, open-source alternatives analysis, self-hosting feasibility, and an actionable migration sequence. - Guarantee: 100% money-back if we don't identify at least $199 in annual savings or operational waste. ### 2. Build Sprint (From $1,200) - **Core MVP Sprint ($1,200 - $3,500):** 14-day delivery of a core working workflow deployed to production with real database, auth, and payments. - **Full Product Sprint ($3,500 - $8,500):** 28-day delivery of a complete multi-role web/mobile application with automated CI/CD and production monitoring. - Model: Fixed-scope or weekly partner sprints. Direct access to principal engineers with zero junior agency bloat. --- # In-House Products ### Ankik - URL: https://emiote.com/products/ankik/ - Category: Accounting & Business Operations (SMEs & Service Businesses) - Problem: Financial operations in service businesses and SMEs are fragmented across spreadsheets, disconnected invoicing tools, and chat threads. Answering simple profitability or ledger questions takes hours. - Solution: Desktop-first accounting and business management workspace. Manages parties, quotations, invoices, purchases, expenses, and strict double-entry ledgers with atomic transactional integrity and project profitability. - Origin: Built to solve fragmented financial operations with strict double-entry accounting guarantees, dynamic quotation-to-invoice workflows, and multi-tenant business isolation. --- # Case Studies & Selected Work ### 1. Book-Hotels-B2B - Category: Travel & Hospitality Tech - Problem: B2B travel agents needed sub-second hotel room search, bulk rate negotiations, and instant inventory booking across multiple global bedbanks. - Approach: Built a high-performance booking engine with distributed caching, optimized search aggregation, and automated voucher generation. - Outcome: 80% reduction in query latency, handling 50k+ daily search requests reliably. ### 2. Ankik Accounting Engine - Category: Financial Software - Problem: Building a bulletproof, transactionally consistent financial core for SMEs & Startups Business without enterprise ERP complexity. - Approach: Strict double-entry ledger engine powered by atomic Prisma transactions, high-precision GST tax math via big.js, PASETO authentication, and multi-tenant isolation. - Outcome: Zero balance discrepancies across 10,000+ reconciled ledger entries with real-time auditability. ### 3. Retainix Multi-Branch Engine - Category: Customer Loyalty - Problem: Preventing double-redemption race conditions across physical store counters with intermittent internet connections. - Approach: Idempotent redemption tokens, atomic PostgreSQL transactions, and lightweight mobile-friendly staff terminals. - Outcome: Deployed across active retail counters with sub-100ms scan-to-redeem verification. ### 4. Sainath Auto Consultancy - Category: Automotive Operations - Problem: Vehicle documentation, RTO filings, and commission tracking managed in physical registers. - Approach: Digitized inventory and client lifecycle management platform with automated document expiration reminders. - Outcome: Eliminated missed compliance deadlines and cut customer inquiry turnaround by 75%. --- # ReframeHub Field Notes & Architecture Reviews ## ReframeHub: Agentic Inbox - Path: https://emiote.com/reframehub/agentic-inbox/ - Category: Email - Description: Cloudflare Agentic Inbox is an Apache-2.0 self-hosted email client combining Cloudflare Workers, Durable Objects, R2, Email Service, and Workers AI. - Pricing / Model: open-source (Self-host: Potentially $0 within applicable Cloudflare free allocations; paid usage and service limits apply, Cloud: Google Workspace Starter: $7/user/month; Zoho Mail Lite: $1/user/month billed annually) - Snapshot Date: 2026-09-01 > **Agentic Inbox** is an Apache-2.0, self-hosted email client from Cloudflare that runs on Cloudflare Workers. It routes inbound mail through Email Routing, stores each mailbox in a Durable Object with SQLite and attachments in R2, and adds an AI agent powered by the Agents SDK and Workers AI for inbox search, drafting, and email actions. --- ## 1. Scope and Currency This is an **architecture evaluation**, not a deployment diary. We reviewed the public repository, package manifest, setup instructions, security policy, current Cloudflare Workers/Workers AI/Durable Objects documentation, and current managed-email pricing. We have not operated Agentic Inbox in production, so this note does not claim production latency, throughput, uptime, memory consumption, or operational scale. The repository is an active main branch rather than a versioned release: GitHub currently shows no published releases. The architecture and feature claims below describe the public repository. They should not be interpreted as proof that Cloudflare's own production email systems use this exact deployment topology. Contrast with our notes on ([self-hosted Postgres](/reframehub/self-hosted-postgres/)): those are lived ops. This page is “what the design implies.” Background on Cloudflare's Email Service + Agents path: [Email for Agents](https://blog.cloudflare.com/email-for-agents/). --- ## 2. What It Is Agentic Inbox is closer to a complete email application than an AI demo. The repository provides: - **Sending and receiving email** via native edge bindings - **Rich-text composition** powered by TipTap - **Reply and forward threading** - **Folders and message organization** - **Full-text search** - **R2 attachment handling** - **Per-mailbox Durable Objects** with embedded SQLite state - **An AI side panel** with persistent agent chat history - **Automatic draft generation** triggered by incoming mail - **Model Context Protocol (MCP) access** at `/mcp` The repository currently describes **nine email-agent tools** for reading, searching, drafting, and sending mail, while outbound sending remains strictly **confirmation-gated**. --- ## 3. What It Replaces — And What It Doesn't The obvious alternatives are managed email providers such as **Google Workspace**, **Zoho Mail**, and **Fastmail**. But the architectural comparison is more important than the feature checklist. A managed provider gives you: - Mail infrastructure and deliverability operations - Administration, user provisioning, and domain management - Backups and point-in-time recovery processes - Dedicated operational support - Organization-wide identity and compliance policies - A mature security, antispam, and abuse-control surface Agentic Inbox instead gives you an application you deploy into your Cloudflare account. That makes it interesting when control over the application architecture matters more than outsourcing the whole mail stack. It is less compelling when email is simply infrastructure your team wants to stop thinking about. --- ## 4. Architecture & Tech Stack Review Agentic Inbox executes entirely within Cloudflare's edge platform. Incoming emails enter through Cloudflare Email Routing, route to a Hono-based Worker, and dispatch to dedicated per-mailbox Durable Objects. ![Cloudflare Agentic Inbox Architecture Diagram](/images/reframehub/agentic-inbox/architecture.svg) ### Stack Implementation | Layer | Implementation | Notes | | :--- | :--- | :--- | | **Frontend** | React 19, React Router v7, Tailwind CSS, Zustand, TipTap, `@cloudflare/kumo` | Modern SPA with rich-text composer and side-panel agent | | **Application Runtime** | Cloudflare Workers | Serverless edge execution | | **HTTP Framework** | Hono | Lightweight edge routing and API handling | | **Mailbox State** | Durable Objects + SQLite | Stateful boundary with local relational queries | | **Attachment Storage** | Cloudflare R2 | S3-compatible zero-egress object storage | | **Email Ingress** | Cloudflare Email Routing | Inbound catch-all routing to Worker | | **Email Egress** | Cloudflare Email Service / `send_email` | Edge binding for outbound email delivery | | **Agent Runtime** | Cloudflare Agents SDK / `AIChatAgent` | Stateful agent execution and WebSocket streaming | | **Model Layer** | Workers AI (`@cf/moonshotai/kimi-k2.5`) | Serverless inference on Cloudflare GPUs | | **AI Interface** | AI SDK v6 | Unified tool calling and streaming primitives | | **Authentication** | Cloudflare Access JWT | Zero Trust boundary protecting web UI and APIs | | **Agent Interface** | Web UI + MCP at `/mcp` | External agent integration for Claude Code, Cursor, etc. | The package manifest independently confirms the major application dependencies and the Cloudflare product bindings. ``` ┌─────────────────────┐ │ Browser │ │ React email client │ │ + Agent panel │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Hono Worker │ │ API + application │ └──────┬───────┬──────┘ │ │ mailbox │ │ /agents/* ▼ ▼ ┌──────────────┐ ┌────────────────┐ │ Mailbox DO │ │ EmailAgent DO │ │ SQLite │ │ AIChatAgent │ │ R2 refs │ │ 9 mail tools │ └──────────────┘ └───────┬────────┘ │ ▼ ┌─────────────────┐ │ Workers AI │ └─────────────────┘ Inbound mail: Cloudflare Email Routing → Worker → Mailbox Durable Object Outbound mail: Email Service / send_email binding ``` ### Why Durable Objects Make Sense Here A mailbox is naturally stateful. Email threads, folders, messages, drafts, and agent state all benefit from having a stable application object representing the mailbox. Durable Objects provide that stateful boundary while SQLite provides relational storage inside the object. The repository therefore avoids building a conventional: ```text Workers ──► PostgreSQL ──► Object Storage ``` stack just to represent individual mailboxes. That is one of the project's strongest architectural choices: storage is co-located with the mailbox actor, eliminating connection pooling overhead and external database management. ### Where the Boundary Stops: Storage Isolation vs. Authorization Isolation The important caveat is that **data isolation and authorization are not the same thing**. The repository isolates each mailbox in its own Durable Object, but also explicitly notes that any user passing the shared Cloudflare Access policy can access all mailboxes. The MCP endpoint uses the same trust boundary. So the architecture is better described as: > **Per-mailbox storage isolation behind a shared application authorization boundary** rather than: > **Multi-tenant mailbox authorization** That distinction matters if multiple independent users or external customers will share one deployment. ### AI Agent Architecture The agent is not simply a chatbot sitting beside the inbox. The repository connects an `AIChatAgent` to email-specific tools that can read, search, draft, and send mail. New inbound mail can also trigger draft generation. The final send remains explicitly confirmed by the user. Cloudflare's current Agents platform separately documents email as a first-class agent communication channel, including inbound routing through Email Service and outbound mail through a `send_email` binding. That makes Agentic Inbox useful as a reference implementation for a broader pattern: ```text Inbound Email ──► Stateful Agent ──► Tools ──► Human Approval Gate ──► Outbound Delivery ``` The approval boundary is particularly important. Draft generation can be automated; sending an email is treated as a consequential action requiring confirmation. ### Model Context Protocol (MCP) Interface The application exposes an MCP server at `/mcp`. This is more significant than simply having an HTTP API. The repository states that external AI clients such as **Claude Code** and **Cursor** can operate on mailboxes through MCP, with `mailboxId` identifying the target mailbox. However, the same Access policy protects the endpoint, and the repository explicitly states there is no per-mailbox authorization. That means MCP expands the application's control surface without changing its authorization model. For a single-user deployment, that is a powerful developer feature. For a multi-user deployment, it is a security boundary that should be reviewed before exposing the server to external agents. --- ## 5. Visual Tour & Interface Workflows The repository includes an official application screenshot, showcasing the full email client with the AI agent side panel. ![Agentic Inbox Application Interface](/images/reframehub/agentic-inbox/app.png) *The Agentic Inbox client: tip-tap email editor, thread view, folder hierarchy, and streaming AI agent side panel.* ### The Human-in-the-Loop Execution Lifecycle The most useful workflow to understand is not merely the inbox UI, but how autonomous drafting interacts with explicit human confirmation gates: ![Agentic Inbox Human-in-the-Loop Lifecycle Diagram](/images/reframehub/agentic-inbox/workflow.svg) 1. **Inbound Ingestion**: Email Routing catches incoming mail on your custom domain and routes it to the Worker. 2. **Mailbox Persistence**: The message is stored in the specific mailbox Durable Object (relational metadata in SQLite, attachments in R2). 3. **Agent Inspection**: `EmailAgent` DO reads the conversation context and searches related threads using its 9 built-in tools. 4. **Draft Synthesis**: Workers AI generates a proposed reply tailored to the thread context. 5. **Human Review Gate**: The draft is presented in the composer. Outbound sending remains locked until the user explicitly reviews and approves. 6. **Outbound Dispatch**: Upon confirmation, the message is dispatched via Cloudflare Email Service (`send_email` binding). --- ## 6. Total Cost of Ownership (TCO) The important correction to the usual “open source = free” argument is that Agentic Inbox has several Cloudflare services in its operating path. ### Infrastructure Economics Comparison | Dimension | Agentic Inbox (Self-Hosted on Cloudflare) | Managed Email (Google Workspace / Zoho Mail) | | :--- | :--- | :--- | | **Application License** | Apache-2.0 / $0 | Included in monthly subscription | | **Worker Runtime** | Free allocation available; Paid starts at $5/month | Included ($0 extra) | | **Durable Objects** | Free allocation available; billed on paid usage | Included ($0 extra) | | **R2 Storage** | 10 GB-month free; $0.015/GB-mo thereafter | Included (pooled 30 GB+ per user) | | **Workers AI** | 10,000 neurons/day free; paid usage thereafter | Provider-dependent (Gemini add-ons extra) | | **Email Infrastructure** | Cloudflare Email Routing + Email Service | Fully managed infrastructure & deliverability | | **Backups & Restore** | Your responsibility | Provider-managed automated snapshots | | **Monitoring & Uptime** | Your responsibility (Cloudflare dashboard) | Provider-managed 99.9% uptime SLA | | **Authorization Design** | Your responsibility beyond shared Access policy | Provider-managed granular IAM | | **Operational Support** | Community / Your engineering time | Vendor support contracts | | **Annualized Cost** | Workload-dependent ($0–$60+/year) | $60–$420/year (for 5 users) | ### Free Tier Limits & Usage Boundaries - **Workers**: 100,000 requests/day on the Free plan. Workers Paid starts at $5/month. - **Workers AI**: 10,000 neurons/day free. High-volume automatic drafting on every inbound message will quickly cross free neuron limits into paid inference. - **R2 Storage**: 10 GB-month standard storage, 1M Class A operations, and 10M Class B operations per month included for free. - **Durable Objects**: Separate compute, storage, and request limits apply. ### Managed Subscription Comparison - **Google Workspace Starter**: Listed at $7/user/month billed annually. - **Zoho Mail Lite**: Listed at $1/user/month billed annually. For a 5-user team, the annual subscription arithmetic is: - **Google Workspace**: \$7/user/mo × 5 users × 12 months = **\$420/year** - **Zoho Mail Lite**: \$1/user/mo × 5 users × 12 months = **\$60/year** Those figures are subscription comparisons, not equivalent TCO measurements. Managed providers bundle substantially more operational responsibility (antispam reputation, compliance retention, user lifecycle management) into the price tag. For Agentic Inbox, an honest annual cost cannot be reduced to one static number without knowing email volume, AI drafting frequency, attachment sizes, and Cloudflare plan tiers. --- ## 7. The Good 1. **Stateful architecture fits the domain**: A mailbox maps naturally to a Durable Object actor. SQLite provides local relational state without requiring an external database cluster. 2. **It is a real email application**: This is not just a chat window attached to an inbox. The repository includes rich composition, threading, folders, search, and attachments. 3. **Human approval is explicit**: The agent can inspect and draft replies, but sending is strictly confirmation-gated. 4. **The stack is internally coherent**: Workers, Durable Objects, R2, Email Routing, Email Service, Agents SDK, and Workers AI all belong to the same Cloudflare platform, eliminating multiple external vendor integrations. 5. **An excellent architecture reference**: Even if you never deploy the application, the repository demonstrates a pristine blueprint for building stateful, email-driven agents on Workers. --- ## 8. The Bad — What to Know Before Adopting 1. **The shared Access policy is the real authorization boundary**: This is the biggest architectural caveat. Per-mailbox Durable Objects do not give you per-user authorization. Anyone who passes the Access policy can reach all mailboxes and invoke MCP on any `mailboxId`. Fine for a solo operator; unacceptable for multi-tenant teams without custom auth. 2. **“Self-hosted” still means Cloudflare-hosted**: You control the deployment in your Cloudflare account, but the codebase depends entirely on proprietary Cloudflare primitives (Workers, DO, R2, Email Routing, Email Service, Access, Workers AI). It cannot run on a generic Linux VPS. 3. **Free tier is a starting point, not a capacity guarantee**: Automatic drafting on every incoming email can exhaust the 10,000 neurons/day Workers AI allowance before storage even becomes a consideration. 4. **Deployment is not one click**: The repository explicitly warns that the Cloudflare deploy button is only part of the setup. You still must manually configure Access, DNS Email Routing rules, Email Service bindings, and mailboxes. 5. **No evidence for production-grade mail operations**: The public repository does not provide enterprise mail retention, compliance e-discovery, point-in-time recovery, formal deliverability SLAs, or organization-wide audit trails. --- ## 9. Security Review The application maintains a published security policy and routes vulnerability reports through Cloudflare's disclosure process. No public security advisories were reported at review time. The primary architectural security consideration is **authorization scope**: ``` Single-User Solo Model (Works as Designed): Internet ──► Cloudflare Access JWT ──► Agentic Inbox ──► Any Mailbox DO Multi-Tenant Team Model (Requires Custom Auth): Internet ──► Cloudflare Access ──► Identity Layer ──► Tenant Auth ──► Mailbox Auth ──► Mailbox DO ``` The MCP endpoint at `/mcp` requires the same scrutiny because external coding agents can query and manipulate mailbox state across all IDs under the shared Access token. --- ## 10. Licensing The repository is licensed under **Apache-2.0**, a permissive open-source license suitable for modification and redistribution subject to its terms. The open-source code license does not alter the commercial terms or usage fees of external Cloudflare services, AI model checkpoints, or upstream npm dependencies. --- ## 11. Quickstart & Deployment Guide ### Local Development ```bash # 1. Clone the repository git clone https://github.com/cloudflare/agentic-inbox.git cd agentic-inbox # 2. Install dependencies npm install # 3. Configure local environment # Set your domain in wrangler.jsonc and ensure R2 bucket 'agentic-inbox' exists cp .dev.vars.example .dev.vars # 4. Start local development server npm run dev ``` ### Production Deployment Sequence 1. **Deploy the Worker**: Run `npm run deploy` or use the Deploy to Cloudflare button. 2. **Configure Cloudflare Access**: Enable one-click Access for Workers; obtain the `POLICY_AUD` (Audience tag) and `TEAM_DOMAIN` (Zero Trust team URL) from the Access modal. 3. **Set Worker Secrets**: Set `POLICY_AUD` and `TEAM_DOMAIN` as Worker environment variables. 4. **Configure Email Routing**: In Cloudflare dashboard, configure an Email Routing catch-all rule pointing to your deployed Worker. 5. **Enable Email Service**: Enable the `send_email` binding for outbound egress. 6. **Create a Mailbox**: Open the web application and register your email address on the verified domain. ### Common Setup Troubleshooting | Symptom | Root Cause / Resolution | | :--- | :--- | | `Invalid or expired Access token` | Mismatched `POLICY_AUD` or `TEAM_DOMAIN`. Toggle Access off and on in Cloudflare dashboard to refresh modal values, then update Worker secrets. | | `Cloudflare Access must be configured in production` | Access is required outside local development to prevent public exposure. Ensure Zero Trust Access is enabled. | --- ## 12. When to Use Agentic Inbox ### Good Fit - You already operate on Cloudflare (domain, DNS, Workers, Zero Trust Access). - You want an AI-assisted personal inbox running directly in your own account. - A single Access trust boundary matches your security model (solo founder or tight internal team). - Your email and drafting volume fits within applicable Cloudflare free or low-tier allocations. - You want an open reference architecture for building stateful Workers + DO + Agents applications. ### Bad Fit - You require strict per-mailbox user authorization or multi-tenant customer isolation. - Your organization requires managed email SLAs, enterprise e-discovery, or compliance retention policies. - You require all email data to reside on independent hardware or non-Cloudflare VPS infrastructure. - Nobody on your team is comfortable operating Wrangler, Cloudflare bindings, and DNS routing. --- ## 13. ReframeHub Insight ### The Interesting Part Is Not the AI The defining architectural decision in Agentic Inbox is the **state boundary**. Email is inherently stateful. Each mailbox has a distinct lifecycle, identity, and relational boundary. By mapping each mailbox directly to a Durable Object, Cloudflare achieves: ```text Mailbox Identity ──► Durable Object ──► SQLite State + R2 Attachments + Agent Context ``` This creates a self-contained actor model without the operational drag of connection pools, database migrations, or separate cache layers. However, it highlights an essential engineering rule: > **Storage isolation does not automatically equal authorization isolation.** Agentic Inbox cleanly isolates data across Durable Objects, but places all objects behind a single Access policy. That is an elegant shortcut for a personal tool; it is a critical vulnerability if imported naively into a multi-tenant SaaS. --- ## 14. What I Would Change **Principal Engineering Critique**: If evolving this architecture into a production multi-user platform, I would preserve the Durable Object mailbox model while introducing an explicit application authorization layer before both the HTTP and MCP endpoints: - Granular mailbox ownership and role-based access control (RBAC) - Scoped MCP permissions per API token rather than open `mailboxId` routing - Explicit audit logging for all agent tool calls and send events - Point-in-time SQLite backup export to external cold storage - Configurable auto-draft triggers with budget rate-limiters per mailbox The underlying edge topology does not need to change; the identity and operational boundary does. --- ## 15. Our Recommendation Apply the **Keep / Configure / Replace / Build** lens: - **Keep**: Keep Agentic Inbox as a premier Cloudflare-native architectural reference. The synergy of Workers, Durable Objects, SQLite, R2, Email Service, and Agents SDK is instructive. - **Configure**: Configure it for personal email or tightly controlled single-operator setups where a single Access policy is acceptable. - **Replace**: Replace with managed email (Google Workspace / Zoho Mail) when email is an operational dependency rather than your core product. - **Build**: Build on this pattern if email workflows and stateful agents are central to your SaaS product. Need help evaluating managed mail vs. a self-hosted Cloudflare edge architecture? [Book a Reframe audit for email stack](/reframe/?from=reframehub&tool=agentic-inbox) ($199 USD). For a parallel evaluation of self-hosted database infrastructure, read our [Supabase](/reframehub/supabase/) and [Self-Hosted Postgres](/reframehub/self-hosted-postgres/) field notes. --- ## 16. Primary Sources - [Cloudflare Agentic Inbox Repository](https://github.com/cloudflare/agentic-inbox) (GitHub) - [Cloudflare Agents SDK Documentation](https://developers.cloudflare.com/agents/) - [Cloudflare Email Service & Email Routing Documentation](https://developers.cloudflare.com/email-routing/) - [Cloudflare Workers AI Documentation & Pricing](https://developers.cloudflare.com/workers-ai/) - [Cloudflare Durable Objects Pricing & Storage Limits](https://developers.cloudflare.com/durable-objects/) - [Google Workspace Official Pricing](https://workspace.google.com/pricing.html) - [Zoho Mail Official Pricing](https://www.zoho.com/mail/zohomail-pricing.html) ## ReframeHub: Buzz - Path: https://emiote.com/reframehub/buzz/ - Category: Automation - Description: Block's self-hostable human+agent workspace on a Nostr relay—vs Slack/Discord bot glue; not a production diary. - Pricing / Model: open-source (Self-host: VM + Postgres + Redis + object storage (Compose stack); ops owned by you, Cloud: Slack Pro from ~$8.75/user/mo; Discord Nitro/server tooling varies; bot/CI glue extra) - Snapshot Date: 2026-08-10 ## Scope and currency This is an **architecture evaluation**, not a deployment diary. In August 2026 we reviewed the official [Buzz README](https://github.com/block/buzz/blob/main/README.md) and [ARCHITECTURE.md](https://github.com/block/buzz/blob/main/ARCHITECTURE.md)—positioning, screenshots, maturity table, crate map, and known limitations. **We have not run Buzz in production.** Release binaries, Railway one-click, and Compose requirements change; confirm current docs and your team's ops capacity before planning a migration. Editorial review: `2026-08-10`. Contrast with our Ankik notes ([self-hosted Postgres](/reframehub/self-hosted-postgres/)): those are lived ops. This page is “what the design implies.” Same posture as [Agentic Inbox](/reframehub/agentic-inbox/)—repo-backed architecture review, not a usage claim. ## What it is Buzz is an open-source (**Apache 2.0**) self-hostable workspace from [Block, Inc.](https://block.xyz) (GitHub repository: [github.com/block/buzz](https://github.com/block/buzz)) where **humans and AI agents share the same rooms**. Under the hood it is a **Nostr relay**: every message, reaction, workflow step, review approval, and git event is a **signed event** in one log—same identity model and audit trail whether the author is a person or a process. A Buzz **community** is the workspace selected by URL. Single-relay self-host: one relay URL ≈ one community. Hosted multi-tenant operators can map many domains, but tenant-visible state stays community-local. In product terms it aims at the sprawl teams fake with chat + forge + bots + CI dashboards + release tools + search: one substrate instead of seven tabs that do not know about each other. Agents are members with their own keys and channel membership—not haunted cron jobs in a side panel. ![A Buzz project channel where people and an agent coordinate on a release plan](/images/reframehub/buzz/channel-thread.webp) *People and agents building together in the same room (official README screenshot).* ### A look inside (official screenshots) ![People and agents collaborating in a Buzz engineering channel](/images/reframehub/buzz/channel-agents.webp) **Agents are members, not bots.** Add an agent to a channel the same way you add a person. ![The Add a channel dialog with search, filters, and channels to join or create](/images/reframehub/buzz/create-channel.webp) **Spin up a room in seconds.** Name it, describe it, make it private. ![A video playing in Buzz with frame-anchored comments in a side panel](/images/reframehub/buzz/media-comments.webp) **Media you can talk about.** Leave comments pinned to specific frames. ### Architecture (official shape) ``` Clients: Human desktop (Tauri + React) · AI agents (Goose, Codex, Claude Code via buzz-acp) · buzz-cli │ │ │ └──────────── WebSocket / REST ──────┴──────────────────────────────────────┘ ▼ buzz-relay (Axum) NIP-01 · NIP-42 auth · channel/DM/media/workflow/git · audit │ │ │ Postgres Redis S3 / MinIO (events + FTS) (pub/sub) (Blossom media) ``` Single source of truth: the **relay**. Clients do not gossip peer-to-peer; they connect to one relay that verifies signatures, persists events, fans out to subscribers, indexes search, and triggers automation. ### Stack (from repo) | Layer | Choices | | --- | --- | | Protocol | Nostr NIP-01 wire format; Schnorr-signed events; kind-based dispatch | | Relay | Rust workspace (`buzz-relay` on Axum); Postgres, Redis, S3/MinIO | | Desktop | Tauri + React | | Agents | `buzz-cli` (JSON in / JSON out) · `buzz-acp` (ACP harness for Goose / Codex / Claude Code) | | Automation | YAML workflows: message / reaction / schedule / webhook triggers | | Git | NIP-34 patches, repo announcements, status; git hosting backend | | Mobile | Flutter clients listed as in progress (not “works today”) | ### Features that matter for a stack decision - **One event log for chat, agents, workflows, and git** — search and audit over the same substrate - **Agents as first-class members** — own keypairs, channel membership, and audit trail (scoped like teammates) - **`buzz-cli` agent surface** — designed for LLM tool calls (JSON in / out), not only human chat UX - **YAML workflows** — message, reaction, schedule, webhook; approval gates exist in infra but are still being wired end-to-end (upstream maturity table) - **Self-host posture** — Docker Compose / production Compose under `deploy/compose/`; packaged desktop builds; optional Railway relay deploy - **Honest maturity table** — README separates ✅ works today vs 🚧 being wired vs 💭 opinions pending code ### Maturity snapshot (upstream README, review window) | ✅ Works today | 🚧 Being wired up | 💭 Strong opinions, pending code | | --- | --- | --- | | Relay, channels, threads, DMs, canvases, media, search, audit log | Mobile (iOS + Android, Flutter) | Web-of-trust reputation across relays | | Desktop app (Tauri + React) | Workflow approval gates (infra exists, glue drying) | Push notifications | | `buzz-cli` + ACP harness | Huddle lifecycle events | Culture features | | YAML workflows (message / reaction / schedule / webhook) | | | | Git events (NIP-34) + git hosting backend | | | ARCHITECTURE.md also lists concrete gaps (e.g. rate-limiter trait not enforced in production path; some workflow actions / approval resume not fully wired). Treat 💭 and “known limitations” as non-negotiable reading before compliance or migration planning. ## Cost breakdown | Path | Reference cost | What you get | | --- | --- | --- | | Buzz self-host | VM + Postgres + Redis + object storage; **your** ops time | Full relay, desktop clients, agent CLI/ACP surface; community-local state you own | | Railway one-click relay (upstream path) | Hosting bill on Railway + your config | Relay without racking a VPS yourself; still not “managed Slack” | | Slack (managed chat) | Pro from ~$8.75/user/mo (public list pricing; confirm current) | Managed chat, ecosystem, zero relay ops—agents usually as bots with separate identity models | | Discord + bots | Free tier / Nitro / bot hosting | Lightweight communities; weak product-engineering audit story | There is **no published SaaS seat price for “Buzz Cloud”** in the OSS README we reviewed: the product is **self-host / operator-run**. Invoice savings vs Slack only matter if someone owns upgrades, backups, identity, and incidents—same total-cost lens as [open-source evaluation](/reframehub/open-source-evaluation/). ## The Good - **Humans and agents in one room** — not a chat product with a bot API bolted on; agents sign events like people - **One log, one search, one audit story** — messages, patches, workflow steps, and approvals share protocol shape - **Serious engineering surface** — Rust monorepo, NIP-42 auth, hash-chain audit, Postgres FTS, explicit crate boundaries - **Agent-first CLI** — `buzz-cli` JSON I/O is a clearer integration path for automation than scraping a web UI - **Honest docs** — maturity columns and ARCHITECTURE “known limitations” reduce surprise vs hype-only AI workspaces - **Credible Block OSS** — Apache 2.0, governance/security docs, vision papers for sovereign / forge / agents ## The Bad — what to know before adopting 1. **This is a platform, not a plugin.** You are adopting a relay + desktop + (optional) agents + Postgres/Redis/object storage. Ops surface is closer to self-hosting a product than flipping a Slack app switch. 2. **Not finished—and they say so.** Mobile incomplete; workflow approval gates and some actions still drying; push / multi-relay reputation are future. Do not plan compliance programs on the 💭 column. 3. **Protocol lock-in is real.** Nostr kinds, keypairs, and Buzz custom ranges are powerful; they are not “export to Slack JSON and forget.” Migration risk is cultural and technical. 4. **Identity model is cryptographic, not Google SSO-first.** NIP-42 / Schnorr keys and channel membership—great for agent parity; different onboarding than Workspace or Microsoft 365. 5. **Desktop-first today.** Packaged builds for macOS / Linux / Windows; Windows agent shell expects Git Bash. Browser-only teams or pure mobile-first orgs will feel the gap until Flutter clients mature. 6. **Rate limiting and some automation paths are incomplete** per ARCHITECTURE.md at review time—design targets exist without full production enforcement. ## When to use / When to skip **Use Buzz if:** - You want **humans and coding agents in the same channels** with shared audit and search - Self-hosting a Rust relay + Compose stack is acceptable (or Railway/operator path fits) - You care about **signed event history** for decisions (incident memory, branch-as-room, release workflows) - Your team can live desktop-first while mobile catches up - You are evaluating **agent workspace architecture** even if you never migrate off Slack (strong reference) **Skip if:** - You need managed chat SLAs, enterprise SSO polish, and zero infra ownership tomorrow—stay on Slack/Teams - Nobody will run Postgres backups, Redis, object storage, and relay upgrades - Mobile-first field teams or non-technical orgs need polished apps day one - You only need a thin bot in existing Slack—Buzz is a workspace replacement thesis, not a `/remind` clone - Compliance depends on features still marked pending or unwired ## Prerequisites (official path) - **Try the app:** packaged builds from [GitHub Releases](https://github.com/block/buzz/releases/latest) (macOS Apple Silicon / Intel, Linux AppImage/deb, Windows x64—unsigned Windows may hit SmartScreen) - **Self-host / dev:** Docker + [Hermit](https://cashapp.github.io/hermit/) (or Rust 1.88+, Node 24+, pnpm 10+, `just`) - **Agents:** `BUZZ_PRIVATE_KEY` + `buzz-cli`; ACP for Goose / Codex / Claude Code - **Windows agents:** Git for Windows (Git Bash) or `BUZZ_SHELL` pointing at a bash-compatible shell - **Production single-node:** `deploy/compose/` (Postgres, Redis, MinIO, optional Caddy/TLS)—root `docker-compose.yml` is day-to-day dev only ## Setup checklist (official path) 1. **Clone and toolchain** — `git clone https://github.com/block/buzz.git && cd buzz` then `. ./bin/activate-hermit` 2. **Bootstrap** — `just setup && just build` (copies `.env.example` if needed, Hermit tools, Docker services + migrations) 3. **Daily dev** — `just dev` (relay + desktop); relay default `ws://localhost:3000` 4. **Split terminals (optional)** — `just relay` + `just desktop-dev` 5. **Agents** — set keys; use `buzz-cli` / ACP harness rather than scraping the UI 6. **Hosted relay (optional)** — To run a relay for your team without managing servers, you can deploy one to Railway in a click: [![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/buzz-relay-block) See also the [Block engineering write-up](https://engineering.block.xyz/blog/run-your-own-buzz-relay). ## Our recommendation Apply the same **Keep / Configure / Replace / Build** lens as every ReframeHub note (start with the [Stack Decision Checklist](/reframehub/stack-decision-checklist/) if you want a self-serve pass). - **As a tool to run today:** credible for engineering teams who already self-host serious infra, want agent-as-member semantics, and accept an evolving surface (desktop + relay first). Not a casual Slack replacement for the whole company next Monday. - **As a reference architecture:** one of the strongest open blueprints we have seen for **signed, searchable human+agent collaboration** on a single event log—worth reading even if you Keep Slack and only steal ideas (channel-as-branch, workflow events, agent keypairs). - **If you need managed chat with zero relay ops:** Keep Slack/Teams/Discord; add agents as integrations carefully. We would not push a full Buzz cutover solely to “have AI in chat.” Need help choosing managed chat + bots vs a self-hosted agent workspace? [Book a Reframe audit for Buzz / collab stack](/reframe/?from=reframehub&tool=buzz) ($199). For a lighter platform self-host lesson on Cloudflare, see [Agentic Inbox](/reframehub/agentic-inbox/); for the general self-host checklist, see [open-source evaluation](/reframehub/open-source-evaluation/). ## ReframeHub: Diagram Design - Path: https://emiote.com/reframehub/diagram-design/ - Category: AI Design and Prototyping - Description: Open-source editorial diagram skill for AI code agents—39 types, HTML+SVG, brand onboarding, zero-JS static output; vs Mermaid/Eraser. - Pricing / Model: open-source (Self-host: $0/mo local skill / agent plugin; runs in-context with your model keys, Cloud: Eraser / Miro from $8–$16/user/mo; Lucidchart from $7.95/mo; Figma Pro from $12/editor/mo) - Snapshot Date: 2026-08-26 **Definition:** Diagram Design is an open-source (MIT) agent skill for Claude Code, Codex, Factory Droid, and Pi that generates publication-grade HTML+SVG diagrams across 39 layout grammars without build steps, external JavaScript, or Mermaid slop. It reduces diagramming SaaS spend to $0/mo, but requires an AI coding agent host and natural-language prompt direction. Choose managed visual SaaS (Miro/Eraser) if you need real-time multi-cursor whiteboarding with non-technical teams. ## Scope and currency This is an **architecture evaluation**, not a deployment diary. In August 2026 we reviewed the official [Diagram Design repository](https://github.com/cathrynlavery/diagram-design) (version 2.5.10+, MIT license)—39 layout grammars, 7 semantic behavior patterns, brand onboarding protocol, import extractors, and automated Chromium layout linter. **We evaluate this as an in-context skill and design system reference.** Model token consumption, plugin host discovery paths, and CLI syntax evolve; verify current repository documentation before adopting. Editorial review: `2026-08-26`. Contrast with our Ankik notes ([self-hosted Postgres](/reframehub/self-hosted-postgres/)): those are lived server ops. This page is “what the skill design implies.” Same posture as [Open Design](/reframehub/open-design/) and [Buzz](/reframehub/buzz/)—repo-backed architecture evaluation, not a usage claim. ## What it is Diagram Design is an open-source (**MIT**) agent skill created by [Cathryn Lavery](https://github.com/cathrynlavery) that equips AI coding agents (Claude Code, Codex, Factory Droid, Pi, Hermes Agent, Antigravity) to produce **editorial-grade, brand-matched architecture and system diagrams**. Instead of generating generic rounded boxes with rainbow gradients (what the author terms *"Mermaid slop"*), Diagram Design enforces a disciplined editorial graphic system: - **39 visual types** spanning engineering, product, and strategy (Architecture, Sequence, Flowchart, State Machine, Entity-Relationship, Timeline, Swimlane, Quadrant Matrix, Sankey, Fishbone, Wardley Map, Kanban, User Journey, Deployment, Dependency Graph, UML Class, Story Map, DB Schema, and more). - **3 static variants per type**: Minimal Light, Minimal Dark, and Full-Editorial (with executive summary callout cards). - **Self-contained HTML5 + inline SVG**: Every diagram is an independent, single-file `.html` document that opens directly in any browser—zero build step, zero JavaScript runtime, and zero external image dependencies. - **Progressive disclosure architecture**: To protect the agent's context window, the root `SKILL.md` routes intent and only loads the single relevant layout reference (e.g. `type-sequence.md` or `type-architecture.md`). - **Semantic system patterns**: Behavior (queues, bottlenecks, policy traces, paved roads, compensating controls) is separated from geometry, preventing unnecessary type explosion. - **60-second brand onboarding**: The agent fetches your production website, extracts the dominant palette and font stack, maps them to semantic roles (`paper`, `ink`, `muted`, `accent`, `title`), performs automated **WCAG AA contrast validation**, and writes your brand contract into `references/style-guide.md`. - **draw.io and Mermaid redraw engine**: Parses `.drawio`, `.drawio.xml`, `.drawio.png`, `.drawio.svg`, `.mmd`, and fenced Markdown blocks, emitting clean editorial HTML at chosen detail levels (`faithful`, `balanced`, `simplified`) and audience framings (`engineer`, `mixed`, `executive`), complete with a transparency ledger of collapsed or dropped nodes. ### A look inside (official diagram renders) ![Architecture Diagram Render](/images/reframehub/diagram-design/architecture.png) *Architecture diagram: Orthogonal connectors, mono sublabels, and single flame-accent focal element.* ![Sequence Diagram Render](/images/reframehub/diagram-design/sequence.png) *Sequence flow: Lifelines, request-response payloads, and ALT branching fragments.* ![Flowchart Diagram Render](/images/reframehub/diagram-design/flowchart.png) *Editorial flowchart: 4px grid alignment, balanced node density, and zero drop shadows.* ![Quadrant Matrix Diagram Render](/images/reframehub/diagram-design/quadrant.png) *Quadrant positioning: 2-axis matrix with clear category clustering and semantic labels.* ![Timeline Diagram Render](/images/reframehub/diagram-design/timeline.png) *Timeline & Milestones: Clean horizontal spine with dates, milestones, and status tags.* ### Architecture (official skill topology) ``` LLM Agent Host (Claude Code / Codex / Factory Droid / Pi / Hermes) │ ▼ skills/diagram-design/SKILL.md (Router & Principles) │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ references/type-*.md references/ references/ (Layout Grammar) style-guide.md semantic-patterns.md │ (Brand Tokens) (Queues/Bottlenecks) └────────────────┬────────────────┘ ▼ Self-Contained Output File (.html) ┌────────────────────────────────────────┐ │ • Semantic HTML + Inline Accessible SVG│ │ • 4px coordinate grid & 1 accent color │ │ • Zero runtime JS / Zero build step │ └────────────────────────────────────────┘ │ (Optional Verification) ▼ Automated Layout & Lint Gates (Python + Playwright) lint-skin.py · lint-render.py · verify-geometry.py · self_check.py ``` ### Why HTML + CSS Beats Fragile Full-Canvas SVG A common failure mode with raw SVG diagramming tools is visual fragility: 1. **Font & Text Truncation**: Fixed SVG `` nodes cannot wrap or reflow automatically. If a user's browser renders a fallback font with a 5% wider character bounding box, text overflows container borders or gets clipped by `clipPath`. 2. **Mobile Viewport Breakage**: Large SVG `viewBox="0 0 1200 800"` canvases shrink proportionally on mobile screens, turning labels into unreadable 4px micro-text. 3. **Accessibility Black Hole**: Screen readers and search engine crawlers struggle to extract structural meaning from nested `` and `` coordinates. Diagram Design solves this by treating **HTML as the carrier of meaning and SVG as the spatial connector**: - Structural metadata (headings, summary cards, bulleted notes, technical specs) is rendered in semantic HTML. - Connectors and directional spines are drawn as clean, accessible SVG (`role="img"` with resolving `aria-labelledby`). - The 4px coordinate grid and automated Chromium test suite (`lint-render.py`) verify that rendered text never clips or overflows across viewports. ### Stack (from repository) | Layer | Choices | | --- | --- | | Format | Standalone HTML5 + inline SVG (`role="img"`, aria-labelledby, ``, `<desc>`) | | Design Rules | 4px coordinate grid, 1 accent color, 1px hairline strokes, max 10px radius, target density 4/10 | | Typography | Instrument Serif (display/callouts), Geist Sans (node labels), Geist Mono (technical ports/types) | | Runtime | In-context markdown skill + Python CLI extractors (`drawio_extract.py`, `mermaid_extract.py`, `self_check.py`) | | Host Support | Claude Code, Codex, Factory Droid, Pi, Hermes Agent, OpenCode, Antigravity | | Quality Gates | Headless Chromium pixel-diffing (`lint-render.py`), geometric label placement masking (`verify-geometry.py`), a11y linter | | Export | Standalone SVG (Google Fonts embedded) · PNG rasterization (via Playwright at 2×) | ### Features that matter for a stack decision - **Zero-JS, zero-build output** — Opens by double-clicking; hostable anywhere without bundling or iframe sandboxing headaches. - **Context-efficient agent routing** — Loads only the active type spec into memory (~1.5k tokens) instead of a massive monolith. - **Semantic brand contract** — All diagrams inherit semantic roles (`bg-paper`, `text-ink`, `border-line`, `text-accent`) rather than hardcoded hex values. - **draw.io & Mermaid modernization** — Cleans up legacy engineering spaghetti diagrams without redrawing by hand in Figma. - **Strict mathematical and geometric quality gates** — CI checks rendered bounding boxes in headless Chromium to catch text clipping, overflowing viewports, and color contrast failures. ## Cost breakdown | Path | Reference cost | What you get | | --- | --- | --- | | Diagram Design (local OSS skill) | $0/mo license + your LLM API tokens | 39 editorial grammars, brand onboarding, HTML/SVG export; runs entirely inside your existing agent host | | Eraser.io (managed SaaS) | Pro from $10/user/mo | Cloud architecture canvas, markdown docs integration, cloud sync | | Miro / Lucidchart (managed SaaS) | $8–$16/user/mo | Real-time multi-cursor whiteboarding, massive template library, non-technical team collaboration | | Figma / FigJam | Pro from $12/editor/mo | Industry standard design canvas; high manual authoring friction for quick architecture flows | | Mermaid.js / draw.io | $0/mo open-source / web | Free manual diagramming; dated visual output, manual alignment friction | There is **no seat fee for Diagram Design**: spend is strictly your existing coding agent subscription or API usage. Savings vs visual SaaS seats only pencil out if your team authors documentation via code agents rather than collaborative live whiteboarding sessions. ## The Good - **High-craft visual output without design fatigue** — Eliminates the 30-minute Figma alignment rabbit hole while avoiding dated flowchart aesthetics. - **Zero runtime dependencies** — No client-side React, Vue, D3, or Mermaid bundle required. The resulting HTML is self-contained and fast. - **Token-conscious progressive disclosure** — Routine prompts only consume context for the requested layout type, leaving headroom for complex architectural code. - **Living brand integration** — Brand onboarding extracts your real CSS tokens and font stacks with automated WCAG AA accessibility verification. - **draw.io and Mermaid import bridge** — Migrates legacy technical documentation directly into cohesive editorial standards with an explicit change ledger. - **Playwright and Chromium CI test suite** — The upstream repository enforces strict layout assertions, geometric clipping guards, and accessibility audits. ## The Bad — what to know before adopting 1. **Not a multiplayer whiteboarding canvas.** There is no real-time multi-cursor UI, drag-and-drop node snapping, or sticky-note collaboration. It is an agent code-generation workflow, not a Miro or Excalidraw substitute. 2. **Output fidelity is bound to agent spatial intelligence.** While the layout grammars provide explicit coordinates, weaker or non-frontier LLMs can still misplace nodes or miscalculate SVG viewBox boundaries without running `self_check.py`. 3. **Static by design.** Motion is deliberately restricted to sequential step/reveal/loop with an immediate static first frame for accessibility; it is not a tool for interactive canvas simulations. 4. **Local profile discipline required.** Managing brand guidelines for multiple client workspaces requires placing `.diagram-design` marker files or maintaining profiles under `~/.diagram-design/profiles/<slug>.md`. 5. **PNG export requires local Python/Playwright.** While HTML and SVG exports are instant, generating 2× PNGs requires a local Python environment with `playwright install chromium`. ## When to use / When to skip **Use Diagram Design if:** - You want **editorial, publication-grade architecture diagrams** in your documentation, blog posts, or pitch decks without opening Figma. - Your engineering team already uses **AI coding agents** (Claude Code, Codex, Factory Droid, Pi, Antigravity) for development. - You want **self-contained HTML+SVG artifacts** that match your brand palette and typography in 60 seconds. - You need to **modernize legacy draw.io or Mermaid diagrams** into clean, executive-ready visuals. - You refuse to pay per-seat SaaS taxes for static diagram authoring. **Skip if:** - You need **real-time multiplayer collaborative whiteboarding** with non-technical stakeholders—stay on Miro, FigJam, or Eraser. - You need a visual drag-and-drop GUI to nudge boxes manually. - Your team does not use CLI coding agents or prefers hosted WYSIWYG interfaces. - You need dynamic, data-driven real-time canvas charting (use D3.js or Observable instead). ## Prerequisites (official path) - **Agent Host**: Claude Code, Codex, Factory Droid, Pi, Hermes Agent, or an Agent Skills-compatible runner. - **Web Browser**: Any modern browser to preview the output `.html` files offline. - **Optional PNG Export**: Python 3.10+ with `pip install playwright && playwright install chromium`. ## Setup checklist (official path) 1. **Install into your agent host**: - **Claude Code**: ```bash /plugin marketplace add cathrynlavery/diagram-design /plugin install diagram-design@diagram-design ``` - **Codex**: ```bash codex plugin marketplace add cathrynlavery/diagram-design codex plugin add diagram-design@diagram-design ``` - **Factory Droid**: ```bash droid plugin marketplace add https://github.com/cathrynlavery/diagram-design droid plugin install diagram-design@diagram-design --scope user ``` - **Pi**: ```bash pi install https://github.com/cathrynlavery/diagram-design ``` 2. **Onboard your brand (60 seconds)**: In your agent chat, run: ```text onboard diagram-design to https://yourdomain.com ``` The agent extracts your background, text, accent colors, and font stack, verifies WCAG AA contrast, and saves your tokens. 3. **Generate your first diagram**: Ask in natural language: ```text "Create an architecture diagram of my stack: Next.js frontend, Cloudflare Worker API, Postgres database, and Redis cache." ``` 4. **Redraw existing diagrams (optional)**: ```bash # Redraw draw.io file for an executive deck /diagram-design:import-drawio architecture.drawio --size=slide-16x9 --detail=simplified --audience=executive # Redraw Markdown Mermaid block /diagram-design:import-mermaid README.md --diagram=all ``` ## Our recommendation Apply the same **Keep / Configure / Replace / Build** lens as every ReframeHub note (start with the [Stack Decision Checklist](/reframehub/stack-decision-checklist/) if you want a self-serve pass). - **As a developer documentation tool:** Configure Diagram Design into your coding agents immediately. It replaces hours of Figma alignment and produces significantly cleaner visuals than Mermaid.js. - **As a team visual whiteboard:** Keep Miro, FigJam, or Eraser for real-time collaborative brainstorming and stakeholder mapping. Diagram Design is an *authoring engine*, not a multiplayer whiteboard. - **As a design reference:** One of the most disciplined open-source graphic systems available for technical diagrams—worth studying for its progressive disclosure routing and 4px layout math. Need help evaluating visual design tooling, documentation architecture, or SaaS sprawl across your stack? [Book a Reframe audit for visual stack](/reframe/?from=reframehub&tool=diagram-design) ($199). For a parallel local-first design evaluation, see [Open Design](/reframehub/open-design/); for general open-source adoption criteria, see [open-source evaluation](/reframehub/open-source-evaluation/). ## ReframeHub: Founder Playbook - Path: https://emiote.com/reframehub/founder-playbook/ - Category: AI & Agents - Description: Open-source system of 16 structured agent skills distilling business frameworks into progressive decision trees and execution rubrics for coding agents. - Pricing / Model: open-source (Self-host: $0 local CLI / $0 repo clone (+ raw LLM API tokens), Cloud: Free open-source / pay-as-you-go LLM inference) - Snapshot Date: 2026-09-15 > **Founder Playbook** is an open-source library of 16 structured business skills for AI agents, created by AgentSeal. It converts foundational startup books into machine-readable decision trees, scoring rubrics, and conflict-resolution maps. Designed for Claude Code and LLM developer tools, it deploys locally via npm or direct git symlinks to guide founders through validation, pricing, and distribution. --- ## 1. What It Replaces & Why It Matters Most technical founders encounter the same commercial obstacles: validating market demand, positioning against incumbents, packaging pricing tiers, and building distribution channels. The conventional playbook is to read foundational business literature, including *The Mom Test*, *The Lean Startup*, *Crossing the Chasm*, *Obviously Awesome*, and *Monetizing Innovation*. While these books contain rigorous models, their core frameworks are buried inside hundreds of pages of narrative anecdotes and historical examples. Founders highlight a few pages, return to coding, and forget the operational details months later when critical commercial decisions arise. When founders consult general-purpose models like ChatGPT or Claude without dedicated skills, the results are rarely practical. Unprompted models default to generic startup advice: stay customer-centric, talk to users, iterate fast, and build an audience. These bland generalities lack concrete decision trees, qualification criteria, and scored checklists. Founder Playbook replaces narrative recall and generic chat prompts with 16 structured agent skills. It translates qualitative business books into machine-readable reference documents designed specifically for agent context engines. Each skill strips away anecdotal filler, leaving only decision matrices, failure modes, case analyses, and fill-in templates. Instead of searching a bookshelf or pasting entire book summaries into a prompt, an engineer working in Claude Code, Cursor, or Windsurf can invoke a verified framework directly inside their terminal. --- ## 2. Architecture & Progressive Disclosure Design Founder Playbook contains 97 files totaling 21,557 lines of curated markdown. The repository is organized as 16 distinct skills: 1 meta-diagnostic router (`diagnose`) and 15 domain skills mapped directly to foundational texts. ```mermaid flowchart TD UserQuery["Founder Asks Commercial Question in Agent CLI"] --> AgentRuntime["Claude Code / Agent Runtime"] AgentRuntime --> ManifestScan["Scan Frontmatter Descriptions (~100 tokens/skill)"] ManifestScan --> DecisionBranch{"Is Root Problem Known?"} DecisionBranch -- No --> DiagnoseRouter["Load diagnose/SKILL.md (Meta Router)"] DecisionBranch -- Yes --> DirectSkill["Load Target skill/SKILL.md (Level 1)"] DiagnoseRouter --> RootEval["Evaluate 5 Failure Modes:\nProduct | Market | Messaging | Distribution | Pricing"] RootEval --> SelectedSkill["Route to Target Skill (e.g. mom-test, traction)"] SelectedSkill --> Level1["SKILL.md Entry Point (200-500 lines):\nDecision Trees, Guardrails, Output Rules"] Level1 --> NeedsDepth{"Does Agent Require Deep Context?"} NeedsDepth -- Yes --> Level2["On-Demand Reference Files (Level 2):\nframeworks.md | cases.md | examples.md | integration.md"] NeedsDepth -- No --> FinalOutput["Execute One-Skill Rule:\n1 Primary Skill + 1 Action for Current Week"] Level2 --> FinalOutput ``` ### The Progressive Disclosure Hierarchy Context efficiency is the primary architectural constraint in AI agent tooling. Loading all 15 frameworks simultaneously would consume over 60,000 tokens, degrading model attention and generating prohibitive inference costs. Founder Playbook solves this through a three-tier progressive disclosure hierarchy: 1. **Level 0 (Discovery Manifest)**: Each skill defines a concise YAML frontmatter description of approximately 100 tokens. The agent runtime inspects these descriptions at startup to determine intent without loading file bodies. 2. **Level 1 (Operational Entry Point)**: When triggered, the agent loads only the root `SKILL.md` (200 to 500 lines). This file contains the primary decision tree, misdiagnosis warnings, quick-reference tables, and boundary rules. 3. **Level 2 (On-Demand Deep Dives)**: Detailed background files are isolated into standalone markdown documents, loaded only when the model requires granular support: - `frameworks.md`: Comprehensive breakdowns of underlying models and mathematical formulas. - `cases.md`: Real-world positive and negative case studies from the source literature. - `examples.md`: Practical worksheets, interview scripts, and fill-in templates. - `integration.md`: Explicit mapping of how the skill connects with or contradicts other frameworks. ### Cross-Framework Conflict Resolution Standard business books present their frameworks as universal truths. When applied together, they frequently collide. For instance, W. Chan Kim and Renee Mauborgne's *Blue Ocean Strategy* advocates looking beyond existing boundaries to non-customers, while April Dunford's *Obviously Awesome* demands extreme focus on best-fit niche buyers. Similarly, Geoffrey Moore's *Crossing the Chasm* mandates dominating a narrow beachhead segment, whereas Alex Hormozi's *$100M Offers* prioritizes high-volume mass-market problem spaces. Rather than ignoring these contradictions, Founder Playbook includes dedicated `integration.md` files for each skill. These documents explicitly catalog conceptual conflicts and provide concrete resolution heuristics. The agent learns when to prioritize one philosophy over another based on the company's verified stage and sales motion. --- ## 3. Visual Tour & Interface Workflows Founder Playbook operates as a clean extension to your local agent environment, turning business literature into actionable terminal workflows. ![Founder Playbook 15 Business Books Distilled into AI Skills](/images/reframehub/founder-playbook/banner.webp) ### The 5-Step Startup Diagnostic Pipeline The core entry point of the collection is `diagnose/SKILL.md`. It provides a deterministic 5-step triage sequence to prevent founders from treating symptoms rather than root causes: 1. **Step 1: Do people want this?** Evaluates whether at least five customers have paid real currency or signed binding letters of intent. If not, it halts feature development and routes to `mom-test` or `four-steps`. 2. **Step 2: Can people understand what you do?** Tests the value proposition against a 5-second stranger test. If confusing, it routes to `storybrand` or `made-to-stick`. 3. **Step 3: Are the right people finding you?** Evaluates traffic volume and audience fit. If the audience is mismatched, it routes to `obviously-awesome` for repositioning; if volume is absent, it routes to `traction` or `100m-leads`. 4. **Step 4: Are they buying?** Diagnoses conversion failure points across price objections (`monetizing-innovation`), lack of trust (`influence`), missing urgency (`100m-offers`), or retention churn (`lean-startup`). 5. **Step 5: Is the sales process working?** Evaluates deal velocity in B2B transactions, routing stalled negotiations to `spin-selling`. ### The One-Skill Rule A critical guardrail enforced throughout the collection is the One-Skill Rule: > Every diagnostic output must yield exactly one primary skill, one optional secondary skill, and one concrete action that a solo founder can execute within seven days. Framework stacking creates an illusion of progress while paralyzing execution. When an agent attempts to combine four separate methodologies simultaneously, it outputs sprawling, unmanageable roadmaps. Founder Playbook forces the model to select a single operational bottleneck and sequence follow-up work chronologically. --- ## 4. Total Cost of Ownership (TCO) Founder Playbook is licensed under the permissive MIT license. There are no subscription fees, seat licenses, or vendor lock-in. The financial cost of operating the system is tied entirely to local compute storage and LLM token consumption. | Dimension | Managed Advisory / Accelerators | Generic AI Chat Prompts | Founder Playbook (OSS Skills) | | :--- | :--- | :--- | :--- | | **Upfront License** | $0 to $10,000 retainer (or 5-7% equity) | $20/month SaaS subscription | **$0 (MIT License)** | | **Installation & Setup** | Weeks of application and scheduling | Instant browser login | **Under 1 minute (`npx skills add`)** | | **Local Storage** | 0 MB | 0 MB | **~35 MB local disk space** | | **Context Token Footprint** | None (human conversations) | High (users paste entire articles) | **~100 tokens idle, ~1.5K-4K active** | | **Inference Cost per Query** | $0 (included in human retainer) | Included in SaaS subscription | **$0.005 to $0.03 per turn (API pricing)** | | **Execution Latency** | Days to weeks for advisory calls | Seconds (often inaccurate) | **Sub-second agent tool loading** | | **Operational Privacy** | Protected under NDA | Subject to vendor data policies | **100% local markdown repository** | | **Annual Operating Cost** | $10,000+ or significant equity | $240/year per seat | **$0 software + pay-as-you-go tokens** | ### Context Token Economics In standard coding agent workflows on Anthropic Claude 3.7 Sonnet or OpenAI GPT-4o, input tokens cost between $2.50 and $3.00 per million tokens. - Reading the startup description for all 16 skills: ~1,600 tokens ($0.0048). - Loading a primary `SKILL.md` entry point: ~2,500 tokens ($0.0075). - Loading supporting deep-dive files (`frameworks.md`, `examples.md`): ~6,000 tokens ($0.018). A comprehensive startup diagnosis and tactical plan costs under $0.05 in API usage. This is orders of magnitude cheaper than human consulting or SaaS advisory platforms. --- ## 5. The Bad: What to Know Before Adopting While Founder Playbook provides exceptional structure, engineering teams must recognize several concrete operational limitations: 1. **Vulnerability to Unverified Founder Self-Reporting**: The diagnostic decision trees rely entirely on human input. If a founder reports that users love their product when users are merely being polite, the diagnostic produces incorrect routing. The skills have no native telemetry integrations with Stripe, PostHog, or database queries to verify real user retention or conversion data independently. 2. **Historical Assumptions in Pre-Cloud Literature**: Foundational works such as Geoffrey Moore's *Crossing the Chasm* (1991) and Steve Blank's *Four Steps to the Epiphany* (2005) were formulated during the era of enterprise enterprise software sold on multi-year contracts by direct sales forces. Applying them directly to modern self-serve developer tools or open-source infrastructure requires careful translation. While the skills contain modern relevance notes, the core heuristics still reflect enterprise sales cycles. 3. **Context Accumulation Across Extended Sessions**: When working in a persistent agent conversation across dozens of turns, auto-loading multiple skills can gradually fill the agent context window with reference documentation. Without active session pruning or context compression tools, historical framework text can compete with project source code for model attention. 4. **Zero Autonomous Execution Capabilities**: These skills are analytical guides, not autonomous workers. They provide frameworks, scoring criteria, and message templates, but they do not automatically execute customer discovery outreach, send cold emails, or modify marketing page markup. The execution burden remains entirely on the human builder. --- ## 6. Quickstart & Deployment Founder Playbook can be installed into your local agent environment using the standard skills package manager or through manual git symlinks. ### Standard Installation via CLI ```bash # Add the entire playbook to your global agent skills npx skills add getagentseal/founder-playbook ``` ### Manual Installation for Claude Code To link the skills directly into Claude Code on macOS, Linux, or Windows WSL: ```bash # Clone the repository locally git clone https://github.com/getagentseal/founder-playbook.git cd founder-playbook # Symlink each skill folder into the Claude skills directory for skill in */SKILL.md; do dir=$(dirname "$skill") ln -sfn "$(pwd)/$dir" ~/.claude/skills/"$dir" done ``` ### Verification and Prompting Once installed, restart your agent session and invoke a diagnostic query: ```bash # Natural language trigger claude "I have built an open source developer tool with 500 stars, but zero users will pay for hosted cloud. What should I fix?" ``` The agent will automatically parse the intent, trigger `diagnose`, evaluate the feedback against the Five Failure Modes, and route into `monetizing-innovation` or `mom-test` with a structured action checklist. --- ## 7. Recommendation & ReframeHub Insight ### Who Should Use This - **Technical Founders & Solo Builders**: Engineers building products who require structured, dispassionate business guidance without reading 15 separate volumes. - **AI-Assisted Development Teams**: Teams using Claude Code, Cursor, Windsurf, or OpenClaw who want commercial decision frameworks accessible directly in their terminal workflow. - **Bootstrapped Software Companies**: Teams navigating early positioning, pricing models, and distribution channels without the budget for commercial advisors. ### Who Should Avoid This - **Late-Stage Enterprise Organizations**: Companies with established revenue operations, dedicated sales management, and specialized enterprise tooling. - **Founders Seeking Fully Autonomous Execution**: Teams expecting an autonomous agent to run sales campaigns or customer interviews without human direction. ### ReframeHub Insight: Codifying Qualitative Domain Knowledge The deeper engineering lesson of Founder Playbook extends beyond business books. It demonstrates a repeatable architecture for codifying qualitative human knowledge into machine-addressable agent interfaces. Human literature is traditionally structured for narrative retention. Authors write 300 pages of stories, case studies, and rhetorical repetition so that a human reader remembers two or three concepts months later. Large language models do not benefit from narrative padding. When models process conversational anecdotes, they often confuse historical specifics with universal rules. To make human knowledge useful to autonomous agents, it must be refactored into: - Scored classification rubrics - Explicit decision trees with strict exit conditions - Documented trade-offs and cross-system contradictions - Progressive disclosure hierarchies that conserve context tokens Founder Playbook provides a reference implementation for this transformation. By decomposing subjective business theory into typed markdown contracts, it proves that any domain library can be transformed into a high-precision reasoning engine for software agents. ## ReframeHub: Gemma Translator - Path: https://emiote.com/reframehub/gemma-translator/ - Category: AI & Agents - Description: Google's open-source fully offline voice translator appliance running Gemma 4, LiteRT-LM, and Moonshine on a Raspberry Pi 5. - Pricing / Model: open-source (Self-host: $0 software; ~$120–$160 hardware (Raspberry Pi 5 8GB + 480x320 display + USB mic/audio), Cloud: Cloud APIs ($20/mo Translate + $0.006/min Whisper + TTS) or $299 proprietary handheld hardware) - Snapshot Date: 2026-09-04 **Gemma Translator** is an open-source, fully offline voice translation appliance from Google that runs on a Raspberry Pi 5. Powered by Google's Gemma 4 E2B model via the LiteRT-LM runtime and Moonshine voice recognition and synthesis, it provides real-time speech-to-speech translation without cloud dependencies, subscriptions, or external network connectivity. ## Scope and currency This is an **architecture evaluation**, not a production field diary across international travel checkpoints. In September 2026 we reviewed the official [Gemma Translator GitHub repository](https://github.com/google-gemma/gemma-translator), source code (`backend/server.py`, `download_model.sh`, `deploy-pi.sh`), Hugging Face model checkpoints (`litert-community/gemma-4-E2B-it-litert-lm`), and hardware specifications. **We evaluated the edge inference pipeline, memory footprint, and systemd kiosk deployment structure.** Model weights, LiteRT runtime optimizations, and speech models evolve; verify current package revisions before fabricating physical hardware. Editorial review: `2026-09-04`. ## What it is Gemma Translator is an open-source (**Apache 2.0**) cyber-deck hardware appliance engineered by Google's open model team. Unlike traditional smartphone translation apps that stream raw voice recordings to remote cloud endpoints, Gemma Translator executes the entire pipeline—**speech-to-text (ASR), multilingual neural translation (LLM), and speech synthesis (TTS)**—completely on a single Raspberry Pi 5 single-board computer. The project bundles: 1. **Gemma 4 E2B-it on LiteRT-LM** — A quantized, instruction-tuned edge language model (~2B parameters) executed via Google AI Edge's high-performance C++ LiteRT runtime on ARM64 CPU. 2. **Moonshine Voice Substrate** — Multilingual speech recognition via Useful Sensors' Moonshine ASR alongside on-device neural TTS (Kokoro/Piper backed) supporting English, Arabic, Spanish, Japanese, Mandarin Chinese, and Korean. 3. **Dedicated Handheld Kiosk UI** — A lightweight React + Vite interface styled with retro monospace green/amber terminal aesthetics, specifically scaled for 480x320 touchscreens. 4. **Physical CAD Enclosure** — 3D-printable industrial design specifications for a self-contained handheld device housing the Raspberry Pi 5, active cooling fan, battery pack, microphone, and speaker. ### Visual tour: Handheld hardware and interface ![3D CAD animated model of the custom Gemma Translator handheld physical enclosure](/images/reframehub/gemma-translator/cad-preview.webp) *The custom 3D-printable CAD handheld enclosure housing the Raspberry Pi 5, active cooler, touchscreen, and audio interface.* ![Gemma Translator live on-device speech-to-speech translation hardware in action](/images/reframehub/gemma-translator/hardware-preview.webp) *Live handheld appliance in action: on-device voice capture, LiteRT-LM neural translation, and synthesized speech playback on a Raspberry Pi 5.* ## What it replaces & why it matters Voice translation in the field has historically forced engineering teams into painful trade-offs between recurring cloud costs, roaming connectivity failure, and vendor lock-in. | Existing Paradigm | Structural Bottleneck | What Gemma Translator Changes | | :--- | :--- | :--- | | **Cloud Speech APIs (Whisper + GPT-4o-mini + ElevenLabs)** | Requires persistent high-bandwidth cellular connection; fails in airplanes, underground transit, border control, or remote field sites; high token/minute metered billing; leaks confidential conversations. | Zero internet requirement after initial model download; zero per-minute API fees; complete physical data sovereignty. | | **Proprietary Hardware Translators (Pocketalk, Vasco, Cheetah TALK)** | $249–$349 upfront device cost; requires proprietary e-SIM subscriptions after 2 years; closed ecosystem with no developer access or custom vocabulary. | $0 open-source software running on open commodity hardware (Raspberry Pi 5); fully auditable Python and React source code. | | **On-Phone General Apps (Google Translate Offline / Apple Translate)** | Bound to consumer smartphone operating systems; lacks dedicated push-to-talk hardware ergonomics; competing background processes cause battery drain and audio routing conflicts. | Dedicated single-purpose appliance; boots directly into fullscreen kiosk mode; deterministic hardware resource allocation. | ## Architecture & tech stack review The system separates audio processing, neural inference, and presentation into decoupled local processes coordinated over localhost sockets. ```mermaid flowchart LR subgraph AudioIn["1. Voice Capture"] Mic["Microphone Input<br/>(USB / ALSA / PulseAudio)"] PCM["16kHz 16-bit Mono PCM"] end subgraph EdgeInference["2. On-Device Edge Compute (Raspberry Pi 5)"] STT["Moonshine STT<br/>(Transcriber LRU Cache)"] LLM["Gemma 4 E2B-it<br/>(LiteRT-LM CPU on :9379)"] TTS["Moonshine Voice<br/>(Kokoro/Piper Synthesis)"] end subgraph AudioOut["3. Output & Feedback"] Speaker["Speaker Output<br/>(3.5mm / USB Audio DAC)"] Kiosk["480x320 Touch Display<br/>(Chromium Kiosk on :3000)"] end Mic --> PCM PCM --> STT STT -->|"Transcribed Text"| LLM LLM -->|"Neural Translation"| TTS LLM -->|"Live Text Stream"| Kiosk TTS -->|"Synthesized Speech"| Speaker ``` ### 1. Neural language engine: `gemma4-e2b` + LiteRT-LM The translation core uses `gemma-4-E2B-it.litertlm`, a specialized CPU-targeted build of Google's Gemma 4 edge architecture published by Google AI Edge under Apache 2.0. Rather than running through heavy Python PyTorch or Hugging Face Transformers runtimes, the model runs inside **LiteRT-LM** (formerly TensorFlow Lite Runtime for Large Models). LiteRT-LM compiles the computational graph with ARM64 NEON vector optimizations and weight quantization, hosting an OpenAI-compatible HTTP inference endpoint on `localhost:9379`. ### 2. Speech pipeline: Moonshine STT & Voice Speech recognition and generation are handled by Useful Sensors' **Moonshine** framework: - **Speech-to-Text (`Transcriber`)**: Converts captured audio into raw text for six target language families (`en`, `ar`, `es`, `ja`, `zh`, `ko`). - **Text-to-Speech (`TextToSpeech`)**: Synthesizes the translated string back into speech using localized voice models (such as `kokoro_zf_xiaoxiao` for gentle Mandarin output). ### 3. Memory safety: Reentrant LRU caching Edge language models and neural speech synthesis run into severe memory pressure when hosted on single-board computers. In `backend/server.py`, the engineering team implemented an explicit Least-Recently-Used (LRU) model cache bounded by `MAX_MODELS = 2`: ```python # RLock ensures safe concurrency without self-deadlocks _stt_lock = threading.RLock() _tts_lock = threading.RLock() if len(_stt_recognizers) >= MAX_MODELS: oldest_lang, oldest_recognizer = _stt_recognizers.popitem(last=False) del oldest_recognizer ``` By aggressively evicting idle acoustic and phoneme weights, the Python backend keeps total memory usage stable within the Raspberry Pi 5's 8GB LPDDR4X envelope, avoiding the Linux kernel Out-Of-Memory (OOM) killer during rapid multi-language conversations. ### Service & process topology ```mermaid graph TD subgraph Enclosure["Hardware Substrate"] Screen["480x320 Touch LCD"] AudioHw["Microphone In / Speaker Out"] end subgraph OS["Raspberry Pi OS (Debian Linux)"] Kiosk["Chromium Kiosk Mode<br/>(LXDE autostart)"] PyServer["Python HTTP Backend (:3000)<br/>(server.py + Moonshine)"] LiteRT["LiteRT-LM Server (:9379)<br/>(gemma-4-E2B-it.litertlm)"] Systemd["systemd unit<br/>(gemma-translator.service)"] end Screen <-->|Touch Events & Display| Kiosk AudioHw <-->|ALSA Audio Stream| PyServer Kiosk <-->|HTTP POST / Audio Blobs| PyServer PyServer <-->|Inference Proxy| LiteRT Systemd -->|Supervises Lifecycle| PyServer Systemd -->|Supervises Lifecycle| LiteRT ``` ## Total cost of ownership (TCO) Because Gemma Translator is self-contained edge hardware, its cost model differs completely from cloud SaaS subscription services. | Dimension | Gemma Translator (Edge Appliance) | Cloud Multi-Model API Chain | Proprietary Appliance (Pocketalk / Vasco) | | :--- | :--- | :--- | :--- | | **Software License** | $0 (Apache 2.0 open source) | Pay-per-token / Pay-per-minute | Included in device purchase | | **Hardware Investment** | ~$135 one-time DIY build | Smartphone ($0 existing or $400+) | $299 upfront hardware cost | | **Monthly Operating Cost** | **$0 / month** | **~$25 – $80 / month** (Translate + Whisper + TTS) | $0 for 2 yrs, then $50/yr cellular renewal | | **Year 1 Total Cost** | **~$135** | **~$300 – $960** | **$299** | | **Year 2 Total Cost** | **$0** (cumulative: ~$135) | **~$300 – $960** (cumulative: ~$600 – $1,920) | **$50** (cumulative: $349) | | **Network Reliance** | Zero (fully offline) | 100% (fails without cellular/WiFi) | 100% (requires cloud servers) | | **Conversational Privacy** | Total on-device retention | Voice audio processed on third-party servers | Vendor cloud servers | | **Maintenance Burden** | DIY assembly and Linux updates | Zero infra maintenance | Zero infra maintenance | ### Hardware Bill of Materials (BOM) A complete standalone Gemma Translator build requires: ```text Raspberry Pi 5 (8GB RAM) : ~$80.00 Official Active Cooler / Fan : ~$5.00 3.5" Touchscreen Display (480x320) : ~$25.00 USB / I2S Audio Mic & Speaker : ~$15.00 64GB SanDisk Extreme MicroSD Card : ~$10.00 3D-Printed Enclosure (PLA Filament): ~$3.00 -------------------------------------------------- Total Hardware Investment : ~$138.00 ``` For teams conducting regular international fieldwork, sensitive interviews, or remote facility inspections, an edge appliance amortizes its hardware cost within 2 to 3 months of cloud API bills. ## The Good - **Complete offline independence:** Operates at 35,000 feet in an airplane, in secure defense facilities, or in remote desert field sites where cellular connectivity is nonexistent. - **Strict conversational confidentiality:** Voice data never leaves the device's RAM. There are no cloud logs, third-party data broker leaks, or model training scraping risks. - **Zero recurring software tax:** No subscriptions, no token meters, no credit cards, and no surprise rate limit throttling. - **Deterministic hardware ergonomics:** Boots directly to fullscreen kiosk mode via systemd in under 20 seconds. - **Open CAD fabrication:** Full mechanical CAD files allow teams to modify the chassis for ruggedized rubber bumpers, lanyard loops, or tactical mounting brackets. ## The Bad — what to know before adopting 1. **Inference latency on CPU:** Running ~2B parameters on four ARM Cortex-A76 cores without a discrete NPU introduces a 1.5 to 3.0 second first-token latency. It is responsive for deliberate dialogue, but not instantaneous simultaneous interpretation. 2. **Thermal demands and power draw:** Under sustained translation, the Pi 5 consumes between 7W and 11W of power. An active cooler fan is mandatory; running inside a sealed 3D-printed enclosure without ventilation causes CPU thermal throttling down to 1.5 GHz. 3. **Language coverage boundaries:** The speech stack currently focuses on 6 primary languages (`en`, `ar`, `es`, `ja`, `zh`, `ko`). Languages outside this set require sourcing and testing custom Moonshine or Piper checkpoints. 4. **LRU cold-switch penalty:** Switching between language pairs triggers disk-to-RAM model swapping. While the first load takes 2–4 seconds, subsequent turns remain fast within the `MAX_MODELS = 2` cache. 5. **Maker assembly barrier:** This is a hardware project. You must flash Linux images, mount GPIO displays, configure ALSA audio gain, and 3D-print your own chassis. ## When to use / When to skip ### Use Gemma Translator if: - You require **strict privacy and data sovereignty** (legal depositions, healthcare diagnostics, executive travel, or military field operations). - You operate in **remote or austere environments** with unreliable or expensive satellite/cellular data. - You want a dedicated, ruggedized translation cyber-deck that does not tie up your primary smartphone. - You are an edge AI developer or hardware engineer studying production patterns for on-device SLMs. ### Skip Gemma Translator if: - You have reliable high-speed 5G connectivity and prioritize the lowest possible latency—cloud-hosted GPT-4o voice pipelines will feel faster. - You need coverage across 100+ low-resource regional dialects—commercial cloud engines (Google Cloud Translation API) maintain vastly broader corpora. - Your team does not have the operational capacity to manage physical hardware, battery charging, and Linux systemd configurations. ## ReframeHub insight: The triumph of the single-purpose appliance The deeper architectural lesson of Gemma Translator is the resurgence of the **dedicated physical appliance**. For fifteen years, consumer software consumed hardware: your GPS, your camera, your translator, and your notebook were all absorbed into smartphone apps. But cloud-dependent smartphones come with attention hijacking, roaming costs, battery starvation, and surveillance-by-default architecture. Gemma Translator demonstrates that **edge AI reverses this trend**. When a 2-billion-parameter language model and a neural speech recognizer can fit into 8GB of memory on an $80 board, single-purpose physical tools become viable again. They do one job with zero distraction, zero telemetry, and total operational reliability. ## Quickstart & deployment ### 1. Bootstrap Python environment On Raspberry Pi OS (64-bit Debian Bookworm) or Linux: ```bash git clone https://github.com/google-gemma/gemma-translator.git cd gemma-translator chmod +x setup.sh download_model.sh start.sh deploy-pi.sh ./setup.sh ``` ### 2. Fetch the LiteRT-LM Gemma 4 weights ```bash ./download_model.sh ``` *This downloads `gemma-4-E2B-it.litertlm` (~1.4 GB) directly from Hugging Face into your local LiteRT model directory.* ### 3. Start development stack ```bash ./start.sh ``` - **Frontend UI (Vite Dev)**: `http://localhost:5173` - **Backend API Server**: `http://localhost:3000` - **LiteRT-LM Inference Engine**: `http://localhost:9379` ### 4. Full Raspberry Pi Kiosk Appliance Deployment To register the systemd service and launch Chromium in fullscreen kiosk mode on boot: ```bash ./deploy-pi.sh ``` This registers `deploy/gemma-translator.service`, compiles production assets into `frontend/dist/`, and configures the LXDE window manager to launch the appliance automatically upon power-up. ## ReframeHub: Headroom - Path: https://emiote.com/reframehub/headroom/ - Category: AI & Agents - Description: Open-source context compression layer for AI coding agents and LLM workflows, cutting repetitive tool outputs and JSON tokens with reversible retrieval. - Pricing / Model: open-source (Self-host: $0/mo local machine / $5-$15/mo VPS (+ raw LLM API tokens), Cloud: Enterprise agent platforms from $40-$500/user/mo; raw API token bills) - Snapshot Date: 2026-09-08 > **Headroom** is an open-source, local-first context compression layer for AI agents and LLM applications, created by Headroom Labs. Built with Rust and Python, it sits between coding assistants and model providers to compress repetitive tool outputs, logs, and JSON data. Using reversible retrieval (CCR), it shrinks token payloads while allowing models to fetch original content on demand. --- ## 1. Why Headroom Matters: The Context Bottleneck Modern coding agents run iterative feedback loops. Claude Code, Codex, Cursor, Aider, and OpenClaw inspect files, run tests, query language servers, and execute shell commands. Each action appends raw output into the session history. Within five turns, a debugging session accumulates tens of thousands of tokens. Most of this data is repetitive ceremony: - Search results return hundreds of file paths where the model only references three. - Test runners print thousands of passing test lines surrounding one assertion failure. - Database queries and API calls return wide JSON arrays containing dozens of unused schema keys. - Diff outputs repeat entire unmodified file contexts. When raw tool payloads fill the context window, two problems occur. First, inference bills scale linearly with input tokens. On frontier models such as Claude 3.7 Sonnet or Claude Opus, input tokens cost between $3.00 and $15.00 per million tokens. Long-running agent sessions routinely spend dollars per task on unread boilerplate. Second, attention dilution degrades reasoning quality. Models fail to locate critical signals when buried under hundreds of lines of passing test logs. ``` Standard Agent Flow (Uncompressed Token Waste): [Agent Action] -> [Raw Tool Output: 50,000 Tokens] -> [Full Prompt Sent to LLM] (Bloated JSON, logs, paths) (Expensive, slow, noisy) Headroom Architecture (Reversible Local Compression): [Agent Action] -> [Raw Tool Output] -> [Headroom ContentRouter] -> [Compressed: 15,000 Tokens] | | +-> [Local SQLite CCR Cache] v | [LLM Receives Focus] | | +<-- headroom_retrieve -+ (if needed) ``` Earlier tools attempted to solve this with lossy token pruning or arbitrary rolling windows. Microsoft's LLMLingua applied small language models to drop low-perplexity words, but unpredictable token removal often corrupted structured JSON and code syntax. Simple rolling-window context managers discarded older conversation turns, causing agents to forget initial requirements. Headroom approaches context optimization through structured, reversible transformation. Instead of guessing token importance with an external model, it identifies the data type and applies deterministic algorithms: statistical filtering on JSON arrays, deduplication on log lines, AST parsing on code, and local caching of original text. --- ## 2. Architecture & Compression Pipeline Headroom is distributed as a Python package (`headroom-ai`), a native Rust core (`crates/headroom-core` exposed via PyO3 as `headroom._core`), an OpenAI and Anthropic compatible HTTP proxy (`headroom proxy`), and a TypeScript client SDK (`sdk/typescript`). ``` +---------------------------------------------------------------+ | YOUR APPLICATION | | (Claude Code · Codex · Cursor · OpenClaw · SDK) | +---------------------------------------------------------------+ | v +---------------------------------------------------------------+ | HEADROOM | | FastAPI Proxy (:8787) · Inline SDK · MCP Server | | | | | v | | Transform Pipeline | | 1. CacheAligner (prefix stability monitoring) | | 2. ContentRouter (Magika classifier + deterministic sniff) | | | | | +--> SmartCrusher (JSON: Kneedle, SimHash, zlib) | | +--> LogCompressor (Logs: error preservation) | | +--> SearchCompressor (Paths: structure dedup) | | +--> CodeCompressor (Tree-sitter AST outlines) | | +--> Kompress (ModernBERT ONNX fallback) | | | | | v | | 3. CCR Store (Local SQLite: hash key + original content) | | 4. Output Shaper (Verbosity steering + effort routing) | +---------------------------------------------------------------+ | v +---------------------------------------------------------------+ | MODEL PROVIDERS (Anthropic, OpenAI, Bedrock) | +---------------------------------------------------------------+ ``` ### Core Subsystems The pipeline evaluates each message block independently and fails open. If any compression step raises an exception, the payload passes through unchanged. | Component | Implementation | Function | | :--- | :--- | :--- | | **Proxy Control Plane** | Python (FastAPI / Uvicorn) | Listens on port 8787, intercepts `/v1/messages` and `/v1/chat/completions`, and handles provider routing. | | **Rust Acceleration Core** | `crates/headroom-core` | High-throughput parsing, Blake3 hashing, SimHash fingerprinting, Aho-Corasick matching, and DashMap storage. | | **ContentRouter** | Hybrid Rust / Python | Detects payload formats using Google Magika ONNX classifier and regex heuristics, routing each block to one compressor. | | **SmartCrusher** | Rust / Python | Compresses JSON arrays of dicts, strings, and numbers using statistical variance and Kneedle elbow detection. | | **Log & Search Compressors** | Rust native | Strips repetitive file prefixes and passing logs while protecting anomaly lines matching errors or exceptions. | | **CodeCompressor** | Tree-sitter (11 languages) | AST-aware code compression. Gated behind strict safety rules and disabled during active code editing. | | **CCR Store** | SQLite / DashMap | Caches full uncompressed content locally, keyed by 24-character Blake3 hashes for on-demand retrieval. | | **Output Shaper** | Proxy middleware | Injects tail system prompts for verbosity control and routes reasoning effort on thinking models. | ### SmartCrusher: Statistical JSON Reduction Tool outputs from database queries, Kubernetes APIs, and REST endpoints consist primarily of JSON arrays. SmartCrusher optimizes these payloads through a multi-stage statistical pipeline: 1. **Schema and Array Detection**: Validates JSON structure. Arrays containing fewer than five items or under 200 tokens pass through untouched. 2. **Kneedle Elbow Sizing**: Calculates bigram coverage curves to determine the exact retention threshold where additional items provide diminishing semantic return. 3. **SimHash Deduplication**: Groups near-duplicate dictionary entries and retains representative prototypes. 4. **Zlib Diversity Validation**: Compresses candidate subsets with DEFLATE to verify that semantic entropy matches the full dataset. 5. **Mandatory Anomaly Gates**: Regardless of the target compression budget, SmartCrusher never drops entries containing error keywords ("error", "exception", "failed", "critical"), numeric anomalies exceeding two standard deviations from the mean, or length outliers. ### Live-Zone-Only Context Management Earlier releases of Headroom included experimental rolling-window context managers that dropped older turns to fit token limits. That architecture was removed. Headroom version 0.37.0 enforces live-zone-only processing: - It never deletes, reorders, or summarizes historical conversation turns. - It compresses tool results and file reads in place within the newest turn. - System prompts and user instructions pass through untouched, maintaining full compatibility with provider KV prefix caches. --- ## 3. Reversible Compression (CCR) The central architectural compromise of traditional prompt compression is lossiness. If an optimizer drops a file path or log line that the model later requires, the agent fails. Headroom addresses this with Compress-Cache-Retrieve (CCR): ``` Step 1: Compression SmartCrusher compresses 1,000 JSON items down to 20 items. Step 2: Caching The original 1,000 items are written to a local SQLite database (ccr_store.db) keyed by Blake3 hash 'a7f9c2'. Step 3: Marker Injection Headroom appends a marker to the compressed tool output: [1000 items compressed to 20. Retrieve more: hash=a7f9c2] Step 4: Tool Injection Headroom injects the 'headroom_retrieve' function into the request payload: { "name": "headroom_retrieve", "description": "Retrieve original uncompressed data from Headroom cache", "parameters": { "hash": "The hash key from the compression marker" } } Step 5: Resolution - Scenario A: The model answers using the 20 representative items. 90% token savings realized. - Scenario B: The model needs the full dataset and calls headroom_retrieve('a7f9c2'). The Headroom proxy intercepts the tool call, fetches the original content from SQLite in ~1ms, and supplies the full data back to the model without human intervention. ``` On Anthropic and OpenAI proxy paths, Headroom handles CCR resolution transparently. The client agent never sees intermediate retrieval round trips. --- ## 4. Visual Tour & Interface Workflows Headroom visualizes token reduction through local metrics, terminal telemetry, and an integrated real-time dashboard. ### Context Compression Pipeline ![Headroom context compression diagram](/images/reframehub/headroom/hero.svg) The diagram above documents a real SRE incident payload. A 55,957-token prompt containing thousands of container log lines is compressed to 24,340 tokens, representing a 57% input reduction. The critical `FATAL` error log at line 67 is detected by the anomaly gate and preserved byte for byte. ### Live Cache and Savings Dashboard Running `headroom dashboard` opens the local browser UI served directly from the proxy process: ![Headroom live dashboard and cache TTL metrics](/images/reframehub/headroom/dashboard.webp) The dashboard surfaces three critical operational metrics: 1. **Total Input Tokens Saved**: Aggregate volume and dollar savings calculated against model list prices. 2. **Cache Hit Rates**: Ratio of turns that successfully matched provider prefix caches. 3. **CCR Store Utilization**: Active keys, storage footprint, and cache eviction cycles in the local SQLite database. --- ## 5. Total Cost of Ownership (TCO) Comparison Headroom is free, open-source software under the Apache 2.0 license. Operating costs are limited to local machine compute or low-cost server infrastructure. ### Workload Modeling: 10-Engineer Agentic Team Consider a software engineering team of 10 developers using Claude Code or Cursor. Each developer runs 30 agent turns per day, averaging 60,000 input tokens and 1,500 output tokens per turn on Claude 3.7 Sonnet ($3.00/M input, $15.00/M output). - **Baseline Daily Input Volume**: 10 devs x 30 turns x 60,000 tokens = 18,000,000 tokens/day ($54.00/day). - **Baseline Monthly Input Cost**: ~22 working days = $1,188.00/month. - **Headroom Compression Savings**: Measured 35% average reduction on coding agent workflows (JSON, search, logs). - **Net Input Tokens Saved**: 6,300,000 tokens/day (~$415.80/month saved). - **Annual Token Cost Avoidance**: ~$4,989.60/year. | Dimension | Managed Enterprise Agent Platforms | Headroom (Self-Hosted OSS) | | :--- | :--- | :--- | | **Software License** | $40 to $500 / user / month (Devin, etc.) | **$0 / month** (Apache 2.0) | | **Proxy & Storage Infrastructure** | Bundled in vendor markup | **$0** (Local laptop) or **$10/mo** (Shared team VPS) | | **Model Token Pricing** | 15% to 50% vendor platform markup | **Raw Provider Rates** (Direct API keys) | | **Context Retention Policy** | Proprietary cloud storage | **Local SQLite** (`~/.headroom/ccr_store.db`) | | **Data Privacy Boundaries** | Transcripts stored on third-party cloud | **100% On-Device** (Payloads never leave machine) | | **Annual Software Cost (10 Devs)** | **$4,800 to $60,000+ / year** | **$0 to $120 / year** (Compute only) | | **Net Annual Token Savings** | $0 (Vendor captures margin) | **~$4,900+ saved** in direct API expenses | --- ## 6. The Bad: What to Know Before Adopting Operating Headroom in real development environments reveals distinct constraints: ### 1. `HEADROOM_BEACON` is Enabled by Default Headroom contains two separate telemetry systems. While `HEADROOM_TELEMETRY` is off by default, `HEADROOM_BEACON` is **enabled by default (opt-out)**. On each request, it transmits an anonymous summary payload to remote servers. This payload includes token counts, compression ratios, model identifiers, skip reasons, OS, and architecture. Although the collector allowlists counters and strips message contents, teams handling regulated data or operating in air-gapped environments must explicitly disable this flag at startup: ```bash export HEADROOM_BEACON=off # or set the cross-tool convention: export DO_NOT_TRACK=1 ``` ### 2. Code Compression is Bypassed in Most Coding Sessions Headroom includes an AST-based `CodeCompressor` using tree-sitter grammars. In practice, code compression rarely fires during interactive development. Two protective safety gates prevent it: - `protect_recent_code=4`: Source code blocks in the four most recent messages are never compressed. - `protect_analysis_context=True`: If the user message contains words like "analyze", "review", "explain", "fix", or "debug", all code compression is disabled across the entire conversation. Because almost every developer prompt contains these terms, code passes through uncompressed. Headroom savings on coding agents come almost entirely from tool outputs, directory listings, grep results, and test logs, not from compressing source code. ### 3. Small Payloads Produce Negative ROI Requests with tool outputs below 50 tokens are bypassed by default. For small prompts, parsing JSON, computing SimHash fingerprints, and executing the FastAPI proxy middleware introduces 1ms to 3ms of overhead without saving meaningful tokens. Headroom is optimized for heavy multi-turn agent workflows, not single-turn chatbots. ### 4. CCR Roundtrip Latency on Model Misses When SmartCrusher compresses an array and the LLM determines that it cannot answer without the missing items, the model issues a `headroom_retrieve` tool call. While local SQLite retrieval takes less than 2 milliseconds, the resulting network round trip back to Anthropic or OpenAI costs between 800ms and 2,500ms. If a workload frequently triggers CCR retrieval, the added inference latency can outweigh the token savings. ### 5. Native Extension Build Requirements Headroom relies on a compiled Rust extension (`headroom._core`) and ONNX Runtime. Prebuilt wheels are published on PyPI for standard architectures, but custom container builds (Alpine Linux musl or older Python versions) require a full Rust toolchain, `maturin`, and C compilers to build tree-sitter bindings. --- ## 7. Quickstart & Deployment Headroom can be deployed as an agent wrapper, a standalone proxy, or an inline SDK. ### Option A: Wrap an Existing Agent (Zero Config) The `headroom wrap` command starts the local proxy in the background, configures environment variables, and launches the coding agent: ```bash # 1. Install CLI and optional extras pip install "headroom-ai[all]" # 2. Wrap Claude Code headroom wrap claude # 3. Wrap Codex or Cursor headroom wrap codex headroom wrap cursor # 4. Remove wrappers when finished headroom unwrap claude ``` ### Option B: Standalone HTTP Proxy Run the proxy as a local service and point your API clients to port 8787: ```bash # Start proxy with default settings export HEADROOM_BEACON=off headroom proxy --port 8787 # Configure tools to route through proxy export ANTHROPIC_BASE_URL="http://127.0.0.1:8787" export OPENAI_BASE_URL="http://127.0.0.1:8787/v1" ``` ### Option C: Inline Python Compression To integrate context optimization directly into custom applications: ```python from headroom import compress from openai import OpenAI messages = [ {"role": "system", "content": "You are an automated code reviewer."}, {"role": "user", "content": "Inspect this test log output:"}, {"role": "user", "content": open("heavy_test_run.log").read()} ] # Compress payload before inference result = compress(messages, model="gpt-4o") client = OpenAI() response = client.chat.completions.create( model="gpt-4o", messages=result.messages ) print(f"Original tokens: {result.original_tokens}") print(f"Tokens sent: {result.compressed_tokens}") print(f"Saved: {result.tokens_saved} ({result.compression_ratio:.1%})") ``` ### Option D: TypeScript SDK ```typescript import { compress } from "headroom-ai"; const messages = [ { role: "system", content: "You are an automated triage assistant." }, { role: "user", content: JSON.stringify(largeApiPayload) } ]; const result = await compress(messages, { model: "claude-3-7-sonnet" }); console.log(`Saved ${result.tokens_saved} tokens`); ``` --- ## 8. ReframeHub Architectural Insight The primary engineering insight in Headroom is that **reversible compression decouples token budgets from reasoning loss**. Traditional prompt compression treated token reduction as an information-loss problem. Optimizers attempted to predict which words an LLM might need, leading to conservative compression ratios (10% to 20%) or catastrophic hallucinations when essential tokens were dropped. By introducing a local, low-latency key-value store (CCR) and injecting a standardized retrieval tool, Headroom transforms prompt optimization into a **hierarchical cache problem**: - The prompt sent to the LLM functions as an index or abstract. - The local SQLite database functions as primary storage. - The model itself acts as the cache-invalidation agent, retrieving full payloads only when the index proves insufficient. This architecture proves that token optimization does not require larger context windows or smaller models. It requires treating the LLM context window as a transient CPU cache rather than a permanent database. --- ## 9. Who Should Use This? ### Good Fit - **Teams running high-volume coding agents**: Engineering teams spending thousands of dollars monthly on Claude Code, Cursor, Codex, or OpenClaw sessions. - **Data-heavy agent pipelines**: Applications that regularly pass database records, JSON dumps, API responses, or CI logs into agent context. - **Privacy-sensitive deployments**: Organizations that need token reduction without routing prompts through third-party cloud optimization proxies. ### Bad Fit - **Short, single-turn conversational chatbots**: Customer-facing chat widgets where prompts average under 200 tokens. - **Code-only editing without tool execution**: Workflows that only read and write small source files without invoking tests, build scripts, or terminal commands. - **Zero-latency real-time voice agents**: Applications where a 2-millisecond proxy evaluation or potential CCR retrieval round trip violates strict sub-second response budgets. ## ReframeHub: Hermes Agent - Path: https://emiote.com/reframehub/hermes-agent/ - Category: AI & Agents - Description: Open-source self-improving AI agent by Nous Research with persistent memory, autonomous skill synthesis, and a multi-platform messaging gateway. - Pricing / Model: open-source (Self-host: $0/mo local CLI / $5/mo VPS (+ raw API usage via OpenRouter/Nous Portal), Cloud: Devin from $500/mo; cloud agent platforms from $40–$200/user/mo) - Snapshot Date: 2026-09-01 > **Hermes Agent** is an open-source, self-hosted autonomous AI agent framework created by [Nous Research](https://github.com/NousResearch/hermes-agent) designed as a pay-as-you-go alternative to commercial agent platforms like Devin and proprietary chatbot gateways. Built with Python, a unified multi-platform messaging gateway, and persistent SQLite FTS5 memory, it features autonomous skill creation, scheduled automation, and isolated subagent delegation across local, Docker, and cloud runtimes. --- ## 1. Why Hermes Agent Matters: The End of Ephemeral Chatbots Most AI coding assistants and commercial agent platforms suffer from **amnesia by design**. Every new session wipes the slate clean: you re-explain your directory structure, re-paste API keys, and manually restate architectural conventions. Commercial cloud workbenches like **Cognition's Devin** ($500/mo) and proprietary agent gateways charge exorbitant per-seat retainers while forcing your code, credentials, and conversation history through third-party proprietary clouds with mandatory model markups. ``` Proprietary Cloud Agent: [User Chat] ---> [Proprietary Cloud Broker] ---> [Locked Model Provider] ---> [Ephemeral Cloud VM] ($500/mo retainer) (200-500% token markup) (Data wiped on reset) Hermes Agent (Local & Open-Source): [Any Chat / TUI] ---> [Unified Gateway Daemon] ---> [Raw API / Local LLM] ---> [Isolated Runtime] (Telegram/Slack/CLI) (100% Owned $0/mo) (OpenRouter/Portal/Ollama) (Docker/SSH/Modal/Daytona) | v [Persistent Memory Loop] (MEMORY.md + FTS5 SQLite + Skills) ``` **Hermes Agent breaks the single-session silo with a self-improving operational posture:** 1. **Closed-Loop Learning**: When Hermes solves a non-trivial engineering task, it extracts the underlying reasoning and tool pattern into an explicit, versioned procedure conforming to the open `agentskills.io` standard. As the agent encounters new edge cases, it updates and refines these skills in place. 2. **Dual-Tier Persistent Memory**: Combines deterministic markdown context files (`MEMORY.md` for project facts, `USER.md` for developer preferences) with a high-performance **SQLite FTS5 full-text search index** for semantic cross-session retrieval and dialectic user modeling via Honcho. 3. **Omnipresent Messaging Gateway**: A single lightweight daemon connects Telegram, Discord, Slack, WhatsApp, Signal, email, and native terminal TUIs. You can kick off a complex multi-hour refactor from your terminal, step away, and inspect live progress or send voice instructions from Telegram. 4. **Model-Agnostic Engine**: Switch providers on the fly with `hermes model`—connect Nous Portal, OpenRouter, Anthropic, OpenAI, or local vLLM / Ollama endpoints with zero markup and zero code changes. ![Hermes Desktop & Terminal Interface](/images/reframehub/hermes-agent/showcase.png) --- ## 2. Multi-Platform Connectivity: Lives Where You Work Rather than confining engineering workflows to a browser tab or an isolated Electron app, Hermes Agent implements a unified **Tool Gateway** architecture that treats messaging protocols as first-class input/output interfaces. <div class="my-6 rounded-xl border border-line bg-surface p-6"> <h4 class="font-mono text-xs uppercase tracking-wider text-muted">Gateway Surface Protocol Architecture</h4> <div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 font-mono text-xs"> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Mobile & Desktop Chat</span> <p class="mt-1 text-muted">Telegram, Discord, Slack, WhatsApp, Signal with native voice memo transcription via Whisper & ffmpeg.</p> </div> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Native Terminal TUI</span> <p class="mt-1 text-muted">Full-screen terminal interface with multiline prompt buffer, slash autocomplete, and live tool stream rendering.</p> </div> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Async Automation Relays</span> <p class="mt-1 text-muted">Natural-language cron scheduler delivering unattended daily briefings, PR summaries, and system health checks.</p> </div> </div> </div> ![Multi-Platform Gateway Connectivity](/images/reframehub/hermes-agent/feature-connect.png) ### Key Gateway Capabilities - **Cross-Platform Thread Continuity**: Conversations initiated on the command line can be resumed seamlessly via mobile messaging apps with unified memory synchronization. - **Native Audio Pipeline**: Send voice memos directly via Telegram or WhatsApp; the gateway automatically transcribes audio using bundled `ffmpeg` and Whisper models before routing to the agent core. - **Interrupt and Redirect**: Real-time streaming tool execution can be interrupted mid-flight directly from any chat client or terminal buffer without killing the background supervisor. --- ## 3. Persistent Memory & Autonomous Skill Synthesis Hermes Agent implements a structured learning loop that bridges the gap between static system prompts and dynamic operational experience. ![Persistent Memory and Autonomous Skills](/images/reframehub/hermes-agent/feature-memory.png) ### Memory and Learning Subsystems | Subsystem | Storage Mechanism | Operational Role | | :--- | :--- | :--- | | **Environment State** | `MEMORY.md` | Tracks repository architecture, database schemas, deployed endpoints, and build flags. Injected directly into root system prompts. | | **User Profile** | `USER.md` | Records communication preferences, timezone constraints, coding idioms, and workflow requirements. | | **Session Search Index** | SQLite FTS5 (`native/fts5_cjk`) | Indexes every conversation turn with CJK tokenizer support. When recalling past context, the agent runs FTS5 queries and synthesizes relevant turns using an LLM summarizer. | | **Autonomous Skills** | `~/.hermes/skills/` | Synthesizes verified multi-step workflows into reusable procedural documents (`agentskills.io` standard) that are auto-discovered on subsequent runs. | | **Dialectic Modeling** | Honcho Integration | Builds a continuous user theory-of-mind model across multi-turn interactions, distinguishing temporary user queries from permanent user preferences. | --- ## 4. Execution Backends & Subagent Parallelization Autonomous execution requires strong isolation to prevent destructive commands from compromising production machines or host environments. Hermes Agent supports **7 decoupled terminal execution backends**: ``` [Hermes Agent Supervisor] | +------------------------------+------------------------------+ | | | [Local Workstation] [Container Sandboxes] [Serverless / Cloud] - Local Host CLI - Docker Containers - Modal Serverless Python - Bundled Git Bash - Singularity (HPC) - Daytona Workspaces - SSH Remote Hosts - Vercel Sandboxes ``` ### Supported Execution Backends 1. **Local Host**: Direct execution on Linux, macOS, or Windows (via isolated bundled MinGit bash). 2. **Docker**: Ephemeral or persistent containerized environments with strict resource constraints. 3. **SSH Remote**: Dispatches commands to remote staging or production servers via secure SSH tunnels. 4. **Singularity**: Optimized for High-Performance Computing (HPC) clusters and scientific computing environments. 5. **Modal**: Serverless Python container execution that hibernates when idle and boots on-demand in milliseconds. 6. **Daytona**: Cloud development workspaces with complete filesystem and environment persistence. 7. **Vercel Sandbox**: Secure, microVM-isolated execution for edge and web applications. ### Subagent Parallelization & RPC Scripting When faced with multi-faceted engineering tasks (e.g. refactoring a database schema while migrating frontend components), Hermes Agent can **spawn isolated subagents** that execute in parallel sandboxes. Additionally, Hermes supports a **Python RPC Tooling Mode**: instead of emitting dozens of individual JSON tool calls (each incurring round-trip LLM latency and context overhead), the agent generates a single Python script that executes multiple tool operations locally over an internal RPC interface, returning only the finalized output. ![Scheduled Automations and Background Jobs](/images/reframehub/hermes-agent/feature-automation.png) --- ## 5. Total Cost of Ownership (TCO) Comparison | Dimension | Devin / Proprietary Agent Cloud | Hermes Agent (Self-Hosted OSS) | | :--- | :--- | :--- | | **Software License** | $500 / month (Devin Enterprise) | **$0 / month** (MIT Open Source) | | **Gateway & Messaging** | $50 – $200 / mo (Botpress / Flowise Cloud) | **$0** (Included native multi-platform daemon) | | **Model & Token Billing** | 200%–500% proprietary cloud markup | **100% Raw API cost** (Nous Portal, OpenRouter, Ollama) | | **Compute Infrastructure** | Proprietary cloud instances only | **$0 local / $5/mo VPS / Serverless on-demand** | | **Memory & Data Privacy** | Stored on vendor cloud databases | **100% Local / Self-Owned** SQLite + Markdown | | **Skill & Tool Extensibility** | Closed proprietary actions | **Open `agentskills.io` + Python RPC** | | **Total Annualized Cost** | **$6,000 – $12,000+ / yr** | **~$60 – $300 / yr** (+ raw model token usage) | --- ## 6. The Bad — What to Know Before Adopting While Hermes Agent provides an exceptionally robust, vendor-free agent harness, engineering teams must understand these operational realities: 1. **Token Burn on Unconstrained Self-Improvement Loops**: Autonomous skill creation and self-refinement loops can rapidly consume tokens if an agent encounters a difficult task and repeatedly retries failed steps. Always configure max-iteration bounds and per-session cost caps when running against high-tier models. 2. **Security Posture on Chat Gateways**: Exposing an agent with local host or Docker execution permissions to Telegram, Discord, or Slack requires strict authorization discipline. If channel whitelist IDs or user permission flags are misconfigured, any authorized chat member could trigger shell execution. Enforce Docker or SSH isolation for shared channels. 3. **Gateway Daemon Process Lifecycle**: Running a background daemon that maintains simultaneous websockets and webhooks across 5+ messaging platforms requires process supervision (e.g. `systemd` or `supervisord`). Transient network hiccups or upstream API rate limits must be monitored. 4. **When to Stay on Commercial SaaS**: If your team requires zero-setup out-of-the-box IDE code completion with SOC2 Type II certifications and corporate enterprise SSO, standard managed copilots remain the appropriate choice. --- ## 7. Quickstart & Deployment Recipes ### Step 1: Install Hermes Agent #### Linux, macOS, WSL2, or Termux ```bash curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash ``` #### Windows (Native PowerShell) ```powershell iex (irm https://hermes-agent.nousresearch.com/install.ps1) ``` The installer automatically configures `uv`, Python 3.11+, Node.js, `ripgrep`, `ffmpeg`, and an isolated MinGit bash runtime without requiring administrator privileges. ### Step 2: Configure Model Provider Select your preferred model endpoint (Nous Portal, OpenRouter, OpenAI, Anthropic, or Local Ollama): ```bash # Launch interactive model selector hermes model # Or set provider keys directly export OPENROUTER_API_KEY="sk-or-v1-..." ``` ### Step 3: Start the Terminal TUI or Messaging Gateway ```bash # Launch full-featured interactive Terminal TUI hermes # Or launch background multi-platform messaging gateway hermes gateway --telegram --discord ``` --- ## 8. Studio Reframe Evaluation If your product team is architecting autonomous AI agent workflows, deciding between closed commercial workbenches (Devin/Operator) and open, self-improving agent harnesses (Hermes Agent / OpenMausBot / Buzz), book an **Emiote Stack Review** ($199 USD). We evaluate execution sandboxing, gateway security boundaries, persistent memory schemas, and token unit economics to build resilient agent infrastructure. ## ReframeHub: Maestro - Path: https://emiote.com/reframehub/maestro/ - Category: Developer Tools - Description: Mobile-dev's open-source declarative mobile UI testing framework using dadb and XCTest to drive Android, iOS, and web without flakiness. - Pricing / Model: open-source (Self-host: $0 local CLI / emulator; CI runner compute (Mac/Linux instances) owned by you, Cloud: Maestro Cloud from $250/device/month (parallel hosted Android, iOS, web)) - Snapshot Date: 2026-09-04 **Maestro** is an open-source, declarative mobile UI testing framework from mobile.dev that automates Android, iOS, and web applications through human-readable YAML flows. It replaces compiled test suites and fragile driver servers by interacting directly with the native operating system accessibility tree via `dadb` and XCTest, delivering resilient cross-platform testing with native Model Context Protocol support for AI coding agents. ## Scope and currency This is an **architecture evaluation**, not an enterprise device-farm deployment diary. In September 2026 we reviewed the official [Maestro GitHub repository](https://github.com/mobile-dev-inc/maestro), source architecture (`dadb`, `maestro-client`, iOS runner), the [official documentation](https://docs.maestro.dev), the [Maestro MCP Server specification](https://docs.maestro.dev/get-started/maestro-mcp), and published Maestro Cloud pricing tiers. **We evaluated Maestro across local Android emulators, iOS simulators, and Claude Code agent workflows.** Release binaries, driver hooks, and cloud concurrency plans evolve; verify current specifications before committing your mobile release pipeline. Editorial review: `2026-09-04`. ## What it is Maestro is an open-source (**Apache 2.0**) cross-platform mobile automation engine engineered by [mobile.dev](https://mobile.dev). Instead of forcing engineering teams to write imperative test code in Swift, Kotlin, Java, or JavaScript—or wrestle with brittle Selenium-based mobile bridges—Maestro treats mobile applications as **black-box state machines** driven by interpreted YAML declarations called **Flows**. A standard Maestro Flow defines user intent in plain syntax: ```yaml appId: com.example.notes --- - launchApp - tapOn: "Create New Note" - inputText: "Release Architecture" - tapOn: "Save" - assertVisible: "Release Architecture" ``` Under the hood, Maestro operates at arm's length from the app binary: 1. **No SDK instrumentation required** — You run tests against release, staging, or debug APKs, IPAs, or simulators without adding test libraries or test harnesses into your production code. 2. **Accessibility-first targeting** — It queries the operating system's native accessibility hierarchy (AccessibilityNodeInfo on Android, AXUIElement on iOS) rather than internal component trees or pixel coordinates. 3. **Smart waiting by default** — It automatically retries interactions and waits for UI animations, network updates, and layout shifts to settle, eliminating arbitrary `Thread.sleep(5000)` statements that plague legacy mobile suites. 4. **Native MCP Server integration** — Bundles a local Model Context Protocol server (`maestro mcp`) that lets AI coding agents (Claude Code, Codex, Cursor, Gemini) inspect the active view hierarchy, author tests, and verify mobile features autonomously. ### Visual tour: The Maestro workflow ![Maestro official web landing page showcasing agentic UI testing and cross-platform automation](/images/reframehub/maestro/browser-preview.png) *The Maestro workflow: declarative YAML flows running across Android, iOS, and web surfaces.* ![Maestro MCP documentation outlining agentic tools, screen inspection, and interactive mobile device control](/images/reframehub/maestro/mcp-preview.png) *Maestro MCP enables AI coding agents to query device view hierarchies and assert UI state in real time.* ## What it replaces & why it matters Mobile end-to-end testing has historically suffered the highest maintenance burden and lowest ROI in software engineering. Teams typically abandon mobile UI test suites within 12 months because of three structural problems: | Legacy Tooling | Core Architectural Failure | How Maestro Fixes It | | :--- | :--- | :--- | | **Appium / Selenium** | Heavy HTTP/JSON-Wire server process between runner and device; frequent server crashes and session disconnects. | Replaced by single local CLI binary and `dadb` direct socket protocol; zero standalone server daemons. | | **Detox** | Requires white-box synchronization hooks compiled into the React Native app binary; breaks during major RN or React Native New Architecture upgrades. | Pure black-box testing from the outside; operates via OS accessibility tree regardless of React Native, Flutter, or native Swift/Kotlin. | | **Espresso & XCUITest** | Platform-siloed codebases (Kotlin vs Swift); requires full app compilation before running; duplicates test suites across platforms. | Unified YAML flow syntax runs identically on iOS simulators, Android emulators, and web Chromium instances. | ## Architecture & tech stack review Maestro is implemented as a modern JVM/Kotlin monorepo designed around clean protocol abstractions and zero-compilation execution. ```mermaid flowchart TD subgraph Authoring["1. Test Authoring & Agents"] Agent["AI Coding Agent<br/>(Claude Code / Cursor / Codex)"] Human["Developer / QA<br/>(Maestro Studio / YAML)"] end subgraph Core["2. Maestro Orchestration Core"] MCP["Maestro MCP Server<br/>(stdio / JSON-RPC)"] CLI["Maestro CLI Engine<br/>(Interpreted YAML Runner)"] SmartWait["Smart Waiting & Tolerance<br/>(Element Polling / Auto-retry)"] end subgraph Bridges["3. Platform Driver Bridges"] DADB["dadb Bridge<br/>(Kotlin Direct Socket to ADB)"] XCTest["xcrun simctl & XCUITest Bridge<br/>(Native Driver Process)"] Playwright["Chromium Web Driver<br/>(DevTools Protocol)"] end subgraph Targets["4. Execution Surface"] AndroidTarget["Android Device / Emulator<br/>(Accessibility Node Hierarchy)"] iOSTarget["iOS Device / Simulator<br/>(AXUIElement Accessibility Tree)"] WebTarget["Web Browser App<br/>(DOM & Accessibility)"] end Agent -->|Tools: run / inspect_screen| MCP Human -->|maestro test flow.yaml| CLI MCP --> CLI CLI --> SmartWait SmartWait --> DADB SmartWait --> XCTest SmartWait --> Playwright DADB -->|TCP socket / no adb server| AndroidTarget XCTest -->|XCTest commands| iOSTarget Playwright -->|CDP| WebTarget ``` ### The Android engine: `dadb` Traditional Android automation communicates through the standard `adb` client-server architecture (`adb client -> adb server daemon -> adbd on device`). In CI environments running parallel tests, the host ADB server process frequently hangs, drops socket connections, or deadlocks on port allocations. To eliminate this failure mode, the mobile.dev team authored **`dadb`** (Direct ADB): a pure Kotlin implementation of the ADB communication protocol. Maestro connects directly to the Android device or emulator over raw TCP sockets (`localhost:5555`). By bypassing the desktop ADB server binary entirely, Maestro achieves deterministic connection lifecycle management and vastly lower connection latency in CI pipelines. ### The iOS engine: `xcrun simctl` + XCTest runner bridge iOS simulator automation operates through Apple's native toolchain. Maestro orchestrates app lifecycle events (install, launch, terminate, erase) via `xcrun simctl` sub-processes. To inspect the iOS accessibility tree and dispatch touch and gesture events, Maestro launches a lightweight, pre-built background XCTest runner process that hooks into Apple's private `XCUIDevice` and `XCUIApplication` accessibility APIs. ### The UI abstraction: Accessibility tree, not DOM Because Maestro targets native applications built in UIKit, SwiftUI, Jetpack Compose, React Native, and Flutter, it does not rely on a document object model (DOM). Instead, it queries the operating system accessibility layer: - On Android, it parses the active window's `AccessibilityNodeInfo` tree. - On iOS, it traverses `AXUIElement` nodes. This design gives Maestro two massive advantages: 1. **Framework neutrality:** It does not care whether an element was rendered by React Native's Yoga layout engine, Flutter's Skia/Impeller canvas, or native Swift. If an element is accessible to a human user or screen reader, Maestro can see it, tap it, and assert its value. 2. **Accessibility enforcement by design:** If a button or input cannot be located by text or accessibility label, your app is broken for disabled users. Maestro tests naturally act as an automated accessibility audit. ## The agentic closed-loop: Maestro MCP The most consequential evolution in Maestro is its native **Model Context Protocol (MCP)** implementation. By running `maestro mcp`, Maestro exposes its entire device introspection and execution engine to AI coding assistants over stdio. ```mermaid sequenceDiagram autonumber actor Dev as Developer participant Agent as Claude Code / Codex participant MCP as Maestro MCP Server participant Device as iOS Simulator / Android Emulator Dev->>Agent: "Build login screen and verify with Maestro" Agent->>Agent: Generate UI code in React Native / Flutter Agent->>MCP: Call inspect_screen MCP->>Device: Dump accessibility hierarchy Device-->>MCP: Return JSON view tree MCP-->>Agent: Compact element list (buttons, inputs) Agent->>Agent: Reason on screen state & draft test flow Agent->>MCP: Call run with inline YAML flow MCP->>Device: Execute tapOn(Email) & inputText(...) MCP->>Device: Execute tapOn(Submit) & assertVisible(Home) Device-->>MCP: Flow assertion passed MCP-->>Agent: Test status: SUCCESS Agent->>Dev: "Feature built and verified against live simulator" ``` ### Exposed MCP tools | Tool | Purpose in the Agent Loop | | :--- | :--- | | `list_devices` | Discovers available local emulators, simulators, and web browsers. | | `inspect_screen` | Dumps the active device screen hierarchy as compact, LLM-token-efficient JSON. The agent calls this to understand what is on screen before acting. | | `take_screenshot` | Captures the active visual frame for multimodal vision models to verify visual styling or resolve ambiguous buttons. | | `run` | Executes inline YAML flow commands (`yaml: "- tapOn: Submit"`) or flow files with instant validation and error diagnostics. | | `cheat_sheet` | Provides Maestro flow syntax and assertions directly into the agent's context window. | | `open_maestro_viewer` | Opens an interactive web stream showing the live simulator and active command trace. | | `list_cloud_devices` | Enumerates hosted cloud device models and OS versions. | | `run_on_cloud` | Submits local flow suites to Maestro Cloud for distributed parallel execution. | This closes the development feedback loop: an AI agent writing mobile code no longer has to guess whether a button rendered correctly or wait for a human developer to manually click through an emulator. ## Cost breakdown: TCO review Maestro is open-source under Apache 2.0. The CLI, Studio, Viewer, and MCP server are free to run locally and in your self-hosted CI pipelines. The commercial tier is **Maestro Cloud**, a purpose-built hosted device cloud for parallel test execution. | Dimension | Maestro Local / OSS | Maestro Cloud (Managed) | Legacy Farms (BrowserStack / Sauce) | | :--- | :--- | :--- | :--- | | **Software License** | $0 (Apache 2.0) | Included in device subscription | $0 for Appium runner; closed platform | | **Device Execution** | Self-hosted emulators / simulators | Dedicated cloud devices (iOS, Android, Web) | Shared cloud device VMs | | **Monthly Pricing** | $0 software fee | **$250 / concurrent device / mo** | ~$199 – $399+ / concurrent session / mo | | **Annual Baseline** | $0 software fee | **$3,000 / device / yr** | ~$2,388 – $4,788+ / session / yr | | **CI Compute Burden** | High (macOS runners cost 10x Linux runners) | Minimal (triggers via API/CLI; execution offloaded) | Low (offloaded to vendor grid) | | **Flakiness Overhead** | Low (smart waiting, direct socket) | Lowest (parallel runs on clean instances) | High (Appium proxy latency, session timeouts) | | **Ops Responsibility** | You manage emulators, Xcode, and CI agents | Managed by mobile.dev | Managed by vendor | ### The hidden cost of self-hosting iOS CI While Maestro itself is free, teams automating iOS locally in CI face a steep infrastructure tax: **macOS runners**. On GitHub Actions, standard Linux runners cost ~$0.008/minute, while Apple Silicon macOS runners cost ~$0.08/minute—a **10x multiplier**. Running a 30-minute end-to-end regression suite across 20 pull requests daily costs: ```text 20 PRs × 30 min × $0.08/min = $48/day ≈ $1,056/month ``` This economic reality makes Maestro Cloud ($250/device/month with unlimited runs per concurrent device) or dedicated in-house Mac mini hardware clusters significantly more economical for mid-sized engineering teams than spinning up ephemeral cloud macOS VMs for sequential test runs. ## The Good - **Single cross-platform syntax:** The same `.yaml` file drives Android and iOS flows with zero platform-specific if/else boilerplate. - **Zero SDK binary pollution:** Works directly on release `.ipa` and `.apk` production builds without modifying application source code or build flavors. - **Deterministic socket communication:** Direct Kotlin `dadb` socket architecture eliminates the persistent ADB server hang-ups that plague Android CI pipelines. - **First-class AI agent integration:** The bundled `maestro mcp` server turns Claude Code, Cursor, and Codex into fully autonomous mobile engineers. - **Fast execution:** Flows are interpreted on the fly without waiting for a compilation step. Updating a test takes seconds, not minutes. - **Built-in flakiness tolerance:** Smart waiting, automatic retries, and scroll-to-view heuristics dramatically reduce false-positive test failures. ## The Bad — what to know before adopting 1. **Strict black-box boundary:** Maestro cannot inspect private Swift/Kotlin variables, mock internal database states, or assert in-memory method invocations. If your testing strategy relies on white-box dependency injection, you will still need unit tests (JUnit / XCTest). 2. **Complex multi-touch gesture limits:** While tap, double-tap, long-press, scroll, swipe, and basic pinch are supported, intricate multi-finger custom gestures (such as CAD rotation or multi-finger drawing surfaces) are difficult or impossible to express cleanly in declarative YAML. 3. **Hybrid WebView inspection depth:** While Maestro can interact with elements inside WebViews that expose accessibility properties, it does not provide deep DOM inspection or network mocking parity with pure-web runners like Playwright. 4. **Host runtime dependency:** Maestro requires **Java 17 or higher** installed on the host machine. In lightweight containerized pipelines, you must ensure a JDK runtime is provisioned alongside the Android SDK. 5. **macOS requirement for iOS simulation:** Running iOS tests locally or in CI requires macOS with Xcode installed. There is no headless Linux path for native iOS simulation without offloading to Maestro Cloud or remote macOS hardware. ## When to use / When to skip ### Use Maestro if: - You build mobile applications with **React Native, Flutter, native Swift/Kotlin, or Expo** and need fast, repeatable smoke and regression flows. - You are tired of spending 20 hours a week fixing flaky Appium or Detox tests that break when timing shifts. - You want QA engineers, product managers, or founders to read, write, and audit test flows without knowing Swift or Kotlin. - You are implementing **agentic development workflows** using Claude Code, Codex, or Cursor and need your agent to test what it builds on a live device. - You want to test release builds identical to what ships to the Apple App Store and Google Play Store. ### Skip Maestro if: - You only build web applications. Stay on **Playwright**—it provides superior network interception, DOM tracing, and browser engine control. - You need deep white-box unit testing of private classes or in-memory state mocks. Use native **XCTest / Espresso**. - Your application relies on complex gaming physics, custom 3D engines (Unity/Unreal), or non-accessible custom-drawn canvas controls that do not expose accessibility metadata. - Your team lacks access to macOS infrastructure for iOS testing and has zero budget for Maestro Cloud. ## ReframeHub insight: Why declarative accessibility wins The deeper engineering lesson of Maestro is the power of choosing the right **abstraction boundary**. For a decade, mobile test automation tried to emulate web testing: inspect the internal view hierarchy, extract proprietary component identifiers, and send imperative commands through a client-server socket driver. Every framework update broke the bridge. Maestro succeeded by recognizing that **the accessibility tree is the universal contract of mobile user interfaces**. Operating systems have invested decades of engineering into making accessibility trees stable, resilient, and synchronized with the render thread so that screen readers never lose context. By aligning its testing model with the OS accessibility contract and exposing that model via declarative YAML and the Model Context Protocol, Maestro transformed mobile testing from an operational tax into a deterministic foundation for high-velocity software engineering. ## Quickstart & deployment ### 1. Install Maestro CLI On macOS and Linux: ```bash curl -FsSL "https://get.maestro.dev" | bash ``` On Windows: ```powershell powershell -Command "Invoke-WebRequest -Uri 'https://get.maestro.dev/win' -OutFile 'install.ps1'; .\install.ps1" ``` Verify installation: ```bash maestro --version ``` *Prerequisite: Java 17+ must be available on your PATH.* ### 2. Run your first Flow Create `flow_login.yaml`: ```yaml appId: com.example.app --- - launchApp - tapOn: "Log in" - inputText: "engineer@emiote.com" - tapOn: "Password" - inputText: "supersecret123" - tapOn: "Continue" - assertVisible: "Dashboard" ``` Run the flow against an active simulator or emulator: ```bash maestro test flow_login.yaml ``` ### 3. Connect to Claude Code or your AI Agent (MCP) Add Maestro MCP to Claude Code: ```bash claude mcp add maestro -- maestro mcp ``` Or configure manually in `claude_desktop_config.json` or Cursor `mcp.json`: ```json { "mcpServers": { "maestro": { "command": "maestro", "args": ["mcp"] } } } ``` Once connected, ask your agent: > *"Inspect the current emulator screen, write a Maestro flow to verify the onboarding carousel, and run it."* ## ReframeHub: Open Code Review - Path: https://emiote.com/reframehub/open-code-review/ - Category: Developer Tools - Description: Open-source AI code review CLI combining deterministic Go file bundling and rule matching with LLM agents for line-precise pull request feedback. - Pricing / Model: open-source (Self-host: $0 local CLI / pay-as-you-go LLM tokens, Cloud: Commercial AI code review at $15-$30/dev/month) - Snapshot Date: 2026-09-15 > **Open Code Review** is an open-source AI code review tool created by Alibaba Group, built in Go. It combines deterministic file selection, sub-agent bundling, and comment reflection with dynamic LLM reasoning to generate line-precise pull request feedback. Designed for local terminals and CI/CD pipelines, it runs via standalone binaries with custom model providers or agent delegation. --- ## 1. What It Replaces & Why It Matters Engineering teams face a growing bottleneck during code review. As AI coding tools accelerate code generation, the volume of pull requests expands rapidly. Traditional peer review struggles to keep pace, while naive AI review prompts introduce severe operational friction. When developers instruct general-purpose agents like Claude Code, ChatGPT, or Cursor to review a repository diff, three predictable defects appear: 1. **Position Drift**: Large language models struggle with relative line arithmetic. Review comments routinely target incorrect line numbers or reference lines outside the modified diff hunk. 2. **Incomplete Coverage**: On changesets containing dozens of files, models quietly cut corners. They review the first three or four files in detail and summarize or ignore the remainder. 3. **Alert Fatigue from False Positives**: Unconstrained prompts produce floods of superficial commentary regarding style preferences, documentation tone, and trivial renames, obscuring critical concurrency bugs and edge-case errors. Commercial code review platforms such as CodeRabbit and Qodo attempt to resolve this with proprietary SaaS wrappers. However, they charge between $15 and $30 per developer each month, route private proprietary source code through external vendor clouds, and offer limited flexibility for local command-line workflows. Open Code Review originated as Alibaba Group's internal review assistant. Over two years, the underlying engine served tens of thousands of engineers and processed millions of review comments across high-concurrency production systems. Now open-sourced under the Apache-2.0 license, it replaces closed SaaS subscriptions and fragile prompt wrappers with a standalone Go binary. It enforces hard engineering constraints around file selection, context budgeting, and line coordinate validation before letting models evaluate code semantics. --- ## 2. Architecture & Deterministic Hybrid Engine Open Code Review is written entirely in Go with zero CGO dependencies (`CGO_ENABLED=0`). It compiles into a single, self-contained binary (`ocr`) that interacts directly with Git. ```mermaid flowchart TD GitChanges["Local Changes / Pull Request Diff"] --> SelectionModule["Deterministic File Selection (internal/agent/selection.go)\nFilters lockfiles, vendor assets, binaries"] SelectionModule --> BundlingModule["Smart File Bundling (internal/agent/grouping.go)\nGroups coupled files (e.g. locale pairs, tests)"] BundlingModule --> SubAgentPool["Sub-Agent Pool with Isolated Contexts"] subgraph ReviewUnit ["Isolated Review Unit Execution"] SubAgentPool --> RuleEngine["Template-Engine Rule Matcher\nApplies path-specific review guidelines"] RuleEngine --> DynamicAgent["Specialized Review Agent (internal/agent)"] DynamicAgent <--> ToolCalls["Tuned Toolset (internal/tool):\nfile_read | file_read_diff | code_search"] DynamicAgent --> RawComments["Candidate Code Comments (JSON)"] end RawComments --> ReflectionModule["Comment Reflection & Validation (internal/tool/comment_args_repair.go)\nVerifies diff bounds, repairs coordinates, drops false positives"] ReflectionModule --> OutputPipeline{"Output Router"} OutputPipeline --> Terminal["Terminal CLI Output"] OutputPipeline --> WebViewer["Local Session Viewer (internal/viewer)"] OutputPipeline --> CIPipeline["GitHub Actions / GitLab CI Bot Comments"] ``` ### Deterministic Hard Constraints Open Code Review separates mechanical correctness from subjective evaluation. The system enforces hard engineering constraints where language models are statistically unreliable: - **Strict File Selection (`internal/agent/selection.go`)**: Evaluates file extensions, size limits, and change semantics. It strips vendor libraries, minified bundles, lockfiles, and auto-generated code before allocating token budgets. - **Smart File Bundling (`internal/agent/grouping.go`)**: Groups related files into unified review units. For example, translation files (`message_en.properties` and `message_zh.properties`) or coupled interface definitions and unit tests are bundled together. Each unit runs as a sub-agent with an isolated context window, enabling concurrent review execution across large changesets without token spillover. - **Template-Engine Rule Matching**: Instead of injecting hundreds of lines of universal guidelines into every prompt turn, OCR matches review rules against specific file paths and language types using Go templates. This concentrates model attention on language-specific anti-patterns. - **Comment Positioning and Reflection (`internal/tool/comment_args_repair.go`)**: Before any comment reaches the user or CI interface, an independent verification pipeline validates line numbers against actual git diff hunks. If a comment drifts outside the modified range or targets phantom code, the coordinate repair module fixes the offset or discards the hallucination. ### Specialized Agent Toolset Rather than exposing a generic bash shell or broad filesystem tools, the review agent uses five specialized tools tuned through production trace analysis: | Tool Name | Implementation | Function | | :--- | :--- | :--- | | `file_read` | `internal/tool/file_read.go` | Reads full source files within the repository root to evaluate context outside the diff. | | `file_read_diff` | `internal/tool/file_read_diff.go` | Inspects exact git diff hunks for a designated file path. | | `file_find` | `internal/tool/file_find.go` | Locates files across the directory tree matching patterns. | | `code_search` | `internal/tool/code_search.go` | Executes regex and symbol searches across the codebase to identify call sites and definition points. | | `code_comment` | `internal/tool/code_comment.go` | Emits structured line comments with severity tags, defect classifications, and fix suggestions. | All file operations enforce path containment via `pathutil.WithinBase()`, blocking directory traversal attacks before and after symlink resolution. --- ## 3. Visual Tour & Interface Workflows Open Code Review operates directly in local development environments, CI runners, and browser interfaces. ![Open Code Review Architecture and Feature Highlights](/images/reframehub/open-code-review/preview.webp) ### Core Operational Modes The tool provides three primary execution workflows depending on where review feedback is consumed: 1. **Workspace Diff Review (`ocr review`)**: Reviews uncommitted working tree changes, staged index updates, or single commits. It outputs line-level annotations directly into the terminal with syntax-highlighted code diffs. 2. **Branch Range Review (`ocr review --from main --to feature`)**: Automatically identifies the merge-base between two git branches, reviewing only code diverged from the upstream trunk. Sessions support persistence and resumption via `--resume <session-id>`. 3. **Full-File Audits (`ocr scan --path <dir>`)**: Audits legacy directories or unfamiliar codebases without requiring git history. It reviews whole files for architectural security defects and code smells. ### Delegation Mode A standout architectural feature is Delegation Mode (`ocr delegate preview` and `ocr delegate rule`). In standard mode, OCR requires its own configured LLM API key. In Delegation Mode, OCR serves as an orchestration engine for host coding agents like Claude Code, Cursor, or Codex. OCR generates the deterministic file bundles, resolves path-specific review rules, and packages the exact diff payloads. The host coding agent then evaluates the review using its existing session tokens. This eliminates the need for separate API credentials in corporate environments. ### Local Session Viewer Running `ocr viewer` starts an embedded HTTP server providing a graphical interface for reviewing session history. Developers can filter comments by severity, mark false positives as ignored, and hide completed items while working through findings. To prevent security vulnerabilities on developer machines, the viewer binds to the loopback interface by default and uses `internal/viewer/hostguard.go` to reject DNS rebinding attempts from non-local host headers. --- ## 4. Total Cost of Ownership (TCO) Operating an automated code review system involves license fees, compute overhead, and model inference tokens. Open Code Review provides massive cost advantages over both commercial SaaS products and unstructured agent prompts. | Dimension | Commercial Review SaaS (CodeRabbit, Qodo) | Unstructured Agent Prompts (Claude Code / Cursor) | Open Code Review (CLI + OSS Engine) | | :--- | :--- | :--- | :--- | | **License Cost** | $15 to $30 per developer / month | Included in assistant seat subscription | **$0 (Apache-2.0 open source)** | | **Token Efficiency** | Proprietary cloud caching | Low (repeats full file contents every turn) | **High (consumes ~1/9 tokens of raw agents)** | | **API Token Bills** | Bundled into seat license | $0.15 to $0.60 per pull request review | **$0.02 to $0.08 per review (direct API pricing)** | | **Infrastructure** | Vendor-managed multi-tenant cloud | Local assistant desktop runtime | **Local Go binary (<50MB) / zero-dependency CI** | | **Data Privacy** | Code sent to third-party vendor clouds | Model provider privacy policy | **Direct connection to private or VPC models** | | **Delegation Mode** | Not supported | Not applicable | **Supported ($0 additional API configuration)** | | **Annual TCO (10 Devs)**| **$1,800 to $3,600 / year** | Variable token consumption | **$0 software + direct pay-as-you-go tokens** | ### Benchmark Evidence: The AACR-Bench Dataset Alibaba open-sourced its evaluation benchmark, AACR-Bench, hosted publicly on Hugging Face (`Alibaba-Aone/aacr-bench`). The benchmark comprises: - 50 popular open-source repositories - 200 real pull requests across 10 programming languages - 1,505 ground-truth issues annotated and cross-validated by 80+ senior engineers When evaluated against general-purpose agents using identical foundation models, Open Code Review achieved significantly higher Precision and F1 scores while consuming approximately **one-ninth (1/9) of the input tokens**. By pre-filtering noise and isolating review files into bounded sub-agent units, it eliminates redundant context passing, directly cutting API inference costs by up to 88%. --- ## 5. The Bad: What to Know Before Adopting Before deploying Open Code Review across production teams, engineers should understand several concrete operational trade-offs: 1. **Deliberate Low Recall Policy**: Open Code Review explicitly favors Precision over Recall. The default filtering and reflection modules are tuned aggressively to eliminate developer alert fatigue. Consequently, the tool will intentionally overlook subjective stylistic choices, minor documentation phrasing, and speculative edge cases. Teams seeking an exhaustive linter that catches every pedantic violation will find its output conservative. 2. **Comment Reflection Fragility on Small Models**: The reflection and line coordinate repair pipeline relies on strict JSON schema compliance and spatial reasoning. When running against smaller local models (such as sub-14B parameter models like Qwen-2.5-Coder-7B), the reflection module frequently fails to resolve line number repairs, resulting in discarded comments. The tool functions reliably only when paired with frontier reasoning models (Claude 3.5/3.7 Sonnet, GPT-4o, DeepSeek-V3, or Qwen-2.5-Coder-32B). 3. **Git Merge-Base Requirements in Shallow CI Environments**: In range-review mode (`ocr review --from main --to feature`), the engine relies on `git merge-base` to detect the divergence commit. In CI environments where repositories are cloned with shallow history (`fetch-depth: 1`), the merge-base command fails unless the CI pipeline explicitly fetches the upstream base branch. 4. **Local Web Viewer Host Restrictions**: The built-in session viewer enforces strict host header checking via `hostguard.go`. When running OCR inside remote development containers (e.g. GitHub Codespaces, remote SSH sessions, or Docker workspaces), accessing the viewer through port forwarding requires configuring `OCR_VIEWER_ALLOWED_HOSTS` to avoid HTTP 403 Forbidden errors. --- ## 6. Quickstart & Deployment Open Code Review distributes as a pre-compiled Go binary, an npm global package, or a GitHub Action. ### Global CLI Installation ```bash # Install via npm package manager npm install -g @alibaba-group/open-code-review # Verify installation ocr --version ``` Alternatively, download the standalone binary directly for Linux, macOS, or Windows from the project's GitHub Releases page. ### Configure Model Provider ```bash # Interactive provider setup (supports OpenAI, Anthropic, Qwen, DeepSeek, Ollama) ocr config provider # Select active model ocr config model ``` ### Run Review ```bash # Review uncommitted changes in current repository ocr review # Review pull request changes between branches ocr review --from main --to feature-branch # Export structured review findings to JSON ocr review --format json --output review-results.json ``` ### GitHub Actions CI Integration To automate reviews on pull requests, add Open Code Review to your workflow: ```yaml name: AI Code Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Full history required for git merge-base - name: Run Open Code Review uses: alibaba/open-code-review@main env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} with: provider: "openai" model: "gpt-4o" ``` --- ## 7. Recommendation & ReframeHub Insight ### Who Should Use This - **Engineering Teams with High PR Velocity**: Organizations seeking to accelerate code review cycles without overwhelming senior developers with initial sanity checking. - **Privacy-Sensitive Organizations**: Teams that cannot transmit proprietary code to third-party SaaS vendors and must run code review through private model endpoints or self-hosted VPCs. - **Developers Using AI Coding Assistants**: Engineers using Claude Code, Cursor, or Windsurf who want deterministic file bundling and rule resolution via Delegation Mode. ### Who Should Avoid This - **Teams Seeking Full Style Enforcement**: Projects that require pedantic linting and formatting feedback; standard static analysis tools (ESLint, golangci-lint, Ruff) handle syntax rules far more reliably. - **Environments Restricted to Low-Resource Local Models**: Setups attempting to run review agents on sub-14B parameter models without cloud API access. ### ReframeHub Insight: Hard Constraints Protect Agent Focus The core engineering lesson of Open Code Review is that language models should never be tasked with deterministic bookkeeping. When developers build review bots, the common temptation is to write a comprehensive prompt and feed it raw git diffs. This approach forces the neural network to calculate line offsets, filter vendor directories, and balance token quotas. Language models are probabilistic pattern engines; asking them to perform coordinate arithmetic guarantees position drift and silent truncation. Open Code Review succeeds because it sandwiches the language model between two deterministic engineering layers: 1. **Upstream Pre-Processing**: Go routines inspect Git trees, filter noise, bundle coupled files, and calculate exact token budgets before calling the LLM. 2. **Downstream Post-Processing**: Dedicated reflection algorithms inspect candidate comments, verify diff ranges, and drop hallucinations before output. The language model is restricted to the single task where it holds a clear advantage: evaluating semantic code logic. By eliminating mechanical overhead, Open Code Review reduces token consumption by 88% while producing reviews that developers actually trust. ## ReframeHub: Open Design - Path: https://emiote.com/reframehub/open-design/ - Category: AI Design and Prototyping - Description: Open-source Claude Design alternative—local daemon, 25 CLIs, DESIGN.md; not a production diary. - Pricing / Model: open-source (Self-host: Desktop app (macOS/Windows) or Docker/daemon + BYOK model keys; $0/mo local ops, Cloud: Claude Design via Anthropic Pro/Max/Team; Figma Pro from ~$12/editor/mo; Lovable/v0/Bolt Pro tiers) - Snapshot Date: 2026-08-10 ## Scope and currency This is an **architecture evaluation**, not a deployment diary. In August 2026 we reviewed the official [Open Design README](https://github.com/nexu-io/open-design/blob/main/README.md) (repo `nexu-io/open-design`, package `0.18.x` at review), product tour assets, architecture section, platform compatibility table, and roadmap. **We have not run Open Design in production.** Desktop builds, runtime registry, plugin counts, and Open Design Cloud billing change; confirm current docs before a cutover. Editorial review: `2026-08-10`. Contrast with our Ankik notes ([self-hosted Postgres](/reframehub/self-hosted-postgres/)): those are lived ops. This page is “what the design implies.” Same posture as [Agentic Inbox](/reframehub/agentic-inbox/) and [Buzz](/reframehub/buzz/). ## What it is Upstream one-liner ([`package.json`](https://github.com/nexu-io/open-design/blob/main/package.json)): a **local-first design product** that detects your installed code-agent CLI, runs design skills + design systems, and streams artifacts into a sandboxed preview. README positioning is more specific: - **The open-source Claude Design alternative** — same agent-native loop (brief → direction → stream artifact → critique → deliver), without Anthropic-only lock-in - **Figma alternative for the agent era** — not a multi-cursor vector canvas; single-page artifacts in real CSS/fonts/components, export HTML / PDF / PPTX / MP4 - **Apache 2.0** · product site [open-design.ai](https://open-design.ai) · org **Nexu** (`nexu-io`) Open Design does **not** ship its own coding agent. The CLIs already on your `PATH` (Claude Code, Codex, Cursor, OpenCode, Copilot, Hermes, Kimi, Antigravity, OpenClaw, …) **are** the design engine—or any OpenAI-compatible endpoint via **BYOK**. Your laptop is the studio; the team’s **`DESIGN.md`** is the brand contract. **Four composable planes** (portable directories anyone can author): | Plane | Role (upstream) | Shipped surface (README review window) | | --- | --- | --- | | **Plugins** | Runnable workflows / marketplace entries | **277** official plugins + **183** remixable examples | | **Functional skills** | Agent behavior (`skills/`, Agent Skills `SKILL.md`) | **100+** functional skills | | **Design templates** | Rendering blueprints (`design-templates/`) | Prototype, deck, image, video/HyperFrames, utility modes | | **Design systems** | Brand packages centered on `DESIGN.md` | **151** systems (legacy MD-only or `manifest.json` + `tokens.css` + components) | Outputs: web · desktop · mobile **prototypes**, live dashboards/artifacts, decks, images, video, **HyperFrames** (HeyGen OSS HTML→MP4). Preview is a sandboxed iframe; filesystem-backed CLI runs write real project files. ![Open Design Home — brief composer with prototype, deck, image, video, and HyperFrames modes](/images/reframehub/open-design/home.png) *Official product tour Home (source: [repo product assets](https://github.com/nexu-io/open-design)).* ### A look inside (official screenshots) ![Studio prototype preview — agent chat left, live HTML artifact right](/images/reframehub/open-design/studio-prototype.png) **Studio streams real files.** Agent writes HTML/CSS into the project; iframe previews runnable output for handoff to engineering. ![Design System workspace — brand tokens, spacing, and review actions](/images/reframehub/open-design/design-system.png) **`DESIGN.md` as brand contract.** Every render reads the active design-system package—drop a brand folder, the picker finds it. ![In-app preview of a generated cinematic landing page](/images/reframehub/open-design/app-preview.webp) **Artifacts are code, not locked vectors.** Export HTML (inlined), PDF (print), PPTX (agent-driven), ZIP, Markdown, MP4 (HyperFrames). ![Mobile onboarding prototype with device chrome](/images/reframehub/open-design/mobile-onboarding.png) **Multi-surface prototypes.** Device frames live in shared assets; agent does not re-draw phone chrome every time. ![Live dashboard skill output — editable KPI wall](/images/reframehub/open-design/live-dashboard.png) **Live artifacts.** KPI walls / decision rooms with tweak manifests; iframe re-renders without full reload. ### Architecture (from upstream README) ![Open Design architecture: Next.js/Electron shell → Express+SQLite daemon → local agent CLIs and BYOK proxy](/images/reframehub/open-design/architecture.svg) Exact topology documented in the [Architecture](https://github.com/nexu-io/open-design/blob/main/README.md#architecture) section: 1. **Shell** — browser (**Next.js 16** App Router) or **Electron**: chat, file workspace, iframe preview, settings, import, MCP 2. **Daemon** — local **Express + SQLite** (`better-sqlite3`, Node **~24**): `/api/skills`, `/api/design-templates`, `/api/plugins`, `/api/design-systems`, `/api/chat` (SSE), `/api/proxy/*`, `/api/projects/:id/files/…`, `/api/artifacts/{save,lint}`, `/api/import/claude-design`, plus **MCP stdio** 3. **BYOK edge** — `POST /api/proxy/{provider}/stream` (SSE) to Anthropic / OpenAI / Azure / Google / Ollama / SenseAudio (and OpenAI-compatible presets incl. Atlas Cloud), **SSRF-guarded** (private/link-local/CGNAT blocked by default) 4. **Runtimes** — `spawn(cli, […], { cwd: managed project cwd })` via `apps/daemon/src/runtimes/` — **26 definitions / 25 distinct CLI executables** (`byok-opencode` shares the OpenCode binary). Agent composes a functional skill **or** design template + **`DESIGN.md`** and writes files. See [`docs/agent-adapters.md`](https://github.com/nexu-io/open-design/blob/main/docs/agent-adapters.md). No CLI installed? BYOK proxy alone still runs the loop (no process spawn)—paste `baseUrl` + `apiKey` + `model`. ### Stack (from repo Architecture table) | Layer | Choices (upstream) | | --- | --- | | Frontend | Next.js 16 App Router + React 18 + TypeScript | | Daemon | Node 24 · Express · SSE streaming · `better-sqlite3` | | Desktop | Electron shell + sandboxed renderer + sidecar IPC | | Preview | Filesystem runs → canonical project files; BYOK/plain-API runs → one complete `<artifact>` block in sandboxed `srcdoc` iframe | | Export | HTML · PDF · PPTX · ZIP · Markdown · MP4 (HyperFrames) | | Agent surface | `od` CLI + MCP stdio + `od mcp install <agent>` | | Self-host | Desktop packages · Docker under `deploy/` · Sealos App Store · README also lists Vercel web path | | Lifecycle (dev) | `pnpm tools-dev` (start / stop / run / status / logs / inspect / check) | ### Features that matter for a stack decision - **Agent-native, model-agnostic** — does not replace Claude Code/Codex/Cursor; wires them as the design engine (**25 CLIs** + BYOK) - **Brand-grade `DESIGN.md` by default** — **151** design-system packages ship in-repo - **Four-plane composability** — plugins · functional skills · design templates · design systems - **Claude Design ZIP import** — `/api/import/claude-design` - **HyperFrames first-class** — HeyGen open-source HTML+GSAP → MP4 (headless Chrome + FFmpeg) - **Optional Open Design Cloud** — official multi-model service (token-billed; zero local key juggling) - **Refresh / migrate plugins** — Figma/Pencil → React/Next/Vue and “refresh existing repo to brand” appear in README **roadmap as alpha / in progress**—do not assume production-ready migration tooling without checking current release notes ### Maturity snapshot (upstream roadmap, review window) | Shipped (README ✅) | Still open / partial | | --- | --- | | Daemon + 26 runtimes / 25 CLIs + skill & design-template registries + 151 design systems | Comment-mode surgical edits (partial) | | Web + Electron desktop + sidecar IPC | AI-emitted tweaks panel UX (not yet) | | BYOK multi-provider proxy + SSRF guard | `npx od init` scaffold | | Plugin marketplace infrastructure + Open Design Cloud | Plugin SDK publish flow still evolving on roadmap | | Claude Design import, artifact lint, packaged builds | Figma/Pencil migration & refresh-codebase plugins (alpha / listed incomplete) | Treat incomplete roadmap items as non-negotiable reading before promising “replace Figma tomorrow.” ## Cost breakdown | Path | Reference cost | What you get | | --- | --- | --- | | Open Design self-host (desktop / Docker + BYOK) | $0/mo product license + your API/token spend | Full local studio; files and keys stay under your control | | Open Design Cloud | Billed by real token usage (upstream “official model service”) | GPT / Claude / Gemini / DeepSeek-class access without per-provider key wrangling | | Claude Design (managed) | Anthropic Pro / Max / Team | Closed, hosted, Anthropic-model design loop | | Figma (managed canvas) | Pro from ~$12/editor/mo | Collaborative vector canvas; not the same artifact model | | Lovable / v0 / Bolt (cloud agents) | Pro / Team tiers | Hosted codegen agents; not local BYOK + `DESIGN.md` filesystem | There is **no seat tax for the OSS product**—spend is model/provider usage (or Cloud tokens) plus your ops if you run Docker/Sealos. ## The Good - **Honest product thesis** — open Claude Design loop + agent-era Figma alternative, not “another AI image box” - **Does not invent a new agent** — PATH CLIs and BYOK are first-class; swap engines without redesigning the brand system - **Filesystem-native craft** — skills, templates, plugins, and `DESIGN.md` packages are directories you can version and review in git - **Serious daemon surface** — Express + SQLite + MCP + SSRF-guarded proxy is a real local product, not a thin prompt UI - **HyperFrames + multi-export** — motion and marketing surfaces beyond static HTML mocks - **Credible open scale** — Apache 2.0, large public community signal at review time; desktop + Docker + Sealos paths documented ## The Bad — what to know before adopting 1. **Not a multiplayer vector canvas.** Real-time path editing, design-ops handoff habits, and Figma’s ecosystem still matter for many teams—Open Design targets **agent-generated artifacts**, not Penpot/Figma feature parity. 2. **Quality tracks the CLI/model.** Weak agent or bad brief → weak HTML; the product amplifies the agent you bring. 3. **PATH / `od` friction.** macOS `/usr/bin/od` can shadow Open Design’s CLI; GUI may miss CLIs installed only in nvm/Homebrew shells until PATH is fixed. 4. **Self-host is still ops.** Docker/Sealos need tokens, reverse-proxy auth, allowed origins—not managed Figma SLAs. 5. **Roadmap honesty applies to you.** Migration plugins, surgical comment edits, and tweaks-panel UX are incomplete; plan around what is ✅ today. ## When to use / When to skip **Use Open Design if:** - You want the **Claude Design workflow** without Anthropic-only hosting lock-in - Your team already runs coding agents and wants **design artifacts as files** shaped by **`DESIGN.md`** - Local-first privacy + **BYOK** (or Open Design Cloud tokens) fits better than another SaaS canvas - You need prototypes, decks, live artifacts, and/or HyperFrames from one local studio **Skip if:** - You need classic Figma-style multiplayer vector editing as the daily driver - Nobody will install a desktop app / daemon or maintain Docker - You only need a hosted “type prompt → deploy Next app” cloud agent (Lovable/v0/Bolt may fit better—different product) ## Prerequisites (official path) - **Desktop:** macOS (Apple Silicon + Intel) or Windows x64 packages; Linux AppImage on optional lane - **Or Docker / source:** Docker Compose; or Node **~24** + pnpm **10.33.x** for `pnpm tools-dev run web` - At least one of: supported agent CLI on `PATH`, or BYOK credentials, or Open Design Cloud - Optional shared deploy: Sealos App Store template or custom reverse proxy per `deploy/README.md` ## Setup checklist (official path) Sources: [README quick start](https://github.com/nexu-io/open-design/blob/main/README.md#quick-start) · [QUICKSTART.md](https://github.com/nexu-io/open-design/blob/main/QUICKSTART.md) · [open-design.ai](https://open-design.ai) 1. **Download desktop (recommended)** — [open-design.ai](https://open-design.ai) or [GitHub Releases](https://github.com/nexu-io/open-design/releases). Auto-detects CLIs on `PATH`, loads skills / templates / design systems. 2. **Or agent-only (no GUI)** — install MCP into the agent you already use: ```bash od mcp install claude # Claude Code od mcp install cursor # Cursor od mcp install codex # Codex CLI # also: copilot | opencode | openclaw | antigravity | hermes | kimi | … # hosted wrapper: curl -fsSL https://open-design.ai/install.sh | sh -s <agent> ``` On macOS desktop installs, prefer **Settings → MCP server** absolute-path snippets if bare `od` is Apple’s octal-dump. 3. **Brand contract** — pick a shipped design system or drop `design-systems/<brand>/DESIGN.md` (optionally with `manifest.json` / `tokens.css`). 4. **Docker self-host (optional)** — ```bash git clone https://github.com/nexu-io/open-design.git cd open-design/deploy cp .env.example .env # set OD_API_TOKEN=… then: docker compose up -d # open http://localhost:7456 ``` 5. **One-click Sealos (optional)** — same role as Railway for [Buzz](/reframehub/buzz/) or Deploy-to-Cloudflare for [Agentic Inbox](/reframehub/agentic-inbox/): [![Deploy on Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://sealos.io/products/app-store/open-design/) Still your ops surface—see [`deploy/README.md`](https://github.com/nexu-io/open-design/blob/main/deploy/README.md) for `OPEN_DESIGN_ALLOWED_ORIGINS` and reverse-proxy guidance. ## Our recommendation Apply the same **Keep / Configure / Replace / Build** lens as every ReframeHub note: - **As a Claude Design alternative:** strongest open reference we have seen for **local, agent-driven artifact generation** with a real `DESIGN.md` contract and multi-CLI support. - **As a Figma replacement:** only for teams whose pain is **agent-era production of HTML/deck/media files**—not for orgs that live in collaborative vector files. - **As a stack decision:** Keep Figma/Penpot for craft canvas work; **Configure** Open Design alongside coding agents for prototypes, decks, and motion; do not **Replace** managed design ops solely on star count. Need help evaluating agent design tooling vs canvas SaaS? [Book a Reframe audit for design stack](/reframe/?from=reframehub&tool=open-design) ($199). Parallel architecture notes: [Agentic Inbox](/reframehub/agentic-inbox/), [Buzz](/reframehub/buzz/). ## ReframeHub: OpenSEO - Path: https://emiote.com/reframehub/open-seo/ - Category: SEO & Growth - Description: Open-source pay-as-you-go alternative to Semrush & Ahrefs with native MCP support for AI coding agents. - Pricing / Model: open-source (Self-host: $0/mo OSS + ~$2–$5/mo DataForSEO API usage, Cloud: $10/mo hosted or $129–$449/mo commercial SaaS) - Snapshot Date: 2026-08-28 > **OpenSEO** is an open-source, self-hostable SEO platform created by [Every App on GitHub](https://github.com/every-app/open-seo) as a pay-as-you-go alternative to Ahrefs and Semrush. Built with React, Vite, Cloudflare Workers, Drizzle ORM, and Better-Auth, it pairs directly with the DataForSEO API and exposes a native Model Context Protocol (MCP) server for AI coding agents, dropping typical tooling costs from $139–$449/mo to $2–$5/mo. --- ## 1. Why OpenSEO Matters: Breaking the SEO SaaS Retainer Commercial SEO platforms like **Ahrefs** ($129–$449/mo) and **Semrush** ($139–$499/mo) operate on high, recurring fixed subscriptions. For early-stage startups, engineering studios, and indie makers who only run rank checks or keyword research a few times a week, you end up paying $1,500 to $5,000 per year for compute and databases you rarely touch. OpenSEO separates the **software interface** from the **raw search data**: 1. **The Software Layer is Free & Open Source**: Self-host via Docker on your local workstation or deploy to serverless Cloudflare Workers for $0/month. 2. **The Data Layer is Pure Pay-As-You-Go**: Connect your own DataForSEO API credentials. A SERP rank check costs ~$0.002, keyword volume lookups cost ~$0.005, and on-page crawls cost pennies. If you perform 200 targeted searches in a month, your total data bill is roughly **$1.50 to $3.00**. 3. **AI-Native MCP Interface**: Unlike legacy dashboards with bloated menus, OpenSEO exposes structured JSON-RPC MCP tools so terminal agents like **Claude Code**, **OpenClaw**, and **Hermes** can audit keyword gaps and pull live SERPs directly during active development. ![OpenSEO official web platform and open-source interface preview](/images/reframehub/open-seo/browser-preview.png) --- ## 2. Architecture & Data Flow OpenSEO is designed for low operational overhead and zero vendor lock-in. It can run in dual modes: a lightweight local developer container or a distributed serverless application. ```mermaid flowchart TD subgraph Clients["1. Clients & Ingestion"] Browser["Web Browser<br/>(React + Vite + Tailwind)"] Agent["AI Coding Agent<br/>(Claude Code / OpenClaw / Cursor)"] end subgraph Runtime["2. OpenSEO Core Runtime (Dual Mode)"] direction TB subgraph ModeA["Edge Serverless"] CF["Cloudflare Workers<br/>(Wrangler & Alchemy IaC)"] D1[("Cloudflare D1<br/>(Edge SQLite)")] end subgraph ModeB["Local / Self-Hosted"] Docker["Docker Container<br/>(Node.js Runtime)"] PG[("PostgreSQL Instance")] end Auth["Better-Auth<br/>(AUTH_MODE=local_noauth or DB Auth)"] Drizzle["Drizzle ORM Layer"] MCPServer["Native MCP Server<br/>(JSON-RPC Tool Handlers)"] end subgraph DataProvider["3. Data Layer (Pure Pay-As-You-Go)"] DFS["DataForSEO API<br/>(SERP, Keywords, Backlinks, OnPage)"] end Browser --> Auth Auth --> Drizzle Agent --> MCPServer MCPServer --> Drizzle Drizzle --> D1 & PG CF & Docker -->|"Encrypted Streaming Proxy"| DFS ``` ### Key Technical Components - **Frontend**: Vite + React with clean Tailwind CSS utility architecture, optimized for dense data tables and fast SERP comparisons. - **Edge & Server Runtime**: Cloudflare Workers (using Wrangler and Alchemy IaC) or Node.js Docker container. - **Database & Persistence**: Drizzle ORM supporting dual backends: - **Cloudflare D1 (SQLite)** for zero-maintenance serverless storage. - **PostgreSQL** for larger multi-user self-hosted instances. - **Authentication**: **Better-Auth** supporting `AUTH_MODE=local_noauth` (instant zero-friction local developer mode) or multi-tenant database authentication for shared team deployments. - **API Bridge**: Direct streaming proxy to DataForSEO endpoints (SERP API, Keywords Data API, Backlinks API, and OnPage API), ensuring your API keys never leave your controlled infrastructure. --- ## 3. Native Model Context Protocol (MCP) for AI Agents Where OpenSEO radically outperforms legacy tools is in agentic workflows. Instead of manually exporting CSVs from Ahrefs to feed into an LLM, OpenSEO runs an **MCP Server** that exposes live SEO data directly to AI coding tools. ```mermaid sequenceDiagram autonumber actor Dev as Developer / Founder participant Agent as Claude Code / OpenClaw participant MCP as OpenSEO MCP Server participant Core as OpenSEO Engine participant DFS as DataForSEO API Dev->>Agent: "Audit top 10 keywords and SERP competitor gap for emiote.com" Agent->>MCP: Call openseo_competitor_gap(domain, competitor) MCP->>Core: Authenticate & route tool request Core->>DFS: POST /v3/serp/google/organic/live (~$0.002) DFS-->>Core: Stream live rank & search volume JSON Core-->>MCP: Formatted structured payload (KD, CPC, Intent) MCP-->>Agent: Return JSON tool result to context Agent->>Dev: Synthesized gap analysis & action recommendations ``` ### Available MCP Tools - `openseo_get_keyword_data`: Pulls live search volume, keyword difficulty (KD), cost-per-click (CPC), and search intent. - `openseo_get_serp_overview`: Fetches top 100 Google/Bing rankings, featured snippets, People Also Ask (PAA), and AI Overview citation blocks. - `openseo_competitor_gap`: Dissects shared vs unranked keywords between two domains in sub-second JSON payloads. - `openseo_audit_page`: Performs on-page technical SEO audits (meta tags, schema validation, response headers, canonical integrity). --- ## 4. Total Cost of Ownership (TCO) Comparison | Dimension | Ahrefs / Semrush (Commercial) | OpenSEO (Self-Hosted + DataForSEO) | | :--- | :--- | :--- | | **Base Monthly License** | $129 – $449 / month | **$0 / month** (MIT Open Source) | | **Per-User Seat Charge** | $30 – $80 / extra user | **$0** (Unlimited team access) | | **Data Billing Model** | Monthly credit allowance (use-it-or-lose-it) | Pay-per-query (~$0.002 to $0.02 / call) | | **Average Monthly Spend (Startup / Studio)** | $150 – $350 / mo | **$2 – $8 / mo** | | **AI / MCP Integration** | Gated or non-existent | **Native open MCP server ($0)** | | **Database Ownership** | Vendor-locked proprietary silo | 100% owned SQLite (D1) or PostgreSQL | | **Annualized Total Cost** | **$1,548 – $5,388 / year** | **$24 – $96 / year** | --- ## 5. The Bad — What to Know Before Adopting OpenSEO is an exceptional cost-saver for technical teams, but it is not a 1:1 drop-in replacement for enterprise enterprise-wide enterprise marketing departments: 1. **No Pre-Indexed Decadal Historical Archive**: Ahrefs maintains trillions of cached historical pages dating back over 10 years. OpenSEO queries live data on-demand via DataForSEO. Running massive multi-year historical backlink trend analyses across 50,000 URLs in bulk will require more API calls and latency. 2. **Local Docker Security Caveat (`local_noauth`)**: When launching OpenSEO via Docker Compose with default settings, it runs with `AUTH_MODE=local_noauth` (no login screen). **Never expose this port directly to the public internet** without placing it behind Cloudflare Access, Zero Trust, or an authenticating reverse proxy (Caddy/Traefik). 3. **Prepaid Credit Maintenance**: Because queries hit DataForSEO directly, you must keep a funded balance (minimum $20–$50 deposit). When your credit hits zero, live searches pause until topped up. --- ## 6. Quickstart & Deployment Guide ### Option A: Local Docker (Fastest for Individual Developers) ```bash # 1. Clone the repository git clone https://github.com/every-app/open-seo.git cd open-seo # 2. Configure credentials cp .env.example .env # Edit .env and set your DATAFORSEO_API_KEY # 3. Launch container docker compose up -d ``` Open `http://localhost:3000` in your browser. ### Option B: Claude Code MCP Configuration Add the OpenSEO MCP endpoint to your `claude.json` or `config.json`: ```json { "mcpServers": { "open-seo": { "command": "npx", "args": ["-y", "@every-app/open-seo-mcp"], "env": { "OPENSEO_API_URL": "http://localhost:3000/api/mcp", "DATAFORSEO_API_KEY": "your_api_key_here" } } } } ``` --- ## 7. Studio Stack Review Context If your team is currently spending $200–$600/month on bloated marketing and SEO SaaS subscriptions that only a fraction of your engineers use, replatforming to pay-as-you-go open-source alternatives like OpenSEO can reclaim thousands of dollars in annual runway. Before switching databases, auth providers, or marketing stacks, book an **Emiote Stack Review** ($199 USD) for a comprehensive, vendor-neutral evaluation of your software boundaries, infrastructure costs, and AI integration architecture. ## ReframeHub: OpenClaw - Path: https://emiote.com/reframehub/openclaw/ - Category: AI & Agents - Description: Open-source self-hosted AI assistant by Peter Steinberger featuring a unified WebSocket gateway, device nodes, and multi-channel chat routing. - Pricing / Model: open-source (Self-host: $0/mo local machine / $5/mo VPS (+ raw API usage via OpenAI/Anthropic/Ollama), Cloud: Devin from $500/mo; cloud agent platforms from $40–$200/user/mo) - Snapshot Date: 2026-09-01 > **OpenClaw** is an open-source, self-hosted autonomous AI assistant framework created by [Peter Steinberger on GitHub](https://github.com/openclaw/openclaw) as a local-first alternative to proprietary cloud agent workbenches. Built with TypeScript and Node.js, it combines a centralized WebSocket Gateway control plane with decoupled device execution nodes, multi-channel messaging (WhatsApp, Telegram, Discord, Slack, iMessage), and Model Context Protocol (MCP) integrations. --- ## 1. Why OpenClaw Matters: The Agentic Operating System Most AI assistants are confined to isolated browser tabs, ephemeral chat boxes, or expensive proprietary SaaS retainers. They cannot access your local file system, inspect your local development servers, or operate ambiently across the messaging applications you use throughout the day. Commercial workbenches like **Cognition's Devin** ($500/mo) and proprietary agent platforms lock teams into third-party cloud infrastructure with mandatory model markups and closed tool ecosystems. ``` Proprietary Agent SaaS ($500/mo): [User App] ---> [Proprietary Cloud Broker] ---> [Mandatory Model Markup] ---> [Ephemeral Cloud VM] (Vendor lock-in) (Closed ecosystem) (Zero local device access) OpenClaw Open-Source Architecture ($0/mo): [Messaging Channels] ---> [OpenClaw Gateway Daemon] ---> [BYO Model / ChatGPT] (WhatsApp/Telegram/Slack) (WebSocket Control Plane) (OpenAI/Anthropic/Ollama) | +---> [Device Execution Nodes] | (macOS / Windows / Linux / iOS) | +---> [MCP & ClawHub Tools] (Local files, SQLite, APIs) ``` **OpenClaw redefines personal AI assistants around three foundational architectural principles:** 1. **Trusted Gateway Control Plane**: A single-port WebSocket daemon coordinates sessions, authentication, event dispatching, and channel routing. The gateway manages the agentic brain while remaining decoupled from execution environments. 2. **Untrusted Device Execution Nodes**: Local machines (macOS Menu Bar app, Windows Hub, Linux CLI, iOS/Android companion) connect to the Gateway as peripheral nodes. Tools execute locally on your physical machine with native permissions or containerized sandboxing. 3. **Open Standards via MCP & ClawHub**: Instead of building brittle proprietary connectors, OpenClaw standardizes on Anthropic's **Model Context Protocol (MCP)** for tools and the **ClawHub** open registry for composable community skills. 4. **Persistent Workspace State**: Maintains state, personality, and operational memory directly in version-controlled markdown files (`SOUL.md`, `AGENTS.md`, `MEMORY.md`, `USER.md`). ![OpenClaw Banner & System Architecture](/images/reframehub/openclaw/banner-dark.png) --- ## 2. Multi-Channel Messaging: Meeting You Everywhere Rather than forcing users into a custom frontend, OpenClaw meets operators inside the messaging apps they already rely on every day. <div class="my-6 rounded-xl border border-line bg-surface p-6"> <h4 class="font-mono text-xs uppercase tracking-wider text-muted">OpenClaw Gateway Channel Matrix</h4> <div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 font-mono text-xs"> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Personal Messaging</span> <p class="mt-1 text-muted">WhatsApp (via Baileys), Telegram Bot API, Apple Messages/iMessage (macOS native), and Signal.</p> </div> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Team Collaboration</span> <p class="mt-1 text-muted">Slack (Bolt socket mode), Discord.js, and Google Chat with per-user pairing and thread isolation.</p> </div> <div class="rounded-lg border border-line bg-paper p-4"> <span class="font-bold text-ink">Local & Web Interfaces</span> <p class="mt-1 text-muted">Browser-based Control UI, interactive Terminal TUI, and native system tray / menu bar apps.</p> </div> </div> </div> ![OpenClaw Overview & Control Interface](/images/reframehub/openclaw/hero.png) ### Pairing and Access Control To prevent unauthorized access on public messaging networks, OpenClaw enforces strict **DM pairing validation**: - Inbound messages from unknown senders trigger an ephemeral pairing challenge. - The operator must explicitly approve the pairing code from the CLI: `openclaw pairing approve <channel> <code>`. - Authorized users are mapped to specific workspace permissions and role-based tool access. --- ## 3. Architecture & Execution Engine OpenClaw is architected as an event-driven distributed system where the brain (Gateway) and limbs (Device Nodes) operate across a typed WebSocket transport. ``` +----------------------------+ | OpenClaw Gateway Core | | (Sessions, Routing, Bus) | +--------------+-------------+ | +-----------------------+-----------------------+ | | | +---------+---------+ +---------+---------+ +---------+---------+ | Multi-Model Router| | Device Nodes | | MCP Tool Registry | | - OpenAI / Claude | | - macOS Menu Bar | | - Filesystem | | - OpenRouter | | - Windows Hub | | - Shell Exec | | - Local Ollama | | - Linux CLI | | - Browser Canvas | | - ChatGPT Login | | - iOS Companion | | - MCPorter Bridge | +-------------------+ +-------------------+ +-------------------+ ``` ### Core Subsystems | Subsystem | Component | Operational Role | | :--- | :--- | :--- | | **Control Plane** | `packages/gateway` | Manages long-lived WebSocket connections, session multiplexing, event dispatching, and cron scheduling. | | **Model Router** | Provider Adapters | Normalizes tool calls and streaming tokens across Anthropic Claude, OpenAI GPT-4o, DeepSeek, OpenRouter, and Ollama. | | **Node Harness** | `packages/node` | Runs on target client machines, executing shell commands, file manipulations, camera clips, and browser automation. | | **Tool Protocol** | Model Context Protocol | Standardizes tool discovery and execution via native MCP servers and `@steipete`'s `MCPorter` utility. | | **Ambient Automation** | Proactive Heartbeat | Evaluates scheduled cron jobs, background webhooks, and inbox sweeps even when the operator is inactive. | --- ## 4. Total Cost of Ownership (TCO) Comparison | Dimension | Commercial Agent Cloud (Devin / Operator) | OpenClaw (Self-Hosted OSS) | | :--- | :--- | :--- | | **Software License** | $500 / month (Devin Enterprise) | **$0 / month** (MIT Open Source) | | **Gateway & Messaging** | $50 – $200 / mo (Botpress / Flowise Cloud) | **$0** (Included native WebSocket daemon) | | **Model & Token Billing** | 200%–500% proprietary cloud markup | **100% Raw API cost** (BYO API / ChatGPT login / Ollama) | | **Compute Infrastructure** | Proprietary cloud instances only | **$0 local machine / $5/mo VPS** | | **Data Privacy & Storage** | Transcripts stored on vendor cloud | **100% Local / Self-Owned** (`~/.openclaw/`) | | **Tool & Skill Ecosystem** | Closed proprietary actions | **Open MCP + ClawHub Plugins** | | **Total Annualized Cost** | **$6,000 – $12,000+ / yr** | **~$60 – $300 / yr** (+ raw model token usage) | --- ## 5. The Bad — What to Know Before Adopting While OpenClaw provides an exceptionally versatile, open-source agent harness, engineering teams must evaluate these operational trade-offs: 1. **Prompt Injection & Blast-Radius Exposure**: Because OpenClaw connects directly to external messaging apps and has access to local host tools, untrusted prompt injections (e.g. via email summaries or public Discord channels) can pose severe security risks. Always enforce DM pairing verification and configure Docker or Microsoft Execution Container sandboxes for shared deployments. 2. **Local Machine Sleep & Node Availability**: If you run OpenClaw entirely on a local laptop, closing the lid suspends the Gateway and disconnects messaging channels. To achieve true 24/7 ambient availability, deploy the Gateway daemon on a low-cost VPS ($5/mo on DigitalOcean/Hetzner) and connect your laptop as an auxiliary execution node. 3. **Rapid Ecosystem Velocity & Breaking Changes**: With over 340k+ GitHub stars and continuous updates, plugin APIs and CLI configuration schemas can shift between release cycles. Use `openclaw update --channel stable` in production environments. 4. **When to Stay on Commercial Managed Copilots**: Teams that only need inline IDE autocomplete or basic chat without local shell access, file control, or external chat routing are better served by standard IDE extensions. --- ## 6. Quickstart & Installation ### Step 1: Install OpenClaw #### macOS, Linux, or WSL2 ```bash curl -fsSL https://openclaw.ai/install.sh | bash ``` #### Windows (PowerShell) ```powershell iwr -useb https://openclaw.ai/install.ps1 | iex ``` #### Via npm (Node.js 22+) ```bash npm install -g openclaw@latest ``` ### Step 2: Complete the Onboarding Wizard ```bash # Launch interactive onboarding wizard and install gateway daemon openclaw onboard --install-daemon ``` ### Step 3: Check Gateway Status & Open Control UI ```bash # Verify gateway daemon health openclaw gateway status # Open browser Control UI openclaw dashboard ``` --- ## 7. Studio Reframe Evaluation If your engineering team is evaluating AI assistant infrastructure, choosing between centralized cloud agent platforms (Devin/Operator) and open self-hosted harnesses (OpenClaw / Hermes Agent / OpenMausBot), book an **Emiote Stack Review** ($199 USD). We audit agent permission boundaries, MCP tool architectures, gateway security, and token unit economics to help you deploy resilient AI workflows. ## ReframeHub: OpenMausBot - Path: https://emiote.com/reframehub/openmausbot/ - Category: AI & Agents - Description: Local-first open-source Grok Bot alternative—run a team of Claude and Codex agents in a unified desktop messaging app. - Pricing / Model: open-source (Self-host: $0/mo local desktop app + existing Claude / Codex CLI subscriptions, Cloud: Devin from $500/mo; cloud agent platforms from $40–$200/user/mo) - Snapshot Date: 2026-08-31 > **OpenMausBot** is an open-source, local-first multi-agent desktop application created by [Milind Soni on GitHub](https://github.com/milind-soni/OpenMausBot) as an alternative to xAI's Grok Bot and proprietary agent workbenches. Built with React 19, TypeScript, Electron, and a local localhost harness, it organizes real autonomous AI agents (running locally via `claude`, `codex`, or `grok` CLIs) into a Telegram-style messaging interface with sandboxed computer use, permission approval gates, and Composio tool integrations. --- ## 1. Why OpenMausBot Matters: Breaking the Single-Chat Silo Most AI developer tools lock you into a single prompt box with one generalist assistant that loses context as soon as conversations branch into multiple disciplines (architecture, frontend UI, database migrations, SRE). Proprietary cloud platforms like **xAI's Grok Bot** and **Cognition's Devin** ($500/mo) solve this by assigning persistent cloud computers to autonomous bots. However, they force vendor lock-in, proprietary model routing, and expensive enterprise seat retainers. **OpenMausBot adopts the multi-agent roster pattern while keeping execution 100% open and local-first:** 1. **Bring Your Own Local Engines**: Bots run directly on the official `claude`, `codex`, and `grok` CLIs installed on your machine. There are no intermediate proxies, extra token markups, or third-party cloud dependencies. 2. **AI as Contacts in a Messaging App**: Each bot in your sidebar represents a dedicated specialist with its own system prompt, memory thread, model provider, and execution environment. 3. **Channels for Context Isolation**: Group bots by project or discipline (e.g. `#Frontend-Sprint`, `#Database-Refactor`) with isolated working directories, shared transcripts, and project-specific instructions. ![OpenMausBot Multi-Agent Chat Interface](/images/reframehub/openmausbot/hero.png) --- ## 2. Model Routing & Bring-Your-Own-Engine OpenMausBot allows switching brains per bot or mid-conversation across Claude, Codex, Grok, and local models. ![OpenMausBot Model Picker with Provider Rail](/images/reframehub/openmausbot/model-picker.png) ### Key Technical Subsystems - **Desktop Shell**: **Electron** + **React 19** frontend featuring dynamic model pickers, live VNC desktop screen streams, and real-time approval cards. - **Local Harness Server (`127.0.0.1`)**: A lightweight daemon that manages agent subprocesses, hot-reloads CLI engine wrappers, and coordinates async tool execution without external telemetry. - **Local Vault Storage (`~/.openmausbot`)**: All thread transcripts, conversation IDs, model parameters, and encrypted API credentials live strictly on your local disk. - **Execution Environments**: - **Cloud Linux Desktop**: Dedicated cloud containers for autonomous browser testing and live screen takeovers. - **Local Sandboxed VM**: Isolated container workspaces running on your workstation. - **Host Machine Control**: Direct macOS and Ubuntu Xorg execution (explicit opt-in required). - **Connected Apps Gateway**: Connects to 500+ external services (GitHub, Slack, Linear, Notion, Gmail) via **Composio** OAuth sessions. ![OpenMausBot Dedicated Cloud Computer and Live Screen Preview](/images/reframehub/openmausbot/computer-panel.png) --- ## 3. Human-in-the-Loop Permission Broker Autonomous agents with direct shell and file-system access present severe blast-radius risks. OpenMausBot addresses this with an inline **Permission Broker** that intercepts dangerous actions before execution. ![OpenMausBot Permission Broker and Approval Cards](/images/reframehub/openmausbot/approval-card.png) ### Connected Apps & External Tools Beyond local files, agents can interact with your real tools (Slack, Linear, GitHub, Gmail) via managed Composio sessions without sharing unencrypted credentials with the models. ![OpenMausBot Connected Apps Marketplace](/images/reframehub/openmausbot/marketplace.png) --- ## 4. Total Cost of Ownership (TCO) Comparison | Dimension | Devin / Cloud Agent SaaS | OpenMausBot (Local-First OSS) | | :--- | :--- | :--- | | **Software License** | $500 / month (Devin Enterprise) | **$0 / month** (MIT Open Source) | | **Model / Compute Billing** | High proprietary cloud markup | Pure BYO CLI (existing Claude/Codex subs) | | **Team / Seat Costs** | $40 – $200 / user / mo | **$0** (Local installation) | | **Data Privacy & Storage** | Transcripts stored on third-party cloud | **100% Local** (`~/.openmausbot`) | | **Connected Tools (GitHub/Linear)** | Proprietary closed toolkits | **500+ Composio Apps + Local CLIs** | | **Annualized Cost** | **$4,800 – $12,000+ / yr** | **$0 / yr** (+ your standard LLM subscriptions) | --- ## 5. The Bad — What to Know Before Adopting While OpenMausBot offers immense agency and freedom from SaaS retainers, technical teams should evaluate these operational constraints: 1. **Local Machine RAM & Compute Overhead**: Running a team of 4 to 6 simultaneous autonomous bots with local harnesses, Electron renderers, and background subprocesses is resource-intensive. A minimum of **16 GB RAM** is required, with **32 GB+ recommended** for running heavy local builds alongside agent sessions. 2. **API Rate Limiting on Concurrent Runs**: Spawning multiple bots that query Claude 3.7 or Codex simultaneously will rapidly burn through individual account rate limits (Tier 1/2 TPM limits) during bursty multi-agent workflows. 3. **Host Control Security Discipline**: Enabling host control grants agents access to your local shell. If you bypass permission cards or enable auto-approve rules, an unconstrained prompt injection could execute destructive filesystem operations. Always enforce the permission broker in production codebases. --- ## 6. Quickstart & Installation OpenMausBot provides pre-compiled signed packages for macOS, Windows, and Ubuntu: ### Step 1: Install the Desktop App - **macOS (Apple Silicon & Intel)**: Download the signed `.dmg` from [OpenMausBot Releases](https://github.com/milind-soni/openmausbot-releases/releases). - **Windows**: Download `OpenMausBot-setup.exe`. - **Ubuntu 24.04**: Install the `.deb` package via `sudo dpkg -i OpenMausBot-amd64.deb`. ### Step 2: Ensure CLI Engines are Configured OpenMausBot automatically discovers installed developer tools: ```bash # Verify your local CLI logins claude --version codex --version ``` In **Settings → Engines**, toggle your active providers, set your preferred default models, and start chatting with your bot roster. --- ## 7. Studio Reframe Evaluation If your product team is evaluating multi-agent architectures, deciding between centralized cloud platforms (Devin/Grok Bot) and local-first open harnesses (OpenMausBot/Buzz), book an **Emiote Stack Review** ($199 USD). We audit agent boundaries, security sandboxing, and token cost economics to help you build resilient AI workflows. ## ReframeHub: Opensource UI - Path: https://emiote.com/reframehub/opensourceui/ - Category: Developer Tools - Description: Free MIT-licensed copy-paste library of 150+ production-ready React and Next.js components built with TypeScript and Tailwind CSS v4. - Pricing / Model: open-source (Self-host: $0 (MIT license, copy-paste into existing React / Next.js codebase), Cloud: Tailwind UI $299 one-time; UI8 / Envato $200 to $400/yr; Cruip $79 to $199) - Snapshot Date: 2026-09-02 > **Opensource UI** is a free, MIT-licensed copy-paste library of over 150 production-ready React and Next.js components created by [Bidyut Kundu on GitHub](https://github.com/bidyut10/opensourceui) as an alternative to paid UI kits. Built with React 19, Next.js 16, TypeScript, and Tailwind CSS v4, it provides self-contained components with zero runtime package dependencies or provider wrappers. --- ## What It Replaces Building polished modern web interfaces usually forces frontend teams into commercial paywalls or runtime bloat: 1. **Commercial Component Paywalls**: Purchasing proprietary component packs like Tailwind UI ($299 one-time), Cruip ($79 to $199), or UI8 ($200 to $400/yr) where source code is locked behind individual licenses. 2. **Heavy Runtime Libraries**: Importing monolithic packages like Material UI or Ant Design that add 250KB to 600KB of runtime JavaScript, inject runtime CSS stylesheets, and require nested provider wrappers. 3. **Complex Registry CLI Overhead**: Configuring multi-step CLI generators, managing Radix UI primitive sub-dependencies, and decoding token maps just to render an audio widget or device frame. Opensource UI strips away the indirection: - **Zero Package Dependencies**: No component runtime packages. Plain React 19, standard HTML element props, and Tailwind CSS v4 classes. - **Self-Contained Files**: Every component lives in its own standalone `.tsx` file with typed props. - **Craft-Focused Widgets**: Beyond basic buttons, it provides realistic phone mockups with camera cutouts, interactive clocks, and audio player cards. --- ## Architecture Opensource UI relies on a direct copy-paste architecture that compiles entirely at build time, eliminating runtime library overhead: ```mermaid flowchart TD subgraph Source["1. Component Source (Opensource UI)"] Cat["Component Catalog (opensourceui.in)"] --> Code[".tsx Component File"] end subgraph Consumer["2. Consumer Application (Next.js 16)"] Code -->|Direct Copy-Paste| UI["components/ui/*.tsx"] Helper["lib/utils.ts (cn helper)"] --> UI Tailwind["Tailwind CSS v4 Engine"] --> UI end subgraph Runtime["3. Production Output"] UI -->|Static Props| RSC["React Server Component (0 KB Client JS)"] UI -->|Interactive Hooks| Client["Client Boundary ('use client')"] end classDef source fill:#f8fafc,stroke:#94a3b8,color:#0f172a classDef consumer fill:#f1f5f9,stroke:#64748b,color:#0f172a classDef runtime fill:#ff4500,stroke:#ea580c,color:#ffffff class Cat,Code source class UI,Helper,Tailwind consumer class RSC,Client runtime ``` ### Technical Implementation Patterns 1. **Standardized `cn()` Helper**: Uses `clsx` and `tailwind-merge` to allow consumers to safely override classes without CSS specificity conflicts. 2. **HTML Element Extension**: Interactive components extend native HTML interfaces (such as `React.HTMLAttributes<HTMLDivElement>`) and forward DOM refs via `React.forwardRef`. 3. **Client Boundary Discipline**: Components render as static React Server Components by default, declaring `"use client"` only when local state (active tab, audio playback, timer interval) requires browser lifecycle hooks. --- ## Visual Tour / Workflow The component workflow focuses on speed of integration and visual precision: 1. **Browse and Inspect**: Developers navigate the live catalog at `opensourceui.in`, test component interactions across light and dark modes, and inspect responsive breakpoints. 2. **Copy Single File**: The developer copies the standalone TypeScript code directly from the browser preview. 3. **Local Customization**: The `.tsx` file is dropped into `components/ui/` where design tokens, animations, and Tailwind classes can be modified directly without fighting third-party style encapsulation. ![Opensource UI Live Web Catalog and Component Previews](/images/reframehub/opensourceui/browser-preview.png) --- ## Total Cost of Ownership (TCO) | Dimension | Commercial UI Packs (Tailwind UI / UI8) | Monolithic UI Kits (MUI / Chakra) | Opensource UI (Self-Hosted OSS) | | :--- | :--- | :--- | :--- | | **Upfront License** | $299 (Tailwind UI) / $39/mo (UI8) | $0 to $3,000+ (MUI X Enterprise) | **$0** (MIT Open Source) | | **Runtime Bundle Size** | Minimal (Tailwind classes) | Heavy (+250KB to 600KB JS/CSS) | **0 KB added runtime** | | **Provider Wrappers** | None | Required (`<ThemeProvider>`) | **None** (Drop-in JSX) | | **Component Customization** | Edit raw JSX | Theme tokens / `sx` props | **Direct Tailwind v4 classes** | | **Icon Dependencies** | Lucide / Heroicons package | `@mui/icons-material` (10MB+) | **Native SVG components** | | **Total Annualized Cost** | **$299 to $500+ / yr** | **$0 to $3,000+ / yr** | **$0 / yr** | --- ## The Bad While Opensource UI eliminates license fees and bundle bloat, teams should evaluate these operational considerations: 1. **Downstream Maintenance and Ownership**: Because you copy code directly into your repository rather than consuming an npm package, bug fixes do not arrive via `pnpm update`. Your team owns the component lifecycle. 2. **Keyboard Navigation and Deep Accessibility**: Unlike headless primitive suites (such as Radix UI or React Aria), complex compound patterns (multi-level dropdowns or modal focus traps) may require manual ARIA verification for strict accessibility compliance. 3. **Framework Lock-In**: The components are engineered specifically for React and Next.js with Tailwind CSS v4. Teams building on Svelte, Vue, or vanilla CSS will need to convert JSX and hooks into their respective template syntaxes. --- ## Quickstart / Deployment ### Step 1: Install Utility Dependencies ```bash pnpm add clsx tailwind-merge ``` ### Step 2: Configure the `cn()` Helper ```typescript // lib/utils.ts import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } ``` ### Step 3: Copy and Paste Components Browse the catalog at [opensourceui.in/components](https://opensourceui.in/components), copy the component source code, and save it directly into your project's `components/ui/` folder. --- ## Recommendation Opensource UI is ideal for early-stage products, marketing sites, and MVP prototypes that need high-craft visual widgets without the bundle bloat of component frameworks or the license cost of commercial kits. For large enterprise applications with strict accessibility compliance audits (WCAG AAA) or complex data tables, pair Opensource UI with headless primitives like Radix UI or React Aria. Use Opensource UI for marketing surfaces and device mockups, and headless primitives for complex transactional forms. --- ## Studio Reframe Evaluation If your engineering team is modernizing its design system, migrating to Tailwind CSS v4, or evaluating copy-paste component architectures vs headless UI libraries, book an **Emiote Stack Review** ($199 USD). We audit frontend bundle performance, component composability, design token consistency, and rendering waterfalls. ## ReframeHub: Postiz - Path: https://emiote.com/reframehub/postiz/ - Category: Automation - Description: Open-source social media scheduling tool with 38 platform integrations, Temporal workflow engine, AI composer, and native MCP agent support. - Pricing / Model: open-source (Self-host: $20-$40/mo VPS (4GB-8GB RAM for Temporal + Elasticsearch) + Social API fees, Cloud: $29/mo (Standard) to $99/mo (Ultimate) on postiz.com) - Snapshot Date: 2026-09-08 > **Postiz** is an open-source social media scheduling and automation platform created by Nevo David. Built with NestJS, Next.js, and Temporal.io, it allows individuals and teams to schedule posts across 38 social networks, manage team workflows, and connect autonomous AI agents via the Model Context Protocol. It deploys locally or via Docker Compose. --- ## 1. Why Postiz Matters: The Social Scheduling Tax Social media schedulers are among the most common recurring software costs for modern businesses, content creators, and growth engineers. Commercial platforms charge steep premiums based on channel counts and user seats: - **Buffer** charges $6 per channel per month. Managing three brands across five networks (15 channels) runs $90 per month. - **Hootsuite** starts at $99 per month for a single user and ten channels, jumping to $249 per month for teams. - **Sprout Social** charges upwards of $199 to $499 per seat per month, placing multi-seat collaboration out of reach for early-stage teams. Beyond pricing penalties, traditional tools treat publishing as a closed, proprietary silo. Programmatic automation requires custom webhooks, proprietary REST APIs with low rate limits, or brittle browser extensions. Adding emerging decentralized networks like Bluesky, Mastodon, Nostr, or Farcaster is either deprioritized or entirely unsupported by incumbent vendors. ``` Proprietary Social Media Tool Model: [Your Content] -> [Proprietary SaaS Silo] -> [Per-Channel Billing Tax: $6/channel/mo] (Closed API, high seats) -> [Limited Network Selection] Postiz Open Architecture Model: [Your Content / Agents] -> [Self-Hosted Postiz API] -> [Temporal Durable Workflow] (Flat VPS, zero seat tax) -> [38 Supported Social Providers] ``` Postiz addresses this friction by providing a self-hostable, full-stack alternative licensed under AGPL-3.0. Instead of taxing users on channel volume or seat count, it runs on standard server infrastructure. It couples a modern visual calendar and multi-channel composer with developer-first integrations: an official Node.js SDK, n8n and Make.com nodes, an MCP (Model Context Protocol) server, and a specialized CLI (`postiz-agent`) tailored for autonomous coding agents like OpenClaw. --- ## 2. Architecture & Container Topology Postiz is structured as a TypeScript monorepo managed with pnpm workspaces. It splits concerns into separate presentation, API, background orchestration, and shared library layers. ```mermaid flowchart TD subgraph Client["Presentation & Consumers"] UI["Web Interface<br/>(Next.js / React / Tailwind)"] Agent["Autonomous Agent / CLI<br/>(postiz-agent / MCP Server)"] External["Automation Pipelines<br/>(n8n / Make / Node SDK)"] end subgraph AppServer["Application Services"] Backend["NestJS REST API (:5200)<br/>(Auth, RBAC, Billing, CRUD)"] Orchestrator["Orchestrator Worker<br/>(Temporal Activity Runner)"] end subgraph DataStore["Storage & State"] Postgres["Primary Database<br/>(PostgreSQL 17 / Prisma ORM)"] Redis["Cache & Rate Limiting<br/>(Redis 7.2)"] end subgraph TemporalCluster["Temporal Workflow Infrastructure"] Temporal["Temporal Server<br/>(auto-setup 1.28.1)"] TemporalES["Elasticsearch 7.17<br/>(Visibility & Search)"] TemporalDB["Temporal Database<br/>(PostgreSQL 16)"] TemporalUI["Temporal Web UI<br/>(:8080)"] end UI -->|REST / SWR| Backend Agent -->|JSON-RPC / REST| Backend External -->|Public API| Backend Backend -->|Queries / Migrations| Postgres Backend -->|Session / Rate Limits| Redis Backend -->|Trigger Workflows| Temporal Orchestrator -->|Poll Task Queues| Temporal Orchestrator -->|Status Updates| Postgres Temporal -->|Store Execution State| TemporalDB Temporal -->|Index Workflows| TemporalES TemporalUI -->|Inspect Runs| Temporal ``` ### Core Monorepo Subsystems | Component | Path | Responsibility | | :--- | :--- | :--- | | **Backend API** | `apps/backend` | NestJS application handling user authentication (JWT/cookies), organization tenancy, role-based access control, Prisma ORM queries, and public developer endpoints. | | **Frontend UI** | `apps/frontend` | Next.js and React client using Tailwind CSS, SWR for reactive data fetching, and live platform preview components. | | **Orchestrator** | `apps/orchestrator` | Dedicated NestJS worker daemon that registers workflows and runs Temporal activities for timed publication, video generation, and token refresh. | | **Social Libraries** | `libraries/nestjs-libraries/src/integrations/social` | Adapter layer housing 38 distinct social provider implementations, each normalizing media uploads, text limits, and OAuth token exchanges. | | **Agent Integration** | `libraries/nestjs-libraries/src/agent` | Graph-based agent service and MCP server integration supporting Dynamic Client Registration (RFC 7591) for autonomous agents. | --- ## 3. The Temporal Workflow Engine The defining architectural decision in Postiz is delegating task scheduling to **Temporal.io** rather than a simple queue like BullMQ or a basic database cron poll. Scheduling social posts introduces challenging failure modes: 1. **Durable Timers**: Posts can be scheduled minutes, weeks, or months into the future. Maintaining millions of long-sleeping jobs in Redis memory is inefficient and vulnerable to queue evictions. 2. **Deterministic Retries**: Social networks regularly fail during execution. Twitter API rate limits, expired Facebook page tokens, and transient YouTube video upload errors require intelligent, stateful exponential backoff. 3. **Multi-Step Pipelines**: Publishing a video post involves polling video transcoding status, uploading chunks, waiting for provider verification, and then posting caption text. ```mermaid sequenceDiagram autonumber actor User as User / MCP Agent participant API as NestJS Backend participant DB as PostgreSQL 17 participant Temp as Temporal Engine participant Worker as Orchestrator Worker participant Social as Social Network (X / LinkedIn) User->>API: Submit scheduled post with media API->>DB: Save post entity (Draft / Scheduled) API->>Temp: Start post.workflow.v1.1.2 (target_date) Temp-->>API: Workflow execution started (WorkflowId) API-->>User: 201 Created (post queued) Note over Temp: Temporal engine sleeps durably until target_date Temp->>Worker: Dispatch task to task_queue Worker->>DB: Fetch fresh OAuth access tokens Worker->>Social: Upload media attachment Social-->>Worker: Media upload confirmation Worker->>Social: Publish post content alt API Error / Rate Limited Social-->>Worker: 429 Too Many Requests / 500 Error Worker-->>Temp: Activity failed Note over Temp: Exponential backoff retry policy triggers Temp->>Worker: Re-execute activity after backoff else Success Social-->>Worker: 200 OK (Post ID: 123456) Worker->>DB: Update post status to PUBLISHED Worker->>Temp: Activity completed end ``` Temporal solves this by treating the post lifecycle as code that can sleep, wake up on exact timestamps, and retry failed activities without losing intermediate execution state. --- ## 4. Visual Tour & Interface Workflows Postiz pairs its backend orchestrator with an intuitive interface designed for managing multi-network publishing calendars. ### Multi-Channel Dashboard & Channel Overview The central dashboard provides visibility into all connected platform channels, recent posts, audience growth metrics, and active queue health. ![Postiz Multi-Channel Dashboard](/images/reframehub/postiz/dashboard.webp) Each connected profile displays real-time OAuth token status, platform capabilities, and quick access to individual stream queues. ### Scheduling Calendar Grid The scheduling calendar enables visual time-slot mapping across daily, weekly, and monthly horizons. ![Postiz Visual Calendar Grid](/images/reframehub/postiz/calendar.webp) Users can drag and drop posts between time slots, identify publishing gaps, and coordinate multi-account campaigns across simultaneous dates. ### Multi-Platform Post Composer Drafting content for multiple networks requires handling distinct character limits, hashtag norms, and media aspect ratios. ![Postiz Multi-Platform Post Composer](/images/reframehub/postiz/composer.webp) The composer renders live previews simultaneously across platforms such as X, LinkedIn, Instagram, Threads, and Reddit, catching formatting errors before scheduling. --- ## 5. Total Cost of Ownership (TCO) Evaluating Postiz requires separating open-source software license fees ($0) from server compute, database overhead, and external third-party API costs. ### TCO Comparison: Commercial SaaS vs. Postiz Cloud vs. Self-Hosted The following model compares managing 15 social accounts across three team members publishing approximately 200 posts per month. | Dimension | Commercial SaaS (Buffer / Hootsuite) | Postiz Managed Cloud (Team Tier) | Postiz Self-Hosted (Dedicated VPS) | | :--- | :--- | :--- | :--- | | **Software License** | $90 to $249/mo | $39/mo flat | $0 (AGPL-3.0) | | **Compute & Memory** | Included | Included | $24 to $40/mo (4GB-8GB VPS) | | **Database & Cache** | Included | Included | Included on VPS (Postgres 17 + Redis) | | **Workflow Engine** | Included | Included | Included on VPS (Temporal + ES 7.17) | | **Platform API Fees** | Absorbed by vendor | Absorbed by Postiz Cloud | Direct developer costs (X API: $0-$100/mo) | | **Team Seats** | Restricted or extra ($/seat) | Unlimited | Unlimited | | **Upgrade Maintenance** | Vendor-managed | Vendor-managed | 2-4 hours/month engineering time | | **Total Annual Cost** | **$1,080 to $2,988/yr** | **$468/yr** | **$288 to $1,680/yr** | | **Operational Burden** | Low | Low | Medium to High | ### Understanding the Self-Hosting Math 1. **Compute Sizing**: The Postiz Docker Compose stack runs eight distinct containers. Elasticsearch and Temporal alone allocate roughly 2GB of RAM on cold boot. Attempting to deploy on a $5 per month 1GB VPS causes immediate Linux OOM (Out Of Memory) container kills. Budget at least 4GB RAM ($20 to $24 per month on Hetzner or DigitalOcean), or 8GB RAM ($40 per month) for sustained production workloads. 2. **Social Developer API Costs**: On managed cloud platforms, the vendor pays for developer app verification and enterprise API access. When self-hosting, you must register your own developer applications. Platforms like LinkedIn, Facebook, Instagram, and TikTok allow free API tiers for verified apps. However, X (formerly Twitter) charges $100 per month for their Basic API tier (10,000 read and 50,000 write requests). If X is essential to your stack, self-hosting direct API access adds $1,200 per year unless utilizing existing community keys. --- ## 6. The Bad: What to Know Before Adopting Postiz is a capable platform, but self-hosting introduces non-trivial operational complexity: 1. **Substantial Memory Footprint**: Many self-hosters expect lightweight single-binary Node apps. Postiz runs a distributed system: Elasticsearch 7.17, two distinct PostgreSQL instances (one for app data, one for Temporal), Redis, Temporal auto-setup, and the NestJS services. It requires serious server headroom. 2. **Developer Application Onboarding Friction**: To publish natively to Facebook, Instagram, LinkedIn, or TikTok from a self-hosted instance, you must create developer accounts with each vendor, submit app privacy policies, complete business verification, and configure redirect URIs. This process can take days or weeks for platform approvals. 3. **Dangerous Auth Flags**: The environment file includes a `NOT_SECURED=true` flag designed for single-user local development without login screens. If this flag is accidentally left set on a publicly exposed server, any visitor gains unrestricted administrative control over the entire platform. 4. **SSRF Risks in Federated Plugins**: Postiz supports federated and self-hosted destinations like Mastodon, Lemmy, and WordPress sites. A configuration flag `DISABLE_SSRF_PROTECTION` exists in the codebase. This must always remain `false` in production to prevent malicious actors from using the Postiz backend to scan your private internal VPC networks. 5. **AGPL-3.0 Copyleft Terms**: Postiz is licensed under the GNU Affero General Public License. If you modify Postiz and offer it as a service over a network, you must make your modified source code available under AGPL-3.0. It is not suitable for closed-source SaaS repackaging. --- ## 7. Quickstart & Deployment The standard self-hosted deployment uses Docker Compose. ### 1. Minimal `docker-compose.yaml` A production installation starts the core services alongside the Temporal cluster: ```yaml services: postiz: image: ghcr.io/gitroomhq/postiz-app:latest container_name: postiz restart: always environment: - MAIN_URL=https://social.example.com - FRONTEND_URL=https://social.example.com - NEXT_PUBLIC_BACKEND_URL=https://social.example.com/api - JWT_SECRET=replace_with_secure_random_string_32_chars - DATABASE_URL=postgresql://postiz:postizpassword@postiz-postgres:5432/postiz - REDIS_URL=redis://postiz-redis:6379 - TEMPORAL_ADDRESS=temporal:7233 - STORAGE_PROVIDER=local - UPLOAD_DIRECTORY=/uploads - IS_GENERAL=true volumes: - ./uploads:/uploads ports: - "5200:5200" depends_on: - postiz-postgres - postiz-redis - temporal postiz-postgres: image: postgres:17-alpine container_name: postiz-postgres restart: always environment: - POSTGRES_USER=postiz - POSTGRES_PASSWORD=postizpassword - POSTGRES_DB=postiz volumes: - postgres_data:/var/lib/postgresql/data postiz-redis: image: redis:7.2-alpine container_name: postiz-redis restart: always volumes: - redis_data:/data volumes: postgres_data: redis_data: ``` *(Note: The full Temporal cluster requires `temporal`, `temporal-elasticsearch`, `temporal-postgresql`, and `temporal-admin-tools` as provided in the official repository `docker-compose.yaml`).* ### 2. Autonomous Agent Setup (`postiz-agent`) For AI coding agents and autonomous workflows, Postiz provides a dedicated CLI tool compatible with OpenClaw and standard MCP environments: ```bash # Install the Postiz agent CLI pnpm add -g postiz-agent # Authenticate against your instance postiz-agent login --url https://social.example.com --key YOUR_API_KEY # Schedule a post programmatically postiz-agent schedule \ --providers "twitter,linkedin" \ --content "Automated deployment verified via Postiz orchestrator." \ --time "2026-09-08T18:00:00Z" ``` --- ## 8. ReframeHub Recommendation ### The Deeper Engineering Insight Postiz demonstrates the difference between **ad-hoc job queues** and **durable workflow orchestration**. Most software projects start scheduling timed tasks with simple database polls or Redis job queues. When tasks need to sleep for thirty days, handle multi-step media pipelines, survive process restarts, and apply platform-specific backoff algorithms, basic queues turn into unmaintainable state machines. By building on Temporal, Postiz offloads timer durability and retry state to an event-sourced engine. The trade-off is infrastructure weight: running Temporal and Elasticsearch requires more operational maturity than running a single web server. ### Who Should Use This? - **Development Agencies & Media Teams**: Teams managing 10 to 50 social channels who want to escape per-channel SaaS seat taxes and maintain total ownership over scheduled data. - **Autonomous Agent Builders**: Engineers building agentic workflows with OpenClaw, Hermes, or custom MCP agents who need programmatic publishing tools with built-in token management. - **Privacy-Sensitive Organizations**: Companies operating under strict compliance rules where social drafts and private tokens cannot sit in third-party multi-tenant databases. ### Who Should Stay with Managed SaaS? - **Solo Founders on Budget VPS**: If your infrastructure budget is $5 per month and you have no experience managing Elasticsearch or Temporal clusters, the operational overhead will outweigh SaaS convenience. Postiz's own managed cloud ($29 per month) or a basic Buffer plan is more cost-effective. - **Teams Relying Exclusively on Free Twitter Automation**: Because self-hosting requires providing your own developer credentials, publishing to X requires paying Twitter's $100 per month developer fee directly. Managed SaaS platforms absorb that API fee across their customer pool. ## ReframeHub: Self-Hosted PostgreSQL - Path: https://emiote.com/reframehub/self-hosted-postgres/ - Category: Database - Description: July 2026 Ankik field note: self-hosting PostgreSQL reduced infrastructure cost, while backups, patching, and recovery became our responsibility. - Pricing / Model: open-source (Self-host: Rs 40/mo extra (part of same VM) + S3 for backups, Cloud: $16/mo for RDS db.t3.micro) - Snapshot Date: 2026-08-01 > **Self-Hosted PostgreSQL** is the practice of running the open-source relational database directly on production virtual machines rather than using managed cloud services. It eliminates cloud database markups and connection limits, requiring teams to manage automated backups, failover replication, patching, and memory allocation manually. ## Scope and currency This is a **July 2026** deployment snapshot from Ankik beta, not a current Amazon RDS quote or a universal reliability recommendation. Cost comparison excludes team operating time and should be re-priced for your region, storage, backups, and recovery requirements. Editorial review: `2026-08-10`. ## Deployment snapshot: Ankik, July 2026 Ankik uses PostgreSQL. Initially on RDS `db.t3.micro` ($16/mo). It worked well: auto backups, auto updates. For ~50 beta users, $16 for the database alone felt high. Total with EC2 was ~$39/mo. We moved Postgres onto the same application VM that runs the app (self-hosted, not [full Supabase self-host](/reframehub/supabase/)). ## Cost breakdown | Setup | Monthly cost | What you get | | --- | --- | --- | | RDS db.t3.micro | $16 + storage extra | Managed, auto backup, auto patch | | Self-hosted on same VM | Rs 0 extra compute (shares VM RAM) + ~Rs 40 S3 | You manage everything | ## The Good - Marginal infrastructure cost can be near zero if a correctly sized 4GB VM already exists; **operations still cost time** - Full control: we enabled `pg_stat_statements` for slow-query visibility - Lower latency: app and DB on the same VM, with no network hop - No free-tier connection caps like some serverless Postgres products ## The Bad: What Actually Breaks 1. **Backups:** RDS did them daily. Now we run off-box dumps (and pgbackrest where it matters). If you skip this, data-loss risk is effectively total. 2. **Updates:** RDS patched Postgres for us. We patch manually on a schedule. 3. **Outage at 2 AM:** RDS would auto-restart. Our VM Postgres stopped once due to OOM; we added Uptime Kuma → Telegram. 4. **RAM floor:** On 2GB, Postgres + app crashed. We moved to 4GB. ## When to use / When to skip **Self-host Postgres if:** - Roughly under ~10k users and DB size under ~20GB (your mileage varies) - Someone has basic Docker competence - You can run daily backups **and** a restore drill on a calendar **Keep RDS (or managed Postgres) if:** - No one will own ops - You cannot afford multi-hour recovery improvisation - You need point-in-time recovery without building it yourself ## How we run it safely (checklist) ```yaml # docker-compose.yml snippet postgres: image: postgres:15-alpine restart: unless-stopped environment: POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - pgdata:/var/lib/postgresql/data command: postgres -c shared_buffers=512MB -c max_connections=100 ``` - **Backup:** Daily to S3; weekly full + daily WAL via pgbackrest where required - **Restore test:** Every 15 days we restore on a local machine - **Monitoring:** Postgres down → Telegram alert - Prefer **4GB RAM** when app and Postgres share one VM As of the August 2026 editorial review, we had run this path for about a month on Ankik beta: zero data loss, one manual restart after OOM. If your team can own this checklist, self-hosting may lower the infrastructure bill. If it cannot, managed RDS is often the safer choice. Need help choosing Postgres self-host vs RDS? [Book a Reframe audit for Postgres](/reframe/?from=reframehub&tool=self-hosted-postgres) ($199). Same trade-off lens as [open-source evaluation](/reframehub/open-source-evaluation/). ## What it replaces Amazon RDS, Supabase Cloud DB, Neon, PlanetScale. ## Architecture ```mermaid flowchart TD App -->|TCP 5432| Postgres[Postgres 15-alpine] Postgres -->|WAL + dumps| S3[Backups S3] UptimeKuma -->|alert| Telegram ``` ## Visual Tour / Workflow ![PostgreSQL Production Terminal and Query Statistics](/images/reframehub/self-hosted-postgres/browser-preview.webp) Operational verification of containerized PostgreSQL with connection pooling and automated WAL archiving. ## Quickstart / Deployment Deploy via Docker Compose on a minimum 4GB RAM virtual machine, configure `pg_stat_statements` for query tracking, and set up daily S3 backup rotation. ## Recommendation Self-host PostgreSQL when database size is under 20GB, team members understand Docker volume persistence and WAL archiving, and daily backup restore drills are practiced regularly. Choose managed cloud services when high availability SLA guarantees and multi-region failover are required without in-house systems operations. ## ReframeHub: Supabase - Path: https://emiote.com/reframehub/supabase/ - Category: Database - Description: Open-source Firebase alternative: managed Postgres, Auth, Storage, and Realtime. Choose Cloud ($25/mo) unless self-hosting capacity justifies ops cost. - Pricing / Model: open-source (Self-host: Rs 800/mo on 4GB VM (needs more RAM), Cloud: $25/mo Cloud (or $0 free tier)) - Snapshot Date: 2026-05-10 > **Supabase** is an open-source Firebase alternative providing managed PostgreSQL, authentication, storage, edge functions, and realtime subscriptions in a unified platform. Engineering teams choose Supabase Cloud ($25/mo) to offload database maintenance, evaluating self-hosted deployments on Linux VMs only when regional compliance, data sovereignty, or infrastructure ownership outweighs ongoing operational maintenance overhead. ## What It Replaces Supabase replaces proprietary backend-as-a-service platforms and fragmented self-hosted components: 1. **Google Firebase**: Replaces proprietary NoSQL Firestore with relational PostgreSQL, Firebase Auth with standard JWT authentication, and Firebase Storage with S3-compatible object storage. 2. **AWS Amplify**: Replaces complex CloudFormation and AppSync deployments with a single cohesive developer interface and instant REST APIs. 3. **Fragmented In-House Stacks**: Eliminates the need to independently assemble and maintain separate services for Postgres, Redis pub/sub, authentication microservices, and file storage gateways. --- ## Architecture Supabase integrates open-source projects behind a unified Kong API gateway: ```mermaid flowchart TD Client[Web & Mobile Clients] -->|HTTP / WebSocket| Kong[Kong API Gateway] Kong -->|/auth/v1| GoTrue[GoTrue Auth Service] Kong -->|/rest/v1| PostgREST[PostgREST Engine] Kong -->|/realtime/v1| Realtime[Realtime WebSocket Engine] Kong -->|/storage/v1| Storage[Storage API Service] Kong -->|/studio| Studio[Supabase Studio UI] GoTrue --> Postgres[(PostgreSQL 15 Core)] PostgREST --> Postgres Realtime -->|WAL Logical Replication| Postgres Storage --> Postgres Storage --> ObjectStore[(S3 / Local Storage)] ``` The core architecture treats PostgreSQL as the single source of truth. Security and data isolation are enforced directly at the database layer using PostgreSQL Row Level Security (RLS) policies rather than custom application middleware. --- ## Visual Tour / Workflow The Supabase developer experience combines a graphical database dashboard with instant API reflection: ![Supabase Studio Web Dashboard and Schema Designer](/images/reframehub/supabase/browser-preview.png) 1. **Visual Schema & Table Editor**: Teams design tables, configure foreign keys, and establish column-level constraints without writing raw DDL queries. 2. **Integrated SQL Editor & Plan Analyzer**: Execute arbitrary SQL queries, inspect execution plans via `EXPLAIN ANALYZE`, and optimize slow join queries directly in the browser. 3. **Declarative Row Level Security (RLS)**: Configure authentication rules directly on database tables so that client applications query Postgres directly with total tenancy safety. 4. **Auto-Generated REST & GraphQL Endpoints**: Any table created in the schema instantly exposes OpenAPI-documented endpoints with filtering, pagination, and relational joins. --- ## Total Cost of Ownership (TCO) | Evaluation Dimension | Google Firebase | Supabase Cloud (Pro) | Supabase Self-Hosted | | :--- | :--- | :--- | :--- | | **Base Monthly Cost** | Pay-as-you-go ($0 to $100s) | **$25 / month** flat | **~$15 to $30 / mo** (4GB to 8GB VM) | | **Database Engine** | Proprietary Firestore NoSQL | **Vanilla PostgreSQL 15** | **Vanilla PostgreSQL 15** | | **Backup Automation** | Point-in-time add-on | Included daily backups | Manual cron dumps to S3 | | **Operational Overhead** | Zero maintenance | Zero maintenance | 4 to 8 hours / month (patching, upgrades) | | **Row Level Security** | Firebase Rules syntax | **Native PostgreSQL RLS** | **Native PostgreSQL RLS** | | **Bandwidth & Egress** | $0.12 per GB | 250 GB included | Included in cloud VM allocation | | **Total Annualized Cost** | **$300 to $2,400+ / yr** | **$300 / yr** | **$180 / yr + engineer ops hours** | --- ## The Bad While Supabase provides strong developer velocity, self-hosting introduces distinct operational liabilities: 1. **Substantial Memory Requirements**: Running the full Docker Compose stack (Postgres, Kong, GoTrue, PostgREST, Realtime, Storage, and Studio) crashes reliably on 2GB VMs. A minimum of 4GB RAM is required for testing, and 8GB RAM is strongly recommended for production stability. 2. **Reverse Proxy & Storage Conflicts**: Deploying Supabase storage behind Cloudflare proxy with caching active frequently causes file upload checksum mismatches. Storage hostnames must bypass Cloudflare edge caching. 3. **Multi-Container Version Orchestration**: Upgrading self-hosted Supabase requires updating multiple Docker images simultaneously. Version mismatches between GoTrue and PostgreSQL extensions can cause authentication downtime. 4. **Realtime Domain Routing**: Setting up WebSockets for Realtime across custom domains requires precise environment variable tuning for SSL termination and upstream proxy handshakes. --- ## Quickstart / Deployment ### Managed Cloud Deployment 1. Create a project at [supabase.com](https://supabase.com). 2. Connect with your client SDK using the project URL and anonymous public API key. ### Self-Hosted Docker Compose Setup ```bash # Clone the official deployment repository git clone --depth 1 https://github.com/supabase/supabase # Navigate to docker environment and generate secret keys cd supabase/docker cp .env.example .env # Pull images and launch the cluster on a 4GB+ Linux VM docker compose pull docker compose up -d ``` --- ## Recommendation For startup founders, agencies, and lean product teams: **Default to Supabase Cloud**. The $25/month Pro tier eliminates hours of infrastructure toil, automated backup configuration, and container debugging. Evaluate self-hosting only when: - Regulatory mandates require data storage on private on-premise hardware. - Monthly managed database bills exceed several hundred dollars while your team already retains dedicated systems administrators. If your engineering team needs an objective evaluation of managed cloud databases vs self-hosting, book an **[Emiote Stack Review](/reframe/?from=reframehub&tool=supabase)** ($199 USD). ## ReframeHub: X Algorithm - Path: https://emiote.com/reframehub/x-algorithm/ - Category: Developer Tools - Description: Deep dive into xAI's open-source Rust Home Mixer, Phoenix recommendation models, candidate retrieval, ranking, and visibility filtering pipeline. - Pricing / Model: open-source (Self-host: Open source; the repository includes a runnable nano Phoenix training/retrieval path for local experimentation, Cloud: Not applicable; production-scale infrastructure costs are not published by the repository) - Snapshot Date: 2026-09-01 > **The X Algorithm** (`xai-org/x-algorithm`) is the open-source codebase for the **For You** feed recommendation system on X. The repository exposes the Rust-based **Home Mixer** orchestration and feed pipeline, candidate retrieval through **Thunder**, **Phoenix**, and **SimClusters**, learned ranking models, visibility filtering, and supporting training/reference infrastructure. --- ## 1. Why the X Algorithm Matters Recommendation systems are often treated as black boxes. X has now open-sourced a substantial portion of the architecture behind its **For You** feed, making it possible to inspect how candidate generation, filtering, machine-learned ranking, selection, and visibility decisions fit together. The important architectural idea is not that every decision is made by one neural network. Instead, the system combines: 1. **Learned relevance models** for predicting viewer behavior. 2. **Fast candidate sources** for posts from followed and non-followed accounts. 3. **Deterministic filters and business logic** around the ranking model. 4. **Visibility and safety systems** that can determine whether a post is allowed to appear at all. 5. **Configuration and experimentation** that control how the pipeline behaves. ```mermaid flowchart TD subgraph Ingestion["1. Context & Query Hydration"] Context["Viewer Context<br/>(Action history, social graph, blocks/mutes, topics)"] end subgraph Retrieval["2. Candidate Retrieval"] Thunder["In-Network: Thunder<br/>(Followed accounts in-memory store)"] PhoenixRetrieval["Out-of-Network: Phoenix<br/>(ANN vector embedding index)"] SimClusters["Out-of-Network: SimClusters<br/>(Community cluster representations)"] end subgraph Processing["3. Candidate Hydration & Pre-Filters"] Hydration["Candidate Hydration<br/>(Post text, media, author features, subscriptions)"] PreFilters["Pre-Scoring Filters<br/>(Deduplication, age thresholds, mute/block lists)"] end subgraph Scoring["4. Neural Ranking & Scoring"] Ranker["Phoenix Neural Ranker<br/>(Multi-action transformer predictions)"] Scorer["RankingScorer<br/>(Weighted sum of action probabilities)"] Adjustments["Ranking Adjustments<br/>(Author diversity decay, out-of-network boosts)"] end subgraph Delivery["5. Visibility Filtering & Blending"] Visibility{"Visibility Filtering<br/>(ALLOW / INTERSTITIAL / DROP)"} Blending["Blending Pipeline<br/>(Interleaves Ads, Prompts, Who to Follow)"] Feed["Final For You Feed Delivery"] end Context --> Thunder & PhoenixRetrieval & SimClusters Thunder & PhoenixRetrieval & SimClusters --> Hydration Hydration --> PreFilters PreFilters --> Ranker Ranker --> Scorer Scorer --> Adjustments Adjustments --> Visibility Visibility -->|ALLOW| Blending Blending --> Feed ``` --- ## 2. Core Architecture & Request Lifecycle When a For You request is processed, the repository describes a pipeline roughly like this: **Query hydration → candidate retrieval → candidate hydration → pre-scoring filters → scoring → selection → post-selection filtering → blending** ### 1. Query Hydration Home Mixer gathers viewer context, including: - Recent user action history. - Following relationships. - Blocks and mutes. - Muted keywords. - Followed topics. - Posts already seen or served. This context is used both for candidate generation and for personalized ranking. ### 2. Candidate Retrieval The repository separates candidate sources into **in-network** and **out-of-network** paths. **In-network** **Thunder** provides recent posts from accounts the viewer follows. **Out-of-network** **Phoenix retrieval** and **SimClusters** provide candidates from outside the viewer's direct network. The important point is that X does not simply rank the posts from accounts you follow. The For You feed intentionally combines content from your existing network with content discovered outside it. ### 3. Candidate Hydration Candidates are enriched with information needed by later stages, such as: - Post text and media. - Author information and labels. - Quoted-post information. - Language. - Engagement information. - Subscription/access information. ### 4. Pre-Scoring Filters Before ranking, the pipeline can remove candidates for reasons including: - Duplicate posts across sources. - Posts older than the configured age threshold. - The viewer's own posts. - Blocked or muted accounts. - Muted keywords. - Posts already seen or served. - Inaccessible subscriber-only posts. --- ## 3. Phoenix: Retrieval and Ranking Models One of the easiest ways to misunderstand the repository is to describe Phoenix as simply a conventional "two-tower model." The current codebase contains **both retrieval and ranking paths**, and the ranking model uses a transformer-style architecture over user/history and candidate representations. The Phoenix ranking model predicts multiple engagement outcomes simultaneously rather than producing one unexplained relevance number. The repository's model documentation describes attention relationships between: - User/history representations. - Candidate representations. - Candidate-to-candidate interactions. This makes Phoenix better described as a **multi-action transformer-based recommendation model with separate retrieval and ranking paths**, rather than reducing the entire system to cosine similarity between one user vector and one post vector. ```mermaid flowchart TD subgraph Inputs["Input Representations"] UserRepr["Viewer Context & History<br/>(Recent engagements, clicks, mutes)"] PostRepr["Candidate Post Features<br/>(Post text, author signals, media)"] end subgraph RetrievalPath["Path A: Phoenix Retrieval (Two-Tower ANN)"] UserTower["User Embedding Tower"] PostTower["Candidate Embedding Tower"] ANN["Approximate Nearest Neighbor (ANN)<br/>Fast sub-millisecond retrieval from millions"] end subgraph RankingPath["Path B: Phoenix Neural Ranker (Multi-Action Transformer)"] CrossAttn["Cross-Attention & Transformer Layers<br/>(Viewer-to-candidate & candidate-to-candidate interactions)"] subgraph MultiTask["Simultaneous Action Heads"] Fav["P(Favorite)"] Rep["P(Reply)"] Ret["P(Repost)"] Clk["P(Click / Dwell)"] Neg["P(Negative Signal)"] end RankingScorer["RankingScorer<br/>Score = ∑ (wₐ · P(actionₐ))"] end UserRepr --> UserTower PostRepr --> PostTower UserTower & PostTower --> ANN ANN -->|"Retrieved Candidate Pool"| CrossAttn UserRepr & PostRepr --> CrossAttn CrossAttn --> Fav & Rep & Ret & Clk & Neg Fav & Rep & Ret & Clk & Neg --> RankingScorer ``` ### What the model is trying to predict The ranking model contains multiple engagement targets, including actions such as: - Favorite - Reply - Repost - Click - Share - Profile click - Dwell/watch-time related signals - Negative feedback signals The exact set and configuration are represented in the repository's model and ranking code. --- ## 4. Scoring, Ranking & Visibility Filtering This is one of the most interesting parts of the source code. ### Multi-Action Prediction Phoenix produces predictions for multiple possible actions. The RankingScorer then combines predicted action values using configurable weights. Conceptually: ```text Score = ∑ [ wₐ · P(actionₐ | viewer, post) ] ``` with additional ranking adjustments and gates applied by the pipeline. ### An Important Misconception The repository explicitly warns against interpreting ranking weights as raw engagement-count equivalents. For example, it would be wrong to conclude: > "One report cancels out hundreds of likes." The weights apply to the **predicted probability/value of an action**, not raw counts of actions. This distinction matters because those predictions are personalized to the viewer. A Like weight therefore does not mean: > 1 Like = X ranking points. It means the model's predicted likelihood/value of that viewer taking the action contributes to the candidate's score according to the configured weight. ### Ranking Adjustments The ranking code also contains mechanisms such as: - Repeated-author decay. - Out-of-network adjustments. - New/unexplored-post signals. - Negative-feedback signals. - Special boosts under particular conditions. These mechanisms sit around the learned predictions rather than replacing them. ### Selection After scoring, the system selects the highest-ranked candidates. ### Visibility Filtering Ranking is not the same thing as permission to show a post. The repository contains a separate **visibility-filtering** system that can determine whether a candidate should: - **ALLOW** - appear normally. - **INTERSTITIAL** - appear behind an additional warning/interstitial. - **DROP** - not appear. This means a highly ranked post can still be removed by downstream visibility or safety logic. --- ## 5. The Full For You Feed Is More Than Ranking The repository describes two major paths: ### Post Pipeline This path handles finding, ranking, filtering, and selecting posts. ### Blending Pipeline The final For You experience also includes items that are not simply ranked posts, such as: - Ads - Who to Follow recommendations - Prompts - Other feed-level items A blending stage interleaves these with ranked posts. This is an important architectural distinction: > **The recommendation model is only one component of the complete feed system.** --- ## 6. The Labeling & Safety Path Visibility decisions can depend on labels generated outside the immediate request-time ranking flow. The repository includes systems for: - Text/content classification. - Image and video analysis. - Account-level signals. - Rule-based labeling. - Abuse enforcement. - Safety-related aggregation. These labels can be stored and later consumed by visibility filtering. This creates a separate path: **Content/account analysis → labels → storage → visibility filtering** rather than requiring every safety decision to be computed from scratch during every feed request. --- ## 7. Training & Local Experimentation The repository includes a runnable **nano Phoenix** reference path for experimentation. The documented quickstart can: 1. Generate synthetic data. 2. Train nano ranking and retrieval models. 3. Write checkpoints. 4. Resume training. 5. Serve the models. 6. Send a retrieve → rank request. Important limitation: > This is a reference/proof-of-concept path, not a reproduction of X's production-scale recommendation infrastructure. The repository explicitly states that production data, production checkpoints, orchestration, and production scale are not included. A simplified starting point is: ```bash git clone https://github.com/xai-org/x-algorithm.git cd x-algorithm # Follow the repository's Phoenix QUICKSTART.md # to generate synthetic data, train the nano models, # serve them, and run a retrieve -> rank request. ``` ## The Bad - Production scale is not reproducible locally without proprietary distributed training clusters. - Safety and visibility filtering operate as separate pipelines; high ranking scores do not guarantee post display. - Synthetic data generation in the quickstart serves as an architectural reference rather than production infrastructure. ## Visual Tour / Workflow ![xAI Recommendation Algorithm Repository and Architecture Pipeline](/images/reframehub/x-algorithm/browser-preview.png) 1. **Repository Layout**: Rust-based Home Mixer coordinates retrieval, scoring, and blending across modular submodules. 2. **Hydration Phase**: User actions, blocks, mutes, and follow graphs hydrate candidate post queries in parallel. 3. **Scoring & Selection**: Two-tower Phoenix models compute interaction probabilities before downstream visibility filters apply policy rules. ## Quickstart / Deployment Clone `xai-org/x-algorithm`. Follow `QUICKSTART.md` in the Phoenix directory to run synthetic training and verify scoring pipelines locally. ## Total Cost of Ownership (TCO) The repository is open source under GNU AGPL v3. Self-hosted compute cost depends on vector index sizing and GPU inference clusters. For standard production applications, self-hosting this infrastructure requires full-time ranking and machine learning operations engineers. ## Recommendation Inspect the repository for systems engineering and multi-stage candidate generation patterns. Use managed recommendation engines or simpler retrieval-augmented pipelines for product MVP feeds unless your business demands petabyte-scale custom feed orchestration. --- # Studio Journal Articles ## Journal: The Day-29 Problem: What to Instrument Post-Launch - Path: https://emiote.com/journal/the-day-29-problem-what-to-instrument/ - Date: 2026-09-10 - Category: Product - Reading Time: 6 min - Description: What founders must measure the morning after launch before spending money on marketing. The minimal 4-point telemetry stack that reveals drop-off. When a team completes a twenty-eight-day build sprint, there is an understandable temptation to celebrate. The core workflow runs on production, payment processing is connected, and the domain DNS resolves cleanly. Then comes day twenty-nine. The product is live to the public. The founder posts an announcement on LinkedIn or sends an email to fifty waitlist leads. Twenty people click the link, three create accounts, and then everything goes silent. Did those seventeen visitors leave because the value proposition was weak? Did the registration form throw an unhandled JavaScript error on Safari mobile? Did the onboarding email get routed to the spam folder? Without instrumentation, founders cannot answer these questions. They spend money on marketing and paid advertising to drive more traffic into a leaky bucket, completely unaware that a broken form input or a confusing third screen is killing user activation. Here is the minimal four-point telemetry stack that every product must have running on day twenty-nine before spending a single dollar on distribution. --- ## The day-29 telemetry architecture You do not need an enterprise observability suite or a dedicated data team. You need four specific telemetry loops wired to alert you when user friction occurs: ```mermaid flowchart TD subgraph UserJourney["User Funnel"] Visit["1. Landing Page Visit"] --> Signup["2. Registration Attempt"] Signup --> Activation["3. Core Transaction Completion"] Activation --> ReturnVisit["4. Day 7 Return Visit"] end subgraph TelemetryStack["Deterministic Telemetry Stack"] Visit -.->|Plausible / Webhook| FunnelMetric["Activation Funnel Counter"] Signup -.->|Sentry / Error Handler| ErrCatch["Unhandled Client Exception Alert"] Activation -.->|Database Query / Cron| MetricDB["Completed Transaction Rate"] ReturnVisit -.->|Weekly Cohort Query| RetentionTable["7-Day Retention Metric"] end subgraph Alerts["Founder Notification Channel"] ErrCatch --> Slack["Founder Telegram / Slack Alert<br/>(Immediate notification on 5xx or unhandled JS)"] FunnelMetric --> Summary["Daily Metrics Summary Email"] end ``` | Layer | Question It Answers | Recommended Tool | Alert Condition | | --- | --- | --- | --- | | **1. Unhandled Errors** | Is the interface breaking on real devices? | Sentry or GlitchTip | Any unhandled 500 error or frontend exception alerts immediately | | **2. Funnel Activation** | Where do users drop out before the core job? | PostHog or database audit log | Registration to first completion rate falls below 40% | | **3. Core Transaction Volume** | Did anyone actually complete the primary job today? | Direct SQL dashboard / query | Daily count of primary state mutations | | **4. In-App Friction Signal** | What confusing step caused users to abandon? | Native feedback widget / Crisp | Immediate notification when a user submits a question | --- ## 1. Unhandled client and server exceptions Never rely on users to tell you when something is broken. When a user encounters an unexpected bug during onboarding, they do not file a bug ticket. They close the browser tab and never return. Before sending your first announcement: - Connect an error tracking service like Sentry or self-hosted GlitchTip. - Configure source maps so error traces point to the exact TypeScript file and line number rather than minified bundle code. - Route error notifications directly to a dedicated Slack channel or Telegram bot. When an exception triggers, inspect the payload immediately: browser version, operating system, network status, and the user's action immediately before the crash. Fixing a mobile rendering bug within fifteen minutes of a visitor reporting it turns a skeptical visitor into an advocate. --- ## 2. The single activation funnel metric Many founders install Google Analytics or Mixpanel and track eighty-five different button hover events. They end up with cluttered dashboards and zero actionable clarity. Focus on one three-step conversion funnel: ``` [Visits Landing Page] ──> [Creates Account] ──> [Completes Core Mutation] ``` In Ankik, the activation funnel is simple: 1. User registers an account. 2. User enters company details. 3. User posts their first ledger invoice. If a hundred people sign up and eighty-five post an invoice, your onboarding is functional. If a hundred people sign up and four post an invoice, your interface is blocking users. By measuring the drop-off rate at each step, you know exactly where to intervene: - Drop-off between visit and signup indicates a messaging or positioning problem. - Drop-off between signup and first invoice indicates interface confusion or excessive onboarding form fields. --- ## 3. Direct SQL query for completed transactions Third-party analytics tools can fail due to ad blockers or client tracking prevention. Your production database never lies. Create a simple daily SQL script or a lightweight Metabase/Metabase-alternative dashboard that counts completed business transactions: ```sql -- Daily core transaction volume check SELECT DATE(created_at) AS date_day, COUNT(DISTINCT organization_id) AS active_tenants, COUNT(id) AS total_invoices_created, ROUND(SUM(amount_cents) / 100.0, 2) AS total_volume_transacted FROM invoices WHERE created_at >= NOW() - INTERVAL '7 days' GROUP BY DATE(created_at) ORDER BY date_day DESC; ``` This query tells you the ground truth: are real accounts logging in and performing work? If active tenants count increases while total invoices created remains flat, users are logging in but failing to find utility. --- ## 4. An immediate, low-friction feedback channel In the first thirty days post-launch, your most valuable asset is raw, unvarnished user feedback. Do not send forty-question survey forms via email two weeks later. Add a visible, single-input feedback widget directly inside the application interface: ```typescript // Minimal in-app feedback submission async function submitFrictionReport(message: string) { await fetch("/api/feedback", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message, currentUrl: window.location.pathname, browser: navigator.userAgent, }), }); } ``` When a user gets confused, they can type two sentences and click submit. Send this feedback directly to your phone via webhook. When a user submits "I cannot figure out how to add sales tax to this invoice," reply personally within twenty minutes explaining the feature. Early-stage software retention is built through rapid, responsive human engineering support. --- ## Measure first, scale second Launching a product is not the finish line. It is the beginning of the learning loop. Before launching marketing campaigns, make sure your telemetry is running. When you can see every unhandled error, identify every funnel drop-off point, and observe real database activity daily, you can iterate calmly based on facts rather than assumptions. To learn how we build and instrument production MVPs in four weeks, read our [28-day build sprint breakdown](/journal/how-we-ship-core-in-14-days-live-in-28/) or [reach out to our engineering team](/contact?service=build-sprint). ## Journal: The Only Technical Debt Acceptable in an MVP - Path: https://emiote.com/journal/acceptable-technical-debt-in-an-mvp/ - Date: 2026-09-09 - Category: Engineering - Reading Time: 5 min - Description: The distinction between borrowed debt that speeds delivery and toxic debt that requires a total rewrite. A practical categorization framework. When founders and engineers discuss building an MVP in twenty-eight days, the first question is usually about technical debt. Will cutting timeline force us to write disposable code? Will we have to throw the software away and start over once we get our first thousand users? The answer depends on understanding what technical debt actually is. Ward Cunningham originally coined the metaphor to describe a deliberate financial loan: you borrow speed today to validate an idea with real users, knowing that you will pay back the principal with interest once the market confirms the opportunity. Problems occur when teams do not differentiate between **borrowed debt** and **toxic debt**. Borrowed debt speeds up learning and can be repaid in clean, incremental refactors. Toxic debt poisons the data layer, introduces silent corruptions, and forces teams into painful ground-up rewrites. --- ## Borrowed debt vs Toxic debt ```mermaid flowchart TD subgraph Borrowed["Borrowed Debt (Acceptable in MVP)"] B1["Manual founder operations (no admin UI)"] B2["Basic SQL queries without caching layers"] B3["Single transactional email templates"] B4["Synchronous report generation for small data"] end subgraph Toxic["Toxic Debt (Unacceptable in Any Release)"] T1["Untyped databases & missing foreign keys"] T2["Floating-point math for financial balances"] T3["Leaky tenant isolation boundaries"] T4["Mutations executed without database transactions"] end Borrowed --> Payoff["Repayable in Days 30 to 90 as Revenue Grows"] Toxic --> Rewrite["Requires Painful Ground-Up Database Rewrite"] ``` | Dimension | Borrowed Debt (Safe to Defer) | Toxic Debt (Fatal to Product) | | --- | --- | --- | | **Data Integrity** | Strict PostgreSQL types and constraints | Loose text fields, nullable assumptions | | **Financial Ledger** | Integer cents stored in atomic transactions | Floating-point numbers, unbalanced rows | | **Admin Operations** | Founder runs direct SQL scripts to update users | Unauthenticated backdoor endpoints | | **Background Processing** | Simple cron script polling a single table | Race conditions silently dropping records | | **Cost to Repay** | Two days of developer time | Complete database migration and data repair | --- ## The three forms of acceptable borrowed debt When building an MVP under strict timeline constraints, here are the three areas where taking on technical debt is smart engineering: ### 1. Manual operations instead of bespoke admin panels Building a custom dashboard where customer support agents can refund orders, change plan tiers, or reassign organizations takes two weeks of development time. In week one or two, founders can execute these updates directly in a database GUI like TablePlus using prepared SQL statements: ```sql -- Acceptable borrowed debt: Manual plan upgrade via secure SQL query UPDATE organizations SET plan_tier = 'growth', updated_at = NOW() WHERE id = 'a8f5c31e-42b7-4d98-8e2b-7f1234567890'; ``` Running direct queries for your first twenty customers costs twenty minutes a week. Building the full admin interface can wait until manual operations become a measurable bottleneck. ### 2. Basic database queries without caching layers Do not set up Redis clusters or memcached layers for an application that gets three queries per minute. A standard PostgreSQL query on an indexed column takes three milliseconds. Premature caching introduces cache invalidation bugs where users see stale data after updating their profile. Rely on standard PostgreSQL indexes until slow query monitoring proves that database CPU is constrained. ### 3. Synchronous processing for low-volume jobs If generating a customer invoice takes 200 milliseconds, generate it synchronously during the HTTP request. You do not need a distributed Celery or Kafka queue to process seven invoices a day. When background volume increases, extracting that logic into a background worker takes half an engineering day because the database schema remains cleanly typed. --- ## The four forms of toxic debt: Never compromise Some shortcuts save two hours during week one but destroy the company in month six. We reject these shortcuts in every build sprint: ### 1. Untyped databases and missing foreign key constraints Using string fields for dates, storing currency as floating-point numbers (`19.99` instead of `1999` cents), or skipping foreign keys to make schema prototyping faster leads to corrupted data. Once bad data enters a database, fixing it requires writing complex reconciliation scripts to guess which records belong together. ### 2. Missing database transactions on mutations If an action creates a billing record and deducts inventory, both operations must occur within a single SQL transaction: ```sql BEGIN; INSERT INTO invoice_payments (invoice_id, amount_cents) VALUES ($1, $2); UPDATE invoices SET status = 'paid' WHERE id = $1; COMMIT; ``` Writing separate independent queries without transactions means a network hiccup leaves an invoice marked as unpaid while charging the customer. ### 3. Loose tenant boundaries in application code Relying on developers to remember `WHERE organization_id = $1` in every application query is a guarantee that someone will eventually forget it, exposing private customer records. Enforce isolation with PostgreSQL Row-Level Security from day one. ### 4. Zero automated test coverage on core financial paths You do not need 100% test coverage on marketing pages. But the central transaction that charges cards or balances ledger entries must have automated tests. If you cannot refactor an internal function without fear of breaking payments, velocity slows to a crawl. --- ## Borrow with intent, repay with discipline Speed in software engineering does not come from writing reckless code. It comes from ruthlessly cutting non-essential features while keeping the foundation solid. Borrow debt on the perimeter: skip the admin dashboard, defer custom email notifications, and keep caching simple. Never borrow debt on the data model, financial calculations, or tenant boundaries. When your foundations are sound, scaling from fifty users to five thousand users is an orderly engineering task rather than an emergency rewrite. To learn how we prune scope while protecting data integrity, read our [MVP scope pruning framework](/journal/mvp-scope-pruning-must-ship-vs-deferred/) or [talk to our studio about your product architecture](/contact?service=build-sprint). ## Journal: Multi-Tenancy Without Microservices: PostgreSQL RLS - Path: https://emiote.com/journal/multi-tenancy-without-microservices-rls/ - Date: 2026-09-08 - Category: Engineering - Reading Time: 6 min - Description: How Ankik isolates tenant data using PostgreSQL Row-Level Security in a single database instead of spinning up complex multi-database clusters. When engineering teams design multi-tenant B2B software, they often look at architecture patterns from multi-billion-dollar enterprise platforms. They consider three approaches: 1. **Database-per-tenant:** Provisioning a separate PostgreSQL instance or managed cloud database for every customer account. 2. **Schema-per-tenant:** Creating a new PostgreSQL schema with duplicate table definitions whenever an organization registers. 3. **Shared database with Row-Level Security (RLS):** Storing all tenant records in shared tables with an `organization_id` foreign key, isolated deterministically at the database engine level. Many teams prematurely pick database-per-tenant or schema-per-tenant because they worry that a shared database might leak data between competing customers. When building Ankik, our cloud accounting platform for small businesses, we evaluated all three models. We chose a shared single database with PostgreSQL Row-Level Security. Here is why that decision saved months of operational maintenance while providing absolute tenant data isolation. --- ## Architectural trade-offs across tenancy models ```mermaid flowchart TD subgraph ModelA["1. Database-Per-Tenant (Operational Nightmare)"] AppA["App Server"] --> PoolA["Connection Pooler"] PoolA --> DB1[("Tenant 1 DB")] PoolA --> DB2[("Tenant 2 DB")] PoolA --> DBN[("Tenant 500 DB...")] end subgraph ModelB["2. Schema-Per-Tenant (Migration Friction)"] AppB["App Server"] --> SingleDB1[("Single Database")] SingleDB1 --> S1["Schema: tenant_1 (50 tables)"] SingleDB1 --> S2["Schema: tenant_2 (50 tables)"] SingleDB1 --> SN["Schema: tenant_500..."] end subgraph ModelC["3. Shared Tables with PostgreSQL RLS (Ankik Architecture)"] AppC["App Server"] --> SingleDB2[("Single Database")] SingleDB2 --> SharedTables["Shared Tables (invoices, accounts, entries)<br/>WHERE organization_id = current_setting('app.current_org')"] end ``` | Dimension | Database-Per-Tenant | Schema-Per-Tenant | Shared Database with RLS | | --- | --- | --- | --- | | **Data Isolation** | Physical separation | Logical schema boundary | Database engine kernel policies | | **Running 500 Migrations** | 500 connection runs, 45 minutes | 500 schema loops, 15 minutes | 1 migration transaction, 2 seconds | | **Connection Pooling** | Hundreds of idle pools, RAM exhaustion | Shared pool, search_path churn | Standard connection pool, minimal RAM | | **Cross-Tenant Analytics** | Requires external ETL / data warehouse | Complex cross-schema unions | Standard SQL aggregation with index | | **Monthly Hosting Cost** | $1,500+ across cloud instances | $80 to $200 managed instance | $10 to $20 on standard VPS | --- ## The hidden pain of schema-per-tenant Schema-per-tenant looks clean in early documentation: every tenant gets `CREATE SCHEMA tenant_123` containing fresh tables. The problems start when you release software updates: - **Migration duration multiplies:** Adding a column to an invoices table requires running the `ALTER TABLE` statement 500 times in sequence. If schema 341 fails due to a lock timeout, your migration pipeline halts halfway through, leaving your system in an inconsistent multi-version state. - **Connection pool thrashing:** Every request must execute `SET search_path = tenant_123;` before querying tables. This invalidates prepared statements in database connection poolers like PgBouncer, increasing query latency. - **System catalog bloat:** A database with 50 tables across 500 schemas contains 25,000 table definitions. The PostgreSQL internal system catalog slows down, memory consumption spikes, and backups take hours. --- ## How PostgreSQL Row-Level Security works Row-Level Security moves authorization from application code into the database kernel. Even if an application developer writes `SELECT * FROM invoices;` without an explicit where clause, PostgreSQL transparently appends the tenant security filter before running query execution plans. ### Step 1: Enable RLS on the table ```sql ALTER TABLE invoices ENABLE ROW LEVEL SECURITY; ALTER TABLE invoices FORCE ROW LEVEL SECURITY; ``` The `FORCE` directive ensures that table owners and background roles cannot bypass policies accidentally. ### Step 2: Define the security policy ```sql CREATE POLICY tenant_isolation_policy ON invoices FOR ALL USING (organization_id = NULLIF(current_setting('app.current_org_id', true), '')::uuid) WITH CHECK (organization_id = NULLIF(current_setting('app.current_org_id', true), '')::uuid); ``` - `USING` controls read visibility (`SELECT`, `UPDATE`, `DELETE`). - `WITH CHECK` controls write validity (`INSERT`, `UPDATE`), preventing tenant A from writing records stamped with tenant B's identifier. ### Step 3: Set tenant context per transaction When an incoming HTTP request is authenticated, the application server opens a database connection and sets the session context within the active transaction: ```typescript export async function executeTenantQuery<T>( orgId: string, callback: (client: pg.PoolClient) => Promise<T> ): Promise<T> { const client = await pool.connect(); try { await client.query("BEGIN;"); // Set tenant context for the duration of this single transaction await client.query("SELECT set_config('app.current_org_id', $1, true);", [orgId]); const result = await callback(client); await client.query("COMMIT;"); return result; } catch (error) { await client.query("ROLLBACK;"); throw error; } finally { client.release(); } } ``` The third argument in `set_config(..., true)` marks the parameter as transaction-local (`is_local = true`). When the transaction finishes or rolls back, the context resets automatically, preventing leakage when the connection returns to the connection pool. --- ## Testing isolation in CI We test tenant isolation using automated integration tests that intentionally attempt data leaks: ```typescript test("tenant B cannot read invoices created by tenant A", async () => { const orgA = await createTestOrganization(); const orgB = await createTestOrganization(); // Insert an invoice under Organization A const invoiceA = await executeTenantQuery(orgA.id, async (client) => { return createInvoice(client, { amountCents: 50000 }); }); // Attempt to query the same invoice ID under Organization B const fetchedByB = await executeTenantQuery(orgB.id, async (client) => { const res = await client.query("SELECT * FROM invoices WHERE id = $1;", [invoiceA.id]); return res.rows[0] ?? null; }); expect(fetchedByB).toBeNull(); }); ``` If any developer removes the RLS policy or changes the configuration key, this test fails immediately in CI. --- ## The performance reality: Indexed RLS is fast A common concern is that checking RLS on every row adds query overhead. In practice, every table in a multi-tenant application must include a composite index starting with `organization_id`: ```sql CREATE INDEX idx_invoices_org_date ON invoices (organization_id, created_at DESC); ``` When PostgreSQL applies the RLS policy, the query planner uses this index to jump directly to the tenant's index partition. Query execution times on our production Ankik ledger remain under 12 milliseconds across queries joining multiple financial tables. --- ## Keep your operational footprint minimal Building a B2B SaaS does not require running complex multi-database infrastructure or coordinating dozens of isolated schema migrations. By combining PostgreSQL Row-Level Security with transactional context variables, you get complete data isolation, single-transaction database migrations, and minimal cloud hosting costs. You spend your engineering time building customer features rather than managing database fleets. If you are designing a multi-tenant data architecture or need guidance on PostgreSQL schema optimization, read our [infrastructure teardown post](/journal/why-we-chose-rs520-vm-over-aws-hosting/) or [contact our engineering studio](/contact?intent=product). ## Journal: When to Build Custom Software vs Configure SaaS - Path: https://emiote.com/journal/when-to-build-custom-software-vs-saas/ - Date: 2026-09-07 - Category: Product - Reading Time: 6 min - Description: The core versus context rule. When to write custom code for business differentiation and when to configure existing tools to protect runway. Early-stage startups and small businesses waste runway on two opposite extremes. On one side are teams that try to build everything from scratch. They spend three months engineering custom authentication libraries, bespoke billing systems, and proprietary notification engines before onboarding a single customer. They burn through their initial capital building commodity features that could have been configured in an afternoon. On the other side are teams that string together sixteen SaaS subscriptions with fragile webhook automations. When customer volume arrives, webhooks drop payloads silently, third-party API rate limits break workflows, and the company pays thousands of dollars monthly for disconnected tools that cannot talk to each other. To make sustainable stack decisions, engineering teams need a clear evaluation rule: **the Core versus Context boundary**. --- ## The Core versus Context decision framework In his classic business technology formulation, Geoffrey Moore divided enterprise work into two buckets: Core and Context. - **Core** is the specific workflow that creates your competitive advantage and defines your customer value. It directly drives your margins and sets you apart from alternatives. - **Context** is necessary operational overhead. It includes payroll, password resets, basic transactional email delivery, and accounting compliance. Customers expect it to work, but no one buys your product because you built a custom password reset form. ```mermaid flowchart TD Start["New Feature or Workflow Requirement"] --> Q1{"Is it Core to your competitive advantage?"} Q1 -- "Yes (Unique Workflow)" --> Q2{"Does an off-the-shelf tool support 80% without hacks?"} Q1 -- "No (Commodity Overhead)" --> Q3{"Do you have an existing tool handling this?"} Q2 -- "No (Forced Workarounds)" --> Build["BUILD: Write custom software in your core application"] Q2 -- "Yes (Standard Pattern)" --> Config["CONFIGURE: Use off-the-shelf SaaS or self-hosted tool"] Q3 -- "Yes (Adequate)" --> Keep["KEEP: Retain current tool, avoid migration churn"] Q3 -- "No / Overpriced" --> Replace["REPLACE: Switch to open-source or lightweight alternative"] ``` Every software decision in your business maps to one of four actions: Keep, Configure, Replace, or Build. | Call | Decision Rule | Best Example | Worst Example | | --- | --- | --- | --- | | **Keep** | Retain existing software when adoption and integrations justify the price | Slack for internal team collaboration with 20+ integrations | Keeping an unused $800/mo enterprise CRM package | | **Configure** | Use an established third-party tool for commodity operational requirements | Stripe Checkout for payment gateway processing | Custom building an entire credit card billing gateway | | **Replace** | Swap an overpriced SaaS subscription for a focused self-hosted or open-source tool | Replacing high-seat analytics with self-hosted PostHog | Swapping active production billing for an unmaintained repo | | **Build** | Write custom application code when the workflow defines your unique business value | The core dispatch algorithm or custom multi-tenant ledger | Writing custom auth tokens instead of session cookies | --- ## When to Build: The three indicators Writing custom software is an investment that incurs permanent maintenance responsibility. You should write custom code only when three conditions are met: ### 1. The workflow touches your unit economics If software directly improves your gross margins or accelerates customer throughput, building it yourself gives you long-term operating leverage. In Retainix, we built custom counter sync logic because waiting for slow third-party loyalty API requests at a petrol counter backed up physical vehicle lines. Owning that interaction directly protected the client's retail transaction velocity. ### 2. Commercial tools require awkward workarounds When you spend weeks hacking custom API connectors, writing duplicate webhooks, and paying for multiple middleware tiers just to force an off-the-shelf tool to support your workflow, you are already building custom software. You are simply doing it on top of a fragile, closed platform that you do not control. ### 3. Your differentiation is the data relationship If your product succeeds because it connects two distinct data sources in a way competitors cannot match, that relational schema belongs in your own PostgreSQL database, not trapped inside isolated third-party SaaS silos. --- ## When to Configure or Replace: Protecting engineering focus Every line of custom code you write must be updated, patched, and monitored. Here are the operational areas where writing custom software is almost always a mistake for early teams: ### 1. Payment gateway orchestration Processing credit cards, handling failed billing retries, generating customer tax invoices, and supporting regional compliance mandates (such as European SCA or Indian e-mandates) requires dedicated compliance teams. Use Stripe, Lemon Squeezy, or Paddle. The transaction fee is vastly cheaper than the engineering salary needed to maintain custom payment pipelines. ### 2. Transactional email deliverability Setting up your own SMTP server on a virtual private server almost guarantees your verification emails land in spam folders. Email deliverability depends on domain reputation, IP warmup, and feedback loops with major inbox providers. Use Postmark or Resend. ### 3. Basic analytics and user telemetry Do not write custom database tables to record page views or button clicks. Your primary database should store state mutations, not high-volume clickstream logs. Use lightweight analytics like Plausible for web traffic, or PostHog for product session tracking. --- ## The compounding cost of SaaS sprawl While custom code brings maintenance debt, indiscriminate SaaS adoption brings vendor lock-in and margin erosion. Many companies sign up for a dozen tools during their first six months. By year two: - Software seats scale automatically, turning a $50 monthly bill into a $1,200 monthly drain. - Customer data is fragmented across HubSpot, Zendesk, Stripe, and Airtable, with no single trusted source of truth. - When an upstream SaaS vendor changes pricing or deprecates an API endpoint, internal operations grind to a halt. In our Reframe audits, we routinely help businesses eliminate $500 to $2,500 in monthly recurring tool spend by replacing bloated SaaS tiers with clean open-source alternatives or consolidating scattered spreadsheets into a single focused application. --- ## Finding the balance Great engineering teams do not take pride in the total lines of code they write. They take pride in shipping reliable products that solve customer problems with the minimum necessary complexity. Build your core workflow with precision. Configure your commodity context tools with restraint. When you protect your engineering focus for what truly differentiates your product, your runway lasts longer and your software stays resilient. If your team is evaluating an overgrown software stack or deciding whether to build a custom internal tool, review our [Reframe evaluation methodology](/reframehub/open-source-evaluation/) or [request a Stack Review with our studio](/contact?intent=reframe). ## Journal: What Principal-Led Means in Practice - Path: https://emiote.com/journal/what-principal-led-means-in-practice/ - Date: 2026-09-06 - Category: Studio - Reading Time: 5 min - Description: Why hiring a studio where principals write the code beats paying agency account managers and junior contractors. Zero communication loss. When founders hire an external development team to build their software, the transaction usually follows a predictable script. During the sales process, the founder speaks with agency executives or senior solutions architects. These leaders understand product positioning, distributed architectures, and database trade-offs. The founder leaves the call convinced that the agency understands their vision. Once the contract is signed, the senior personnel disappear. The project is handed down to an account manager, who translates requirements to an offshore project manager, who writes Jira tickets for junior developers who have never operated a production product. Every technical requirement passes through four layers of telephone before a single line of code is written. By week three, the software drifts away from the intended product mechanics, and the founder spends twenty hours a week explaining basic domain concepts to intermediaries. At Emiote, we operate as a principal-led product and engineering studio. Here is what that model looks like in daily practice, and why it changes how software gets delivered. --- ## The communication chain: Agency relay vs Principal-led loop The primary cause of project delay is not typing speed. It is communication latency and translation loss. ```mermaid flowchart TD subgraph Agency["Traditional Agency Model (4 Layers of Translation Loss)"] FounderA["Founder"] --> VP["Agency VP / Sales Lead"] VP --> AM["Account Manager"] AM --> PM["Offshore Project Manager"] PM --> Dev["Junior Contractors"] Dev -.->|Questions & Clarifications| PM PM -.-> AM AM -.-> VP VP -.-> FounderA end subgraph Studio["Emiote Principal-Led Model (Zero Relay)"] FounderB["Founder"] <--> Principal["Principal Engineer<br/>(Dhanji Bhagat)"] Principal --> Codebase["Direct Code, Architecture & Production Deploy"] end ``` In the agency relay model, simple questions require days to resolve: 1. The developer discovers an ambiguous requirement in the database schema. 2. The developer asks the project manager during the morning standup. 3. The project manager emails the account manager. 4. The account manager schedules a weekly status call with the founder. 5. Five business days pass before a three-minute technical decision is made. In our studio, the principal engineer designs the schema, writes the application routes, runs the automated test suites, and configures the production infrastructure. When an edge case emerges, we address it directly in shared asynchronous documents or a direct five-minute discussion. --- ## What a principal-led engagement changes Working directly with the person writing the software changes four aspects of the project. ### 1. Scope decisions happen during implementation When an account manager receives a founder request, their incentive is to say yes to keep the client happy, then issue a change order billing for additional hours. They do not evaluate how the request impacts database performance or release deadlines. When a principal engineer evaluates a request, they assess the architectural cost immediately: - "Adding custom notification preferences now will push our staging launch by four days." - "If we use a standard transactional template instead, we can test user onboarding by Friday." You receive honest technical advice rather than commercial accommodation. ### 2. Zero translation loss in domain logic Every industry has specific domain rules that generic developers overlook. In building Ankik, accounting entries cannot use floating-point numbers because rounding errors compound across ledger reconciliations. In building Retainix, counter staff operate with customers waiting in line, meaning an offline sync failure cannot block a sale. A principal engineer internalizes these operational realities before writing database migrations. We do not need a project manager to translate business logic into ticket descriptions. ### 3. Fewer engineers, higher output Adding developers to a late project makes it later. When an agency assigns five junior developers to an application, they spend half their time resolving merge conflicts, standardizing code conventions, and attending internal coordination meetings. One experienced engineer who understands the full stack from PostgreSQL queries to server-side components can ship more working software in twenty-eight days than a fragmented team of six. There are no pull requests sitting unreviewed for three days and no mismatched API contracts between separate teams. ### 4. Direct accountability for production uptime In traditional agencies, the team that writes the code rarely runs the code in production. The developers finish their contract, deliver a zip file or GitHub repository, and hand support off to an internal IT department or a maintenance tier. In our studio, we deploy our own software (Ankik, Retainix) and run client applications on live infrastructure. When we build an MVP, we configure the SSL certificates, database connection pooling, and error alerting ourselves. We write software with the knowledge that we are directly responsible if the system fails under user load. --- ## When principal-led is the right fit Our studio model is not for every company. If an enterprise client requires thirty developers to staff a legacy software migration or wants weekly slide decks presented to an executive steering committee, large staff-augmentation agencies are built for that workflow. If you are an early-stage founder building an MVP, an SME modernizing core operations, or a product team needing a validated software core shipped in twenty-eight days without agency overhead, the principal-led model protects your capital and keeps your timeline predictable. To see how we structure our 28-day MVP builds, read our [14-day core timeline breakdown](/journal/how-we-ship-core-in-14-days-live-in-28/) or [book a direct technical discussion with our studio](/contact?service=build-sprint). ## Journal: Why Autonomous AI Agents Fail in Production - Path: https://emiote.com/journal/why-autonomous-ai-agents-fail-in-production/ - Date: 2026-09-05 - Category: Search & AI - Reading Time: 6 min - Description: Prompting LLMs in a loop works in terminal demos but breaks in production. How idempotency, schema checks, and state boundaries prevent failure. Demonstrating an autonomous AI agent in a terminal recording is straightforward. You give a language model a system prompt, equip it with three shell tools, and let it run in a loop. For twenty seconds, it inspects a file, runs a command, and prints a success message. Running that same agent as an autonomous service on production infrastructure is completely different. Without rigid boundaries, autonomous loops break down rapidly. Language models encounter unexpected API formats, hallucinate non-existent tool arguments to fix the error, exhaust context windows, and execute duplicate mutations against external services. A single unhandled error can trigger an infinite correction loop that consumes twenty dollars in API tokens in three minutes while corrupting application state. In building our autonomous operational systems (such as Drishti for background audit management and WebMCP for browser agent integration), we learned that reliable agent execution requires treating the model as an untrusted reasoning engine surrounded by strict deterministic guardrails. --- ## The four catastrophic failure modes of agentic loops Autonomous agents fail in predictable patterns when exposed to live systems: ```mermaid flowchart TD Trigger["Trigger Event"] --> Agent["LLM Agent Loop"] Agent -->|Unvalidated Tool Call| BadState["Corrupted State / Duplicate API Call"] Agent -->|Tool Error Response| Retry["Hallucinated Self-Correction"] Retry -->|Appends Error to Context| Poison["Context Window Poisoning"] Poison -->|Degraded Reasoning| Drain["Token Budget Drain / Timeout Loop"] Drain --> Retry ``` ### 1. The unbounded self-correction spiral When an agent calls a tool that returns an error code, its natural inclination is to explain why the failure occurred and immediately retry. If the underlying cause is a persistent system condition (such as an invalid authentication token or a down upstream service), the model begins inventing hypothetical command-line flags or phantom parameters to make the call succeed. Each failed attempt adds hundreds of tokens to the context window, degrading the model's reasoning capability until it hits timeout limits or exhausts API budgets. ### 2. Side-effects without idempotency In ordinary software, a failed HTTP request is safely retried by the client using an idempotency key. Standard agent architectures rarely enforce idempotency on their tool definitions. If an agent executes a payment mutation or sends an outbound email, and the network connection resets before receiving the response, the agent assumes the operation never completed. It issues the call a second time, charging the customer twice or sending duplicated messages. ### 3. Context poisoning and confirmation bias As an agent executes multiple steps, its conversation history accumulates previous thoughts, tool inputs, and error traces. If the model makes an incorrect assumption on step two, that faulty assumption becomes part of the permanent context for step five. The model attends to its own previous hallucinations, treating them as verified system facts. By step eight, the agent is solving an imaginary problem that has nothing to do with the original user request. ### 4. Credential and path leakage Agents with raw file or shell access easily leak private server state into outbound model calls. Reading an unparsed log file or error stack trace can pull database connection strings, bearer tokens, or internal hostnames into the prompt payload. Once that sensitive data enters the model context, subsequent external web search or webhook calls can transmit credentials to third-party endpoints. --- ## Four deterministic guardrails for reliable production agents Fixing these failure modes does not require larger models or prompt adjustments. It requires deterministic software engineering around the model interface. ```mermaid sequenceDiagram autonumber actor System as Trigger Event participant Guard as Deterministic Guardrail participant Model as LLM Reasoning Engine participant Tool as Tool Executor participant DB as Production State System->>Guard: Incoming Task Guard->>Guard: Redact Secrets & Filter 98% Noise Guard->>Model: Sanitized Prompt Context Model->>Guard: Tool Invocation Intent alt Schema Valid & Idempotency Key Fresh Guard->>Tool: Execute Mutation Tool->>DB: Atomic Write DB-->>Guard: Success Confirmation Guard-->>Model: Structured Output else Invalid Schema or Missing Parameters Guard-->>Model: Local Error (Execution Blocked) else Iteration Limit Reached (Max 3 Loops) Guard->>System: Circuit Breaker Tripped (Escalate to Human) end ``` | Failure Mode | Production Guardrail | Implementation Mechanism | | --- | --- | --- | | Infinite retry loops | Hard iteration budget with human escalation | Loop terminates after three failed attempts; alerts human operator | | Duplicate actions | Mandatory idempotency keys on side-effects | Database unique constraint rejects identical mutations | | Malformed tool inputs | Runtime schema enforcement with TypeBox or Zod | Tool execution blocked unless payload passes validation | | Credential leakage | In-memory redaction and sanitization pipeline | Regex filters strip API keys and server paths before prompt assembly | --- ## Guardrail 1: Runtime schema enforcement with TypeBox Language models should never pass unvalidated string arguments directly to executing functions. Every tool made available to an agent must define a strict schema. The execution harness validates the model's structured output against the schema before invoking the underlying logic: ```typescript import { Type, type Static } from "@sinclair/typebox"; import { Value } from "@sinclair/typebox/value"; export const DeployServiceSchema = Type.Object({ serviceName: Type.Union([ Type.Literal("api"), Type.Literal("web"), Type.Literal("worker"), ]), environment: Type.Literal("staging"), // Production deployments locked from autonomous agents commitHash: Type.String({ minLength: 7, maxLength: 40 }), idempotencyToken: Type.String({ format: "uuid" }), }); export type DeployServiceInput = Static<typeof DeployServiceSchema>; export function validateToolInvocation(rawInput: unknown): DeployServiceInput { if (!Value.Check(DeployServiceSchema, rawInput)) { const errors = [...Value.Errors(DeployServiceSchema, rawInput)]; throw new Error(`Schema validation failed: ${errors.map(e => e.message).join(", ")}`); } return rawInput; } ``` If the model outputs invalid parameters, the tool handler rejects the call locally without executing side-effects, returning structured feedback that points out the exact schema violation. --- ## Guardrail 2: Hard iteration caps and state rollback Every agent execution loop must have a fixed ceiling on execution steps and cost. In our Drishti audit pipeline, an autonomous worker is allowed a maximum of three self-correction cycles on a single task. If the worker cannot resolve the failure within three iterations, the loop halts immediately: ```typescript export async function runBoundedAgentLoop(task: AgentTask, maxCycles = 3) { let cycleCount = 0; while (cycleCount < maxCycles) { cycleCount++; const stepResult = await executeAgentStep(task); if (stepResult.status === "completed") { return stepResult.data; } if (stepResult.status === "fatal_error") { break; } } // Escalate to human operator when budget is reached await notifyHumanOperator({ taskId: task.id, lastError: "Max retry limit reached without resolution", cyclesAttempted: cycleCount, }); throw new Error(`Agent halted: exceeded maximum iteration budget of ${maxCycles}`); } ``` This simple circuit breaker prevents runway token costs and stops runaway agents from spamming external APIs. --- ## Guardrail 3: Pre-prompt noise filtering and sanitization Raw system outputs contain noise that distracts language models and wastes context window capacity. In our operational event pipeline, over 98% of system telemetry consists of routine low-priority events (successful heartbeats, clean database vacuum runs, routine cron checks). Passing every low-level log line into an agent forces the model to sift through irrelevant data, increasing the likelihood of hallucinated anomalies. We apply a strict significance filter before assembling the agent context: 1. Routine logs are counted in local memory and discarded. 2. Only status transitions, security anomalies, and error spikes pass through to the agent prompt. 3. All file paths, internal IP addresses, API tokens, and authorization headers are scrubbed using regular expression redaction masks. By keeping the context clean, the agent receives only the anomalous facts it needs to diagnose the issue. --- ## Guardrail 4: Human-in-the-loop checkpoints for irreversible actions Certain actions must never be delegated to an autonomous agent without explicit human authorization: - Deleting production database records or tables - Modifying DNS records or routing configurations - Issuing customer refunds or financial payouts - Sending broad communications to entire customer lists For these operations, the agent is restricted to generating a proposed action artifact. The artifact details the intended command, the expected blast radius, and the rollback plan. The mutation remains in a pending state until an authorized human engineer clicks an approval button or sends an explicit confirmation signal. If confirmation is not received within a set timeout window, the transaction expires and rolls back safely. --- ## Building agents that survive production Autonomous agents become valuable when they operate inside predictable, deterministic containers. The language model provides flexible reasoning and synthesis. The surrounding software architecture provides authentication, schema validation, rate limiting, and rollback safety. When you separate reasoning from execution authority, agents stop being unpredictable demo toys and start becoming reliable production workers. If you are developing an AI-native product and want practical engineering help building reliable systems, review our [AI features retention matrix](/journal/ai-features-that-earn-retention/) or [schedule a Build Sprint consultation with our team](/contact?service=build-sprint). ## Journal: Boring Stack Decisions That Age Well for Startups - Path: https://emiote.com/journal/boring-stack-decisions-that-age-well/ - Date: 2026-09-04 - Category: Engineering - Reading Time: 6 min - Description: Why PostgreSQL, server-rendered components, and single monoliths outlast microservices and bleeding-edge frameworks for early software products. The most expensive mistake an early-stage startup can make is confusing architectural complexity with engineering quality. Founders and technical leads often pick infrastructure based on what large technology companies use to serve twenty million requests per minute. They adopt microservices, Kubernetes clusters, distributed message brokers, and complex client-side state managers before acquiring their tenth customer. Six months later, the team spends half their engineering hours fixing hydration mismatches, managing multi-repo package versions, and debugging network partitions between five internal services. Meanwhile, the actual product roadmap sits frozen. When we build software at Emiote, we optimize for durability, debuggability, and low operational overhead. Here are the five architectural decisions that consistently survive five years without requiring an emergency rewrite. --- ## The five-year durability matrix Technology choices carry two costs: the initial implementation cost and the recurring maintenance tax. Bleeding-edge setups promise quick initial development through heavy abstraction, but they demand continuous maintenance as frameworks change APIs and dependencies break. Boring technologies require explicit initial setup, then run quietly for years. ```mermaid flowchart TD subgraph Durable["Durable Boring Stack (Under $20/mo, Single Node)"] BrowserA["Browser Client"] --> AppNode["Monolith App Server<br/>(SSR + Islands)"] AppNode --> PG[("PostgreSQL Instance<br/>- Row-Level Security<br/>- SKIP LOCKED Queues<br/>- ACID Transactions")] end subgraph Fragile["Fragile Novelty Stack (High Maintenance Tax)"] BrowserB["Client SPA Bundle"] --> Gateway["API Gateway"] Gateway --> AuthSvc["Auth Service"] Gateway --> BillSvc["Billing Service"] Gateway --> CoreSvc["Core Service"] AuthSvc --> AuthDB[("Auth DB")] BillSvc --> BillDB[("Billing DB")] CoreSvc --> CoreDB[("Core DB")] AuthSvc & BillSvc & CoreSvc <--> Bus{"Kafka Event Bus"} end ``` | Problem Domain | Novel Choice (High Tax) | Boring Choice (Durable) | What Happens in Year Three | | --- | --- | --- | --- | | Primary Database | Microservices with separate databases | Single PostgreSQL with Row-Level Security | Single transactions guarantee balance integrity without distributed locks | | Code Organization | Polyrepo across six separate repositories | Single monolithic repository | Refactors take minutes with typed imports instead of coordinated npm releases | | User Interface | Client-side SPA with heavy client state | Server-rendered HTML with lightweight islands | Zero hydration errors and search engines index every page instantly | | Background Jobs | Distributed event streaming (Kafka/RabbitMQ) | PostgreSQL advisory locks or Redis queues | Zero queue cluster maintenance; queries run directly against main data | | Hosting & Ops | Multi-node Kubernetes on managed cloud | Single virtual private server or Lightsail | Infrastructure costs stay under $20 monthly with minimal monitoring overhead | --- ## 1. Single PostgreSQL database with Row-Level Security Dividing an early product into separate database instances per tenant or microservice introduces immediate distributed systems problems. You lose cross-table foreign key constraints. You lose single-statement atomic transactions. Generating a simple customer report requires network joins across HTTP endpoints or eventual consistency synchronization workers that silently drift out of alignment. PostgreSQL handles structured relational data, JSON documents, full-text search, and geographic coordinates within a single engine. For multi-tenant applications like our accounting software Ankik, PostgreSQL Row-Level Security (RLS) isolates tenant data at the query engine layer: ```sql ALTER TABLE invoices ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_policy ON invoices FOR ALL USING (organization_id = current_setting('app.current_org_id')::uuid); ``` Every query automatically filters by tenant, preventing data leaks across organizations even if application code forgets an explicit where clause. A single PostgreSQL instance on an inexpensive virtual server easily handles millions of records and dozens of concurrent queries at sub-50ms latencies. --- ## 2. Monolithic repository over polyrepo sprawl Splitting an early application across separate git repositories creates immediate organizational drag. Updating an API payload schema requires editing the backend repository, running a build script, tagging a package version, publishing to an internal registry, updating the frontend repository, and resolving version conflicts across pull requests. Small changes that should take ten minutes require half a day of dependency coordination. A single repository containing the server, frontend, and shared type definitions keeps dependencies aligned. With TypeScript, a backend schema change immediately produces compile-time warnings across any frontend component using that model: ```typescript // packages/shared/src/schemas/invoice.ts export interface InvoiceItem { description: string; quantity: number; unitPriceCents: number; } ``` Both client and server import the exact same contract. Refactoring an API field requires one find-and-replace operation across the entire codebase. --- ## 3. Server-rendered HTML with lightweight interactive islands Single-page applications (SPAs) that render entirely in the client browser shift enormous complexity onto the user's device. The client must download several megabytes of JavaScript, execute bundle parsing, render a blank loading spinner, call four API endpoints in parallel, manage client cache invalidation, and reconcile state updates. When a network connection stutters, users see partial white screens and frozen buttons. Server-rendered pages with progressive islands flip this dynamic. The server generates standard HTML and CSS, sending complete documents that render immediately on slow mobile connections. Interactive islands (such as a complex dropdown or a dynamic calculation widget) hydrate only when required. Benefits of this approach: - Initial page load times drop to fractions of a second. - Search engines and AI scrapers index content without running expensive headless browser emulation. - Client state bugs disappear because the server remains the single authoritative source of truth. --- ## 4. PostgreSQL advisory locks and BullMQ over Kafka Distributed event streaming platforms like Apache Kafka or RabbitMQ are built for engineering organizations with hundreds of developers processing terabytes of log streams. Using Kafka in an early-stage startup adds cluster coordination services, consumer group rebalancing bugs, and deployment overhead before the product has meaningful background volume. Most background tasks in early products fall into three categories: sending transactional emails, generating PDF invoices, and processing webhook payloads. PostgreSQL handles background queues natively using `FOR UPDATE SKIP LOCKED`: ```sql WITH next_job AS ( SELECT id FROM background_jobs WHERE status = 'pending' AND run_at <= NOW() ORDER BY run_at ASC LIMIT 1 FOR UPDATE SKIP LOCKED ) UPDATE background_jobs SET status = 'processing', locked_at = NOW() WHERE id IN (SELECT id FROM next_job) RETURNING *; ``` This pattern avoids external message broker dependencies entirely. The job queue lives in the same transaction as the application state, eliminating partial writes where a record is saved to the database but the message broker call fails. When background volume eventually grows into thousands of jobs per minute, migrating to a simple Redis-backed queue like BullMQ takes less than one engineering day. --- ## 5. Single VPS deployment over Kubernetes Container orchestration platforms like Kubernetes add layers of networking abstraction, ingress controllers, volume claims, and manifest files that demand specialized DevOps maintenance. For products with under ten thousand active users, a single virtual private server (such as AWS Lightsail or Hetzner) running Docker with automated backup scripts is reliable, predictable, and simple to debug. Real operational facts from Ankik: - Runs on a single instance with managed PostgreSQL backups. - Total hosting cost remains under $10 monthly. - Server CPU utilization sits below 8% under typical business daily workloads. - Debugging an error requires SSH access and reading a single unified container log file with `docker logs`, without searching through distributed pod logs. When you control your deployment directly, you can diagnose performance bottlenecks in seconds instead of navigating cloud provider management dashboards. --- ## Choosing predictability over novelty Engineers often pick novel tools because solving infrastructure puzzles feels engaging. But customers do not pay for your build pipeline or your service mesh. They pay for reliable software that finishes their work without unexpected downtime. Boring technology allows a small team of two engineers to build and maintain what previously required a team of ten. It keeps monthly operating expenses minimal and frees founders to focus on user feedback, product refinement, and distribution. If you want a technical evaluation of your current architecture or want to simplify an overgrown tech stack, read our [infrastructure migration post](/journal/why-we-chose-rs520-vm-over-aws-hosting/) or [schedule a Stack Review with our studio](/contact?intent=reframe). ## Journal: What Belongs in Week One of an MVP - Path: https://emiote.com/journal/what-belongs-in-week-one-of-an-mvp/ - Date: 2026-09-03 - Category: Product - Reading Time: 6 min - Description: Why founders waste week one on profile avatars while core data flow stays unbuilt. The 7-day sequencing that protects startup runway. Week one determines whether a software build completes in twenty-eight days or drifts into month four. When early-stage projects fall behind schedule, the delay rarely comes from complex database queries or difficult infrastructure. The delay happens because the team spent the first seven days polishing secondary surfaces before verifying the central transaction. Founders often start a project by sketching user settings, profile picture uploaders, dark mode toggles, and team invite modals. These features feel like progress because they look like complete software in a browser. None of them prove that a stranger will use the product or pay for the outcome. In our Build Sprints, we follow a strict seven-day sequence. If the central data path does not run on staging by the end of day five, the project will not hit its day twenty-eight launch target. --- ## The trap: building the perimeter first Most software products have a core transaction and a perimeter. The core transaction is the specific mutation that produces the primary value. In an accounting tool like Ankik, the core transaction is posting a balanced ledger entry that updates accounts. In a dispatch tool, it is assigning a driver to a pickup route. In a retention platform like Retainix, it is logging customer activity at the counter and updating points balance. The perimeter includes everything else: - Password resets and email verification flows - Profile pictures and bio fields - Multi-organization permission matrices (owner, admin, member, viewer) - Theme preferences and notification preferences - Account deletion workflows Teams build the perimeter first because it is familiar. Writing a user settings form is comfortable. Designing the data model for a complex domain requires difficult trade-offs. Building perimeter features first creates an illusion of velocity. By day seven, the repository has forty commits and twelve visual components, but the product cannot complete a single customer job. When the team finally tackles the core workflow in week three, they discover that their initial database assumptions were incorrect. They must rewrite the auth boundaries, rework the models, and discard days of perimeter interface code. --- ## The seven-day week one schedule We treat week one as a sequencing test. The objective is to have a stranger complete the central mutation on a live staging server before the first weekend. ```mermaid flowchart TD D1["Day 1: Single Mutation Contract<br/>(One actor, one mutation, one outcome)"] --> D2["Day 2: Relational Schema<br/>(PostgreSQL tables, foreign keys, integer cents)"] D2 --> D3["Day 3: Tenant & Auth Boundary<br/>(Session cookie, organization_id scoping)"] D3 --> D4["Day 4: Core Endpoint & Tests<br/>(Happy path and rejection integration tests)"] D4 --> D5["Day 5: Bare Interactive Surface<br/>(Plain server-rendered HTML form on staging)"] D5 --> D6["Day 6: Automated CI/CD Pipeline<br/>(Git push deploys to HTTPS in under 4 minutes)"] D6 --> D7["Day 7: The Cold Stranger Test<br/>(External user finishes job without walkthrough)"] ``` | Day | Focus | Milestone Output | Verification Gate | | --- | --- | --- | --- | | Day 1 | Single mutation contract | One-page technical specification | Can the outcome be defined in one sentence? | | Day 2 | Relational schema | Migration scripts in PostgreSQL | Do tables have strict foreign keys and checks? | | Day 3 | Tenant & auth boundary | Session cookie and tenant middleware | Does every query require an organization identifier? | | Day 4 | Core endpoint | Automated API integration test | Does the test assert balanced state after mutation? | | Day 5 | Bare interactive surface | Server-rendered form on staging | Can an external tester submit valid data? | | Day 6 | Automated CI/CD pipeline | Continuous deployment on git push | Does staging update within four minutes of push? | | Day 7 | The cold stranger test | Screen recording of unassisted run | Did the tester finish without asking for guidance? | --- ## Day 1: The single mutation contract Before opening an editor, we write down the single mutation that defines the application. This contract must fit into one sentence: > "When an authenticated manager submits an invoice, the system writes a draft record, assigns an incremental sequence number, and recalculates the customer balance." If defining the mutation requires three sentences, the project is trying to ship three distinct products at once. We remove secondary actions until only one remains. Multi-currency support, PDF export, and email delivery belong to later phases. --- ## Day 2: Relational schema and integrity On day two, we write the PostgreSQL schema directly. We avoid abstract ORM schema generators that hide database behavior. We enforce strict data integrity from the first commit: - Foreign keys with explicit `ON DELETE RESTRICT` rules to prevent orphaned records. - Integer storage for financial amounts to eliminate floating-point rounding errors. - Check constraints on status fields rather than loose text columns. - Timestamps with timezone (`timestamptz`) on every record. ```sql CREATE TABLE organizations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE ledger_entries ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), organization_id UUID NOT NULL REFERENCES organizations(id) ON DELETE RESTRICT, account_code TEXT NOT NULL, amount_cents BIGINT NOT NULL, entry_type TEXT NOT NULL CHECK (entry_type IN ('debit', 'credit')), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_ledger_org_account ON ledger_entries(organization_id, account_code); ``` Fixing schema errors on day two costs twenty minutes. Fixing schema errors after building twelve UI screens takes two days. --- ## Day 3: Authentication and tenant boundaries You cannot test return visits or user retention without identity. Mock authentication in localStorage hides security defects and tenancy bugs that break production environments later. On day three, we set up real session management. Every query executed by the application must accept an organization identifier. We write automated tests to verify that tenant A cannot access records belonging to tenant B, even when guessing valid primary keys. We do not write custom password hashing algorithms or complex permission matrices. We use standard session cookies and a single role flag. Fine-grained permissions can wait until paying customers request them. --- ## Day 4: The core endpoint and tests Day four is dedicated to the application backend. We build the route that handles the primary mutation defined on day one. We write two types of automated tests: 1. A happy-path test confirming that valid inputs create the database records and return a success response. 2. A rejection test confirming that invalid inputs (negative amounts, missing foreign keys, mismatched tenant identifiers) return clear error codes without leaving partial state. The endpoint must return explicit error payloads following standard problem details. Generic internal server errors are not acceptable. --- ## Day 5: The bare interactive surface On day five, we build the interface. We intentionally skip design systems, animation libraries, and component frameworks. A plain HTML form with clean styling is enough: - An input for every required field - Inline validation messages for missing or malformed inputs - A submit button with a pending state to prevent duplicate submissions - A confirmation view that displays the resulting database record If the workflow feels confusing on a simple white page, adding drop shadows and gradient buttons will not fix the confusion. Plain interfaces expose confusing user experience immediately. --- ## Day 6: Continuous deployment pipeline Software running only on a developer's laptop is unvalidated software. Local environments hide missing environment variables, filesystem differences, and network latency. On day six, we connect the repository to continuous deployment. Every push to the main branch runs automated tests and updates a staging environment reachable over HTTPS. We configure database connection pooling and SSL certificates on day six. Discovering deployment problems in week one gives the team three weeks to fix them calmly. Discovering deployment problems on day twenty-seven creates panic. --- ## Day 7: The cold stranger test On Friday afternoon, we send the staging URL to one person who was not involved in planning the product. We provide only two pieces of context: 1. The URL and test login credentials. 2. The intended outcome: "Create one customer invoice and record a payment." We do not provide a call walkthrough or a setup document. We observe where they pause, which buttons they click, and where they encounter validation errors. If the stranger finishes the task in four minutes, week one is successful. The foundation is sound. If the stranger gets stuck on step two, we know exactly what must be simplified before building secondary features in week two. --- ## What to defer until week three or four Protecting week one requires saying no to non-essential requests. Here is the explicit cut list for the first seven days: - Social logins (Google, GitHub, Apple). Use magic link or email and password. - Custom notification preferences. Send transactional emails directly or skip until week three. - Dark mode. Stick to a clean light theme. - Export to Excel or CSV. Raw database access is sufficient for early founder testing. - Billing integration. Stripe checkout can be wired in days fifteen to twenty-one. Foundations decide whether an MVP lasts. By keeping week one focused on the single core transaction, founders save their capital and give their product a realistic chance of reaching paying users. If you are planning an MVP and want experienced engineers to build your core workflow in twenty-eight days, review our [Build Sprint timeline](/journal/how-we-ship-core-in-14-days-live-in-28/) or [book a technical discussion with our studio](/contact?service=build-sprint). ## Journal: We Changed Ankik's Infrastructure Three Times. Here's Why. - Path: https://emiote.com/journal/why-we-chose-rs520-vm-over-aws-hosting/ - Date: 2026-09-02 - Category: Engineering - Reading Time: 8 min - Description: From AWS EC2 + RDS to a ₹520 private VM and finally AWS Lightsail — what Ankik learned about cost, latency, reliability, and operational uncertainty. We didn't keep changing Ankik's infrastructure because we couldn't decide. We changed it because the constraints changed — and each move taught us what mattered next. Ankik's journey has had three stages: managed AWS, a private VM that looked best on price, and now AWS Lightsail. Each stage was correct for the problem we were solving at that time. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="vm-vs-rds-tradeoff" caption="The bill you see vs the bill you operate — why the cheapest VM per rupee was not the cheapest to run." /> > **TL;DR:** EC2 + RDS (~$39/mo for ~50 beta users) → ₹520 VM (84% cheaper infra bill, more uncertainty to own) → Lightsail 2 GB (predictability over raw RAM). We resize when we observe sustained pressure, not the plan page. ## We changed Ankik's infrastructure three times Ankik runs on PostgreSQL. For a long time the data lived across notebooks, Excel, and WhatsApp — but the infrastructure story is more recent. This is a founder-written field note. It documents three real moves, what we actually paid, what we learned, and why we now run on Lightsail. It is not a generic hosting comparison and not an AWS promotion. The progression is: **AWS EC2 + RDS → ₹520 Private VM + self-hosted PostgreSQL → AWS Lightsail + self-hosted PostgreSQL** Stages 1 and 2 are historical snapshots. Stage 3 is current. We do not mix the old $39 figure with Lightsail pricing, and we do not present Lightsail as immune to downtime. ## Stage 1 — EC2 + RDS Ankik initially ran with: - **EC2** for the application - **RDS** for PostgreSQL - AWS-managed database infrastructure - Higher operational convenience — daily backups, auto patches, auto restart - Higher monthly infrastructure cost At that point this was not a mistake. It was the reasonable default: managed infrastructure lets a small team focus on the product, and the application and database were cleanly separated. We documented this starting point in our [self-hosted Postgres field note](/reframehub/self-hosted-postgres/). The snapshot below is from that note. ## Why we left managed AWS The workload was still small and beta-scale — roughly **~50 beta users** — and the managed bill felt disproportionate. **Historical July 2026 deployment snapshot (not a current AWS price quote):** - EC2 t3.small — $18/mo - RDS db.t3.micro — $16/mo plus storage - EBS and transfer — ~$5/mo - **Total: ~$39/mo** (~₹3,300, USD billing, ~180 ms from Gujarat in that placement) That total is a historical measurement excluded team operating time and is not a quote you should re-price from today. The reason we reconsidered was not that RDS failed — it worked well. It was that ~$39/mo for ~50 beta users was more than Ankik needed at that stage, and the separated architecture added cost and latency we could consolidate. ## Stage 2 — the ₹520 private VM We moved from **EC2 + RDS → one private VM**, moving PostgreSQL onto the same machine. Historical characteristics from 10 July 2026: - 2 vCPU, 4 GB RAM - ~₹520/month (INR/UPI billing) - Self-hosted PostgreSQL (Rs 0 extra compute — it shares the VM's RAM) - Backups to S3 — ~Rs 40/mo - Application and database colocated — ~28 ms from Vadodara when measured, no connection caps like some serverless Postgres - About 84% lower infra bill in that snapshot — **excluding** team time The VM worked. For roughly a month we had zero data loss and one manual restart after an OOM on 2 GB — we then moved to 4 GB and added Uptime Kuma → Telegram. We enabled `pg_stat_statements` for slow-query visibility, a small win that was easier with full control. The private VM was attractive because it dramatically reduced infrastructure cost and provided more raw resources per rupee. Raw resources and low price, however, are not the only variables that matter. ## What the private VM taught us The private VM was cheaper and more powerful on paper, but it required us to own more **infrastructure-level uncertainty**. Not a dramatic outage — the note records only that single OOM — but the broader concern: how standardized the VPS management was, how networking behaved, how IP continuity was handled, and how much of the underlying environment we had to reason about ourselves. The correct framing is: > The private VM was cheaper and more powerful on paper, but it required us to own more infrastructure-level uncertainty. Operations still had a cost, even when the infra bill approached zero. That trade is visible in our own words from the field note: marginal infra cost can be near zero if a correctly sized 4 GB VM already exists; **operations still cost time**. ## Why we moved again We did not move because the VM couldn't handle the load. We moved because the optimization target changed. Previously: > Maximize resources while minimizing infrastructure cost. Now: > Maximize predictability and operational confidence while keeping the architecture simple. The decision was not primarily about getting more CPU or RAM — we actually accepted less RAM. It was about reducing uncertainty in the infrastructure layer so the team can reason about the system at 2 a.m. ## Stage 3 — AWS Lightsail Ankik now runs on **AWS Lightsail**. Current setup: - AWS Lightsail - 2 vCPU, 2 GB RAM, 60 GB SSD - Self-hosted PostgreSQL - Docker - Caddy - MinIO - Dozzle - Static IPv4 attached to the Lightsail instance Current stack on Lightsail: ```text AWS Lightsail │ ├── Caddy ├── Ankik Backend ├── PostgreSQL ├── MinIO └── Dozzle ``` Lightsail provides a simpler VPS-style experience without immediately returning to the larger EC2 + RDS cost profile. It is backed by AWS infrastructure and the ecosystem we already use elsewhere, with a console and networking primitive we can reason about. We do not claim a single Lightsail instance provides 99.99% uptime. That is too broad for a single VPS. If you need that level of SLA you need multiple instances across zones — a path we have not built. If discussing AWS's SLA, verify the current [AWS documentation](https://aws.amazon.com) and distinguish single-instance from multi-instance architectures. ## Why 2 GB is enough for now The previous VM had 4 GB RAM. Lightsail has **2 GB RAM**. We deliberately accepted less RAM. We did that because the 2 GB Lightsail instance is **currently** sufficient for the Ankik beta workload: - Ankik's Docker stack is lightweight. App, Postgres, Caddy, and MinIO comfortably share 2 GB at current load. - We monitor actual consumption rather than sizing for a hypothetical peak. - We do not claim 2 GB is universally enough for all future Ankik workloads. - If memory pressure becomes a sustained production constraint, we can resize the Lightsail instance — a documented scale step, not a rebuild. We stopped sizing for the biggest number on the plan page and started sizing for the **steady-state we actually observe**. That is the opposite of the early “model the whole business on day one” mistake described in [Ankik's ledger story](/journal/ankik-ledger-one-trusted-number-first/). ## Static IP and infrastructure predictability On Lightsail we attached a **Lightsail Static IPv4**. A normal public IPv4 can change after certain stop/start operations, while a Static IPv4 remains associated with the instance. You allocate it, attach it, and DNS can point to a stable address. This reduces surprises involving DNS, allowlists, external integrations, and service configuration. We do not imply Lightsail automatically provides a static IP unless one is explicitly attached, and we do not claim a Static IPv4 prevents every networking issue. A misconfigured Caddy, an expired DNS record, a security group change, or a bad deploy can still make the app unreachable. Static IP solves one specific class of surprise — the address itself changing. ## Monitoring and failure detection Ankik today runs fully containerized. Our current monitoring on Lightsail is: - **Docker restart policies** on every service - **Persistent volumes** for Postgres and MinIO data - **PostgreSQL backups** — regular dumps, with instance snapshots where appropriate - **Dozzle** for logs — we watch container lifecycle events in one place - **Dozzle alerts** for container restarts, OOM kills, health issues, and CPU/memory thresholds - **Discord** for infrastructure and container alerts (Dozzle → Discord) - **Google Chat** for CI/CD notifications (deploy pipeline → Chat) - **Application health endpoints** that verify the app can reach Postgres - **External uptime monitoring** that probes the public URL from outside AWS and alerts when the entire VPS is unreachable An important distinction we learned while operating the private VM and now on Lightsail: **Dozzle monitors the services inside the VPS. If the entire Lightsail instance becomes unreachable, Dozzle also becomes unavailable.** Internal monitoring answers “did my container restart?” External monitoring answers “is the whole machine reachable from the internet?” We need both, and we page differently for each. ## Why PostgreSQL is still self-hosted Our current choice remains **AWS Lightsail + self-hosted PostgreSQL** rather than immediately returning to RDS. The reasoning is: - Beta-scale workload - Application and database can currently share the machine - Actual resource usage is manageable at 2 GB - We can operate backups and restores - Managed PostgreSQL is not currently necessary for the workload We are explicit about when this decision would change: - Significant database growth or higher traffic - Sustained resource pressure - Need for managed point-in-time recovery without operating it ourselves - Multi-AZ or higher availability requirements - Inability to maintain backups and restores - Operational burden becoming too high That is the same five-check lens we apply in our [open-source evaluation guide](/reframehub/open-source-evaluation/) and in every Stack Review. As we note in our [cost breakdown](/journal/mvp-cost-breakdown/), saving about $20 while spending five hours maintaining infra is not a saving at a founder hourly rate. ## When we would change again We would reconsider Lightsail if: - Memory pressure on 2 GB becomes sustained and verified (not just a brief spike) - We need managed PITR, multi-AZ, or an uptime story we cannot staff on a single instance - The team cannot own the restore drill that month If any of those become true, the honest call may be a larger Lightsail instance — or back to managed Postgres — not “more tuning on 2 GB.” We keep a written rollback plan, just as we keep a [scope cut list](/journal/mvp-scope-pruning-must-ship-vs-deferred/) for product. ## What we actually learned Each infrastructure decision was correct for the problem we were solving at that time: **EC2 + RDS** → optimize for managed infrastructure and less operational burden **₹520 private VM** → optimize for cost, raw resources, and low latency **AWS Lightsail** → optimize for predictable infrastructure, stable networking, operational confidence, and simplicity We didn't keep changing infrastructure because we couldn't decide. We changed it because the constraints changed — and each move taught us what mattered next. Choosing between managed and self-hosted Postgres? Run the same five checks we use — business fit, team capability, true cost with hours, security, and migration risk. Want us to run it with you? [Run the Five Checks With Us](/contact/?service=build-sprint) or book a [Stack Review](/reframe/) — we will tell you to stay managed if that is the better trade. We document the historical self-host details in our [self-hosted Postgres field note](/reframehub/self-hosted-postgres/) and the hosted-vs-managed framework in our [cost breakdown](/journal/mvp-cost-breakdown/) and [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/). For live pricing, verify current Lightsail pricing at [aws.amazon.com/lightsail/pricing](https://aws.amazon.com/lightsail/pricing) — do not re-price from our July 2026 $39 snapshot. ## Journal: The Retainix 5-Second Counter Rule - Path: https://emiote.com/journal/retainix-5-second-counter-rule/ - Date: 2026-09-01 - Category: Product - Reading Time: 5 min - Description: Why loyalty at the petrol counter must be branch-safe and explainable in five seconds — a lesson from building Retainix. I learned the counter rule while watching staff use Retainix at a petrol pump. If earning or redeeming takes more than five seconds to explain, the queue backs up, the staff skips it, and loyalty adoption drops to zero — no matter how good the platform looks in a demo. Importantly, the reward is not per branch. It is **one programme, shared members, branch-aware activity** — as we describe in our [case study](/work/retainix/). A reward earned at one branch must be usable at another when the rules allow it, and staff must see the same rules wherever they walk in. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="branch-sync" caption="Earn at one branch, sync on the platform, redeem at another — one programme, one rule set, one member view." /> ## What the counter teaches Loyalty rules look simple on a whiteboard: earn points on purchase, redeem later. At the counter they fracture: - Which branch's rule applies right now? - What is the cashback timing — immediate or after settlement? - What happens if the ticket is refunded? - Who can explain this without opening a manual? If those answers live in different branch memories or spreadsheets, the member experience is already broken. Retainix started from those multi-location operations — not from a loyalty feature list. The requirement was that earn and redeem be simple for staff, consistent across sites, and measurable as one programme. ## One programme, not per-branch reinvention We run **one programme shared across all branches**. That is a product decision, not a setting. | Where it works | How we kept it simple — so the queue never stalls | | --- | --- | | **Earn** | Same rule at every counter; staff taps once, member sees the same balance — no manual needed | | **Redeem** | Shared member base — reward earned at one branch is valid at another when you allow it | | **Reporting** | Branch-aware activity without a separate spreadsheet per site — one view you trust | | **Mental model** | One rule set taught at the counter, not per-branch exceptions in a deck | Multi-business admin is intentionally not exposed until a real second organisation needs it. The platform is multi-tenant under the hood; the surface today is one business with live multi-branch. That constraint is discussed in our [product story](/journal/products-teach-better-than-pitches/) and mirrors the [MVP checklist](/journal/mvp-means-minimum-viable-not-minimum-care/): cut surface, raise quality on what remains. ## Branch-safe by design — the flow we run The flow that survives the queue is the simplest that can be trusted: 1. **Earn** at the counter — a single POST with branch context. 2. **Sync** on the platform — member view updated once, visible from any branch. 3. **Redeem** check — shared member read, branch-aware rule applied, staff sees a clear “eligible or why not.” Speed is the quality bar. As we noted in our case study, if cashiers take more than five seconds to grant points, loyalty adoption drops to zero. That is why we built explicit states for each step — the same invisible engineering we describe in [good engineering by design](/journal/good-engineering-is-invisible/). When the sync is pending, the staff sees what is safe to retry. When redemption is denied, the screen says who can help without exposing role IDs. ## What this means for your MVP If your product has more than one location, door, or counter, test the core job where time actually matters. A demo that adds three seconds per transaction will not survive the first busy hour. We scope that risk in the [timeline](/journal/how-we-ship-core-in-14-days-live-in-28/) — weeks 3–4 harden the paths where money and trust are on the line — and we price it honestly in the [cost breakdown](/journal/mvp-cost-breakdown/). Want to apply the counter test to your product? [Test Your Core Job at the Counter](/contact/?service=build-sprint) — we map it where time actually matters and make the rule teachable in five seconds. ## Journal: Ankik Ledger: One Trusted Number First - Path: https://emiote.com/journal/ankik-ledger-one-trusted-number-first/ - Date: 2026-08-31 - Category: Studio - Reading Time: 6 min - Description: How I built Ankik around one trusted balance — from scattered notebooks to a typed ledger — and what it taught me about MVPs. I did not start Ankik to build a product. I started it because operating a real business ran on scattered truth. Notebooks. Excel sheets. WhatsApp threads. Invoices and PDFs in a chat. The data existed — it just never answered the simple question: *where do we stand?* My first instinct was the usual one: model the whole business on day one. Every report, every role, every edge case he could name in a single sitting. It failed quietly. A dense system no one finishes onboarding leaves the notebook open next to the app. What finally worked was narrower: one trusted number first. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="ledger-flow" caption="Notebook → one entry path → one trusted balance. Reports came after trust, not before." /> ## The idea that was too big When books live across notebooks, spreadsheets, and chats, the fantasy is that software can mirror every report from the start — job profit, party outstanding, pending payments, quotation-to-invoice chain, all at once. That fantasy ships a system that does many things thinly and earns no habit. We learned what we now enforce in [scope pruning](/journal/mvp-scope-pruning-must-ship-vs-deferred/): name one primary user and one primary job in one sentence. If you need three sentences, you have three products. For Ankik, that sentence became: *show the owner where he stands today, from a ledger he can trust.* ## One entry path before any dashboard We cut to a single entry path: opening balance, a clean ledger entry, and a view that answers “where do we stand?” before multi-entity dashboards. In product terms that means: - Parties — one place for customers and vendors - Quotations that become invoices without losing the thread - Purchases and expenses tied to the job that owns them - A balance people will actually keep updated because the entry path is fast Reports for the questions that used to take half an afternoon came later. They attached to a ledger habit that already existed. This is the same 14-day core we describe in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/) — a slice a stranger can finish, not a catalog of all future reports. ## Money is not a float — a typed boundary The cheapest bug in accounting software is treating money as a float and status as a string — it drifts by ₹0.01 and hides who owes what. We drew a boundary early: ```typescript export interface AccountLedger { readonly id: string; readonly partyId: string; readonly balanceInCents: bigint; readonly status: "reconciled" | "pending" | "disputed"; } ``` That interface is not clever. It is a promise: precision is integer cents, state is explicit, and “we'll fix currency later” is not an option. It is the same lesson from our [MVP pillar](/journal/mvp-means-minimum-viable-not-minimum-care/) — typed, validated schema boundaries beat a clever engine that sells a demo. The boundary also shaped the interface. We named screens after how the shop talks about the work, not how the database stores rows. “Who still owes us?” beat “parties table.” ## Why this matters for your MVP If you are shaping an MVP, the Ankik story is not about accounting. It is about habit. The surface that earns habit in your product is probably not the full vision. It is the one trusted number or action that, if correct, makes the user return. We price that distinction in our [cost breakdown](/journal/mvp-cost-breakdown/) — $1,200 can be enough for a fair test when the scope is one trusted job on production infra. Larger surfaces are phased. Our products are not side projects. As we wrote in [products teach better than pitches](/journal/products-teach-better-than-pitches/), ownership is how we learn the cost of every awkward default before we bring it to your product. I still consider Ankik beta. Multi-user signup and business setup are live, but we keep tightening the ledger habit rather than shipping every report at once. If you want that same bar on your MVP, [Name Your One Trusted Number With Us](/contact/?service=build-sprint) — we agree it in writing before we write a scope contract. ## Journal: Cheap vs Correct AI Integration: Cost of Hype - Path: https://emiote.com/journal/cheap-vs-correct-ai-integration/ - Date: 2026-08-30 - Category: Search & AI - Reading Time: 6 min - Description: The difference between cheap AI that demos well and correct AI that retains users — hype vs correct comparison and cost of hype. A cheap AI integration demos in five minutes. A correct AI integration changes whether users come back. The difference is not model price. It is whether the AI sits inside a trustworthy job. We have not published a separate post-mortem of a failed AI feature in a client product, so this page sticks to the framework we actually use in reviews — not an invented story. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="decision-matrix" caption="The same matrix from our retention guide, applied to cost: cheap AI optimizes for demo, correct AI optimizes for completion." /> ## Cheap AI: what it looks like Cheap AI is a generation step added on top of a fragile flow. - Prompt stitched into a screen without typed boundaries — `number` for money, `string` for status. - No clear empty, failure, and permission-denied states for the AI output itself. - No measurement of whether the job is finished faster or more reliably. - The demo is a generated paragraph; the production question is “what do we retry when the model times out?” It feels fast. It generates support load where the generation is wrong in a way the user cannot spot quickly. The cost shows up after launch. ## Correct AI: what we aim for Correct AI is a material inside a well-defined job, as described in our [AI retention guide](/journal/ai-features-that-earn-retention/). - Typed boundaries around AI output — the same discipline we use for money in [Ankik](/journal/ankik-ledger-one-trusted-number-first/), where `balanceInCents` is a `bigint` with explicit `reconciled | pending | disputed`. - Optimistic UI where relevant — show the result now, verify in the background, explain clearly on failure, as shown in [good engineering by design](/journal/good-engineering-is-invisible/). - Instrumented before/after: completion rate, time-to-complete, and retry rate measured on the core job. - Five states designed for the AI path as well: what empty looks like, what measurable “success” is, what failed safely preserves, and who can fix a denied case. The engineering is not about the model vendor. It is about where the generation lives in the product. ## Hype vs correct — comparison we use in reviews | Dimension | Cheap (hype) | Correct (earn retention) | | --- | --- | --- | | **Placement** | On top of a fragile flow | Inside a typed job with clear boundaries | | **States** | Happy path only; errors bubble as 500s | Empty, loading, success, failure, denied — all designed | | **Measurement** | None, or vanity “tokens used” | Completion rate and friction before/after | | **Cost view** | Model call price only | Model + support + rework + trust cost | | **Retention impact** | Demo liked, return rate flat or down | Return rate moves because the job is genuinely easier | | **When we ship** | Because a deck needed “AI” | Because a specific friction was measured and removed | We review each proposed AI feature against this table before we estimate it. The same table determines where it falls in the [MVP cost breakdown](/journal/mvp-cost-breakdown/) — a cheap call that creates a support queue is not cheap. ## The cost of hype Hype cost is not the invoice. It is: - Users who pause to verify every generation, adding a second job (checking) to the first. - Support threads about “is this number right?” because money was a float and status was a string. - A second build to re-wire the job after users have already learned to distrust it. We prefer the checklist from our [MVP pillar](/journal/mvp-means-minimum-viable-not-minimum-care/): if the AI path cannot answer the five states, it does not ship — no matter how good the demo looks in a review. For scope, use our [pruning template](/journal/mvp-scope-pruning-must-ship-vs-deferred/). For timeline, see [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/). ## FAQ — cheap vs correct AI integration **What is cheap vs correct AI integration?** Cheap ships a prompt on a fragile flow and optimizes for the demo. Correct places generation inside a typed job with empty, failure, and denied states and measures completion rate before and after. **Why does cheap AI cost more after launch?** The invoice hides support threads, verification pauses, and a second rebuild once users distrust the output. Correct AI counts model plus support, rework, and trust cost. **How do you know if AI earns retention?** Instrument the same core job twice — with and without the AI variant — and keep it only if more strangers finish faster and with fewer retries. Have an AI idea you want to pressure-test? [Map Your AI Idea to Hype vs Correct](/contact/?service=build-sprint) — we put each proposal in the table with you and instrument the one that earns retention. ## Journal: AI Features That Earn Retention, Not Just Demos - Path: https://emiote.com/journal/ai-features-that-earn-retention/ - Date: 2026-08-29 - Category: Search & AI - Reading Time: 6 min - Description: When AI earns a slot in your MVP — and when it is hype. A decision matrix based on completion rate and friction. We love AI where it removes a real step a user would otherwise struggle with. We defer AI where it adds a demo but not a reason to return. Does this AI help a stranger finish the job — or just make the demo longer? The answer shows up in one number: **completion rate** for the core job, measured before and after the AI ships. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="decision-matrix" caption="We ship AI only when it moves completion rate or removes friction we can measure." /> ## Answer first: does this AI change whether the job gets finished? If an AI feature shortens the path to a clear outcome — fewer fields, fewer decisions, fewer errors — it has an honest slot in an MVP. If it adds a generation step the user must check, edit, and re-do, it is not an MVP feature. It is a follow-up iteration that needs its own instrumented test. We learned this the same way we learned to cut scope in our [MVP checklist](/journal/mvp-means-minimum-viable-not-minimum-care/): viability is trust, and trust is measured by whether a stranger can finish without a sales call. ## The decision matrix we use Ask two questions: 1. **Does it increase the rate at which strangers complete the core job?** 2. **Does it increase friction, cost, or the need to double-check?** | | Low friction | High friction | | --- | --- | --- | | **Increases completion** | **Ship** — AI removes a real step. Measure before/after. | **Test first** — help for some, hurt for others. Needs instrumented slice. | | **No increase** | **Skip** — AI doesn't change the job. Adds cost, not value. | **Hype trap — defer** — demo that adds steps and lowers completion. | We put every proposed AI feature in one quadrant before we estimate it. The quadrant decides the roadmap, not the demo schedule. ## When AI earns a slot — concrete earns AI earns a slot when one of these is true and measurable: - A field users often get wrong is auto-filled inside a typed boundary — so mistakes don't become dispute threads. Example: parsing an invoice total into `balanceInCents` with explicit `pending` vs `reconciled`, as we do in [Ankik](/journal/ankik-ledger-one-trusted-number-first/). - A step that takes minutes drops to seconds without adding a new decision — so more strangers finish without help. Example: suggesting the next status update for a field visit — the user taps accept or edits, not composes from scratch. - Error handling becomes obvious — so the user knows what is safe to retry without calling support. Example: explaining why a save failed in plain language tied to retry safety, as shown in [failure states](/journal/good-engineering-is-invisible/). In each case we measure: did more strangers finish the job without help after the AI shipped? If yes, we keep it. If not, we remove it — even if the demo was liked in a review. ## When AI is hype AI is hype when: - It generates a draft the user must carefully verify every time, adding a second job (checking the draft) to the first. - It creates content for a job that wasn't asked for — a summary page when the user actually needed a status update they can trust. - It is added because “every MVP needs AI” rather than because a specific friction was measured. We prefer what we call boring structure first: explicit flows, typed boundaries, and the five-state checklist. AI is a material inside that structure, not the product. For a practical map of hype vs correct trade-offs, read [cheap vs correct AI integration](/journal/cheap-vs-correct-ai-integration/). ## How we test AI in a Build Sprint We treat an AI slice like any other hypothesis in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/): 1. Define the job and the friction in one sentence. 2. Ship the non-AI path that already lets a stranger finish. 3. Add the AI as a flagged variant on the same path. 4. Measure completion rate and time-to-complete for both variants. 5. Keep the AI only if the variant wins on real use. The cost of an AI feature is not just the model bill. It is the support load when the generation is wrong in a way the user cannot spot quickly. That is why we pair AI with careful [pricing of scope](/journal/mvp-cost-breakdown/) — a cheap model call that creates a support queue is not cheap. Scoping an MVP where AI might help? [Put Each AI Idea Through the Ship / Skip Matrix](/contact/?service=build-sprint) — we instrument the winner so you keep what moves completion rate, not what demoed well. ## Journal: MVP Scope Pruning: Must Ship vs Deferred - Path: https://emiote.com/journal/mvp-scope-pruning-must-ship-vs-deferred/ - Date: 2026-08-28 - Category: Product - Reading Time: 5 min - Description: A practical framework for pruning MVP scope — must-ship vs deferred, the five-state checklist, and a copyable scope cut list. **Definition:** MustShip vs deferred is a written scope contract for what an MVP should include — mustShip holds the smallest surface that earns a fair test, deferred parks the rest. We also gate each keep with five states (empty, loading, success, failure, permission denied) and revisit the list at day 14. Has a week-three "quick add" quietly become your product? The fastest way to ship is not more hours. It is less surface, done well. We keep one written list: **mustShip vs deferred**. It stops scope from growing between demos. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="scope-funnel" caption="Four steps we run before any code — the written cut list is what keeps scope honest." /> ## The four-question framework before code We run the same four questions with every founder: 1. **Name the primary user and the primary job.** One sentence. If you need three sentences, you have three products. 2. **List every feature request.** Then move most of them to deferred without apology. 3. **For what remains, list states.** Empty, loading, success, failure, permission denied. If a state has no design, the feature is not ready to ship. 4. **Define done as a stranger completing the job on production.** Not “the happy path works on my laptop.” Those questions turn a wish list into a [fair test](/journal/mvp-means-minimum-viable-not-minimum-care/) — the goal described in our MVP pillar. ## Must ship vs deferred — a real example A founder wants a B2B tool for scheduling field visits. The full vision is maps, offline mobile, custom roles, AI route optimization, and three CRM integrations. A minimum-care build tries to sketch all of that thinly. A minimum-viable cut ships only the smallest shippable surface: | Must ship | Why it earns a slot | | --- | --- | | Invite and sign-in | You cannot test retention without identity | | Create a job and assign a window | The core job itself | | Status updates the customer can trust | Without this, WhatsApp remains the real system | | Payment or contract step for the pilot | Answers willingness to pay | | Error and empty states on those paths | Protects the validity of the test | Maps, offline, AI routing, and CRM sync wait. Not because they are unimportant — because they do not answer the first question yet. They are priced in the next phase, as explained in our [cost breakdown](/journal/mvp-cost-breakdown/). This is the same discipline that let [Ankik](/journal/ankik-ledger-one-trusted-number-first/) replace scattered notebooks with a single ledger path before we added reports. ## The five-state checklist For every feature that stays in mustShip, we check five states. If one has no design, we pause. | State | Question we answer before shipping | | --- | --- | | **Empty** | What do we show when there is no data, and what is the first step? | | **Loading** | What does the user see while we verify in the background? | | **Success** | Is completion obvious and is the next step clear? | | **Failure** | What failed, what is safe to retry, and what was not stored? | | **Permission denied** | Who can help, without exposing internal role IDs? | We treat this as part of engineering, not polish. Our notes on [invisible engineering](/journal/good-engineering-is-invisible/) describe why these states matter more than animation on secondary screens. ## A copyable scope cut list We write the list in code so it can be reviewed and versioned: ```typescript export const mvpScopeCutList = { mustShip: [ "Core auth and onboarding flow", "Primary user job execution", "Stripe checkout integration", "Basic audit telemetry", ], deferredForV2: [ "Complex role-based permissions", "Custom theme overrides", "Multi-tenant custom subdomains", "Deep analytics suite", ], } as const; ``` The list has two owners and a renewal point at day 14, as shown in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/). At day 14 we ask: what did we learn, and what now earns a slot in mustShip? ## Why we prefer boring structure here For an MVP, “clever” architecture is a tax. Generic engines and runtime-configurable workflows look senior on a whiteboard and slow every change when the domain shifts. We prefer explicit flows for the core path, with extension points only where a second real use case has already arrived. That is how a product stays changeable without a total rebuild when the second customer arrives. Detailed foundations we treat as non-optional — backups with a tested restore, secrets out of the repo, CI on every change, logging to answer “what happened for this user?” — are covered in the pillar. ## FAQ — MVP checklist and scope **What should an MVP include?** Only the smallest shippable surface that lets a stranger complete one primary job on production — auth, the core path with all five states, payments where money moves, and deploy/telemetry. Everything else is deferred. **What is the five-state checklist?** Empty, loading, success, failure, and permission denied — each with a designed copy and next step. If a state has no design, the feature is not ready to ship. **When do deferred items come back?** At the day-14 renewal. We ask what we learned from the usable slice and what now earns a slot in mustShip — not what was requested loudest. Run it yourself: copy the list above, name each job in one sentence, and mark overlap. Want us to run it with you? [Map Your Scope to Must Ship vs Deferred](/contact/?service=build-sprint) — we put it in writing before code and keep the contract visible. ## Journal: MVP Cost Breakdown: $1,200 to $4,500 Explained - Path: https://emiote.com/journal/mvp-cost-breakdown/ - Date: 2026-08-27 - Category: Product - Reading Time: 6 min - Description: How we price Build Sprints from $1,200 to $4,500 — what moves the price, what each tier includes, and the cost of cutting care. **Definition:** MVP development cost at Emiote is scope-driven — Build Sprint starts at **$1,200** and most scoped MVPs land **$1,200–$4,500**. Larger surfaces are phased. Price reflects one primary job done well on production-infra (auth, five states, deploy, telemetry), not hourly theater. Need a price before you commit runway? Our Build Sprint starts at **$1,200**. Most scoped MVPs land between **$1,200 and $4,500**. If your product needs more surface, we phase it — we don't squeeze it into $1,200. Those numbers are our estimates, not market rates. What follows is exactly what moves the price inside our sprint — so you know what you're buying. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="cost-stack" caption="Price is scope. The stack shows which components change the number." /> ## What $1,200 means in our studio $1,200 is a tightly scoped sprint — one core workflow, tightly defined, with no scope creep between week one and week four. It includes: - Real auth and onboarding - One primary job done well on staging by day 14 and hardened for production by day 28 - A deploy path, basic telemetry, and the non-optional foundations It does not include multiple roles, multiple core flows, custom themes, or deep analytics. Those are real needs for larger products — they just belong in a phased next slice, not in the first slice. We agree scope in writing before code, using the same [MVP checklist](/journal/mvp-means-minimum-viable-not-minimum-care/) we keep on the wall. ## What $4,500 includes $4,500 is a more complete MVP — still ruthlessly scoped, but with more surface covered well. That usually means: - A primary job plus one or two adjacent jobs that are required for the job to feel complete - Payments and checkout where money moves, with failure and retry paths - Telemetry and a simple admin view so you can answer “what happened for this user?” - Backups, restore drill notes, and hardening that keeps the product alive after the first real user When a product needs more than that — multiple roles, multi-tenant customization, or integrations with three CRMs — we phase it. The first phase is still priced inside $1,200–$4,500; the next phase is estimated separately. ## The cost stack — what moves the number | Component | What’s in our scoped price | What increases price | | --- | --- | --- | | **Auth + onboarding** | Real auth day one, invite and sign-in that lets you test retention | Complex RBAC before first retention test | | **Core workflow** | One or two flows done well, with all five states | Adding maps, offline, or AI routing before the core is proven | | **Checkout / payments** | Stripe integration where money moves, with receipts and retry | Custom billing rules or multi-tenant custom pricing before first paid pilot | | **Telemetry + infra** | Logs, basic admin, deploy path, backups story | Deep analytics suite or elaborate design system | | **Handoff** | Weekly live increments, scope contract, quality contract | Building the “generic engine” for all future requests | The table is why we use the 14/28 split described in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/). Days 0–14 prove the job; days 15–28 make it trustworthy. ## The cost of cutting care The cheapest way to build is to cut care: skip empty states, defer auth, ignore backups, and assume “we’ll harden after users.” That is expensive confusion. Take two paths for the same scheduling B2B pilot: - **Path A (cut care):** try to sketch maps, offline, AI routing, and three CRM syncs thinly. Users bounce. No one knows which hypothesis failed. You learned the demo was fragile. - **Path B (our bar):** invite and sign-in, create a job and assign a window, status updates the customer can trust, a payment step for the pilot, and error and empty states on those paths. Maps and AI routing wait until the pilot proves the job. Both paths cost money. Only one gives you a fair test. That difference is what we optimize for when we price a sprint. We have lived this trade-off on our own products and client platforms. [Ankik](/journal/ankik-ledger-one-trusted-number-first/) did not need every report to be viable — it needed a ledger path that replaces the notebook. [Retainix](/journal/retainix-5-second-counter-rule/) did not need every campaign type — it needed branch-safe earn and redeem that staff can explain in five seconds. ## What we leave out of most MVPs We deliberately leave out of many first slices: - Complex multi-tenant customization - Deep analytics suites - Elaborate design systems - AI features that do not change whether the core job gets finished AI is a material, not a product. The product is still the job. When we add AI, we do it where we can measure completion rate before and after, as described in [AI features that earn retention](/journal/ai-features-that-earn-retention/). ## A note on pricing expectations If your idea needs a full platform with multiple roles, multiple workflows, and custom integrations from day one, $1,200 will not cover it. We will tell you that before the sprint and propose a phased plan with scope and price agreed before development begins. If your idea can be tested with one trusted job on production infrastructure, $1,200 can be enough for a fair test. Either way, the price is scope — not hourly theater. ## FAQ — MVP development cost **How much does an MVP cost at Emiote?** Build Sprint starts at $1,200. Most scoped MVPs land $1,200–$4,500. Larger surfaces are phased separately with price agreed before code. **What makes an MVP cost more than $1,200?** Additional roles, adjacent core jobs, checkout with retry paths, admin views, and hardening beyond the single primary job. These are real needs — they belong in a phased next slice. **Does $1,200 include design, payments, and deploy?** Yes for one primary job — real auth, one core workflow with all five states, deploy path, basic telemetry, and foundations. Custom themes, multi-tenant pricing, or deep analytics wait until phased. Ready to scope yours? [Get a Scope-Bound Estimate Before Code](/contact/?service=build-sprint) — we review the primary job in writing and confirm price before we code. ## Journal: How We Ship a Core in 14 Days and Live in 28 - Path: https://emiote.com/journal/how-we-ship-core-in-14-days-live-in-28/ - Date: 2026-08-26 - Category: Product - Reading Time: 6 min - Description: Our Build Sprint timeline: a usable core in 14 days, a hardened product live in 28 — and what happens in each phase. **Definition:** MVP development timeline at Emiote is a Build Sprint — **core usable on staging in 14 days, hardened live in 28**. Days 0–14 ship one primary job a stranger can finish without a walkthrough; days 15–28 harden payments, five states, backups, and deploy so a user can pay and return. Why wait six months to learn one thing? Most founders need two weeks to see if a stranger can finish the core job. We run Build Sprints in two phases: **core in 14 days, live in 28**. The first half answers "does this work for a real user?" The second makes sure it stays working when money and trust are on the line. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; <JournalDiagram variant="timeline-gantt" caption="Two phases. Day 14 is a usable slice on staging; day 28 is a hardened product real users can pay for." /> ## The problem we solve: waiting six months to learn one thing A common path looks like this: plan for a month, build a full roadmap for three, polish for two, then show it to a user. If the core job is wrong, you paid for four months of detail before the first real test. We flip that. We agree on one primary job, ship the thinnest slice that lets a stranger complete it, and learn on real infrastructure. If you need three sentences to name the primary job, you have three products. That clarity is what makes 14 days possible. We use the same scope contract from our [MVP checklist](/journal/mvp-means-minimum-viable-not-minimum-care/) — mustShip vs deferred — and we run it as a written decision, not a Slack thread. --- ## Our 14/28 split — what each phase is for | Phase | Outcome | What we optimize for | | --- | --- | --- | | **Days 0–14 · Core** | A usable slice on staging that a stranger can complete without a walkthrough | Learning — does the job map to real workflow? | | **Days 15–28 · Harden & Live** | A product on production that handles money, errors, and return visits | Trust — will someone pay and come back? | Day 14 is not a Figma prototype. It is working software on staging with real auth and a real path through the core job. Day 28 is not “add more features.” It is the same slice with the parts that make it production-ready. We keep one product at a time and work principal-led so scope doesn't quietly grow between demos. --- ## Days 0–14: what we build in weeks 1–2 Weeks 1 and 2 are intentionally boring in the right way. **We build:** - One primary user and one primary job — named in a single sentence - Auth and onboarding that lets us test retention (you cannot test return visits without identity) - The shortest path that completes the job — not the admin surface, not the third CRM integration - A usable slice demo at the end of week 2 that a stranger can finish What we deliberately leave out of this window: custom roles, themes, subdomains, deep analytics, and AI that doesn't change whether the core job gets finished. This is the same discipline that shaped [Ankik](/journal/ankik-ledger-one-trusted-number-first/) — we did not need every report on day one; we needed a ledger path people would use instead of the notebook. If the core job is not complete on staging by day 14, the scope was too big. We cut, not add. --- ## Days 15–28: hardening, payments, telemetry This is where MVPs usually fail quietly. The demo works, but the first real user hits an empty state with no guidance, a payment retry with no clarity, or a backup story that was never tested. **We harden:** - **Payments and checkout** where money is involved — Stripe integration, receipts, and the paths for failure and retry - **Telemetry and admin** so we can answer “what happened for this user?” without guessing - **Empty, loading, success, failure, and permission-denied states** on every shipped path - **Backups, secrets, CI, and a deploy path** that is not FTP — the short list we treat as non-optional We also add logging enough to trace a single user's journey and alerts that tell us if the core job breaks. This is why our [invisible engineering](/journal/good-engineering-is-invisible/) work matters more than animation budgets on secondary screens. --- ## Why foundations are not optional “We'll harden it after we get users” sounds rational until the first users are the ones who find the holes. We treat a short list as part of the MVP itself: - Backups and a restore story we have practiced once - Secrets out of the repo - CI that runs on every change - A deploy path we trust These do not need a platform team. They need a decision to not call a fragile demo an MVP. We use the same bar described in our [scope pruning guide](/journal/mvp-scope-pruning-must-ship-vs-deferred/) — if a state has no design, the feature is not ready to ship. --- ## The scope contract — written before code On day 0 we write the contract: ```typescript export const mvpScopeCutList = { mustShip: [ "Auth and onboarding", "Primary job execution", "Checkout where money moves", "Telemetry and deploy health", ], deferredForV2: [ "Complex roles", "Custom themes", "Subdomains", "Deep analytics", ], } as const; ``` The contract has two owners and a renewal point at day 14. If someone wants to add scope in week two, the question is not “is this a good idea?” It is “what leaves the mustShip list to make room?” This is how we keep a Build Sprint from becoming an agency timeline with AI hype added. --- ## What you get at day 14 and day 28 At day 14 you have a slice you can test with a stranger. At day 28 you have a product a user can pay for and return to. Both are built principal-led, AI-native in the seat (we use models where they remove real friction, not where they demo well), and measured by usable paths, not slide updates. If you want to see how we price that scope, read our [MVP cost breakdown](/journal/mvp-cost-breakdown/). If you want the practical template, use the [scope pruning guide](/journal/mvp-scope-pruning-must-ship-vs-deferred/). ## FAQ — MVP development timeline **What is the MVP development timeline at Emiote?** Core usable on staging in 14 days, hardened live in 28. Days 0–14 prove the primary job; days 15–28 harden payments, five states, backups, and deploy. **What do you ship by day 14?** Working software on staging — real auth, the shortest path to complete the primary job, and a demo a stranger can finish without a walkthrough. Not a Figma prototype. **Why does hardening take another 14 days?** The demo path fails where money and trust are on the line — empty states, payment retries, telemetry, and restore story. That is where MVPs quietly fail if skipped. Ready to ship? [Ship a Core Strangers Can Finish in 14 Days](/contact/?service=build-sprint) — we take one product at a time and keep accountability in the studio. ## Journal: Beyond Google: Measuring AI Search Grounding via Bing - Path: https://emiote.com/journal/beyond-google-measuring-ai-search-grounding-via-bing/ - Date: 2026-08-19 - Category: Search & AI - Reading Time: 5 min - Description: Why Bing is the core retrieval backbone for AI search engines, and how its AI Performance Report turns generative discovery into measurable telemetry. If ChatGPT can't cite you, you don't exist for that buyer. When a founder asks ChatGPT Search, Copilot, or a coding agent a technical question, the model doesn't answer from memory alone. It runs live retrieval over a web index to ground its answer in a cited page. For much of that ecosystem, **Bing is the index under the hood** — including the grounding layer for ChatGPT Search. If your workflow stops at Google Search Console, you're invisible in the AI discovery pipeline. --- import JournalDiagram from "../../components/journal/JournalDiagram.astro"; ## The AI Retrieval Architecture <JournalDiagram variant="grounding-pipeline" caption="Bing is the retrieval backbone for ChatGPT Search, Copilot, and coding agents — optimize for it first." /> Traditional search engines index pages to present snippets and drive navigational clicks. Generative search engines use web indices as **grounding context**: 1. **User Prompt:** A user asks a specific product or architectural question. 2. **Sub-query Generation:** The model breaks down the prompt into one or more live search queries. 3. **Index Retrieval:** The engine queries a live web index (predominantly Bing or dedicated crawlers like `OAI-SearchBot`) to fetch the most relevant text blocks. 4. **Synthesis & Citation:** The model synthesizes the answer, attaching citation anchors to the specific URLs that provided evidence. ```text [User Prompt] ──▶ [LLM Query Expander] ──▶ [Bing Index / Retrieval API] │ [Cited Answer] ◀── [Context Synthesis] ◀── [Grounding Context Chunks] ``` When you understand that Bing's index feeds both Microsoft Copilot and the grounding layer for OpenAI's search workflows, optimizing for Bing stops being an afterthought. It becomes primary infrastructure for AI visibility. --- ## The AI discovery checklist — 3 steps to be cited Three moves that make your docs and product pages retrievable by generative engines — so the answer includes you: ### 1. Bing Webmaster Tools & Ownership Claim domain ownership in Bing Webmaster Tools (via DNS TXT record or XML verification). Unlike Google Search Console, Bing gives immediate visibility into both standard crawler activity and AI-specific grounding signals. ### 2. Push updates with IndexNow — so they appear in seconds, not days Instead of waiting for crawlers to find your sitemap, **IndexNow** lets your deploy pipeline push a lightweight POST the moment you publish: ```bash # Push updated routes directly to IndexNow curl -X POST "https://api.indexnow.org/indexnow" \ -H "Content-Type: application/json; charset=utf-8" \ -d '{ "host": "emiote.com", "key": "your-indexnow-key", "keyLocation": "https://emiote.com/your-indexnow-key.txt", "urlList": [ "https://emiote.com/journal/beyond-google-measuring-ai-search-grounding-via-bing", "https://emiote.com/products/ankik" ] }' ``` Participating engines (Bing, Yandex, Seznam, Naver) receive the update in seconds rather than days. ### 3. Explicit Bot Allow-listing in `robots.txt` Many generic `robots.txt` templates inadvertently block newer AI crawlers or restrict non-Google bots. Ensure your configuration explicitly permits both general indexing bots and AI retrieval agents: ```text # Explicit AI retrieval and search crawler permissions User-agent: Bingbot Allow: / User-agent: OAI-SearchBot Allow: / User-agent: GPTBot Allow: / User-agent: ChatGPT-User Allow: / User-agent: PerplexityBot Allow: / User-agent: ClaudeBot Allow: / Sitemap: https://emiote.com/sitemap-index.xml ``` `OAI-SearchBot` is specifically used by OpenAI to find fresh search results for users, distinct from general training crawlers. --- ## Measuring Grounding: The AI Performance Report The critical advantage of Bing Webmaster Tools today is the **AI Performance Report**. Historically, Answer Engine Optimization (AEO) and Generative Engine Optimization (GEO) suffered from an evaluation problem: teams resorted to manually prompting ChatGPT or Claude to see if their product was mentioned—a noisy, non-deterministic heuristic. Bing's AI Performance Report replaces guesswork with server-side telemetry: | Metric | What it reveals | Engineering implication | | --- | --- | --- | | **Cited Pages** | Exact URLs selected as source truth in AI answers | Identifies which docs or articles carry high semantic authority | | **Grounding Queries** | The underlying search queries triggering citations | Reveals real problem-framing language used by searchers | | **Citation Frequency** | Temporal shifts in how often your pages are referenced | Measures whether documentation updates improved or diluted retrieval | ```text ┌─────────────────────────────────────────────────────────────┐ │ Bing AI Performance Telemetry │ ├─────────────────────────────────────────────────────────────┤ │ Cited URL: /reframehub/supabase-vs-self-hosted-postgres │ │ Grounding Query: "self hosted postgres vs supabase cost" │ │ Citation Activity: +34% following July 2026 data refresh │ └─────────────────────────────────────────────────────────────┘ ``` When you see that a specific comparison table or architectural breakdown is repeatedly cited for a grounding query, you know that the content's structure, semantic clarity, and factual density are working. --- ## What This Means for Product Builders Optimizing for retrieval grounding requires the same discipline as good software engineering: - **Structure over fluff:** Clean HTML headings (`h1`-`h4`), typed tables, and explicit schema markup (`BlogPosting`, `SoftwareApplication`, `BreadcrumbList`) make extraction reliable for LLM parsers. - **Machine-readable artifacts:** Exposing `llms.txt`, RFC 8288 link headers, and OpenAPI schemas turns your entire site into an open knowledge surface for agents. - **Continuous telemetry:** Using Bing Webmaster Tools alongside Google Search Console ensures you monitor both traditional navigational rank and generative citation health. > **Research note:** Aggarwal et al., *GEO: Generative Engine Optimization* (KDD 2024, tested across Perplexity.ai) ranked 9 optimization methods — cite sources +40%, add statistics +37% visibility. See [arXiv:2311.09735](https://arxiv.org/abs/2311.09735). ## FAQ — AI search grounding via Bing **Why does Bing matter for AI search visibility?** Much of ChatGPT Search and Copilot's retrieval grounds in Bing's index and the `OAI-SearchBot` crawl. If you only optimize for Google Search Console, you're invisible in that grounding pipeline. **How do I check if AI engines cite my site?** In Bing Webmaster Tools → AI Performance Report check Cited Pages, Grounding Queries, and Citation Frequency. It replaces manually prompting ChatGPT with server-side telemetry. **What is IndexNow and why use it?** IndexNow is a push protocol — your deploy pipeline POSTs updated URLs so Bing, Yandex, and others re-index in seconds instead of days. Use it for every publish. ## Closing — what to do next Search is now an agentic retrieval layer. Optimizing only for Google is optimizing for yesterday's web. We ship our own products with this rigor from day one. For where AI actually earns retention, read [AI features that earn retention](/journal/ai-features-that-earn-retention/). Ready to be cited? [Audit Your AI Visibility](/contact/) — we check Bing, robots, and extractability so agents can cite you. Or explore [how we weigh self-hosted vs managed on ReframeHub](/reframehub/). ## Journal: Good engineering is invisible — by design - Path: https://emiote.com/journal/good-engineering-is-invisible/ - Date: 2026-08-18 - Category: Engineering - Reading Time: 5 min - Description: Users shouldn't notice the implementation. They should notice how easy everything feels. Notes on craft that stays out of the way. **Definition:** Invisible engineering is craft aimed entirely at eliminating friction — sub-100ms responses, predictable failure guidance, intuitive data models, and stable defaults — so a user finishes without noticing the stack. It is not absence of rigor; it is rigor spent where trust is won or lost. Users don't open an application to admire the underlying database schema or the reactivity model. They open it to finish a job and move on with their day. **Invisible engineering** is not the absence of technical craft—it is craft aimed entirely at eliminating friction. --- import JournalDiagram from "../../components/journal/JournalDiagram.astro"; ## What invisible engineering looks like <JournalDiagram variant="invisible-engineering" caption="Invisible craft = boring core path + explicit failure guidance. Users feel it; they rarely photograph it." /> You rarely hear users praise the stack. You hear them say the tool “just works,” or that they finished something without thinking about the software. That outcome is engineered. In practice, invisible craft shows up as concrete properties: - **Sub-100ms UI responses** — Interactions feel instant, so the user finishes without waiting. Performance is the product, not polish. - **Predictable failure modes** — When something breaks, the user gets what failed and what is safe to retry — not an opaque `500`. - **Intuitive data models** — Software reflects how people talk about the work, not only how a database stores rows. - **Stable defaults** — First-run paths assume a careful beginner, not a developer who already knows the schema. None of these require a flashy framework. They require attention to the moments where trust is won or lost: first click, first save, first error, first return visit. --- ## Speed that feels like calm <JournalDiagram variant="optimistic-ui" caption="Optimistic UI pattern — apply it to every primary job before adding animation to secondary screens." /> Fast interfaces are not only about network latency. They are about when the UI updates relative to the user’s intent. A common pattern: show the result of an action immediately, then reconcile with the server. If the write fails, roll back and explain what happened. The user stays in flow; the system stays honest. ```typescript // Optimistic UI: feel instant, stay correct when the network disagrees async function submitInvoice(invoiceData: Invoice): Promise<Result<InvoiceId>> { invoiceStore.addOptimistic(invoiceData); return await api.invoices.create(invoiceData).catch((err) => { invoiceStore.rollback(invoiceData.id); return Result.err(err); }); } ``` In plain language: **assume success for the hands, verify in the background, recover with clarity.** Loading spinners on every keystroke teach users that the product is fragile. Silent failure teaches them not to trust it at all. The same idea applies beyond invoices—any primary job path (ledger entry, loyalty redeem, invite accept) deserves that treatment before secondary screens get animation budgets. --- ## The trap of visible engineering Visible engineering frequently sneaks into codebases as **cleverness for its own sake**: - Novel state abstractions introduced without a clear requirement - UI components designed to display framework features rather than user intent - Architecture built to impress other engineers in blog posts rather than serve the product - Error surfaces that expose stack traces to non-technical users “for transparency” Craft becomes visible in the wrong way when the implementation is the star of the experience. ### A pattern we reject by default Early in a product, it is tempting to build a “flexible engine”: generic entities, runtime-configurable workflows, a meta-layer that could support any future request. On a whiteboard it looks senior. In a real codebase it often means: - Nobody can answer “what happens when the user clicks this?” without tracing three indirection layers - Simple changes require migrating abstract config - New engineers optimize the engine instead of the job We prefer **boring, explicit flows** for the core path, with extension points only where a second real use case has already arrived. Invisible engineering is often the courage to leave the clever design in the notes app. --- ## Designing for the failure path Happy-path demos hide cost. Invisible quality shows up when the network drops, the payment provider times out, or two branches edit the same record. Minimum care for failure looks like a red banner and a shrug. Viable care looks like: | Situation | Invisible-quality response | | --- | --- | | Save failed | What failed, what is safe to retry, what was not stored | | Partial success | Which step completed; what to do next | | Permission denied | Who can help; no internal role IDs in the UI | | Empty data | What to do first, not a blank table that feels broken | That work is engineering and product writing at once. It rarely screenshots well for a case study. Users feel it every week. --- ## Four failure states we design for Not every error is the same. We design for four distinct states on every MustShip path — the same discipline behind our [scope pruning](/journal/mvp-scope-pruning-must-ship-vs-deferred/). <JournalDiagram variant="state-machine" caption="Empty → Saving → Success, with typed transitions to Failed, Partial and Denied. If a state has no design, the feature is not ready." /> I learned this while watching a save fail leave money in `pending` with no guidance. Typed status alone was not enough — the UI also had to say *what failed, what to retry, and what stayed safe*. That incident maps directly to the “Save failed” and “Partial success” states above. We test each state before we add animation to secondary screens. It is the same bar we enforce at day 14 in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/) and price honestly in our [cost breakdown](/journal/mvp-cost-breakdown/). --- ## The ultimate test After someone uses software we built, do they praise the framework—or do they remark on **how effortless the work felt**? We optimize for the second outcome every time. If they mention React, the queue library, or our “elegant service mesh,” we missed. If they finished reconciliation, closed the shop, or launched the beta without narrating the UI, we got closer. Invisible does not mean undocumented or untested. Internally we still want clear modules, typed boundaries, and deploy confidence. Externally, the product should disappear into the job. --- ## Closing Good engineering leaves a quiet trail: fewer support tickets about “what does this mean?”, fewer rewrites forced by early cleverness, more users who simply complete the task. We hold the same bar on [our own products](/products/) and on partner builds. Want engineering that stays out of the way? [Get Engineering That Stays Out of the Way](/contact/) — tell us what you are shipping and we will show where friction lives. ## Journal: Products teach better than pitches - Path: https://emiote.com/journal/products-teach-better-than-pitches/ - Date: 2026-08-12 - Category: Studio - Reading Time: 5 min - Description: Why building our own products is the strongest training ground for client engineering—and what that means for how we partner. import JournalDiagram from "../../components/journal/JournalDiagram.astro"; Agencies pitch. Studios ship. The difference shows up the first time a client asks how we would handle a hard product decision—not just a coding task. Building software of our own forces us through the full loop: **problem discovery, aggressive scope pruning, trade-offs under constraints, customer support, and the quiet work of long-term maintenance**. That loop is our curriculum. Client work is where we apply it. --- ## Dogfooding creates standards When we build products like **Ankik** (desktop-first accounting workspace with strict double-entry ledgers) or architect multi-location systems like **Retainix** (multi-branch loyalty and cashback), we experience the true cost of software decisions: > Every awkward default, missing empty state, or overly clever architecture choice doesn't just annoy a client—it directly hits our own product velocity. These scars become the engineering standards we bring into every partner engagement. Ownership is not a marketing line. It is a feedback loop with consequences. ### What ownership teaches that slides cannot A deck can claim “product-minded engineering.” A product you maintain will disagree with you in public: - **Ship day is not done day.** The first real user will press paths you never demoed. Support load is a design signal, not an afterthought. - **Clever code has a bill.** Abstractions that impressed in a review slow the next change when the domain shifts. - **Defaults are product decisions.** Empty states, error copy, and “what happens when this fails” decide whether people trust the tool. When we partner with founders, we are not guessing about those costs. We have paid them on software we still run. --- ## A scar from real books Ankik started because books lived across notebooks, spreadsheets, and chat threads. The first instinct in software is always the same: model the full business on day one—every report, every role, every edge case the owner can name in a single conversation. That path fails quietly. You ship a dense system nobody finishes onboarding, and the notebook stays open next to the app. What we learned—and now insist on with client MVPs—was narrower: 1. **One trusted number first.** Opening balance, a clean ledger entry path, and a view that answers “where do we stand?” before multi-entity dashboards. 2. **Money is not a float.** Domain types that refuse sloppy precision (cents as integers, explicit status) beat “we’ll fix currency later.” 3. **The owner’s language wins.** Screens named after how they talk about the work beat screens named after how the database stores rows. ```typescript // Exact money and explicit status—not “number and vibes” export interface AccountLedger { readonly id: string; readonly partyId: string; readonly balanceInCents: bigint; readonly status: "reconciled" | "pending" | "disputed"; } ``` That interface is not clever. It is a boundary that keeps the product honest. Client work benefits when the same discipline shows up early: typed edges, clear states, fewer silent lies in the data. Retainix taught a parallel lesson for multi-branch operations: loyalty rules that look simple on a whiteboard fracture at the counter. Branch context, cashback timing, and “what if this ticket is refunded?” are product decisions. Shipping a points total without those paths is not an MVP—it is a demo that will be trusted until the first dispute. --- ## Why we operate on two equal pillars <JournalDiagram variant="studio-pillars" caption="Two pillars, one loop — products teach client work, client work funds products. Pitches expire, products keep scoring." /> We balance work across two core areas: 1. **In-house products** — Software we design, own, and maintain in public. 2. **Product partner work** — Building MVPs, modernizing systems in place, integrating AI where it earns its keep, and embedding with teams. We do not treat internal products as side projects or brochure props. Ownership is the fastest path to genuine product judgment—and **product judgment is what founders actually hire for**. The two pillars reinforce each other: | From products — what it taught us | Into client work — what you gain | | --- | --- | | Maintenance pressure | Boring, changeable designs — so a second customer doesn't force a rebuild | | Real support threads | Failure paths designed early — so users know what is safe to retry | | Scope regret | Cut features, raise quality on what remains — so the test is valid | | Domain messiness | Workflows over feature lists — so software matches how work actually happens | Client work funds time to improve products. Products raise the bar on what we will accept in a partner engagement. If a proposed build would embarrass us on our own stack, we say so before the sprint starts. --- ## What this means when you work with us You should expect conversation that sounds more like a product team than a vendor checklist: - **We argue for less surface area** when more would dilute the hypothesis you need to test. - **We write down trade-offs** so “we’ll clean that up later” has an owner and a date, not a shrug. - **We optimize for the job the user is finishing**, not for how impressive the architecture diagram looks in a weekly update. We will still move fast. Speed comes from deciding what not to build, and from craft on the path that remains—not from skipping empty states, tests, or deploy discipline. If you want a partner who has only shipped for other people, plenty of teams do that well. If you want a partner who also lives with the long tail of their own products, that is the studio model on purpose. --- ## Closing Pitches expire. Products keep scoring your decisions after the call ends. We build both because the second one keeps the first one honest. Ready to shape an MVP or strengthen a product already in market? [Work With a Studio That Ships Its Own Products](/contact/) — or read how we define [minimum viable without minimum care](/journal/mvp-means-minimum-viable-not-minimum-care/). ## Journal: MVP means minimum viable, not minimum care - Path: https://emiote.com/journal/mvp-means-minimum-viable-not-minimum-care/ - Date: 2026-08-06 - Category: Product - Reading Time: 6 min - Description: How we define MVP surfaces with founders so speed doesn't become an excuse for fragile foundations. **Definition:** An MVP is a minimal but trusted slice that lets a stranger complete one primary job on production infrastructure — so you can test retention, willingness to pay, and workflow fit. Minimum controls how much surface you ship; viable controls whether that surface earns trust. Founders often hear "Minimum Viable" as permission to ship fragile software. But **viable means trusted**. If the first interaction breaks confidence, your hypothesis never gets a fair test. When we shape an MVP with a founder, we cut surface aggressively — and raise the quality bar on what remains. --- ## What MVP is actually for An MVP is not a smaller version of the eventual roadmap. It is a **focused instrument** for answering a business question with real users on real infrastructure. Typical questions look like: - Will someone complete the core job without a sales call walking them through every screen? - Will they come back a second time without us nudging them daily? - Does the workflow match how they already work—or only how we wish they worked? If the product collapses under basic use, you did not learn that the idea failed. You learned that the test was invalid. That is expensive confusion dressed up as speed. --- import JournalDiagram from "../../components/journal/JournalDiagram.astro"; ## The MVP quality matrix <JournalDiagram variant="mvp-matrix" caption="We keep this matrix on the wall. Minimum = how much surface. Viable = whether that surface earns trust." /> | Minimal care (avoid) | Minimum viable (our approach) | | --- | --- | | Fragile database models | Typed, validated schema boundaries | | Missing empty and error states | Clear guidance for every user-visible state | | Huge feature list done poorly | One or two core flows done well | | Deferred “we’ll add auth later” | Real auth (or a deliberate, safe constraint) | | No observability | Basic telemetry and deploy health from day one | | Rewrite-on-arrival architecture | Boring structure that can grow without a total rebuild | Minimum is about **how much surface** you expose. Viable is about **whether that surface can be trusted**. --- ## Ruthless scope pruning <JournalDiagram variant="scope-funnel" caption="Four steps we run with founders before any code — write the cut list so a week-three 'quick add' doesn't become the product." /> Speed comes from cutting scope, not cutting craft. > Minimum care looks like missing error states, no path for failure, and an architecture that forces a total rewrite when your second customer arrives. That isn't speed—that's high-interest debt. A useful pruning conversation sounds like this: 1. **Name the primary user and the primary job.** One sentence. If you need three sentences, you have three products. 2. **List every feature request.** Move most of them to a deferred list without apology. 3. **For what remains, list states:** empty, loading, success, failure, permission denied. If a state has no design, the feature is not ready to ship. 4. **Define “done” as a user completing the job on production**, not as “the happy path works on my laptop.” ```typescript // A constrained MVP boundary written down—not implied in Slack export const mvpScopeCutList = { mustShip: [ "Core auth and onboarding flow", "Primary user job execution", "Stripe checkout integration", "Basic audit telemetry", ], deferredForV2: [ "Complex role-based permissions", "Custom theme overrides", "Multi-tenant custom subdomains", ], } as const; ``` Writing the cut list is not bureaucracy. It is how you stop a week-three “quick add” from quietly becoming the new product. --- ## A realistic cut: waitlist to paid pilot Suppose a founder wants a B2B tool for scheduling field visits. The full vision includes maps, offline mobile, custom roles, AI route optimization, and integrations with three CRMs. A minimum-care build tries to sketch all of that thinly. Users bounce; nobody knows which hypothesis failed. A minimum-viable cut might ship only: | Must ship | Why it earns a slot | | --- | --- | | Invite and sign-in | You cannot test retention without identity | | Create a job and assign a window | The core job | | Status updates the customer can trust | Without this, WhatsApp remains the real system | | Payment or contract step for the pilot | Answers willingness to pay, not only curiosity | | Error and empty states on those paths | Protects the test’s validity | Maps, offline, AI routing, and CRM sync wait. Not because they are unimportant—because they do not answer the first question yet. When the pilot proves the job, those features attach to a product people already trust. This is the same discipline we use across our builds: Ankik did not need every report on day one; it needed a ledger path people would use instead of the notebook. Retainix did not need every campaign type; it needed branch-safe earn and redeem that staff could explain at the counter. --- ## MVP checklist — before you call it ready We use this checklist before we call any slice an MVP. It answers the keyword behind this page — *MVP checklist* — quickly. | Check | Pass means | | --- | --- | | One primary job in one sentence | A stranger can name the job after one use | | MustShip vs deferred in writing | Day-14 scope has two owners and a date | | Five states designed for each MustShip path | Empty, loading, success, failure, denied — no gap | | Backups and restore story practiced once | You can answer “what if we lose this DB?” concretely | | Secrets out of the repo, CI on every change | Small suite is enough; “hope and FTP” is not | | Logging for “what happened for this user?” | Trace a single user’s journey without guessing | | Deploy path that is not manual | Staging and production are separate and repeatable | If one check fails, the slice is a demo, not an MVP. We review this live at day 14 in [how we ship in 28 days](/journal/how-we-ship-core-in-14-days-live-in-28/) and price the gap in our [cost breakdown](/journal/mvp-cost-breakdown/). For the template, use our [scope pruning guide](/journal/mvp-scope-pruning-must-ship-vs-deferred/). ## Foundations that are not optional “We’ll harden it after we get users” sounds rational until the first users are the ones who find the holes. A short list we treat as part of MVP, not as enterprise theater: - **Backups and a restore story you have practiced once** - **Secrets out of the repo** - **CI that runs on every change** (even a small suite) - **Logging enough to answer “what happened for this user?”** - **A deploy path that is not “hope and FTP”** These do not require a platform team. They require refusing to call a fragile demo an MVP. What we deliberately leave out of many MVPs: complex multi-tenant customization, deep analytics suites, elaborate design systems, and AI features that do not change completion of the core job. AI is a material, not a product—the product is still the job. --- ## How we run the conversation with founders Partner engagements go better when the quality bar is explicit before the sprint: 1. **Hypothesis in writing** — What will we know after four weeks that we do not know now? 2. **Scope contract** — Must-ship vs deferred, with names on both lists. 3. **Quality contract** — Which states and operational basics are non-negotiable. 4. **Weekly working software** — Progress measured in usable paths, not slide updates. 5. **End-of-MVP decision** — Kill, iterate, or expand—based on usage and learning, not sunk cost. If a founder only wants the feature list done “somehow,” we are a poor fit. If they want a fair test of the product idea, minimum viable with real care is the fastest honest path. --- ## Closing A well-architected MVP answers a critical business question with real users on production infrastructure. Everything else can wait. Minimum is a scalpel. Care is what keeps the patient alive long enough to learn. Shaping a first release — or repairing an MVP that was rushed into fragility? [Shape a Fair Test for Your Idea](/contact/) — or [see how we partner on product builds](/services/). For how product ownership shapes our standards, read [Products teach better than pitches](/journal/products-teach-better-than-pitches/). --- # Frequently Asked Questions (FAQ) ### What does Emiote do? Emiote is a product and engineering studio. We build in-house products (like Ankik desktop accounting) and partner with founders and companies to design, build, and launch software products, MVPs, AI integrations, and stack modernizations. ### Are you a software agency? No. Agencies sell billable hours and staff augmentation. Emiote is a product studio. We ship and maintain our own live software products, which forces high standards on architecture, code quality, and maintainability. When we work with clients, we work as product engineering partners with fixed-outcome scopes. ### What is Reframe? Reframe is our dedicated Software Stack Audit service. For a fixed fee of $199, we analyze your current tools, SaaS subscriptions, and custom code, then provide an actionable roadmap classifying everything into Keep, Configure, Replace, or Build. ### How much does a Build Sprint cost? Build Sprints start at $1,200 for a 14-day core MVP workflow and scale up to $3,500–$8,500 for a comprehensive 28-day full product build. ### Who founded Emiote? Emiote was founded by Dhanji Bhagat, Principal Engineer and Product Architect. ### How do we get started? Book a 15-minute scoping call at https://cal.com/dhanjib/15min or email dhanji@emiote.com.