Files
pad/internal/server
xarmian 228abe9702 fix(store): a JSON blob that repeats a member is stored collapsed, so SQLite's json_extract and Go read the same value (BUG-2896) (#1547)
SQLite's json_extract reads the FIRST occurrence of a repeated member; Go
and Postgres jsonb read the LAST. Two doors stored such blobs raw:

- collection create/update with `traits` in the string wire form (the object
  form was already re-encoded). Measured: a PATCH whose pre-check read
  `playbook` was refused 409 by the unique index, which read `convention`.
- workspace import, for collection traits and item fields.

At each door, a blob in which some object repeats a member (any depth,
models.FirstDuplicateJSONKey, moved from internal/server) is stored
collapsed: traits as the parsed declaration's own encoding (what the
resolver reads), item fields as a map re-encode that keeps number literals
(last wins, as jsonb). Any other blob keeps its bytes.

Surfaces: collection create/update responses carry additive omitempty
warnings.collapsed_duplicate_keys; imports carry
X-Pad-Import-Collapsed-Duplicate-Keys (always set, "0" when clean) plus a
slog line per blob. No MCP tool can send `traits`, so no ToolSurfaceVersion
bump; a guard test fails if pad_collection gains a traits param.

Live census: 0 of 233 collections and 0 of 9,796 items affected.

Claude-Session: https://claude.ai/code/session_01A3rXV7GDLAhBe9mL4V6z2m
2026-09-25 16:24:50 -04:00
..