sourcepack 1.10.0a0__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.
- sourcepack/__init__.py +19 -0
- sourcepack/assets/__init__.py +1 -0
- sourcepack/assets/audit_template.md +3 -0
- sourcepack/assets/packet_instructions.md +3 -0
- sourcepack/baseline.py +285 -0
- sourcepack/cli.py +2991 -0
- sourcepack/commands.py +149 -0
- sourcepack/dependencies.py +98 -0
- sourcepack/diff_parser.py +122 -0
- sourcepack/ecosystems/__init__.py +3 -0
- sourcepack/ecosystems/generic.py +13 -0
- sourcepack/ecosystems/node.py +3 -0
- sourcepack/ecosystems/python.py +12 -0
- sourcepack/errors.py +19 -0
- sourcepack/evidence.py +109 -0
- sourcepack/execution_ledger.py +252 -0
- sourcepack/git.py +50 -0
- sourcepack/judgment.py +1922 -0
- sourcepack/packet.py +837 -0
- sourcepack/paths.py +68 -0
- sourcepack/policy.py +38 -0
- sourcepack/reason_codes.py +72 -0
- sourcepack/reports/__init__.py +5 -0
- sourcepack/reports/html.py +88 -0
- sourcepack/reports/json.py +123 -0
- sourcepack/reports/markdown.py +61 -0
- sourcepack/schemas.py +63 -0
- sourcepack-1.10.0a0.dist-info/METADATA +311 -0
- sourcepack-1.10.0a0.dist-info/RECORD +33 -0
- sourcepack-1.10.0a0.dist-info/WHEEL +5 -0
- sourcepack-1.10.0a0.dist-info/entry_points.txt +2 -0
- sourcepack-1.10.0a0.dist-info/licenses/LICENSE +21 -0
- sourcepack-1.10.0a0.dist-info/top_level.txt +1 -0
sourcepack/__init__.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
__version__ = "1.10.0a0"
|
|
7
|
+
|
|
8
|
+
# Keep subprocess-based development/test invocations runnable from temporary
|
|
9
|
+
# repositories before the package is installed. Installed packages do not need
|
|
10
|
+
# this, but local `python -m sourcepack.cli` smoke tests spawned from another
|
|
11
|
+
# cwd do.
|
|
12
|
+
_src_root = str(Path(__file__).resolve().parents[1])
|
|
13
|
+
_pythonpath = os.environ.get("PYTHONPATH")
|
|
14
|
+
if _pythonpath:
|
|
15
|
+
_parts = _pythonpath.split(os.pathsep)
|
|
16
|
+
if _src_root not in _parts:
|
|
17
|
+
os.environ["PYTHONPATH"] = os.pathsep.join([_src_root, *_parts])
|
|
18
|
+
else:
|
|
19
|
+
os.environ["PYTHONPATH"] = _src_root
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Packaged SourcePack markdown assets."""
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# SourcePack Audit Template
|
|
2
|
+
|
|
3
|
+
Review the AI answer against the packet manifest and packet contents. Identify supported references, missing references, unsupported dependency claims, unsupported command claims, and unsupported capability claims. Do not claim semantic truth verification unless deterministic packet evidence supports it.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# SourcePack Packet Instructions
|
|
2
|
+
|
|
3
|
+
Use only the supplied SourcePack packet as source material. Cite file paths when making claims. Do not infer files, commands, dependencies, services, or capabilities that are not present in the packet. If evidence is missing, say NOT FOUND or UNCERTAIN.
|
sourcepack/baseline.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
from datetime import datetime, timezone
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from .paths import ensure_sourcepack_dirs, sourcepack_paths
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from . import __version__
|
|
15
|
+
except Exception:
|
|
16
|
+
__version__ = "1.10.0-alpha"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def protected_baseline_path(path: str) -> bool:
|
|
21
|
+
p = path.replace("\\", "/").lstrip("./")
|
|
22
|
+
return p.startswith(".sourcepack/baseline/")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def utc_now() -> str:
|
|
26
|
+
return datetime.now(timezone.utc).isoformat()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def sha256_file(path: Path) -> str:
|
|
30
|
+
h = hashlib.sha256()
|
|
31
|
+
with path.open("rb") as f:
|
|
32
|
+
for block in iter(lambda: f.read(1024 * 1024), b""):
|
|
33
|
+
h.update(block)
|
|
34
|
+
return h.hexdigest()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def sha256_text(text: str) -> str:
|
|
38
|
+
return hashlib.sha256(text.encode("utf-8")).hexdigest()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class BaselineLockError(RuntimeError):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _rel_to_repo(repo: Path, path: Path | None) -> str | None:
|
|
46
|
+
if path is None:
|
|
47
|
+
return None
|
|
48
|
+
try:
|
|
49
|
+
return str(path.resolve().relative_to(repo.resolve())).replace("\\", "/")
|
|
50
|
+
except Exception:
|
|
51
|
+
return str(path)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _read_json_file(path: Path) -> tuple[dict | None, str | None]:
|
|
55
|
+
try:
|
|
56
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
57
|
+
except json.JSONDecodeError as exc:
|
|
58
|
+
return None, f"malformed JSON: {exc}"
|
|
59
|
+
except OSError as exc:
|
|
60
|
+
return None, f"unreadable: {exc}"
|
|
61
|
+
if not isinstance(data, dict):
|
|
62
|
+
return None, "JSON root is not an object"
|
|
63
|
+
return data, None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def baseline_corrupt_result(repo: Path, message: str, details: dict | None = None, packet_path: Path | None = None, metadata_path: Path | None = None, active_pointer_path: Path | None = None, mode: str = "none", active_build_id: str | None = None) -> dict:
|
|
67
|
+
return {"ok": False, "state": "corrupt", "finding_id": "baseline_corrupt", "message": "Trusted SourcePack baseline is corrupt or unverifiable. Recreate the baseline only after verifying the current repo state should be trusted.", "details": {"reason": message, **(details or {})}, "packet_path": _rel_to_repo(repo, packet_path), "metadata_path": _rel_to_repo(repo, metadata_path), "active_pointer_path": _rel_to_repo(repo, active_pointer_path), "mode": mode, "active_build_id": active_build_id}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def resolve_active_baseline(repo: str | Path) -> dict:
|
|
71
|
+
repo = Path(repo).resolve(); paths = sourcepack_paths(repo); pointer = paths["active_pointer"]
|
|
72
|
+
if pointer.exists():
|
|
73
|
+
data, err = _read_json_file(pointer)
|
|
74
|
+
if err:
|
|
75
|
+
return baseline_corrupt_result(repo, f"active.json {err}", active_pointer_path=pointer, mode="pointer")
|
|
76
|
+
build_id = data.get("active_build_id")
|
|
77
|
+
if not isinstance(build_id, str) or not build_id or "/" in build_id or "\\" in build_id or build_id in {".", ".."}:
|
|
78
|
+
return baseline_corrupt_result(repo, "active.json has invalid active_build_id", active_pointer_path=pointer, mode="pointer")
|
|
79
|
+
build_dir = (paths["builds"] / build_id).resolve(); builds_dir = paths["builds"].resolve()
|
|
80
|
+
try:
|
|
81
|
+
build_dir.relative_to(builds_dir)
|
|
82
|
+
except ValueError:
|
|
83
|
+
return baseline_corrupt_result(repo, "active.json points outside baseline builds", active_pointer_path=pointer, mode="pointer", active_build_id=build_id)
|
|
84
|
+
packet = build_dir / "packet"; meta = build_dir / "metadata.json"
|
|
85
|
+
if not build_dir.exists() or not packet.exists():
|
|
86
|
+
return baseline_corrupt_result(repo, "active.json points to a missing build", packet_path=packet, metadata_path=meta, active_pointer_path=pointer, mode="pointer", active_build_id=build_id)
|
|
87
|
+
return {"ok": True, "state": "resolved", "mode": "pointer", "packet_path": _rel_to_repo(repo, packet), "metadata_path": _rel_to_repo(repo, meta), "active_pointer_path": _rel_to_repo(repo, pointer), "active_build_id": build_id, "details": {}}
|
|
88
|
+
legacy = paths["packet"]
|
|
89
|
+
if legacy.exists():
|
|
90
|
+
legacy_artifacts = {"manifest.json", "receipt.json", "reality_map.json", "context.md", "ai_instructions.md"}
|
|
91
|
+
present = {child.name for child in legacy.iterdir()} if legacy.is_dir() else set()
|
|
92
|
+
if (legacy / "manifest.json").exists():
|
|
93
|
+
return {"ok": True, "state": "resolved", "mode": "legacy", "packet_path": _rel_to_repo(repo, legacy), "metadata_path": _rel_to_repo(repo, paths["baseline_meta"]), "active_pointer_path": None, "active_build_id": None, "details": {}}
|
|
94
|
+
if present & legacy_artifacts:
|
|
95
|
+
return baseline_corrupt_result(repo, "legacy baseline packet has baseline artifacts but is missing manifest.json", packet_path=legacy, mode="legacy")
|
|
96
|
+
return {"ok": False, "state": "missing", "finding_id": "baseline_missing", "message": "No trusted SourcePack baseline exists while changes are present.", "details": {}, "packet_path": None, "metadata_path": None, "active_pointer_path": None, "mode": "none", "active_build_id": None}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _validate_packet_artifacts(repo: Path, packet: Path) -> dict | None:
|
|
100
|
+
required = ["manifest.json", "receipt.json", "reality_map.json"]
|
|
101
|
+
for name in required:
|
|
102
|
+
if not (packet / name).exists():
|
|
103
|
+
return baseline_corrupt_result(repo, f"active packet missing {name}", packet_path=packet)
|
|
104
|
+
for name in ["manifest.json", "receipt.json", "reality_map.json", "token_report.json", "redactions.json"]:
|
|
105
|
+
path = packet / name
|
|
106
|
+
if path.exists():
|
|
107
|
+
_, err = _read_json_file(path)
|
|
108
|
+
if err:
|
|
109
|
+
return baseline_corrupt_result(repo, f"{name} {err}", packet_path=packet)
|
|
110
|
+
receipt, err = _read_json_file(packet / "receipt.json")
|
|
111
|
+
if err:
|
|
112
|
+
return baseline_corrupt_result(repo, f"receipt.json {err}", packet_path=packet)
|
|
113
|
+
hashes = receipt.get("hashes")
|
|
114
|
+
if not isinstance(hashes, dict) or not hashes:
|
|
115
|
+
return baseline_corrupt_result(repo, "receipt.json has no hashes", packet_path=packet)
|
|
116
|
+
for name, expected in hashes.items():
|
|
117
|
+
if not isinstance(name, str) or not isinstance(expected, str):
|
|
118
|
+
return baseline_corrupt_result(repo, "receipt.json contains invalid hash entry", packet_path=packet)
|
|
119
|
+
if Path(name).is_absolute() or ".." in Path(name).parts:
|
|
120
|
+
return baseline_corrupt_result(repo, "receipt.json tracks unsafe artifact path", packet_path=packet)
|
|
121
|
+
packet_root = packet.resolve(); path = (packet / name).resolve()
|
|
122
|
+
try:
|
|
123
|
+
path.relative_to(packet_root)
|
|
124
|
+
except ValueError:
|
|
125
|
+
return baseline_corrupt_result(repo, "receipt.json tracks path outside packet", packet_path=packet)
|
|
126
|
+
if not path.exists():
|
|
127
|
+
return baseline_corrupt_result(repo, f"receipt-tracked artifact missing: {name}", packet_path=packet)
|
|
128
|
+
try:
|
|
129
|
+
actual = sha256_file(path)
|
|
130
|
+
except OSError as exc:
|
|
131
|
+
return baseline_corrupt_result(repo, f"receipt-tracked artifact unreadable: {name}: {exc}", packet_path=packet)
|
|
132
|
+
if actual != expected:
|
|
133
|
+
return baseline_corrupt_result(repo, f"receipt hash mismatch: {name}", packet_path=packet)
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def validate_baseline(repo: str | Path) -> dict:
|
|
138
|
+
repo = Path(repo).resolve(); resolved = resolve_active_baseline(repo)
|
|
139
|
+
if resolved.get("state") in {"corrupt", "missing"}:
|
|
140
|
+
return resolved
|
|
141
|
+
packet = repo / resolved["packet_path"] if resolved.get("packet_path") else None
|
|
142
|
+
meta = repo / resolved["metadata_path"] if resolved.get("metadata_path") else None
|
|
143
|
+
corrupt = _validate_packet_artifacts(repo, packet)
|
|
144
|
+
if corrupt:
|
|
145
|
+
corrupt.update({"mode": resolved.get("mode", "none"), "metadata_path": resolved.get("metadata_path"), "active_pointer_path": resolved.get("active_pointer_path"), "active_build_id": resolved.get("active_build_id")})
|
|
146
|
+
return corrupt
|
|
147
|
+
if meta and meta.exists():
|
|
148
|
+
_, err = _read_json_file(meta)
|
|
149
|
+
if err:
|
|
150
|
+
return baseline_corrupt_result(repo, f"metadata.json {err}", packet_path=packet, metadata_path=meta, active_pointer_path=repo / resolved["active_pointer_path"] if resolved.get("active_pointer_path") else None, mode=resolved.get("mode", "none"), active_build_id=resolved.get("active_build_id"))
|
|
151
|
+
paths = sourcepack_paths(repo); stale = paths["stale_marker"].exists(); stale_details = None
|
|
152
|
+
if stale:
|
|
153
|
+
stale_details, err = _read_json_file(paths["stale_marker"])
|
|
154
|
+
if err:
|
|
155
|
+
stale_details = {"reason": "unreadable"}
|
|
156
|
+
return {"ok": True, "state": "stale" if stale else "present", "finding_id": "baseline_stale" if stale else None, "message": "Trusted SourcePack baseline may not match current repo state." if stale else "Trusted SourcePack baseline is present.", "details": {"stale_details": stale_details} if stale else {}, "packet_path": resolved.get("packet_path"), "metadata_path": resolved.get("metadata_path"), "active_pointer_path": resolved.get("active_pointer_path"), "mode": resolved.get("mode"), "active_build_id": resolved.get("active_build_id")}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def acquire_baseline_lock(repo: str | Path, command: str | None = None) -> tuple[Path, int]:
|
|
160
|
+
paths = ensure_sourcepack_dirs(repo); lock = paths["baseline_lock"]
|
|
161
|
+
try:
|
|
162
|
+
fd = os.open(lock, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
|
|
163
|
+
except FileExistsError as exc:
|
|
164
|
+
raise BaselineLockError("Another SourcePack baseline operation is already in progress.") from exc
|
|
165
|
+
os.write(fd, json.dumps({"pid": os.getpid(), "command": command, "started_at": utc_now()}).encode("utf-8")); os.fsync(fd)
|
|
166
|
+
return lock, fd
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def release_baseline_lock(lock: Path, fd: int) -> None:
|
|
170
|
+
try:
|
|
171
|
+
os.close(fd)
|
|
172
|
+
finally:
|
|
173
|
+
try:
|
|
174
|
+
lock.unlink()
|
|
175
|
+
except FileNotFoundError:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _write_json_atomic(path: Path, payload: dict) -> None:
|
|
180
|
+
tmp = path.with_name(path.name + ".tmp")
|
|
181
|
+
with tmp.open("w", encoding="utf-8") as f:
|
|
182
|
+
json.dump(payload, f, indent=2); f.write("\n"); f.flush(); os.fsync(f.fileno())
|
|
183
|
+
os.replace(tmp, path)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _unique_build_id() -> str:
|
|
187
|
+
return datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ") + f"-{os.getpid()}"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _write_baseline_packet(repo: Path, packet: Path) -> None:
|
|
191
|
+
from .packet import PacketWriter, SourceScanner
|
|
192
|
+
|
|
193
|
+
PacketWriter(packet, SourceScanner(repo).scan(), force=True).write_all()
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _verify_baseline_packet(packet: Path) -> bool:
|
|
197
|
+
from .packet import verify_packet
|
|
198
|
+
|
|
199
|
+
return verify_packet(packet)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _run_git(repo: Path, args: list[str]) -> subprocess.CompletedProcess:
|
|
203
|
+
return subprocess.run(["git", *args], cwd=repo, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _git_worktree_dirty(repo: str | Path) -> tuple[bool, str | None]:
|
|
207
|
+
root = Path(repo)
|
|
208
|
+
cp = _run_git(root, ["status", "--porcelain=v1", "--untracked-files=all"])
|
|
209
|
+
if cp.returncode != 0:
|
|
210
|
+
return False, "git_status_failed"
|
|
211
|
+
lines = [line for line in cp.stdout.splitlines() if line.strip()]
|
|
212
|
+
protected = [line for line in lines if protected_baseline_path(line[3:] if len(line) > 3 else line)]
|
|
213
|
+
non_baseline = [line for line in lines if line not in protected]
|
|
214
|
+
if non_baseline:
|
|
215
|
+
return True, None
|
|
216
|
+
if protected:
|
|
217
|
+
return False, "baseline_only_dirty"
|
|
218
|
+
return False, None
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def scanner_config_hash() -> str:
|
|
222
|
+
from .packet import scanner_config_hash as packet_scanner_config_hash
|
|
223
|
+
|
|
224
|
+
return packet_scanner_config_hash()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def git_metadata(repo: str | Path) -> dict:
|
|
228
|
+
root = Path(repo)
|
|
229
|
+
head = _run_git(root, ["rev-parse", "HEAD"])
|
|
230
|
+
branch = _run_git(root, ["rev-parse", "--abbrev-ref", "HEAD"])
|
|
231
|
+
dirty, dirty_state = _git_worktree_dirty(root)
|
|
232
|
+
return {
|
|
233
|
+
"branch": branch.stdout.strip() if branch.returncode == 0 else None,
|
|
234
|
+
"head_commit": head.stdout.strip() if head.returncode == 0 else None,
|
|
235
|
+
"dirty": dirty if dirty_state is None else None,
|
|
236
|
+
"dirty_state": dirty_state,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def build_current_baseline(repo: str | Path, quiet: bool = False, fail_stage: str | None = None) -> tuple[dict, bool]:
|
|
241
|
+
repo = Path(repo).resolve(); paths = ensure_sourcepack_dirs(repo)
|
|
242
|
+
previous = validate_baseline(repo); created = previous.get("state") == "missing"
|
|
243
|
+
lock = fd = None; build_dir = None
|
|
244
|
+
try:
|
|
245
|
+
lock, fd = acquire_baseline_lock(repo, "baseline")
|
|
246
|
+
build_id = _unique_build_id(); build_dir = paths["builds"] / build_id; packet = build_dir / "packet"
|
|
247
|
+
build_dir.mkdir(parents=True, exist_ok=False)
|
|
248
|
+
_write_baseline_packet(repo, packet)
|
|
249
|
+
if not quiet and not _verify_baseline_packet(packet):
|
|
250
|
+
raise RuntimeError("packet verification returned FAIL")
|
|
251
|
+
candidate = _validate_packet_artifacts(repo, packet)
|
|
252
|
+
if candidate:
|
|
253
|
+
raise RuntimeError(candidate["details"].get("reason", "candidate baseline invalid"))
|
|
254
|
+
meta = {"created_at": utc_now(), "packet_path": _rel_to_repo(repo, packet), "scanner_config_hash": scanner_config_hash(), **git_metadata(repo)}
|
|
255
|
+
(build_dir / "metadata.json").write_text(json.dumps(meta, indent=2), encoding="utf-8")
|
|
256
|
+
_, meta_err = _read_json_file(build_dir / "metadata.json")
|
|
257
|
+
if meta_err:
|
|
258
|
+
raise RuntimeError(f"metadata.json {meta_err}")
|
|
259
|
+
if fail_stage == "before_pointer_replace":
|
|
260
|
+
raise RuntimeError("injected failure before pointer replacement")
|
|
261
|
+
pointer = {"schema_version": "baseline_pointer.v1", "active_build_id": build_id, "activated_at": utc_now(), "packet_path": _rel_to_repo(repo, packet), "metadata_path": _rel_to_repo(repo, build_dir / "metadata.json")}
|
|
262
|
+
_write_json_atomic(paths["active_pointer"], pointer)
|
|
263
|
+
if fail_stage == "after_pointer_replace":
|
|
264
|
+
raise RuntimeError("injected failure after pointer replacement")
|
|
265
|
+
if paths["stale_marker"].exists():
|
|
266
|
+
paths["stale_marker"].unlink()
|
|
267
|
+
return paths, created
|
|
268
|
+
except Exception:
|
|
269
|
+
if build_dir is not None:
|
|
270
|
+
active = None
|
|
271
|
+
try:
|
|
272
|
+
if paths["active_pointer"].exists():
|
|
273
|
+
active = json.loads(paths["active_pointer"].read_text(encoding="utf-8")).get("active_build_id")
|
|
274
|
+
except Exception:
|
|
275
|
+
active = None
|
|
276
|
+
if active != build_dir.name:
|
|
277
|
+
shutil.rmtree(build_dir, ignore_errors=True)
|
|
278
|
+
raise
|
|
279
|
+
finally:
|
|
280
|
+
if lock is not None and fd is not None:
|
|
281
|
+
release_baseline_lock(lock, fd)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def baseline_report_fields(status: dict) -> dict:
|
|
285
|
+
return {"baseline_state": status.get("state"), "baseline_integrity_ok": bool(status.get("ok")) and status.get("state") in {"present", "stale"}, "baseline_integrity_finding_id": status.get("finding_id"), "baseline_integrity_message": status.get("message"), "baseline_stale": status.get("state") == "stale", "baseline_stale_details": (status.get("details") or {}).get("stale_details"), "baseline_mode": status.get("mode"), "baseline_packet_path": status.get("packet_path"), "baseline_metadata_path": status.get("metadata_path"), "baseline_active_pointer_path": status.get("active_pointer_path")}
|