OIXA Protocol: The Open Infrastructure for Agent-to-Agent Commerce

The Problem Nobody Is Solving

There are over 1 million autonomous AI agents active today. Each one has cognitive capacity that — while its owner sleeps, works, or has not assigned a task — sits idle. Wasted. Generating cost without generating value.

At the same time, other agents are executing complex tasks and need additional capacity. They need specialized analysis. They need to subcontract reasoning. They need access to agents with specific context they do not have.

Today, when an agent needs another agent, it has two options: struggle alone, or stop and wait for a human.

Both options are inefficient. Both limit what the agent economy can achieve.

That is the problem. OIXA is the infrastructure that solves it.

How OIXA Works

1. Registry (ERC-8004)

Agents publish an Agent Card: capabilities, models, price, and current availability. Updated in real-time. Other agents can query the registry to find exactly the capacity they need.

2. Reverse Auction

A buying agent posts an RFI (Request for Intelligence): the exact prompt, required model, max budget. OIXA notifies compatible agents. A reverse auction opens — sellers compete downward. The market discovers the real price.

Auction timing is dynamic:

  • $0.001–$0.10 → 1–2 seconds
  • $0.10–$10 → 3–5 seconds
  • $10–$1,000 → 10–30 seconds

3. Stake System (Anti-Sybil)

Every bidder deposits 20% of their bid as stake. No stake, no bid. This makes flooding the market with fake identities economically impossible.

4. Automatic Verification

OIXA verifies the output cryptographically: right model, delivery time met, coherent result. If it passes → escrow releases in USDC automatically.

5. Public Ledger

Every transaction is recorded immutably. Behavior is public. Content is private. Reputation is built on real data.

The Stack

LOGIC    → Off-chain (fast, efficient)
FUNDS    → On-chain via Base + USDC (trustless)
REGISTRY → On-chain via ERC-8004 (permanent)
PAYMENT  → x402 Protocol (autonomous)
COMMS    → A2A + MCP (standard)

Why This Is Different

Others OIXA
What is sold Raw GPU compute Verified cognitive outputs
Who hires Humans hire agents Agents hire agents
Pricing Fixed Real-time reverse auctions
Trust layer None Stake-based economic guarantees
Architecture Centralized Open protocol

The A2A Economy Is Already Happening

Agent-to-agent commerce is not a future concept. It is happening today — informally, unreliably, without economic guarantees. Agents call other agents via APIs. They chain tasks. They subcontract.

OIXA makes this trustless. Autonomous. Paid.

Like HTTP defined how computers communicate on the internet, OIXA defines how agents discover, hire, verify, and pay each other. Anyone can build on it. No permission required.

Where We Are

Phase 0 — Foundation: whitepaper published, protocol server running, GitHub live, community growing.

Phase 1 (next): first 100 agents connected, first real transactions on Base mainnet.

GitHub: https://github.com/ivoshemi-sys/oixa-protocol
Community: https://t.me/oixaprotocol_ai
Whitepaper: https://github.com/ivoshemi-sys/oixa-protocol/blob/main/WHITEPAPER.md

The agent economy needs infrastructure. We are building it.

Give Your AI Full Access to Your Obsidian Vault — 35 MCP Tools

Your Obsidian vault is your second brain. Years of notes, project plans, daily journals, meeting records, research — all connected with wikilinks and tags in a carefully organized folder of Markdown files.

But your AI can’t see any of it. You copy-paste snippets into ChatGPT. You describe your note structure to Claude. You manually relay information between your knowledge base and your AI.

That ends now. MCPBundles provides an Obsidian MCP bundle — 35 tools that give your AI full read/write access to your vault through the Model Context Protocol. It’s a standard MCP server — the tools show up natively in whatever AI you already use. Claude Desktop, ChatGPT, Cursor, Windsurf, the mcpbundles CLI, or any MCP-compatible client.

35 tools. Your AI becomes an Obsidian power user.

The Obsidian MCP bundle gives your AI the same access to your vault that you have — and then some. It reads notes and gets back structured data — parsed frontmatter, tags, file stats — not just raw text. It browses your folder hierarchy. It searches across every note in your vault with relevance scoring, regex patterns, frontmatter queries, and date ranges.

It writes. Not just “dump a whole file” writing. Your AI can create notes with full frontmatter, append entries to existing notes, and — this is the part that matters — surgically edit specific sections of a document without touching anything else.

It sees your images. It analyzes your graph structure. It finds orphaned notes and broken links. It lists every task across your entire vault.

Surgical edits change everything

Most integrations that touch files do the same thing: read the whole file, modify it in memory, overwrite the whole file. Fine for code. Terrible for a living document with dozens of sections, tasks, and metadata fields that you don’t want an AI to accidentally mangle.

The Obsidian PATCH operation works differently. Your AI targets a specific heading, block reference, or frontmatter field and inserts, replaces, or appends content just there.

Say you’ve got a project plan with milestones, discussion notes, and action items. You tell your AI to add two items to the milestones section. It reads the document map (a lightweight call that returns all headings, block refs, and frontmatter fields), finds the right heading, and appends only to that section. Your discussion notes and action items stay exactly as they were.

The same precision works for frontmatter. Your AI can flip status: draft to status: shipped on a single field without rewriting the YAML block. It can add a new reviewer: Tony field that didn’t exist before. It can target nested heading paths like "Launch Plan::Key Milestones" to reach the right section in a deeply structured document.

This is the difference between an AI that can edit text files and an AI that understands Obsidian’s document structure.

Daily notes are the fast path

The most common Obsidian workflow is appending to today’s daily note. A quick thought, a task, a meeting summary — you open today’s note and add a line.

Your AI does the same thing in one call. No need to figure out today’s date, construct the filename, check if the file exists. Just “append this to my daily note.” It handles the rest, including creating the note if it doesn’t exist yet.

This turns your AI into a persistent journal. Every conversation can leave a trace in your vault. Meeting summaries go into the daily note. Research findings get filed in project notes. Action items land where they belong.

Your AI can see your images

When your AI reads an image from your vault, it doesn’t get a file path or a base64 blob dumped into a text response. It gets the actual image as an MCP ImageContent block — the same way a screenshot tool returns visual content.

That means any AI model with vision — Claude, GPT-4o, Gemini — actually sees the image. Your AI can describe a diagram, read handwritten notes from a photo, interpret a screenshot, or analyze a chart. All from files already sitting in your vault.

PNG, JPEG, GIF, WebP, BMP, and SVG are all supported. The image flows through the same proxy tunnel as everything else — nothing gets stored on MCPBundles servers.

Graph analysis and vault maintenance

Obsidian’s power comes from connections between notes. Wikilinks turn a folder of Markdown files into a knowledge graph. But maintaining that graph — finding orphans, fixing broken links, understanding relationships — is manual work.

Your AI traverses your link graph. Graph neighbors does a breadth-first search from any note, finding every connected note within a configurable depth. Direction matters: outgoing links, incoming backlinks, or both.

Orphan detection scans every note in your vault and identifies the ones with zero incoming wikilinks — notes that nothing else links to. These are the ones you forgot about, the stubs you never connected, the ideas that fell through the cracks.

Broken link detection scans every wikilink in every note and checks whether the target actually exists. That reference to [[Old Project Name]] you renamed three months ago? Found.

Task management across your entire vault

Obsidian is great for tasks — the checkbox syntax (- [ ] do the thing) works in any note. But there’s no built-in way to see tasks across your entire vault. Your AI can.

The task listing tool scans every note, extracts every checkbox, and returns them with their source file and line number. Filter by status (open, completed, all), by folder, by tag, or by keyword. Ask your AI “what are my open tasks tagged with Q2?” and get an answer without installing any plugins.

How the proxy tunnel works

Obsidian runs on your desktop. AI services run in the cloud. The MCPBundles desktop proxy bridges them with an encrypted tunnel.

AI → MCPBundles → Proxy Tunnel → Your Desktop → Obsidian (localhost:27124)

Your vault data flows through the tunnel in real time. Nothing gets stored on MCPBundles servers. The proxy handles Obsidian’s self-signed TLS certificate automatically.

Works with the AI you already use

MCPBundles is a remote MCP server. You connect it once and the Obsidian tools appear in your AI’s tool list — alongside any other bundles you’ve enabled.

Claude Desktop, ChatGPT, Cursor, Windsurf — add the MCPBundles MCP server URL and the tools are there.

mcpbundles CLI — for terminal workflows, scripting, and automation. pip install mcpbundles and you’re set.

Any MCP-compatible client — if it speaks MCP, it works. The tools are standard MCP tools with proper schemas, annotations, and content types.

Five minutes to set up

1. Install the Obsidian plugin

Install the Local REST API community plugin in Obsidian (by Adam Coddington). Enable it and copy the API key from the plugin settings.

2. Start the proxy

pip install mcpbundles
mcpbundles login
mcpbundles proxy start

3. Enable the bundle

Go to MCPBundles, enable the Obsidian bundle, and paste your API key. The 35 tools are now available to every AI client connected to your MCPBundles server.

What this looks like in practice

You’re prepping for a team meeting. You tell your AI: “Create meeting notes for the Q2 planning sync with attendees Tony and Sarah, agenda: hiring, roadmap, budget.” A fully structured note appears in your vault with frontmatter, sections, and wikilinks to related project notes.

After the meeting, you tell your AI to append the action items. It doesn’t overwrite your agenda — it surgically appends to the action items section.

Later, you ask your AI to search your vault for everything related to “database migration.” It finds four notes across different projects, reads them, and creates a consolidated summary note linking back to the originals.

You photographed a whiteboard and dropped the image into your vault. Your AI sees the photo, reads the sticky notes, and creates structured tasks in a new project note.

Your vault has grown to 500 notes. You ask your AI to run a health check. It finds 23 orphaned notes, 7 broken wikilinks, and 45 open tasks scattered across 12 files. It creates a maintenance summary with links to every issue.

None of this requires you to leave your AI chat.

Get started

pip install mcpbundles
mcpbundles login
mcpbundles proxy start

Enable the Obsidian bundle, add your API key, and start talking to your vault.

MCPBundles is a hosted platform for connecting AI agents to real third-party services via the Model Context Protocol. 60+ bundles, 1900+ tools — Stripe, HubSpot, Postgres, Gmail, Obsidian, and more. Get started free.

What Breeders Actually Need From Software (And What Developers Assume They Need)

It’s 11pm. A breeder has three browser tabs open, a Google Sheet with color-coded columns, and a notebook sitting next to the keyboard with handwritten pairing notes from two seasons ago. They’re trying to figure out whether a planned breeding will push the coefficient of inbreeding above a threshold they’ve set for their program. Nothing on their screen talks to anything else. They’ve been doing this for years.

Not because they haven’t looked for better options. They have. They’ve tried CRMs, inventory apps, animal management platforms, and general-purpose databases. Every tool either bends the problem into something it wasn’t, or buries the actual work under features built for a different kind of business entirely.

This is the starting point for almost every serious breeder I’ve talked to. And it’s the starting point for understanding why software built for breeders keeps failing them.

What Developers Assume Breeders Need

The reasonable guesses aren’t wrong. They’re just incomplete.

A developer approaching the breeder space for the first time would probably reach for a familiar toolkit. A CRM to track customers and waitlists. A database or spreadsheet for animal records. A calendar for scheduling. A storefront for selling. Maybe a notes field or two.

These tools exist. Some of them are excellent at what they do. Breeders have tried them. The failure point is always the same: these tools treat breeding like inventory management. Animals become product records. Bloodlines become tags. The actual craft, the decision-making, the verification, the longitudinal tracking that spans years and generations, falls completely through the cracks.

The gap isn’t a missing feature. It’s a missing frame of reference.

What Breeders Actually Need

1. Lineage integrity, not just lineage storage

A field in a database that says “Sire: Rocky” is not lineage. It’s a note.

Real lineage is verified, multi-generational, and tamper-resistant. It is the foundation of the animal’s value. When a buyer pays a premium for a dog, a gecko, or any production animal, they are buying the bloodline as much as the animal itself. An unverifiable or inconsistently documented pedigree doesn’t just weaken a sale. It erodes trust in the entire breeding program.

This is why registries exist. The AKC has been solving this problem for 140 years. ABKC built it from scratch for a new breed. The model works: verified registration, traceable multi-generation pedigrees, records that transfer with the animal. What breeders need from software is a version of that infrastructure that works at the program level, not just at the registry level.

Storing a sire and dam field is not lineage. Lineage is structural. This is the core problem that ReptiDex solves with multi-generation pedigree trees and cross-collection lineage linking, and it’s the foundation of the registry and pedigree platforms I build for breed clubs.

2. Pairing logic, not just pairing records

Breeders don’t just need to log who was bred to whom. They need to understand what a pairing means before it happens.

Coefficient of inbreeding (COI) calculations. Trait probability distributions. Genetic incompatibility flags. Restrictions on first-generation linebreeding, which organizations like the Gold Standard Gecko Club have built into their competition rules precisely because it matters. A form with a sire field and a dam field captures none of this.

The pairing decision is where the breeding program lives or dies. The software either helps you make it well or it doesn’t help you at all. Most software doesn’t help at all. The breeding records and genetics apps I build for breeders start here, with trait probability, COI awareness, and genetic compatibility checks built into the pairing workflow.

3. Clutch and litter tracking built for biology, not inventory

A litter is not a batch. A clutch is not a shipment.

Offspring need to be tracked individually, from first record to final placement, with their own records linking directly back to parents. Weights at hatch or birth. Dates. Morphs or phenotypes. Retained animals. Placed animals. Animals lost. Each one is a data point in the lineage tree. Each one has downstream consequences for the program.

Generic inventory tools treat offspring as a transaction. You record the sale, close the ticket, move on. But a breeder may be tracking animals they placed five years ago because the buyer wants to breed back into the line, or because they’re building a multi-generation study, or because that animal’s offspring just showed up at a show and they want the record.

The biology doesn’t end at the sale. The software has to reflect that.

4. Show and competition history that travels with the animal

A dog’s show record is part of its value. So is a gecko’s placement history. Judges, events, placements, titles, pointed wins, majors. That history needs to live on the animal’s profile, not in a separate spreadsheet, not in someone’s email archive.

When a buyer is evaluating a stud or a broodmother, they want to see the full picture. When a registry is verifying eligibility for competition, they need documented proof. When a breeder is making pairing decisions, the show record of both animals is relevant information.

No CRM is designed to think about an individual animal as a long-term record of achievement. That’s not a CRM problem. CRMs are built for people, not animals. The category mismatch is total.

5. Waitlist management that respects how breeders actually sell

Breeder waitlists are not e-commerce carts. Shopify cannot model them. A checkout flow cannot capture them.

A waitlist for a specific pairing might start before the animals are even bred. There are deposits, which may or may not be refundable depending on outcome. There are first-right-of-refusal arrangements. There are cohort assignments, where buyers pick pick order rather than picking specific animals. There are communication threads tied to a specific pairing that need to stay connected to the records, not float off into a general inbox.

And when the clutch or litter doesn’t go as planned, because sometimes it doesn’t, all of that needs to be renegotiated, documented, and communicated. A shopping cart abandonment workflow is not going to help you here. This is exactly why I built Geckistry as a custom sales platform from scratch rather than forcing my gecko business onto Shopify.

Why the Gap Exists

This is not a problem of bad developers. It is a structural problem.

You cannot spec out what you have never lived. A developer who has never sat with a stud book, never calculated a COI, never navigated a waitlist dispute when a litter came out smaller than projected, does not know what questions to ask. They build what makes sense from the outside. It looks reasonable. It fails in practice, quietly, in ways that don’t always surface in a demo or a trial period.

The domain knowledge is not a bonus. It is the product.

This pattern shows up in every industry where the work is specialized. Healthcare software built without clinical input produces tools that technically meet requirements and fail at the bedside. Legal technology built without practicing attorneys builds workflows that don’t map to how cases actually move. The breeder space is no different. The gap between what software promises and what breeders actually need is almost always a gap in domain understanding, not engineering capability. That gap is the entire reason Built By Dusty exists.

What Staying on Spreadsheets Actually Costs

The spreadsheet and notebook system works until it doesn’t. Most breeders don’t feel the cost of it until something breaks.

Hours per week on manual data entry that should be automatic. Lineage errors that surface years later and are nearly impossible to trace. Pairing decisions made without full genetic context because the information exists but isn’t connected. Waitlist disputes because the terms were never formally documented. Records that live in one person’s head and disappear when a hard drive fails or a phone breaks.

The competition for better breeder software is not other software. It is the status quo. And the status quo has real costs that most breeders have simply learned to absorb.

The Standard Already Exists

The AKC figured this out in 1884. The ABKC built it for a breed that didn’t exist yet and got it right. The pattern is consistent across every established species club that takes lineage seriously: verified registration, multi-generation pedigree, show records, transferable titles, and a system of trust that makes the record worth something.

What breeders need from modern software is that same infrastructure, updated, accessible at the program level, and integrated into the daily work of running a breeding operation. Not a replacement for registries. An extension of what registries do, built for the breeder who is living the work.

The standard is not new. The software that meets it is.

Built From the Inside

BBD exists because I am a breeder first. I’ve been in dogs since I was five years old. My family bred and showed ADBA American Pit Bull Terriers, moved into American Bullies around 2005 when the breed was still being formed, and I was part of the group that established ABKC during those early years. I’ve made group placements in UKC. I breed crested geckos. I built ReptiDex because I needed it and nothing adequate existed.

ReptiDex launched with 50 paid subscribers and 200 animals tracked in its first nine days. Not because of marketing. Because breeders recognized something built by someone who understood the problem. You can read the full build stories for ReptiDex, Geckistry, and Texas Top Notch Frenchies in the case studies.

The best software for breeders will never come from someone who Googled the problem. It will come from someone who lived it.

If you’re a developer working in this space, this is the bar. If you’re a breeder evaluating your options, this is what to ask for.

I build breeder websites, records and genetics apps, sales platforms, and registry systems through my studio, Built By Dusty. Every one of them is built on software I use in my own breeding program. If you’re a breeder who is ready to replace the spreadsheets, or a breed club that needs real infrastructure, I’d like to hear from you.

The Open-Source Security Guide for Flutter Developers

We spend a lot of time in the Flutter community arguing about state management and app architecture. But when I recently went looking for a centralized list of mobile AppSec tools specifically for Flutter, I hit a wall.

There wasn’t a dedicated “Awesome” repository for Flutter security. The resources for both defending and reverse-engineering compiled Dart apps were completely scattered.

So, instead of hoarding my personal bookmarks, I made the repo myself.

Meet Awesome Flutter Security.

It’s a curated, open-source list of Flutter application security resources, defensive tools, and vulnerable sandboxes. Whether you are a developer trying to lock down your app or a pentester trying to break one, I wanted everything in one place.

What’s inside:

  • Defensive Tools: RASP (Runtime Application Self-Protection), obfuscation guides, and the right ways to handle secure storage and biometrics.
  • Offensive Tools: Frameworks like reFlutter and blutter for intercepting traffic, bypassing SSL pinning, and reverse-engineering AOT binaries.
  • Practice Sandboxes: Intentionally vulnerable apps (like DVFA) mapped to the OWASP Mobile Top 10 so you can practice your hacking skills.
  • Standards: The must-read guidelines from OWASP and the official Flutter team.

Let’s build this together

The goal is to make this the standard AppSec reference for the Flutter ecosystem. If you know of a tool, a great article, or a package that belongs on this list, PRs are highly welcome!

Check out the repository here: Awesome Flutter Security

Drop a ⭐️ if you find it useful, and let me know in the comments: what is your go-to package for securing your Flutter apps? Did I miss any hidden gems?

How npm, pnpm, and yarn Ate 40GB of My 256GB SSD

Last week my MacBook started complaining: “Your disk is almost full.”

I had 8GB free. On a 256GB machine. I hadn’t downloaded any movies or photos. What was going on?

The Investigation

I started hunting. First suspect: node_modules.

find ~ -name "node_modules" -type d -exec du -sh {} ; 2>/dev/null

The results made me want to cry:

~/projects/2022-client-work/node_modules              1.2GB
~/projects/abandoned-react-app/node_modules          890MB
~/projects/experiment-three-js/node_modules          750MB
~/projects/old-work-project/node_modules             1.8GB
~/projects/that-one-tutorial/node_modules            420MB
# ...20 more entries

25GB of node_modules from projects I hadn’t touched in months. Some were from 2022.

Then I checked the package manager caches:

npm cache verify    # 3.2GB
pnpm store prune    # Would free 5GB
yarn cache clean    # 2.1GB

Another 10GB just sitting in package manager caches.

In total: 40GB of JavaScript build artifacts and caches. On a 256GB SSD, that’s 15% of my entire disk — gone to a dependency graveyard.

The Three Package Managers Problem

If you work with JavaScript/TypeScript, you know this pain. You try npm. Then pnpm for speed. Then yarn for work. Each one maintains its own cache in a different location:

  • ~/.npm — npm’s cache
  • ~/Library/pnpm — pnpm’s store
  • ~/Library/Caches/Yarn — yarn’s cache

Plus every project has its own node_modules. You npm install once, build, deploy… and that folder sits there forever. Multiply by 20+ projects over 3 years.

I found a React project from 2022 with 1.8GB of node_modules. I had run npm install exactly once, built the project, and never touched it again. That 1.8GB sat on my SSD for 3 years.

Xcode Wasn’t Innocent Either

While I was at it, I checked Xcode’s cache:

du -sh ~/Library/Developer/Xcode/DerivedData
# 47GB

So my actual breakdown was:

  • node_modules: 25GB
  • npm/pnpm/yarn caches: 10GB
  • Xcode DerivedData: 47GB
  • Docker images: 8GB
  • Rust/Python/Go build artifacts: 5GB

95GB of dev cache on a 256GB machine. My actual code? Under 3GB.

The Manual Cleanup (Don’t Do This)

I spent a Saturday manually cleaning:

# Delete old node_modules... carefully
rm -rf ~/projects/2022-*/node_modules

# Clean package manager caches
npm cache clean --force
pnpm store prune
yarn cache clean

# Wait, where does pnpm store things again?
# And did I just break something?

It took 3 hours. I was paranoid about deleting the wrong thing. And I knew I’d have to do it again in 6 months.

Building DevCleaner

I wanted a tool that would:

  1. Find everything automatically — node_modules, npm cache, pnpm store, yarn cache, and 40+ other dev tools
  2. Show me before deleting — no surprises, no “oops I deleted the wrong folder”
  3. Move to Trash first — so I can verify nothing broke before emptying
  4. Be fast — scan my entire disk in seconds, not hours

So I built it. In Nim, because I wanted to learn something new and ship something fast.

The Results

First scan: 63GB of cleanable cache.

I reviewed the list — all old projects, all safe to delete. Clicked “Clean All”, everything moved to Trash. Verified my current projects still worked. Emptied Trash.

63GB back. My 256GB MacBook finally had breathing room again.

See it in action:

Sovereign Attention Firewall: A Zero-Trust AI Perimeter for Your Calendar

System Architecture

This is a submission for the Notion MCP Challenge

What I Built

The Sovereign Attention Firewall — a zero-trust AI perimeter that defends your calendar and inbox from Calendar Snipers (unverified external invites) and Ghost Projects (meetings tied to archived work), before they ever interrupt deep work.

Why this exists: Procurement professionals, operations leads, and anyone with a visible business title knows the pain. ZoomInfo scraped your LinkedIn. Now your calendar is bleeding ghost meetings, your inbox drowns in “just circling back” sequences, and every cold SDR thinks they own 30 minutes of your Tuesday. The Reddit procurement community has a name for it: attention theft. The only current defenses are manual — reply templates, block lists, and sheer emotional labour.

The real cost isn’t the emails. It’s the cognitive fragmentation. Every unvetted vendor ping is a context switch tax on your focused work.

What it does: The Sovereign Attention Firewall creates a human-in-the-loop AI enforcement system that:

  • Intercepts every external calendar invite and runs it through a zero-trust identity check
  • Detects Identity Phantoms (invites from unverified or suspicious organizers) and Ghost Projects (meetings tied to archived/completed work)
  • Quarantines flagged invites into a Notion Waiting Room for human review — nothing is blocked without your approval
  • Executes silent enforcement: rejected invites are deleted with sendUpdates: false, giving no signal back to the sender that your address is active
  • Escalates repeat offenders automatically to a permanent Block List after two rejections
  • Maintains a daily Sovereign Security Log in Notion — a full audit trail of what was caught, why, and what action was taken

The default flips: your calendar becomes as defensible as your infrastructure.

Video Demo

View on YouTube

Show Us the Code

🔗 github.com/olawolemoses/sovereign-attention-firewall

The system is built with:

  • Cloudflare Workers (TypeScript) for:

    • identity-oracle — deterministic identity registry; checks email allowlists, falls back to domain whitelists, returns Unverified for unknowns. Verdicts are cached in Cloudflare KV for sub-second performance.
    • sovereign-bouncer-mcp — custom MCP server enforcing Bearer auth and trust logic, deployed at the edge
  • Notion Agent + Notion databases as the governance and decision layer — the orchestration core

  • Zapier (Webhook + Paths) as the enforcement bridge across Google Calendar and Gmail

  • Google Calendar + Gmail for event handling, silent enforcement, and RSVP management

How I Used Notion MCP

Notion MCP is not a peripheral integration here. It is the orchestration core of the Sovereign Attention Firewall.

Every external meeting invite is evaluated through a Notion-governed workflow combined with a custom MCP trust check:

  • The Agent calls verify_email_trust(email) on Sovereign Bouncer (MCP)
  • Sovereign Bouncer queries the Identity Oracle and returns trust verdicts
  • Decisions and full policy reasoning are persisted in Notion for human review and auditability
  • When a human updates the Decision property in the 📥 Waiting Room DB from Pending to any terminal state (Approved, Rejected, Blocked, or Cancelled), a native Notion automation fires a webhook to Zapier — passing event metadata and the decision downstream for enforcement

System Architecture

The MCP + Notion integration specifically unlocks:

1. Deterministic policy enforcement

The Agent operates from explicit policy records in the 🛡️ Sovereign Policy DB — P1: Identity Proof, P2: Ghost Hunter, P3: Context Tax — rather than ad-hoc AI judgment. Policies are readable and editable by any team member directly in Notion.

Sovereign Policy DB

2. Persistent operational memory

The 📥 Waiting Room DB stores event metadata, policy reasoning, and decision state across every interaction. Nothing disappears into a black box — every triage decision is traceable over time.

Waiting Room DB

3. Human-in-the-loop governance

A human updates the Decision property in Notion — that single gesture triggers the entire enforcement chain downstream. State-lock behavior in the Agent Constitution prevents the AI from ever re-auditing a decision a human has already made.

4. Context-aware Ghost Project detection

The 📂 Projects DB allows the Agent to match incoming meeting invites against archived or completed project context. A meeting tied to a project marked Archived in Notion is automatically treated as a Ghost Project — no manual flagging required.

Projects DB

5. Automated enforcement with clean separation of concerns

Notion decides. Zapier enforces.

Zapier Enforcement Structure

Three enforcement paths execute based on the human’s decision in Notion:

Path A — Block/Reject: Delete the calendar event silently (sendUpdates: false) + find and delete the source email. No activity signal leaks to the sender.

Path B — Approve: Mark the event as accepted via a PATCH request, preserving full event metadata.

export async function updateEventStatusToAccepted({
  calendarId,
  eventId
}: {
  calendarId: string;
  eventId: string;
}): Promise<{ result: string }> {
  const url = `https://www.googleapis.com/calendar/v3/calendars/${calendarId}/events/${eventId}`;

  const requestBody = {
    attendees: [
      {
        email: calendarId,
        responseStatus: "accepted"
      }
    ]
  };

  const response = await fetchWithZapier(url, {
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(requestBody)
  });

  await response.throwErrorIfNotOk();
  return { result: "Attendee response status updated to 'Accepted'" };
}

Path C — Cancel: Update RSVP to declined, signaling a professional boundary without ghosting.

export async function updateEventRSVPStatus({
  calendarId,
  eventId
}: {
  calendarId: string;
  eventId: string;
}): Promise<{ result: any }> {
  const url = `https://www.googleapis.com/calendar/v3/calendars/${calendarId}/events/${eventId}`;

  const requestBody = {
    attendees: [
      {
        email: calendarId,
        responseStatus: "declined"
      }
    ]
  };

  const response = await fetchWithZapier(url, {
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(requestBody)
  });

  await response.throwErrorIfNotOk();
  return { result: await response.json() };
}

6. Security-aware silent enforcement

sendUpdates: false on all rejection actions ensures unverified senders never receive confirmation that your email address is active. This prevents the sender verification loops that most calendar tools inadvertently create.

7. Daily security intelligence

The Sovereign Security Log auto-generates a daily brief in Notion — phantoms blocked, ghost projects defended, system health status — giving you full situational awareness without opening a dashboard.

Sovereign Security Log

Core insight:
Most productivity systems optimize scheduling. The Sovereign Attention Firewall optimizes attention defense — combining edge policy execution (Cloudflare Workers), governance memory (Notion), and action enforcement (Zapier) into a system where your calendar is treated as a security perimeter, not an open invitation.

Your Turn

I’d love to hear from the community:

  1. How do you currently handle calendar spam and unsolicited vendor invites? Is this a problem you’ve solved, or one you’ve accepted?
  2. Where would you draw the human-in-the-loop line? At what trust level would you feel comfortable letting the AI auto-reject without your review?
  3. What’s missing from this system? What would make the Sovereign Attention Firewall genuinely useful for your workflow?

Hangfire Had a DB Support Problem. I Fixed It. You’re Welcome.

HangFire proper is hugely popular but the official implementation only supports Microsoft SQL Server. They could have made it much more database independent, but didn’t. I suspect the original authors were scratching an itch. Hangfire feels to me like someone who either didn’t want to use scheduled tasks/cron jobs, or didn’t know how. So they wrote something that would act as a cron job inside their code. This led them to only support their environment — they solved their problem for them. Nothing wrong with that — pengdows.crud is also scratching an itch. That doesn’t make software bad. It means it wasn’t born of careful planning to support everything from day one, it is “I need this, it doesn’t exist, let me write it.” The difference is the itch. Hangfire’s itch was “I need a job scheduler in my environment.” pengdows.crud’s itch was “nobody handles cross-database work in .NET correctly.” One of those itches produces a single-database solution. The other one doesn’t.

Let’s be honest about what the two biggest problems with Hangfire actually are. First, connection handling — pool exhaustion under spike load, connection leaking, and single-writer databases like SQLite falling apart under write contention. Second, lock contention — distributed lock implementations that produce violations, deadlocks, or overlapping ownership under burst load. I am going to tell you I solved both. Then I am going to show you the receipts.

When other people started extending Hangfire to work with their DBs, those people had to re-solve problems that had already been solved elsewhere. The road to hell is paved with good intentions, and the Hangfire storage ecosystem is well-paved. Here is what the community has produced:

Database Package Status
SQL Server Hangfire.SqlServer (official) ✅ Maintained
PostgreSQL Hangfire.PostgreSql ✅ Maintained
MySQL Hangfire.MySqlStorage ⚠️ Known deadlock bugs
MySQL Hangfire.Storage.MySql ⚠️ Fork created to fix the above, stuck in beta, author moved on
SQLite Hangfire.Storage.SQLite ⚠️ Alive but threadbare
Firebird Hangfire.Firebird ☠️ Dead since 2015
Oracle Hangfire.FluentNHibernateStorage ☠️ Via NHibernate, last real work 2022, SQLite/Access/SQL CE broken by its own README
Dameng DMStorage.Hangfire ❓ Chinese ecosystem only

That isn’t the edge case, it is systemic. MySQL has two packages because the first one had deadlock bugs bad enough that someone forked it. The fork has been stuck in beta for years. The author’s own README says he got fed up and wrote a different scheduler entirely. The NHibernate-backed provider claims to support six databases — its own README admits that SQLite, MS Access, and SQL Server Compact “proved not to work” and there’s no plan to fix them. As a sidenote, SQL CE requires careful handling most people never handle correctly, my SingleWriter mode. Firebird hasn’t been touched since 2015. They still install. Whether they behave correctly against a current version of their target database is a question you get to answer in production.

The SQLite Detour

So when I started readying pengdows.crud 2.0, I really wanted to show off my new SingleWriter mode. If you aren’t familiar with pengdows.crud that is ok, go check it out on Github (https://github.com/pengdows/pengdows.crud). My crud has 5 different connection modes reflecting the reality of database behavior:

  • SingleConnection — all database work has to be done via a single connection. This is the mode that SQLite and DuckDB :memory: databases have to use. If you try to connect a second connection you literally get a new DB.
  • SingleWriter — these databases can have as many readers as you like (within reason), but all writes have to be serialized. If two connections try to write simultaneously you either end up with a corrupted database or it throws “database is busy” and one of them fails. Neither is acceptable in production.
  • KeepAlive — created for SQL Server LocalDB, to keep the server alive. I hold 1 connection open for the life of the app. That connection is never used for anything other than keeping the server alive.
  • Standard — my default mode. Open a connection, run your SQL, consume the results, close the connection the moment it is available to be closed.
  • Best — choose the best one for the DB you are using.

pengdows.crud allows you to change how your app interacts with your DB without changing your code. With 2.0 I revamped some things and that had the effect of really optimizing my single writer — only 1 writer is allowed at a time, and it is NOT a pinned connection, it is controlled through a governor. In short this makes DuckDB and SQLite safe to use under moderate write load, and I have a turnstile that prevents writer starvation.

With this new feature, I was really just looking for a SQLite project to rewrite and show it off. Hangfire is notorious for pool exhaustion. If I can make SQLite work reliably under Hangfire that helps Hangfire users, helps developers, and shows off what pengdows.crud can do.

When I started really digging in though, I found that it was not written as I expected, and a lot of the other storage providers seem to be suffering from code rot and abandonment. I thought to myself — well pengdows.crud supports 14 relational database systems, so lets write it once. I whipped out pengdows.poco.mint (available either as a NuGet command line tool or a self-contained WebUI Docker image), spun up a SQL Server container, ran the scripts to get POCOs based on the tables, and got to work.

The Lock Problem

As I said, Hangfire feels like a scratch-an-itch project meant for one environment. Evidence of this showed up right here. The SQL Server code uses a SQL Server-only stored procedure to keep other processes from grabbing a task. So every other storage implementation has to solve this problem in a new way. It wasn’t even necessary for SQLite since it only allows one writer, but the author created a table named “Lock” to solve the problem anyway — so I borrowed that approach. “Lock” is a reserved word in several of my supported databases, so I renamed it to “hf_lock” and moved on. It is not as fast as the stored procedure on SQL Server, but it is uniform across all 13 supported databases, and the benchmarks show it.

What’s Supported and What Isn’t

pengdows.hangfire supports 13 databases. Here is how that stacks up against what existed before:

Database Had Support Before pengdows.hangfire
SQL Server ✅ ✅
PostgreSQL ✅ ✅
MySQL ✅ ⚠️ ✅
SQLite ✅ ⚠️ ✅
Firebird ✅ ☠️ ✅
Oracle ✅ ☠️ ✅
MariaDB ❌ Never ✅
CockroachDB ❌ Never ✅
DuckDB ❌ Never ✅
YugabyteDB ❌ Never ✅
TiDB ❌ Never ✅
Aurora MySQL ❌ Never ✅
Aurora PostgreSQL ❌ Never ✅

Seven databases that have never had Hangfire storage support before. The ones that did exist either had known bugs, were forks of broken packages, or hadn’t been touched in a decade.

Two databases from the pengdows.crud supported list aren’t in pengdows.hangfire. Dameng has no Docker image to test against and no modern .NET provider. When those exist, adding it is trivial — the door is open. Snowflake is a different problem entirely. pengdows.crud includes a Snowflake dialect, but Snowflake is designed for analytical workloads — columnar storage, warehouse-level concurrency, high per-query latency. Hangfire needs row-level locking, low-latency queue polling, high-frequency small writes and deletes, and reliable distributed lock semantics. These requirements are fundamentally at odds with Snowflake’s architecture. It isn’t a missing SQL feature, it’s the wrong database for the workload. If that changes, the support will follow.

The Receipts

Here is what I said I would show you.

111 abstract facts, instantiated across 11 databases via Testcontainers, producing 1,204 concrete test cases. Real engines, not mocks. Connection behavior, transaction mutations, expiration cleanup, counter aggregation, queue fetch/claim/ack — covered.

That handles correctness. For contention there is a separate stress suite, and that is where it gets interesting.

200 workers. One resource. All contending simultaneously. Required invariants: zero ownership violations, zero interval overlaps, max concurrent owners never exceeding 1. That test passes against SQL Server at full pool size. It passes again with pool size forced down to 40 — where timeouts and pool rejections are expected but successful acquisitions still cannot overlap. It passes with 200 workers spread across 20 resources with 80% of traffic on 2 hot keys. SQLite and DuckDB each have their own 200-worker SingleWriter variants. All pass.

Correctness is verified three ways: live CAS-style ownership conflicts, max concurrent holders per resource, and post-run overlap analysis on recorded hold intervals. You cannot get a false pass on one check and slip through — all three have to agree.

There is also a crash path. Process killed mid-lock, TTL set to 15 seconds — the dead lock was stolen and cleaned up in 14.8 seconds. Lock rows do not orphan.

The MySQL fork in the ecosystem exists because the original had deadlock bugs under burst load. The fork’s author eventually gave up and wrote a different scheduler. These tests are the direct answer to that problem. 40 passed. 0 failed.

These are not one-off validation runs. The unit tests, integration tests, and stress suite are part of the open source library. They run on every change. If you pull the repo, you get the tests.

Why I Built This

So yeah, I wrote this for three reasons:

  1. Help Hangfire users — you now have 13 databases to choose from, connection handling that doesn’t fall apart under load, and lock contention that has been stress tested to 200 concurrent workers.
  2. Help Hangfire developers — pool saturation and lock violations are solved problems if you use the right storage.
  3. Show off pengdows.crud and generate some interest.

This whole thing is me proving out my own scratch-an-itch software. pengdows.crud exists because nobody was handling cross-database work in .NET correctly. pengdows.hangfire exists because I needed a real-world, production-grade project to prove it works. Hangfire users get more database options, better connection handling, and a lock implementation that holds under pressure. The world gets a robust example of what pengdows.crud can actually do. That’s not a bad outcome for an itch.

The package is pengdows.hangfire. It’s on NuGet. Go kick the tires.