graphite-code 0.3.0__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 (112) hide show
  1. graphite/__init__.py +41 -0
  2. graphite/__main__.py +7 -0
  3. graphite/_cleanup_worker.py +525 -0
  4. graphite/activation.py +164 -0
  5. graphite/agent_hooks.py +577 -0
  6. graphite/agent_settings.py +226 -0
  7. graphite/analyze.py +146 -0
  8. graphite/answer_contract.py +420 -0
  9. graphite/bootstrap.py +210 -0
  10. graphite/buildlock.py +99 -0
  11. graphite/cache.py +131 -0
  12. graphite/channel.py +1325 -0
  13. graphite/cli.py +3053 -0
  14. graphite/cluster.py +111 -0
  15. graphite/config.py +209 -0
  16. graphite/context.py +355 -0
  17. graphite/daemon.py +745 -0
  18. graphite/daemon_health.py +733 -0
  19. graphite/debt.py +118 -0
  20. graphite/dependency_install.py +1597 -0
  21. graphite/detach.py +33 -0
  22. graphite/doctor.py +678 -0
  23. graphite/doctor_probes.py +2100 -0
  24. graphite/engine_identity.py +238 -0
  25. graphite/export/__init__.py +6 -0
  26. graphite/export/html.py +244 -0
  27. graphite/export/json.py +39 -0
  28. graphite/export/md.py +68 -0
  29. graphite/extract/__init__.py +4 -0
  30. graphite/extract/ast.py +1964 -0
  31. graphite/freshness.py +127 -0
  32. graphite/git.py +406 -0
  33. graphite/graph.py +117 -0
  34. graphite/graph_io.py +188 -0
  35. graphite/health.py +147 -0
  36. graphite/hook_entry.py +68 -0
  37. graphite/hookinstall.py +224 -0
  38. graphite/hookshim.py +86 -0
  39. graphite/incident_ledger.py +247 -0
  40. graphite/ingest.py +279 -0
  41. graphite/init.py +791 -0
  42. graphite/io.py +32 -0
  43. graphite/listing.py +51 -0
  44. graphite/llm.py +518 -0
  45. graphite/llm_probe.py +157 -0
  46. graphite/mcp.py +7 -0
  47. graphite/mcp_server.py +450 -0
  48. graphite/natural_query.py +252 -0
  49. graphite/overlays.py +713 -0
  50. graphite/probe_process.py +879 -0
  51. graphite/probe_workspace.py +728 -0
  52. graphite/process_contracts.py +22 -0
  53. graphite/provider_observer.py +397 -0
  54. graphite/query.py +646 -0
  55. graphite/query_plan.py +97 -0
  56. graphite/replacement_audit.py +291 -0
  57. graphite/resolve.py +660 -0
  58. graphite/review.py +782 -0
  59. graphite/routing/__init__.py +5 -0
  60. graphite/routing/approval.py +362 -0
  61. graphite/routing/classifier.py +169 -0
  62. graphite/routing/claude_executor.py +419 -0
  63. graphite/routing/claude_probe.py +102 -0
  64. graphite/routing/cli_identity.py +84 -0
  65. graphite/routing/codex_executor.py +383 -0
  66. graphite/routing/codex_probe.py +93 -0
  67. graphite/routing/context_builder.py +327 -0
  68. graphite/routing/contracts.py +802 -0
  69. graphite/routing/diff_policy.py +468 -0
  70. graphite/routing/edit_apply.py +166 -0
  71. graphite/routing/effort.py +43 -0
  72. graphite/routing/lifecycle.py +771 -0
  73. graphite/routing/lifecycle_operator.py +227 -0
  74. graphite/routing/lifecycle_service.py +555 -0
  75. graphite/routing/lifecycle_storage.py +977 -0
  76. graphite/routing/ollama_executor.py +341 -0
  77. graphite/routing/ollama_probe.py +72 -0
  78. graphite/routing/openrouter_executor.py +338 -0
  79. graphite/routing/openrouter_probe.py +188 -0
  80. graphite/routing/policy.py +815 -0
  81. graphite/routing/probe_runner.py +543 -0
  82. graphite/routing/process_runner.py +523 -0
  83. graphite/routing/profiles.py +554 -0
  84. graphite/routing/prompt.py +58 -0
  85. graphite/routing/registry.py +444 -0
  86. graphite/routing/route_pool.py +629 -0
  87. graphite/routing/route_pool_execution.py +275 -0
  88. graphite/routing/schema_validation.py +169 -0
  89. graphite/routing/service.py +1263 -0
  90. graphite/routing/settings.py +99 -0
  91. graphite/routing/shadow.py +201 -0
  92. graphite/routing/storage.py +4001 -0
  93. graphite/routing/telemetry.py +346 -0
  94. graphite/routing/worktree.py +259 -0
  95. graphite/routing/zai_edit.py +113 -0
  96. graphite/routing/zai_executor.py +191 -0
  97. graphite/routing/zai_probe.py +126 -0
  98. graphite/savings.py +84 -0
  99. graphite/ts_bridge.py +142 -0
  100. graphite/ts_resolver.mjs +314 -0
  101. graphite/typescript_activation.py +1586 -0
  102. graphite/usage_ledger.py +156 -0
  103. graphite/validation.py +148 -0
  104. graphite/watch.py +167 -0
  105. graphite/windows_job.py +368 -0
  106. graphite/windows_startup.py +144 -0
  107. graphite/windows_task.py +212 -0
  108. graphite_code-0.3.0.dist-info/METADATA +743 -0
  109. graphite_code-0.3.0.dist-info/RECORD +112 -0
  110. graphite_code-0.3.0.dist-info/WHEEL +4 -0
  111. graphite_code-0.3.0.dist-info/entry_points.txt +3 -0
  112. graphite_code-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,728 @@
1
+ """Private, identity-bound workspace leases for destructive readiness probes.
2
+
3
+ The local OS user and same-user process namespace remain a trust boundary. The
4
+ lease provides best-effort identity checks and Windows rename pinning; it does
5
+ not claim complete protection from a malicious process running as that user.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import ctypes
10
+ import os
11
+ import secrets
12
+ import shutil
13
+ import stat
14
+ import tempfile
15
+ from collections.abc import Callable
16
+ from dataclasses import dataclass
17
+ from pathlib import Path
18
+
19
+
20
+ class WorkspaceLeaseError(RuntimeError):
21
+ """A workspace could not be acquired, revalidated, or safely cleaned."""
22
+
23
+ def __init__(self, code: str) -> None:
24
+ super().__init__(code)
25
+ self.code = code
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class _PathSnapshot:
30
+ lexical: Path
31
+ canonical: Path
32
+ identity: tuple[int, int]
33
+ size: int
34
+ mtime_ns: int
35
+ mode: int
36
+ uid: int | None
37
+ gid: int | None
38
+
39
+
40
+ ParentFactory = Callable[..., str]
41
+ OwnedDirectoryFactory = Callable[[Path], tuple[Path, tuple[int, int]]]
42
+
43
+
44
+ class ProbeWorkspaceLease:
45
+ """Own a private parent and fixed child workspace until bounded cleanup."""
46
+
47
+ def __init__(
48
+ self,
49
+ *,
50
+ temp_root: Path,
51
+ parent: _PathSnapshot,
52
+ workspace: _PathSnapshot,
53
+ temp_root_handle: int | None,
54
+ parent_handle: int,
55
+ workspace_handle: int,
56
+ windows_handle_identities: tuple[tuple[int, int, int], tuple[int, int, int]] | None,
57
+ ) -> None:
58
+ self.temp_root = temp_root
59
+ self._parent = parent
60
+ self._workspace = workspace
61
+ self._temp_root_handle: int | None = temp_root_handle
62
+ self._parent_handle: int | None = parent_handle
63
+ self._workspace_handle: int | None = workspace_handle
64
+ self._windows_handle_identities = windows_handle_identities
65
+ self._closed = False
66
+ self._cleaned = False
67
+
68
+ @property
69
+ def parent_path(self) -> Path:
70
+ return self._parent.lexical
71
+
72
+ @property
73
+ def path(self) -> Path:
74
+ return self._workspace.lexical
75
+
76
+ @classmethod
77
+ def acquire(
78
+ cls,
79
+ *,
80
+ temp_root: Path | None = None,
81
+ _parent_factory: ParentFactory | None = None,
82
+ _owned_parent_factory: OwnedDirectoryFactory | None = None,
83
+ _workspace_factory: OwnedDirectoryFactory | None = None,
84
+ ) -> ProbeWorkspaceLease:
85
+ """Create and pin a private randomized parent with a fixed workspace child."""
86
+ try:
87
+ root = (temp_root or Path(tempfile.gettempdir())).resolve(strict=True)
88
+ if not root.is_dir():
89
+ raise WorkspaceLeaseError("workspace_isolation_failed")
90
+ except (OSError, RuntimeError) as exc:
91
+ raise WorkspaceLeaseError("workspace_isolation_failed") from exc
92
+
93
+ parent_path: Path | None = None
94
+ workspace_path: Path | None = None
95
+ parent_handle: int | None = None
96
+ workspace_handle: int | None = None
97
+ temp_root_handle: int | None = None
98
+ parent_owned: _PathSnapshot | None = None
99
+ workspace_owned: _PathSnapshot | None = None
100
+ try:
101
+ if os.name != "nt":
102
+ root_snapshot = _snapshot(root, root)
103
+ temp_root_handle, root_handle_identity = _open_directory_handle(root)
104
+ _assert_handle_matches_snapshot(
105
+ temp_root_handle,
106
+ root_handle_identity,
107
+ root_snapshot,
108
+ )
109
+ if _parent_factory is not None:
110
+ if _owned_parent_factory is not None:
111
+ raise WorkspaceLeaseError("workspace_isolation_failed")
112
+ parent_path = Path(
113
+ _parent_factory(prefix="graphite-doctor-", dir=str(root))
114
+ )
115
+ parent_path = Path(os.path.abspath(parent_path))
116
+ _snapshot(parent_path, root)
117
+ # A path-only factory provides no proof that this acquisition
118
+ # created the candidate. It is safe to inspect, never to adopt.
119
+ raise WorkspaceLeaseError("workspace_isolation_failed")
120
+ parent_creator = _owned_parent_factory or _create_owned_parent
121
+ parent_path, parent_identity = parent_creator(root)
122
+ parent_path = Path(os.path.abspath(parent_path))
123
+ parent_before = _snapshot(parent_path, root)
124
+ if parent_before.identity != parent_identity:
125
+ raise WorkspaceLeaseError("workspace_isolation_failed")
126
+ parent_owned = parent_before
127
+ if os.name != "nt" and parent_before.mode != 0o700:
128
+ raise WorkspaceLeaseError("workspace_isolation_failed")
129
+ if os.name == "nt" and _owned_parent_factory is not None:
130
+ _set_private_windows_dacl(parent_path)
131
+ parent_handle, parent_handle_identity = _open_directory_handle(parent_path)
132
+ _assert_handle_matches_snapshot(
133
+ parent_handle,
134
+ parent_handle_identity,
135
+ parent_before,
136
+ )
137
+
138
+ workspace_path = parent_path / "workspace"
139
+ workspace_creator = _workspace_factory or _create_owned_workspace
140
+ if _workspace_factory is None and os.name != "nt":
141
+ created_workspace_path, workspace_identity = _create_owned_workspace(
142
+ parent_path,
143
+ parent_handle,
144
+ )
145
+ else:
146
+ created_workspace_path, workspace_identity = workspace_creator(parent_path)
147
+ created_workspace_path = Path(os.path.abspath(created_workspace_path))
148
+ if created_workspace_path != workspace_path:
149
+ raise WorkspaceLeaseError("workspace_isolation_failed")
150
+ workspace_owned = _snapshot(created_workspace_path, root)
151
+ if workspace_owned.identity != workspace_identity:
152
+ workspace_owned = None
153
+ raise WorkspaceLeaseError("workspace_isolation_failed")
154
+ if os.name != "nt" and workspace_owned.mode != 0o700:
155
+ raise WorkspaceLeaseError("workspace_isolation_failed")
156
+ if os.name == "nt" and _workspace_factory is not None:
157
+ _set_private_windows_dacl(workspace_path)
158
+ workspace_snapshot = _snapshot(workspace_path, root)
159
+ workspace_handle, workspace_handle_identity = _open_directory_handle(workspace_path)
160
+ _assert_handle_matches_snapshot(
161
+ workspace_handle,
162
+ workspace_handle_identity,
163
+ workspace_snapshot,
164
+ )
165
+ parent_snapshot = _snapshot(parent_path, root)
166
+ if parent_snapshot.identity != parent_before.identity:
167
+ raise WorkspaceLeaseError("workspace_isolation_failed")
168
+ _assert_handle_matches_snapshot(
169
+ parent_handle,
170
+ parent_handle_identity,
171
+ parent_snapshot,
172
+ )
173
+ _assert_handle_matches_snapshot(
174
+ workspace_handle,
175
+ workspace_handle_identity,
176
+ workspace_snapshot,
177
+ )
178
+ return cls(
179
+ temp_root=root,
180
+ parent=parent_snapshot,
181
+ workspace=workspace_snapshot,
182
+ temp_root_handle=temp_root_handle,
183
+ parent_handle=parent_handle,
184
+ workspace_handle=workspace_handle,
185
+ windows_handle_identities=(parent_handle_identity, workspace_handle_identity)
186
+ if os.name == "nt"
187
+ else None,
188
+ )
189
+ except WorkspaceLeaseError:
190
+ _close_raw_handle(workspace_handle)
191
+ _close_raw_handle(parent_handle)
192
+ _close_raw_handle(temp_root_handle)
193
+ _initial_cleanup(root, parent_owned, workspace_owned)
194
+ raise
195
+ except (OSError, RuntimeError, ValueError) as exc:
196
+ _close_raw_handle(workspace_handle)
197
+ _close_raw_handle(parent_handle)
198
+ _close_raw_handle(temp_root_handle)
199
+ _initial_cleanup(root, parent_owned, workspace_owned)
200
+ raise WorkspaceLeaseError("workspace_isolation_failed") from exc
201
+
202
+ def validate(self) -> None:
203
+ """Revalidate containment, type, identity, ownership, and pinned handles."""
204
+ if self._closed or self._cleaned:
205
+ raise WorkspaceLeaseError("workspace_isolation_changed")
206
+ try:
207
+ parent = _snapshot(self.parent_path, self.temp_root)
208
+ workspace = _snapshot(self.path, self.temp_root)
209
+ if not _same_binding(parent, self._parent) or not _same_binding(workspace, self._workspace):
210
+ raise WorkspaceLeaseError("workspace_isolation_changed")
211
+ if os.name == "nt":
212
+ assert self._windows_handle_identities is not None
213
+ current_parent = _windows_handle_identity(self._required_handle(self._parent_handle))
214
+ current_workspace = _windows_handle_identity(self._required_handle(self._workspace_handle))
215
+ if (current_parent, current_workspace) != self._windows_handle_identities:
216
+ raise WorkspaceLeaseError("workspace_isolation_changed")
217
+ _assert_handle_matches_snapshot(
218
+ self._required_handle(self._parent_handle),
219
+ current_parent,
220
+ self._parent,
221
+ )
222
+ _assert_handle_matches_snapshot(
223
+ self._required_handle(self._workspace_handle),
224
+ current_workspace,
225
+ self._workspace,
226
+ )
227
+ else:
228
+ root_stat = os.fstat(self._required_handle(self._temp_root_handle))
229
+ parent_stat = os.fstat(self._required_handle(self._parent_handle))
230
+ workspace_stat = os.fstat(self._required_handle(self._workspace_handle))
231
+ root_path_stat = self.temp_root.lstat()
232
+ if (root_stat.st_dev, root_stat.st_ino) != (
233
+ root_path_stat.st_dev,
234
+ root_path_stat.st_ino,
235
+ ):
236
+ raise WorkspaceLeaseError("workspace_isolation_changed")
237
+ if (parent_stat.st_dev, parent_stat.st_ino) != self._parent.identity:
238
+ raise WorkspaceLeaseError("workspace_isolation_changed")
239
+ if (workspace_stat.st_dev, workspace_stat.st_ino) != self._workspace.identity:
240
+ raise WorkspaceLeaseError("workspace_isolation_changed")
241
+ except WorkspaceLeaseError:
242
+ raise
243
+ except (OSError, RuntimeError, ValueError) as exc:
244
+ raise WorkspaceLeaseError("workspace_isolation_changed") from exc
245
+
246
+ def cleanup(self) -> None:
247
+ """Delete only the still-bound lease target, otherwise deliberately leak it."""
248
+ if self._cleaned:
249
+ self.close()
250
+ return
251
+ try:
252
+ self.validate()
253
+ except WorkspaceLeaseError as exc:
254
+ self.close()
255
+ raise WorkspaceLeaseError("workspace_cleanup_blocked") from exc
256
+
257
+ try:
258
+ if os.name == "nt":
259
+ self._cleanup_windows()
260
+ else:
261
+ if not getattr(shutil.rmtree, "avoids_symlink_attacks", False):
262
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
263
+ if os.rmdir not in os.supports_dir_fd:
264
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
265
+ hook = getattr(self, "_before_cleanup_delete", None)
266
+ if hook is not None:
267
+ hook()
268
+ try:
269
+ self.validate()
270
+ except WorkspaceLeaseError as exc:
271
+ raise WorkspaceLeaseError("workspace_cleanup_blocked") from exc
272
+ if self.parent_path.parent != self.temp_root or self.path.name != "workspace":
273
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
274
+ shutil.rmtree(
275
+ self.path.name,
276
+ dir_fd=self._required_handle(self._parent_handle),
277
+ )
278
+ self._validate_posix_parent_binding()
279
+ os.rmdir(
280
+ self.parent_path.name,
281
+ dir_fd=self._required_handle(self._temp_root_handle),
282
+ )
283
+ self._cleaned = True
284
+ self.close()
285
+ except WorkspaceLeaseError:
286
+ self.close()
287
+ raise
288
+ except OSError as exc:
289
+ self.close()
290
+ raise WorkspaceLeaseError("workspace_cleanup_failed") from exc
291
+
292
+ def _cleanup_windows(self) -> None:
293
+ for entry in os.scandir(self.path):
294
+ entry_path = Path(entry.path)
295
+ if entry.is_dir(follow_symlinks=False):
296
+ shutil.rmtree(entry_path)
297
+ else:
298
+ entry_path.unlink()
299
+ self.validate()
300
+ _close_raw_handle(self._workspace_handle)
301
+ self._workspace_handle = None
302
+ os.rmdir(self.path)
303
+ parent = _snapshot(self.parent_path, self.temp_root)
304
+ if not _same_binding(parent, self._parent):
305
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
306
+ if any(os.scandir(self.parent_path)):
307
+ raise WorkspaceLeaseError("workspace_cleanup_failed")
308
+ _close_raw_handle(self._parent_handle)
309
+ self._parent_handle = None
310
+ os.rmdir(self.parent_path)
311
+ self._cleaned = True
312
+ self.close()
313
+
314
+ def close(self) -> None:
315
+ """Release lease handles; safe to call repeatedly."""
316
+ if self._closed:
317
+ return
318
+ _close_raw_handle(self._workspace_handle)
319
+ _close_raw_handle(self._parent_handle)
320
+ _close_raw_handle(self._temp_root_handle)
321
+ self._workspace_handle = None
322
+ self._parent_handle = None
323
+ self._temp_root_handle = None
324
+ self._closed = True
325
+
326
+ def _validate_posix_parent_binding(self) -> None:
327
+ parent = _snapshot(self.parent_path, self.temp_root)
328
+ if not _same_binding(parent, self._parent):
329
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
330
+ root_stat = os.fstat(self._required_handle(self._temp_root_handle))
331
+ path_root_stat = self.temp_root.lstat()
332
+ if (root_stat.st_dev, root_stat.st_ino) != (
333
+ path_root_stat.st_dev,
334
+ path_root_stat.st_ino,
335
+ ):
336
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
337
+ parent_stat = os.fstat(self._required_handle(self._parent_handle))
338
+ if (parent_stat.st_dev, parent_stat.st_ino) != self._parent.identity:
339
+ raise WorkspaceLeaseError("workspace_cleanup_blocked")
340
+
341
+ @staticmethod
342
+ def _required_handle(handle: int | None) -> int:
343
+ if handle is None:
344
+ raise WorkspaceLeaseError("workspace_isolation_changed")
345
+ return handle
346
+
347
+
348
+ def _snapshot(path: Path, root: Path) -> _PathSnapshot:
349
+ lexical = Path(os.path.abspath(path))
350
+ info = lexical.lstat()
351
+ if stat.S_ISLNK(info.st_mode) or not stat.S_ISDIR(info.st_mode) or _path_is_reparse(info):
352
+ raise WorkspaceLeaseError("workspace_isolation_failed")
353
+ canonical = lexical.resolve(strict=True)
354
+ try:
355
+ canonical.relative_to(root)
356
+ except ValueError as exc:
357
+ raise WorkspaceLeaseError("workspace_isolation_failed") from exc
358
+ if os.name == "nt" and _windows_path_is_reparse(lexical):
359
+ raise WorkspaceLeaseError("workspace_isolation_failed")
360
+ return _PathSnapshot(
361
+ lexical=lexical,
362
+ canonical=canonical,
363
+ identity=(info.st_dev, info.st_ino),
364
+ size=info.st_size,
365
+ mtime_ns=info.st_mtime_ns,
366
+ mode=stat.S_IMODE(info.st_mode),
367
+ uid=getattr(info, "st_uid", None),
368
+ gid=getattr(info, "st_gid", None),
369
+ )
370
+
371
+
372
+ def _same_binding(current: _PathSnapshot, expected: _PathSnapshot) -> bool:
373
+ return (
374
+ current.lexical == expected.lexical
375
+ and current.canonical == expected.canonical
376
+ and current.identity == expected.identity
377
+ and current.mode == expected.mode
378
+ and current.uid == expected.uid
379
+ and current.gid == expected.gid
380
+ )
381
+
382
+
383
+ def _path_is_reparse(info: os.stat_result) -> bool:
384
+ return bool(getattr(info, "st_file_attributes", 0) & 0x400)
385
+
386
+
387
+ def _create_owned_parent(root: Path) -> tuple[Path, tuple[int, int]]:
388
+ if os.name == "nt":
389
+ path = _create_private_windows_directory(root)
390
+ else:
391
+ path = Path(tempfile.mkdtemp(prefix="graphite-doctor-", dir=str(root)))
392
+ info = path.lstat()
393
+ return path, (info.st_dev, info.st_ino)
394
+
395
+
396
+ def _create_owned_workspace(
397
+ parent: Path,
398
+ parent_handle: int | None = None,
399
+ ) -> tuple[Path, tuple[int, int]]:
400
+ if os.name == "nt":
401
+ path = _create_private_windows_directory(parent, "workspace")
402
+ else:
403
+ path = parent / "workspace"
404
+ if parent_handle is None:
405
+ os.mkdir(path, 0o700)
406
+ info = path.lstat()
407
+ return path, (info.st_dev, info.st_ino)
408
+ os.mkdir(path.name, 0o700, dir_fd=parent_handle)
409
+ info = os.stat(path.name, dir_fd=parent_handle, follow_symlinks=False)
410
+ return path, (info.st_dev, info.st_ino)
411
+ info = path.lstat()
412
+ return path, (info.st_dev, info.st_ino)
413
+
414
+
415
+ def _initial_cleanup(
416
+ root: Path,
417
+ parent: _PathSnapshot | None,
418
+ workspace: _PathSnapshot | None,
419
+ ) -> None:
420
+ for owned in (workspace, parent):
421
+ if owned is None:
422
+ continue
423
+ try:
424
+ current = _snapshot(owned.lexical, root)
425
+ if _same_binding(current, owned):
426
+ os.rmdir(owned.lexical)
427
+ except (OSError, WorkspaceLeaseError):
428
+ # Acquisition failure cleanup is deliberately best effort. An
429
+ # uncertain binding is leaked rather than pathname-deleted.
430
+ pass
431
+
432
+
433
+ def _open_directory_handle(path: Path) -> tuple[int, tuple[int, int, int]]:
434
+ if os.name != "nt":
435
+ flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0)
436
+ handle = os.open(path, flags)
437
+ os.set_inheritable(handle, False)
438
+ info = os.fstat(handle)
439
+ return handle, (info.st_dev, 0, info.st_ino)
440
+
441
+ from ctypes import wintypes
442
+
443
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
444
+ create_file = kernel32.CreateFileW
445
+ create_file.argtypes = [
446
+ wintypes.LPCWSTR,
447
+ wintypes.DWORD,
448
+ wintypes.DWORD,
449
+ wintypes.LPVOID,
450
+ wintypes.DWORD,
451
+ wintypes.DWORD,
452
+ wintypes.HANDLE,
453
+ ]
454
+ create_file.restype = wintypes.HANDLE
455
+ handle = create_file(
456
+ str(path),
457
+ 0x80000000 | 0x80,
458
+ 0x1 | 0x2,
459
+ None,
460
+ 3,
461
+ 0x02000000 | 0x00200000,
462
+ None,
463
+ )
464
+ invalid_handle = ctypes.c_void_p(-1).value
465
+ if handle == invalid_handle:
466
+ raise ctypes.WinError(ctypes.get_last_error())
467
+ raw_handle = int(handle)
468
+ set_handle_information = kernel32.SetHandleInformation
469
+ set_handle_information.argtypes = [wintypes.HANDLE, wintypes.DWORD, wintypes.DWORD]
470
+ set_handle_information.restype = wintypes.BOOL
471
+ if not set_handle_information(raw_handle, 0x1, 0):
472
+ error = ctypes.get_last_error()
473
+ _close_raw_handle(raw_handle)
474
+ raise ctypes.WinError(error)
475
+ try:
476
+ identity = _windows_handle_identity(raw_handle)
477
+ _reject_windows_handle_reparse(raw_handle)
478
+ return raw_handle, identity
479
+ except Exception:
480
+ _close_raw_handle(raw_handle)
481
+ raise
482
+
483
+
484
+ def _close_raw_handle(handle: int | None) -> None:
485
+ if handle is None:
486
+ return
487
+ if os.name != "nt":
488
+ try:
489
+ os.close(handle)
490
+ except OSError:
491
+ pass
492
+ return
493
+ from ctypes import wintypes
494
+
495
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
496
+ close_handle = kernel32.CloseHandle
497
+ close_handle.argtypes = [wintypes.HANDLE]
498
+ close_handle.restype = wintypes.BOOL
499
+ close_handle(handle)
500
+
501
+
502
+ def _windows_handle_identity(handle: int) -> tuple[int, int, int]:
503
+ from ctypes import wintypes
504
+
505
+ class ByHandleFileInformation(ctypes.Structure):
506
+ _fields_ = [
507
+ ("file_attributes", wintypes.DWORD),
508
+ ("creation_time", wintypes.FILETIME),
509
+ ("last_access_time", wintypes.FILETIME),
510
+ ("last_write_time", wintypes.FILETIME),
511
+ ("volume_serial_number", wintypes.DWORD),
512
+ ("file_size_high", wintypes.DWORD),
513
+ ("file_size_low", wintypes.DWORD),
514
+ ("number_of_links", wintypes.DWORD),
515
+ ("file_index_high", wintypes.DWORD),
516
+ ("file_index_low", wintypes.DWORD),
517
+ ]
518
+
519
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
520
+ function = kernel32.GetFileInformationByHandle
521
+ function.argtypes = [wintypes.HANDLE, ctypes.POINTER(ByHandleFileInformation)]
522
+ function.restype = wintypes.BOOL
523
+ information = ByHandleFileInformation()
524
+ if not function(handle, ctypes.byref(information)):
525
+ raise ctypes.WinError(ctypes.get_last_error())
526
+ return (
527
+ information.volume_serial_number,
528
+ information.file_index_high,
529
+ information.file_index_low,
530
+ )
531
+
532
+
533
+ def _windows_handle_final_path(handle: int) -> Path:
534
+ from ctypes import wintypes
535
+
536
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
537
+ function = kernel32.GetFinalPathNameByHandleW
538
+ function.argtypes = [wintypes.HANDLE, wintypes.LPWSTR, wintypes.DWORD, wintypes.DWORD]
539
+ function.restype = wintypes.DWORD
540
+ buffer = ctypes.create_unicode_buffer(32768)
541
+ length = function(handle, buffer, len(buffer), 0)
542
+ if not length or length >= len(buffer):
543
+ raise ctypes.WinError(ctypes.get_last_error())
544
+ value = buffer.value
545
+ if value.startswith("\\\\?\\UNC\\"):
546
+ value = "\\\\" + value[8:]
547
+ elif value.startswith("\\\\?\\"):
548
+ value = value[4:]
549
+ return Path(value).resolve(strict=True)
550
+
551
+
552
+ def _assert_handle_matches_snapshot(
553
+ handle: int,
554
+ handle_identity: tuple[int, int, int],
555
+ snapshot: _PathSnapshot,
556
+ ) -> None:
557
+ if os.name == "nt":
558
+ file_index = (handle_identity[1] << 32) | handle_identity[2]
559
+ if file_index != snapshot.identity[1]:
560
+ raise WorkspaceLeaseError("workspace_isolation_failed")
561
+ final_path = _windows_handle_final_path(handle)
562
+ if os.path.normcase(str(final_path)) != os.path.normcase(str(snapshot.canonical)):
563
+ raise WorkspaceLeaseError("workspace_isolation_failed")
564
+ return
565
+ info = os.fstat(handle)
566
+ if (info.st_dev, info.st_ino) != snapshot.identity:
567
+ raise WorkspaceLeaseError("workspace_isolation_failed")
568
+
569
+
570
+ def _reject_windows_handle_reparse(handle: int) -> None:
571
+ from ctypes import wintypes
572
+
573
+ class FileAttributeTagInformation(ctypes.Structure):
574
+ _fields_ = [("file_attributes", wintypes.DWORD), ("reparse_tag", wintypes.DWORD)]
575
+
576
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
577
+ function = kernel32.GetFileInformationByHandleEx
578
+ function.argtypes = [wintypes.HANDLE, ctypes.c_int, wintypes.LPVOID, wintypes.DWORD]
579
+ function.restype = wintypes.BOOL
580
+ information = FileAttributeTagInformation()
581
+ if not function(handle, 9, ctypes.byref(information), ctypes.sizeof(information)):
582
+ raise ctypes.WinError(ctypes.get_last_error())
583
+ if information.file_attributes & 0x400 or information.reparse_tag:
584
+ raise WorkspaceLeaseError("workspace_isolation_failed")
585
+
586
+
587
+ def _windows_path_is_reparse(path: Path) -> bool:
588
+ if os.name != "nt":
589
+ return False
590
+ from ctypes import wintypes
591
+
592
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
593
+ function = kernel32.GetFileAttributesW
594
+ function.argtypes = [wintypes.LPCWSTR]
595
+ function.restype = wintypes.DWORD
596
+ attributes = function(str(path))
597
+ if attributes == 0xFFFFFFFF:
598
+ raise ctypes.WinError(ctypes.get_last_error())
599
+ return bool(attributes & 0x400)
600
+
601
+
602
+ def _windows_private_security_descriptor() -> int:
603
+ """Allocate a protected DACL granting full control only to the current user."""
604
+ from ctypes import wintypes
605
+
606
+ advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)
607
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
608
+ open_process_token = advapi32.OpenProcessToken
609
+ open_process_token.argtypes = [wintypes.HANDLE, wintypes.DWORD, ctypes.POINTER(wintypes.HANDLE)]
610
+ open_process_token.restype = wintypes.BOOL
611
+ get_token_information = advapi32.GetTokenInformation
612
+ get_token_information.argtypes = [
613
+ wintypes.HANDLE,
614
+ ctypes.c_int,
615
+ wintypes.LPVOID,
616
+ wintypes.DWORD,
617
+ ctypes.POINTER(wintypes.DWORD),
618
+ ]
619
+ get_token_information.restype = wintypes.BOOL
620
+ convert_sid = advapi32.ConvertSidToStringSidW
621
+ convert_sid.argtypes = [wintypes.LPVOID, ctypes.POINTER(wintypes.LPWSTR)]
622
+ convert_sid.restype = wintypes.BOOL
623
+ convert_descriptor = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
624
+ convert_descriptor.argtypes = [
625
+ wintypes.LPCWSTR,
626
+ wintypes.DWORD,
627
+ ctypes.POINTER(wintypes.LPVOID),
628
+ ctypes.POINTER(wintypes.DWORD),
629
+ ]
630
+ convert_descriptor.restype = wintypes.BOOL
631
+ local_free = kernel32.LocalFree
632
+ local_free.argtypes = [wintypes.HLOCAL]
633
+ local_free.restype = wintypes.HLOCAL
634
+ get_current_process = kernel32.GetCurrentProcess
635
+ get_current_process.argtypes = []
636
+ get_current_process.restype = wintypes.HANDLE
637
+
638
+ token = wintypes.HANDLE()
639
+ if not open_process_token(get_current_process(), 0x0008, ctypes.byref(token)):
640
+ raise ctypes.WinError(ctypes.get_last_error())
641
+ sid_text = wintypes.LPWSTR()
642
+ descriptor = wintypes.LPVOID()
643
+ try:
644
+ needed = wintypes.DWORD()
645
+ get_token_information(token, 1, None, 0, ctypes.byref(needed))
646
+ if not needed.value:
647
+ raise ctypes.WinError(ctypes.get_last_error())
648
+ buffer = ctypes.create_string_buffer(needed.value)
649
+ if not get_token_information(token, 1, buffer, needed, ctypes.byref(needed)):
650
+ raise ctypes.WinError(ctypes.get_last_error())
651
+ sid = ctypes.cast(buffer, ctypes.POINTER(wintypes.LPVOID))[0]
652
+ if not convert_sid(sid, ctypes.byref(sid_text)):
653
+ raise ctypes.WinError(ctypes.get_last_error())
654
+ sddl = f"D:P(A;OICI;FA;;;{sid_text.value})"
655
+ if not convert_descriptor(sddl, 1, ctypes.byref(descriptor), None):
656
+ raise ctypes.WinError(ctypes.get_last_error())
657
+ result = int(descriptor.value)
658
+ descriptor = wintypes.LPVOID()
659
+ return result
660
+ finally:
661
+ if descriptor:
662
+ local_free(descriptor)
663
+ if sid_text:
664
+ local_free(sid_text)
665
+ _close_raw_handle(int(token.value) if token.value else None)
666
+
667
+
668
+ def _free_windows_security_descriptor(descriptor: int) -> None:
669
+ from ctypes import wintypes
670
+
671
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
672
+ local_free = kernel32.LocalFree
673
+ local_free.argtypes = [wintypes.HLOCAL]
674
+ local_free.restype = wintypes.HLOCAL
675
+ local_free(descriptor)
676
+
677
+
678
+ def _create_private_windows_directory(parent: Path, name: str | None = None) -> Path:
679
+ """Create a Windows directory with its protected DACL applied atomically."""
680
+ from ctypes import wintypes
681
+
682
+ class SecurityAttributes(ctypes.Structure):
683
+ _fields_ = [
684
+ ("length", wintypes.DWORD),
685
+ ("security_descriptor", wintypes.LPVOID),
686
+ ("inherit_handle", wintypes.BOOL),
687
+ ]
688
+
689
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
690
+ create_directory = kernel32.CreateDirectoryW
691
+ create_directory.argtypes = [wintypes.LPCWSTR, ctypes.POINTER(SecurityAttributes)]
692
+ create_directory.restype = wintypes.BOOL
693
+ descriptor = _windows_private_security_descriptor()
694
+ attributes = SecurityAttributes(
695
+ ctypes.sizeof(SecurityAttributes),
696
+ ctypes.c_void_p(descriptor),
697
+ False,
698
+ )
699
+ try:
700
+ for _ in range(64):
701
+ child_name = name or f"graphite-doctor-{secrets.token_hex(16)}"
702
+ path = parent / child_name
703
+ if create_directory(str(path), ctypes.byref(attributes)):
704
+ return path
705
+ error = ctypes.get_last_error()
706
+ if name is not None or error != 183:
707
+ raise ctypes.WinError(error)
708
+ raise FileExistsError("unable to allocate a unique probe workspace parent")
709
+ finally:
710
+ _free_windows_security_descriptor(descriptor)
711
+
712
+
713
+ def _set_private_windows_dacl(path: Path) -> None:
714
+ """Apply the protected DACL to an already identity-verified injected path."""
715
+ if os.name != "nt":
716
+ return
717
+ from ctypes import wintypes
718
+
719
+ advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)
720
+ set_file_security = advapi32.SetFileSecurityW
721
+ set_file_security.argtypes = [wintypes.LPCWSTR, wintypes.DWORD, wintypes.LPVOID]
722
+ set_file_security.restype = wintypes.BOOL
723
+ descriptor = _windows_private_security_descriptor()
724
+ try:
725
+ if not set_file_security(str(path), 0x80000004, descriptor):
726
+ raise ctypes.WinError(ctypes.get_last_error())
727
+ finally:
728
+ _free_windows_security_descriptor(descriptor)