Files
chemenu/instructions/bug-report.md
T
torben f9c047bd2e
CI / verify (push) Successful in 2m11s
Release / release (push) Successful in 38s
feat: bug-report collector tools/bugreport.py and instructions/bug-report.md (#157)
Files changed:
- .gitea/workflows/ci.yml
- CHANGES.md
- INSTALL.md
- VERSION
- instructions/bug-report.md
- instructions/gates.md
- instructions/setup-instance.md
- instructions/upgrade-instance.md
- reports/CONTRACT.md
- tools/README.md
- tools/bugreport.py
- tools/chemenu/tests/test_bugreport.py
2026-09-30 17:29:39 +02:00

136 lines
6.9 KiB
Markdown

---
type: types/instruction.md
name: bug-report
description: How to collect a bug-report bundle when the stack misbehaves on this machine - run tools/bugreport.py, write a fact-only chronology, tell the user what the bundle contains, and stop short of sending it anywhere.
manual: true
---
# Collect a bug report
When setup, an upgrade or a command fails on one machine and works on another, the person who has to
fix it sees nothing of what happened here. This procedure produces one bundle that answers the first
round of their questions - which machine, which Python, which shell, which harness, what the stack
looked like, what `wikitool` printed - so that the report is not a guessing game.
**Run this only when asked, by name, or when the user agrees to it after a failure.** It is
`manual: true` on purpose: the bundle contains private data, and whether to produce one is the
user's decision, not the agent's. Nothing links to this file from `AGENTS.md` or a skill, apart from
the pointers at the failure decision points of [setup-instance.md](setup-instance.md) and
[upgrade-instance.md](upgrade-instance.md), which only offer it.
<!-- wikitool:toc -->
## Contents
- [What the bundle holds](#what-the-bundle-holds)
- [When to run](#when-to-run)
- [Steps](#steps)
- [Chronology template](#chronology-template)
- [Decision points](#decision-points)
- [Scope](#scope)
<!-- /wikitool:toc -->
## What the bundle holds
`tools/bugreport.py` is a standalone script. It uses the standard library only and imports nothing
from the stack, so it still runs when `wikitool` does not start - no venv, a broken package, a Python
that is too old for the stack. It writes `reports/bugreport-<UTC stamp>/` and a zip beside it, in
four layers:
| Layer | Files | Holds |
|-------|-------|-------|
| 1 Environment | `environment.json` | OS, every Python and shell found, harness, `PATH`, environment variable names (values only for a fixed list), git configuration, venv, line endings, on Windows also long paths, execution policy and mark-of-the-web |
| 2 Stack | `stack.json`, `tree-structure.json` | `VERSION`, the `.wikitool-*.json` files with secrets removed, git status and the last commits, and the shape of `kb/` and `raw/` (counts, depths, path lengths, names that break on Windows) |
| 3 wikitool | `wikitool/*.txt`, `trace.jsonl` | Verbatim output of `version show`, `doctor`, `budget status`, `instructions verify` and `docs verify`, and the caller's session trace. If `version show` fails, `wikitool` counts as not started and nothing else runs |
| 4 Chronology | `CHRONOLOGY.md`, `transcripts/` | What the agent did and saw, and harness transcripts if the user asked for them |
`MANIFEST.md` lists every file and marks the ones that may contain page content and titles: the trace,
the chronology and the transcripts.
Two rules hold for everything the script generates itself. **Secrets are always removed**: values of
keys that look like a token, password, secret, key or auth entry, credentials in URLs, and every value
of that kind found while collecting is also replaced wherever else it turns up. **Page titles are kept
out** unless `--titles` is given: paths under `kb/` and `raw/` are replaced by their shape
(depth, length, whether they hold a space or a non-ASCII character) and `[[wikilinks]]` by the same
flags. A title that stands as bare prose is not found - which is why the trace, the chronology and the
transcripts are marked instead.
## When to run
- Setup or an upgrade failed and the user wants to report it.
- A command fails in a way that looks tied to the machine, and the user asks for a report.
- The user asks for a bug report by name.
## Steps
1. **Tell the user what is about to happen**, in the instance's KB language: a bundle will be written
under `reports/`, it is not pseudonymised, it holds machine, user and path names and the git
remotes, and it is not sent anywhere. Ask whether the session trace, page titles and transcripts
may go in. The defaults are: trace in, titles out, no transcripts.
2. **Write the chronology** to a file under `reports/` (which is gitignored) from the
[template](#chronology-template) below. Facts only - no diagnosis. If the session's own history is
too long to reconstruct, say what is missing instead of filling the gap.
3. **Run the collector**, with whichever Python 3.8 or later the machine has:
```bash
python3 tools/bugreport.py --chronology reports/chronology.md
```
Add `--no-trace` if the user declined the trace, `--titles` if titles may stay,
`--transcript <file>` (repeatable) for a transcript the user pointed at, `--session <id>` to take a
trace other than the caller's. `python3` may be `python` or `py -3` on Windows. If no Python starts
at all, that is the report: give the user the exact error text, verbatim.
4. **Do not imitate the collector's session id.** It runs its counting `wikitool` calls under
`WIKITOOL_SESSION_ID=bugreport-<stamp>` itself; do not export that variable, or any `bugreport-*`
one, in the session. The exception it gets in [gates.md](gates.md) § "Taking a new session id"
belongs to the script alone.
5. **Report the result.** Quote the bundle path, the archive path and the privacy notice the script
prints, name the gaps in `MANIFEST.md`, and tell the user to read the bundle before sharing it.
Then stop: the channel - a tracker issue, an email, a chat - is the user's choice, and the agent
never uploads the bundle.
## Chronology template
```markdown
# Chronology
## Goal
One sentence: what the user asked for, e.g. "Set up a new instance from a fresh clone."
## Environment as the agent saw it
Harness, shell, OS, anything the user said about the machine that the collector cannot know.
## Steps
1. `<exact command>` - exit code, and the first line of the error or output that mattered, verbatim.
2. ...
## Expected and observed
- Expected: what the instruction said would happen.
- Observed: what happened instead, verbatim where it is short.
## Changes made by hand
Every file edited or created outside a `wikitool` command, and every setting changed, in order.
## Not known
What the agent could not find out, or did not check.
```
Facts only: no page content, no guessed cause, no advice.
## Decision points
- **The user declines the trace?** Run with `--no-trace`. The manifest records the exclusion.
- **The user wants the report to name pages?** Run with `--titles`; the bundle then also carries
`tree-paths.txt`, which lists every path under `kb/` and `raw/`.
- **The collector exits 1?** It could not write the bundle (a missing input file, a full disk). Read
the message, fix the cause, retry once, then report the exact error.
- **A `wikitool` output in the bundle looks wrong or refuses to run?** Do not re-run it to see more.
The bundle records what happened; that is the report.
## Scope
Covers producing the bundle. It does not cover reading a bundle someone else sent, triaging the
report, or filing it - all of that is the maintainer's side and the user's choice of channel.