all: delete the code nothing calls
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Web typecheck and unit tests (push) Successful in 8s
CI & Build / Python tests (push) Successful in 10s
CI & Build / integration (push) Failing after 1m21s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m47s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 2m48s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m39s
Desktop (Tauri) / Update manifest (push) Successful in 3s
Android / Kotlin + Rust (APK) (push) Successful in 8m37s

From the audit (#5178). Each was unreachable from every client:

- Checklist add-item and delete-item: REST POST /items and DELETE /items/<id>,
  the Tauri commands, the store, rest and local adapters, the core's
  add_item/delete_item, set_item_text and remove_item, and the FFI exports.
  Adding, rewording and removing an item are body edits in every editor. The
  checked toggle stays, and its rewriter is simpler without the drop branch.
- Manual unfurl: POST /unfurl and its adapters. Previews arrive in the
  background after a save (unfurl_queue).
- The /api/config `android_client` key, android_release() and the
  APK_NAME/MANIFEST_NAME aliases. Phones poll /api/client/android.
- users.email_verified and users.avatar_path (migration 0037). Nothing set
  the first or read the second; the SMTP reset never checked verification.
- derive::extract_tags (only tests used it; the shared fixture now runs
  through extract_tag_spans), the unused check and link icons, and the
  unused editor_add_item string.
- The blob scheme is renamed tsblob -> inkblob. URLs are built as notes are
  read, so nothing stored carries the old one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 19:00:44 -04:00
co-authored by Claude Opus 5.5
parent fd1d50662f
commit 7eacd0569c
26 changed files with 159 additions and 491 deletions
+8 -23
View File
@@ -6,12 +6,9 @@ import pytest
from inkwell import client_dist
from inkwell.app import create_app
from inkwell.client_dist import (
APK_NAME,
BY_ID,
MANIFEST_NAME,
PLATFORMS,
advertisement,
android_release,
release,
releases,
)
@@ -127,8 +124,8 @@ def test_the_android_names_are_the_ones_the_image_build_writes():
Phones never ask for these names; they poll `/api/client/android`. The names
changed once, with the rename to Inkwell (Scribe note 5071).
"""
assert APK_NAME == "inkwell.apk"
assert MANIFEST_NAME == "inkwell-android.json"
assert BY_ID["android"].artifact == "inkwell.apk"
assert BY_ID["android"].sidecar == "inkwell-android.json"
# --- absence is an ordinary answer -------------------------------------------
@@ -242,7 +239,7 @@ def test_the_android_payload_still_carries_every_field_it_used_to():
core/src/sync/client.rs is a plain serde struct and ignores what it does not
know — but none of these may move or change meaning."""
place("android")
found = android_release()
found = release("android")
for key in ("version", "version_code", "size", "sha256", "url"):
assert key in found, key
assert found["url"] == "/api/client/android/download"
@@ -299,7 +296,7 @@ def test_a_platform_the_server_lacks_is_simply_not_in_the_set():
def test_the_baked_in_copy_is_used_when_nothing_was_dropped_in():
"""The ordinary case for a self-hoster who just pulled the image."""
place("android", root=client_dist.BAKED_ROOT, version_code=300)
assert android_release()["version_code"] == 300
assert release("android")["version_code"] == 300
def test_a_dropped_in_build_beats_the_one_the_image_shipped():
@@ -308,7 +305,7 @@ def test_a_dropped_in_build_beats_the_one_the_image_shipped():
place("android", version_code=99)
# Lower version and all — precedence is about intent, not about newness. An
# operator pinning an older client is doing it on purpose.
assert android_release()["version_code"] == 99
assert release("android")["version_code"] == 99
def test_precedence_is_decided_per_platform_not_for_the_whole_set():
@@ -334,7 +331,7 @@ def test_a_broken_drop_in_does_not_shadow_the_baked_copy():
"""
place("android", root=client_dist.BAKED_ROOT, version_code=300)
place("android", size=999_999) # sidecar describing a different build
assert android_release()["version_code"] == 300
assert release("android")["version_code"] == 300
# --- the advertisement -------------------------------------------------------
@@ -345,20 +342,8 @@ def test_the_advertisement_carries_the_whole_table():
assert set(advertisement()["clients"]) == {"linux-deb"}
def test_the_advertisement_still_carries_the_key_phones_already_read():
"""Not deprecated in the change that introduces its replacement. An installed
Android client reads `android_client`, and one duplicated dict is what it costs
to not strand it."""
place("android")
data = advertisement()
assert data["android_client"] == data["clients"]["android"]
def test_no_android_client_means_no_android_key_even_when_others_are_present():
place("windows")
data = advertisement()
assert "android_client" not in data
assert set(data["clients"]) == {"windows"}
def test_a_server_with_no_clients_advertises_nothing():
assert advertisement() == {}
# --- routes ------------------------------------------------------------------