Contextfulv0.23.0

Docs / Specification

contract run · 30-run.md · 31-pipeline.md · 32-derive.md · guide · card

The derive tier

Derive tasks process committed rows and append results through the ordinary write path. Implementers use this contract for task selection, engine bindings and output rows. Media tasks produce citable passages; link tasks extract document head fields and advertised images.

Derive tasks read parent rows, invoke an engine and write output rows:

Flowchart diagram Flowchart, top to bottom. 8 nodes, 9 edges. store contract: landed parent table → outstanding row set [landed rows] store contract: derive output table → outstanding row set [rows and markers] run contract: outstanding row set → exec driver [transcribe binding]; → fetch driver [link_preview binding] run contract: exec driver → land path [parsed cues]; → resolver [credential references] run contract: fetch driver → land path [link rows]; → host mediation [mediated client] run contract: land path → derive output table [append rows, markers] connector contract: resolver connector contract: host mediation store contract landed parent table derive output table run contract transcribe binding link_preview binding parsed cues link rows outstanding row set exec driver fetch driver land path connector contract resolver host mediation landed rows rows and markers append rows, markers credential references mediated client

select

The derive source selects eligible parent rows each tick and limits each run’s work.

Scenarios

bind

Engine bindings select registered tasks, configure engine interfaces and constrain media access and returned values.

exec

The executor runs operator-declared argument arrays as local processes with pinned binaries, restricted environments and bounded runtime and output.

fetch

The fetch driver follows third-party links with host and address checks, bounded redirects, document head scanning and image probes.

  • schemetestAn address whose scheme is neither http nor https raises DeriveSchemeUnsupported before any socket opens.
    WhyA-connector#outbound-transport-origin
  • address-literaltestA host written as an address literal raises DeriveAddressLiteral.
    WhyA-connector#outbound-transport-origin
  • redirect-chaintestA redirect chain runs to at most 5 hops.
  • binding-keytestA Binding key env, preprocess, engine or max_output_bytes on a fetch binding raises DeriveFetchBindingKey, naming the key.
    Whybecause a silently ignored key leaves an operator believing a fetch carries a credential or runs a process
  • document-prefixtestmax_document_bytes bounds the scanned document prefix at 1 MiB by default, dropping the remainder.
  • probe-prefixtestmax_probe_bytes bounds one picture range request at 64 KiB by default.
  • hop-timeouttestrequest_timeout_secs bounds one hop at 20 s by default.
  • retry-after-defaulttestA 429 without a usable Retry-After maps to RateLimited carrying 60 s.
  • charsettestA declared character set other than UTF-8 raises DeriveCharsetUnsupported, naming the value.
    WhyA-connector#untrusted-input-decodes
  • not-utf8testIf a document declares no character set and fails UTF-8 validation, the fetch driver raises DeriveBytesNotUtf8. The validator tolerates a character split at the byte bound.
    WhyA-connector#untrusted-input-decodes
  • head-rowstestA link preview lands one passage for non-empty head title or description and one passage per distinct advertised head image, each carrying the scrubbed page URL and each image its probe status.
    Whybecause the head and its image claims remain separately citable, including an image whose probe fails

Scenarios

emit

Derive tasks emit content rows and completion markers with status, attempt counts, citation keys and provenance.

Scenarios

parse-cues

The caption parser reads SubRip and WebVTT through one grammar and groups cues into bounded passages.

  • backward-cuetestIf a block starts before the last accepted block, the caption parser raises DeriveCueOutOfOrder and drops the block.
    WhyP4
  • passage-charstestA passage stays open while it holds fewer than 600 chars.
  • passage-spantestA passage stays open while it spans less than 60 s.
  • passage-bytestestOne passage’s text holds at most 8 KiB.
  • passages-per-documenttestOne document yields at most 2000 rows of passages.
  • grammartestSubRip and WebVTT read through one grammar: a block’s timing line, then its text lines joined by a space.

test-engine

The test-engine command builds one derive engine outside a pipeline and runs that engine against one file.

  • unsupported-drivertestA fetch engine named to the verb raises DeriveTestEngineUnsupported.
    Whybecause the verb drives a transcriber over media, and a link engine takes no media

Shapes

Three engine bindings at the top level of contextful.toml:

[derive.local-asr]
driver           = "exec"
timeout_secs     = 1800
max_output_bytes = 8388608
zone             = "local:device"          # advisory; the adapter writes the row value

[[derive.local-asr.preprocess]]
when        = "engine_requires_pcm16_wav"
command     = ["ffmpeg", "-i", "{input}", "-ar", "16000", "-ac", "1", "{output}"]
output_path = "{output_stem}.wav"

[derive.local-asr.engine]
command       = ["speech-cli", "--model", "base", "--srt", "{input}"]
output_format = "srt"
output_path   = "{output_stem}.srt"

[derive.local-asr.env]
SPEECH_MODEL = "base"

[derive.cloud-asr]
driver        = "exec"
endpoint_host = "api.speech.example"       # steps reach it through CONTEXTFUL_EGRESS_URL

[derive.cloud-asr.attach]
Authorization = "Bearer ${secret://speech-vendor}"

[derive.cloud-asr.engine]
command       = ["speech-upload", "--server", "{input}"]
output_format = "srt"

[derive.card-reader]
driver               = "fetch"
allow_hosts          = ["example.com", "*.example.com"]
allow_image_hosts    = ["*.cdn.example.net"]
request_timeout_secs = 20