fix(ingest): mirror semseg-mask + missing DataValidator parity in preflight (cli#352)#374
Merged
Merged
Conversation
…flight (cli#352)
The `data ingest` preflight under-mirrored two in-cluster validators, so
some datasets ACCEPTED locally then REJECTED after the full upload:
- Semantic-segmentation mask resolution: the ingestor runs a SECOND
ImageResolutionValidator ("Mask Resolution Validator", subdir=masks)
the CLI never replicated, so a corrupt or mis-sized mask slipped through.
Now previewed by ValidateMaskResolution over masks/, with the same
target-size + min-size as the images (shared decode core with
ValidateImages).
- DataValidator per-value NUMERIC type check: for tabular / time-series
schemas the ingestor validates every value against its declared type;
the CLI only checked column presence. Now previewed by
CheckColumnValueTypes: a non-numeric or fractional value in an INT
column, or a non-numeric value in a FLOAT column, is caught locally.
Scope is deliberately numeric-only and never-over-rejects (string /
boolean / date length + coercion, integer overflow and non-finite stay
a documented under-preview — mirroring pandas there would risk
rejecting values the cluster accepts).
Parity corpus extended with 4 cases (semseg mask-res mismatch, INT
non-numeric, INT non-integer, and a fully-typed accept guard). Pin left
unchanged: both validators already exist at the pinned data-ingestors ref,
so the drift is a mirror gap, not a stale pin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
👋 Heads-up — Code review queue is at 31 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
This was referenced Jul 21, 2026
Merged
Contributor
Author
|
@BugBot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit b9b0fa3. Configure here.
This was referenced Jul 21, 2026
saadqbal
approved these changes
Jul 21, 2026
Collaborator
|
/fr-pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Closes two
data ingestpreflight parity gaps where a dataset accepts locally then rejects after the full upload (cli#352):Semantic-segmentation mask resolution. data-ingestors composes a second
ImageResolutionValidatorfor semseg — name"Mask Resolution Validator",subdir="masks", sametarget_size/min_sizeas the image one (modalities/validators.py:168-173). The CLI only validatedimages/, so a corrupt or mis-sized mask sailed through preflight and failed in-cluster. Now previewed by a newValidateMaskResolutionovermasks/.DataValidatorper-value type check. For tabular / time-series schemas the ingestor validates every value against its declared SQL type (validators/data_validator.py); the CLI only checked that the schema's columns exist (CheckSchemaColumns). A non-numeric or fractional value in anINTcolumn, or a non-numeric value in aFLOATcolumn, passed preflight and rejected in-cluster after the table was created (orphaning it). Now previewed by a newCheckColumnValueTypes.Why this scope (and what's deliberately left out)
preflight.go's contract is never out-strict the ingestor — an over-reject burns a valid upload.DataValidatoris a ~1000-line, ~15-type validator built on pandasto_numeric/to_datetimecoercion. Reproducing the string-length,BOOLEAN, andDATE/DATETIME/TIMESTAMP/TIMEchecks (plus integer overflow and non-finite) in Go risks rejecting values the cluster accepts — the same reasonperGroupTimeViolationalready leaves the date branch a documented under-preview. So this mirrors only the numeric type mismatch (INT-family non-numeric + non-integer; FLOAT-family non-numeric), which is provably never-over-reject (NA handling matchescoercion.NA_SENTINELS;ParseFloataccepts a superset of pandas' numeric grammar; the time-series grouping time column is excluded exactly as the ingestor's factory excludes it). The remainingDataValidatorsurface is left as a safe under-preview — flagged for a follow-up.Pin
scripts/.data-ingestors-refis left unchanged. Both validators already exist at the pinned ref (8f89aec), so this is a mirror gap, not a stale pin — no goldens regeneration is required to fix it. (The pinned commit is behind develop and its comment is out of date; bumping it is a separate, deliberate change that would pull in unrelated upstream drift and needs a full goldens regen against a data-ingestors checkout.)Test plan
TestValidateMaskResolution,TestCheckColumnValueTypes(17 sub-cases incl. over-reject guards),TestNumericCellBad.semseg-mask-res-mismatch(reject),tabular-int-nonnumeric(reject),tabular-int-noninteger(reject),tabular-typed-ok(accept — over-reject guard).TestValidatorParitygreen across all 71 cases.go build,go vet,gofmt -s -l(clean),go test ./...,make lint(errcheck/ineffassign/misspell/staticcheck),make fmt-check,make schema-check,make deadcode,make vulncheck,scripts/file-budget.sh(preflight.go 1650 ≤ 1700 — the new validators live inimage_resolution.go+value_types.go).goldens-driftruns in CI (needs a data-ingestors checkout); the four added golden verdicts were derived from the validator source at the pin and the existing analog goldens.🤖 Generated with Claude Code
Note
Medium Risk
Changes ingest preflight gates on tabular CSVs and semseg datasets; scope is limited to under-reject-safe numeric checks and mask parity with images, with strong unit and golden parity coverage.
Overview
Closes two accept-locally, reject-after-upload preflight gaps (cli#352) so failures surface before the full ingest.
Semantic segmentation masks: Preflight now validates
masks/with the same rules as images—corrupt/empty files,--min-size, and exacttarget_size—via sharedscanImageResolutionsandValidateMaskResolution, wired into the semseg branch ofPreflightDataset.Tabular schema values: After column presence checks, preflight runs
CheckColumnValueTypesto mirror the ingestor’s numeric DataValidator slice: non-numeric or fractional values inINTcolumns and non-numeric values inFLOAT/DOUBLE/etc. String, date, and boolean per-value rules are intentionally not mirrored to avoid over-rejecting valid uploads.ValidateImagesdelegates decoding to the shared scanner so image and mask resolution previews stay aligned. Four parity cases plus unit tests cover mismatch rejects and an over-reject guard for valid typed data.Reviewed by Cursor Bugbot for commit b9b0fa3. Bugbot is set up for automated code reviews on this repo. Configure here.