Use python3 as the canonical command name course-wide (#104)
CI / check (pull_request) Successful in 7s

Most current systems (default Debian/Ubuntu, recent macOS) install Python
only as `python3`, with no bare `python` on PATH, so learners who copied
`python cli.py ...` into their host shell hit "command not found".

Convert host-shell `python <cmd>` -> `python3 <cmd>` across module/lab
READMEs, lab `.py` docstrings & usage strings, blog posts, lab prompt and
instruction files, the M04 verify.sh message, and the M10/M24 lab patches.
Module 01's convention note (and its blog/02 mirror) is rewritten so
`python3` is canonical and `python` is the documented fallback.

Stop-lines respected: Docker image tags (`python:3.12-slim`), `.venv/.../python`
and `...\.venv\Scripts\python.exe` paths, the M20 `"command": "python"`
teaching example and surrounding venv prose, container-internal invocations
(M16/M18 Dockerfiles, M16 README `docker run` examples), and CI-workflow
`run:` steps fed by `actions/setup-python` / `image: python:3.12` are left
as `python` on purpose.

pip was left out of scope: most occurrences are prose or CI/container-internal,
and `pip3` does not fix the PEP 668 externally-managed-environment refusal that
the course already addresses with venvs. The M01 note is worded to stay
consistent with bare `pip` (use whichever pip pairs with your Python).

Build (tools/build_wiki.py) and tools/check.sh both pass.

Closes #104

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GAEzanEoGJT5o1VizQar47
This commit is contained in:
2026-06-23 20:18:04 -04:00
parent 7f439212ac
commit 3221f7abe8
102 changed files with 380 additions and 378 deletions
+9 -9
View File
@@ -184,7 +184,7 @@ This is the real production loop with the forge plumbing simulated locally.
**You'll need:**
- Python 3.10+ (`python --version`).
- Python 3.10+ (`python3 --version`).
- The lab files in `~/ai-workflow-course/modules/24-assistive-agents/lab/`.
- Claude Code (`claude --version`; sub your own agent), the editor/CLI agent from Module 4.
@@ -205,7 +205,7 @@ it runs the scripts and writes the files. You verify at the gate.
```
You: In ~/ai-workflow-course/modules/24-assistive-agents/lab, run
`python reviewer.py apply ai-review.sample.json` and show me the output.
`python3 reviewer.py apply ai-review.sample.json` and show me the output.
```
Read what comes back: comments sorted by severity, a recommendation, and then the **human decision
@@ -215,7 +215,7 @@ it runs the scripts and writes the files. You verify at the gate.
the reviewer, and write its JSON review to a file:
```
You: Run `python reviewer.py prompt`, follow the rubric in that output to review the diff, and
You: Run `python3 reviewer.py prompt`, follow the rubric in that output to review the diff, and
save your review as JSON to my-review.json.
```
@@ -226,7 +226,7 @@ it runs the scripts and writes the files. You verify at the gate.
3. Have the agent render its own review through the gate:
```
You: Run `python reviewer.py apply my-review.json` and show me the result.
You: Run `python3 reviewer.py apply my-review.json` and show me the result.
```
4. **Make the human decision. This part stays yours.** Open `feature.patch` and check the agent's
@@ -243,7 +243,7 @@ A new issue just arrived: `sample-issue.md` (the `done` command crashes on an em
1. See the loop with the canned response:
```
You: Run `python triage.py apply ai-triage.sample.json` and show me the output.
You: Run `python3 triage.py apply ai-triage.sample.json` and show me the output.
```
Read the suggested labels, the route, and the **human confirm gate**. The agent applied nothing.
@@ -252,14 +252,14 @@ A new issue just arrived: `sample-issue.md` (the `done` command crashes on an em
and save its suggestion:
```
You: Run `python triage.py prompt`, follow it to triage the issue using only the committed
You: Run `python3 triage.py prompt`, follow it to triage the issue using only the committed
taxonomy, and save your JSON suggestion to my-triage.json.
```
3. Render the suggestion through the gate:
```
You: Run `python triage.py apply my-triage.json` and show me the result.
You: Run `python3 triage.py apply my-triage.json` and show me the result.
```
4. **Watch the guardrail.** The script validates every suggested label against the committed
@@ -340,8 +340,8 @@ This is expansion-zone material; the agent-tooling landscape moves fast. Re-chec
merge/close, so comment/label-only is actually grantable? Name two that do.
- [ ] Is the turnkey "AI review bot / app" framing still accurate, or has the dominant pattern shifted
(e.g. baked into the forge, or into editor agents)? Keep the description vendor-neutral.
- [ ] Confirm the lab scripts run on a current Python (`python reviewer.py apply ai-review.sample.json`
and `python triage.py apply ai-triage.sample.json`) with no dependencies.
- [ ] Confirm the lab scripts run on a current Python (`python3 reviewer.py apply ai-review.sample.json`
and `python3 triage.py apply ai-triage.sample.json`) with no dependencies.
- [ ] Re-verify the cross-references resolve to the right module numbers (9, 10, 13, 14, 15, 22, 25)
if any modules were renumbered.
- [ ] Check that nothing here pins a specific LLM vendor or a specific bot's config filename.
@@ -6,8 +6,8 @@ index 91e9276..b2c4f1a 100644
def main(argv: list[str]) -> int:
tlist = load()
if not argv:
- print("usage: python cli.py [add <title> | list | done <index>]")
+ print("usage: python cli.py [add <title> | list | done <index> | clear]")
- print("usage: python3 cli.py [add <title> | list | done <index>]")
+ print("usage: python3 cli.py [add <title> | list | done <index> | clear]")
return 1
command = argv[0]
+2 -2
View File
@@ -4,8 +4,8 @@ This stands in for a forge-native reviewer (an app/bot triggered when a PR opens
runner from Module 19) without needing any hosted account. It does the two deterministic halves of
the job and leaves the one judgment call (what actually happens to the PR) to you.
python reviewer.py prompt # assemble the prompt: rubric + diff, for the agent to review
python reviewer.py apply ai-review.sample.json # ingest the agent's JSON, render it, gate it
python3 reviewer.py prompt # assemble the prompt: rubric + diff, for the agent to review
python3 reviewer.py apply ai-review.sample.json # ingest the agent's JSON, render it, gate it
The point of this module: the agent produces comments and a recommendation. It never approves,
never requests-changes-as-a-gate, never merges. The `apply` step ends at a HUMAN DECISION, every
@@ -1,12 +1,12 @@
Title: `done` command crashes on an empty list
When I run `python cli.py done 0` right after a fresh checkout, before adding any tasks, it throws
When I run `python3 cli.py done 0` right after a fresh checkout, before adding any tasks, it throws
an IndexError and dumps a stack trace instead of a friendly message. Every other command handles the
empty-list case fine, so this one feels like an oversight.
Steps to reproduce:
1. Delete tasks.json (or clone fresh).
2. Run `python cli.py done 0`.
2. Run `python3 cli.py done 0`.
3. See the traceback.
Expected: a clear message like "no task at index 0", exit non-zero, no traceback.
+2 -2
View File
@@ -4,8 +4,8 @@ Stands in for a forge-native triage agent (triggered when an issue opens) withou
It assembles the prompt, then validates and renders the AI's suggestion, and stops at a human
confirm. The agent proposes labels and a route; it does not apply them.
python triage.py prompt # taxonomy + issue -> prompt for the agent
python triage.py apply ai-triage.sample.json # validate + render + confirm gate
python3 triage.py prompt # taxonomy + issue -> prompt for the agent
python3 triage.py apply ai-triage.sample.json # validate + render + confirm gate
The validation step matters: the agent may only use labels that exist in label-taxonomy.md. A
hallucinated label is rejected. Stdlib only, no pip install.