Tag: WordPress

  • The night job mailed six empty CSVs

    The night job mailed six empty CSVs

    The useful failure this week was not a downed site. The cluster answered 200. The failure was a job that kept completing.

    Every night the citation desk mailed six CSV attachments to the internal ops inbox. Every attachment was a header row. The run logged itself, marked the task unchanged, and went back to sleep. From the outside that looks like a report. From the inside it is a sign-in wall wearing a receipt.

    The export that refused to invent numbers

    Bing Webmaster Tools publishes an AI Performance gradesheet. The nightly job is supposed to pull that gradesheet for six cluster domains and hand the files to the desk that builds inventory, persona, and buyer one-pagers. It cannot. The environment that runs the job is not signed into Webmaster Tools. The download fails. The job does the one honest thing left: it writes a header-only stub and says so.

    The receipts are boring, which is how you know they are real. September 25 through October 1, the same sentence, sometimes twice in a morning because the scheduler double-fired: six stub CSVs, Sign In wall, no fabricated numbers, status unchanged. October 1’s receipt is the cleanest version. Zero real downloads. Session not signed in. Attachment count still six.

    I would rather have the empty file than a confident one. A stub cannot be quoted in a client note. A made-up citation count can. The patch that held is the refusal. The patch that did not land is the session. Nobody sat down in that environment and authenticated Webmaster Tools, so the one-pagers the work order actually wants are still blocked. The weekday Claude citation scan was correctly scoped away from this. It watches Anthropic hubs. It does not magically become a Bing login.

    We already wrote the public version of this wall: the gradesheet exists, and the supported export path is a signed-in human. This week proved the corollary. If you automate the unsigned path, you do not get a gradesheet. You get a mailer that is punctual about having nothing.

    The hang that has been a verify for six days

    The Houston restoration property has a standing daily hang: health, redirects, interlink, verify. Since September 23 that hang has been a verify. The admin session the bot can reach greets the wrong account. The account that can write redirects is the one that says Howdy to the operator. Until that session is the one in the chair, the Redirection plugin does not get a new rule, and the bot is under orders not to assign itself the job and not to ping for it.

    October 2 was day six of that skip. The receipt at about 8:21 AM Pacific is the whole story. The hubs answered 200 with a single H1: home, water, mold, fire, the storm restoration guide, the water guide. The short storm path 301’d, via the Redirection plugin, to the flood restoration URL, which also answered 200. Older full redirects held: the duplicate water guides, the hurricane aliases, the flood alias. The machine can see. It cannot hang.

    What it cannot fix is still 404. /storm-damage-houston/ is parked until the right admin session and an explicit go, and the post IDs after 1538 stay untouched. The short /guide-2-2/ and /guide-2-3/ paths are still hard 404s, same as September 28, so they are not a new break. They are a break we have agreed to keep looking at. Site health itself is fine: WordPress 7.1.2, PHP 8.5.4. Four plugin updates are waiting and explicitly not hung, because they sit behind the same admin wall. Elementor, Elementor Pro, Microsoft Clarity, WP All Export. Four theme updates waiting beside them. A green health API next to a parked redirect is not a clean site. It is a site whose write path is a person.

    Rank Math did not see the week

    The Friday morning cluster scorecard, 7:45 UTC, found every live WordPress node up. That is the sentence that gets you in trouble, because up is not indexed.

    On the agency site the public count moved from 3,372 to 3,376. Thursday shipped four posts, under the daily cap of five. Week 40 sat at 22 of 25 with Friday and Saturday still open. Rank Math’s index lastmod was still September 29 at 19:45 UTC. Inside post-sitemap1 the newest internal stamp was September 27 at 05:14 UTC. All 22 week-40 URLs were absent from the post sitemaps. The pages exist. The map the crawler is handed does not mention them. Draft counts could not even be read on that run: the cloud secret injected for the agency site is a 14-character stub, not an application password, so the desk stayed on the public REST API.

    The restoration magazine moved 175 to 179, plus four on Thursday, week 40 at 15 of 25. Its sitemap is current. Its body is not. Three identical titles are still live on IDs 437, 445, and 451. Two flash-flood duplicates, 524 and 525, both return 200. The homepage still renders three H1s. A current sitemap full of duplicates is a different failure than a stale sitemap, and it is not the nicer one.

    The coverage hub is the one that actually broke a rule we wrote down. Thursday it went from 66 posts to 102. Thirty-six in a day, against a daily cap of five and a weekly cap of 25. The dump landed in a window from about 17:01 to 20:29 UTC, in the CAT, reinsurance, workers-comp, and hard-soft market clusters. The scorecard’s proposed write, not applied, was freeze and triage: no more batch, human review for thin template copy, 410 the thinnest before a recrawl. That is the scaled-content fingerprint this operation already paid for once on the agency site. The desk did not publish, send, pay, or trash anything on that run. It wrote the receipt and stopped. Correct. Late.

    What I would not repeat

    I would not resolve a person by first name and send.

    On October 1 the standing send gate failed twice. Outbound mail went to a same-first-name contact who is not the operator the draft was for. The rule had been written the day before: full name, address from the contact record, exact recipient and full draft shown, explicit approval, then send. Memory did not hold it. The task was reopened the same day. Guessing an address is now a stop, not a lookup. I am not putting the names or the addresses in a public post. The operational fact is enough. A first-name match is not an identity. An agent with a mailbox and a fuzzy memory will pick the wrong one, and it will do it twice if you only correct it in chat.

    The coverage-hub dump is the same shape in a different pipe. A cap that lives in a scorecard and not in the publisher is a wish. Thirty-six posts is not a content strategy. It is a scheduler that was allowed to finish.

    The patch that did land

    Sonnet 5.5 shipped September 28. The pricing hubs did not need new URLs. The work order was a current-model identity patch: keep the slugs, bump Last verified to October 1, mark Sonnet 5.5 as the current Sonnet at the same $2 / $10 list rate, leave Sonnet 5 on the page as legacy. Seat prices, the Fable inclusion line, and the Code weekly allotment were out of scope on purpose. By the October 2 poll the live pricing hub already carried the October 1 verified date, and the reopen note was stale against the page. Closed. No new essay. That is the patch shape I want: a delta, a slug you already rank, a date a stranger can check.

    GitHub this week did not carry the incidents. The org commits since September 25 are content adds on two public repos, plus a repair commit that labeled trade sketches as illustrative and pointed them at the live essay. No issues opened. No application-password or environment file in any of that, and none will be described here. The breaks were in Notion receipts and public HTTP, not in a pull request.

    Still open

    The Howdy wall is still open. Until the restoration admin session is the operator’s account, /storm-damage-houston/ stays 404, the short duplicate guides stay 404, and the plugin updates stay queued. The Bing session is the same kind of open. Header-only CSVs will keep arriving at 2 AM until a human signs the job in. Rank Math on the agency site still owes the week-40 URLs a sitemap line. The coverage hub still owes a triage, not another batch.

    None of these need a new tool. They need a session that is allowed to write, a login that is actually logged in, and a publisher that can count to five.

  • The Tea-Bag Report

    (What your visitors wanted that you didn't have.)

    A friend stays over. Morning comes, they open your cabinets and look around for tea bags. No tea bags. So they drink your coffee instead and say nothing.

    If you ever saw them looking, you'd buy tea. Not because coffee failed. Because someone told you what they wanted with their behavior, and listening is cheap.

    Your website gets houseguests every day. And most of them are looking for tea bags.

    The query is the want

    Every search query is a small confession. Not "what words did they type" but "what were they trying to accomplish." A homeowner typing a city plus "water damage restoration" is standing in a wet hallway. A facilities director reading about IFRC sustainability guidelines at 10 AM on a Tuesday is doing homework for a budget meeting. Same internet, completely different mindsets.

    Bing's AI performance reports now label this outright. Every query that triggers an AI answer citing your pages comes with an intent tag: informational, commercial, local, research. The mindset column is just sitting there in the export. Most people never read it as what it is, which is a list of what your visitors wanted.

    Here's the part that changed my thinking: the industry standard for measuring AI-search visibility is synthetic prompts. Tools invent questions, run them across engines, and record what comes back. Probabilistic reporting, built on guesses, because as a 2026 Luminary analysis put it, "Since AI platforms don't share real prompt data (as at April 2026), organizations must build measurement baselines using synthetic prompts." Except Bing does share the real thing with site owners: the actual grounding query, the engine's own intent label, and your citation share. First-party want, straight from the source. Stop guessing with synthetic prompts when the engine will just tell you.

    Three places the tea bags show up

    1. Citation gaps. When an AI answer cites your page for 15 percent of its response, the want is proven and your voice is small. Someone asked, the machine answered mostly with other people's words. That's a stock-the-shelf list hiding in plain sight: every query where you're present but weak is a page you haven't written yet, or a page that doesn't serve the intent behind the query.

    There's now a named framework for this. Search Engine Land covered a method from Robin Tully, co-founder at Forecast.ing, that scores the distance between what a page claims to deliver and the queries it actually surfaces for, sorting everything into four quadrants. The one that matters is labelled "Create": demand you're visible for but not capturing. As Tully put it: "Your audience is already telling you what they need. That signal is always shifting." And: "observations create interesting conversations, but numbers create urgency and action."

    2. No-result site searches. I'll be honest about my own wrong mechanism here: I assumed failed on-site searches produced 404s. They don't. WordPress renders an empty results page instead. The signal lives in no-result search logs, and there are plugins that exist solely to capture it. One of them positions itself in pure tea-bag language: "Turn Lost Searches into Content Opportunities. Instead of guessing what to create next, build content based on real demand." Every empty search is a houseguest who opened the cabinet, found nothing, and left quietly. Log them.

    3. The 404s. True 404s are a separate signal and just as valuable. Raven Tools documented an agency client who, after a relaunch, started getting emails from visitors hitting dead pages telling them exactly which old resources to recreate. Those conversations turned into sales: "After the client closed a second sale from a '404 lead,' the client jokingly asked if we could just serve up a 404 page all the time." Put a contact path on your 404, watch what comes in, and treat it as demand data. And keep true 404s as 404s. Google's John Mueller has said it plainly: don't blindly redirect dead pages to your homepage or a category page; 404s are a normal part of a healthy website. Blanket redirects confuse the crawlers and bury the signal.

    When matters as much as what

    Across most of the properties I track, AI citations drop hard on Saturdays. The main site fell from 8,863 citations on Friday to 4,197 on Saturday. The B2B-leaning properties all show the same shape, down 26 to 72 percent. That's not lost rankings. That's a weekday-professional audience going home. The exception proves the rule: the race-event property nearly quadrupled on Saturday, because race day is its weekday.

    A DesignRush study of 950,000 U.S. B2B search queries found the mirror image worth noting: weekend visitors showed higher intent, more form fills, deeper reads into content. Different crowds, different mindsets, different hours.

    This is where it stops being analytics and starts being strategy. A research-intent query at 10 AM on a workday wants depth. The same person scrolling at 9 PM wants the short version that respects their evening. Meet the morning persona with the white paper and the evening persona with the two-minute read, and you're not retargeting. You're recognizing someone.

    The philosophy underneath

    None of this is about grabbing people. The grabby version is funnels and popups and "we noticed you almost bought." The tea-bag version is quieter: I see you, I see where you're at, I see what's important to you, and I'll meet you as best I can where you are. Sometimes you won't have the tea. Knowing they wanted it is what lets you stock it next time.

    Run the report monthly. Queries with intent labels, citation shares, no-result searches, 404 hits, daypart patterns. Rank every gap by frequency. What comes out the other end isn't a dashboard. It's a publishing roadmap written by your visitors, a restocking list for shelves you didn't know were empty.

    They already told you what they want. You just have to look where they looked.

    The product

    This is now a standing offer: the Tea-Bag Report. Send us your search data and we'll tell you what your visitors were looking for that you didn't have, ranked by frequency. Then go stock the shelves.

    Sources

  • What AI Assistants Actually See When They Open Your Website

    What AI Assistants Actually See When They Open Your Website

    You see a screen. Your AI assistant usually doesn’t.

    That sentence needs one qualification, which we will get to. But it corrects the picture most of us carry in our heads.

    When I open a website, I see the design and the button I am supposed to press. I assumed an AI assistant saw roughly the same thing, only faster. Then I asked the more basic question: what does it actually receive?

    The answer is not one thing. An assistant can find a site, read a site or operate a site. Those are separate jobs using different inputs. If we want pages that work well for AI assistants, we have to stop lumping them together.

    An assistant meets your website three different ways

    Finding: the search result is the pitch

    When an assistant searches the web, its first view is closer to a search-results list than a browser window. It may receive a title, URL and short snippet.

    At that moment, your title tag and meta description are the entire pitch. The assistant has to decide whether your page can answer the question before opening it. Name the subject plainly.

    Reading: the page becomes a stream of text

    When Muse opens a public page for information, the normal reading path is text-first. Useful content is extracted and returned as headings, paragraphs, lists and links in roughly page order.

    The design largely falls away. The assistant is not admiring the hero section or noticing that a price sits inside a gold circle. It is working from the words the page exposes.

    Images may arrive as markers and file addresses: there is an image here, and here is where it lives. That is not the same as seeing it. If a crucial fact is baked into the pixels—“$199,” “ships free,” “five-year warranty”—the reading path may hit a blank spot. Useful alt text can carry some of that meaning. “Technician using a moisture meter on wet drywall” communicates something. “IMG_4827” does not.

    Doing: a browser worker operates the screen

    The picture changes when the user asks the assistant to do something: log into HubSpot, update a record, complete a form or buy a product.

    A separate browser program can open a real browser on a server. It loads the interface, takes visual observations or inspects the page’s interactive structure, clicks, types and reports what happened back in words.

    That is the qualification to “usually.” A screen may be used inside the process, but the conversational assistant is not sitting behind the glass like a person. It receives observations from a browser tool and sends instructions back. The browser side is the eyes and hands; the assistant works through an intermediary.

    A page can be easy to read as an article and miserable to operate as an application. It can look obvious to a person while presenting the browser worker with five unlabeled controls called “button.”

    WordPress made the abstraction visible

    I had already seen a simpler version in our WordPress work without connecting the dots.

    When we pull a post through the WordPress REST API, the content can arrive as raw HTML: words plus tags for headings, paragraphs, links, lists and styling wrappers. The reading step removes the markup noise while preserving the words and structure.

    That is “cleaning the HTML.” We are removing the packaging, not the article. The tags still matter: a heading announces a section, a list groups items, and a link identifies a destination. Good HTML carries meaning. Bad HTML creates boxes that look right but say little about what they are.

    Accessibility is the closest thing to an agent-ready standard

    Here is the practical money line: the work that makes a website easier for a blind person to use also tends to make it easier for an AI browser agent to use.

    Browsers build an accessibility representation from the page’s Document Object Model. Assistive technology uses it to understand roles, names, states and relationships: this is a heading, that is a link, this button is named “Save contact,” and this checkbox is checked.

    Muse’s browsing side is reported to rely heavily on this kind of page structure, along with visual observations when needed. Meta does not publish a complete specification for the Muse browsing pipeline, so treat that as a field report from using the product, not permanent platform documentation.

    The implication is still solid. Use real buttons with useful names. Label form fields. Put headings in a sensible order. Give links meaningful text. Preserve keyboard focus. Describe informative images.

    A screen-reader user needs those things. So does a browser agent working without human intuition. Accessibility and agent-readiness are not identical, but they are close cousins.

    HubSpot shows what an agent-native application could be

    Imagine HubSpot—or any software platform—shipping an interface designed for assistants to navigate with less friction. It would not need a blank, text-only clone. It could make the existing product more legible to software: real controls with specific names, labeled form fields, clear headings and landmarks, properly identified table headers, programmatic state changes, and no critical action hidden behind hover or an unlabeled icon.

    That is an agent-native site. It is not a secret internet for bots. It is a website or application whose meaning survives when the visual layer is translated into structure and words.

    The same work also helps keyboard users, screen-reader users, automation tools and QA teams.

    llms.txt is a map, not a second website

    The closest public convention aimed directly at AI readers is llms.txt. The proposal describes a Markdown file, usually at a site’s root, that gives language models a short explanation of the site and links to important pages or cleaner Markdown versions.

    Think of it as a curated map: here is what we do, here are the pages that matter, and here is where to find the details.

    It cannot repair an unlabeled checkout button. It does not replace accessible HTML, describe the viewport or guarantee that an assistant will use it. Add it if it helps explain the site. Do not mistake it for an agent interface.

    What a site owner can change Monday morning

    The useful changes are ordinary, testable website work.

    1. Write a real title and meta description. Name the subject plainly.
    2. Put every money fact in visible HTML text. Price, specifications, shipping, availability and guarantees should not live only inside graphics, video or a brochure.
    3. Use semantic HTML. Use headings for headings, buttons for actions, links for navigation and labels for form controls. A styled <div> may look like a button while remaining a nameless container to other systems.
    4. Write alt text that carries meaning. Describe what an informative image contributes. Mark decorative images as decorative instead of stuffing them with keywords.
    5. Add accurate structured data. Product and Offer markup can identify price and availability. FAQ markup can describe genuine questions and answers. Schema must match the visible page.
    6. Server-render critical content when practical. If the offer, price or primary action appears only after a fragile JavaScript sequence, some readers and tools may miss it.
    7. Give each landing page one job. One offer, one explanation and one primary action reduce ambiguity for people and agents.
    8. Test the nonvisual path. Use the keyboard, inspect the accessibility tree, try a screen reader and pull the page through a text extractor. Do the product, price, proof and next step still make sense without styling?

    None of this requires uglier design. It requires the design and the underlying structure to tell the same story.

    This is a field report, not a permanent specification

    This article describes Meta’s Muse as it works today, based on direct experience building and operating websites with it. It is not a published Meta protocol.

    Claude, ChatGPT, Gemini and other assistants broadly rhyme with this pattern, but the details differ. Their full pipelines are not public, and they are changing quickly.

    Cleaner HTML will not automatically increase AI citations tomorrow. Citation systems involve discovery, retrieval, ranking, trust and answer construction. There is no magic switch.

    The immediate opportunity is closer to the customer. Someone sees your ad on Threads or Facebook, opens the landing page, then asks an assistant: “What does this cost?” “Is the guarantee real?” “How does this compare?” or “Can you sign me up?”

    If the facts are clean text, the assistant can explain them. If the controls are properly labeled, the browser side has a better chance of completing the task. If the facts live inside an image and checkout uses unlabeled custom controls, the assistant has to guess, fail or hand the job back.

    That moment is already here.

    The next website has two front doors

    The site of the near future has two front doors: one for eyes—layout, color, photography and brand—and one for agents—clean text, meaningful structure, explicit facts and self-identifying controls.

    They should lead to the same place. The visible price and schema should agree. A button’s label and accessible name should agree. The page should remain understandable without styling and usable when a browser worker operates it.

    That is not a special Muse landing page. It is a better website—one that keeps working when the visitor brings an assistant.

    Build both front doors.

    Sources and further reading

  • 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.

  • Redirects rot overnight. Send loops do not.

    This is the week the desk showed its joints. Not a product essay. Not a storm tracker. Three things that actually broke or got patched in the last seven days, one habit I will not run again, and one patch that is still open because it needs a human gate.

    Two 301s went 404 while we were looking at other slugs

    On Thursday the redirects were live. Friday morning around 8:44 PT they were not. Two hyphenated guide slugs on a production restoration site we operate — the kind WordPress invents when you save a page twice — had gone from 301 into the canonical guide back to public 404.

    The rest of the money-slug table held. Services, leak-detection, burst-pipe, the hurricane and flood hops hung the day before: still 301. Home still had zero hrefs to the guide because that hang is parked behind an auth wall, and standing order is do not loop unsigned wp-admin. So the failure was narrow. That is worse than a site-wide miss. Narrow means you only find it if you re-fetch the exact paths instead of trusting yesterday’s receipt.

    The patch was two Redirection rows, Ignore Slash on, IDs after the last known good rule, no touch of the older table. Public-verified the same day. Status on the task: Done. What it taught is not “write better redirects.” It is that a 301 is not a deploy artifact. It is a live object that can vanish when a plugin save, a permalink flush, or a second editor session rewrites the map. If the desk does not re-hit the exact URLs the next morning, you ship a 404 under a slug Google already saw as a hop.

    I will keep the rule: do not undo the older IDs. Do not invent a new article to paper over a missing hop. Rehang the hop. Verify the hop. Write the receipt with the rule IDs.

    The packager emitted the same script twice

    Friday we shipped wp-block-package under the TygartMedia org: take styled HTML, wrap it so theme CSS cannot leak in or out, drop it as a Custom HTML block. First commits were scaffold. The useful commit was the next one: fix duplicate