diff --git a/PUBLIC_SOURCE_EXPORT.md b/PUBLIC_SOURCE_EXPORT.md index 58a0084..14492ad 100644 --- a/PUBLIC_SOURCE_EXPORT.md +++ b/PUBLIC_SOURCE_EXPORT.md @@ -1,3 +1,3 @@ # Public source export -This source snapshot was generated from the private canonical repository at revision `c61e0e1e292914893b40354f904f23dd9fd4a958`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. +This source snapshot was generated from the private canonical repository at revision `0ea6f267c28d51ac7113e6d943c89857d3a189ab`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. diff --git a/PUBLIC_SOURCE_MANIFEST.json b/PUBLIC_SOURCE_MANIFEST.json index 97e2fd5..d42b96a 100644 --- a/PUBLIC_SOURCE_MANIFEST.json +++ b/PUBLIC_SOURCE_MANIFEST.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "sourceRevision": "c61e0e1e292914893b40354f904f23dd9fd4a958", + "sourceRevision": "0ea6f267c28d51ac7113e6d943c89857d3a189ab", "files": [ { "path": ".dockerignore", @@ -964,8 +964,8 @@ }, { "path": "backend/tests/test_controller_artifact_promoter.py", - "sha256": "f139565d2508fe9f71113bc52041e2b0545a202f0529417ddf7516bddcf955da", - "bytes": 8667 + "sha256": "d769b1cc1151875d7d9601ad281e8423066588db12cb1608fdcf7a1eb53db53e", + "bytes": 9565 }, { "path": "backend/tests/test_controller_artifact_promotion_diagnostics.py", @@ -1584,8 +1584,8 @@ }, { "path": "backend/tests/test_runner_acceptance_quiescence.py", - "sha256": "c7212b67f2995bf2c09d88ef6df38498fcfe7f3d513d43fd00bb3f8b62d4673d", - "bytes": 33359 + "sha256": "62ce270a8b3e9c9a613cd7bb91f0a7d8b6071bccf914def33f5672084b7a3841", + "bytes": 42074 }, { "path": "backend/tests/test_runner_acceptance_surface.py", diff --git a/backend/tests/test_controller_artifact_promoter.py b/backend/tests/test_controller_artifact_promoter.py index 8d58404..a4c35f3 100644 --- a/backend/tests/test_controller_artifact_promoter.py +++ b/backend/tests/test_controller_artifact_promoter.py @@ -217,3 +217,20 @@ def test_modern_promoter_21_binds_actual_installed_19_without_widening_bootstrap assert labels["itworx.controller.bootstrap.target.version"] == "2.1.19" assert labels["itworx.controller.bootstrap.target.id"] == "c" * 64 assert labels["itworx.controller.bootstrap.target.tree"] == "d" * 40 + + +def test_modern_promoter_preserves_exact_current_21_predecessor_for_reader_correction(): + from backend.app.services.controller_artifact_promoter import helper_container_spec + + actual_revision = "c61e0e1e292914893b40354f904f23dd9fd4a958" + spec = helper_container_spec( + revision="a" * 40, image_id="sha256:" + "b" * 64, + current_controller_id="c" * 64, current_controller_revision=actual_revision, + current_controller_tree="d" * 40, current_controller_version="2.1.21", + ) + labels = spec["Labels"] + assert labels["itworx.controller.version"] == "2.1.21" + assert labels["itworx.controller.bootstrap.target.version"] == "2.1.21" + assert labels["itworx.controller.bootstrap.target.revision"] == actual_revision + assert labels["itworx.controller.bootstrap.target.id"] == "c" * 64 + assert labels["itworx.controller.bootstrap.target.tree"] == "d" * 40 diff --git a/backend/tests/test_runner_acceptance_quiescence.py b/backend/tests/test_runner_acceptance_quiescence.py index 91d8ac9..4b5cea2 100644 --- a/backend/tests/test_runner_acceptance_quiescence.py +++ b/backend/tests/test_runner_acceptance_quiescence.py @@ -228,6 +228,40 @@ def test_positive_preserves_resources_and_windows_then_idempotent(module, proven module.quiesce(revision="e" * 40, projects={}, driver=driver) +def test_mount_order_is_canonical_for_fixed_current_and_resume_baseline(module, proven): + driver, _ = proven + baseline = copy.deepcopy(driver.state) + row = next(row for row in driver.state["rows"] if len(row["mounts"]) >= 2) + row["mounts"].reverse() + module.attest_snapshot(driver.state) + module.attest_snapshot(driver.state, baseline=baseline, progress={}) + assert module.preflight(revision="d" * 40, projects={}, driver=driver)["status"] == "ready" + assert module.quiesce(revision="d" * 40, projects={}, driver=driver)["status"] == "quiesced" + + +@pytest.mark.parametrize("field,value", [("Source", "/foreign"), ("Destination", "/foreign"), + ("Type", "bind"), ("Name", "foreign-volume"), ("RW", False)]) +def test_mount_order_normalization_preserves_all_identity_fields(module, proven, field, value): + driver, _ = proven + row = next(row for row in driver.state["rows"] + if any(mount["Type"] == "volume" and mount["RW"] is True for mount in row["mounts"])) + mount = next(mount for mount in row["mounts"] if mount["Type"] == "volume" and mount["RW"] is True) + mount[field] = value + row["mounts"].reverse() + with pytest.raises(module.QuiescenceError, match="container_identity_changed"): + module.attest_snapshot(driver.state) + assert driver.effects == [] + + +def test_mount_normalization_rejects_duplicate_destinations(module, proven): + driver, _ = proven + row = next(row for row in driver.state["rows"] if row["mounts"]) + row["mounts"].append(copy.deepcopy(row["mounts"][0])) + with pytest.raises(module.QuiescenceError, match="container_mount_inventory_invalid"): + module.attest_snapshot(driver.state) + assert driver.effects == [] + + @pytest.mark.parametrize("kind", ["queued", "in_progress", "pending"]) def test_initial_new_work_refuses_all_effects(module, proven, kind): driver, _ = proven @@ -686,6 +720,163 @@ def test_manual_product_observation_protects_exact_healthy_target_without_fake_r ) +def test_product_baseline_mount_order_is_stable_without_discarding_fields(module, product): + target, rows, _, _ = product + row = next(iter(rows.values())) + row["Mounts"].append({"Type": "bind", "Source": "/production/bootstrap.sh", + "Destination": "/bootstrap.sh", "RW": False}) + driver = module.ControllerDriver({"jens/workmesh": target}) + baseline = driver._product_binding({"engineId": "private"}, []) + row["Mounts"].reverse() + assert driver._product_binding({"engineId": "private"}, []) == baseline + row["Mounts"][0]["RW"] = True + assert driver._product_binding({"engineId": "private"}, []) != baseline + + +@pytest.fixture +def product_state(module, monkeypatch, tmp_path): + import os + import stat + from types import SimpleNamespace + + path = tmp_path / "workmesh.json" + path.write_bytes(b'{"status":"healthy","live_legacy_provenance":true}') + path.chmod(0o644) + monkeypatch.setattr(module, "WORKMESH_STATE_PATH", path) + original_lstat, original_fstat = Path.lstat, os.fstat + changes = {"st_uid": 0, "st_mode": stat.S_IFREG | 0o644, "st_nlink": 1} + fields = ("st_dev", "st_ino", "st_uid", "st_gid", "st_mode", "st_nlink", + "st_size", "st_mtime_ns", "st_ctime_ns") + + def metadata(info): + # Windows cannot express POSIX ownership/modes; retain real file + # identity/size/timestamps and exercise the same strict native contract. + values = {name: getattr(info, name) for name in fields} + if os.name == "nt": + # Windows reports different ctime precision for path/FD queries. + # The deployed Linux reader still compares the real nanosecond value. + values["st_ctime_ns"] = original_lstat(path).st_ctime_ns + return SimpleNamespace(**{**values, **changes}) + + monkeypatch.setattr(Path, "lstat", lambda self, **kw: metadata(original_lstat(self, **kw)) + if self == path else original_lstat(self, **kw)) + monkeypatch.setattr(os, "fstat", lambda fd: metadata(original_fstat(fd))) + return path, changes + + +@pytest.mark.parametrize("mode", [0o600, 0o644]) +def test_product_state_accepts_exact_normal_producer_modes(module, product, product_state, mode): + import stat + + target, _, _, _ = product + _, changes = product_state + changes["st_mode"] = stat.S_IFREG | mode + assert module.ControllerDriver({})._product_receipt(target, []) == "legacy-physical-observation" + + +def test_actual_posix_producer_0644_is_readable_without_metadata_shims(module, monkeypatch, tmp_path): + import os + + if os.name == "nt" or os.geteuid() != 0: + pytest.skip("actual root-owned POSIX producer proof requires the native root harness") + path = tmp_path / "workmesh.json" + path.write_bytes(b'{"status":"healthy","live_legacy_provenance":true}') + path.chmod(0o644) + monkeypatch.setattr(module, "WORKMESH_STATE_PATH", path) + assert module.ControllerDriver({})._product_receipt({}, []) == "legacy-physical-observation" + with pytest.raises(module.fleet.RunnerFleetSpecializeError): + module.fleet._trusted_private_file(path) + + +@pytest.mark.parametrize("mode", [0o400, 0o640, 0o664, 0o666, 0o700, 0o755, 0o4644]) +def test_product_metadata_does_not_accept_other_modes(module, product_state, mode): + import stat + + _, changes = product_state + changes["st_mode"] = stat.S_IFREG | mode + with pytest.raises(module.QuiescenceError, match="active_product_receipt_untrusted"): + module._read_workmesh_product_state() + + +@pytest.mark.parametrize("change", ["owner", "symlink", "directory", "hardlink", "empty", "oversized"]) +def test_product_metadata_rejects_unsafe_objects(module, product_state, change): + import stat + + _, changes = product_state + changes.update({ + "owner": {"st_uid": 1}, "symlink": {"st_mode": stat.S_IFLNK | 0o644}, + "directory": {"st_mode": stat.S_IFDIR | 0o644}, "hardlink": {"st_nlink": 2}, + "empty": {"st_size": 0}, "oversized": {"st_size": 512 * 1024 + 1}, + }[change]) + with pytest.raises(module.QuiescenceError, match="active_product_receipt_untrusted"): + module._read_workmesh_product_state() + + +@pytest.mark.parametrize("stage", ["open", "read", "path"]) +@pytest.mark.parametrize("field", ["st_ino", "st_dev", "st_uid", "st_size", "st_mtime_ns", "st_ctime_ns"]) +def test_product_metadata_rejects_open_read_and_replace_races(module, product_state, monkeypatch, stage, field): + path, _ = product_state + original_fstat, original_lstat = module.os.fstat, Path.lstat + calls = 0 + + def fstat(fd): + nonlocal calls + calls += 1 + info = original_fstat(fd) + if (stage == "open" and calls == 1) or (stage == "read" and calls == 2): + setattr(info, field, getattr(info, field) + 1) + return info + + def lstat(self, **kw): + info = original_lstat(self, **kw) + if stage == "path" and self == path and calls >= 2: + setattr(info, field, getattr(info, field) + 1) + return info + + monkeypatch.setattr(module.os, "fstat", fstat) + monkeypatch.setattr(Path, "lstat", lstat) + with pytest.raises(module.QuiescenceError, match="active_product_receipt_untrusted"): + module._read_workmesh_product_state() + + +def test_product_metadata_open_is_nofollow_and_size_bounded(module, product_state, monkeypatch): + original_open = module.os.open + flags_seen = [] + + def opening(path, flags, *args, **kw): + flags_seen.append(flags) + return original_open(path, flags, *args, **kw) + + monkeypatch.setattr(module.os, "open", opening) + assert len(module._read_workmesh_product_state()) < 512 * 1024 + assert flags_seen == [module.os.O_RDONLY | getattr(module.os, "O_NOFOLLOW", 0) + | getattr(module.os, "O_NONBLOCK", 0)] + + +@pytest.mark.parametrize("valid", [True, False]) +def test_public_product_metadata_keeps_existing_receipt_verifier(module, product_state, monkeypatch, valid): + import json + from types import SimpleNamespace + + path, _ = product_state + path.write_text(json.dumps({"live_receipt": {"receipt": "existing"}}), encoding="utf-8") + calls = [] + rows = [{"name": "/workmesh-api-1", "imageId": "sha256:" + "a" * 64}] + + def verified(state, repository, revision, project): + calls.append((state, repository, revision, project)) + return {"containers": {"workmesh-api-1": {"image_id": rows[0]["imageId"]}}} if valid else None + + monkeypatch.setitem(sys.modules, "status_server", SimpleNamespace( + _live_revision=lambda state: "a" * 40, _verified_receipt=verified)) + if valid: + assert module.ControllerDriver({})._product_receipt({}, rows)["status"] == "verified-existing" + else: + with pytest.raises(module.QuiescenceError, match="active_product_receipt_untrusted"): + module.ControllerDriver({})._product_receipt({}, rows) + assert len(calls) == 1 and calls[0][1] == "jens/workmesh" + + @pytest.mark.parametrize( "change", ["source", "engine", "root", "cid", "health", "mount", "network", "extra-product"],