chore: save current work

This commit is contained in:
2026-09-01 16:37:27 +08:00
parent bc87bd6d2d
commit 97a03c290b
24 changed files with 1380 additions and 5073 deletions
@@ -39,6 +39,7 @@ class FileArtifactStore:
request: str,
*,
source_blocks: list[dict[str, Any]] | None = None,
image_inputs: list[dict[str, str]] | None = None,
) -> None:
root = self.task_dir(task_id)
(root / "documents").mkdir(parents=True, exist_ok=True)
@@ -50,6 +51,21 @@ class FileArtifactStore:
if not source.exists():
self._write_once(source, "\n\n".join(block["text"] for block in blocks) + "\n")
self.write_source_index(task_id, request, source_blocks=blocks)
images: list[dict[str, str]] = []
for position, item in enumerate(image_inputs or (), 1):
source_path = Path(str(item.get("path") or "")).resolve()
digest = str(item.get("sha256") or "")
if not source_path.is_file() or not re.fullmatch(r"[a-f0-9]{64}", digest):
raise ValueError("Image input is unavailable or has no valid checksum")
data = source_path.read_bytes()
if sha256(data).hexdigest() != digest:
raise ValueError("Image input checksum mismatch")
suffix = source_path.suffix.lower() if source_path.suffix.lower() in {".png", ".jpg", ".jpeg", ".webp"} else ".bin"
relative = f"inputs/reference-{position:03d}{suffix}"
self._write_bytes_once(self._path(task_id, relative), data)
images.append({"path": relative, "mime": str(item.get("mime") or "image/*"), "sha256": digest})
if images:
self.write_json_once(task_id, "documents/source-images.json", {"schema_version": "cad.source-images.v1", "images": images})
def sync_action_ledger(self, task_id: str, events: list[dict[str, Any]]) -> str:
"""Mirror committed SQLite events into an append-only JSONL audit log.
@@ -171,30 +187,16 @@ class FileArtifactStore:
path = self.task_dir(task_id) / "source-requirements.md"
return path.read_text(encoding="utf-8") if path.is_file() else ""
def read_requirements_draft(self, task_id: str, artifact_path: str = "") -> dict[str, Any]:
if artifact_path:
value = self.read_json(task_id, artifact_path)
if value is None:
raise ValueError("Committed requirements draft artifact is unavailable")
return value
documents = self.task_dir(task_id) / "documents"
candidates = sorted(documents.glob("requirements-draft-v*.json"))
if not candidates:
return {"schema_version": "cad.requirements-draft.v1", "revision": 0, "items": []}
value = json.loads(candidates[-1].read_text(encoding="utf-8"))
return value if isinstance(value, dict) else {"schema_version": "cad.requirements-draft.v1", "revision": 0, "items": []}
def source_image_paths(self, task_id: str) -> list[str]:
manifest = self.read_json(task_id, "documents/source-images.json") or {}
return [
str(self._path(task_id, str(item.get("path") or "")))
for item in manifest.get("images") or ()
if isinstance(item, dict) and item.get("path") and self._path(task_id, str(item["path"])).is_file()
]
def write_requirements_draft(self, task_id: str, payload: dict[str, Any], *, invocation_id: str) -> str:
revision = int(payload.get("revision") or 0)
if revision < 1:
raise ValueError("Requirements draft revision is invalid")
return self._write_invocation_json(task_id, f"requirements-draft-v{revision}", payload, invocation_id)
def read_requirements_review(self, task_id: str, artifact_path: str = "") -> dict[str, Any] | None:
return self.read_json(task_id, artifact_path) if artifact_path else None
def write_requirements_review(self, task_id: str, payload: dict[str, Any], *, invocation_id: str) -> str:
return self._write_invocation_json(task_id, "requirements-review", payload, invocation_id)
def read_requirements_spec(self, task_id: str, artifact_path: str = "") -> dict[str, Any] | None:
return self.read_json(task_id, artifact_path or "documents/requirements-spec.json")
def read_requirements_contract(self, task_id: str, artifact_path: str = "") -> dict[str, Any] | None:
# State points to the immutable artifact used as program input. The
@@ -338,6 +340,17 @@ class FileArtifactStore:
temporary.write_bytes(encoded)
os.replace(temporary, path)
@staticmethod
def _write_bytes_once(path: Path, data: bytes) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
if path.exists():
if path.read_bytes() != data:
raise ValueError(f"Immutable artifact already exists: {path.name}")
return
temporary = path.with_name(path.name + ".tmp-" + secrets.token_hex(4))
temporary.write_bytes(data)
os.replace(temporary, path)
def _write_invocation_json(self, task_id: str, stem: str, payload: dict[str, Any], invocation_id: str) -> str:
digest = sha256(json.dumps(payload, ensure_ascii=True, sort_keys=True, separators=(",", ":")).encode("utf-8")).hexdigest()[:12]
safe_invocation = re.sub(r"[^A-Za-z0-9_-]", "", invocation_id)[:32]