## Summary
Two workflow additions to `CLAUDE.md`, with the detail in `dev-docs/`, plus a GitHub issue form.
### Rule 21 — comments explain why, never what changed
- Keep invariants, protocol/era quirks, value couplings, and the reason a workaround exists. One line where one line will do.
- Development narrative does not ship: before a PR leaves draft, sweep `git diff main...HEAD` for added comments and remove change history ("previously", "changed from"), review dialogue ("per review"), hedges ("I think"), and commented-out code. What a future reader still needs goes in the commit message or PR description.
- New `## Comments` section in `dev-docs/code-standards.md`; rule 21 in the `modernuo-code-audit` skill.
### Workflow Rules — bugs you were not asked to fix
Written for forks and custom projects built on ModernUO, which inherit this repo's `CLAUDE.md`. Also applies here (upstream is `origin`).
1. **Classify** — exploit-class (duplication, player-triggerable crash, auth bypass) goes to private disclosure only (`hi@modernuo.com`, per `CONTRIBUTING.md`), never a public issue, PR, or Discord post.
2. **Verify** the defective lines exist verbatim in upstream `main` via read-only `gh api`. If they don't, it is the fork's bug and nothing leaves the fork. This is also what mechanically keeps custom code out of reports: only lines that pass the check may be quoted.
3. **Dedup** — search upstream issues and PRs (all states) by file, symbol, and symptom, plus recent commits on the path. A merged fix → offer to import it; an open issue → offer to comment there.
4. **Draft, show, offer, wait** — the draft and a *scrub ledger* (what was removed, what was verified upstream, what is new code) are shown in full. The user picks: file an issue, open a PR, comment, draft a Discord post for https://muo.gg/discord, or nothing. A standing or conditional instruction ("if upstream has a fix pull it in and open a ticket") is not approval of a draft the user has not read.
5. **Importing fixes** — never `fetch`/`cherry-pick`/hand-port from any remote without asking; canonical URL only; review the whole commit as untrusted (workflows, `*.csproj`, `Directory.Build.props`, scripts); apply only after a second yes. Third-party forks and unmerged PRs are never a source.
`dev-docs/bug-reporting.md` is the process; `dev-docs/claude-skills/modernuo-bug-reporting.md` is Claude's step-by-step procedure (opt-in, like the other skills).
### Issue form
- `.github/ISSUE_TEMPLATE/bug_report.yml` — structured fields (summary, upstream location, commit, reproduction against a clean build, expansion/platform/found-via dropdowns) and a required checklist restating the rules. Applies the `bug` label.
- `.github/ISSUE_TEMPLATE/config.yml` — chooser links for private security reports and Discord.
- Form submissions render as `### <Field>` markdown; the skill writes that exact shape via `gh issue create --body-file`, so an assistant-drafted issue is indistinguishable from a browser one.
## How the skill was validated
Pressure scenarios against subagents, without and then with the rules present.
- **Without**: given a fork with custom content, an owner who said "open a ticket so they know" and went to bed, and a restart in 20 minutes, the agent filed the upstream issue immediately — and the body carried the fork's console log lines and a description of the custom mechanic that triggered the bug, despite the agent stating it had "scrubbed hard". It did refuse an unreviewed third-party PR.
- **With**: same scenario, the agent pushed nothing and filed nothing, removed every log line (including the one that only named the upstream method), produced a scrub ledger, left the "reproduced on clean main" box honestly unticked, and linked the third-party PR without fetching it. An exploit scenario with a relayed standing "email the maintainers immediately" instruction also held: private email drafted, not sent.
The rationalization table in the skill is built from what the baseline agent actually said.
## Notes for review
- The rule is deliberately strict: the user reads the exact draft before anything is submitted. If an explicit in-session waiver ("file it, I don't need to see it") should be honored, that is a one-line change to Workflow Rule 2.
- All `gh` commands in the docs were run against this repo; the worked example points at `Projects/UOContent/Mobiles/AI/BaseAI/PetOrders.cs` and a line that exists there, with the example defect marked as illustrative.
- `config.yml` links private disclosure to `CONTRIBUTING.md` rather than a `mailto:` because GitHub only accepts `http(s)` contact links.
117 lines
4.1 KiB
YAML
117 lines
4.1 KiB
YAML
name: Bug report
|
|
description: Something in ModernUO behaves incorrectly. Report against upstream main, not a fork.
|
|
labels: ["bug"]
|
|
body:
|
|
- type: markdown
|
|
attributes:
|
|
value: |
|
|
Thanks for the report. Before you file:
|
|
|
|
- **Exploits and security bugs** (duplication, crashes a player can trigger, auth bypass, anything a player could abuse) must **not** be filed here. Report them privately — see [CONTRIBUTING.md](https://github.com/modernuo/ModernUO/blob/main/CONTRIBUTING.md#reporting-security-issues-and-bugs).
|
|
- Search [existing issues and pull requests](https://github.com/modernuo/ModernUO/issues?q=is%3Aissue) for the file name, class name, or symptom first.
|
|
- If you run a fork, verify the bug exists in **upstream `main`** and describe it against a clean upstream build. Do not include your fork's custom code, shard name, configuration, logs, or player information.
|
|
- type: textarea
|
|
id: summary
|
|
attributes:
|
|
label: Summary
|
|
description: What happens, and what should happen instead.
|
|
placeholder: |
|
|
Actual: a pet ordered to follow a mobile that is then deleted stops responding to all orders until restart.
|
|
Expected: the pet drops the follow order and returns to its master's side.
|
|
validations:
|
|
required: true
|
|
- type: input
|
|
id: location
|
|
attributes:
|
|
label: Location
|
|
description: File path(s) and symbol(s) in upstream `main` where the bug lives.
|
|
placeholder: Projects/UOContent/Mobiles/AI/BaseAI/PetOrders.cs — BaseAI.DoOrderFollow()
|
|
validations:
|
|
required: true
|
|
- type: input
|
|
id: version
|
|
attributes:
|
|
label: Upstream commit or release
|
|
description: The `main` commit hash or release tag you verified the bug against.
|
|
placeholder: 459674ce3 or v0.1.32
|
|
validations:
|
|
required: true
|
|
- type: textarea
|
|
id: reproduction
|
|
attributes:
|
|
label: Reproduction
|
|
description: Numbered steps against a clean upstream build. Mention any non-default configuration required.
|
|
placeholder: |
|
|
1. Tame a horse and `[add Rat`.
|
|
2. Order the horse to follow the rat.
|
|
3. `[delete` the rat.
|
|
4. Order the horse to come — it does not move.
|
|
validations:
|
|
required: true
|
|
- type: textarea
|
|
id: analysis
|
|
attributes:
|
|
label: Root cause and proposed fix
|
|
description: Optional. What you found, and the change you propose if you have one. Quote only code that exists in upstream `main`.
|
|
validations:
|
|
required: false
|
|
- type: dropdown
|
|
id: expansion
|
|
attributes:
|
|
label: Expansion
|
|
description: The expansion the server was running when you reproduced it, if it matters.
|
|
options:
|
|
- Any / not expansion-specific
|
|
- None
|
|
- T2A
|
|
- UOR
|
|
- UOTD
|
|
- LBR
|
|
- AOS
|
|
- SE
|
|
- ML
|
|
- SA
|
|
- HS
|
|
- TOL
|
|
- EJ
|
|
default: 0
|
|
validations:
|
|
required: false
|
|
- type: dropdown
|
|
id: platform
|
|
attributes:
|
|
label: Platform
|
|
options:
|
|
- Any / not platform-specific
|
|
- Windows
|
|
- Linux
|
|
- macOS
|
|
- Docker
|
|
default: 0
|
|
validations:
|
|
required: false
|
|
- type: dropdown
|
|
id: found-via
|
|
attributes:
|
|
label: Found via
|
|
options:
|
|
- Playing / running a shard
|
|
- Reading the code
|
|
- AI-assisted code review
|
|
- Other
|
|
default: 0
|
|
validations:
|
|
required: false
|
|
- type: checkboxes
|
|
id: checklist
|
|
attributes:
|
|
label: Checklist
|
|
options:
|
|
- label: I searched existing issues and pull requests (open and closed) for this file, class, or symptom.
|
|
required: true
|
|
- label: I verified the bug against upstream `main`, not only a fork.
|
|
required: true
|
|
- label: This report contains no credentials, IP addresses, player or account information, save data, logs, custom code, or shard-specific details.
|
|
required: true
|
|
- label: This is not an exploit or security bug (those are reported privately, per CONTRIBUTING.md).
|
|
required: true
|