thth 2.3.3__tar.gz → 2.5.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.
- {thth-2.3.3 → thth-2.5.0}/.gitignore +4 -0
- {thth-2.3.3 → thth-2.5.0}/PKG-INFO +34 -11
- {thth-2.3.3 → thth-2.5.0}/README.md +33 -10
- {thth-2.3.3 → thth-2.5.0}/mcp/server.py +75 -5
- {thth-2.3.3 → thth-2.5.0}/skills/thth/SKILL.md +22 -3
- thth-2.5.0/tests/test_after_cli.py +422 -0
- thth-2.5.0/tests/test_analytics_comparison.py +213 -0
- thth-2.5.0/tests/test_analytics_report.py +115 -0
- thth-2.5.0/tests/test_api_diagnostic.py +181 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_bluesky_secret_scrub.py +6 -2
- {thth-2.3.3 → thth-2.5.0}/tests/test_board_running.py +35 -3
- {thth-2.3.3 → thth-2.5.0}/tests/test_cli_help.py +2 -2
- thth-2.5.0/tests/test_healthcheck_notifications.py +347 -0
- thth-2.5.0/tests/test_incident_notifications.py +416 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_llm_trial.py +93 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_mcp.py +1 -1
- thth-2.5.0/tests/test_operations_handoff.py +156 -0
- thth-2.5.0/tests/test_report_checkout_import.py +36 -0
- thth-2.5.0/tests/test_report_http.py +366 -0
- thth-2.5.0/tests/test_report_isolation.py +131 -0
- thth-2.5.0/tests/test_report_service.py +107 -0
- thth-2.5.0/tests/test_search_media_routes.py +85 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_secret_value_redact.py +55 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_selfupdate.py +56 -0
- thth-2.5.0/tests/test_send_control_chars.py +59 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_site.py +5 -7
- thth-2.5.0/tests/test_study_report.py +169 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_thread_read.py +10 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_review_fixes.py +26 -14
- {thth-2.3.3 → thth-2.5.0}/tests/test_trial_frictions.py +36 -0
- thth-2.5.0/tests/test_x_metrics.py +156 -0
- thth-2.5.0/thth/VERSION +1 -0
- {thth-2.3.3 → thth-2.5.0}/thth/account_cli.py +22 -2
- {thth-2.3.3 → thth-2.5.0}/thth/adapters/base.py +9 -0
- {thth-2.3.3 → thth-2.5.0}/thth/adapters/bluesky.py +12 -0
- {thth-2.3.3 → thth-2.5.0}/thth/adapters/mastodon.py +7 -0
- {thth-2.3.3 → thth-2.5.0}/thth/adapters/threads.py +11 -7
- thth-2.5.0/thth/after_cli.py +623 -0
- thth-2.5.0/thth/analytics_comparison.py +257 -0
- thth-2.5.0/thth/analytics_report.py +129 -0
- thth-2.5.0/thth/api_diagnostic.py +51 -0
- {thth-2.3.3 → thth-2.5.0}/thth/cli.py +149 -31
- {thth-2.3.3 → thth-2.5.0}/thth/core.py +40 -12
- {thth-2.3.3 → thth-2.5.0}/thth/doctor.py +4 -0
- {thth-2.3.3 → thth-2.5.0}/thth/engagements.py +4 -1
- thth-2.5.0/thth/healthcheck.py +451 -0
- thth-2.5.0/thth/incident.py +536 -0
- {thth-2.3.3 → thth-2.5.0}/thth/measured.py +13 -2
- thth-2.5.0/thth/operations_handoff.py +231 -0
- {thth-2.3.3 → thth-2.5.0}/thth/report.py +37 -1
- thth-2.5.0/thth/report_http.py +337 -0
- thth-2.5.0/thth/report_isolation.py +128 -0
- thth-2.5.0/thth/report_service.py +102 -0
- {thth-2.3.3 → thth-2.5.0}/thth/runs.py +3 -0
- {thth-2.3.3 → thth-2.5.0}/thth/selfupdate.py +33 -12
- thth-2.5.0/thth/study_report.py +201 -0
- {thth-2.3.3 → thth-2.5.0}/thth/thread_read.py +1 -12
- {thth-2.3.3 → thth-2.5.0}/thth/threads_read_cli.py +6 -2
- {thth-2.3.3 → thth-2.5.0}/thth/threadthrow.py +11 -4
- thth-2.5.0/thth/x_metrics.py +158 -0
- thth-2.3.3/tests/test_after_cli.py +0 -205
- thth-2.3.3/thth/VERSION +0 -1
- thth-2.3.3/thth/after_cli.py +0 -342
- {thth-2.3.3 → thth-2.5.0}/LICENSE +0 -0
- {thth-2.3.3 → thth-2.5.0}/accounts.example/bluesky.json +0 -0
- {thth-2.3.3 → thth-2.5.0}/accounts.example/mastodon.json +0 -0
- {thth-2.3.3 → thth-2.5.0}/accounts.example/threads.json +0 -0
- {thth-2.3.3 → thth-2.5.0}/bin/thth +0 -0
- {thth-2.3.3 → thth-2.5.0}/bin/thth-remote +0 -0
- {thth-2.3.3 → thth-2.5.0}/bin/thth-run +0 -0
- {thth-2.3.3 → thth-2.5.0}/pyproject.toml +0 -0
- {thth-2.3.3 → thth-2.5.0}/systemd/thth@.service +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/__init__.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/conftest.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/fixtures/build_injection_eval.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/fixtures/callback/worker_responses.json +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/fixtures/injection_eval.json +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/fixtures/umami-bile.md +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/__init__.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_oauth_server.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_push_adapter.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_redirect_server.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_search_adapter.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_threads_reader.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/fake_threads_writes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/hold_lock.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/hold_repo_lock.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/helpers/worker_probe.mjs +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_account_name_check.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_account_report.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_accounts_dir.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_adapter_boundary.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_api_error_body.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_app_env_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_approval.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_approve_cmd.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_ask.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_atlas_fifth_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_atlas_fourth_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_atlas_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_atlas_second_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_atlas_third_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit1_fixes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit2_fixes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_b_counterexamples.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_b_m1_semantics.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_b_n1_depth.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_b_r1_closure.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_v201.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_audit_v23_details.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_auth.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_auth_identity_required.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_behind_remote.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_bluesky_adapter.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_board_needs_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_bundle.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_charcount.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_cli_entrypoint.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_cli_vm_path.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_collect.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_collect_engagements.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_collect_runs.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_collect_sent.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_comparability.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_control_chars_refused.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_conversation_paging.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_count_for.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_docs_links.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_doctor.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_doctor_all_permissions.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_doctor_next_step.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_duplicate_front_matter_keys.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_editorial_audit.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_editorial_n3_n4.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_engagements.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_external_acceptance.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_fake_api.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_form_spec.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_form_spec_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_forms.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_fresh_install.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_front_matter_injection.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_hypotheses.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_hypothesis_boundaries.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_hypothesis_units.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_impact_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_inbox_granted_scopes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_independent_thread_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_independent_topic_review.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_independent_topic_review_r2.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_inflight.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_jst.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_lint.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_list_projections.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_llm_trial_engage.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_lock.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_m2_independent.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_maintain.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_mastodon_adapter.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_mastodon_visibility.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_max_per_run.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_mcp_robustness.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_measured.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_media_accounts.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_media_next_steps.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_media_roundtrip.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_mismatch_diagnostics.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_n5_reply_null_element.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_n6_replies_incomplete_ledger.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_n7_doctor_error_body.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_no_limits.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_observation_provenance.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_packaging.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_preview.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_production_mode.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_pull_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_queue.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_quiet_hours.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_r2_r4_r5.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_read_cli_bare_runtimeerror.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_reason_adoption.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_redact.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_redirect_token_leak.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_refresh.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_refresh_destination.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_rejudge_new.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_rejudge_r2_r3.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_replies.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_replies_refresh.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_repo_lock.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_repo_sync.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_reverse_audit.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_case_id_cluster_m2.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_case_id_cluster_r2.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_evidence_account.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_form_spec_and_case_id.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_provenance.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_review_records.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_revoke.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_roundtrip.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_run_missing_env.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_run_record_failclosed.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_runs_collected.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_runs_read_rows.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_schedule_multiple.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_schedule_view.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_scopes_source_requested.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_search_engage_targets.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_secrets_grep.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_security_small_fixes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_select.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_send.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_send_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_send_media.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_send_visibility.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_sent_integrity.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_server_json.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_skill_doc.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_systemd.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_thread_publish.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_threadrun.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_threads_read_permissions.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_threadshape.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_thth_root.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_token_exists.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_token_scopes_record.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_token_set.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_advice.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_models.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_shelf_observers.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topic_store.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topics_record_concurrent.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_topics_tool.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_v21b_approved_writes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_value_domains_shown.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_version.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_where_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_who_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_writeback_rebase.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/tests/test_writeback_validate.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/__init__.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/__main__.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/account_report.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/accounts.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/adapters/__init__.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/appenv.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/approval.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/ask.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/ask_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/bundle.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/collect.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/forms.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/httpsafe.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/inflight.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/jst.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/lint.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/lock.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/maintain.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/oauth.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/postid.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/queuefile.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/redact.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/replies.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/retract_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/scopes.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/secrets_fs.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/select.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/sent.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/systemd_gen.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/threadrun.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/threadshape.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/topic_advice.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/topic_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/topic_models.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/topic_store.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/topics.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/where_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/who_cli.py +0 -0
- {thth-2.3.3 → thth-2.5.0}/thth/writeback.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: thth
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.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.
|
|
36
|
+
このソースの版は **2.5.0**。現在の設計は [自分の泉](docs/設計_自分の泉_2026-09-16.md)、導入は [自分の Meta アプリで動かす](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
|
|
37
37
|
|
|
38
|
-
`thth/VERSION`
|
|
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
|
-
##
|
|
46
|
+
## 実装と運用の状態(2026-09-18)
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
2.5.0 の実装 revision の全件テストは **2690 件**(`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
|
-
|
|
53
|
-
timer(systemd・`thth systemd`
|
|
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,21 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
|
|
|
59
59
|
|
|
60
60
|
**トピックの棚**(`thth topics`): 観測者ごとに並ぶ・打ち消し `retract-note`・`history`。
|
|
61
61
|
|
|
62
|
+
### v2.5.0 の変更
|
|
63
|
+
|
|
64
|
+
- 読み取り専用のレポート 3 本: `analytics-report`(活動のスナップショット・`--compare-previous` で隣接期間の比較)・`handoff-report`(ローカル運用記録の引継ぎ)・`study-report`(施策の宣言と本人の観測の結合)。MCP に `analytics_report`・`operations_handoff`・`study_report`。数値は期間・母数・欠測・根拠を連れて歩き、因果や推奨は出しません。
|
|
65
|
+
- `serve-reports`: 専用環境向けの非公開レポート HTTP(Unix socket 既定・service credential・読むだけ)。**開発版**で、人の認証・TLS・一般提供は含みません。[限界](docs/非公開レポートHTTP_v1.md)。
|
|
66
|
+
- X の本人公開指標の純粋な変換関数(API・投稿・台帳には未接続)。
|
|
67
|
+
- 独立監査(P2 4・P3 7)とその直し: Unix socket 既定・要求全体の 10 秒 deadline・分離検査の走査を読取 dir に限定・期間比較の母集団から時刻不一致の返信を除外・git 無しでも import 可。
|
|
68
|
+
|
|
69
|
+
### v2.4.0 の変更
|
|
70
|
+
|
|
71
|
+
- 利用者・管理者への停止/復旧メールと、元原稿の運用記録。設定・秘密は repo 外に保存します。導入時は [共通通知手順](docs/停止通知と運用記録.md) を実施します。
|
|
72
|
+
- VM・プロセス停止を検知する外部 missed-ping 監視と、board の停止理由表示。
|
|
73
|
+
- Threads の投稿エラーに HTTP 番号・許可した API コード等を記録。本文や任意のエラーメッセージは保存しません。
|
|
74
|
+
- `after` の投稿集計、project 指定、topic kind 別集計。
|
|
75
|
+
- self-update の署名検証と merge を同一 commit に固定し、媒体固有の秘密値を伏字対象へ追加。
|
|
76
|
+
|
|
62
77
|
### v2.0.0 で増えた口
|
|
63
78
|
|
|
64
79
|
- **台帳を repo の外へ**(設計 v2 §3・裁定 §7-1)。正は `$THTH_ROOT/accounts/`(`$THTH_ACCOUNTS_DIR` があればそちら)。
|
|
@@ -74,16 +89,16 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
|
|
|
74
89
|
は `local`。泉のサーバはまだ無い)。原稿本文は渡さないし、答えにも出ない。
|
|
75
90
|
**n が閾値(既定 20)に満たない群は中央値を返さず `cannot_say` に理由を出す**——
|
|
76
91
|
手元の水ではほとんどが `cannot_say` になる。それが正しい答えで、rc は 0。MCP からは `before_you_post`。
|
|
77
|
-
- **読む口(`thth where`・`thth thread`・`thth who
|
|
78
|
-
2026-09-16
|
|
92
|
+
- **読む口(`thth where`・`thth thread`・`thth who`)は取得した投稿本文を保存しません**(裁定
|
|
93
|
+
2026-09-16「横断の泉はやめる」)。検索語・投稿ID・件数等の最小限の実行記録と、絡みの台帳(自分の行為と反応)は残ります。
|
|
79
94
|
- **英語の文書**: [README.en.md](README.en.md)・[docs/usage.en.md](docs/usage.en.md)・[llms.txt](llms.txt)。
|
|
80
95
|
- **skill**: `skills/thth/SKILL.md`(wheel にも入る)。
|
|
81
96
|
|
|
82
|
-
- **動くもの**(`thth --help` の全
|
|
97
|
+
- **動くもの**(`thth --help` の全 40 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`analytics-report`・`study-report`・`handoff-report`・`serve-reports`・`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
98
|
- **最初の本番投稿の記録**: 2026-09-09、@aoking に疎通確認を 1 本(`17916074118445631`)。
|
|
84
99
|
- **未着手**: X・Facebook ページ・Instagram の各アダプタ。トピック検索の権限(tester には降りない)。泉のサーバ(v2-5)。
|
|
85
100
|
- **権限の制約**: tester に降りる scope は 5 つ。削除はできない。
|
|
86
|
-
-
|
|
101
|
+
- **配布**: `release` への反映と version tag の push を分けます。tag の CI が全件テスト後に PyPI と MCP registry へ OIDC で公開します。
|
|
87
102
|
|
|
88
103
|
## MCP registry
|
|
89
104
|
|
|
@@ -91,3 +106,11 @@ registry は「この PyPI の名前を名乗ってよいのは誰か」を、**
|
|
|
91
106
|
|
|
92
107
|
mcp-name: io.github.aokings/thth
|
|
93
108
|
|
|
109
|
+
## v3 基盤(2.5.0 から)
|
|
110
|
+
|
|
111
|
+
`study-report` は明示した施策の宣言と本人の投稿観測を結ぶ読み取り専用レポートです。採用者の本人確認や因果効果は主張しません。[使い方と契約](docs/施策レポート_v1.md)。
|
|
112
|
+
|
|
113
|
+
`analytics-report` はローカル台帳から期間・母数・欠測・根拠を揃えたスナップショットを返します。
|
|
114
|
+
[形式と使い方](docs/分析レポート_v1.md)。
|
|
115
|
+
|
|
116
|
+
`handoff-report` / MCP `operations_handoff` はローカル運用状態・通知未処理を鮮度の制約付きで返します。[形式と使い方](docs/運用引継ぎレポート_v1.md)。
|
|
@@ -9,9 +9,9 @@ watchtower(`~/Developer/watchtower`)の隣に同じ流儀で並べる。watc
|
|
|
9
9
|
|
|
10
10
|
## 版
|
|
11
11
|
|
|
12
|
-
**2.
|
|
12
|
+
このソースの版は **2.5.0**。現在の設計は [自分の泉](docs/設計_自分の泉_2026-09-16.md)、導入は [自分の Meta アプリで動かす](docs/導入_自分のMetaアプリで動かす.md)、文書の索引は [docs/README.md](docs/README.md)。
|
|
13
13
|
|
|
14
|
-
`thth/VERSION`
|
|
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
|
-
##
|
|
22
|
+
## 実装と運用の状態(2026-09-18)
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
2.5.0 の実装 revision の全件テストは **2690 件**(`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
|
-
|
|
29
|
-
timer(systemd・`thth systemd`
|
|
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,21 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
|
|
|
35
35
|
|
|
36
36
|
**トピックの棚**(`thth topics`): 観測者ごとに並ぶ・打ち消し `retract-note`・`history`。
|
|
37
37
|
|
|
38
|
+
### v2.5.0 の変更
|
|
39
|
+
|
|
40
|
+
- 読み取り専用のレポート 3 本: `analytics-report`(活動のスナップショット・`--compare-previous` で隣接期間の比較)・`handoff-report`(ローカル運用記録の引継ぎ)・`study-report`(施策の宣言と本人の観測の結合)。MCP に `analytics_report`・`operations_handoff`・`study_report`。数値は期間・母数・欠測・根拠を連れて歩き、因果や推奨は出しません。
|
|
41
|
+
- `serve-reports`: 専用環境向けの非公開レポート HTTP(Unix socket 既定・service credential・読むだけ)。**開発版**で、人の認証・TLS・一般提供は含みません。[限界](docs/非公開レポートHTTP_v1.md)。
|
|
42
|
+
- X の本人公開指標の純粋な変換関数(API・投稿・台帳には未接続)。
|
|
43
|
+
- 独立監査(P2 4・P3 7)とその直し: Unix socket 既定・要求全体の 10 秒 deadline・分離検査の走査を読取 dir に限定・期間比較の母集団から時刻不一致の返信を除外・git 無しでも import 可。
|
|
44
|
+
|
|
45
|
+
### v2.4.0 の変更
|
|
46
|
+
|
|
47
|
+
- 利用者・管理者への停止/復旧メールと、元原稿の運用記録。設定・秘密は repo 外に保存します。導入時は [共通通知手順](docs/停止通知と運用記録.md) を実施します。
|
|
48
|
+
- VM・プロセス停止を検知する外部 missed-ping 監視と、board の停止理由表示。
|
|
49
|
+
- Threads の投稿エラーに HTTP 番号・許可した API コード等を記録。本文や任意のエラーメッセージは保存しません。
|
|
50
|
+
- `after` の投稿集計、project 指定、topic kind 別集計。
|
|
51
|
+
- self-update の署名検証と merge を同一 commit に固定し、媒体固有の秘密値を伏字対象へ追加。
|
|
52
|
+
|
|
38
53
|
### v2.0.0 で増えた口
|
|
39
54
|
|
|
40
55
|
- **台帳を repo の外へ**(設計 v2 §3・裁定 §7-1)。正は `$THTH_ROOT/accounts/`(`$THTH_ACCOUNTS_DIR` があればそちら)。
|
|
@@ -50,16 +65,16 @@ timer(systemd・`thth systemd` で生成)で毎時投稿、返信の採集
|
|
|
50
65
|
は `local`。泉のサーバはまだ無い)。原稿本文は渡さないし、答えにも出ない。
|
|
51
66
|
**n が閾値(既定 20)に満たない群は中央値を返さず `cannot_say` に理由を出す**——
|
|
52
67
|
手元の水ではほとんどが `cannot_say` になる。それが正しい答えで、rc は 0。MCP からは `before_you_post`。
|
|
53
|
-
- **読む口(`thth where`・`thth thread`・`thth who
|
|
54
|
-
2026-09-16
|
|
68
|
+
- **読む口(`thth where`・`thth thread`・`thth who`)は取得した投稿本文を保存しません**(裁定
|
|
69
|
+
2026-09-16「横断の泉はやめる」)。検索語・投稿ID・件数等の最小限の実行記録と、絡みの台帳(自分の行為と反応)は残ります。
|
|
55
70
|
- **英語の文書**: [README.en.md](README.en.md)・[docs/usage.en.md](docs/usage.en.md)・[llms.txt](llms.txt)。
|
|
56
71
|
- **skill**: `skills/thth/SKILL.md`(wheel にも入る)。
|
|
57
72
|
|
|
58
|
-
- **動くもの**(`thth --help` の全
|
|
73
|
+
- **動くもの**(`thth --help` の全 40 サブコマンド): `lint`・`preview`・`approve`・`account`・`revoke`・`posts`・`replies`・`measured`・`threads`・`after`・`analytics-report`・`study-report`・`handoff-report`・`serve-reports`・`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
74
|
- **最初の本番投稿の記録**: 2026-09-09、@aoking に疎通確認を 1 本(`17916074118445631`)。
|
|
60
75
|
- **未着手**: X・Facebook ページ・Instagram の各アダプタ。トピック検索の権限(tester には降りない)。泉のサーバ(v2-5)。
|
|
61
76
|
- **権限の制約**: tester に降りる scope は 5 つ。削除はできない。
|
|
62
|
-
-
|
|
77
|
+
- **配布**: `release` への反映と version tag の push を分けます。tag の CI が全件テスト後に PyPI と MCP registry へ OIDC で公開します。
|
|
63
78
|
|
|
64
79
|
## MCP registry
|
|
65
80
|
|
|
@@ -67,3 +82,11 @@ registry は「この PyPI の名前を名乗ってよいのは誰か」を、**
|
|
|
67
82
|
|
|
68
83
|
mcp-name: io.github.aokings/thth
|
|
69
84
|
|
|
85
|
+
## v3 基盤(2.5.0 から)
|
|
86
|
+
|
|
87
|
+
`study-report` は明示した施策の宣言と本人の投稿観測を結ぶ読み取り専用レポートです。採用者の本人確認や因果効果は主張しません。[使い方と契約](docs/施策レポート_v1.md)。
|
|
88
|
+
|
|
89
|
+
`analytics-report` はローカル台帳から期間・母数・欠測・根拠を揃えたスナップショットを返します。
|
|
90
|
+
[形式と使い方](docs/分析レポート_v1.md)。
|
|
91
|
+
|
|
92
|
+
`handoff-report` / MCP `operations_handoff` はローカル運用状態・通知未処理を鮮度の制約付きで返します。[形式と使い方](docs/運用引継ぎレポート_v1.md)。
|
|
@@ -139,6 +139,34 @@ TOOLS = [
|
|
|
139
139
|
"required": ["account", "topic"],
|
|
140
140
|
},
|
|
141
141
|
},
|
|
142
|
+
{
|
|
143
|
+
"name": "operations_handoff",
|
|
144
|
+
"description": "ローカル運用記録の状態・承認待ち・inflight・通知未処理を根拠と鮮度の制約付きで返す。同期・承認・再送はしない",
|
|
145
|
+
"inputSchema": {"type": "object", "properties": {
|
|
146
|
+
"account": {"type": "string"}, "project": {"type": "string"}}},
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "study_report",
|
|
150
|
+
"description": "ローカル施策JSONの未検証の採用宣言と本人の観測を結ぶ。proposedは集計せず、adoptedも因果効果や投稿承認を証明しない。読むだけ",
|
|
151
|
+
"inputSchema": {
|
|
152
|
+
"type": "object", "required": ["file"],
|
|
153
|
+
"properties": {"file": {"type": "string"}, "min_n": {"type": "integer"}},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "analytics_report",
|
|
158
|
+
"description": "自分の活動のスナップショットを期間・母数・欠測・根拠つきで返す。ローカル台帳を読むだけ。compare_previous=trueで前期間比較。推奨は含まない",
|
|
159
|
+
"inputSchema": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"properties": {
|
|
162
|
+
"compare_previous": {"type": "boolean", "description": "直前の同じ日数との比較(既定false)"},
|
|
163
|
+
"account": {"type": "string"},
|
|
164
|
+
"project": {"type": "string"},
|
|
165
|
+
"window_days": {"type": "integer", "description": "直近何日(既定7)"},
|
|
166
|
+
"min_n": {"type": "integer", "description": "中央値の最小母数(既定5)"},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
142
170
|
{
|
|
143
171
|
# **名前と説明文がそのまま売り文句**(設計「自分の泉」§2.2)。
|
|
144
172
|
# 実装が 1 語でも足したら設計書でなく実装を戻す(§2 の頭書きそのまま)。
|
|
@@ -151,7 +179,10 @@ TOOLS = [
|
|
|
151
179
|
"inputSchema": {
|
|
152
180
|
"type": "object",
|
|
153
181
|
"properties": {
|
|
154
|
-
"account": {"type": "string",
|
|
182
|
+
"account": {"type": "string",
|
|
183
|
+
"description": "account 名(project の代わり)"},
|
|
184
|
+
"project": {"type": "string",
|
|
185
|
+
"description": "この project の account 全部(account の代わり)"},
|
|
155
186
|
"topic": {"type": "string", "description": "語(トピック)"},
|
|
156
187
|
"kind": {"type": "string", "description": "型(行動・年度付き 等)"},
|
|
157
188
|
"hour_band": {"type": "string",
|
|
@@ -164,7 +195,7 @@ TOOLS = [
|
|
|
164
195
|
"min_n": {"type": "integer",
|
|
165
196
|
"description": "中央値を返す下限(既定 5)"},
|
|
166
197
|
},
|
|
167
|
-
|
|
198
|
+
# account / project の排他的 OR は validate_arguments() で見る。
|
|
168
199
|
},
|
|
169
200
|
},
|
|
170
201
|
{
|
|
@@ -409,12 +440,17 @@ def validate_arguments(name: str, arguments) -> dict:
|
|
|
409
440
|
f"CLI の旗と区別できないので受け取りません")
|
|
410
441
|
if key == "file":
|
|
411
442
|
check_file_argument(name, value)
|
|
412
|
-
if name in ("
|
|
443
|
+
if name in ("operations_handoff", "analytics_report", "after_you_posted", "where_to_appear", "who_is_this") \
|
|
444
|
+
and not arguments.get("account") \
|
|
413
445
|
and not arguments.get("project"):
|
|
414
446
|
# **`account` か `project` のどちらか必須**(`required` は AND の意味しか
|
|
415
447
|
# 持てないので、ここで OR を見る・T2-3 発注書・T3-3 も同じ形)。
|
|
416
448
|
raise ToolInputError(
|
|
417
449
|
f"{name}: account か project のどちらかが要ります")
|
|
450
|
+
if name in ("operations_handoff", "analytics_report", "after_you_posted") and arguments.get("account") \
|
|
451
|
+
and arguments.get("project"):
|
|
452
|
+
raise ToolInputError(
|
|
453
|
+
f"{name}: account と project は同時に指定できません")
|
|
418
454
|
if name == "who_is_this" and not arguments.get("author_key") \
|
|
419
455
|
and not arguments.get("username"):
|
|
420
456
|
# **`author_key` か `username` のどちらか必須**(同じ理由で OR を
|
|
@@ -495,9 +531,43 @@ def call_tool(name: str, arguments: dict | None) -> dict:
|
|
|
495
531
|
args.append("--json")
|
|
496
532
|
proc = run_cli(args)
|
|
497
533
|
text = proc.stdout
|
|
534
|
+
elif name == "operations_handoff":
|
|
535
|
+
args = ["handoff-report"]
|
|
536
|
+
if arguments.get("project"):
|
|
537
|
+
args += ["--project", arguments["project"]]
|
|
538
|
+
else:
|
|
539
|
+
args.append(arguments["account"])
|
|
540
|
+
args.append("--json")
|
|
541
|
+
proc = run_cli(args)
|
|
542
|
+
text = proc.stdout
|
|
543
|
+
elif name == "study_report":
|
|
544
|
+
args = ["study-report", arguments["file"]]
|
|
545
|
+
if arguments.get("min_n") is not None:
|
|
546
|
+
args += ["--min-n", str(arguments["min_n"])]
|
|
547
|
+
args.append("--json")
|
|
548
|
+
proc = run_cli(args)
|
|
549
|
+
text = proc.stdout
|
|
550
|
+
elif name == "analytics_report":
|
|
551
|
+
args = ["analytics-report"]
|
|
552
|
+
if arguments.get("project"):
|
|
553
|
+
args += ["--project", arguments["project"]]
|
|
554
|
+
else:
|
|
555
|
+
args.append(arguments["account"])
|
|
556
|
+
for key in ("window_days", "min_n"):
|
|
557
|
+
if arguments.get(key) is not None:
|
|
558
|
+
args += ["--" + key.replace("_", "-"), str(arguments[key])]
|
|
559
|
+
if arguments.get("compare_previous"):
|
|
560
|
+
args.append("--compare-previous")
|
|
561
|
+
args.append("--json")
|
|
562
|
+
proc = run_cli(args)
|
|
563
|
+
text = proc.stdout
|
|
498
564
|
elif name == "after_you_posted":
|
|
499
565
|
# **`before_you_post` と同じ型**(発注 T0-2): CLI を `--json` で呼ぶだけ。
|
|
500
|
-
args = ["after"
|
|
566
|
+
args = ["after"]
|
|
567
|
+
if arguments.get("project"):
|
|
568
|
+
args += ["--project", arguments["project"]]
|
|
569
|
+
else:
|
|
570
|
+
args.append(arguments["account"])
|
|
501
571
|
if arguments.get("topic"):
|
|
502
572
|
args += ["--topic", arguments["topic"]]
|
|
503
573
|
if arguments.get("kind"):
|
|
@@ -567,7 +637,7 @@ def call_tool(name: str, arguments: dict | None) -> dict:
|
|
|
567
637
|
return {"content": [{"type": "text", "text": f"unknown tool: {name}"}], "isError": True}
|
|
568
638
|
|
|
569
639
|
if name.startswith("thth_topic_") or name in (
|
|
570
|
-
"before_you_post", "after_you_posted", "thread_read", "where_to_appear",
|
|
640
|
+
"before_you_post", "after_you_posted", "analytics_report", "operations_handoff", "study_report", "thread_read", "where_to_appear",
|
|
571
641
|
"who_is_this"):
|
|
572
642
|
# **新しい道具は exit 1 も isError**(設計 §7)。lint の exit 1(検査結果)
|
|
573
643
|
# とは意味が違う——こちらは stale_context・不正な候補比較で、
|
|
@@ -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
|
-
|
|
117
|
-
|
|
119
|
+
**媒体・account をまたぐ数は無い**——`--project` は `by_account` に並べるだけで、
|
|
120
|
+
足さない・割らない・順位も付けない。
|
|
118
121
|
|
|
119
122
|
---
|
|
120
123
|
|
|
@@ -123,3 +126,19 @@ 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
|
+
## 運用と分析のレポート(v3系・2.5.0 から)
|
|
131
|
+
|
|
132
|
+
2.4.0 以前には無い入口を含む。接続先のhelp/tools一覧にある場合だけ使う。
|
|
133
|
+
|
|
134
|
+
- 再開時は `handoff-report` / MCP `operations_handoff`。ローカルの停止・要確認・通知記録を読む。`waiting`をtimer正常や投稿成功と解釈しない。
|
|
135
|
+
- `analytics-report` / MCP `analytics_report` は期間・母数・欠測・根拠付きsnapshot。生成時刻とデータ更新時刻を混同しない。
|
|
136
|
+
- 前期間比較は `--compare-previous` / `compare_previous: true`。投稿後24〜30時間未満の実観測で比較し、欠測をゼロにしない。
|
|
137
|
+
- 施策メモの振り返りは `study-report` / `study_report`。採用宣言と観測を分け、提案を自動で採用済みにしない。投稿の承認には使えない。
|
|
138
|
+
- 観測差を因果効果と断定しない。accountをまたいだ合算・順位を作らない。詳しい読み順は `docs/手順_LLM_分析と運用の引継ぎ.md`。
|
|
139
|
+
|
|
140
|
+
## 停止通知と運用状況(開発版 main)
|
|
141
|
+
|
|
142
|
+
新規 account は利用者メール・管理者メール・TLS SMTP を `thth notifications config` で設定し、`status` → `test` を実行する。両宛先の受信箱で到達、account 専用 HEALTHCHECK_URL の missed-ping 通知を確認してから production/scheduled を有効にする。既存 account にも同じ設定を追加する。詳細は `docs/停止通知と運用記録.md`。
|
|
143
|
+
|
|
144
|
+
プロジェクトの作業開始・再開時は `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 を見る。
|