@seanyao/roll 2026.521.3 → 2026.522.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## v2026.522.1
4
+
5
+ ### Fixed
6
+
7
+ - **loop 不再被 Roll 自身测试遗留的后台调度静默杀掉** `[loop]`
8
+
3
9
  ## v2026.521.3
4
10
 
5
11
  ### Added
package/bin/roll CHANGED
@@ -4,7 +4,7 @@ set -euo pipefail
4
4
  # Roll — AI Agent Convention Manager
5
5
  # Single source of truth for how all AI coding agents behave.
6
6
 
7
- VERSION="2026.521.3"
7
+ VERSION="2026.522.1"
8
8
  ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
9
9
  ROLL_CONFIG="${ROLL_HOME}/config.yaml"
10
10
  ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
@@ -3810,7 +3810,40 @@ fi
3810
3810
  # _SHARED_ROOT overrides and silently leaked test runs.jsonl writes into prod.
3811
3811
  _LOOP_RUNS="${_SHARED_ROOT}/loop/runs.jsonl"
3812
3812
  : "${_LOOP_MUTE_FILE:=${_SHARED_ROOT}/loop/mute-${_LOOP_PROJ_SLUG}}"
3813
- _LAUNCHD_DIR="${HOME}/Library/LaunchAgents"
3813
+ # FIX-087: parallel to FIX-065's _SHARED_ROOT auto-sandbox above. Without this,
3814
+ # tests that source bin/roll (directly via BATS or indirectly via a runner-inner
3815
+ # fork under /tmp / /var/folders/) wrote plists into the developer's real
3816
+ # ~/Library/LaunchAgents/ while their runner paths lived in the sandbox. When
3817
+ # the sandbox got cleaned up, those plists outlived their runners and launchd
3818
+ # fired them every hour with EX_CONFIG, silently killing the autonomous loop.
3819
+ # Detection signals mirror the _SHARED_ROOT block; under a sandbox we route
3820
+ # _LAUNCHD_DIR into _SHARED_ROOT so a single teardown removes both.
3821
+ if [ -z "${_LAUNCHD_DIR:-}" ]; then
3822
+ # When HOME itself is a sandbox dir (run_roll-style wrappers, roll_status
3823
+ # setup, etc.) the default ${HOME}/Library/LaunchAgents is ALREADY in the
3824
+ # sandbox — redirecting again would break tests that pre-seed plists under
3825
+ # the sandboxed HOME. Only auto-sandbox when HOME points to a real user dir.
3826
+ case "${HOME:-}" in
3827
+ /tmp/*|/private/tmp/*|*/var/folders/*|*/tmp.*) ;;
3828
+ *)
3829
+ _roll_in_test_ctx=0
3830
+ if [ -n "${BATS_TEST_FILENAME:-}" ]; then
3831
+ _roll_in_test_ctx=1
3832
+ else
3833
+ _roll_caller="${BASH_SOURCE[1]:-}"
3834
+ case "$_roll_caller" in /tmp/*|/private/tmp/*|/var/folders/*) _roll_in_test_ctx=1 ;; esac
3835
+ case "$PWD" in /tmp/*|/private/tmp/*|/var/folders/*) _roll_in_test_ctx=1 ;; esac
3836
+ fi
3837
+ if [ "$_roll_in_test_ctx" = 1 ]; then
3838
+ _LAUNCHD_DIR="${_SHARED_ROOT}/LaunchAgents"
3839
+ mkdir -p "$_LAUNCHD_DIR"
3840
+ export _LAUNCHD_DIR
3841
+ fi
3842
+ unset _roll_in_test_ctx _roll_caller
3843
+ ;;
3844
+ esac
3845
+ fi
3846
+ : "${_LAUNCHD_DIR:=${HOME}/Library/LaunchAgents}"
3814
3847
 
3815
3848
  _config_read_int() {
3816
3849
  local key="$1" default="$2"
@@ -3940,6 +3973,25 @@ _write_launchd_plist() {
3940
3973
  local plist_path="$1" label="$2" project_path="$3"
3941
3974
  local minute="$4" hour="$5" runner_script="$6"
3942
3975
 
3976
+ # FIX-087 tripwire: last line of defense if some caller explicitly set
3977
+ # _LAUNCHD_DIR back to the real path (or built plist_path manually) while
3978
+ # in a test context. Refuse rather than pollute the user's launchd domain.
3979
+ # Skipped when HOME itself has been redirected to a sandbox dir — then
3980
+ # $HOME/Library/LaunchAgents IS the sandbox, not prod.
3981
+ case "${HOME:-}" in
3982
+ /tmp/*|/private/tmp/*|*/var/folders/*|*/tmp.*) ;;
3983
+ *)
3984
+ if [ -n "${HOME:-}" ] && [ "${plist_path#${HOME}/Library/LaunchAgents/}" != "$plist_path" ]; then
3985
+ case "${BATS_TEST_FILENAME:-}${PWD}" in
3986
+ */tmp.*|*/var/folders/*|/tmp/*|/private/tmp/*|*.bats)
3987
+ echo "[FIX-087] refusing prod plist write: $plist_path (test context)" >&2
3988
+ return 1
3989
+ ;;
3990
+ esac
3991
+ fi
3992
+ ;;
3993
+ esac
3994
+
3943
3995
  local hour_xml=""
3944
3996
  [[ -n "$hour" ]] && hour_xml=" <key>Hour</key>
3945
3997
  <integer>${hour}</integer>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanyao/roll",
3
- "version": "2026.521.3",
3
+ "version": "2026.522.1",
4
4
  "description": "Roll — Roll out features with AI agents",
5
5
  "scripts": {
6
6
  "test": "bash tests/run.sh"