00Plan
Issue: sue5t-fix-tags-default-filters-and-add-additive-column-syntax · Generated 2026-06-01 09:17 UTC
01Strategy
Read this first - the rest is detail.
The two halves of this issue look unrelated but share one funnel:
cli.py::determine_column_filters is where user column arguments meet
defaults, and formatters.transform_tags_structure is the post-fetch
transform whose output the YAML defaults must anchor against. Both halves get
small, surgical changes at those two sites.
The direction:
strip + at the CLI funnel before
any grammar / validator code sees it, then merge
defaults + stripped_user_cols with
list(dict.fromkeys(...)) for order-preserving dedup. For the YAML,
fix only the 5 truly broken entries surfaced by a static shape-aware audit
(no global rewrite) and unblock directconnect with a one-line
case-insensitive companion patch to _is_aws_tags_structure.
One strip site, one merge function.
All +-handling lives at the top of
determine_column_filters. The grammar layer
(parse_filter_pattern) stays untouched, as CONTEXT.md D7 mandates.
Five YAML edits, not a global rewrite.
The audit confirms only 5 broken
Tags$-class entries (directconnect, ec2 vpcs, redshift x2,
ecr describe_images) plus two redundant Key$/Value$
leftovers under redshift.
directconnect needs a companion transform fix.
Its botocore shape uses lowercase
key/value;
_is_aws_tags_structure is case-sensitive today. Without the
one-line case-insensitive fix in Task 4, the YAML edit alone produces
empty columns at runtime.
Re-runnable audit, not a snapshot.
A shape-aware
scripts/audit_default_filters.py plus a unit test that runs it
catches regressions in CI without a separate workflow step.
02Flow
03Decisions
D1 - + semantics: global mode flip
LockedAny +-prefix anywhere in the column-filter group flips the whole invocation into additive mode. Defaults are kept; ALL named columns (bare and + alike) merge with them.
Per-column form (+ opts in only that column, bare opts out) - leaves "bare + +" mixed mode ambiguous.
Strict split (error if mixed bare + +) - forces users to either fully type out the defaults or fully use +.
D2 - Merge order & dedup
LockedDefaults first (in YAML order), then user-added columns in CLI argument order. Dedup is case-sensitive on the full pattern string via list(dict.fromkeys(...)).
Case-insensitive dedup - matches runtime semantics but creates surprising collapses; living with redundant columns is fine (column-width fitter handles it).
Where + is stripped
ChosenAt the very top of cli.py::determine_column_filters. Single funnel feeding both FilterValidator and apply_default_filters; zero collisions with argparse, parse_filter_pattern, parse_multi_level_filters_for_mode, or any helper.
Strip inside parse_filter_pattern - leaks CLI semantics into the grammar layer; CONTEXT.md D7 forbids.
Strip inside parse_multi_level_filters_for_mode - wrong layer; would apply uniformly to single/multi modes and value filters too (D3 forbids).
D4 - Per-service YAML fixes (not global)
LockedEach broken entry gets the right replacement for its service's actual shape: K/V-tagged services get Tags.Name$; list-of-string services get bare substring (no $); directconnect uses lowercase tags.Name.
Global Tags$ -> Tags.Name$ rewrite - breaks list-of-string-tagged services (e.g. ecr describe_images imageTags).
Fix _is_aws_tags_structure vs YAML workaround for directconnect
ChosenOne-line case-insensitive fix in _is_aws_tags_structure and _transform_aws_tags_list. Helps every future lowercase-key service for free.
Hard-code tags.0.key/tags.0.value literals in the YAML - bypasses the transform and produces ugly column names.
Re-runnable audit script + CI-bound test vs snapshot
ChosenShip scripts/audit_default_filters.py and a unit test that asserts the in-scope broken entries no longer appear. Self-updating when boto3 ships new shapes.
Snapshot of the corrected YAML - drifts the moment boto3 publishes a new service model; brittle and high-maintenance.
--additive flag as a non-prefix alternative
DeferredCONTEXT.md D7 defers this. RESEARCH.md confirms no shell breaks + tokens in practice (bash/zsh both treat it as literal).
ssm.get_parameters Parameters$ (RESEARCH.md P7)
Out of scopeSeparate audit finding, unrelated to Tags or additive. Defer to a follow-up issue.
04Detail
05Provenance
Generated from the canonical .md. This HTML is never
hand-edited - regenerate with /issue:view.