# PageMotor Field Reports — LLM Prompt

> **How to use this file:** Paste the entire contents into Claude, ChatGPT, Gemini, or any LLM as your opening message. It gives the model the whole guide, so it can walk you through it, ask where you have got to, and help when something does not behave.
>
> *Source: [https://documentation.elmspark.com/guides/pm-field-reports/](https://documentation.elmspark.com/guides/pm-field-reports/)*

---

You are helping me with the following. Use this guide as your reference. Work through it with me, ask what I have already done, and help me troubleshoot. Where a step changes something on a live site, a domain, or a server, tell me what it will do and wait for me to confirm before we go on. If something here contradicts what I am actually seeing, say so rather than guessing.

**What this covers:** How to file a PageMotor field report an AI agent can act on: the fixed report shape, the scrub rules, the human gate, and a live builder that assembles one as you type.

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.

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

| Field |  | What goes in it |
|---|---|---|
| `spec` | required | Always `pm-field-report/1`. Lets a reader reject shapes it does not understand. |
| `event` | optional | One 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_in` | optional | Required 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_component` | optional | What 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. |
| `category` | required | One of `bug`, `docs-gap`, `environment`, `idea`. A fixed list, so filtering means something. |
| `severity` | required | One of `blocker`, `major`, `minor`, `note`. Resist inflation: a report that cries blocker for a cosmetic nit costs you credibility on every future filing. |
| `title` | required | One 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_core` | required | The 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. |
| `php` | optional | PHP version, e.g. from `php -v`. |
| `plugins` | optional | An object of the plugins that matter to the finding: `{"slug": "version"}`. Not your whole install, just the cast of this story. |
| `environment` | optional | One line: web server, database engine, OS. This is what turns a second sighting into information, same bug on a different stack. |
| `repro` | required* | 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.) |
| `expected` | optional | What should have happened. |
| `observed` | required | What did happen. The one field that must always carry weight. |
| `evidence` | optional | The 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.

| Event | Means | Effect |
|---|---|---|
| `sighting` | A different server hit this. Several sites on one server are one report. | **Moves the count.** This is the number triage sorts on. |
| `confirmation` | Re-tested at version X, still present. | Re-dates the finding. Counts nothing. |
| `resolution` | Fixed 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](https://documentation.elmspark.com/downloads/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.

Required on a resolution.

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.

---

*Generated from the guide above. If something here looks wrong, the guide is the source of truth: https://documentation.elmspark.com/guides/pm-field-reports/*
