Skip to content

v0.5.0 — Welle 6: tree wipe

Choose a tag to compare

@CyberGitJul CyberGitJul released this 29 Jul 12:51
· 44 commits to main since this release
0394cb6

Welle 6 — tree wipe. gramps_delete_all_objects empties a tree completely, so a reset to
exactly one source file is now export → wipe → import instead of one delete call per object.

  • New destructive tool gramps_delete_all_objects(confirm, expected_count) behind the existing
    GRAMPS_ENABLE_DESTRUCTIVE=1 gate. Both arguments are mandatory: expected_count must equal
    the tree's live total, so nothing is deleted unless the caller counted the tree first. A counts
    read that comes back empty is refused as well, rather than letting expected_count=0 through
    without the tree's real size ever being established.
  • Completion is confirmed by polling object_counts to zero, never /api/tasks/. Requires
    OWNER role. The call can run for minutes, so the failure modes are classified rather than
    guessed: a read timeout on the POST, or a 502/503/504 from a reverse proxy in front of a
    synchronous deployment, falls through to the counts poll instead of being reported as a
    failure — a connect timeout, where the request never landed, still fails fast, as does any
    other status. If the delete was accepted but the counts cannot then be read, the call raises
    DeleteAllStateUnknownError and points at gramps_get_object_counts: the counts, not the
    response, are the authority on what happened to the tree.
  • Fix: orphaned-note cleanup after gramps_delete_person / gramps_delete_blog_post now skips
    transport failures (connection reset, read timeout) as well as HTTP errors. Previously a
    network blip while tidying up notes propagated out of a delete that had already succeeded,
    so the caller got a bare network error instead of the before/after/deleted result this server
    exists to guarantee. A failure that is not a failed request still propagates. Pre-existing
    behaviour, not introduced by Welle 6.
  • Fix: gramps_import_file no longer reports a legitimately empty import as a timeout. An
    import that adds nothing now returns added: 0 once the counts have held steady for 30s,
    instead of running the full 300s and raising ImportTimeoutError for a success.
  • Packaging: mcp is now bounded to >=1.2.0,<2. mcp 2.0.0 removed mcp.server.fastmcp
    outright, which server.py imports, so an unbounded requirement makes docker build produce
    an image that builds fine and crashes on import. Raise the bound only together with the port
    to mcp.server.mcpserver.MCPServer — that is a real port, not a rename.
  • Docs/build hygiene: .env.example now names all four tools the destructive gate unlocks — it
    had omitted the wipe, which is the one with no undo, in the file you read while deciding
    whether to enable the gate. .dockerignore now excludes .env*, .venv/ and .git/ rather
    than the bare name .env.
  • Internals: the three 401→relogin branches were consolidated into one helper (with the
    characterization tests they never had), and import_file's polling loop was extracted as
    _wait_for_counts, now shared with the wipe. CI runs the 243-test suite alongside ruff.

Tools: 27 with the destructive gate off, 31 with it on.