Commit Graph

21 Commits

Author SHA1 Message Date
Kpa-clawbot 1da2034341 refactor(db): move all writes from server to ingestor; server truly read-only (fixes #1283) (#1286)
**Red commit:** f6290b63 — CI run will appear at
https://github.com/Kpa-clawbot/CoreScope/actions

Fixes #1283.

## What

Moves all four DB write operations out of `cmd/server/` into
`cmd/ingestor/`, making the server truly read-only and eliminating the
SQLITE_BUSY VACUUM bug at its root: the server can no longer race the
ingestor for the write lock because the server has no write path.

## The four operations

| # | Was in | Now in |
|---|--------|--------|
| 1 | `cmd/server/vacuum.go` (`checkAutoVacuum`, full VACUUM +
`auto_vacuum=INCREMENTAL` migration) | `cmd/ingestor/db.go`
`Store.CheckAutoVacuum` (already existed; ingestor runs it at startup
**before** the MQTT subscriber starts → no contention) |
| 2 | `cmd/server/db.go` `PruneOldPackets` (`DELETE FROM transmissions`)
| `cmd/ingestor/maintenance.go` `Store.PruneOldPackets` (new) + 24h
ticker in `cmd/ingestor/main.go` |
| 3 | `cmd/server/db.go` `PruneOldMetrics` (`DELETE FROM
observer_metrics`) | `cmd/ingestor/db.go` `Store.PruneOldMetrics`
(already existed) |
| 4 | `cmd/server/db.go` `RemoveStaleObservers` (`UPDATE observers SET
inactive=1`) | `cmd/ingestor/db.go` `Store.RemoveStaleObservers`
(already existed) |

## HTTP surface

- **Removed:** `POST /api/admin/prune` (`handleAdminPrune`, route,
openapi entry). Operators trigger an ad-hoc prune by restarting the
ingestor.
- **Kept:** `GET /api/backup` — uses `VACUUM INTO` which writes to a
separate file, not the live DB; read-only-safe.

## Tests

- `cmd/server/readonly_invariant_test.go` (RED gate) — reflect-asserts
`PruneOldPackets`/`PruneOldMetrics`/`RemoveStaleObservers` are NOT
methods on the server's `*DB`. Fails on master, passes after this PR.
- `cmd/ingestor/issue1283_test.go` — exercises `Store.PruneOldPackets`
and the auto_vacuum=NONE → INCREMENTAL migration through
`Store.CheckAutoVacuum` with `vacuumOnStartup=true`.

## Why the bug is gone

The SQLITE_BUSY VACUUM failure happened because supervisord launched
both ingestor + server in one container; the ingestor took the write
lock for INSERTs and the server's `checkAutoVacuum` then failed to
acquire it within `busy_timeout=5000`. After this PR, only the ingestor
ever opens a writable connection, and it runs `CheckAutoVacuum`
**before** spawning the MQTT subscriber → no contention possible.

## Scope notes

- `cachedRW()` still has three pre-existing callers in `cmd/server/`
(`neighbor_persist.go`, `ensure_indexes.go`,
`from_pubkey_migration.go`). These pre-date #1283 and are not in the
issue's four-operation list. Leaving them for follow-up keeps this PR
honest about scope; AGENTS.md documents the invariant so new write paths
can't sneak in.
- PII preflight reports false positives on the Go method name
`requireAPIKey` in `routes.go` diff context — no real PII.
- Server-side neighbor-edge prune (`PruneNeighborEdges`) intentionally
left in place — out of scope of #1283.

---------

Co-authored-by: MeshCore Bot <bot@meshcore.local>
2026-05-18 23:52:27 -07:00
Kpa-clawbot 48923db3d0 Add deep linking rule to AGENTS.md (#535)
Adds a rule to AGENTS.md requiring all new UI states to be
URL-addressable (deep-linkable). Part of #536.

Co-authored-by: you <you@example.com>
2026-04-03 13:01:31 -07:00
Kpa-clawbot bf2e721dd7 feat: auto-inject cache busters at server startup — eliminates merge conflicts (#481)
## Problem

Every PR that touches `public/` files requires manually bumping cache
buster timestamps in `index.html` (e.g. `?v=1775111407`). Since all PRs
change the same lines in the same file, this causes **constant merge
conflicts** — it's been the #1 source of unnecessary PR friction.

## Solution

Replace all hardcoded `?v=TIMESTAMP` values in `index.html` with a
`?v=__BUST__` placeholder. The Go server replaces `__BUST__` with the
current Unix timestamp **once at startup** when it reads `index.html`,
then serves the pre-processed HTML from memory.

Every server restart automatically picks up fresh cache busters — no
manual intervention needed.

## What changed

| File | Change |
|------|--------|
| `public/index.html` | All `v=1775111407` → `v=__BUST__` (28
occurrences) |
| `cmd/server/main.go` | `spaHandler` reads index.html at init, replaces
`__BUST__` with Unix timestamp, serves from memory for `/`,
`/index.html`, and SPA fallback |
| `cmd/server/helpers_test.go` | New `TestSpaHandlerCacheBust` —
verifies placeholder replacement works for root, SPA fallback, and
direct `/index.html` requests. Also added tests for root `/` and
`/index.html` routes |
| `AGENTS.md` | Rule 3 updated: cache busters are now automatic, agents
should not manually edit them |

## Testing

- `go build ./...` — compiles cleanly
- `go test ./...` — all tests pass (including new cache-bust tests)
- `node test-frontend-helpers.js && node test-packet-filter.js && node
test-aging.js` — all frontend tests pass
- No hardcoded timestamps remain in `index.html`

---------

Co-authored-by: Kpa-clawbot <259247574+Kpa-clawbot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: you <you@example.com>
2026-04-01 23:59:59 -07:00
you 8f3d12eca5 docs: perf claims require proof — benchmarks, timings, or test assertions 2026-04-01 15:08:06 +00:00
you 357f7952f7 docs: add Rule 0 — performance-first mindset in AGENTS.md 2026-04-01 14:55:35 +00:00
Kpa-clawbot bd98a19662 docs: add rule 13 — git worktree isolation for parallel agents
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-30 21:46:42 -07:00
Kpa-clawbot 380da0ee0b docs: add AGENTS.md rule 12 — PR review follow-up comments (#301)
Adds rule 12 to AGENTS.md: when review feedback is addressed, post a
follow-up comment on the PR listing what was fixed with the commit hash.

Co-authored-by: Kpa-clawbot <259247574+Kpa-clawbot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-30 19:23:30 -07:00
Kpa-clawbot 4c371e3231 docs: add rule 11 — PR descriptions must be clean markdown
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-30 17:15:01 -07:00
Kpa-clawbot f438411a27 chore: remove deprecated Node.js backend (-11,291 lines) (#265)
## Summary

Removes all deprecated Node.js backend server code. The Go server
(`cmd/server/`) has been the production backend — the Node.js server was
kept "just in case" but is no longer needed.

### Removed (19 files, -11,291 lines)

**Backend server (6 files):**
`server.js`, `db.js`, `decoder.js`, `server-helpers.js`,
`packet-store.js`, `iata-coords.js`

**Backend tests (9 files):**
`test-decoder.js`, `test-decoder-spec.js`, `test-server-helpers.js`,
`test-server-routes.js`, `test-packet-store.js`, `test-db.js`,
`test-db-migration.js`, `test-regional-filter.js`,
`test-regional-integration.js`

**Backend tooling (4 files):**
`tools/e2e-test.js`, `tools/frontend-test.js`, `benchmark.js`,
`benchmark-ab.sh`

### Updated
- `AGENTS.md` — Rewritten architecture section for Go, explicit
deprecation warnings
- `test-all.sh` — Only runs frontend tests
- `package.json` — Updated test:unit
- `scripts/validate.sh` — Removed Node.js server syntax check
- `docker/supervisord.conf` — Points to Go binary

### NOT touched
- `public/` (active frontend) 
- `test-e2e-playwright.js` (frontend E2E tests) 
- Frontend test files (`test-packet-filter.js`, `test-aging.js`,
`test-frontend-helpers.js`) 
- `package.json` / Playwright deps 

### Follow-up
- Server-only npm deps (express, better-sqlite3, mqtt, ws, supertest)
can be cleaned from package.json separately
- `Dockerfile.node` can be removed separately

---------

Co-authored-by: you <you@example.com>
2026-03-29 15:53:51 -07:00
Kpa-clawbot cdcaa476f2 rename: MeshCore Analyzer → CoreScope (Phase 1 — backend + infra)
Rename product branding, binary names, Docker images, container names,
Go modules, proto go_package, CI, manage.sh, and documentation.

Preserved (backward compat):
- meshcore.db database filename
- meshcore-data / meshcore-staging-data directory paths
- MQTT topics (meshcore/#, meshcore/+/+/packets, etc.)
- proto package namespace (meshcore.v1)
- localStorage keys

Changes by category:
- Go modules: github.com/corescope/{server,ingestor}
- Binaries: corescope-server, corescope-ingestor
- Docker images: corescope:latest, corescope-go:latest
- Containers: corescope-prod, corescope-staging, corescope-staging-go
- Supervisord programs: corescope, corescope-server, corescope-ingestor
- Branding: siteName, heroTitle, startup logs, fallback HTML
- Proto go_package: github.com/corescope/proto/v1
- CI: container refs, deploy path
- Docs: 8 markdown files updated

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-28 14:08:15 -07:00
you 5182ea69a2 docs: add XP practices to AGENTS.md
Test-First, YAGNI, Refactor Mercilessly, Simple Design,
Pair Programming (subagent→review→push), CI as gate not cleanup,
10-Minute Build, Collective Code Ownership, Small Releases.

Each with concrete examples from today's failures.
2026-03-24 21:06:04 +00:00
you 3ccefb0fe8 docs: add engineering principles to AGENTS.md
DRY, SOLID, code reuse, dependency injection, testability,
type safety, performance. These were being violated repeatedly
(5 implementations of disambiguation, .toFixed on strings, etc).
Now explicitly codified as rules.
2026-03-24 21:03:07 +00:00
you 1061a6209e docs: AGENTS.md updated with all testing learnings + fix E2E default to localhost
- Full test file list with all 12+ test files
- Feature development workflow: write code → write tests → run locally → push
- Playwright defaults to localhost:3000, NEVER prod
- Coverage infrastructure explained (Istanbul instrument → Playwright → nyc)
- ARM testing notes (basic tests work, heavy coverage use CI)
- 4 new pitfalls from today's session
2026-03-24 05:16:16 +00:00
you 8a1bfd8b06 feat: code coverage with c8, npm test runs full suite
npm test: all tests + coverage summary
npm run test:unit: fast unit tests only
npm run test:coverage: full suite + HTML report in coverage/

Baseline: 37% statements, 42% branches, 54% functions
Fixed e2e channels crash (undefined .length on null)
2026-03-24 00:51:33 +00:00
you 84be29dcc8 docs: all tests must pass, all features must add tests — no exceptions 2026-03-24 00:47:29 +00:00
you d9012a005a docs: accurate test status, public API note, no fake 'known failures' 2026-03-24 00:03:36 +00:00
you b4558dea4d docs: remove hardcoded protocol details, point to firmware source files
Don't memorize protocol details from AGENTS.md — read the actual
firmware source. Lists exactly which files to check for what.
2026-03-24 00:00:43 +00:00
you 6324879d24 docs: list all 6 test files in AGENTS.md, not just 2 2026-03-23 23:59:49 +00:00
you 058fb5b0d0 docs: firmware source is THE source of truth for protocol behavior
Cloned meshcore-dev/MeshCore to firmware/ (gitignored).
AGENTS.md now mandates reading firmware source before implementing
anything protocol-related. Lists key files to check.
2026-03-23 23:58:58 +00:00
you 8bd9ce0431 docs: add rule — never check in private info (public repo) 2026-03-23 23:53:44 +00:00
you ac3577d719 docs: add AGENTS.md — AI agent guide based on 685 commits of lessons
Derived from git history analysis: 4.3x fix ratio, 12 reverts, 7 cache
buster regressions, 21 commits for hash size, 6 for QR overlay.

Rules: test before push, bump cache busters, verify API shape, plan
before implementing, one commit per change, understand before fixing.
2026-03-23 23:48:10 +00:00