foley.obs.run_artifact#
The reproducible run-artifact SSOT — RunManifest + SpanRecord (#11).
Every instrumented foley operation (generate / add_from / ingest /
search / similar — and, later, a #7 find() / #8 weave() scope) emits
one RunManifest: simultaneously the debug trace (the span tree), the
reproducible plan/seed record (inputs, params, seeds, chosen clips), and the
provenance record (credits + disclosure refs) — report 10 §1.3. It is the join
that makes foley debuggable, evaluable, and reproducible; #8’s
SoundDesignTimeline.run_manifest_ref will point at RunManifest.run_id.
Pure data: both dataclasses subclass SerializableMixin, so
to_dict / to_json / from_dict (incl. spans rehydrating element-wise to
SpanRecord, exactly like IngestReport.results) come for free, and adding
fields later (token usage, cost, timings for #7) is schema-safe with no
SCHEMA_VERSION bump. The manifest composes the existing shapes — it embeds
IngestReport.to_dict() and Credits.manifest and references Candidate ids +
LicenseRecord generation fields — it never forks them.
Functions
|
Serialize |
|
A leak-free digest of an |
|
Load and typed-rehydrate a |
Classes
|
The reproducible run-artifact for one foley operation (trace ⊕ plan ⊕ provenance). |
|
One node of the run's span tree (the trace half of the artifact). |
|
One SELECT-stage step of a |
- class foley.obs.run_artifact.RunManifest(run_id, op, created_at=None, foley_version=None, inputs=<factory>, params=<factory>, spans=<factory>, steps=<factory>, ingest_report=None, result_ids=<factory>, candidate_scores=<factory>, credits_ref=None, disclosure_refs=<factory>, seeds=<factory>, plan_ref=None, trace_ref=None, status='ok', error=None, schema_version=1)[source]#
Bases:
SerializableMixinThe reproducible run-artifact for one foley operation (trace ⊕ plan ⊕ provenance).
Persisted by
emit_run_manifest()into a run store keyed byrun_id. Sensitive prompt/query text lives redacted (seefoley.obs.redact); chosen clips are held by reference (SoundRecordid) so the manifest stays light and a trace can be replayed against a fresh index.
- class foley.obs.run_artifact.SpanRecord(name, span_id, parent_id=None, kind=None, start_ms=None, duration_ms=None, status='ok', attributes=<factory>, events=<factory>, error=None)[source]#
Bases:
SerializableMixinOne node of the run’s span tree (the trace half of the artifact).
Built by the recorder from its own clock + id-factory, independent of any tracer, so the tree is complete even when the OTel mirror is a total no-op.
- class foley.obs.run_artifact.Step(kind, seq=None, event_index=None, span_id=None, status='ok', detail=<factory>)[source]#
Bases:
SerializableMixinOne SELECT-stage step of a
find()run (the plan half of the artifact, #7).The typed entry type of
RunManifest.steps: a compact, redacted record of eachdecompose/refine/search/license_gate/verify/decide/generate/placestage, inseqorder, withspan_idjoining the step back to theSpanRecordthat timed it.detailis a small, already-redacted dict (event text lives under thequerykey so the redactor catches it). Rehydrated element-wise byRunManifest.from_dict()exactly likespans(see the module docstring).
- foley.obs.run_artifact.emit_run_manifest(store, manifest, *, redactor=None)[source]#
Serialize
manifest(redacting the payload) and write it tostore.The plain-dict write path keeps an emit-time interposition point for the belt-and-suspenders redaction sweep (do NOT couple the write to auto-serialization). Returns the
run_id.- Parameters:
store (
MutableMapping) – AMutableMapping[str, dict](default:foley.stores.make_run_store(); a dict in tests).manifest (
RunManifest) – TheRunManifestto persist.redactor – An optional
Redactorapplied to the full payload before the write (the emit-time net).
- Return type:
- foley.obs.run_artifact.ingest_digest(report)[source]#
A leak-free digest of an
IngestReportfor a manifest.Records the per-clip outcomes (id, status, QC status, notes) + summary counts — NOT the full
SoundRecords. The records carrycaption(which equals the raw generation prompt for a generated clip) +tagsand already live in the meta store keyed by the id referenced inresult_ids, so embedding them would both leak prompt text into the manifest and duplicate data. Duck-typed over the report (.summary()+.results) to avoid an obs → index import coupling.- Return type:
- foley.obs.run_artifact.load_run(store, run_id)[source]#
Load and typed-rehydrate a
RunManifestfromstore(the read helper).- Return type: