feat: semantic validation and conflict detection (#11) #17

Merged
yorunikakeru merged 14 commits from feat/semantic-validation-conflicts into main 2026-06-09 22:06:05 +02:00
Owner

Add DSL.Validate with validate :: UnvalidatedConfiguration ->
Either [ValidationError] IRDocument as the authoritative pipeline
stage between the DSL builder and the IR.

Three error phases accumulate independently: structural (empty names,
multiple conditions, condition-in-service, empty port lists,
poll/cpu/battery range checks), duplicates (repeated profile or service
names), and conflicts (intra-section enable+disable of the same service;
inter-section opposing intents across unconditional profiles).

ValidationError carries SectionKind and section name for every error.
Lowering from UnvalidatedConfiguration to IRDocument runs only when
no errors are found.

Retire IR.Validated (superseded). Add Arbitrary instances for
UnvalidatedProfile, UnvalidatedService, UnvalidatedConfiguration.
Add containers ^>=0.7 for nubOrd (replaces quadratic nub).

Closes #11

Add DSL.Validate with validate :: UnvalidatedConfiguration -> Either [ValidationError] IRDocument as the authoritative pipeline stage between the DSL builder and the IR. Three error phases accumulate independently: structural (empty names, multiple conditions, condition-in-service, empty port lists, poll/cpu/battery range checks), duplicates (repeated profile or service names), and conflicts (intra-section enable+disable of the same service; inter-section opposing intents across unconditional profiles). ValidationError carries SectionKind and section name for every error. Lowering from UnvalidatedConfiguration to IRDocument runs only when no errors are found. Retire IR.Validated (superseded). Add Arbitrary instances for UnvalidatedProfile, UnvalidatedService, UnvalidatedConfiguration. Add containers ^>=0.7 for nubOrd (replaces quadratic nub). Closes #11
feat: semantic validation and conflict detection (#11)
All checks were successful
CI / linux (pull_request) Successful in 3m1s
0bc71fd751
Add DSL.Validate with validate :: UnvalidatedConfiguration ->
Either [ValidationError] IRDocument as the authoritative pipeline
stage between the DSL builder and the IR.

Three error phases accumulate independently: structural (empty names,
multiple conditions, condition-in-service, empty port lists,
poll/cpu/battery range checks), duplicates (repeated profile or service
names), and conflicts (intra-section enable+disable of the same service;
inter-section opposing intents across unconditional profiles).

ValidationError carries SectionKind and section name for every error.
Lowering from UnvalidatedConfiguration to IRDocument runs only when
no errors are found.

Retire IR.Validated (superseded). Add Arbitrary instances for
UnvalidatedProfile, UnvalidatedService, UnvalidatedConfiguration.
Add containers ^>=0.7 for nubOrd (replaces quadratic nub).
fix: semantic validation correctness and API hardening
All checks were successful
CI / linux (pull_request) Successful in 2m40s
d92ee87807
- ValidatedIR opaque newtype: validate now returns Either [ValidationError]
  ValidatedIR instead of IRDocument; getIRDocument accessor exported. Callers
  can no longer bypass validate by constructing IRDocument directly.

- MultipleConditions gains a 0-based index field so unnamed profiles produce
  distinguishable errors (MultipleConditions "" 0 vs MultipleConditions "" 1).

- InterConflict gains a SectionKind field and now covers service-service pairs;
  empty-named profiles and services excluded from inter-conflict detection to
  avoid duplicating EmptySectionName.

- serviceStructuralErrors calls conditionErrors so domain errors
  (InvalidCpuLoadThreshold, InvalidPollingInterval, etc.) are reported even
  when the condition is structurally invalid in a service section.

- intraConflicts: remove redundant nubOrd on disabled (elem is unaffected
  by duplicates in the searched list).

- DSL module re-exports ValidationError(..), SectionKind(..), ValidatedIR,
  getIRDocument so callers need only a single import.
refactor: generalise LocalError constructors
All checks were successful
CI / linux (pull_request) Successful in 2m33s
354661b2d8
EmptyAllowPorts + EmptyFallbackCandidates → EmptyList Text
InvalidPollingInterval → InvalidInterval
InvalidCpuLoadThreshold → InvalidThreshold
InvalidBatteryPercent → InvalidPercent
mkThreshold/mkPercent/mkName/mkInterval replace inline guard logic in
specific smart constructors, which become one-liner wrappers.
Hide ProcessName constructor; validate empty names at construction
and JSON decode time.
perf(validate): use set for duplicate names
All checks were successful
CI / linux (pull_request) Successful in 2m41s
46f860dce0
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
FrogOS/DSL!17
No description provided.