Recover stable-v6 upgrade intake on current source

Carry the exact validated six-file correction from 7699c5e3 and 29ad279b onto the current assignment without importing their unrelated frontend ancestry. Let reports separate failing server, agent and platform versions from an observed working baseline; preserve unknowns, passive evidence and API-only setups. Original candidates and adverse proofs remain unchanged.

Contract-Neutral: Community intake fields, mirrored guidance and regression tests only; runtime, release, installer and label automation contracts are unchanged.
Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-06 20:27:24 +01:00
parent 49805f32e3
commit f2a52d2db6
6 changed files with 123 additions and 7 deletions
+11 -2
View File
@@ -64,12 +64,21 @@ body:
validations:
required: true
- type: input
id: previous_version
attributes:
label: Last known working Pulse version
description: If you already observed the same behaviour working, give that version. The version before an upgrade is not necessarily a working baseline. Leave blank or write "unknown" if not known; do not downgrade, restart or repeat the action to find out.
placeholder: v6.x.y or unknown
validations:
required: false
- type: input
id: agent_version
attributes:
label: Agent version
description: Exact agent version (or "none" if no agents are involved).
placeholder: v6.x.y or none
description: Running version of the affected agent, separately from the Pulse server; write "none" for an API-only connection or "unknown" if unavailable. Do not reinstall or re-enrol an agent to find out.
placeholder: v6.x.y, none, or unknown
validations:
required: true
+23 -3
View File
@@ -33,24 +33,44 @@ body:
attributes:
label: Pulse version
description: Running version for an existing install; for a failed install, the exact version or release asset attempted, or "unknown" if it was not shown.
placeholder: v6.0.0-rc.N, release asset name, or unknown
placeholder: v6.x.y-rc.N, release asset name, or unknown
validations:
required: true
- type: input
id: previous_version
attributes:
label: Last known working Pulse version
description: If you already observed the same behaviour working, give that version. The version before an upgrade is not necessarily a working baseline. Leave blank or write "unknown" if not known; do not downgrade, restart or repeat the action to find out.
placeholder: v6.x.y or unknown
validations:
required: false
- type: input
id: agent_version
attributes:
label: Agent version
description: Running version of the affected agent, separately from the Pulse server; write "none" for an API-only connection or "unknown" if unavailable. Do not reinstall or re-enrol an agent to find out.
placeholder: v6.x.y, none, or unknown
validations:
required: false
- type: input
id: image_ref
attributes:
label: Running Pulse container image tag or digest
description: For a running Docker, Compose, or Kubernetes container, give its exact Pulse image tag or digest. Leave blank for LXC, bare metal, and failed installs that never started; put an attempted release asset in Pulse version instead.
placeholder: rcourtman/pulse:v6.0.0-rc.N or rcourtman/pulse@sha256:...
placeholder: rcourtman/pulse:v6.x.y-rc.N or rcourtman/pulse@sha256:...
- type: dropdown
id: install_path
attributes:
label: Install path
description: How you reached the affected version; an upgrade path alone does not establish that the previous version worked.
options:
- Clean v6 install
- Upgrade from v5
- Upgrade from a stable v6 release
- Upgrade from an earlier v6 prerelease
- Not sure
validations:
@@ -84,7 +104,7 @@ body:
id: environment
attributes:
label: OS / environment
description: Host OS, distro, or environment details that matter to the report.
description: Pulse server OS and, for platform-specific failures, the affected monitored platform and its release where known. Keep these separate from the Pulse server and agent versions; write "unknown" for unavailable details.
placeholder: Ubuntu 24.04, Debian 12, Unraid 7, Proxmox 8, macOS 15
validations:
required: true
@@ -553,3 +553,31 @@ test("version-label removal tolerates an absent label but propagates access fail
else await assert.rejects(run, { status: 403 });
}
});
// Different software versions can coexist in the same upgrade report. Only
// the affected server field may determine the affects-* label.
test("stable-to-preview intake keeps baseline, agent and platform versions out of labels", async () => {
for (const [running, expected] of [
["6.5.0-rc.1", "affects-6.5.0-rc.1"],
["unknown", "needs-version-info"],
]) {
const { github, calls } = createGithub({ latestVersion: "6.5.0" });
const issue = {
number: 2400,
title: "[v6 pre-release]: upgraded from 6.4.5",
body: [
"### Feedback type", "Bug / regression",
"### Pulse version", running,
"### Last known working Pulse version", "6.4.1",
"### Agent version", "6.4.5",
"### Install path", "Upgrade from a stable v6 release",
"### OS / environment", "Debian 12 / SCALE 26.0.0-BETA.3",
"### Additional actionable topics", "None",
].join("\n\n"),
labels: [],
};
await triage.syncLabels({ github, context: createContext({ issue }), core: createCore() });
assert.deepEqual(calls.addLabels.flatMap((call) => call.labels).sort(), [expected, "bug"].sort());
assert.equal(calls.createComment.length, 0);
}
});
+9
View File
@@ -32,6 +32,15 @@ symptom: logs or sanitized diagnostics for connection and data failures, and
screenshots or exact error text for visual failures. Do not make a reporter
invent logs where none apply.
For upgrades and regressions, keep the affected Pulse server version, agent
version and monitored platform release separate. The pre-release form covers
upgrades from stable v6 as well as earlier previews. Its optional **Last known
working Pulse version** is a baseline only when the reporter observed the same
behaviour working; an upgrade's starting version alone does not establish that.
An API-only connection can have no agent. Accept "unknown" or an omitted optional
field, and use existing evidence; do not ask for a downgrade, restart, reinstall
or re-enrolment to obtain version context. Existing reports need no refile.
Keep the Pulse server's installation separate from the affected target. A
Docker-hosted Pulse server can monitor a VM, LXC or NAS; its installation type
does not make Docker commands relevant to that target. Read later comments as
@@ -32,6 +32,15 @@ symptom: logs or sanitized diagnostics for connection and data failures, and
screenshots or exact error text for visual failures. Do not make a reporter
invent logs where none apply.
For upgrades and regressions, keep the affected Pulse server version, agent
version and monitored platform release separate. The pre-release form covers
upgrades from stable v6 as well as earlier previews. Its optional **Last known
working Pulse version** is a baseline only when the reporter observed the same
behaviour working; an upgrade's starting version alone does not establish that.
An API-only connection can have no agent. Accept "unknown" or an omitted optional
field, and use existing evidence; do not ask for a downgrade, restart, reinstall
or re-enrolment to obtain version context. Existing reports need no refile.
Keep the Pulse server's installation separate from the affected target. A
Docker-hosted Pulse server can monitor a VM, LXC or NAS; its installation type
does not make Docker commands relevant to that target. Read later comments as
@@ -1751,11 +1751,52 @@ class ReleasePromotionPolicyTest(unittest.TestCase):
def test_prerelease_feedback_template_uses_generic_current_rc_wording(self) -> None:
template = read(".github/ISSUE_TEMPLATE/v6_rc_feedback.yml")
self.assertIn("placeholder: v6.0.0-rc.N", template)
self.assertIn("placeholder: rcourtman/pulse:v6.0.0-rc.N or rcourtman/pulse@sha256:...", template)
self.assertIn("placeholder: v6.x.y-rc.N", template)
self.assertIn("placeholder: rcourtman/pulse:v6.x.y-rc.N or rcourtman/pulse@sha256:...", template)
self.assertIn("I upgraded to the current v6 RC build", template)
self.assertNotIn("v6.0.0-rc.1", template)
def test_prerelease_intake_covers_stable_upgrades_and_separate_agent_versions(self) -> None:
form = yaml.load(read(".github/ISSUE_TEMPLATE/v6_rc_feedback.yml"), Loader=UniqueKeyLoader)
fields = {field["id"]: field for field in form["body"] if "id" in field}
self.assertEqual(len(fields), sum("id" in field for field in form["body"]))
self.assertEqual(fields["install_path"]["attributes"]["options"], [
"Clean v6 install", "Upgrade from v5", "Upgrade from a stable v6 release",
"Upgrade from an earlier v6 prerelease", "Not sure",
])
self.assertTrue(fields["install_path"]["validations"]["required"])
agent = fields["agent_version"]
self.assertEqual(agent["type"], "input")
self.assertEqual(agent["attributes"]["label"], "Agent version")
self.assertFalse(agent["validations"]["required"])
for distinction in ("affected agent", "separately from the Pulse server", '"none"',
'"unknown"', "Do not reinstall or re-enrol"):
self.assertIn(distinction, agent["attributes"]["description"])
self.assertIn("affected monitored platform and its release", fields["environment"]["attributes"]["description"])
def test_working_version_context_is_optional_and_never_requires_another_attempt(self) -> None:
for name in ("bug_report.yml", "v6_rc_feedback.yml"):
with self.subTest(form=name):
form = yaml.load(read(f".github/ISSUE_TEMPLATE/{name}"), Loader=UniqueKeyLoader)
fields = {field["id"]: field for field in form["body"] if "id" in field}
self.assertEqual(len(fields), sum("id" in field for field in form["body"]))
previous = fields["previous_version"]
self.assertEqual(previous["type"], "input")
self.assertEqual(previous["attributes"]["label"], "Last known working Pulse version")
self.assertFalse(previous["validations"]["required"])
for precaution in ("already observed the same behaviour working",
"not necessarily a working baseline", 'write "unknown"',
"do not downgrade, restart or repeat the action"):
self.assertIn(precaution, previous["attributes"]["description"])
self.assertEqual(fields["pulse_version"]["attributes"]["label"], "Pulse version")
self.assertTrue(fields["pulse_version"]["validations"]["required"])
self.assertIn('"unknown"', fields["agent_version"]["attributes"]["description"])
self.assertNotIn("render", previous["attributes"])
for document in ("docs/ISSUE_TRIAGE.md", "frontend-modern/public/docs/ISSUE_TRIAGE.md"):
triage = normalize_ws(read(document))
self.assertIn("an upgrade's starting version alone does not establish that", triage)
self.assertIn("do not ask for a downgrade, restart, reinstall or re-enrolment", triage)
def test_report_intake_safety_is_self_contained_for_installed_releases(self) -> None:
for name, evidence_id in (("bug_report.yml", "logs"), ("v6_rc_feedback.yml", "evidence")):
with self.subTest(form=name):