Quellcode durchsuchen

docs(MEMORY): document Lua 5.1 compatibility rule for all OpenWrt code

Adds a new 'Conventions' section to client2server/MEMORY.md that
codifies what the 5.1 audit just validated: every .lua file in
package/ must target plain Lua 5.1 (the OpenWrt default).

The section lists:
  - Forbidden features (5.2+/5.3+/5.4/LuaJIT-only constructs that
    would silently produce unparseable files)
  - Features to avoid (work in 5.1 but trap you on upgrade)
  - Safe features (full 5.1 stdlib)
  - A one-line validation gate: `luac5.1 -p <file>` before commit
  - The real-world bug that motivated this rule: commit 466fddc
    inserted a literal LF in a string literal, which left the Lua
    agent dead on every router for ~5 days until ff7bf22 fixed it

Also propagated a one-line pointer to the parent workspace
MEMORY.md under 'Documentation Tips' so the rule surfaces for any
future OpenWrt project, not just client2server.
Luis Rosales vor 2 Monaten
Ursprung
Commit
87f476dcb1
1 geänderte Dateien mit 57 neuen und 0 gelöschten Zeilen
  1. 57 0
      MEMORY.md

+ 57 - 0
MEMORY.md

@@ -11,6 +11,63 @@
 - Server can also push commands back to routers (uci_set, shell, reboot, wifi_restart, status).
 - Dashboard (new in 2.1) provides Apple-style web UI for monitoring and control.
 
+## Conventions
+
+### ⛔ All Lua code targets Lua 5.1 (OpenWrt default)
+
+OpenWrt ships **Lua 5.1** (with `compat-5.3` in some builds, but not all
+packages). Every `.lua` file under `package/` must parse and run cleanly
+on plain Lua 5.1. **Never use 5.2+/5.3+/5.4/LuaJIT-only features.**
+
+**Forbidden (will silently break on the router):**
+- `goto` / `::label::` statements (5.2+)
+- `continue` statement (5.2+)
+- `<close>` attribute on to-be-closed locals (5.4)
+- `integer` type, hex floats (`0x1.8p3`), `\xNN` escapes (5.3+)
+- `//` floor division, `&` `|` `~` `<<` `>>` bitwise operators (5.3+, LuaJIT)
+- `utf8.*` standard library (5.3+)
+- `table.move` / `table.pack` (5.2+/5.3); use `table.insert` + `table.remove`
+- `string.pack` / `string.unpack` / `string.dump` (3rd-arg signature 5.3+)
+- `<toclose>` metamethod pattern
+
+**Avoid (work in 5.1 but trap you later):**
+- Global `unpack` (use `table.unpack` if you must, or just `for i,v in ipairs`)
+- `setfenv` / `getfenv` (removed in 5.2)
+- `module(...)` (5.2 deprecates the implicit module function)
+
+**Safe to use (all in 5.1):**
+- `string.byte(s, i, j)` multi-return, `string.char(...)` with numeric args
+- `string.find` with 4th-arg `init`, `string.match`, `string.gmatch`,
+  `string.gsub` (string or function replacement)
+- `io.popen(cmd)` — always guard the result with `if f then`
+- `coroutine.create / resume / yield / status / wrap`
+- `pcall` / `xpcall` (single-arg or with custom message handler)
+- `math.floor / random / randomseed / min / max / huge` etc.
+- `pairs` / `ipairs` / `next`
+- Pattern escapes: `%a %A %d %D %s %S %w %W %l %u %c %C %p %P %x %X`
+- `table.insert(t, [pos,] v)`, `table.remove(t, [pos])`, `table.concat(t, sep)`
+- `debug` library (5.1+) — avoid in production; only for diagnostics
+
+**Validation gate (run before every commit that touches `.lua` files):**
+```bash
+luac5.1 -p package/src/client2server-unified.lua   # must exit 0
+```
+If `luac5.1` is unavailable locally, do a manual review against the
+forbidden-list above. CI on the router will surface real syntax errors
+at agent startup, but those are silent and look like a dead daemon.
+
+**Real-world example of a bug this rule would have caught:**
+Commit `466fddc` ("Print at start", 5 Jun 2026) introduced a literal
+newline inside a Lua string literal:
+```lua
+print("START
+")--[[
+```
+That `LF` should have been the two-character escape `\n`. The result
+was an unparseable file — the Lua agent was dead on every router for
+~5 days before commit `ff7bf22` fixed it. **Do not let this happen
+again.** A single `luac5.1 -p` before commit would have caught it.
+
 ## Stack
 | Layer | Tech |
 |-------|------|