Building in Public

Honest thoughts on building an enterprise AI agent platform. No marketing fluff.

Day 105: Memory, and Closing the Loops

The busy day Day 104 saw coming. Thirteen PRs land, and the headline answers yesterday's question with a worse truth than I feared: Pinchy agents couldn't write memory at all. One had hallucinated a memory write that never happened, and the watcher I shipped on Day 91 to audit memory changes turned out to be dead code — it watched the wrong path and had never fired in production. PR #448 opens a narrow, file-granular write path so an agent can rewrite its memory but never its identity, and fixes the watcher. Then #454 closes the Day 96 loop by making CI refuse a release whose package.json version doesn't match the tag. Around them: PWA install, a self-service support bundle, CSV/text workspace attachments, DOCX-to-Markdown, and an honest-error callback to the Day 93 composer saga.

Day 104: What Should an Agent Remember?

The last quiet day before a big one, spent on a question I've been treating as solved when it isn't: what should an agent remember, and who gets to see what it remembered? Day 91 shipped a watcher to audit memory changes, and I've been quietly assuming the whole memory story is in good shape. The more I poke at it, the less sure I am. Durable memory is what makes an agent feel like it knows you across sessions — and it's also a thing that silently shapes every future answer, can be written without anyone asking, and must never be allowed to rewrite the agent's identity. A reflection on the line between memory and identity, the day before that line gets tested.

Day 103: The Tour Guide Problem

A Sunday spent guiding a group of RubyConf attendees around Vienna, which turned out to be the most useful thing I could have done for thinking about agents. Giving a good walking tour is an exercise in curation: you decide what to show whom, you read the group, you leave things out, you adapt on the fly. That's exactly the discipline Pinchy tries to encode — show the right person the right thing, don't dump everything. But the part that made the tour work was the part an agent can't do: sensing when the group was tired, when a story was landing, when to drop the script entirely. A reflection on what guiding a city taught me about building a tool that works through people rather than instead of them.

Day 102: A Room Full of Ruby

A Saturday away from the keyboard, at RubyConf Austria, talking about Pinchy and AI with a few hundred people who don't already agree with me — which is exactly the point of going. A conference is where your pitch meets a thoughtful, craft-minded, healthily skeptical crowd, and you find out fast which parts of the story land and which parts you've been telling yourself. The boundary thesis and the self-hosting angle resonated; 'isn't this just a wrapper' and 'you're betting the whole thing on OpenClaw' were the hard questions I couldn't wave away. The most credible thing I said all day was that I run my own company's books through it.

Day 101: Three Bugs, One Symptom

The worst place for a bug is the first message after a fresh install — and that's exactly where one was hiding. Smithers answered the very first chat with 'No API key found for provider' on a brand-new setup. What started as a single secrets.json race fix turned into three distinct production bugs that all produced the identical symptom from different root causes: a secrets-provider boot race, an agent hot-reload race, and one more. The fix ships with a protocol-level smoke-test suite across five providers so this whole class of first-run failure gets caught before every release. A separate fix un-sticks the 'Restarting…' overlay when OpenClaw defers a restart behind active runs.

Day 100: The MCP Question

One hundred days in, a quiet Thursday to sit with the hardest open product question: MCP. There's a branch in review that would let Pinchy agents reach arbitrary MCP servers, and the breadth is obviously valuable — connect any tool, instantly. The problem is that breadth and boundaries pull in opposite directions, and boundaries are the entire reason Pinchy exists. An agent that can reach any MCP server is an agent whose permissions and audit trail just got an open-ended hole punched in them. A reflection on the tension between 'connect anything' and 'who can see what,' and why the answer can't be either extreme.

Day 99: The Stream That Survives a Reconnect

After two days of essays, a day of code aimed at one of the oldest production complaints: 'the agent didn't respond,' followed by duplicate retries. Issue #310 gets its architectural fix in three stacked PRs. Tier 1 is a defensive client patch for the drop-before-first-chunk window. Tier 2a adds a server-side run registry and a watchdog that tears down stuck runs and finally makes a run that finishes after the browser left auditable. Tier 2b is the headline: a browser that drops mid-stream and reconnects now rejoins the in-flight run as a listener and receives every remaining chunk — no orphan bubble, no spinner without a response.

Day 98: The Model Underneath Keeps Changing

Another quiet day, another foundation that won't hold still — this time the models themselves. Pinchy picks a model for you automatically, across four providers, and the set of right answers changes monthly: new releases, renamed variants, a shiny preview model that advertises a 1M context window and silently drops tool calls. Day 91 was five layers of defense against exactly this, and it'll erode the moment the next generation ships. A reflection on why 'just let the user pick' is a worse answer than it sounds, and what it actually takes to keep a good default good when the thing underneath it is a moving target.

Day 97: Building on Ground That Moves

A quiet Monday with nothing merged, spent thinking about the structural bet underneath everything: Pinchy is built on OpenClaw, and OpenClaw moves fast. In the last three weeks alone it went from 2026.5.7 to 2026.5.20, jumped the client protocol from v3 to v4, fixed a thought_signature bug on one provider path but not the one we hit, and shipped two defaults — silent tool-registration no-ops and a 4 AM session reset — that each turned into a Pinchy-shaped bug. The speed is the reason Pinchy exists at all and the reason half my week is reaction. This is an honest accounting of building on a dependency that won't hold still.

Day 96: The Version That Lied About Its Number

Two releases on a Sunday, an hour and fourteen minutes apart, and the second one exists only to fix the first. v0.5.5 ships at 10:49 with OpenClaw 2026.5.20 and its v4 protocol, the workbench/ subdir, multi-company Odoo hardening, the session-reset fix, and a tightened password-reset path. Then I notice the image reports its version as 0.5.4 — because I cut v0.5.5 with gh release create instead of pnpm release, which skipped the package.json version bump. v0.5.6 at 12:03 is a purely cosmetic patch to make the tag and the reported number agree again. Underneath it all, a universal chat.agent_error audit event lands as the measurement floor for future auto-retry work.

Day 95: The History That Vanished Overnight

One PR on a Saturday, and it fixes a bug that would have read as data loss to anyone who hit it: OpenClaw's default session reset rotates every session at 4 AM, so Pinchy's chat history with each agent appeared to vanish every morning. The transcript was never deleted — the session pointer just moved to a fresh empty one. It surfaced when a scheduled cron job fired into the post-reset session and showed only its own message as the entire visible history. The fix is one line of config: disable the daily reset so Pinchy sessions never auto-expire.

Day 94: Two Companies, One Chart of Accounts

A real production chat surfaced the bug: the Finance Controller agent got confused by a multi-company Odoo database where the same account — 1000 Wareneinsatz — exists in two GmbHs, and the plugin neither showed which company a record belonged to nor refused a cross-company write. Today's fix makes company a first-class part of every Odoo reference: odoo_read auto-includes company_id, refs carry a [CompanyName] suffix, and a write-time guard refuses creates and writes whose company tags disagree. Around it: a workbench/ subdir so fresh agents can write without a prior upload, the CRM template gains quotation-ready models, and two OpenClaw bumps land back to back.

Day 93: v0.5.4 and the Cursor That Jumped

v0.5.4 ships at 13:16 — six read-write Odoo operator templates, the schema split, the FK-lookup grants, and a batch of chat-reliability edges. But the release nearly didn't go out on time, because a regression turned the chat composer hostile: typing into the middle of a draft jumped the cursor to the end after every character. The first fix (PR #413) was a clean hypothesis that didn't survive a re-test on staging. The real fix (PR #414) was to delete the code that caused it — a bespoke onChange wrapper that turned out to be doing, badly, exactly what the upstream primitive already did well.

Day 92: Errors That Tell the Truth

A misleading error bubble gets replaced with an honest one: when Gemini 3 drops a thought_signature on a tool call, Pinchy now names the cause and tells the user that Retry usually clears it — instead of the old 'provider rejected the schema' copy that made people think their agent was broken. The same classifier emits a throttled audit event so 'how often does this happen?' becomes a SQL query. Around it: a build-once-run-many CI rebuild that stops every job from rebuilding the image, an Odoo fix that makes the id-vs-SKU trap impossible to miss, and the v0.5.4 release notes get finalised ahead of tomorrow's cut.

Day 91: The Default Gets Opinionated

Fifteen PRs land today, and unlike yesterday's single Odoo cluster they don't share a folder — they share a question: what does the agent run on, and what is it allowed to touch? The headline is the default model tier moving from fast to balanced — new agents now default to Sonnet / GPT-5.5 / Gemini-Pro instead of the cheap-fast tier, because agent workloads are not chatbot workloads. The same PR kills a gpt-4o-mini selection bug hiding in a date parser. By evening the agent finally gets a place to write: pinchy_write lands with an always-on read side, memory-file changes become an audit event, and two guardrails close off the broken-but-shiny model and the unreachable Ollama URL.

Day 90: A Monday on Odoo

Five PRs merge today — every one of them in the Odoo cluster. The headline is the schema split Day 89 set up: odoo_schema becomes odoo_list_models + odoo_describe_model with a compact type encoding that takes the per-model context burn from ~18 kB down to single-digit kB. A deprecated alias keeps pre-v0.5.4 agents alive while a data-migration rewrites every agent's allowed_tools list. By evening the self-ref chain lands: odoo_create now emits a _pinchy_ref on every record, so the Bookkeeper's create-invoice-then-attach-receipt flow stops being two disconnected tool calls. The MCP and Microsoft 365 branches that Day 89 talked about are still in review — both were pushed today, neither merged.

Day 89: Two Weeks of Production

No commits today, but two weeks of using Pinchy in production has produced enough notes for one. Running my own bookkeeping through it surfaced several Odoo edges that have since landed as fixes. The attachment work two weeks ago started here — uploading a PDF wasn't possible on Day 70-something, and the chain of commits to make it real is what Days 81 and 82 were. The next stretch of thinking — multi-integration agents, a task model, MCP — is where the questions are.

Day 88: The Saturday Drain

One commit lands at 06:14 — the cleanup tail of yesterday's dispatch-probe shakeout. The web E2E suite hadn't picked up the config.apply rate-limit drain that the odoo and email suites got yesterday, and was failing on the rare run that interleaved with the odoo suite's startup. Same fix, different file. After that, the day stays quiet.

Day 87: The Silent No-Op

A new plugin-tool-coverage test goes red for five Pinchy plugins. Behind the red: OpenClaw 5.3 silently no-ops registerTool() unless contracts.tools is declared in the plugin manifest, and the field was missing in five of the seven manifests. Nineteen tools had been registering successfully on the team's dev OpenClaw and silently failing on the production one. Three rounds of CI fixes follow as the dispatch probes hit a different shape of failure each time.

Day 86: The Attach-File Tool

odoo_attach_file lands — read-write Odoo operator agents can now attach uploaded files to Odoo records as ir.attachment, with permission-gated writes and the file lifted from the agent's workspace volume. The same PR fixes a vision-resolver bug where templates declaring vision capabilities were falling through to a text-only model. By afternoon, a code-review pass hardens the new tool against path traversal and OOMs with eleven tests pinning down the failure modes.

Day 85: Naming the Version

An end user upgrading Pinchy had no reliable way to confirm which version was actually running — /api/health returned only ok, /api/diagnostics was Domain-Lock-gated, and the OCI image-version label was empty. A new public /api/version endpoint plus populated OCI labels close the gap. Meanwhile, a staging click-through for v0.5.4 reveals that 14 of 22 Odoo templates declare required models that odoo-sync never probes — the operator templates were quietly disabled despite the modules being present. A drift-guard test pins the failure mode down.

Day 84: Rebuilding the Snapshot Chain

Drizzle migrations 0025–0030 got tangled during a rebase — the snapshot chain that each migration carries as its predecessor was no longer consistent. The fix rebuilds the chain by walking the migrations in their committed order and regenerating each snapshot from the previous one. A new contract test guards the chain integrity and prefix collisions; a runbook captures the recovery procedure for the next time.

Day 83: v0.5.3 and the Per-Agent Runtime

v0.5.3 ships, and the headline is the one #199 has been pointing at since the chat first started using WebSockets: switching between agents in the sidebar no longer tears down the runtime that's mid-stream. A new ChatSessionProvider mounts one runtime per agent at the (app) layout level, the sidebar shows a pulse on agents with an active turn and a red dot on agents that errored, and a chat.background_run_completed audit event makes background activity auditable without leaking content.

Day 82: Attachments That Open

The composer's attachment chip becomes a real preview surface — click a PDF, an in-app modal renders it with the actual document on screen rather than a forced download. The uploads route picks up authentication for GET (it had been open) and a deliberate X-Frame-Options override for the route alone, so the modal can embed the document without weakening the rest of the app. Plus: an Agent Workspaces concept page that ties the architecture together.

Day 81: Saturday on Three Fronts

Three threads that have been queued for a while land together. Images compress client-side to WebP before crossing the wire and the WS frame limit goes from 1 MB to 25 MB to match. An Ollama Cloud model that started returning silent HTTP 500s gets dropped from the allowlist, with the chat learning to render the error as a structured switch-model bubble instead of a raw status code. And the #199 Layer A test finally proves the cache-retry behaviour Layer B fixed yesterday.

Day 80: v0.5.2 and the Drain That Doesn't Stop

v0.5.2 ships, rolling up the security fix and Ollama-local work from the last two days alongside today's new headline: client-router keeps draining the OpenClaw stream after the browser disconnects. Without it, an assistant message that finished generating while the user navigated away never made it into the cache, so the next page load looked like a half-finished reply that had quietly succeeded somewhere off-screen.

Day 79: Personal Means Personal

A security fix lands quietly in assertAgentAccess: an admin used to be able to GET/PATCH/DELETE another user's personal agent by calling the API directly, even though the UI didn't expose them. The admin fast-path now checks isPersonal before granting access. The fix sits inside a much larger E2E pass that's verifying — across groups, invites, audit log, permissions, knowledge base — that what the UI shows and what the API enforces actually agree.

Day 78: v0.5.1 and the Host Rewrite

v0.5.1 ships as a hotfix for a v0.5.0 startup loop — the generated openclaw.json was missing a baseUrl field for the bundled Anthropic/OpenAI/Google providers, and OpenClaw refused to come up. The same release fixes the long-standing Ollama-local setup, which never worked on a default install because host.docker.internal doesn't resolve inside the OpenClaw container. The fix is a host-gateway alias and a hostname rewrite that runs invisibly at config-write time.

Day 77: The Day After

v0.5.0 has been out for less than 24 hours and the inbox already has the kind of feedback that's the most useful kind: the docs were almost right. BETTER_AUTH_URL was documented but not actually passed through to the container, the domain-lock middleware was rejecting internal callbacks, and the post-release docs got a polish pass. Also: a 234-line AGENTS.md gets carved out of CLAUDE.md so a different coding assistant has its own contract.

Day 76: v0.5.0 Goes Out

v0.5.0 ships after a morning of CI failures get hammered out one bracket at a time. Underneath the release tag: a plugin-manifest contract that every Pinchy plugin must now satisfy at build time, HTTP mocks for Gmail and Brave so the external plugins are exercised in E2E, and a ~50-second cold-start improvement from pre-warming runtime deps and disabling the plugins nobody asked for.

Day 75: The Bonjour Watchdog and Other Ghosts

OpenClaw runtime bumps from 2026.4.14 to 2026.4.27, in two hops. The big news in 4.27: a per-agent auth-profiles.json that scopes credentials per agent. The smaller news: a Bonjour watchdog that was sending SIGTERM to the container in environments where mDNS announcement is blocked. Plus: an idempotency contract test for cold-start regenerate, and the CLAUDE.md docs get a careful re-read.

Day 74: The Saturday Hardening Pass

CSRF gate on every state-changing API route. Password policy moves to 12 chars plus a breach-list check. Audit emissions go from fire-and-forget to a single await-or-defer pattern. Two large files (1097 and 1395 lines) get split into focused modules. SSRF guard closes a DNS-rebinding TOCTOU. RBAC filter lands on the telegram-bots endpoint. The kind of list that gets handed to procurement before any demo.

Day 73: A Chat That Stops Claiming Green

The chat-status indicator had been defaulting to connected during cold-start — a small lie that made every fresh session look broken. Two PRs land that fix the lie at both ends, plus a Starting Agent state that holds until the first message is actually on screen. In parallel: audit PDF export with an integrity-hash CSV column, the audit refactor that backs it, and the agent-create cascade fix gets the matching test.

Day 72: Agent Create Without the Cascade

Creating a new agent had been quietly triggering a full gateway restart cascade — every plugin reloaded, every connection paused for several seconds. The fix swaps the inotify-driven config reload for a WebSocket RPC push, with a fire-and-forget retry that never blocks on the gateway's own boot. Plus: an inotify watcher restores secrets ownership in milliseconds, telegram silent EACCES swallows are plugged, and CI starts running against the production image.

Day 71: The 0600 Dance

The secrets-ownership bug surfaces in integration: secrets.json gets the right mode but the wrong owner, OpenClaw refuses to read it, the gateway boots without a token. The fix is a chown + chmod dance every gateway boot. Plus: staging Caddyfile drops the timeout that was eating cold-start requests, the composer stops greying out during reconnects, and the v0.5.0 upgrade notes consolidate.

Day 70: When the Licence Has Teeth

The seat cap stops being a label and starts being enforcement: invite endpoint blocks at the maxUsers count, banner warns ahead of it, audit log records the block. The chat UI grows real delivery states — sending/sent/failed — with a retry path that knows the difference between a dropped message and a half-streamed reply. openclaw-node 0.7.0 ships.

Day 69: Switching Off the Lambda

The AWS Lambda that issued every trial key for the last two months gets a one-shot decommission workflow and disappears. The Odoo addon learns to look like part of Odoo — Pinchy logo on the menu, fields freeze after activation, the trial partner is a company. Plus: Squawk lints destructive migrations on every PR and the upgrade notes get a policy.

Day 68: When the Form Actually Submits

Sunday. Two commits on the website, both about getting Saturday's Odoo trial endpoint to work from a real browser instead of from a curl command. The first teaches CI to forward the shared-secret env var into the Astro build. The second swaps a custom auth header for Authorization: Bearer because Odoo's default CORS handling allows one and not the other.

Day 67: The Trial Comes Home

Saturday. The trial endpoint leaves AWS for a custom Odoo addon, built end-to-end in one TDD pass — licence model, trial throttle, mail template, admin UI, CI. Plus: SecretRef follow-ups, Squawk-CLI for destructive-migration linting, and a release-notes template that refuses to merge without Breaking changes and Upgrade notes as separate subsections.

Day 66: Streams That Announce Themselves

openclaw-node 0.6.0 ships — agent_start and agent_end lifecycle chunks bracket every turn, lifecycle errors surface as real error chunks, duplicate errors get deduped between paths. Plus: v0.4.5 release notes consolidate the week, and the integration-delete flow gets one more round of polish.

Day 65: Secrets Out of the Config

The big one. Every secret that used to live in plaintext in openclaw.json — gateway tokens, Telegram bot tokens, Brave and Ollama API keys, Odoo passwords — moves to a tmpfs-backed secrets.json referenced by opaque SecretRef markers. Delivery status and retry ship in the same push, along with a safer integration-delete flow.

Day 64: The Open Web, Closed Carefully

Web Search merges — Pinchy's first integration past Odoo. Brave Search under the hood, a per-agent domain list with an Include/Exclude toggle, SSRF guards that validate every redirect hop, and a plugin-config refactor that pays for itself the moment a second plugin needs config.

Day 63: Billing Where We Already Live

A quiet day on main — one commit on a branch, the last review round before Web Search merges. The interesting work today was off the keyboard: the first companies asking about a production deployment, and the decision to run Pinchy's subscriptions through the same Odoo instance Pinchy already integrates with.

Day 62: Gmail Without the Dev Console

Gmail ships. The first Pinchy integration whose setup story includes a trip through the Google Cloud Console — folded into a wizard that hands over the redirect URI, stores credentials once per workspace, and treats abandoned OAuth flows as a visible pending state instead of limbo.

Day 61: Docs That Know Who's Asking

Two branches, both moving. The pinchy-docs plugin learning to scope documentation to the agent that's asking; the password reset page finally existing, instead of routing resets through an invite form pretending to be one.

Day 60: One Guide Instead of Two

Saturday. One commit on main. Two docs pages that had been saying almost the same thing about HTTPS setup — nearly the same is the dangerous part. The fix is not adding content; it's picking which page owns the flow and making the in-app link point there.

Day 59: Three Releases Before Lunch

Three point releases in ten hours, each closing a real report from the first day v0.4.0 spent in the wild — a Docker port bypassing UFW, a Caddyfile dpkg refused to install, a validator that trusted a public endpoint, and one unreadable row that hid every integration.

Day 58: v0.4.0 Is Out

Release day. Three last-hours fixes to Ollama Cloud support — tokens tracking, vision flags, and model IDs that actually match the API. The kind of thing you only find by running the product yourself.

Day 57: A UI That Stops Lying

Two clean-ups before shipping v0.4.0: the agent permission screen was offering toggles that didn't do anything, and Smithers had been repeating the docs back at itself instead of reading them. Both cut.

Day 56: When the Other Side Disappears

What happens when the model backend vanishes mid-stream — and how the user finds out. Disconnect errors, timeout errors, and heartbeats that stop lying about progress.

Day 55: Shared Memory, Different Boundaries

Three conversations in one day, all circling the same problem: companies want agents that can access shared knowledge — but only with the right boundaries, roles, and permissions in place.

Day 54: Making the Dashboard Honest

A usage dashboard is only useful if the numbers are trustworthy. Today was about timezones, cache tokens, missing days, retry states, and the details that make cost visibility reliable.

Day 53: Three Tracks Toward v0.4.0

Usage tracking, Telegram guardrails, and a growing library of Odoo templates — three parallel workstreams pointing in the same direction: making Pinchy operational for real teams.

Day 52: Stabilizing the Edges

The day after a feature lands is when the real product work starts: fixing merge fallout, tightening error handling, improving validation UX, and making edge cases fail clearly.

Day 51: Complexity and Regulation

Day two of the workshop. And the EU Cloud Act turns out to be a tailwind for everything Pinchy is already designed to be.

Day 50: Audit Outcome

The audit trail now shows success or failure. Pre-built images ship to GHCR. And a two-day workshop on automating complex workforce scheduling.

Day 49: Audit Trail v2

A new audit log format that records outcomes — not just what happened, but whether it worked. Plus Smithers reads the docs on demand.

Day 48: Qwen by Default

A small change to default model selection that makes local Ollama dramatically more reliable. Plus a WebSocket fix nobody asked for but everybody needed.

Day 47: The Merge Day

The insecure mode banner officially merges. Ollama gets tool-calling enforcement. And a deep dive into why dependencies are a constant maintenance tax.

Day 46: Pull, Not Build

Pinchy now ships pre-built Docker images instead of building them on every deploy. First-time setup goes from 15 minutes to under a minute.

Day 45: Polish Day

Easter weekend, low-energy work, but the small UX details that make the difference between a developer toy and a real product.

Day 44: Two Tracks

Odoo agent templates that configure themselves, and local Ollama support that discovers models automatically. 45 commits, one very productive day.

Day 43: Grok Sent Him

Someone found Pinchy because Grok recommended it. The Odoo config went from 867KB to 3KB. And who is Pinchy actually for?

Day 42: The Merge

Telegram is merged. The multi-user test found bugs, I fixed them, and the biggest feature branch in Pinchy's history landed on main.

Day 41: Telegram Is Done

The Telegram integration that almost derailed everything is finally finished. Plus two meetings that confirmed the direction is right.

Day 40: The Email Question

Every company I've talked to wants the same thing: an agent that reads their email. Here's what that actually means to build.

Day 39: The Mock Server Trick

How a fake Telegram server made the real integration better, and why the feedback loop matters more than it sounds.

Day 38: v0.3.0

The deployment release ships, Telegram goes multi-bot, a recruitment company wants to automate their entire workflow, and the product roadmap writes itself.

Day 37: Three Calls, Three Countries

An Austrian manufacturer wants AI-generated quotes. An Irish fleet company wants to scale NanoClaw. Same core needs, different industries.

Day 36: Deployment Hardening

Fixing everything that breaks when Pinchy leaves localhost — cookies, HTTPS, OpenClaw restarts, Telegram stability, and the gap between demo and production.

Day 35: The First Real Deploy

A pilot user tried to deploy Pinchy on Hetzner. It didn't go smoothly. So I built the deployment docs, a loading page, and fixed every issue he hit — in one day.

Day 34: The Scaling Question

Telegram integration, security hardening, dynamic model selection — and the uncomfortable realization that demand is outpacing what one person can build.

Day 33: Show Me the Tokens

A full usage dashboard with cost tracking, a screenshot CI pipeline that fought back hard, and a WebSocket fix that should have been obvious.

Day 32: The PDF That Needed Eyes

Building a PDF reader that actually works — from text extraction to vision fallback, plus five feature pages, an automated screenshot pipeline, and a security fix.

What Jensen Huang's OpenClaw Strategy Means for Pinchy

Nvidia's NemoClaw validates the enterprise OpenClaw market. Here's how infrastructure and application layers are complementary, not competitive.

Day 31: Three Talks in Ten Days

v0.2.0 shipped, a freelancer meetup talk, star challenge round 2, and Jensen Huang just validated our entire market.

Day 30: The Last Mile

21 commits of polish, dependency upgrades, tab flicker fixes, and eating our own dog food with two new Pinchy agents.

Day 29: 100 Stars and Three Handshakes

Two major PRs merged, a sold-out meetup talk, three companies wanting to integrate Pinchy, and crossing 100 GitHub stars.

Day 28: Secrets and Stages

Building defense-in-depth for audit logs, and getting ready to tell the Pinchy story to a sold-out meetup.

Day 27: Release Prep

Testing for v0.2.0, a look at everything shipping in the next release, and why openclaw-node deserves more attention.

Day 26: Three Branches, One Saturday

Enterprise key system, Telegram integration, and provider config migration. Three feature branches running in parallel on a Saturday.

Day 25: Messaging, Not Workflows

Telegram integration design, the first external feature request, 5 community PRs, and a clarity moment: Pinchy is a messaging tool.

Day 24: Tokens Are Money

RBAC is merged, a real company wants to pilot Pinchy, and I'm learning that token cost is the concern nobody talks about publicly.

Day 23: The Bug-Free Demo

First demo without a single bug. A cybersecurity startup grills Pinchy on security. And the confidence is building.

Day 22: The Perfect Setup

Peter Steinberger says nobody's building enterprise OpenClaw tooling. 30 seconds later, I'm on stage showing Pinchy. Plus: RBAC edge cases and why manual testing still matters.

Day 21: The Calls That Shaped the Roadmap

Multiple demo calls, an enterprise from Dubai, a potential partnership, and the first enterprise feature: RBAC. Plus: a lightning talk at tomorrow's 280-person meetup.

Day 20: v0.1.0

542 commits. 33 PRs. 20 days. Pinchy has its first official release.

Day 19: Release Ready

24 commits, 5 PRs, zero new features. Just making Docker startup actually work. The unglamorous work that makes a v1 possible.

Day 18: First Users, First Lessons

A no-show demo, the founder impatience problem, and 14 commits making Pinchy actually work for the people who cloned it.

Day 17: The Merge

Coded in the dentist's waiting room. Claude kept going during the cleaning. Then PR #21 landed: Better Auth replaces Auth.js. 11 commits, and the kind of work that makes everything else possible.

Day 16: Auth, Mobile, and Real Users

43 commits: migrated from Auth.js to Better Auth, built mobile navigation, added in-app bug reporting, and had a call that changed how I think about Pinchy's future.

Day 15: The Fix-Everything Day

84 commits, 5 PRs merged, 112 files changed. Every bug from yesterday's demo, plus a complete audit log overhaul, soft-delete, and settings polish.

Day 14: The Demo That Broke Everything

A live demo, an Anthropic outage, and the most productive bug-finding session in weeks.

Day 13: The Thinking Day

Zero commits. No code. Just thinking about RBAC, knowledge base indexing, and what Pinchy needs next.

Day 12: The Audit Trail Closes

PR #3 merged. Every tool call now leaves a trace. Plus: a marketing experiment that backfired.

Day 11: The Ecosystem Day

Two npm releases, audit trail upgrades, and three calls with people who want to build with us.

Day 10: Context Belongs to People, Not Agents

A data model that felt right at 2 agents broke at 5. Why USER.md moved from agent settings to general settings.

Day 9: Making It Feel Right

31 commits. 128 files. The first PR merge, fun-emoji avatars, and why polish isn't optional.

Day 8: Give Your Agent a Face

11 commits. 72 files. Personality presets, DiceBear avatars, taglines, and the Settings UI that ties it all together.

Day 7: Agents Are People Too

16 commits. A product philosophy, a lobster in a bowtie, and a complete session architecture rewrite.

Day 6: The Personality Layer

26 commits. 5,000 lines. Agent greetings, memory privacy, SBOM pipelines, and the question: what makes an AI agent feel like yours?

Day 5: The Enterprise Gauntlet

77 commits. 15,000 lines of code. Security hardening, audit trails, compliance docs, and a conversation in a gym that changed everything.

Read more →

Day 4: From Solo to Team

63 commits. 12,000 lines of code. Multi-user support, invite system, personal agents, custom plugins, E2E tests, and eating our own dog food.

Read more →

Day 3: Encryption, Onboarding, and a Trojan Horse

30 commits, 7,600 lines of code. Encrypted API key storage, a full provider setup flow, Docker dev mode, a documentation site — and we shipped the first Node.js client for OpenClaw.

Read more →

Day 2: From Zero to Chat in One Day

Yesterday we had a website. Today we have a working app — login, setup wizard, chat UI, WebSocket bridge to OpenClaw, and Docker Compose. 29 commits, ~2,000 lines of code.

Read more →

Building Pinchy in Public: Why We're Open-Sourcing an Enterprise AI Agent Platform

It started with an AI agent leaking internal reasoning to a friend via WhatsApp. Now imagine that happening at a company. That's the problem Pinchy solves.

Read more →