gabriel / muse public
merge_debug.py python
51 lines 1.5 KB
Raw
sha256:39065bc65b1a541916c4ea32ccd53eac38bb93015db2be2e342326064e86c44f fix: convergent-edit phantom conflicts in ops_commute + mer… Sonnet 4.6 minor ⚠ breaking 10 days ago
1 """Merge debug instrumentation — enabled by MUSE_MERGE_DEBUG=1.
2
3 When the env var is set, every merge event is appended as a JSON line to
4 /tmp/muse_merge_debug.log. Importing this module is always safe; logging is
5 a no-op unless the env var is set.
6
7 Usage::
8
9 from muse.core.merge_debug import merge_debug_log
10 merge_debug_log("phase", {"key": "value"})
11 """
12
13 from __future__ import annotations
14
15 import json
16 import os
17 import pathlib
18 import time
19
20 from muse.core.types import JsonObject, Manifest
21
22 _ENABLED = os.getenv("MUSE_MERGE_DEBUG", "").strip() not in ("", "0", "false", "no")
23 _LOG_PATH = pathlib.Path(os.getenv("MUSE_MERGE_DEBUG_LOG", "/tmp/muse_merge_debug.log"))
24
25
26 def merge_debug_log(event: str, data: JsonObject) -> None:
27 """Append a JSON-line record to the merge debug log.
28
29 No-op unless MUSE_MERGE_DEBUG=1. Never raises — debug logging must not
30 break the merge path.
31 """
32 if not _ENABLED:
33 return
34 try:
35 record = {"t": round(time.time(), 4), "event": event, **data}
36 with _LOG_PATH.open("a") as fh:
37 fh.write(json.dumps(record) + "\n")
38 except Exception: # pragma: no cover
39 pass # debug logging must never break the merge path
40
41
42 def merge_debug_manifest_summary(manifest: Manifest) -> JsonObject:
43 """Return a compact, loggable summary of a manifest.
44
45 Full manifest is included — every path and object_id — so we can
46 reconstruct exactly what both sides held at merge time.
47 """
48 return {
49 "file_count": len(manifest),
50 "files": manifest,
51 }
File History 1 commit
sha256:39065bc65b1a541916c4ea32ccd53eac38bb93015db2be2e342326064e86c44f fix: convergent-edit phantom conflicts in ops_commute + mer… Sonnet 4.6 minor 10 days ago