Bind demo controls without broadening unrelated release proof

Keep new source paths on their own connected proof policy after the full lookup suite exposed six broadened metadata expectations. Preserve terminal no-op cancellation evidence and the runtime file owner.

Contract-Neutral: Correct connected observation and verification routing within the existing demo operations and authority.
Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-03 01:12:47 +01:00
parent f56e28e6af
commit 751fb67523
5 changed files with 47 additions and 11 deletions
+6 -3
View File
@@ -275,6 +275,8 @@ class Host:
pattern = re.compile(r"^[ \t]*" + re.escape(key) + r"=.*$", re.M)
text = pattern.sub(key + "=" + value, text) if pattern.search(text) else text.rstrip("\n") + "\n" + key + "=" + value + "\n"
env_file.write_text(text)
data_owner = PATHS["data"].stat()
os.chown(env_file, data_owner.st_uid, data_owner.st_gid)
os.chmod(env_file, 0o600)
billing = json.loads(billing_file.read_text())
if not isinstance(billing, dict) or not isinstance(billing.get("capabilities", []), list):
@@ -282,6 +284,7 @@ class Host:
billing["capabilities"] = sorted(set(billing.get("capabilities", []) + ["demo_fixtures"]))
billing.pop("integrity", None)
billing_file.write_text(json.dumps(billing))
os.chown(billing_file, data_owner.st_uid, data_owner.st_gid)
os.chmod(billing_file, 0o600)
if unhealthy:
for relative in DEMO_HISTORY:
@@ -408,14 +411,14 @@ class Transaction:
elif self.request["mode"] == "update":
raise Failure("update-baseline-unhealthy")
self.receipt["healthy_baseline"] = healthy_baseline
old_handlers = {sig: signal.getsignal(sig) for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP)}
for sig in old_handlers:
signal.signal(sig, cancel)
# The no-op is observed too; an immediate healthy sample is not success.
if self.request["mode"] == "recover" and healthy_baseline and self.host.profile_matches(self.request):
self.watch("forward", original_version, self.host.cursors())
self.save("healthy_noop")
return 0
old_handlers = {sig: signal.getsignal(sig) for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP)}
for sig in old_handlers:
signal.signal(sig, cancel)
self.save("capturing")
stopped = True
self.host.stop()
@@ -1,4 +1,3 @@
import copy
import hashlib
import importlib.util
import json
@@ -195,6 +194,16 @@ class TransactionTest(unittest.TestCase):
self.assertFalse(receipt["mutated"])
self.assertEqual(self.host.stops, 0)
def test_noop_cancellation_retains_terminal_failure_without_stopping_service(self):
self.host.profile(request(), False)
self.host.cancel_at = 55
code, receipt = self.run_transaction()
self.assertEqual(code, 1)
self.assertEqual(receipt["status"], "refused")
self.assertEqual(receipt["failure"], "cancelled-forward")
self.assertEqual(self.host.stops, 0)
self.assertFalse(receipt["mutated"])
def test_update_restores_complete_changed_executable_unit_and_data_after_late_failure(self):
self.host.fail_at = 55
code, receipt = self.run_transaction("update", "v6.4.6")
@@ -404,8 +413,6 @@ class DispatchLifecycleTest(unittest.TestCase):
for uncertain in (False, True):
with self.subTest(uncertain=uncertain), tempfile.TemporaryDirectory() as directory:
root = Path(directory) / "state"
source = dispatcher.BOOTSTRAP.replace("pathlib.Path('/var/lib/pulse-deploy/demo')", repr(root))
# repr(Path) is not a Python literal: bind just the fixed path.
source = dispatcher.BOOTSTRAP.replace("'/var/lib/pulse-deploy/demo'", repr(str(root)))
source = source.replace("root.stat().st_uid == 0", "root.stat().st_uid == os.getuid()")
clock = [0]
@@ -4751,8 +4751,6 @@
"match_files": [
".github/ISSUE_TEMPLATE/v6_rc_feedback.yml",
".github/scripts/check-demo-reachability.sh",
".github/scripts/demo-runtime-transaction.py",
".github/scripts/dispatch-demo-runtime.py",
".github/scripts/recover-demo-runtime.sh",
".github/scripts/resolve-demo-runtime-profile.sh",
".github/scripts/setup-demo-ssh.sh",
@@ -4813,13 +4811,11 @@
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
".github/scripts/tests/test_demo_runtime_transaction.py",
"frontend-modern/src/components/__tests__/whatsNewModel.test.ts",
"frontend-modern/src/utils/__tests__/docsLinks.test.ts",
"pulse-enterprise:scripts/validate-pro-release-line_test.sh",
"pulse-pro:scripts/tests/test_validate_paid_runtime_distribution.py",
"scripts/installtests/build_release_assets_test.go",
"scripts/installtests/demo_transaction_test.go",
"scripts/release_control/internal/record_rc_to_ga_rehearsal_test.py",
"scripts/release_control/internal/release_preflight_test.py",
"scripts/release_control/mobile_release_gate_test.py",
@@ -5173,6 +5169,21 @@
"scripts/installtests/install_sh_test.go",
"scripts/installtests/safe_profile_migration_test.go"
]
},
{
"id": "demo-runtime-transaction",
"label": "demo shared-host transaction and retained recovery proof",
"match_prefixes": [],
"match_files": [
".github/scripts/demo-runtime-transaction.py",
".github/scripts/dispatch-demo-runtime.py"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"scripts/installtests/demo_transaction_test.go",
".github/scripts/tests/test_demo_runtime_transaction.py"
]
}
],
"match_files": null
@@ -25,8 +25,11 @@ func TestDemoTransactionKeepsSignedAdmissionAndVerificationOnlyReadOnly(t *testi
}
text := string(workflow)
start := strings.Index(text, "- name: Apply guarded demo transaction")
if start < 0 {
t.Fatal("missing retained demo transaction entry")
}
end := strings.Index(text[start:], "- name: Retain guarded demo transaction evidence")
if start < 0 || end < 0 {
if end < 0 {
t.Fatal("missing retained demo transaction entry")
}
entry := text[start : start+end]
@@ -100,6 +100,18 @@ def _contract_reference(contract_path: str, needle: str, runtime_path: str) -> d
class SubsystemLookupTest(unittest.TestCase):
def test_demo_transaction_sources_have_connected_proof_without_widening_release_metadata(self):
for path in (".github/scripts/demo-runtime-transaction.py", ".github/scripts/dispatch-demo-runtime.py"):
with self.subTest(path=path):
result = lookup_paths([path])
subsystem = next(item for item in result["subsystems"] if item["id"] == "deployment-installability")
self.assertEqual(subsystem["matched_verification_policies"][0]["id"], "demo-runtime-transaction")
self.assertEqual(sorted(subsystem["required_verification"]["exact_files"]), [
".github/scripts/tests/test_demo_runtime_transaction.py",
"scripts/installtests/demo_transaction_test.go",
])
def git(self, repo_root: Path, *args: str) -> None:
subprocess.run(
["git", *args],