Use content_hash as asset names for all run assets

- RecordRunRequest.output_name now optional (deprecated)
- Input assets named by their content_hash
- Output assets named by their content_hash
- Simplified registered_inputs - just content_hash and ipfs_cid
- All assets now referenced by content_hash, not friendly names

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-09 12:06:43 +00:00
parent c53f67fb19
commit 00820b09cf

View File

@@ -166,8 +166,8 @@ class RegisterRequest(BaseModel):
class RecordRunRequest(BaseModel):
"""Request to record an L1 run."""
run_id: str
output_name: str
l1_server: str # URL of the L1 server that has this run
output_name: Optional[str] = None # Deprecated - assets now named by content_hash
class PublishCacheRequest(BaseModel):
@@ -1995,22 +1995,13 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
"effects_commit": run.get("effects_commit"),
}
# Build registered_inputs list (deterministic - can compute before DB transaction)
# Build registered_inputs list - all referenced by content_hash
registered_inputs = []
for inp in input_infos:
if inp["existing_asset"]:
registered_inputs.append({
"content_hash": inp["content_hash"],
"name": inp["existing_asset"]["name"],
"ipfs_cid": inp["ipfs_cid"]
})
else:
# New input - name is deterministic
registered_inputs.append({
"content_hash": inp["content_hash"],
"name": f"input-{inp['content_hash'][:16]}",
"ipfs_cid": inp["ipfs_cid"]
})
registered_inputs.append({
"content_hash": inp["content_hash"],
"ipfs_cid": inp["ipfs_cid"]
})
# ===== PHASE 2: IPFS OPERATIONS (non-blocking for event loop) =====
def do_ipfs_operations():
@@ -2074,19 +2065,15 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
try:
async with db.transaction() as conn:
# Register input assets (if not already on L2)
# Register input assets (if not already on L2) - named by content_hash
for inp in input_infos:
if not inp["existing_asset"]:
# Create new input asset with appropriate name based on type
media_type = inp["media_type"]
tags = ["auto-registered", "input"]
if media_type == "recipe":
input_name = f"recipe-{inp['content_hash'][:16]}"
tags = ["auto-registered", "input", "recipe"]
else:
input_name = f"input-{inp['content_hash'][:16]}"
tags = ["auto-registered", "input"]
tags.append("recipe")
input_asset = {
"name": input_name,
"name": inp["content_hash"], # Use content_hash as name
"content_hash": inp["content_hash"],
"ipfs_cid": inp["ipfs_cid"],
"asset_type": media_type,
@@ -2097,13 +2084,13 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
}
await db.create_asset_tx(conn, input_asset)
# Check output name doesn't exist
if await db.asset_exists_by_name_tx(conn, req.output_name):
raise HTTPException(400, f"Asset already exists: {req.output_name}")
# Check output doesn't already exist (by content_hash)
if await db.asset_exists_by_name_tx(conn, output_hash):
raise HTTPException(400, f"Asset already exists: {output_hash[:16]}...")
# Create output asset with provenance (includes provenance_cid)
# Create output asset with provenance - named by content_hash
output_asset = {
"name": req.output_name,
"name": output_hash, # Use content_hash as name
"content_hash": output_hash,
"ipfs_cid": output_ipfs_cid,
"asset_type": output_media_type,
@@ -2115,10 +2102,10 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
}
created_asset = await db.create_asset_tx(conn, output_asset)
# Create activity
# Create activity - all referenced by content_hash
object_data = {
"type": output_media_type.capitalize(),
"name": req.output_name,
"name": output_hash, # Use content_hash as name
"id": f"https://{DOMAIN}/objects/{output_hash}",
"contentHash": {
"algorithm": "sha3-256",
@@ -2146,7 +2133,7 @@ async def record_run(req: RecordRunRequest, user: User = Depends(get_required_us
logger.error(f"record_run: Database transaction failed: {e}")
raise HTTPException(500, f"Failed to record run: {e}")
logger.info(f"record_run: Successfully published {req.output_name} with {len(registered_inputs)} inputs")
logger.info(f"record_run: Successfully published {output_hash[:16]}... with {len(registered_inputs)} inputs")
return {"asset": created_asset, "activity": created_activity}