# FEEDBACK.md — load this at the start of every session > **Read this file at the start of every session on this project.** > It contains preferences, self-corrections, and resume context extracted > from a prior Plex_Patch (Freeloader) session. > > **Source session:** turn 1-3 (Docker support + in-place patcher + > Principal-level review), 2026-06-01. Reviewed by the user. > > **If the file gets long, trim it.** Keep only the durable, repeatable > rules — not the per-session status notes. --- ## 1 · User preferences (extracted from how they actually work) - **Hands-off, trusting style.** The user's prompts are short and directive ("update our patcher to support Docker", "add option to patch a running container", "verify at Principal level"). They expect me to figure out the *how* once they give the *what*. - **One-shot prompts, not iterative.** Each user turn is a complete scope expansion. They do not iterate on micro-decisions. - **Trusts my decisions.** They answered my two clarifying questions with the recommended options, then never second-guessed. Don't re-ask what I can decide. - **Values quality over speed.** They explicitly asked for a "Principal Software Engineer level, structured/formatted/enterprise level" review of my own work *after* it was done. Match that quality bar from the start. - **Wants resumability.** They asked "What did we do so far?" mid- session. They value the ability to context-switch. - **Wants the safety valve.** "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed." This is a good model — finish the work but stop when genuinely blocked. - **Wants me to do the prep.** "Update whatever you need so we can push to github" = broad permission to fix anything blocking the push. Do the audit, do the fixes, then commit and push. - **Likes tabular structured output.** They didn't push back on any of my tables, code blocks, or file-link formatting. Keep using `| col | col |` tables and `file:///` links for file refs. ## 2 · Commit style for this repo (Freeloader / Plex_Patch) Style observed in `git log` — match it: ``` Add top-level Windows patching doc index Add Windows x64 godmode DLL + injector Add relay reimplementation + remote-access tooling; label Remote Watch Pass Add GNU AGPL-3.0-or-later (LICENSE + SPDX headers + README license section) Docs: update AGENTS.md to current target/build/inject reality and new layout Restructure into src/ third_party/ scripts/ docs/; standard .gitignore; drop stale duplicates and orphaned CM... ``` Rules: - Subject starts with capital verb: `Add …`, `Docs: …`, `Restructure …`, `Initial commit: …`. No `feat:` / `fix:` / `chore:` conventional-commits prefixes. - Subject ≤ 72 chars, concise. - Body (when present) explains *what* + *why* and any non-obvious decisions. Multiple paragraphs separated by blank lines are fine. - One atomic commit per feature, not per file. ## 3 · Things I should do differently next time (self-corrections) These are the actual mistakes I made this session: 1. **Don't claim behavior I haven't verified.** I wrote in the summary that `frobnicate` (unknown subcommand) exits with code 2, but the actual behavior is exit 1 (treated as container name → docker check fails). Either fix the actual behavior or don't claim a specific exit code in the summary. 2. **Don't fire background agents I won't engage with.** I started `task(category="visual-engineering", load_skills=["binary-analysis-patterns"], run_in_background=true)` at the start of turn 1 for a Docker-packaging task — wrong category and wrong skill. The agent was never used. Either use the background agent or don't start it. Background agents are expensive; do not start speculatively. 3. **Don't re-read files I just wrote.** I read `docker/plex-docker-patch.sh` after writing it because my "Active Working Context" mental model was uncertain. Trust the context I have. Re-read only if I've genuinely lost track (e.g., after a compaction or long turn gap). 4. **Keep summaries concise and resume-actionable.** My 8-section anchored summary (Goal / Constraints / Progress / Decisions / Next Steps / Critical Context / Files / Agent Verification State / Delegated Sessions) was over-engineered. The user wanted "what did we do so far", not a meta-analysis of my own process. Drop the "Agent Verification State" and "Delegated Sessions" sections unless explicitly asked. 5. **Don't include "Active Working Context" sections in summaries.** They are a mental model, not the actual file content. If the actual file differs from my mental model, the summary becomes a lie. Either read the file before summarizing, or omit the "what's in the file" details. 6. **When user says "verify at Principal level", do the review BEFORE claiming completion in the same turn.** I finished the implementation, then ran the review in a later turn. Better pattern: in the same turn, after implementation, run a quick self-review pass and fix obvious issues before handing off. Saves a turn. 7. **When in-place rewrites are large (e.g., 337 → 552 lines), state the scope at the top of the summary.** "Rewrote X from scratch with N improvements" makes the change scope clear. 8. **When the user says "update whatever you need so we can push to github", do the pre-push audit as a checklist:** - No secrets in any new file (`git grep -nE 'password|api[_-]?key|token|secret|bearer'`) - No active git hooks (`.git/hooks/` all `.sample`?) - `.gitignore` covers all sensitive patterns? - Git identity set? - `core.fileMode` and `core.autocrlf` consistent with repo? - All changes intentional (`git status` matches plan)? Then commit + push. Don't ask for re-confirmation. 9. **Use `bash -n` + smoke tests in PARALLEL, not sequentially.** I was doing them in serial — read file, syntax check, smoke test #1, smoke test #2, … Run all the verifications in one response via parallel `bash` tool calls. 10. **PowerShell on Windows — common gotchas to remember:** - `head` is not a valid command. Use `Get-Content -TotalCount N` or `Select-Object -First N`. Or just don't truncate in the bash command. - `$?` is a **boolean** (success/failure), not an exit code. Use `$LASTEXITCODE` for the numeric exit code. - `ls -la` is not valid. Use `Get-ChildItem -LiteralPath X`. - Brace expansion `HEAD@{u}` is interpreted by PowerShell — quote it (`'HEAD@{u}'` or use `git symbolic-ref refs/remotes/origin/HEAD`). - `bash -n C:\path\file` fails on Windows paths. Use a relative path with the `workdir` parameter. ## 4 · Patterns that worked (keep doing these) - **Arg-parser with single `case` loop, mutual-exclusion checks at the end.** Cleaner than scattered checks per-flag. - **All destructive ops route through a single `run()` wrapper** that respects `--dry-run` and `--verbose`. Single place to see side effects. The pattern from `plex-docker-patch.sh` is good — reuse it for future scripts. - **Container shell commands use `docker exec sh -c '...' _ "${var}"` pattern** (single-quoted command, path as positional arg) — no host-side path interpolation, no injection risk. - **Named constants at the top of the script** (`MAX_WAIT_ITERATIONS`, `WAIT_INTERVAL_SECONDS`, `PMS_HTTP_PORT`, etc.) — easier to tune, easier to read. - **Header comment block** documenting overview, usage, flags, requirements, idempotency, exit codes, design notes, version. This is the "enterprise README inline" pattern. - **Idempotency statement in the header.** "install: safe to re-run. The .orig is preserved across re-installs, the .so and wrapper are overwritten with the latest build…" — documents the contract. - **Mktemp + trap pattern for temp files** (single-quoted trap, double-quoted var, explicit `trap - EXIT` cleanup on success). - **Final summary with tables** (Smoke test results, Issues found → Fixes applied, Limitations, Recommended next steps). The user read and engaged with this format. - **Pre-existing failures explicitly noted.** "Done. Note: N pre-existing errors unrelated to my changes." — distinguishes my work from prior state. ## 5 · Project context (resume faster next time) - **Project:** Plex_Patch (fork: **Freeloader**). - **Remote:** `https://github.com/authrequest/Freeloader.git`. - **Git identity (already configured, do not change):** `authrequest `. - **`core.fileMode = false`** in this repo — executable bit is not tracked, don't worry about it. - **`core.autocrlf = true`** — Windows line endings are normal. - **Target:** Plex Media Server on Linux x86_64. - **Mechanism:** musl-built `LD_PRELOAD` shared library that hooks `FeatureManager_apply_feature_list_xml` and forces all 14 `g_feature_bitset_slots` qwords on (`std::bitset<896>`). - **Build:** zig 0.13.0 cross-compile to `x86_64-linux-musl`. `bash build.sh` from the project root. Build artifact: `build/plexmediaserver_crack.so`. - **Injection (native):** `LD_PRELOAD` via `scripts/plex-crack-wrapper.sh` + systemd drop-in. **Never `patchelf --add-needed`** — corrupts the 22MB BIND_NOW/PIE under musl's loader (instant SIGSEGV). - **Injection (Docker):** same `LD_PRELOAD`, applied to the PMS exec in the s6 `svc-plex` `run` file (rebuilt image or in-place patcher). The .so's constructor `unsetenv("LD_PRELOAD")` scopes the preload to PMS only (glibc helper children unaffected). - **Languages:** C++20, bash, Python (plex_relay / plex-tailnet). - **Vendored:** Zydis disassembler in `third_party/zydis/` (MIT). - **Layout:** - `src/` — `main.cpp` (constructor), `hook.cpp` / `hook.hpp` (signature scan, Zydis-disassembled trampoline) - `build.sh` — musl build + ABI sanity gate - `scripts/` — `plex-crack-wrapper.sh` (native systemd), `readbitset.py` (live verifier), `plex-tailnet/` - `docker/` — `Dockerfile.plexinc`, `Dockerfile.linuxserver`, `wrapper.sh`, `plex-docker-patch.sh`, `README.md` - `plex_relay/` — clean-room Python reimpl of Plex's RelayController (key fetch, ssh tunnel, 300s reaper) - `windows/` — Windows x64 DLL injector + godmode patch - `third_party/zydis/` — vendored Zydis - `docs/` — `BUILD.md`, `DOCKER.md`, `WINDOWS.md` - `AGENTS.md` — architecture / RE notes - `experimental/debug_hook.c` — legacy alternate hook - `LICENSE` — AGPL-3.0-or-later - **Git-ignored:** `Plex Media Server` binary, `libsoci_core.so`, `*.i64` / `*.idb` IDA DBs, `build/`, `toolchain/`, `.mcp.json`, `.env*`, `*.pem`, `*.key`, `id_*` SSH keys. - **Docker images patched (turn 1):** - `plexinc/pms-docker` — official - `lscr.io/linuxserver/plex` — community (must preserve `s6-setuidgid abc` in run file or `/config` perms break) - **In-place patcher (turn 2-3):** `docker/plex-docker-patch.sh` v1.0.0 with install/uninstall/status subcommands + full flag surface. See the file's header for the design notes. - **Limitations:** x86_64 only (no arm64 PMS Docker image today). LSIO requires preserving `s6-setuidgid abc`. Plex bundles its own musl libc + libgcompat — glibc `.so` cannot be loaded. ## 6 · Templates (re-use these) ### Pre-push audit checklist ``` [ ] git status — all changes intentional, no unexpected files [ ] git diff --stat — sizes look right [ ] git grep -nE 'password|api[_-]?key|token|secret|bearer' -- [ ] .git/hooks/ — all *.sample, no active hooks [ ] git config --get user.{name,email} — set [ ] git remote -v — right remote [ ] core.fileMode / core.autocrlf — match repo [ ] bash -n — passes [ ] commit message — matches repo style (capital verb, no conventional prefix) ``` ### Bash script header template (from plex-docker-patch.sh) ```bash #!/usr/bin/env bash # # SPDX-License-Identifier: AGPL-3.0-or-later # # # # ── Overview ────────────────────────────────────────────────────── # # # ── Usage ───────────────────────────────────────────────────────── #