Skip to content

fix(loop): C063 loop options audit — 6 discrepancy fixes#270

Merged
pocky merged 1 commit intomainfrom
issue/264-c063-loop-options-audit--fix-6-documenta
Mar 19, 2026
Merged

fix(loop): C063 loop options audit — 6 discrepancy fixes#270
pocky merged 1 commit intomainfrom
issue/264-c063-loop-options-audit--fix-6-documenta

Conversation

@pocky
Copy link
Copy Markdown
Contributor

@pocky pocky commented Mar 19, 2026

Summary

  • Fixes 6 documentation-vs-implementation discrepancies found in a loop options audit: ~56 lowercase loop variable references (loop.item, loop.index) corrected to PascalCase (loop.Item, loop.Index) across 4 doc files
  • Adds missing index1 and parent keys to makeLoopAccessor in template_resolver.go, enabling {{.loop.Index1}} and {{.loop.Parent.*}} to resolve correctly in templates
  • Fixes silent bug where modulo (%) expressions in max_iterations were not routed to the arithmetic evaluator, causing them to be parsed as literal integers and fail
  • Fixes nested loop Parent chain being silently dropped: ExecuteForEach now preserves the Parent field from buildContext output or falls back to buildLoopDataChain on the domain context

Changes

Documentation

  • docs/reference/interpolation.md: Replaced all lowercase loop variable references with PascalCase; updated nested parent access examples
  • docs/reference/loop.md: Replaced lowercase loop variable references with PascalCase across all examples and reference tables
  • docs/user-guide/workflow-syntax.md: Updated for_each and while loop context tables (added Index1, Last, Item, Parent rows); corrected variable casing; replaced invalid arithmetic max_iterations example with single-variable form; improved while/break_when field descriptions
  • docs/user-guide/examples.md: Corrected loop variable casing in for_each and nested loop examples
  • CHANGELOG.md: Added C063 entry detailing all 6 findings and code changes
  • CLAUDE.md: Added convention: apply code deletions before writing tests that validate the deletion effect

Implementation

  • pkg/interpolation/template_resolver.go: Extracted loopToMap() helper; added index1 (Index+1) and parent (recursive map or nil) to loop accessor map
  • internal/application/loop_executor.go: Added % to strings.ContainsAny operator detection in parseMaxIterationsValue; updated ExecuteForEach to preserve the Parent chain from buildContext output, with fallback to buildLoopDataChain from domain context

Tests

  • pkg/interpolation/template_resolver_test.go: New file — tests for index1 (0-based, large), parent nil/value/recursive access, error on missing loop, and complex parent item serialization
  • internal/application/loop_executor_refactor_test.go: Added modulo test case to table-driven suite; added 5 standalone tests covering modulo detection, error handling, and complex expressions
  • internal/application/loop_foreach_test.go: Added 3 tests for buildContext equivalence verification, single-level parent nil assertion, and full iteration variable correctness after removing the redundant override
  • internal/application/loop_iterations_test.go: Updated TestLoopExecutor_ResolveMaxIterations_ArithmeticModulo from negative test (expecting error) to positive test (expecting 2)
  • internal/application/loop_executor_mocks_test.go: Added Parent field capture to stepExecutorRecorder

Test plan

  • Run unit tests: go test ./pkg/interpolation/... ./internal/application/...
  • Verify {{.loop.Index1}} and {{.loop.Parent.Item}} resolve correctly in a real nested for_each workflow
  • Confirm max_iterations: "{{inputs.a % inputs.b}}" evaluates correctly (e.g., 7 % 3 → 1 iteration)
  • Run full test suite: make test

Closes #264


Generated with awf commit workflow

- `CHANGELOG.md`: Document C063 6-finding audit with per-finding descriptions
- `CLAUDE.md`: Add rule on deletion-before-test ordering
- `docs/reference/interpolation.md`: Fix ~13 lowercase loop vars to PascalCase
- `docs/reference/loop.md`: Fix ~20 lowercase loop vars to PascalCase
- `docs/user-guide/examples.md`: Fix 3 lowercase loop var references
- `docs/user-guide/workflow-syntax.md`: Fix ~15 lowercase vars; expand while loop context table; fix break_when/while/max_iterations descriptions
- `internal/application/loop_executor.go`: Preserve Parent chain in ExecuteForEach; add `%` to arithmetic operator detection
- `internal/application/loop_executor_mocks_test.go`: Capture Parent field in stepExecutorRecorder
- `internal/application/loop_executor_refactor_test.go`: Add 6 modulo operator test cases
- `internal/application/loop_foreach_test.go`: Add 3 tests for buildContext equivalence and Parent chain preservation
- `internal/application/loop_iterations_test.go`: Update modulo test from negative to positive assertion
- `pkg/interpolation/template_resolver.go`: Add index1 and parent keys to makeLoopAccessor via loopToMap helper
- `pkg/interpolation/template_resolver_test.go`: Add 7 tests for index1 and parent accessor behavior

Closes #264
@pocky pocky marked this pull request as ready for review March 19, 2026 15:24
@pocky pocky merged commit 1a6b400 into main Mar 19, 2026
5 checks passed
@pocky pocky deleted the issue/264-c063-loop-options-audit--fix-6-documenta branch March 22, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C063: Loop Options Audit — Fix 6 Documentation-vs-Implementation Discrepancies

1 participant