v1_mirror_reader.py python
84 lines 3.6 KB
Raw
sha256:c87cf2c2f03da507f66f93922cb339a2cbebb33ad6372a6039032fb09a20da12 Reconcile reviewed Overseer recovery d47291d5d9030de5ebef71… Human minor ⚠ breaking 8 days ago
1 """Pinned native object reads for offline mirror projection; no native exporter.
2
3 The Muse snapshot lacks POSIX metadata. The caller approves executable paths;
4 this helper refuses symlinks and verifies working bytes/modes against that policy.
5 All blobs, including excluded ones, must exist and pass native hash validation.
6 """
7 from __future__ import annotations
8
9 import base64
10 import json
11 from pathlib import Path
12 import stat
13 import sys
14
15 sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
16 from cli.v1_io import Refusal, confined, read
17 from cli.v1_muse_reader import run
18 from cli.v1_policy import local_path
19
20 MAX_BYTES = 32 * 1024 * 1024
21
22
23 def excluded(path):
24 parts = path.split('/')
25 return (local_path(path) or any(p.lower() in {'.git', '.muse'} for p in parts)
26 or any(p == '.env' or p.startswith('.env.') for p in parts)
27 or path == '.overseer/.muse-bridge-sentinel')
28
29
30 def projection(root, executables):
31 state = run(root, False) # Installs the R1 side-effect assertion and pins APIs.
32 from muse.core.commits import read_commit
33 from muse.core.snapshots import read_snapshot
34 from muse.core.object_store import read_object
35 store = Path(state['store'])
36 for path in ('.muse/bridge-hooks.toml', '.muse/hooks'):
37 if (store / path).exists() or (store / path).is_symlink():
38 raise Refusal('inherited_muse_hooks: ' + path)
39 if state['head'] == 'unborn':
40 raise Refusal('mirror_source_unborn')
41 stage = read(store, '.muse/code/stage.json', missing=True)
42 if stage and json.loads(stage).get('entries'):
43 raise Refusal('mirror_source_staged')
44 commit = read_commit(store, state['head'])
45 snapshot = read_snapshot(store, commit.snapshot_id)
46 result, omitted, total = {}, [], 0
47 for path, oid in sorted(snapshot.manifest.items()):
48 if (not path or path != Path(path).as_posix() or Path(path).is_absolute()
49 or any(p in {'', '.', '..'} for p in path.split('/'))
50 or any(ord(c) < 32 for c in path) or '\\' in path):
51 raise Refusal('mirror_snapshot_path_invalid')
52 data = read_object(store, oid)
53 if data is None:
54 raise Refusal('mirror_blob_missing: ' + path)
55 total += len(data)
56 if total > MAX_BYTES:
57 raise Refusal('mirror_projection_too_large')
58 if excluded(path):
59 omitted.append(path)
60 continue
61 file = confined(root, path)
62 mode = 0o755 if path in executables else 0o644
63 actual = stat.S_IMODE(file.stat().st_mode)
64 if actual & 0o7000 or bool(actual & 0o111) != (path in executables):
65 raise Refusal('mirror_mode_mismatch: ' + path)
66 if file.read_bytes() != data:
67 raise Refusal('mirror_source_working_drift: ' + path)
68 result[path] = {'data': base64.b64encode(data).decode(), 'mode': format(mode | stat.S_IFREG, 'o')}
69 if set(executables) - result.keys():
70 raise Refusal('mirror_executable_not_projected')
71 if run(root, False) != state:
72 raise Refusal('mirror_source_changed')
73 return {'state': state, 'files': result, 'excluded': omitted,
74 'directories_omitted': snapshot.directories}
75
76
77 if __name__ == '__main__':
78 try:
79 print(json.dumps(projection(Path(sys.argv[1]), json.loads(sys.argv[2]))))
80 except Exception as exc:
81 # R1's bounded process reader intentionally discards stderr. Return only
82 # a bounded diagnostic (never object bytes) through its structured channel.
83 print(json.dumps({'error': (str(exc) if isinstance(exc, Refusal) else type(exc).__name__)[:300]}))
84 raise SystemExit(2)
File History 1 commit
sha256:c87cf2c2f03da507f66f93922cb339a2cbebb33ad6372a6039032fb09a20da12 Reconcile reviewed Overseer recovery d47291d5d9030de5ebef71… Human minor ⚠ 8 days ago