fix: remove leftover merge marker in pack registry

This commit is contained in:
rookiestar28
2026-02-16 06:12:57 +08:00
parent c796dde48e
commit 7e9f4985cf
9 changed files with 136 additions and 92 deletions
+6 -6
View File
@@ -40,11 +40,11 @@ class BoundedQueue(Generic[T]):
def __init__(self, capacity: int) -> None:
if capacity <= 0:
raise ValueError("Capacity must be positive")
self._capacity = capacity
self._deque: Deque[T] = deque(maxlen=capacity)
self._lock = threading.Lock()
# Metrics
self._high_watermark = 0
self._total_enqueued = 0
@@ -64,14 +64,14 @@ class BoundedQueue(Generic[T]):
self._total_dropped += 1
self._last_drop_ts = time.time()
dropped = True
self._deque.append(item)
self._total_enqueued += 1
current_size = len(self._deque)
if current_size > self._high_watermark:
self._high_watermark = current_size
return not dropped
def get_all(self) -> List[T]:
@@ -88,7 +88,7 @@ class BoundedQueue(Generic[T]):
high_watermark=self._high_watermark,
total_enqueued=self._total_enqueued,
total_dropped=self._total_dropped,
last_drop_ts=self._last_drop_ts
last_drop_ts=self._last_drop_ts,
)
def clear(self) -> None:
+3 -10
View File
@@ -3,7 +3,6 @@ import re
import shutil
from typing import Dict, List, Optional
<<<<<<< HEAD
from ..safe_io import resolve_under_root
from .pack_archive import PackArchive, PackError
from .pack_types import PackMetadata
@@ -57,9 +56,7 @@ class PackRegistry:
# A malicious pack.json could contain traversal sequences.
_validate_pack_segment(name, "name")
_validate_pack_segment(version, "version")
target_dir = resolve_under_root(
self.packs_dir, os.path.join(name, version)
)
target_dir = resolve_under_root(self.packs_dir, os.path.join(name, version))
if os.path.exists(target_dir):
if not overwrite:
@@ -76,9 +73,7 @@ class PackRegistry:
def uninstall_pack(self, name: str, version: str) -> bool:
_validate_pack_segment(name, "name")
_validate_pack_segment(version, "version")
target_dir = resolve_under_root(
self.packs_dir, os.path.join(name, version)
)
target_dir = resolve_under_root(self.packs_dir, os.path.join(name, version))
if os.path.exists(target_dir):
shutil.rmtree(target_dir)
# Clean up parent if empty
@@ -118,9 +113,7 @@ class PackRegistry:
def get_pack_path(self, name: str, version: str) -> Optional[str]:
_validate_pack_segment(name, "name")
_validate_pack_segment(version, "version")
target_dir = resolve_under_root(
self.packs_dir, os.path.join(name, version)
)
target_dir = resolve_under_root(self.packs_dir, os.path.join(name, version))
if os.path.exists(target_dir):
return target_dir
return None
+29 -19
View File
@@ -60,24 +60,24 @@ class PermissionEvaluator:
def evaluate(self) -> List[PermissionResult]:
"""Run all permission checks."""
results = []
# 1. State Directory
results.append(self._check_state_dir())
# 2. Secrets File
results.append(self._check_secrets_file())
return results
def _check_state_dir(self) -> PermissionResult:
"""Check state directory permissions."""
path = self.state_dir
if not path.exists():
return PermissionResult(
return PermissionResult(
resource="state_dir",
severity=PermissionSeverity.SKIP,
message="State directory does not exist",
code="perm.state_dir.missing"
code="perm.state_dir.missing",
)
# Common: Must be writable by owner/current user
@@ -88,7 +88,7 @@ class PermissionEvaluator:
severity=PermissionSeverity.FAIL,
message=f"State directory not writable: {path}",
code="perm.state_dir.not_writable",
remediation="Ensure the process user has write access."
remediation="Ensure the process user has write access.",
)
# POSIX Hardening
@@ -97,13 +97,17 @@ class PermissionEvaluator:
mode = path.stat().st_mode
if mode & stat.S_IWOTH:
# World writable is CRITICAL in Hardened
sev = PermissionSeverity.FAIL if self.profile == RuntimeProfile.HARDENED else PermissionSeverity.WARN
sev = (
PermissionSeverity.FAIL
if self.profile == RuntimeProfile.HARDENED
else PermissionSeverity.WARN
)
return PermissionResult(
resource="state_dir",
severity=sev,
message="State directory is world-writable",
message="State directory is world-writable",
code="perm.state_dir.world_writable",
remediation=f"chmod 700 {path}"
remediation=f"chmod 700 {path}",
)
except Exception as e:
logger.warning(f"Failed to stat state dir: {e}")
@@ -112,19 +116,19 @@ class PermissionEvaluator:
resource="state_dir",
severity=PermissionSeverity.PASS,
message="State directory permissions OK",
code="perm.state_dir.ok"
code="perm.state_dir.ok",
)
def _check_secrets_file(self) -> PermissionResult:
"""Check secrets.json permissions."""
path = self.state_dir / "secrets.json"
if not path.exists():
return PermissionResult(
return PermissionResult(
resource="secrets_file",
severity=PermissionSeverity.PASS, # Not an error to not exist
severity=PermissionSeverity.PASS, # Not an error to not exist
message="Secrets file not present",
code="perm.secrets.missing"
code="perm.secrets.missing",
)
if self.system != "Windows":
@@ -132,13 +136,17 @@ class PermissionEvaluator:
mode = path.stat().st_mode
# Check World Readable/Writable
if mode & (stat.S_IROTH | stat.S_IWOTH):
sev = PermissionSeverity.FAIL if self.profile == RuntimeProfile.HARDENED else PermissionSeverity.WARN
sev = (
PermissionSeverity.FAIL
if self.profile == RuntimeProfile.HARDENED
else PermissionSeverity.WARN
)
return PermissionResult(
resource="secrets_file",
severity=sev,
message="Secrets file is world-accessible",
code="perm.secrets.world_accessible",
remediation=f"chmod 600 {path}"
remediation=f"chmod 600 {path}",
)
except Exception as e:
logger.warning(f"Failed to stat secrets file: {e}")
@@ -147,7 +155,7 @@ class PermissionEvaluator:
resource="secrets_file",
severity=PermissionSeverity.PASS,
message="Secrets file permissions OK",
code="perm.secrets.ok"
code="perm.secrets.ok",
)
@@ -158,13 +166,15 @@ def evaluate_startup_permissions() -> Tuple[bool, List[PermissionResult]]:
"""
evaluator = PermissionEvaluator()
results = evaluator.evaluate()
# Block startup if any FAIL result exists
failures = [r for r in results if r.severity == PermissionSeverity.FAIL]
if failures:
logger.critical(f"Startup blocked by permission checks ({len(failures)} failures).")
logger.critical(
f"Startup blocked by permission checks ({len(failures)} failures)."
)
for f in failures:
logger.critical(f" [{f.code}] {f.message} -> {f.remediation}")
return False, results
return True, results
+14 -12
View File
@@ -1,31 +1,32 @@
import unittest
import time
import unittest
from services.observability.backpressure import BoundedQueue
class TestBoundedQueue(unittest.TestCase):
def test_capacity_and_drops(self):
"""Test strict capacity enforcement and drop counting."""
q = BoundedQueue[int](capacity=2)
# 1. Fill to capacity
self.assertTrue(q.enqueue(1))
self.assertTrue(q.enqueue(2))
stats = q.stats()
self.assertEqual(stats.current_size, 2)
self.assertEqual(stats.high_watermark, 2)
self.assertEqual(stats.total_dropped, 0)
# 2. Overflow (Drop Oldest)
self.assertFalse(q.enqueue(3))
stats = q.stats()
self.assertEqual(stats.current_size, 2)
self.assertEqual(stats.total_dropped, 1)
self.assertGreater(stats.last_drop_ts, 0)
# Check content (1 should be dropped, 2 and 3 remain)
items = q.get_all()
self.assertEqual(items, [2, 3])
@@ -33,18 +34,19 @@ class TestBoundedQueue(unittest.TestCase):
def test_stats_tracking(self):
"""Test cumulative stats logic."""
q = BoundedQueue[str](capacity=5)
q.enqueue("a")
q.enqueue("b")
self.assertEqual(q.stats().high_watermark, 2)
q.get_all() # Just reading doesn't change state
q.get_all() # Just reading doesn't change state
q.clear()
stats = q.stats()
self.assertEqual(stats.current_size, 0)
self.assertEqual(stats.high_watermark, 0)
self.assertEqual(stats.total_enqueued, 0)
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -6,13 +6,13 @@ import unittest
import zipfile
from services.packs.pack_archive import PackArchive
from services.packs.pack_registry import PackRegistry, _validate_pack_segment
from services.packs.pack_manifest import (
MAX_MANIFEST_FILES,
PackError,
validate_manifest_integrity,
validate_pack_metadata,
)
from services.packs.pack_registry import PackRegistry, _validate_pack_segment
from services.packs.pack_types import PackMetadata, PackType
+44 -16
View File
@@ -1,16 +1,17 @@
import unittest
import stat
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
from services.permission_posture import (
PermissionEvaluator,
PermissionResult,
PermissionSeverity,
evaluate_startup_permissions
evaluate_startup_permissions,
)
from services.runtime_profile import RuntimeProfile
class TestPermissionPosture(unittest.TestCase):
@patch("services.permission_posture.get_runtime_profile")
@@ -19,15 +20,23 @@ class TestPermissionPosture(unittest.TestCase):
@patch("pathlib.Path.exists")
@patch("os.access")
@patch("pathlib.Path.stat")
def test_posix_hardened_fail(self, mock_stat, mock_access, mock_exists, mock_system, mock_get_state, mock_get_profile):
def test_posix_hardened_fail(
self,
mock_stat,
mock_access,
mock_exists,
mock_system,
mock_get_state,
mock_get_profile,
):
"""Hardened profile fails on world-writable state dir."""
# Setup
mock_get_profile.return_value = RuntimeProfile.HARDENED
mock_get_state.return_value = "/tmp/state"
mock_system.return_value = "Linux"
mock_exists.return_value = True
mock_access.return_value = True # Writable by us
mock_access.return_value = True # Writable by us
# Mock world-writable mode
mock_stat_res = MagicMock()
mock_stat_res.st_mode = stat.S_IWOTH | stat.S_IRWXU
@@ -48,7 +57,15 @@ class TestPermissionPosture(unittest.TestCase):
@patch("pathlib.Path.exists")
@patch("os.access")
@patch("pathlib.Path.stat")
def test_posix_minimal_warn(self, mock_stat, mock_access, mock_exists, mock_system, mock_get_state, mock_get_profile):
def test_posix_minimal_warn(
self,
mock_stat,
mock_access,
mock_exists,
mock_system,
mock_get_state,
mock_get_profile,
):
"""Minimal profile warns on world-writable state dir."""
# Setup
mock_get_profile.return_value = RuntimeProfile.MINIMAL
@@ -56,7 +73,7 @@ class TestPermissionPosture(unittest.TestCase):
mock_system.return_value = "Linux"
mock_exists.return_value = True
mock_access.return_value = True
# Mock world-writable mode
mock_stat_res = MagicMock()
mock_stat_res.st_mode = stat.S_IWOTH | stat.S_IRWXU
@@ -77,7 +94,15 @@ class TestPermissionPosture(unittest.TestCase):
@patch("pathlib.Path.exists")
@patch("os.access")
@patch("pathlib.Path.stat")
def test_secrets_world_readable_hardened(self, mock_stat, mock_access, mock_exists, mock_system, mock_get_state, mock_get_profile):
def test_secrets_world_readable_hardened(
self,
mock_stat,
mock_access,
mock_exists,
mock_system,
mock_get_state,
mock_get_profile,
):
"""Hardened profile fails on world-readable secrets."""
mock_get_profile.return_value = RuntimeProfile.HARDENED
mock_get_state.return_value = "/tmp/state"
@@ -89,10 +114,10 @@ class TestPermissionPosture(unittest.TestCase):
mock_stat_res = MagicMock()
mock_stat_res.st_mode = stat.S_IROTH | stat.S_IRWXU
mock_stat.return_value = mock_stat_res
evaluator = PermissionEvaluator()
results = evaluator.evaluate()
# Check secrets result
secret_res = next(r for r in results if r.resource == "secrets_file")
self.assertEqual(secret_res.severity, PermissionSeverity.FAIL)
@@ -103,20 +128,23 @@ class TestPermissionPosture(unittest.TestCase):
@patch("services.permission_posture.platform.system")
@patch("pathlib.Path.exists")
@patch("os.access")
def test_startup_gate_block(self, mock_access, mock_exists, mock_system, mock_get_state, mock_get_profile):
def test_startup_gate_block(
self, mock_access, mock_exists, mock_system, mock_get_state, mock_get_profile
):
"""Ensure evaluate_startup_permissions returns False on failures."""
mock_get_profile.return_value = RuntimeProfile.HARDENED
mock_get_state.return_value = "/tmp/state"
mock_system.return_value = "Linux"
mock_exists.return_value = True
# Fail access check (critical for all profiles)
mock_access.return_value = False
mock_access.return_value = False
allowed, results = evaluate_startup_permissions()
self.assertFalse(allowed)
self.assertTrue(any(r.severity == PermissionSeverity.FAIL for r in results))
if __name__ == "__main__":
unittest.main()
+22 -16
View File
@@ -1,34 +1,37 @@
import unittest
from unittest.mock import patch, MagicMock
from unittest.mock import MagicMock, patch
from services.permission_posture import PermissionResult, PermissionSeverity
from services.security_gate import SecurityGate, enforce_startup_gate
from services.permission_posture import PermissionResult, PermissionSeverity
class TestSecurityGatePermissions(unittest.TestCase):
@patch("services.security_gate.is_hardened_mode")
@patch("services.permission_posture.evaluate_startup_permissions")
@patch("services.access_control.is_auth_configured") # Patch source module
@patch("services.access_control.is_auth_configured") # Patch source module
@patch("services.redaction.redact_text")
def test_gate_fails_on_permission_error(self, mock_redact, mock_auth, mock_eval_perms, mock_hardened):
def test_gate_fails_on_permission_error(
self, mock_redact, mock_auth, mock_eval_perms, mock_hardened
):
"""Gate should report failure if permission check fails in Hardened mode."""
# Setup
mock_hardened.return_value = True
mock_auth.return_value = True # Auth OK
mock_redact.return_value = "redacted" # Redaction OK
mock_auth.return_value = True # Auth OK
mock_redact.return_value = "redacted" # Redaction OK
# Mock permission failure
fail_res = PermissionResult(
resource="test",
severity=PermissionSeverity.FAIL,
message="Test Perm Fail",
code="perm.test.fail"
code="perm.test.fail",
)
mock_eval_perms.return_value = (False, [fail_res])
# Execute
passed, reasons = SecurityGate.verify_mandatory_controls()
# Assert
self.assertFalse(passed)
self.assertTrue(any("Test Perm Fail" in r for r in reasons))
@@ -37,21 +40,24 @@ class TestSecurityGatePermissions(unittest.TestCase):
@patch("services.permission_posture.evaluate_startup_permissions")
@patch("services.access_control.is_auth_configured")
@patch("services.redaction.redact_text")
def test_gate_raise_exception(self, mock_redact, mock_auth, mock_eval_perms, mock_hardened):
def test_gate_raise_exception(
self, mock_redact, mock_auth, mock_eval_perms, mock_hardened
):
"""enforce_startup_gate should raise RuntimeError on failure."""
mock_hardened.return_value = True
mock_auth.return_value = True
fail_res = PermissionResult(
resource="test",
severity=PermissionSeverity.FAIL,
message="Test Perm Fail",
code="perm.test.fail"
code="perm.test.fail",
)
mock_eval_perms.return_value = (False, [fail_res])
with self.assertRaises(RuntimeError):
enforce_startup_gate()
if __name__ == "__main__":
unittest.main()
+17 -11
View File
@@ -1,10 +1,15 @@
import unittest
import json
import unittest
from dataclasses import asdict
from services.job_events import JobEvent, JobEventStore, JobEventType
from services.operator_doctor import CheckResult, DoctorReport, Severity
from services.security_doctor import SecurityCheckResult, SecurityReport, SecuritySeverity
from services.job_events import JobEvent, JobEventType, JobEventStore
from services.security_doctor import (
SecurityCheckResult,
SecurityReport,
SecuritySeverity,
)
class TestWP0ContractBaseline(unittest.TestCase):
"""
@@ -20,7 +25,7 @@ class TestWP0ContractBaseline(unittest.TestCase):
severity=Severity.PASS.value,
message="Test Message",
detail="Details",
remediation="Fix it"
remediation="Fix it",
)
d = result.to_dict()
self.assertEqual(d["name"], "test-check")
@@ -44,13 +49,13 @@ class TestWP0ContractBaseline(unittest.TestCase):
message="Security Fail",
category="endpoint",
detail="Detail",
remediation="Remedy"
remediation="Remedy",
)
d = result.to_dict()
self.assertEqual(d["name"], "sec-check")
self.assertEqual(d["severity"], "fail")
self.assertEqual(d["category"], "endpoint")
report = SecurityReport()
report.add(result)
rd = report.to_dict()
@@ -60,25 +65,26 @@ class TestWP0ContractBaseline(unittest.TestCase):
def test_job_event_structure(self):
"""Verify Job Event structure and basic ring buffer behavior."""
store = JobEventStore(max_size=2)
# Emit 1
e1 = store.emit(JobEventType.QUEUED, "p1")
self.assertEqual(e1.seq, 1)
self.assertEqual(e1.event_type, "queued")
self.assertEqual(e1.prompt_id, "p1")
# Emit 2
e2 = store.emit(JobEventType.RUNNING, "p1")
self.assertEqual(e2.seq, 2)
# Emit 3 (Should evict 1)
e3 = store.emit(JobEventType.COMPLETED, "p1")
self.assertEqual(e3.seq, 3)
events = store.events_since(0)
self.assertEqual(len(events), 2)
self.assertEqual(events[0].seq, 2)
self.assertEqual(events[1].seq, 3)
if __name__ == "__main__":
unittest.main()
-1
View File
@@ -232,4 +232,3 @@ class QueueMonitor {
export const moltbotUI = new MoltbotUI();
const monitor = new QueueMonitor(moltbotUI);
monitor.start();