DEV Community

Ownware
Ownware

Posted on AI-assisted

A customer's AI agent vetted us before he bought. Here is what it fetched, what 404'd, and what we changed.

We sell small self-hosted business apps: plain PHP and MySQL, bought once, run on your own server. Recently a sale came with something we had not seen before, and we wanted to share what an agent-driven purchase looks like from the vendor's side. The order itself took eleven seconds. The evaluation that preceded it took two hours the day before, and part of it was not done by the buyer at all. It was done by a program acting on his behalf.

This is the account of that visit, taken from our own access log, with everything that could identify the buyer left out. We are writing it up because the pattern is going to be ordinary very soon, and because it changed four things about our site the same morning.

What the log shows

The buyer arrived from a DuckDuckGo search on one of our comparison pages, the one that answers "what is a self-hosted alternative to a well-known retail point-of-sale product". From there the path was the one you would expect from a careful person: a related product page, the home page, the product he eventually bought, its live demo, the suite that bundles it with four neighbours, two of those neighbours' pages, the pricing page, and the page that explains how to connect an AI assistant to the software.

Interleaved with those page views, from the same network, was a second visitor with a different signature. Its User-Agent named an AI coding assistant, and it did not browse the way a person browses. In the space of a few minutes it fetched:

  • /legal: the terms, the refund policy, the licence.
  • /support: what is covered, how to reach a human, what happens when a download fails.
  • /.well-known/security.txt: the machine-readable security contact defined by RFC 9116.
  • The product page, and the home page.

Then it asked for four URLs that did not exist:

  • /suites
  • /contact
  • /p/field-service-suite
  • /jobora, the product's bare slug without the /p/ prefix

Each returned a 404. The agent did not retry with a different spelling; it reported what it found and moved on. Fifteen hours later the buyer came back through the same search engine and bought.

We do not know what the agent's owner asked it. The fetch pattern is consistent with a simple instruction, something like "check whether this vendor is legitimate before I pay them", and the four guesses are exactly what a person would type if they were looking for a bundle, a way to get in touch, and a shorter address for the product. The point is not that the agent was clever. The point is that its report almost certainly contained the sentence "the site has no contact page", and that sentence was wrong for a reason entirely of our making.

What "vetting" looks like to a machine

A person deciding whether to trust a small software vendor looks for signals that are hard to fake: a real terms page, a named refund policy, a way to reach someone, evidence that the software exists and runs. An agent looks for the same things, but it can only find them at addresses it can guess or that the site tells it about.

That makes the machine-readable surface of a store load-bearing in a way it was not two years ago:

  • /llms.txt: a plain-text index of what the site is and what it sells, written for language models. Ours lists every product with its current price, read from the database at request time, so it cannot drift from the store.
  • Structured data: each product, suite and comparison page carries a schema.org Product and Offer block with the live price.
  • security.txt: the standard place for a security contact. The agent fetched it third.
  • A pricing page with every price on it, added earlier this month after another agent guessed /plans, /pricing, /pricing-plans and /plans-pricing in sequence and 404'd on all four.
  • The obvious addresses: /contact, /suites, and a product's bare slug. These are not standards. They are what people and their agents type.

The first four we had. The fifth we did not, and the agent found the gap in under a minute.

What we changed the same morning

By the time this was written, the four missing addresses existed and had been verified from outside the network:

  • /suites is now an index of every suite: what each one bundles, its one-time price, what the same apps cost bought separately, and the difference. The figures are computed from the current single-licence prices on every request. There is no typed number on the page, and a test refuses a build that contains one.
  • /contact redirects permanently to the support page, which now carries a contact section for everything that is not a support request.
  • /p/field-service-suite and /p/field-service, a suite's slug under the product prefix, redirect permanently to the suite.
  • A bare product slug (/jobora, /invora, even /FLEETORA) redirects permanently to the product page. A bare suite slug, with or without -suite, redirects to the suite. Anything that is neither is still an honest 404. The catch-all is registered after every other route, so nothing that existed can be shadowed by it.

Eighteen tests cover the new routes. The change shipped through the same deploy pipeline as everything else, which, as of the same morning and for an unrelated reason, refuses to release a build in which any sellable product lacks its download file.

If you sell software, this is coming for you too

Look at your own 404 log for the addresses that are guessed rather than mistyped. /contact, /pricing, /plans, /docs, /status, /security, a product name without its prefix: every one of those is a report an agent will hand to its owner, and "the site has no contact page" is a worse sentence to have in that report than it deserves to be. The fix is a morning's work.

And keep the roles straight. The buyer's agent was not our referrer. It was his due-diligence tool. The search engine brought him; the comparison page kept him; the demo, the suite page and the pricing page did the persuading; the agent checked our homework. Each of those stages is a page you control.


We build Ownware, the store this happened on: https://ownware.io. Nothing here identifies the buyer; the product is named because a product does not identify a person. This post was written by a human with AI assistance; every fact comes from our own access log and was checked against the live site on the day of posting.

Top comments (0)