thth 2.3.3__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. {thth-2.3.3 → thth-2.4.0}/.gitignore +4 -0
  2. {thth-2.3.3 → thth-2.4.0}/PKG-INFO +19 -12
  3. {thth-2.3.3 → thth-2.4.0}/README.md +18 -11
  4. {thth-2.3.3 → thth-2.4.0}/mcp/server.py +16 -4
  5. {thth-2.3.3 → thth-2.4.0}/skills/thth/SKILL.md +12 -3
  6. thth-2.4.0/tests/test_after_cli.py +422 -0
  7. thth-2.4.0/tests/test_api_diagnostic.py +181 -0
  8. {thth-2.3.3 → thth-2.4.0}/tests/test_bluesky_secret_scrub.py +6 -2
  9. thth-2.4.0/tests/test_healthcheck_notifications.py +347 -0
  10. thth-2.4.0/tests/test_incident_notifications.py +416 -0
  11. {thth-2.3.3 → thth-2.4.0}/tests/test_llm_trial.py +93 -0
  12. thth-2.4.0/tests/test_search_media_routes.py +85 -0
  13. {thth-2.3.3 → thth-2.4.0}/tests/test_secret_value_redact.py +55 -0
  14. {thth-2.3.3 → thth-2.4.0}/tests/test_selfupdate.py +56 -0
  15. thth-2.4.0/tests/test_send_control_chars.py +59 -0
  16. {thth-2.3.3 → thth-2.4.0}/tests/test_site.py +5 -7
  17. {thth-2.3.3 → thth-2.4.0}/tests/test_thread_read.py +10 -0
  18. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_review_fixes.py +26 -14
  19. {thth-2.3.3 → thth-2.4.0}/tests/test_trial_frictions.py +36 -0
  20. thth-2.4.0/thth/VERSION +1 -0
  21. {thth-2.3.3 → thth-2.4.0}/thth/account_cli.py +22 -2
  22. {thth-2.3.3 → thth-2.4.0}/thth/adapters/base.py +9 -0
  23. {thth-2.3.3 → thth-2.4.0}/thth/adapters/bluesky.py +12 -0
  24. {thth-2.3.3 → thth-2.4.0}/thth/adapters/mastodon.py +7 -0
  25. {thth-2.3.3 → thth-2.4.0}/thth/adapters/threads.py +11 -7
  26. thth-2.4.0/thth/after_cli.py +623 -0
  27. thth-2.4.0/thth/api_diagnostic.py +51 -0
  28. {thth-2.3.3 → thth-2.4.0}/thth/cli.py +116 -31
  29. {thth-2.3.3 → thth-2.4.0}/thth/core.py +40 -12
  30. {thth-2.3.3 → thth-2.4.0}/thth/doctor.py +4 -0
  31. {thth-2.3.3 → thth-2.4.0}/thth/engagements.py +4 -1
  32. thth-2.4.0/thth/healthcheck.py +451 -0
  33. thth-2.4.0/thth/incident.py +536 -0
  34. {thth-2.3.3 → thth-2.4.0}/thth/measured.py +8 -1
  35. {thth-2.3.3 → thth-2.4.0}/thth/report.py +37 -1
  36. {thth-2.3.3 → thth-2.4.0}/thth/runs.py +3 -0
  37. {thth-2.3.3 → thth-2.4.0}/thth/selfupdate.py +27 -11
  38. {thth-2.3.3 → thth-2.4.0}/thth/thread_read.py +1 -12
  39. {thth-2.3.3 → thth-2.4.0}/thth/threads_read_cli.py +6 -2
  40. {thth-2.3.3 → thth-2.4.0}/thth/threadthrow.py +11 -4
  41. thth-2.3.3/tests/test_after_cli.py +0 -205
  42. thth-2.3.3/thth/VERSION +0 -1
  43. thth-2.3.3/thth/after_cli.py +0 -342
  44. {thth-2.3.3 → thth-2.4.0}/LICENSE +0 -0
  45. {thth-2.3.3 → thth-2.4.0}/accounts.example/bluesky.json +0 -0
  46. {thth-2.3.3 → thth-2.4.0}/accounts.example/mastodon.json +0 -0
  47. {thth-2.3.3 → thth-2.4.0}/accounts.example/threads.json +0 -0
  48. {thth-2.3.3 → thth-2.4.0}/bin/thth +0 -0
  49. {thth-2.3.3 → thth-2.4.0}/bin/thth-remote +0 -0
  50. {thth-2.3.3 → thth-2.4.0}/bin/thth-run +0 -0
  51. {thth-2.3.3 → thth-2.4.0}/pyproject.toml +0 -0
  52. {thth-2.3.3 → thth-2.4.0}/systemd/thth@.service +0 -0
  53. {thth-2.3.3 → thth-2.4.0}/tests/__init__.py +0 -0
  54. {thth-2.3.3 → thth-2.4.0}/tests/conftest.py +0 -0
  55. {thth-2.3.3 → thth-2.4.0}/tests/fixtures/build_injection_eval.py +0 -0
  56. {thth-2.3.3 → thth-2.4.0}/tests/fixtures/callback/worker_responses.json +0 -0
  57. {thth-2.3.3 → thth-2.4.0}/tests/fixtures/injection_eval.json +0 -0
  58. {thth-2.3.3 → thth-2.4.0}/tests/fixtures/umami-bile.md +0 -0
  59. {thth-2.3.3 → thth-2.4.0}/tests/helpers/__init__.py +0 -0
  60. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_oauth_server.py +0 -0
  61. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_push_adapter.py +0 -0
  62. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_redirect_server.py +0 -0
  63. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_search_adapter.py +0 -0
  64. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_threads_reader.py +0 -0
  65. {thth-2.3.3 → thth-2.4.0}/tests/helpers/fake_threads_writes.py +0 -0
  66. {thth-2.3.3 → thth-2.4.0}/tests/helpers/hold_lock.py +0 -0
  67. {thth-2.3.3 → thth-2.4.0}/tests/helpers/hold_repo_lock.py +0 -0
  68. {thth-2.3.3 → thth-2.4.0}/tests/helpers/worker_probe.mjs +0 -0
  69. {thth-2.3.3 → thth-2.4.0}/tests/test_account_name_check.py +0 -0
  70. {thth-2.3.3 → thth-2.4.0}/tests/test_account_report.py +0 -0
  71. {thth-2.3.3 → thth-2.4.0}/tests/test_accounts_dir.py +0 -0
  72. {thth-2.3.3 → thth-2.4.0}/tests/test_adapter_boundary.py +0 -0
  73. {thth-2.3.3 → thth-2.4.0}/tests/test_api_error_body.py +0 -0
  74. {thth-2.3.3 → thth-2.4.0}/tests/test_app_env_cli.py +0 -0
  75. {thth-2.3.3 → thth-2.4.0}/tests/test_approval.py +0 -0
  76. {thth-2.3.3 → thth-2.4.0}/tests/test_approve_cmd.py +0 -0
  77. {thth-2.3.3 → thth-2.4.0}/tests/test_ask.py +0 -0
  78. {thth-2.3.3 → thth-2.4.0}/tests/test_atlas_fifth_review.py +0 -0
  79. {thth-2.3.3 → thth-2.4.0}/tests/test_atlas_fourth_review.py +0 -0
  80. {thth-2.3.3 → thth-2.4.0}/tests/test_atlas_review.py +0 -0
  81. {thth-2.3.3 → thth-2.4.0}/tests/test_atlas_second_review.py +0 -0
  82. {thth-2.3.3 → thth-2.4.0}/tests/test_atlas_third_review.py +0 -0
  83. {thth-2.3.3 → thth-2.4.0}/tests/test_audit1_fixes.py +0 -0
  84. {thth-2.3.3 → thth-2.4.0}/tests/test_audit2_fixes.py +0 -0
  85. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_b_counterexamples.py +0 -0
  86. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_b_m1_semantics.py +0 -0
  87. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_b_n1_depth.py +0 -0
  88. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_b_r1_closure.py +0 -0
  89. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_v201.py +0 -0
  90. {thth-2.3.3 → thth-2.4.0}/tests/test_audit_v23_details.py +0 -0
  91. {thth-2.3.3 → thth-2.4.0}/tests/test_auth.py +0 -0
  92. {thth-2.3.3 → thth-2.4.0}/tests/test_auth_identity_required.py +0 -0
  93. {thth-2.3.3 → thth-2.4.0}/tests/test_behind_remote.py +0 -0
  94. {thth-2.3.3 → thth-2.4.0}/tests/test_bluesky_adapter.py +0 -0
  95. {thth-2.3.3 → thth-2.4.0}/tests/test_board_needs_review.py +0 -0
  96. {thth-2.3.3 → thth-2.4.0}/tests/test_board_running.py +0 -0
  97. {thth-2.3.3 → thth-2.4.0}/tests/test_bundle.py +0 -0
  98. {thth-2.3.3 → thth-2.4.0}/tests/test_charcount.py +0 -0
  99. {thth-2.3.3 → thth-2.4.0}/tests/test_cli_entrypoint.py +0 -0
  100. {thth-2.3.3 → thth-2.4.0}/tests/test_cli_help.py +0 -0
  101. {thth-2.3.3 → thth-2.4.0}/tests/test_cli_vm_path.py +0 -0
  102. {thth-2.3.3 → thth-2.4.0}/tests/test_collect.py +0 -0
  103. {thth-2.3.3 → thth-2.4.0}/tests/test_collect_engagements.py +0 -0
  104. {thth-2.3.3 → thth-2.4.0}/tests/test_collect_runs.py +0 -0
  105. {thth-2.3.3 → thth-2.4.0}/tests/test_collect_sent.py +0 -0
  106. {thth-2.3.3 → thth-2.4.0}/tests/test_comparability.py +0 -0
  107. {thth-2.3.3 → thth-2.4.0}/tests/test_control_chars_refused.py +0 -0
  108. {thth-2.3.3 → thth-2.4.0}/tests/test_conversation_paging.py +0 -0
  109. {thth-2.3.3 → thth-2.4.0}/tests/test_count_for.py +0 -0
  110. {thth-2.3.3 → thth-2.4.0}/tests/test_docs_links.py +0 -0
  111. {thth-2.3.3 → thth-2.4.0}/tests/test_doctor.py +0 -0
  112. {thth-2.3.3 → thth-2.4.0}/tests/test_doctor_all_permissions.py +0 -0
  113. {thth-2.3.3 → thth-2.4.0}/tests/test_doctor_next_step.py +0 -0
  114. {thth-2.3.3 → thth-2.4.0}/tests/test_duplicate_front_matter_keys.py +0 -0
  115. {thth-2.3.3 → thth-2.4.0}/tests/test_editorial_audit.py +0 -0
  116. {thth-2.3.3 → thth-2.4.0}/tests/test_editorial_n3_n4.py +0 -0
  117. {thth-2.3.3 → thth-2.4.0}/tests/test_engagements.py +0 -0
  118. {thth-2.3.3 → thth-2.4.0}/tests/test_external_acceptance.py +0 -0
  119. {thth-2.3.3 → thth-2.4.0}/tests/test_fake_api.py +0 -0
  120. {thth-2.3.3 → thth-2.4.0}/tests/test_form_spec.py +0 -0
  121. {thth-2.3.3 → thth-2.4.0}/tests/test_form_spec_cli.py +0 -0
  122. {thth-2.3.3 → thth-2.4.0}/tests/test_forms.py +0 -0
  123. {thth-2.3.3 → thth-2.4.0}/tests/test_fresh_install.py +0 -0
  124. {thth-2.3.3 → thth-2.4.0}/tests/test_front_matter_injection.py +0 -0
  125. {thth-2.3.3 → thth-2.4.0}/tests/test_hypotheses.py +0 -0
  126. {thth-2.3.3 → thth-2.4.0}/tests/test_hypothesis_boundaries.py +0 -0
  127. {thth-2.3.3 → thth-2.4.0}/tests/test_hypothesis_units.py +0 -0
  128. {thth-2.3.3 → thth-2.4.0}/tests/test_impact_cli.py +0 -0
  129. {thth-2.3.3 → thth-2.4.0}/tests/test_inbox_granted_scopes.py +0 -0
  130. {thth-2.3.3 → thth-2.4.0}/tests/test_independent_thread_review.py +0 -0
  131. {thth-2.3.3 → thth-2.4.0}/tests/test_independent_topic_review.py +0 -0
  132. {thth-2.3.3 → thth-2.4.0}/tests/test_independent_topic_review_r2.py +0 -0
  133. {thth-2.3.3 → thth-2.4.0}/tests/test_inflight.py +0 -0
  134. {thth-2.3.3 → thth-2.4.0}/tests/test_jst.py +0 -0
  135. {thth-2.3.3 → thth-2.4.0}/tests/test_lint.py +0 -0
  136. {thth-2.3.3 → thth-2.4.0}/tests/test_list_projections.py +0 -0
  137. {thth-2.3.3 → thth-2.4.0}/tests/test_llm_trial_engage.py +0 -0
  138. {thth-2.3.3 → thth-2.4.0}/tests/test_lock.py +0 -0
  139. {thth-2.3.3 → thth-2.4.0}/tests/test_m2_independent.py +0 -0
  140. {thth-2.3.3 → thth-2.4.0}/tests/test_maintain.py +0 -0
  141. {thth-2.3.3 → thth-2.4.0}/tests/test_mastodon_adapter.py +0 -0
  142. {thth-2.3.3 → thth-2.4.0}/tests/test_mastodon_visibility.py +0 -0
  143. {thth-2.3.3 → thth-2.4.0}/tests/test_max_per_run.py +0 -0
  144. {thth-2.3.3 → thth-2.4.0}/tests/test_mcp.py +0 -0
  145. {thth-2.3.3 → thth-2.4.0}/tests/test_mcp_robustness.py +0 -0
  146. {thth-2.3.3 → thth-2.4.0}/tests/test_measured.py +0 -0
  147. {thth-2.3.3 → thth-2.4.0}/tests/test_media_accounts.py +0 -0
  148. {thth-2.3.3 → thth-2.4.0}/tests/test_media_next_steps.py +0 -0
  149. {thth-2.3.3 → thth-2.4.0}/tests/test_media_roundtrip.py +0 -0
  150. {thth-2.3.3 → thth-2.4.0}/tests/test_mismatch_diagnostics.py +0 -0
  151. {thth-2.3.3 → thth-2.4.0}/tests/test_n5_reply_null_element.py +0 -0
  152. {thth-2.3.3 → thth-2.4.0}/tests/test_n6_replies_incomplete_ledger.py +0 -0
  153. {thth-2.3.3 → thth-2.4.0}/tests/test_n7_doctor_error_body.py +0 -0
  154. {thth-2.3.3 → thth-2.4.0}/tests/test_no_limits.py +0 -0
  155. {thth-2.3.3 → thth-2.4.0}/tests/test_observation_provenance.py +0 -0
  156. {thth-2.3.3 → thth-2.4.0}/tests/test_packaging.py +0 -0
  157. {thth-2.3.3 → thth-2.4.0}/tests/test_preview.py +0 -0
  158. {thth-2.3.3 → thth-2.4.0}/tests/test_production_mode.py +0 -0
  159. {thth-2.3.3 → thth-2.4.0}/tests/test_pull_cli.py +0 -0
  160. {thth-2.3.3 → thth-2.4.0}/tests/test_queue.py +0 -0
  161. {thth-2.3.3 → thth-2.4.0}/tests/test_quiet_hours.py +0 -0
  162. {thth-2.3.3 → thth-2.4.0}/tests/test_r2_r4_r5.py +0 -0
  163. {thth-2.3.3 → thth-2.4.0}/tests/test_read_cli_bare_runtimeerror.py +0 -0
  164. {thth-2.3.3 → thth-2.4.0}/tests/test_reason_adoption.py +0 -0
  165. {thth-2.3.3 → thth-2.4.0}/tests/test_redact.py +0 -0
  166. {thth-2.3.3 → thth-2.4.0}/tests/test_redirect_token_leak.py +0 -0
  167. {thth-2.3.3 → thth-2.4.0}/tests/test_refresh.py +0 -0
  168. {thth-2.3.3 → thth-2.4.0}/tests/test_refresh_destination.py +0 -0
  169. {thth-2.3.3 → thth-2.4.0}/tests/test_rejudge_new.py +0 -0
  170. {thth-2.3.3 → thth-2.4.0}/tests/test_rejudge_r2_r3.py +0 -0
  171. {thth-2.3.3 → thth-2.4.0}/tests/test_replies.py +0 -0
  172. {thth-2.3.3 → thth-2.4.0}/tests/test_replies_refresh.py +0 -0
  173. {thth-2.3.3 → thth-2.4.0}/tests/test_repo_lock.py +0 -0
  174. {thth-2.3.3 → thth-2.4.0}/tests/test_repo_sync.py +0 -0
  175. {thth-2.3.3 → thth-2.4.0}/tests/test_reverse_audit.py +0 -0
  176. {thth-2.3.3 → thth-2.4.0}/tests/test_review_case_id_cluster_m2.py +0 -0
  177. {thth-2.3.3 → thth-2.4.0}/tests/test_review_case_id_cluster_r2.py +0 -0
  178. {thth-2.3.3 → thth-2.4.0}/tests/test_review_cli.py +0 -0
  179. {thth-2.3.3 → thth-2.4.0}/tests/test_review_evidence_account.py +0 -0
  180. {thth-2.3.3 → thth-2.4.0}/tests/test_review_form_spec_and_case_id.py +0 -0
  181. {thth-2.3.3 → thth-2.4.0}/tests/test_review_provenance.py +0 -0
  182. {thth-2.3.3 → thth-2.4.0}/tests/test_review_records.py +0 -0
  183. {thth-2.3.3 → thth-2.4.0}/tests/test_revoke.py +0 -0
  184. {thth-2.3.3 → thth-2.4.0}/tests/test_roundtrip.py +0 -0
  185. {thth-2.3.3 → thth-2.4.0}/tests/test_run_missing_env.py +0 -0
  186. {thth-2.3.3 → thth-2.4.0}/tests/test_run_record_failclosed.py +0 -0
  187. {thth-2.3.3 → thth-2.4.0}/tests/test_runs_collected.py +0 -0
  188. {thth-2.3.3 → thth-2.4.0}/tests/test_runs_read_rows.py +0 -0
  189. {thth-2.3.3 → thth-2.4.0}/tests/test_schedule_multiple.py +0 -0
  190. {thth-2.3.3 → thth-2.4.0}/tests/test_schedule_view.py +0 -0
  191. {thth-2.3.3 → thth-2.4.0}/tests/test_scopes_source_requested.py +0 -0
  192. {thth-2.3.3 → thth-2.4.0}/tests/test_search_engage_targets.py +0 -0
  193. {thth-2.3.3 → thth-2.4.0}/tests/test_secrets_grep.py +0 -0
  194. {thth-2.3.3 → thth-2.4.0}/tests/test_security_small_fixes.py +0 -0
  195. {thth-2.3.3 → thth-2.4.0}/tests/test_select.py +0 -0
  196. {thth-2.3.3 → thth-2.4.0}/tests/test_send.py +0 -0
  197. {thth-2.3.3 → thth-2.4.0}/tests/test_send_cli.py +0 -0
  198. {thth-2.3.3 → thth-2.4.0}/tests/test_send_media.py +0 -0
  199. {thth-2.3.3 → thth-2.4.0}/tests/test_send_visibility.py +0 -0
  200. {thth-2.3.3 → thth-2.4.0}/tests/test_sent_integrity.py +0 -0
  201. {thth-2.3.3 → thth-2.4.0}/tests/test_server_json.py +0 -0
  202. {thth-2.3.3 → thth-2.4.0}/tests/test_skill_doc.py +0 -0
  203. {thth-2.3.3 → thth-2.4.0}/tests/test_systemd.py +0 -0
  204. {thth-2.3.3 → thth-2.4.0}/tests/test_thread_publish.py +0 -0
  205. {thth-2.3.3 → thth-2.4.0}/tests/test_threadrun.py +0 -0
  206. {thth-2.3.3 → thth-2.4.0}/tests/test_threads_read_permissions.py +0 -0
  207. {thth-2.3.3 → thth-2.4.0}/tests/test_threadshape.py +0 -0
  208. {thth-2.3.3 → thth-2.4.0}/tests/test_thth_root.py +0 -0
  209. {thth-2.3.3 → thth-2.4.0}/tests/test_token_exists.py +0 -0
  210. {thth-2.3.3 → thth-2.4.0}/tests/test_token_scopes_record.py +0 -0
  211. {thth-2.3.3 → thth-2.4.0}/tests/test_token_set.py +0 -0
  212. {thth-2.3.3 → thth-2.4.0}/tests/test_topic.py +0 -0
  213. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_advice.py +0 -0
  214. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_cli.py +0 -0
  215. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_models.py +0 -0
  216. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_shelf_observers.py +0 -0
  217. {thth-2.3.3 → thth-2.4.0}/tests/test_topic_store.py +0 -0
  218. {thth-2.3.3 → thth-2.4.0}/tests/test_topics_record_concurrent.py +0 -0
  219. {thth-2.3.3 → thth-2.4.0}/tests/test_topics_tool.py +0 -0
  220. {thth-2.3.3 → thth-2.4.0}/tests/test_v21b_approved_writes.py +0 -0
  221. {thth-2.3.3 → thth-2.4.0}/tests/test_value_domains_shown.py +0 -0
  222. {thth-2.3.3 → thth-2.4.0}/tests/test_version.py +0 -0
  223. {thth-2.3.3 → thth-2.4.0}/tests/test_where_cli.py +0 -0
  224. {thth-2.3.3 → thth-2.4.0}/tests/test_who_cli.py +0 -0
  225. {thth-2.3.3 → thth-2.4.0}/tests/test_writeback_rebase.py +0 -0
  226. {thth-2.3.3 → thth-2.4.0}/tests/test_writeback_validate.py +0 -0
  227. {thth-2.3.3 → thth-2.4.0}/thth/__init__.py +0 -0
  228. {thth-2.3.3 → thth-2.4.0}/thth/__main__.py +0 -0
  229. {thth-2.3.3 → thth-2.4.0}/thth/account_report.py +0 -0
  230. {thth-2.3.3 → thth-2.4.0}/thth/accounts.py +0 -0
  231. {thth-2.3.3 → thth-2.4.0}/thth/adapters/__init__.py +0 -0
  232. {thth-2.3.3 → thth-2.4.0}/thth/appenv.py +0 -0
  233. {thth-2.3.3 → thth-2.4.0}/thth/approval.py +0 -0
  234. {thth-2.3.3 → thth-2.4.0}/thth/ask.py +0 -0
  235. {thth-2.3.3 → thth-2.4.0}/thth/ask_cli.py +0 -0
  236. {thth-2.3.3 → thth-2.4.0}/thth/bundle.py +0 -0
  237. {thth-2.3.3 → thth-2.4.0}/thth/collect.py +0 -0
  238. {thth-2.3.3 → thth-2.4.0}/thth/forms.py +0 -0
  239. {thth-2.3.3 → thth-2.4.0}/thth/httpsafe.py +0 -0
  240. {thth-2.3.3 → thth-2.4.0}/thth/inflight.py +0 -0
  241. {thth-2.3.3 → thth-2.4.0}/thth/jst.py +0 -0
  242. {thth-2.3.3 → thth-2.4.0}/thth/lint.py +0 -0
  243. {thth-2.3.3 → thth-2.4.0}/thth/lock.py +0 -0
  244. {thth-2.3.3 → thth-2.4.0}/thth/maintain.py +0 -0
  245. {thth-2.3.3 → thth-2.4.0}/thth/oauth.py +0 -0
  246. {thth-2.3.3 → thth-2.4.0}/thth/postid.py +0 -0
  247. {thth-2.3.3 → thth-2.4.0}/thth/queuefile.py +0 -0
  248. {thth-2.3.3 → thth-2.4.0}/thth/redact.py +0 -0
  249. {thth-2.3.3 → thth-2.4.0}/thth/replies.py +0 -0
  250. {thth-2.3.3 → thth-2.4.0}/thth/retract_cli.py +0 -0
  251. {thth-2.3.3 → thth-2.4.0}/thth/scopes.py +0 -0
  252. {thth-2.3.3 → thth-2.4.0}/thth/secrets_fs.py +0 -0
  253. {thth-2.3.3 → thth-2.4.0}/thth/select.py +0 -0
  254. {thth-2.3.3 → thth-2.4.0}/thth/sent.py +0 -0
  255. {thth-2.3.3 → thth-2.4.0}/thth/systemd_gen.py +0 -0
  256. {thth-2.3.3 → thth-2.4.0}/thth/threadrun.py +0 -0
  257. {thth-2.3.3 → thth-2.4.0}/thth/threadshape.py +0 -0
  258. {thth-2.3.3 → thth-2.4.0}/thth/topic_advice.py +0 -0
  259. {thth-2.3.3 → thth-2.4.0}/thth/topic_cli.py +0 -0
  260. {thth-2.3.3 → thth-2.4.0}/thth/topic_models.py +0 -0
  261. {thth-2.3.3 → thth-2.4.0}/thth/topic_store.py +0 -0
  262. {thth-2.3.3 → thth-2.4.0}/thth/topics.py +0 -0
  263. {thth-2.3.3 → thth-2.4.0}/thth/where_cli.py +0 -0
  264. {thth-2.3.3 → thth-2.4.0}/thth/who_cli.py +0 -0
  265. {thth-2.3.3 → thth-2.4.0}/thth/writeback.py +0 -0
@@ -9,3 +9,7 @@ dist/
9
9
  .claude/worktrees/
10
10
  callback/.wrangler/
11
11
  callback/node_modules/
12
+
13
+ # Defense in depth: notification credentials must use a repo-external THTH_ROOT.
14
+ /notifications.json
15
+ /notifications.json.*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: thth
3
- Version: 2.3.3
3
+ Version: 2.4.0
4
4
  Summary: 承認済みの投稿だけを投げる門(Threads・Bluesky・Mastodon)。人が承認し、記録は利用者の git に残る。
5
5
  Project-URL: Homepage, https://thth.me
6
6
  Project-URL: Source, https://github.com/aokings/thth
@@ -33,9 +33,9 @@ watchtower(`~/Developer/watchtower`)の隣に同じ流儀で並べる。watc
33
33
 
34
34
  ## 版
35
35
 
36
- **2.0.1**。門を無料で開ける版(2.0.1: 同席送信の採集・セキュリティ監査 2 回の直し)(`pip install`・`thth ask`・台帳を repo の外へ)。範囲と裁定は [docs/設計_v2_泉と門_2026-09-13.md](docs/設計_v2_泉と門_2026-09-13.md) §3・§7、その前の版は [docs/設計_v1.0.0_他人が導入できる版_2026-09-12.md](docs/設計_v1.0.0_他人が導入できる版_2026-09-12.md)、導入は [docs/導入_自分のMetaアプリで動かす.md](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
36
+ このソースの版は **2.4.0**。現在の設計は [自分の泉](docs/設計_自分の泉_2026-09-16.md)、導入は [自分の Meta アプリで動かす](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
37
37
 
38
- `thth/VERSION` は `2.0.1`(版は `thth/VERSION` の 1 か所・`server.json` はテストで一致を強制)。`origin/release` は v2.0.0(`216af9f`)で、**v2.0.1 はまだ配っていない**(配布は masaru の一言)。出口条件の試験は(運用日誌 thth-notes: `記録/試験_LLMに選ばせる_2026-09-13.md`)。
38
+ 版の正本は `thth/VERSION`(`server.json` はテストで一致を強制)。開発中の `main` には未配布の変更も含まれます。インストール済みの版は `thth --version`、VM の版と revision は `thth board` で確認してください。
39
39
 
40
40
  **`main` への push は保存だけ。`release` を進める操作が配布**(VM は `release` だけを追う。設計 §3.2.1)。
41
41
 
@@ -43,14 +43,14 @@ watchtower(`~/Developer/watchtower`)の隣に同じ流儀で並べる。watc
43
43
 
44
44
  各プロジェクトのセッションが読むのは [docs/使い方_プロジェクトのセッション向け_2026-09-09.md](docs/使い方_プロジェクトのセッション向け_2026-09-09.md) **だけ**。設計書は作った側の記録なので読まなくてよい。
45
45
 
46
- ## いまの状態(2026-09-13)
46
+ ## 実装と運用の状態(2026-09-18)
47
47
 
48
- 版 **2.3.3**。全件テスト **2320 件**(`python -m pytest tests/ -q -n auto -p no:cacheprovider`・1 skip・rc=0)。
48
+ 2.4.0 の実装 revision の全件テストは **2452 件**(`python -m pytest tests/ -q -n auto -p no:cacheprovider`・1 skip・rc=0)。開発中の変更の検証は対象 revision の CI を参照してください。
49
49
 
50
50
  **媒体**: Threads(稼働)・Bluesky・Mastodon(同席用の台帳あり・未稼働)。
51
51
 
52
- **本番稼働中**: Threads の 4 アカウント(nigamilab・asmon 関東・kopicha・masaru の同席用)。
53
- timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集(`thth replies`)と数の採集
52
+ **定期実行中**: Threads の 3 アカウント(nigamilab・asmon 関東・kopicha)。masaru の Threads は同席用です。
53
+ timer(systemd・`thth systemd` で生成)は10分ごとに実行し、投稿間隔と静かな時間帯を尊重します。返信の採集(`thth replies`)と数の採集
54
54
  (`thth measured`)は稼働、トークン更新は `thth maintain` が毎日。
55
55
 
56
56
  **入口は 4 つ**: 厚い CLI(`bin/thth`・`python -m thth`)、薄い MCP(`mcp/server.py`・読み取りと
@@ -59,6 +59,14 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
59
59
 
60
60
  **トピックの棚**(`thth topics`): 観測者ごとに並ぶ・打ち消し `retract-note`・`history`。
61
61
 
62
+ ### v2.4.0 の変更
63
+
64
+ - 利用者・管理者への停止/復旧メールと、元原稿の運用記録。設定・秘密は repo 外に保存します。導入時は [共通通知手順](docs/停止通知と運用記録.md) を実施します。
65
+ - VM・プロセス停止を検知する外部 missed-ping 監視と、board の停止理由表示。
66
+ - Threads の投稿エラーに HTTP 番号・許可した API コード等を記録。本文や任意のエラーメッセージは保存しません。
67
+ - `after` の投稿集計、project 指定、topic kind 別集計。
68
+ - self-update の署名検証と merge を同一 commit に固定し、媒体固有の秘密値を伏字対象へ追加。
69
+
62
70
  ### v2.0.0 で増えた口
63
71
 
64
72
  - **台帳を repo の外へ**(設計 v2 §3・裁定 §7-1)。正は `$THTH_ROOT/accounts/`(`$THTH_ACCOUNTS_DIR` があればそちら)。
@@ -74,20 +82,19 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
74
82
  は `local`。泉のサーバはまだ無い)。原稿本文は渡さないし、答えにも出ない。
75
83
  **n が閾値(既定 20)に満たない群は中央値を返さず `cannot_say` に理由を出す**——
76
84
  手元の水ではほとんどが `cannot_say` になる。それが正しい答えで、rc は 0。MCP からは `before_you_post`。
77
- - **読む口(`thth where`・`thth thread`・`thth who`)は何も保存しない**(裁定
78
- 2026-09-16「横断の泉はやめる」)。残るのは絡みの台帳(自分の行為と反応)だけ。
85
+ - **読む口(`thth where`・`thth thread`・`thth who`)は取得した投稿本文を保存しません**(裁定
86
+ 2026-09-16「横断の泉はやめる」)。検索語・投稿ID・件数等の最小限の実行記録と、絡みの台帳(自分の行為と反応)は残ります。
79
87
  - **英語の文書**: [README.en.md](README.en.md)・[docs/usage.en.md](docs/usage.en.md)・[llms.txt](llms.txt)。
80
88
  - **skill**: `skills/thth/SKILL.md`(wheel にも入る)。
81
89
 
82
- - **動くもの**(`thth --help` の全 35 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`topics`・`forms`・`queue`・`schedule`・`throw`・`run`・`systemd`・`board`・`collect`・`pull`・`auth`・`refresh`・`maintain`・`send`・`doctor`・`app`・`token`・`ask`・`mentions`・`profile`・`thread`・`where`・`who`・`retract`・`location`。
90
+ - **動くもの**(`thth --help` の全 36 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`topics`・`forms`・`queue`・`schedule`・`throw`・`run`・`systemd`・`board`・`collect`・`pull`・`auth`・`refresh`・`maintain`・`send`・`doctor`・`app`・`token`・`ask`・`mentions`・`profile`・`thread`・`where`・`who`・`retract`・`location`・`notifications`。
83
91
  - **最初の本番投稿の記録**: 2026-09-09、@aoking に疎通確認を 1 本(`17916074118445631`)。
84
92
  - **未着手**: X・Facebook ページ・Instagram の各アダプタ。トピック検索の権限(tester には降りない)。泉のサーバ(v2-5)。
85
93
  - **権限の制約**: tester に降りる scope は 5 つ。削除はできない。
86
- - **masaru の手が要るもの**: repo を public にする切替と `LICENSE`、tag と `release` を進める操作(PyPI と MCP registry は 2.0.1 まで公開済み)。
94
+ - **配布**: `release` への反映と version tag の push を分けます。tag の CI が全件テスト後に PyPI と MCP registry へ OIDC で公開します。
87
95
 
88
96
  ## MCP registry
89
97
 
90
98
  registry は「この PyPI の名前を名乗ってよいのは誰か」を、**配布物の README にこの 1 行があるか**で確かめる(設計 v2-4 §3・一次資料は quickstart・**L2**)。だから消さないこと——消すと登録(`mcp-publisher publish`)が通らなくなる。形(`server.json` と版の一致)は `tests/test_server_json.py` が見張る。
91
99
 
92
100
  mcp-name: io.github.aokings/thth
93
-
@@ -9,9 +9,9 @@ watchtower(`~/Developer/watchtower`)の隣に同じ流儀で並べる。watc
9
9
 
10
10
  ## 版
11
11
 
12
- **2.0.1**。門を無料で開ける版(2.0.1: 同席送信の採集・セキュリティ監査 2 回の直し)(`pip install`・`thth ask`・台帳を repo の外へ)。範囲と裁定は [docs/設計_v2_泉と門_2026-09-13.md](docs/設計_v2_泉と門_2026-09-13.md) §3・§7、その前の版は [docs/設計_v1.0.0_他人が導入できる版_2026-09-12.md](docs/設計_v1.0.0_他人が導入できる版_2026-09-12.md)、導入は [docs/導入_自分のMetaアプリで動かす.md](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
12
+ このソースの版は **2.4.0**。現在の設計は [自分の泉](docs/設計_自分の泉_2026-09-16.md)、導入は [自分の Meta アプリで動かす](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
13
13
 
14
- `thth/VERSION` は `2.0.1`(版は `thth/VERSION` の 1 か所・`server.json` はテストで一致を強制)。`origin/release` は v2.0.0(`216af9f`)で、**v2.0.1 はまだ配っていない**(配布は masaru の一言)。出口条件の試験は(運用日誌 thth-notes: `記録/試験_LLMに選ばせる_2026-09-13.md`)。
14
+ 版の正本は `thth/VERSION`(`server.json` はテストで一致を強制)。開発中の `main` には未配布の変更も含まれます。インストール済みの版は `thth --version`、VM の版と revision は `thth board` で確認してください。
15
15
 
16
16
  **`main` への push は保存だけ。`release` を進める操作が配布**(VM は `release` だけを追う。設計 §3.2.1)。
17
17
 
@@ -19,14 +19,14 @@ watchtower(`~/Developer/watchtower`)の隣に同じ流儀で並べる。watc
19
19
 
20
20
  各プロジェクトのセッションが読むのは [docs/使い方_プロジェクトのセッション向け_2026-09-09.md](docs/使い方_プロジェクトのセッション向け_2026-09-09.md) **だけ**。設計書は作った側の記録なので読まなくてよい。
21
21
 
22
- ## いまの状態(2026-09-13)
22
+ ## 実装と運用の状態(2026-09-18)
23
23
 
24
- 版 **2.3.3**。全件テスト **2320 件**(`python -m pytest tests/ -q -n auto -p no:cacheprovider`・1 skip・rc=0)。
24
+ 2.4.0 の実装 revision の全件テストは **2452 件**(`python -m pytest tests/ -q -n auto -p no:cacheprovider`・1 skip・rc=0)。開発中の変更の検証は対象 revision の CI を参照してください。
25
25
 
26
26
  **媒体**: Threads(稼働)・Bluesky・Mastodon(同席用の台帳あり・未稼働)。
27
27
 
28
- **本番稼働中**: Threads の 4 アカウント(nigamilab・asmon 関東・kopicha・masaru の同席用)。
29
- timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集(`thth replies`)と数の採集
28
+ **定期実行中**: Threads の 3 アカウント(nigamilab・asmon 関東・kopicha)。masaru の Threads は同席用です。
29
+ timer(systemd・`thth systemd` で生成)は10分ごとに実行し、投稿間隔と静かな時間帯を尊重します。返信の採集(`thth replies`)と数の採集
30
30
  (`thth measured`)は稼働、トークン更新は `thth maintain` が毎日。
31
31
 
32
32
  **入口は 4 つ**: 厚い CLI(`bin/thth`・`python -m thth`)、薄い MCP(`mcp/server.py`・読み取りと
@@ -35,6 +35,14 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
35
35
 
36
36
  **トピックの棚**(`thth topics`): 観測者ごとに並ぶ・打ち消し `retract-note`・`history`。
37
37
 
38
+ ### v2.4.0 の変更
39
+
40
+ - 利用者・管理者への停止/復旧メールと、元原稿の運用記録。設定・秘密は repo 外に保存します。導入時は [共通通知手順](docs/停止通知と運用記録.md) を実施します。
41
+ - VM・プロセス停止を検知する外部 missed-ping 監視と、board の停止理由表示。
42
+ - Threads の投稿エラーに HTTP 番号・許可した API コード等を記録。本文や任意のエラーメッセージは保存しません。
43
+ - `after` の投稿集計、project 指定、topic kind 別集計。
44
+ - self-update の署名検証と merge を同一 commit に固定し、媒体固有の秘密値を伏字対象へ追加。
45
+
38
46
  ### v2.0.0 で増えた口
39
47
 
40
48
  - **台帳を repo の外へ**(設計 v2 §3・裁定 §7-1)。正は `$THTH_ROOT/accounts/`(`$THTH_ACCOUNTS_DIR` があればそちら)。
@@ -50,20 +58,19 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
50
58
  は `local`。泉のサーバはまだ無い)。原稿本文は渡さないし、答えにも出ない。
51
59
  **n が閾値(既定 20)に満たない群は中央値を返さず `cannot_say` に理由を出す**——
52
60
  手元の水ではほとんどが `cannot_say` になる。それが正しい答えで、rc は 0。MCP からは `before_you_post`。
53
- - **読む口(`thth where`・`thth thread`・`thth who`)は何も保存しない**(裁定
54
- 2026-09-16「横断の泉はやめる」)。残るのは絡みの台帳(自分の行為と反応)だけ。
61
+ - **読む口(`thth where`・`thth thread`・`thth who`)は取得した投稿本文を保存しません**(裁定
62
+ 2026-09-16「横断の泉はやめる」)。検索語・投稿ID・件数等の最小限の実行記録と、絡みの台帳(自分の行為と反応)は残ります。
55
63
  - **英語の文書**: [README.en.md](README.en.md)・[docs/usage.en.md](docs/usage.en.md)・[llms.txt](llms.txt)。
56
64
  - **skill**: `skills/thth/SKILL.md`(wheel にも入る)。
57
65
 
58
- - **動くもの**(`thth --help` の全 35 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`topics`・`forms`・`queue`・`schedule`・`throw`・`run`・`systemd`・`board`・`collect`・`pull`・`auth`・`refresh`・`maintain`・`send`・`doctor`・`app`・`token`・`ask`・`mentions`・`profile`・`thread`・`where`・`who`・`retract`・`location`。
66
+ - **動くもの**(`thth --help` の全 36 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`topics`・`forms`・`queue`・`schedule`・`throw`・`run`・`systemd`・`board`・`collect`・`pull`・`auth`・`refresh`・`maintain`・`send`・`doctor`・`app`・`token`・`ask`・`mentions`・`profile`・`thread`・`where`・`who`・`retract`・`location`・`notifications`。
59
67
  - **最初の本番投稿の記録**: 2026-09-09、@aoking に疎通確認を 1 本(`17916074118445631`)。
60
68
  - **未着手**: X・Facebook ページ・Instagram の各アダプタ。トピック検索の権限(tester には降りない)。泉のサーバ(v2-5)。
61
69
  - **権限の制約**: tester に降りる scope は 5 つ。削除はできない。
62
- - **masaru の手が要るもの**: repo を public にする切替と `LICENSE`、tag と `release` を進める操作(PyPI と MCP registry は 2.0.1 まで公開済み)。
70
+ - **配布**: `release` への反映と version tag の push を分けます。tag の CI が全件テスト後に PyPI と MCP registry へ OIDC で公開します。
63
71
 
64
72
  ## MCP registry
65
73
 
66
74
  registry は「この PyPI の名前を名乗ってよいのは誰か」を、**配布物の README にこの 1 行があるか**で確かめる(設計 v2-4 §3・一次資料は quickstart・**L2**)。だから消さないこと——消すと登録(`mcp-publisher publish`)が通らなくなる。形(`server.json` と版の一致)は `tests/test_server_json.py` が見張る。
67
75
 
68
76
  mcp-name: io.github.aokings/thth
69
-
@@ -151,7 +151,10 @@ TOOLS = [
151
151
  "inputSchema": {
152
152
  "type": "object",
153
153
  "properties": {
154
- "account": {"type": "string", "description": "account 名"},
154
+ "account": {"type": "string",
155
+ "description": "account 名(project の代わり)"},
156
+ "project": {"type": "string",
157
+ "description": "この project の account 全部(account の代わり)"},
155
158
  "topic": {"type": "string", "description": "語(トピック)"},
156
159
  "kind": {"type": "string", "description": "型(行動・年度付き 等)"},
157
160
  "hour_band": {"type": "string",
@@ -164,7 +167,7 @@ TOOLS = [
164
167
  "min_n": {"type": "integer",
165
168
  "description": "中央値を返す下限(既定 5)"},
166
169
  },
167
- "required": ["account"],
170
+ # account / project の排他的 OR は validate_arguments() で見る。
168
171
  },
169
172
  },
170
173
  {
@@ -409,12 +412,17 @@ def validate_arguments(name: str, arguments) -> dict:
409
412
  f"CLI の旗と区別できないので受け取りません")
410
413
  if key == "file":
411
414
  check_file_argument(name, value)
412
- if name in ("where_to_appear", "who_is_this") and not arguments.get("account") \
415
+ if name in ("after_you_posted", "where_to_appear", "who_is_this") \
416
+ and not arguments.get("account") \
413
417
  and not arguments.get("project"):
414
418
  # **`account` か `project` のどちらか必須**(`required` は AND の意味しか
415
419
  # 持てないので、ここで OR を見る・T2-3 発注書・T3-3 も同じ形)。
416
420
  raise ToolInputError(
417
421
  f"{name}: account か project のどちらかが要ります")
422
+ if name == "after_you_posted" and arguments.get("account") \
423
+ and arguments.get("project"):
424
+ raise ToolInputError(
425
+ f"{name}: account と project は同時に指定できません")
418
426
  if name == "who_is_this" and not arguments.get("author_key") \
419
427
  and not arguments.get("username"):
420
428
  # **`author_key` か `username` のどちらか必須**(同じ理由で OR を
@@ -497,7 +505,11 @@ def call_tool(name: str, arguments: dict | None) -> dict:
497
505
  text = proc.stdout
498
506
  elif name == "after_you_posted":
499
507
  # **`before_you_post` と同じ型**(発注 T0-2): CLI を `--json` で呼ぶだけ。
500
- args = ["after", arguments["account"]]
508
+ args = ["after"]
509
+ if arguments.get("project"):
510
+ args += ["--project", arguments["project"]]
511
+ else:
512
+ args.append(arguments["account"])
501
513
  if arguments.get("topic"):
502
514
  args += ["--topic", arguments["topic"]]
503
515
  if arguments.get("kind"):
@@ -106,15 +106,18 @@ thth approve <同じ> --confirm <digest> --by "<承認した人>" # 二段
106
106
  ### 6. 測る——出したあとの反応
107
107
 
108
108
  ```bash
109
- thth after <account> [--reply-to <post_id>] [--topic …]
109
+ thth after (<account>|--project <project>) [--reply-to <post_id>] [--topic …] [--kind …]
110
110
  ```
111
111
 
112
112
  MCP `after_you_posted`。**24h の刻みが無ければ `null`**(0 と混ぜない・
113
113
  `covered: false` を付ける)。`one_thing_to_change` は 1 個か `null`。
114
+ `posts` は所有を確認できた実測台帳の根投稿だけ(`n` と 24h views の中央値・
115
+ 分母)、`engagements` は絡みに行った返信。`kind` は現在の topic shelf の分類で、
116
+ 投稿構成の `form` や投稿時点の分類ではない。
114
117
  **残すもの: なし**(この口は読むだけ。絡みの台帳は**公開の瞬間**に 1 行書かれる——
115
118
  自分の行為と反応だけで、相手の本文・名前・自分の判断は入らない)。
116
- **媒体をまたぐ数は無い**——project 単位で並べるだけで、足さない・割らない・
117
- 順位も付けない。
119
+ **媒体・account をまたぐ数は無い**——`--project` は `by_account` に並べるだけで、
120
+ 足さない・割らない・順位も付けない。
118
121
 
119
122
  ---
120
123
 
@@ -123,3 +126,9 @@ MCP `after_you_posted`。**24h の刻みが無ければ `null`**(0 と混ぜ
123
126
  - `thth --help` / `thth <subcommand> --help` が正本。
124
127
  - `thth doctor <account>` が「いま投稿できる状態か」を最初から最後まで言う。
125
128
  - 使い方の全文: `docs/使い方_プロジェクトのセッション向け_2026-09-09.md`。
129
+
130
+ ## 停止通知と運用状況(開発版 main)
131
+
132
+ 新規 account は利用者メール・管理者メール・TLS SMTP を `thth notifications config` で設定し、`status` → `test` を実行する。両宛先の受信箱で到達、account 専用 HEALTHCHECK_URL の missed-ping 通知を確認してから production/scheduled を有効にする。既存 account にも同じ設定を追加する。詳細は `docs/停止通知と運用記録.md`。
133
+
134
+ プロジェクトの作業開始・再開時は `git fetch` 後にリモート `docs/sns/queue/` の `thth_run_state`・`thth_run_detail`・`thth_run_next` を確認する。dirty worktree へ無条件に pull しない。リモートの確認は `git show origin/main:docs/sns/queue/FILE.md` 等で行える。停止・成否不明なら inflight を消して再投稿せず、示された確認を行う。復旧状態は投稿成功の保証ではなく、公開結果は status/post_id/posted_at を見る。