清理: 根目录散乱文件归位
- 删根 9 个构建/换装日志(*.log 本已 gitignore,属磁盘残留)+ 根 todo.md(陈旧副本,真板为 docs/todo.md)+ .dockerignore(无 Dockerfile) - 根 swap-install.ps1(v3 加固版)迁 scripts/,替换其中陈旧 43 行版(句柄探测/SHA256 校验/重试/自清理) - dev-tools.bat / dev-server.bat 迁 scripts/ - Batch.md / PROGRESS.md 迁 docs/07-项目管理/,同步修正 5 处指向根的文档链接 - .gitignore 补 /swap-install.lock(v3 运行期锁)
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
# docker build 排除(docker context = repo 根,仅 df-relay 编译需 workspace 源码)
|
||||
target
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
.git
|
||||
*.db
|
||||
*.log
|
||||
apps/df-miniapp/node_modules
|
||||
apps/df-miniapp/dist
|
||||
src-tauri/target
|
||||
@@ -3,6 +3,9 @@ logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# 换装脚本(scripts/swap-install.ps1)运行期锁文件
|
||||
/swap-install.lock
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
|
||||
@@ -63,5 +63,5 @@ Phase 1 目标:**引擎骨架**,打通 `df-core → df-workflow → df-stora
|
||||
## 参考文档
|
||||
|
||||
- [ARCHITECTURE.md](../../ARCHITECTURE.md) — 完整架构设计
|
||||
- [PROGRESS.md](../../PROGRESS.md) — 工作进展与交接
|
||||
- [PROGRESS.md](./PROGRESS.md) — 工作进展与交接
|
||||
- [Phase1 架构决策](../02-架构设计/滚动规范/Phase1架构决策-2026-06-12.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# DevFlow 批次可视化总览
|
||||
|
||||
> 基于 [Batch.md](../Batch.md) 生成 | 更新: 2026-07-01
|
||||
> 基于 [Batch.md](./07-项目管理/Batch.md) 生成 | 更新: 2026-07-01
|
||||
|
||||
---
|
||||
|
||||
|
||||
+2
-2
@@ -138,7 +138,7 @@ docs/
|
||||
| 🚀 快速开始 | [README.md](./README.md) | 安装、启动、快速上手 |
|
||||
| 📖 使用手册 | [使用手册-2026-06-12.md](./08-用户指南/使用手册-2026-06-12.md) | 用户手册 |
|
||||
| 🔧 AI 工具手册 | [AI文件操作工具手册.md](./08-用户指南/AI文件操作工具手册.md) | 10 个文件操作工具 API 参考 |
|
||||
| 📋 项目进度 | [PROGRESS.md](../PROGRESS.md) | 实时项目进展与状态 |
|
||||
| 📋 项目进度 | [PROGRESS.md](./07-项目管理/PROGRESS.md) | 实时项目进展与状态 |
|
||||
| 📝 工作看板 | [todo.md](./todo.md) | 任务/bug 路踪(P0~P3 + aichat 交互专区) |
|
||||
| 🔍 审查队列 | [待审查.md](./待审查.md) | 代码审查登记+回填(67 条已审) |
|
||||
| ⚖️ 决策项 | [待决策.md](./待决策.md) | 需人工决策的产品/设计/排期 |
|
||||
@@ -174,7 +174,7 @@ docs/
|
||||
| 文档 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| 架构设计 | `../ARCHITECTURE.md` | 完整架构文档 |
|
||||
| 项目进展 | `../PROGRESS.md` | 工作进展与交接 |
|
||||
| 项目进展 | `./07-项目管理/PROGRESS.md` | 工作进展与交接 |
|
||||
| 工作看板 | `./todo.md` | 任务/bug 跟踪(含决策记录) |
|
||||
| Crate 结构 | `../ARCHITECTURE.md#四crate-结构` | 8 个 Crate 概览 |
|
||||
| 数据模型 | `../ARCHITECTURE.md#六数据模型` | SQLite 表结构定义 |
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
- [DevFlow 使用手册](./08-用户指南/使用手册-2026-06-12.md) - 完整的使用指南,包含功能介绍、操作流程和最佳实践
|
||||
|
||||
### 📋 项目进度
|
||||
- [PROGRESS.md](../PROGRESS.md) - 项目开发进展与交接记录
|
||||
- [PROGRESS.md](./07-项目管理/PROGRESS.md) - 项目开发进展与交接记录
|
||||
|
||||
## 🎯 核心理念
|
||||
|
||||
|
||||
+180
-34
@@ -1,43 +1,189 @@
|
||||
# DevFlow 换装脚本:kill 旧进程 -> 静默安装 -> 启动验证
|
||||
# 独立后台执行,避免中断当前会话导致换装半途而废
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$log = 'E:/wk-lab/devflow/swap.log'
|
||||
function Log($m) { "$(Get-Date -Format 'HH:mm:ss') $m" | Tee-Object -FilePath $log -Append }
|
||||
# DevFlow 自宿主换装脚本 v3
|
||||
# 流程: 等旧进程退出并探测句柄释放, 静默安装, 按构建产物哈希校验且失败重试一次, 交互用户可见重启, 结束自清理
|
||||
$ErrorActionPreference = 'Stop'
|
||||
# 安装包路径:按构建产物 glob 探测(不硬编码版本号,版本升级时脚本零改动)。
|
||||
# C3 决议:脚本消费构建产物,版本号唯一源头是 Cargo.toml → tauri.conf.json 注入文件名。
|
||||
$nsisDir = 'E:\wk-lab\devflow\target\release\bundle\nsis'
|
||||
$installer = $null
|
||||
if (Test-Path $nsisDir) {
|
||||
$installer = Get-ChildItem -Path $nsisDir -Filter 'devflow_*_x64-setup.exe' -ErrorAction SilentlyContinue |
|
||||
Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName
|
||||
}
|
||||
if (-not $installer) {
|
||||
# 兜底:目录缺失或无匹配产物时,保留旧硬编码路径以维持既有失败提示语义
|
||||
$installer = 'E:\wk-lab\devflow\target\release\bundle\nsis\devflow_0.1.1_x64-setup.exe'
|
||||
}
|
||||
$target = 'C:\Users\23780\AppData\Local\devflow\devflow.exe'
|
||||
$builtExe = 'E:\wk-lab\devflow\target\release\devflow.exe'
|
||||
$log = 'E:\wk-lab\devflow\swap-install.log'
|
||||
$lockFile = 'E:\wk-lab\devflow\swap-install.lock'
|
||||
|
||||
Log "=== 换装开始 ==="
|
||||
# 构建产物哈希是唯一强基准; 产物缺失时退化为与安装前快照比对的弱校验
|
||||
$hashWant = $null
|
||||
if (Test-Path $builtExe) { $hashWant = (Get-FileHash $builtExe -Algorithm SHA256).Hash }
|
||||
|
||||
# 1. kill 旧进程
|
||||
$procs = Get-Process devflow -ErrorAction SilentlyContinue
|
||||
if ($procs) {
|
||||
Log "发现运行中 devflow 进程: $($procs.Id -join ','),正在结束..."
|
||||
$procs | Stop-Process -Force -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
$still = Get-Process devflow -ErrorAction SilentlyContinue
|
||||
if ($still) { Log "警告: 仍有残留进程 $($still.Id -join ',')"; $still | Stop-Process -Force -ErrorAction SilentlyContinue; Start-Sleep -Seconds 2 }
|
||||
Log "旧进程已结束"
|
||||
# 0. SYSTEM 上下文转投用户会话
|
||||
$who = whoami
|
||||
if ($who -like '*SYSTEM*') {
|
||||
$loggedUser = (Get-CimInstance Win32_ComputerSystem).UserName
|
||||
if ($loggedUser) {
|
||||
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$PSCommandPath`""
|
||||
$principal = New-ScheduledTaskPrincipal -UserId $loggedUser -LogonType Interactive
|
||||
Register-ScheduledTask -TaskName 'DevFlowSwapUser' -Action $action -Principal $principal -Force | Out-Null
|
||||
Start-ScheduledTask -TaskName 'DevFlowSwapUser'
|
||||
# 锁由重入脚本创建删除, 是其存活的可靠信号; 按 task State 等有 Ready 竞态且超时会腰斩换装
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while (-not (Test-Path $lockFile) -and (Get-Date) -lt $deadline) { Start-Sleep -Seconds 1 }
|
||||
$deadline = (Get-Date).AddSeconds(300)
|
||||
while ((Test-Path $lockFile) -and (Get-Date) -lt $deadline) { Start-Sleep -Seconds 2 }
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapUser' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
Log "无运行中 devflow 进程"
|
||||
"[FAIL] SYSTEM context and no logged-on user found" | Out-File $log -Encoding utf8
|
||||
}
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapInstall' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 2. 静默安装新包
|
||||
$setup = 'E:/wk-lab/devflow/target/release/bundle/nsis/devflow_0.1.1_x64-setup.exe'
|
||||
if (-not (Test-Path $setup)) { Log "错误: 安装包不存在 $setup"; exit 1 }
|
||||
Log "静默安装: $setup"
|
||||
$p = Start-Process -FilePath $setup -ArgumentList '/S' -PassThru -Wait
|
||||
Log "安装器退出码: $($p.ExitCode)"
|
||||
Start-Sleep -Seconds 3
|
||||
if (Test-Path $lockFile) {
|
||||
$lockAge = (Get-Date) - (Get-Item $lockFile).LastWriteTime
|
||||
if ($lockAge.TotalMinutes -lt 5) { exit 0 }
|
||||
}
|
||||
New-Item $lockFile -Force | Out-Null
|
||||
|
||||
# 3. 启动验证
|
||||
$installed = 'C:\Users\23780\AppData\Local\devflow\devflow.exe'
|
||||
if (Test-Path $installed) {
|
||||
$ver = (Get-Item $installed).VersionInfo.FileVersion
|
||||
Log "已安装二进制: $installed (FileVersion=$ver)"
|
||||
Start-Process -FilePath $installed
|
||||
# 独占打开目标 exe 成功即旧句柄已释放; Windows 文件锁延迟释放会让 NSIS 静默伪成功
|
||||
function Wait-HandleReleased {
|
||||
if (-not (Test-Path $target)) { return $true }
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
try {
|
||||
$fs = [IO.File]::Open($target, 'Open', 'ReadWrite', 'None')
|
||||
$fs.Close()
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] handle released" | Add-Content $log
|
||||
return $true
|
||||
} catch {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] handle wait timeout, continue" | Add-Content $log
|
||||
return $false
|
||||
}
|
||||
|
||||
# 静默安装并校验新 exe, 返回安装后哈希($null=失败)
|
||||
# 基准说明: NSIS 打包器会重写主 exe 资源, 包内哈希原理上不等于磁盘构建产物,
|
||||
# 故哈希比对只作参考, 本质判据=安装器确定性输出(两次装出同一哈希且实变)
|
||||
function Invoke-SwapInstall {
|
||||
param([string]$Attempt)
|
||||
$p = Start-Process $installer -ArgumentList '/S' -Wait -PassThru
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] installer exit=$($p.ExitCode) (attempt $Attempt)" | Add-Content $log
|
||||
if ($p.ExitCode -ne 0) { return $null }
|
||||
if (-not (Test-Path $target)) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: target missing after install" | Add-Content $log
|
||||
return $null
|
||||
}
|
||||
$afterHash = (Get-FileHash $target -Algorithm SHA256).Hash
|
||||
$afterSize = (Get-Item $target).Length
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] installed size=$afterSize hash=$($afterHash.Substring(0, 12))" | Add-Content $log
|
||||
return $afterHash
|
||||
}
|
||||
|
||||
try {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] swap start (user=$(whoami))" | Out-File $log -Encoding utf8
|
||||
if ($hashWant) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify baseline: built exe hash=$($hashWant.Substring(0, 12))" | Add-Content $log
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify baseline: weak check (built exe absent)" | Add-Content $log
|
||||
}
|
||||
|
||||
# 1. 等旧进程退出(最多 30s), 超时强杀
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
if (-not (Get-Process devflow -ErrorAction SilentlyContinue)) { break }
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
Get-Process devflow -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
Start-Sleep -Seconds 2
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] old process stopped" | Add-Content $log
|
||||
|
||||
# 2. 探测句柄释放
|
||||
Wait-HandleReleased | Out-Null
|
||||
|
||||
# 3. 安装前快照, 供弱校验与前后比对
|
||||
$before = @{ hash = 'absent'; size = 0 }
|
||||
if (Test-Path $target) {
|
||||
$before.hash = (Get-FileHash $target -Algorithm SHA256).Hash
|
||||
$before.size = (Get-Item $target).Length
|
||||
}
|
||||
$beforeHashShort = $before.hash
|
||||
if ($beforeHashShort.Length -gt 12) { $beforeHashShort = $beforeHashShort.Substring(0, 12) }
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] before size=$($before.size) hash=$beforeHashShort" | Add-Content $log
|
||||
|
||||
# 4. 静默安装 + 校验, 判据三级: 等磁盘快照强过; 两次装出同一哈希且实变为安装器确定性输出; 其余 FAIL
|
||||
$firstHash = Invoke-SwapInstall 'first'
|
||||
$pass = $false
|
||||
if ($firstHash) {
|
||||
if ($hashWant -and $firstHash -eq $hashWant) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (match disk build)" | Add-Content $log
|
||||
$pass = $true
|
||||
} elseif (-not $hashWant -and $firstHash -ne $before.hash) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (weak check, changed from before)" | Add-Content $log
|
||||
$pass = $true
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify mismatch disk baseline, retry once" | Add-Content $log
|
||||
Wait-HandleReleased | Out-Null
|
||||
$retryHash = Invoke-SwapInstall 'retry'
|
||||
if ($retryHash -and $firstHash -eq $retryHash) {
|
||||
if ($retryHash -ne $before.hash) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (installer deterministic output $($retryHash.Substring(0, 12)))" | Add-Content $log
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (already up to date, same version reinstalled)" | Add-Content $log
|
||||
}
|
||||
$pass = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-not $pass) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: verify failed twice" | Add-Content $log
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 5. 重启并验证; GUI 必须起在交互用户会话才可见
|
||||
Start-Process $target
|
||||
Start-Sleep -Seconds 5
|
||||
$new = Get-Process devflow -ErrorAction SilentlyContinue
|
||||
if ($new) { Log "启动成功, PID=$($new.Id -join ',')" } else { Log "警告: 启动后未检测到进程" }
|
||||
} else {
|
||||
Log "警告: 未找到安装后二进制 $installed"
|
||||
$proc = Get-Process devflow -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($proc) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] OK: restarted pid=$($proc.Id)" | Add-Content $log
|
||||
exit 0
|
||||
}
|
||||
|
||||
Log "=== 换装结束 ==="
|
||||
# SYSTEM 会话直启的 GUI 不可见, 转投交互登录用户名下的一次性计划任务
|
||||
$explorer = Get-CimInstance Win32_Process -Filter "Name='explorer.exe'" | Select-Object -First 1
|
||||
if ($explorer) {
|
||||
$o = Invoke-CimMethod -InputObject $explorer -MethodName GetOwner
|
||||
$user = "$($o.Domain)\$($o.User)"
|
||||
try {
|
||||
$action = New-ScheduledTaskAction -Execute $target
|
||||
$principal = New-ScheduledTaskPrincipal -UserId $user -LogonType Interactive
|
||||
Register-ScheduledTask -TaskName 'DevFlowStartOnce' -Action $action -Principal $principal -Force -ErrorAction Stop | Out-Null
|
||||
Start-ScheduledTask -TaskName 'DevFlowStartOnce'
|
||||
Start-Sleep -Seconds 5
|
||||
} catch {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] start task error: $($_.Exception.Message)" | Add-Content $log
|
||||
} finally {
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowStartOnce' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
$proc = Get-Process devflow -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($proc) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] OK: restarted as $user pid=$($proc.Id)" | Add-Content $log
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
# 仍无进程, 落标记等人工拉起
|
||||
Set-Content -Path 'E:\wk-lab\devflow\swap-need-start.flag' -Value (Get-Date -Format o)
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: need manual start" | Add-Content $log
|
||||
exit 1
|
||||
}
|
||||
finally {
|
||||
Remove-Item $lockFile -ErrorAction SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapInstall' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
# DevFlow 自宿主换装脚本 v3
|
||||
# 流程: 等旧进程退出并探测句柄释放, 静默安装, 按构建产物哈希校验且失败重试一次, 交互用户可见重启, 结束自清理
|
||||
$ErrorActionPreference = 'Stop'
|
||||
# 安装包路径:按构建产物 glob 探测(不硬编码版本号,版本升级时脚本零改动)。
|
||||
# C3 决议:脚本消费构建产物,版本号唯一源头是 Cargo.toml → tauri.conf.json 注入文件名。
|
||||
$nsisDir = 'E:\wk-lab\devflow\target\release\bundle\nsis'
|
||||
$installer = $null
|
||||
if (Test-Path $nsisDir) {
|
||||
$installer = Get-ChildItem -Path $nsisDir -Filter 'devflow_*_x64-setup.exe' -ErrorAction SilentlyContinue |
|
||||
Sort-Object LastWriteTime -Descending | Select-Object -First 1 -ExpandProperty FullName
|
||||
}
|
||||
if (-not $installer) {
|
||||
# 兜底:目录缺失或无匹配产物时,保留旧硬编码路径以维持既有失败提示语义
|
||||
$installer = 'E:\wk-lab\devflow\target\release\bundle\nsis\devflow_0.1.1_x64-setup.exe'
|
||||
}
|
||||
$target = 'C:\Users\23780\AppData\Local\devflow\devflow.exe'
|
||||
$builtExe = 'E:\wk-lab\devflow\target\release\devflow.exe'
|
||||
$log = 'E:\wk-lab\devflow\swap-install.log'
|
||||
$lockFile = 'E:\wk-lab\devflow\swap-install.lock'
|
||||
|
||||
# 构建产物哈希是唯一强基准; 产物缺失时退化为与安装前快照比对的弱校验
|
||||
$hashWant = $null
|
||||
if (Test-Path $builtExe) { $hashWant = (Get-FileHash $builtExe -Algorithm SHA256).Hash }
|
||||
|
||||
# 0. SYSTEM 上下文转投用户会话
|
||||
$who = whoami
|
||||
if ($who -like '*SYSTEM*') {
|
||||
$loggedUser = (Get-CimInstance Win32_ComputerSystem).UserName
|
||||
if ($loggedUser) {
|
||||
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$PSCommandPath`""
|
||||
$principal = New-ScheduledTaskPrincipal -UserId $loggedUser -LogonType Interactive
|
||||
Register-ScheduledTask -TaskName 'DevFlowSwapUser' -Action $action -Principal $principal -Force | Out-Null
|
||||
Start-ScheduledTask -TaskName 'DevFlowSwapUser'
|
||||
# 锁由重入脚本创建删除, 是其存活的可靠信号; 按 task State 等有 Ready 竞态且超时会腰斩换装
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while (-not (Test-Path $lockFile) -and (Get-Date) -lt $deadline) { Start-Sleep -Seconds 1 }
|
||||
$deadline = (Get-Date).AddSeconds(300)
|
||||
while ((Test-Path $lockFile) -and (Get-Date) -lt $deadline) { Start-Sleep -Seconds 2 }
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapUser' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
"[FAIL] SYSTEM context and no logged-on user found" | Out-File $log -Encoding utf8
|
||||
}
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapInstall' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
exit 0
|
||||
}
|
||||
|
||||
if (Test-Path $lockFile) {
|
||||
$lockAge = (Get-Date) - (Get-Item $lockFile).LastWriteTime
|
||||
if ($lockAge.TotalMinutes -lt 5) { exit 0 }
|
||||
}
|
||||
New-Item $lockFile -Force | Out-Null
|
||||
|
||||
# 独占打开目标 exe 成功即旧句柄已释放; Windows 文件锁延迟释放会让 NSIS 静默伪成功
|
||||
function Wait-HandleReleased {
|
||||
if (-not (Test-Path $target)) { return $true }
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
try {
|
||||
$fs = [IO.File]::Open($target, 'Open', 'ReadWrite', 'None')
|
||||
$fs.Close()
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] handle released" | Add-Content $log
|
||||
return $true
|
||||
} catch {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
}
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] handle wait timeout, continue" | Add-Content $log
|
||||
return $false
|
||||
}
|
||||
|
||||
# 静默安装并校验新 exe, 返回安装后哈希($null=失败)
|
||||
# 基准说明: NSIS 打包器会重写主 exe 资源, 包内哈希原理上不等于磁盘构建产物,
|
||||
# 故哈希比对只作参考, 本质判据=安装器确定性输出(两次装出同一哈希且实变)
|
||||
function Invoke-SwapInstall {
|
||||
param([string]$Attempt)
|
||||
$p = Start-Process $installer -ArgumentList '/S' -Wait -PassThru
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] installer exit=$($p.ExitCode) (attempt $Attempt)" | Add-Content $log
|
||||
if ($p.ExitCode -ne 0) { return $null }
|
||||
if (-not (Test-Path $target)) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: target missing after install" | Add-Content $log
|
||||
return $null
|
||||
}
|
||||
$afterHash = (Get-FileHash $target -Algorithm SHA256).Hash
|
||||
$afterSize = (Get-Item $target).Length
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] installed size=$afterSize hash=$($afterHash.Substring(0, 12))" | Add-Content $log
|
||||
return $afterHash
|
||||
}
|
||||
|
||||
try {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] swap start (user=$(whoami))" | Out-File $log -Encoding utf8
|
||||
if ($hashWant) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify baseline: built exe hash=$($hashWant.Substring(0, 12))" | Add-Content $log
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify baseline: weak check (built exe absent)" | Add-Content $log
|
||||
}
|
||||
|
||||
# 1. 等旧进程退出(最多 30s), 超时强杀
|
||||
$deadline = (Get-Date).AddSeconds(30)
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
if (-not (Get-Process devflow -ErrorAction SilentlyContinue)) { break }
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
Get-Process devflow -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
Start-Sleep -Seconds 2
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] old process stopped" | Add-Content $log
|
||||
|
||||
# 2. 探测句柄释放
|
||||
Wait-HandleReleased | Out-Null
|
||||
|
||||
# 3. 安装前快照, 供弱校验与前后比对
|
||||
$before = @{ hash = 'absent'; size = 0 }
|
||||
if (Test-Path $target) {
|
||||
$before.hash = (Get-FileHash $target -Algorithm SHA256).Hash
|
||||
$before.size = (Get-Item $target).Length
|
||||
}
|
||||
$beforeHashShort = $before.hash
|
||||
if ($beforeHashShort.Length -gt 12) { $beforeHashShort = $beforeHashShort.Substring(0, 12) }
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] before size=$($before.size) hash=$beforeHashShort" | Add-Content $log
|
||||
|
||||
# 4. 静默安装 + 校验, 判据三级: 等磁盘快照强过; 两次装出同一哈希且实变为安装器确定性输出; 其余 FAIL
|
||||
$firstHash = Invoke-SwapInstall 'first'
|
||||
$pass = $false
|
||||
if ($firstHash) {
|
||||
if ($hashWant -and $firstHash -eq $hashWant) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (match disk build)" | Add-Content $log
|
||||
$pass = $true
|
||||
} elseif (-not $hashWant -and $firstHash -ne $before.hash) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (weak check, changed from before)" | Add-Content $log
|
||||
$pass = $true
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify mismatch disk baseline, retry once" | Add-Content $log
|
||||
Wait-HandleReleased | Out-Null
|
||||
$retryHash = Invoke-SwapInstall 'retry'
|
||||
if ($retryHash -and $firstHash -eq $retryHash) {
|
||||
if ($retryHash -ne $before.hash) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (installer deterministic output $($retryHash.Substring(0, 12)))" | Add-Content $log
|
||||
} else {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] verify pass (already up to date, same version reinstalled)" | Add-Content $log
|
||||
}
|
||||
$pass = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-not $pass) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: verify failed twice" | Add-Content $log
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 5. 重启并验证; GUI 必须起在交互用户会话才可见
|
||||
Start-Process $target
|
||||
Start-Sleep -Seconds 5
|
||||
$proc = Get-Process devflow -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($proc) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] OK: restarted pid=$($proc.Id)" | Add-Content $log
|
||||
exit 0
|
||||
}
|
||||
|
||||
# SYSTEM 会话直启的 GUI 不可见, 转投交互登录用户名下的一次性计划任务
|
||||
$explorer = Get-CimInstance Win32_Process -Filter "Name='explorer.exe'" | Select-Object -First 1
|
||||
if ($explorer) {
|
||||
$o = Invoke-CimMethod -InputObject $explorer -MethodName GetOwner
|
||||
$user = "$($o.Domain)\$($o.User)"
|
||||
try {
|
||||
$action = New-ScheduledTaskAction -Execute $target
|
||||
$principal = New-ScheduledTaskPrincipal -UserId $user -LogonType Interactive
|
||||
Register-ScheduledTask -TaskName 'DevFlowStartOnce' -Action $action -Principal $principal -Force -ErrorAction Stop | Out-Null
|
||||
Start-ScheduledTask -TaskName 'DevFlowStartOnce'
|
||||
Start-Sleep -Seconds 5
|
||||
} catch {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] start task error: $($_.Exception.Message)" | Add-Content $log
|
||||
} finally {
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowStartOnce' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
$proc = Get-Process devflow -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($proc) {
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] OK: restarted as $user pid=$($proc.Id)" | Add-Content $log
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
|
||||
# 仍无进程, 落标记等人工拉起
|
||||
Set-Content -Path 'E:\wk-lab\devflow\swap-need-start.flag' -Value (Get-Date -Format o)
|
||||
"[$(Get-Date -Format 'HH:mm:ss')] FAIL: need manual start" | Add-Content $log
|
||||
exit 1
|
||||
}
|
||||
finally {
|
||||
Remove-Item $lockFile -ErrorAction SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName 'DevFlowSwapInstall' -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
# DevFlow 待办
|
||||
|
||||
## 灵感模块功能完善(合并推进)
|
||||
|
||||
> 诊断发现的 P0-P2 问题合并为单次任务,逐项推进。
|
||||
> 排除项:#3 status 无状态机(暂保留状态可跳跃迁移,不处理)。
|
||||
|
||||
### P2 — 前端 / UX
|
||||
|
||||
- [x] **#12 前端 filter 改后端查询** ✅ 团队决策已落地:`hot`/`pending` 保留前端 filter(keyword/order_by 已下沉后端)。
|
||||
|
||||
## AI 对话目标丢失(诊断待办)
|
||||
|
||||
> 诊断报告:`docs/02-架构设计/专项设计/AI对话目标丢失诊断-2026-06-26.md`
|
||||
> 实测会话 `54c8b5bd`:480 万 token,原始目标消息被压缩出局,LLM 尾部盲搜死循环。
|
||||
|
||||
- [x] **G1 目标钉扎** ✅ 代码已落地(`GOAL_PIN_ENABLED=true`),pinned_goals 入口拼入 system_prompt。`PerConvState.pinned_goals: Vec<GoalEntry>`(含 text+status 状态追踪)。
|
||||
- 2026-07-03 改:提取方式从「用户消息规则提取」→「工具调用推理」(infer_goal_from_tool_calls),支持多条/轮 + 自动 active→completed 状态流转。
|
||||
- [x] **G2 探索熔断** ✅ 代码已落地(`STALL_BREAKER_ENABLED=true`,`STALL_BREAKER_THRESHOLD=3`),stall_count + is_empty_tool_result 完整实现。
|
||||
- [x] **G4 话题标记修正** ✅ 代码已落地(`TOPIC_MARKER_GOAL_AWARE=true`),pinned_goals 非空时 take 后丢弃跳过 insert。
|
||||
|
||||
> 落地开关(均可单点回退):`GOAL_PIN_ENABLED`/`GOAL_INJECT_BANNER`/`GOAL_MAX_CHARS=500`/`MAX_GOALS=5`/`STALL_BREAKER_ENABLED`/`STALL_BREAKER_THRESHOLD=3`/`STALL_BREAKER_WARN_FIRST`/`STALL_BREAKER_GOAL_REMIND`/`TOPIC_MARKER_GOAL_AWARE`。全置 false 等价改动前。
|
||||
> 方案源:设计 workflow `wf_09a0385f-2ee` 综合裁决(system_prompt 字符串注入 > insert_at(0))。
|
||||
|
||||
## 对抗式评估接入(引擎已实现 → IPC + 前端打通)
|
||||
|
||||
> 引擎代码已就绪(`df-ideas/src/adversarial.rs` + `adversarial_helpers.rs`),
|
||||
> 但 IPC 层和前端零引用,用户无法使用。需补接入层。
|
||||
|
||||
### 后端 — IPC 接入
|
||||
|
||||
- [x] **A2 批量评估命令** ⏸️ **暂不做**:单 idea 评估 `evaluate_idea` IPC 已接入(AdversarialEngine),批量评估当前无前端消费方,属过度设计。
|
||||
|
||||
## 最新对话分析-2026-06-28:死锁与审批卡死
|
||||
|
||||
> 分析来源:`devflow-trace.log` + `devflow-dev.db` 最新对话 `d9aef24f`(语音输入应用需求)。
|
||||
> 核心表现:7 次工具连续失败后 L1 断路器熔断,1 条 pending 审批导致全链路死锁。
|
||||
|
||||
### P0 — 审批 pending 死锁
|
||||
|
||||
- [x] **审批超时自动取消** ✅ 已实现(15min 默认,可配置):
|
||||
- 后端 `agentic/approval_timeout.rs::cleanup_expired_approvals` 在 `try_continue_agent_loop` 入口检测超时,超时审批自动取消 + emit AiApprovalResult + audit_finalize 记入审计。
|
||||
- `PendingApproval.created_at` 记录创建时刻(SystemTime,重启恢复的按重启时刻计)。
|
||||
- `AppState.approval_timeout_minutes` + `reload_approval_timeout()` 从 Settings KV `df-approval-timeout` 启动恢复(与前端 AdvancedSection.vue 同 key,值为毫秒)。
|
||||
- IPC `ai_get_approval_timeout` / `ai_set_approval_timeout`(0=禁用,范围 0-1440 分钟)。
|
||||
- 前端已有 Settings UI(0/5/15/30/60 分钟 select),前端定时器负责运行期会话内超时,后端负责重启恢复场景兼底。
|
||||
- [x] **`create_project` 自动创建目录** ✅ 已实现(`project.rs:137`):有 path 且目录不存在时自动 `create_dir_all`,死锁链已消除(非参数控制,直接自动创建)。
|
||||
|
||||
### P1 — Windows 平台兼容
|
||||
|
||||
- [x] **`run_command` 失败追加 shell 适配提示** ✅ 已实现(`tool_registry.rs:2351-2358`):Windows 下 tool result 尾部追加 PowerShell 适配提示(路径引用、`&&`→`;`)。
|
||||
- [x] **PowerShell 反斜杠自动转义** ✅ 已修复(`tool_registry.rs:2306-2328` 注释说明根因):serde_json 已正确还原反斜杠,不做额外转义,PowerShell 正确接受裸反斜杠路径。
|
||||
|
||||
### P2 — 标题 LLM 失败
|
||||
|
||||
- [x] **标题摘要合并连续同 role** ✅ 已实现(`title.rs:79-83`):`merge_consecutive_roles` 发 LLM 前合并相邻 user/assistant,已覆盖 Anthropic/GLM 1214。
|
||||
|
||||
### P3 — 其他
|
||||
|
||||
- [x] **migration V33** ✅ 已实现(`migrations.rs` migrate_v33):`workflow_executions` 加 `updated_at` 列 + `ai_conversations` 加 `pending_approvals`(审批重启恢复)。
|
||||
- [x] **L0-handshake 防抖** ✅ 已实现(`lib.rs:73-82`):3s 内重复 `ai-client-ready` 跳过。
|
||||
|
||||
## AI Chat 体验优化(2026-07-03 批次)
|
||||
|
||||
> 本轮完成的 10 项需求中,8 项已落地,3 项暂缓待后续批次。
|
||||
|
||||
### 已完成
|
||||
|
||||
- [x] **AI Chat 入口图标换** ✅ 灯泡→星花 sparkles + 发光效果(`AppSidebar.vue`)
|
||||
- [x] **LLM 回复文字重叠防御** ✅ delta 重复检测+丢弃(`useAiEvents.ts`)
|
||||
- [x] **全部接管仍审批** ✅ patch_file 全档位自动放行(`approval.rs`) + 诊断日志(`audit/mod.rs`)
|
||||
- [x] **设置导入导出去除** ✅ `SettingsImportExport.vue` 已删,引用清理(`Settings.vue`/`SettingsNav.vue`)
|
||||
- [x] **分离窗口默认置顶** ✅ `alwaysOnTop: true`(`useAiWindow.ts`)
|
||||
- [x] **审批通知浮层** ✅ 全局右上角浮层(`ApprovalOverlay.vue` + `App.vue` 挂载)
|
||||
- [x] **header 菜单聚合 `...`** ✅ 清空/压缩上下文收入 popout(`TopBar.vue`)
|
||||
- [x] **置顶图标换** ✅ 星→大头针 pushpin(`TopBar.vue`)
|
||||
- [x] **全部批准无响应** ✅ 防抖守卫 `_batchProcessing`(`useAiApproval.ts`)
|
||||
- [x] **工具卡执行中卡死** ✅ 乐观更新 `status !== 'completed'` 守卫(`useAiApproval.ts`)
|
||||
- [x] **置顶状态刷新丢失** ✅ 持久化到 appSettings KV(`AiChat.vue`)
|
||||
- [x] **目标提取根本性改造** ✅ 工具调用推理(`infer_goal_from_tool_calls` in `helpers.rs`)
|
||||
- 提取源:用户消息规则 → **工具调用推理**(结构化数据,零污染)
|
||||
- 数据结构:`Vec<String>` → **`Vec<GoalEntry>`**(text+status)
|
||||
- 状态流转:新目标加入 → 之前 active 自动标记 completed
|
||||
- system_prompt 仅注入 active 目标
|
||||
- 前端显示 3/5 计数 + ✓/● 状态标记
|
||||
- 代码拆分到 `helpers.rs`(解决 brace 嵌套致 pub(crate) 不可见)
|
||||
|
||||
### 暂缓待后续批次
|
||||
|
||||
- [ ] **9b 审批交互 UI/UX 重新设计** ⏸️
|
||||
- 当前:审批卡片是 ToolCard 的 pending_approval 态,布局单调、args 展示过长、风险等级不直观
|
||||
- 待做:重新设计卡片布局(缩短 args 预览 + 展开/收起、风险等级着色条、审批耗时提示、批量操作栏视觉增强)
|
||||
- 涉及:`ToolCard.vue`(~360 行) + `ToolCardList.vue` 少量调整
|
||||
- 优先级:中——现有功能可用但体验不够好
|
||||
|
||||
- [ ] **9d 底部工具区(目标/历史/上下文)展开交互优化** ⏸️
|
||||
- 当前:底部 🎯📋📄 三个入口紧凑排列,展开后内容区窄、超出不滚动、缺少动画
|
||||
- 待做:popover 浮层替代内联展开、加入平滑过渡动画、内容超出滚动、点击外部收起
|
||||
- 涉及:`TopBar.vue` 底部区
|
||||
- 优先级:低——功能完整,体验改善不迫切
|
||||
|
||||
- [ ] **`[UPDATE_GOALS]` LLM 主动修正目标列表** ⏸️
|
||||
- 设计已完成,实现暂缓
|
||||
- 格式:`[UPDATE_GOALS]\n1: 目标文本 (active)\n2: 目标文本 (completed)\n[END]`
|
||||
- LLM 输出此标记 → 后端解析并替换 pinned_goals → 标记从正文剥离
|
||||
- 函数签名 `extract_update_goals_block` 已设计未实现
|
||||
- 覆盖场景:意图增强/纠偏/递进(用户补充信息后发现之前目标提取偏了)
|
||||
- 优先级:中——价值高改动小,补全目标维护闭环
|
||||
|
||||
## 上下文精细化管理(对齐 10-04 三层记忆设计)+ 工程可行性(AI-Ops 分析移交)
|
||||
|
||||
> 分析来源:凌晨窗口实测(221 轮/508 条,prompt 均值 71K/峰值 135K,压缩 ~120K 才触发,tool 结果 4.9KB×279 条,cargo 验证同步阻塞占 45%)。
|
||||
> 方向定调(用户 10-05):1M 窗口下调阈值意义不大;主轴 = 按任务相关性精细组织上下文 + 自主管理,外置内容长久可找回并持续蒸馏进知识库。
|
||||
> 对齐结论:本组需求与「上下文三层记忆-设计-2026-10-04」高度同路,实施以该设计为准,不平行立方案。映射:相关性压缩/结构化 → C-m1 记忆卡;压缩时机 → C-m2 信息增益信号;外置找回/蒸馏知识库 → C-m3 提炼链与知识库衔接。
|
||||
|
||||
### 实施序(按 10-04 分期 + 可行性排序)
|
||||
|
||||
- [ ] **C-r0 验证命令后台化与降频**(独立,先行):全仓测试攒批收官一次(凌晨重复跑 2 次),中途只单包 check;长命令异步执行 + 完成回填。验收:>90s 同步等待占比 <15%(现状 45%)。
|
||||
- [ ] **C-m1 记忆卡产出**(10-04 分期一):按设计实施四类卡 + 渲染,压缩产物结构化。
|
||||
- [ ] **C-m2 压缩时机关联**(分期二):信息增益信号触发;AI-Ops 补充输入——相关性判据挂 pinned_goals,水位仅作失控兜底(窗口 80%),prompt_tokens 已逐轮在库可直读。
|
||||
- [ ] **C-r1 压缩可逆:按段重载**(AI-Ops 增量):compressed 原文全在库(status 标记未删),给 agent 按段重载手段,压缩从不可逆变可逆。
|
||||
- [ ] **C-m3 外置找回 + 蒸馏衔接**(分期三,依赖召回闭环):大内容外置区(上下文只留句柄 + 头部摘要,跨会话按任务索引,外置区是资产不是垃圾暂存);蒸馏接现有 knowledge 模块(提取侧 knowledge.rs、注入侧 knowledge_inject.rs 均已在)。
|
||||
|
||||
### 设计风险与工程可行性(R 条款,实施前必读)
|
||||
|
||||
- **R1 相关性判别的成本账**:"LLM 按段自评"若逐段调用,压缩一次 = 几十次 LLM 调用,成本延迟反噬。要求:规则初筛粗分,LLM 只评模糊带;或随摘要生成批量一次判定。验收加一条:压缩动作自身成本 < 被省成本的 10%。
|
||||
- **R2 目标漂移误压**:pinned_goals 中途变更后,按旧目标判"无关"的段对新目标可能关键。压缩判定带目标版本标记;目标变更时对判无关段重估。
|
||||
- **R3 盲区问题(压缩可逆的边界)**:被压内容里可能有关键细节而 agent 不知道存在,重载依赖"想起"。缓解:记忆卡必须带检索锚点(关键字/路径/数字清单),不只是叙述摘要——四类卡若无此字段,实施时补。
|
||||
- **R4 错误知识反哺循环(最危险)**:蒸馏出错条目 → auto_inject 污染后续会话 → 错误自我强化。准入门槛必须先于注入开关:条目带溯源 + 置信标记,被验证/被引用后才升格可注入;先建评测集再开 auto_inject。
|
||||
- **R7 知识库代谢:只进不出必腐化(用户 10-05 拍板)**:现状知识库只加条目、无 update 进化机制。蒸馏入库必须先查存量——相似条目走 update(合并/修正/增强)而非新增,防同主题碎片堆叠;条目短小精准(单条单事实,宁短勿滥)、带时效(过期检测)与使用频率,常用上浮、久未用沉降、被证伪淘汰,形成代谢闭环(参照 u-claw 知识库冷热分层:沉降/激活/消亡/代谢)。知识不在多,在于精、巧、即时。
|
||||
- 精细化设计:`docs/02-架构设计/专项设计/知识库模型重审-精细化设计-2026-10-05.md`(六用例走查+五场景推演+实施序;现状实证:向量 0/1073、verified 2%、置信 87% high——三项地基数据)
|
||||
- **R8 架构统一性:三套体系并行 vs 统一条目模型(可扩张性/优雅性审查)**:现状压缩段(消息 id)、外置件(路径)、知识条目(知识 id)三套标识、三个模块并行,信息在热/温/冷三层流转时身份断裂,溯源靠约定。优雅解 = 统一信息条目模型:唯一 id + 内容 + 溯源 parent 链 + 元数据(相关性/时效/频率/归属),生命周期状态机 hot→warm→cold→dead,流转动作(compress/reload/distill/inject/merge/evict)即状态转移;新策略(相关性/时机/蒸馏)= 转移策略可插拔,新存储后端 = warm 层 trait 实现,四类卡/知识条目 = 同一 schema 的类型扩展。多 agent/云端多人预留:条目元数据现在就留归属字段(与设计 §十 演进预留对齐)。
|
||||
- **R5 外置区边界**:工具输出可能含密钥等敏感信息,外置明文落盘需权限面;清理策略(会话删除级联 vs 长期资产)需显式定,防两读。
|
||||
- **R6 效果度量**:无度量则无法迭代。三指标:重载命中率(重载后解决问题的比例)/ 误压率(重载回来说明压错的)/ 蒸馏采纳率(条目注入后被引用比例)。ai_messages 全程记录,评测基建现成,凌晨窗口数据即首个测试集。
|
||||
|
||||
### 分工口径
|
||||
|
||||
- 10-04 设计(记忆卡结构/压缩时机/分期路线)= 实施主依据;本段增量 = R1-R6 风险条款 + C-r0/C-r1 两个设计外条目 + 水位兜底与相关性判据输入。
|
||||
- 数据复现:ai_messages 按 conversation_id + timestamp 可复现全部实测。口径:AI-Ops 2026-10-05。
|
||||
|
||||
## 提交纪律反馈-1005(AI-Ops 核查)
|
||||
|
||||
> f6eb55b(11:56)审查:内容与敏感面✅,形式三处待改——①一笔混 4 功能(u-claw集成/WebChat/项目归档/审批重设计),下次按功能分组拆笔;②多主题细节下沉 body,不留空 body;③设计文档/问题记录独立「文档:」笔,不混功能提交。
|
||||
|
||||
**根因(2026-10-05 AI-Ops 查证)**:提交纪律从未进入系统提示 — prompt.rs(981 行)工具纪律完备,「提交/commit/攒批」零命中;git 能力随工具下发而纪律未同源下发,违反本项目自己的「纪律随工具同源下发」原则(prompt.rs:213)。长会话中仅存于上下文的约定被稀释,提交质量全凭运气。
|
||||
|
||||
- [ ] **P0(升级版,2026-10-05 拍板)行为规范数据化治理**:devflow 定位 ai-working,行为规范会持续增多,不走「每条硬编码 prompt.rs」。架构=三层(铁律层 prompt.rs 现有工具纪律不动 / 规范层知识库 review_rule 条目(提交规范 5 条落为首批,带 enabled/scope)/ 任务层 pinned_goals 已有)+ prompt.rs 增一个通用规范注入口(读启用的 review_rule 拼入 system_prompt,一处代码永久扩展点)。扩展=加条目零代码;治理复用知识库 R4/R7(置信/代谢);观测=违规事件反哺条目置信(与 UC3 同机制)。验收:提交规范 5 条以 review_rule 数据条目生效;新加一条规范不改代码。
|
||||
|
||||
**首批规范条目扩容(2026-10-05 第二案,拆分提交卡循环触发停滞保护)**:任务策略类 2 条与提交规范同期落库——
|
||||
- *批量分类/分组任务*:先一次性取全貌(如 git show --stat),制定分组映射表再机械执行,禁止逐文件深潜分析(实证:56 文件拆分反复 grep 卡停靠)
|
||||
- *自换策略检查点*:同签名工具调用连续 2 次无新信息即主动停手换策略,不等熔断器(熔断是最后防线非第一反应)
|
||||
- *停滞保护提示增强*:停靠消息自动附疑似病因与建议方向(现状只说"补充新方向",用户无从下手)
|
||||
|
||||
**审查修订(同日三维度红队)**:①review_rule 条目加 constraint 声明,注入时约束段「必须」句式独立成段,与参考记忆物理分开;先核 61 条存量语义纯度 ②注入配额:启用条目 ≤20 条/1.5K token,超出按 scope+置信+频次取 top,条目单条单规则 ③规范声明可执行性两级:可执行化(如提交规范→提交后确定性校验)配自动检查器,原则性走 LLM 低频抽查 ④agent 沉淀规范前一句话确认防误判临时要求;每轮组装读库保即时生效(成本实测);注入日志标记条目命中便于排查;管理 UI 复用知识库界面。
|
||||
|
||||
## 基础设施走查-1005:存储空间治理与进程自检(AI-Ops 分析移交)
|
||||
|
||||
> 实测:DB 168MB,实数据仅 ~69MB(ai_messages content 22MB + tool_executions.result 41MB + 其他 ~7MB),近 100MB 为 SQLite 空闲页/碎片空转;WAL 15.9MB;增速 1-5MB/天。核心查询 14ms 当前无性能压力——问题是空间,不是速度。
|
||||
|
||||
### D1 空间止血(一次性)
|
||||
|
||||
- [ ] **D1 VACUUM 回收**:①备份 DB 并登记台账(铁律)②关 devflow.exe(或空闲时)③`VACUUM` + `PRAGMA wal_checkpoint(TRUNCATE)`。预期 168MB → ~70MB。注意:VACUUM 全表锁,勿在会话进行中做。
|
||||
|
||||
### D2 空间机制(防再膨胀)
|
||||
|
||||
- [ ] **D2a tool_executions.result 过期外置**:超 30 天的执行结果本体移出库落归档文件,库内留路径句柄(与 C5 外置同构,一套机制两处用)。预期消掉 41MB 最大头的增长。
|
||||
- [ ] **D2b 定例化**:月度 VACUUM + 启动时 WAL checkpoint(挂启动流程)。
|
||||
- [ ] **D2c 体积水位监控**:文件/实数据比 >1.5 告警,进 agent-monitor。
|
||||
- [ ] **D2d 归档会话消息过期**(阈值待用户拍板,建议 90 天):archive 会话的消息到期物理清理+VACUUM。
|
||||
|
||||
### D3 其他走查项(按优先级)
|
||||
|
||||
- [ ] **D3a 换装后就绪自检**:换装重启后探测「DB 可写/IPC 通/provider 可达」再宣布就绪(凌晨换装引发消息闪失暂态的根治配套)。
|
||||
- [ ] **D3b timestamp 索引**:ai_messages 加 timestamp 索引(一条迁移,监控/统计类查询从全表扫变索引)。
|
||||
- [ ] **D3c 单连接 Mutex 复核**(08-02 存量 P1):挂机模式引入并发后复核触发条件是否已变,实测锁竞争再定方案。
|
||||
- [ ] **D3d df-nodes HTTP 连接池**(存量 P1):工作流高并发才触发,场景未到,标记缓治。
|
||||
|
||||
> 分工口径:storage/migrations 机制内实施;D1 需用户配合关应用;D2d 阈值待拍板。走查口径:AI-Ops 2026-10-05。
|
||||
> 换库评估结论(用户问询 10-05):**现在不换**——PG 的 autovacuum/并发/网络优势在单机桌面场景用不上,迁移是周级工程;空间痛点 D1-D3 治理用 1/10 成本拿 80% 效果。云端多人(S3)启动时:**服务端用 PG**(多租户),桌面端 SQLite 不动(本地缓存/离线),同步桥连接——换库是分层不是替换。
|
||||
> 量级基准修正(用户 10-05:按全部 u-claw 实例+Claude Code 数据 ×10):实测全生态 ≈2.1GB(本机 ~/.claude 2.0G 大头是会话 jsonl 流水,六容器实例合计 <25MB),×10 ≈ 21GB。21GB 走分层不进主库——流水外置文件(Claude Code 自身即先例:jsonl 存会话不用 DB),主库装结构化条目,GB 级内 SQLite 稳定。结论不变:**现在不换库**;C5 外置分层从"优化项"升为"量级前提"。
|
||||
> **存储架构定稿**:`docs/02-架构设计/专项设计/数据存储架构-定稿-2026-10-05.md`(四维评估收敛:分层+统一条目模型+同步桥+治理度量,四预留字段随 C-m1 一次建齐)
|
||||
> 分布式跨端协同预留(用户 10-05):跨端协同靠同步层不靠换网络库——各端 SQLite 自治(离线优先),同步 = 条目级变更事件流(append-only)复用既有 u-relay/df-tunnel 通道;冲突普通条目 LWW、关键实体走状态机(task_state_machine CAS 先例);外置件用内容哈希做 id(去重/可验证/任意端拉取);云端多人时服务端 PG 作汇聚点。前提依赖 R8 统一条目模型——条目需带 origin(来源端)与修订标记,实施 C-m1 建模时一并落。
|
||||
|
||||
Reference in New Issue
Block a user