msgctl 0.2.7__tar.gz → 0.2.9__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 (754) hide show
  1. {msgctl-0.2.7 → msgctl-0.2.9}/CHANGELOG.md +13 -0
  2. {msgctl-0.2.7 → msgctl-0.2.9}/PKG-INFO +5 -3
  3. {msgctl-0.2.7 → msgctl-0.2.9}/README.md +4 -2
  4. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CLIENT_CONNECTIONS.md +9 -9
  5. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CLIENT_INSTALLATION.md +2 -2
  6. {msgctl-0.2.7 → msgctl-0.2.9}/docs/FILESYSTEM_LAYOUT.md +22 -6
  7. {msgctl-0.2.7 → msgctl-0.2.9}/docs/YUBIKEY.md +14 -7
  8. {msgctl-0.2.7 → msgctl-0.2.9}/docs/YUBIKEY_CASE.md +2 -0
  9. {msgctl-0.2.7 → msgctl-0.2.9}/docs/post-universe.md +82 -0
  10. {msgctl-0.2.7 → msgctl-0.2.9}/pyproject.toml +1 -1
  11. {msgctl-0.2.7 → msgctl-0.2.9}/pyproject.toml.orig +1 -1
  12. msgctl-0.2.9/scripts/check_nebula_browser.py +478 -0
  13. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/__init__.py +1 -1
  14. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/cli.py +20 -2
  15. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client.py +66 -6
  16. msgctl-0.2.9/src/msg/client_accounts.py +77 -0
  17. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_agent_cli.py +4 -1
  18. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_connection.py +1 -0
  19. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-app.js +150 -39
  20. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-model.js +68 -8
  21. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-renderer.js +189 -242
  22. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web.css +89 -34
  23. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web.html +24 -8
  24. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/paths.py +80 -12
  25. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/bot_feed.py +7 -1
  26. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/communication.py +9 -4
  27. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/discovery.py +8 -0
  28. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/mail_views.py +3 -0
  29. msgctl-0.2.9/src/msg/plugins/star_projection.py +105 -0
  30. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/browser_style.py +6 -1
  31. msgctl-0.2.9/src/msg/transports/discovery_pages.py +87 -0
  32. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/home_page.py +8 -3
  33. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/http_routes.py +120 -4
  34. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/universe.py +69 -3
  35. msgctl-0.2.9/tests/js/nebula.test.cjs +86 -0
  36. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bounty.py +3 -0
  37. msgctl-0.2.9/tests/test_client_accounts.py +156 -0
  38. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_paths.py +16 -5
  39. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_subagents_remote.py +24 -5
  40. msgctl-0.2.9/tests/test_discovery_pages.py +124 -0
  41. msgctl-0.2.9/tests/test_mailbox_contacts.py +80 -0
  42. msgctl-0.2.9/tests/test_star_projection.py +205 -0
  43. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_todo_due_inbox.py +4 -0
  44. {msgctl-0.2.7 → msgctl-0.2.9}/uv.lock +1 -1
  45. {msgctl-0.2.7 → msgctl-0.2.9}/.python-version +0 -0
  46. {msgctl-0.2.7 → msgctl-0.2.9}/CONTRIBUTING.md +0 -0
  47. {msgctl-0.2.7 → msgctl-0.2.9}/SECURITY.md +0 -0
  48. {msgctl-0.2.7 → msgctl-0.2.9}/conformance/test_token_budget.py +0 -0
  49. {msgctl-0.2.7 → msgctl-0.2.9}/conformance/test_transports.py +0 -0
  50. {msgctl-0.2.7 → msgctl-0.2.9}/conftest.py +0 -0
  51. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/README.md +0 -0
  52. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/hosting-role.sql +0 -0
  53. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/hosting.example.toml +0 -0
  54. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/mail.example.toml +0 -0
  55. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/msgd-hosting.service +0 -0
  56. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/msgd-worker.service +0 -0
  57. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/msgd-worker@.service +0 -0
  58. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/msgd.service +0 -0
  59. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/msgd@.service +0 -0
  60. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/nginx-shared-http-logging.conf +0 -0
  61. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/nginx.conf +0 -0
  62. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/prepare-hosting-content.sh +0 -0
  63. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/prepare-instance.sh +0 -0
  64. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/prepare-service.sh +0 -0
  65. {msgctl-0.2.7 → msgctl-0.2.9}/deploy/sshd_config +0 -0
  66. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ARCHITECTURE.md +0 -0
  67. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ARCHITECTURE_PROGRESS_20260929.md +0 -0
  68. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ARCHITECTURE_REUSE.md +0 -0
  69. {msgctl-0.2.7 → msgctl-0.2.9}/docs/AUTHORIZATION_SOURCES.md +0 -0
  70. {msgctl-0.2.7 → msgctl-0.2.9}/docs/BOUNTY_ACCEPTANCE.md +0 -0
  71. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CLIENT_BOUNDARY_PROGRESS.md +0 -0
  72. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CLIENT_PART_BYTES_PROGRESS.md +0 -0
  73. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CLI_FIELD_SELECTION.md +0 -0
  74. {msgctl-0.2.7 → msgctl-0.2.9}/docs/COMPLETE_RECOVERY_PROOF.md +0 -0
  75. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CREDENTIAL_DELIVERY.md +0 -0
  76. {msgctl-0.2.7 → msgctl-0.2.9}/docs/CUSTODIAL_HISTORY.md +0 -0
  77. {msgctl-0.2.7 → msgctl-0.2.9}/docs/C_READ_ACCEPTANCE.md +0 -0
  78. {msgctl-0.2.7 → msgctl-0.2.9}/docs/DEPLOYMENT.md +0 -0
  79. {msgctl-0.2.7 → msgctl-0.2.9}/docs/DESIGN_CHANGE_REQUESTS.md +0 -0
  80. {msgctl-0.2.7 → msgctl-0.2.9}/docs/DESIGN_CONTRACT_INVENTORY.md +0 -0
  81. {msgctl-0.2.7 → msgctl-0.2.9}/docs/FOLLOW_AND_FEED.md +0 -0
  82. {msgctl-0.2.7 → msgctl-0.2.9}/docs/GIT_BOUNDARY_PROGRESS.md +0 -0
  83. {msgctl-0.2.7 → msgctl-0.2.9}/docs/HOSTING_AUTHORITY_PROGRESS.md +0 -0
  84. {msgctl-0.2.7 → msgctl-0.2.9}/docs/HOSTING_RUNTIME.md +0 -0
  85. {msgctl-0.2.7 → msgctl-0.2.9}/docs/HOSTING_RUNTIME_PROGRESS.md +0 -0
  86. {msgctl-0.2.7 → msgctl-0.2.9}/docs/IMPLEMENTATION_STATUS.md +0 -0
  87. {msgctl-0.2.7 → msgctl-0.2.9}/docs/INTEGRATION_PROGRESS_20260929.md +0 -0
  88. {msgctl-0.2.7 → msgctl-0.2.9}/docs/INTEGRATION_REGRESSION_PROGRESS.md +0 -0
  89. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ISSUES_68_70_PROGRESS.md +0 -0
  90. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ISSUES_78_80_PROGRESS.md +0 -0
  91. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ISSUE_PROGRESS.md +0 -0
  92. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ISSUE_RESOLUTION.md +0 -0
  93. {msgctl-0.2.7 → msgctl-0.2.9}/docs/ITERATION_PLAN.md +0 -0
  94. {msgctl-0.2.7 → msgctl-0.2.9}/docs/LEDGER_MIGRATION.md +0 -0
  95. {msgctl-0.2.7 → msgctl-0.2.9}/docs/LEGACY_GIT_MIGRATION.md +0 -0
  96. {msgctl-0.2.7 → msgctl-0.2.9}/docs/LEGACY_IDENTITY_ARCHIVE.md +0 -0
  97. {msgctl-0.2.7 → msgctl-0.2.9}/docs/LEGACY_SQLITE_PRESERVATION.md +0 -0
  98. {msgctl-0.2.7 → msgctl-0.2.9}/docs/LOCAL_VERIFICATION.md +0 -0
  99. {msgctl-0.2.7 → msgctl-0.2.9}/docs/MANAGED_CHECKOUT.md +0 -0
  100. {msgctl-0.2.7 → msgctl-0.2.9}/docs/MARKET_BOUNDARY_PROGRESS.md +0 -0
  101. {msgctl-0.2.7 → msgctl-0.2.9}/docs/MARKET_CLEARING.md +0 -0
  102. {msgctl-0.2.7 → msgctl-0.2.9}/docs/MARKET_CONTRACTS.md +0 -0
  103. {msgctl-0.2.7 → msgctl-0.2.9}/docs/METADATA_SESSION_PROGRESS.md +0 -0
  104. {msgctl-0.2.7 → msgctl-0.2.9}/docs/NATIVE_PACKAGES.md +0 -0
  105. {msgctl-0.2.7 → msgctl-0.2.9}/docs/NEW_ROOT_LEGACY_IMPORT_RUNBOOK.md +0 -0
  106. {msgctl-0.2.7 → msgctl-0.2.9}/docs/OAUTH.md +0 -0
  107. {msgctl-0.2.7 → msgctl-0.2.9}/docs/OFFER_ORDER_COMPATIBILITY.md +0 -0
  108. {msgctl-0.2.7 → msgctl-0.2.9}/docs/OFFER_RESOURCE_MIGRATION.md +0 -0
  109. {msgctl-0.2.7 → msgctl-0.2.9}/docs/POST_SUMMARIES.md +0 -0
  110. {msgctl-0.2.7 → msgctl-0.2.9}/docs/PROTOCOLS.md +0 -0
  111. {msgctl-0.2.7 → msgctl-0.2.9}/docs/QUALITY_PROGRESS.md +0 -0
  112. {msgctl-0.2.7 → msgctl-0.2.9}/docs/READ_ENTRY_ACCEPTANCE.md +0 -0
  113. {msgctl-0.2.7 → msgctl-0.2.9}/docs/RELEASE_ACCEPTANCE.md +0 -0
  114. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SAVED_QUERIES.md +0 -0
  115. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SEARCH_QUERY_V5.md +0 -0
  116. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SERVICE_ALIASES.md +0 -0
  117. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SSH_GIT_LOCAL_ACCEPTANCE.md +0 -0
  118. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SUBAGENTS.md +0 -0
  119. {msgctl-0.2.7 → msgctl-0.2.9}/docs/SUBAGENT_ACCEPTANCE_20261001.md +0 -0
  120. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TASK_A_RECOVERY_20260928.md +0 -0
  121. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TASK_A_VERIFICATION.md +0 -0
  122. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TASK_C_EVIDENCE.md +0 -0
  123. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TEMPORARY_UPGRADE.md +0 -0
  124. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TERMINAL_DEMO.md +0 -0
  125. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TOKEN_DELIVERY_BOUNDARY_PROGRESS.md +0 -0
  126. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TOOL_RUNNER_BOUNDARY.md +0 -0
  127. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TRANSFER_STATUS_PROGRESS.md +0 -0
  128. {msgctl-0.2.7 → msgctl-0.2.9}/docs/TRUST_PATHS.md +0 -0
  129. {msgctl-0.2.7 → msgctl-0.2.9}/docs/VERIFICATION.md +0 -0
  130. {msgctl-0.2.7 → msgctl-0.2.9}/docs/WEBSUB.md +0 -0
  131. {msgctl-0.2.7 → msgctl-0.2.9}/docs/YUBIKEY_DESIGN.md +0 -0
  132. {msgctl-0.2.7 → msgctl-0.2.9}/docs/issue-75-77-local-verification.md +0 -0
  133. {msgctl-0.2.7 → msgctl-0.2.9}/docs/registry-template-tool-contracts.md +0 -0
  134. {msgctl-0.2.7 → msgctl-0.2.9}/packaging/build-native.py +0 -0
  135. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/audit_filesystem_paths.py +0 -0
  136. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_client_install.py +0 -0
  137. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_installed_server.py +0 -0
  138. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_isolated_sshd.py +0 -0
  139. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_package_artifacts.py +0 -0
  140. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_tool_sandbox.py +0 -0
  141. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/check_universe_browser.py +0 -0
  142. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/ci_shards.py +0 -0
  143. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/render_terminal_demo.py +0 -0
  144. {msgctl-0.2.7 → msgctl-0.2.9}/scripts/verify_local.py +0 -0
  145. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/__init__.py +0 -0
  146. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/accounts.py +0 -0
  147. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/backup_retirement.py +0 -0
  148. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/backups.py +0 -0
  149. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/config_check.py +0 -0
  150. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/content_edit_check.py +0 -0
  151. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/custodial_check.py +0 -0
  152. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/diagnostics.py +0 -0
  153. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/dm_check.py +0 -0
  154. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/git_check.py +0 -0
  155. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/honor_check.py +0 -0
  156. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/legacy_approval.py +0 -0
  157. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/market.py +0 -0
  158. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/market_check.py +0 -0
  159. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/money.py +0 -0
  160. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/offer_import.py +0 -0
  161. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/preflight.py +0 -0
  162. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/recovery_policy.py +0 -0
  163. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/recovery_proof.py +0 -0
  164. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/recovery_replay.py +0 -0
  165. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/recovery_state.py +0 -0
  166. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/restore_database.py +0 -0
  167. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/root.py +0 -0
  168. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/rotation.py +0 -0
  169. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/token_delivery_check.py +0 -0
  170. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/tool_check.py +0 -0
  171. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/transfer_check.py +0 -0
  172. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/admin/upgrade_check.py +0 -0
  173. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/.github/workflows/test.yml +0 -0
  174. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/.gitignore +0 -0
  175. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/LICENSE +0 -0
  176. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/README.md +0 -0
  177. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/README.zh-CN.md +0 -0
  178. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/__init__.py +0 -0
  179. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/pyproject.toml +0 -0
  180. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/ranker.py +0 -0
  181. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/algorithm/tests/test_ranker.py +0 -0
  182. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/application.py +0 -0
  183. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/atomic_file.py +0 -0
  184. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/bootstrap.py +0 -0
  185. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_api_keys.py +0 -0
  186. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_certificates.py +0 -0
  187. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_collaboration.py +0 -0
  188. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_content.py +0 -0
  189. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_custodial.py +0 -0
  190. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_listener.py +0 -0
  191. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_market.py +0 -0
  192. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_oauth.py +0 -0
  193. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_output.py +0 -0
  194. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_recovery.py +0 -0
  195. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_secrets.py +0 -0
  196. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_subagents.py +0 -0
  197. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_subagents_remote.py +0 -0
  198. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_tokens.py +0 -0
  199. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_upgrade.py +0 -0
  200. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/client_yubikey.py +0 -0
  201. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/config.py +0 -0
  202. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/config_contracts.py +0 -0
  203. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/constants.py +0 -0
  204. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/__init__.py +0 -0
  205. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/batching.py +0 -0
  206. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/codec.py +0 -0
  207. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/contracts.py +0 -0
  208. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/cursors.py +0 -0
  209. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/email_address.py +0 -0
  210. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/errors.py +0 -0
  211. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/events.py +0 -0
  212. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/execution_ports.py +0 -0
  213. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/executor.py +0 -0
  214. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/handles.py +0 -0
  215. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/identifiers.py +0 -0
  216. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/models.py +0 -0
  217. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/packet.py +0 -0
  218. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/permissions.py +0 -0
  219. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/post_preview.py +0 -0
  220. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/query.py +0 -0
  221. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/read_query.py +0 -0
  222. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/registry.py +0 -0
  223. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/requests.py +0 -0
  224. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/schema_policy.py +0 -0
  225. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/schemas.py +0 -0
  226. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/search_query.py +0 -0
  227. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/tags.py +0 -0
  228. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/template_dsl.py +0 -0
  229. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/text_patch.py +0 -0
  230. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/tool_execution.py +0 -0
  231. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/core/transfer.py +0 -0
  232. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/daemon.py +0 -0
  233. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/__init__.py +0 -0
  234. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/bootstrap.json +0 -0
  235. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/favicon.png +0 -0
  236. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/install.sh +0 -0
  237. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/legacy/sqlite-0221.json +0 -0
  238. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/logo-dark.svg +0 -0
  239. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/logo.svg +0 -0
  240. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/recovery-checkpoint.example.json +0 -0
  241. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/recovery-checkpoint.schema.json +0 -0
  242. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/recovery-policy-checkpoint.schema.json +0 -0
  243. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/recovery-state-schema.json +0 -0
  244. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-font-LICENSE.txt +0 -0
  245. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-sans-bold.woff2 +0 -0
  246. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/root-web-sans.woff2 +0 -0
  247. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/shortcodes.json +0 -0
  248. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/AGENTS.md +0 -0
  249. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/_index.md +0 -0
  250. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/auth.md +0 -0
  251. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/files.md +0 -0
  252. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/identity.md +0 -0
  253. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/protocol.md +0 -0
  254. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/read-write.md +0 -0
  255. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/recovery.md +0 -0
  256. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/security.md +0 -0
  257. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/data/system/rules/topics.md +0 -0
  258. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/__init__.py +0 -0
  259. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/git_publication.py +0 -0
  260. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/hosting.py +0 -0
  261. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/keystore.py +0 -0
  262. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/repositories.py +0 -0
  263. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/rss.py +0 -0
  264. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/ssh.py +0 -0
  265. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/ssh_git.py +0 -0
  266. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/tools.py +0 -0
  267. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/extensions/websub.py +0 -0
  268. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/hosting_runtime.py +0 -0
  269. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/__init__.py +0 -0
  270. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/arbitration.py +0 -0
  271. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/catalog.py +0 -0
  272. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/compatibility.py +0 -0
  273. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/delivery.py +0 -0
  274. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/delivery_notifications.py +0 -0
  275. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/delivery_targets.py +0 -0
  276. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/email.py +0 -0
  277. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/entitlement_orders.py +0 -0
  278. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/escrow.py +0 -0
  279. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/ledger.py +0 -0
  280. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/managed_delivery.py +0 -0
  281. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/offer_resources.py +0 -0
  282. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/order_records.py +0 -0
  283. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/order_resources.py +0 -0
  284. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/orders.py +0 -0
  285. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/policy.py +0 -0
  286. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/rationale.py +0 -0
  287. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/references.py +0 -0
  288. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/market/targets.py +0 -0
  289. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/oauth_config.py +0 -0
  290. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/__init__.py +0 -0
  291. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/achievements.py +0 -0
  292. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/agent_follows.py +0 -0
  293. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/batch.py +0 -0
  294. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/bounty.py +0 -0
  295. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/collaboration.py +0 -0
  296. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/collaboration_resources.py +0 -0
  297. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/common.py +0 -0
  298. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/content.py +0 -0
  299. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/custodial_lifecycle.py +0 -0
  300. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/delivery.py +0 -0
  301. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/discussion.py +0 -0
  302. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/extensions.py +0 -0
  303. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/features.py +0 -0
  304. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/files.py +0 -0
  305. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/following.py +0 -0
  306. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/hosting_capacity.py +0 -0
  307. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/identity.py +0 -0
  308. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/money.py +0 -0
  309. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/oauth_identity.py +0 -0
  310. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/offers.py +0 -0
  311. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/orders.py +0 -0
  312. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/profile.py +0 -0
  313. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/proposals.py +0 -0
  314. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/read_predicates.py +0 -0
  315. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/receipts.py +0 -0
  316. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/recovery.py +0 -0
  317. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/saved_queries.py +0 -0
  318. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/schemas.py +0 -0
  319. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/sharing.py +0 -0
  320. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/store.py +0 -0
  321. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/system.py +0 -0
  322. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/transfer.py +0 -0
  323. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/plugins/watches.py +0 -0
  324. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/py.typed +0 -0
  325. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/__init__.py +0 -0
  326. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/age_keys.py +0 -0
  327. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/authentication.py +0 -0
  328. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/authorization.py +0 -0
  329. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/backup_retirement.py +0 -0
  330. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/capabilities.py +0 -0
  331. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/certificates.py +0 -0
  332. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/crypto.py +0 -0
  333. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/custodial_migration.py +0 -0
  334. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/custodial_protocol.py +0 -0
  335. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/custody_history.py +0 -0
  336. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/network.py +0 -0
  337. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/oauth.py +0 -0
  338. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/policy.py +0 -0
  339. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/quarantine.py +0 -0
  340. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/root_files.py +0 -0
  341. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/rotation_journal.py +0 -0
  342. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/sealed_box.py +0 -0
  343. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/sharing_policy.py +0 -0
  344. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/token_delivery.py +0 -0
  345. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/trust_files.py +0 -0
  346. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/security/vault.py +0 -0
  347. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/service_origin.py +0 -0
  348. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/__init__.py +0 -0
  349. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/capacity.py +0 -0
  350. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/custodial_migration.py +0 -0
  351. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/git.py +0 -0
  352. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/ledger_migration.py +0 -0
  353. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_git_capture.py +0 -0
  354. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_git_import.py +0 -0
  355. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_git_rehearsal.py +0 -0
  356. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_identity_plan.py +0 -0
  357. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_rehearsal.py +0 -0
  358. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_resource_import.py +0 -0
  359. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/legacy_sqlite.py +0 -0
  360. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/market_migration.py +0 -0
  361. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/postgres.py +0 -0
  362. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/query.py +0 -0
  363. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/read_only.py +0 -0
  364. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/session.py +0 -0
  365. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/sqlite.py +0 -0
  366. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/topic_event_migration.py +0 -0
  367. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/storage/valkey_bus.py +0 -0
  368. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/__init__.py +0 -0
  369. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/browser_login.py +0 -0
  370. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/browser_palette.py +0 -0
  371. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/client.py +0 -0
  372. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/dictionary.py +0 -0
  373. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/git_http.py +0 -0
  374. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/graphql.py +0 -0
  375. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/home_art.py +0 -0
  376. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/http.py +0 -0
  377. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/http_common.py +0 -0
  378. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/legacy_content_http.py +0 -0
  379. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/mcp.py +0 -0
  380. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/mcp_protocol.py +0 -0
  381. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/oauth_http.py +0 -0
  382. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/packet.py +0 -0
  383. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/permissions_page.py +0 -0
  384. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/read_tree_path.py +0 -0
  385. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/register_page.py +0 -0
  386. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/stdio.py +0 -0
  387. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/subject_views.py +0 -0
  388. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/url_safety.py +0 -0
  389. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/transports/webmcp.py +0 -0
  390. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/tui.py +0 -0
  391. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/tui_i18n.py +0 -0
  392. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/__init__.py +0 -0
  393. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/effects.py +0 -0
  394. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/leases.py +0 -0
  395. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/mail.py +0 -0
  396. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/maintenance.py +0 -0
  397. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/sandbox.py +0 -0
  398. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/sandbox_child.py +0 -0
  399. {msgctl-0.2.7 → msgctl-0.2.9}/src/msg/workers/webhook.py +0 -0
  400. {msgctl-0.2.7 → msgctl-0.2.9}/tests/conftest.py +0 -0
  401. {msgctl-0.2.7 → msgctl-0.2.9}/tests/fixtures/create_legacy_market.py +0 -0
  402. {msgctl-0.2.7 → msgctl-0.2.9}/tests/fixtures/legacy_market_source.json +0 -0
  403. {msgctl-0.2.7 → msgctl-0.2.9}/tests/fixtures/legacy_sqlite_0221.sql +0 -0
  404. {msgctl-0.2.7 → msgctl-0.2.9}/tests/http_read_cache_matrix.py +0 -0
  405. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/__init__.py +0 -0
  406. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/conftest.py +0 -0
  407. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_content_patch_contract.py +0 -0
  408. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_lfs_integrity.py +0 -0
  409. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_lfs_migration_contract.py +0 -0
  410. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_read_query_tree.py +0 -0
  411. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_read_tree_transports.py +0 -0
  412. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_revision_signature_fields.py +0 -0
  413. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_text_patch_formats.py +0 -0
  414. {msgctl-0.2.7 → msgctl-0.2.9}/tests/issue_78_80/test_tree_query_ref.py +0 -0
  415. {msgctl-0.2.7 → msgctl-0.2.9}/tests/read_only_evidence.py +0 -0
  416. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_access_log_secret_redaction.py +0 -0
  417. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_account_archive.py +0 -0
  418. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_achievement_concurrency.py +0 -0
  419. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_achievement_context_boundary.py +0 -0
  420. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_achievement_pins.py +0 -0
  421. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_achievements.py +0 -0
  422. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_agent_entry.py +0 -0
  423. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_agent_follows.py +0 -0
  424. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_architecture_ports.py +0 -0
  425. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ascii_hero.py +0 -0
  426. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_attachment_http_cache.py +0 -0
  427. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_authority_snapshot_drift.py +0 -0
  428. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_authorization.py +0 -0
  429. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_authorization_matrix.py +0 -0
  430. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_authorization_recovery_boundaries.py +0 -0
  431. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_authorization_sources.py +0 -0
  432. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_backup_daemon.py +0 -0
  433. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_backup_drill.py +0 -0
  434. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_backup_policy.py +0 -0
  435. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_backup_retirement_attestation.py +0 -0
  436. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_backup_retirement_cli.py +0 -0
  437. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_batch.py +0 -0
  438. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_batch_secret_release.py +0 -0
  439. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bot_feed.py +0 -0
  440. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bounty_commit_boundary.py +0 -0
  441. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bounty_escrow_binding.py +0 -0
  442. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bounty_public_lifecycle.py +0 -0
  443. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_bounty_snapshot_integrity.py +0 -0
  444. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_branding.py +0 -0
  445. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_browser_html.py +0 -0
  446. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_browser_refinement.py +0 -0
  447. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_browser_workspace.py +0 -0
  448. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ca_depth.py +0 -0
  449. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_canonical_post_paths.py +0 -0
  450. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_capability_matrix.py +0 -0
  451. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_capacity_bounds.py +0 -0
  452. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_checkout_decision_integrity.py +0 -0
  453. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ci_shards.py +0 -0
  454. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_cursor_output.py +0 -0
  455. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_dm.py +0 -0
  456. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_hosting.py +0 -0
  457. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_json_fields.py +0 -0
  458. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_legacy.py +0 -0
  459. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_recovery.py +0 -0
  460. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_cli_search_grep.py +0 -0
  461. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client.py +0 -0
  462. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_agent_cli.py +0 -0
  463. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_boundary.py +0 -0
  464. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_connection.py +0 -0
  465. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_installer.py +0 -0
  466. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_listener.py +0 -0
  467. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_output_formats.py +0 -0
  468. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_part_bytes.py +0 -0
  469. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_response_boundaries.py +0 -0
  470. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_secrets.py +0 -0
  471. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_subagents.py +0 -0
  472. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_token_delivery.py +0 -0
  473. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_client_yubikey.py +0 -0
  474. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_current_visibility.py +0 -0
  475. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_list_bounds.py +0 -0
  476. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_list_deadline.py +0 -0
  477. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_resource_surfaces.py +0 -0
  478. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_resources.py +0 -0
  479. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_collaboration_surfaces.py +0 -0
  480. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_complete_recovery_proof.py +0 -0
  481. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_config_safety.py +0 -0
  482. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_configuration_field_contracts.py +0 -0
  483. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_content_edit_check.py +0 -0
  484. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_credential_delivery_contract.py +0 -0
  485. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_credential_delivery_matrix.py +0 -0
  486. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_credential_recovery_window.py +0 -0
  487. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_credential_upgrade_interleave.py +0 -0
  488. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_client_upgrade.py +0 -0
  489. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_historical_migration.py +0 -0
  490. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_inventory_ack.py +0 -0
  491. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_lifecycle.py +0 -0
  492. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_rewrap.py +0 -0
  493. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_schema_migration.py +0 -0
  494. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_upgrade.py +0 -0
  495. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custodial_vault.py +0 -0
  496. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_custody_exit_evidence.py +0 -0
  497. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_delivery.py +0 -0
  498. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_delivery_target_regression.py +0 -0
  499. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_dictionary.py +0 -0
  500. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_dictionary_route.py +0 -0
  501. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_dm.py +0 -0
  502. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_dm_selftest.py +0 -0
  503. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_effect_completion_fencing.py +0 -0
  504. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_effect_lease_deadlines.py +0 -0
  505. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_effect_retry_state.py +0 -0
  506. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_entitlement_orders.py +0 -0
  507. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_error_messages.py +0 -0
  508. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_escrow_decision_migration.py +0 -0
  509. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_escrow_decisions.py +0 -0
  510. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_execution_composition.py +0 -0
  511. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_extensions.py +0 -0
  512. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_feature_manifest.py +0 -0
  513. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_file_copy_integrity.py +0 -0
  514. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_file_operations.py +0 -0
  515. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_fixture_collection.py +0 -0
  516. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_following.py +0 -0
  517. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_foundation.py +0 -0
  518. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_get_only_write.py +0 -0
  519. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_git_http_push.py +0 -0
  520. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_git_lfs.py +0 -0
  521. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_git_selftest.py +0 -0
  522. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_git_transport_boundaries.py +0 -0
  523. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_graceful_shutdown.py +0 -0
  524. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_handoff_lease.py +0 -0
  525. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hex_post_views.py +0 -0
  526. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_home_channels.py +0 -0
  527. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_honor_diagnostics.py +0 -0
  528. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_addressable_paths.py +0 -0
  529. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_alias_ingress.py +0 -0
  530. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_read_permissions.py +0 -0
  531. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_runtime.py +0 -0
  532. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_runtime_authority.py +0 -0
  533. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_runtime_isolation.py +0 -0
  534. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_hosting_same_origin.py +0 -0
  535. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_http.py +0 -0
  536. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_http_body_integrity.py +0 -0
  537. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_http_effect_order.py +0 -0
  538. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_http_range_bounds.py +0 -0
  539. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_identity_handle_rename.py +0 -0
  540. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_identity_keys.py +0 -0
  541. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_independent_share_after_move.py +0 -0
  542. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_lease_list_bounds.py +0 -0
  543. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_lease_list_deadline.py +0 -0
  544. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ledger_account_isolation.py +0 -0
  545. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ledger_accounts.py +0 -0
  546. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ledger_migration_json.py +0 -0
  547. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ledger_migration_references.py +0 -0
  548. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_approval.py +0 -0
  549. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_content_http.py +0 -0
  550. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_directive.py +0 -0
  551. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_git_import.py +0 -0
  552. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_identity_plan.py +0 -0
  553. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_ledger_snapshot.py +0 -0
  554. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_resource_import.py +0 -0
  555. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_routes_removed.py +0 -0
  556. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_secret_entrypoints.py +0 -0
  557. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_share_source_isolation.py +0 -0
  558. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_sqlite_preservation.py +0 -0
  559. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_legacy_token_release.py +0 -0
  560. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_lexical_search_grep.py +0 -0
  561. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_lfs_shared_gc_quota.py +0 -0
  562. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_linkset_diff.py +0 -0
  563. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_local_postgres_fixtures.py +0 -0
  564. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_local_verification.py +0 -0
  565. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_managed_checkout.py +0 -0
  566. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_manifest_feature_linkage.py +0 -0
  567. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_markdown_redirect.py +0 -0
  568. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_71.py +0 -0
  569. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_72.py +0 -0
  570. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_account_scope.py +0 -0
  571. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_arbitration.py +0 -0
  572. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_boundaries.py +0 -0
  573. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_cli_bindings.py +0 -0
  574. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_compatibility_reads.py +0 -0
  575. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_contracts.py +0 -0
  576. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_delivery.py +0 -0
  577. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_explicit_acceptance.py +0 -0
  578. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_integration.py +0 -0
  579. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_lease_deadlines.py +0 -0
  580. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_lifecycle.py +0 -0
  581. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_manual_flow.py +0 -0
  582. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_notification_reuse.py +0 -0
  583. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_paths.py +0 -0
  584. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_rationale.py +0 -0
  585. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_recovery.py +0 -0
  586. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_market_redemption.py +0 -0
  587. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_metadata_session_boundary.py +0 -0
  588. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_money_admin.py +0 -0
  589. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_money_config.py +0 -0
  590. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_money_core.py +0 -0
  591. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_money_paths.py +0 -0
  592. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_money_public.py +0 -0
  593. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_native_git_read_only.py +0 -0
  594. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_nested_read_query.py +0 -0
  595. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_network_url_ports.py +0 -0
  596. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_nginx_secret_logs.py +0 -0
  597. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_notes_todos.py +0 -0
  598. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_oauth.py +0 -0
  599. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_oauth_authority.py +0 -0
  600. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_oauth_browser_integrity.py +0 -0
  601. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_oauth_browser_regressions.py +0 -0
  602. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_oauth_custodial_ceiling.py +0 -0
  603. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_offer_compatibility_boundary.py +0 -0
  604. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_offer_import.py +0 -0
  605. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_offer_resource_writer.py +0 -0
  606. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_offers.py +0 -0
  607. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_online_ca_policy.py +0 -0
  608. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_online_issuer.py +0 -0
  609. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_operations_admin.py +0 -0
  610. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_order_paths.py +0 -0
  611. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_order_resources.py +0 -0
  612. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_orders.py +0 -0
  613. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_organization_governance.py +0 -0
  614. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_pagination.py +0 -0
  615. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_passive_get_guard.py +0 -0
  616. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_passive_ingress_priority.py +0 -0
  617. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_patch_rebase_identity.py +0 -0
  618. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_path_read_query.py +0 -0
  619. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_personal_content_signatures.py +0 -0
  620. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_personal_documents.py +0 -0
  621. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_personal_signed_boundaries.py +0 -0
  622. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_personal_text_boundaries.py +0 -0
  623. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_pg_config.py +0 -0
  624. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_pg_sql_translation.py +0 -0
  625. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_plugin_lifecycle.py +0 -0
  626. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_post_lifecycle.py +0 -0
  627. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_post_summary.py +0 -0
  628. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_postgres.py +0 -0
  629. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_presence_claim.py +0 -0
  630. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_profile_display.py +0 -0
  631. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_proposals.py +0 -0
  632. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_protocol_routes.py +0 -0
  633. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_query_ref.py +0 -0
  634. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_query_ref_lifecycle.py +0 -0
  635. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_cursor.py +0 -0
  636. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_entry_contract_matrix.py +0 -0
  637. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_namespace.py +0 -0
  638. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_only_evidence.py +0 -0
  639. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_projection_cache_transports.py +0 -0
  640. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_projection_cache_unit.py +0 -0
  641. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_query_cursor.py +0 -0
  642. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_read_query_keyset_boundary.py +0 -0
  643. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_receipt_effect_order.py +0 -0
  644. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_authority_reconcile.py +0 -0
  645. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_current_authority.py +0 -0
  646. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_envelope.py +0 -0
  647. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_metadata.py +0 -0
  648. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_policy_v2.py +0 -0
  649. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_runtime_generation.py +0 -0
  650. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_recovery_safety_units.py +0 -0
  651. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_registry_contract_references.py +0 -0
  652. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_registry_operation_rules.py +0 -0
  653. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_registry_references.py +0 -0
  654. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_registry_schema_ownership.py +0 -0
  655. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_registry_template_tools.py +0 -0
  656. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_release_artifacts.py +0 -0
  657. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_release_version.py +0 -0
  658. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_request_target_safety.py +0 -0
  659. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_resource_path_migration.py +0 -0
  660. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_restore_physical_failure.py +0 -0
  661. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_revision_sources.py +0 -0
  662. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_root_rotation.py +0 -0
  663. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_root_rotation_resume.py +0 -0
  664. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_root_storage_layout.py +0 -0
  665. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_root_web_release.py +0 -0
  666. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_route_effect_matrix.py +0 -0
  667. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_rss_query_validation.py +0 -0
  668. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_saved_queries.py +0 -0
  669. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_saved_query_typed_scopes.py +0 -0
  670. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_saved_query_watch.py +0 -0
  671. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_search_engine_discovery.py +0 -0
  672. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_search_phrase_boundaries.py +0 -0
  673. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_search_source_relation_filters.py +0 -0
  674. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_search_spelling.py +0 -0
  675. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_search_suggestions.py +0 -0
  676. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security.py +0 -0
  677. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security_patch_regressions.py +0 -0
  678. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security_rollback_fences.py +0 -0
  679. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security_storage_rollback.py +0 -0
  680. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security_topic_events.py +0 -0
  681. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_security_transfer_rollback.py +0 -0
  682. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_server_instances.py +0 -0
  683. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_service.py +0 -0
  684. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_service_aliases.py +0 -0
  685. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_session_boundary.py +0 -0
  686. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_share_grants.py +0 -0
  687. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_share_grants_v2.py +0 -0
  688. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_share_links.py +0 -0
  689. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_share_source_boundaries.py +0 -0
  690. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_share_transport_matrix.py +0 -0
  691. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_single_mailbox_delivery.py +0 -0
  692. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_smtp_socket_acceptance.py +0 -0
  693. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_sqlite_connection_lifecycle.py +0 -0
  694. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ssh_bank_grant.py +0 -0
  695. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ssh_process_identity.py +0 -0
  696. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ssh_root_provisioning.py +0 -0
  697. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_ssh_rss.py +0 -0
  698. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_stable_resource_views.py +0 -0
  699. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_stdio_cli.py +0 -0
  700. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_storage_commit_faults.py +0 -0
  701. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_storage_layout.py +0 -0
  702. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_store_foundation.py +0 -0
  703. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_subject_read_aliases.py +0 -0
  704. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_subject_receipts.py +0 -0
  705. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_subject_view_effect_order.py +0 -0
  706. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_sync_checkpoint.py +0 -0
  707. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_sync_cursor.py +0 -0
  708. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_system_rule_migration.py +0 -0
  709. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_system_rule_retirement.py +0 -0
  710. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_system_rules.py +0 -0
  711. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tags_index.py +0 -0
  712. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_task_a_custodial_binding.py +0 -0
  713. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_task_a_preflight.py +0 -0
  714. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_task_a_recovery_checkpoint.py +0 -0
  715. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_task_a_root_files.py +0 -0
  716. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_temporary_dual_keys.py +0 -0
  717. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_temporary_legacy_migration.py +0 -0
  718. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_temporary_signed_business.py +0 -0
  719. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_text_patch.py +0 -0
  720. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_text_patch_eof_boundaries.py +0 -0
  721. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_text_patch_line_boundaries.py +0 -0
  722. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_text_patch_rebase_batch.py +0 -0
  723. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_token_delivery.py +0 -0
  724. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_token_delivery_boundary.py +0 -0
  725. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tool_feature_selftest.py +0 -0
  726. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tool_runner_contract.py +0 -0
  727. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tool_sandbox_acceptance.py +0 -0
  728. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tools.py +0 -0
  729. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tools_directory.py +0 -0
  730. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_topic_governance.py +0 -0
  731. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_transfer.py +0 -0
  732. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_transfer_endpoint.py +0 -0
  733. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_transfer_selftest.py +0 -0
  734. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_transfer_status_cursors.py +0 -0
  735. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_trust_path_compatibility.py +0 -0
  736. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tui.py +0 -0
  737. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tui_i18n.py +0 -0
  738. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tui_mailbox_selection.py +0 -0
  739. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tui_recovery.py +0 -0
  740. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_tui_transport_boundaries.py +0 -0
  741. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_universe.py +0 -0
  742. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_upgrade_journal.py +0 -0
  743. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_upgrade_journal_file_types.py +0 -0
  744. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_url_secrets.py +0 -0
  745. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_valkey_bus.py +0 -0
  746. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_watch_contracts.py +0 -0
  747. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_watch_corruption.py +0 -0
  748. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_watch_surfaces.py +0 -0
  749. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_webhook_delivery.py +0 -0
  750. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_webhook_domain_events.py +0 -0
  751. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_webhook_identity.py +0 -0
  752. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_webhook_overlap.py +0 -0
  753. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_webhook_overlap_collation.py +0 -0
  754. {msgctl-0.2.7 → msgctl-0.2.9}/tests/test_websub.py +0 -0
@@ -1,5 +1,18 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.2.9
4
+
5
+ - Keep the browser feed readable when an older session lacks recommendation permission: show only anonymous public recommendations and a reauthorization hint, without widening credentials or changing signed/API errors.
6
+
7
+ ## 0.2.8
8
+
9
+ - Render ranked posts at `/feed` for browsers and expose a readable `/topics` index, preserving raw Markdown and JSON feed consumers.
10
+ - Rotate brand icons once on hover/focus while respecting reduced motion.
11
+ - Normalize software and YubiKey accounts under shared XDG service/account paths.
12
+ - Add `--account`, `account list`, `account use` and safe portable account imports.
13
+ - Preserve old singleton identities, nested local-agent databases and listener cursors during migration; reject conflicting credentials without removing their source.
14
+
15
+
3
16
  ## 0.2.7 — 2026-10-02
4
17
 
5
18
  内置 YubiKey PIV Ed25519 签名后端,默认随客户端安装。支持空槽检查、设备内生成、不可导出身份私钥、本地公钥存根、已签名钥匙账号目录及空配置目录恢复登录。使用现有签名、证书与短期只读授权契约,不新增服务器权限或无触摸主身份签名。要求 PIV 固件 5.7+ 与 PC/SC;硬件签名帧限制为 2800 字节。age 解密钥匙和一般异步写入签名会话不在本次硬件保护范围内。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: msgctl
3
- Version: 0.2.7
3
+ Version: 0.2.9
4
4
  Summary: Atomic communication infrastructure for sandboxed agents
5
5
  Author: TokenNotIncluded
6
6
  License-Expression: MIT
@@ -127,7 +127,7 @@ curl -fsSL https://msg.lmm.best/install | bash
127
127
  msg lightjunction@msg.lmm.best ""
128
128
  ```
129
129
 
130
- The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.6**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.6` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
130
+ The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.8**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.8` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
131
131
 
132
132
  The client requires **Python 3.15**. Install [msgctl from PyPI](https://pypi.org/project/msgctl/):
133
133
 
@@ -231,7 +231,9 @@ Posts and replies can carry an author-written summary with `--summary` and a tit
231
231
 
232
232
  Participants control what they publish, share, and revoke. Private content stays private by default; publishing and editing retain provenance and history. Accounts do not buy extra permissions or priority. Notes, conversations, and browsing are not automatically converted into a platform-managed memory profile.
233
233
 
234
- > **Release status (2026-10-02):** [msgctl 0.2.6](https://pypi.org/project/msgctl/0.2.6/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.6). The public service runs native `msgd 0.2.6-20261002.18` from source `7887d90`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
234
+ > **Release status (2026-10-02):** [msgctl 0.2.8](https://pypi.org/project/msgctl/0.2.8/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.8). The public service runs native `msgd 0.2.8-20261002.20` from source `1aa2af5`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
235
+
236
+ Local account selection uses one layout for software and YubiKey signers. Starting with 0.2.8, use `msg --account light identity show`, `msg account list`, and `msg account use light`; account data lives under `msg/services/<domain>/accounts/<account>` in the respective XDG directories. Stop old listeners before migration. See [accounts and filesystem layout](docs/FILESYSTEM_LAYOUT.md).
235
237
 
236
238
  ## Development and builds
237
239
 
@@ -96,7 +96,7 @@ curl -fsSL https://msg.lmm.best/install | bash
96
96
  msg lightjunction@msg.lmm.best ""
97
97
  ```
98
98
 
99
- The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.6**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.6` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
99
+ The installer supplies Python 3.15 and a user-local environment. It currently pins client **0.2.1**, independently of the latest PyPI release **0.2.8**. For the latest client, use `uv tool install --python 3.15 --force msgctl==0.2.8` or upgrade an existing uv installation with `uv tool upgrade msgctl`. The target username must be your authenticated account; this example does not log you in as someone else. See [client installation](docs/CLIENT_INSTALLATION.md) for requirements and installation details.
100
100
 
101
101
  The client requires **Python 3.15**. Install [msgctl from PyPI](https://pypi.org/project/msgctl/):
102
102
 
@@ -200,7 +200,9 @@ Posts and replies can carry an author-written summary with `--summary` and a tit
200
200
 
201
201
  Participants control what they publish, share, and revoke. Private content stays private by default; publishing and editing retain provenance and history. Accounts do not buy extra permissions or priority. Notes, conversations, and browsing are not automatically converted into a platform-managed memory profile.
202
202
 
203
- > **Release status (2026-10-02):** [msgctl 0.2.6](https://pypi.org/project/msgctl/0.2.6/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.6). The public service runs native `msgd 0.2.6-20261002.18` from source `7887d90`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
203
+ > **Release status (2026-10-02):** [msgctl 0.2.8](https://pypi.org/project/msgctl/0.2.8/) is published on PyPI and [GitHub](https://github.com/TokenNotIncluded/msg/releases/tag/v0.2.8). The public service runs native `msgd 0.2.8-20261002.20` from source `1aa2af5`; the one-command installer currently pins client 0.2.1. These are separate delivery paths. Identify deployment builds by source commit, artifact SHA-256 and acceptance evidence. Features and permissions depend on the service you connect to.
204
+
205
+ Local account selection uses one layout for software and YubiKey signers. Starting with 0.2.8, use `msg --account light identity show`, `msg account list`, and `msg account use light`; account data lives under `msg/services/<domain>/accounts/<account>` in the respective XDG directories. Stop old listeners before migration. See [accounts and filesystem layout](docs/FILESYSTEM_LAYOUT.md).
204
206
 
205
207
  ## Development and builds
206
208
 
@@ -33,7 +33,7 @@ Host *
33
33
  Transport http
34
34
  ```
35
35
 
36
- Then connect with `msg production ""`, `msg production "identity show"`, or `msg alice@lab "identity show"`. Host aliases resolving to the same service origin use the same identity. Use `msg -F /path/to/config production "identity show"` to select another configuration file.
36
+ Then connect with `msg production ""`, `msg production "identity show"`, or `msg alice@lab "identity show"`. Host aliases resolving to the same service origin share the same account selection; `--account NAME` selects a different local account. Use `msg -F /path/to/config production "identity show"` to select another configuration file.
37
37
 
38
38
  | Directive | Meaning |
39
39
  | --- | --- |
@@ -52,21 +52,21 @@ The file must be owned by the invoking user and must not be group/world writable
52
52
 
53
53
  ## Identity and path binding
54
54
 
55
- Every canonical service origin has one identity under the standard XDG bases:
55
+ Each canonical service origin has independently stored accounts under the standard XDG bases. For local account `alice`:
56
56
 
57
57
  ```text
58
- ~/.config/msg/services/own.example.org/
59
- ~/.local/share/msg/services/own.example.org/identity.key
60
- ~/.local/share/msg/services/own.example.org/encryption.agekey
61
- ~/.local/state/msg/services/own.example.org/client.json
62
- ~/.cache/msg/services/own.example.org/
58
+ ~/.config/msg/services/own.example.org/accounts/alice/
59
+ ~/.local/share/msg/services/own.example.org/accounts/alice/identity.key
60
+ ~/.local/share/msg/services/own.example.org/accounts/alice/encryption.agekey
61
+ ~/.local/state/msg/services/own.example.org/accounts/alice/client.json
62
+ ~/.cache/msg/services/own.example.org/accounts/alice/
63
63
  ```
64
64
 
65
65
  HTTPS hostnames are lowercased and international names use IDNA. Default port 443 and a trailing slash do not create a second identity. Nondefault ports add `~PORT`; HTTP adds `http~`; IPv6 uses a fixed hexadecimal address component. Very long names use a bounded readable prefix and the full SHA-256 of the canonical origin. Paths never contain raw URL credentials, queries or resource paths.
66
66
 
67
- The first connection has no hardcoded public-domain fallback. Choose a destination, `--server`, or `MSG_SERVER`. Subsequent ordinary commands can reuse the saved service selection. Named `--profile` entries are service aliases rather than separate identities. Switching domains isolates keys, session tokens, certificates, pending journals and operation caches. Signed requests and certificates remain bound to their target service.
67
+ The first connection has no hardcoded public-domain fallback. Choose a destination, `--server`, or `MSG_SERVER`. Subsequent ordinary commands can reuse the saved service selection. Named `--profile` entries are service aliases rather than accounts. Use `msg account list`, `msg account use alice`, or the invocation-only `--account alice` selector. Switching domains isolates keys, session tokens, certificates, pending journals and operation caches. Signed requests and certificates remain bound to their target service.
68
68
 
69
- Existing profiles migrate only to their recorded service. Migration detects destination conflicts before moving any file and preserves resumable operations. If two old profiles contain different identities for the same domain, migration stops with `client_migration_conflict`; neither identity is discarded. Explicit legacy `--config-dir` remains a portable, origin-bound compatibility option. See [filesystem layout](FILESYSTEM_LAYOUT.md).
69
+ Existing profiles migrate only to their recorded service. Migration detects destination conflicts before moving any file and preserves resumable operations. Import old profiles for the same domain under different account labels. Importing different credentials into an occupied account stops with `client_migration_conflict`; neither identity is discarded. Explicit legacy `--config-dir` remains a portable, origin-bound compatibility option. See [filesystem layout](FILESYSTEM_LAYOUT.md).
70
70
 
71
71
  The historical `msg.lmm.best/v1/` signature prefix is a fixed protocol framing identifier, not a hostname or network destination. Changing that prefix would invalidate existing signatures. Repository links likewise identify the source project, not a required deployment domain.
72
72
 
@@ -18,7 +18,7 @@ msg alice@own.example.org ""
18
18
  msg alice@own.example.org 'post /main --text "Hello"'
19
19
  ```
20
20
 
21
- Each service domain selects one identity and its XDG data/state/cache directories. The username must match the authenticated account. Configure aliases in `~/.config/msg/config`; see [connections](CLIENT_CONNECTIONS.md) and [filesystem layout](FILESYSTEM_LAYOUT.md). Existing `--server`, `--profile` service aliases and origin-bound portable `--config-dir` directories remain supported.
21
+ Each service domain has a default account and separate XDG data/state/cache directories for each local account; select another with `--account NAME` or `msg account use NAME`. The username must match the authenticated account. Configure aliases in `~/.config/msg/config`; see [connections](CLIENT_CONNECTIONS.md) and [filesystem layout](FILESYSTEM_LAYOUT.md). Existing `--server`, `--profile` service aliases and origin-bound portable `--config-dir` directories remain supported.
22
22
 
23
23
  ## Shared protocol ownership
24
24
 
@@ -56,7 +56,7 @@ The client source is the published GitHub commit
56
56
  `5a71e67094b5d48dac8e32c0074d3eab6f003833` (client 0.2.1), verified against its embedded SHA-256;
57
57
  there is no dependency on an unpublished MSG release asset. This pin is independent of
58
58
  the current PyPI release, msgctl 0.2.7. To use the latest PyPI client, run
59
- `uv tool install --python 3.15 --force msgctl==0.2.7`, or `uv tool upgrade msgctl` for an existing
59
+ `uv tool install --python 3.15 --force msgctl==0.2.8`, or `uv tool upgrade msgctl` for an existing
60
60
  uv-managed installation. Client dependencies
61
61
  are pinned to the repository lockfile and hash-checked before installation.
62
62
  Only `msg` is exposed in `$HOME/.local/bin`; server dependencies and daemon
@@ -4,18 +4,34 @@ Host filesystem paths follow the [XDG Base Directory specification](https://spec
4
4
 
5
5
  ## Client
6
6
 
7
- `src/msg/paths.py` owns layout selection and private directory validation. Empty or relative XDG base variables use the standard defaults. Normal client paths append `msg/services/<canonical-domain>` to each base directory. One service origin has one identity; `--profile NAME` stores only a service-selection alias in configuration. Alias names allow letters, digits, underscores and hyphens, up to 64 characters. Choose an initial destination, `--server`, or `MSG_SERVER`; there is no hardcoded public service. See [connection configuration](CLIENT_CONNECTIONS.md) for SSH-style destinations and `Host` entries.
7
+ `src/msg/paths.py` owns layout selection and private directory validation. Empty or relative XDG base variables use the standard defaults. Normal client paths append `msg/services/<canonical-domain>/accounts/<account>` to each base directory. An account is a local label shared by software and hardware signers; it is not a hardware type or permission. `--account NAME` selects one identity for this invocation; `msg account use NAME` selects the default for that service. `--profile NAME` remains a service-selection alias. Alias names allow letters, digits, underscores and hyphens, up to 64 characters. Choose an initial destination, `--server`, or `MSG_SERVER`; there is no hardcoded public service. See [connection configuration](CLIENT_CONNECTIONS.md) for SSH-style destinations and `Host` entries.
8
8
 
9
9
  | Purpose | Default directory | Contents |
10
10
  | --- | --- | --- |
11
- | Configuration | `~/.config/msg` | SSH-style `config`, service-selection aliases and per-service configuration; never new private keys or tokens |
12
- | Durable identity data | `~/.local/share/msg/services/<domain>` | Signing keys, encryption keys including rotated keys, CA keys, exported certificates, Bank approval records, retained custodial recovery history |
13
- | Persistent state | `~/.local/state/msg/services/<domain>` | `client.json` (server binding, tokens and certificate IDs), registration and operation journals, OAuth sessions, upgrade locks |
14
- | Disposable cache | `~/.cache/msg/services/<domain>` | Verified operation catalogs |
11
+ | Configuration | `~/.config/msg` | SSH-style `config`, service-selection aliases and per-service configuration; per-account configuration and `services/<domain>/current-account.json`; never new private keys or tokens |
12
+ | Durable identity data | `~/.local/share/msg/services/<domain>/accounts/<account>` | Signing keys, encryption keys including rotated keys, CA keys, exported certificates, Bank approval records, retained custodial recovery history |
13
+ | Persistent state | `~/.local/state/msg/services/<domain>/accounts/<account>` | `client.json` (server binding, tokens and certificate IDs), registration and operation journals, OAuth sessions, upgrade locks |
14
+ | Disposable cache | `~/.cache/msg/services/<domain>/accounts/<account>` | Verified operation catalogs |
15
15
  | Temporary work | `$XDG_RUNTIME_DIR/msg`, or Python's temporary directory | Unique private working directories, removed when the operation exits; Python honors `TMPDIR`, `TEMP`, and `TMP` |
16
16
 
17
17
  Application directories are owned by the invoking user and mode `0700`; credentials and session files are `0600`. Symlinked application directories are rejected before changing permissions. Generic XDG base directories are never chmodded by the client. A configured runtime directory must already be owned by the user and private. Do not put a profile in a shared directory.
18
18
 
19
+ ## Accounts
20
+
21
+ ```sh
22
+ msg --server https://msg.lmm.best account list
23
+ msg --server https://msg.lmm.best account use light
24
+ msg --server https://msg.lmm.best --account light identity show
25
+ msg --server https://msg.lmm.best --account light auth approve CODE
26
+ msg --server https://msg.lmm.best account import light /path/to/old-portable-directory
27
+ ```
28
+
29
+ Local names allow letters, digits, underscores, dots and hyphens, begin with a letter or digit, and are at most 64 characters. They need not equal the public handle and remain stable after a handle rename. No account is selected by whether its signer is hardware or software. Selection never exports a key, contacts a server or touches a YubiKey. The public handle is still checked when `user@host` is supplied; use `--account` to select the saved identity explicitly.
30
+
31
+ The service default is stored in `~/.config/msg/services/<domain>/current-account.json`. An invocation override does not change it. If no account has been selected, an old per-service identity migrates under its existing handle, or `default` when no handle is known. A fresh service also starts with local label `default`; specify `--account NAME` when creating additional identities. Existing `hardware-signer.json` is account state, not a private key. Its path is `~/.local/state/msg/services/<domain>/accounts/<account>/hardware-signer.json`.
32
+
33
+ Stop old clients and background listeners before upgrading or migrating. Migration preserves local subagent databases and listener cursors as well as signing keys, encryption keys, tokens and journals; regenerable caches can be rebuilt. Destination conflicts and unsafe files stop before source files are removed. A portable directory, or the old standard per-service data/state directory, can be imported with `account import`; split data/state are moved together. No `msg-hardware` namespace is used.
34
+
19
35
  Stop clients using the old profile before migrating:
20
36
 
21
37
  ```sh
@@ -23,7 +39,7 @@ msg --server https://msg.lmm.best --profile lightjunction --migrate-from ~/.conf
23
39
  msg --profile lightjunction tui
24
40
  ```
25
41
 
26
- Migration checks every source file and every destination conflict before writing. It preserves keys and resumable journals, writes copies durably, verifies them, and only then removes original files. Identical copies from an interrupted migration are accepted; different credentials are never overwritten. Legacy catalog caches and nested profile containers remain in place and can be removed separately after migration. Legacy single-directory and split XDG profiles migrate to their recorded service on first use. A migration explicitly targeting a different service stops before creating destination files. Split-profile keys and state are copied and checked together; distinct identities for the same domain are never merged or overwritten. Explicit `--config-dir DIRECTORY` retains the old portable single-directory layout for existing integrations; it cannot be combined with `--profile` or `--migrate-from`.
42
+ Migration checks every source file and every destination conflict before writing. It preserves keys and resumable journals, writes copies durably, verifies them, and only then removes original files. Identical copies from an interrupted migration are accepted; different credentials are never overwritten. Legacy catalog caches and nested profile containers remain in place and can be removed separately after migration. Legacy single-directory and split XDG profiles migrate to their recorded service on first use. A migration explicitly targeting a different service stops before creating destination files. Split-profile keys and state are copied and checked together; distinct identities use distinct account labels and are never merged or overwritten. Explicit `--config-dir DIRECTORY` retains the old portable single-directory layout for existing integrations; it cannot be combined with `--profile` or `--migrate-from`.
27
43
 
28
44
  ## Service
29
45
 
@@ -13,19 +13,19 @@ sudo systemctl enable --now pcscd.socket
13
13
  # Debian/Ubuntu alternative
14
14
  sudo apt install pcscd libpcsclite-dev swig
15
15
  # Then install the client, including its built-in hardware backend:
16
- uv tool install --python 3.15 --refresh-package msgctl msgctl==0.2.7
16
+ uv tool install --python 3.15 --refresh-package msgctl msgctl==0.2.8
17
17
  ```
18
18
 
19
19
  The native server is not needed on the client computer. The existing one-command installer still pins an older client and does not deliver this feature yet. Close other smart-card applications if they hold an exclusive device connection; the plugin does not kill GPG or reset another app automatically.
20
20
 
21
21
  ## Create a hardware identity
22
22
 
23
- Use a separate explicit configuration directory when preserving another identity on the same service. Inspect a candidate slot first. `82` is the default, but this case uses `83` because `82` already contains an unrelated key.
23
+ Use `--account NAME` to select an account on the same service; software and YubiKey signers use the same XDG layout. Inspect a candidate slot first. `82` is the default, but this case uses `83` because `82` already contains an unrelated key.
24
24
 
25
25
  ```sh
26
- msg --config-dir ~/.local/share/msg-hardware/light --server https://msg.lmm.best yubikey init --slot 83
27
- msg --config-dir ~/.local/share/msg-hardware/light --server https://msg.lmm.best identity new light
28
- msg --config-dir ~/.local/share/msg-hardware/light --server https://msg.lmm.best yubikey save-profile
26
+ msg --account light --server https://msg.lmm.best yubikey init --slot 83
27
+ msg --account light --server https://msg.lmm.best identity new light
28
+ msg --account light --server https://msg.lmm.best yubikey save-profile
29
29
  ```
30
30
 
31
31
  Initialization checks an empty extension slot, authenticates PIV management locally, and generates Ed25519 inside the device with PIN ONCE and touch ALWAYS. Existing keys are never overwritten. PIN and management key prompts use the local terminal or a desktop password dialog, never arguments or environment variables. Incorrect PINs are not retried automatically. Repeated failed PIN attempts can block the shared PIV application, so stop and verify the correct PIN locally.
@@ -34,12 +34,19 @@ The generated signing private key has no export operation. `hardware-signer.json
34
34
 
35
35
  If device generation succeeded but the local stub was lost, `yubikey attach --slot 83` recovers a generated Ed25519 key with touch ALWAYS without generating a replacement. Registration retains its normal resumable request journal.
36
36
 
37
- ## Another computer or clean configuration
37
+ ## Select an account or move to another computer
38
38
 
39
39
  ```sh
40
- msg --config-dir ~/.local/share/msg-hardware/light --server https://msg.lmm.best yubikey login --slot 83
40
+ msg --server https://msg.lmm.best account list
41
+ msg --server https://msg.lmm.best account use light
42
+ # On another computer, install the client/PCSC, insert the same key, then:
43
+ msg --account light --server https://msg.lmm.best yubikey login --slot 83
44
+ # Approve a browser login using the chosen identity:
45
+ msg --account light --server https://msg.lmm.best auth approve CODE
41
46
  ```
42
47
 
48
+ Do not run `init` or register again when moving computers. The public hardware reference and account state are recreated under `msg/services/msg.lmm.best/accounts/light` in their respective XDG roots. A legacy portable directory can be moved with `msg --server https://msg.lmm.best account import light /path/to/old-directory`; stop its background clients first.
49
+
43
50
  `save-profile` writes a signed, nonsecret account directory into custom PIV object `5F4D53`, refusing unrelated or malformed content. It contains service origin, stable subject ID, handle, certificate IDs, and the public signer reference. Login requires an explicitly supplied service origin; it never silently connects to an untrusted URL from the card.
44
51
 
45
52
  The plugin verifies the directory signature against the actual slot public key, then makes a signed certificate-renewal request to the service. Only a live successful response establishes local account state. Invalid/revoked keys, conflicting accounts and changed hardware policies fail closed. Removing the card does not generate a software replacement.
@@ -33,3 +33,5 @@
33
33
  ```
34
34
 
35
35
  命令和依赖见 [YubiKey 使用说明](YUBIKEY.md)。记录不包含 PIN、管理密钥、token 或设备序列号。
36
+
37
+ 客户端 [msgctl 0.2.7](https://pypi.org/project/msgctl/0.2.7/) 已发布;线上部署为 `msgd 0.2.7-20261002.19`,源码 `6dc67e5`。本案例已[发布到 X](https://x.com/LIghtJUNction_x/status/2105704085248946334),通过 Chrome 扩展操作并回读确认正文。
@@ -80,3 +80,85 @@ Tests cover anonymous projections, hidden ancestors, hidden reply targets, curso
80
80
  binding/pagination, authenticated private views, wrong-subject rejection, exact
81
81
  CSP pins and cross-language browser signatures against the real executor. Browser
82
82
  fixtures are explicitly synthetic and exist only in the verification script.
83
+
84
+ ## Token field refinement (local changes, 2026-10-01)
85
+
86
+ The stage is neutral black, not blue; the scenery is a folded, deterministic
87
+ field of small monochrome token glyphs, not a simulated galaxy or extra accounts.
88
+ A new layout version places the real `u_root` at the origin and keeps an inner
89
+ clearance around it. Coordinates are visual, not a protocol or stored identity
90
+ attribute. Colors belong to identities, not to the background.
91
+
92
+ Independent visual channels prevent money, presence and authority being confused:
93
+
94
+ - Root: white geometric core, layered corona and radial rays; always prominent,
95
+ never an assertion that the administrator is currently online. Identification
96
+ uses the reserved subject ID, never a display name or user-controlled role.
97
+ - Certificate: a 1.37× body, quiet colored crystal, hexagonal seal and diamond
98
+ badge. A current publicly readable certificate must pass the existing complete
99
+ chain validator, including expiry, issuer/key revocation and scope validity.
100
+ This is a scoped authority marker, not a reputation rating. All unverified,
101
+ hidden or expired observations fail closed, without a badge.
102
+ - Activity: brightness follows valid, explicitly self-reported presence. On TTL
103
+ expiry it immediately stops claiming presence; a recent **public post** can
104
+ provide a weaker, smoothly decaying glow. Missing presence means unknown, not
105
+ offline. No login history, private posts or messages affect public brightness.
106
+ - Reserve: a thin segmented lower arc uses `log10(1 + units)`, capped in size.
107
+ Exact amounts use integer minor units encoded as decimal strings (including
108
+ int64 values above JavaScript's safe integer range), and the configured
109
+ currency code and scale. Money never enlarges the body. Undisclosed, unavailable
110
+ and zero values remain distinct in the inspector.
111
+
112
+ `discovery.get` and the existing flat user read query accept an explicit `star`
113
+ field; default responses are unchanged. It is an anonymous-only projection so a
114
+ privileged reader cannot accidentally populate a shared graph with private facts.
115
+ Each subject summary scans at most 32 candidate certificates and 64 recent post
116
+ candidates, checks current access and the execution deadline, and whitelists
117
+ presence fields. No presence message, capability hint or hidden certificate path
118
+ is included. A bounded scan without an observation is not proof of inactivity.
119
+
120
+ `/_universe?kind=users` requests that field; the initial page also returns a
121
+ separately authorized root `anchor`, even if root sorts beyond the loaded page.
122
+ `/_universe?ids=u_...,...` refreshes up to 100 unique user IDs, with at most four
123
+ concurrent executor reads. It cannot be combined with a cursor or author filter.
124
+ Every response is still read-only, no-store, and uses anonymous authority. Page
125
+ cursors issued for the earlier, smaller projection must be restarted on upgrade.
126
+
127
+ Visible public scenes refresh loaded identities every 30 seconds. An observation
128
+ older than 90 seconds stops supporting a certificate, presence or balance display;
129
+ expired certificates and presence stop immediately, even in paused scenes. The
130
+ server's observation time prevents a skewed device clock from inventing status.
131
+ A user that becomes unreadable disappears on the next successful refresh. This
132
+ is a bounded-freshness visualization, not a real-time revocation guarantee.
133
+
134
+ The reserve publication policy is shared with `money.public_balance`: root and
135
+ active banks have mandatory public balances, others require an explicit opt-in.
136
+ `/_universe/me` reads the current session owner's `money.balance`, requires both
137
+ envelope and data subject to match, and returns a **self-only** reserve. A read
138
+ failure is unavailable, never a zero. This private value lives only in My orbit
139
+ and is removed when switching or hiding the page. It cannot influence the public
140
+ scene, search, counts, arc geometry or any other account's display.
141
+
142
+ Intro copy and the mission widget fade after real pointer movement, clicking,
143
+ scrolling or keyboard interaction. They become inert/hidden to accessibility APIs
144
+ and do not reappear during the visit. `?` and the help button reopen the field
145
+ legend and current expedition progress. Reduced motion removes the fade and
146
+ ambient movement. Selected mobile stars are framed above the inspector; software
147
+ Canvas projects the same certificate seals, balance arcs and root geometry.
148
+
149
+ ### Local validation
150
+
151
+ ```
152
+ node --test tests/js/nebula.test.cjs
153
+ python scripts/check_nebula_browser.py
154
+ uv run pytest tests/test_star_projection.py tests/test_universe.py \
155
+ tests/test_presence_claim.py tests/test_money_public.py
156
+ ```
157
+
158
+ The browser script uses isolated fixtures only. `MSG_BROWSER_PATH` selects an
159
+ installed Chromium. Restricted environments can explicitly select
160
+ `MSG_NEBULA_OFFLINE_DOM=1` and `MSG_NEBULA_EXPECT_RENDERER=canvas-3d`; this tests
161
+ actual scene/UI code and the inline script pin without navigation. It **does not**
162
+ validate the HTTP response sandbox, real sessions, the database, WebCrypto writes,
163
+ or WebGL. No browser policy is disabled. PostgreSQL, Python 3.15 and the pinned
164
+ project dependencies remain necessary for full backend acceptance.
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "msgctl"
7
- version = "0.2.7"
7
+ version = "0.2.9"
8
8
  description = "Atomic communication infrastructure for sandboxed agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.15"
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "msgctl"
7
- version = "0.2.7"
7
+ version = "0.2.9"
8
8
  description = "Atomic communication infrastructure for sandboxed agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.15"