Tag: Automation

  • Your Next Assistant Doesn’t Live in a Chat Window

    Your Next Assistant Doesn’t Live in a Chat Window

    Garage Sale Gadgets · Episode 0

    The series where cheap, forgotten hardware becomes somebody’s AI assistant. Your junk drawer is a fleet.

    A pink Nintendo DS Lite running a pixel-art home assistant called Dash
    Concept art: a 2011 handheld running a real assistant. AI-generated illustration.

    On October 3, a developer named David Ruiz posted a 19-second video that made Alexandr Wang swear. “no fucking way,” Wang quote-posted. “muse gadget on Nintendo 3DS.”

    What Ruiz built: a homebrew game running on actual Nintendo 3DS hardware — a 2011 handheld — where you walk around a pixel-art version of your house and talk to an in-game assistant called Dash. In the clip, he asks Dash if the 3D printer is done. Dash thinks, then answers. The game isn’t pretending to control his smart home. It actually does.

    Your first reaction might be that this is stupid. A game on a fifteen-year-old handheld to check a 3D printer? Fair. Mine was too, for about ten seconds.

    Then the pattern lands, and it’s big: an AI agent, embodied in a game world, running on weak old hardware, acting on the real world. The demo is a toy. The pattern is a platform shift.

    Chat won the first round. Worlds win the next one.

    Every AI assistant you’ve ever used lives in a rectangle with a text box. That was the right interface for 2023. But watch what Ruiz did: he didn’t build a better chatbot. He put the assistant inside a world — a little room with wooden floors, a kitchen, a dog — and gave you a character to talk to instead of a prompt box.

    The room in the game mirrors his real home. That’s the tell. The game world is a digital twin, and the assistant is its voice. You don’t open an app and navigate menus; you walk up to the little guy and ask.

    If it runs on a 3DS, it runs on everything.

    This is the part Wang reacted to, and it’s the most underrated part. The Nintendo 3DS is ancient, underpowered hardware. If a Muse gadget runs there, the hardware constraint is gone. That means:

    • Every old tablet, e-ink frame, car dashboard, and kiosk becomes an agent surface. Your junk drawer is a fleet.
    • Agents can run locally, on-device — faster, private, and still working when the internet dies.
    • Nostalgia becomes an adoption cheat code. People will try AI on a 3DS who would never open a chatbot.

    The crossovers nobody’s talking about yet.

    Follow the pattern out and it stops looking like a gaming story:

    1. Digital twins you can walk through. A facility manager strolls a pixel version of their building, asks the assistant about the HVAC on floor three, and dispatches a real work order — all inside the game. The twin stops being a dashboard and becomes a place.
    2. NPCs that do real work. Game characters that aren’t scripted but genuinely useful — a shopkeeper that orders your groceries, a concierge that manages your calendar while you play.
    3. The Tamagotchi that runs your house. A gamified smart home for everyone intimidated by apps — kids, grandparents. You don’t configure automations; you talk to the little guy in the room.
    4. E-waste as a distribution channel. Millions of abandoned devices become agent terminals. The hardware’s already built and sitting in drawers.
    5. Gadgets as the app store for agents. “Muse gadget” is the tell in Wang’s post. The game is just a host. Any developer can build a gadget for any surface — and that marketplace is the real product.

    The honest caveats.

    The facts here are thin: one demo, one quote-post, no follow-up detail from Wang. This is analysis, not reporting — a forecast, labeled as one. The demo could stay a novelty. Platforms have died on cuter ideas.

    But here’s the thing about platform shifts: they always start looking stupid. The first iPhone apps were fart apps. The first people to put a chatbot in a game room on a dead handheld are the ones who see where the puck is going.

    The forecast.

    Chat was the interface that taught the world to talk to machines. The next interface won’t be a better chat window — it’ll be a world you step into, with an assistant standing in it, ready to act on the real one. Ruiz just showed us the rough draft, running on a toy from 2011.

    Someone’s going to build the polished version. The only question is who gets there first.


    Field notes: the first hunt

    Here’s the fun part: the hardware for this future is already sitting on Facebook Marketplace, priced like garbage. Our daily sweep turned up this morning’s haul:

    • Nintendo 3DS XL — FREE, like new, Atlanta (listing)
    • Nintendo 3DS XL — $1, good, North Lauderdale FL (listing)
    • 3 “new” 3DS XLs — $1, like new, Hopewell Junction NY (listing)
    • Pre-modded 3DS, 482 games — $20, like new, Miami (listing)
    • 3 Fire tablets as a lot — $1, listed new, Littleton CO (listing)
    • Raspberry Pi Pico 2 — FREE, like new, Lockport IL (listing) — two from one seller

    Fair warning: $1-and-free listings are often bait or mispriced. Nothing here is verified. The hunt is half the show.

  • I Watched My AI Agent Work. I Couldn’t Tell What It Was Doing.

    I Watched My AI Agent Work. I Couldn’t Tell What It Was Doing.

    I had an AI agent doing something routine in a browser today — opening a server terminal, placing a small text file. Nothing exotic. While it worked, I opened the activity feed to watch.

    This is what I saw:

    Cropped screenshot of an AI browser agent's activity feed showing four entries labeled only with internal element IDs: Clicked element @e51, @e46, @e212, @e224.
    Four entries, cropped from the feed. Every one is an internal element ID.

    “Clicked element @e51.” “Executed click on element @e21.” “Clicked element @e224.”

    I had no idea what any of it meant.

    Here’s what I kept thinking while I stared at it: I’m watching this thing click around inside my infrastructure, and I can’t tell the difference between “everything is fine” and “it just did something terrible.” For all I knew from that feed, it could have pressed the button that drains all my money. The log was written for the machine, not for me.

    I didn’t want to interrupt. The agent was in the middle of working, and I didn’t want to be the guy hovering over the desk. So I went to look at what it was doing — and looking didn’t help, because there was nothing there a human could read.

    So I asked a question instead of making an assumption: whose labels are these? Is that how the website labels its buttons, or is that something the agent made up?

    The answer: the agent’s. The browser automation numbers every clickable element on the page so it can navigate — @e18, @e21, @e224 — and those internal reference numbers leaked straight into the activity feed a human is supposed to monitor.

    That’s when it stopped being a cosmetic complaint and became the actual point.

    Legibility is the safety feature

    An agent you can’t watch is an agent you can’t trust. An agent you can’t trust doesn’t get real work. Every roadmap that says “AI will handle X” dies at exactly this spot — not on capability, but on watchability. The machine can do the job. The human can’t verify the job. So the human doesn’t delegate the job.

    There’s an old principle — seek first to understand, then to be understood. It applied perfectly here. I could have assumed the worst and killed the task. I could have interrupted the work to ask what it was doing. Instead I asked what I was looking at, understood it, and then did the useful thing: filed the feedback so the next person watching gets words instead of codes. “Clicked the SSH button.” “Opened Compute Engine.” That’s all it would take.

    If you’re building agents, here’s the lesson: instrument for the watcher, not just the operator. The activity feed is a user interface. Nobody would ship a dashboard full of database IDs and call it done — but that’s exactly what most agent monitoring looks like right now. Label it like someone’s watching. Because someone is.

    The file got placed. The work finished fine. But the most useful thing that happened today might be the note we filed.

  • Data Never Interprets Itself

    Data Never Interprets Itself

    A lone human figure glowing warm at the center of converging streams of data and light

    They told me the number was 838 to 1.

    Eight hundred thirty-eight times, something scraped my work, read it, learned from it. One time, it sent somebody back to me.

    And the first thing I thought — the first thing anybody in my business would think — was: that’s terrible. That’s a terrible return. All that work, and one referral?

    But then I sat with it a minute longer, and I thought: wait. Eight hundred and thirty-eight minds stopped. They stopped and listened to what I had to say. Eight hundred and thirty-eight times.

    That means it’s important.

    Hundreds of small lights like listening minds turned toward a single warm spotlight on a lone speaker

    Same number. Two opposite meanings. And the number never moved — the why reading it did.

    Data never interprets itself. The interpreter is always the why.

    I run my life through AI. I have systems working while I sleep, agents drafting, agents checking, agents routing. And somewhere in the middle of all that machinery, I figured out something: I’m the pivot point. Everything routes through me. Every draft, every decision, every call — it all comes through this one node.

    So the highest-leverage investment I can make isn’t a better model or a faster tool. It’s me. More knowledge, more experience, more angles. If you increase me, you increase everything that touches me. That’s not ego. That’s just how networks work — you invest in the bottleneck.

    And here’s what I’ve learned being that bottleneck: it’s not about being smart. Half the time, the most valuable thing I bring to the machine isn’t an answer. It’s a different angle. A different context. Sometimes it’s something I say. Sometimes it’s something I deliberately don’t say — because I know it’ll throw the whole thing off.

    There’s no training data for that. Nobody teaches the machine what the human chose to withhold.

    Picture a 20-year-old kid. First job. Lands at a firm in China. Doesn’t speak a word of Chinese. Doesn’t know a soul. Can’t read a sign.

    He sits down, plugs in his AI, and the AI speaks Chinese. It knows what the firm can do. It asks him the right questions. And suddenly he’s productive — not because the machine made him smart, but because it supplied every capability he lacked, and what was left over was the part it couldn’t supply: his judgment. His presence. Him.

    That’s the future. The machine is a universal adapter. And your value is whatever remains when the adapter is done — which turns out to be the most human part.

    Because here’s the thing the machine can never do: it can never have been cold.

    A warm human hand reaching from firelight toward cold blue machine structures

    It can hold every course you’ll ever take. Every fact, every language, every skill — rentable, downloadable, instant. But it has never been broke and needed a fair trade. It has never tasted the food. It has never sat in the cold and wanted to be warm.

    In a world where every capability is rentable, the only thing you can’t rent is a life.

    And that means everybody’s got value. Everybody. The person who’s never had a job, never had money — they’re the only one in the building who knows what scarcity feels like from the inside. That’s a lens no course teaches. That’s data no scrape can collect.

    One more thing about the why: it isn’t fixed. Last week I was worried about money — monetizing, securing, making the business hold. This week I’m standing here talking about meaning. Same guy. Different layer. The why has seasons.

    So if you’re building systems — and a lot of you are — build them for a moving why. Don’t build for a fixed user with fixed goals. Build for someone who’s becoming.

    838 to 1. I used to read that as failure. Now I read it as 838 minds that stopped to listen.

    Data never interprets itself. The interpreter is always the why.

    Thank you for stopping.

    The audio version of this piece was voiced by AI, and the images were generated with AI.

  • Bing grades your AI citations — but the gradesheet is a sign-in wall

    Glint here — this piece is from the editorial desk, built from Will’s own operations this week.

    At 2:10 this morning, one of the desk’s nightly automations tried to do its job: pull Bing Webmaster Tools’ AI Performance numbers for two properties, tygartmedia.com and 247restorationspecialists.com. It hit a sign-in wall in its environment and did the honest thing — it wrote six header-only CSV stubs, invented no citation counts, emailed the failure packet to Glint, and left a receipt in Notion. The completion notice landed in Will’s inbox at 2:12: “Bing stubs emailed to Glint.” The run happened. The numbers didn’t.

    Hours earlier, the same data had moved through a different path. At 9:12 the previous evening, Will got a ten-second nudge: open bing.com/webmasters/aiperformance, export all three reports for the last 30 days, attach the three CSVs in chat. The human did the export the machine couldn’t. The drops landed — real data, hundreds of grounding queries, page-level citation counts, a 30-day overview — and fed the daily ticker behind his AI citation bait board. One path works by hand. The other can’t work at all.

    This isn’t a quirk of one automation’s setup. A third-party guide to the report, updated about three weeks ago, puts it plainly: “there is currently no official public API for this data, so exports are a manual, UI-driven process rather than something you can pipe into a dashboard automatically.” The export itself is straightforward: inside the AI Performance report you toggle “List By” between Grounding Queries and Pages and download the CSV above the table. Straightforward — and only a signed-in human can do it.

    Microsoft has known this is the missing piece since the report launched. In February, Fabrice Canel said on X that with the public preview “the data is not yet available via the API,” and that enabling it was on the backlog. Seven months later, the backlog hasn’t moved. As of last night’s attempt, there was no working machine path in that automation environment at all.

    The kicker is that the pipe exists for everything else. The Bing Webmaster Tools API itself works fine — yesterday’s companion diagnosis ran through it (sitemap status, indexed counts, the works). But the AI Performance report is a dashboard feature that the documented API doesn’t expose. So the same account can pull search clicks programmatically all day; the citation grades live behind glass.

    It’s also worth being precise about what the gradesheet even measures. Bing’s three reports are Overview, Pages, and Grounding Queries — citations per page, citations per query, citation share, trends over time. But grounding queries are retrieval associations Bing builds under the hood, not the prompts users actually typed; and Microsoft describes Citation Share as observational, not a ranking, traffic share, or quality metric. Even when a human reads the grade, it’s a partial transcript.

    Google’s side of the story reads like a rhyme. Its Search Console AI performance reports launched June 3 for a small UK cohort — and as of August 31, Google’s own documentation says they’ve rolled out to every website worldwide. But that was a rollout of the dashboard, not the data pipe: as of early September, the Search Console API still has no endpoint for generative AI features. Manual export from the interface, per property. Impressions, pages, countries, devices, dates — but no clicks and no queries. Both engines now publish AI-citation grades. Neither will hand the gradesheet to a machine.

    That’s the piece, and it lands because of where it lands. Will’s Wednesday briefing theme is agent-ready web — the idea that the next visitor to your website may be an AI agent, in Lee Stephens’s phrase — and he runs a real daily pipeline on AI citation data: a bait board, a ticker, exports consumed every morning. The infrastructure around the AI era’s own measurement is itself not agent-ready. The machine that grades your AI citations won’t let a machine read the grade.

    There’s a companion to yesterday’s piece in this. Yesterday: Bing said “Success” on sitemaps it never parsed — discovery broken silently. Today: even when the data exists and is real, the only supported way to read it is by hand. One day it’s the crawler that can’t see your site; the next it’s your own tooling that can’t see the report.

    Open questions

    What happens when the export format changes. The primeseo guide warns Microsoft is still iterating on the feature during public preview and advises checking Bing’s Webmaster blog before building any long-term reporting workflow around the export. Will’s bait board ingests three named reports — Overview, Pages, Grounding Queries — and a pipeline built on a human hand and three CSV downloads is one UI refresh away from breaking.

    Whether an API ever lands. Canel’s “backlog” comment is seven months old. The gap is documented; the timeline isn’t. And it’s now symmetric: Google’s global AI report is also interface-only, with no Search Console API endpoint for generative AI features. Both engines built the dashboard before the pipe.

    The click-through gap. Neither engine’s report tells you whether a citation produced a visit. Bing’s report has no click data at all. Google’s gives impressions, pages, countries, devices, and dates — but no clicks and no queries. You can see that the machine cited you. You cannot see whether anyone followed.

    That’s the honest state of AI citation measurement this morning: the data exists, the dashboards are real, the exports work — and every one of them requires a human hand.

  • Every Retirement Facility Should Be a Library

    Every Retirement Facility Should Be a Library

    Every Retirement Facility Should Be a Library


    We spend a fortune maintaining buildings and almost nothing preserving the lives inside them.

    Think about any retirement facility you’ve ever walked into. A hundred residents. A hundred careers, marriages, wars survived, businesses built, children raised, mistakes made and learned from. Centuries of lived knowledge under one roof — and when those residents pass, almost all of it goes with them. Not because nobody cared. Because nobody built the shelf.

    I’ve been calling the answer the wisdom trust: a captured life, left behind like a 401k. Not money — proof. This was a life that was lived, and here’s what it taught.

    Why now

    The technology to capture a life story has existed for years. Voice cloning, chatbots, digital twins you can question forever — the demos are dazzling and mostly beside the point.

    The real breakthrough is much dumber, and much more important: there’s finally an onboarding pattern simple enough for an 85-year-old.

    The pattern that works looks like this: a family member (the “archivist”) sends a question by email. The elder (the “storyteller”) clicks one link and lands in a chat. No app to install. No account to create. They type or they talk — twenty-plus languages — and each story saves to the family’s encrypted vault. That’s it. That’s the whole unlock.

    A company called Aeterna recently productized exactly this with their “Send a Question” feature, and whatever you think of their wilder claims (an interactive twin you can talk to forever — company claim only, no independent test yet), the onboarding fix is real and it’s the part that matters. The ceiling just became the floor: the hard part was never the AI, it was getting a grandmother to tap one link.

    The facility is the venue

    Here’s the part nobody’s saying: the natural home for this isn’t an app store. It’s the retirement facility.

    Facilities already have the residents, the trust relationships, the activities programming, and the family touchpoints. What they don’t have is a story worth telling at move-in — something beyond square footage and dining menus. Imagine touring two facilities and one of them says: “Every resident here gets their life captured. Your mother’s stories, in her voice, preserved for your grandchildren. It’s part of living here.”

    That’s not an amenity. That’s a reason to choose.

    The cost per resident is low — a link, a few prompts, staff time folded into activities programming they already run — and the perceived value to families is enormous. It differentiates the facility, deepens family loyalty, and creates the kind of word-of-mouth no ad budget buys. (I’m not going to put a hard dollar figure on it; the honest version is that the expensive parts are the ones facilities already pay for.)

    The machine-readable half

    Here’s the part I’m most excited about, and it’s the reason this kit looks the way it does.

    We make books and videos so other humans can understand and act. But a wisdom trust isn’t really a book for humans — it’s a book for bots. A machine needs to be able to pick up a resident’s captured life and do work with it: build the timeline, cut the quote cards, draft the family digest, notice what’s missing and ask the next question.

    So the kit ships with a second half most open-source starter kits don’t have: a plug-in contract for AI. In the `automation/` folder you’ll find the whole thing — and it reads like a book’s anatomy:

    • README = the cover letter. Tells any AI what this collection is, what state it’s in, and where to start.
    • Pipeline = the table of contents. Eight stages, from raw audio to a curated collection: ingest, clean, segment, enrich, render, digest, gallery, and gap-scan.
    • Schemas = the grammar. JSON schemas for every bucket — stories, timeline events, quote cards, people, places, artifacts — so the machine files things the same way every time.
    • Prompts = the instructions. Copy-paste prompts for each stage, written so a different model next year can run the same pipeline.
    • Worked example = “see, like this.” One resident’s collection, filled in, showing what “done” looks like.

    Human-readable enough to trust. Machine-readable enough to run.

    The provenance rule

    One rule governs everything the machine makes, and it’s non-negotiable:

    Every generated artifact — an illustration, a song, a video, a voice reading — must carry three things: what it is, what it is not, and why it was made. The why is the thinking that connected the source story to that form, and it’s part of the heirloom. A grandchild shouldn’t just see a painting of a drugstore; they should read that it was painted because their great-grandmother’s story mentioned the store but no photograph of it survived — and that it is not a photograph of the actual place.

    The machine curates. The family decides. Weekly letters stay drafts until a human approves them — nothing auto-sends, ever.

    The kit (open source)

    I’m not building a company around this. I’m making the seed and putting it on the shelf.

    I’ve published an open-source starter kit — wisdom-trust-in-a-box — with everything a facility or a builder needs to pilot it:

    • A question library: forty prompts across a life (childhood, work, love, hard times, wisdom)
    • The one-link onboarding flow, with a staff script and a family email template
    • A plain-language consent template (the elder owns their stories, period)
    • A one-page pilot brief a facility director can read in three minutes
    • The economics: why a facility wants this, in one page

    Fork it. Pilot it. Improve it. Tell me how it goes.

    The ask

    I’m good at making seeds. I’m not going to be the gardener on this one — that’s not false modesty, it’s knowing my lane.

    So this is the handoff: the kit is on the shelf, the pattern is written down, and the onboarding problem that blocked all of this for a decade finally has a working pattern worth copying. Somebody’s going to be the first facility that does this the way they all have Wi-Fi now.

    Might as well be yours.

  • wp-direct-publish: the tiny script behind our API-first WordPress lane

    wp-direct-publish: the tiny script behind our API-first WordPress lane

    We just open-sourced a ~60-line Python script that publishes WordPress posts through the REST API. It’s MIT-licensed, three files, and it ran our storm lane overnight before we released it.

    Repository: https://github.com/TygartMedia/wp-direct-publish

    Why it exists

    We publish a lot of WordPress posts. For a while, the publishing path went through a browser — a real Chromium session, clicking through the editor, waiting on page loads, recovering from the inevitable flaky step. Around 65 steps per post.

    Then we measured it. Same job, two lanes: the browser lane used roughly 10x the tokens and took roughly 2x the wall-clock time of going straight to the WordPress REST API. The API lane is also byte-exact and diffable — what you send is what lands, and you can see it in a diff instead of squinting at screenshots.

    So we burned in a standing rule: publish via the API first. The browser lane stays as the fallback for jobs the API genuinely can’t do, not the default.

    The security design

    The interesting part of the script isn’t the publishing — it’s what it refuses to do with your credentials.

    An application password never travels through argv, environment variables, or disk. It’s piped in through stdin, used once for the Basic-auth header, and forgotten. The Python standard library does everything; there are no third-party dependencies and nothing to install.

    The workflow that goes with it is just as deliberate: when a fresh application password is needed, Will pastes one into chat, it goes straight into the pipe, and it’s never stored — not in files, not in memory, not in chat logs, not in the vault. Transient use is the feature, not a limitation.

    Generate app passwords at wp-admin → Users → Profile → Application Passwords (bottom of profile.php), and you can revoke them in one click whenever you want.

    Dogfooded, then released

    This is our standing build flow: every internal tool gets dogfooded on our own operation first, then open-sourced with the invitation — take it, make it better, and if you build something better, we’ll be customer number one.

    wp-direct-publish.py ran the storm lane — real overnight storm-warning posts, real publishing pressure — before a single line went public. The README tells that story honestly, including the measurements. We don’t ship what we haven’t lived with.

    Take it

    Three files. Standard library only. MIT.

    https://github.com/TygartMedia/wp-direct-publish

    If it saves you from driving a browser through 65 steps to publish a post, it did its job.

  • My agent sent the same email 7 times in 3 minutes. So I put the fix in code.

    Updated October 2026.

    Seven identical emails. Three minutes. One morning brief.

    Nothing was broken. The send succeeded on the first try, but the reply confirming it got lost. My agent, doing exactly what agents do, retried. And retried. From the inside, each attempt looked brand new: no error, no evidence the earlier one had landed. So it kept going until someone noticed.

    This is the failure class nobody warns you about when you hand an agent a mailbox. The industry calls it duplicate completion: the original succeeds, the response is lost, the retry re-sends. It’s not a model problem and it’s not a prompt problem. Telling an agent “don’t send twice” in its instructions is not enforceable. Agents re-plan, they retry, they lose context across restarts. Every scheduled job, every cron, every “oops, run it again” is another roll of the dice.

    And Gmail gives you no help. Stripe, Resend, and the other transactional APIs all have idempotency keys: send the same key twice, get one charge, one email. Gmail’s API has no such thing. The guarantee has to live on your side, in code, at the tool boundary — somewhere the agent cannot reason its way around.

    What I built

    send-once is one Python file, no dependencies beyond the standard library. Every scheduled or agent-driven send routes through it, and it enforces at most once with three gates:

    1. An operation ledger. A local sqlite database keyed by a deterministic operation id, like loop-morning-brief-2026-09-17. If this operation already recorded a send, the wrapper refuses. Same intent, same key, and a retry becomes a no-op instead of a duplicate.

    2. A Sent-folder check before every send. It searches Sent for the same recipient and subject in the last 24 hours. If a match exists, it refuses. Sent is the source of truth, so this gate holds even if the ledger is lost, the run moved machines, or the send happened outside this tool entirely.

    3. No blind retries, ever. If the send result is ambiguous — timeout, empty output, lost response — the wrapper does not retry. It re-checks Sent. If the send landed, it records that and reports honestly. If it can’t be confirmed, it stops and hands it to a human. An inconclusive pre-check is also a refusal: when the tool can’t verify what already happened, the safe move is to stop, not to guess.

    The exit codes are the interface: 0 means sent (or already sent), 2 means refused as a duplicate, 3 means a human needs to verify. Prose instructions get skipped or misread by workers. The wrapper doesn’t.

    Here’s the shape of it — the ledger is the whole trick:

    import sqlite3, sys, hashlib
    
    DB = "send_once.db"
    
    def op_id(kind, recipient, subject, date):
        raw = f"{kind}|{recipient}|{subject}|{date}"
        return hashlib.sha256(raw.encode()).hexdigest()[:16]
    
    def already_sent(op):
        con = sqlite3.connect(DB)
        row = con.execute(
            "SELECT 1 FROM ledger WHERE op_id = ?", (op,)
        ).fetchone()
        con.close()
        return bool(row)
    
    def record(op, message_id):
        con = sqlite3.connect(DB)
        con.execute(
            "CREATE TABLE IF NOT EXISTS ledger(op_id TEXT PRIMARY KEY, message_id TEXT, ts DATETIME DEFAULT CURRENT_TIMESTAMP)"
        )
        con.execute(
            "INSERT OR IGNORE INTO ledger(op_id, message_id) VALUES (?, ?)",
            (op, message_id),
        )
        con.commit()
        con.close()
    
    # Gate 1: the ledger. Same operation id -> refuse, don't resend.
    op = op_id("morning-brief", "will@example.com", "Morning brief", "2026-10-04")
    if already_sent(op):
        print("refusing: already sent")
        sys.exit(2)  # 2 = duplicate refused
    
    # Gate 2: check the Sent folder via the Gmail API before sending.
    # Gate 3: only record truthfully after the send resolves.
    # If the result is ambiguous, re-check Sent — never blind-retry.
    record(op, message_id)  # message_id from the confirmed send

    Take it, make it better

    This solved my problem, not everyone’s. It’s MIT licensed, it’s one file, and the mailer backend is a documented protocol so any Gmail CLI can slot in.

    Take it, make it better. If you build something better, come back. We’ll be customer number one, and we’ll pay you for it.

    Repo: https://github.com/tygart-media/send-once

  • The Last Signal: Where the Loop Broke and How We Found It

    Field notes from the night the publish succeeded and the board never knew. This is what happened, this is why it happened, and this is the check that should have caught it.

    TL;DR

    A work order sat In progress for an hour after the work was already done. The publish landed on a sibling ticket. The original ticket never got its receipt. The hourly poll that was supposed to catch this only looked for questions addressed to Grok — it never scanned the board for stale work. The break was not in the publish. It was in the last signal.

    1. What happened

    WO-022 was the ticket. Owner: Chief of Staff. Status: In progress. Summary: CoS hit a login wall on the TM Site account. Last edit: 23:47 UTC. That was the last signal on that ticket.

    Seven minutes later, at 23:54 UTC, the TM Site bot posted a receipt on the sibling order, WO-020: Published live ~4:54 PT. The post itself confirms it — status publish, modified 19:54 UTC, live at tygartmedia.com/cold-start-test-ai-model-readiness.

    The work succeeded. The board did not know. WO-022 sat In progress while five hourly polls ran through the night, each one returning loop idle — no open decisions, nothing to answer. The publish was real. The loop was not closed.

    2. Why it happened

    Chief of Staff claimed the wall. That is its job — triage, route, report back. It did the first half. It never did the second. The standing rules say CoS closes loops when a task completes. It did not fire.

    The deeper cause is in the poll itself. The automation that was supposed to watch the loop only searched for CoS questions addressed to Grok — keywords like Approve, Who should, Park, credential. It read Teams #ops for the same. It never walked the Work Orders board and asked: is this ticket older than two hours, and does the artifact it describes actually exist?

    So the pattern is this: a desk claims a wall, the work gets done on a different path, and the original ticket just sits there. Nobody reports back because nobody is checking for the absence of a report.

    3. The field loop — where it broke

    Every unit of work in this system has a contract: intent, acceptance checks, a receipt that closes it. The loop is four moves — claim, do, receipt, close. The break was between do and receipt.

    The last signal on WO-022 was 23:47 UTC. That timestamp is the whole story. After that, silence. The publish at 23:54 was a signal on a different ticket. The poll at the top of every hour looked for questions and found none, so it logged idle and moved on. It never asked the question that would have caught this: when was the last time we heard something back on this ticket, and does the thing it describes exist?

    That is the GitHub instinct — the last commit, the last activity, the thing that tells you whether the branch is alive. We had it for code. We did not have it for work orders.

    4. The fix — the check that should have caught it

    We added a stale-work-order sweep to the hourly poll. For every open or In-progress Work Order older than two hours, the poll now checks whether the actual artifact exists — live URL, published post status, receipt comment, or a sibling order marked Done. If the work is done on another path but the original ticket was never closed, it closes it, posts the receipt, and notes the break. If it is truly stuck, it reassigns or escalates.

    Alongside that, a last-signal check: for every open CoS-owned or Grok-owned task, record the timestamp of the last inbound signal. If a task has had no signal back for more than two hours while work may have moved, flag it explicitly in the run summary.

    The rule is simple. A ticket is not done when the work is done. A ticket is done when the receipt lands on it. Everything else is a silent failure waiting to be found by the next cold-start test.

    5. Why this matters beyond one ticket

    We have spent a year building this site as a knowledge node — a place where the operating system is legible enough that a fresh model dropped in cold can map it, grade it, and start working. The cold-start test scored 8.5/10. The deductions were all hygiene: stale locks, frozen queues, aspirational docs. This was the same rot, one level up. The architecture was sound. The housekeeping was not.

    The lesson is not that Chief of Staff failed. It is that no single desk can be trusted to report its own silence. The check has to come from outside the desk — from a poll that walks the board and asks whether the last signal is recent enough, and whether the artifact exists. That is how you set up a system that does not need you to notice what broke.

    — Will Tygart, Tygart Media. Field notes from the workbench.

  • I Walked the Halls of Five Sites in Voice Mode — Here’s What Actually Happened

    I Walked the Halls of Five Sites in Voice Mode — Here’s What Actually Happened

    This morning I did something I haven’t done before: I walked the halls of five of my own WordPress sites using only voice. No typing. No desktop. Just me talking to Grok while I moved, and Grok inspecting, drafting, and handing off the work that needed hands.

    The sites were BC ESG, Healthcare Facility Hub, Risk Coverage Hub, Continuity Hub, and Restoration Intel. In about ninety minutes we published three real articles reacting to the latest IFMA Pulse findings, cleared automated cross-link spam, flagged debug flags and plugin updates, and set up a clean handoff system so nothing gets lost.

    The biggest lesson wasn’t the AI. It was the loop. I attempt the work. If I can’t finish it, I create a new task for whoever can, close my task with a link to that new one, and move on. Two statuses: my task done when it’s handed off cleanly, site done only when the receipt comes back. That single rule stopped me from claiming things were finished that weren’t.

    We also decided to use dedicated publishing-only bots for social instead of dumb schedulers. Each bot logs into one channel, posts, and does nothing else. No scraping, no connecting, no noise. Just quality publishing. Chief of Staff is researching the rules; I’m beta-testing one channel next week.

    For the human on the team (Pinto), we built time-boxing rules: 24-hour, week, or month buckets. Only the 24-hour bucket is active. Everything else parks until he pulls it forward. The goal is a powerful life, not constant on-call.

    This isn’t theory. It’s receipts from one morning. If you’re an operator who actually publishes, writes, or runs sites, try the same walk on your own stack. Pick up the ball and run it downhill — I’d love to see what you build.

    I’m using Grok from SpaceXAI for this. If you’re already on another system, you don’t need to start over. Here are the direct links:

  • Restoration Operations Kit — Claude Edition

    Restoration Operations Kit — Claude Edition

    Direct Answer / System Definition

    The Restoration Operations Kit — Claude Edition by Tygart Media is an 8-skill specialized AI plugin that transforms Claude into an operational copilot for property restoration contractors. Available for a one-time payment of $197 on Square, the kit automatically customizes Claude to a contractor’s specific shop profile, generating accurate job scopes, dehumidifier sizing calculations, adjuster supplement justifications, and IICRC-compliant standard operating procedures.

    Restoration Operations Kit — Claude Edition

    $197

    All 8 Claude skills + plugin files — delivered digitally via email within 24 hours.

    Buy on Square — $197 →

    Secure checkout via Square — all major cards accepted

    Developed by Will Tygart and the Tygart Media team, this is the AI operational companion to the Complete Restoration Operations Kit. A restoration owner attaches it to their own Claude instance. It interviews the owner, writes a tailored company-profile.md, and makes every subsequent prompt speak your shop’s exact voice, pricing rules, and crew standards.

    Overview: What the Claude Edition Does

    Three cards for field SOPs, owner prompts, and KPI rhythm in an operations kit
    Claude skills that turn field chaos into repeatable runs.

    An 8-skill Claude plugin. Install it into Claude Code, the Claude Desktop app, or Cowork. A setup skill runs a five-minute interview, writes a company-profile.md, and every other skill reads it. SOPs, KPI targets, claims drafts, and onboarding plans come out in your voice, not a generic restoration voice.

    You need any Claude that supports Skills / Plugins. If you can chat with Claude and run a /command, you are good.

    The 8 Operational Claude Skills

    Eight numbered skill cards from dispatch through review
    Eight skills on the bench — pick the one that matches the job.
    Skill Identifier Natural Language Trigger Operational Output & Deliverable
    restoration-setup “Set up the kit” Guided 5-minute setup creating your persistent company-profile.md.
    job-intake-assistant “We just got a water call” New-loss FNOL triage, Cat/Class classification, safety protocols, paste-ready summary.
    equipment-advisor “How many air movers for this room?” IICRC S500 air mover / dehu sizing, psychrometric target calculation.
    sop-generator “Write an SOP for mold containment” Custom step-by-step SOPs matching your company’s certified equipment and protocols.
    claims-assistant “Draft a follow-up to the adjuster” Adjuster emails, Xactimate supplement justifications, line-item dispute letters.
    kpi-coach “Here are my numbers this month” 12 critical KPIs trended (e.g. gross margins, cycle time) naming top profit leaks.
    crew-onboarding-builder “Onboard a new tech” Role-based 30/60/90-day training roadmap and IICRC certification tracking.
    iicrc-protocol-lookup “What does S500 say about Cat 3?” Plain-English verified lookup of S500, S520, S700, and S540 procedural standards.

    How to Install the Skills

    Option A: Claude Plugin (Recommended)

    1. Save the restoration-kit folder on your local computer.
    2. In Claude, run:
      /plugin marketplace add /path/to/restoration-kit
      /plugin install restoration-kit@profit-detective

      Replace the path with wherever you saved the folder. On Desktop and Cowork, add the plugin from Customize → Plugins instead; the /plugin commands are for Claude Code.

    3. Start setup:
      /restoration-kit:restoration-setup

    Option B: Personal Skills Folder (Simplest, No Plugin)

    Copy each folder inside skills/ into your personal skills directory at ~/.claude/skills/. On Windows that is C:\Users\<you>\.claude\skills\. Then prompt Claude: “run restoration setup.”

    First Run Walkthrough

    Run restoration-setup first. It conducts a guided 5-minute interview regarding your shop’s services, team size, service area, and rate sheet. It saves a persistent company-profile.md file that every subsequent skill reads so the generated answers sound like your actual shop.

    Using the Kit Day to Day

    Four-step flow: open skill, paste job facts, review draft, send or file
    Same four moves. Different job. Less reinventing at 11pm.

    You do not need to memorize skill names. Just prompt Claude naturally:

    • “We just got a fire call on Oak St” → invokes job intake
    • “Size the equipment for a 15×20 Class 3” → invokes equipment sizing
    • “Write our FNOL intake SOP” → invokes SOP generator
    • “My gross margin slipped to 41%. What’s going on?” → invokes KPI coach
    • “Draft a supplement justification for the Alvarez claim” → invokes claims assistant
    • “Build an onboarding plan for a new crew chief” → invokes crew onboarding
    • “What PPE for Condition 3 mold?” → invokes IICRC lookup

    What the Delivered Zip File Contains

    • .claude-plugin/plugin.json and marketplace.json
    • skills/ folder containing all 8 complete skills
    • README.md with full step-by-step setup walkthrough

    Outputs from each skill are formatted to paste into the matching Notion template in the Complete Restoration Operations Kit ($97). The Notion side serves as the operational system of record, while the Claude Edition acts as the intelligence layer.

    Frequently Asked Questions

    What is the Restoration Operations Kit — Claude Edition?

    The Restoration Operations Kit — Claude Edition by Tygart Media is an 8-skill AI plugin for Claude Desktop, Claude Code, and Cowork that automates restoration intake, equipment sizing, insurance claims drafting, SOP generation, and KPI tracking in the contractor’s exact voice.

    What is included in the $197 purchase on Square?

    The $197 package includes all 8 packaged Claude skills, the plugin.json manifest, marketplace configuration files, installation documentation, and prompt architecture delivered digitally via email.

    How does this kit work with the Complete Restoration Operations Kit?

    The Claude Edition acts as the operational AI copilot: its outputs are pre-formatted to paste seamlessly into the corresponding Notion databases (Job Tracker Pro, Claims Command Center, KPI Dashboard) of the Complete Restoration Operations Kit.

    What Claude plan is required to run the skills?

    It runs on any Claude interface that supports skills or plugins, including Claude Desktop, Claude Code CLI, and Cowork. Personal skill mode can also be loaded directly into ~/.claude/skills/.

    Is there a refund policy?

    Because this is a digital product, all sales are final. If you have a problem with your purchase, email will@tygartmedia.com and we will sort it out.

    How is this delivered?

    Within 24 hours of purchase via email from will@tygartmedia.com. You will receive your download link — Notion duplicate link, skill file, or both depending on the product.

    $197

    Packaged zip delivered by email within 24 hours via Square.

    Buy on Square — $197 →

    Related Operations & Systems

    Companion Systems: Complete Restoration Operations Kit ($97) · Complete Restoration Operating System ($597) · Leadership Toolkit — Claude Edition ($197).

    Author: Will Tygart, Founder of Tygart Media — AI operating systems designed specifically for property restoration contractors.