fable-engine 1.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. fable_compressor.py +356 -0
  2. fable_engine/__init__.py +1 -0
  3. fable_engine/actions/__init__.py +291 -0
  4. fable_engine/actions/cas.py +182 -0
  5. fable_engine/actions/deliberation.py +523 -0
  6. fable_engine/actions/fleet.py +807 -0
  7. fable_engine/actions/lifecycle.py +298 -0
  8. fable_engine/actions/scrapers.py +116 -0
  9. fable_engine/actions/system3.py +815 -0
  10. fable_engine/browser.py +824 -0
  11. fable_engine/cas.py +974 -0
  12. fable_engine/fable_session.json +510 -0
  13. fable_engine/guards.py +283 -0
  14. fable_engine/schema.py +714 -0
  15. fable_engine/scrapers/__init__.py +32 -0
  16. fable_engine/scrapers/arxiv.py +115 -0
  17. fable_engine/scrapers/base.py +386 -0
  18. fable_engine/scrapers/github.py +129 -0
  19. fable_engine/scrapers/reddit.py +154 -0
  20. fable_engine/scrapers/web.py +120 -0
  21. fable_engine/scrapers/x.py +125 -0
  22. fable_engine/scrapers/youtube.py +132 -0
  23. fable_engine/server.py +414 -0
  24. fable_engine/session.py +1819 -0
  25. fable_engine/test_server.py +1362 -0
  26. fable_engine/updater.py +541 -0
  27. fable_engine-1.3.1.dist-info/LICENSE +22 -0
  28. fable_engine-1.3.1.dist-info/METADATA +173 -0
  29. fable_engine-1.3.1.dist-info/RECORD +104 -0
  30. fable_engine-1.3.1.dist-info/WHEEL +5 -0
  31. fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
  32. fable_engine-1.3.1.dist-info/top_level.txt +6 -0
  33. fable_mode/__init__.py +3 -0
  34. fable_mode/__main__.py +4 -0
  35. fable_mode/adapters.py +1014 -0
  36. fable_mode/installer.py +553 -0
  37. fable_mode/launcher.py +437 -0
  38. fable_mode/manifest.py +142 -0
  39. fable_mode/resources.json +114 -0
  40. fable_mode/safety.py +103 -0
  41. fable_mode_entry.py +10 -0
  42. fable_v2/__init__.py +146 -0
  43. fable_v2/adapters.py +151 -0
  44. fable_v2/coder_fleet/__init__.py +100 -0
  45. fable_v2/coder_fleet/ast_tools.py +158 -0
  46. fable_v2/coder_fleet/compute.py +199 -0
  47. fable_v2/coder_fleet/design_engine.py +1316 -0
  48. fable_v2/coder_fleet/diagnostics.py +293 -0
  49. fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
  50. fable_v2/coder_fleet/mock_auditor.py +306 -0
  51. fable_v2/coder_fleet/mutation.py +216 -0
  52. fable_v2/coder_fleet/property_oracle.py +260 -0
  53. fable_v2/coder_fleet/receipt_attestor.py +122 -0
  54. fable_v2/coder_fleet/red_team_swarm.py +908 -0
  55. fable_v2/coder_fleet/test_harness.py +198 -0
  56. fable_v2/coder_fleet/vector_engine.py +1287 -0
  57. fable_v2/coder_fleet/visual.py +357 -0
  58. fable_v2/coder_fleet/workspace.py +153 -0
  59. fable_v2/cortical/__init__.py +20 -0
  60. fable_v2/cortical/plasticity_engine.py +992 -0
  61. fable_v2/execution_broker.py +811 -0
  62. fable_v2/proof_engine.py +1141 -0
  63. fable_v2/protocol.py +485 -0
  64. fable_v2/runtime.py +1010 -0
  65. fable_v2/system3/__init__.py +204 -0
  66. fable_v2/system3/causal.py +558 -0
  67. fable_v2/system3/dialectical.py +577 -0
  68. fable_v2/system3/evolution.py +503 -0
  69. fable_v2/system3/executive.py +338 -0
  70. fable_v2/system3/free_energy.py +479 -0
  71. fable_v2/system3/hyperbolic.py +555 -0
  72. fable_v2/system3/induction.py +336 -0
  73. fable_v2/system3/kripke.py +548 -0
  74. fable_v2/system3/oracle.py +745 -0
  75. fable_v2/verifiers.py +72 -0
  76. tests/__init__.py +1 -0
  77. tests/test_anti_loop_circuit_breaker.py +64 -0
  78. tests/test_auto_updater.py +407 -0
  79. tests/test_coder_fleet.py +535 -0
  80. tests/test_delegation_compiler.py +54 -0
  81. tests/test_descriptor_boundaries.py +126 -0
  82. tests/test_design_engine.py +603 -0
  83. tests/test_epistemic_evidence_validator.py +66 -0
  84. tests/test_execution_broker.py +233 -0
  85. tests/test_fable_v2.py +406 -0
  86. tests/test_fleet_transitions.py +116 -0
  87. tests/test_fsm_redteam_evolution.py +406 -0
  88. tests/test_goal_rubric_and_pipeline.py +367 -0
  89. tests/test_hebbian_plasticity.py +585 -0
  90. tests/test_packaging_runtime.py +194 -0
  91. tests/test_proof_engine.py +259 -0
  92. tests/test_red_team_swarm.py +645 -0
  93. tests/test_redteam_remediation.py +169 -0
  94. tests/test_registration_transaction.py +375 -0
  95. tests/test_requested_regressions.py +467 -0
  96. tests/test_scrapers.py +370 -0
  97. tests/test_server_actions.py +93 -0
  98. tests/test_server_frontier_actions.py +269 -0
  99. tests/test_server_protocol.py +88 -0
  100. tests/test_stealth_browser.py +970 -0
  101. tests/test_system3.py +381 -0
  102. tests/test_system3_deep_integration.py +385 -0
  103. tests/test_system3_frontier.py +436 -0
  104. tests/test_vector_engine.py +608 -0
@@ -0,0 +1,126 @@
1
+ """Regression coverage for descriptor-relative boundary operations."""
2
+ from __future__ import annotations
3
+
4
+ import hashlib
5
+ import os
6
+ import shutil
7
+ import tempfile
8
+ import unittest
9
+ from pathlib import Path
10
+ from unittest import mock
11
+
12
+
13
+ class DescriptorBoundaryTests(unittest.TestCase):
14
+ @unittest.skipIf(os.name == "nt", "Windows handle-relative race probe requires native CI implementation")
15
+ def test_broker_parent_swap_cannot_redirect_read_write_or_cwd(self):
16
+ import fable_v2.execution_broker as broker
17
+
18
+ with tempfile.TemporaryDirectory() as td:
19
+ root = Path(td) / "workspace"
20
+ root.mkdir()
21
+ sub = root / "sub"
22
+ sub.mkdir()
23
+ outside = Path(td) / "outside"
24
+ outside.mkdir()
25
+ (outside / "secret").write_text("outside")
26
+ policy = broker.BrokerPolicy(root, allowed_executables=("true",))
27
+ instance = broker.ExecutionBroker(policy)
28
+ original = broker._open_child_dirs
29
+
30
+ def swap(root_fd, parts, *, create=False):
31
+ if parts:
32
+ shutil.rmtree(sub)
33
+ sub.symlink_to(outside, target_is_directory=True)
34
+ return original(root_fd, parts, create=create)
35
+
36
+ with mock.patch.object(broker, "_open_child_dirs", side_effect=swap):
37
+ with self.assertRaises(Exception):
38
+ instance.inspect_files("sub/secret")
39
+ instance._writes_unlocked = True
40
+ with self.assertRaises(Exception):
41
+ instance.write_file("sub/new", "must stay inside")
42
+ with self.assertRaises(Exception):
43
+ instance.execute_command(("true",), cwd="sub", timeout_seconds=1)
44
+ self.assertFalse((outside / "new").exists())
45
+ self.assertFalse((outside / "cwd-race").exists())
46
+
47
+ def test_config_atomic_write_rejects_parent_swap(self):
48
+ import fable_mode.adapters as adapters
49
+
50
+ with tempfile.TemporaryDirectory() as td:
51
+ root = Path(td)
52
+ parent = root / "config"
53
+ parent.mkdir()
54
+ outside = root / "outside"
55
+ outside.mkdir()
56
+ target = parent / "mcp.json"
57
+ original = adapters._safe_path
58
+ fired = False
59
+
60
+ def swap(path, *args, **kwargs):
61
+ nonlocal fired
62
+ result = original(path, *args, **kwargs)
63
+ if path == parent and not fired:
64
+ fired = True
65
+ shutil.rmtree(parent)
66
+ parent.symlink_to(outside, target_is_directory=True)
67
+ return result
68
+
69
+ with mock.patch.object(adapters, "_safe_path", side_effect=swap):
70
+ with self.assertRaises(Exception):
71
+ adapters._atomic_write(target, b"secret")
72
+ self.assertFalse((outside / "mcp.json").exists())
73
+
74
+ def test_session_and_cas_parent_swaps_fail_closed(self):
75
+ import fable_engine.server as server
76
+
77
+ with tempfile.TemporaryDirectory() as td:
78
+ root = Path(td)
79
+ sessions = root / "sessions"
80
+ sessions.mkdir()
81
+ outside = root / "outside"
82
+ outside.mkdir()
83
+ target = sessions / "x.json"
84
+ original_assert = server._assert_private_path
85
+ fired = False
86
+
87
+ def swap(path):
88
+ nonlocal fired
89
+ original_assert(path)
90
+ if path == sessions and not fired:
91
+ fired = True
92
+ shutil.rmtree(sessions)
93
+ sessions.symlink_to(outside, target_is_directory=True)
94
+
95
+ with mock.patch.object(server, "_assert_private_path", side_effect=swap):
96
+ with self.assertRaises(Exception):
97
+ server.FableSession("x", "x", 1).save(target)
98
+ self.assertFalse((outside / "x.json").exists())
99
+
100
+ cas_root = root / "cas"
101
+ store = server.FableCASStore(cas_root)
102
+ payload = b"payload"
103
+ digest = hashlib.sha256(payload).hexdigest()
104
+ shard = cas_root / "objects" / digest[:2]
105
+ outside_shard = root / "outside-shard"
106
+ outside_shard.mkdir()
107
+ original_safe = server._safe_cas_node
108
+ fired = False
109
+
110
+ def cas_swap(path, *args, **kwargs):
111
+ nonlocal fired
112
+ result = original_safe(path, *args, **kwargs)
113
+ if path == store._get_object_path(digest) and not fired:
114
+ fired = True
115
+ shutil.rmtree(shard)
116
+ shard.symlink_to(outside_shard, target_is_directory=True)
117
+ return result
118
+
119
+ with mock.patch.object(server, "_safe_cas_node", side_effect=cas_swap):
120
+ with self.assertRaises(Exception):
121
+ store.put(payload)
122
+ self.assertFalse((outside_shard / digest[2:]).exists())
123
+
124
+
125
+ if __name__ == "__main__":
126
+ unittest.main()