sync: auto-sync from GURU-5070 at 2026-06-10 20:18:48
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-10 20:18:48
This commit is contained in:
26
.claude/memory/feedback_ascii_only_api_payloads.md
Normal file
26
.claude/memory/feedback_ascii_only_api_payloads.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: feedback_ascii_only_api_payloads
|
||||
description: On Windows/Git-bash, non-ASCII chars (em-dash, arrow, smart quotes) in JSON payload TEXT passed to curl get mangled and rejected — Discord bot-alert returns 400, the coord API returns "error parsing the body". Use ASCII-only in API payload text, or a single-quoted heredoc.
|
||||
metadata:
|
||||
type: feedback
|
||||
---
|
||||
|
||||
When building JSON API payloads on Windows/Git-bash and sending via `curl`, **non-ASCII characters
|
||||
in the text fields get mangled in transit and rejected by the server**, even though `jq -n`
|
||||
produces valid UTF-8 JSON. Hit twice on 2026-06-01:
|
||||
- `post-bot-alert.sh` → Discord **400** `{"message":"The request body contains invalid JSON","code":50109}` on a message containing `—` (em-dash) and `→` (arrow).
|
||||
- Coord todos API (`POST /api/coord/todos`) → **`{"detail":"There was an error parsing the body"}`** on todo text containing em-dashes (both the inline `$(jq -n ...)` and the `P=$(jq -n ...); curl --data-binary "$P"` patterns failed).
|
||||
|
||||
**Why:** the round-trip through a bash variable → `curl --data-binary` re-encodes/mangles the
|
||||
multibyte UTF-8 (Git-bash codepage quirk), so the bytes the server receives are no longer valid JSON.
|
||||
|
||||
**Fix:** keep API payload text **ASCII-only** — use `-` not `—`, `->` not `→`, straight quotes not
|
||||
smart quotes. The most robust transport is a **single-quoted heredoc** piped to curl:
|
||||
```bash
|
||||
curl -s -X POST "$API" -H "Content-Type: application/json" --data-binary @- <<'JSON'
|
||||
{"text":"ASCII only - no em-dashes or arrows","project_key":"..."}
|
||||
JSON
|
||||
```
|
||||
This bit the Syncro bot-alert (resolved by ASCII retry) and the coord-todo filings the same day.
|
||||
NOTE-TO-SELF tie-in: the project's NO-EMOJIS rule already pushes ASCII markers; extend that habit to
|
||||
all API payload text, not just console output.
|
||||
12
.claude/memory/reference_backblaze_storage_rate.md
Normal file
12
.claude/memory/reference_backblaze_storage_rate.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: reference_backblaze_storage_rate
|
||||
description: ACG's Backblaze B2 storage cost rate ($0.00695/GB) for the GuruRMM mspbackups storage-cost calculation
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
|
||||
ACG's Backblaze B2 storage rate is **$0.00695 per GB**. Use this as the cost input when calculating client storage cost in the GuruRMM **mspbackups** (MSP360) ability.
|
||||
|
||||
- Cost = stored_GB x 0.00695 (USD).
|
||||
- This is ACG's cost basis; client-facing markup/billing is a separate decision, not this figure.
|
||||
- The B2 storage-management credential is the vault entry `projects/claudetools/backblaze-b2.sops.yaml` (key name "ClaudeTools", manages buckets/keys for the mspbackups feature).
|
||||
33
.claude/memory/reference_sqlx_migrations_immutable.md
Normal file
33
.claude/memory/reference_sqlx_migrations_immutable.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: reference_sqlx_migrations_immutable
|
||||
description: NEVER edit an already-applied sqlx migration file — even a comment. sqlx::migrate! checksums each file at compile time and validates against _sqlx_migrations at startup; a changed checksum crash-loops the server with "migration N was previously applied but has been modified". Code review MUST flag any edit to an applied migration.
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
|
||||
GuruRMM and GuruConnect both apply DB migrations at server startup via `sqlx::migrate!()`
|
||||
(embedded at COMPILE time from `server/migrations/`). sqlx stores a **checksum** of each migration
|
||||
in the `_sqlx_migrations` table when it first applies it, and on every startup re-validates the
|
||||
embedded migration files' checksums against that table.
|
||||
|
||||
**Editing an already-applied migration file — even just a COMMENT — changes its checksum** and the
|
||||
server fails to boot:
|
||||
```
|
||||
ERROR Failed to run migrations: migration 8 was previously applied but has been modified
|
||||
```
|
||||
systemd then crash-loops it and eventually trips the start-limit ("Start request repeated too quickly").
|
||||
|
||||
**Incident 2026-06-01 (GuruConnect):** a one-line `ON CONFLICT` fix in `server/src/db/machines.rs`
|
||||
was bundled with a *comment-only* edit to `server/migrations/008_machine_uid.sql`. The code fix was
|
||||
correct, but the migration comment edit took the relay down for ~6 min on deploy. Both the Coding
|
||||
Agent and the Code Review Agent explicitly judged the comment edit "zero runtime effect" — WRONG.
|
||||
|
||||
**Rules:**
|
||||
- Applied migrations are **immutable**. Never touch them. To change schema, write a NEW migration.
|
||||
- If documentation about a migration needs fixing, put it in code comments / docs, NOT the migration file.
|
||||
- **Code review must reject ANY diff that touches a file under `server/migrations/` that has already
|
||||
been applied in prod** (or require a brand-new migration instead).
|
||||
- **Recovery:** restore the migration's exact original bytes (`git checkout <prev> -- path/to/NNN.sql`),
|
||||
rebuild (sqlx embeds at compile time, so a rebuild is required), restart. If systemd shows
|
||||
"Start request repeated too quickly", clear the limiter first: `sudo systemctl reset-failed <svc>`
|
||||
then `sudo systemctl start <svc>`.
|
||||
Reference in New Issue
Block a user