loki-mode 7.78.0 → 7.80.0

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.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v7.78.0
6
+ # Loki Mode v7.80.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -406,4 +406,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
406
406
 
407
407
  ---
408
408
 
409
- **v7.78.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
409
+ **v7.80.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.78.0
1
+ 7.80.0
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ A3: object-store checkpoint sync shim for run.sh.
4
+
5
+ This is the thin bridge between run.sh (bash) and the LokiStore object-store
6
+ backends (S3 / GCS / Azure). It is invoked ONLY when LOKI_STORAGE_BACKEND is set
7
+ to a non-local backend; when the backend is local/unset, run.sh never calls this
8
+ and behavior is unchanged.
9
+
10
+ Honest scope
11
+ ------------
12
+ - This syncs the lightweight checkpoint state (.loki/state/checkpoints/**) to the
13
+ configured object store, and hydrates it back on a durable resume when the
14
+ local volume came up empty. It does NOT sync the git refs/loki/cp/* worktree
15
+ snapshots (those live in .git, not .loki, and are out of LokiStore's root);
16
+ the checkpoint metadata + .loki snapshot are what this transfers.
17
+ - All operations are best-effort. A sync/hydrate error never raises to the
18
+ caller's control flow (run.sh treats a nonzero exit as "skip, continue").
19
+ The bash side logs and continues a build on any failure.
20
+
21
+ Run identity
22
+ ------------
23
+ Object-store keys are namespaced per run so concurrent / sequential runs do not
24
+ overwrite each other: runs/<run-id>/state/checkpoints/<...>
25
+ The run-id resolves from (first set wins): LOKI_RUN_ID, LOKI_SESSION_ID, or the
26
+ persisted trust-run-id at .loki/state/trust-run-id. For a durable resume on a
27
+ FRESH volume to find its prior checkpoints, the operator MUST provide a STABLE
28
+ id across pod restarts (set LOKI_RUN_ID or LOKI_SESSION_ID on the Job); the
29
+ minted trust-run-id is per-process and will not match after a restart.
30
+
31
+ Usage
32
+ -----
33
+ checkpoint_sync.py sync # push local .loki/state/checkpoints/** to store
34
+ checkpoint_sync.py hydrate # pull store -> local IF local checkpoints empty
35
+
36
+ Exit codes: 0 on success (including "nothing to do"); nonzero on any error
37
+ (caller ignores it and continues).
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ import os
43
+ import sys
44
+
45
+ # Local-first guard: this shim is only meaningful for a non-local backend. If the
46
+ # backend is local/unset, do nothing (run.sh should not even call us, but be
47
+ # defensive so a stray call is a no-op rather than a needless local copy).
48
+ _BACKEND = (os.environ.get("LOKI_STORAGE_BACKEND") or "local").strip().lower()
49
+
50
+ # The subtree of the .loki/ store that holds checkpoint state.
51
+ _CHECKPOINT_PREFIX = "state/checkpoints/"
52
+
53
+
54
+ def _resolve_run_id() -> str:
55
+ """Resolve the per-run key namespace component (see module docstring)."""
56
+ for env_name in ("LOKI_RUN_ID", "LOKI_SESSION_ID"):
57
+ val = os.environ.get(env_name)
58
+ if val and val.strip():
59
+ return val.strip()
60
+ # Fall back to the persisted trust-run-id on the local volume.
61
+ loki_dir = os.environ.get("LOKI_DIR") or os.path.join(
62
+ os.environ.get("TARGET_DIR", "."), ".loki"
63
+ )
64
+ id_file = os.path.join(loki_dir, "state", "trust-run-id")
65
+ try:
66
+ with open(id_file, "r", encoding="utf-8") as f:
67
+ persisted = f.read().strip()
68
+ if persisted:
69
+ return persisted
70
+ except OSError:
71
+ pass
72
+ return "default"
73
+
74
+
75
+ def _run_key(run_id: str, store_subkey: str) -> str:
76
+ """Build the object-store key for a checkpoint subkey under this run."""
77
+ return f"runs/{run_id}/{store_subkey}"
78
+
79
+
80
+ def _get_store():
81
+ """Import + construct the configured store. Raises on backend/SDK error."""
82
+ # Make the repo root importable so `import lokistore` works regardless of cwd.
83
+ here = os.path.dirname(os.path.abspath(__file__))
84
+ repo_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
85
+ if repo_root not in sys.path:
86
+ sys.path.insert(0, repo_root)
87
+ from lokistore import get_store # noqa: E402
88
+
89
+ return get_store()
90
+
91
+
92
+ def _local_store():
93
+ """A LocalStore rooted at the project .loki/ for reading/writing local keys."""
94
+ here = os.path.dirname(os.path.abspath(__file__))
95
+ repo_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
96
+ if repo_root not in sys.path:
97
+ sys.path.insert(0, repo_root)
98
+ from lokistore import build_store # noqa: E402
99
+
100
+ return build_store({"backend": "local"})
101
+
102
+
103
+ def cmd_sync() -> int:
104
+ """Push local checkpoint state to the object store under this run's prefix."""
105
+ if _BACKEND in ("local", "", "file", "filesystem"):
106
+ return 0 # no-op for local backend
107
+
108
+ run_id = _resolve_run_id()
109
+ local = _local_store()
110
+ remote = _get_store()
111
+
112
+ keys = local.list(_CHECKPOINT_PREFIX)
113
+ if not keys:
114
+ return 0 # nothing to sync yet
115
+
116
+ count = 0
117
+ for subkey in keys:
118
+ data = local.get(subkey)
119
+ remote.put(_run_key(run_id, subkey), data)
120
+ count += 1
121
+ sys.stderr.write(
122
+ f"[checkpoint-sync] pushed {count} checkpoint object(s) to "
123
+ f"{_BACKEND} under runs/{run_id}/\n"
124
+ )
125
+ return 0
126
+
127
+
128
+ def cmd_hydrate() -> int:
129
+ """
130
+ Pull checkpoint state from the object store into the local volume, but ONLY
131
+ when the local checkpoint state is empty (a fresh volume). If the local
132
+ volume already has checkpoints, do nothing (the local copy wins; we never
133
+ clobber a live volume).
134
+ """
135
+ if _BACKEND in ("local", "", "file", "filesystem"):
136
+ return 0 # no-op for local backend
137
+
138
+ local = _local_store()
139
+ # Guard: never overwrite a non-empty local volume.
140
+ if local.list(_CHECKPOINT_PREFIX):
141
+ return 0
142
+
143
+ run_id = _resolve_run_id()
144
+ remote = _get_store()
145
+ remote_prefix = _run_key(run_id, _CHECKPOINT_PREFIX)
146
+ remote_keys = remote.list(remote_prefix)
147
+ if not remote_keys:
148
+ return 0 # store has nothing for this run; fall through to normal flow
149
+
150
+ loki_dir = os.environ.get("LOKI_DIR") or os.path.join(
151
+ os.environ.get("TARGET_DIR", "."), ".loki"
152
+ )
153
+ strip = f"runs/{run_id}/"
154
+ loki_dir_real = os.path.realpath(loki_dir)
155
+ count = 0
156
+ for rk in remote_keys:
157
+ if not rk.startswith(strip):
158
+ continue
159
+ local_subkey = rk[len(strip):] # e.g. state/checkpoints/cp-1/metadata.json
160
+ dest = os.path.join(loki_dir, *local_subkey.split("/"))
161
+ # Path-traversal guard: a malicious/buggy store key with ../ could make
162
+ # dest escape loki_dir. Skip + log anything that does not stay inside.
163
+ if not os.path.realpath(dest).startswith(loki_dir_real + os.sep):
164
+ sys.stderr.write(f"[checkpoint-sync] skipped out-of-tree key: {rk}\n")
165
+ continue
166
+ remote.get_to(rk, dest)
167
+ count += 1
168
+ sys.stderr.write(
169
+ f"[checkpoint-sync] hydrated {count} checkpoint object(s) from "
170
+ f"{_BACKEND} for runs/{run_id}/\n"
171
+ )
172
+ return 0
173
+
174
+
175
+ def main(argv) -> int:
176
+ if len(argv) < 2 or argv[1] not in ("sync", "hydrate"):
177
+ sys.stderr.write("usage: checkpoint_sync.py {sync|hydrate}\n")
178
+ return 2
179
+ try:
180
+ if argv[1] == "sync":
181
+ return cmd_sync()
182
+ return cmd_hydrate()
183
+ except Exception as exc: # best-effort: never break the build
184
+ sys.stderr.write(f"[checkpoint-sync] {argv[1]} skipped: {exc}\n")
185
+ return 1
186
+
187
+
188
+ if __name__ == "__main__":
189
+ raise SystemExit(main(sys.argv))