Workload .wapi/ validation reference
This page documents the struct-tag validation used for workload local state stored in .wapi/ (for example config.json and manifest.json).
Validation is implemented with github.com/go-playground/validator/v10 and centralized in internal/workload/wapi/validate.go.
Custom validator tags
The workload .wapi/ validation uses these custom tags (registered in internal/workload/wapi/validate.go):
dr_id: Non-empty identifier (max 256 chars) with no/,\, or..(safe for filesystem paths).dr_nonempty_ptr: If a*stringis non-nil, the pointed-to string must not be""(rejects JSON""wherenullwas intended).dr_sha256hex: Exactly 64 lowercase hex digits, no0x/0Xprefix (matcheshex.EncodeToStringoutput from the sync engine).
Built-in tags used
The structs also use standard validator/v10 tags:
required: Field must be present and non-zero (e.g. non-empty string, non-zerotime.Time).omitempty: Skip remaining tag checks when the field is empty (nil pointer, empty string, zero number).eq=1: Integer field must equal1(only supported manifest schema version).gte=0: Numeric field must be greater than or equal to zero.len=64: String must be exactly 64 characters long.dive: Validate each value inside a map/slice (used so everyfilesentry runsFileMetarules).
JSON fields (by struct)
Config / InitOptions
artifactId(Config,InitOptions):required,dr_idcatalogId(Configas*string):omitempty,dr_nonempty_ptr,dr_idcatalogId(InitOptionsasstring):omitempty,dr_idlastSyncedVersionId(Configas*string):omitempty,dr_nonempty_ptr,dr_idlastSyncedVersionId(InitOptionsasstring):omitempty,dr_idcreatedAt(Config):requiredcliVersion(Config):required
Manifest / FileMeta
version(Manifest):eq=1syncedVersionId(Manifestas*string):omitempty,dr_nonempty_ptr,dr_idsyncedAt(Manifest): validated by a cross-field rule (see below)files(Manifest): values validated viadive; keys are validated withfileops.SafeRelPathhash(FileMeta):required,dr_sha256hexsize(FileMeta):gte=0
Cross-field rules (not tags)
Some rules are enforced in code in addition to struct tags:
- Catalog required with version (
Config,InitOptions): iflastSyncedVersionIdis set,catalogIdmust also be set. syncedAt↔syncedVersionId(Manifest): if either is set, both must be set; both unset is valid for a fresh init.- Safe file paths (
Manifest.fileskeys): each key must passfileops.SafeRelPath(rejects traversal, absolute paths, and backslashes).
Where validation runs
LoadConfig: callsvalidateConfigand returns a*CorruptedErroron failure.LoadManifest: callsvalidateManifestand returns a*CorruptedErroron failure.Initialize: callsvalidateInitOptionsat the start and returns a plainerroron failure (before.wapi/is created).
Validation is intentionally not run on SaveConfig / SaveManifest (trusted writers).
Note on SemVer
Semantic version validation in this repo is handled separately via github.com/Masterminds/semver/v3 (for example internal/tools/validation.go), not via validator/v10.