Dataset Ingestion
Dataset ingestion turns submitted cases into verified immutable files and a finalized catalog reference. The CLI owns preparation and upload work; PostgreSQL stores compact ownership, file references, and progress. Blob storage holds case bytes, source fields, indexes, and the dataset manifest.
Upload and Resume
vigilo dataset upload --input-file dataset.jsonl --input-format jsonl \
--storage-config storage.toml --batch-cases 100 --batch-bytes 8388608
vigilo dataset status <upload-id>
vigilo dataset resume <upload-id> --input-file dataset.jsonl --input-format jsonl \
--storage-config storage.toml
Supply --upload-id <uuid> to choose an upload identity before starting. Otherwise
the command creates one and includes it in failures after upload registration.
If the process exits before registration, repeat
upload with the same chosen ID; there is no registered upload to resume yet.
Success returns data.id and data.manifest, the compact catalog identity and
verified manifest reference. Status exposes case_cursor, the number of
contiguous acknowledged cases, batch_count, the acknowledged batch count, and
the total under identity.case_count. Lease and expiry timestamps show when work
can be reclaimed; cleanup_after shows the quarantine deadline and cleaned_at
records completed cleanup. File bytes never enter these progress rows.
Case-file progress commits in bounded groups, so status advances at checkpoints. Each group contains at most 64 files, 64 MiB of encoded payload, and 256 KiB of queued metadata. Every exact file reference is registered together before any group upload. Files upload and verify individually, outside database transactions; one transaction acknowledges only a verified contiguous prefix. A failed group retains its exact ownership records for replay and cleanup.
An operator or job scheduler runs resume with the original input after a failed
invocation or process restart. Coordinators do not discover or retain local
input paths. A live lease rejects competing resumptions; a terminated process's
lease becomes reclaimable after five minutes. Ctrl-C cancels preparation and
storage work and yields the lease when the process can still reach PostgreSQL.
Resume checks the logical dataset identity, batching policy and recorded storage binding. Changed cases, source fields, ordering, or physical owner are rejected. Whitespace and object-key ordering do not change logical identity. Acknowledged batches avoid another upload; an uncertain completed object is verified at its same immutable key before acknowledgement. Finalization reads and validates all stored membership again, including acknowledged batches. Missing or corrupt files cannot produce a catalog reference.
An upload without an explicit ID reuses a finalized catalog entry when its source hash, owner binding and admitted limits match. A finalized ID returns its existing reference. Concurrent independent upload IDs may produce separate immutable copies; publication requires no global dataset lock.
Input Formats
--input-format json and yaml accept the dataset document
with an 8 MiB document limit. YAML also bounds expanded values and nesting so
aliases cannot evade admission. Large inputs use the versioned JSONL format:
{"schema":"vigilo/dataset-upload/v1","fields":{"dataset_id":"018f1111-1111-7111-8111-111111111111","dataset_version":"1.0.0"}}
{"id":"018f1111-1111-7111-8111-111111111101","task_type":"generation","input":{"prompt":"Hello"}}
{"id":"018f1111-1111-7111-8111-111111111102","task_type":"generation","input":{"prompt":"Goodbye"}}
The first line contains original top-level fields except cases. Every following
line is one original case object, in submitted order. Every line ends with LF;
blank lines, duplicate JSON keys, unknown upload schemas, and malformed suffixes
fail validation. An equivalent JSON/YAML document and JSONL upload preserve the
same source hash, case hashes, and dataset-version UUID. Dataset version labels
are bounded to 1,024 UTF-8 bytes.
Input is a regular file, bounded to 8 GiB. The header is bounded by the source-field limit; each case record must fit the admitted batch budget including its stored envelope and header. Preparation spools canonical records and detects duplicate UUIDs with 1 MiB sort runs and merges of at most 32 readers. One preparation/upload holds the process's 8 GiB validation-spool reservation. Remote transfer uses the separate shared object I/O budgets. Batch case and byte caps both apply; they do not change execution chunk size.
Checkpoint preparation retains small headers, references, and offsets into the canonical preparation spool. Upload reconstructs one file at a time from that spool and verifies its digest before remote I/O. It adds no group payload spool and does not retain 64 file payloads in memory. The file count and byte limits also bound the work that may need replay after a failed checkpoint.
Storage Owner Configuration
storage.toml selects a provider and physical namespace separately from case or
evaluator policy:
provider = "s3"
alias = "case-storage"
bucket = "vigilo-cases"
prefix = "vigilo"
region = "us-east-1"
endpoint = "http://127.0.0.1:3900"
allow_http = true
path_style = true
[credential_variables]
access_key = "AWS_ACCESS_KEY_ID"
secret_key = "AWS_SECRET_ACCESS_KEY"
# session_token = "AWS_SESSION_TOKEN"
This S3 API configuration applies to Ceph RGW and S3-compatible services. AWS uses
its regional endpoint when endpoint is omitted. Omitting credential_variables
selects the AWS workload credential chain. HTTP needs an explicit opt-in for
local development. The configuration file is bounded to 64 KiB; namespace prefixes
are bounded to 256 UTF-8 bytes. Credentials and signed URLs are not persisted.
An upload pins the alias's bucket, prefix, region, endpoint and addressing style through a binding hash. Changing these values cannot redirect a resumed upload. Credential-variable names and credential values can rotate without changing the physical binding. The connector returns the provider-neutral storage interface; ingestion does not depend on an SDK or provider-specific file type.
An optional S3 read_endpoint_variable names an environment variable containing
an alternate read URL, such as an internal container address. If unset, reads use
endpoint. It affects only read connections; publication and the immutable
physical binding use the canonical endpoint. The alternate route must serve the
same bucket/prefix and exact immutable objects. It undergoes the same URL
validation, and every object read still verifies its expected digest and size.
This lets host creators and container workers share one owner configuration.
Authority and Publication
One upload lease owns a generation. Object registration and acknowledgement check that generation under a row lock, including a live-time check after acquiring the lock. A case-file group receives a 150-second monotonic admission deadline before registration and lease renewal. Each file retains its normal 120-second operation budget, capped by that admission deadline. After 30 seconds of work, the next completed file triggers a prefix checkpoint and the remaining files require fresh admission. A paused owner cannot mint a fresh transfer window without a live authority check. Single metadata objects retain their own bounded operation and fenced checkpoint. No database transaction spans remote storage work. Database operations have a 30-second outer budget covering pool and lock waits as well as SQL execution.
Read-only finalization renews authority at the first file and when 60 seconds have elapsed, instead of renewing per file. Each read has its own 120-second deadline within the five-minute lease. Every file is still verified, and final publication checks live authority again.
Finalization verifies contiguous ranges, exact case counts, source/membership
identity, unique case IDs, and bounded index coverage. Catalog insertion and the
finalized transition commit atomically under current authority. Run identifiers,
profile policy and execution results are outside dataset publication.
The diagram’s cleanup and cleaned nodes describe maintenance progress. The
persisted upload status remains aborted or expired; cleaned_at records
completion.
Expiry and Cleanup
vigilo dataset abort <upload-id>
vigilo dataset expire
vigilo dataset cleanup <upload-id> --storage-config storage.toml --limit 100
A scheduler invokes expire and repeats cleanup for eligible upload IDs.
expire returns at most 64 upload IDs per invocation for cleanup scheduling. Active ingestion renews its
seven-day inactivity expiry. abort and expiry revoke the current generation;
finalized datasets cannot be aborted or claimed for upload cleanup.
Cleanup waits until the former lease window plus the 120-second object-operation
window has elapsed. This quarantine protects against transfers admitted before
revocation. Each invocation deletes at most --limit data/object records
(1–256), plus a bounded connection-probe reconciliation page. Delete failures
retain their exact ownership records for retry. Missing keys are safe to delete
again. cleanup_complete is true only after every recorded key is reconciled.
SQL tombstones remain separate from blob retention policy.
Connection capability probes are recorded before their first PUT. Each connection reconciles at most 64 older probes. Cleanup targets only recorded keys, never a bucket or prefix listing. Shared finalized content is never upload-cleanup work.
Control Data
dataset_uploads contains identity, admitted limits, progress, lease and expiry.
dataset_upload_objects contains one bounded reference per owned file and its
acknowledgement/cleanup state. dataset_catalog exposes only finalized roots.
These records scale with files rather than individual case payloads. Cases and
case-ID uniqueness data are not inserted into the control database during upload.