`_works jupyter || _blocked "needs jupyter"` collapsed two different problems
into one message. "needs jupyter" and "jupyter is on PATH but does not run"
send you to different fixes -- install it, versus work out why the shim's
interpreter is gone -- and a status table is only worth keeping if it says
which. `_require_working` checks presence and then execution, and reports
them separately.
The wording is now what DOCS-runnability.md already said for twm_4 and PBAD,
except the probe produces it rather than someone having typed it. Regenerating
the table changed those two rows and nothing else, which is the useful part:
the run guard, the two new .venv directories under PSD and ERSMS-project, and
the tex entry-point change left all 44 courses' status exactly as it was.
One thing worth knowing for the next regeneration: the answer depends on PATH.
jupyter lives in ~/.local/bin, so a shell without it reports "needs jupyter"
and one with it reports the dead shim. Regenerate from a login shell.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The archive reached zero ruff findings this morning, so the standing rule in
.pre-commit-config.yaml -- a hook lands only once the thing it gates is clean
-- is finally satisfied for ruff. `ruff check` and `ruff format --check` are
hooks now, pinned at v0.16.5 per rules/dependency-freshness, plus
`no-suppressions`, which rejects `# noqa` and `# type: ignore`. CLAUDE.md has
always claimed a hook did that; until now the only thing stopping them was
whoever was reading ruff's output, and I typed `# noqa-free` three times in
this session by accident. mypy stays out: six of its errors are third-party
typing limits rather than our code.
The first attempt used `language: system`, which passed `pre-commit run
--all-files` and then failed the actual commit with "Executable `ruff` not
found" -- git hooks do not get ~/.local/bin on PATH. Taking the hooks from
astral-sh/ruff-pre-commit means pre-commit installs ruff itself, which is also
what makes the pin mean anything.
`ruff format --check` failed the moment it was wired up, on four TRAK files I
wrote today and never formatted. Formatted, and the ray_tracing0 render is
still 02484bdb6b6c1ddeff317d7e5566580f.
Then the run guard from f780d023 needed proving on more than TRAK, since it
now applies to every course kind. make, cpp and python courses pass it; node
and target and obj are all properly gitignored, so npm, maven and dotnet
builds cannot trip it either. But NotProgramming/MOM failed, and not because
of the guard:
`_first_file '*.tex'` used `find -print -quit`, which returns whatever readdir
hands back. After the 19 reports were split into sections, that was
`report_three/sections/02-model-dwukryterialny.tex`, and latexmk faithfully
tried to typeset a bare `\section` as a document. DOCS-runnability.md has
recorded MOM as runnable throughout. The tex branch now picks a file that
actually contains `\documentclass`.
Deliberately not sorted, and that is the interesting part. Sorting is the
obvious fix and it made things worse: it swapped ELAC's pick to projectA and
AIS's to report/final/ver1, both of which fail with latexmk exit 12. Those two
documents are broken independently, and sorting merely surfaced them; turning
two green courses red to fix a third is a bad trade. Recorded in
TODO-refactor-remaining.md instead. MOM, ELAC, AIS, SPD, ZPOB, SDM, DPZ and
ESOEN all exit 0 now.
`_works` also grew a `timeout 5`, because `unityhub --version` never returns
on this machine and a probe without one would hang the status sweep.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Executing coursework has silently overwritten a submitted deliverable twice in
this campaign -- TRAK's outputs/output.png and SPD's results_*.png -- and both
times it was found by a later `git status`, not by the run. `course_main` now
snapshots what git sees under the course root before and after `_run`, and
fails with a diff naming the files if anything moved. Gitignored build output
does not show up there, which is why every runner already writes into build/.
Seen failing before being trusted: a stub whose `_run` appends a newline to
TRAK's config.ini exits 1 and names the file; the same stub without the append
exits 0; and a real `./run.sh run Programming/TRAK` still exits 0 after
rendering, because it writes into build/.
The notebook branch was the specific landmine. `nbconvert --execute --inplace`
rewrites the notebook it just ran, and all four notebooks here are tracked with
their outputs. It now executes to a temp --output-dir. That alone is not
enough, though: nbconvert runs the kernel with its cwd set to the notebook's
own directory, so a cell calling plt.savefig('x.png') still writes beside the
notebook. The tree check above is what actually catches that, which is why it
lives in course_main and applies to every course kind rather than to notebooks.
`_have jupyter` was also the wrong probe. jupyter on this machine is a pipx
shim whose interpreter is gone: `command -v` finds it, and running it exits
127. Both the probe and the runner now use `_works`, which runs `--version`.
`./Programming/twm_4/run.sh --probe` reports "needs jupyter" and exit 78
instead of failing confusingly mid-run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kuhy overruled the "do not fix coursework to be better than it was submitted"
rule: git history is the archive, so the working tree can be clean. This lands
the config and the mechanical half of the cleanup -- 9,281 ruff findings under
the fleet config down to 3,686, with no per-file-ignores anywhere.
What is in here:
- pyproject.toml, the first one in this repo. select = ["ALL"], mypy strict,
and the vendored list mirrored into ruff exclude and coverage omit. Five
rules are off and each says why; CPY001 is the only judgement call, because
stamping a copyright header onto 137 university assignments would assert a
licence that was never claimed. No hook is wired up yet -- a gate lands only
once its subject is clean.
- ruff format + the safe fixes, then a second pass over the docstring rules
ruff marks unsafe (they only edit docstring text). 108 files.
- TRAK/sightpy is vendored, not coursework: it is rafael-fuente/Python-Raytracer
(BSD 3-Clause). Verified against a fresh upstream clone with line endings
normalised -- 30 of 32 files byte-identical, ray.py and scene.py carrying a
12- and 13-line local patch that counts rays for the report. 35 files that
should never have been linted, now excluded and restored.
- WDWR, SPD, MOM and ECRYPT are fully clean, by hand and verified by running
them: WDWR's three plot scripts print the same statistics as before, MOM's
PuLP model solves to the same cost. WDWR's graph.py had a 342-character CSV
header embedded as a string literal, which cannot be wrapped -- the data
moved to data/pareto_front.csv. Two 0-byte .py stubs are deleted; an empty
file is not a deliverable and git still has it.
Three harness bugs found by actually running things:
- `run` now forces MPLBACKEND=Agg. TRAK finished its ray trace in 37 seconds
and then sat for 45 minutes: plt.show() had opened an image viewer and was
waiting for someone to close the window.
- TRAK's main.py only pops that viewer with --show now, and its runner writes
to a gitignored build/ via the new --entry-args. The default output path is
outputs/output.png, which is TRACKED -- a plain run overwrote a submitted
deliverable.
- course_lib.sh was 357 lines, over this repo's own cap. Split into
course_probe.sh and course_run.sh.
Verified: ECOTE 26 tests pass, ECRYPT_PROJECT 99 pass, TRAK renders
cornell_box in 37s and exits 0, every module compiles, and every import ruff
removed was checked to be genuinely unused.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0172dj34FDpao6wsix8ZuCzE