Skip to content

docs: design turtle geometry and a guiltty-sprite crate extraction - #37

Merged
rsenna merged 5 commits into
mainfrom
turtle-and-sprite-design-docs
Aug 1, 2026
Merged

docs: design turtle geometry and a guiltty-sprite crate extraction#37
rsenna merged 5 commits into
mainfrom
turtle-and-sprite-design-docs

Conversation

@owkwo-bot

@owkwo-bot owkwo-bot commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two design docs for forward-looking iklo work (games + turtle graphics), not tied to a v0 success criterion:

  • docs/design/sprite-crate-extraction.md — extracts Sprite/Bitmap out of guiltty-core into a new guiltty-sprite crate, keeping guiltty-core scoped to exactly "draw into a kitty-like terminal" (absolute-coordinate Canvas/Shape/text/Backend). Flags the one real technical wrinkle: Canvas::draw_sprite's save/restore-under logic currently reads Canvas's private pixels/id fields directly, so the extraction needs one small additive public method (Canvas::id()) and reimplementing the draw against Canvas's existing public pixel/set_pixel accessors. Also adds a relative, actor-centric movement API (heading/forward/backward/turn) to Sprite, alongside its existing absolute move_to — both stay available, useful independently (e.g. games) of turtle graphics specifically.
  • docs/design/turtle-geometry.md — a Turtle that wraps a guiltty-sprite-based Sprite, adding only pen up/down + pen color. Movement itself is entirely delegated to the wrapped sprite; multiple turtles fall out for free from multiple sprites.

Sequencing (each its own follow-up PR): (1) extract guiltty-sprite mechanically, (2) add relative movement to Sprite, (3) build guiltty-turtle on top.

Test plan

  • Docs-only change — no code/tests affected; nothing to run.

Summary by Sourcery

Add forward-looking design documents for extracting sprite functionality into a dedicated crate and building a turtle-geometry layer on top.

Documentation:

  • Document the planned extraction of Sprite/Bitmap from guiltty-core into a new guiltty-sprite crate with added relative movement APIs.
  • Document the planned guiltty-turtle crate that wraps sprites with turtle-style pen state and drawing behavior.

Summary by cubic

Adds two forward-looking design docs: extracting Sprite/Bitmap from guiltty-core into guiltty-sprite with a relative movement API, and a guiltty-turtle layer that wraps a sprite for pen drawing. Documents a breaking API change (Canvas::draw_spriteSprite::draw_on), region-scoped footprint versioning, and recovery paths to avoid trail corruption.

  • Refactors

    • Extract Sprite/Bitmap to guiltty-sprite; keep guiltty-core focused on absolute drawing.
    • Breaking change: replace Canvas::draw_sprite with Sprite::draw_on(&mut Canvas); add Canvas::id() and Canvas::region_version(Rect); use public pixel/set_pixel.
    • Bitmap::from_file continues returning guiltty_core::Error.
    • Follow-up docs list tests to port (transparency, clipping, same/cross-canvas) and add wrong-canvas-id and region-scoped staleness checks.
  • New Features

    • Relative movement on Sprite: heading in degrees (clockwise, top-left origin), forward/backward, turn/left/right, plus move_to; track exact_position: (f32, f32) with Point as a rounded view.
    • Split drawing into clear_footprint and place; footprints are version-stamped by canvas id and region_version(Rect); clear_footprint returns Result<(), StaleFootprint> on wrong-canvas or region changes; add Sprite::discard_footprint to recover.
    • guiltty-turtle: wraps a Sprite, adds pen_up/pen_down and pen_color; drawing moves (forward/backward/goto) return Result and use clear/draw/place so trails don’t lose their start; safe trail crossings via staleness errors; Turtle::resync recovers from stale footprints.

Written for commit f86a9d1. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Documentation
    • Added design documentation for separating sprites and bitmaps from canvas drawing.
    • Documented absolute positioning, heading-based movement, turning, and sub-pixel positioning.
    • Specified footprint clearing, placement, and stale-footprint handling.
    • Added a proposed turtle API with pen controls, colors, movement, turning, and direct positioning.
    • Outlined implementation phases, testing plans, integration considerations, and known non-goals.

Forward-looking groundwork for iklo, not tied to a v0 success criterion.

- sprite-crate-extraction.md: move Sprite/Bitmap out of guiltty-core into a
  new guiltty-sprite crate, keeping core scoped to absolute-coordinate
  drawing only. Adds relative (heading/forward/turn) movement to Sprite
  alongside its existing absolute move_to.
- turtle-geometry.md: rewritten to wrap a guiltty-sprite Sprite, adding only
  pen state -- movement itself is guiltty-sprite's concern.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai

sourcery-ai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds two forward-looking design documents describing the extraction of Sprite/Bitmap into a new guiltty-sprite crate with relative movement APIs, and a guiltty-turtle crate that layers Logo-style turtle geometry and pen state on top of sprites.

File-Level Changes

Change Details Files
Document the planned extraction of Sprite/Bitmap into a new guiltty-sprite crate and the introduction of relative movement APIs on Sprite.
  • Describe splitting guiltty-core to keep only absolute-coordinate drawing (Canvas/Shape/text/Backend) while moving Sprite/Bitmap into a new guiltty-sprite crate.
  • Explain the Canvas::draw_sprite private-field access issue and propose adding a public Canvas::id accessor plus reimplementing sprite drawing as Sprite::draw_on(Canvas) using public pixel/set_pixel APIs.
  • Specify the new relative movement API for Sprite (heading, forward/backward, turn/left/right) alongside the existing absolute move_to, including internal f32 tracking and rounding semantics.
  • Outline the planned follow-up PR sequence: first mechanically extract guiltty-sprite and Canvas::id, then add relative movement with tests.
docs/design/sprite-crate-extraction.md
Document the design for a new guiltty-turtle crate that wraps Sprite to provide turtle-geometry pen behavior.
  • Define a Turtle type that wraps a Sprite and adds pen_up/pen_down and pen_color while delegating movement to the underlying Sprite.
  • Describe how turtle movement methods draw Shape::line segments on the Canvas when the pen is down, then redraw the sprite bitmap using Sprite::draw_on for non-destructive rendering.
  • Clarify non-goals such as no automatic closed-shape fill, no arc/circle commands, and no collision/game features, plus open questions around constructor shape and heading convention.
  • Outline the follow-up plan to create the guiltty-turtle crate, implement Turtle with tests, and add an example that draws a recognizable shape.
docs/design/turtle-geometry.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

owkwo-bot has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds design documents for extracting Sprite and Bitmap into guiltty-sprite, adding relative movement and footprint handling, and defining a future guiltty-turtle wrapper with pen state and trail drawing.

Changes

Sprite and Turtle Geometry

Layer / File(s) Summary
Sprite extraction and drawing contracts
docs/design/sprite-crate-extraction.md
Defines the guiltty-sprite extraction, Canvas identity and version accessors, Sprite::draw_on, footprint operations, and StaleFootprint.
Relative sprite movement
docs/design/sprite-crate-extraction.md
Defines heading-based movement, turning, exact floating-point position tracking, rounded Point views, and absolute movement behavior.
Sprite integration and validation plan
docs/design/sprite-crate-extraction.md
Sequences workspace integration, call-site migration, preserved drawing semantics, and tests for movement, rounding, and stale footprints.
Turtle wrapper API
docs/design/turtle-geometry.md
Defines Turtle state, pen-enabled movement, delegated sprite operations, stale-footprint handling, accessors, open questions, and follow-up tests and examples.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • rsenna/guiltty#6: The design evolves the existing Canvas/Sprite drawing and footprint APIs.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both design documents and the proposed guiltty-sprite crate extraction.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch turtle-and-sprite-design-docs

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="docs/design/sprite-crate-extraction.md" line_range="116-117" />
<code_context>
+}
+```
+
+`forward`/`backward` track position as `f32` internally (same
+rounding-drift reasoning as `guiltty-turtle`'s original sketch: many small
+moves compounding integer rounding error is a real problem for both games
+and turtle patterns) and round to `Point`'s `i32` only when the position is
</code_context>
<issue_to_address>
**issue (typo):** Plural subject in the rounding-drift sentence should take "are" instead of "is".

These lines read as a single sentence: "many small moves compounding integer rounding error is a real problem...". Because the subject "many small moves" is plural, the verb should be "are a real problem" rather than "is a real problem."

```suggestion
rounding-drift reasoning as `guiltty-turtle`'s original sketch: many small
moves compounding integer rounding error are a real problem for both games
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread docs/design/sprite-crate-extraction.md Outdated
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
docs/design/turtle-geometry.md (1)

40-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Define the contract for sprite_mut.

Turtle movement applies pen logic, but sprite_mut() exposes Sprite::move_to, Sprite::forward, and Sprite::draw_on directly. These operations can bypass pen trails. Either restrict mutable access or document that direct sprite operations do not create pen segments. Add Turtle::draw_on if callers need to render the initial sprite without using this escape hatch.

Also applies to: 53-60

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/turtle-geometry.md` around lines 40 - 50, Document the contract
of Turtle::sprite_mut to state that direct Sprite operations, including move_to,
forward, and draw_on, bypass Turtle pen-trail handling and do not create pen
segments. Add a Turtle::draw_on method for rendering the initial sprite without
exposing the escape hatch, and update the related API documentation
consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/sprite-crate-extraction.md`:
- Around line 66-79: Update the extraction design around the public API changes
to explicitly classify them as a breaking semver release and document the
required migration, or define a supported compatibility layer that preserves
existing Sprite, Bitmap, and Canvas::draw_sprite usage. Address the affected
call sites and explain how re-exports and the new Sprite::draw_on API handle
compatibility, noting that re-exports alone cannot preserve the inherent Canvas
method.
- Around line 81-82: Clarify the extraction design around Bitmap::from_file by
specifying which error type it returns after moving to the new crate, how
image-loading failures are represented, and which image dependency supplies
them. Define whether callers retain guiltty-core::Error::ImageLoad or migrate to
a new crate-local error, including the required caller impact, before describing
the move as mechanical.
- Around line 87-92: The Sprite API sketch must include a separate exact
floating-point position alongside the integer position. Update Sprite and the
documented new, move_to, position, forward/backward, and drawing behavior to
keep these states synchronized, preserve fractional displacement across repeated
sub-pixel movement, and reset the exact position from the supplied integer point
in move_to.
- Around line 38-41: Update the Sprite forward movement formula to convert
heading_deg from degrees with to_radians() before passing it to sin or cos, and
document that the top-left origin makes positive Y downward and positive turns
clockwise. Add movement tests covering 0° and 90° with assertions for the
expected cardinal positions.

In `@docs/design/turtle-geometry.md`:
- Around line 25-50: Add guiltty-core as a direct dependency of guiltty-turtle
and import Canvas, Color, Point, Shape, and Fill from it, while continuing to
source Sprite and Bitmap from guiltty-sprite. If using re-exports instead,
define and apply those paths consistently throughout the Turtle API.

---

Nitpick comments:
In `@docs/design/turtle-geometry.md`:
- Around line 40-50: Document the contract of Turtle::sprite_mut to state that
direct Sprite operations, including move_to, forward, and draw_on, bypass Turtle
pen-trail handling and do not create pen segments. Add a Turtle::draw_on method
for rendering the initial sprite without exposing the escape hatch, and update
the related API documentation consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e884b3e2-055c-435b-b7a0-dab59a850186

📥 Commits

Reviewing files that changed from the base of the PR and between 1ca813b and f9c2133.

📒 Files selected for processing (2)
  • docs/design/sprite-crate-extraction.md
  • docs/design/turtle-geometry.md

Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md
Comment thread docs/design/turtle-geometry.md

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

The PR provides a solid conceptual foundation for the guiltty-sprite extraction and guiltty-turtle geometry layer. While Codacy results are up to standards, two critical design issues must be resolved before merging. First, the Sprite implementation details contradict the acceptance criteria regarding f32 coordinate tracking, which is essential to prevent rounding drift during accumulated relative movements. Second, the proposed drawing sequence for the Turtle will lead to visual bugs where the sprite's restoration logic overwrites the start of its own trail. These consistency and logic gaps should be addressed to ensure the design is technically sound.

Test suggestions

  • Missing recommended test scenario: Verify Sprite relative movement updates position correctly based on heading and distance using f32 precision.
  • Missing recommended test scenario: Verify Turtle draws a line segment on the Canvas when moving while the pen is down.
  • Missing recommended test scenario: Verify Turtle does not draw a trail when moving while the pen is up.
  • Missing recommended test scenario: Verify Sprite::draw_on correctly uses the proposed Canvas::id() to prevent drawing on incorrect canvas instances.
  • Missing recommended test scenario: Verify that Sprite absolute (move_to) and relative (forward) movement methods compose correctly.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Missing recommended test scenario: Verify `Sprite` relative movement updates position correctly based on heading and distance using f32 precision.
2. Missing recommended test scenario: Verify `Turtle` draws a line segment on the `Canvas` when moving while the pen is down.
3. Missing recommended test scenario: Verify `Turtle` does not draw a trail when moving while the pen is up.
4. Missing recommended test scenario: Verify `Sprite::draw_on` correctly uses the proposed `Canvas::id()` to prevent drawing on incorrect canvas instances.
5. Missing recommended test scenario: Verify that `Sprite` absolute (`move_to`) and relative (`forward`) movement methods compose correctly.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread docs/design/turtle-geometry.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread docs/design/turtle-geometry.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/turtle-geometry.md Outdated
- Convert heading degrees to radians in the movement formula, and document
  the clockwise/top-left-origin convention explicitly.
- Stop calling the guiltty-sprite extraction "non-breaking" -- moving
  Sprite/Bitmap out and replacing Canvas::draw_sprite with sprite.draw_on
  is a breaking public-API change; document it as such with no
  compatibility shim planned (pre-1.0, matches T1's precedent).
- Define Bitmap::from_file's error ownership after extraction: it keeps
  returning guiltty_core::Error, not a new crate-local error type.
- Fix the Sprite API sketch's position field: exact_position: (f32, f32)
  is now the one canonical field, with Point only ever a rounded view of
  it -- resolves the contradiction between the struct (Point) and prose
  (f32 tracking).
- Split Sprite's draw_on into clear_footprint/place primitives, needed to
  fix a real bug in the turtle drawing sequence: drawing a trail line then
  calling draw_on restored the sprite's *old* footprint after the line
  already drew into it, erasing the trail's start on every move. The fix
  clears first, draws the trail, then places -- with a regression test
  requirement added to the follow-up.
- Clarify guiltty-turtle depends directly on guiltty-core (Canvas, Color,
  Point, Shape, Fill) in addition to guiltty-sprite, not guiltty-sprite
  alone.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/design/sprite-crate-extraction.md (1)

78-85: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Move and extend the sprite drawing tests before removing Canvas::draw_sprite.

Adapt the existing tests for transparency, clipping, same-canvas movement, and cross-canvas drawing to Sprite::draw_on. Add an interleaving test for clear_footprint/place that checks underlay capture and restoration order.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/sprite-crate-extraction.md` around lines 78 - 85, Move the
existing transparency, clipping, same-canvas movement, and cross-canvas drawing
tests from Canvas::draw_sprite to Sprite::draw_on, preserving their current
assertions. Add an interleaving test covering clear_footprint and place that
verifies underlays are captured and restored in the correct order before
removing Canvas::draw_sprite.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/sprite-crate-extraction.md`:
- Around line 139-150: Update the clear_footprint/place API description to
specify that clear_footprint restores and consumes last_draw only on the canvas
where it was captured, making repeated clears no-ops; calls with a different
canvas must not restore or consume the saved footprint. State that place
captures and blits the new footprint, replacing any existing last_draw with the
new canvas and footprint.

In `@docs/design/turtle-geometry.md`:
- Around line 53-77: The design must define a mechanism that preserves trails
when one Turtle draws through another Turtle’s footprint, such as a separate
persistent trail layer or deterministic full-scene redraw order. Update the
movement and rendering design around clear_footprint, place, and Turtle state
accordingly, and add a test covering two turtles whose trails cross without
either trail being erased.

---

Nitpick comments:
In `@docs/design/sprite-crate-extraction.md`:
- Around line 78-85: Move the existing transparency, clipping, same-canvas
movement, and cross-canvas drawing tests from Canvas::draw_sprite to
Sprite::draw_on, preserving their current assertions. Add an interleaving test
covering clear_footprint and place that verifies underlays are captured and
restored in the correct order before removing Canvas::draw_sprite.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 20251ef9-cfe9-4032-b035-3283349eb9bd

📥 Commits

Reviewing files that changed from the base of the PR and between f9c2133 and f1f9faa.

📒 Files selected for processing (2)
  • docs/design/sprite-crate-extraction.md
  • docs/design/turtle-geometry.md

Comment thread docs/design/sprite-crate-extraction.md
Comment thread docs/design/turtle-geometry.md
owkwo-bot and others added 2 commits August 1, 2026 01:55
clear_footprint restored a captured snapshot with no check that the
canvas had changed since capture -- a second clear, or another
sprite's trail drawn through this one's footprint, would silently
blit stale pixels back over newer drawing. Add a monotonic
Canvas::version() counter, stamp it onto DrawnFootprint at capture
time, and have clear_footprint return Err(StaleFootprint) on a
mismatch instead of restoring. Propagate that into Turtle's
forward/backward/goto, which now return Result instead of &mut Self.

Co-Authored-By: WOZCODE <contact@withwoz.com>
Bot review flagged two test-coverage gaps in the Follow-up sections:
which of Canvas::draw_sprite's existing tests must survive the move
to Sprite::draw_on (transparency, clipping, same/cross-canvas), plus
a wrong-canvas-id no-op test; and Turtle's pen-down case was only
implied by the no-gap regression test, never stated on its own.

Co-Authored-By: WOZCODE <contact@withwoz.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/design/sprite-crate-extraction.md (1)

142-153: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Propagate stale-footprint errors from draw_on.

draw_on composes clear_footprint, but clear_footprint can fail while draw_on returns (). Return Result<(), StaleFootprint> and skip place when clearing fails. Otherwise callers cannot handle stale footprints safely.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/design/sprite-crate-extraction.md` around lines 142 - 153, Update the
draw_on method contract to return Result<(), StaleFootprint>, propagate any
error from clear_footprint, and only call place after clearing succeeds.
Preserve the existing successful draw behavior by returning Ok(()) after place
completes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/design/sprite-crate-extraction.md`:
- Around line 184-199: Update the sprite place flow so the footprint’s
under-pixel data is captured before blitting, but assign DrawnFootprint.version
from canvas.version() only after place completes its pixel writes. Ensure the
saved version represents the post-blit canvas state so the first clear_footprint
call succeeds.
- Around line 194-201: Define recovery for stale clears in the Canvas
clear_footprint flow: ensure a StaleFootprint cannot leave an indefinitely
retryable last_draw with a permanently mismatched version. Either add an
explicit operation to discard or recover the saved footprint, or consume
last_draw when returning StaleFootprint, and document that the previously drawn
pixels remain unchanged.

In `@docs/design/turtle-geometry.md`:
- Around line 75-85: Define a recovery path for StaleFootprint in the public
Turtle API: add an explicit resynchronization operation or document a safe
low-level sequence that rebases or discards sprite.last_draw before retrying
forward, backward, or goto. Update the turtle geometry documentation and add
tests covering stale failure followed by successful recovery, while preserving
the guarantee that the failed move leaves position and canvas unchanged.
- Around line 75-86: Update the stale-footprint handling described for Canvas
and clear_footprint so canvas writes invalidate only footprints whose regions
overlap the affected write, rather than comparing a global Canvas::version().
Preserve Err(StaleFootprint) for actual footprint conflicts and add coverage for
two non-overlapping turtles moving sequentially without errors.

---

Outside diff comments:
In `@docs/design/sprite-crate-extraction.md`:
- Around line 142-153: Update the draw_on method contract to return Result<(),
StaleFootprint>, propagate any error from clear_footprint, and only call place
after clearing succeeds. Preserve the existing successful draw behavior by
returning Ok(()) after place completes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c994937-5b01-4c05-9cb1-cff27bd5b720

📥 Commits

Reviewing files that changed from the base of the PR and between f1f9faa and 53526bf.

📒 Files selected for processing (2)
  • docs/design/sprite-crate-extraction.md
  • docs/design/turtle-geometry.md

Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/sprite-crate-extraction.md Outdated
Comment thread docs/design/turtle-geometry.md
Comment thread docs/design/turtle-geometry.md
Three bugs in the previous fix:
- place stamped the footprint's version before its own blit, which is
  itself a canvas write -- every sprite self-invalidated on the very
  first clear_footprint call.
- Canvas::version() was a single global counter, so any sprite's move
  invalidated every other sprite's footprint too, even in disjoint
  areas -- breaking the multi-turtle case the design's own Objective
  promises "falls out for free."
- Once stale, a footprint's version can never match again (monotonic),
  but nothing let a caller escape that -- a stale Turtle was
  permanently stuck retrying the same failing clear_footprint forever.

Replace the single counter with Canvas::region_version(Rect), backed
by a per-tile version grid: only writes that overlap a footprint's own
tiles can invalidate it, and place stamps the version after its blit
completes. Add Sprite::discard_footprint and Turtle::resync as the
explicit recovery path out of a permanently-stale footprint.

Co-Authored-By: WOZCODE <contact@withwoz.com>
@rsenna
rsenna merged commit d187745 into main Aug 1, 2026
4 checks passed
@rsenna
rsenna deleted the turtle-and-sprite-design-docs branch August 1, 2026 01:04
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.

2 participants