Implement TASK-030 (Periodic Boundary), Stage 4's ninth and last task - #38
Merged
Conversation
Adds StructuredCartesianMesh.wrapped_neighbour_cell (mesh geometry, not a third BoundaryCondition shape) and threads a periodic_pairs mapping into FirstOrderUpwindAdvection/CentralDifferenceDiffusion alongside boundary_conditions. The round-trip invariant is checked as convergence under mesh refinement rather than exact equality at one resolution -- a real wrap's own error drops ~62% over a 4x refinement, a mirrored/ clamped mutation only ~16% -- since first-order upwind's own numerical diffusion makes "matches exactly" the wrong claim even for a correct wrap, verified numerically before writing the assertion. Also builds Stage 4's own golden demo, Passive Scalar Transport: a new SimulationConfig section, and bootstrap.py's first wiring of a real simulation.step() call into RenderWindow.run(on_frame=...) via _add_passive_scalar_transport. The demo's centroid-displacement tolerance was likewise measured from a real run (~4% agreement), not guessed, and confirmed to fail under a frozen-state mutation. This closes Stage 4: nine of ten Completion Criteria met locally (make ci green, 603 tests, 53 Gherkin scenarios, all doc-consistency checks passing); Criterion 9 (a real CI run) is left honestly pending in the roadmap's own status table until this PR's own run completes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PR #38, run 33159480722: ci (ubuntu-latest) and ci (windows-latest) both green, checked directly via gh pr checks --watch rather than inferred from the PR merging. All ten of Stage 4's Completion Criteria are now genuinely met, not just locally green -- matching Stage 3's own precedent for how this row gets its "Met" verdict. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
AdamClemens
added a commit
that referenced
this pull request
Aug 28, 2026
… timeframe claim README.md's Project Status and Current Phase sections still said PyFlow "has completed Stage 3... and is about to begin Stage 4" and pointed a reader at Stage 2's Field Display demo as "the most recent" -- stale since Stage 4 closed (PR #38), caught while auditing the CLI help text for the same kind of staleness. Updated both sections to reflect Stage 4 being complete and Stage 5 not yet started, and repointed the "try the most recent demonstration" command at the Passive Scalar Transport demo. Added a rule in docs/practices.md: README's Project Status/Current Phase sections must be updated in the same change a stage opens or closes, same standing as the existing Quick Start rule, and stale docs found during unrelated work should be fixed on the spot rather than only flagged. Also corrects an inaccurate claim made in this same fix's own prior commit (src/pyflow/CLAUDE.md): the CLI help text was described as having gone stale "long after" Stage 4 landed, when in fact Stage 4 landed within about a day and the closing PR merged under an hour before that claim was written. Reworded to state the actual timeline.
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
StructuredCartesianMesh.wrapped_neighbour_cell(mesh geometry, not a thirdBoundaryConditionshape, per this task's own recorded Design decision) and threads a newperiodic_pairsmapping intoFirstOrderUpwindAdvection/CentralDifferenceDiffusionalongsideboundary_conditions— no interface change, no new ADR (mirrorsdiffusion_coefficient's own TASK-024 precedent).pyflow runthat steps a real simulation forward live, one timestep per rendered frame, via a newSimulationConfigsection andbootstrap.py's_add_passive_scalar_transportwired throughRenderWindow.run(on_frame=...). The demo's own centroid-displacement tolerance was likewise measured from a real run (~4% agreement with the closed-form prediction), not guessed.docs/planning/roadmap.md(TASK-030's own entry, Stage 4's closing status table),docs/architecture/{sequences,icds,engine}.md,adr/ADR-003,docs/implementation/golden-demos.md, and every touchedCLAUDE.md— including correcting two now-stale claims found mid-sweep (src/pyflow/engine/CLAUDE.mdhad said a periodic face raisesUnconfiguredBoundaryFaceError, which TASK-030 makes untrue) and one honestly-flagged still-open gap (docs/planning/backlog.md: periodic boundaries now exist, but total-quantity conservation under a periodic wrap specifically is still unchecked).Test plan
wrapped_neighbour_cell's own tests,periodic_boundary.feature's three scenarios, and the golden demo's own scenario all written and confirmed red before the corresponding production code.make cigreen locally: 603 tests, 53 Gherkin scenarios (all bound,make check-scenarios), 99% coverage, all doc-consistency checks (check-references/check-manifest/check-inventory/check-dependency-tree/check-docs/check-docs-index/check-graph/check-status) passing.🤖 Generated with Claude Code