Tests used test, test/1, and test/2 on 2026-05-28.
• put created test/1 and test/2 successfully.
• get(include_block_ids=true) returned revisions and stable block IDs for patching.
• batch handled metadata, block replacement, and appending atomically.
• patch with stale if_rev correctly failed with 409 revision mismatch.
• table_op table.set_cell updated a table cell and incremented the revision.
• batch insert ops (e.g. insert_after) that repeatedly target the same anchor block_id insert in reverse order, since each insert lands immediately after the anchor rather than after the previously-inserted block. A reorder op would let callers fix ordering after the fact without a full put rewrite. Recurred 2026-06-28; the refined design — set order by passing the full list of block IDs (total permutation, validated: reject on missing/unknown/duplicate), with an optional subset/relative mode — is written up in proposals/verb-taxonomy under the POST op set. Requirement (unchanged): this is a core server-side operation, exposed consistently through all three interfaces — MCP, HTTP API, and CLI — not an MCP-only convenience. (As a cheaper partial fix, insert ops could alternatively chain off the previous insert in the same batch rather than the original anchor.)
• Clarification (2026-06-28): full MCP tool set is 7, not 4. The tools are: get, put, keys, batch, delete, patch, table_op. Claude incorrectly reported only 4 tools as available — the other 3 are registered as deferred tools in Claude's system (requiring tool_search to load) and were therefore invisible without explicitly searching for them. This was a Claude-side visibility gap, not a server gap. No missing tools to implement; the delete item added above is withdrawn. The parity audit item below still stands — confirm all 7 MCP tools have equivalents on HTTP and CLI.
• batch insert ops (e.g. insert_after) that repeatedly target the same anchor block_id insert in reverse order, since each insert lands immediately after the anchor rather than after the previously-inserted block. A reorder op (move a block, or a list of blocks, to an absolute position or relative to another block) would let callers fix ordering after the fact without a full put rewrite. Alternatively, insert ops could chain off the previous insert in the same batch rather than the original anchor. This should be a core server-side operation, exposed consistently through all three interfaces: the MCP tools, the HTTP API, and the command-line tool — not added as an MCP-only convenience.
• Superseded 2026-07-09. put now returns {status, rev, block_ids} — observed live this session. The rev half is done and useful. The block_ids half should never have been asked for: Tier 1 verbs are dumb KV primitives and carry no block IDs (verb-taxonomy). The request has been struck from verb-api-implementation; the live behaviour is drift. Decide: remove it (breaking) or leave deprecated. Do not build on it — use get_ids.
• keys returns the entire key list as one large JSON payload. Add filtering, prefix search, pagination, or a separate keys(prefix=...) option for large stores.
• Missing-key and revision-mismatch failures are returned as text content containing JSON rather than surfaced as typed MCP errors. Consider exposing structured errors more directly if the MCP framework supports it.
• table_op worked but was noticeably slower than ordinary get/put/batch calls in this run. Investigate whether this is repeatable and whether table ops have avoidable overhead.
• Add an explicit MCP smoke-test note or script that exercises get/put/patch/batch/table_op and records expected responses, including a deliberate stale-revision failure.
• Follow-up from ChatGPT review: response-shape consistency, README/mcp-tools documentation drift, and manifest verification suggestions are recorded in gdata-server/todo/chatgpt-notes-review-2026-06-29.
• Session findings 2026-07-09 (agent editing incident). An agent silently overwrote the wrong block via replace_block. batch was then reproduced in isolation and cleared: bare replace_block, patch_meta+one replace, and patch_meta+two replaces all targeted exactly the named blocks. There is no off-by-one in the batch handler — do not go looking for one. The cause was the caller mis-mapping the parallel block_ids array onto document.content. Two interface fixes follow, specced as Phase 1b in verb-api-implementation: an expect guard on block-targeting ops (a wrong block ID currently always succeeds — silent corruption, contrary to philosophy), and get_ids returning IDs inline per block rather than as a positionally-coupled sidecar array.
• Considered and rejected 2026-07-09: an IDs-only fetch endpoint. Proposed as a cheap POST returning just the block-ID list. Rejected because it strips the content that anchors an ID to its block, and so makes the mis-mapping failure above more likely, not less; it also opens a stale-ID window unless threaded through if_rev. The correct endpoint is the already-specified get_ids, which returns {document, rev, block_ids} — IDs with their content. Recorded here so the idea is not re-proposed.
• Session findings 2026-07-10 (notes-browser/todo edit). Two issues hit while editing notes-browser/todo on the public store: (1) replace_block with a valid block_id and correct if_rev did not replace the target block — it left the old block in place and inserted the new content as an extra block elsewhere in the document, producing a duplicate. Had to detect this by re-reading with include_block_ids=true and manually delete_block the leftover. (2) A same-session batch call against the same key, with the same if_rev that had just worked for patch, failed with "key not found: notes-browser/todo" (404) even though the key demonstrably exists and was being edited successfully via patch moments before and after. Not yet root-caused; noted here rather than assumed to be caller error, since the corresponding tool-loading and parameter names were correct. Suggest: (a) add a server-side invariant test that replace_block never increases block count for a given call, (b) check whether batch resolves keys through a different code path/cache than patch/get that can go stale or miss the public/private store distinction.
• Resolved 2026-07-09: reorder is MCP-only, by decision. The tool exists and works (total permutation, if_rev honoured; parameter is order, not block_ids; test_reorder.py is in the suite). Its absence from HTTP and CLI is intended, not drift: those callers have a local file and an editor, so they reorder lines and PUT. The old standing requirement — "reorder is a core server-side operation exposed consistently through all three interfaces, not an MCP-only convenience" — is withdrawn; see verb-taxonomy → Interface Parity. What survives: one shared core, no duplicated per-transport logic, and every divergence documented. The parity audit below is rescoped — hunt for undocumented divergence and duplicated code paths (notably gdata_mcp_server.py's own REST batch route), not for uniform surface. Still to do: document reorder and its order parameter in README/mcp-tools.
• Audit feature parity across the three interfaces (MCP, HTTP API, CLI): check whether each operation supported by one is supported by the others, and identify any interface-specific functionality (e.g. table ops, batch, reorder once added) worth porting across so the three stay consistent.
No data outside the explicit test namespace was modified by the interface tests, except for this todo report and the todo link to it.