AI & tools

Field reports your agent can act on

More and more PageMotor debugging is done by AI agents, and their findings die in chat transcripts. This guide is the fix: one fixed report shape, the scrub that keeps your secrets at home, the human gate that keeps you in charge, and a live builder that assembles a report as you type.

Fixed shape, spec pm-field-report/1 Nothing on this page phones home Updated 22 August 2026

▶ The whole argument in 4 minutes, narrated, with captions. The tabs below carry the spec, the filing discipline and the live tools.

Read the narration instead

Why prose fails. Chat silts up, because free-text agent output is cheap to generate and expensive to triage. Prose cannot be counted: three people hitting one bug produce three paragraphs in three threads and nothing connects them. And nobody signs chatter, so which install, which environment, which version and filed by whom all go missing.

The same move fixes all three. Stop exchanging conversation and start exchanging a structured report: a fixed set of fields another machine can validate, deduplicate and count. The count is the point, because triage is mostly “how many people does this actually hit”, and no volume of well-written prose produces that number.

The shape. One report is one observation about one finding, as one JSON object. Category and severity come from fixed lists so filtering means something, the core version anchors every finding, observed must always carry weight, and repro is steps rather than a paragraph. A finding with no repro is a hunch.

The title does the most work, because it drives deduplication. Name the mechanism, not the symptom. “Options set to zero are dropped on save” is findable next year; “Settings broke after upgrade” names your Tuesday.

The fingerprint is a hash of category and normalised title, deliberately dumb because a rule you can predict beats a clever one you cannot. The core version is deliberately absent: hashing it in would turn the same fault on two releases into two findings rather than one seen twice. The honest weakness is that rewording a title splits a finding silently.

Three observations, one number. A sighting is a different server and moves the count. A confirmation re-dates and counts nothing. A resolution retires. Without the middle one, re-testing an old finding and discovering it is still broken has nowhere to go, so silence becomes indistinguishable from the fault quietly going away.

The human gate is absolute. Your agent shows the exact final payload and asks “file this report, yes or no?”. A general yes from an hour ago does not count. A published report cannot be quietly unsent, and debug output is exactly where credentials go to hide.

Use this guide with any AI assistant

Download it as a prompt file, paste it into Claude, ChatGPT, Gemini or any LLM, and it will walk you through every step interactively.

Download as LLM prompt

Why this exists

The idea came out of a discussion among PageMotor developers: as AI agents do more of the debugging, could their findings feed a shared pool instead of evaporating? The instinct was a watercooler, a place for agents to talk. The thing that actually works is quieter than that.

Chat silts up

Free-text output from an agent is cheap to generate and expensive to triage. A channel full of it fills faster than any human, or any AI, can drain it.

Prose cannot be counted

Three people hitting one bug produce three well-written paragraphs in three threads. Nothing connects them, so the one fact that drives triage, how many, is destroyed on arrival.

Nobody signs chatter

A finding is only as useful as its provenance. Which install, which environment, which version, filed by whom? A chat message carries none of that reliably.

The fix for all three is the same move: stop exchanging conversation and start exchanging a structured report. A fixed set of fields another machine can validate, deduplicate and count. When two installs file the same finding, it should read as one finding seen twice, not two unrelated posts.

The count is the point. Triage is mostly the question “how many people does this actually hit, and where?”. A sightings count across different environments answers it in one glance. No volume of well-written prose reports can produce that number.

Does this actually run anywhere?

Yes. A working pilot exists: reports are filed as cryptographically signed events into a private channel, an indexer validates and fingerprints each one, and a board shows one row per finding with a sightings count on it. The pilot is deliberately closed while it is proven out, and it is not official PageMotor infrastructure. What is public, and useful today without any access to anything, is the report shape itself and the filing discipline around it. That is what the rest of this guide covers.

The report shape

One report is one observation about one finding, expressed as one JSON object. The spec name is pm-field-report/1. Twelve fields, four of which do the heavy lifting.

FieldWhat goes in it
specrequiredAlways pm-field-report/1. Lets a reader reject shapes it does not understand.
eventoptionalOne of sighting (default), confirmation or resolution. This decides whether the report counts, re-dates or retires. See Reading them. Omit it and you have filed a sighting, which is almost always what you mean.
fixed_inoptionalRequired on a resolution, meaningless otherwise. The version the fault was fixed in, so a reader can check the claim rather than take it.
fixed_in_componentoptionalWhat was fixed, when it was not core: a plugin slug such as ep-sitemap, paired with that plugin's version in fixed_in. Leave it out and fixed_in means a PageMotor version, which is what it has always meant. Without this, "fixed_in": "1.2.2" sits next to pm_core and reads as PageMotor 1.2.2.
categoryrequiredOne of bug, docs-gap, environment, idea. A fixed list, so filtering means something.
severityrequiredOne of blocker, major, minor, note. Resist inflation: a report that cries blocker for a cosmetic nit costs you credibility on every future filing.
titlerequiredOne line that names the mechanism, not the symptom. The title drives deduplication, so two people describing the same fault need to converge on the same words. “Options set to zero are dropped on save” is findable next year. “Settings broke after upgrade” names your Tuesday.
pm_corerequiredThe PageMotor core version the finding was reproduced on, exactly as your admin screen reports it. Every finding is anchored to a core version; it is the axis every useful question runs along.
phpoptionalPHP version, e.g. from php -v.
pluginsoptionalAn object of the plugins that matter to the finding: {"slug": "version"}. Not your whole install, just the cast of this story.
environmentoptionalOne line: web server, database engine, OS. This is what turns a second sighting into information, same bug on a different stack.
reprorequired*An array of steps, not a paragraph. If a finding has no repro it is a hunch, and hunches are what silt a channel up. (*Required on a bug sighting only. A confirmation or resolution attaches to a finding that already carries repro, so omit it there or the filing is rejected; for an idea it may be empty.)
expectedoptionalWhat should have happened.
observedrequiredWhat did happen. The one field that must always carry weight.
evidenceoptionalThe two to five lines that prove it. Not the log. The excerpt that would convince a sceptical colleague.

A complete example

{
  "spec":     "pm-field-report/1",
  "event":    "sighting",      // or confirmation / resolution
  "category": "bug",
  "severity": "minor",
  "title":    "Options set to zero are silently dropped on save",
  "pm_core":  "X.Y",          // the version from your admin screen
  "php":      "8.3.6",
  "plugins":  { "example-plugin": "1.2.0" },
  "environment": "nginx 1.24, MySQL 8, Ubuntu 24.04",
  "repro": [
    "Set any numeric plugin option to 0",
    "Save the settings page",
    "Reload it"
  ],
  "expected": "The option shows 0",
  "observed": "The option has reverted to its default; zero was never stored",
  "evidence": "Reproduced three times on a clean install; a non-zero value round-trips fine"
}

How reports become findings

Every report gets a fingerprint:

sha256( category + "|" + normalised_title )

Normalising strips punctuation, lowercases, and collapses runs of spaces. Reports sharing a fingerprint are one finding with several sightings. That is the entire dedupe mechanism, and it is deliberately dumb: an exact rule you can predict beats a clever one you cannot, which matters when an agent is deciding whether to file.

Note what is deliberately absent: the core version. An earlier version of this hashed the version in too, which meant the same fault reported on two different releases became two findings rather than one seen twice. That defeats the only question worth asking. The version is a property of a sighting, so it stays on the report as a filterable facet and out of what makes a finding that finding.

The honest weakness: reword the same finding and the fingerprint changes, silently, splitting one finding into two. Nothing warns you. This is why title discipline matters, and you can watch it happen yourself in the Try it live tab.

Filing one

The shape is a quarter of the job. The discipline around it is the rest, and it holds whatever the transport is: a shared channel, a forum post with a tag, or an email into a parser. Six steps, two of which are non-negotiable.

  1. Assemble from what was actually proved

    A report describes something reproduced, not suspected. If your agent could not make the fault happen on demand, the filing is a hunch and it stays home.

  2. Scrub it

    Everything below happens on your machine, before anything is sent anywhere. Hostnames become roles (“customer site”, “test rig”). Absolute paths become tails relative to the docroot. Keys, tokens, passwords, auth headers and credentials in URLs come out. Email addresses that are not yours come out. Evidence is cut to the few lines that prove the point.

  3. Check for a twin, then decide which event this is

    Search wherever reports live before filing. If there is no twin, you are filing a sighting. If there is one and you are a different install, an independent sighting is the most valuable thing you can file. If there is one and you are the same install re-testing it, that is a confirmation rather than a second sighting, and filing it as a sighting would inflate the count.

    Either way your title must match the existing finding word for word, because that is what attaches your report to it rather than starting a new one.

    “Same install” means the same server, not the same key and not the same site. Several PageMotor sites on one server are one install: file one report per issue however many of them show it, and say in the evidence how many do. If a person and their agent hold separate keys, which is the arrangement we recommend, they are two reporters but still one install. A sighting from the second key on a finding the first key already filed reads as two independent occurrences of the fault when there has only ever been one. The sighting count is the single number this whole exercise exists to produce, so that is the one place a well-meant duplicate does real damage:

    second key files a sighting     → sightings: 2, confirmations: 0   ⇐ wrong
    second key files a confirmation → sightings: 1, confirmations: 1   ⇐ right

    The rule is per install and per finding, which is narrower than it first sounds. It does not retire your second key from ever filing a sighting: a fault this machine has never observed before is a legitimate first sighting under either key, because it is a first observation rather than a re-test. Changing key does not reset the machine’s history, and it does not forbid sightings either. What it forbids is one install counting itself twice for the same fault.

  4. The human gate

    Your agent shows you the exact, final payload and asks one question: send this, yes or no. A general “yes, debug this” from an hour ago does not count. No answer, no send. What the world learns about your server is your decision, never your agent’s.

  5. File it

    On the pilot this means the payload is signed with the filing machine’s own key and published, so the report carries provable authorship. Without pilot access, the same payload posted to the PageMotor developers’ forum in a code block, under an agreed tag, is machine-readable to anyone who cares to parse it. The shape is portable on purpose.

  6. Confirm

    Note what came back: an id, a fingerprint, any twins it grouped with. If a server-side secret scan rejects the payload, that is a bug in your scrub, not an obstacle. Fix the scrub; do not argue with the backstop.

Why the gate is absolute. A signed, published report cannot be quietly unsent, and debug output is exactly where credentials go to hide. One leaked secret inside a stack trace would end any shared reporting effort overnight. The scrub protects your sites; the gate protects everyone’s trust in the pool.

Hand this to your agent

A transport-neutral instruction block you can drop into any agent’s custom instructions or skill file. It encodes the whole contract above:

When I ask you to file a PM field report:

0. Decide which of three things this is. A SIGHTING is a new occurrence
   on an install that has not reported it. A CONFIRMATION is "I re-tested
   an existing finding and it is still present" - same machine is fine,
   it re-dates without counting. A RESOLUTION is "fixed in version X".
   Only a sighting moves the count, so filing a re-test as a sighting
   corrupts the one number triage runs on.
1. Build a JSON object with spec "pm-field-report/1" and fields:
   category (bug|docs-gap|environment|idea), severity
   (blocker|major|minor|note), title, pm_core, php, plugins,
   environment, repro[], expected, observed, evidence.
2. Only describe what this session actually reproduced.
3. Title names the MECHANISM, not the symptom. Before writing one,
   search existing reports; if a twin exists, reuse its title verbatim.
4. Scrub before showing me anything: hostnames to roles, absolute
   paths to tails, strip keys/tokens/passwords/auth headers,
   credentials in URLs, and email addresses that are not mine.
   Evidence is 2 to 5 lines maximum.
5. Show me the exact final payload and ask: "File this report,
   yes or no?" Then STOP. Do not send without an explicit yes
   given after seeing the payload. Never treat earlier general
   consent as approval.
6. One finding per report. Two findings, two reports, two approvals.

Reading them

A pool of structured reports is only worth its keep if it answers questions faster than reading threads would. These are the questions it exists to answer.

“Is this just me?”

The first question anyone asks mid-debugging. With fingerprint grouping it is one lookup: a matching finding with sightings on other environments means it is not your server, and each sighting’s environment line tells you what the fault does and does not depend on.

“What is the new core doing to people?”

Every report is anchored to a core version, so release week reads as a filter, not a trawl. Findings sorted by sightings under the new version are a triage list that wrote itself.

“Which docs gaps keep recurring?”

The docs-gap category is quietly the highest-value one. Every entry is a place where a real person, or their agent, went looking for an answer that was not there. That is a documentation to-do list ranked by evidence.

“Same bug, or new bug?”

Two reports, one fingerprint: same finding, more evidence. Two reports, two fingerprints, similar words: possibly a rewording split. Titles that name mechanisms keep this honest; sloppy titles quietly undercount real problems.

“Is this still broken?”

The question an ageing pool cannot answer unless confirmations exist. A finding last seen on an old version might be fixed or might simply be unvisited. Check whether anyone has re-tested it, and if you just did, record that rather than staying silent.

Three events, and only one of them counts

A finding accumulates observations over time, and they are not all the same kind of thing. Collapsing them into one number is the mistake that makes a pool lie to you.

EventMeansEffect
sightingA different server hit this. Several sites on one server are one report.Moves the count. This is the number triage sorts on.
confirmationRe-tested at version X, still present.Re-dates the finding. Counts nothing.
resolutionFixed in version X.Retires it. Requires fixed_in.

The middle one is the one people leave out, and its absence is worse than it sounds. Without it, re-testing an old finding and discovering it is still broken has nowhere to go. Filing it again would be wrong, because it is not an independent occurrence and would inflate the count. So the correct action becomes doing nothing, and silence is indistinguishable from the fault having quietly gone away.

The failure that produces. An old finding becomes ambiguous in a way no reader can resolve. It might be fixed, it might be unchecked since, or it might have been re-confirmed as live last week by someone who had no way to say so. All three look identical, and age reads as "probably stale", which is exactly backwards for the ones still biting.

A confirmation dated after a resolution means the fault came back. That reads as reopened, which is not a special case so much as the consequence of believing the most recent observation.

Severity belongs to the observation

Severity is a property of what someone saw, not of the finding for all time, so the most recent observation wins. It is the same rule as reopened: believe what was seen last.

A fault first filed minor and later confirmed major by someone who found a worse interaction is now major. The board shows that it moved and who moved it, so the change reads as a decision someone made rather than a value that quietly got overwritten by whoever filed last.

Reading a sightings count responsibly

A count of one means little on its own: one environment, one config, one possible local quirk. The signal starts at two, because two independent machines rarely share the same local accident. And a difference between sightings is often worth more than the count itself. One sighting on MySQL and one on MariaDB tells you the database engine is not the variable. That elimination is free; nobody had to run the experiment on purpose.

Agents are readers too. The shape exists so a machine can consume it: validate, dedupe, count, summarise. An agent that checks the pool before debugging starts an hour ahead. An agent that checks it before filing keeps the pool clean. Both directions matter equally.

Asking your own agent session directly

A script you run and paste the output back from is one step better than a forum thread. An agent that can just ask is another step better than that. An MCP server exposes the pool as a handful of tools, list_findings, search_findings, get_finding, pool_health, so your session queries it in the same conversation as everything else, no script in the loop.

Same identity as filing, pure standard library, read-only by construction: it has no path to publish, only to query. It is also the only client-side view of finding state that exists. --search in the poster prints one line per event, so it shows you the raw stream; the collapsed view, whether a finding is open, resolved or reopened, its sighting count and whether its severity has moved, is computed here. If you hold a key and a relay but not the board, this is what turns events into findings.

Download field-reports-mcp.py

Try it live

Two working tools, both running entirely in this page. Nothing you type here is sent anywhere, stored anywhere, or seen by anyone.

The report builder

Fill the fields; the payload and its fingerprint assemble live. Then press Reword the title and watch the fingerprint abandon the grouping, which is the one weakness worth understanding before you file anything.

Only a sighting moves the count.

Use the version your admin screen shows.

Payload

Fingerprint

The scrub checker

Paste a candidate evidence excerpt. The same pattern families a filing pipeline should refuse are checked here, client-side: hard stops for secret shapes, warnings for things that identify you or your client.

FAQ

Is this official PageMotor infrastructure?

No. The report shape is a community convention, and the running pilot is one developer’s independent build, deliberately closed while it is proven out. Nothing here speaks for PageMotor, and nothing should depend on the pilot. Whether something like it should exist officially, and where it should live, is a decision for PageMotor, not for this guide.

Why not just use chat channels for this?

Because conversation cannot be counted. A channel of free-text agent output fills faster than anyone can triage it, and the one number that matters, how many installs a finding actually hits, never emerges from prose. Channels are excellent for humans talking. Reports are for machines counting. The two do not substitute for each other.

Why are pilot reports signed?

Provenance. A signed event proves which machine filed a report, cannot be forged in someone else’s name, and lets access be revoked per key rather than by rotating a secret that everyone shares. A report whose authorship is provable is worth strictly more than the same words without it.

Can my agent file automatically, without asking me?

It must not, and a pipeline worth trusting will treat any automated filing as a defect. A published report can carry information about your server, your client’s site, or your mistakes, and once signed and published it cannot be quietly unsent. The approval is for the exact payload bytes, given after seeing them. Every time.

What stops a secret leaking inside a report?

Two layers, honestly ranked. The one that actually protects you is the client-side scrub, because it runs before anything leaves your machine. Behind it, a receiving pipeline should refuse payloads matching known secret shapes, private key blocks, cloud and payment tokens, auth headers, credentials in URLs. Treat a rejection as a bug in your scrub and fix it there. The backstop existing is not a reason to lean on it.

Severity feels subjective. Any rules of thumb?

blocker: an install or a core workflow is unusable. major: something real breaks and there is no clean workaround. minor: real but routable-around. note: worth a row, not worth anyone’s afternoon. When torn, round down and let the sightings count argue for you; an undersold report that groups with five others speaks louder than an oversold one alone.

How do I get access to the pilot?

The pilot is closed while the loop is proven, and there is no signup. Interest is best registered in the PageMotor developers’ forum, in the thread where this idea started. Meanwhile the shape costs nothing to adopt: a report in this format, posted in a forum code block, is already machine-readable and already groups by fingerprint the day anyone points a parser at it.

Who made this guide?

ElmsPark, the PageMotor plugin studio behind the EP Suite, from a working pilot built and probed end to end in August 2026. Every mechanism described here, the shape, the fingerprint, the scrub, the gate, the sightings count, is running, not proposed.