@tyhld/conductor 0.7.0 → 0.8.0

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 (2) hide show
  1. package/dist/relay.js +40 -5
  2. package/package.json +1 -1
package/dist/relay.js CHANGED
@@ -57,7 +57,30 @@ function envPositiveNumber(name, def) {
57
57
  return Number.isFinite(parsed) && parsed > 0 ? parsed : def;
58
58
  }
59
59
  /**
60
- * 生存の見張り(keepalive)を打ち切るまでの上限(ms)。既定30分=中央のタイムアウトと同じ長さ。
60
+ * ★中央(devlog-tracker)が「手が挙がっていても必ず現場を解放する」上限(ms)
61
+ *
62
+ * 【この数字の持ち主は中央】便1 PR#250 で中央がこう決めた:
63
+ * 「busy の印が新しい間は30分の時間切れをしない。ただし着信から3時間で必ず解放する
64
+ * (手を挙げ直しても伸びない)」。
65
+ * =relay がどれだけ手を挙げ続けても、3時間を過ぎれば現場は解放される。
66
+ *
67
+ * 【★片方だけ動かさないこと】中央がこの値を変えたら、ここも合わせる。
68
+ * 合っていないと次のどちらかになる:
69
+ * ・ここが短い … 中央はまだ守ってくれるのに職人が先に手を下ろす=割り込まれる
70
+ * (2026-09-04 に実際に起きた。中央3時間・relay 30分だった)
71
+ * ・ここが長い … 中央は既に解放しているのに職人だけ手を挙げ続ける=意味がない
72
+ * ★長い側は下の clampToCentralHold が構造的に潰す(設定を間違えても中央を超えない)。
73
+ */
74
+ export const CENTRAL_BUSY_HOLD_MAX_MS = 3 * 60 * 60 * 1000; // 3時間(中央 PR#250 と同じ値)
75
+ /**
76
+ * 見張りの上限を中央の上限に収める。★中央より長い値は意味がないので切り詰める。
77
+ * 環境変数で誤って長く設定しても、中央を超えないことをここで保証する。
78
+ */
79
+ export function clampToCentralHold(ms) {
80
+ return Math.min(ms, CENTRAL_BUSY_HOLD_MAX_MS);
81
+ }
82
+ /**
83
+ * 生存の見張り(keepalive)を打ち切るまでの上限(ms)。★既定は中央と同じ3時間。
61
84
  *
62
85
  * 【なぜ pending とは別の寿命が要るのか(調査 176aebcf・案①-a)】
63
86
  * 上の RELAY_PENDING_TIMEOUT_MS は「配達の追跡」を諦める時計で、固着して次の指示を拾えなく
@@ -70,11 +93,23 @@ function envPositiveNumber(name, def) {
70
93
  * そこで「配達の追跡(pending)」と「生存の見張り(keepalive)」の寿命を分ける。pending は従来
71
94
  * どおり15分で解除して次の指示を拾えるようにし、生存通知だけをこの時計で続ける。
72
95
  *
73
- * 【なぜ30分か】中央が sent/stalled を timeout(=諦めて現場を解放)に落とすのと同じ長さ。
74
- * これより長く見張っても、中央は既に別の指示を配れる状態になっており意味がない。
75
- * 環境変数 RELAY_KEEPALIVE_MAX_MS で上書き可(正の数のみ)。
96
+ * 【なぜ30分→3時間へ広げたか(えふさん決定 2026-09-04)】
97
+ * 便2で「作業中です」と手を挙げる仕掛けを入れたが、この上限が30分のままだと
98
+ * 30分で手が下りて、また割り込まれる。実測 2026-09-04: 15分の pending 解除が18件=
99
+ * 30分を超える便が常態で、割り込まれた便は着信から35分だった。
100
+ * ★中央だけ3時間に伸びていて、職人側が30分で足を引っ張っている状態だったので合わせる。
101
+ *
102
+ * 【★引き受けたリスク(えふさん判断)】職人が固まった場合、その現場は最大3時間ふさがる。
103
+ * だから「時間で下ろす」以外の下ろし方が生命線になる。次の4つは時間を待たずに効く:
104
+ * ① 画面の DONE を検出した (decideKeepalive の 'done')
105
+ * ② 中央で終端になった ('probe' → isCentralFinished)
106
+ * ③ 職人が静止した ('probe' → 手を下ろす。終端でなくても下ろす)
107
+ * ④ relayTick 入口の砦 (pending でも keepalive でもなくなったら必ず下ろす)
108
+ * ★この4つはテスト(test/relay-busy-hold.test.ts)で固定してある。外すと落ちる。
109
+ *
110
+ * 環境変数 RELAY_KEEPALIVE_MAX_MS で上書き可(正の数のみ・★中央の上限までに切り詰める)。
76
111
  */
77
- export const RELAY_KEEPALIVE_MAX_MS = envPositiveNumber('RELAY_KEEPALIVE_MAX_MS', 30 * 60 * 1000);
112
+ export const RELAY_KEEPALIVE_MAX_MS = clampToCentralHold(envPositiveNumber('RELAY_KEEPALIVE_MAX_MS', CENTRAL_BUSY_HOLD_MAX_MS));
78
113
  /**
79
114
  * 自動再送(2-a)のポリシー。生存中の職人が動かないときに同一指示を再送する。
80
115
  * - RELAY_RESEND_DELAY_MS: 初回送信(sentAt)から最初の再送までの待機(ms)。既定30秒。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyhld/conductor",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "采配くん管制の見守りアプリ(conductor-agent)。各PCで常駐し、中央(devlog-tracker)へ定期的に生存報告(heartbeat)を送る常駐CLI。",
5
5
  "type": "module",
6
6
  "bin": {