@zq-silk/yui 0.16.0 → 0.16.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/dist/cli/updatePorts.js
CHANGED
|
@@ -355,6 +355,7 @@ function stopReplacementControllerForUpdate(home, expectedPid, environment, spaw
|
|
|
355
355
|
function runSchemaIndependentControllerStop(home, environment, spawn, expectedPid) {
|
|
356
356
|
const helper = [
|
|
357
357
|
"const values = process.argv.slice(1);",
|
|
358
|
+
"const handoverOwnerPid = Number(values.pop());",
|
|
358
359
|
"const expectedPid = values.length === 3 ? Number(values.pop()) : undefined;",
|
|
359
360
|
"const home = values.pop();",
|
|
360
361
|
"const runtimeModule = values.pop();",
|
|
@@ -362,6 +363,7 @@ function runSchemaIndependentControllerStop(home, environment, spawn, expectedPi
|
|
|
362
363
|
" const { stopFileTaskController } = await import(runtimeModule);",
|
|
363
364
|
" const data = await stopFileTaskController(home, {",
|
|
364
365
|
" environment: process.env,",
|
|
366
|
+
" handoverOwnerPid,",
|
|
365
367
|
" ...(expectedPid === undefined ? {} : { expectedPid })",
|
|
366
368
|
" });",
|
|
367
369
|
" process.stdout.write(JSON.stringify({ ok: true, data }));",
|
|
@@ -377,7 +379,10 @@ function runSchemaIndependentControllerStop(home, environment, spawn, expectedPi
|
|
|
377
379
|
helper,
|
|
378
380
|
UPDATE_CLIENT_RUNTIME_PATH,
|
|
379
381
|
home,
|
|
380
|
-
...(expectedPid === undefined ? [] : [String(expectedPid)])
|
|
382
|
+
...(expectedPid === undefined ? [] : [String(expectedPid)]),
|
|
383
|
+
// The runtime validates the existing lock owner; the child must identify
|
|
384
|
+
// its owning updater instead of waiting on the parent's lock as foreign.
|
|
385
|
+
String(process.pid)
|
|
381
386
|
], { cwd: process.cwd(), env: { ...environment, YUI_HOME: home }, shell: false });
|
|
382
387
|
if (result.error !== undefined || result.status !== 0) {
|
|
383
388
|
const detail = result.stderr.toString("utf8").trim();
|
|
@@ -491,10 +496,11 @@ function restoreControllerIdentity(home, identity, environment, spawn) {
|
|
|
491
496
|
// Spawn a detached child through a short-lived Node helper so the synchronous
|
|
492
497
|
// update process can still use the authenticated, bounded readiness handshake
|
|
493
498
|
// shared by Controller startup. No retry, sleep, or new identity inference is
|
|
494
|
-
// hidden here.
|
|
499
|
+
// hidden here. Restoration participates in the same parent-owned lock.
|
|
495
500
|
const helper = [
|
|
496
501
|
"const { spawn } = require('node:child_process');",
|
|
497
502
|
"const values = process.argv.slice(1);",
|
|
503
|
+
"const handoverOwnerPid = Number(values.pop());",
|
|
498
504
|
"const version = values.pop();",
|
|
499
505
|
"const args = JSON.parse(values.pop());",
|
|
500
506
|
"const executable = values.pop();",
|
|
@@ -504,6 +510,7 @@ function restoreControllerIdentity(home, identity, environment, spawn) {
|
|
|
504
510
|
" const { ensureFileTaskControllerIdentity } = await import(runtimeModule);",
|
|
505
511
|
" await ensureFileTaskControllerIdentity(home, { executablePath: executable, args, version }, {",
|
|
506
512
|
" environment: process.env,",
|
|
513
|
+
" handoverOwnerPid,",
|
|
507
514
|
" spawnController: (_home, launchEnv) => {",
|
|
508
515
|
" const child = spawn(executable, args, { detached: true, stdio: 'ignore', env: launchEnv });",
|
|
509
516
|
" child.unref();",
|
|
@@ -518,7 +525,8 @@ function restoreControllerIdentity(home, identity, environment, spawn) {
|
|
|
518
525
|
home,
|
|
519
526
|
identity.executablePath,
|
|
520
527
|
JSON.stringify(identity.args),
|
|
521
|
-
identity.version
|
|
528
|
+
identity.version,
|
|
529
|
+
String(process.pid)
|
|
522
530
|
], { cwd: process.cwd(), env: launchEnvironment, shell: false, stdio: "pipe" });
|
|
523
531
|
assertSpawnOk(result, "restore the previously running Controller identity");
|
|
524
532
|
}
|
package/docs/release-workflow.md
CHANGED
|
@@ -27,6 +27,21 @@ system sits behind `ReleaseWorkflowPorts`
|
|
|
27
27
|
external ports exercise recovery without real GitHub, npm, git, Controller,
|
|
28
28
|
or model effects.
|
|
29
29
|
|
|
30
|
+
## Controller handover fix in 0.16.1
|
|
31
|
+
|
|
32
|
+
The updater's stop and exact-identity restoration children now explicitly receive
|
|
33
|
+
the parent updater's handover-lock owner identity. They no longer wait on their
|
|
34
|
+
own parent's lock; unrelated callers remain fenced. Storage remains at version 37.
|
|
35
|
+
|
|
36
|
+
An already-installed older updater, including 0.15.12 or 0.16.0, cannot gain this
|
|
37
|
+
fix merely by staging the new package. If it reports `CONTROLLER_HANDOVER_TIMEOUT`
|
|
38
|
+
before activation, inspect the original Controller and lock ownership. Once the
|
|
39
|
+
failed updater has released its own lock and the original Controller is confirmed
|
|
40
|
+
healthy, normally stop it with that installed release's `yui controller stop`,
|
|
41
|
+
then retry `yui update`. This preserves managed Agent Sessions and retains the
|
|
42
|
+
normal preflight, backup, migration and verification boundaries. Do not delete
|
|
43
|
+
an active lock or force-kill a Controller to bypass the failure.
|
|
44
|
+
|
|
30
45
|
## Pre-1.0 contract cleanup
|
|
31
46
|
|
|
32
47
|
Version 0.16.0 retires runtime compatibility before the final
|
|
@@ -20,6 +20,18 @@ Agent 选择一个预先声明的计划,设施从持久状态驱动该计划
|
|
|
20
20
|
(`src/release/releaseWorkflowPorts.ts`)之后。可用临时 SQLite 和确定性的外部端口测试
|
|
21
21
|
恢复逻辑,无需真实 GitHub、npm、git、Controller 或模型效果。
|
|
22
22
|
|
|
23
|
+
## 0.16.1 的 Controller 交接修复
|
|
24
|
+
|
|
25
|
+
升级器的停止与精确身份恢复子进程,现在显式接收父升级进程的交接锁归属身份,
|
|
26
|
+
不再等待自己父进程持有的锁;无关调用仍被阻止。存储版本保持 37。
|
|
27
|
+
|
|
28
|
+
已经安装的旧升级器(包括 0.15.12、0.16.0)不会因为暂存新包而提前获得此修复。
|
|
29
|
+
若其在激活前报告 `CONTROLLER_HANDOVER_TIMEOUT`,先检查原 Controller 和锁的归属。
|
|
30
|
+
确认失败的升级器已释放自己的锁、原 Controller 仍健康后,使用已安装版本的
|
|
31
|
+
`yui controller stop` 正常停止 Controller,再重试 `yui update`。此操作保留受管
|
|
32
|
+
Agent Session,仍完整执行预检、备份、迁移和验证;不要删除活动锁或强杀 Controller
|
|
33
|
+
来绕过失败。
|
|
34
|
+
|
|
23
35
|
## 1.0 前的契约清理
|
|
24
36
|
|
|
25
37
|
版本 `0.16.0` 先清退运行时兼容分支,尚未执行最终 1.0 基线切换,也不重置
|
|
@@ -245,7 +245,10 @@ artifact and provenance boundaries. This validates runtime integration, not
|
|
|
245
245
|
real-model behavior. Pure contract and safety tests remain in `test/core`;
|
|
246
246
|
production wiring is exercised here rather than only through mocked ports.
|
|
247
247
|
The package smoke also checks unconditional status identity and update-owned
|
|
248
|
-
resource/identity capture through the assembled package
|
|
248
|
+
resource/identity capture through the assembled package. Real lifecycle children
|
|
249
|
+
stop the exact Controller and restore its captured launch identity while their
|
|
250
|
+
parent holds the handover lock. Unrelated callers remain fenced, the lock stays
|
|
251
|
+
owned by the parent, and durable input survives. These checks have no installation
|
|
249
252
|
or publication effect.
|
|
250
253
|
|
|
251
254
|
Configured Agents acting as developers or reviewers are ordinary execution
|
|
@@ -175,7 +175,9 @@ npm bin、依赖、受支持 Node 版本、产物和 provenance 边界。这证
|
|
|
175
175
|
真实模型行为。纯契约与安全检查保留在 `test/core`,生产组件组装在这里验证,
|
|
176
176
|
不只依赖模拟端口。
|
|
177
177
|
组装包检查还验证固定身份输出,以及升级侧通过组装包采集资源和精确 Controller 身份,
|
|
178
|
-
|
|
178
|
+
并在父进程持有交接锁时,通过真实生命周期子进程停止精确 Controller、恢复其已捕获的
|
|
179
|
+
启动身份。无关调用仍被锁阻止,锁保持由父进程持有,持久输入不变;
|
|
180
|
+
这些检查不执行安装或发布效果。
|
|
179
181
|
|
|
180
182
|
作为开发者或审查者的已配置 Agent 是普通执行资源。把一个真实 provider 或模型作为验证
|
|
181
183
|
对象则不同:付费 API、共享 Home、生产系统、真实账号额度以及其他不可丢弃的外部效果,
|