StackGuardian / StackGuardian/tirith
docs(cookbook): engine-verified path idioms — membership, at-least-one, and the traps
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 165
- Forks
- 42
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 11
Description
A cookbook page of zero-code recipes, each verified against the running engine. House rule: every
path idiom names which of the two path engines it holds for — the shared json/kubernetes engine
and terraform_plan disagree more often than they agree, and "true idiom, wrong engine" fails
silently.
- Collection membership: drop the trailing
.*and the provider emits the whole collection as
one value per resource;Containswith an element dict is membership. Limit: exact element
equality (fails where elements carry extra keys, e.g.aws_db_parameter_group.parameterwith
apply_method). - At-least-one via
guard && !none:!idis existential ineval_expression, so De Morgan
applies — anIsNotEmptyguard on the collection, aNot*condition on
<collection>.*.<field>, andeval_expression: "guard && !none". Verified across matching /
non-matching / empty-array / absent-key / empty-document cases. The guard is load-bearing:
without it an absent collection satisfies the negation vacuously. Caveat, measured: on
terraform_planthis is plan-wide, not per-resource (the provider flattens instances into one
stream — two resources where only one matches returnstrue); sound for single-instance json
documents and genuinely plan-wide intent only. It cannot bind two attributes of the same element,
and the negated condition cannot be a regex. - Scalar-or-list: a trailing
.*unwraps a scalar on the shared json/kubernetes engine, so one
path covers a scalar-or-list union (Statement.*.Action.*). It does not hold on
terraform_plan, where a scalar under.*is a severity-2 miss. *iterates dict values, so CloudFormation'sResourcesmap addresses exactly like ARM's
array.- An empty list pads
Noneat inner wildcard levels; only the outermost segment is a severity-2
miss — this decideserror_tolerancefor nested-block-inside-repeated-block checks. - When every id is deleted from the AST the result is
null, nottrue— the trap for
all-absence policies, whose compliant case is exactly "every path misses". - The type-guard idiom is polarity-specific: type present + attribute absent FAILS at every inner
tolerance, so omit the guard when upstream passes on absence; use!selected || checkfor
sibling-attribute scoping. nullable.TypeNullableBoolprovider arguments arrive in the plan as the strings
"true"/"false", soEquals: truesilently never fires — useContainedIn: [true, "true"].
Related bug, fileable separately: a mixed-type list in ContainedIn/Equals evaluates correctly
but logs a full traceback from utils.sort_collections — cosmetic, noisy, ~2-line fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the cookbook documentation and the running-engine verification entry points, then compare each recipe across the shared json/kubernetes engine and terraform_plan. Use eval_expression for the guard behavior and preserve the listed edge cases, engine limitations, and type handling; the completed page should label every idiom with the engines it supports. Keep the utils.sort_collections traceback as a separate bug.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kubernetes, python, terraform
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100