Add resumable LLM investigation loop with bounded controller execution
This commit is contained in:
1 parent
c03f70e3e1
commit
c39b5881d1
23 files changed
+2872
-15
No files matched your search
@@ -101,6 +101,7 @@ class CheckpointStore:
|
||||
self.workspace = workspace
|
||||
self.writer = PackageWriter(limits)
|
||||
self.limits = self.writer.validator.limits
|
||||
self._validation_cache = {}
|
||||
|
||||
@contextmanager
|
||||
def _locks(self, case_id: str):
|
||||
@@ -115,6 +116,21 @@ class CheckpointStore:
|
||||
if path.is_symlink():
|
||||
raise LifecycleError("UNSAFE_WORKSPACE", "Managed packages cannot be symlinks")
|
||||
try:
|
||||
# Cache only after complete validation, keyed by a fresh hash
|
||||
# of every archive byte. Never trust mtime/filename as identity.
|
||||
archive_hash = hashlib.sha256()
|
||||
total = 0
|
||||
with path.open("rb") as stream:
|
||||
while chunk := stream.read(CHUNK_SIZE):
|
||||
total += len(chunk)
|
||||
if total > self.limits.max_archive_bytes:
|
||||
raise LifecycleError("STORAGE_PACKAGE_INVALID", "Managed archive exceeds configured limits")
|
||||
archive_hash.update(chunk)
|
||||
cache_key = (case_id, package_id, path, repr(self.limits))
|
||||
cached = self._validation_cache.get(cache_key)
|
||||
if cached and cached[0] == archive_hash.hexdigest():
|
||||
candidates[cached[1]] = path
|
||||
continue
|
||||
with PackageReader(path, self.limits) as reader:
|
||||
manifest = reader.manifest
|
||||
generation = int(manifest["package_generation"])
|
||||
@@ -124,6 +140,15 @@ class CheckpointStore:
|
||||
if not chain or chain[0][1]["package_generation"] != generation:
|
||||
raise LifecycleError("CHECKPOINT_INVALID", "Managed generation has no matching checkpoint")
|
||||
candidates[generation] = path
|
||||
validated_hash = hashlib.sha256()
|
||||
reader._source.seek(0)
|
||||
while chunk := reader._source.read(CHUNK_SIZE):
|
||||
validated_hash.update(chunk)
|
||||
if validated_hash.hexdigest() != archive_hash.hexdigest():
|
||||
raise LifecycleError("STORAGE_PACKAGE_CHANGED", "Managed archive changed during validation")
|
||||
self._validation_cache[cache_key] = (validated_hash.hexdigest(), generation)
|
||||
if len(self._validation_cache) > 4096:
|
||||
self._validation_cache.pop(next(iter(self._validation_cache)))
|
||||
except PackageReadError as error:
|
||||
raise LifecycleError("STORAGE_PACKAGE_INVALID", str(error)) from error
|
||||
except LifecycleError as error:
|
||||
|
||||
Reference in new issue
Block a user