Skip to main content
The Flow source executor reads files into a pipeline run with five production-grade behaviors:
  1. Pattern matching — glob, regex, or date-templated globs.
  2. Ordering — latest-by-mtime, FIFO, lexicographic, or process-all.
  3. Wait policy — retry up to N times with configurable interval; act on deadline miss with alert / skip / fail.
  4. Atomic staging — every matched file is renamed into a .processing/ folder before any byte is read; on success it moves to a date-templated .archive/ folder, on failure to .failed/.
  5. Format parsers — CSV, JSON, and JSONL parse via native + papaparse helpers; Parquet, Avro, TSV, and XML parse via hyparquet, avsc, papaparse, and fast-xml-parser respectively. ORC throws an explicit actionable error pointing to the convert-to-parquet upstream workaround (the optional @kaireonai/orc-native add-on package is planned but not yet published).

Connector scope

As of Phase 6.2, the source executor runs against six connector kinds in production: local_fs, s3, gcs, azure_blob, sftp, and http_pull. All six share a single cloud-object-store abstraction — list, get, and archive — so pattern matching, ordering, atomic staging, and wait-policy semantics behave identically across backends. The IR enum still includes ftp for forward compatibility, but plaintext FTP has no runtime executor; users on plaintext FTP should switch to sftp.
Calling the source executor with connector: "ftp" throws an explicit “connector ftp has no runtime executor (deprecated plaintext; use sftp)” error so the boundary is visible to operators.

Cloud source credentials

Cloud connectors load credentials from the Connector.authConfig field, which is encrypted at rest (AES-256-GCM). The runtime decrypts on-demand; plaintext credentials never persist outside the per-run process.

S3 (connector: "s3")

Two auth modes — pick one. Both rely on region (e.g. us-east-1). Access keys: IAM Role assumption (preferred for App Runner / EKS workloads): The runtime calls AWS STS to assume the role and tags the resulting session with the kaireon-flow-runtime- name prefix (distinguishable from connector-test sessions in CloudTrail).

GCS (connector: "gcs")

If neither serviceAccountKey nor accessToken is set, the runtime falls through to Application Default Credentials (requires the GOOGLE_APPLICATION_CREDENTIALS env var on the runner).

Azure Blob (connector: "azure_blob")

Two auth modes — pick one. Connection string: Account + key:

SFTP (connector: "sftp")

The connection opens lazily on first call and is reused across list / get / archive within a single run; the source executor closes it in the run-level finally block. Connect uses readyTimeout: 10000 (10 s) to fail fast on unreachable hosts.

HTTP-pull (connector: "http_pull")

The source URL goes in node.config.path (not authConfig). Auth headers come from: Every URL is gated by the platform’s URL validator before fetch. Loopback (localhost, 127.0.0.1), link-local (169.254.x.x — including the AWS IMDS endpoint), and RFC1918 private ranges are rejected up-front. Both list and get operations validate independently so a maliciously-crafted file descriptor cannot bypass the SSRF check.

Cloud archive semantics

The source executor’s successFolder / failureFolder config is honored across backends with backend-appropriate semantics: Duplicate-key handling on the destination: every backend appends a .dup-${ts} suffix when the target already exists, mirroring the local-filesystem atomic-staging behavior.
For http_pull, the IR atomicity.successFolder/failureFolder config is still required for schema validation parity but its values are ignored at runtime. A debug log emits “http_pull archive: no-op (read-only external source)” so operators can confirm the no-op was reached.

Pattern types

Date-template tokens

Tokens are evaluated against the source’s configured timezone (IANA), defaulting to UTC. After expansion, the value is compiled as a glob (literal text + * and ? wildcards).

Ordering

The source executor processes ALL matched files in the chosen order. Single-file mode is a future option.

Wait policy

The discover loop runs up to maxRetries times, sleeping intervalMinutes between attempts. On exhaustion:

Atomic staging

Every matched file is renamed into stagingFolder BEFORE any byte is read. On clean parse, files move to successFolder (date templates are expanded at archive time, in UTC by default). On parse failure, they move to failureFolder and the upstream error rethrows. stagingFolder, successFolder, and failureFolder may be relative to path or absolute. If a file with the same basename already exists at the destination, a .dup-<unix-ms> suffix is appended.
These folders are jailed the same way the source path is. A folder value containing .. is rejected at runtime, and when FLOW_LOCAL_FS_ROOT is set every resolved folder must stay inside that root — this prevents an editor-authored successFolder: "../../etc" from moving ingested files out of the ingest tree. Absolute paths are allowed (unless FLOW_LOCAL_FS_ROOT confines them), matching the source-path rules.

Crash recovery

If a run crashes mid-parse, files remain in stagingFolder. A follow-up improvement will rescan that folder first on the next run; today the operator should manually move files back if needed.

File integrity (checksums)

Optional checksum validation on the source node, run AFTER file discovery and BEFORE any parse/materialize. Supports a per-file sidecar hash, a manifest/control file, or both:
Hex comparison is case-insensitive. A data file with no expected hash found (missing sidecar / not listed in the manifest, per mode) is treated the same as a mismatch. In manifest/both mode, every file NAMED in the manifest must be PRESENT — a listed-but-missing file also triggers onMismatch handling. Sidecar and manifest files are excluded from the ingested data set (even when a broad data pattern like * matches them) and are archived to successFolder/failureFolder with the run outcome. Per-file results (verified / mismatch / missing_expected / conflict, with expected + actual digests) land in the source node’s result meta.integrity — visible in the run drawer, never silent. Cloud connectors (S3 / GCS / Azure / SFTP / HTTP-pull) hash the object’s bytes after download; the sidecar/manifest lookup uses the same connector and credentials as the source itself (no new external fetch surface).

Formats

XML recordPath

Specify which XML elements become rows via the recordPath config field on the source node:
When recordPath is omitted (or set to *), every direct child of the root element becomes a row.

Error model