Add the business case, stakeholder analysis, plan, milestones, dictionary and reviews

Business case BC-001, stakeholder analysis SA-001, project plan PP-001, the four
milestones MIL-001 to MIL-004, the domain dictionary DICT-001, the review records
RC-001 to RC-013 and the traceability matrix.

The reviews end in Go: the business case, stakeholder analysis, dictionary and the
four milestones are Accepted. The project plan is still Proposed; it has no
checklist and is accepted directly by the Product Owner.
This commit is contained in:
2026-10-07 23:58:31 +08:00
parent fe45ebfcbe
commit 4b3391b226
23 changed files with 1715 additions and 0 deletions
@@ -0,0 +1,83 @@
# Milestone 001: Project Foundation
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-001 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-07 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | pending |
---
## Purpose
This milestone decides whether the repository has a working, documented and presentable base on which the five challenges can be built: project configuration, ignore rules, package and test skeleton, source documentation, continuous integration, README and repository description with topics.
## Deliverable
The `mil-001-project-foundation` branch, opened as one pull request, containing `pyproject.toml`, a Python `.gitignore`, `src/turtle_challenges/` with `constants.py`, a `tests/` folder with a passing smoke test, a `Doxyfile`, a continuous integration workflow, and a `README.md` that follows the agreed template. The repository description and topics are set on the Gitea host and on its GitHub mirror.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | In a fresh `.venv` on Python 3.13, `python -m pip install --upgrade pip` and `python -m pip install -e ".[dev]"` succeed | Both exit 0 | Either fails |
| 2 | `dependencies = []` in `pyproject.toml`; `requires-python` is `>=3.13` | Both hold | A runtime dependency is declared, or the Python bound is missing |
| 3 | `python -m pytest` runs | Exit 0 with at least one test | Exit not 0, or no test collected |
| 4 | `ruff check .`, `ruff format --check .` and `mypy` | All exit 0 | Any exit not 0 |
| 5 | `doxygen Doxyfile` | 0 warnings | Any warning or error |
| 6 | `README.md` has the template sections in order, with no placeholder text | All sections present and filled | A section is missing or a `<placeholder>` remains |
| 7 | `.env` is not tracked and is listed in `.gitignore` | `git ls-files .env` prints nothing and `git check-ignore .env` prints `.env` | `.env` is tracked, or not ignored |
| 8 | Repository description and at least 5 topics | Set on the Gitea host and on GitHub | Missing on either host |
| 9 | The continuous integration workflow file exists and runs the install, lint, type check, test and Doxygen steps | All steps present | A step is missing |
| 10 | Review record against `QC-PY-001` | Verdict Go | Go-with-conditions or No-Go |
## Dependencies
| Depends on | Reason |
| --- | --- |
| BC-001, SA-001 and PP-001 accepted | The plan-first gate: no file goes under `src/` or `tests/` before the plan is accepted |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Reproducible set-up guide | O3 in [BC-001] |
| No runtime dependencies | O4 in [BC-001] |
| Source documentation | O5 in [BC-001] |
| Repository presentation | O6 in [BC-001] |
| One branch and pull request per milestone | O7 in [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-10 — the first of four milestones, leaving eleven days of the plan that ends 2026-10-21 (Constraints in [BC-001]).
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Create pyproject.toml | Declare the project in one file: name, version, `requires-python = ">=3.13"`, an empty runtime `dependencies` list, a `dev` extra with pytest, ruff and mypy, the `src` layout, and the pytest (`pythonpath`, `testpaths`), ruff and mypy settings. Keeping runtime dependencies at zero is objective O4 of the Business Case. | No | |
| 2 | Add Python .gitignore | Add the standard Python ignore rules plus `.env`, `.venv/` and the Doxygen output folder `build/`, so virtual environments, caches, generated documentation and the personal token file are never committed. | No | |
| 3 | Create package and test skeleton | Create `src/turtle_challenges/__init__.py` and `constants.py` (color mode 255, window title) and a `tests/` folder with a smoke test that imports the package, so the test run is green from the first pull request. Constants live only in `constants.py`. | No | |
| 4 | Add Doxyfile | Add a `Doxyfile` for the Python source (`INPUT = src`, README as main page, Hypertext Markup Language (HTML) output to `build/doxygen`, warnings treated as errors) and check that `doxygen Doxyfile` reports 0 warnings. Source files use Doxygen commands in their docstrings (`@brief`, `@param`, `@return`). | No | |
| 5 | Add continuous integration workflow | Add `.github/workflows/ci.yml` (read by GitHub Actions and by Gitea Actions): set up Python 3.13, upgrade pip, install `.[dev]`, then run ruff, mypy, pytest and the Doxygen build. The workflow never opens a turtle window. | No | |
| 6 | Write README from the agreed template | Write `README.md` with the sections Requirements, Set up (Windows PowerShell, Linux Debian, MacOS), Run, Run the tests, Continuous integration, Build the source documentation, Project layout and License. The set-up shows how to create and use a local `.venv` and how to run `python -m pip install --upgrade pip`. The Run section is completed in milestone 004. | No | |
| 7 | Set repository description and topics | Set a one-sentence description and at least 5 topics on the Gitea repository and on its GitHub mirror, using the tokens in `.env`. That file is for S01's personal use: it is never imported, tested, printed or committed. | No | |
| 8 | Review milestone 001 against QC-PY-001 | Review the configuration and skeleton against `QC-PY-001`, record the result as an `RC-*` and add the instance to the traceability matrix. | No | |
---
[BC-001]: ../business-case.md
@@ -0,0 +1,77 @@
# Milestone 002: Square and Dashed Line
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-002 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-07 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | pending |
---
## Purpose
This milestone decides whether the first two challenges (Turtle Challenge 1, draw a square, and Turtle Challenge 2, draw a dashed line) work, are tested without a display and can be started from the command line, and whether the turtle abstraction that every later challenge relies on is sound.
## Deliverable
The `mil-002-square-and-dashed-line` branch, opened as one pull request, containing the `Pen` protocol and window helpers, `draw_square`, `draw_dashed_line`, a recording fake turtle for tests, tests for both functions, and the `turtle-challenges` command with the `square` and `dashed-line` challenges.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | `draw_square` draws four sides of 100 units, turning 90 degrees after each, as shown by the recording fake turtle | The recorded moves match | Any recorded move differs |
| 2 | `draw_dashed_line` draws the configured number of dashes of 10 units, each followed by a gap of 10 units, with the pen down for each dash and up for each gap, and leaves the pen down when it returns | The recorded moves match | Any recorded move differs |
| 3 | Every number and name used by the two functions comes from `constants.py` | No magic number in the function bodies | A literal constant is found in a function body |
| 4 | `python -m turtle_challenges square` and `python -m turtle_challenges dashed-line` each open a window and draw to completion on Windows PowerShell | S01 confirms both in the review record | Either fails |
| 5 | No test opens a window | The test run passes with no display available | A test needs a display |
| 6 | `python -m pytest`, `ruff check .`, `ruff format --check .`, `mypy` and `doxygen Doxyfile` | All exit 0 with 0 Doxygen warnings | Any fails or warns |
| 7 | Review record against `QC-PY-001` | Verdict Go | Go-with-conditions or No-Go |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-001 accepted | Needs the project configuration, package skeleton, test setup and continuous integration |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Challenges 1 and 2 run | O1 in [BC-001] |
| Drawing logic separate from the window | O2 in [BC-001] |
| Source documented with Doxygen | O5 in [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-14 — the second milestone, after the foundation milestone of 2026-10-10 and before the plan ends on 2026-10-21 (Constraints in [BC-001]).
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Define the `Pen` protocol and window helpers | Add `pen.py` with a `Pen` protocol listing the turtle methods the challenges use, and helpers that create the `Screen` (color mode 255) and the `Turtle` named `tim`. The drawing functions take a `Pen`, so tests can pass a fake. The Doxygen comments also explain the import styles of the lecture (`import turtle`, `from turtle import Turtle`, `import turtle as t`) and why the wildcard import is avoided. | No | |
| 2 | Add a recording fake turtle for tests | Add a fake in `tests/` that implements the `Pen` protocol and records every call (move, turn, pen up, pen down, color), so tests assert on the drawing without a window. | No | |
| 3 | Implement draw_square | Implement `draw_square(pen, side_length)`: four times move forward by the side length (100) and turn right 90 degrees, using a `for` loop. The default side length is a constant in `constants.py`. | No | |
| 4 | Implement draw_dashed_line | Implement `draw_dashed_line(pen, dash_count, dash_length)`: for each dash put the pen down and move forward 10, then put the pen up and move forward 10 for the gap. The number of dashes (50) and the lengths are constants; see the open issue on 50 versus 15 in the Project Plan. | No | |
| 5 | Add tests for square and dashed line | Test both functions against the recording fake turtle: number of moves, lengths, turn angles, pen up and pen down order, and rejection of a non-positive length. | No | |
| 6 | Add the command line entry point | Add `cli.py` with `main(argv)` and `__main__.py` so that `python -m turtle_challenges <challenge>` creates the window, runs the named challenge and waits for a click. Register `square` and `dashed-line`; the choices are listed by `--help`. Declare the `turtle-challenges` command in `pyproject.toml`, since it points at `cli.py`. | No | |
| 7 | Review milestone 002 against QC-PY-001 | Review the code and tests against `QC-PY-001`, record the result as an `RC-*` and update the instance in the traceability matrix. | No | |
---
[BC-001]: ../business-case.md
@@ -0,0 +1,77 @@
# Milestone 003: Shapes and Random Color
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-003 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-07 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | pending |
---
## Purpose
This milestone decides whether Turtle Challenge 3 (draw different shapes, triangle to decagon, in random colors) works and whether the `random_color` helper from the tuple lecture is correct, because the random walk and the spirograph of the last milestone both depend on it.
## Deliverable
The `mil-003-shapes-and-random-color` branch, opened as one pull request, containing `random_color` (an red, green and blue (RGB) tuple), the color palette constant, `draw_shape`, `draw_shapes`, their tests, and the `shapes` challenge in the command line.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | `random_color` returns a tuple of three integers, each from 0 to 255 inclusive, and is repeatable with a seeded random generator | All three properties hold in tests | Any property fails |
| 2 | `draw_shape(pen, num_sides)` turns 360 / `num_sides` degrees after each of `num_sides` sides of 100 units | Recorded moves match for 3 to 10 sides | Any recorded move differs |
| 3 | `draw_shape` rejects fewer than 3 sides with `ValueError` | The error is raised | No error, or another exception type |
| 4 | `draw_shapes` draws the shapes with 3 to 10 sides, each in a color chosen from the palette in `constants.py` | Eight shapes, each with a palette color | Any shape missing or off palette |
| 5 | `python -m turtle_challenges shapes` opens a window and draws to completion on Windows PowerShell | S01 confirms in the review record | It fails |
| 6 | `python -m pytest`, `ruff check .`, `ruff format --check .`, `mypy` and `doxygen Doxyfile` | All exit 0 with 0 Doxygen warnings | Any fails or warns |
| 7 | Review record against `QC-PY-001` | Verdict Go | Go-with-conditions or No-Go |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-002 accepted | Needs the `Pen` protocol, the fake turtle and the command line entry point |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Challenge 3 and the `random_color` helper run | O1 in [BC-001] |
| Drawing logic separate from the window | O2 in [BC-001] |
| Source documented with Doxygen | O5 in [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-17 — the third milestone, leaving four days for the last milestone before the plan ends on 2026-10-21 (Constraints in [BC-001]).
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Implement random_color | Implement `random_color(rng)` in `colors.py`: three random integers from 0 to 255 returned as a tuple (immutable, so it is safe as a constant-like value). It accepts an optional `random.Random` so tests can seed it. The upper bound comes from `constants.py`. | No | |
| 2 | Add the color palette constant | Add the lecture's list of named colors to `constants.py` as a tuple (for example CornflowerBlue, DarkOrchid, IndianRed, DeepSkyBlue, LightSeaGreen, wheat, SlateGray, SeaGreen) and a helper that picks one with `random.choice`. | No | |
| 3 | Implement draw_shape | Implement `draw_shape(pen, num_sides, side_length)`: the turn angle is 360 divided by the number of sides, repeated for each side with a `for` loop. Fewer than 3 sides raises `ValueError`. | No | |
| 4 | Implement draw_shapes | Implement `draw_shapes(pen, rng)`: loop over 3 to 10 sides, choose a palette color for each shape and call `draw_shape`. The range bounds are constants. | No | |
| 5 | Add tests for random_color, draw_shape and draw_shapes | Test the tuple type and range of `random_color`, repeatability with a seed, the turn angle and side count for every shape from 3 to 10 sides, the `ValueError` for fewer than 3 sides, and the palette use of `draw_shapes`. | No | |
| 6 | Register the shapes challenge in the command line | Add `shapes` to the choices of `python -m turtle_challenges` and to the `--help` text, with a test of the argument parsing. | No | |
| 7 | Review milestone 003 against QC-PY-001 | Review the code and tests against `QC-PY-001`, record the result as an `RC-*` and update the instance in the traceability matrix. | No | |
---
[BC-001]: ../business-case.md
@@ -0,0 +1,80 @@
# Milestone 004: Random Walk and Spirograph
## Metadata
| Key | Value |
| --- | --- |
| ID | MIL-004 |
| CrossReference | [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-07 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | pending |
---
## Purpose
This milestone decides whether the last two challenges (Turtle Challenge 4, generate a random walk, and Turtle Challenge 5, draw a spirograph) work and whether the whole repository is ready to be shared: all five challenges run, the README is complete and checked from a fresh clone, and every success criterion of the Business Case is met.
## Deliverable
The `mil-004-random-walk-and-spirograph` branch, opened as one pull request, containing `random_walk`, `draw_spirograph`, their tests, the `random-walk` and `spirograph` challenges in the command line, and the final `README.md` with the Run section for all five challenges.
## Go / No-Go Criteria
| # | Criterion (objectively checkable) | Go | No-Go |
| --- | --- | --- | --- |
| 1 | `random_walk` takes the configured number of steps (200), each of the same distance, each in a heading from the north, east, south and west list, and each in an red, green and blue (RGB) color from `random_color` | Recorded moves match with a seeded generator | Any recorded move differs |
| 2 | `random_walk` sets the pen size and the speed from constants | Both are recorded before the first move | Either is missing |
| 3 | `draw_spirograph(pen, size_of_gap)` draws `int(360 / size_of_gap)` circles, each in an RGB color, turning the heading by the gap after each circle | Circle count, color and heading changes match | Any differs |
| 4 | `draw_spirograph` rejects a gap that is zero or negative with `ValueError` and never passes a float to `range` | The error is raised; a gap of 7 does not raise `TypeError` | A float reaches `range` |
| 5 | `python -m turtle_challenges random-walk` and `python -m turtle_challenges spirograph` open a window and draw to completion on Windows PowerShell | S01 confirms both in the review record | Either fails |
| 6 | Business Case success criteria 1 to 7 | Every criterion met, evidence in the review record | Any criterion not met |
| 7 | A fresh clone follows only the README (set-up, run, test, build the documentation) on Windows PowerShell | Every step works as written | A step fails or is missing |
| 8 | `python -m pytest`, `ruff check .`, `ruff format --check .`, `mypy` and `doxygen Doxyfile` | All exit 0 with 0 Doxygen warnings | Any fails or warns |
| 9 | Review record against `QC-PY-001` | Verdict Go | Go-with-conditions or No-Go |
## Dependencies
| Depends on | Reason |
| --- | --- |
| MIL-003 accepted | Needs `random_color` and the command line entry point |
## Traceability
| Business Case objective / KPI / user story | Reference |
| --- | --- |
| Challenges 4 and 5 run | O1 in [BC-001] |
| Set-up and run guide complete | O3 in [BC-001] |
| Repository ready to share | O6 in [BC-001] |
| Every pull request closes its issues | O7 in [BC-001] |
## Ownership
| Role | Stakeholder ID (SA) |
| --- | --- |
| Owner | S01 |
| Approving reviewer | S01 |
## Target Date
2026-10-21 — the last milestone, on the day the plan ends (Constraints in [BC-001]).
## Tasks
| # | Task | Summary | Needs its own Use Case/User Story? | Reference |
| --- | --- | --- | --- | --- |
| 1 | Implement random_walk | Implement `random_walk(pen, steps, distance, rng)`: set the pen size and speed, then for each of 200 steps choose a heading from the list of 0, 90, 180 and 270 degrees, give the line a `random_color` RGB value and move forward by a fixed distance. The directions are a tuple constant. | No | |
| 2 | Implement draw_spirograph | Implement `draw_spirograph(pen, size_of_gap, radius, rng)`: draw `int(360 / size_of_gap)` circles, each in a `random_color` RGB value, and after each circle set the heading to the current heading plus the gap. A zero or negative gap raises `ValueError`; the `int` conversion avoids the float error that `range` raises. | No | |
| 3 | Add tests for random_walk and draw_spirograph | Test the recorded moves of both functions with a seeded generator and the recording fake turtle: step count, distance, headings drawn from the list, RGB values in range, circle count, heading change and the `ValueError` for an invalid gap. | No | |
| 4 | Register random-walk and spirograph in the command line | Add `random-walk` and `spirograph` to the choices of `python -m turtle_challenges`, with a `--gap` option for the spirograph, and test the argument parsing. | No | |
| 5 | Complete the README Run section and verify it from a fresh clone | Document the command for each of the five challenges and the `--gap` option, then follow the README from an empty folder on Windows PowerShell and record the result. Debian and macOS steps are documented but not verified by S01; the README says so. | No | |
| 6 | Verify the Business Case success criteria | Check each of the seven success criteria of the Business Case, record the evidence (command output, repository page) in the review record, and update the Project Plan if a date moved. | No | |
| 7 | Review milestone 004 against QC-PY-001 | Review the code and tests against `QC-PY-001`, record the result as an `RC-*` and update the instance in the traceability matrix. | No | |
---
[BC-001]: ../business-case.md