Compare commits

...
Author SHA1 Message Date
Tirsvad f5a0434a98 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 52s
2026-10-13 16:41:09 +08:00
Tirsvad 5b948e5a66 Define the link targets cited in 18 review records
No issue closed: documentation housekeeping.
2026-10-13 16:41:05 +08:00
Tirsvad e44b9f7341 Merge pull request 'Define the SA-001 link in MIL-001, MIL-003 and MIL-004' (#44) from fix-sa-links into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 8s
2026-10-13 10:40:10 +02:00
Tirsvad e7e5c68ce0 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 53s
2026-10-13 16:39:53 +08:00
Tirsvad fa5bb84025 Define the SA-001 link in MIL-001, MIL-003 and MIL-004
No issue closed: documentation housekeeping.
2026-10-13 16:39:51 +08:00
Tirsvad 60af1e00ef Merge pull request 'Fix RC-033 scope and update the traceability matrix history' (#43) from fix-rc033-tm001 into main
Tests / Run the tests (push) Canceled after 46s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 7s
2026-10-13 10:38:35 +02:00
Tirsvad 5cb6665e4a Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 55s
2026-10-13 16:38:27 +08:00
Tirsvad c88434c583 Fix RC-033 scope and bring the traceability matrix history up to date
No issue closed: documentation housekeeping.
2026-10-13 16:38:26 +08:00
Tirsvad a9df555dd3 Merge pull request 'Add task 8 to MIL-001: lint steps in CI' (#42) from mil-001-task-8 into main
Tests / Run the tests (push) Successful in 59s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 9s
2026-10-13 10:36:03 +02:00
Tirsvad ed9897b4c1 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 55s
2026-10-13 16:35:54 +08:00
Tirsvad 78a0d02bf3 Add task 8 to MIL-001: lint steps in CI
Refs #39
2026-10-13 16:35:27 +08:00
Tirsvad 12d4beef7a Merge pull request 'Record RC-031 and RC-032: CI lint steps reviewed' (#40) from rc-ci-lint into main
Tests / Run the tests (push) Successful in 56s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 7s
2026-10-13 10:29:36 +02:00
Tirsvad da7efc1120 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 58s
2026-10-13 16:29:28 +08:00
Tirsvad e406d65f6a Record RC-031 and RC-032: CI lint steps reviewed
No issue closed: review records for #39.
2026-10-13 16:29:27 +08:00
Tirsvad 51e546e9f5 Merge pull request 'Run yamllint and actionlint in CI' (#39) from ci-lint-steps into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 7s
2026-10-13 10:29:21 +02:00
Tirsvad 16811c53fa Wrap the workflow header comment to the yamllint line limit
Tests / Run the tests (pull_request) Successful in 49s
2026-10-13 16:27:26 +08:00
Tirsvad 7c2604108c Run yamllint and actionlint in CI
Tests / Run the tests (pull_request) Canceled after 0s
No issue closed: CI change requested by S01.
2026-10-13 16:27:09 +08:00
Tirsvad 9b063bf58f Merge pull request 'Add yamllint and actionlint to the dev extra' (#38) from dev-lint-tools into main
Tests / Run the tests (push) Successful in 50s
TirSystem/github-action: Publish wiki / publish-wiki (push) Successful in 7s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 10:26:07 +02:00
Tirsvad fbf73fc6d7 Add yamllint and actionlint to the dev extra
Tests / Run the tests (pull_request) Successful in 50s
No issue closed: dev tooling change requested by S01.
2026-10-13 16:24:31 +08:00
Tirsvad 0bbf4c22d4 Merge pull request 'Close the conditions of RC-007 and RC-010 in their Version History' (#37) from rc-history-rows into main
Tests / Run the tests (push) Successful in 44s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 10:22:31 +02:00
Tirsvad 10d8a6de3d Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 45s
2026-10-13 16:22:22 +08:00
Tirsvad 40c3387ea7 Close the conditions of RC-007 and RC-010 in their Version History
No issue closed: documentation housekeeping.
2026-10-13 16:22:21 +08:00
Tirsvad 89683f9c75 Merge pull request 'Add Version History row to the traceability matrix' (#36) from tm-version-history into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 10:21:41 +02:00
Tirsvad 64511c9fef Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 52s
2026-10-13 16:21:33 +08:00
Tirsvad dfaa8400c3 Add Version History row to the traceability matrix
No issue closed: documentation housekeeping.
2026-10-13 16:21:32 +08:00
Tirsvad 8f73cd8cba Merge pull request 'Add static workflow test for ci.yml' (#35) from mil-001-workflow-test into main
Tests / Run the tests (push) Successful in 43s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:59:42 +02:00
Tirsvad 329cc1484c Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 44s
2026-10-13 15:59:35 +08:00
Tirsvad 7202aac595 Add static workflow test for ci.yml
Closes #34

Task: MIL-001#7
2026-10-13 15:59:25 +08:00
Tirsvad 6fb75ddb86 Add task 7 to MIL-001: static workflow test
Refs #6
2026-10-13 15:57:31 +08:00
Tirsvad b52a739649 Merge pull request 'Correct wiki folder references to wiki/' (#33) from fix-wiki-path-refs into main
Tests / Run the tests (push) Successful in 40s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:56:37 +02:00
Tirsvad d3d2d03cd5 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 41s
2026-10-13 15:56:21 +08:00
Tirsvad d85cfe5c4b Correct the wiki folder references to wiki/
No issue closed: documentation correction only.
2026-10-13 15:56:19 +08:00
Tirsvad 1b217785c6 Merge pull request 'RC-025: CI workflow verified on the instance' (#32) from ci-verified into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:52:43 +02:00
Tirsvad d2f36bfde3 Record RC-025: CI workflow verified on the instance
Tests / Run the tests (pull_request) Successful in 42s
No issue closed: the workflow task #6 was closed by an earlier pull request.
2026-10-13 15:52:36 +08:00
Tirsvad c4e88c6da6 Merge pull request 'Move wiki sources to wiki/' (#31) from fix-wiki-location into main
Tests / Run the tests (push) Successful in 42s
TirSystem/github-action: Publish wiki / publish-wiki (push) Successful in 5s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:44:06 +02:00
Tirsvad 632fa61b89 Move the wiki sources to wiki/ and tidy version history statuses
Tests / Run the tests (pull_request) Successful in 42s
No issue closed: all issues of MIL-001 to MIL-004 are closed.
2026-10-13 15:43:56 +08:00
Tirsvad d825bef0f1 Merge pull request 'MIL-004 Wiki in English, Danish and Bahasa Malaysia' (#30) from mil-004-wiki-publication into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:42:38 +02:00
Tirsvad 9e41ae87b9 Add the wiki sources in English, Danish and Bahasa Malaysia
Tests / Run the tests (pull_request) Successful in 41s
Closes #21
Closes #22
Closes #23
Closes #24
2026-10-13 15:42:30 +08:00
Tirsvad 57e12637f0 Merge pull request 'Fix Doxygen warnings' (#29) from fix-doxygen-warnings into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:41:23 +02:00
Tirsvad b0132498ba Fix Doxygen warnings: document the source only, with a main page
Tests / Run the tests (pull_request) Successful in 40s
Refs #17
2026-10-13 15:41:11 +08:00
Tirsvad 933f71eb39 Merge pull request 'MIL-003 README, source documentation and screenshots' (#28) from mil-003-documentation into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 6s
2026-10-13 09:40:24 +02:00
Tirsvad 0e73d7d0d0 Add README with set up, run, test, CI, documentation build and screenshots
Tests / Run the tests (pull_request) Successful in 41s
Closes #17
Closes #18
Closes #19
Closes #20
2026-10-13 15:40:16 +08:00
Tirsvad 4751b6a5f8 Merge pull request 'MIL-002 Squirrel census analysis' (#27) from mil-002-census-analysis into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
2026-10-13 09:38:24 +02:00
Tirsvad 2916b0efb0 Resolve pending commit links
Tests / Run the tests (pull_request) Successful in 43s
2026-10-13 15:38:09 +08:00
Tirsvad ba27a97cfd Add the 2018 census file and the generated squirrel_count.csv
Closes #16
2026-10-13 15:37:57 +08:00
Tirsvad 7459711243 Implement census analysis: read, count, summarise, write and CLI
Closes #11
Closes #12
Closes #13
Closes #14
Closes #15

Task: MIL-002#4
Task: MIL-002#5
Task: MIL-002#6
Task: MIL-002#7
Task: MIL-002#8
2026-10-13 15:37:51 +08:00
Tirsvad 259d017ad2 Add use case model, ADR-0001, dictionary update and reviews RC-011 to RC-023
Refs #8
Refs #9
Refs #10
2026-10-13 15:37:50 +08:00
Tirsvad ca084c65a0 Merge pull request 'MIL-001 Project scaffold and tooling' (#26) from mil-001-project-scaffold into main
Tests / Run the tests (push) Canceled after 0s
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 7s
2026-10-13 09:33:07 +02:00
77 changed files with 6523 additions and 325 deletions
+11 -4
View File
@@ -1,7 +1,8 @@
# Continuous integration for the squirrel census project: runs the pytest tests # Continuous integration for the squirrel census project: lints the YAML and
# on Python 3.13 for every push and pull request. Read by Gitea Actions (a # workflow files and runs the pytest tests on Python 3.13 for every push and
# runner must be registered for the repository). It changes nothing outside the # pull request. Read by Gitea Actions (a runner must be registered for the
# repository and uses no secret. Decision: MIL-001 task "Add CI workflow". # repository). It changes nothing outside the repository and uses no secret.
# Decision: MIL-001 task "Add CI workflow".
# Host: Gitea Actions; uses only github.* contexts, so it also runs on GitHub. # Host: Gitea Actions; uses only github.* contexts, so it also runs on GitHub.
name: Tests name: Tests
@@ -42,5 +43,11 @@ jobs:
.venv/bin/python -m pip install --upgrade "pip==${PIP_VERSION}" .venv/bin/python -m pip install --upgrade "pip==${PIP_VERSION}"
.venv/bin/python -m pip install -e ".[dev]" .venv/bin/python -m pip install -e ".[dev]"
- name: Lint the YAML files
run: .venv/bin/python -m yamllint -c .yamllint.yml .gitea .yamllint.yml
- name: Lint the workflow files
run: .venv/bin/actionlint .gitea/workflows/*.yml
- name: Run the tests - name: Run the tests
run: .venv/bin/python -m pytest run: .venv/bin/python -m pytest
+3
View File
@@ -6,3 +6,6 @@ rules:
max: 100 max: 100
truthy: truthy:
check-keys: false check-keys: false
# Line endings are normalised by git (LF in the repository, CRLF in some
# Windows checkouts), so the rule would fail on a local checkout only.
new-lines: disable
+2 -3
View File
@@ -7,10 +7,9 @@ PROJECT_NAME = "Squirrel Census"
PROJECT_BRIEF = "Count squirrels by primary fur colour" PROJECT_BRIEF = "Count squirrels by primary fur colour"
PROJECT_NUMBER = 0.1.0 PROJECT_NUMBER = 0.1.0
OUTPUT_DIRECTORY = docs/doxygen OUTPUT_DIRECTORY = docs/doxygen
INPUT = src README.md INPUT = src docs/mainpage.dox
FILE_PATTERNS = *.py *.md FILE_PATTERNS = *.py *.dox
RECURSIVE = YES RECURSIVE = YES
USE_MDFILE_AS_MAINPAGE = README.md
OPTIMIZE_OUTPUT_JAVA = YES OPTIMIZE_OUTPUT_JAVA = YES
EXTRACT_ALL = YES EXTRACT_ALL = YES
GENERATE_HTML = YES GENERATE_HTML = YES
+142 -1
View File
@@ -1,2 +1,143 @@
# 025-squirrel # Squirrel Census
Day 25 of Udemy's *100 Days of Code: The Complete Python Pro Bootcamp*: count the
squirrels of the 2018 Central Park Squirrel Census by primary fur colour (gray,
cinnamon, black) and export the counts to `squirrel_count.csv`. Python 3.13 or
later, no runtime dependencies, with tests and source documentation.
![Program run][img-run]
## Requirements
- Python 3.13 or later (`python --version` on Windows, `python3 --version` on Linux and macOS).
- `venv`, which ships with Python (on Debian: the `python3-venv` package).
- The 2018 census file. It is already in the repository under `data/`.
- Optional: [Doxygen][doxygen] 1.9 or later, only to build the source documentation.
There are no runtime dependencies: the program uses only the Python standard library
([ADR-0001][adr-0001]). `pytest` is needed only to run the tests.
## Set up
Create a local virtual environment named `.venv` in the project folder, upgrade `pip`
and install the project with its development tools (pytest, ruff, mypy, yamllint, actionlint).
### Windows powershell
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
If PowerShell refuses to run the activation script, allow it for the current session:
`Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned`.
### Linux debian
```bash
sudo apt install python3 python3-venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
### MacOS
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
On macOS, Python 3.13 can be installed with `brew install python@3.13`.
## Run
With the virtual environment active, run from the project folder:
```bash
python -m squirrel
```
The program reads `data/2018_Central_Park_Squirrel_Census_-_Squirrel_Data.csv`, prints
the colour counts and writes `squirrel_count.csv`:
```text
Gray: 2473
Cinnamon: 392
Black: 103
```
Use other files by passing them as arguments, `python -m squirrel <census file> <summary file>`.
If the census file does not exist the program prints a message and exits with status 2.
## Run the tests
```bash
python -m pytest
```
![Test run][img-tests]
The tests use small fixture rows; one test also checks the real 2018 census file when
it is present.
## Continuous integration
The workflow [`.gitea/workflows/ci.yml`][ci] runs for every push to `main` and for every
pull request. It sets up Python 3.13, creates a `.venv`, upgrades `pip`, installs the
project with `.[dev]`, lints the YAML and workflow files with `yamllint` and
`actionlint`, and runs `python -m pytest`. It uses `github.*` contexts only, so
it also runs on GitHub Actions.
## Build the source documentation
The source is documented with Doxygen comments and configured by [`Doxyfile`][doxyfile].
```bash
doxygen Doxyfile
```
Open `docs/doxygen/html/index.html` in a browser. The output folder is ignored by git.
## Project layout
```text
.gitea/workflows/ci.yml continuous integration workflow
data/ the 2018 census file
docs/ business case, plan, milestones, models, reviews, ADRs
docs/images/ screenshots used by this README and the wiki
src/squirrel/ the package: census.py, cli.py, constants.py
tests/ pytest tests
wiki/ wiki pages in English, Danish (.da) and Bahasa Malaysia (.ms)
Doxyfile Doxygen configuration
pyproject.toml project configuration (Python >=3.13, no runtime dependencies)
squirrel_count.csv the result of the assignment
```
The project documents, in reading order: [Business Case][bc], [Stakeholder
Analysis][sa], [Project Plan][pp], [Use Case][uc], [Domain Model][dm], [ADR-0001][adr-0001].
The repository also has a wiki in English, Danish and Bahasa Malaysia.
## License
GNU Affero General Public License v3.0 or later. See [LICENSE][license].
---
[img-run]: docs/images/run.png
[img-tests]: docs/images/tests.png
[doxygen]: https://www.doxygen.nl/
[adr-0001]: docs/adr/adr-0001-standard-library-instead-of-pandas.md
[ci]: .gitea/workflows/ci.yml
[doxyfile]: Doxyfile
[bc]: docs/business-case.md
[sa]: docs/stakeholder-analysis.md
[pp]: docs/project-plan.md
[uc]: docs/uc-001/uc.md
[dm]: docs/domain-model.md
[license]: LICENSE
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,56 @@
# ADR-0001 Use the standard library instead of Pandas
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0001 |
| CrossReference | [BC-001], [SA-001], [MIL-002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
The day 25 lecture reads the census with `pandas.read_csv`, filters rows by fur colour and builds a DataFrame for the export. The Business Case sets a success criterion of zero third-party runtime packages ([BC-001], criterion 3), and stakeholder S03 wants a repository with no runtime dependencies ([SA-001]). Stakeholder S02 wants the function names of the assignment.
Options evaluated:
1. **Pandas** — closest to the lecture; adds a large runtime dependency (with NumPy) that every visitor must install.
2. **Standard library** — the `csv` module to read and write and `collections.Counter` to count; no runtime dependency, a few more lines than Pandas.
3. **Pandas as an optional extra** — two code paths for one result; more code to test and explain.
## Decision
Use the standard library (`csv` and `collections.Counter`) for reading, counting and writing, and keep the lecture's step names (`read_csv`, `count_by_fur_color`, `build_summary`, `write_csv`) as public function names.
## Consequences
**Positive:**
- The project has no runtime dependency; `pip install .` installs only the package ([BC-001] criterion 3).
- Setup is the same on Windows PowerShell, Linux Debian and macOS, with no compiled wheels.
- The code is short enough to read in one sitting (S02).
**Negative:**
- The code differs from the lecture's Pandas calls, so a participant comparing line by line sees different statements.
- A later assignment that needs DataFrame features must introduce Pandas then.
## Affected Artifacts
- [BC-001] — meets success criterion 3 and mitigates the Pandas risk.
- [SA-001] — resolves the conflict between S01's lecture and S03's expectation.
- [MIL-002] — the tasks "Read the census file" to "Add the command line entry point" implement it.
---
[BC-001]: ../business-case.md
[SA-001]: ../stakeholder-analysis.md
[MIL-002]: ../milestones/mil-002-census-analysis.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+7 -2
View File
@@ -15,10 +15,15 @@ document of a type. `Primary File` may contain a glob (e.g.
| SA | Stakeholder Analysis | docs/stakeholder-analysis.md | 002 | | SA | Stakeholder Analysis | docs/stakeholder-analysis.md | 002 |
| PP | Project Plan | docs/project-plan.md | 002 | | PP | Project Plan | docs/project-plan.md | 002 |
| MIL | Milestone / Gateway | docs/milestones/*.md | 005 | | MIL | Milestone / Gateway | docs/milestones/*.md | 005 |
| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0001 | | ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0002 |
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 011 | | RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 037 |
| DICT | Domain Dictionary | docs/dictionary.md | 002 | | DICT | Domain Dictionary | docs/dictionary.md | 002 |
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 | | TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
| UCD | Use Case Diagram | docs/use-case-diagram.md | 002 |
| US | User Story | docs/user-stories.md | 002 |
| UC | Use Case | docs/uc-*/uc.md | 002 |
| DM | Domain Model | docs/domain-model.md | 003 |
| SSD | System Sequence Diagram | docs/uc-*/ssd.md | 002 |
## Languages ## Languages
+6 -4
View File
@@ -11,8 +11,8 @@
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | CrossReference: added [UCD-001] | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Corrected the wiki folder `docs/wiki/` to `wiki/` | [d85cfe5] |
--- ---
## Executive Summary ## Executive Summary
@@ -91,7 +91,7 @@ The project supports the participant's goal of finishing the 100 Days of Code bo
| The lecture uses Pandas but the repository must have no runtime dependencies | The solution differs from the lecture code | Use the standard library `csv` module; record the decision in an architecture decision record (ADR) and keep the lecture's step names as function names | | The lecture uses Pandas but the repository must have no runtime dependencies | The solution differs from the lecture code | Use the standard library `csv` module; record the decision in an architecture decision record (ADR) and keep the lecture's step names as function names |
| The census file is large and not part of the repository | Others cannot run the program | Keep the census file under `data/` and let the program accept a path argument | | The census file is large and not part of the repository | Others cannot run the program | Keep the census file under `data/` and let the program accept a path argument |
| Tokens in `.env` leak into the repository | Credential exposure | `.env` is git-ignored, never read by the project and never printed | | Tokens in `.env` leak into the repository | Credential exposure | `.env` is git-ignored, never read by the project and never printed |
| Wiki push is not available on the host | Wiki pages are not published | Keep the pages in the repository under `docs/wiki/` and report the failure | | Wiki push is not available on the host | Wiki pages are not published | Keep the pages in the repository under `wiki/` and report the failure |
| Fur colour spelling differs in the data | Wrong counts | Count exact values `Gray`, `Cinnamon`, `Black` and test with fixture rows | | Fur colour spelling differs in the data | Wrong counts | Count exact values `Gray`, `Cinnamon`, `Black` and test with fixture rows |
## Assumptions ## Assumptions
@@ -133,4 +133,6 @@ Proceed — the scope is small, the risks are mitigated and the result is direct
--- ---
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [UCD-001]: ./use-case-diagram.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[d85cfe5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d85cfe5c4b62b2e1759f1c47b25bdb787ba6fd68
+7 -4
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | DICT-001 | | ID | DICT-001 |
| CrossReference | [BC-001], [SA-001] | | CrossReference | [BC-001], [SA-001], [DM-002] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | CrossReference: added [DM-002] | [259d017] |
--- ---
## Purpose and Scope ## Purpose and Scope
@@ -27,7 +27,8 @@ Maps each Product Owner (PO) term of the squirrel census project to its professi
| Squirrel sighting | en | sighting row | One recorded observation of one squirrel in the census file. | BC, MIL, US, UC, DM | SSD, source code | | Squirrel sighting | en | sighting row | One recorded observation of one squirrel in the census file. | BC, MIL, US, UC, DM | SSD, source code |
| Fur colour | en | fur_color | The primary fur colour of a squirrel: Gray, Cinnamon or Black. | BC, SA, MIL, US, UC, DM | SSD, source code | | Fur colour | en | fur_color | The primary fur colour of a squirrel: Gray, Cinnamon or Black. | BC, SA, MIL, US, UC, DM | SSD, source code |
| Colour count | en | color_count | The number of squirrel sightings with one fur colour. | BC, MIL, US, UC, DM | SSD, source code | | Colour count | en | color_count | The number of squirrel sightings with one fur colour. | BC, MIL, US, UC, DM | SSD, source code |
| Summary | en | summary table | The table of fur colours and their counts that is exported as `squirrel_count.csv`. | BC, MIL, US, UC, DM | SSD, source code | | Summary | en | summary table | The table of fur colours and their counts. | BC, MIL, US, UC, DM | SSD, source code |
| Summary file | en | output file | The file the summary is written to. | BC, MIL, US, UC, DM | SSD, source code |
| Participant | en | command line user | The course participant who runs the program on the census file. | BC, SA, US, UC | SSD | | Participant | en | command line user | The course participant who runs the program on the census file. | BC, SA, US, UC | SSD |
## Rules ## Rules
@@ -42,3 +43,5 @@ Maps each Product Owner (PO) term of the squirrel census project to its professi
[BC-001]: ./business-case.md [BC-001]: ./business-case.md
[SA-001]: ./stakeholder-analysis.md [SA-001]: ./stakeholder-analysis.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3
[DM-002]: ./domain-model.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+87
View File
@@ -0,0 +1,87 @@
# Domain Model
## Metadata
| Key | Value |
| --- | --- |
| ID | DM-002 |
| CrossReference | [UC-001], [UCD-001], [SSD-001], [DICT-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Purpose and Scope
Covers: [UC-001] Count squirrels by fur colour.
## Diagram
Concepts, attributes and associations only — no operations.
```plantuml
@startuml
class Participant
class "Census file" as CF {
name
}
class "Squirrel sighting" as SS
class "Fur colour" as FC {
name
}
class "Colour count" as CC {
number of sightings
}
class Summary
class "Summary file" as SF {
name
}
Participant "1" --> "1" CF : supplies
CF "1" --> "0..*" SS : contains
SS "0..*" --> "0..1" FC : has
CC "0..*" --> "1" FC : counts sightings of
Summary "1" --> "3" CC : consists of
Summary "1" --> "1" SF : is written to
Participant "1" --> "0..*" Summary : receives
@enduml
```
## Concept Table
| Concept | Definition | Attributes | Source (use case / glossary) |
| --- | --- | --- | --- |
| Participant | The course participant who runs the program | - | [UC-001] primary actor |
| Census file | The file with the 2018 squirrel census | name | [UC-001] step 1, [DICT-001] |
| Squirrel sighting | One recorded observation of one squirrel | - | [UC-001] step 2, [DICT-001] |
| Fur colour | The primary fur colour of a squirrel: Gray, Cinnamon or Black | name | [UC-001] step 2, [DICT-001] |
| Colour count | The number of sightings with one fur colour | number of sightings | [UC-001] step 4, [DICT-001] |
| Summary | The table of colour counts | - | [UC-001] step 3, [DICT-001] |
| Summary file | The file the summary is written to | name | [UC-001] step 1, [DICT-001] |
## Association Table
| From | Association (reading direction) | To | Multiplicity |
| --- | --- | --- | --- |
| Participant | supplies | Census file | 1 to 1 |
| Census file | contains | Squirrel sighting | 1 to 0..* |
| Squirrel sighting | has | Fur colour | 0..* to 0..1 |
| Colour count | counts sightings of | Fur colour | 0..* to 1 |
| Summary | consists of | Colour count | 1 to 3 |
| Summary | is written to | Summary file | 1 to 1 |
| Participant | receives | Summary | 1 to 0..* |
## Generalizations
None.
---
[UC-001]: ./uc-001/uc.md
[UCD-001]: ./use-case-diagram.md
[SSD-001]: ./uc-001/ssd.md
[DICT-001]: ./dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+13
View File
@@ -0,0 +1,13 @@
/**
@mainpage Squirrel Census
Count the squirrels of the 2018 Central Park Squirrel Census by primary fur colour
(Gray, Cinnamon, Black) and export the counts to `squirrel_count.csv`.
The steps follow the Udemy "100 Days of Code" lecture of day 25: squirrel.census.read_csv,
squirrel.census.count_by_fur_color, squirrel.census.build_summary and
squirrel.census.write_csv. The command line entry point is squirrel.cli.main, started
with `python -m squirrel`. Every literal is defined once in squirrel.constants.
The package uses only the Python standard library.
*/
+9 -4
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | MIL-001 | | ID | MIL-001 |
| CrossReference | [BC-001] | | CrossReference | [BC-001], [US-001], [SA-001] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Added task 8: lint steps in CI (recorded after the work) | [78a0d02] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Added the missing link definition and CrossReference for [SA-001] | [fa5bb84] |
--- ---
## Purpose ## Purpose
@@ -67,8 +67,13 @@ A branch merged to `main` containing `.gitignore`, `pyproject.toml`, `src/squirr
| 4 | Add Doxyfile | Create a `Doxyfile` that reads `src/` and writes to `docs/doxygen/`, with Python optimisation enabled, so the source documentation can be built with `doxygen Doxyfile`. | No | | | 4 | Add Doxyfile | Create a `Doxyfile` that reads `src/` and writes to `docs/doxygen/`, with Python optimisation enabled, so the source documentation can be built with `doxygen Doxyfile`. | No | |
| 5 | Add CI workflow | Add a Gitea Actions workflow that sets up Python 3.13, creates a venv, upgrades pip, installs the dev extra and runs pytest on push and pull request. It backs the "Continuous integration" section of the README. | No | | | 5 | Add CI workflow | Add a Gitea Actions workflow that sets up Python 3.13, creates a venv, upgrades pip, installs the dev extra and runs pytest on push and pull request. It backs the "Continuous integration" section of the README. | No | |
| 6 | Set repository description and topics | Use the Gitea API with the token from `.env` (read by the shell only, never by the project) to set a description and topics such as `python`, `csv`, `squirrel-census`, `udemy`, `100-days-of-code`, `pytest`. Satisfies stakeholder S03. | No | | | 6 | Set repository description and topics | Use the Gitea API with the token from `.env` (read by the shell only, never by the project) to set a description and topics such as `python`, `csv`, `squirrel-census`, `udemy`, `100-days-of-code`, `pytest`. Satisfies stakeholder S03. | No | |
| 7 | Add static workflow test | Add `tests/test_workflow.py`, run by pytest on every pull request, that parses `.gitea/workflows/ci.yml` with a safe YAML loader and checks the required keys, explicit permissions, runner and timeout, named steps, exact-tag action pins and the five-line limit on `run:` blocks. Closes criterion 24 (optional) of the workflow review RC-010. | No | RC-010 |
| 8 | Run yamllint and actionlint in CI | Add two steps to `.gitea/workflows/ci.yml` that run `yamllint` on `.gitea` and `.yamllint.yml` and `actionlint` on the workflow files, after the dev extra is installed, so a malformed workflow fails the pull request. Done in pull request 39 at the request of S01 and recorded here afterwards; reviewed in RC-031 and RC-032. | No | RC-031, RC-032 |
--- ---
[BC-001]: ../business-case.md [BC-001]: ../business-case.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [US-001]: ../user-stories.md
[78a0d02]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/78a0d02bf373b92163f45d93449dd1009b62e568
[SA-001]: ../stakeholder-analysis.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
+5 -3
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | MIL-002 | | ID | MIL-002 |
| CrossReference | [BC-001] | | CrossReference | [BC-001], [US-001] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | CrossReference: added [US-001] | [259d017] |
--- ---
## Purpose ## Purpose
@@ -74,3 +74,5 @@ A branch merged to `main` containing the user story, use case, system sequence d
[BC-001]: ../business-case.md [BC-001]: ../business-case.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3
[US-001]: ../user-stories.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+7 -4
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | MIL-003 | | ID | MIL-003 |
| CrossReference | [BC-001] | | CrossReference | [BC-001], [US-001], [SA-001] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | CrossReference: added [US-001] | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Added the missing link definition and CrossReference for [SA-001] | [fa5bb84] |
--- ---
## Purpose ## Purpose
@@ -69,4 +69,7 @@ A branch merged to `main` containing `README.md` with the requested sections, Do
--- ---
[BC-001]: ../business-case.md [BC-001]: ../business-case.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [US-001]: ../user-stories.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[SA-001]: ../stakeholder-analysis.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
+8 -5
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | MIL-004 | | ID | MIL-004 |
| CrossReference | [BC-001] | | CrossReference | [BC-001], [US-001], [SA-001] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Corrected the wiki folder `docs/wiki/` to `wiki/` | [d85cfe5] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Added the missing link definition and CrossReference for [SA-001] | [fa5bb84] |
--- ---
## Purpose ## Purpose
@@ -29,7 +29,7 @@ Wiki pages `Home`, `Install`, `Usage` and `Description` in English plus `-da` an
| --- | --- | --- | --- | | --- | --- | --- | --- |
| 1 | Each wiki page exists in English, Danish (`-da`) and Bahasa Malaysia (`-ms`) | All present | Any missing | | 1 | Each wiki page exists in English, Danish (`-da`) and Bahasa Malaysia (`-ms`) | All present | Any missing |
| 2 | The sidebar links every page in all three languages | All linked | Missing link | | 2 | The sidebar links every page in all three languages | All linked | Missing link |
| 3 | Wiki pages are on the git host wiki, or kept under `docs/wiki/` with the failure reported | Published or reported | Neither | | 3 | Wiki pages are on the git host wiki, or kept under `wiki/` with the failure reported | Published or reported | Neither |
| 4 | Screenshots appear on the wiki pages | Present | Missing | | 4 | Screenshots appear on the wiki pages | Present | Missing |
## Dependencies ## Dependencies
@@ -69,4 +69,7 @@ Wiki pages `Home`, `Install`, `Usage` and `Description` in English plus `-da` an
--- ---
[BC-001]: ../business-case.md [BC-001]: ../business-case.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [US-001]: ../user-stories.md
[d85cfe5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d85cfe5c4b62b2e1759f1c47b25bdb787ba6fd68
[SA-001]: ../stakeholder-analysis.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
+7 -5
View File
@@ -4,15 +4,15 @@
| Key | Value | | Key | Value |
| --- | --- | | --- | --- |
| ID | PP-001 | | ID | PP-001 |
| CrossReference | [BC-001], [SA-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004] | | CrossReference | [BC-001], [SA-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004], [US-001] |
| Language | en | | Language | en |
| Domain | it | | Domain | it |
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | CrossReference: added [US-001] | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Corrected the wiki folder `docs/wiki/` to `wiki/` | [d85cfe5] |
--- ---
## Purpose ## Purpose
@@ -75,7 +75,7 @@ A No-Go at a gateway stops the later gateways; their dates move by the days the
| Risk | Impact | Mitigation | | Risk | Impact | Mitigation |
| --- | --- | --- | | --- | --- | --- |
| CI runner is not available on the git host | The CI workflow cannot be shown green | Run the same commands locally and report the missing runner | | CI runner is not available on the git host | The CI workflow cannot be shown green | Run the same commands locally and report the missing runner |
| Wiki repository cannot be pushed | G4 deliverable is not published | Keep the pages under `docs/wiki/` and report it | | Wiki repository cannot be pushed | G4 deliverable is not published | Keep the pages under `wiki/` and report it |
| Doxygen is not installed locally | The documentation build cannot be verified | Report as not verified; document the command | | Doxygen is not installed locally | The documentation build cannot be verified | Report as not verified; document the command |
## Open Issues ## Open Issues
@@ -92,8 +92,10 @@ A No-Go at a gateway stops the later gateways; their dates move by the days the
[MIL-002]: ./milestones/mil-002-census-analysis.md [MIL-002]: ./milestones/mil-002-census-analysis.md
[MIL-003]: ./milestones/mil-003-documentation.md [MIL-003]: ./milestones/mil-003-documentation.md
[MIL-004]: ./milestones/mil-004-wiki-publication.md [MIL-004]: ./milestones/mil-004-wiki-publication.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3
[MS-124]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/124 [MS-124]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/124
[MS-125]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/125 [MS-125]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/125
[MS-126]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/126 [MS-126]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/126
[MS-127]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/127 [MS-127]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/milestone/127
[US-001]: ./user-stories.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[d85cfe5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d85cfe5c4b62b2e1759f1c47b25bdb787ba6fd68
+3 -1
View File
@@ -9,7 +9,8 @@
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Action item closed: criteria 3 and 4 re-reviewed in RC-018 (Go) | [40c3387] |
--- ---
@@ -65,3 +66,4 @@ Go-with-conditions — criteria 3 and 4 cannot be checked until DM-001 and the d
[QC-DICT-001]: ../../../framework/qc/artifacts/qc-dictionary.md [QC-DICT-001]: ../../../framework/qc/artifacts/qc-dictionary.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md [QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3
[40c3387]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/40c3387ea7a4b601e8d20a5a7b6eba20c3d5323d
+5 -2
View File
@@ -9,7 +9,8 @@
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Proposed | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [d71b586] | | 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Action items closed: criterion 22 by RC-025 (Go), criterion 24 by RC-030 (Go) | [40c3387] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
--- ---
@@ -66,4 +67,6 @@ Go-with-conditions — all Mandatory criteria pass except 22: the workflow has n
[WF-MIL-001]: ../../../.gitea/workflows/ci.yml [WF-MIL-001]: ../../../.gitea/workflows/ci.yml
[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md [QC-WF-001]: ../../../framework/qc/code/qc-workflow.md
[d71b586]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d71b5863eba3dc29c5a5e09e4ffa087c67565fae [40c3387]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/40c3387ea7a4b601e8d20a5a7b6eba20c3d5323d
[QC-YML-001]: ../../../framework/qc/code/qc-yaml.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
@@ -0,0 +1,74 @@
# RC-011 Review of UCD-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-011 |
| CrossReference | [UCD-001], [QC-UCD-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [UCD-001]
- Checklist used: [QC-UCD-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Actors are defined with correct UML stereotypes (e.g. `<<System>>`, `<<Actor>>`) (Mandatory) | Pass | Participant is <<Actor>> and Squirrel Census Program is <<System>> in the Actor Table. |
| 2 | System boundary is clearly drawn and labeled (Mandatory) | Pass | The diagram draws the labelled rectangle "Squirrel Census Program". |
| 3 | Include/extend relationships are used correctly per UML 2.5.1, not as generic "uses" arrows (Mandatory) | Pass | No include or extend relationship is used; the Relationships table says why. |
| 4 | Every actor participates in at least one use case (no orphan actors) (Mandatory) | Pass | The Participant takes part in the only use case. |
| 5 | Diagram is traceable to a documented stakeholder need (Mandatory) | Pass | The actor table traces the Participant to S01 and S02 of [SA-001]. |
| 6 | Use case names are verb phrases describing actor goals, not internal system operations (Mandatory) | Pass | The use case "Count squirrels by fur colour" is a verb phrase of the actor goal. |
| 7 | Diagram is free of implementation detail (e.g. UI widgets, database tables) (Optional) | Pass | No UI or storage detail. |
| 8 | Actor and use case naming is consistent with corresponding Use Case and User Story documents (Optional) | Pass | Names match [UC-001] and [US-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The use case diagram is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: actors, stereotypes and goals. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[UCD-001]: ../../use-case-diagram.md
[QC-UCD-001]: ../../../framework/qc/artifacts/qc-use-case-diagram.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[SA-001]: ../../stakeholder-analysis.md
[UC-001]: ../../uc-001/uc.md
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+73
View File
@@ -0,0 +1,73 @@
# RC-012 Review of US-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-012 |
| CrossReference | [US-001], [QC-US-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [US-001]
- Checklist used: [QC-US-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Follows INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) (Mandatory) | Pass | INVEST check line states each property; one story, no exceptions. |
| 2 | Written in "As a / I want / So that" form (Mandatory) | Pass | US-001.01 uses "As a / I want / so that". |
| 3 | Clear, testable acceptance criteria are included (Mandatory) | Pass | Four Given/When/Then criteria, including the figures 2473, 392 and 103. |
| 4 | Traceable to a use case or epic (Mandatory) | Pass | Traces to [UC-001] and [MIL-002]. |
| 5 | Story is sized to fit within a single iteration (Optional) | Pass | Fits one iteration. |
| 6 | Story statement avoids technical implementation detail (Optional) | Pass | The story names no technology. |
| 7 | Role named in the story matches an actor defined in the Use Case Diagram (Mandatory) | Pass | Role "Participant" is the actor of [UCD-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The user story is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: story form and acceptance criteria. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[US-001]: ../../user-stories.md
[QC-US-001]: ../../../framework/qc/artifacts/qc-user-story.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[MIL-002]: ../../milestones/mil-002-census-analysis.md
[UC-001]: ../../uc-001/uc.md
[UCD-001]: ../../use-case-diagram.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+77
View File
@@ -0,0 +1,77 @@
# RC-013 Review of UC-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-013 |
| CrossReference | [UC-001], [QC-UC-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [UC-001]
- Checklist used: [QC-UC-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Consists of a single, concise paragraph summarizing only the primary success scenario (Mandatory) | N-A | The format is Fully Dressed, not Brief. |
| 2 | Written as an informal multi-paragraph narrative; may mention some alternate flows without formal structure (Mandatory) | N-A | The format is Fully Dressed, not Casual. |
| 3 | All standard sections are present: actors, preconditions, postconditions, main success scenario, alternative/exception flows (Mandatory) | Pass | Scope, level, primary actor, stakeholders, pre- and postconditions, main scenario, extensions, business rules and open issues are present. |
| 4 | Preconditions and postconditions are explicitly defined (Mandatory) | Pass | Preconditions and postconditions are stated. |
| 5 | Primary actor is explicitly stated (Mandatory) | Pass | Primary actor is Participant. |
| 6 | Stakeholders and their interests are stated (Mandatory) | Pass | S01, S02 and S03 with their interests. |
| 7 | Main success scenario is written as clear, numbered steps (Mandatory) | Pass | Main success scenario has four numbered steps. |
| 8 | Alternative/exception flows correctly reference `<<include>>`/`<<extend>>` use cases where relevant, per UML 2.5.1 (Mandatory) | Pass | Extensions 1a and 2a need no include or extend use case. |
| 9 | Explicit business rules are captured per step where applicable, rather than embedded loosely in narrative text (Optional) | Pass | Business rules are listed per step. |
| 10 | Naming of actors and use case title is consistent with the corresponding Use Case Diagram and User Stories (Mandatory) | Pass | Title and actor match [UCD-001] and [US-001]. |
| 11 | Scope/level (e.g. summary, user-goal, subfunction) is explicitly stated (Optional) | Pass | Level is user-goal. |
| 12 | Use case is written from the actor's goal perspective, free of UI or implementation detail (Mandatory) | Pass | Written from the goal of the participant; no UI detail. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The use case is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: numbered scenario and business rules. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass; criteria 1 and 2 apply to other formats.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[UC-001]: ../../uc-001/uc.md
[QC-UC-001]: ../../../framework/qc/artifacts/qc-use-case.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[UCD-001]: ../../use-case-diagram.md
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+71
View File
@@ -0,0 +1,71 @@
# RC-014 Review of SSD-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-014 |
| CrossReference | [SSD-001], [QC-SSD-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [SSD-001]
- Checklist used: [QC-SSD-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Input/output messages match the corresponding Use Case's main success scenario step-for-step (Mandatory) | Pass | One message `countByFurColor` covers use case steps 1 to 4; the table justifies it. |
| 2 | Actor and System are treated strictly as black boxes (system shown as `:System`) (Mandatory) | Pass | Only Participant and :System appear. |
| 3 | Object creation/destruction of the System instance handled explicitly where relevant (Optional) | Pass | Lifecycle Notes: the instance lives for one run. |
| 4 | Return values are shown for operations that produce one, using dashed return arrows (Mandatory) | Pass | Dashed return arrows `summary` and `censusFileMissing`. |
| 5 | Alternate/exceptional flows are represented separately (or explicitly out of scope noted) (Mandatory) | Pass | The alternate flow 1a is the second diagram; 2a is stated to have no message. |
| 6 | Message names are verb phrases consistent with the use case's system responsibilities (Optional) | Pass | `countByFurColor` is a verb phrase. |
| 7 | Diagram references the specific Use Case (name and ID) it depicts (Mandatory) | Pass | Source Use Case names Count squirrels by fur colour ([UC-001]). |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The system sequence diagram is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: messages, parameters and returns. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[SSD-001]: ../../uc-001/ssd.md
[QC-SSD-001]: ../../../framework/qc/artifacts/qc-ssd.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[UC-001]: ../../uc-001/uc.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+71
View File
@@ -0,0 +1,71 @@
# RC-015 Review of DM-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-015 |
| CrossReference | [DM-001], [QC-DM-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [DM-001]
- Checklist used: [QC-DM-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Uses ubiquitous/business language throughout; no technical or implementation jargon (e.g. no "table", "class", "pointer") (Mandatory) | Pass | Concepts are business terms from [DICT-001]; no table or class names. |
| 2 | Multiplicities on associations are correct and complete (e.g. `1..*`, `0..1`) (Mandatory) | Pass | All six associations have multiplicities at both ends. |
| 3 | No operation/method signatures shown — attributes and associations only (Mandatory) | Pass | Concepts show attributes and associations only. |
| 4 | Associations are named with an unambiguous reading direction (Optional) | Pass | Association names have a reading direction (supplies, contains, has, counts sightings of, consists of, is written to, receives). |
| 5 | Generalization/specialization used correctly, reflecting true "is-a" relationships, not misused for code reuse (Optional) | Pass | No generalization is used. |
| 6 | Every concept traces to a noun phrase found in the use cases or glossary (Mandatory) | Pass | Every concept traces to a noun in [UC-001] or [DICT-001]. |
| 7 | Attributes are simple domain data (no foreign-key-like references or object pointers modeled as attributes) (Mandatory) | Pass | Attributes are name and number of sightings; relations are associations. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The domain model is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: concepts and associations. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[DM-001]: ../../uc-001/dm.md
[QC-DM-001]: ../../../framework/qc/artifacts/qc-domain-model.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[UC-001]: ../../uc-001/uc.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+71
View File
@@ -0,0 +1,71 @@
# RC-016 Review of DM-002
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-016 |
| CrossReference | [DM-002], [QC-DM-001], [QC-LANG-001], [DICT-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [DM-002]
- Checklist used: [QC-DM-001] and [QC-LANG-001]
- Scope: full review
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Uses ubiquitous/business language throughout; no technical or implementation jargon (e.g. no "table", "class", "pointer") (Mandatory) | Pass | Concepts are business terms from [DICT-001]; no table or class names. |
| 2 | Multiplicities on associations are correct and complete (e.g. `1..*`, `0..1`) (Mandatory) | Pass | All six associations have multiplicities at both ends. |
| 3 | No operation/method signatures shown — attributes and associations only (Mandatory) | Pass | Concepts show attributes and associations only. |
| 4 | Associations are named with an unambiguous reading direction (Optional) | Pass | Association names have a reading direction (supplies, contains, has, counts sightings of, consists of, is written to, receives). |
| 5 | Generalization/specialization used correctly, reflecting true "is-a" relationships, not misused for code reuse (Optional) | Pass | No generalization is used. |
| 6 | Every concept traces to a noun phrase found in the use cases or glossary (Mandatory) | Pass | Every concept traces to a noun in [UC-001] or [DICT-001]. |
| 7 | Attributes are simple domain data (no foreign-key-like references or object pointers modeled as attributes) (Mandatory) | Pass | Attributes are name and number of sightings; relations are associations. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The domain model is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: concepts and associations. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | Terms Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary and Summary file match [DICT-001]. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[DM-002]: ../../domain-model.md
[QC-DM-001]: ../../../framework/qc/artifacts/qc-domain-model.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DICT-001]: ../../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[UC-001]: ../../uc-001/uc.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+55
View File
@@ -0,0 +1,55 @@
# RC-017 Review of ADR-0001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-017 |
| CrossReference | [ADR-0001], [QC-ADR-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Artifact Under Review
- Instance reviewed: [ADR-0001]
- Checklist used: [QC-ADR-001]
- Scope: full review
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The ID (`ADR-NNNN`, 4-digit) matches the filename number and is unique and sequential (Mandatory) | Pass | ID ADR-0001 matches `adr-0001-...` and is the first ADR. |
| 2 | Context states the problem, the forces (cost, risk, constraints) and the options evaluated (Mandatory) | Pass | Context states the criterion, the stakeholders S02 and S03 and three options. |
| 3 | At least two options were considered, or the absence of alternatives is justified (Mandatory) | Pass | Three options were evaluated. |
| 4 | Decision is stated in one or two unhedged sentences and matches one of the evaluated options (Mandatory) | Pass | The decision is one sentence and equals option 2. |
| 5 | Consequences list both Positive and Negative outcomes (Mandatory) | Pass | Positive and Negative lists are present. |
| 6 | Quality-attribute impacts (performance, security, portability, etc.) are named where the decision affects them (Optional) | Pass | Portability across Windows, Debian and macOS is named. |
| 7 | Affected Artifacts are listed as links, and each is also in CrossReference (Mandatory) | Pass | Affected Artifacts BC-001, SA-001 and MIL-002 are also in CrossReference. |
| 8 | Status changes are recorded as new Version History rows with a Change summary and Commit link; retained rows are never rewritten (Mandatory) | Pass | First version; row is Proposed then Accepted by this review. |
| 9 | A superseded or deprecated ADR names its successor, and the successor links back (Optional) | N-A | No superseded ADR. |
| 10 | Written in business or technical language of the domain, with no unexplained abbreviations (Optional) | Pass | Abbreviations are used as in the Business Case; CSV is spelled by the module name. |
| 11 | Status is one of `Proposed`, `Accepted`, `Rejected`, `Deprecated` or `Superseded by ADR-NNNN`, and every Version History row uses only these (Mandatory) | Pass | Status values are Proposed and Accepted. |
## Overall Verdict
Go — all Mandatory criteria pass.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[ADR-0001]: ../../adr/adr-0001-standard-library-instead-of-pandas.md
[QC-ADR-001]: ../../../framework/qc/artifacts/qc-adr.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+71
View File
@@ -0,0 +1,71 @@
# RC-018 Review of DICT-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-018 |
| CrossReference | [DICT-001], [QC-DICT-001], [QC-LANG-001], [DM-002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [DICT-001]
- Checklist used: [QC-DICT-001] and [QC-LANG-001]
- Scope: full review (second review; conditions of RC-007 closed)
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Every row has a PO term, its language, an IT term and a definition (Mandatory) | Pass | All seven rows have PO term, language, IT term and definition. |
| 2 | Each PO term maps to exactly one IT term and the reverse (no synonyms) (Mandatory) | Pass | One IT term per PO term and the reverse; no synonyms. |
| 3 | Every Domain Model concept has a row, and the Domain Model uses its PO term (Mandatory) | Pass | Every concept of [DM-001] and [DM-002] has a row (Participant, Census file, Squirrel sighting, Fur colour, Colour count, Summary, Summary file) and the model uses the PO terms. |
| 4 | The Operation Contracts, Sequence Diagrams, Design Class Diagrams and ERD use the IT term, not the PO term (Mandatory) | N-A | The project creates no Operation Contract, Sequence Diagram, Design Class Diagram or ERD; design is the system sequence diagram and source code. |
| 5 | Definitions are written in the PO language and are one sentence (Optional) | Pass | Definitions are single English sentences. |
| 6 | "Used as PO term in" and "Used as IT term in" name artifact types that exist in the project (Optional) | Pass | Used-in columns name existing types. |
| 7 | The dictionary's `Language` and `Domain` rows, and the language of every row, match the PO language and domain in the project registry (Mandatory) | Pass | Language en and Domain it match the registry. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Metadata has `Language | en` and `Domain | it`. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | `en` is a BCP 47 code; `it` is in the registry domain list. |
| 3 | The content (prose and table cells) is written in the stated language (Mandatory) | Pass | The dictionary is written in English throughout. |
| 4 | The register matches the one the registry gives for the artifact type (Mandatory) | Pass | Professional register: term pairs. |
| 5 | Domain terms are the PO terms of the domain's dictionary, with no synonyms (Mandatory) | Pass | This document is the dictionary. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Metadata keys, headings, IDs and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin exists in `docs/`. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | First version; no earlier accepted language. |
| 9 | A reviewer competent in the domain, and in the language, has confirmed that the domain terms are used correctly (Mandatory) | Pass | Reviewer reads English and knows the software domain; no second reviewer needed. |
| 10 | Abbreviations are spelled out on first use, in the stated language (Optional) | Pass | Abbreviations are expanded on first use in the body (S-IDs and artifact IDs are framework labels). |
## Overall Verdict
Go — all Mandatory criteria that can apply pass; criterion 4 has no object in this project. Supersedes the conditions of RC-007.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[DICT-001]: ../../dictionary.md
[QC-DICT-001]: ../../../framework/qc/artifacts/qc-dictionary.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[DM-002]: ../../domain-model.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[DM-001]: ../../uc-001/dm.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
@@ -0,0 +1,59 @@
# RC-019 Review of BC-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-019 |
| CrossReference | [BC-001], [QC-BC-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [BC-001]
- Checklist used: [QC-BC-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that cites the changed row and criteria 1, 2, 6, 7, 8 of QC-LANG-001: only the CrossReference row changed (first instance of a candidate type was created); earlier record applies to the rest
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 5 | Stakeholders are cross-referenced to Stakeholder Analysis IDs rather than re-described inline (Mandatory) | Pass | Stakeholders table is unchanged; CrossReference now also lists [UCD-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged since the accepted version. |
## Overall Verdict
Go — only Metadata (CrossReference) and the Version History changed; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[BC-001]: ../../business-case.md
[QC-BC-001]: ../../../framework/qc/artifacts/qc-business-case.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[UCD-001]: ../../use-case-diagram.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+59
View File
@@ -0,0 +1,59 @@
# RC-020 Review of MIL-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-020 |
| CrossReference | [MIL-001], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that cites the changed row and criteria 1, 2, 6, 7, 8 of QC-LANG-001: only the CrossReference row changed (first instance of a candidate type was created); earlier record applies to the rest
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | Traceability table is unchanged; the CrossReference row now also lists [US-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged since the accepted version. |
## Overall Verdict
Go — only Metadata (CrossReference) and the Version History changed; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-001]: ../../milestones/mil-001-project-scaffold.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+59
View File
@@ -0,0 +1,59 @@
# RC-021 Review of MIL-002
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-021 |
| CrossReference | [MIL-002], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-002]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that cites the changed row and criteria 1, 2, 6, 7, 8 of QC-LANG-001: only the CrossReference row changed (first instance of a candidate type was created); earlier record applies to the rest
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | Traceability table is unchanged; the CrossReference row now also lists [US-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged since the accepted version. |
## Overall Verdict
Go — only Metadata (CrossReference) and the Version History changed; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-002]: ../../milestones/mil-002-census-analysis.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+59
View File
@@ -0,0 +1,59 @@
# RC-022 Review of MIL-003
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-022 |
| CrossReference | [MIL-003], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that cites the changed row and criteria 1, 2, 6, 7, 8 of QC-LANG-001: only the CrossReference row changed (first instance of a candidate type was created); earlier record applies to the rest
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | Traceability table is unchanged; the CrossReference row now also lists [US-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged since the accepted version. |
## Overall Verdict
Go — only Metadata (CrossReference) and the Version History changed; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-003]: ../../milestones/mil-003-documentation.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+59
View File
@@ -0,0 +1,59 @@
# RC-023 Review of MIL-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-023 |
| CrossReference | [MIL-004], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that cites the changed row and criteria 1, 2, 6, 7, 8 of QC-LANG-001: only the CrossReference row changed (first instance of a candidate type was created); earlier record applies to the rest
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | Traceability table is unchanged; the CrossReference row now also lists [US-001]. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged since the accepted version. |
## Overall Verdict
Go — only Metadata (CrossReference) and the Version History changed; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-004]: ../../milestones/mil-004-wiki-publication.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[US-001]: ../../user-stories.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+64
View File
@@ -0,0 +1,64 @@
# RC Review of the MIL-002 Python files
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-024 |
| CrossReference | [PY-MIL-002], [QC-PY-001], [ADR-0001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [PY-MIL-002]
- Checklist used: [QC-PY-001]
- Scope: full review of src/squirrel/census.py, cli.py, __main__.py, constants.py and tests/
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Packages, modules, functions, variables, classes and constants follow PEP 8 casing (`snake_case`, `PascalCase`, `UPPER_SNAKE`) (Mandatory) | Pass | Modules, functions and constants use snake_case and UPPER_SNAKE; helper `_build_parser` has one leading underscore. |
| 2 | Names state purpose in the domain's language; no unexplained abbreviations, no single-letter names outside tiny scopes (Mandatory) | Pass | Names state purpose (`count_by_fur_color`, `write_csv`); the lecture step names are kept (ADR-0001). |
| 3 | Code is produced by the project's formatter and passes its linter with no unexplained suppressions (Mandatory) | Pass | `ruff check` and `ruff format --check` (0.17.0) pass with no suppressions. |
| 4 | Every function and method signature is type-annotated, including `-> None` (Mandatory) | Pass | Every function is annotated including `-> None`; `mypy --strict` passes on 10 files. |
| 5 | No bare `except:`, no swallowed exceptions; specific exceptions are raised and the cause is kept (`raise ... from`) (Mandatory) | Pass | No exception handling; a missing file is checked with `is_file()` and reported with exit status 2. |
| 6 | No mutable default arguments and no shadowed builtins (Mandatory) | Pass | The only default argument is the immutable tuple `FUR_COLORS`; no builtin is shadowed. |
| 7 | Files, locks and connections are managed with context managers (Mandatory) | Pass | Files are opened with `with path.open(...)`. |
| 8 | Public modules, classes and functions have docstrings that say what, not how (Optional) | Pass | Public modules and functions have Doxygen blocks and docstrings. |
| 9 | Logging uses `logging`, not `print`; no secrets or personal data in log output (Mandatory) | Pass | `print` is used only for the CLI output to the participant and the stderr error line, not for logging; no secrets. |
| 10 | Classes and operations trace to the Design Class Diagram they implement; deviations are recorded (Mandatory) | N-A | No class is defined and no Design Class Diagram exists; operations trace to [SSD-001] (`countByFurColor`). |
| 11 | Tests exist for new behaviour, are named for the behaviour, and do not depend on order or the network (Mandatory) | Pass | 20 tests: unit tests per function, CLI tests, a real-census test and an imports test; none depends on order or network. |
| 12 | Type checker runs in strict mode without errors; `Any` is justified in a comment (Optional) | Pass | `mypy 2.4.0 --strict` reports no issues. |
| 13 | Dependencies are declared and pinned in the project's dependency file, none unused (Optional) | Pass | No runtime dependency; dev tools pinned in `pyproject.toml`. |
| 14 | Each piece of knowledge (a business rule, constant, format, validation or query) is defined in one place; code is merged only where it expresses the same knowledge, not where it merely looks alike (Mandatory) | Pass | All literals live in `constants.py`; each step is defined once. |
| 15 | Imports point inward: business-rule modules import no framework, database, UI or delivery-mechanism code, and there are no import cycles (Mandatory) | Pass | `census.py` imports only the standard library and constants; `cli.py` imports `census`; no cycle. |
| 16 | SOLID holds: a class or module has one reason to change; new behaviour is added by extension, not by editing a type test in several places; subclasses honour the contract of their base; protocols are narrow; high-level code depends on protocols or abstract types and receives its implementations (Mandatory) | Pass | `census.py` holds four single-purpose functions; the CLI only wires them. |
## Overall Verdict
Go — all Mandatory criteria pass; criterion 10 is not applicable because no class exists.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[PY-MIL-002]: ../../../src/squirrel/census.py
[QC-PY-001]: ../../../framework/qc/code/qc-programming-python.md
[ADR-0001]: ../../adr/adr-0001-standard-library-instead-of-pandas.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
[SSD-001]: ../../uc-001/ssd.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
@@ -0,0 +1,44 @@
# RC Review of ci.yml, delta re-review of criterion 22
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-025 |
| CrossReference | [WF-MIL-001], [QC-WF-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | pending |
---
## Artifact Under Review
- Instance reviewed: [WF-MIL-001]
- Checklist used: [QC-WF-001]
- Scope: delta re-review of criterion 22 of QC-WF-001; reason: the condition of RC-010 (run 1012 queued); earlier record RC-010
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 22 | Every workflow feature used is verified on the instance that runs it, and the host and version are recorded; a feature the target hosts differ on is noted in the header (Mandatory) | Pass | Gitea 1.27.3, runner labels ubuntu-latest. `ci.yml` completed with success on the instance: pull_request runs 1037, 1040 and 1043, and the push run 1044 on main (commit c4e88c6). Header states the host and that only github.* contexts are used. |
## Overall Verdict
Go — criterion 22, the only open Mandatory criterion of RC-010, now passes; the other rows of RC-010 still hold, so the workflow is Go. Closes the condition of RC-010.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[WF-MIL-001]: ../../../.gitea/workflows/ci.yml
[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md
@@ -0,0 +1,56 @@
# RC-026 Review of BC-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-026 |
| CrossReference | [BC-001], [QC-BC-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [d85cfe5] |
---
## Artifact Under Review
- Instance reviewed: [BC-001]
- Checklist used: [QC-BC-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that covers the changed text and criteria 1, 2, 6, 7, 8 of QC-LANG-001: the path `docs/wiki/` was corrected to `wiki/`
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 2 | Risks are identified with documented impact and mitigation (Mandatory) | Pass | The changed text is a folder path in a risk mitigation or a Go criterion; it is still objectively checkable and has a mitigation. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — only a folder path was corrected; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[BC-001]: ../../business-case.md
[QC-BC-001]: ../../../framework/qc/artifacts/qc-business-case.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[d85cfe5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d85cfe5c4b62b2e1759f1c47b25bdb787ba6fd68
@@ -0,0 +1,56 @@
# RC-027 Review of MIL-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-027 |
| CrossReference | [MIL-004], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [d85cfe5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of the criterion that covers the changed text and criteria 1, 2, 6, 7, 8 of QC-LANG-001: the path `docs/wiki/` was corrected to `wiki/`
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 2 | Explicit Go/No-Go criteria are stated for each gate (Mandatory) | Pass | The changed text is a folder path in a risk mitigation or a Go criterion; it is still objectively checkable and has a mitigation. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Language and Domain rows unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — only a folder path was corrected; the earlier review of the content still holds.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-004]: ../../milestones/mil-004-wiki-publication.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[d85cfe5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/d85cfe5c4b62b2e1759f1c47b25bdb787ba6fd68
+57
View File
@@ -0,0 +1,57 @@
# RC-028 Review of MIL-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-028 |
| CrossReference | [MIL-001], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [6fb75dd] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of criteria 1 and 2 and criteria 1, 2, 6, 7, 8 of QC-LANG-001: task 7 added to the Tasks section
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate (Mandatory) | Pass | Deliverable unchanged; the new task adds a test file to the same CI deliverable. |
| 2 | Explicit Go/No-Go criteria are stated for each gate (Mandatory) | Pass | Go / No-Go criteria unchanged and still objectively checkable; the new test runs under criterion 3 (pytest exits 0). |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — one task row was added at the request of S01 in chat; the gate criteria and deliverable are unchanged.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-001]: ../../milestones/mil-001-project-scaffold.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[6fb75dd]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/6fb75ddb8671636869b859d8718d3f3f8783659c
@@ -0,0 +1,60 @@
# RC Review of the workflow test
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-029 |
| CrossReference | [PY-MIL-001-7], [QC-PY-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [7202aac] |
---
## Artifact Under Review
- Instance reviewed: [PY-MIL-001-7]
- Checklist used: [QC-PY-001]
- Scope: full review of tests/test_workflow.py and the dev extra of pyproject.toml
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | Packages, modules, functions, variables, classes and constants follow PEP 8 casing (`snake_case`, `PascalCase`, `UPPER_SNAKE`) (Mandatory) | Pass | Functions, constants (`MAX_RUN_LINES`) and class (`UniqueKeyLoader`) follow PEP 8 casing. |
| 2 | Names state purpose in the domain's language; no unexplained abbreviations, no single-letter names outside tiny scopes (Mandatory) | Pass | Names state purpose (`exceeds_line_limit`, `load_workflow`). |
| 3 | Code is produced by the project's formatter and passes its linter with no unexplained suppressions (Mandatory) | Pass | `ruff check` and `ruff format --check` pass with no suppressions. |
| 4 | Every function and method signature is type-annotated, including `-> None` (Mandatory) | Pass | Every function is annotated; `mypy --strict` passes on 11 files; `Any` is justified by a comment. |
| 5 | No bare `except:`, no swallowed exceptions; specific exceptions are raised and the cause is kept (`raise ... from`) (Mandatory) | Pass | The duplicate-key loader raises `ValueError` with the key named; no bare except. |
| 6 | No mutable default arguments and no shadowed builtins (Mandatory) | Pass | No mutable defaults; no builtins shadowed. |
| 7 | Files, locks and connections are managed with context managers (Mandatory) | Pass | The workflow file is read through `pathlib` and the YAML loader, which close the file. |
| 8 | Public modules, classes and functions have docstrings that say what, not how (Optional) | Pass | Helpers and tests have docstrings. |
| 9 | Logging uses `logging`, not `print`; no secrets or personal data in log output (Mandatory) | Pass | No print and no logging; no secrets. |
| 10 | Classes and operations trace to the Design Class Diagram they implement; deviations are recorded (Mandatory) | N-A | Test code; no class or operation of a design class diagram. |
| 11 | Tests exist for new behaviour, are named for the behaviour, and do not depend on order or the network (Mandatory) | Pass | 14 tests, one behaviour each, plus a negative self-test of the line limit; no order or network dependence. |
| 12 | Type checker runs in strict mode without errors; `Any` is justified in a comment (Optional) | Pass | `mypy --strict` passes; `Any` is commented. |
| 13 | Dependencies are declared and pinned in the project's dependency file, none unused (Optional) | Pass | `pyyaml` and `types-PyYAML` are dev dependencies pinned exactly; no runtime dependency added. |
| 14 | Each piece of knowledge (a business rule, constant, format, validation or query) is defined in one place; code is merged only where it expresses the same knowledge, not where it merely looks alike (Mandatory) | Pass | The line limit is the single constant `MAX_RUN_LINES`, matching the rule in the YAML convention. |
| 15 | Imports point inward: business-rule modules import no framework, database, UI or delivery-mechanism code, and there are no import cycles (Mandatory) | Pass | The test imports the standard library and `yaml`; it imports no application code. |
| 16 | SOLID holds: a class or module has one reason to change; new behaviour is added by extension, not by editing a type test in several places; subclasses honour the contract of their base; protocols are narrow; high-level code depends on protocols or abstract types and receives its implementations (Mandatory) | Pass | One module of small single-purpose helpers and tests. |
## Overall Verdict
Go — all Mandatory criteria pass; criterion 10 is not applicable.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[PY-MIL-001-7]: ../../../tests/test_workflow.py
[QC-PY-001]: ../../../framework/qc/code/qc-programming-python.md
[7202aac]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/7202aac5956ef92ab6a4efc6cb1917de075d771a
@@ -0,0 +1,45 @@
# RC Review of ci.yml, delta re-review of criterion 24
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-030 |
| CrossReference | [WF-MIL-001], [QC-WF-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [7202aac] |
---
## Artifact Under Review
- Instance reviewed: [WF-MIL-001]
- Checklist used: [QC-WF-001]
- Scope: delta re-review of criterion 24 of QC-WF-001; reason: action item of RC-010; earlier records RC-010 and RC-025
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 24 | A static test of the repository's workflows exists and runs on every pull request: valid YAML, required keys, explicit permissions and runner, no inline script above the limit (Optional) | Pass | `tests/test_workflow.py` runs in the pytest step of `ci.yml` on every pull request: it checks safe-loader parsing, required keys, duplicate keys, explicit permissions and runner, timeout, step names, exact-tag pins and the five-line limit on `run:` blocks. 33 tests pass locally. |
## Overall Verdict
Go — criterion 24 (Optional) now passes; the other rows of RC-010 and RC-025 still hold. Closes the second action item of RC-010.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[WF-MIL-001]: ../../../.gitea/workflows/ci.yml
[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md
[7202aac]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/7202aac5956ef92ab6a4efc6cb1917de075d771a
@@ -0,0 +1,48 @@
# RC Review of ci.yml, delta re-review for the lint steps (YAML)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-031 |
| CrossReference | [WF-MIL-001], [QC-YML-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [e406d65] |
---
## Artifact Under Review
- Instance reviewed: [WF-MIL-001]
- Checklist used: [QC-YML-001]
- Scope: delta re-review of criteria 3, 7, 10 and 15 of QC-YML-001: two lint steps added to ci.yml; earlier record RC-009
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 3 | Passes `yamllint` (or the project's YAML linter) with its configuration committed next to the code and no unexplained `disable` comments (Mandatory) | Pass | `yamllint 1.38.0` with `.yamllint.yml` runs in CI on `.gitea` and `.yamllint.yml`; no errors. `new-lines` is disabled with a comment because git normalises line endings. |
| 7 | Embedded program text (shell, Python, SQL, `jq`, and so on) in a value is at most five lines; a longer one is moved to a file of its own, in its own language, and the YAML calls it (Mandatory) | Pass | The two new `run:` blocks have one line each; the longest block is still 3 lines. |
| 10 | The file validates against the schema of the consuming tool where one exists, and the schema or tool version is stated (Optional) | Pass | `actionlint` validates the workflow schema in CI. |
| 15 | A change is exercised by a check that runs without the real target: a parse and schema test, or a dry run of the consuming tool (Optional) | Pass | yamllint and actionlint now run on every push and pull request without the real target. |
## Overall Verdict
Go — the changed rows pass; the other rows of RC-009 still hold.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[WF-MIL-001]: ../../../.gitea/workflows/ci.yml
[QC-YML-001]: ../../../framework/qc/code/qc-yaml.md
[e406d65]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/e406d65f6a53332750204ec3fd876ab2daa2bbd2
@@ -0,0 +1,53 @@
# RC Review of ci.yml, delta re-review for the lint steps (workflow)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-032 |
| CrossReference | [WF-MIL-001], [QC-WF-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [e406d65] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [WF-MIL-001]
- Checklist used: [QC-WF-001]
- Scope: delta re-review of criteria 5, 6, 17, 20, 22 and 24 of QC-WF-001: two lint steps added; earlier records RC-010, RC-025, RC-030
- Language and domain: n/a
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 5 | Every job and step has a descriptive `name`, unique within its job (Mandatory) | Pass | The new steps are named "Lint the YAML files" and "Lint the workflow files"; step names stay unique. |
| 6 | The file passes `actionlint` (or the project's workflow validation test) and the tool version is stated (Mandatory) | Pass | `actionlint 1.7.12` runs in CI against `.gitea/workflows/*.yml` and passes. |
| 17 | Tools and dependencies are installed at pinned versions; a version is a workflow input with a default or a value in one place (Mandatory) | Pass | `yamllint==1.38.0` and `actionlint-py==1.7.12.25` are exact pins in the dev extra of `pyproject.toml`. |
| 20 | A `run:` block is within the limit on embedded program text of criterion 7 of [QC-YML-001]; a longer script is a file (`tools/`, or a shared repository fetched at a pinned ref) that the step calls with one command, and the workflow passes its settings through `env:` (Mandatory) | Pass | Each new `run:` block is one line. |
| 22 | Every workflow feature used is verified on the instance that runs it, and the host and version are recorded; a feature the target hosts differ on is noted in the header (Mandatory) | Pass | The changed workflow completed with success on Gitea 1.27.3: run 1087 on pull request #39. |
| 24 | A static test of the repository's workflows exists and runs on every pull request: valid YAML, required keys, explicit permissions and runner, no inline script above the limit (Optional) | Pass | `tests/test_workflow.py` still passes (33 tests) with the new steps. |
## Overall Verdict
Go — the changed rows pass; the other rows of RC-010, RC-025 and RC-030 still hold.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[WF-MIL-001]: ../../../.gitea/workflows/ci.yml
[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md
[e406d65]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/e406d65f6a53332750204ec3fd876ab2daa2bbd2
[QC-YML-001]: ../../../framework/qc/code/qc-yaml.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+59
View File
@@ -0,0 +1,59 @@
# RC-033 Review of MIL-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-033 |
| CrossReference | [MIL-001], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [78a0d02] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Scope names the earlier records RC-003, RC-020 and RC-028 and says the other criteria still hold | [c88434c] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of criteria 1 and 2 and criteria 1, 2, 6, 7, 8 of QC-LANG-001: task 8 added to the Tasks section; earlier records RC-003 (full review), RC-020 and RC-028 (deltas)
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | A concrete deliverable is defined for every gate (Mandatory) | Pass | Deliverable unchanged; the new task extends the CI workflow already in the deliverable. |
| 2 | Explicit Go/No-Go criteria are stated for each gate (Mandatory) | Pass | Go / No-Go criteria unchanged and objectively checkable; the lint steps run in the same CI run as criterion 3. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — one task row was added at the request of S01 in chat, after the work was done and reviewed in RC-031 and RC-032; the gate criteria and deliverable are unchanged. The remaining criteria 3 to 6 of QC-MIL-001 and 3, 4, 5, 9, 10 of QC-LANG-001 were passed in RC-003 and are unaffected by a new task row.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-001]: ../../milestones/mil-001-project-scaffold.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[78a0d02]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/78a0d02bf373b92163f45d93449dd1009b62e568
[c88434c]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/c88434c58398f6b8d0aa828bf89b2b21606b39a9
@@ -0,0 +1,59 @@
# RC-034 Review of MIL-001
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-034 |
| CrossReference | [MIL-001], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [fa5bb84] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-001]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of criterion 4 and criteria 1, 2, 6, 7, 8 of QC-LANG-001: link definition and CrossReference for [SA-001] added; earlier records RC-003, RC-020, RC-028, RC-033
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | The Traceability table cites [SA-001]; the link definition and the CrossReference entry now exist, so the reference resolves. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — only a missing link definition and a CrossReference entry were added; the other criteria were passed in the earlier records (RC-003, RC-020, RC-028, RC-033) and are unaffected.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-001]: ../../milestones/mil-001-project-scaffold.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
[SA-001]: ../../stakeholder-analysis.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
@@ -0,0 +1,59 @@
# RC-035 Review of MIL-003
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-035 |
| CrossReference | [MIL-003], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [fa5bb84] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of criterion 4 and criteria 1, 2, 6, 7, 8 of QC-LANG-001: link definition and CrossReference for [SA-001] added; earlier records RC-005, RC-022
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | The Traceability table cites [SA-001]; the link definition and the CrossReference entry now exist, so the reference resolves. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — only a missing link definition and a CrossReference entry were added; the other criteria were passed in the earlier records (RC-005, RC-022) and are unaffected.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-003]: ../../milestones/mil-003-documentation.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
[SA-001]: ../../stakeholder-analysis.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
@@ -0,0 +1,59 @@
# RC-036 Review of MIL-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-036 |
| CrossReference | [MIL-004], [QC-MIL-001], [QC-LANG-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Deprecated | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [fa5bb84] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Link definitions added for the IDs cited in the text | [5b948e5] |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-MIL-001] and [QC-LANG-001]
- Scope: delta re-review of criterion 4 and criteria 1, 2, 6, 7, 8 of QC-LANG-001: link definition and CrossReference for [SA-001] added; earlier records RC-006, RC-023, RC-027
- Language and domain: en / it
- Language reviewer: none (the stand-in reviewer reads English and the `it` domain)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 4 | Each milestone is traceable to a Business Case objective or KPI (Mandatory) | Pass | The Traceability table cites [SA-001]; the link definition and the CrossReference entry now exist, so the reference resolves. |
## Language and Domain Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The Metadata table has a `Language` row and a `Domain` row, and neither is a placeholder (Mandatory) | Pass | Unchanged. |
| 2 | `Language` is a BCP 47 code and `Domain` is a value from the registry's domain list (Mandatory) | Pass | Unchanged. |
| 6 | Metadata keys, section headings, IDs and statuses are in English (Mandatory) | Pass | Keys, headings and statuses are English. |
| 7 | No translated twin (`<name>.<language>.md`) exists beside the document (Mandatory) | Pass | No translated twin. |
| 8 | A change of language or domain since the previous accepted version has a Version History row and was reviewed again (Mandatory) | Pass | Language unchanged. |
## Overall Verdict
Go — only a missing link definition and a CrossReference entry were added; the other criteria were passed in the earlier records (RC-006, RC-023, RC-027) and are unaffected.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| None | S01 | - |
---
[MIL-004]: ../../milestones/mil-004-wiki-publication.md
[QC-MIL-001]: ../../../framework/qc/artifacts/qc-milestones-gateways.md
[QC-LANG-001]: ../../../framework/qc/artifacts/qc-language-domain.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
[SA-001]: ../../stakeholder-analysis.md
[5b948e5]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/5b948e5a66bbcea5ef062f4557f47aae113a4e07
+54 -10
View File
@@ -9,7 +9,8 @@
## Version History ## Version History
| Date | Status | Author | Reviewer | Change | Commit | | Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [f1b3c03] | | 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Last Reviewed updated up to RC-033 (RC-026 to RC-033 added)<br>Version History row added for each change batch since the first version | [c88434c] |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Last Reviewed updated up to RC-036 (MIL-001, MIL-003 and MIL-004 link fix) | [fa5bb84] |
--- ---
@@ -23,21 +24,30 @@ updated whenever an artifact instance is created or reviewed.
| Artifact Instance | Type | Language | Domain | Upstream (Backward Link) | Downstream (Forward Link) | Last Reviewed (RC-ID) | | Artifact Instance | Type | Language | Domain | Upstream (Backward Link) | Downstream (Forward Link) | Last Reviewed (RC-ID) |
| --- | --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- | --- |
| [BC-001] | Business Case | en | it | - | [SA-001], [PP-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004] | [RC-001] | | [BC-001] | Business Case | en | it | - | [SA-001], [PP-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004] | [RC-001], [RC-019], [RC-026] |
| [SA-001] | Stakeholder Analysis | en | it | [BC-001] | [PP-001] | [RC-002] | | [SA-001] | Stakeholder Analysis | en | it | [BC-001] | [PP-001] | [RC-002] |
| [PP-001] | Project Plan | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003], [MIL-004] | - (no checklist; accepted by S01 in chat) | | [PP-001] | Project Plan | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003], [MIL-004] | - (no checklist; accepted by S01 in chat) |
| [MIL-001] | Milestone | en | it | [BC-001], [PP-001] | - | [RC-003] | | [MIL-001] | Milestone | en | it | [BC-001], [PP-001] | - | [RC-003], [RC-020], [RC-028], [RC-033], [RC-034] |
| [MIL-002] | Milestone | en | it | [BC-001], [PP-001], [MIL-001] | - | [RC-004] | | [MIL-002] | Milestone | en | it | [BC-001], [PP-001], [MIL-001] | - | [RC-004], [RC-021] |
| [MIL-003] | Milestone | en | it | [BC-001], [PP-001], [MIL-002] | - | [RC-005] | | [MIL-003] | Milestone | en | it | [BC-001], [PP-001], [MIL-002] | - | [RC-005], [RC-022], [RC-035] |
| [MIL-004] | Milestone | en | it | [BC-001], [PP-001], [MIL-003] | - | [RC-006] | | [MIL-004] | Milestone | en | it | [BC-001], [PP-001], [MIL-003] | - | [RC-006], [RC-023], [RC-027], [RC-036] |
| [DICT-001] | Domain Dictionary | en | it | [BC-001], [SA-001] | - | [RC-007] | | [DICT-001] | Domain Dictionary | en | it | [BC-001], [SA-001] | - | [RC-007], [RC-018] |
| [UCD-001] | Use Case Diagram | en | it | [SA-001], [BC-001] | [US-001], [UC-001] | [RC-011] |
| [US-001] | User Story | en | it | [UCD-001], [BC-001], [MIL-002] | [UC-001] | [RC-012] |
| [UC-001] | Use Case | en | it | [UCD-001], [US-001], [SA-001] | [SSD-001], [DM-001] | [RC-013] |
| [SSD-001] | System Sequence Diagram | en | it | [UC-001] | - | [RC-014] |
| [DM-001] | Domain Model | en | it | [UC-001], [DICT-001] | [DM-002] | [RC-015] |
| [DM-002] | Domain Model | en | it | [DM-001], [DICT-001] | - | [RC-016] |
| [ADR-0001] | Architecture Decision Record | - | - | [BC-001], [SA-001], [MIL-002] | `src/squirrel/census.py` | [RC-017] |
| `src/squirrel/census.py`, `cli.py`, `__main__.py`, `tests/` | Python Source Code | - | - | [UC-001], [SSD-001], [ADR-0001] | - | [RC-024] |
| `src/squirrel/constants.py`, `tests/test_constants.py` | Python Source Code | - | - | [MIL-001] | - | [RC-008] | | `src/squirrel/constants.py`, `tests/test_constants.py` | Python Source Code | - | - | [MIL-001] | - | [RC-008] |
| `.gitea/workflows/ci.yml` | CI Workflow | - | - | [MIL-001] | - | [RC-009], [RC-010] | | `tests/test_workflow.py` | Python Source Code | - | - | [MIL-001], [RC-010] | - | [RC-029] |
| `.gitea/workflows/ci.yml` | CI Workflow | - | - | [MIL-001] | - | [RC-009], [RC-010], [RC-025], [RC-030], [RC-031], [RC-032] |
## Coverage Notes ## Coverage Notes
- `-` in Upstream means foundational; in Downstream, nothing is built on it yet; in Last Reviewed, no `RC-*` exists yet. - `-` in Upstream means foundational; in Downstream, nothing is built on it yet; in Last Reviewed, no `RC-*` exists yet.
- No instance yet of US, UC, SSD, DM or ADR; they are added in MIL-002. - No instance of OC, SD, DCD, ERD or KPI; the project creates none (see RC-018).
--- ---
@@ -59,4 +69,38 @@ updated whenever an artifact instance is created or reviewed.
[RC-008]: ./reviews/rc-008-python-constants.md [RC-008]: ./reviews/rc-008-python-constants.md
[RC-009]: ./reviews/rc-009-ci-workflow-yaml.md [RC-009]: ./reviews/rc-009-ci-workflow-yaml.md
[RC-010]: ./reviews/rc-010-ci-workflow.md [RC-010]: ./reviews/rc-010-ci-workflow.md
[f1b3c03]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/f1b3c034dc3880b7884646b4a4ed28e5f98fbcd3 [UCD-001]: ../use-case-diagram.md
[US-001]: ../user-stories.md
[UC-001]: ../uc-001/uc.md
[SSD-001]: ../uc-001/ssd.md
[DM-001]: ../uc-001/dm.md
[DM-002]: ../domain-model.md
[ADR-0001]: ../adr/adr-0001-standard-library-instead-of-pandas.md
[RC-011]: ./reviews/rc-011-use-case-diagram.md
[RC-012]: ./reviews/rc-012-user-stories.md
[RC-013]: ./reviews/rc-013-use-case.md
[RC-014]: ./reviews/rc-014-ssd.md
[RC-015]: ./reviews/rc-015-dm-use-case.md
[RC-016]: ./reviews/rc-016-dm-project.md
[RC-017]: ./reviews/rc-017-adr-0001.md
[RC-018]: ./reviews/rc-018-dictionary-2.md
[RC-019]: ./reviews/rc-019-business-case-delta.md
[RC-020]: ./reviews/rc-020-mil-001-delta.md
[RC-021]: ./reviews/rc-021-mil-002-delta.md
[RC-022]: ./reviews/rc-022-mil-003-delta.md
[RC-023]: ./reviews/rc-023-mil-004-delta.md
[RC-024]: ./reviews/rc-024-python-census.md
[RC-025]: ./reviews/rc-025-ci-workflow-delta.md
[RC-026]: ./reviews/rc-026-business-case-wiki-path.md
[RC-027]: ./reviews/rc-027-mil-004-wiki-path.md
[RC-028]: ./reviews/rc-028-mil-001-task-7.md
[RC-029]: ./reviews/rc-029-python-workflow-test.md
[RC-030]: ./reviews/rc-030-ci-workflow-delta-24.md
[RC-031]: ./reviews/rc-031-ci-yaml-lint-steps.md
[RC-032]: ./reviews/rc-032-ci-workflow-lint-steps.md
[RC-033]: ./reviews/rc-033-mil-001-task-8.md
[c88434c]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/c88434c58398f6b8d0aa828bf89b2b21606b39a9
[RC-034]: ./reviews/rc-034-mil-001-sa-link.md
[RC-035]: ./reviews/rc-035-mil-003-sa-link.md
[RC-036]: ./reviews/rc-036-mil-004-sa-link.md
[fa5bb84]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/fa5bb84025ca0fa1957434d34b0b678280a3abe5
+87
View File
@@ -0,0 +1,87 @@
# Domain Model
## Metadata
| Key | Value |
| --- | --- |
| ID | DM-001 |
| CrossReference | [UC-001], [UCD-001], [SSD-001], [DICT-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Purpose and Scope
Covers: [UC-001] Count squirrels by fur colour.
## Diagram
Concepts, attributes and associations only — no operations.
```plantuml
@startuml
class Participant
class "Census file" as CF {
name
}
class "Squirrel sighting" as SS
class "Fur colour" as FC {
name
}
class "Colour count" as CC {
number of sightings
}
class Summary
class "Summary file" as SF {
name
}
Participant "1" --> "1" CF : supplies
CF "1" --> "0..*" SS : contains
SS "0..*" --> "0..1" FC : has
CC "0..*" --> "1" FC : counts sightings of
Summary "1" --> "3" CC : consists of
Summary "1" --> "1" SF : is written to
Participant "1" --> "0..*" Summary : receives
@enduml
```
## Concept Table
| Concept | Definition | Attributes | Source (use case / glossary) |
| --- | --- | --- | --- |
| Participant | The course participant who runs the program | - | [UC-001] primary actor |
| Census file | The file with the 2018 squirrel census | name | [UC-001] step 1, [DICT-001] |
| Squirrel sighting | One recorded observation of one squirrel | - | [UC-001] step 2, [DICT-001] |
| Fur colour | The primary fur colour of a squirrel: Gray, Cinnamon or Black | name | [UC-001] step 2, [DICT-001] |
| Colour count | The number of sightings with one fur colour | number of sightings | [UC-001] step 4, [DICT-001] |
| Summary | The table of colour counts | - | [UC-001] step 3, [DICT-001] |
| Summary file | The file the summary is written to | name | [UC-001] step 1, [DICT-001] |
## Association Table
| From | Association (reading direction) | To | Multiplicity |
| --- | --- | --- | --- |
| Participant | supplies | Census file | 1 to 1 |
| Census file | contains | Squirrel sighting | 1 to 0..* |
| Squirrel sighting | has | Fur colour | 0..* to 0..1 |
| Colour count | counts sightings of | Fur colour | 0..* to 1 |
| Summary | consists of | Colour count | 1 to 3 |
| Summary | is written to | Summary file | 1 to 1 |
| Participant | receives | Summary | 1 to 0..* |
## Generalizations
None.
---
[UC-001]: ./uc.md
[UCD-001]: ../use-case-diagram.md
[SSD-001]: ./ssd.md
[DICT-001]: ../dictionary.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+58
View File
@@ -0,0 +1,58 @@
# System Sequence Diagram
## Metadata
| Key | Value |
| --- | --- |
| ID | SSD-001 |
| CrossReference | [UC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Source Use Case
Count squirrels by fur colour ([UC-001]) — scenario: main success scenario. The alternate flow 1a (census file missing) is the second diagram; flow 2a has no system message of its own.
## Diagram
```plantuml
@startuml
actor Participant as A
participant ":System" as S
A -> S : countByFurColor(censusFile, summaryFile)
S --> A : summary
@enduml
```
```plantuml
@startuml
actor Participant as A
participant ":System" as S
A -> S : countByFurColor(censusFile, summaryFile)
S --> A : censusFileMissing
@enduml
```
## System Operations
| Step | Message | Parameters | Return | Use case step |
| --- | --- | --- | --- | --- |
| 1 | countByFurColor | censusFile, summaryFile | summary (colour count of each fur colour) | 1 (input), 2 (count), 3 (write), 4 (shown to the participant) |
| 1a | countByFurColor | censusFile, summaryFile | censusFileMissing | 1a |
Steps 2 to 4 of the use case are the work of the system inside one operation: the system receives one message and returns one result, so one message covers steps 1 to 4.
## Lifecycle Notes
The system instance lives for one run of the program; nothing is kept between runs.
---
[UC-001]: ./uc.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+56
View File
@@ -0,0 +1,56 @@
# Use Case (Brief/Casual/Fully Dressed)
## Metadata
| Key | Value |
| --- | --- |
| ID | UC-001 |
| CrossReference | [UCD-001], [US-001], [SA-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
**Format:** Fully Dressed
- **Scope:** Squirrel census program
- **Level:** user-goal
- **Primary Actor:** Participant (as named in [UCD-001])
- **Stakeholders and Interests:**
- S01 — a correct summary that matches the dataset and the assignment
- S02 — a result that is easy to reproduce from the README
- S03 — a program with no runtime dependencies
- **Preconditions:** The participant has the census file.
- **Postconditions (success guarantee):** The summary file exists and holds the colour count of Gray, Cinnamon and Black; the participant has seen the counts.
### Main Success Scenario
1. The participant supplies the census file and the name of the summary file.
2. The system counts the squirrel sightings of each fur colour.
3. The system writes the summary to the summary file.
4. The system shows the participant the colour count of each fur colour.
### Extensions / Alternative Flows
- 1a. The census file does not exist: the system tells the participant that the file is missing and ends without writing a summary.
- 2a. A squirrel sighting has no fur colour: the system leaves it out of every colour count.
### Special Requirements / Business Rules
- Step 2: only the fur colours Gray, Cinnamon and Black are counted; a colour count is the number of sightings with that exact fur colour.
- Step 3: the summary has one row per counted fur colour, in the order Gray, Cinnamon, Black.
### Open Issues
None.
---
[UCD-001]: ../use-case-diagram.md
[US-001]: ../user-stories.md
[SA-001]: ../stakeholder-analysis.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+58
View File
@@ -0,0 +1,58 @@
# Use Case Diagram
## Metadata
| Key | Value |
| --- | --- |
| ID | UCD-001 |
| CrossReference | [SA-001], [BC-001] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Purpose and Scope
The system is the squirrel census program. The boundary contains the one goal of the assignment: counting squirrels by fur colour from the census file and writing the summary. The participant is the only actor.
## Diagram
```plantuml
@startuml
left to right direction
actor "Participant" as A1
rectangle "Squirrel Census Program" {
usecase "Count squirrels by fur colour" as UC1
}
A1 --> UC1
@enduml
```
## Actor Table
| Actor | Stereotype | Stakeholder ID (SA) | Goals (use cases) |
| --- | --- | --- | --- |
| Participant | <<Actor>> | S01, S02 | Count squirrels by fur colour |
| Squirrel Census Program | <<System>> | S01 | - |
## Use Case Table
| Use Case | Actor(s) | Goal |
| --- | --- | --- |
| Count squirrels by fur colour | Participant | Get the number of squirrels of each fur colour as a summary file |
## Relationships
| From | Relationship (`<<include>>` / `<<extend>>`) | To | Justification |
| --- | --- | --- | --- |
| - | - | - | There is only one use case, so there is no include or extend relationship |
---
[SA-001]: ./stakeholder-analysis.md
[BC-001]: ./business-case.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+52
View File
@@ -0,0 +1,52 @@
# User Story
## Metadata
| Key | Value |
| --- | --- |
| ID | US-001 |
| CrossReference | [UCD-001], [BC-001], [MIL-001], [MIL-002], [MIL-003], [MIL-004] |
| Language | en |
| Domain | it |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-13 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [259d017] |
---
## Purpose and Scope
Covers the epic delivered by [MIL-002]: the participant counts squirrels by fur colour. Objective 1 of [BC-001].
## Story List
### US-001.01 — Count squirrels by fur colour
**As a** Participant, **I want** to count the squirrels of each fur colour in the census file, **so that** I get a summary file with the number of gray, cinnamon and black squirrels.
**Acceptance Criteria**
- Given a census file with squirrel sightings, when the participant counts by fur colour, then the summary lists Gray, Cinnamon and Black with the number of sightings of each.
- Given the 2018 census file, when the participant counts by fur colour, then the summary shows Gray 2473, Cinnamon 392 and Black 103.
- Given a census file with a sighting that has no fur colour, when the participant counts, then that sighting is in no colour count.
- Given a census file that does not exist, when the participant counts, then the participant is told that the file is missing and no summary is written.
| Traces to | Size | INVEST exceptions |
| --- | --- | --- |
| [UC-001], [MIL-002] | fits one iteration | none |
## INVEST Check
Independent (the only story), Negotiable (file names are defaults), Valuable (delivers the assignment result), Estimable, Small (one iteration), Testable (the criteria are checkable with fixture rows and the 2018 census file). No exceptions.
---
[UCD-001]: ./use-case-diagram.md
[BC-001]: ./business-case.md
[MIL-001]: ./milestones/mil-001-project-scaffold.md
[MIL-002]: ./milestones/mil-002-census-analysis.md
[MIL-003]: ./milestones/mil-003-documentation.md
[MIL-004]: ./milestones/mil-004-wiki-publication.md
[UC-001]: ./uc-001/uc.md
[259d017]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/commit/259d017ad257059330eb9a8bdbf940c9d082664e
+3 -1
View File
@@ -21,7 +21,9 @@ classifiers = [
] ]
[project.optional-dependencies] [project.optional-dependencies]
dev = ["pytest==9.1.1", "ruff==0.17.0", "mypy==2.4.0"] dev = ["pytest==9.1.1", "ruff==0.17.0", "mypy==2.4.0",
"pyyaml==6.0.3", "types-PyYAML==6.0.12.20260906",
"yamllint==1.38.0", "actionlint-py==1.7.12.25"]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where = ["src"] where = ["src"]
+4
View File
@@ -0,0 +1,4 @@
Fur Color,Count
Gray,2473
Cinnamon,392
Black,103
1 Fur Color Count
2 Gray 2473
3 Cinnamon 392
4 Black 103
+10
View File
@@ -0,0 +1,10 @@
##
# @file __main__.py
# @brief Allows `python -m squirrel` to run the command line.
"""Allows `python -m squirrel` to run the command line."""
from squirrel.cli import main
if __name__ == "__main__":
raise SystemExit(main())
+63
View File
@@ -0,0 +1,63 @@
##
# @file census.py
# @brief Pure steps of the census analysis: read, count, summarise, write.
"""Pure steps of the census analysis: read, count, summarise, write."""
import collections
import csv
import pathlib
from collections.abc import Iterable, Mapping, Sequence
from squirrel.constants import (
FILE_ENCODING,
FUR_COLOR_COLUMN,
FUR_COLORS,
SUMMARY_COLUMNS,
)
##
# @brief Read a CSV file into one dictionary per row, keyed by the header names.
# @param path Location of the CSV file.
# @return The rows of the file, in file order.
def read_csv(path: pathlib.Path) -> list[dict[str, str]]:
"""Read a CSV file into one dictionary per row, keyed by the header names."""
with path.open(encoding=FILE_ENCODING, newline="") as file:
return list(csv.DictReader(file))
##
# @brief Count the rows per fur colour; other or blank colours are counted in none.
# @param rows Census rows, each holding the fur colour column.
# @param colors Fur colours to count, in the order of the result.
# @return Count per colour of `colors`, 0 for a colour that does not occur.
def count_by_fur_color(
rows: Iterable[Mapping[str, str]],
colors: Sequence[str] = FUR_COLORS,
) -> dict[str, int]:
"""Count the rows per fur colour; other or blank colours are counted in none."""
seen = collections.Counter(row.get(FUR_COLOR_COLUMN) for row in rows)
return {color: seen[color] for color in colors}
##
# @brief Turn the counts into summary rows, keeping the order of the counts.
# @param counts Count per fur colour.
# @return One (colour, count) pair per colour.
def build_summary(counts: Mapping[str, int]) -> list[tuple[str, int]]:
"""Turn the counts into summary rows, keeping the order of the counts."""
return list(counts.items())
##
# @brief Write the summary as a CSV file: the header row, then one row per colour.
# @param summary Rows to write, as built by `build_summary`.
# @param path Location of the CSV file; its folder must exist.
# @return None.
def write_csv(summary: Sequence[tuple[str, int]], path: pathlib.Path) -> None:
"""Write the summary as a CSV file: the header row, then one row per colour."""
with path.open("w", encoding=FILE_ENCODING, newline="") as file:
writer = csv.writer(file)
writer.writerow(SUMMARY_COLUMNS)
writer.writerows(summary)
+67
View File
@@ -0,0 +1,67 @@
##
# @file cli.py
# @brief Command line entry point: count the squirrels and write the summary.
"""Command line entry point: count the squirrels and write the summary."""
import argparse
import pathlib
import sys
from collections.abc import Sequence
from squirrel import census
from squirrel.constants import (
DEFAULT_INPUT_PATH,
DEFAULT_OUTPUT_PATH,
EXIT_INPUT_MISSING,
)
##
# @brief Build the argument parser of the command line.
# @return The parser with the optional `input` and `output` positionals.
def _build_parser() -> argparse.ArgumentParser:
"""Build the argument parser of the command line."""
parser = argparse.ArgumentParser(
prog="squirrel",
description="Count the census squirrels by primary fur colour.",
)
parser.add_argument(
"input",
nargs="?",
type=pathlib.Path,
default=DEFAULT_INPUT_PATH,
help="census CSV file (default: %(default)s)",
)
parser.add_argument(
"output",
nargs="?",
type=pathlib.Path,
default=DEFAULT_OUTPUT_PATH,
help="summary CSV file to write (default: %(default)s)",
)
return parser
##
# @brief Run the census analysis from the command line.
# @param argv Arguments without the program name; `sys.argv` is used when None.
# @return 0 on success, 2 when the census file does not exist.
def main(argv: Sequence[str] | None = None) -> int:
"""Run the census analysis from the command line."""
args = _build_parser().parse_args(argv)
input_path: pathlib.Path = args.input
output_path: pathlib.Path = args.output
if not input_path.is_file():
print(f"Census file not found: {input_path}", file=sys.stderr)
return EXIT_INPUT_MISSING
counts = census.count_by_fur_color(census.read_csv(input_path))
summary = census.build_summary(counts)
census.write_csv(summary, output_path)
# print is the intended output here: the counts are shown to the participant.
for color, count in summary:
print(f"{color}: {count}")
return 0
+3
View File
@@ -23,5 +23,8 @@ FUR_COLOR_COLUMN: str = "Primary Fur Color"
## @brief Fur colours that are counted, in the order they appear in the summary. ## @brief Fur colours that are counted, in the order they appear in the summary.
FUR_COLORS: tuple[str, ...] = ("Gray", "Cinnamon", "Black") FUR_COLORS: tuple[str, ...] = ("Gray", "Cinnamon", "Black")
## @brief Exit status of the command line when the census file does not exist.
EXIT_INPUT_MISSING: int = 2
## @brief Header of the summary file: the colour column, then the count column. ## @brief Header of the summary file: the colour column, then the count column.
SUMMARY_COLUMNS: tuple[str, str] = ("Fur Color", "Count") SUMMARY_COLUMNS: tuple[str, str] = ("Fur Color", "Count")
+89
View File
@@ -0,0 +1,89 @@
"""Tests for the squirrel.census module."""
import pathlib
from squirrel import census
from squirrel.constants import (
FILE_ENCODING,
FUR_COLOR_COLUMN,
FUR_COLORS,
SUMMARY_COLUMNS,
)
OTHER_COLUMN = "Unique Squirrel ID"
def _row(color: str) -> dict[str, str]:
return {FUR_COLOR_COLUMN: color}
def test_read_csv_returns_one_dict_per_row(tmp_path: pathlib.Path) -> None:
path = tmp_path / "census.csv"
path.write_text(
f"{OTHER_COLUMN},{FUR_COLOR_COLUMN}\n1,{FUR_COLORS[0]}\n2,\n",
encoding=FILE_ENCODING,
)
rows = census.read_csv(path)
assert rows == [
{OTHER_COLUMN: "1", FUR_COLOR_COLUMN: FUR_COLORS[0]},
{OTHER_COLUMN: "2", FUR_COLOR_COLUMN: ""},
]
def test_count_by_fur_color_counts_each_colour() -> None:
gray, cinnamon, black = FUR_COLORS
rows = [
_row(gray),
_row(gray),
_row(cinnamon),
_row(black),
_row(black),
_row(black),
]
counts = census.count_by_fur_color(rows)
assert counts == {gray: 2, cinnamon: 1, black: 3}
def test_count_by_fur_color_ignores_blank_and_unknown_colours() -> None:
rows = [_row(""), _row("White"), _row(FUR_COLORS[0].lower()), {OTHER_COLUMN: "1"}]
counts = census.count_by_fur_color(rows)
assert sum(counts.values()) == 0
def test_count_by_fur_color_includes_zero_counts_in_colour_order() -> None:
counts = census.count_by_fur_color([_row(FUR_COLORS[1])])
assert list(counts.items()) == [
(FUR_COLORS[0], 0),
(FUR_COLORS[1], 1),
(FUR_COLORS[2], 0),
]
def test_count_by_fur_color_uses_given_colours() -> None:
counts = census.count_by_fur_color([_row("White"), _row("White")], colors=["White"])
assert counts == {"White": 2}
def test_build_summary_keeps_order_of_counts() -> None:
counts = {"Black": 3, "Gray": 1, "Cinnamon": 2}
assert census.build_summary(counts) == [("Black", 3), ("Gray", 1), ("Cinnamon", 2)]
def test_write_csv_writes_header_then_rows(tmp_path: pathlib.Path) -> None:
path = tmp_path / "summary.csv"
summary = [(FUR_COLORS[0], 5), (FUR_COLORS[1], 0)]
census.write_csv(summary, path)
header = ",".join(SUMMARY_COLUMNS)
expected = f"{header}\n{FUR_COLORS[0]},5\n{FUR_COLORS[1]},0\n"
assert path.read_bytes().decode(FILE_ENCODING).replace("\r\n", "\n") == expected
+67
View File
@@ -0,0 +1,67 @@
"""Tests for the squirrel.cli module."""
import pathlib
import pytest
from squirrel import cli
from squirrel.constants import (
FILE_ENCODING,
FUR_COLOR_COLUMN,
FUR_COLORS,
SUMMARY_COLUMNS,
)
def _write_census(path: pathlib.Path) -> None:
gray, cinnamon, _black = FUR_COLORS
lines = [FUR_COLOR_COLUMN, gray, gray, cinnamon, ""]
path.write_text("\n".join(lines) + "\n", encoding=FILE_ENCODING)
def test_main_writes_summary_file_and_returns_zero(tmp_path: pathlib.Path) -> None:
census_path = tmp_path / "census.csv"
summary_path = tmp_path / "summary.csv"
_write_census(census_path)
status = cli.main([str(census_path), str(summary_path)])
assert status == 0
lines = summary_path.read_text(encoding=FILE_ENCODING).splitlines()
assert lines == [
",".join(SUMMARY_COLUMNS),
f"{FUR_COLORS[0]},2",
f"{FUR_COLORS[1]},1",
f"{FUR_COLORS[2]},0",
]
def test_main_prints_one_line_per_colour(
tmp_path: pathlib.Path, capsys: pytest.CaptureFixture[str]
) -> None:
census_path = tmp_path / "census.csv"
_write_census(census_path)
cli.main([str(census_path), str(tmp_path / "summary.csv")])
out_lines = capsys.readouterr().out.splitlines()
assert out_lines == [
f"{FUR_COLORS[0]}: 2",
f"{FUR_COLORS[1]}: 1",
f"{FUR_COLORS[2]}: 0",
]
def test_main_returns_2_and_writes_nothing_when_census_missing(
tmp_path: pathlib.Path, capsys: pytest.CaptureFixture[str]
) -> None:
missing = tmp_path / "missing.csv"
summary_path = tmp_path / "summary.csv"
status = cli.main([str(missing), str(summary_path)])
captured = capsys.readouterr()
assert status == 2
assert not summary_path.exists()
assert captured.err.strip() == f"Census file not found: {missing}"
assert captured.out == ""
+4
View File
@@ -31,6 +31,10 @@ def test_file_encoding_and_column_name_values() -> None:
assert constants.FUR_COLOR_COLUMN == "Primary Fur Color" assert constants.FUR_COLOR_COLUMN == "Primary Fur Color"
def test_exit_input_missing_is_2() -> None:
assert constants.EXIT_INPUT_MISSING == 2
def test_module_imports_only_standard_library() -> None: def test_module_imports_only_standard_library() -> None:
source = pathlib.Path(constants.__file__).read_text(encoding="utf-8") source = pathlib.Path(constants.__file__).read_text(encoding="utf-8")
imported: set[str] = set() imported: set[str] = set()
+40
View File
@@ -0,0 +1,40 @@
"""Every module of the package imports only the standard library or itself."""
import ast
import pathlib
import sys
import squirrel
PACKAGE_NAME = squirrel.__name__
PACKAGE_DIR = pathlib.Path(squirrel.__file__).parent
ALLOWED = sys.stdlib_module_names | {PACKAGE_NAME}
def _imported_top_level_names(source: str) -> set[str]:
imported: set[str] = set()
for node in ast.walk(ast.parse(source)):
if isinstance(node, ast.Import):
imported.update(alias.name.split(".")[0] for alias in node.names)
elif (
isinstance(node, ast.ImportFrom)
and node.module is not None
and node.level == 0
):
imported.add(node.module.split(".")[0])
return imported
def test_package_has_modules_to_check() -> None:
assert list(PACKAGE_DIR.glob("*.py"))
def test_every_module_imports_only_standard_library_or_squirrel() -> None:
offenders: dict[str, set[str]] = {}
for module in PACKAGE_DIR.rglob("*.py"):
source = module.read_text(encoding="utf-8")
foreign = _imported_top_level_names(source) - ALLOWED
if foreign:
offenders[module.name] = foreign
assert offenders == {}
+21
View File
@@ -0,0 +1,21 @@
"""Check the counts of the real 2018 Central Park census file, when present."""
import pathlib
import pytest
from squirrel import census
from squirrel.constants import DEFAULT_INPUT_PATH, FUR_COLORS
REPO_ROOT = pathlib.Path(__file__).parents[1]
def test_real_census_counts_match_published_figures() -> None:
path = REPO_ROOT / DEFAULT_INPUT_PATH
if not path.is_file():
pytest.skip(f"census file not present: {path}")
counts = census.count_by_fur_color(census.read_csv(path))
gray, cinnamon, black = FUR_COLORS
assert counts == {gray: 2473, cinnamon: 392, black: 103}
+167
View File
@@ -0,0 +1,167 @@
"""Static checks of the CI workflow (QC-WF-001 criterion 24, MIL-001 task 7)."""
import re
from collections.abc import Hashable, Iterator
from pathlib import Path
from typing import Any
import pytest
import yaml
ROOT = Path(__file__).parents[1]
WORKFLOW_PATH = ROOT / ".gitea" / "workflows" / "ci.yml"
GITHUB_WORKFLOW_PATH = ROOT / ".github" / "workflows" / "ci.yml"
MAX_RUN_LINES = 5
EXACT_TAG = re.compile(r"@v\d+\.\d+\.\d+$")
FULL_SHA = re.compile(r"@[0-9a-f]{40}$")
# Parsed YAML is untyped data, so Any is the honest type here.
Workflow = dict[Any, Any]
class UniqueKeyLoader(yaml.SafeLoader):
"""Safe loader that rejects a mapping with a repeated key."""
def construct_mapping(
self, node: yaml.MappingNode, deep: bool = False
) -> dict[Hashable, Any]:
"""Build the mapping, raising ValueError on a duplicate key."""
seen: set[Hashable] = set()
for key_node, _ in node.value:
key = self.construct_object(key_node, deep=deep)
if key in seen:
raise ValueError(f"duplicate key {key!r} at {key_node.start_mark}")
seen.add(key)
return super().construct_mapping(node, deep=deep)
def load_workflow() -> Workflow:
"""Parse the workflow with the safe loader."""
loaded = yaml.safe_load(WORKFLOW_PATH.read_text(encoding="utf-8"))
assert isinstance(loaded, dict)
return loaded
def triggers(workflow: Workflow) -> Any:
"""Return the trigger section; YAML 1.1 reads the key `on` as True."""
return workflow["on"] if "on" in workflow else workflow[True]
def trigger_names(workflow: Workflow) -> set[str]:
"""Return the names of the events that trigger the workflow."""
section = triggers(workflow)
if isinstance(section, str):
return {section}
return {str(name) for name in section}
def jobs(workflow: Workflow) -> dict[str, Workflow]:
"""Return the jobs by id."""
found: dict[str, Workflow] = workflow["jobs"]
return found
def steps(job: Workflow) -> list[Workflow]:
"""Return the steps of a job."""
found: list[Workflow] = job.get("steps", [])
return found
def all_steps(workflow: Workflow) -> Iterator[Workflow]:
"""Yield every step of every job."""
for job in jobs(workflow).values():
yield from steps(job)
def exceeds_line_limit(script: str, limit: int = MAX_RUN_LINES) -> bool:
"""Tell whether a script has more lines than the limit, as written.
Blank lines and comments count.
"""
return len(script.splitlines()) > limit
def test_workflow_parses_with_required_keys() -> None:
"""The file is valid YAML with a name, a trigger and jobs."""
workflow = load_workflow()
assert "name" in workflow
assert "on" in workflow or True in workflow
assert "jobs" in workflow
def test_workflow_has_no_duplicate_keys() -> None:
"""No mapping in the file repeats a key."""
text = WORKFLOW_PATH.read_text(encoding="utf-8")
assert yaml.load(text, Loader=UniqueKeyLoader) is not None
def test_duplicate_key_loader_rejects_repeated_key() -> None:
"""The duplicate-key loader bites on a repeated key."""
with pytest.raises(ValueError, match="duplicate key"):
yaml.load("a: 1\na: 2\n", Loader=UniqueKeyLoader)
def test_permissions_are_declared() -> None:
"""Permissions are set at workflow level or on every job."""
workflow = load_workflow()
if "permissions" in workflow:
return
assert all("permissions" in job for job in jobs(workflow).values())
def test_every_job_has_runner_and_timeout() -> None:
"""Each job names its runner and a timeout."""
for job_id, job in jobs(load_workflow()).items():
assert "runs-on" in job, job_id
assert "timeout-minutes" in job, job_id
def test_every_step_has_a_name() -> None:
"""Each step carries a name."""
for job_id, job in jobs(load_workflow()).items():
for step in steps(job):
assert "name" in step, f"{job_id}: {step}"
def test_step_names_are_unique_within_a_job() -> None:
"""No two steps of one job share a name."""
for job_id, job in jobs(load_workflow()).items():
names = [step["name"] for step in steps(job) if "name" in step]
assert len(names) == len(set(names)), job_id
def test_uses_are_pinned_to_exact_release_or_sha() -> None:
"""Each action is pinned to an exact tag or a full commit SHA."""
for step in all_steps(load_workflow()):
if "uses" in step:
ref = str(step["uses"])
assert EXACT_TAG.search(ref) or FULL_SHA.search(ref), ref
def test_run_blocks_stay_within_line_limit() -> None:
"""No inline script is longer than the limit."""
for step in all_steps(load_workflow()):
if "run" in step:
assert not exceeds_line_limit(str(step["run"])), step.get("name")
def test_line_limit_check_rejects_six_lines() -> None:
"""The line-limit helper counts lines as written, blank lines included."""
assert exceeds_line_limit("a\nb\nc\nd\ne\nf\n")
assert exceeds_line_limit("a\nb\nc\nd\ne\n\n")
assert not exceeds_line_limit("a\nb\n\nc\nd\n")
def test_workflow_uses_no_secrets() -> None:
"""The file refers to no secret."""
assert "secrets." not in WORKFLOW_PATH.read_text(encoding="utf-8")
def test_workflow_is_not_triggered_by_pull_request_target() -> None:
"""The privileged pull_request_target trigger is not used."""
assert "pull_request_target" not in trigger_names(load_workflow())
def test_workflow_is_not_duplicated_for_github() -> None:
"""The same workflow does not also live under .github/workflows."""
assert not GITHUB_WORKFLOW_PATH.exists()
+32
View File
@@ -0,0 +1,32 @@
🌐 [English](Description) · **Dansk** · [Bahasa Melayu](Description.ms)
# Beskrivelse
## Hvad programmet gør
Programmet følger lektionens trin:
1. `read_csv` læser optællingsfilen.
2. `count_by_fur_color` tæller observationerne af Gray, Cinnamon og Black.
3. `build_summary` gør tallene til rækkerne i en opsummering.
4. `write_csv` skriver opsummeringen til `squirrel_count.csv`.
På optællingsfilen fra 2018 er resultatet Gray 2473, Cinnamon 392 og Black 103. Observationer uden pelsfarve tælles ikke med i nogen af dem.
## Hvorfor ikke Pandas
Lektionen bruger Pandas. Dette projekt bruger kun Pythons standardbibliotek (`csv` og `collections.Counter`), så der ikke er noget at installere for at køre det. Beslutningen er beskrevet som ADR-0001 i repositoryet.
## Opbygning
| Sti | Indhold |
| --- | --- |
| `src/squirrel/census.py` | De fire trin ovenfor |
| `src/squirrel/cli.py` | Kommandolinjen, `python -m squirrel` |
| `src/squirrel/constants.py` | Alle konstanter, defineret ét sted |
| `tests/` | pytest-testene |
| `docs/` | Business case, plan, modeller, reviewposter |
## Kvalitet
Alle dokumenter og al kode er gennemgået mod tjeklisterne i SQA- og QC-frameworket i autonom tilstand: reviewer er en AI-stedfortræder, så reviewene er ikke uafhængige.
+32
View File
@@ -0,0 +1,32 @@
🌐 **English** · [Dansk](Description.da) · [Bahasa Melayu](Description.ms)
# Description
## What it does
The program follows the steps of the lecture:
1. `read_csv` reads the census file.
2. `count_by_fur_color` counts the sightings of Gray, Cinnamon and Black.
3. `build_summary` turns the counts into the rows of a summary.
4. `write_csv` writes the summary to `squirrel_count.csv`.
On the 2018 census file the result is Gray 2473, Cinnamon 392 and Black 103. Sightings without a fur colour are counted in none of them.
## Why no Pandas
The lecture uses Pandas. This project uses only the Python standard library (`csv` and `collections.Counter`) so that there is nothing to install to run it. The decision is recorded as ADR-0001 in the repository.
## Layout
| Path | Content |
| --- | --- |
| `src/squirrel/census.py` | The four steps above |
| `src/squirrel/cli.py` | The command line, `python -m squirrel` |
| `src/squirrel/constants.py` | Every literal, defined once |
| `tests/` | The pytest tests |
| `docs/` | Business case, plan, models, review records |
## Quality
Every document and every piece of code was reviewed against the checklists of the SQA and QC framework, in autonomous mode: the reviewer is an AI stand-in, so the reviews are not independent.
+32
View File
@@ -0,0 +1,32 @@
🌐 [English](Description) · [Dansk](Description.da) · **Bahasa Melayu**
# Penerangan
## Apa yang dilakukan program
Program mengikut langkah dalam pelajaran:
1. `read_csv` membaca fail banci.
2. `count_by_fur_color` mengira pemerhatian Gray, Cinnamon dan Black.
3. `build_summary` menukar kiraan kepada baris ringkasan.
4. `write_csv` menulis ringkasan ke `squirrel_count.csv`.
Pada fail banci 2018 hasilnya ialah Gray 2473, Cinnamon 392 dan Black 103. Pemerhatian tanpa warna bulu tidak dikira dalam mana-mana satu.
## Mengapa tidak menggunakan Pandas
Pelajaran menggunakan Pandas. Projek ini hanya menggunakan pustaka standard Python (`csv` dan `collections.Counter`) supaya tiada apa-apa untuk dipasang bagi menjalankannya. Keputusan itu direkodkan sebagai ADR-0001 dalam repositori.
## Susun atur
| Laluan | Kandungan |
| --- | --- |
| `src/squirrel/census.py` | Empat langkah di atas |
| `src/squirrel/cli.py` | Baris perintah, `python -m squirrel` |
| `src/squirrel/constants.py` | Semua pemalar, ditakrif sekali |
| `tests/` | Ujian pytest |
| `docs/` | Kes perniagaan, pelan, model, rekod semakan |
## Kualiti
Setiap dokumen dan kod disemak berdasarkan senarai semak rangka kerja SQA dan QC dalam mod autonomi: penyemak ialah pengganti AI, jadi semakan itu tidak bebas.
+15
View File
@@ -0,0 +1,15 @@
🌐 [English](Home) · **Dansk** · [Bahasa Melayu](Home.ms)
# Egern-optælling
Dag 25 i Udemys *100 Days of Code: The Complete Python Pro Bootcamp*: tæl egernene i Central Parks egern-optælling fra 2018 efter primær pelsfarve (grå, kanel, sort) og eksportér tallene til `squirrel_count.csv`.
![Programkørsel](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
| Side | Læs den, når du vil |
| --- | --- |
| [Installation](Install.da) | Oprette et `.venv` og installere projektet på Windows PowerShell, Linux Debian eller macOS |
| [Brug](Usage.da) | Køre programmet og testene |
| [Beskrivelse](Description.da) | Forstå hvordan koden er bygget, og hvorfor den ikke har kørselsafhængigheder |
Koden, testene og projektdokumenterne ligger i [repositoryet](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel).
+15
View File
@@ -0,0 +1,15 @@
🌐 **English** · [Dansk](Home.da) · [Bahasa Melayu](Home.ms)
# Squirrel Census
Day 25 of Udemy's *100 Days of Code: The Complete Python Pro Bootcamp*: count the squirrels of the 2018 Central Park Squirrel Census by primary fur colour (gray, cinnamon, black) and export the counts to `squirrel_count.csv`.
![Program run](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
| Page | Read it when you want to |
| --- | --- |
| [Install](Install) | Create a `.venv` and install the project on Windows PowerShell, Linux Debian or macOS |
| [Usage](Usage) | Run the program and the tests |
| [Description](Description) | Understand how the code is built and why it has no runtime dependencies |
The code, the tests and the project documents are in the [repository](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel).
+15
View File
@@ -0,0 +1,15 @@
🌐 [English](Home) · [Dansk](Home.da) · **Bahasa Melayu**
# Banci Tupai
Hari ke-25 dalam *100 Days of Code: The Complete Python Pro Bootcamp* Udemy: kira tupai dalam Banci Tupai Central Park 2018 mengikut warna bulu utama (kelabu, kayu manis, hitam) dan eksport kiraan ke `squirrel_count.csv`.
![Larian program](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
| Halaman | Baca apabila anda mahu |
| --- | --- |
| [Pemasangan](Install.ms) | Mencipta `.venv` dan memasang projek di Windows PowerShell, Linux Debian atau macOS |
| [Penggunaan](Usage.ms) | Menjalankan program dan ujian |
| [Penerangan](Description.ms) | Memahami cara kod dibina dan sebab ia tiada kebergantungan masa jalan |
Kod, ujian dan dokumen projek berada dalam [repositori](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel).
+35
View File
@@ -0,0 +1,35 @@
🌐 [English](Install) · **Dansk** · [Bahasa Melayu](Install.ms)
# Installation
Projektet kræver **Python 3.13 eller nyere**. Det har ingen kørselsafhængigheder; `pytest`, `ruff`, `mypy`, `yamllint` og `actionlint` er udviklingsværktøjer.
## Windows PowerShell
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## Linux Debian
```bash
sudo apt install python3 python3-venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## macOS
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
Næste: [Brug](Usage.da).
+35
View File
@@ -0,0 +1,35 @@
🌐 **English** · [Dansk](Install.da) · [Bahasa Melayu](Install.ms)
# Install
The project needs **Python 3.13 or later**. It has no runtime dependencies; `pytest`, `ruff`, `mypy`, `yamllint` and `actionlint` are development tools.
## Windows PowerShell
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## Linux Debian
```bash
sudo apt install python3 python3-venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## macOS
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
Next: [Usage](Usage).
+35
View File
@@ -0,0 +1,35 @@
🌐 [English](Install) · [Dansk](Install.da) · **Bahasa Melayu**
# Pemasangan
Projek ini memerlukan **Python 3.13 atau lebih baharu**. Ia tiada kebergantungan masa jalan; `pytest`, `ruff`, `mypy`, `yamllint` dan `actionlint` ialah alat pembangunan.
## Windows PowerShell
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## Linux Debian
```bash
sudo apt install python3 python3-venv
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
## macOS
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
```
Seterusnya: [Penggunaan](Usage.ms).
+33
View File
@@ -0,0 +1,33 @@
🌐 [English](Usage) · **Dansk** · [Bahasa Melayu](Usage.ms)
# Brug
## Kør programmet
Med det virtuelle miljø aktivt, fra projektmappen:
```bash
python -m squirrel
```
Programmet læser `data/2018_Central_Park_Squirrel_Census_-_Squirrel_Data.csv`, skriver tallene for hver pelsfarve og gemmer `squirrel_count.csv`.
![Programkørsel](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
Brug andre filer med `python -m squirrel <optællingsfil> <opsummeringsfil>`. Findes optællingsfilen ikke, skriver programmet `Census file not found` og afslutter med status 2.
## Kør testene
```bash
python -m pytest
```
![Testkørsel](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/tests.png)
## Byg kildedokumentationen
```bash
doxygen Doxyfile
```
Åbn `docs/doxygen/html/index.html`.
+33
View File
@@ -0,0 +1,33 @@
🌐 **English** · [Dansk](Usage.da) · [Bahasa Melayu](Usage.ms)
# Usage
## Run the program
With the virtual environment active, from the project folder:
```bash
python -m squirrel
```
The program reads `data/2018_Central_Park_Squirrel_Census_-_Squirrel_Data.csv`, prints the colour counts and writes `squirrel_count.csv`.
![Program run](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
Use other files with `python -m squirrel <census file> <summary file>`. If the census file does not exist, the program prints `Census file not found` and exits with status 2.
## Run the tests
```bash
python -m pytest
```
![Test run](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/tests.png)
## Build the source documentation
```bash
doxygen Doxyfile
```
Open `docs/doxygen/html/index.html`.
+33
View File
@@ -0,0 +1,33 @@
🌐 [English](Usage) · [Dansk](Usage.da) · **Bahasa Melayu**
# Penggunaan
## Jalankan program
Dengan persekitaran maya aktif, dari folder projek:
```bash
python -m squirrel
```
Program membaca `data/2018_Central_Park_Squirrel_Census_-_Squirrel_Data.csv`, mencetak kiraan setiap warna bulu dan menulis `squirrel_count.csv`.
![Larian program](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/run.png)
Gunakan fail lain dengan `python -m squirrel <fail banci> <fail ringkasan>`. Jika fail banci tidak wujud, program mencetak `Census file not found` dan keluar dengan status 2.
## Jalankan ujian
```bash
python -m pytest
```
![Larian ujian](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/025-squirrel/raw/branch/main/docs/images/tests.png)
## Bina dokumentasi sumber
```bash
doxygen Doxyfile
```
Buka `docs/doxygen/html/index.html`.
+24
View File
@@ -0,0 +1,24 @@
<!-- Generated from wiki; edit the source pages, not the published wiki. -->
**Squirrel Census**
**English**
- [Home](Home)
- [Install](Install)
- [Usage](Usage)
- [Description](Description)
**Dansk**
- [Hjem](Home.da)
- [Installation](Install.da)
- [Brug](Usage.da)
- [Beskrivelse](Description.da)
**Bahasa Melayu**
- [Utama](Home.ms)
- [Pemasangan](Install.ms)
- [Penggunaan](Usage.ms)
- [Penerangan](Description.ms)