You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- SQLite connections now set journal_mode=WAL + busy_timeout=5000 so
concurrent UI/MCP writes queue instead of raising "database is locked"
- allocate_next retries (up to 5x) when a concurrent writer claims the
chosen IP, rolling to the next free candidate; race covered by test
- list_hosts search uses ilike for IP/MAC (uppercase MAC queries now match)
- Host.device_type widened String(16) -> String(40) to match DeviceType.name
- bulk_create_hosts docstring now includes desktop in the device-type list
- New batched subnets_out serialiser replaces per-subnet allocated/reserved
queries (two queries total) in the REST list endpoint and MCP list_subnets
- Brief updated: WAL pragmas and allocation retry behaviour
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: TLG-IPAM-Project-Brief.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -229,7 +229,7 @@ An IP is **free** iff all of the following hold:
229
229
230
230
Manual host creation (`POST /hosts`) only rejects the network/broadcast addresses — placing a host at the gateway, inside the DHCP pool, or inside a reserved range is deliberate and allowed.
231
231
232
-
`next-free`allocates the lowest free IP and creates the host record in a single transaction. The `UNIQUE(subnet_id, ip)` constraint is the backstop against races.
232
+
`next-free` allocates the lowest free IP and creates the host record in a single transaction. The `UNIQUE(subnet_id, ip)` constraint is the backstop against races: if a concurrent writer claims the chosen IP first, allocation re-reads the free list and rolls to the next candidate (up to 5 attempts) rather than surfacing a conflict.
233
233
234
234
Gateway, DHCP, reserved-range, and allocated-address exclusions are represented as clipped, merged integer intervals. Utilisation counts interval lengths, and free-IP iteration skips blocked spans rather than materialising every address in a range.
235
235
@@ -428,7 +428,7 @@ Follow this sequence to stay unblocked. Each step is independently runnable and
428
428
429
429
| Decision | Rationale |
430
430
|---|---|
431
-
| SQLite not Postgres | Zero ops overhead. A homelab IPAM will never have concurrent write contention. Backup = copy one file. |
431
+
| SQLite not Postgres | Zero ops overhead. A homelab IPAM will never have sustained write contention. Backup = copy one file. Connections run with `journal_mode=WAL` and `busy_timeout=5000` so the occasional simultaneous UI/MCP write queues instead of raising "database is locked". |
432
432
| FastAPI not Flask | Native async, automatic OpenAPI schema generation, Pydantic validation built in. |
433
433
| FastMCP with curated tools, not OpenAPI auto-generation | Hand-written tools have better names, parameters, and denormalised answers — materially better Claude ergonomics. Shared `services/` layer eliminates the drift risk that auto-generation was meant to solve. FastMCP is the actively-maintained de facto standard. |
434
434
| Streamable HTTP not stdio | Works with mcp-remote for Claude Desktop. Also compatible with any future MCP client without modification. |
0 commit comments