ctrlrelay 0.12.2__tar.gz → 0.12.4__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 (141) hide show
  1. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/CHANGELOG.md +60 -1
  2. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/PKG-INFO +1 -1
  3. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/pyproject.toml +1 -1
  4. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/cli.py +1091 -79
  5. ctrlrelay-0.12.4/src/ctrlrelay/core/binaries.py +198 -0
  6. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/code_review.py +27 -1
  7. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/config.py +23 -0
  8. ctrlrelay-0.12.4/src/ctrlrelay/core/dispatch_health.py +276 -0
  9. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/dispatcher.py +215 -21
  10. ctrlrelay-0.12.4/src/ctrlrelay/core/redact.py +321 -0
  11. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/state.py +455 -1
  12. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/base.py +12 -0
  13. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/dev.py +436 -13
  14. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/secops.py +7 -0
  15. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/launchd/bridge.plist.template +9 -1
  16. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/launchd/poller.plist.template +9 -1
  17. ctrlrelay-0.12.4/src/ctrlrelay/templates/systemd/bridge.service.template +37 -0
  18. ctrlrelay-0.12.4/src/ctrlrelay/templates/systemd/poller.service.template +42 -0
  19. ctrlrelay-0.12.4/tests/test_binary_resolution.py +1009 -0
  20. ctrlrelay-0.12.4/tests/test_claim_reconciliation.py +999 -0
  21. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_config.py +6 -2
  22. ctrlrelay-0.12.4/tests/test_dispatch_health.py +462 -0
  23. ctrlrelay-0.12.4/tests/test_dispatch_outcome_hook.py +1512 -0
  24. ctrlrelay-0.12.4/tests/test_issue_outcome_announcement.py +182 -0
  25. ctrlrelay-0.12.4/tests/test_notify_transport.py +1238 -0
  26. ctrlrelay-0.12.4/tests/test_redact.py +512 -0
  27. ctrlrelay-0.12.4/tests/test_unreviewed_pr_announcement.py +1009 -0
  28. ctrlrelay-0.12.2/src/ctrlrelay/templates/systemd/bridge.service.template +0 -20
  29. ctrlrelay-0.12.2/src/ctrlrelay/templates/systemd/poller.service.template +0 -25
  30. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  31. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  32. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  33. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/dependabot.yml +0 -0
  34. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/workflows/build.yml +0 -0
  35. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/workflows/cla.yml +0 -0
  36. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/workflows/pages.yml +0 -0
  37. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/workflows/publish.yml +0 -0
  38. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.github/workflows/test.yml +0 -0
  39. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/.gitignore +0 -0
  40. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/CODE_OF_CONDUCT.md +0 -0
  41. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/CONTRIBUTING.md +0 -0
  42. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/LICENSE +0 -0
  43. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/README.md +0 -0
  44. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/SECURITY.md +0 -0
  45. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/config/orchestrator.yaml.example +0 -0
  46. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/Gemfile +0 -0
  47. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/_config.yml +0 -0
  48. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/architecture.md +0 -0
  49. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/bridge.md +0 -0
  50. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/cli.md +0 -0
  51. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/configuration.md +0 -0
  52. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/development.md +0 -0
  53. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/feedback-loop.md +0 -0
  54. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/getting-started.md +0 -0
  55. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/index.md +0 -0
  56. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/operations.md +0 -0
  57. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/docs/personalization.md +0 -0
  58. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/__init__.py +0 -0
  59. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/__init__.py +0 -0
  60. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/__main__.py +0 -0
  61. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/factory.py +0 -0
  62. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/handler.py +0 -0
  63. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/mattermost_handler.py +0 -0
  64. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/protocol.py +0 -0
  65. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/server.py +0 -0
  66. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/bridge/telegram_handler.py +0 -0
  67. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/__init__.py +0 -0
  68. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/archived.py +0 -0
  69. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/audit.py +0 -0
  70. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/checkpoint.py +0 -0
  71. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/github.py +0 -0
  72. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/network.py +0 -0
  73. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/obs.py +0 -0
  74. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/poller.py +0 -0
  75. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/pr_verifier.py +0 -0
  76. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/pr_watcher.py +0 -0
  77. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/question_expiry.py +0 -0
  78. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/scheduler.py +0 -0
  79. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/core/worktree.py +0 -0
  80. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/dashboard/__init__.py +0 -0
  81. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/dashboard/client.py +0 -0
  82. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/gh_protocol.py +0 -0
  83. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/install.py +0 -0
  84. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/personalization/__init__.py +0 -0
  85. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/personalization/manager.py +0 -0
  86. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/personalization/paths.py +0 -0
  87. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/__init__.py +0 -0
  88. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/post_merge.py +0 -0
  89. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/pipelines/task.py +0 -0
  90. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/setup.py +0 -0
  91. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/__init__.py +0 -0
  92. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/global-CLAUDE.md.snippet +0 -0
  93. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/launchd/__init__.py +0 -0
  94. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/templates/systemd/__init__.py +0 -0
  95. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/transports/__init__.py +0 -0
  96. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/transports/base.py +0 -0
  97. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/transports/file_mock.py +0 -0
  98. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/src/ctrlrelay/transports/socket_client.py +0 -0
  99. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/__init__.py +0 -0
  100. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/conftest.py +0 -0
  101. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_archived.py +0 -0
  102. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_audit.py +0 -0
  103. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_bridge_protocol.py +0 -0
  104. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_bridge_server.py +0 -0
  105. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_checkpoint.py +0 -0
  106. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_ci_wait.py +0 -0
  107. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_dev.py +0 -0
  108. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_repos.py +0 -0
  109. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_secops.py +0 -0
  110. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_start.py +0 -0
  111. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_cli_version.py +0 -0
  112. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_code_review.py +0 -0
  113. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_dashboard_client.py +0 -0
  114. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_dev_integration.py +0 -0
  115. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_dev_pipeline.py +0 -0
  116. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_dispatcher.py +0 -0
  117. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_docs_site.py +0 -0
  118. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_gh_protocol.py +0 -0
  119. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_github.py +0 -0
  120. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_install.py +0 -0
  121. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_mattermost_handler.py +0 -0
  122. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_network.py +0 -0
  123. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_obs.py +0 -0
  124. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_personalization.py +0 -0
  125. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_pipeline_base.py +0 -0
  126. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_poller.py +0 -0
  127. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_post_merge.py +0 -0
  128. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_pr_verifier.py +0 -0
  129. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_pr_watcher.py +0 -0
  130. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_question_expiry.py +0 -0
  131. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_resume_prompt_contract.py +0 -0
  132. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_scheduler.py +0 -0
  133. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_secops_integration.py +0 -0
  134. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_secops_pipeline.py +0 -0
  135. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_setup.py +0 -0
  136. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_state.py +0 -0
  137. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_task_pipeline.py +0 -0
  138. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_telegram_handler.py +0 -0
  139. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_transport.py +0 -0
  140. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_transport_resolution.py +0 -0
  141. {ctrlrelay-0.12.2 → ctrlrelay-0.12.4}/tests/test_worktree.py +0 -0
@@ -7,6 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.12.4] - 2026-10-18
11
+
12
+ Carries 0.12.3's entries too: v0.12.3 was never tagged, so nothing has
13
+ shipped since v0.12.2 and this is the first release to reach a running
14
+ daemon with any of it.
15
+
16
+ ### Fixed
17
+
18
+ - Reconcile the claim comment with a failed dispatch, alert on a run of
19
+ failures, and keep the exit code and the worker's output (#206, closes
20
+ #204)
21
+
22
+ The dev lane posted *"a PR will be opened for review"* before the
23
+ worker started and never returned to the issue when the worker
24
+ exited non-zero, so that sentence stood on a beta tester's own ticket
25
+ for eighteen hours. Separately, 163 consecutive failed dispatches over
26
+ two days told nobody while both units stayed `active (running)`.
27
+ Separately again, `sessions.claude_exit_code` was never written on the
28
+ failure path and no worker output was retained, so the only durable
29
+ evidence of why they failed was that each took about two seconds.
30
+
31
+ New: `sessions.output_tail`, the `dispatch_health` table, and an
32
+ `alerts` config block (`alerts.enabled`,
33
+ `alerts.consecutive_dispatch_failures`, default 3). All additive and
34
+ defaulted — no config edit is needed.
35
+
36
+ **Known limits**, stated because they are decisions rather than
37
+ oversights: the relay-health alert is awaited inside the dispatcher,
38
+ so it can hold the per-repo lock for up to ~15 s against a wedged
39
+ bridge; delivery is at-least-once, so an alert that is sent but whose
40
+ delivery cannot be recorded may be sent once more; and the output
41
+ scrubber removes known credential shapes, which is not a proof that
42
+ nothing sensitive remains. A numeric value under a credential key is
43
+ kept, because treating every number as a possible secret destroyed the
44
+ token counts in an API error.
45
+
46
+ ### Added
47
+
48
+ - Announce a pull request whose review could not run (#202, closes #196)
49
+
50
+ ### Fixed (0.12.3, never released)
51
+
52
+ - Resolve the reviewer binary before exec, and ship a unit PATH that finds
53
+ it (#201, closes #197)
54
+ - Resolve the notification transport at use, not at boot (#199, closes #198)
55
+
56
+ ## [0.12.3] - 2026-10-12
57
+
58
+ ### Added
59
+
60
+ - Announce a pull request whose review could not run (#202, closes #196)
61
+
62
+ ### Fixed
63
+
64
+ - Resolve the reviewer binary before exec, and ship a unit PATH that finds
65
+ it (#201, closes #197)
66
+ - Resolve the notification transport at use, not at boot (#199, closes #198)
67
+
10
68
  ## [0.12.2] - 2026-10-06
11
69
 
12
70
  ### Fixed
@@ -1689,7 +1747,8 @@ pipeline).
1689
1747
  per-phase implementation plans (Phase 0 through Phase 4).
1690
1748
  - `docs/Claude_Code_Project_Guide.md` — project development guide.
1691
1749
 
1692
- [Unreleased]: https://github.com/AInvirion/ctrlrelay/compare/v0.12.2...HEAD
1750
+ [Unreleased]: https://github.com/AInvirion/ctrlrelay/compare/v0.12.3...HEAD
1751
+ [0.12.3]: https://github.com/AInvirion/ctrlrelay/compare/v0.12.2...v0.12.3
1693
1752
  [0.12.2]: https://github.com/AInvirion/ctrlrelay/compare/v0.12.1...v0.12.2
1694
1753
  [0.12.1]: https://github.com/AInvirion/ctrlrelay/compare/v0.12.0...v0.12.1
1695
1754
  [0.12.0]: https://github.com/AInvirion/ctrlrelay/compare/v0.11.3...v0.12.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ctrlrelay
3
- Version: 0.12.2
3
+ Version: 0.12.4
4
4
  Summary: Local-first orchestrator for headless coding agents across multiple GitHub repos
5
5
  Project-URL: Homepage, https://github.com/AInvirion/ctrlrelay
6
6
  Project-URL: Documentation, https://ainvirion.github.io/ctrlrelay/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ctrlrelay"
3
- version = "0.12.2"
3
+ version = "0.12.4"
4
4
  description = "Local-first orchestrator for headless coding agents across multiple GitHub repos"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"