Keep the file name a node gave an artifact

A run_artifact row is keyed by the message the bytes left on, and that was
also the only name it could answer with — so an `@run:` reference resolved
through the row was the same bytes under a name its producer never chose.
The row now records the file name beside the message name; rows written
before the column answer as they always did.

The fallback also checks the bytes are still in the store, which the bare
digest spelling beside it has always done. A missing blob now fails at
submit rather than in the middle of the run that wanted it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-26 22:45:11 +02:00
co-authored by Claude Opus 5
parent 001ec7b282
commit 2e82367926
4 changed files with 81 additions and 8 deletions
@@ -0,0 +1,38 @@
"""run_artifact.filename
The row is keyed by the message the bytes left on, and that was also the only
name it could answer with. A reference rebuilt from it was then the same bytes
under a different name from the one the producing node gave them.
Revision ID: e5b8c2f4a913
Revises: a4d9e2b71c68
Create Date: 2026-08-26
"""
import sqlalchemy as sa
import sqlmodel.sql.sqltypes
from alembic import op
# revision identifiers, used by Alembic.
revision = "e5b8c2f4a913"
down_revision = "a4d9e2b71c68"
branch_labels = None
depends_on = None
def upgrade():
# Nullable: the rows already here never recorded one, and the message name
# is what they keep answering with.
op.add_column(
"run_artifact",
sa.Column(
"filename",
sqlmodel.sql.sqltypes.AutoString(length=255),
nullable=True,
),
)
def downgrade():
op.drop_column("run_artifact", "filename")