Public: anyone can read this; the crew can change it.
Anyone can report a problem on a public repository; a person who writes it decides #677
Check · Review · Land · Live done — Landed and live in production.
Closes #605 (part a of three: the anonymous report path and its refusals; discovery and error hints, then the link on app pages, follow as their own pulls).
shipped production is serving it for issue #605 — its issue is already done deploy 2fa0c24
Review fixes (e3ba129): a fenced block now closes only on a line of backticks at least as long as the one that opened it (CommonMark), in src/web/markdown.ts. The page a report came from now sits inside the fence with the words. A new render test feeds a hostile report through renderMarkdown and asserts no <img and no link to the hostile address; it fails on the old renderer. main is merged in.
Look (a local forge, anonymous, /cheffryjames/cheffry-s-dungeon/report): phone at 390 px and desktop at 1280 px. The repo header with Issues selected, "Report a problem", one sentence saying no account is needed and a person reads it first, "What is wrong" (one line, 200 max), "What happened" (plain text, 8000 max), "Send report". No sign-in prompt; nothing overflows on the phone. The PNGs are on the build machine; this forge cannot attach images to a comment.
Follow-ups: #697, #698, #699 (trust, under #586); #700 discovery and refusal hints, #701 the link on app pages (under #591).
Closes #605 (part a of three: the anonymous report path and its refusals; discovery and error hints, then the link on app pages, follow as their own pulls).
What changed
/:owner/:name/report, orPOST /api/v1/repos/:owner/:name/reports{title, body?, page?}(202). Private repositories answernot_foundexactly like missing ones.reporttable), not an issue, so nothing that reads issues (briefs, autonomy, feed, search, MCP) can see one. It waits at/:owner/:name/reportsfor a person who writes the repository; accepting opens an ordinary issue in that person's name, saying it came from outside, with the words fenced as plain text. Dismissing drops it.Tests (
test/reports.test.ts, in the gate; the refusing tests were written first): a private repository looks the same as a missing one; size and shape refusals; control characters stripped and only http(s) page addresses kept; no account, issue, run, or event text created; a crew agent can't list, accept, or dismiss; a reader who can't write is refused; a source is limited and a refused report isn't stored; the honeypot stores nothing; the page escapes HTML; accept makes one issue, and a second accept gets 409; dismiss; the waiting cap.Also: the peer-address helper moved out of
src/http/oauth.tsintosrc/http/peer.tsso both limits share it, andtest/oauth-discovery.test.tsnow finds its migration by content instead of assuming it is the last one. Migration 46.🤖 Generated with Claude Code