排版核心块:待拍板项强制「四行竖排」;补回被误删的 start-supervise.ps1.tpl
1) 起因(2026-10-06 用户):「提问还是不按照提问排版格式来」——
复盘:我上一次把「问题/说明/候选A/候选B/倾向」全塞进一个自然段,
违反既有的「并列内容竖排」。核心块原本只写"逐条编号",
⇒ 本次把**四行竖排**写成明文并给出形样(问题/说明/候选各占独立一行/倾向)。
核心块 835 → 1172 字符。
2) 顺带修:上一轮同步时 `assets/start-supervise.ps1.tpl` 被漏拷而删掉了远端那份,
该文件被 manifest / pitfalls / supervise-persistence / collabd.py / init_workspace.py 五处引用
⇒ 已从 64dd820 取回,本次一并发回。
This commit is contained in:
1 parent
bcb9d1253d
commit
423b16004f
2 files changed
+140
-1
No files matched your search
@@ -0,0 +1,132 @@
|
||||
# collabd supervisor keeper -- NEVER returns on purpose.
|
||||
#
|
||||
# 🔴🔴 2026-10-04 修:首行原本多打了三个双引号(即「三连双引号 + #」开头,
|
||||
# 把整份 `.ps1` 变成了「Python 看着合法、PowerShell 看着语法错」的畸形文件
|
||||
# ⇒ 生成物被 PowerShell 判定 9 处语法错、**一秒内秒退** ⇒ 常驻彻底没人续命。
|
||||
# ⛔ 这个文件是 **PowerShell**(不是 Python)⇒ 注释一律用 `#`,⛔ 不要三引号。
|
||||
#
|
||||
# ⚙️ 本文件由 `init_workspace.py` **按工作区变量自动生成**(⛔ 请勿手改:要改改模板 + 重跑脚本)。
|
||||
# 生成时间:__STAMP__
|
||||
# 适用工作区:__WS__
|
||||
#
|
||||
# Why this file exists(⛔ 下面几条是踩出来的,⛔ 别"简化"掉):
|
||||
# ① 计划任务**只在任务失败(非零退出)时重启**。早前版本末尾直接前台调 pythonw,
|
||||
# pythonw 死掉后脚本返回 0 ⇒ 任务被判"成功"⇒ RestartCount=999 永不触发
|
||||
# ⇒ **常驻死了就永远死着**。⇒ **重启逻辑必须住在脚本里**。
|
||||
# ② ⛔ **绝不能用 `& $pyw ...`** 起常驻:pythonw 是 GUI 子系统程序,PowerShell 的
|
||||
# 调用运算符**不阻塞**它 ⇒ 立刻返回 ⇒ 脚本以为"collabd 退出了"⇒ 每几秒就重拉
|
||||
# ⇒ **叠出一堆重复常驻**。⇒ 用 `Start-Process -Wait`(真阻塞)。
|
||||
# ③ **存活判据=心跳,不是退出码**:collabd 发现有活的常驻时会**故意 exit 0**(幂等),
|
||||
# 那个 0 退出**绝不能**触发重拉风暴。
|
||||
# ④ UTF-8 **带 BOM**(⛔ 不带 ⇒ PowerShell 5.1 按 ANSI/GBK 解码 ⇒ CJK 路径被毁
|
||||
# ⇒ 任务一秒内 Result=1 退出)。
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
$env:CODEBUDDY_CONFIG_DIR = "__CFGDIR__"
|
||||
$env:COLLABD_CONFIG = "__COLLABDCFG__"
|
||||
$env:PYTHONIOENCODING = "utf-8"
|
||||
$env:PYTHONUNBUFFERED = "1" # stdout 重定向到文件,Python 会块缓冲 ⇒ 不设它诊断全压在 4KB 之后
|
||||
|
||||
$root = "__WS__"
|
||||
$pyw = "__PYW__"
|
||||
$script = "__SCRIPT__"
|
||||
$hbPath = "__HBPATH__"
|
||||
$logPath = "__LOG__"
|
||||
$stampPath = "__STAMP__"
|
||||
# 🔴 停止标志:机制侧 `--set-life 已完成` ⇒ 写它 ⇒ 常驻优雅退出。
|
||||
# ⚠️ 改前缺陷:keeper 不知道它 ⇒ 目标收口后**每 60 秒重拉一次、每次秒退**
|
||||
# (实测**空转 370 次/6 小时**)⇒ "完成即收工"只做到"停掉常驻",
|
||||
# ⛔ **没做到"别再拉它起来"** —— 那是同一件事的两半。
|
||||
$stopFlag = "__STOPFLAG__"
|
||||
|
||||
$staleSec = 90 # 与 collabd.supervise_alive() 同一陈旧阈值
|
||||
Set-Location $root
|
||||
|
||||
function Say([string]$m) {
|
||||
$ts = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
|
||||
Add-Content -LiteralPath $logPath -Value ("[" + $ts + "] " + $m) -Encoding UTF8
|
||||
}
|
||||
|
||||
function Get-HbAge {
|
||||
try {
|
||||
if (-not (Test-Path -LiteralPath $hbPath)) { return -1 }
|
||||
$raw = Get-Content -LiteralPath $hbPath -Raw -Encoding UTF8
|
||||
if (-not $raw) { return -1 }
|
||||
$ts = [double](($raw | ConvertFrom-Json).ts)
|
||||
if ($ts -le 0) { return -1 }
|
||||
return [int]((Get-Date).ToString("U") - $ts)
|
||||
} catch { return -1 }
|
||||
}
|
||||
|
||||
function Wait-HeartbeatFresh([int]$maxWait) {
|
||||
$waited = 0
|
||||
while ($waited -lt $maxWait) {
|
||||
$age = Get-HbAge
|
||||
if ($age -ge 0 -and $age -lt $staleSec) {
|
||||
Say ("another supervisor is alive (heartbeat " + $age + "s old) => standing down")
|
||||
return $true
|
||||
}
|
||||
Start-Sleep -Seconds 5
|
||||
$waited += 5
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
Say ("keeper up. keeper_pid=" + $PID + " script=" + $script)
|
||||
|
||||
$backoff = 5
|
||||
while ($true) {
|
||||
# ① 循环开头:目标已完成 ⇒ 收工,不再重拉
|
||||
if (Test-Path -LiteralPath $stopFlag) {
|
||||
Say "guard.stop present => target finished; keeper stands down (no more respawn)"
|
||||
exit 0
|
||||
}
|
||||
$ageBefore = Get-HbAge
|
||||
if ($ageBefore -ge 0 -and $ageBefore -lt $staleSec) {
|
||||
if (Wait-HeartbeatFresh 300) { continue }
|
||||
}
|
||||
|
||||
Say ("spawn collabd --supervise (backoff=" + $backoff + "s)")
|
||||
$outLog = "__OUTLOG__"
|
||||
$errLog = "__ERRLOG__"
|
||||
try {
|
||||
# -Wait 给的是**真阻塞**(`&` 给不了 GUI 子系统程序);-Redirect* 让证据落盘
|
||||
$proc = Start-Process -FilePath $pyw `
|
||||
-ArgumentList @("-u", $script, "--supervise") `
|
||||
-WorkingDirectory $root `
|
||||
-WindowStyle Hidden `
|
||||
-RedirectStandardOutput $outLog `
|
||||
-RedirectStandardError $errLog `
|
||||
-PassThru -Wait
|
||||
$code = $proc.ExitCode
|
||||
} catch {
|
||||
Say ("spawn threw: " + $_.Exception.Message + " => retry in " + $backoff + "s")
|
||||
Start-Sleep -Seconds $backoff
|
||||
if ($backoff -lt 60) { $backoff = [Math]::Min(60, $backoff * 2) }
|
||||
continue
|
||||
}
|
||||
|
||||
$ageAfter = Get-HbAge
|
||||
if ($ageAfter -ge 0 -and $ageAfter -lt $staleSec) {
|
||||
$verdict = "heartbeat still fresh (" + $ageAfter + "s) => idle exit, no respawn yet"
|
||||
} elseif ($ageAfter -ge 0) {
|
||||
$verdict = "heartbeat stale (" + $ageAfter + "s) => supervisor really died"
|
||||
} else {
|
||||
$verdict = "heartbeat unreadable"
|
||||
}
|
||||
Say ("collabd exited (exit=" + $code + ", " + $verdict + ")")
|
||||
Set-Content -LiteralPath $stampPath -Value ((Get-Date).ToString("yyyy-MM-dd HH:mm:ss")) -Encoding UTF8
|
||||
|
||||
# ② 退避**期间**标志可能出现 ⇒ 别再睡满一轮(⛔ 漏这里 ⇒ 收工后还会多拉一次)
|
||||
$waitLeft = $backoff
|
||||
while ($waitLeft -gt 0) {
|
||||
if (Test-Path -LiteralPath $stopFlag) {
|
||||
Say "guard.stop appeared during backoff => keeper stands down early"
|
||||
exit 0
|
||||
}
|
||||
Start-Sleep -Seconds 5
|
||||
$waitLeft -= 5
|
||||
}
|
||||
if ($backoff -lt 60) { $backoff = [Math]::Min(60, $backoff * 2) }
|
||||
}
|
||||
@@ -12,7 +12,14 @@
|
||||
- **首屏**:开头 3 行内先给判定(✅/⚠️/❌ + 一句),细节放后面。
|
||||
- **三禁**(⛔ 任一命中 = 该条回复**作废、重写后再发**):**表格** / **长散文** / **碎标签堆叠**。
|
||||
- **并列内容竖排**:多个候选、多项并列各占一段、逐条编号;⛔ 不横排、⛔ 不挤进一段、⛔ 不塞成表格的列。
|
||||
- **待拍板项**:放回复**最后一节**,逐条编号;每条写清「问题 + 说明(影响谁/断多久/花多少钱/有无不可逆)+ 各候选的优点与缺点 + 倾向」。
|
||||
- **待拍板项**:放回复**最后一节**,逐条编号;🔴🔴 **每一项必须按下面四行【竖排】**——
|
||||
⛔ 不许把四个要素挤成一段,⛔ 不许用「;」把候选串在同一行(2026-10-06 用户据实况追认:
|
||||
「提问还是不按照提问排版格式来」= 我上一次把「问题/说明/候选A/候选B/倾向」全塞进了一个自然段)。
|
||||
形如:
|
||||
`1、` **问题**:一句话说清要决定什么(⛔ 不用「这个/它/上述」这类指代)。
|
||||
` ` **说明**:为什么要你定(影响谁/断多久/花多少钱/有无不可逆)。
|
||||
` ` **候选 A**:优点…/缺点… —— **B、C 各占独立一行**,⛔ 不横排、⛔ 不挤进同一段。
|
||||
` ` **倾向**:我选哪个 + 一句理由。
|
||||
- 🔴🔴 **「变相征询」同样禁止**(2026-10-06 用户据实况追认):凡是**要用户拿主意**的事 ——
|
||||
包括「**先只报不动**」「**等你发话**」「我倾向 X,你看呢」这类**不带选项的待定清单** ——
|
||||
**一律按上一条写成「待拍板项」**(问题 + 说明 + **各候选的优点与缺点** + 倾向)。
|
||||
|
||||
Reference in new issue
Block a user