From 6c12467f2da37d3a879c4878c36dde82d34836db Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Tue, 25 Aug 2026 21:31:32 +0200 Subject: [PATCH] ci: check out shared gates in pre-commit; add punchme icon `Pre-commit checks` has been red on main since 2026-08-24: the md-naming and file-length hooks are thin shims that exec the real gate out of the utils repo, and a runner has no ~/utils, so both died with "shared gate not found at /home/runner/utils/...". The dedicated md-naming.yml already checks utils out into .utils/; this does the same and points UTILS_ROOT at it, which is the override the shims already support. CI_GREEN_SKIP is set because this commit IS that fix. Also registers punchme (github.com/kuhyx/punchme) in the shared icon family on the family accent, Android-only so linux=False. Its glyph is a time card with a clipped corner, a column of four punched holes and three ruled lines; the first draft put two holes above two wide slots and read unmistakably as a face at every size. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/pre-commit.yml | 12 +++++ ...x-precommit-utils-checkout-2026-08-25.json | 48 +++++++++++++++++++ python_pkg/app_icons/_glyph_art_more.py | 24 ++++++++++ python_pkg/app_icons/apps.py | 9 ++++ python_pkg/app_icons/glyphs.py | 2 + 5 files changed, 95 insertions(+) create mode 100644 docs/superpowers/evidence/fix-precommit-utils-checkout-2026-08-25.json diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 251242a6..e92ede86 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -13,9 +13,21 @@ on: jobs: pre-commit: runs-on: ubuntu-latest + env: + # The md-naming / file-length hooks are thin shims that exec the shared + # gate out of the utils repo. A runner has no ~/utils, so without this + # checkout they fail with "shared gate not found" -- which is exactly + # how this workflow went red on 2026-08-24. + UTILS_ROOT: ${{ github.workspace }}/.utils steps: - uses: actions/checkout@v4 + - name: Check out the shared gates + uses: actions/checkout@v4 + with: + repository: kuhyx/utils + path: .utils + - uses: actions/setup-python@v5 with: python-version: "3.12" diff --git a/docs/superpowers/evidence/fix-precommit-utils-checkout-2026-08-25.json b/docs/superpowers/evidence/fix-precommit-utils-checkout-2026-08-25.json new file mode 100644 index 00000000..393115e6 --- /dev/null +++ b/docs/superpowers/evidence/fix-precommit-utils-checkout-2026-08-25.json @@ -0,0 +1,48 @@ +{ + "intent": "Turn the `Pre-commit checks` workflow green again on main, and register the new punchme app in the shared launcher-icon family.", + "scope": [ + ".github/workflows/pre-commit.yml", + "python_pkg/app_icons/{apps,glyphs,_glyph_art_more}.py", + "Non-goal: changing any gate's rules, or restyling the existing icon family" + ], + "changes": [ + "pre-commit.yml now checks out kuhyx/utils into .utils/ and points UTILS_ROOT at it. The md-naming and file-length hooks are thin shims that exec the real gate out of that repo; a runner has no ~/utils, so both failed with 'shared gate not found at /home/runner/utils/...' and the workflow has been red since 2026-08-24. The dedicated md-naming.yml already did this checkout — this copies the same approach rather than inventing one.", + "Registered app_icons entry 'punchme' (shared family accent #B8862E, glyph punch-card, linux=False since the app is Android-only).", + "Added the _PUNCH_CARD glyph: a time card with a clipped corner, a column of four punched holes and three ruled lines. The first draft put two holes above two wide slots and read unmistakably as a face (eyes over teeth) at every size, which is why the holes are now a vertical column." + ], + "verification": [ + { + "command": "UTILS_ROOT=/home/kuhy/utils bash scripts/check_md_naming.sh README.md", + "result": "pass", + "evidence": "Exit 0. With UTILS_ROOT=/nonexistent the same shim fails with 'shared gate not found at /nonexistent/scripts/check_md_naming.sh', so the override is what the fix relies on and it is proven in both directions." + }, + { + "command": "python3 -m pytest python_pkg/app_icons/tests -q", + "result": "pass", + "evidence": "44 passed. test_registry.py iterates every entry in APPS, so the new punchme entry's accent, glyph reference and repo path are all asserted without a bespoke test." + }, + { + "command": "python3 -m pytest python_pkg/app_icons/tests --cov=python_pkg/app_icons", + "result": "pass", + "evidence": "100% on every app_icons module, including _glyph_art_more.py with the new glyph." + }, + { + "command": "pre-commit run --files python_pkg/app_icons/_glyph_art_more.py python_pkg/app_icons/apps.py python_pkg/app_icons/glyphs.py", + "result": "pass", + "evidence": "All hooks passed, including pylint, bandit and 'pytest with coverage enforcement'." + }, + { + "command": "PYTHONPATH=~/testsAndMisc python3 -m python_pkg.app_icons generate --app punchme --android", + "result": "pass", + "evidence": "Wrote 6 asset files and regenerated the Android mipmaps with no safe-box warning. Rendered at full size, circle-masked and 48dp and reviewed each; legible at all three." + } + ], + "risks": [ + "The utils checkout pins no ref, so a breaking change to the shared gate lands in this repo's CI without a commit here. That matches how md-naming.yml already behaves, so this change does not add a new class of risk.", + "CI_GREEN_SKIP was set on the commit because the red baseline the gate objects to is the very thing this commit fixes." + ], + "rollback": [ + "git revert the commit; the workflow returns to its previous (red) state and no other behaviour changes.", + "After rollback, confirm `Pre-commit checks` is the only red workflow and that app_icons tests still pass, since the icon change is independent of the CI fix." + ] +} diff --git a/python_pkg/app_icons/_glyph_art_more.py b/python_pkg/app_icons/_glyph_art_more.py index ac8ac5df..45541052 100644 --- a/python_pkg/app_icons/_glyph_art_more.py +++ b/python_pkg/app_icons/_glyph_art_more.py @@ -75,3 +75,27 @@ M 332 520 L 692 520 A 40 40 0 0 1 732 560 L 732 752 A 40 40 0 0 1 692 792 \ L 332 792 A 40 40 0 0 1 292 752 L 292 560 A 40 40 0 0 1 332 520 Z \ M 512 580 A 40 40 0 0 0 492 655 L 480 716 L 544 716 L 532 655 \ A 40 40 0 0 0 512 580 Z"/>""" + + +# Punch card: a time card with a clipped top-left corner and a row of punched +# holes down one side, the way a real card is read by a column of sensors. +# +# An earlier version put two holes above two wide slots, which read as a face +# (eyes over teeth) at every size. Four holes in a vertical column with three +# short ruled lines beside them reads as a card instead. +# +# Geometry, all inside SAFE_BOX (232..792) and clear of MIN_NEGATIVE_SPACE=36: +# card x=292..732, y=232..792, top-left corner clipped 104px. +# holes r=34 at x=392, y=376/476/576/676. Centres 100 apart, so 32 of gap +# between edges... too tight, hence r=30 and 100 spacing -> 40 gap. +# lines three 46-tall bars from x=488 to x=652, aligned to the hole rows. +_PUNCH_CARD = """\ + """ diff --git a/python_pkg/app_icons/apps.py b/python_pkg/app_icons/apps.py index 33ffd04a..5ffc71b2 100644 --- a/python_pkg/app_icons/apps.py +++ b/python_pkg/app_icons/apps.py @@ -109,6 +109,15 @@ APPS: Final[dict[str, AppIcon]] = { # no GTK app to hand a hicolor PNG to. linux=False, ), + AppIcon( + key="punchme", + repo=_HOME / "punchme", + accent="#B8862E", + glyph="punch-card", + icon_name="punchme", + # Android-only app: no GTK desktop build to hand a hicolor PNG to. + linux=False, + ), AppIcon( key="habit_stack", repo=_HOME / "habit_stack", diff --git a/python_pkg/app_icons/glyphs.py b/python_pkg/app_icons/glyphs.py index 1f8a4b19..79ee6ad8 100644 --- a/python_pkg/app_icons/glyphs.py +++ b/python_pkg/app_icons/glyphs.py @@ -32,6 +32,7 @@ from python_pkg.app_icons._glyph_art import ( from python_pkg.app_icons._glyph_art_more import ( _NOTE_ASCENDER, _PADLOCK_CLOSED, + _PUNCH_CARD, _TRACK_BARS, ) @@ -60,6 +61,7 @@ GLYPHS: Final[dict[str, Glyph]] = { Glyph("cloud-down", "Cloud with a download arrow", _CLOUD_DOWN), Glyph("barbell", "Barbell with plates and collars", _BARBELL), Glyph("clock", "Clock face with hands", _CLOCK), + Glyph("punch-card", "Time card with punched holes", _PUNCH_CARD), Glyph("shield-cutlery", "Shield guarding a fork and knife", _SHIELD_CUTLERY), Glyph("checklist", "Two ticked-off list rows", _CHECKLIST), Glyph("chain-link", "Two interlocking chain links", _CHAIN_LINK),