Skip to content

Commit 47efec9

Browse files
SJrXSteve Ramageclaude
authored
feat: add support for another 35 more validators (Resolves #435)
* feat: import 5 HIGH-confidence AI validators (verified against systemd source) First batch of HIGH-confidence validators from the LLM batch processor, manually verified and corrected against the systemd C source and gperf data: - config_parse_string (CONFIG_PARSE_STRING_SAFE) — string_is_safe semantics - config_parse_bind_user_shell — boolean OR absolute path (parse_user_shell) - config_parse_cake_priority_queueing_preset — adds missing diffserv3 - config_parse_hostname — proper hostname_is_valid grammar - config_parse_device_allow — /dev/path or block-/char- + optional [rwm]+ perms Each AI generation had bugs (wrong section names, hallucinated grammar shape, or grammars not matching the actual C validation function). Tests rewritten to use the real (section, key) pairs from the gperf source. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: import 10 more HIGH-confidence AI validators (verified) Batch 2: 10 validators verified against systemd source via parallel agents and corrected. Each has been checked against gperf (real section/key/ltype) and the C parser function (real validation logic): - config_parse_wol — WakeOnLan flag list (off | space-separated flags) - config_parse_dnssec_mode — boolean | "allow-downgrade" - config_parse_protect_hostname — boolean | <kw>:<hostname> form - config_parse_ip_tos — symbolic name | integer 0-255 - config_parse_ip_protocol — protocol name | integer - config_parse_dns — list of IPv4/IPv6 with optional :port and %iface - config_parse_trigger_unit — unit name with valid type suffix - config_parse_sr_iov_link_state — boolean | "auto" - config_parse_required_family_for_online — ipv4/ipv6/both/any - config_parse_ifname — interface name (max 15 chars, no whitespace/slash) Burndown test now passes — moved from 432 missing to ~417, under the 427 cap for today (2026-04-30). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: import 20 more HIGH-confidence AI validators (verified) Adds validators for fq_bool, fq_size, fq_u32, si_uint64, fdb_vlan_id, dhcp_socket_priority, cake_rtt, coalesce_sec, codel_usec, tbf_latency, service_timeout, service_timeout_abort, job_running_timeout_sec, exec_secure_bits, namespace_flags, can_bitrate, can_time_quanta, fdname, udev_property_name, dns_name. Time-suffix regexes order longer alternatives (year/week/hour/day/min/sec) before shorter (m/h/d/w/y) so that "1min" doesn't get mismatched as "1m" + leftover "in". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: align AI validators with actual systemd C parser semantics Adds shared TIME_VALUE combinator (mirrors extract_multiplier in time-util.c) that accepts "infinity", fractional decimals, all long-form suffixes (seconds/minutes/hours/days/months/years/etc.), whitespace between number and suffix, and compound forms like "1h 30s". Eight time-related validators now use it: cake_rtt, coalesce_sec, codel_usec, tbf_latency, service_timeout, service_timeout_abort, job_running_timeout_sec, can_time_quanta. can_bitrate now accepts the full parse_size suffix set (B/K/M/G/T/P/E) with optional fractional part. dns_name regex relaxed to match dns_label_unescape's permissive behavior — leading/trailing hyphens, underscores and most printable punctuation are now accepted; only empty labels are rejected. ifname tightened to reject ':', '%', the reserved names "all"/"default"/"."/"..", and purely-numeric strings (interpreted as ifindex by the kernel). Tests updated to match the corrected semantics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: tighten dns_name and ifname validators to match C parser more closely dns_name regex now rejects ASCII control characters (U+0000-U+001F, U+007F) that dns_label_unescape rejects via the (uint8_t)*n >= ' ' check. ifname regex now rejects 0x-prefixed hex strings, which safe_atoi32 (called by parse_ifindex via base 0 strtol) treats as ifindex. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Steve Ramage <gitcommits@sjrx.net> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 497893e commit 47efec9

72 files changed

Lines changed: 3142 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ fun getAllAIGeneratedValidators(): Map<Validator, OptionValueInformation> {
9999
Validator("config_parse_iaid", "AF_INET") to ConfigParseIaidOptionValue() as OptionValueInformation,
100100
Validator("config_parse_in_addr_non_null", "AF_INET") to ConfigParseInAddrNonNullOptionValue() as OptionValueInformation,
101101
Validator("config_parse_ip_masquerade", "0") to ConfigParseIpMasqueradeOptionValue() as OptionValueInformation,
102+
Validator("config_parse_ip_protocol", "true") to ConfigParseIpProtocolOptionValue() as OptionValueInformation,
102103
Validator("config_parse_ip_reverse_path_filter", "0") to ConfigParseIpReversePathFilterOptionValue() as OptionValueInformation,
103104
Validator("config_parse_ipoib_mode", "0") to ConfigParseIpoibModeOptionValue() as OptionValueInformation,
104105
Validator("config_parse_ipv4_force_igmp_version", "0") to ConfigParseIpv4ForceIgmpVersionOptionValue() as OptionValueInformation,
@@ -163,11 +164,13 @@ fun getAllAIGeneratedValidators(): Map<Validator, OptionValueInformation> {
163164
Validator("config_parse_rx_tx_queues", "0") to ConfigParseRxTxQueuesOptionValue() as OptionValueInformation,
164165
Validator("config_parse_service_restart_mode", "0") to ConfigParseServiceRestartModeOptionValue() as OptionValueInformation,
165166
Validator("config_parse_socket_defer_trigger", "0") to ConfigParseSocketDeferTriggerOptionValue() as OptionValueInformation,
167+
Validator("config_parse_sr_iov_link_state", "0") to ConfigParseSrIovLinkStateOptionValue() as OptionValueInformation,
166168
Validator("config_parse_sr_iov_num_vfs", "0") to ConfigParseSrIovNumVfsOptionValue() as OptionValueInformation,
167169
Validator("config_parse_sr_iov_vlan_proto", "0") to ConfigParseSrIovVlanProtoOptionValue() as OptionValueInformation,
168170
Validator("config_parse_swap_priority", "0") to ConfigParseSwapPriorityOptionValue() as OptionValueInformation,
169171
Validator("config_parse_tcp_window", "0") to ConfigParseTcpWindowOptionValue() as OptionValueInformation,
170172
Validator("config_parse_timezone_mode", "0") to ConfigParseTimezoneModeOptionValue() as OptionValueInformation,
173+
Validator("config_parse_trigger_unit", "0") to ConfigParseTriggerUnitOptionValue() as OptionValueInformation,
171174
Validator("config_parse_tunnel_mode", "0") to ConfigParseTunnelModeOptionValue() as OptionValueInformation,
172175
Validator("config_parse_txqueuelen", "0") to ConfigParseTxqueuelenOptionValue() as OptionValueInformation,
173176
Validator("config_parse_unit_condition_string", "CONDITION_AC_POWER") to ConfigParseUnitConditionStringOptionValue() as OptionValueInformation,
@@ -186,6 +189,38 @@ fun getAllAIGeneratedValidators(): Map<Validator, OptionValueInformation> {
186189
Validator("config_parse_wlan_iftype", "0") to ConfigParseWlanIftypeOptionValue() as OptionValueInformation,
187190
Validator("config_parse_ad_actor_system", "0") to ConfigParseAdActorSystemOptionValue() as OptionValueInformation,
188191
Validator("config_parse_address_section", "ADDRESS_SCOPE") to ConfigParseAddressSectionAddressScopeOptionValue() as OptionValueInformation,
192+
Validator("config_parse_string", "CONFIG_PARSE_STRING_SAFE") to ConfigParseStringOptionValue() as OptionValueInformation,
193+
Validator("config_parse_bind_user_shell", "0") to ConfigParseBindUserShellOptionValue() as OptionValueInformation,
194+
Validator("config_parse_cake_priority_queueing_preset", "QDISC_KIND_CAKE") to ConfigParseCakePriorityQueueingPresetOptionValue() as OptionValueInformation,
195+
Validator("config_parse_hostname", "0") to ConfigParseHostnameOptionValue() as OptionValueInformation,
196+
Validator("config_parse_device_allow", "0") to ConfigParseDeviceAllowOptionValue() as OptionValueInformation,
197+
Validator("config_parse_ifname", "0") to ConfigParseIfnameOptionValue() as OptionValueInformation,
198+
Validator("config_parse_dns", "0") to ConfigParseDnsOptionValue() as OptionValueInformation,
199+
Validator("config_parse_dns_name", "0") to ConfigParseDnsNameOptionValue() as OptionValueInformation,
200+
Validator("config_parse_wol", "0") to ConfigParseWolOptionValue() as OptionValueInformation,
201+
Validator("config_parse_dnssec_mode", "0") to ConfigParseDnssecModeOptionValue() as OptionValueInformation,
202+
Validator("config_parse_protect_hostname", "0") to ConfigParseProtectHostnameOptionValue() as OptionValueInformation,
203+
Validator("config_parse_ip_tos", "0") to ConfigParseIpTosOptionValue() as OptionValueInformation,
204+
Validator("config_parse_required_family_for_online", "0") to ConfigParseRequiredFamilyForOnlineOptionValue() as OptionValueInformation,
205+
Validator("config_parse_fq_bool", "QDISC_KIND_FQ") to ConfigParseFairQueueingBoolOptionValue() as OptionValueInformation,
206+
Validator("config_parse_fq_size", "QDISC_KIND_FQ") to ConfigParseFairQueueingSizeOptionValue() as OptionValueInformation,
207+
Validator("config_parse_fq_u32", "QDISC_KIND_FQ") to ConfigParseFairQueueingU32OptionValue() as OptionValueInformation,
208+
Validator("config_parse_si_uint64", "0") to ConfigParseSiUint64OptionValue() as OptionValueInformation,
209+
Validator("config_parse_fdb_vlan_id", "0") to ConfigParseFdbVlanIdOptionValue() as OptionValueInformation,
210+
Validator("config_parse_dhcp_socket_priority", "0") to ConfigParseDhcpSocketPriorityOptionValue() as OptionValueInformation,
211+
Validator("config_parse_cake_rtt", "QDISC_KIND_CAKE") to ConfigParseCakeRttOptionValue() as OptionValueInformation,
212+
Validator("config_parse_coalesce_sec", "0") to ConfigParseCoalesceSecOptionValue() as OptionValueInformation,
213+
Validator("config_parse_codel_usec", "QDISC_KIND_CODEL") to ConfigParseControlledDelayUsecOptionValue() as OptionValueInformation,
214+
Validator("config_parse_tbf_latency", "QDISC_KIND_TBF") to ConfigParseTokenBucketFilterLatencyOptionValue() as OptionValueInformation,
215+
Validator("config_parse_service_timeout", "0") to ConfigParseServiceTimeoutOptionValue() as OptionValueInformation,
216+
Validator("config_parse_service_timeout_abort", "0") to ConfigParseServiceTimeoutAbortOptionValue() as OptionValueInformation,
217+
Validator("config_parse_job_running_timeout_sec", "0") to ConfigParseJobRunningTimeoutSecOptionValue() as OptionValueInformation,
218+
Validator("config_parse_exec_secure_bits", "0") to ConfigParseExecSecureBitsOptionValue() as OptionValueInformation,
219+
Validator("config_parse_namespace_flags", "0") to ConfigParseNamespaceFlagsOptionValue() as OptionValueInformation,
220+
Validator("config_parse_can_bitrate", "0") to ConfigParseCanBitrateOptionValue() as OptionValueInformation,
221+
Validator("config_parse_can_time_quanta", "0") to ConfigParseCanTimeQuantaOptionValue() as OptionValueInformation,
222+
Validator("config_parse_fdname", "0") to ConfigParseFdnameOptionValue() as OptionValueInformation,
223+
Validator("config_parse_udev_property_name", "0") to ConfigParseUdevPropertyNameOptionValue() as OptionValueInformation,
189224

190225
)
191226

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for Files.BindUserShell (.nspawn).
8+
* C Function: config_parse_bind_user_shell(0)
9+
*
10+
* The C path calls parse_user_shell which accepts either:
11+
* - an absolute, normalized path (path_is_absolute && path_is_normalized), or
12+
* - a boolean (parse_boolean)
13+
*/
14+
class ConfigParseBindUserShellOptionValue : SimpleGrammarOptionValues(
15+
"config_parse_bind_user_shell",
16+
SequenceCombinator(
17+
AlternativeCombinator(
18+
BOOLEAN,
19+
RegexTerminal("/[^\\s]+", "/[^\\s]+")
20+
),
21+
EOF()
22+
)
23+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for CAKE.PriorityQueueingPreset (.network).
8+
* C Function: config_parse_cake_priority_queueing_preset(QDISC_KIND_CAKE)
9+
*
10+
* Accepts the 5 entries in cake_priority_queueing_preset_table:
11+
* besteffort, precedence, diffserv3, diffserv4, diffserv8.
12+
*/
13+
class ConfigParseCakePriorityQueueingPresetOptionValue : SimpleGrammarOptionValues(
14+
"config_parse_cake_priority_queueing_preset",
15+
SequenceCombinator(
16+
FlexibleLiteralChoiceTerminal("besteffort", "precedence", "diffserv3", "diffserv4", "diffserv8"),
17+
EOF()
18+
)
19+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for CAKE.RTTSec (.network).
8+
* C Function: config_parse_cake_rtt(QDISC_KIND_CAKE)
9+
*
10+
* Calls parse_sec, which accepts "infinity", a fractional or integer number
11+
* with any of systemd's time-unit suffixes, and compound forms like "1h 30s".
12+
*/
13+
class ConfigParseCakeRttOptionValue : SimpleGrammarOptionValues(
14+
"config_parse_cake_rtt",
15+
SequenceCombinator(TIME_VALUE, EOF())
16+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for CAN.BitRate and CAN.DataBitRate.
8+
* C Function: config_parse_can_bitrate(0) in src/network/networkd-can.c.
9+
*
10+
* Internally calls parse_size(rvalue, 1000, &sz). parse_size accepts a decimal
11+
* number (with optional fractional part) optionally suffixed with B/K/M/G/T/P/E.
12+
* The result must fit in a uint32_t; the range check is not enforced here.
13+
*/
14+
class ConfigParseCanBitrateOptionValue : SimpleGrammarOptionValues(
15+
"config_parse_can_bitrate",
16+
SequenceCombinator(
17+
RegexTerminal(
18+
"[0-9]+(?:\\.[0-9]+)?\\s*[BKMGTPE]?",
19+
"[0-9]+(?:\\.[0-9]+)?\\s*[BKMGTPE]?"
20+
),
21+
EOF()
22+
)
23+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for CAN.TimeQuantaNSec, CAN.DataTimeQuantaNSec.
8+
* C Function: config_parse_can_time_quanta(0)
9+
*
10+
* Per parse_nsec, accepts "infinity", a fractional or integer number with any of
11+
* systemd's time-unit suffixes (default unit: nanoseconds), and compound forms
12+
* like "1ms 500us".
13+
*/
14+
class ConfigParseCanTimeQuantaOptionValue : SimpleGrammarOptionValues(
15+
"config_parse_can_time_quanta",
16+
SequenceCombinator(TIME_VALUE, EOF())
17+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for Link.{RxCoalesceSec, RxCoalesceIrqSec, TxCoalesceSec, TxCoalesceIrqSec,
8+
* StatisticsBlockCoalesceSec, RxCoalesceLowSec, TxCoalesceLowSec,
9+
* RxCoalesceHighSec, TxCoalesceHighSec, CoalescePacketRateSampleIntervalSec}.
10+
* C Function: config_parse_coalesce_sec(0)
11+
*
12+
* Calls parse_sec, which accepts "infinity", a fractional or integer number with any
13+
* of systemd's time-unit suffixes, and compound forms like "1h 30s".
14+
*/
15+
class ConfigParseCoalesceSecOptionValue : SimpleGrammarOptionValues(
16+
"config_parse_coalesce_sec",
17+
SequenceCombinator(TIME_VALUE, EOF())
18+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for ControlledDelay.TargetSec, ControlledDelay.IntervalSec, ControlledDelay.CEThresholdSec
8+
* C Function: config_parse_codel_usec(QDISC_KIND_CODEL)
9+
*
10+
* Calls parse_sec, which accepts "infinity", a fractional or integer number with any
11+
* of systemd's time-unit suffixes, and compound forms like "1h 30s".
12+
*/
13+
class ConfigParseControlledDelayUsecOptionValue : SimpleGrammarOptionValues(
14+
"config_parse_codel_usec",
15+
SequenceCombinator(TIME_VALUE, EOF())
16+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for {Service,Socket,Mount,Swap,Slice,Scope}.DeviceAllow.
8+
* C Function: config_parse_device_allow(0)
9+
*
10+
* Per valid_device_allow_pattern + cgroup_device_permissions_from_string:
11+
* - device specifier is either a /dev/... path or a block-/char- prefixed device class
12+
* - optional whitespace + permissions, where permissions is a single token of [rwm]+
13+
*/
14+
class ConfigParseDeviceAllowOptionValue : SimpleGrammarOptionValues(
15+
"config_parse_device_allow",
16+
SequenceCombinator(
17+
AlternativeCombinator(
18+
RegexTerminal("(block-|char-)\\S+", "(block-|char-)\\S+"),
19+
RegexTerminal("/dev/\\S+", "/dev/\\S+")
20+
),
21+
ZeroOrOne(
22+
SequenceCombinator(
23+
WhitespaceTerminal(),
24+
RegexTerminal("[rwm]+", "[rwm]+")
25+
)
26+
),
27+
EOF()
28+
)
29+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues
5+
6+
/**
7+
* Validator for DHCPv4.SocketPriority
8+
* C Function: config_parse_dhcp_socket_priority(0)
9+
* Used by Options: DHCPv4.SocketPriority
10+
*
11+
* The C implementation uses safe_atoi() with no range restriction beyond what fits in a
12+
* signed 32-bit int. SO_PRIORITY values 0..6 are typical, but the parser itself accepts
13+
* any signed int. Empty values are allowed (clears the setting) and so are skipped here.
14+
*/
15+
class ConfigParseDhcpSocketPriorityOptionValue : SimpleGrammarOptionValues(
16+
"config_parse_dhcp_socket_priority",
17+
SequenceCombinator(
18+
IntegerTerminal(Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong() + 1L),
19+
EOF()
20+
)
21+
)

0 commit comments

Comments
 (0)