Rules and facts about the MComix GTK4 code base that hold for many
iterations, split out of SKILL.md so that the protocol comes first when the
harness truncates the skill after a compaction. Facts about one installation
— fork, review status, decisions, finished campaigns — are in
state/project.md. Do not edit either; record contradictions under Prompt corrections.
- Bugs of every kind: logic, uncaught cases, races, state that outlives what owns it.
- Speed, measured, on the paths that run per page turn first.
- Idiom and structure, with the standards in
SKILL.mdfor refactors. - Comments that describe the code as it is now. Delete the ones that narrate a fixed bug or a removed workaround; write the missing ones where the code is genuinely not obvious; complete a comment that has drifted.
- Workarounds and deprecations. Remove shims for versions the floors no
longer allow, and say which version made each unnecessary. List what the
suite still reaches with
gates.sh deprecations. A deprecation notice names a replacement; check the replacement can do the job before porting to it. The names still reached are listed with their reasons under "Finished campaigns" instate/project.md; a new name there is a regression unless a new test is what reached it (compare with--ignore=<that test file>). - Incomplete features: options defined but never read, actions with no way to reach them, a behaviour offered in one place and missing from its twin.
- SQL in
mcomix/library/backend.pyand its callers: aWHEREno index covers (a composite primary key does not serve its second column), per-row loops where one statement would do, bulk writes outsidebackend.transaction()— the connection auto-commits every statement. - Dependencies: prefer what the raised floors now permit. Raising a floor
is the user's decision; ask under
Questions for the user. - Translations: complete and correct.
- Typing: keep mypy at zero, and read what is already annotated for types that are accepted but say nothing.
The standing emphasis, when no bug is known, is optimization, idiomatization and refactoring, with documentation and comment coverage close behind.
- A release is a commit the user orders, and that commit is what writes
the version, the
ChangeLog.mddate and the AppStream metainfo<release>entry (docs/releasing.mdhas the procedure). Nothing before it carries a guessed date, and whether a(unreleased)section is opened in the meantime is the user's practice, inSTATE/project.md. A plausible date is worse than a missing one, because nothing can tell it from a right one afterwards. - Python floor 3.12. The machine running the loop is usually newer, so a feature past 3.12 works here and breaks a supported install. Review https://docs.python.org/3/deprecations/index.html at that baseline when touching anything it lists.
- Dependencies: the floors in
pyproject.tomlare the truth; optional chardet and PyMuPDF, the latter at the versionPYMUPDF_VERSION_REQUIREDinmcomix/archive/pdf_multi.pynames, which a test enforces. Numbers are not repeated here because they drift.pygobject-stubsis built for GTK4 by default, which is what this code uses. - Archive handlers in
mcomix/archive/: zip, tar, rar (libunrar and external), 7z, lha, PDF (native PyMuPDF and external mutool), mobi. - Translations:
mcomix/messages/mcomix.potand one catalogue per language,.poand compiled.moboth committed. GTK's own catalogues (/usr/share/locale/<lang>/LC_MESSAGES/gtk40.mo) are LGPL and a legitimate source for common button labels. - The hot path is
image_tools.load_pixbufand everything reached fromMainWindow.set_page. Where gdk-pixbuf's loaders are sandboxed by glycin, any gdk-pixbuf call that touches a file costs about as much as decoding it, so a Pillow header read is far cheaper. - Structure:
MainWindowinmcomix/main.pydraws, lays out and navigates; the operations on the book's files and their undo stack areFileActionsinmcomix/file_actions.py. - Test data is in
test/files/: images in several JPEG and PNG modes with Exif-rotated variants (described intest/test_image_tools.py), and 68 archives including encrypted ones (passwordpassword). flake8ignores E501 by configuration;--select=Fis the gate.