|
26 | 26 | ### Gotcha |
27 | 27 |
|
28 | 28 | <!-- lore:019c91d6-04af-7334-8374-e8bbf14cb43d --> |
29 | | -* **Calibration used DB message count instead of transformed window count — caused layer 0 false passthrough**: Lore gradient calibration bugs that caused context overflow: (1) Used DB message count instead of transformed window count — after compression, delta saw ~1 new msg → layer 0 passthrough → overflow. Fix: getLastTransformedCount(). (2) actualInput omitted cache.write — cold-cache turns showed ~3 tokens instead of 150K → layer 0. Fix: include cache.write. (3) Trailing pure-text assistant messages cause Anthropic prefill errors, but messages with tool parts must NOT be dropped (SDK converts to tool\_result user-role). Drop predicate: \`hasToolParts\`. (4) Don't mutate message parts you don't own — removed stats PATCH that caused system-reminder persistence bug. |
30 | | - |
31 | | -<!-- lore:019cb171-c0ef-7335-9afd-e7874b507b77 --> |
32 | | -* **hostapd -t is not a config dry-run — it adds timestamps to debug output**: hostapd v2.10's \`-t\` flag means 'include timestamps in debug messages', NOT syntax check or dry-run. Running \`hostapd -t \<conf>\` fully initialises the interface and hangs as a running AP. There is no built-in config validation flag in hostapd. For validation, use grep-based checks for known-bad directives (e.g. checking for ieee80211r when it's not compiled in) rather than invoking hostapd itself. |
33 | | - |
34 | | -<!-- lore:019c91c0-cdf3-71c9-be52-7f6441fb643e --> |
35 | | -* **Lore plugin only protects projects where it's registered in opencode.json**: The lore gradient transform only runs for projects with lore registered in opencode.json (or globally in ~/.config/opencode/). Projects without it get zero context management — messages accumulate until overflow triggers a stuck compaction loop. This caused a 404K-token overflow in a getsentry/cli session with no opencode.json. |
| 29 | +* **Calibration used DB message count instead of transformed window count — caused layer 0 false passthrough**: Lore gradient/context management bugs and fixes: (1) Used DB message count instead of transformed window count — delta ≈ 1 after compression → layer 0 passthrough → overflow. Fix: getLastTransformedCount(). (2) actualInput omitted cache.write — cold-cache showed ~3 tokens → layer 0. Fix: include cache.write. (3) Trailing pure-text assistant messages cause Anthropic prefill errors. Drop loop must run at ALL layers including 0 — at layer 0 result.messages === output.messages (same ref), so pop() trims in place. Messages with tool parts must NOT be dropped (hasToolParts) — dropping causes infinite tool-call loops. (4) Lore only protects projects registered in opencode.json — unregistered projects get zero context management → stuck compaction loops creating orphaned message pairs. Recovery: delete all messages after last good assistant message (has tokens, no error). |
36 | 30 |
|
37 | 31 | <!-- lore:019cb171-c0ea-75cf-bf65-b081373f136b --> |
38 | 32 | * **mt7921e 3dBm tx power on desktop — disable CLC firmware table**: mt7921e/mt7922 PCIe WiFi cards in desktop PCs (no ACPI SAR tables like WRDS/EWRD) get stuck at ~3 dBm tx power because the CLC (Country Location Code) firmware power lookup falls back to a conservative default when no SAR table exists. Fix: set \`options mt7921\_common disable\_clc=1\` in /etc/modprobe.d/mt7921.conf. This lets the regulatory domain ceiling apply (e.g. 23 dBm on 5GHz ch44 in GB). Also set explicit tx power via \`iw dev \<iface> set txpower fixed 2000\` in ExecStartPost since the module param only takes effect on next module load/reboot. |
39 | 33 |
|
40 | 34 | <!-- lore:019cb171-c0fa-74b0-a9a6-847901efa907 --> |
41 | 35 | * **Pixel phones fail WPA group key rekey during doze — use 86400s interval**: Android Pixel devices in deep doze/sleep fail to respond to WPA group key handshake frames within hostapd's retry window. With wpa\_group\_rekey=3600, the phone gets deauthenticated every hour ('group key handshake failed (RSN) after 4 tries'). Other devices on the same AP complete the rekey fine. Fix: set wpa\_group\_rekey=86400 (24h) instead of 0 (disabled) for security balance. Also apply to Asus router: nvram set wpa\_gtk\_rekey=86400, wl0\_wpa\_gtk\_rekey=86400, wl1\_wpa\_gtk\_rekey=86400. |
42 | 36 |
|
43 | | -<!-- lore:019c91ad-4d47-7afc-90e0-239a9eda57a4 --> |
44 | | -* **Stuck compaction loops leave orphaned user+assistant message pairs in DB**: When OpenCode compaction overflows, it creates paired user+assistant messages per retry (assistant has error.name:'ContextOverflowError', mode:'compaction'). These accumulate and worsen the session. Recovery: find last good assistant message (has tokens, no error), delete all messages after it from both \`message\` and \`part\` tables. Use json\_extract(data, '$.error.name') to identify compaction debris. |
45 | | - |
46 | 37 | <!-- lore:019cb171-c0fe-78a8-a5f8-4ae8e2980a70 --> |
47 | 38 | * **sudo changes $HOME to /root — hardcode user home in scripts run with sudo**: When running a script with \`sudo\`, \`$HOME\` resolves to \`/root\`, not the invoking user's home. SSH key paths like \`$HOME/.ssh/id\_ed25519\` break. Fix: use \`SUDO\_USER\` env var: \`USER\_HOME=$(eval echo ~${SUDO\_USER:-$USER})\` and reference \`$USER\_HOME/.ssh/id\_ed25519\`. This is a common trap in scripts that need both root privileges (systemctl, writing to /etc) and user-specific resources (SSH keys). |
48 | 39 |
|
49 | 40 | <!-- lore:019c8f4f-67ca-7212-a8c4-8a75b230ceea --> |
50 | | -* **Test DB isolation via LORE\_DB\_PATH and Bun test preload**: Lore test suite uses an isolated temp DB via test/setup.ts preload (bunfig.toml). The preload sets LORE\_DB\_PATH to a mkdtempSync path before any test file imports src/db.ts, and the afterAll cleans up. src/db.ts checks LORE\_DB\_PATH first — if set, uses that exact path instead of ~/.local/share/opencode-lore/lore.db. agents-file.test.ts still needs beforeEach cleanup for intra-file isolation and TEST\_UUIDS cleanup in afterAll (shared explicit UUIDs with ltm.test.ts). Individual test files no longer need close() calls or cross-run cleanup beforeAll blocks — the preload handles DB lifecycle. |
| 41 | +* **Test DB isolation via LORE\_DB\_PATH and Bun test preload**: Lore test suite uses isolated temp DB via test/setup.ts preload (bunfig.toml). Preload sets LORE\_DB\_PATH to mkdtempSync path before any imports of src/db.ts; afterAll cleans up. src/db.ts checks LORE\_DB\_PATH first. agents-file.test.ts needs beforeEach cleanup for intra-file isolation and TEST\_UUIDS cleanup in afterAll (shared with ltm.test.ts). Individual test files don't need close() calls — preload handles DB lifecycle. |
51 | 42 |
|
52 | 43 | <!-- lore:019cb171-c0f5-741f-96cc-e0862c846202 --> |
53 | | -* **Ubuntu packaged hostapd lacks 802.11r (CONFIG\_IEEE80211R not compiled)**: Ubuntu 24.04's hostapd package (2:2.10-21ubuntu0.x) is compiled without CONFIG\_IEEE80211R. Using \`ieee80211r=1\`, \`mobility\_domain\`, \`ft\_over\_ds\`, \`r0kh\`, \`r1kh\`, or \`FT-PSK\` in wpa\_key\_mgmt causes 'unknown configuration item' errors and hostapd fails to start. 802.11k (rrm\_neighbor\_report, rrm\_beacon\_report) and 802.11v (bss\_transition) ARE compiled in and work. Verify with \`strings /usr/sbin/hostapd | grep ieee80211r\` — absence confirms no FT support. Building from source with CONFIG\_IEEE80211R=y is the only workaround. |
| 44 | +* **Ubuntu packaged hostapd lacks 802.11r (CONFIG\_IEEE80211R not compiled)**: Ubuntu 24.04 hostapd (2:2.10-21ubuntu0.x) lacks CONFIG\_IEEE80211R. Using \`ieee80211r=1\`, \`mobility\_domain\`, \`FT-PSK\` etc. causes 'unknown configuration item' and fails to start. 802.11k/v directives ARE compiled in. Verify: \`strings /usr/sbin/hostapd | grep ieee80211r\` — absence confirms no FT support. Build from source with CONFIG\_IEEE80211R=y. Note: hostapd has NO config dry-run flag — \`-t\` just adds timestamps to debug output and fully starts the AP. Use grep-based validation for known-bad directives instead. |
| 45 | + |
| 46 | +<!-- lore:019cb286-7c85-7039-aecf-25781892c9da --> |
| 47 | +* **Zod v4 .default({}) no longer applies inner field defaults**: Zod v4 changed \`.default()\` to short-circuit: when input is \`undefined\`, it returns the default value directly without parsing it through inner schema defaults. So \`.object({ enabled: z.boolean().default(true) }).default({})\` returns \`{}\` (no \`enabled\` key), not \`{ enabled: true }\`. Fix: provide fully-populated default objects — \`.default({ enabled: true })\`. This affected all nested config sections in src/config.ts during the v3→v4 upgrade. The import \`import { z } from "zod"\` is unchanged — Zod 4's main entry point is the v4 API. |
54 | 48 |
|
55 | 49 | ### Pattern |
56 | 50 |
|
|
0 commit comments