feat: give users a signposted route to report a bug - #120
Conversation
## Problem An ordinary user on freenet.org who hits a bug has nowhere correct to go. Concretely, on the live site today: - The strings "report a bug", "file an issue" and "bug report" appear nowhere in the site's content or templates. - The only GitHub link in the footer is the "src: freenet/web" credit, so the single most obvious place a user would click routes every River bug and every node bug into the *website's* tracker. - /community/support/ and /community/get-involved/ are published but completely empty (title front matter, no body). Quickstart's "What's Next" list links to the latter, so the one navigational promise of a community route is a blank page. - Nothing anywhere states which repo covers what. /apps/ links ten repos, but as project homepages, not as "report bugs here". Freenet spans freenet-core, river, web, ghostkeys and the rest, so "file an issue" is ambiguous even for someone willing to look. ## Approach Fill the existing empty /community/support/ page with a routing page that sorts a reporter by what they were doing, rather than adding new scaffolding. It covers River, the node itself, the website, Ghost Keys, other apps, and an explicit "Not sure" route (freenet-core, which the maintainers watch most and can move a report from). It says plainly that filing on GitHub needs a GitHub account, and offers Matrix as the route for people who do not want one. It also documents `freenet service report`, which produces a report code maintainers can look up, along with `--local` for anyone who would rather inspect the bundle before uploading it. Discovery: one footer link, present on every page, plus an entry in the homepage's secondary-links row and in Quickstart's Troubleshooting and "What's Next" sections, which is where a struggling user already is. The empty get-involved stub is deleted; /community/get-involved/ and a new short /report/ both alias to the page, so the Quickstart link that previously dead-ended now lands somewhere real. ## Testing - `hugo` builds clean; `scripts/check-links.py` reports no broken internal links across 223 pages. - Alias redirects verified in the built output for /report/ and /community/get-involved/. - All five external GitHub targets return 200. - Rendered and screenshotted at 1200px and 390px, light and dark palettes covered by the CSS. [AI-assisted - Claude]
Independent review findings, all verified against source before acting. Blocking: - The privacy disclosure for `freenet service report` understated the upload. Verified in report.rs: it also sends the machine's hostname (SystemInfo.hostname, report.rs:169), and the serialized NodeDiagnosticsResponse, which carries the peer ID, the addresses of every connected peer, and the subscribed contracts (for River, the rooms you are in). The page now says all of that plainly, including that the receiving end records your IP. Should-fix: - "each has a CONTRIBUTING.md" was false: it exists in freenet-core, river and web only, absent in the other seven repos. Now links freenet-core's guide alone, and warns that feature PRs without an agreed issue are closed, which that guide states and the page previously contradicted. - The described order of operations was reversed. get_user_message() runs last (report.rs:187), after the node query that can block for up to 60s. Corrected, and the wait is called out so a user with a broken node is not left staring at nothing. - `--local` is a dead end: run() takes that branch instead of uploading, so nothing can be sent afterwards. The page said "see what is in it first" without saying you must re-run. - Raven was missing from the routing, and sending people via /apps/ cost three hops. All six other apps now have direct issue links. - No contractions anywhere, which read stiff against /try/ and /uninstall/. Rewritten in the site's voice. - /community/ had no _index.md, so Hugo titled it "Communities" and rendered the support page as a summary. Added a real section page. Nits: dropped the British "agonising" and the sentence it padded; use the full "Ghostkey Vault"; demoted the GitHub-account note from a yellow warning box to plain prose, since it is ordinary information rather than a caution; folded the duplicated .footer-report link CSS into the existing .footer-institutional selectors. Also fixed, adjacent and in this repo: two links sending users to the wrong Matrix room. content/build/manual/community.md pointed at #locutus:matrix.org and CONTRIBUTING.md at #freenet:matrix.org. Resolved against matrix.org's directory API, those are two distinct rooms, and the second is the Libera.Chat IRC bridge. Both now point at #freenet-locutus:matrix.org, which is what the homepage and quickstart already use. freenet-core's CONTRIBUTING.md has the same problem and needs a follow-up in that repo. Dismissed with reason: the inert `description:` front matter (the template emits no meta description; five other pages do the same, so it is a pre-existing pattern, not a regression), prettier's 4-space indent in footer.html and its whole-file reformat of freenet.css (both files were already prettier-dirty on main and no CI job checks formatting, so reformatting them here would bury the change in churn). Rebuilt: hugo clean, check-links clean across 223 pages, aliases generate, all sixteen external links 200, rendered in light and dark. [AI-assisted - Claude]
Second review pass, findings verified against source. - The Ghost Keys entry sent donation and certificate problems to freenet/ghostkeys, which cannot fix them: the Stripe integration and the certificate signer are `rust/api/` in this repo (routes.rs, handle_sign_cert.rs, async-stripe in Cargo.toml), and /donate/ and /ghostkey/ are Hugo pages here. freenet/ghostkeys is the vault and the delegate. Split: vault problems there, payment and certificate problems here. Getting this wrong is the one thing a routing page cannot afford. - Three more links to the wrong Matrix room, missed in the last commit: content/donate/thanks/_index.md (the page a donor lands on right after paying) and two slide partials, all pointing at #freenet:matrix.org, which resolves to the Libera.Chat IRC bridge rather than the project's room. No stale room aliases remain in the repo. - The diagnostics upload lists every contract the node holds, not only subscribed ones: collect_contract_states takes the empty-contract_keys branch and enumerates oracle.hosting_contract_keys() (p2p_protoc.rs:640). Corrected, since completeness is the whole point of that paragraph. - Attributed the up-to-a-minute wait to the right condition. Connection refused is not retried, so a node that simply isn't running fails at once; the full 60s only happens when something accepts the connection and never answers. - Re-running without `--local` collects a fresh bundle rather than sending the one you just read. Said so. - Dropped the suggestion to send the report code over Matrix instead of a public issue. There is no public read-by-code endpoint, so the code is not a retrieval vector, and Matrix is a public room with ~120 participating servers, so the sentence implied a privacy difference that does not exist. - Nits: "the first time", "What makes a report easy to act on", and /community/ no longer repeats the child page's own summary above it. Rebuilt: hugo clean, check-links clean across 223 pages, new freenet/web issues link 200, page prettier-clean. [AI-assisted - Claude]
ReviewLight-tier change (site content plus a footer link), so one independent adversarial reviewer, blind to the authoring, then a second verification pass over the fixes because the content changed materially between them. Both lenses read the checked-out branch and traced claims to primary source rather than to the page. External model pass not run; substituted a second Claude lens with a distinct brief, per Every finding was either fixed or dismissed with a stated reason. Nothing was carried forward. Round oneBlocking. The privacy disclosure for Should-fix. "each has a Nits. British "agonising"; lowercase "the vault"; a yellow warning box used for the ordinary fact that GitHub needs an account; duplicated footer-link CSS. Round twoShould-fix. The Ghost Keys entry sent donation and certificate problems to Nits. The upload lists every contract the node holds, not only subscribed ones ( Dismissed, with reasons
Verification
One thing is out of scope for this repo: [AI-assisted - Claude] |
Problem
An ordinary user on freenet.org who hits a bug has nowhere correct to go.
Concretely, on the live site today:
nowhere in the site's content or templates.
the single most obvious place a user would click routes every River bug
and every node bug into the website's tracker.
completely empty (title front matter, no body). Quickstart's "What's
Next" list links to the latter, so the one navigational promise of a
community route is a blank page.
but as project homepages, not as "report bugs here".
Freenet spans freenet-core, river, web, ghostkeys and the rest, so "file
an issue" is ambiguous even for someone willing to look.
Approach
Fill the existing empty /community/support/ page with a routing page that
sorts a reporter by what they were doing, rather than adding new
scaffolding. It covers River, the node itself, the website, Ghost Keys,
other apps, and an explicit "Not sure" route (freenet-core, which the
maintainers watch most and can move a report from).
It says plainly that filing on GitHub needs a GitHub account, and offers
Matrix as the route for people who do not want one. It also documents
freenet service report, which produces a report code maintainers canlook up, along with
--localfor anyone who would rather inspect thebundle before uploading it.
Discovery: one footer link, present on every page, plus an entry in the
homepage's secondary-links row and in Quickstart's Troubleshooting and
"What's Next" sections, which is where a struggling user already is.
The empty get-involved stub is deleted; /community/get-involved/ and a
new short /report/ both alias to the page, so the Quickstart link that
previously dead-ended now lands somewhere real.
Testing
hugobuilds clean;scripts/check-links.pyreports no brokeninternal links across 223 pages.
/community/get-involved/.
palettes covered by the CSS.
[AI-assisted - Claude]