@zq-silk/yui 2.4.0 → 2.6.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.
Files changed (58) hide show
  1. package/dist/cli/commandCatalog.js +4 -3
  2. package/dist/commands/taskCommands.js +48 -15
  3. package/dist/commands/taskContextCommand.js +3 -2
  4. package/dist/context/sessionBootstrapManifest.js +8 -2
  5. package/dist/context/taskContext.js +7 -4
  6. package/dist/controller/fileSchedulerStoreAdapter.js +7 -2
  7. package/dist/controller/globalInputDelivery.js +2 -4
  8. package/dist/controller/providerRetryDelivery.js +4 -2
  9. package/dist/executor/agentAdapter.js +3 -5
  10. package/dist/executor/fileRoleLaunchPlanner.js +2 -2
  11. package/dist/interaction/notificationPresentation.js +85 -0
  12. package/dist/interaction/operatorPresentation.js +1 -2
  13. package/dist/kernel/builtinCapabilities.js +2 -1
  14. package/dist/runtime/builtinAgentErrorMappers.js +9 -5
  15. package/dist/runtime/providerRetry.js +38 -0
  16. package/dist/runtime/taskSessions.js +240 -0
  17. package/dist/scheduler/leaderWakeupProcessor.js +1 -9
  18. package/dist/scheduler/taskExecutionProjection.js +78 -6
  19. package/dist/web/assets/assetManifest.js +2 -0
  20. package/dist/web/assets/client/app/taskView.js +1 -0
  21. package/dist/web/assets/client/domain/records.js +70 -2
  22. package/dist/web/assets/client/domain/runs.js +3 -2
  23. package/dist/web/assets/client/domain/vocab.js +1 -1
  24. package/dist/web/assets/client/i18n/en.js +17 -1
  25. package/dist/web/assets/client/i18n/zh-CN.js +17 -1
  26. package/dist/web/assets/client/lib/api.js +4 -1
  27. package/dist/web/assets/client/lib/theme.js +31 -10
  28. package/dist/web/assets/client/views/task/actions.js +38 -21
  29. package/dist/web/assets/client/views/task/observation.js +12 -3
  30. package/dist/web/assets/client/views/task/overview.js +7 -40
  31. package/dist/web/assets/client/views/task/runtime.js +71 -34
  32. package/dist/web/assets/shared/icons.js +2 -0
  33. package/dist/web/assets/shell/index.js +1 -0
  34. package/dist/web/assets/shell/settings.js +1 -0
  35. package/dist/web/assets/styles/views/task.js +14 -0
  36. package/dist/web/webConversation.js +2 -2
  37. package/dist/web/webServer.js +12 -0
  38. package/dist/web/webSessions.js +2 -165
  39. package/dist/web/webSnapshot.js +9 -5
  40. package/dist/web/webTaskActivity.js +54 -0
  41. package/dist/web/webTaskSurface.js +1 -0
  42. package/docs/cli-information-contract.md +1 -1
  43. package/docs/cli-information-contract.zh-CN.md +1 -1
  44. package/docs/managed-turn-and-session-runtime.md +22 -0
  45. package/docs/managed-turn-and-session-runtime.zh-CN.md +15 -0
  46. package/docs/observability/README.md +25 -1
  47. package/docs/observability/README.zh-CN.md +18 -1
  48. package/docs/provider-retry.md +11 -0
  49. package/docs/release-workflow.md +53 -0
  50. package/docs/release-workflow.zh-CN.md +40 -0
  51. package/package.json +1 -1
  52. package/skills/yui-leader/SKILL.md +5 -4
  53. package/skills/yui-leader/references/execution.md +2 -1
  54. package/skills/yui-operator/SKILL.md +3 -0
  55. package/skills/yui-reviewer/SKILL.md +4 -2
  56. package/skills/yui-runtime/SKILL.md +43 -2
  57. package/skills/yui-runtime/references/recovery.md +9 -0
  58. package/skills/yui-worker/SKILL.md +3 -2
@@ -1,165 +1,2 @@
1
- import { builtinDriverIdForAdapter } from "../runtime/builtinAgentDrivers.js";
2
- import { runtimeObservationFromTaskEvent } from "../runtime/runtimeObservation.js";
3
- import { projectRuntimeTaskEvents, classifyRuntimeHealth } from "../runtime/runtimeProjection.js";
4
- import { DEFAULT_RUNTIME_HEALTH_POLICY } from "../runtime/runtimeHealthPolicy.js";
5
- import { providerRetryProjection } from "../runtime/providerRetry.js";
6
- /** Read-only presentation of the selected native connections, never an AgentRun
7
- * count. Foreground facts are fenced to the exact input; retained continuations
8
- * stay attached to their original input and are not counted as extra Sessions.
9
- * No live probe, timers, persistence or recovery actions are introduced here. */
10
- export function projectWebSessions(input) {
11
- const policy = input.policy ?? DEFAULT_RUNTIME_HEALTH_POLICY;
12
- const sessions = [];
13
- const seen = new Map();
14
- const observations = input.events.map(event => ({ event, observation: runtimeObservationFromTaskEvent(event) }))
15
- .filter(entry => entry.observation !== null);
16
- for (const set of input.sessionSets) {
17
- const session = set.sessions[set.activeAgentId];
18
- const binding = set.providerBinding;
19
- const conversation = binding?.conversations.find(c => c.epoch === binding.currentConversationEpoch && c.status === "current");
20
- const nativeSessionId = session?.nativeSessionId ?? conversation?.conversationId ?? null;
21
- const identity = JSON.stringify([binding?.providerNamespace ?? session?.adapterId,
22
- binding?.accountScope ?? set.activeAgentId, nativeSessionId ?? set.owner.roleName]);
23
- const prior = seen.get(identity);
24
- if (prior !== undefined) {
25
- if (sessions[prior].roleName !== set.owner.roleName)
26
- sessions[prior] = {
27
- ...sessions[prior], group: "unknown", reason: "Multiple Roles name this native Session; inspect ownership."
28
- };
29
- continue;
30
- }
31
- seen.set(identity, sessions.length);
32
- const turn = binding?.run;
33
- const row = {
34
- taskId: input.taskId, roleName: set.owner.roleName, agentId: set.activeAgentId,
35
- nativeSessionId, attemptId: turn?.attemptId ?? null, nativeTurnId: turn?.nativeTurnId ?? null,
36
- runId: turn?.runId ?? null, group: "unknown", reason: "Current native input is not observable.",
37
- layer: null, lastActivityAt: null, semanticProgressAt: input.semanticProgressAt ?? null,
38
- sourceUpdatedAt: turn?.updatedAt ?? session?.updatedAt ?? set.updatedAt,
39
- waitingReason: null, operations: [], background: []
40
- };
41
- if (!session || !binding || !conversation || conversation.conversationId !== session.nativeSessionId) {
42
- sessions.push(row);
43
- continue;
44
- }
45
- let driverId;
46
- try {
47
- driverId = builtinDriverIdForAdapter(session.adapterId);
48
- }
49
- catch {
50
- sessions.push(row);
51
- continue;
52
- }
53
- const fence = { taskId: input.taskId, roleName: set.owner.roleName,
54
- agentId: session.agentId, driverId, nativeSessionId: session.nativeSessionId };
55
- const sessionFacts = observations.filter(({ observation }) => Object.entries(fence).every(([key, value]) => observation.fence[key] === value));
56
- // Each Run's continuation fold has its own authority. Foreground operations
57
- // from older inputs must not make the current input look active.
58
- const groups = new Map();
59
- for (const { event, observation } of sessionFacts) {
60
- const runId = observation.fence.runId;
61
- const group = groups.get(runId) ?? [];
62
- group.push(event);
63
- groups.set(runId, group);
64
- }
65
- const background = [...groups].flatMap(([runId, events]) => {
66
- const projection = projectRuntimeTaskEvents({ ...fence, ...(runId ? { runId } : {}) }, session.createdAt, events);
67
- const children = Object.entries(projection.continuations)
68
- .filter(([, c]) => c.execution !== "quiescent" || c.identityConflict)
69
- .map(([id, c]) => ({ id: `${runId ?? "native"}/${id}`, execution: c.execution }));
70
- return [...children, ...Object.entries(projection.operations)
71
- .filter(([, operation]) => operation.kind === "subagent")
72
- .map(([id]) => ({ id: `${runId ?? "native"}/operation:${id}`, execution: "unsettled" }))];
73
- });
74
- if (!turn) {
75
- sessions.push({ ...row, background, ...(background.length ? {
76
- group: "background", reason: "Retained background execution is not settled."
77
- } : {}) });
78
- continue;
79
- }
80
- const exactEvents = sessionFacts.filter(({ observation }) => {
81
- const observed = observation;
82
- const f = observed.fence;
83
- if (f.continuationId !== undefined || f.runId !== turn.runId)
84
- return false;
85
- if (f.receiptId === undefined && f.nativeTurnId === undefined
86
- && ["host.observed", "session.ended", "session.failed", "observer.health"].includes(observed.kind)) {
87
- return observed.receivedAt >= turn.submittedAt;
88
- }
89
- if (f.receiptId !== undefined && f.receiptId !== turn.attemptId)
90
- return false;
91
- if (f.nativeTurnId !== undefined && f.nativeTurnId !== turn.nativeTurnId)
92
- return false;
93
- return f.receiptId === turn.attemptId
94
- || (turn.nativeTurnId !== undefined && f.nativeTurnId === turn.nativeTurnId);
95
- }).map(entry => entry.event);
96
- const projection = projectRuntimeTaskEvents({
97
- ...fence, ...(turn.runId ? { runId: turn.runId } : {}),
98
- receiptId: turn.attemptId, ...(turn.nativeTurnId ? { nativeTurnId: turn.nativeTurnId } : {})
99
- }, turn.submittedAt, exactEvents);
100
- const health = classifyRuntimeHealth({ projection, now: input.now, policy,
101
- semanticProgressAt: input.semanticProgressAt ?? turn.submittedAt });
102
- const retry = providerRetryProjection(binding);
103
- let group;
104
- let reason = health.reason;
105
- if (turn.status === "delivery-unknown") {
106
- group = "unknown";
107
- reason = "Original input delivery is unknown; do not replay it.";
108
- }
109
- else if (session.status === "ended") {
110
- group = background.length ? "background" : "stopped";
111
- reason = "The selected Session ended; Task acceptance and retained background execution are separate.";
112
- }
113
- else if (retry?.status === "waiting") {
114
- group = "waiting";
115
- reason = `Controller-owned Provider retry waiting (${retry.attempts}/${retry.limit}); next eligible ${retry.nextEligibleAt}. Existing work is preserved.`;
116
- }
117
- else if (["failed", "cancelled", "rejected"].includes(turn.status)) {
118
- group = background.length ? "background" : "stopped";
119
- reason = turn.terminalReason ?? "The selected native execution stopped; Task acceptance is separate.";
120
- }
121
- else if (turn.status === "completed") {
122
- group = background.length ? "background" : "idle";
123
- reason = background.length ? "Main Turn ended; background execution remains unsettled."
124
- : "The native Turn ended; this is not Task completion.";
125
- }
126
- else if (turn.status !== "accepted") {
127
- group = "waiting";
128
- reason = "Waiting for native input acceptance.";
129
- }
130
- else if (projection.run === "waiting") {
131
- group = "waiting";
132
- }
133
- else if (["broken", "stopped"].includes(health.layer)) {
134
- group = "stopped";
135
- }
136
- else if (["completed", "failed", "cancelled"].includes(projection.run)) {
137
- group = "unknown";
138
- reason = "Native terminal and current input binding disagree; inspect the exact original input.";
139
- }
140
- else if (projection.observer.status === "unavailable") {
141
- group = "unknown";
142
- }
143
- else if (health.layer === "diagnostic-needed") {
144
- group = "diagnostic";
145
- }
146
- else if (health.runtimeIdleMs < policy.quietAfterMs && projection.activity.kind !== "provider") {
147
- group = "active";
148
- }
149
- else {
150
- group = "quiet";
151
- reason = "Accepted input has no recent structured activity; silence is not a proven deadlock.";
152
- }
153
- sessions.push({ ...row, group, reason, layer: health.layer, background,
154
- lastActivityAt: projection.lastRuntimeActivityAt ?? null,
155
- waitingReason: projection.waitingReason ?? null, operations: health.activeOperations });
156
- }
157
- const counts = {
158
- active: 0, waiting: 0, quiet: 0, diagnostic: 0, unknown: 0, stopped: 0, idle: 0, background: 0
159
- };
160
- for (const session of sessions)
161
- counts[session.group]++;
162
- return { scope: "task-selected-native-sessions", taskId: input.taskId,
163
- readAt: input.now.toISOString(), counts, sessions,
164
- coverage: "Recorded selected Sessions only; not a live process or historical resource inventory." };
165
- }
1
+ // CLI and Web share the same read-only native observation fold.
2
+ export { projectTaskSessions as projectWebSessions } from "../runtime/taskSessions.js";
@@ -96,14 +96,14 @@ export function buildWebTaskDetail(store, taskId, now = new Date(), compact = fa
96
96
  && effectiveLaunch.sourceDesiredRevision !== role.launchRevision
97
97
  };
98
98
  });
99
- const execution = buildTaskExecutionProjection(reader, taskId, now);
100
- if (execution === null)
101
- return null;
102
99
  const brief = reader.getTaskBrief(taskId);
103
100
  const roleSessionSets = reader.listRoleSessionSets(taskId);
104
101
  const sessions = projectWebSessions({ taskId, sessionSets: roleSessionSets, events, now,
105
102
  ...(brief?.updatedAt === undefined ? {} : { semanticProgressAt: brief.updatedAt }),
106
103
  policy: resolveRuntimeHealth(reader.getConfig().runtimeHealth) });
104
+ const execution = buildTaskExecutionProjection(reader, taskId, now, sessions);
105
+ if (execution === null)
106
+ return null;
107
107
  if (compact) {
108
108
  // Observation is not semantic progress. No Task/Message/Run bodies,
109
109
  // Role history or validation logs ride the default polling response.
@@ -115,15 +115,19 @@ export function buildWebTaskDetail(store, taskId, now = new Date(), compact = fa
115
115
  monitoring: execution.monitoring, failClosed: execution.failClosed,
116
116
  activeRuns: execution.activeRuns.slice(0, 16).map(run => ({ id: run.id })),
117
117
  activeRunCount: execution.activeRuns.length,
118
+ activity: execution.activity,
118
119
  attention: execution.attention.slice(0, 8).map(item => ({ ...item, summary: clip(item.summary) })),
119
120
  blockers: execution.blockers.slice(0, 8).map(item => ({ ...item, summary: clip(item.summary) }))
120
121
  },
122
+ roleCount: roles.length,
121
123
  roles: roles.slice(0, 16).map(role => ({
122
124
  name: role.name, status: role.status, runtimeSession: role.runtimeSession
123
125
  })),
124
- sessions: { ...sessions, sessions: sessions.sessions.slice(0, 16).map(session => ({
126
+ sessions: { ...sessions, total: sessions.sessions.length, coverageStatus: "partial",
127
+ sessions: sessions.sessions.slice(0, 16).map(session => ({
125
128
  ...session, reason: session.reason.slice(0, 1200),
126
- operations: session.operations.slice(0, 16), background: session.background.slice(0, 16)
129
+ operationCount: session.operations.length, backgroundCount: session.background.length,
130
+ operations: [], background: []
127
131
  })) },
128
132
  observability: {
129
133
  cost: execution.observability.cost,
@@ -0,0 +1,54 @@
1
+ import { taskNotFound } from "../errors/cliError.js";
2
+ import { recordPage } from "../output/boundedRead.js";
3
+ import { resolveRuntimeHealth } from "../config/yuiConfig.js";
4
+ import { projectTaskSessions } from "../runtime/taskSessions.js";
5
+ /** Native observations are not durable execution records. Flatten only the
6
+ * unfinished, recorded facts so one bounded page cannot hide a large child
7
+ * collection inside a single Session. Detail remains in the native Session. */
8
+ export function nativeActivityRows(projection) {
9
+ return projection.sessions.flatMap(session => {
10
+ const identity = {
11
+ roleName: session.roleName, agentId: session.agentId,
12
+ driverId: session.driverId,
13
+ nativeSessionId: session.nativeSessionId, runId: session.runId,
14
+ sourceUpdatedAt: session.sourceUpdatedAt
15
+ };
16
+ const key = JSON.stringify([session.roleName, session.agentId, session.driverId, session.nativeSessionId]);
17
+ return [
18
+ ...(["idle", "stopped"].includes(session.group) ? [] : [{
19
+ ...identity, id: key, kind: "session", status: session.group,
20
+ summary: session.reason.slice(0, 1200), waitingReason: session.waitingReason,
21
+ lastActivityAt: session.lastActivityAt
22
+ }]),
23
+ ...session.operations.filter(operation => !operation.startsWith("subagent:")).map(operation => ({
24
+ ...identity, id: `${key}/operation/${operation}`, kind: "operation",
25
+ status: "unsettled", summary: operation.slice(0, 1200)
26
+ })),
27
+ ...session.background.map(child => ({
28
+ ...identity, runId: child.runId, id: `${key}/background/${child.id}`, kind: "background",
29
+ status: child.execution, summary: child.id.slice(0, 1200)
30
+ }))
31
+ ];
32
+ });
33
+ }
34
+ export function readWebTaskActivity(store, taskId, options, now = new Date()) {
35
+ return store.readTransaction(reader => {
36
+ if (reader.getTask(taskId) === null)
37
+ throw taskNotFound(taskId);
38
+ const projection = projectTaskSessions({
39
+ taskId, sessionSets: reader.listRoleSessionSets(taskId), events: reader.listEvents(taskId), now,
40
+ policy: resolveRuntimeHealth(reader.getConfig().runtimeHealth)
41
+ });
42
+ const rows = nativeActivityRows(projection);
43
+ return {
44
+ ...recordPage(rows, `task:${taskId}/native-activity`, options),
45
+ readAt: now.toISOString(), coverage: "partial",
46
+ scope: projection.coverage,
47
+ counts: {
48
+ sessions: rows.filter(row => row.kind === "session").length,
49
+ operations: rows.filter(row => row.kind === "operation").length,
50
+ background: rows.filter(row => row.kind === "background").length
51
+ }
52
+ };
53
+ });
54
+ }
@@ -349,6 +349,7 @@ export function createWebTaskSurface(store, options = {}, observations = [], hos
349
349
  // The same paged family discovery as `task context list`: summaries and
350
350
  // exact references, never bodies; continuations keep their filters.
351
351
  list: (taskId, input) => listTaskContext(store, taskId, input.store, {
352
+ ...(input.view === undefined ? {} : { view: input.view }),
352
353
  ...(input.status === undefined ? {} : { status: input.status }),
353
354
  ...(input.cursor === undefined ? {} : { cursor: input.cursor }),
354
355
  ...(input.limit === undefined ? {} : { limit: input.limit })
@@ -20,7 +20,7 @@ schema migration or new snapshot/cache store is introduced.
20
20
  | What changed? | `task context delta <task> --after <cursor>` | Immutable events with a fixed upper bound, not a snapshot of current mutable state |
21
21
  | Which Global input? | `session context <role>` | Identity, profile, authority, current native Turn/retry and separate bounded pending/recent Message pages |
22
22
  | Read Global input | `role message list <role> [--pending]`, `role message show <role> <id>` | Scoped discovery, then exact original; queue acceptance never erases history |
23
- | What arrived in this wake? | `task wake show <task> <wake>` | Fixed window and Message/Run/Event read pointers, not duplicated bodies |
23
+ | What arrived in this wake? | `task wake show <task> <wake>` | Fixed-window inputs/results, attributed optional summaries and exact original reads; `--history` expands diagnostics |
24
24
  | What was assigned? | `task run context <task>/<run>` | Frozen authority and a single `pointers` inventory with summaries; changed identities in `deltaRefs`; current observations remain separate |
25
25
  | Which configuration is real? | `task role session inspect <task> <role>` | Task/Role identity, desired binding, frozen Session, current Provider binding, retry and explicit Host observation; no full Task/Role copies or Provider conversation history |
26
26
 
@@ -18,7 +18,7 @@ CLI 调用成功,不代表 Task、原生 Turn 或远端投递完成。
18
18
  | 发生了什么变化? | `task context delta <task> --after <cursor>` | 固定上界内的不可变事件,不是可变当前状态的快照 |
19
19
  | Global 收到了什么? | `session context <role>` | 身份、Profile、权限、当前原生 Turn/retry,以及分别有界的 pending/recent Message 页 |
20
20
  | 读取 Global 输入 | `role message list <role> [--pending]`、`role message show <role> <id>` | 在自身范围内发现,再读完整原文;队列接受不删除历史 |
21
- | 本次唤醒带来什么? | `task wake show <task> <wake>` | 固定窗口与 Message/Run/Event 读取指针,不重复正文 |
21
+ | 本次唤醒带来什么? | `task wake show <task> <wake>` | 固定窗口的输入/结果、标明来源的可选摘要和确切原文入口;`--history` 展开诊断历史 |
22
22
  | 分配了什么? | `task run context <task>/<run>` | 冻结授权与一份带摘要的 `pointers` 目录;`deltaRefs` 表示变化身份;当前观察独立 |
23
23
  | 实际配置是什么? | `task role session inspect <task> <role>` | Task/Role 身份、期望绑定、冻结 Session、当前 Provider 绑定、retry 与显式 Host 观察;不复制整个 Task/Role 或 Provider 会话历史 |
24
24
 
@@ -69,6 +69,14 @@ Run Pack is a reference directory: read the relevant requirement and message
69
69
  bodies before acting, rather than treating a successful load as the deliverable.
70
70
  Planning Packs expose no Project write scope or Task-completion permission.
71
71
 
72
+ The Manifest pointer is a recovery locator, not a read receipt. Load its exact
73
+ `yui-runtime`, Role Skills and profile on first entry, a new/version-changed
74
+ Session, or missing context after compaction/recovery. Reuse instructions only
75
+ when the same-version full content is still available; Yui stores no "already
76
+ read" state. Always refresh dynamic facts. Leader notifications use
77
+ `currentCommand`; dispatched AgentRuns use the actual Run ID with
78
+ `loadCommand`/`expandCommand`, never their placeholder templates.
79
+
72
80
  Every new Run, including planning, Review and continuation, binds an explicit
73
81
  frozen Snapshot before dispatch. Context reads validate its full identity and
74
82
  content digest, then read its stored values without rebuilding current Task
@@ -123,6 +131,20 @@ Human input, explicit execution entry and activation failure are delivered
123
131
  promptly through the existing wake mechanism. Worker results retain their
124
132
  aggregation window. Busy native input still preserves pending messages.
125
133
 
134
+ Normal and retry notifications share the same bounded presentation: factual
135
+ change labels, attributed optional author summaries, and original read entries.
136
+ An author can begin a Message/report with `Yui-Summary: <one line>` (summary
137
+ at most 512 UTF-8 bytes). It remains in the original record; no schema migration,
138
+ summary store, read-acknowledgement or extra model call is involved. Missing or
139
+ oversized summaries fall back to facts without clipping qualifications.
140
+ Summaries never grant authority, accept results or mark reviews approved.
141
+
142
+ `task wake show <task> <wake>` now defaults to inputs/results and explicit
143
+ references, including older referenced originals. It omits unrelated diagnostic
144
+ events and merely started Runs; `--history` restores full fixed-window discovery.
145
+ Both views retain the fixed window, deduplication, exact detail commands and
146
+ bounded `contentPage` continuations. Read decision-relevant originals in full.
147
+
126
148
  | Evidence | Disposition |
127
149
  | --- | --- |
128
150
  | Busy with proven non-acceptance | Preserve input; a new transport attempt may use the same Session |
@@ -55,6 +55,21 @@ Run Context 冻结 Assignment、来源引用、生效配置和工作区边界。
55
55
  和消息正文,而不是把加载成功当成交付物。规划 Pack 不暴露 Project 写范围或 Task 完成
56
56
  权限。
57
57
 
58
+ Manifest 指针是恢复定位入口,不是已读凭据。首次进入、新会话、版本变化、压缩或恢复后
59
+ 说明缺失时,从其确切路径加载 `yui-runtime`、Role Skills 和 profile;仅当同版本全文仍在
60
+ 当前可用上下文中,才复用而不机械重读。系统不保存“已经读过”状态。动态事实仍须刷新:
61
+ Leader 通知使用 `currentCommand`,显式 AgentRun 使用真实 Run ID 的
62
+ `loadCommand`/`expandCommand`,不可直接执行占位模板。
63
+
64
+ 正常和重试通知共用有界呈现:流程事实、标明作者来源的可选摘要与原文入口。Agent 可在
65
+ Message/报告首行写 `Yui-Summary: <单行摘要>`(摘要最多 512 UTF-8 字节),保留失败、
66
+ 未验证、待决定等限定。摘要存在原文本身,不新增数据格式、摘要存储、已读状态或模型调用;
67
+ 缺失或超长时使用事实模板,不截断关键限定。摘要不是授权、验收或审查通过结论。
68
+
69
+ `task wake show <task> <wake>` 默认展示消息、结果与明确引用(包括窗口外原文),
70
+ 不再枚举无关诊断事件和仅启动的 Run;`--history` 展开完整固定窗口历史。两个视图保留
71
+ 去重、固定窗口、确切原文命令及 `contentPage` 续读。决策所依赖的原文仍须全文读取。
72
+
58
73
  新 Run(包括规划、Review 和消息续接)必须在派发前绑定明确冻结的 Snapshot。
59
74
  Context 读取校验完整身份与内容 digest,然后直接读取已保存的值,不重新收集当前
60
75
  Task 记录。聚合执行从该 Snapshot 读取已选择的 Producer 结果;可写 Project 来自
@@ -108,8 +108,32 @@ All routes use the local Web token and Task boundary.
108
108
  `GET /api/tasks/<id>/artifacts` lists a fixed repository revision;
109
109
  `?path=<relative-path>&commit=<full-commit>` reads its exact text file.
110
110
  `GET /api/tasks/<id>/evidence` reads original check/Review/workspace records.
111
- `GET /api/tasks/<id>/list?store=<family>[&status&cursor&limit]` returns the same
111
+ `GET /api/tasks/<id>/list?store=<family>[&view=current|all&status&cursor&limit]` returns the same
112
112
  paged summaries as `task context list`.
113
+
114
+ `task context list <task> --store <family> --view current` uses the same
115
+ membership as the compact Context counts: active runs, pending/running reviews,
116
+ open InputRequests and queued/running/unknown Jobs. The default `all` view
117
+ preserves history. Each continuation binds the filtered collection and rejects
118
+ changed sources; refresh instead of mixing versions. Runtime lists expose
119
+ loaded/total counts, continuation, explicit refresh and read failures. Exact
120
+ record bodies remain on demand.
121
+
122
+ `GET /api/tasks/<id>/activity[?cursor=...&limit=20]` is a token-authenticated,
123
+ read-only page of recorded native Session, operation and background facts.
124
+ It uses the shared runtime projection, including retained, exactly fenced
125
+ children after Session replacement; it never probes processes or Providers.
126
+ Pages contain at most 100 items and 32 KiB, with separate category counts,
127
+ read time and explicit partial coverage. Compact observations carry full
128
+ counts with bounded Session samples, not nested child lists. Native facts and
129
+ AgentRuns can describe the same execution; their counts are not additive.
130
+ Unknown, unloaded and unavailable observations must not mean no activity.
131
+
132
+ The execution summary includes Job and native facts alongside open inputs and
133
+ AgentRuns. `waiting-on-jobs` is a derived display/next-action state, not a Task
134
+ lifecycle value. Waiting for a user keeps parallel work visible; unknown Job
135
+ outcomes or native activity remain attention facts, never completion or replay
136
+ authority.
113
137
  These reads do not start a runtime, fetch a remote, write business state, require
114
138
  a migration, or introduce a new persistent protocol.
115
139
 
@@ -89,8 +89,25 @@ skipped/缺失检查不算通过。工作区所有权不证明可清理;既
89
89
  `GET /api/tasks/<id>/artifacts` 列出固定仓库版本;
90
90
  `?path=<relative-path>&commit=<full-commit>` 读取该版本文本;
91
91
  `GET /api/tasks/<id>/evidence` 读取原检查/Review/工作区记录;
92
- `GET /api/tasks/<id>/list?store=<family>[&status&cursor&limit]` 返回与
92
+ `GET /api/tasks/<id>/list?store=<family>[&view=current|all&status&cursor&limit]` 返回与
93
93
  `task context list` 相同的分页摘要。
94
+
95
+ `task context list <task> --store <family> --view current` 与紧凑 Context
96
+ 计数使用同一筛选:active Run、pending/running Review、open InputRequest,
97
+ 以及 queued/running/unknown Job。默认 `all` 保留历史。分页游标绑定筛选后的
98
+ 集合,来源变化时明确拒绝继续拼接;应刷新重读。运行页展示已加载/总数、继续
99
+ 加载、刷新及读取失败,记录原文仍按需展开。
100
+
101
+ `GET /api/tasks/<id>/activity[?cursor=...&limit=20]` 是经过 token 鉴权的只读
102
+ 原生会话、operation 和后台活动分页。复用共享运行投影,覆盖会话更换后身份
103
+ 明确的保留子活动,不探测系统进程或 Provider。每页最多 100 项、32 KiB,
104
+ 包含分类计数、读取时间和明确的 partial 覆盖范围。紧凑观测返回完整计数及
105
+ 有限的会话样本,不携带嵌套子活动清单。原生事实与 AgentRun 可能指向同一
106
+ 执行,计数不可相加;未知、未加载和观测不可用都不能表示没有活动。
107
+
108
+ 执行摘要同时考虑 Job、原生事实、用户输入和 AgentRun。`waiting-on-jobs`
109
+ 只是派生展示/下一步状态,不改变 Task 生命周期。等待用户不隐藏并行工作;
110
+ 未知 Job 结果和原生活动保留为关注事实,不能据此判定完成或授权重放。
94
111
  读取不启动运行时、不访问远端、不写业务状态、不引入迁移或新持久协议。
95
112
 
96
113
  ## 执行审计
@@ -21,6 +21,10 @@ next input. Agents still own semantic recovery and acceptance.
21
21
  - An explicit manual retry of the same Run retains its recovery lineage,
22
22
  automatic count and original deadline. It is not charged as an automatic
23
23
  attempt, but a further failure cannot replenish automatic allowance.
24
+ If no automatic chain exists, it can still use the current binding's exact
25
+ accepted failed Turn and original input. The error need not have qualified
26
+ for automation; manual intent does not waive Session, authority, latest-Turn
27
+ or background-quiescence checks.
24
28
 
25
29
  The records live on the existing Provider binding, with indexed pending-record
26
30
  reads and the existing Controller deadline timer. There is no retry Task status,
@@ -56,6 +60,13 @@ failure and earlier chain references. A changed error that still satisfies the
56
60
  same safe retry rule continues within the original budget. Loss of that rule,
57
61
  authority or budget stops automatic submission.
58
62
 
63
+ Codex's structured `codexErrorInfo: "serverOverloaded"` qualifies as temporary
64
+ capacity failure. Capacity prose alone does not grant replay eligibility.
65
+ Native nonterminal error/retry notifications do not create a Yui retry; only
66
+ the exact failed terminal does. A missing retry record therefore does not
67
+ prove budget exhaustion or an unrecoverable Session: inspect the original
68
+ error and current Turn before choosing explicit recovery.
69
+
59
70
  Task errors retain their original `runtime.agent-error` evidence and notify the
60
71
  Leader, or the Operator when the affected Role is the Leader. Global failures
61
72
  retain record-only Messages in their own Role inbox, including intermediate
@@ -51,6 +51,59 @@ 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.6.0 compatibility and migration notes
55
+
56
+ This minor includes Task111's paged current activity and parallel execution
57
+ summary. Task runtime lists can discover all current Roles, Runs, Reviews,
58
+ Jobs and open InputRequests beyond the compact samples; exact record details
59
+ remain on demand. `task context list --view current` selects current membership,
60
+ while the default `all` retains history. Refresh a changed collection instead
61
+ of reusing its stale pagination cursor.
62
+
63
+ Execution consumers must handle the additional derived `waiting-on-jobs`
64
+ status and `wait-for-jobs` action, and the parallel `activity` categories.
65
+ These are not Task lifecycle states or new scheduling authority. Waiting for
66
+ user input no longer hides concurrent work. Unknown outcomes remain unknown
67
+ and never authorize replay.
68
+
69
+ Compact native observations now return category totals and bounded Session
70
+ samples with `operationCount`/`backgroundCount`, not embedded child lists.
71
+ Consumers needing those rows must page `/api/tasks/<id>/activity`.
72
+ Coverage is explicitly partial: selected native Sessions and retained,
73
+ exactly fenced child observations, not a live process inventory. Native facts
74
+ may describe an AgentRun and must not be added to it as separate executors.
75
+
76
+ No storage migration is added; storage remains **1.6**. Existing acceptance
77
+ evidence uses deterministic tests and isolated browser fixtures, not real-model
78
+ validation. Publishing this package does not upgrade a global CLI, migrate a
79
+ Home or restart a Controller.
80
+
81
+ ### 2.5.0 compatibility and migration notes
82
+
83
+ This minor includes Task110's notification and context-loading improvements.
84
+ Normal and recovery notifications share bounded facts, optional attributed
85
+ author summaries and exact action entries. A summary is not acceptance or
86
+ authority: relevant requirements, user messages and execution results must
87
+ still be read in full.
88
+
89
+ Session instructions name the required Skills explicitly. Reuse is conditional
90
+ on the complete same-version instructions remaining available in context;
91
+ first entry, changed instructions or missing/compacted content require loading
92
+ the exact Manifest and referenced files again. There is no persistent read
93
+ receipt, instruction cache or additional model call for summarization.
94
+
95
+ `task wake show` now focuses on relevant messages, results and referenced
96
+ evidence by default. Use `--history` for the broader fixed-window diagnostic
97
+ view and follow pagination when present. Consumers must not treat the focused
98
+ view as all history. Original records, exact older references, deduplication,
99
+ snapshot boundaries and unknown-input no-replay rules are preserved.
100
+
101
+ No storage migration is added; storage remains **1.6**. Deterministic tests and
102
+ package smoke do not prove real-model instruction reuse or compaction recovery.
103
+ Byte measurements are not token savings and can increase for a simple first
104
+ entry. Publishing this package does not upgrade a global CLI, migrate a Home
105
+ or restart a Controller.
106
+
54
107
  ### 2.4.0 compatibility and migration notes
55
108
 
56
109
  This minor ships the unified Web Task/Operator conversations and same-thread
@@ -36,6 +36,46 @@ Agent 选择一个预先声明的计划,设施从持久状态驱动该计划
36
36
  不能将不兼容冒称为兼容,也不为回避版本选择新增历史兼容机制。包版本与协议、
37
37
  持久存储契约仍然独立:兼容性检查和必要迁移要求不变,下文存储规则不授予发版权限。
38
38
 
39
+ ### 2.6.0 兼容性及迁移说明
40
+
41
+ 本 minor 包含 Task111 的当前活动分页与并行执行摘要。任务运行列表可发现超出
42
+ 紧凑样本的全部当前 Role、Run、Review、Job 及 open InputRequest,精确记录
43
+ 仍按需展开。`task context list --view current` 筛选当前事项,默认 `all`
44
+ 保留历史。集合变化后须刷新,不可继续使用旧分页游标拼接结果。
45
+
46
+ 执行摘要的消费者须支持新增的派生状态 `waiting-on-jobs`、动作
47
+ `wait-for-jobs` 及并行 `activity` 分类。这些不是 Task 生命周期状态,
48
+ 也不增加调度权限。等待用户输入不再隐藏并行工作;未知结果仍为未知,
49
+ 不能据此重放执行。
50
+
51
+ 紧凑原生观测现在返回分类总数及有界会话样本,使用
52
+ `operationCount`/`backgroundCount`,不再内嵌子活动列表。需要这些记录的
53
+ 消费者须分页读取 `/api/tasks/<id>/activity`。覆盖范围明确为 partial:
54
+ 选中的原生会话及身份明确的保留子活动观测,不是实时进程清单。原生事实
55
+ 可能描述同一个 AgentRun,不可相加为独立执行者数量。
56
+
57
+ 没有新增存储迁移,存储版本仍为 **1.6**。既有验收证据来自确定性测试和
58
+ 隔离浏览器夹具,不代表真实模型验证。发布此包不升级全局 CLI、不迁移 Home,
59
+ 也不重启 Controller。
60
+
61
+ ### 2.5.0 兼容性及迁移说明
62
+
63
+ 本 minor 包含 Task110 的通知和上下文加载优化。正常与恢复通知共用有界事实、
64
+ 可选且注明来源的作者摘要及精确行动入口。摘要不是验收或授权:相关需求、
65
+ 用户消息和执行结果仍须全文读取。
66
+
67
+ 会话说明显式列出所需 Skill。只有完整的同版本说明仍在可用上下文中时才能复用;
68
+ 首次进入、说明变更或内容缺失/被压缩时,须重新加载精确 Manifest 及其引用文件。
69
+ 没有新增持久已读回执、说明缓存或专用模型摘要调用。
70
+
71
+ `task wake show` 默认聚焦相关消息、结果及引用证据;如需更完整的固定窗口诊断,
72
+ 使用 `--history`,有分页时继续读取。调用方不能将聚焦视图当作全部历史。
73
+ 原始记录、精确旧引用、去重、快照边界及未知输入不得重放的规则保持不变。
74
+
75
+ 本版不新增存储迁移,存储仍为 **1.6**。确定性测试及安装包冒烟不证明真实模型
76
+ 会复用说明或在压缩后正确补读;字节测量不是 token 节省,简单首次进入的开销
77
+ 可能增加。发布本包不会升级全局 CLI、迁移 Home 或重启 Controller。
78
+
39
79
  ### 2.4.0 兼容性及迁移说明
40
80
 
41
81
  本 minor 发布统一 Web Task/Operator 对话及同 Thread Codex 终端、任务工作台、
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zq-silk/yui",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Local control plane for long-running native agent CLI sessions backed by tmux.",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -14,10 +14,11 @@ their summaries. Resolve links relative to the file containing them.
14
14
 
15
15
  Current Context is a bounded working set, not all Task history. Use
16
16
  `task context list <task> --store <store>` or a domain list for discovery,
17
- then an exact detail read. A wake contains original Message/Run read pointers,
18
- not copied reports. Follow Runtime's `nextCursor` and `contentPage` rules:
19
- read the full relevant window and originals before disposition, without
20
- unconditionally walking unrelated history.
17
+ then an exact detail read. A wake contains attributed change summaries and
18
+ original Message/Run pointers, not complete reports. Follow `yui-runtime`'s
19
+ `nextCursor` and `contentPage` rules: read the complete focused wake view and
20
+ relevant originals before disposition; use `wake show --history` only when
21
+ window history/diagnostics matter. Summaries never decide completion.
21
22
 
22
23
  Before WorkItem dispatch, put the complete bounded requirements in the WorkItem
23
24
  or explicitly select up to 16 relevant readable materials with repeated
@@ -420,7 +420,8 @@ notification; no active AgentRun is required.
420
420
 
421
421
  Before ending authorized execution:
422
422
 
423
- 1. Inspect the wake delta, resolve every referenced Worker or Reviewer AgentRun
423
+ 1. Inspect the focused wake inputs/results (expand `--history` when needed),
424
+ resolve every referenced Worker or Reviewer AgentRun
424
425
  with `yui task run show`, read each original result in full, and make the
425
426
  next decision.
426
427
  2. Persist actual WorkItem lifecycle and material Brief, Decision, Milestone,
@@ -30,6 +30,9 @@ another reader's understanding or action. Do not narrate dispatch, attach,
30
30
  heartbeat, sampling, unchanged waiting, or routine recovery.
31
31
 
32
32
  A `[Yui updates]` message is a wake envelope containing durable references.
33
+ Follow `yui-runtime`'s conditional instruction loading and attributed summary
34
+ contract for both Global Message inputs and these notices. Summaries locate
35
+ originals; they cannot grant user authority or prove result acceptance.
33
36
  Read those exact records before responding and combine related updates into one
34
37
  user-level summary. Do not create a Codex Goal, polling loop, private monitoring
35
38
  task, or synthetic progress message; future durable events will wake the
@@ -110,8 +110,10 @@ frozen Review or its original report.
110
110
 
111
111
  A helpful default result layout is Conclusion, Material findings, Verification,
112
112
  Uncertainty, and Recommended next action. Markdown or JSON are both acceptable.
113
- Yui preserves the original text and does not parse, normalize, or reject it for
114
- missing headings, field names, or formatting.
113
+ Yui preserves the original text and does not parse a verdict or reject it for
114
+ missing headings, field names, or formatting. Follow `yui-runtime`'s optional
115
+ `Yui-Summary:` first-line convention for attributed notification text; retain
116
+ material findings and uncertainty rather than implying automatic approval.
115
117
 
116
118
  For normal software delivery, follow the applicable Project Policy. The
117
119
  Leader decides whether risk warrants one independent Task-final Review of the