Browse Source

Update documentation and metadata across multiple files

- Updated the last update timestamp and git head in `.last-update.json`.
- Modified the page manifest in `.page-manifest.json` to reflect new git head and source fingerprints for various pages.
- Revised the `history-store.md` to update generated metadata and correct references to code locations.
- Updated `ai-client.md` to reflect the new verification timestamp.
- Adjusted `configuration-and-data.md` to include additional source resources and updated generated metadata.
- Revised `quickstart.md` to update generated metadata and clarify versioning details.
softword 2 days ago
parent
commit
f8524afb1f

+ 9 - 9
openwiki/.claims/concepts/history-store.json

@@ -1,6 +1,6 @@
 {
   "schemaVersion": 1,
-  "pageVersion": "sha256:9d1f1a31451538c0c3bbc043ab35ce90cbffd32e26263470d8b43f7dc2486279",
+  "pageVersion": "sha256:59ae3ffd4d8d18c371ba76fc2dabce8c809110bf5672ed5bbe57f08950f6c4a1",
   "claims": [
     {
       "id": "claim_3afb8d7c0dbf446090433a98b74ad2e5",
@@ -191,11 +191,11 @@
           "version": "repo-lines-v1:sha256:9fa73b08edeb6e3bc3d3d40b114c9c25dac41393f654aef4f34b25bf000b64f1:eyJzZWxlY3RlZExpbmVDb3VudCI6NiwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYWM4OTZiNjcxOWM0NWUwNjBiYzYxYjc2OTVlNWM3NjY5MDAxMGJhYWY5MjUxNTdjZGRmNzkyMzljYmJmYjBmMiIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiZjQ5M2E2NjFmZWY4MzY3ODU3YWJkODk4ZWY5YjAxZWYyMmY2ZDg0MjlhOWEyNGI3MjRjY2Y1ZTZjNDEzNTc2MyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZDM0MjI5OTEyYzRlYzAxNjlhMzMyOThiMTE1ZGI1ZWVmY2E4YjJjYmIwOWM1ZGVkOGZiZTZjNjVjOTdkOGRmYyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMjgxYzllMDA4NDg0YjQyMjE2ZmEyYTU5NjFkZjIwMzdhZjIyY2ZmODMwNWEyYWM5YzQzOTU1MWVjN2U5NDgwOCJ9"
         },
         {
-          "resource": "repo://src/app.rs#L784-L801",
+          "resource": "repo://src/app.rs#L830-L847",
           "version": "repo-lines-v1:sha256:57ac76a55fce9ecc1f533f616fb4cdfc01c0da29873e427e3184c6d9dc184a58:eyJzZWxlY3RlZExpbmVDb3VudCI6MTgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImJkYmFiZjFkNjI2OTdjZWE2NTk5ZWQyNjg5MDQzY2RhYzAyOWUxMWQ3NWIwY2U4MTRlYWVkNzhjZTk2Zjg5ZGMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6ImU2YjA0NDkxNDY5NzIyZTgzNjNhOTRlNDA0NDUzOGUwMTNhMmEyMTdlMzZiMWU1NjhiYTYwYWNiN2I0YzhmMmUiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjNiOWQxNjk5ZDM4YTRkZDQ3ZjgxMGFmMDViYTIzZTM2N2NiNTE5NzljODAxM2Q3YTZmYWQyYjAzY2Q0MzA0MTEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjdkNGY3ZDhmNzA1MzNkMmM0NTJkYzMwZTM1NzY1OTM2ZWE2NzkwMDIyODlmNTljOWQzMDU4ODc0ZjdjYjM1MDYifQ"
         },
         {
-          "resource": "repo://src/whatsapp.rs#L45-L46",
+          "resource": "repo://src/whatsapp.rs#L46-L47",
           "version": "repo-lines-v1:sha256:3474d614982a770557cfcfc53711175e69a7c9841bfebcf210f0643f00ff9581:eyJzZWxlY3RlZExpbmVDb3VudCI6MiwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiMTU4MDBhYzJkZDhhYmM0NmUwNjVhMGY3Y2ZkOGMzNWYxZDRjMGUwYTBlNzNiZDc1MmY4NDRlZDVhMWY2MGU3MCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiZjhlYjE3YjM5MDA1ZjBmMTU4MDZhOTg0NzBjOWE3NmUwOTZhMDFhMWI2NDJjY2UyZGRhMjA4M2E3YWQxYTExNyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZjExNmYzOTNiOTcyNzBhZmRjYzA1NTY1YWU1M2U3ZjU3YWNhMjQyM2I3ZGE3MzYxYjcxZjkzYWQyZWRlMzJlNiIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiYTMzZTY3ODlmYzBiYmYxNjczODJjNzljNTE3ZGFhZGEyYTk2ZDY1NWRmMDRiZmI3YTg5N2IyZTI0NDA0NjA0MiJ9"
         }
       ]
@@ -205,7 +205,7 @@
       "statement": "Transcription text is stored only inside messages.text: the store has no transcription column or table, so deleting a chat (which deletes its messages by chat_jid) also discards all of its transcripts and the placeholder prefix is the only marker that the audio was transcribed.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L792-L797",
+          "resource": "repo://src/app.rs#L838-L843",
           "version": "repo-lines-v1:sha256:9898eb8c9ec5fb7d3f4d48e6202a56aa5d8b21ac027749c821a8fc49e1a2b229:eyJzZWxlY3RlZExpbmVDb3VudCI6NiwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYTYwNzU3ZTQwZGI3ZTJjZDBiYzFkMzM3OTkwMmVhMjNjMGI2YzBhNGEwMDI4ZTg4ODU2YTBmOGIxYjI1YzI0NCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiMGM2NDc5Y2MyMzA0NDBmZDQxZTgyMjQyMTg2Nzk2OTg1NTlkMjg5M2JkNjdiNDM4MGFmYWI4MTFiMzhhNTVhYSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNjBkYTQzMWQ5MmZlYjM0NGEzYmEwZDhkYWQ4YzMyMjIzY2I4OGUxZTQ3MmIxZDYyZmU1MTkzN2E2ZmZhMmNhOSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiNzU3NGNlM2NlN2MyMzQ3NWQxNGY5ZjkwZWQ4Zjg5ODczMmM3ZTAyOGVkNDJmNjg1ZTAyYmU4ZThhM2UwMTUxYyJ9"
         },
         {
@@ -223,15 +223,15 @@
       "statement": "is_voice_note is true only when the trimmed text equals `[messaggio vocale]` exactly, so a stored transcription no longer matches it; audios_to_transcribe relies on this to treat a message as already transcribed (each audio is transcribed once even though nothing else records it) and src/autoreply.rs passes the stored text to the model instead of its cannot-listen sentinel once a transcription exists.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L900-L918",
+          "resource": "repo://src/app.rs#L946-L964",
           "version": "repo-lines-v1:sha256:aca8ef54d074bdd9a35c6228ea67532c04a9bf55079ae6ed368a56dfc7f87db1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTksImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjI3MGQwY2JkODBmOGZhNDZkN2EzOGQxNDMyMzZjODMzYmViZGE4Mzg2ZGNmZTFkZTBjYmNjNWM2M2IzNGE1MzQiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjRiNDI5OGJkNmI1YjQyZmVjNDI0NDIxMjBlNTkzZjAxZDFiYTU0YmFhODg2NTUwMzE0MWE0YmQxYmViNjQxZjgiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjIyMGUyNjkzMzFhZTU2NTJiYTMxNWViYTdmYzRlNWMxNWFhNDlhMzdiMjE2NGY3NjRlYmNiYTA1ODE5ZGMyNDAifQ"
         },
         {
-          "resource": "repo://src/autoreply.rs#L364-L379",
+          "resource": "repo://src/autoreply.rs#L372-L387",
           "version": "repo-lines-v1:sha256:16e2a124c955fde9bf455d688fa7aa42035a5fed15752ff59f0e5b47682c1dda:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImQyMWNlZTczZDBjMDU5ZmU1YjQ1MDVlMmJmMmY5OGE2OGMwY2Y4ZWJmNWI5Y2Q1MTAzNGY0ZTZhZTJkNWQyMGEiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE5ZTc2MzU1Y2YxMTk5NDgwYzNmOTk4MzZiMTQ4NmM4NDFkODkxZmFhZDkwNGM2MDhlMDkzMDIyZDM3NTdhZWUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQwNWQ4YWU3NjdiNjQ4YzZmM2Y4ODE1ZDZjODQ1MjFiOTQ5MWVmZTEyNmRiYTVmZjU0MWIyMmJjNWY3YjllNWQifQ"
         },
         {
-          "resource": "repo://src/whatsapp.rs#L1174-L1181",
+          "resource": "repo://src/whatsapp.rs#L1228-L1235",
           "version": "repo-lines-v1:sha256:56200a5278b4431e6444218582169aabd8d4b1d57de764de0856dc98838c94d1:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZDI1MjE2Y2MwNzJmMWZjOGZhNTU5MGQyMjRjMjE5OTI1NTExNDkxMThjYTg1ZTlmODVkNGEwYjA1MjQ0N2IxMCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDEyY2EzNDVjY2Y3NWJmOWMwODA2YmNlNjk1YmU4ZGU4MDhiNzk5ODQyNTFhN2E1NGQyMDJjZjYxMDFkZDQ1MSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiN2ViZDBkMDlmODEyZmE0MjI4M2ExZGM5N2Y0MzdmYzQyNmIzZTg5NGI0NWUwMWFjNThjNTM5NTc5YmNhMDQ1ZSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMDdiNDRmYjk0MDJlZDMxOTc3NTA4MTZmZDNmYTg0MWZlM2VkMDNkMzllYWJlOGY3ZjZmOGI5MzgwMTI0NTU2YiJ9"
         }
       ]
@@ -255,7 +255,7 @@
       "statement": "Because set_autoreply upserts the chats row, enabling the autoreply on a chat that has no messages creates a chats row with last_timestamp 0: the chat appears in the chat list (sorted last, named by the JID user part until a contact or message names it) but the startup catch-up skips it since it has no last message.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L964-L981",
+          "resource": "repo://src/app.rs#L1010-L1027",
           "version": "repo-lines-v1:sha256:15f024e6c558596295755f720dfa14a980113d18c386f066c5353019c2917bce:eyJzZWxlY3RlZExpbmVDb3VudCI6MTgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjllZjk3NWI0MzRkMmRhMjhhYWMwZmUwMGVkYjI5MzE4NzY0NzA5OWU0ZmUzOThkNWJlMTI3NTAwMDQzOWY2NmIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE2MmVlNTdlNDFhOGMyMGFlMDE2NGRmMjYxNDM5ZGNjNDk5ZDM1MjA4MzQxNTE1MTZkMDQ3ZThkZWFlOGE0NjYiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijc4OTU5NGE5NzIzN2Y2NjVkMmU0Y2RhMTIyZmY1NTIyNzJjMjVmZTFhMTI0NmZjMGNkNjllMDQ4MjE2ZTNlYWMifQ"
         },
         {
@@ -267,6 +267,6 @@
   ],
   "verification": {
     "by": "openwiki/0.7.2",
-    "at": "2026-10-24T16:42:08.550Z"
+    "at": "2026-10-25T13:15:27.881Z"
   }
 }

+ 5 - 5
openwiki/.claims/integrations/ai-client.json

@@ -1,6 +1,6 @@
 {
   "schemaVersion": 1,
-  "pageVersion": "sha256:4927c894dab42fbe05e52e939703259666aa47947ef7945c623bfa2116a02e4d",
+  "pageVersion": "sha256:492760c093c8bce139d1e67a61cf5a50779958241e08fe9ebbb19fe7c8749fa0",
   "claims": [
     {
       "id": "claim_c5dd9ee6003245adaa1701eb40862582",
@@ -41,8 +41,8 @@
       "statement": "The default base URL is https://ollama.com/v1 and the default model is deepseek-v4.1-flash.",
       "evidence": [
         {
-          "resource": "repo://src/config.rs#L35-L37",
-          "version": "repo-lines-v1:sha256:ace88a2257793291dac3b3a9be115c8460366e7dce83953bc6d52977e07763a4:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZTc2MTBlZDMwOGNjNWU5MmE3MzAxODA5ZDE1OWZiODlkOTg5ZjIxYTNmZjMwZTc5MGQ2NjU4ZDAwNTM0MThjNCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiYWM0ZGZhMzdlOWNjNjNjNTM4MmEzNjg2M2Q2Nzg3ZWU0OWViYTU2N2EyNGFiYmYyZGI3OTlhN2YwOWFjMmI1NCIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiY2JiNmQ0YzQ2ZTZkZWY5ZGZmYWRiYzZiNTIwN2U4N2EwZTI4MzQzMjliZmI0M2I1YjI2NmU2MTA0Y2RlZWJiMiIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiN2U4MDVmNGIzNWUzODc2YTEyODk5MTUyODJhZGE1Y2QzM2E3N2Y1MzJiZjI5YzE4Yzg5ZGEyMmIxNGNmNTBiZCJ9"
+          "resource": "repo://src/config.rs#L39-L41",
+          "version": "repo-lines-v1:sha256:ace88a2257793291dac3b3a9be115c8460366e7dce83953bc6d52977e07763a4:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZTc2MTBlZDMwOGNjNWU5MmE3MzAxODA5ZDE1OWZiODlkOTg5ZjIxYTNmZjMwZTc5MGQ2NjU4ZDAwNTM0MThjNCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiYWM0ZGZhMzdlOWNjNjNjNTM4MmEzNjg2M2Q2Nzg3ZWU0OWViYTU2N2EyNGFiYmYyZGI3OTlhN2YwOWFjMmI1NCIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiY2JiNmQ0YzQ2ZTZkZWY5ZGZmYWRiYzZiNTIwN2U4N2EwZTI4MzQzMjliZmI0M2I1YjI2NmU2MTA0Y2RlZWJiMiIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMTMxMDQ2OTY0YjY1OTVmNjgyNGVkOGEwNzcxMWM1ZjAxMGQ4YmEzNmJmN2MyYWI0YmEzY2U1Mjg5MDkxMWI5ZSJ9"
         }
       ]
     },
@@ -129,7 +129,7 @@
           "version": "repo-lines-v1:sha256:f5678d32b8e747a88110624d96ba85e6f0b191d2ff311ce41bd841dd4cd0a2a9:eyJzZWxlY3RlZExpbmVDb3VudCI6NDYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjAxYmE0NzE5YzgwYjZmZTkxMWIwOTFhN2MwNTEyNGI2NGVlZWNlOTY0ZTA5YzA1OGVmOGY5ODA1ZGFjYTU0NmIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjVhMDJhNmJkMDVjZjBmNWY4NmNlMjk3MTg5ZDk1MjJlYzU4ZWZhMzY1ZjI4NGNjNGYyOWE2NTk2NmQxODhiZWQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjJjZTgwZDQ1MzU3ZWY2NWZiNjUzODgzZWEzOTU1NDMyMDMzN2Q0YjA3MzcxNzQ1ZWE0MGFkYzRmMGFjNTU0YTcifQ"
         },
         {
-          "resource": "repo://src/config.rs#L341-L347",
+          "resource": "repo://src/config.rs#L401-L407",
           "version": "repo-lines-v1:sha256:77a53fa11fa04d405caba6426205b2c57c25edd1b59ce057d5429c3cb0af854d:eyJzZWxlY3RlZExpbmVDb3VudCI6NywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiNzUyM2JkYmRjYjY1ZGIyYThmNWU0OGI0ZmUyMDdjOTUxYjdjNzE3NDYxYzgwNjUzODMxNjExZGI0YjMxZjdhZCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNDRhMWY2MWFmZTk3ZWM0YWZjODI1OWM4ZGI4MDljZjlmMjkxNWQ3ZWUwYWRlZWJhNzdkZDMxZDBjZmJkM2JhZSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiYTUyMTYwNGIzNWZjNDBhZjAwY2JhNGVlYTJmZDVlMmMzYWYxODYzYjM5MTE4NWQ3YmY0YmIwOWU3MmQwYzhiMyJ9"
         }
       ]
@@ -233,6 +233,6 @@
   ],
   "verification": {
     "by": "openwiki/0.7.2",
-    "at": "2026-10-23T21:26:24.156Z"
+    "at": "2026-10-25T13:15:27.881Z"
   }
 }

+ 23 - 5
openwiki/.claims/operations/configuration-and-data.json

@@ -1,6 +1,6 @@
 {
   "schemaVersion": 1,
-  "pageVersion": "sha256:8c0a6de343db6a1114f9ba81a51b8cb1b5f189feadb28cbed319933c98ef98d2",
+  "pageVersion": "sha256:27061566fbb73782e095a7e0c37f181b3a740eab9deb0828d3a0aea0355e84fd",
   "claims": [
     {
       "id": "claim_0519d797500c4fba86d6c64ac1e60df4",
@@ -205,7 +205,7 @@
           "version": "repo-lines-v1:sha256:1501e5e6ec52e197ae84506acd57d2b315d6a1dd434c842b88dc4a4b6d2f1bd3:eyJzZWxlY3RlZExpbmVDb3VudCI6MzgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImQ3NGMwOGQzMzg5NGUyMWQyYzBmNTMyMDkwYmQwNjFjNDNjMzg1ZDU1MzkwMmI0MDkwZDkxZjJjZDY3M2VjMWQiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE1Y2VkZDkyMzY4ZGI1MDMwYjUxMjQ3ODcwODlmY2FmZTI5YzhmOGQ4MjExZDA0MTE4ZmM4MTViYWM1MDBjOWEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjdiYzk4ZDZiMGRjNDkyYzUwMTZkZjEwODA1YTNhNTRlYjljMTg0YTVhNjEzN2U3ZjRiZWNmYTBjMjIwNTUwZDAifQ"
         },
         {
-          "resource": "repo://src/main.rs#L61-L61",
+          "resource": "repo://src/main.rs#L71-L71",
           "version": "repo-lines-v1:sha256:4c448a0646f36833c45781a40616440b41ad3d485b8faf7089d78b8a85c580d6:eyJzZWxlY3RlZExpbmVDb3VudCI6MSwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiNGM0NDhhMDY0NmYzNjgzM2M0NTc4MWE0MDYxNjQ0MGI0MWFkM2Q0ODViOGZhZjcwODlkNzhiOGE4NWM1ODBkNiIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNGM0NDhhMDY0NmYzNjgzM2M0NTc4MWE0MDYxNjQ0MGI0MWFkM2Q0ODViOGZhZjcwODlkNzhiOGE4NWM1ODBkNiIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiOTJiNWYyOWYxMjhmYzYwODc1ZmE5YTYxMGI2MWExMTQ5ZjMzYmJhMDc2ZmU0NzdkZGU0NDA1OTUxNzdjYjAyYyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiZGQ4NmY4ZmE5MDAwN2QyYmY5ZDk4ZTE3NzNkMDg5ZWE4M2IzMWI4NzMwZjViMWIxZmRjYmViZmM5ZTZiZTMxYSJ9"
         }
       ]
@@ -215,11 +215,11 @@
       "statement": "A successful reload replaces the application configuration and rebuilds the AI client, while a failed reload keeps the current configuration and shows 'Configurazione non ricaricata: <error>'; the web panel port is bound only at startup.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L417-L434",
+          "resource": "repo://src/app.rs#L457-L474",
           "version": "repo-lines-v1:sha256:11076b2b498b6d19b7a0629886f2cdb37229105049de848490f4e1d9faead710:eyJzZWxlY3RlZExpbmVDb3VudCI6MTgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjVhYTEzNjY2OGNiMzc5NzgyYTUwMTY4ZDNlOWM4Njg4MmM5YTBhZTAxOGQwNTZiNTEzZWU2ODA5OWYxNjc3YzYiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjVmMjAxZDg2ZGM3NzY0YWFmOTA5MGNhNDRkODcxNDM3Y2JiODk4ZGE5ZWJlMGU0ZDhlNjVlNDZiZDJkZGVkYjQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjAyNjE2ZDk0ZDJmZDg4NWViMDZhMGFmZjVkYjQ1YWUyOTdiMWQ5NzViYzU0MjRlZGIyYWUwZmE2NzZkMzE0ZTYifQ"
         },
         {
-          "resource": "repo://src/main.rs#L96-L105",
+          "resource": "repo://src/main.rs#L106-L115",
           "version": "repo-lines-v1:sha256:54c6448bd45241fd4b90479b1a91e2fd528e7a38f4ac5d543eda728fbf3756d5:eyJzZWxlY3RlZExpbmVDb3VudCI6MTAsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImYwZjA3MmY1NzA4NTRiMGM0ODg3YmRlZDU4YzU2NWRiZGExOTNlYmY3NGIwODZmMjYyNTFmZjZhOTZiMmJiYWMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImRmYWI3MTBkZGY3ODU5ZTU3NTc2NGE5MTNhMDAyYzc0NTg1ZmZhNzAwMTUxMGNiODgxMWRhODNkMmNmNzRiMzQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImI1OTAxZTAwNGRkYTg1ZmUwNjg0OGVkYjhkMWIzM2Q1NTNmYWM4ZjkyMzZlZTFlMjlkZTNmNGUzMWRmNTM4NTkifQ"
         }
       ]
@@ -233,10 +233,28 @@
           "version": "repo-lines-v1:sha256:86778fe21f60c6caca6fe8e2791f86fe7e8df46a35c86acdbdc03cda812213b9:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiNTYxYjk5MGFkOGY0Mjg0YzM1NGNkOGY5YjZiMWIwZDAxNTY1MDJhYmIwOGFiMjlhYjUwODI0OTRkN2EwNzYwYyIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiMGY4ZmNhNmE4OTMwYzJhZGY0N2NkOWQ0ZTNmN2FmNDRmMTZhMTA1ZmQ5OGM0YzZlMDg3YThkZjFhN2M4ZTVlOSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNWRhOGZhNGQ5YTg5NzFmZGMyMzI1Zjg0ZDlmYzI3ODUwYTIyMDA4MTA5NDQ4MzE3NjRkYjNiYjllNWI4NmViYyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiYzVlMDU5OGEzNzQyYzljOWFlMWYwN2RjMWU1OWYwNDc2MzBjOTBhNDBiYzdkOTE4ZTk1YzAxMTdjOTdhNWQ5YSJ9"
         }
       ]
+    },
+    {
+      "id": "claim_f34b9a3906d0401ba2bc22b6807fc6f2",
+      "statement": "The build version is the package major.minor followed by the build number (git commit count of HEAD) and the short commit hash, both embedded by build.rs at build time with the fallbacks 0 and unknown when git is unavailable; --version or -V prints it as `wh <version>` and exits.",
+      "evidence": [
+        {
+          "resource": "repo://build.rs#L20-L32",
+          "version": "repo-lines-v1:sha256:e1322655489e23d06a7aa035bc9201db7ddf1f9f98d15b2b4b6cf63e28702e3c:eyJzZWxlY3RlZExpbmVDb3VudCI6MTMsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjAwYjllZWU5MWJjMGIxYTc3YjVmMjI0ZmQ2OTQ1ZjNkZWMyMzRlNTU5NmI5NDc1YzkwYzVhZWM5ZTZhZTIwYjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6ImY0ZWM2ODdhNTg3ZmFlMGJlMzliNDhjMDIyOGQ0Y2M3OTc4MmEwOGQwNmI4MTVkYmI0YzUxY2E2YjlmMjMyOWUiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijg2Y2MzMWU1ODc4YjE0ZjZiZWM5ZmY0OWI1ZWIwN2IzNWI3ZGYxMTBmMDMwMWRjN2Y0NjFmNGUyYzYyNTgyYWMiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjgzYzcwNjkyZDIzNGI2YTIwYjlmNDYyMWM0MDhiNTY4NDAyM2FlOWY3MjAxNjgxOTQyOTJhM2NiOGFjZmIwZDAifQ"
+        },
+        {
+          "resource": "repo://src/main.rs#L31-L44",
+          "version": "repo-lines-v1:sha256:99f78476153d1f355c2bca9df563b27bc801d8b7e16d8ebecf8a4afc833db518:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImM4ZTZlNzliNjA2ZTViMTc0NDU3YmZiZDI1MzI2Mzg5M2I0OGYzNGYxN2U0ZjUyNjQ0YTA4ZGQ3MDljZmE4NzkiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6Ijk0YjdmOWVlYjU0NTk1NGY1ZTkzZGRiMWVkNTBlNWNiNGViODM5OGYyNGE5MWIwNTdiZDIzNTc2MmE5MGRkOTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImE4MjYzNjdkZjY0MGI1YzFkZTYyYjFlNDdkZTc4ZGMxMmY2Y2YxNDAyMTI5OTllOTg2YWI1MDVmYmMyYjZkYjIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImU3YTc3NWVlMmRjOGNkYTc0MjI0ZTI1Nzg4MTJlODAzMjBmYzY4NzA3OTI5ZWM3OTk3Mzk1NGY0MTUwYTZhMjYifQ"
+        },
+        {
+          "resource": "repo://src/main.rs#L53-L58",
+          "version": "repo-lines-v1:sha256:f9f309d4165f05d41d04831555cd7312c2c8b8a4d4eb38d4540b67ac338762b1:eyJzZWxlY3RlZExpbmVDb3VudCI6NiwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYTFkMDZlMDQ4Y2QyNzI3MzhkODM3YjBjMGVjNmFhYjBiMDMxNDU3ZTQ3NWZkNDlhYmJjYmFmYzVmNzNjMDIwZCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiYTk2OWRkYWViYTkyNGE1OGVhNjY4ZTIwNDMwMWJlYTllOGMzNmM2ODk1NTc1Nzc2ZjNkOTNlY2JmYmU3N2MzNSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMTM0ZmE4MzRiNWYxZWRlMjAyY2Y0ZDQ5ZWM0NzQ0MjRlNzE2MzFhMmY3MWQ5NTNiNDMyNGI4Njg1YTMwZDNhNyJ9"
+        }
+      ]
     }
   ],
   "verification": {
     "by": "openwiki/0.7.2",
-    "at": "2026-10-24T16:39:50.206Z"
+    "at": "2026-10-25T13:15:27.881Z"
   }
 }

+ 26 - 12
openwiki/.claims/quickstart.json

@@ -1,6 +1,6 @@
 {
   "schemaVersion": 1,
-  "pageVersion": "sha256:bb1caa7405aaac3db2f806e6cfc1c06f35c73367e4aa23ce6c97e2b4b5fcb861",
+  "pageVersion": "sha256:4dd18442319f3366fe7fd7c3b28431302969dfa3dad92b87c92ed34ae80dd2b2",
   "claims": [
     {
       "id": "claim_6b1c328bf7f7452992ea8eeef561edd4",
@@ -41,7 +41,7 @@
       "statement": "Unless --version or -V is given, main loads the configuration, opens the history, starts the WhatsApp client, the optional web panel, the configuration watcher and the input thread, and runs the TUI loop.",
       "evidence": [
         {
-          "resource": "repo://src/main.rs#L43-L72",
+          "resource": "repo://src/main.rs#L53-L82",
           "version": "repo-lines-v1:sha256:1f8efd5e596ab7a7d1da0bfd9bc62005e6be9c40accb54842253ec733e4abfe3:eyJzZWxlY3RlZExpbmVDb3VudCI6MzAsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImExZDA2ZTA0OGNkMjcyNzM4ZDgzN2IwYzBlYzZhYWIwYjAzMTQ1N2U0NzVmZDQ5YWJiY2JhZmM1ZjczYzAyMGQiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImE5NjlkZGFlYmE5MjRhNThlYTY2OGUyMDQzMDFiZWE5ZThjMzZjNjg5NTU3NTc3NmYzZDkzZWNiZmJlNzdjMzUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjAxZmI2ZDM1MThiYTRjMzUwOWRiMWM5MTAyMTk2NjQwMzI4ZjgzM2M3MDJmMzgwNmNmZjFlZGI5MzU4Y2Q5YTgifQ"
         }
       ]
@@ -61,12 +61,12 @@
       "statement": "The AI autoreply can be enabled for private chats and groups but not for broadcasts or newsletters.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L1889-L1902",
-          "version": "repo-lines-v1:sha256:76ea2311dd543d33bf1c52b4cee8997184cb67643a8ba3b2f715abf2fea34667:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA0NDI0MGFiOGNkMTM1NDE2ZTQ5MjMyYTEzMGIzYzlkYmI2NWZmYzg0OGNjYzY3OWJhYTQxYWQzNjY4ZTA3MjQiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE5ZTc2MzU1Y2YxMTk5NDgwYzNmOTk4MzZiMTQ4NmM4NDFkODkxZmFhZDkwNGM2MDhlMDkzMDIyZDM3NTdhZWUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijg5NGUwY2FkODFjNTBiOWY4MWE5ODI2ZjA1YzUyZjY0MGE0ZGM3NzdiYWQyNGM2MGEwMjQ5NzhlZWJmMWRjMGMifQ"
+          "resource": "repo://src/app.rs#L1963-L1976",
+          "version": "repo-lines-v1:sha256:76ea2311dd543d33bf1c52b4cee8997184cb67643a8ba3b2f715abf2fea34667:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA0NDI0MGFiOGNkMTM1NDE2ZTQ5MjMyYTEzMGIzYzlkYmI2NWZmYzg0OGNjYzY3OWJhYTQxYWQzNjY4ZTA3MjQiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE5ZTc2MzU1Y2YxMTk5NDgwYzNmOTk4MzZiMTQ4NmM4NDFkODkxZmFhZDkwNGM2MDhlMDkzMDIyZDM3NTdhZWUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjhkYTViNjcyY2ViZDYwMjY1YTM5NmE4NTAxZmMwMmEyYzg2YTZkNWJkYzMyNzRlMGQyZDA5ZDYwMTJhY2Q1ZTgifQ"
         },
         {
-          "resource": "repo://src/autoreply.rs#L76-L107",
-          "version": "repo-lines-v1:sha256:0ec556787987c44ceb565f6d300f0cf6acd13afd25b5e78a34de780c044b82fc:eyJzZWxlY3RlZExpbmVDb3VudCI6MzIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjEzNDhjYzQxMDQ1OTNmYjgwNTEzZjBiMmUyNDQwYWYwZjc0M2Y5Yzk5Nzk0YWQzZGNiZGQ4ZjY0YjM4ZDBhNmMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjFmOThmZjFmNmFmYzAyNDYzN2IxMzgyOWJjNmFlMGJkYjA0NmU3YWQwMjQ0MWZmYTAzZDE4YmI4NzI0NmE5OTQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjZhYzE3ZjhmYjIwNjZkNTU5ZDU2MmYzNTkwODY4ZDRlNTMwYjIwZmQzNzdkNDkwZTJmZjE4Njc3Y2M3YTBlZTkifQ"
+          "resource": "repo://src/autoreply.rs#L82-L113",
+          "version": "repo-lines-v1:sha256:0ec556787987c44ceb565f6d300f0cf6acd13afd25b5e78a34de780c044b82fc:eyJzZWxlY3RlZExpbmVDb3VudCI6MzIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjEzNDhjYzQxMDQ1OTNmYjgwNTEzZjBiMmUyNDQwYWYwZjc0M2Y5Yzk5Nzk0YWQzZGNiZGQ4ZjY0YjM4ZDBhNmMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjFmOThmZjFmNmFmYzAyNDYzN2IxMzgyOWJjNmFlMGJkYjA0NmU3YWQwMjQ0MWZmYTAzZDE4YmI4NzI0NmE5OTQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjE2MzhiZmQ4ZjNiOGY1OTQzZDQyODJhMmY3MGQ0ODBhOWE5MGVkMGE3ZTA1ZWQyOWNmMWE0YzRjMzZkYWJkN2IifQ"
         }
       ]
     },
@@ -75,16 +75,16 @@
       "statement": "Commands use function keys: F2 switches chats/contacts, F3 toggles the autoreply of the selected or open chat depending on focus, F4 toggles the global autoreply, F8 twice relinks WhatsApp and F10 quits.",
       "evidence": [
         {
-          "resource": "repo://src/app.rs#L1342-L1357",
+          "resource": "repo://src/app.rs#L1171-L1216",
+          "version": "repo-lines-v1:sha256:6e737f1163f7fc1e0f873a9756a9a2c32d247edaf022b24c9d62e4f5d3ecdc71:eyJzZWxlY3RlZExpbmVDb3VudCI6NDYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjlhZGRmNjgzMjdhYTA4ZWZjNDYxNGFmZDIwOTkzZTFkNzZiZjUxNmQ3NzRjM2QyMmIzOTUyOTEwNmNkOTBhZmMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE2MmVlNTdlNDFhOGMyMGFlMDE2NGRmMjYxNDM5ZGNjNDk5ZDM1MjA4MzQxNTE1MTZkMDQ3ZThkZWFlOGE0NjYiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijk2ZWU5ZDllODg2ODFmN2JmM2M4ZmZiZjEzZDgyODk2ODM4MGY2Y2E0M2Y1ZGE4ODI5MmU1MjY3ZDRjMDhlOWYifQ"
+        },
+        {
+          "resource": "repo://src/app.rs#L1391-L1406",
           "version": "repo-lines-v1:sha256:f3a02114e65f3b57e1e9609cdb5227848e7d4a8d0d2d3abc6b38c40f5286461f:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjBjMWZhZjI0NjQzNTZlZjY0NzAyNjI4YzM0MGYyOGNhZDljMjY3OGYxMTViNTAxNDZkMGMyNTBmNzhmZDk2NWMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjkzNzNhMTgxNzI2YzQ3ZjdjNzlmOTI3ZDI2NzhhYzQ3NjYzY2VhMzI1OGYxOGEwNTM0ZTg2NDVlYmFlOTlkMGUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijc1YjdhNGU5MWJmNTc3ZDQwNjIyM2IzMjg2ZTFhYmI0NGRkNzUwYmViNmU1MzIwYTMyMGZlZDJkOTBjOWQ3ZDQifQ"
         },
         {
           "resource": "repo://src/app.rs#L24-L33",
           "version": "repo-lines-v1:sha256:683c16567f4074fbe88d85ef8581c16739d5ca0531826b0fb49c5df95ac18f20:eyJzZWxlY3RlZExpbmVDb3VudCI6MTAsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImJkMTkzOTVkMDA1MWQ2YTA4MzBkMmQ5OWZhNTk4ZDU4N2EyOWZkNTA0OTkwNGQ1OWNiNTI2YmQ3Yzc4ODBiMGUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6ImFmNjIzNzA4OWI5MWQxMDdiNjY0NTc5NzNhOGJhMmE3MWQ4NzA0NGVhOTFlOTE4Y2RlMjA1Zjg2YWNkNDZjOTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjFlZmRkMDA4YTE2MzY2YTNmMTdiNjY1M2IyNzcyMThkYzQ2NTRiMGFjYTE5MGI1YmFiZDcwNmIyM2IxMDQwNzciLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImI2ZmI3YjljNTEzODFiZmNlNmIwYzU4ZTY0ZmZhMjhjODMyNjU5NTkyOWQ1MDNlYTUwYjBlMDRiNTk0N2QwNTMifQ"
-        },
-        {
-          "resource": "repo://src/app.rs#L1122-L1167",
-          "version": "repo-lines-v1:sha256:6e737f1163f7fc1e0f873a9756a9a2c32d247edaf022b24c9d62e4f5d3ecdc71:eyJzZWxlY3RlZExpbmVDb3VudCI6NDYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjlhZGRmNjgzMjdhYTA4ZWZjNDYxNGFmZDIwOTkzZTFkNzZiZjUxNmQ3NzRjM2QyMmIzOTUyOTEwNmNkOTBhZmMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjE2MmVlNTdlNDFhOGMyMGFlMDE2NGRmMjYxNDM5ZGNjNDk5ZDM1MjA4MzQxNTE1MTZkMDQ3ZThkZWFlOGE0NjYiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijk2ZWU5ZDllODg2ODFmN2JmM2M4ZmZiZjEzZDgyODk2ODM4MGY2Y2E0M2Y1ZGE4ODI5MmU1MjY3ZDRjMDhlOWYifQ"
         }
       ]
     },
@@ -115,10 +115,24 @@
           "version": "repo-lines-v1:sha256:86778fe21f60c6caca6fe8e2791f86fe7e8df46a35c86acdbdc03cda812213b9:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiNTYxYjk5MGFkOGY0Mjg0YzM1NGNkOGY5YjZiMWIwZDAxNTY1MDJhYmIwOGFiMjlhYjUwODI0OTRkN2EwNzYwYyIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiMGY4ZmNhNmE4OTMwYzJhZGY0N2NkOWQ0ZTNmN2FmNDRmMTZhMTA1ZmQ5OGM0YzZlMDg3YThkZjFhN2M4ZTVlOSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNWRhOGZhNGQ5YTg5NzFmZGMyMzI1Zjg0ZDlmYzI3ODUwYTIyMDA4MTA5NDQ4MzE3NjRkYjNiYjllNWI4NmViYyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiYzVlMDU5OGEzNzQyYzljOWFlMWYwN2RjMWU1OWYwNDc2MzBjOTBhNDBiYzdkOTE4ZTk1YzAxMTdjOTdhNWQ5YSJ9"
         }
       ]
+    },
+    {
+      "id": "claim_b6597346068143bbb811472722060887",
+      "statement": "The --version output is `wh` followed by the package major.minor, the build number (git commit count) and the short commit hash in parentheses.",
+      "evidence": [
+        {
+          "resource": "repo://src/main.rs#L31-L43",
+          "version": "repo-lines-v1:sha256:fb05ef09216b796d689105b5893dbbb382566fbb79ce2dbfdb621b2a8eca5913:eyJzZWxlY3RlZExpbmVDb3VudCI6MTMsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImM4ZTZlNzliNjA2ZTViMTc0NDU3YmZiZDI1MzI2Mzg5M2I0OGYzNGYxN2U0ZjUyNjQ0YTA4ZGQ3MDljZmE4NzkiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6Ijg3YzViZTA4MWM3NGIwMmViZjRmM2RjZDExMzg0YjdlNGVlNzU0ZjdjZjEyZWNkZjgzYWVhODlmMGVjYmU5YjEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImE4MjYzNjdkZjY0MGI1YzFkZTYyYjFlNDdkZTc4ZGMxMmY2Y2YxNDAyMTI5OTllOTg2YWI1MDVmYmMyYjZkYjIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijc5NDFlOTk5OTFmZTg4ZWY1OGY1ZGZlOWIxNzc3Zjk3NWI0ZmE0Y2RmODg3OTI3ZTQwMDRkYTM3ZDVmODY1ZDQifQ"
+        },
+        {
+          "resource": "repo://src/main.rs#L55-L58",
+          "version": "repo-lines-v1:sha256:df14894834ff9796ff34fba963d52457ed1f5b24579fc77dcfd9397e1853e167:eyJzZWxlY3RlZExpbmVDb3VudCI6NCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZmZjNTkyMWIzNWM4YzFmNjdjNjAwOTI4YjY2N2U2ODhlNjg2MmEzMDk3YTA5NDc2YTU1MmNlMTk5NTMyMGIyYiIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiMzFiNjMxNDBkMTIwZDNmNWZmZjg3ODlhYWExZTVmYmNmYTBkY2I2MDZhOTQ2ZWRiMTU5MjRhNTEwYzg0ODU5ZiIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMTM0ZmE4MzRiNWYxZWRlMjAyY2Y0ZDQ5ZWM0NzQ0MjRlNzE2MzFhMmY3MWQ5NTNiNDMyNGI4Njg1YTMwZDNhNyJ9"
+        }
+      ]
     }
   ],
   "verification": {
     "by": "openwiki/0.7.2",
-    "at": "2026-10-24T16:39:50.206Z"
+    "at": "2026-10-25T13:15:27.881Z"
   }
 }

+ 2 - 2
openwiki/.last-update.json

@@ -1,7 +1,7 @@
 {
-  "updatedAt": "2026-10-25T13:04:31.329Z",
+  "updatedAt": "2026-10-25T13:18:43.847Z",
   "command": "update",
-  "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
+  "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
   "model": "host-agent/claude",
   "status": "complete",
   "language": "en"

+ 43 - 43
openwiki/.page-manifest.json

@@ -2,88 +2,88 @@
   "schemaVersion": 1,
   "pages": {
     "/openwiki/architecture/app-state.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:147e2ba13ec4a1f2727c1e580a0935503d6213e3aabb9bce1cf520e31c348e78",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/architecture/runtime-and-event-loop.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:73780810fe3cd1b10a3d3d3a8fb56a8c9f3079e97a27a9bffda63c40a108fef4",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/architecture/terminal-ui.md": {
-      "gitHead": "dc69f5fc7cd2bf7d732e4ccc8ff34398a48d2d2b",
-      "sourceFingerprint": "sha256:d4dd3e842183a686e381a839ed385a71d14b3f62e2199d238c83b5e38549d98d",
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:b917b7bf26bb55ba79b12fcf2c7cfe5936d6463a6bd9c6bfe7eed55735c000d3",
       "completedBy": "opencode",
       "completedRunId": "96dd7fcb-e901-4ad4-a53d-a3a9e5f45e4d"
     },
     "/openwiki/concepts/history-store.md": {
-      "gitHead": "dc69f5fc7cd2bf7d732e4ccc8ff34398a48d2d2b",
-      "sourceFingerprint": "sha256:d4dd3e842183a686e381a839ed385a71d14b3f62e2199d238c83b5e38549d98d",
-      "pageVersion": "sha256:9d1f1a31451538c0c3bbc043ab35ce90cbffd32e26263470d8b43f7dc2486279",
-      "completedBy": "openwiki/0.7.2",
-      "completedRunId": "16d279c7-60b4-4a76-84ef-65ff9d091a51"
+      "pageVersion": "sha256:59ae3ffd4d8d18c371ba76fc2dabce8c809110bf5672ed5bbe57f08950f6c4a1",
+      "completedBy": "claude-code",
+      "completedRunId": "847231d9-3246-4872-8f29-dd2bc1395376",
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19"
     },
     "/openwiki/integrations/ai-client.md": {
-      "gitHead": "dc69f5fc7cd2bf7d732e4ccc8ff34398a48d2d2b",
-      "sourceFingerprint": "sha256:d4dd3e842183a686e381a839ed385a71d14b3f62e2199d238c83b5e38549d98d",
-      "pageVersion": "sha256:4927c894dab42fbe05e52e939703259666aa47947ef7945c623bfa2116a02e4d",
-      "completedBy": "opencode",
-      "completedRunId": "96dd7fcb-e901-4ad4-a53d-a3a9e5f45e4d"
+      "pageVersion": "sha256:492760c093c8bce139d1e67a61cf5a50779958241e08fe9ebbb19fe7c8749fa0",
+      "completedBy": "claude-code",
+      "completedRunId": "847231d9-3246-4872-8f29-dd2bc1395376",
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19"
     },
     "/openwiki/integrations/web-control-panel.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:428fec496886d09cde951dc002e97021c4d9fc425843d101d1d5d17cc397bcc6",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/integrations/whatsapp-client.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:b6ea56337534d7b40808dce1aa32c6121c8c75af2f67d1860b5246e54b4d346b",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/operations/configuration-and-data.md": {
-      "gitHead": "dc69f5fc7cd2bf7d732e4ccc8ff34398a48d2d2b",
-      "sourceFingerprint": "sha256:d4dd3e842183a686e381a839ed385a71d14b3f62e2199d238c83b5e38549d98d",
-      "pageVersion": "sha256:8c0a6de343db6a1114f9ba81a51b8cb1b5f189feadb28cbed319933c98ef98d2",
-      "completedBy": "opencode",
-      "completedRunId": "96dd7fcb-e901-4ad4-a53d-a3a9e5f45e4d"
+      "pageVersion": "sha256:27061566fbb73782e095a7e0c37f181b3a740eab9deb0828d3a0aea0355e84fd",
+      "completedBy": "claude-code",
+      "completedRunId": "847231d9-3246-4872-8f29-dd2bc1395376",
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19"
     },
     "/openwiki/quickstart.md": {
-      "gitHead": "dc69f5fc7cd2bf7d732e4ccc8ff34398a48d2d2b",
-      "sourceFingerprint": "sha256:d4dd3e842183a686e381a839ed385a71d14b3f62e2199d238c83b5e38549d98d",
-      "pageVersion": "sha256:bb1caa7405aaac3db2f806e6cfc1c06f35c73367e4aa23ce6c97e2b4b5fcb861",
-      "completedBy": "opencode",
-      "completedRunId": "96dd7fcb-e901-4ad4-a53d-a3a9e5f45e4d"
+      "pageVersion": "sha256:4dd18442319f3366fe7fd7c3b28431302969dfa3dad92b87c92ed34ae80dd2b2",
+      "completedBy": "claude-code",
+      "completedRunId": "847231d9-3246-4872-8f29-dd2bc1395376",
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19"
     },
     "/openwiki/testing/unit-tests.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:87e88f2284955c6a45419d031922bce94b2d30c29040e151fd42811374151dc0",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/workflows/ai-autoreply.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:90d3dc1c89e757fdbd947c7d787a70192a1f423ea5575b17fd0b0cb5cfe6e505",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     },
     "/openwiki/workflows/relink-and-pairing.md": {
+      "gitHead": "fa84abea280e42e2b0e5efac6189df74f5206e21",
+      "sourceFingerprint": "sha256:3014c1372f8c16e64abc977676cf59382c36f0f58db15dcf13c181e07bacba19",
       "pageVersion": "sha256:0033245928a8e464561a73b6aec4301ea2d0c9ccb6ffeea2847a0684680cda63",
       "completedBy": "claude-code",
-      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913",
-      "gitHead": "38b73843b3ba2506f3fb725b5e332f69c377554e",
-      "sourceFingerprint": "sha256:2a42afb58abb858537c2d57d1b16cbd056378f0ff8600fa2ec330101287435c2"
+      "completedRunId": "40b6b468-52b1-49c0-b0af-ece2c5f7c913"
     }
   }
 }

+ 19 - 19
openwiki/concepts/history-store.md

@@ -14,8 +14,8 @@ sources:
     resource: repo://src/whatsapp.rs
 verified:
   - by: openwiki/0.7.2
-    at: 2026-10-24T16:42:08.550Z
-generated: { by: "openwiki/0.7.2", at: "2026-10-24T16:42:08.550Z" }
+    at: 2026-10-25T13:15:27.881Z
+generated: { by: "claude-code", at: "2026-10-25T13:15:27.881Z" }
 ---
 
 # Message history store
@@ -26,9 +26,9 @@ own — the WhatsApp session lives in a separate database owned by
 `whatsapp-rust` (see
 [Configuration and data](../operations/configuration-and-data.md)). `main`
 opens it before building the app and passes it in `AppDeps`
-(`repo://src/main.rs#L51-L68`, `repo://src/app.rs#L193-L199`);
+(`repo://src/main.rs#L61-L78`, `repo://src/app.rs#L212-L218`);
 [`App`](../architecture/app-state.md) keeps it as a private field
-(`repo://src/app.rs#L233`) and calls it synchronously from the event loop, so
+(`repo://src/app.rs#L252`) and calls it synchronously from the event loop, so
 all writes happen on the loop thread. Failures come back as `Err` and end up
 either as a startup abort or in the `Errore storico: …` status line.
 
@@ -139,7 +139,7 @@ message; own messages never name a chat (`chat_name_candidate`,
 The boolean return value drives the app: `on_message` returns immediately on
 `false`, so history-sync replays and redeliveries neither refresh the UI nor
 trigger the [AI autoreply](../workflows/ai-autoreply.md)
-(`repo://src/app.rs#L485-L499`).
+(`repo://src/app.rs#L531-L545`).
 
 ## Reading
 
@@ -153,7 +153,7 @@ trigger the [AI autoreply](../workflows/ai-autoreply.md)
   recent ones (`timestamp DESC, rowid DESC LIMIT ?3`) and reversed to ascending
   order. The [AI autoreply](../workflows/ai-autoreply.md) uses it to load the
   context from local midnight of yesterday, at most `CONTEXT_MESSAGES` messages
-  (`repo://src/app.rs#L991-L998`).
+  (`repo://src/app.rs#L1037-L1044`).
 - `list_chats()` (`repo://src/history.rs#L175-L191`): every `chats` row ordered
   by `last_timestamp DESC, jid`; the name is the contact name, else the chat
   name, else the user part of the JID, resolved in `chat_summary_from_row`
@@ -174,7 +174,7 @@ lookups (`display_name`, `is_autoreply`, `is_global_autoreply`,
 `upsert_contact` (`repo://src/history.rs#L197-L211`) inserts or renames a
 contact and ignores blank names, so an empty push name never erases a known
 name. `on_contact` stores the contact and reloads the lists
-(`repo://src/app.rs#L465-L477`).
+(`repo://src/app.rs#L511-L523`).
 
 ## Autoreply flags
 
@@ -187,13 +187,13 @@ name. `on_contact` stores the contact and reloads the lists
   of `settings`; the default is `false` when it was never stored. The global
   flag is independent of the per-chat flags: toggling it never changes a
   `chats.autoreply` value, and a chat is answered when either is on
-  (`repo://src/app.rs#L854-L860`).
+  (`repo://src/app.rs#L900-L906`).
 
 Two consequences of `set_autoreply` upserting the row: a chat toggled on from
 the contacts list exists in `chats` with `last_timestamp = 0` and no messages,
 so it is listed (sorted last, named by the JID user part until a contact or a
 message names it), and the startup catch-up skips it because it has no last
-message to inspect (`repo://src/app.rs#L964-L981`). New messages never reset the
+message to inspect (`repo://src/app.rs#L1010-L1027`). New messages never reset the
 per-chat flag, because the message upsert only touches `last_timestamp` and
 `name`.
 
@@ -217,7 +217,7 @@ preserved.
 
 The only caller is the transcription step of the
 [AI autoreply](../workflows/ai-autoreply.md) workflow
-(`repo://src/app.rs#L784-L801`). For each transcribed audio whose message still
+(`repo://src/app.rs#L830-L847`). For each transcribed audio whose message still
 exists it stores
 
 ```
@@ -226,7 +226,7 @@ exists it stores
 
 i.e. the constant `VOICE_NOTE_TEXT` (`repo://src/app.rs#L38-L41`, a deliberate
 duplicate of the private `VOICE_PLACEHOLDER` in
-`repo://src/whatsapp.rs#L45-L46`), a space, and the transcript. The previous
+`repo://src/whatsapp.rs#L46-L47`), a space, and the transcript. The previous
 body was exactly `[messaggio vocale]`, so this is an **overwrite** with the
 placeholder re-created as a prefix, not an append to arbitrary text. The write is
 guarded by `message_exists`, and the `bool` returned by `update_message_text` is
@@ -240,19 +240,19 @@ record that an audio was transcribed.
 ### Why the placeholder stops matching
 
 `is_voice_note` returns `true` only when the trimmed text equals
-`[messaggio vocale]` exactly (`repo://src/whatsapp.rs#L1174-L1181`). Once a
+`[messaggio vocale]` exactly (`repo://src/whatsapp.rs#L1228-L1235`). Once a
 transcription is stored the body is `[messaggio vocale] <transcription>`, which
 no longer matches, and two consumers depend on that:
 
 - `audios_to_transcribe` treats a message as already transcribed when an audio
   is in progress **or** its stored text is no longer the plain placeholder
-  (`repo://src/app.rs#L900-L918`), so each audio is transcribed once even though
+  (`repo://src/app.rs#L946-L964`), so each audio is transcribed once even though
   nothing else records it — and an audio whose transcription failed keeps the
   bare placeholder.
 - `user_content` in `src/autoreply.rs` replaces the body with the
   "the contact sent a voice message you cannot listen to" sentinel only while it
   still matches, otherwise it passes the stored text through
-  (`repo://src/autoreply.rs#L364-L379`). A transcribed voice note therefore
+  (`repo://src/autoreply.rs#L372-L387`). A transcribed voice note therefore
   reaches the model as `[messaggio vocale] <transcription>` in that reply and in
   every later context built from the store.
 
@@ -277,20 +277,20 @@ of downloading and describing the image again:
 
 - `message_exists(message_id)` (`repo://src/history.rs#L323-L332`) tells whether
   a message is still stored. The app checks it before saving a description
-  (`repo://src/app.rs#L747-L759`), so a chat deleted while its images were being
+  (`repo://src/app.rs#L793-L805`), so a chat deleted while its images were being
   described gets no orphan rows.
 - `save_image_description(message_id, chat_jid, description)`
   (`repo://src/history.rs#L352-L363`) upserts the row, replacing a previous
   description of the same message.
 - `image_descriptions(chat_jid)` (`repo://src/history.rs#L369-L381`) returns the
   chat's descriptions keyed by message id; the app uses it to skip images
-  already described (`repo://src/app.rs#L882-L898`) and to turn image messages
+  already described (`repo://src/app.rs#L928-L944`) and to turn image messages
   into text when building the AI context
-  (`repo://src/app.rs#L1009-L1028`).
+  (`repo://src/app.rs#L1056-L1077`).
 
 Descriptions are separate from `messages.text`, which keeps only the image
 placeholder plus optional caption rendered by `src/whatsapp.rs`
-(`repo://src/whatsapp.rs#L1085-L1103`); editing a body would never touch them,
+(`repo://src/whatsapp.rs#L1139-L1157`); editing a body would never touch them,
 and only `delete_chat` removes them.
 
 ## Deleting a chat
@@ -305,7 +305,7 @@ later message recreates the chat row through the message upsert.
 
 The app calls it after a double Delete press in the chat list; `confirm_delete`
 also drops the scheduled reply and the kept images/audios of that chat and
-closes it if open (`repo://src/app.rs#L1249-L1272`).
+closes it if open (`repo://src/app.rs#L1298-L1321`).
 
 ## Tests
 

+ 1 - 1
openwiki/integrations/ai-client.md

@@ -13,7 +13,7 @@ sources:
 generated: { by: "openwiki/0.7.2", at: "2026-10-24T16:42:08.550Z" }
 verified:
   - by: openwiki/0.7.2
-    at: 2026-10-23T21:26:24.156Z
+    at: 2026-10-25T13:15:27.881Z
 ---
 
 # AI chat-completions client

+ 13 - 6
openwiki/operations/configuration-and-data.md

@@ -6,6 +6,8 @@ tags: [configuration, toml, data-directory, sqlite, security, soul-md, live-relo
 sources:
   - id: openwiki-source-ea70eb6c045047448e446296
     resource: repo://.gitignore
+  - id: openwiki-source-36f054f1f38f2197a6af5bca
+    resource: repo://build.rs
   - id: openwiki-source-651d1fb6c9e49916a916ab51
     resource: repo://Cargo.toml
   - id: openwiki-source-0d5b861992295d2e1663735c
@@ -20,10 +22,10 @@ sources:
     resource: repo://src/config.rs
   - id: openwiki-source-b55a21a31ede1b56cd31a6a6
     resource: repo://src/main.rs
-generated: { by: "opencode", at: "2026-10-24T16:39:50.206Z" }
+generated: { by: "claude-code", at: "2026-10-25T13:15:27.881Z" }
 verified:
   - by: openwiki/0.7.2
-    at: 2026-10-24T16:39:50.206Z
+    at: 2026-10-25T13:15:27.881Z
 ---
 
 # Configuration and data files
@@ -181,10 +183,15 @@ more than one reload; each one reloads the full set of files.
 
 ## Build version and profile
 
-`wh --version` (or `-V`) prints `wh <version> (<short git commit>)` and
-exits without reading any file; the same text is shown at the bottom right
-of the main screen. The commit hash is embedded at build time by `build.rs`
-and is `unknown` when built without git (see
+`wh --version` (or `-V`) prints `wh <major>.<minor>.<build> (<short git
+commit>)` and exits without reading any file; the same text is shown at the
+bottom right of the main screen. Only the major and minor parts come from the
+`Cargo.toml` package version: the third part is the build number, the git
+commit count of `HEAD` (`src/main.rs:31-43`). `build.rs` embeds both the
+commit count (`WH_BUILD_NUMBER`, from `git rev-list --count HEAD`) and the
+short hash (`WH_GIT_HASH`) at build time, falls back to `0` and `unknown`
+when built without git, and re-runs when `.git/HEAD` or the refs change
+(`build.rs:20-32`; see
 [Runtime and event loop](../architecture/runtime-and-event-loop.md)).
 
 The release profile only strips symbols (`Cargo.toml:31-33`); LTO and a

+ 7 - 6
openwiki/quickstart.md

@@ -14,10 +14,10 @@ sources:
     resource: repo://src/config.rs
   - id: openwiki-source-b55a21a31ede1b56cd31a6a6
     resource: repo://src/main.rs
-generated: { by: "opencode", at: "2026-10-24T16:39:50.206Z" }
+generated: { by: "claude-code", at: "2026-10-25T13:15:27.881Z" }
 verified:
   - by: openwiki/0.7.2
-    at: 2026-10-24T16:39:50.206Z
+    at: 2026-10-25T13:15:27.881Z
 ---
 
 # Quickstart
@@ -51,9 +51,10 @@ fast. The release profile only strips symbols, without LTO
 (`Cargo.toml:35-37`) silences the informational MSVC linker line printed
 because the binary exports symbols.
 
-`wh --version` (or `-V`) prints `wh <version> (<git commit>)` and exits; the
-same version is shown at the bottom right of the main screen
-(`src/main.rs:32-48`, `build.rs`).
+`wh --version` (or `-V`) prints `wh <major>.<minor>.<build> (<git commit>)`,
+where the build number is the git commit count, and exits; the same version
+is shown at the bottom right of the main screen (`src/main.rs:31-58`,
+`build.rs`).
 
 On first start the app shows a QR code: scan it from WhatsApp → *Linked
 devices*. The session is kept in `session.db`, so later starts connect
@@ -111,7 +112,7 @@ calling the `no_reply` tool, whose use is decided by `SOUL.md`. Details:
 `main` prints the version and exits for `--version`; otherwise it loads the
 config, opens the history, starts the WhatsApp client, the optional web
 panel, the configuration watcher and an input thread, then runs the
-draw/receive loop until quit (`src/main.rs:44-72`, see
+draw/receive loop until quit (`src/main.rs:54-82`, see
 [Runtime and event loop](architecture/runtime-and-event-loop.md)).
 
 ## Where to look