Skip to content

Commit 696c77b

Browse files
committed
docs(spec): trim per-driver table and PRAGMA listing to clear Sonar gate
SonarCloud quality-gate kept failing at 3.5% duplication on new code because the spec's "Per-driver config defaults" table and "SQLite tuning" code block were lifted near-verbatim from CLAUDE.md (and the implementation sites in internal/config/config.go and internal/storage/factory.go). Replace both with a short pointer to CLAUDE.md / factory.go so the spec still tells the story (problem, decision, migration notes) but stops copying the operator-facing reference data verbatim. CLAUDE.md remains the authoritative table; the spec is now a thinner historical record.
1 parent 210d14f commit 696c77b

1 file changed

Lines changed: 16 additions & 33 deletions

File tree

docs/superpowers/specs/2026-05-24-mcp-7tool-sqlite-survival-design.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -107,42 +107,25 @@ forensic-analytics workflow (`get_investigations`, `get_investigation`,
107107

108108
### SQLite tuning
109109

110-
After `gorm.Open` succeeds with `DB_DRIVER=sqlite`, apply these PRAGMAs in
111-
order with fail-closed error handling:
112-
113-
```go
114-
pragmas := []string{
115-
"PRAGMA journal_mode=WAL", // existing
116-
"PRAGMA synchronous=NORMAL", // existing
117-
"PRAGMA cache_size=-262144", // 256 MB page cache (new)
118-
"PRAGMA temp_store=MEMORY", // new
119-
"PRAGMA mmap_size=1073741824", // 1 GB mmap (new)
120-
"PRAGMA wal_autocheckpoint=10000", // new — keeps WAL bounded
121-
"PRAGMA journal_size_limit=67108864", // cap WAL at 64 MB (new)
122-
"PRAGMA busy_timeout=5000", // existing
123-
}
124-
```
125-
126-
A PRAGMA failure is fatal — these are not optional, and silent fallback
127-
to defaults defeats the survivability goal.
110+
`internal/storage/factory.go` applies an 8-PRAGMA stanza (WAL mode, sync
111+
NORMAL, 256 MB page cache, MEMORY temp store, 1 GB mmap, 10k-page
112+
autocheckpoint, 64 MB WAL cap, 5s busy_timeout) immediately after
113+
`gorm.Open` when the driver is SQLite. Any PRAGMA failure aborts startup
114+
— these are not optional, and silent fallback to defaults defeats the
115+
survivability goal. CLAUDE.md "SQLite PRAGMA stanza" enumerates each
116+
PRAGMA with its rationale.
128117

129118
### Per-driver config defaults
130119

131-
The following defaults override the Postgres-tuned defaults when
132-
`DB_DRIVER=sqlite`, only if the operator has not explicitly set the env
133-
var (detected via `os.LookupEnv`, not value comparison):
134-
135-
| Env var | SQLite default | Postgres/MSSQL default | Reason |
136-
|---|---|---|---|
137-
| `DB_MAX_OPEN_CONNS` | 1 | 50 | SQLite single-writer; multiple open conns are wasted slots. |
138-
| `DB_MAX_IDLE_CONNS` | 1 | 10 | Match open conns. |
139-
| `INGEST_PIPELINE_WORKERS` | 2 | 8 | 8 workers all serialize through the SQLite writer lock anyway; 2 is enough to keep the writer queue non-empty without pushing extra work into heap. |
140-
| `INGEST_PIPELINE_QUEUE_SIZE` | 10000 | 50000 | Smaller queue = lower heap watermark; backpressure kicks in earlier so OTLP clients back off rather than us OOMing. |
141-
| `METRIC_MAX_CARDINALITY` | 3000 | 10000 | Bound the TSDB series map. 120 services × 25 series/service still fits. |
142-
| `STORE_MIN_SEVERITY` | `WARN` | `""` (== ingest) | Skip INFO/DEBUG persists on the SQLite path — in-memory GraphRAG/anomaly detection still benefits from the full stream. |
143-
| `SAMPLING_RATE` | 0.05 | 1.0 | Trace volume is the primary disk-growth contributor. 5% sample at 120 services ≈ what 1.0 used to do at 6 services. |
144-
| `GRPC_MAX_CONCURRENT_STREAMS` | 240 | 1000 | Each stream costs heap; 120 services × 2 = 240 covers the deployment with no overhead. |
145-
| `LOG_FTS_ENABLED` | `true` | n/a | FTS5 is dramatically faster than LIKE on the kept `search_logs` path; operators who want the ~30% disk savings can opt out. |
120+
When `DB_DRIVER=sqlite`, `config.Load()` overrides nine defaults that are
121+
otherwise Postgres-tuned. The override applies only when the operator did
122+
not set the env var explicitly (detected via `os.LookupEnv` presence, not
123+
value comparison). The authoritative table — env var, SQLite default,
124+
Postgres default, and per-row rationale — lives in `CLAUDE.md` under
125+
"SQLite per-driver defaults". The implementation in
126+
`internal/config/config.go::applyDriverDefaults` and its tests in
127+
`internal/config/driver_defaults_test.go` are the runtime source of
128+
truth.
146129

147130
### `search_logs` backend swap
148131

0 commit comments

Comments
 (0)