|
| 1 | +# Arrow: library-infrastructure |
| 2 | + |
| 3 | +Provides context lifecycle, hook routing, configuration, plugin loading, recording, device factory, and both the low-level hook API and high-level Simple API. |
| 4 | + |
| 5 | +## Status |
| 6 | + |
| 7 | +**MAPPED** - 2026-04-12. Full LLD written from brownfield reconnaissance. EARS specs written. Core infrastructure is stable and well-tested. Key gaps: broken hook chain detection, event queue overflow visibility. |
| 8 | + |
| 9 | +## References |
| 10 | + |
| 11 | +### HLD |
| 12 | +- [docs/high-level-design.md](../high-level-design.md) — "The Hook System: Connective Tissue", "Cross-Cutting Concerns" |
| 13 | + |
| 14 | +### LLD |
| 15 | +- [docs/llds/library-infrastructure.md](../llds/library-infrastructure.md) |
| 16 | + |
| 17 | +### EARS |
| 18 | +- [docs/specs/library-infrastructure-specs.md](../specs/library-infrastructure-specs.md) (29 specs) |
| 19 | + |
| 20 | +### Tests |
| 21 | +- src/test_cases/main.c, src/test_cases/test_case.h |
| 22 | +- src/test_cases/str.c |
| 23 | +- src/test_cases/export_config.c |
| 24 | +- src/test_cases/test_replays.c |
| 25 | + |
| 26 | +### Code |
| 27 | +- src/survive.c, src/survive_api.c |
| 28 | +- src/survive_config.c, src/survive_config.h |
| 29 | +- src/survive_plugins.c, src/survive_driverman.c |
| 30 | +- src/survive_recording.c, src/survive_recording.h |
| 31 | +- src/survive_default_devices.c |
| 32 | +- src/survive_str.c, src/survive_buildinfo.c, src/survive_gz.h |
| 33 | +- src/survive_internal.h, src/survive_private.h |
| 34 | +- include/libsurvive/ |
| 35 | +- redist/ (non-HID) |
| 36 | +- src/test_cases/ |
| 37 | + |
| 38 | +## Architecture |
| 39 | + |
| 40 | +**Purpose:** Provide the runtime environment — context, hooks, config, plugins, recording — that all other clusters run inside. |
| 41 | + |
| 42 | +**Key Components:** |
| 43 | +1. `survive.c` — Context init/poll/close; default hook implementations; button servicer thread |
| 44 | +2. `survive_api.c` — Simple API: background poll thread, event queue, object wrappers |
| 45 | +3. `survive_config.c` — Static-time registration + runtime access + file persistence |
| 46 | +4. `survive_plugins.c` — Retry-based `.so`/`.dll` discovery and loading |
| 47 | +5. `survive_recording.c` — Hook-intercepting recorder to `.rec.gz` |
| 48 | +6. `survive_default_devices.c` — `SurviveObject` factory from JSON config blobs |
| 49 | +7. `redist/os_generic.h` — Portable threads/mutexes/semaphores/timing |
| 50 | + |
| 51 | +## EARS Coverage |
| 52 | + |
| 53 | +| Category | Spec IDs | Implemented | Gaps | Deferred | |
| 54 | +|----------|----------|-------------|------|----------| |
| 55 | +| Context lifecycle | LI-API-001 to 005 | 4 | 1 | 0 | |
| 56 | +| Hook system | LI-BE-010 to 013 | 3 | 1 | 0 | |
| 57 | +| Configuration system | LI-BE-020 to 024 | 5 | 0 | 0 | |
| 58 | +| Plugin system | LI-BE-030 to 033 | 3 | 1 | 0 | |
| 59 | +| Device factory | LI-BE-040 to 042 | 3 | 0 | 0 | |
| 60 | +| Simple API | LI-API-050 to 053 | 3 | 1 | 0 | |
| 61 | +| Recording system | LI-BE-060 to 063 | 3 | 1 | 0 | |
| 62 | +| Threading | LI-BE-070 to 072 | 3 | 0 | 0 | |
| 63 | + |
| 64 | +**Summary:** 27 of 29 active specs implemented; 6 active gaps; 0 deferred. |
| 65 | + |
| 66 | +## Key Findings |
| 67 | + |
| 68 | +1. **Hook chaining is silently fragile** — Callers who install hooks but fail to chain to the previous handler silently break recording, the Simple API queue, and downstream processing. No runtime detection exists. (LI-BE-013) |
| 69 | + |
| 70 | +2. **Simple API event queue overflows silently** — Events are dropped without any counter or notification to the application. High button-event rates or slow consumers lose data invisibly. (LI-API-053) |
| 71 | + |
| 72 | +3. **`survive_close()` thread-safety undocumented** — The context mutex is recursive but not cross-thread-safe for close. Calling `survive_close()` from a callback thread can deadlock. No documentation warns against this. (LI-API-005) |
| 73 | + |
| 74 | +4. **Plugin failure diagnostics are weak** — When a plugin fails all load retries, the error message does not identify the missing symbol. Debugging new plugin dependencies requires manual `dlopen` inspection. (LI-BE-033) |
| 75 | + |
| 76 | +5. **`json_helpers.c` destructive parsing is undocumented** — The parser modifies its input string in-place. This is a correctness trap for callers who pass string literals or shared buffers. (`redist/json_helpers.c`) |
| 77 | + |
| 78 | +## Work Required |
| 79 | + |
| 80 | +### Must Fix |
| 81 | +1. Document `survive_close()` threading constraint — must be called from the init thread (LI-API-005) |
| 82 | + |
| 83 | +### Should Fix |
| 84 | +2. Add overflow counter to Simple API event queue so callers can detect dropped events (LI-API-053) |
| 85 | +3. Add debug-mode broken hook chain detection — warn when a hook is installed without chaining (LI-BE-013) |
| 86 | +4. Improve plugin load failure diagnostics to identify the missing symbol (LI-BE-033) |
| 87 | +5. Document `json_helpers.c` destructive parsing in the header |
| 88 | + |
| 89 | +### Nice to Have |
| 90 | +6. Add recording-open failure error path with graceful disable (LI-BE-063) |
| 91 | +7. Consider raising the 32-driver limit or making it dynamic (LI-BE-032) |
0 commit comments