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.
- fable_compressor.py +356 -0
- fable_engine/__init__.py +1 -0
- fable_engine/actions/__init__.py +291 -0
- fable_engine/actions/cas.py +182 -0
- fable_engine/actions/deliberation.py +523 -0
- fable_engine/actions/fleet.py +807 -0
- fable_engine/actions/lifecycle.py +298 -0
- fable_engine/actions/scrapers.py +116 -0
- fable_engine/actions/system3.py +815 -0
- fable_engine/browser.py +824 -0
- fable_engine/cas.py +974 -0
- fable_engine/fable_session.json +510 -0
- fable_engine/guards.py +283 -0
- fable_engine/schema.py +714 -0
- fable_engine/scrapers/__init__.py +32 -0
- fable_engine/scrapers/arxiv.py +115 -0
- fable_engine/scrapers/base.py +386 -0
- fable_engine/scrapers/github.py +129 -0
- fable_engine/scrapers/reddit.py +154 -0
- fable_engine/scrapers/web.py +120 -0
- fable_engine/scrapers/x.py +125 -0
- fable_engine/scrapers/youtube.py +132 -0
- fable_engine/server.py +414 -0
- fable_engine/session.py +1819 -0
- fable_engine/test_server.py +1362 -0
- fable_engine/updater.py +541 -0
- fable_engine-1.3.1.dist-info/LICENSE +22 -0
- fable_engine-1.3.1.dist-info/METADATA +173 -0
- fable_engine-1.3.1.dist-info/RECORD +104 -0
- fable_engine-1.3.1.dist-info/WHEEL +5 -0
- fable_engine-1.3.1.dist-info/entry_points.txt +5 -0
- fable_engine-1.3.1.dist-info/top_level.txt +6 -0
- fable_mode/__init__.py +3 -0
- fable_mode/__main__.py +4 -0
- fable_mode/adapters.py +1014 -0
- fable_mode/installer.py +553 -0
- fable_mode/launcher.py +437 -0
- fable_mode/manifest.py +142 -0
- fable_mode/resources.json +114 -0
- fable_mode/safety.py +103 -0
- fable_mode_entry.py +10 -0
- fable_v2/__init__.py +146 -0
- fable_v2/adapters.py +151 -0
- fable_v2/coder_fleet/__init__.py +100 -0
- fable_v2/coder_fleet/ast_tools.py +158 -0
- fable_v2/coder_fleet/compute.py +199 -0
- fable_v2/coder_fleet/design_engine.py +1316 -0
- fable_v2/coder_fleet/diagnostics.py +293 -0
- fable_v2/coder_fleet/fleet_dispatcher.py +214 -0
- fable_v2/coder_fleet/mock_auditor.py +306 -0
- fable_v2/coder_fleet/mutation.py +216 -0
- fable_v2/coder_fleet/property_oracle.py +260 -0
- fable_v2/coder_fleet/receipt_attestor.py +122 -0
- fable_v2/coder_fleet/red_team_swarm.py +908 -0
- fable_v2/coder_fleet/test_harness.py +198 -0
- fable_v2/coder_fleet/vector_engine.py +1287 -0
- fable_v2/coder_fleet/visual.py +357 -0
- fable_v2/coder_fleet/workspace.py +153 -0
- fable_v2/cortical/__init__.py +20 -0
- fable_v2/cortical/plasticity_engine.py +992 -0
- fable_v2/execution_broker.py +811 -0
- fable_v2/proof_engine.py +1141 -0
- fable_v2/protocol.py +485 -0
- fable_v2/runtime.py +1010 -0
- fable_v2/system3/__init__.py +204 -0
- fable_v2/system3/causal.py +558 -0
- fable_v2/system3/dialectical.py +577 -0
- fable_v2/system3/evolution.py +503 -0
- fable_v2/system3/executive.py +338 -0
- fable_v2/system3/free_energy.py +479 -0
- fable_v2/system3/hyperbolic.py +555 -0
- fable_v2/system3/induction.py +336 -0
- fable_v2/system3/kripke.py +548 -0
- fable_v2/system3/oracle.py +745 -0
- fable_v2/verifiers.py +72 -0
- tests/__init__.py +1 -0
- tests/test_anti_loop_circuit_breaker.py +64 -0
- tests/test_auto_updater.py +407 -0
- tests/test_coder_fleet.py +535 -0
- tests/test_delegation_compiler.py +54 -0
- tests/test_descriptor_boundaries.py +126 -0
- tests/test_design_engine.py +603 -0
- tests/test_epistemic_evidence_validator.py +66 -0
- tests/test_execution_broker.py +233 -0
- tests/test_fable_v2.py +406 -0
- tests/test_fleet_transitions.py +116 -0
- tests/test_fsm_redteam_evolution.py +406 -0
- tests/test_goal_rubric_and_pipeline.py +367 -0
- tests/test_hebbian_plasticity.py +585 -0
- tests/test_packaging_runtime.py +194 -0
- tests/test_proof_engine.py +259 -0
- tests/test_red_team_swarm.py +645 -0
- tests/test_redteam_remediation.py +169 -0
- tests/test_registration_transaction.py +375 -0
- tests/test_requested_regressions.py +467 -0
- tests/test_scrapers.py +370 -0
- tests/test_server_actions.py +93 -0
- tests/test_server_frontier_actions.py +269 -0
- tests/test_server_protocol.py +88 -0
- tests/test_stealth_browser.py +970 -0
- tests/test_system3.py +381 -0
- tests/test_system3_deep_integration.py +385 -0
- tests/test_system3_frontier.py +436 -0
- 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()
|