Lab Notes
Research

Artifacts

Los typed files que una research mission escribe a disco. Cada artifact se valida con un Pydantic schema. La auditability del framework depende de que cada artifact sea typed, versioned y reproducible.

Propósito

Esta página lista los artifacts que el research framework produce, dónde viven, qué schema los valida y para qué se usan. Las phases que los producen están en Mission DAG; el lifecycle está en Mission Lifecycle.

Run directory layout

Cada mission escribe a un único directory:

<runs_dir>/<mission_id>/
├── task.json
├── phase.json
├── candidates.json
├── reviews.json
├── prices.json
├── youtube_search.json
├── transcripts.json
├── synthesis.json           # solo si P3 corrió
├── report.md
└── logs/
    └── mission.log

Cada JSON artifact se valida con un Pydantic schema al escribir. Los artifacts inválidos se rechazan con un clear error message.

task.json

La mission task. Producido por F0.

FieldTypeDescription
mission_idstringStable mission identifier.
raw_querystringLa query original del usuario, verbatim.
parsedParsedQueryLa parsed structure (topic, location, etc.).
created_atdatetime (UTC)Cuándo se creó la task.
configobjectRun configuration opcional (flags, overrides).

ParsedQuery:

FieldTypeDescription
topicstringPrimary research topic.
locationstring | nullTarget location, si hay.
periodstring | nullTarget date range o period.
budget_maxfloat | nullMaximum budget, si hay.
budget_currencystringISO-style currency code (default EUR).
constraintslist[string]Constraints adicionales.

candidates.json

La candidate list. Producida por F1.

FieldTypeDescription
mission_idstringBack-reference a la task.
created_atdatetime (UTC)Cuándo se finalizó la list.
candidateslist[Candidate]Los candidates deduplicados y normalizados.
sourceslist[Source]Todas las sources usadas para descubrir los candidates.

Candidate:

FieldTypeDescription
idstringStable candidate ID (UUID prefix).
namestringDisplay name.
aliaseslist[string]Alternative names encontrados.
categorystringCandidate category (p. ej., hotel, restaurant).
source_idslist[string]Los Source.id values que produjeron este candidate.
metadataobjectFree-form metadata (depende de category).
confidencefloatConfidence score de 0.0 a 1.0.

reviews.json

Reviews agregadas. Producidas por F2.

FieldTypeDescription
mission_idstringBack-reference.
created_atdatetime (UTC)Cuándo se finalizó el summary.
summarieslist[ReviewSummary]Un summary per candidate.
partialboolSi falta alguna review.

ReviewSummary:

FieldTypeDescription
candidate_idstringBack-reference al candidate.
total_reviewsintegerNúmero de reviews agregadas.
average_ratingfloat | nullAverage rating en la scale original.
sentimentobjectDistribución de sentiment (positive, neutral, negative).
topicslist[object]Topic aggregates (topic, count, sentiment).
sourceslist[Source]Sources usadas para el summary.

prices.json

Price series. Producidas por F4.

FieldTypeDescription
mission_idstringBack-reference.
created_atdatetime (UTC)Cuándo se finalizó la series.
currencystringISO-style currency code.
serieslist[PriceSeries]Una series per candidate.
partialboolSi falta algún price.

PriceSeries:

FieldTypeDescription
candidate_idstringBack-reference.
snapshotslist[PriceSnapshot]Observaciones de price time-stamped.
minfloat | nullMinimum observed price.
maxfloat | nullMaximum observed price.
medianfloat | nullMedian price.
trendstringup, down, flat, o unknown.
sourceslist[Source]Sources usadas para la series.

youtube_search.json

YouTube search hits. Producido por Y1.

FieldTypeDescription
mission_idstringBack-reference.
created_atdatetime (UTC)Cuándo corrió la search.
resultslist[object]Un record per video encontrado.
partialboolSi alguna search falló.

Cada result tiene: candidate_id, video_id, title, channel, url, published_at, duration_s, view_count, relevance_score.

transcripts.json

YouTube transcripts. Producido por Y2.

FieldTypeDescription
mission_idstringBack-reference.
created_atdatetime (UTC)Cuándo corrió la extraction.
transcriptslist[Transcript]Un transcript per video.
partialboolSi alguna extraction falló.

Transcript:

FieldTypeDescription
video_idstringYouTube video ID.
urlstringVideo URL.
languagestringTranscript language.
chunkslist[TranscriptChunk]Chunks time-stamped.
full_textstringPlain text concatenado.
sourcestringyoutube_transcript_api o yt_dlp.

synthesis.json (optional)

Narrative summaries. Producido por P3 (Perplexity).

FieldTypeDescription
mission_idstringBack-reference.
created_atdatetime (UTC)Cuándo corrió la synthesis.
summarieslist[object]Un narrative per top candidate.
tokens_usedintegerTotal tokens consumidos por Perplexity.

Cada summary tiene: candidate_id, summary (narrative text), highlights (list of strings), caveats (list of strings).

report.md

El final aggregated report. Producido por F6. No está typed (el markdown es intencionalmente flexible), pero tiene una structure estable documentada en Mission DAG → F6.

phase.json

El mission state. Lo escribe el orchestrator después de cada phase. Documentado en Mission Lifecycle → Checkpointing.

Validation

Todos los artifacts se validan al escribir. El ArtifactStore llama al model_validate del schema (Pydantic v2) y rechaza payloads inválidos. Una validation fallida:

  1. Marca la current phase como failed_terminal.
  2. Escribe el validation error al state.
  3. Detiene la mission.

El Coordinator surface el error al usuario. El usuario puede:

  • Arreglar los datos y reintentar.
  • Saltarse la phase (si allow_partial es true) y continuar.
  • Cancelar la mission.

Reproducibility

Una mission es reproducible si y solo si:

  • Se usa el mismo task.json como input.
  • Todas las adapter responses son deterministas para la misma query al mismo tiempo (true para DuckDuckGo, aproximadamente true para Tavily y Google, false para Perplexity).

El framework no garantiza reproducibility, pero el audit trail hace posible detectar divergence e investigar.

See also

On this page