@zq-silk/yui 2.22.0 → 2.23.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.
- package/dist/cli/commandCatalog.js +2 -2
- package/dist/cli/updateCommand.js +20 -3
- package/dist/cli/updateOrchestrator.js +13 -0
- package/dist/cli/updatePorts.js +27 -0
- package/dist/commands/taskRoleRuntimeStatus.js +4 -0
- package/dist/context/currentSkills.js +32 -1
- package/dist/context/sessionBootstrapManifest.js +17 -4
- package/dist/context/sessionSkillNotice.js +33 -12
- package/dist/controller/clientRuntime.js +37 -18
- package/dist/controller/controller.js +16 -1
- package/dist/controller/fileSchedulerStoreAdapter.js +2 -0
- package/dist/controller/hostLifecycle.js +153 -0
- package/dist/controller/hostLifecycleChecks.js +27 -0
- package/dist/controller/hostUpgrade.js +344 -0
- package/dist/controller/runtime.js +67 -16
- package/dist/controller/sessionNotify.js +5 -46
- package/dist/execution/codexThreadNaming.js +54 -43
- package/dist/executor/fileRoleLaunchPlanner.js +18 -3
- package/dist/runtime/agentEndpoint.js +11 -1
- package/dist/runtime/agentEndpointIdentity.js +2 -0
- package/dist/runtime/agentHost.js +167 -42
- package/dist/runtime/agentHostImplementation.js +3 -1
- package/dist/runtime/codexAppServerRuntime.js +3 -0
- package/dist/runtime/codexInteractiveHost.js +62 -17
- package/dist/runtime/codexNativeAccess.js +1 -1
- package/dist/runtime/contextRecovery.js +15 -0
- package/dist/runtime/hostSessionLifecycle.js +83 -0
- package/dist/runtime/hostUpgradeGate.js +43 -0
- package/dist/runtime/lifecycleChecks.js +47 -0
- package/dist/runtime/lifecycleReservation.js +9 -1
- package/dist/runtime/nativeTitleReceipt.js +31 -0
- package/dist/runtime/nativeTitleSync.js +192 -0
- package/dist/runtime/providerRetry.js +4 -4
- package/dist/runtime/structuredProviderHost.js +42 -10
- package/dist/storage/sqliteSchema.js +20 -0
- package/dist/storage/storageVersions.js +1 -1
- package/docs/managed-turn-and-session-runtime.md +96 -1
- package/docs/managed-turn-and-session-runtime.zh-CN.md +70 -1
- package/docs/release-workflow.md +28 -0
- package/docs/release-workflow.zh-CN.md +20 -0
- package/docs/storage-baseline.md +10 -1
- package/docs/storage-baseline.zh-CN.md +5 -1
- package/docs/testing/verification-levels.md +2 -2
- package/docs/testing/verification-levels.zh-CN.md +2 -2
- package/package.json +1 -1
- package/skills/yui-runtime/SKILL.md +7 -2
- package/skills/yui-runtime/VERSION +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { createNativeTitleSync } from "./nativeTitleSync.js";
|
|
3
4
|
import { Duplex } from "node:stream";
|
|
4
5
|
import { nativeExecutable } from "./nativeExecutable.js";
|
|
5
6
|
import { startMissingCodexSharedDaemon } from "./codexSharedDaemon.js";
|
|
@@ -15,6 +16,7 @@ import { JsonLineChannel, PROVIDER_MESSAGE_MAX_BYTES, terminateProcessGroup } fr
|
|
|
15
16
|
import { PROVIDER_ACCEPT_TIMEOUT_MS } from "./runtimeDeadlines.js";
|
|
16
17
|
import { foldPublicReply } from "./publicReply.js";
|
|
17
18
|
import { createCodexNativeAccess } from "./codexNativeAccess.js";
|
|
19
|
+
import { isNativeContextRecovery } from "./contextRecovery.js";
|
|
18
20
|
const CODEX_PROXY_HANDSHAKE_TIMEOUT_MS = 10_000;
|
|
19
21
|
/**
|
|
20
22
|
* These Session implementations do not expose run-configuration observations.
|
|
@@ -396,7 +398,22 @@ class CodexStructuredProviderSession {
|
|
|
396
398
|
onActivity;
|
|
397
399
|
mirror;
|
|
398
400
|
nativeAccountHome;
|
|
401
|
+
contextEpoch = 0;
|
|
402
|
+
async checkQuiescent() {
|
|
403
|
+
const snapshot = await this.runtime.readConversation(this.conversationId, { includeTurns: false });
|
|
404
|
+
if (snapshot.threadId !== this.conversationId || snapshot.status !== "idle"
|
|
405
|
+
|| snapshot.activeTurnId !== undefined)
|
|
406
|
+
return false;
|
|
407
|
+
const backgrounds = await this.nativeAccess.read("thread/backgroundTerminals/list", {
|
|
408
|
+
threadId: this.conversationId, limit: 1
|
|
409
|
+
});
|
|
410
|
+
if (!Array.isArray(backgrounds.data) || !("nextCursor" in backgrounds)) {
|
|
411
|
+
throw new Error("Native background execution response is invalid.");
|
|
412
|
+
}
|
|
413
|
+
return backgrounds.data.length === 0 && backgrounds.nextCursor === null;
|
|
414
|
+
}
|
|
399
415
|
appliedGeneratedTitle;
|
|
416
|
+
#titleSync;
|
|
400
417
|
nativeAccess;
|
|
401
418
|
#turnAttempts = new Map();
|
|
402
419
|
adapterId = "codex";
|
|
@@ -456,16 +473,6 @@ class CodexStructuredProviderSession {
|
|
|
456
473
|
throw error;
|
|
457
474
|
}
|
|
458
475
|
}
|
|
459
|
-
if (control.sessionTitle !== undefined) {
|
|
460
|
-
// The native title mutation can persist without replying and stall later
|
|
461
|
-
// Goal/Turn requests, even through a separate metadata connection. Keep
|
|
462
|
-
// Yui's launch title, but do not put that optional mutation on a managed
|
|
463
|
-
// Session's execution path. Reconnect must not replay it either.
|
|
464
|
-
// This is an intentional omission, not a failed delivery or unavailable
|
|
465
|
-
// observer. Keep it in the Host log without waking an Agent to recover
|
|
466
|
-
// an operation that was never attempted.
|
|
467
|
-
mirror("stderr", "Native title synchronization was not submitted; Yui retains its Session title without blocking native Goal/Turn control.\n");
|
|
468
|
-
}
|
|
469
476
|
const ownedTurn = control.kind === "restore" ? control.ownedTurn : undefined;
|
|
470
477
|
// Keep notifications buffered during paginated recovery. Otherwise a live
|
|
471
478
|
// terminal can be emitted before open returns and then returned again as a
|
|
@@ -521,6 +528,15 @@ class CodexStructuredProviderSession {
|
|
|
521
528
|
}
|
|
522
529
|
}
|
|
523
530
|
const goal = await runtime.readGoal(conversationId);
|
|
531
|
+
session.#titleSync = createNativeTitleSync(payload, conversationId, session.nativeAccountHome, result => {
|
|
532
|
+
if (result.status === "confirmed")
|
|
533
|
+
session.appliedGeneratedTitle = result.title;
|
|
534
|
+
mirror("stderr", `Native title: ${JSON.stringify(result)}\n`);
|
|
535
|
+
});
|
|
536
|
+
void exit.then(() => session.#titleSync?.close());
|
|
537
|
+
// Fresh Threads may not be persisted until their first accepted input.
|
|
538
|
+
if (control.mode === "resume")
|
|
539
|
+
session.#titleSync.notify();
|
|
524
540
|
return Object.freeze({
|
|
525
541
|
session,
|
|
526
542
|
...(recoveredTerminal === undefined ? {} : { recoveredTerminal }),
|
|
@@ -530,6 +546,8 @@ class CodexStructuredProviderSession {
|
|
|
530
546
|
#observeMessage(message, emit) {
|
|
531
547
|
const method = typeof message.method === "string" ? message.method : "";
|
|
532
548
|
const params = object(message.params) ?? {};
|
|
549
|
+
if (isNativeContextRecovery("codex", this.conversationId, message))
|
|
550
|
+
this.contextEpoch += 1;
|
|
533
551
|
const threadId = optionalId(params.threadId);
|
|
534
552
|
if (emit)
|
|
535
553
|
this.publicReply = foldPublicReply(this.publicReply, this.conversationId, method, params);
|
|
@@ -539,6 +557,13 @@ class CodexStructuredProviderSession {
|
|
|
539
557
|
}
|
|
540
558
|
return undefined;
|
|
541
559
|
}
|
|
560
|
+
if (method === "thread/name/updated") {
|
|
561
|
+
this.#titleSync?.close();
|
|
562
|
+
if (params.threadName !== this.appliedGeneratedTitle)
|
|
563
|
+
this.appliedGeneratedTitle = undefined;
|
|
564
|
+
}
|
|
565
|
+
if (method === "turn/started")
|
|
566
|
+
this.#titleSync?.notify();
|
|
542
567
|
let goal;
|
|
543
568
|
try {
|
|
544
569
|
goal = codexGoalNotification({ method, params });
|
|
@@ -663,6 +688,7 @@ class CodexStructuredProviderSession {
|
|
|
663
688
|
conversationId: this.conversationId,
|
|
664
689
|
attemptId: turn.attemptId,
|
|
665
690
|
text: turn.boundedText,
|
|
691
|
+
...(turn.additionalContext === undefined ? {} : { additionalContext: turn.additionalContext }),
|
|
666
692
|
expectedNoActiveTurn: true,
|
|
667
693
|
...(turn.requireQuiescent ? { requireQuiescent: true } : {}),
|
|
668
694
|
...(turn.expectedFailedNativeTurnId === undefined ? {} : {
|
|
@@ -682,6 +708,7 @@ class CodexStructuredProviderSession {
|
|
|
682
708
|
this.#clientOwnedTurnId = acceptance.turnId;
|
|
683
709
|
this.#clientOwnedAttemptId = turn.attemptId;
|
|
684
710
|
this.#turnAttempts.set(acceptance.turnId, turn.attemptId);
|
|
711
|
+
this.#titleSync?.notify();
|
|
685
712
|
return Object.freeze({
|
|
686
713
|
attemptId: turn.attemptId,
|
|
687
714
|
conversationId: this.conversationId,
|
|
@@ -712,6 +739,7 @@ class CodexStructuredProviderSession {
|
|
|
712
739
|
conversationId: this.conversationId,
|
|
713
740
|
expectedTurnId: nativeTurnId,
|
|
714
741
|
text: turn.boundedText,
|
|
742
|
+
...(turn.additionalContext === undefined ? {} : { additionalContext: turn.additionalContext }),
|
|
715
743
|
clientUserMessageId: turn.attemptId
|
|
716
744
|
});
|
|
717
745
|
if (acceptance.status === "unknown") {
|
|
@@ -776,6 +804,7 @@ class CodexStructuredProviderSession {
|
|
|
776
804
|
return result === "interrupted" ? "requested" : result;
|
|
777
805
|
}
|
|
778
806
|
terminate(signal) {
|
|
807
|
+
this.#titleSync?.close();
|
|
779
808
|
terminateProcessGroup(this.child, signal);
|
|
780
809
|
}
|
|
781
810
|
}
|
|
@@ -787,6 +816,7 @@ class ClaudeStructuredProviderSession {
|
|
|
787
816
|
channel;
|
|
788
817
|
onGoal;
|
|
789
818
|
mirror;
|
|
819
|
+
contextEpoch = 0;
|
|
790
820
|
adapterId = "claude";
|
|
791
821
|
get ownedProcessId() { return this.child.pid; }
|
|
792
822
|
#activeAttemptId;
|
|
@@ -903,6 +933,8 @@ class ClaudeStructuredProviderSession {
|
|
|
903
933
|
terminateProcessGroup(this.child, signal);
|
|
904
934
|
}
|
|
905
935
|
#receive(message, onTerminal, onAccepted, onActivity) {
|
|
936
|
+
if (isNativeContextRecovery("claude", this.conversationId, message))
|
|
937
|
+
this.contextEpoch += 1;
|
|
906
938
|
const goal = claudeActiveGoal(message, this.conversationId);
|
|
907
939
|
if (goal !== undefined) {
|
|
908
940
|
const key = JSON.stringify(goal === null ? null : {
|
|
@@ -295,6 +295,26 @@ const MINOR_UPGRADES = Object.freeze([{
|
|
|
295
295
|
targetChecksum: CURRENT_SCHEMA_CHECKSUM,
|
|
296
296
|
// Optional workspace-write permission fields; preserve all existing payloads.
|
|
297
297
|
sql: ""
|
|
298
|
+
}, {
|
|
299
|
+
fromVersion: "1.26",
|
|
300
|
+
toVersion: "1.27",
|
|
301
|
+
name: "host-upgrade-lifecycle-signals",
|
|
302
|
+
introducedIn: "next",
|
|
303
|
+
sourceChecksum: CURRENT_SCHEMA_CHECKSUM,
|
|
304
|
+
targetChecksum: CURRENT_SCHEMA_CHECKSUM,
|
|
305
|
+
// New versioned signal sources in the existing role-runtime mailbox. No
|
|
306
|
+
// historical requests are inferred and existing records remain unchanged.
|
|
307
|
+
sql: ""
|
|
308
|
+
}, {
|
|
309
|
+
fromVersion: "1.27",
|
|
310
|
+
toVersion: "1.28",
|
|
311
|
+
name: "native-title-effect-receipts",
|
|
312
|
+
introducedIn: "next",
|
|
313
|
+
sourceChecksum: CURRENT_SCHEMA_CHECKSUM,
|
|
314
|
+
targetChecksum: CURRENT_SCHEMA_CHECKSUM,
|
|
315
|
+
// Additive exact-identity intent/confirmation files under runtime/native-titles.
|
|
316
|
+
// Never invent native ownership or replay history during migration.
|
|
317
|
+
sql: ""
|
|
298
318
|
}]);
|
|
299
319
|
export function storageMinorUpgradePlan(from) {
|
|
300
320
|
if (from === CURRENT_STORAGE_VERSION)
|
|
@@ -2,6 +2,99 @@
|
|
|
2
2
|
|
|
3
3
|
# Session, AgentRun and notifications
|
|
4
4
|
|
|
5
|
+
## Two lifecycle layers and nonblocking checks
|
|
6
|
+
|
|
7
|
+
Controller custody of a Host and the Host's native Session lifecycle have
|
|
8
|
+
separate event/guard/transition tables. Neither is an upgrade workflow.
|
|
9
|
+
|
|
10
|
+
| Layer | Events and transitions | Authority and correlation |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Controller → Host | Fresh physical observations recover `unavailable`/`stopped`/`starting`/`running`. Authorized launch enters `starting`; matching launch handshake enters `running`. Stop or graceful-exit request enters `stopping`; sending exit does not prove `stopped`. Physical absence confirms `stopped`; unknown effects enter `unavailable`. | Owner, local operation/revision, returned binding and native Session ID. Durable Role/Task intent, launch reservations and exact process custody remain authoritative. |
|
|
13
|
+
| Host → native Session | Launch, attachment, input acceptance, native activity, terminal, persistence, disconnect and exit drive the native states described below. | Native Session, proxy process, attempt and Turn identity; existing writer/resource fences still authorize effects. |
|
|
14
|
+
|
|
15
|
+
The Controller wraps the shared Host port for launch/restore, observation and
|
|
16
|
+
stop, including graceful-upgrade exit. A competing physical operation is
|
|
17
|
+
rejected before its side effect, not queued or replayed by this FSM. Late
|
|
18
|
+
reads and old bindings cannot overwrite newer custody; identical observations
|
|
19
|
+
produce no hook feedback loop. A Controller restart reconstructs by observation,
|
|
20
|
+
never by replaying the process-local state. Native completion/attachment exit
|
|
21
|
+
does not prove Host process exit. Legal same-conversation resume correlates the
|
|
22
|
+
layers without sharing their state enums or inventing another durable authority.
|
|
23
|
+
|
|
24
|
+
Host-side native Session lifecycle state is owned by an explicit transition table, not
|
|
25
|
+
by version detection. Launch/submit enters `starting`; attachment facts select
|
|
26
|
+
`idle`, `busy`, `ready` (owned input), or `delivery-unknown`; acceptance enters
|
|
27
|
+
`ready`; native execution enters `busy`; terminal handling enters `settling`;
|
|
28
|
+
persisted settlement returns to observed `idle`/`busy`. Disconnect enters
|
|
29
|
+
`starting`, classified failures retain their failure outcome, and exit enters
|
|
30
|
+
`exited`. Only an explicit launch can leave `exited`. Native-TUI attachment
|
|
31
|
+
readiness has its own event: `ready` there is not proof of native quiescence.
|
|
32
|
+
Illegal edges do not mutate state; stale process, attempt and terminal-Turn
|
|
33
|
+
facts are ignored. Exact writer/resource guards remain at command admission.
|
|
34
|
+
This process-local reducer reconstructs from existing launch and native facts;
|
|
35
|
+
it adds no persisted Session authority or upgrade workflow state machine.
|
|
36
|
+
|
|
37
|
+
Optional before/after observations are immutable, deferred and independently
|
|
38
|
+
coalesced (at most one running and one latest pending observation per check).
|
|
39
|
+
“Before” describes the transition's source, not an awaited precondition.
|
|
40
|
+
A slow or failing check cannot veto a transition or hold event folding/input
|
|
41
|
+
delivery; checks must yield for I/O and honour cancellation before effects.
|
|
42
|
+
They may recommend work to the separate fenced upgrade coordinator.
|
|
43
|
+
Controller Host-state hooks suggest version reconciliation. Host Session-state
|
|
44
|
+
hooks asynchronously observe current Skill metadata on attachment/settlement,
|
|
45
|
+
without reading Skill bodies, committing a notice or assuming model memory.
|
|
46
|
+
The exact per-input integrity check remains an ingress safeguard: invalid
|
|
47
|
+
Skills can reject that input, but an optional check cannot stall lifecycle.
|
|
48
|
+
Only accepted input advances the existing notice baseline; unchanged input
|
|
49
|
+
is passed through without any extra content.
|
|
50
|
+
|
|
51
|
+
Controller startup, Host connection/exit observations, Host state-change
|
|
52
|
+
signals and event persistence trigger version checks without an explicit
|
|
53
|
+
`update` request. Existing periodic reconciliation covers missed hints,
|
|
54
|
+
including providers without reliable background-execution-end events and
|
|
55
|
+
graceful exits that cannot emit a post-exit hint. Checks
|
|
56
|
+
compare actual loaded Host/Endpoint implementations with this Controller's
|
|
57
|
+
loaded target, never npm `latest`. Incomplete readiness on matching versions
|
|
58
|
+
is not an upgrade reason. Checks stop on shutdown; already-admitted work
|
|
59
|
+
retains the existing durable mailbox. A request pinned to a different target
|
|
60
|
+
stays waiting for explicit recovery, not silent retargeting. An explicitly
|
|
61
|
+
stopped Session is never restarted by a check.
|
|
62
|
+
|
|
63
|
+
## Host upgrade and context checks
|
|
64
|
+
|
|
65
|
+
`update` reports package installation, verified Controller startup and each
|
|
66
|
+
Host separately. `update --hosts-status` reads current per-Host evidence without
|
|
67
|
+
installing, starting or advancing a switch. Supported controlled Codex Hosts fence new input immediately,
|
|
68
|
+
wait for the current native Turn and event persistence, inspect native background
|
|
69
|
+
execution, and release their owned Endpoint before exiting gracefully. The
|
|
70
|
+
existing role-runtime mailbox retains the exact generation, native Session,
|
|
71
|
+
configuration digest and drain receipt across Controller restarts. A successor
|
|
72
|
+
uses the recorded effective configuration and resumes that same conversation;
|
|
73
|
+
only its loaded Host/Endpoint and control/event handshake confirm success.
|
|
74
|
+
Queued Messages remain original and accepted/unknown inputs are never replayed.
|
|
75
|
+
|
|
76
|
+
Paused Roles stay paused. Older Hosts, native-TUI-only attachments and Endpoints
|
|
77
|
+
without a quiescence capability are retained with an unsupported diagnosis; no
|
|
78
|
+
unsupported drain command is sent. A busy/unknown native execution has no
|
|
79
|
+
bounded upgrade-completion promise. An uncertain launch is not automatically
|
|
80
|
+
repeated; a later exact successful handshake can settle the retained request.
|
|
81
|
+
This fence covers Host-controlled ingress, not arbitrary external native clients;
|
|
82
|
+
it never terminates a shared daemon or native conversation.
|
|
83
|
+
|
|
84
|
+
Host Skill checks still run before every input. Unchanged inputs are passed
|
|
85
|
+
through exactly, with no notice, marker, separator or extra native input part.
|
|
86
|
+
The attachment's loading guidance explains this managed-input contract; no
|
|
87
|
+
notice is not a reason to repeat the check. Unmediated clients or uncertain
|
|
88
|
+
current input routing retain the explicit Manifest check fallback; reusing a
|
|
89
|
+
conversation alone does not establish Host mediation. Cold attachment,
|
|
90
|
+
affected Skill changes and observed native compaction supply loading guidance;
|
|
91
|
+
compaction invalidates the next input's metadata baseline. Without a reliable
|
|
92
|
+
native event, the Agent must still recover any missing instructions using the
|
|
93
|
+
Manifest. Neither a version nor an accepted notice proves model memory.
|
|
94
|
+
Routine checks and empty inboxes are not user-facing progress.
|
|
95
|
+
|
|
96
|
+
## Session stop and runtime observations
|
|
97
|
+
|
|
5
98
|
Global Session stop/replacement uses the same exact native-execution quiescence
|
|
6
99
|
boundary as Task Sessions. A departed Host or archived Session alone is not
|
|
7
100
|
proof that an accepted input ended: its retained Provider binding is inspected
|
|
@@ -31,7 +124,9 @@ Samples use a process-monotonic clock and hashed target/request labels, with
|
|
|
31
124
|
at most 16 recent and 16 active samples plus the slowest completed sample.
|
|
32
125
|
In-flight request count is not queue depth; total client-to-route wait is not
|
|
33
126
|
measured by the server alone. These observations neither identify an old incident
|
|
34
|
-
retroactively nor establish quiescence
|
|
127
|
+
retroactively nor establish quiescence. A Controller restart does not itself
|
|
128
|
+
prove Host replacement; asynchronous lifecycle checks still require a safe
|
|
129
|
+
drain and the successor's actual handshake.
|
|
35
130
|
|
|
36
131
|
`observations.commands.routes.transport` correlates socket accept-to-route,
|
|
37
132
|
complete-frame receive-to-route and route-to-local-flush stages by the same
|
|
@@ -2,6 +2,74 @@
|
|
|
2
2
|
|
|
3
3
|
# Session、AgentRun 与通知
|
|
4
4
|
|
|
5
|
+
## 两层生命周期与非阻塞检查
|
|
6
|
+
|
|
7
|
+
Controller 对 Host 的管理状态、Host 对原生 Session 的生命周期分别拥有自己的
|
|
8
|
+
事件、guard 和转换表,都不是升级流程状态机。
|
|
9
|
+
|
|
10
|
+
| 层级 | 事件与转换 | 权限及关联 |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| Controller → Host | 新鲜物理观测恢复 `unavailable`/`stopped`/`starting`/`running`;合法 launch 进入 `starting`,匹配启动握手进入 `running`。停止或优雅退出请求进入 `stopping`,发送退出不证明 `stopped`;物理不存在才确认 `stopped`,未知效果进入 `unavailable`。 | owner、本地操作/观测 revision、返回 binding 和原生 Session ID;持久 Role/Task 意图、启动 reservation 和精确进程权属仍是权威。 |
|
|
13
|
+
| Host → 原生 Session | launch、附件、输入接受、原生活动、终态、持久化、断连和退出驱动下述原生状态。 | 原生 Session、proxy 进程、attempt 和 Turn 身份;原有 writer/资源栅栏继续授权副作用。 |
|
|
14
|
+
|
|
15
|
+
Controller 在共享 Host port 处统一管理启动/恢复、观测与停止(含安全升级的优雅退出)。
|
|
16
|
+
冲突物理操作在副作用前拒绝,不由状态机另建队列或重放。迟到读取和旧 binding 不能覆盖
|
|
17
|
+
新管理状态;相同观测不重复触发检查反馈循环。Controller 重启后从观测重建,
|
|
18
|
+
不重放进程内状态。原生轮次完成或附件退出不能证明 Host 进程已退出;
|
|
19
|
+
合法恢复通过同一原生对话关联两层,不共用状态枚举或新增持久权威。
|
|
20
|
+
|
|
21
|
+
Host 内的原生 Session 生命周期由明确的转换表管理,不由版本检查管理。
|
|
22
|
+
launch/submit 进入 `starting`;附件事实选择 `idle`、`busy`、
|
|
23
|
+
`ready`(持有输入)或 `delivery-unknown`;接受输入进入 `ready`;
|
|
24
|
+
原生执行进入 `busy`;终态处理进入 `settling`;持久化结清后回到观测到的
|
|
25
|
+
`idle`/`busy`。断连进入 `starting`,分类失败保留对应失败状态,退出进入
|
|
26
|
+
`exited`,只有显式 launch 可离开它。原生 TUI 附件就绪有独立事件,
|
|
27
|
+
其 `ready` 不证明原生执行静止。非法边不改变状态;过期的进程、attempt、
|
|
28
|
+
终态 Turn 事实被忽略。精确 writer/资源 guard 仍在命令准入处执行。
|
|
29
|
+
状态机仅在进程内从现有 launch 和原生事实恢复,不新增持久 Session 权威或升级流程状态机。
|
|
30
|
+
|
|
31
|
+
可组合的前/后检查接收不可变观测,各自异步执行并合并重复提示
|
|
32
|
+
(每项最多一个执行中和一个最新待处理观测)。“前”表示转换来源,不是等待完成的前置条件。
|
|
33
|
+
慢检查或失败不能否决转换、阻塞事件折叠或输入投递;检查回调必须异步等待 I/O,
|
|
34
|
+
并在请求副作用前响应取消。它们只能向独立的、受精确栅栏保护的升级协调器提出请求。
|
|
35
|
+
Controller 的 Host 状态 hook 提议版本对账;Host 的 Session 状态 hook 在附件和结清时
|
|
36
|
+
异步观测当前 Skill 元数据,不读正文、不提交通知基线、不假定模型记忆。
|
|
37
|
+
逐输入完整性核验仍是投递安全门:无效 Skill 可以拒绝该次输入,但可选检查不能卡住生命周期。
|
|
38
|
+
仍只有被接受的输入推进通知基线,未变化输入原样通过,不额外注入内容。
|
|
39
|
+
|
|
40
|
+
Controller 启动、Host 连接/退出观测、Host 状态变化 signal 和事件持久化均可触发版本检查,
|
|
41
|
+
不依赖显式 `update`。现有周期对账覆盖丢失提示、无法可靠提供后台执行结束事件的提供方,
|
|
42
|
+
以及无法在退出后发出提示的优雅退出。
|
|
43
|
+
比较对象是实际加载的 Host/Endpoint 实现与当前 Controller 已加载的目标,不查询 npm `latest`。
|
|
44
|
+
版本匹配但就绪证据未齐不是升级理由。关闭时停止检查,已准入工作仍保留现有持久 mailbox;
|
|
45
|
+
请求固定的目标与当前 Controller 不同时保持等待,交由显式恢复,不静默改目标。
|
|
46
|
+
检查不会复活明确停止的 Session。
|
|
47
|
+
|
|
48
|
+
## Host 升级与上下文检查
|
|
49
|
+
|
|
50
|
+
`update` 分别报告程序安装、Controller 启动核验及逐 Host 的状态。
|
|
51
|
+
`update --hosts-status` 只读查询逐 Host 证据,不安装、启动或推进切换。支持此能力的
|
|
52
|
+
受控 Codex Host 先关闭新输入准入,等待当前原生轮次和事件持久化、核验后台执行,
|
|
53
|
+
释放自己持有的 Endpoint 后优雅退出。现有 role-runtime mailbox 保存精确实现代际、
|
|
54
|
+
native Session、配置摘要和排空回执,Controller 重启后仍可继续。
|
|
55
|
+
后继使用原 effective 配置接回同一对话;实际加载的 Host/Endpoint、控制与事件能力
|
|
56
|
+
握手通过后才确认成功。队列中的 Message 原文不变,不重放 accepted 或 unknown 输入。
|
|
57
|
+
|
|
58
|
+
暂停角色保持暂停。旧 Host、仅有原生 TUI 的附件及不能证明静止的 Endpoint
|
|
59
|
+
保留并报告不支持,不反复发送不支持的排空命令。忙碌或未知执行不承诺限时升级。
|
|
60
|
+
启动结果未知不自动重放;后续精确成功握手可结清原请求。
|
|
61
|
+
准入栅栏覆盖 Host 控制的入口,不控制任意外部原生客户端,也不会终止共享 daemon 或原生对话。
|
|
62
|
+
|
|
63
|
+
Host 仍逐输入机械检查 Skills。未变化时原文原样通过,不添加检查通知、隐藏标记、
|
|
64
|
+
分隔换行或原生输入片段。附件加载指引说明这一托管输入约定,不因没有通知而重复检查。
|
|
65
|
+
绕过 Host 的客户端或当前输入路由不明时仍通过 Manifest 显式检查;复用同一对话
|
|
66
|
+
本身不证明当前输入受 Host 托管。首次附件、局部 Skill 变化、已观测到的原生压缩
|
|
67
|
+
提供相应加载指引;压缩使下一次输入的元数据基线失效。
|
|
68
|
+
提供方无法可靠暴露事件时,Agent 仍须通过 Manifest 恢复缺失指令。
|
|
69
|
+
版本和已接受的通知都不能证明模型记忆;例行检查、角色版本和空 inbox 不作为用户进度播报。
|
|
70
|
+
|
|
71
|
+
## 会话停止与运行时观测
|
|
72
|
+
|
|
5
73
|
局部停止等待自身的持久清理义务完成,不等待整个 Home 的 `scheduler.scan`
|
|
6
74
|
循环排空。signal 只请求调度;完成仍以现有物理停止证明及清理事务为准。
|
|
7
75
|
超时保留义务并阻止替换;选择失败和新会话启动未确认分别报告,不允许重放未知效果。
|
|
@@ -16,7 +84,8 @@ interrupt-owned 输入仍保留原处理路径。
|
|
|
16
84
|
目标/请求标签仅保存哈希;每组最多保留 16 个近期样本、16 个活动样本及最慢完成样本。
|
|
17
85
|
in-flight 请求数不是排队数,服务端不能独自测量客户端到路由的完整等待。
|
|
18
86
|
观测不能反推旧事故的唯一根因,
|
|
19
|
-
|
|
87
|
+
也不构成静止证明;Controller 重启本身不证明 Host 已替换,
|
|
88
|
+
异步生命周期检查仍须经过安全排空和后继实际握手。
|
|
20
89
|
|
|
21
90
|
`observations.commands.routes.transport` 使用与 route service time 相同的请求哈希,
|
|
22
91
|
分别关联 socket accept→route、完整帧 receive→route、route→本地 flush。
|
package/docs/release-workflow.md
CHANGED
|
@@ -51,6 +51,34 @@ merely to avoid a version decision. Package versions remain distinct from protoc
|
|
|
51
51
|
and persistent-storage contracts: their compatibility checks and required migrations
|
|
52
52
|
are unchanged, and the storage rules below do not authorize a package release.
|
|
53
53
|
|
|
54
|
+
### 2.23.0 compatibility and migration notes
|
|
55
|
+
|
|
56
|
+
Host upgrades use explicit lifecycle signals and safe drain/reattachment
|
|
57
|
+
boundaries without replaying business input or replacing native identity.
|
|
58
|
+
Routine Skill checks remain inside the Host; unchanged Turns carry no Skill
|
|
59
|
+
notice. Cold attachment, explicit context loss/compaction and changed Skills
|
|
60
|
+
provide only the current loading pointers.
|
|
61
|
+
|
|
62
|
+
Codex keeps original user input separate from application context on start and
|
|
63
|
+
steer. Failed-Turn recovery does not duplicate the original input or imply lost
|
|
64
|
+
Skill context. This requires the native `additionalContext` contract verified
|
|
65
|
+
against Codex CLI 0.159.2; older native implementations are not covered and there
|
|
66
|
+
is no fallback that reinserts metadata into user input.
|
|
67
|
+
|
|
68
|
+
Native titles reuse the Role/Task/Draft/instance format through an independent,
|
|
69
|
+
bounded metadata process, never blocking Startup, Goal or Turn. Exact identity,
|
|
70
|
+
persisted intent and native readback distinguish confirmed naming from unknown
|
|
71
|
+
effects. Observed manual names are preserved; unknown writes are not replayed.
|
|
72
|
+
Historical polluted names without ownership evidence are diagnosed, not renamed.
|
|
73
|
+
The native naming API has no compare-and-swap, so a final concurrent external
|
|
74
|
+
rename cannot be protected atomically.
|
|
75
|
+
|
|
76
|
+
Storage advances to **1.28**, preserving **1.26 → 1.27** Host-upgrade signals and
|
|
77
|
+
adding **1.27 → 1.28** native-title receipts without rewriting history. Back up
|
|
78
|
+
the Home and use the normal upgrade/migration path; do not open a migrated Home
|
|
79
|
+
with an older binary. Controller/Host protocols remain v1. Publishing does not
|
|
80
|
+
update the global CLI, migrate production data or restart shared services.
|
|
81
|
+
|
|
54
82
|
### 2.22.0 compatibility and migration notes
|
|
55
83
|
|
|
56
84
|
Context reads now support bounded discovery, precise batched original retrieval,
|
|
@@ -36,6 +36,26 @@ Agent 选择一个预先声明的计划,设施从持久状态驱动该计划
|
|
|
36
36
|
不能将不兼容冒称为兼容,也不为回避版本选择新增历史兼容机制。包版本与协议、
|
|
37
37
|
持久存储契约仍然独立:兼容性检查和必要迁移要求不变,下文存储规则不授予发版权限。
|
|
38
38
|
|
|
39
|
+
### 2.23.0 兼容性及迁移说明
|
|
40
|
+
|
|
41
|
+
Host 升级使用明确的生命周期信号及安全排空/重新挂接边界,不重放业务输入、
|
|
42
|
+
不替换原生会话身份。常规 Skill 检查保留在 Host 内,未变化的 Turn 不携带
|
|
43
|
+
Skill 提示;仅首次挂接、明确上下文丢失/压缩及 Skill 变化提供当前加载指针。
|
|
44
|
+
|
|
45
|
+
Codex 的 start/steer 将用户原文与应用上下文分离。失败 Turn 恢复不复制原文,
|
|
46
|
+
也不视为 Skill 上下文丢失。此路径要求原生 `additionalContext` 契约,已核对
|
|
47
|
+
Codex CLI 0.159.2;旧原生实现不在验证范围内,不提供把元信息塞回用户输入的回退。
|
|
48
|
+
|
|
49
|
+
原生标题复用 Role/Task/Draft/实例格式,通过独立、有界的元数据进程同步,
|
|
50
|
+
不阻塞 Startup、Goal 或 Turn。精确身份、持久化意图和原生读回区分成功与未知效果。
|
|
51
|
+
保留已观测到的手动命名,未知写入不重放;缺乏归属证据的历史污染标题只诊断、不改名。
|
|
52
|
+
原生命名 API 没有 compare-and-swap,无法原子保护最后读写窗口内的外部并发改名。
|
|
53
|
+
|
|
54
|
+
存储升级至 **1.28**:保留 **1.26 → 1.27** Host 升级信号迁移,追加
|
|
55
|
+
**1.27 → 1.28** 原生标题回执,不改写历史。升级前备份 Home,使用正常升级/迁移
|
|
56
|
+
路径,不要用旧二进制打开已迁移的 Home。Controller/Host 协议仍为 v1。
|
|
57
|
+
发布本身不更新全局 CLI、不迁移生产数据,也不重启共享服务。
|
|
58
|
+
|
|
39
59
|
### 2.22.0 兼容性及迁移说明
|
|
40
60
|
|
|
41
61
|
上下文读取增加有界发现、精确批量原文读取、正文传输回执及聚焦通知。
|
package/docs/storage-baseline.md
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
# Storage baseline 1.0
|
|
4
4
|
|
|
5
|
-
Current storage is 1.
|
|
5
|
+
Current storage is 1.28. The 1.27 → 1.28 transition admits exact-identity native
|
|
6
|
+
title effect receipts under `runtime/native-titles`. It does not infer historical
|
|
7
|
+
title ownership, rename conversations, or change existing database payloads.
|
|
8
|
+
Unconfirmed naming intents remain non-replayable across Host replacement.
|
|
9
|
+
|
|
10
|
+
The 1.26 → 1.27 transition admits versioned Host-upgrade
|
|
11
|
+
signals in the existing role-runtime mailbox. It adds no table, infers no past
|
|
12
|
+
upgrade request, and preserves existing payloads. Drain receipts precede Host
|
|
13
|
+
exit; a Controller restart resumes the exact request, not business input.
|
|
14
|
+
The 1.25 → 1.26 transition admits optional Codex
|
|
6
15
|
workspace-write temporary-directory exclusions without changing historical
|
|
7
16
|
permission payloads. The published 1.24 → 1.25 transition remains unchanged
|
|
8
17
|
and admits optional Role
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# 存储基线 1.0
|
|
4
4
|
|
|
5
|
-
当前存储为 1.
|
|
5
|
+
当前存储为 1.28。1.27 → 1.28 声明 `runtime/native-titles` 下绑定精确会话身份的原生标题意图与回执;迁移不认领历史标题、不改名、不改写既有数据库 payload。未确认改名意图在 Host 替换后也不得重放。
|
|
6
|
+
|
|
7
|
+
1.26 → 1.27 允许现有 role-runtime mailbox 保存版本化 Host 升级信号,不新增表、不推断历史升级请求、不改写既有 payload。排空回执先于 Host 退出持久化;Controller 重启继续精确升级请求,不重放业务输入。
|
|
8
|
+
|
|
9
|
+
1.25 → 1.26 增加 Codex workspace-write 可选临时目录排除字段,不改写历史权限 payload。已发布的 1.24 → 1.25 定义保持不变:增加可选 Role `instanceCode` 和 Session `generatedTitle` 展示字段,不回填历史标题来源或实例码,不改写既有记录。1.23 → 1.24 为调度器的九类来源表增加事务维护的 Task 读取缓存修订号。插入、更新和删除只使对应 Task 的缓存失效,回滚同时回滚修订号。该值仅是派生缓存标识,不是 Task 权限或 Home revision CAS 的替代。历史 payload 不变,旧 Task 在首次修改前使用隐含的零修订号。
|
|
6
10
|
同时增加两个局部索引,支持按精确运行观测身份查找,不再扫描或反序列化历史观测集合。
|
|
7
11
|
|
|
8
12
|
1.22 → 1.23 新增全局 Shell Job、版本化脚本文件及每次运行的配置快照,不改写已有 Job、计划和历史记录。
|
|
@@ -53,12 +53,12 @@ is required.
|
|
|
53
53
|
Both include `test/core` and `test/platform`. For an already built checkout,
|
|
54
54
|
`npm run test:business` runs only `test/core` and `npm run test:platform` runs
|
|
55
55
|
only `test/platform`; neither rebuilds. CI owns one explicit build per job.
|
|
56
|
-
The stable suite owns current storage 1.
|
|
56
|
+
The stable suite owns current storage 1.28 and its declared 1.0 through 1.27 minor
|
|
57
57
|
transition. It contains no undeclared historical format compatibility path.
|
|
58
58
|
|
|
59
59
|
Current coverage includes:
|
|
60
60
|
|
|
61
|
-
1. Fresh storage 1.
|
|
61
|
+
1. Fresh storage 1.28, exact schema/record validation, no initialization over
|
|
62
62
|
unknown data, and rejection of old integer formats without mutation.
|
|
63
63
|
2. Exact-version staging, mismatched-target refusal, same-major contiguous
|
|
64
64
|
minor preflight, explicit maintenance-owner identity across handover, and
|
|
@@ -39,12 +39,12 @@ Yui 是一个单用户本地产品。永久验证保护关键的 happy path 和
|
|
|
39
39
|
两者均包含 `test/core` 和 `test/platform`。已构建的 checkout 可分别运行
|
|
40
40
|
`npm run test:business` 与 `npm run test:platform`,它们不会再次构建。
|
|
41
41
|
CI 每个作业只显式构建一次。
|
|
42
|
-
稳定套件维护当前存储 1.
|
|
42
|
+
稳定套件维护当前存储 1.28 和明确声明的 1.0 至 1.27 连续小版本迁移,
|
|
43
43
|
不包含未声明的历史格式兼容路径。
|
|
44
44
|
|
|
45
45
|
当前覆盖包括:
|
|
46
46
|
|
|
47
|
-
1. 新建存储 1.
|
|
47
|
+
1. 新建存储 1.28、精确结构与记录校验、禁止覆盖未知数据库、无修改拒绝旧整数格式。
|
|
48
48
|
2. 精确版本暂存、目标不匹配拒绝、同主版本连续小版本预检、交接锁显式所有者,
|
|
49
49
|
以及恢复时核对捕获的协议和存储身份,不接受缺失字段。
|
|
50
50
|
3. 持久 Task/Message/Decision 上下文、Draft 激活权威、mailbox 认领、
|
package/package.json
CHANGED
|
@@ -13,9 +13,14 @@ Resolve links relative to their containing file.
|
|
|
13
13
|
## Keep the current working set
|
|
14
14
|
|
|
15
15
|
The managed Host mechanically checks current Skill VERSION/readability for each
|
|
16
|
-
input.
|
|
17
|
-
|
|
16
|
+
input. It injects guidance only when loading is needed; unchanged inputs carry
|
|
17
|
+
no notice or marker. Do not duplicate the Host's check merely because no notice
|
|
18
|
+
appears. For unmediated clients or uncertain current input routing, run the
|
|
19
|
+
Manifest's `contextProtocol.skillCheckCommand`
|
|
18
20
|
(older Manifests: `yui session skills --json`) through the intended CLI/Home.
|
|
21
|
+
Conversation reuse alone does not establish Host mediation. Keep routine
|
|
22
|
+
role/Skill checks and empty-inbox observations internal; only report business
|
|
23
|
+
progress or actionable failures.
|
|
19
24
|
Global `loadCommand` includes the check. Recheck after repair/relevant change.
|
|
20
25
|
|
|
21
26
|
A check is metadata, not bodies, remembered instructions, a loading receipt or
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
46
|