feat: repeatable-arg support, merge refactor, and --flat mode for tools - #111
Merged
Merged
Conversation
…ture Allow validation groups in requirements files to declare args as repeatable (e.g. tool-kernel's sysfs-trace-setup/-cleanup), so multiple occurrences survive merging instead of collapsing to one. A multi-valued single occurrence is rejected outright -- the cartesian-product interaction is undefined and was silently producing wrong results. Replace the old param_exists() inline scan with a shared identity model (_identity_key, _find_by_identity) and a merge-function family (merge_param, merge_param_include, merge_param_own, merge_repeatable_param) that gives include, own-params, defaults, and essentials uniform duplicate-conflict diagnostics. Refactor override_presets() to resolve defaults/essentials once via _resolve_preset_group() (which filters disabled entries before identity claiming, not after) and apply them per-set via merge_param_own(), fixing a bug where a disabled essential could permanently block an enabled one, and another where essentials were destructively consumed on the first set in a multi-set input. Fix include-preset handling that iterated every key in presets_dict instead of looking up the named group directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add apply_flat_params() as a narrow entry point for consumers with no
sets/include/sweep concept (i.e. tools). It validates/converts/transforms
a flat {arg, val} list via override_presets() with force_role='all',
reusing the full merge/preset infrastructure without routing through
load_param_sets()'s include handling or the cartesian-product engine.
Add --flat CLI flag that routes main() through apply_flat_params()
instead of the general pipeline, and flat-schema.json for input
validation. apply_flat_params() validates its own inputs (both params
and requirements schemas) so it is safe to call directly as a library
function without relying on CLI-level validation.
Add conftest.py with autouse fixture resetting all module-level state
dicts between tests, and test-flat.py with 14 tests covering own params,
disabled filtering, defaults/essentials, repeatable occurrences, state
isolation between calls, and schema boundary enforcement.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
conftest.py is loaded by pytest before multiplex.py is collected as a test module, so the repo root isn't on sys.path yet when conftest tries to import multiplex. This worked locally but failed in CI where pytest runs from a clean checkout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merged
2 tasks done
k-rister
added a commit
to k-rister/rickshaw
that referenced
this pull request
Aug 17, 2026
multiplex.py now provides a --flat mode (perftool-incubator/multiplex#111) purpose-built for consumers with no sets/include/cartesian-product concept. Tools always have exactly one implicit param set and, per schema/tool-params.json, never more than one value per param, so the previous wrap-into-sets-document/unwrap dance and the len(...) == 1 defensive check were ceremony around something structurally impossible. This writes the tool's flat params directly, invokes --flat, and reads the result back as-is -- filtering of disabled params and enforcement of exactly-one-combination now live inside multiplex.py itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
k-rister
added a commit
to perftool-incubator/tool-kernel
that referenced
this pull request
Aug 17, 2026
…rammar
sysfs-trace-setup/-cleanup shared the generic_string validation group
with no repeatable flag, so a second occurrence of either silently
collapsed onto the first ("last one takes effect") -- data loss for
kerneltools-start/-stop, which both accumulate these into an array and
expect every occurrence to survive. Split them into their own
sysfs_trace_command group with "repeatable": true, now that multiplex
supports it (perftool-incubator/multiplex#111).
Separately, rickshaw.json's param_regex for the perf-gen-local-report
ON/OFF flag hack was written against the old two-token rendering
grammar ('--flag' 'ON'). Rickshaw's param-rendering unification
(perftool-incubator/rickshaw#868) now renders params as a single
--flag=value token, so the old regex silently matched nothing --
verified this let --perf-gen-local-report=OFF pass through unchanged,
which would break kerneltools-stop's getopt parsing (that flag takes
no argument) at runtime. Rewrote both patterns for the new grammar and
verified against the real render_param()/apply_param_regex_and_split()
pipeline: ON renders as a bare flag, OFF is stripped entirely.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
repeatable: truevalidation-group flag so args like tool-kernel'ssysfs-trace-setup/sysfs-trace-cleanupcan appear more than once in a param set without being collapsed. A multi-valued single occurrence is rejected outright (the cartesian-product interaction is undefined and was silently producing wrong results).param_exists()inline scan with a shared identity model (_identity_key,_find_by_identity) and a merge-function family (merge_param,merge_param_include,merge_param_own,merge_repeatable_param) that gives include, own-params, defaults, and essentials uniform duplicate-conflict diagnostics.override_presets()to resolve defaults/essentials once via_resolve_preset_group()(filtering disabled entries before identity claiming), fixing bugs where a disabled essential could block an enabled one and essentials were destructively consumed on the first set in a multi-set input.include-presethandling that iterated every key inpresets_dictinstead of looking up the named group directly.--flatCLI mode andapply_flat_params()as a narrow entry point for tools: validates/converts/transforms a flat{arg, val}list viaoverride_presets()withforce_role='all', reusing all existing merge/preset primitives without routing throughload_param_sets()'s include handling or the cartesian-product engine.Test plan
pytest multiplex.py tests/test-json.py, etc.)crucible runwith tool-kernel against a live remotehosts endpoint —apply_tool_multiplex()→multiplex.py --flat→ tool-kernel'skerneltools-start→ turbostat producing real outputload_param_sets()/multiplex_set()untouched by Part 2)🤖 Generated with Claude Code