Scrambo Docs

Validation and repair

Run deterministic validators and route findings to the right specialist.

report = timeline.validate("all,-edit_quality.sfx", name="quality-check")

Validation checks the current timeline deterministically and returns a ValidationReport. Pass either a validator selection spec or an immutable, serializable ValidationPolicy — never a natural-language prompt.

A selection is a comma-separated list of exact validator names or dotted group prefixes:

timeline.validate("all")
timeline.validate("edit_quality.caption")
timeline.validate("all,-edit_quality.sfx")
timeline.validate("edit_contract.duration_matches")
  • all means every registered validator.
  • none selects no validators.
  • A prefix such as edit_quality.caption selects that whole quality group.
  • A leading - excludes a name or group.
  • With exclusions but no positive token, selection starts from all validators.
  • An unknown token raises an error and lists the valid names.

Validator catalog

Validators split into two families. edit_contract.* checks are hard invariants of a correct edit — the caller's declared canvas, target duration, and plan are realized exactly. edit_quality.* checks are editorial judgments you opt into and tune.

GroupWhat it checks
edit_contract.*Canvas, optional target duration, plan realization, no video gaps, captions/titles/graphics/sound realization, and loaded fonts.
edit_quality.pacing.*Short shots and parent flashes, from both the live edit and the plan.
edit_quality.caption.*Cadence, segmentation, row layout, and balance.
edit_quality.typography.*Minimum text size and overlap.
edit_quality.sfx.*Density and mix levels.
Other qualityedit_quality.coverage.broll, edit_quality.structure.plan.

edit_contract.duration_matches is skipped when the project has no declared target duration. For a meaningful duration gate, give the storyboard or direct author an explicit target duration.

program.safe and program.executable are mandatory specialist-transaction verification — they are never selectable through timeline.validate(). A specialist is promoted only after those checks and its relevant edit_contract.* invariants pass. Specialists never run edit_quality.* automatically: editorial acceptance is caller-owned, which is what the rest of this page is about.

Policies with settings

For quality checks you want to tune, build a ValidationPolicy. It bundles a selection with per-validator settings, validates both at construction time, and is immutable and serializable so you can reuse it across runs.

from scrambo import ValidationPolicy

policy = ValidationPolicy(
    "edit_quality.caption,edit_quality.typography",
    settings={
        "edit_quality.caption.cadence.minimum_duration": {"min_duration": 0.25},
    },
)
report = timeline.validate(policy, name="quality-check")

Settings are keyed by a concrete edit_quality.* validator and use that validator config's field names. Contract and program checks do not accept caller settings — passing settings for them raises.

Inspecting a report

if report.passed:
    print("ready")
else:
    print(report.md)
    for finding in report.findings:
        print(finding)

Call report.require_passed() to fail the program when any selected validator fails.

The repair loop

To attempt repair, hand the failing report to the specialist that owns the problem, then re-check. timeline.ensure() makes this caller-owned loop transparent while keeping routing explicit:

report = timeline.ensure(
    "edit_quality.caption,edit_quality.typography",
    repair_with=timeline.captions_agent,
    repairs=2,
    name="caption-quality",
    require_passed=True,
)

ensure() runs the policy, hands any failure to the one repair_with specialist, and revalidates — up to repairs times. Stages are deterministically named caption-quality-repair-N and caption-quality-recheck-N. It performs no routing inference: choose the one specialist that owns the selected quality policy. With require_passed=False (the default), an exhausted loop returns the final failed report for custom handling.

Use a focused specialist for focused findings — captions_agent for caption layout or timing, sound_agent for mix levels, titles_agent for typography. Use author_agent for cross-cutting or structural findings. If you want the loop spelled out instead of ensure():

selection = "edit_contract,edit_quality.caption,edit_quality.typography"
report = timeline.validate(selection, name="quality-check")

for attempt in range(2):
    if report.passed:
        break
    timeline.author_agent.edit(report, name=f"quality-repair-{attempt + 1}")
    report = timeline.validate(selection, name=f"quality-check-{attempt + 2}")

report.require_passed()

On this page