diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c011651c37..09a684a756 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -110,6 +110,9 @@ body: description: | Add relevant redacted logs or a reviewed GitHub diagnostics export for connection and data failures; for visual failures, a screenshot or exact error may be enough. Prefer existing evidence when new collection is unsafe. Review files and screenshots locally; remove secrets and identifying details, including those echoed in errors, before attaching them here. + + For CPU, memory or disk-write reports, use existing readings or safe, passive observations. Say whether the reading covers the Pulse process, its container or the whole host, and give its units, measurement window and uptime. Include allocated CPUs or memory limit, fleet size, polling interval and open dashboards where relevant and known. A process-start CPU average is not a recent sampling window; database size is not a write rate. + Existing screenshots are useful; write "unavailable" when safe collection is not possible. Do not restart, create load or change polling or retention just to measure. Do not attach raw profiles, heap dumps, databases or full process command lines; summarise only relevant counters after local review. validations: required: false diff --git a/.github/ISSUE_TEMPLATE/v6_rc_feedback.yml b/.github/ISSUE_TEMPLATE/v6_rc_feedback.yml index 16d3ee0b5d..56d7d9ab7d 100644 --- a/.github/ISSUE_TEMPLATE/v6_rc_feedback.yml +++ b/.github/ISSUE_TEMPLATE/v6_rc_feedback.yml @@ -151,6 +151,9 @@ body: Attach screenshots or paste relevant redacted logs if useful. For connection or data failures, a reviewed GitHub diagnostics export can help; prefer existing evidence when new collection is unsafe. Review files and screenshots locally; remove secrets and identifying details, including those echoed in errors, before attaching them here. + For CPU, memory or disk-write reports, use existing readings or safe, passive observations. Say whether the reading covers the Pulse process, its container or the whole host, and give its units, measurement window and uptime. Include allocated CPUs or memory limit, fleet size, polling interval and open dashboards where relevant and known. A process-start CPU average is not a recent sampling window; database size is not a write rate. + Existing screenshots are useful; write "unavailable" when safe collection is not possible. Do not restart, create load or change polling or retention just to measure. Do not attach raw profiles, heap dumps, databases or full process command lines; summarise only relevant counters after local review. + - type: checkboxes id: confirmations attributes: diff --git a/.github/scripts/issue-version-triage.test.cjs b/.github/scripts/issue-version-triage.test.cjs index f55e1ed26c..fd38dad10b 100644 --- a/.github/scripts/issue-version-triage.test.cjs +++ b/.github/scripts/issue-version-triage.test.cjs @@ -344,6 +344,48 @@ for (const [name, field] of [ }); } +for (const [name, field] of [ + ["bug_report.yml", "logs"], + ["v6_rc_feedback.yml", "evidence"], +]) { + const evidenceField = () => { + const form = fs.readFileSync(path.resolve(__dirname, "../ISSUE_TEMPLATE", name), "utf8"); + return form.split(` id: ${field}\n`)[1].split(" - type: ")[0]; + }; + + test(`performance report measurement context stays optional: ${name}`, () => { + const attachment = evidenceField(); + assert.match(attachment, /For CPU, memory or disk-write reports/); + assert.match(attachment, /existing readings or safe, passive observations/); + assert.match(attachment, /Pulse process, its container or the whole host/); + for (const context of ["units", "measurement window", "uptime", "allocated CPUs", "memory limit", "fleet size", "polling interval", "open dashboards"]) { + assert.ok(attachment.includes(context), `${name} must distinguish ${context}`); + } + assert.match(attachment, /where relevant and known/); + assert.match(attachment, /process-start CPU average is not a recent sampling window/); + assert.match(attachment, /database size is not a write rate/); + assert.match(attachment, /Existing screenshots are useful/); + assert.match(attachment, /write "unavailable" when safe collection is not possible/); + assert.doesNotMatch(attachment, /required: true|render:/); + }); + + test(`performance report attachment safety: ${name}`, () => { + const attachment = evidenceField(); + assert.match(attachment, /Do not restart, create load or change polling or retention just to measure/); + assert.match(attachment, /Do not attach raw profiles, heap dumps, databases or full process command lines/); + assert.match(attachment, /summarise only relevant counters after local review/); + }); +} + +test("performance report triage retains measurement boundaries without demanding unsafe evidence", () => { + const guide = fs.readFileSync(path.resolve(__dirname, "../../docs/ISSUE_TRIAGE.md"), "utf8"); + assert.match(guide, /Pulse process, container or whole host/); + assert.match(guide, /process-start CPU average is not a recent window/); + assert.match(guide, /database\nsize is not a write rate/); + assert.match(guide, /without making new collection a condition of reporting/); + assert.match(guide, /Do not request raw\nprofiles, heap dumps, databases or full process command lines/); +}); + test("older-version reports cannot trigger event or scheduled retest posting", async () => { const issue = { number: 1200, diff --git a/docs/ISSUE_TRIAGE.md b/docs/ISSUE_TRIAGE.md index e7dc060f7a..52cb5839a9 100644 --- a/docs/ISSUE_TRIAGE.md +++ b/docs/ISSUE_TRIAGE.md @@ -40,6 +40,17 @@ triage. Where the installed state is uncertain, check it before suggesting another action. A diagnostics export is useful only when Pulse is running and collecting it is safe. +For performance reports, retain what a reading measures before comparing it: +Pulse process, container or whole host; units, measurement window and uptime; +and the relevant CPU allocation or memory limit, fleet, polling and open +dashboards. A process-start CPU average is not a recent window, and database +size is not a write rate. The evidence field asks for these distinctions only +where known, without making new collection a condition of reporting. Existing +screenshots or an unavailable reading are valid evidence. Do not request raw +profiles, heap dumps, databases or full process command lines in a public +thread; use locally reviewed counter summaries, without restarting, creating +load or changing polling or retention just to measure. + ## Required disposition Before removing `needs-decomposition` or declaring a mixed report triaged: