21 lessons. Most-repeated first.
Get-Content/Set-Content: it reads UTF-8 as cp1252 and writes a BOM, so every non-ASCII character becomes mojibake (≥ -> ≥). Edit from Python with encoding="utf-8" and keep LF; add a test that tracked text files have no BOM and no mojibake.--query "" argument, which shifts every later argument. Omit the flag instead of passing an empty string.(Get-Content f -Raw).Replace(..) | Set-Content -Encoding utf8 reads UTF-8 as ANSI and writes back mojibake (“·” -> “·”) plus a BOM. Edit source files with Python (read_text/write_text encoding=’utf-8’) only; if it happens, fix with text.encode(‘cp1252’).decode(‘utf-8’).git ls-files --eol and convert back to CRLF before committing.add_card.py rewrote apps.json with LF while the repo file is CRLF (diff showed the whole file). Restore CRLF before committing so the diff is only the new card.*> logs are UTF-16; a cp1252 console crashed a bench on a Chinese print (set PYTHONIOENCODING=utf-8); Python write_text turns LF into CRLF - write bytes. 6) Compress-Archive on a 440 MB PyInstaller folder takes far longer than the build itself under load and the zip size looks stuck meanwhile; check the file lock before assuming it died. 7) The skill’s shared portfolio state clone can hold another session’s unpushed commit - edit the catalog in a fresh clone instead.apps.json is LF in the skill’s clone; check the bytes before “restoring” CRLF. In a shared clone with someone else’s untracked files, add your files by name instead of git add -A.*> writes UTF-16 logs; Python write_text on Windows writes CRLF (pass newline=”\n”); run anything over ~60 s as a detached script with a log file.\r\n; normalise it before pasting into an LF file, and read line endings with git ls-files --eol.CREATE_NO_WINDOW combined with DETACHED_PROCESS shows a console on the desktop; use CREATE_NO_WINDOW alone for background jobs.svchost.exe means the Task Scheduler started it.Path.write_text on Windows turns LF into CRLF; write bytes when a tracked file must keep its line endings.... | Set-Content file pipeline keeps the file locked until the command ends.Path(windows_path).name does nothing useful on Linux; use PureWindowsPath for paths written on Windows. Wait for the Linux CI run before calling a release done (the first v0.3.0 run failed there).