fix: support Noctalia lock lifecycle - #9
Conversation
Review correction — PR is not ready to mergeA later independent final review found two real blockers that the earlier PR description overstated as cleared:
I am keeping this PR open and will repair both with regression coverage, rerun the complete verification, amend/push the final head, and update the hardware/issue evidence accurately. Do not merge the current head. |
阻断更新:IPC marker 所有权验证不足,PR 仍不可合入最新独立只读终审发现,当前本地候选的 Noctalia IPC 进程组回收方案不能安全合入;请勿合并 PR #9 当前远端 head 问题为回收 Noctalia IPC 后代,本地候选曾引入 若 arm 进程异常终止(例如 当前处理状态
后续修复要求在恢复实现前,IPC cleanup 必须使用可验证的所有权记录:至少原子保存 session leader PID、 还需要增加回归:构造指向无关、存活独立进程组的 stale marker;运行 在该设计和完整回归被重新完成、独立复审放行、并获得新的真机验收前,PR #9 应继续视为 not ready to merge。 隐私边界:未上传或提交真实用户配置、事件 TSV、抓拍、诊断或凭据。ShellCheck 仍未安装,不能作为已通过的检查。 |
YangYuS8
left a comment
There was a problem hiding this comment.
验收结论:PR #9 当前不可合并,已转为 Draft。
远端 head d25c265 本身已有两个确定阻断:
noctalia_locked()只区分“匹配 true”和“其他”。Noctalia 命令成功但返回无法解析的内容时,函数返回 1;锁定已获取后的循环会把这个 1 当作locked=false,错误记录DISARMED reason=unlock。必须严格区分true、false和 unavailable/unparseable,后者一律 fail closed。- arm PID 与 start-time 分两个文件写入,存在初始化竞态。
vigilia-disarm可能在两个写入之间删除状态并记录手动撤防,随后原 arm 继续写入并启动监控。
后来发现的 ipc.*.pgid 重用误杀问题存在于未推送实验方案,不在当前远端 diff 中;但该方案不应继续推进。这里没有必要维护、扫描并 TERM/KILL Noctalia IPC 进程组。
建议采用更小、更安全的设计:
- 使用临时文件 +
mv原子发布一份 arm 生命周期记录,至少包含 token、PID、start-time; vigilia-disarm只停止vigilia.target并写入与当前 token 对应的取消标记,不向 arm 或 IPC 进程组发送 TERM/KILL;vigilia-arm在每次轮询、锁获取后和解锁返回前检查取消标记;已手动撤防时直接退出,不再记录 unlock-disarm;- command 后端手动撤防时可以保持锁屏命令运行,待用户正常解锁后退出,但不得重新启动监控或生成第二条 DISARMED;
- 严格增加 malformed-success status、原子发布竞态、stale marker 指向无关进程、手动撤防后解锁等回归。
修复后请更新 PR 描述,重新运行完整回归和真实 Noctalia lock/unlock 验收,再标记 Ready for review。此前真机正常路径不能替代新实现的最终验收。
|
Luna,请继续修复 PR #9,但保持 Draft。 要求:不要使用 PGID/进程组 TERM/KILL 回收方案;改为原子生命周期记录 + 手动撤防取消标记,由 补齐竞态与 stale marker 回归后,重新跑完整验证和真实 Noctalia 锁屏测试;确认无误再推送并标记 Ready for review。 |
问题与复现
Niri 的实际锁屏路径是 Noctalia v5:
noctalia msg session lock只是 IPC 请求,会在会话真正锁定或解锁前返回。旧实现把阻塞式swaylock命令的退出当作解锁;若直接替换为 Noctalia IPC 命令,将会在锁定期间过早撤防并伪造DISARMED。另有两项从回归审查中发现的边界:
vigilia-disarm后,后台vigilia-arm可能在后续解锁时再次记录为 unlock-disarm。Closes #8
Refs #2
实现
noctalia;仅有既有LOCK_COMMAND的安装保留command兼容路径。msg status已观察到locked=true、随后观察到locked=false后记录DISARMED reason=unlock backend=noctalia。IPC 请求、超时、状态不可用和请求失败统一记录LOCK_FAILED,不会伪称解锁。vigilia-disarm通过 PID 加/proc/<pid>/statstart-time 双校验终止同一 arm 生命周期,防止 PID 重用误杀,也避免手动撤防后产生第二条 unlock-disarm。awk、loginctl及按实际/默认后端需要的 Noctalia;既有单独LOCK_COMMAND配置仍无需 Noctalia。scripts/verify.sh;更新示例配置、README、架构、硬件测试说明和项目规则。验证
本地(Arch/CachyOS,Noctalia v5.0.0,Motion 4.7.1):
ShellCheck未安装,因此项目脚本按既有行为报告 skipped;没有把它伪装成通过。受控真机 Noctalia 验收(无旁人摄像头画面):
最终验收后:
vigilia.target、motion/power/inhibit 均为 inactive;Noctalialocked=false;/dev/video0无持有进程;未发现 Motion control/stream listener。Motion journal 记录了 V4L2 打开、解锁后的 SIGTERM 和/dev/video0cleanup。操作者还确认锁定期间 LED 亮起、解锁后熄灭。运行了
./scripts/collect-diagnostics.sh artifacts/vigilia-diagnostics-noctalia-final.txt;报告为 0600,但含 32 个 home path 和 19 条 capture metadata,已本地审阅、未上传。未发现 Authorization/ntfy topic/token/Bearer 标记。隐私与安全
LOCK_FAILED,不将其伪造为解锁。风险、回滚与限制
msg status目前以无新增依赖的严格键/布尔值正则读取;Noctalia 若未来改变 IPC JSON 契约,需要重新验证。