@zq-silk/yui 0.16.0 → 0.99.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.

Potentially problematic release.


This version of @zq-silk/yui might be problematic. Click here for more details.

Files changed (114) hide show
  1. package/ARCHITECTURE.md +12 -0
  2. package/ARCHITECTURE.zh-CN.md +8 -0
  3. package/README.md +3 -0
  4. package/dist/agent/managedRuntimeEnvironment.js +0 -4
  5. package/dist/agentRun/agentRun.js +7 -17
  6. package/dist/cli/agentConfigurationPicker.js +24 -21
  7. package/dist/cli/commandCatalog.js +18 -10
  8. package/dist/cli/roleWizard.js +41 -30
  9. package/dist/cli/updateCommand.js +35 -13
  10. package/dist/cli/updateOrchestrator.js +73 -33
  11. package/dist/cli/updatePorts.js +51 -20
  12. package/dist/cli.js +35 -26
  13. package/dist/commands/controllerCommands.js +1 -1
  14. package/dist/commands/executionAuditCommands.js +2 -2
  15. package/dist/commands/projectCommands.js +1 -1
  16. package/dist/commands/releaseCommands.js +9 -38
  17. package/dist/commands/taskCommands.js +84 -81
  18. package/dist/commands/taskCompletionGate.js +0 -117
  19. package/dist/commands/taskRoleRuntimeStatus.js +1 -1
  20. package/dist/commands/taskUpstreamCommands.js +93 -54
  21. package/dist/context/runContextPack.js +30 -54
  22. package/dist/context/runInputContract.js +9 -0
  23. package/dist/context/sessionBootstrapManifest.js +11 -19
  24. package/dist/controller/agentHostObservation.js +4 -2
  25. package/dist/controller/controller.js +8 -6
  26. package/dist/controller/fileSchedulerStoreAdapter.js +85 -18
  27. package/dist/controller/globalInputDelivery.js +28 -7
  28. package/dist/controller/globalRuntimeAttention.js +34 -0
  29. package/dist/controller/operatorNotification.js +31 -0
  30. package/dist/controller/providerRetryAdmission.js +3 -1
  31. package/dist/controller/providerRetryDelivery.js +10 -3
  32. package/dist/controller/runtime.js +1 -27
  33. package/dist/controller/sessionOwnerReconciliation.js +42 -24
  34. package/dist/controller/structuredProviderObservation.js +27 -0
  35. package/dist/controller/updateReconciliation.js +72 -20
  36. package/dist/doctor/doctor.js +2 -1
  37. package/dist/executor/agentAdapter.js +28 -96
  38. package/dist/executor/agentConfigurationCatalog.js +13 -68
  39. package/dist/executor/agentConfigurationFields.js +120 -0
  40. package/dist/executor/agentConfigurationProbe.js +55 -80
  41. package/dist/executor/agentExecutor.js +5 -2
  42. package/dist/executor/executorRegistry.js +0 -9
  43. package/dist/executor/fileRoleLaunchPlanner.js +12 -11
  44. package/dist/interaction/operatorPresentation.js +2 -1
  45. package/dist/message/messageContinuation.js +8 -9
  46. package/dist/observability/executionAudit.js +1 -10
  47. package/dist/observability/runtimeIdentity.js +0 -23
  48. package/dist/output/agentConfigurationPresentation.js +4 -2
  49. package/dist/release/releaseHandover.js +2 -2
  50. package/dist/release/releaseIdempotencyStore.js +0 -23
  51. package/dist/release/releaseWorkflowPorts.js +8 -4
  52. package/dist/repository/gitWorkspace.js +66 -19
  53. package/dist/repository/taskWorkspacePreparer.js +75 -68
  54. package/dist/resources/resourceRegistry.js +90 -44
  55. package/dist/resources/sqliteResourceRegistry.js +3 -5
  56. package/dist/runtime/acpSession.js +21 -5
  57. package/dist/runtime/agentEndpoint.js +4 -1
  58. package/dist/runtime/agentHost.js +22 -62
  59. package/dist/runtime/agentHostCleanup.js +85 -0
  60. package/dist/runtime/agentHostProtocol.js +1 -1
  61. package/dist/runtime/builtinAgentDrivers.js +46 -119
  62. package/dist/runtime/builtinTranscriptObserver.js +10 -6
  63. package/dist/runtime/codexAppServerRuntime.js +55 -89
  64. package/dist/runtime/jsonLineChannel.js +35 -7
  65. package/dist/runtime/providerContinuationReconciliationService.js +42 -3
  66. package/dist/runtime/providerRetry.js +15 -0
  67. package/dist/runtime/providerRuntimeReconciler.js +12 -2
  68. package/dist/runtime/structuredProviderHost.js +106 -81
  69. package/dist/scheduler/activeRoleRunDelivery.js +5 -1
  70. package/dist/scheduler/operatorInputNotificationProcessor.js +7 -17
  71. package/dist/storage/upgrade/upgradeOrchestrator.js +0 -10
  72. package/dist/task/nextAction.js +33 -23
  73. package/dist/task/task.js +2 -1
  74. package/dist/web/assets/assetManifest.js +2 -0
  75. package/dist/web/assets/client/app.js +72 -3
  76. package/dist/web/assets/client/components.js +2 -1
  77. package/dist/web/assets/client/i18n.js +2 -0
  78. package/dist/web/assets/client/taskSummary.js +345 -0
  79. package/dist/web/assets/client/taskSurface.js +44 -26
  80. package/dist/web/assets/client/view.js +33 -0
  81. package/dist/web/assets/shell.js +1 -0
  82. package/dist/web/assets/styles/cards.js +21 -0
  83. package/dist/web/webServer.js +39 -5
  84. package/dist/web/webSessions.js +165 -0
  85. package/dist/web/webSnapshot.js +23 -0
  86. package/dist/web/webTaskSurface.js +23 -0
  87. package/docs/managed-turn-and-session-runtime.md +31 -0
  88. package/docs/managed-turn-and-session-runtime.zh-CN.md +23 -0
  89. package/docs/observability/README.md +47 -0
  90. package/docs/observability/README.zh-CN.md +37 -0
  91. package/docs/project-refresh.md +9 -0
  92. package/docs/project-refresh.zh-CN.md +8 -0
  93. package/docs/provider-retry.md +35 -0
  94. package/docs/release-workflow.md +128 -20
  95. package/docs/release-workflow.zh-CN.md +107 -14
  96. package/docs/roles-and-configuration.md +30 -0
  97. package/docs/roles-and-configuration.zh-CN.md +20 -0
  98. package/docs/task-delivery.md +109 -0
  99. package/docs/task-delivery.zh-CN.md +80 -0
  100. package/docs/task-discovery.md +9 -0
  101. package/docs/task-discovery.zh-CN.md +6 -0
  102. package/docs/testing/verification-levels.md +33 -12
  103. package/docs/testing/verification-levels.zh-CN.md +28 -8
  104. package/i18n/README.zh-CN.md +2 -0
  105. package/package.json +1 -1
  106. package/skills/yui-leader/SKILL.md +11 -0
  107. package/skills/yui-leader/references/execution.md +22 -0
  108. package/skills/yui-leader/references/planning.md +6 -2
  109. package/skills/yui-operator/SKILL.md +45 -13
  110. package/skills/yui-operator/references/task-delivery.md +99 -0
  111. package/skills/yui-runtime/SKILL.md +5 -3
  112. package/skills/yui-runtime/references/publication.md +56 -5
  113. package/skills/yui-runtime/references/recovery.md +12 -2
  114. package/dist/runtime/agentHostCompatibility.js +0 -127
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: yui-operator
3
- description: Route user requests into Yui Tasks, explain progress, manage confirmed configuration and lifecycle actions, and intervene directly when that is the simplest way to advance the outcome.
3
+ description: Route requests and follow-up delivery through the owning Task Leaders, coordinate serial delivery across Tasks, explain progress, and manage authorized configuration, lifecycle and safety interventions.
4
4
  ---
5
5
 
6
6
  # Yui Operator
@@ -10,10 +10,13 @@ its Global Context without inventing a Task AgentRun. For explicit Task dispatch
10
10
  load the exact Run Context Pack and preserve its scope and permission boundaries.
11
11
 
12
12
  Be the task-neutral user entry point. Let the user discuss outcomes rather than
13
- Yui records and commands. The Leader is the default Task coordinator, but the
14
- Operator may perform any legal Task action when direct intervention is the
15
- clearest and lowest-complexity path. Global context does not grant a delivery
16
- workspace. Resolve Skill links relative to this Skill's directory.
13
+ Yui records and commands. Keep implementation, acceptance and follow-up delivery
14
+ with the owning Task's Leader by default. The Operator routes intent and
15
+ authority, verifies outcomes and reports to the user; it does not normally take
16
+ over implementation or create a second Task for the same result's delivery.
17
+ Legal configuration, lifecycle and urgent safety interventions remain available;
18
+ responsibility is not an extra permission gate. Global context does not grant a
19
+ delivery workspace. Resolve Skill links relative to this Skill's directory.
17
20
 
18
21
  ## Communicate at the user's level
19
22
 
@@ -55,8 +58,16 @@ before routing or deciding; a summary/ref is not the requirement or report.
55
58
 
56
59
  Route new input to an existing Task when it advances, corrects, narrows, or
57
60
  extends the same bounded outcome and shares final acceptance, delivery, or
58
- rollback. Create a new Task only when the new outcome can succeed, fail,
59
- complete, and be delivered independently.
61
+ rollback. Development, local completion, PR/MR submission, merge and ordinary
62
+ follow-up fixes are not inherently separate outcomes. Keep their original
63
+ authorization, acceptance and Publication traceable in the owning Task.
64
+
65
+ Create a new Task for a genuinely independent outcome that can be accepted,
66
+ delivered and rolled back separately, or when the user explicitly asks for a new
67
+ Task. State the substantive new outcome or explicit instruction in its routed
68
+ context. An old Task being completed, needing revalidation, sharing files or
69
+ needing a PR is not that reason. A blocked continuation is a boundary to report,
70
+ not evidence that the result has become independent.
60
71
 
61
72
  Repository, file overlap, technical layer, request size, and Task type do not
62
73
  determine Task identity. They also do not determine WorkItem count. Let
@@ -67,7 +78,9 @@ in its description or routed Message. The examples below are separate
67
78
  operations, not an automatic create/submit/activate sequence. For creation-only
68
79
  intent, save the Task without starting planning. Discussion does not authorize
69
80
  delivery; follow the Leader's [planning and activation boundary](../yui-leader/references/planning.md)
70
- before activation. Do not reopen terminal Tasks merely because new input arrives.
81
+ before activation. Queries, record-only input and discussion do not authorize
82
+ reopening. An explicit request to continue the same completed result can authorize
83
+ the necessary reopening; follow the delivery guidance below.
71
84
 
72
85
  ```sh
73
86
  yui operator submit "<related request and delta>" --task <task-id> --intent discuss
@@ -106,10 +119,28 @@ from current ownership and acceptance boundaries. A WorkItem is justified only
106
119
  for a substantial independently useful requirement, not for investigation,
107
120
  phases, files, tests, reviews, findings, or small repairs.
108
121
 
109
- When directly taking over Task coordination, read
122
+ Before an exceptional, authorized takeover of Task coordination, state why
123
+ Leader routing cannot meet the current need and read
110
124
  [yui-leader](../yui-leader/SKILL.md) for execution, review and Integration choices.
111
125
  Do not reproduce that scheduling policy in configuration or routing.
112
126
 
127
+ ## Keep delivery in the owning Tasks
128
+
129
+ For PR/MR submission, merge or delivery-related corrections, read
130
+ [same-Task and serial delivery](references/task-delivery.md) before routing.
131
+ For several Tasks, send the bounded authorized request to one owning Leader,
132
+ verify its exact delivery evidence, then advance the next. Do not default to
133
+ a new integration/delivery Task, concurrent dependent publications or direct
134
+ Global implementation. A successful send, native terminal or completed Task
135
+ does not establish remote merge.
136
+
137
+ For an explicitly requested continuation of a completed, unarchived result,
138
+ use the existing `task reopen` then durable submission path. The user's request
139
+ authorizes the necessary reopening within that scope; do not demand that they
140
+ also say “reopen.” Ordinary messages do not auto-reopen a Task. Keep cancelled,
141
+ archived and independently stopped execution boundaries separate, and do not
142
+ use Session recovery to bypass them.
143
+
113
144
  ## Prefer the lowest-complexity intervention
114
145
 
115
146
  Before intervening, read current intent and the existing configuration or
@@ -117,10 +148,11 @@ execution path. An explanation request is not a request to change configuration.
117
148
  Distinguish a missing capability from an existing one that was not supplied
118
149
  the user's actual environment or context.
119
150
 
120
- Choose routine legal alternatives yourself, including architecture, allocation,
121
- review and recovery. Reuse the current authority and primitives when sufficient;
122
- choose a bounded redesign when the responsibility is wrong. Preserve user-owned
123
- configuration and external-effect boundaries.
151
+ Choose routine legal routing and management actions yourself; leave Task
152
+ architecture, allocation, review and delivery choices with its Leader unless a
153
+ justified intervention is needed. Reuse current authority and primitives.
154
+ Do not require a new Task for every atomic management action. Preserve
155
+ user-owned configuration and external-effect boundaries.
124
156
 
125
157
  Escalate only a real product tradeoff, new authority, unavailable external fact,
126
158
  credential, irreversible effect, or safety boundary.
@@ -0,0 +1,99 @@
1
+ # Same-Task and serial delivery
2
+
3
+ Use this when the user asks to submit, merge or correct existing Task results.
4
+ The owning Task remains the default home of the result, even after local
5
+ acceptance. This is Agent coordination using current facts and atomic commands,
6
+ not a new delivery workflow or persistent scheduling state.
7
+
8
+ ## Establish the current boundary
9
+
10
+ Read each selected Task's current Context, full original request and relevant
11
+ Messages, completion evidence, existing Publication/PR identity and dependencies:
12
+
13
+ ```sh
14
+ yui task context <task> --json
15
+ yui task message show <task/message>
16
+ yui task publication list <task> --json
17
+ yui task remote-delivery <task> --json
18
+ yui task role session inspect <task> leader
19
+ ```
20
+
21
+ Local reads do not refresh a provider. When an authorized external read is needed,
22
+ inspect the exact existing PR and commits before creating or retrying anything.
23
+ Unknown delivery or external effects are not permission to repeat the operation.
24
+ Use [Runtime recovery](../../yui-runtime/references/recovery.md) for exact
25
+ notification/Session uncertainty, not a private retry or polling loop.
26
+
27
+ Separate lifecycle, execution gate and Session authority:
28
+
29
+ - An active, execution-enabled Task can receive ordinary Leader input. Inspect
30
+ the submission receipt and subsequent notification/result; admission is not
31
+ implementation.
32
+ - A Draft still follows [planning and activation](../../yui-leader/references/planning.md).
33
+ An old planning Session does not gain delivery authority from activation.
34
+ - An explicitly stopped Task needs authorized `task execution start <task>`
35
+ after exact cleanup, not another message or Session replacement to bypass the
36
+ stop. Starting execution is available only for open Tasks.
37
+ - A completed, unarchived Task has separate local acceptance and remote delivery
38
+ facts. An explicit user request to continue the same result authorizes the
39
+ necessary `task reopen` before submitting that bounded request. Follow the
40
+ [authorized two-step path](../../yui-runtime/references/publication.md#post-completion-routing-boundary);
41
+ do not require a second mechanical “reopen” confirmation.
42
+ - Cancelled/retired intent is not active work. An archived Task cannot be reopened;
43
+ retained workspaces and historical Sessions do not authorize execution.
44
+ - Session loss or replacement is not a new result or an automatic lifecycle
45
+ change. Recover only within the Task's current authority, preserving its intent.
46
+
47
+ Use the existing reopen and submission operations, not an invented auto-reopen
48
+ option or a new delivery Task. Reopening and saving input have separate receipts;
49
+ inspect current state after a failure and retain the original request identity.
50
+ Only a real missing authority, resource or unresolved execution boundary calls
51
+ for escalation. Do not reopen for a query, implicitly restore cancelled intent,
52
+ use archived workspaces, restart a separate execution stop, or claim rejected
53
+ input was saved.
54
+
55
+ ## Advance one owning Leader at a time
56
+
57
+ Choose a sensible order from the user's order, real dependencies and current
58
+ target-branch facts. For a serial multi-Task delivery request:
59
+
60
+ 1. Send only the current Task's Leader a durable request naming the authorized
61
+ external effects, repository and target branch, source result/PR, relevant
62
+ earlier merge evidence, limits and expected proof. Development alone does not
63
+ authorize push/PR/merge; merge does not authorize release, production update or
64
+ archive. Resolve genuinely missing authority before requesting those effects.
65
+ 2. The Leader handles synchronization, necessary conflict resolution, relevant
66
+ validation and the authorized normal push/PR/merge in its own legal managed
67
+ workspace. It records confirmed operations promptly through
68
+ [Publication](../../yui-runtime/references/publication.md), retaining original
69
+ acceptance and reviewing/adopting a changed candidate when applicable.
70
+ Do not register the same PR again under another Task to manufacture coverage.
71
+ 3. On the durable result/update, read the original report in full and inspect
72
+ the exact Publication, source/merge commits and target. Use authorized
73
+ `task publication verify <task>/<publication>` when needed; then check
74
+ `task remote-delivery <task> --json` for verified merge and coverage of the
75
+ owning Task's accepted result, not just a merged PR label.
76
+ 4. Only after that evidence satisfies this Task's requested delivery, send the
77
+ next Leader its request with the now-confirmed predecessor facts. If blocked,
78
+ retain the order and pending intent in existing durable context and report the
79
+ specific boundary. Do not launch the dependent delivery or emit unchanged
80
+ waiting messages; future durable updates supply the next opportunity.
81
+
82
+ After any necessary authorized reopening, either of these is an ordinary durable
83
+ Leader submission for the active Task; choose one, do not send both:
84
+
85
+ ```sh
86
+ yui operator submit "<delivery request with authority and boundaries>" \
87
+ --task <task> --intent develop --request-id <id>
88
+ yui task message send <task> "<delivery request with authority and boundaries>" \
89
+ --intent develop --request-id <id>
90
+ ```
91
+
92
+ Omit `--to leader` for this ordinary Leader input. Explicit `--to` addresses an
93
+ existing WorkItem/ReviewRound Assignment, not the Task's general conversation.
94
+ Keep the exact request ID on a retry of the same submission and inspect its
95
+ receipt; a new ID is not a remedy for unknown acceptance.
96
+
97
+ For three ordered Tasks, this means request A, verify A, request B against A's
98
+ confirmed delivery, verify B, then request and verify C. It does not mean sending
99
+ three messages immediately and hoping the Leaders serialize themselves.
@@ -49,9 +49,11 @@ For every explicitly dispatched managed Task AgentRun:
49
49
  "$YUI_SESSION_CLI" task run context expand "$YUI_TASK_ID/<run-id>" <ref-id> --store <store> --mode full --json
50
50
  ```
51
51
 
52
- A bare `<ref-id>` remains supported only when it identifies exactly one
53
- authorized pointer. If multiple stores use that id, bare expansion fails
54
- closed; never guess which store was intended.
52
+ `--store` is required, even when the ref id is unique. Select both fields
53
+ from the exact authorized pointer; never infer a store from the id.
54
+ Dispatched Runs require an explicit frozen Snapshot. A historical Run
55
+ without one is audit-only: current Task facts cannot reconstruct its
56
+ execution Context.
55
57
 
56
58
  A pointer or summary is not the request's body. Before planning or executing,
57
59
  read the relevant WorkItem/Task requirements and referenced user/Operator
@@ -1,20 +1,69 @@
1
1
  # Record external delivery
2
2
 
3
- Use this after creating, updating, closing, reopening or merging a PR/MR
4
- within existing user authorization. This procedure does not grant permission
3
+ Use this when routing authorized follow-up delivery or after creating, updating,
4
+ closing, reopening or merging a PR/MR. This procedure does not grant permission
5
5
  to push, publish, merge, query an external provider or archive.
6
6
 
7
+ ## Post-completion routing boundary
8
+
9
+ An explicit user request to continue implementation or delivery of the same
10
+ completed, unarchived result authorizes its necessary reopening within that
11
+ request's scope. The Operator need not ask the user to additionally say “reopen.”
12
+ Read the original completion, fixed heads/reports, Publication and current
13
+ authority first, then use the existing two operations:
14
+
15
+ ```sh
16
+ yui task reopen <task>
17
+ yui operator submit "<new request, authority, boundaries and prior evidence>" \
18
+ --task <task> --intent develop --request-id <id>
19
+ ```
20
+
21
+ Unaddressed `task message send` with the same intent/key options is an alternative
22
+ to the second command, not an additional send. Ordinary send/queue/submit still
23
+ refuses completed Tasks before saving new input; no intent implicitly changes
24
+ lifecycle and there is no auto-reopen option. `--to leader` instead requires an existing
25
+ WorkItem/ReviewRound Assignment.
26
+
27
+ Reopen returns the Task to active and clears its current completion fields;
28
+ original completion events, fixed commits/artifacts and Publication history stay
29
+ intact. The Leader must assess the new request and separately accept any new
30
+ result, not pretend old validation proves changed work. Reopen does not replay
31
+ historical Messages/Runs, change the Role's Agent/model/permissions, or lift an
32
+ independent execution stop. Queries, ordinary record/discussion input and Session
33
+ recovery do not authorize resumption. Cancelled intent needs its own explicit
34
+ restoration authority; archived Tasks cannot reopen. A stopped gate still needs
35
+ the separately authorized start/cleanup path.
36
+
37
+ These are two atomic operations, not one transaction. Read the reopen result and
38
+ the submission's saved/queued receipt separately. If the second step fails,
39
+ inspect current Task/Message facts and continue only the unapplied step within
40
+ unchanged authority. Keep the same submission key on a matching retry; unknown
41
+ native or external effects are never replay permission. Do not reopen again just
42
+ to retry input after another completion, cancellation or stop. A lifecycle-only
43
+ notification may precede the new Message: the Leader waits for the actual request,
44
+ without rerunning old work or immediately completing the reopened Task.
45
+
46
+ Publication recording, diff/adopt and verification remain separately authorized
47
+ atomic operations on completed, unarchived results. They need no reopening when
48
+ no further execution is requested, and never grant authority for code changes.
49
+
50
+ ## Record and verify the owning Task's publication
51
+
7
52
  Immediately record the confirmed operation with `yui task publication upsert`.
8
53
  Supply only facts already known from the operation; do not defer recording to
9
- another Role or depend on provider-specific discovery.
54
+ another Role or depend on provider-specific discovery. Keep it with the Task
55
+ whose result is delivered; do not duplicate the same PR/MR across Tasks to
56
+ substitute for missing ownership or acceptance evidence.
10
57
 
11
58
  Track PR/MR identity, state, commits, URL, merge time and evidence, not CI or
12
59
  deployment status. After merge, use `yui task publication verify` only when
13
60
  current authorization covers that external provider read. Otherwise retain
14
61
  reported evidence and state the verification gap.
15
62
 
16
- Keep the completion head as the original acceptance evidence. If an authorized
17
- post-completion integration produced a different publication candidate, record
63
+ Preserve each completion head as that acceptance's evidence. After an authorized
64
+ reopen, finish the new work and record its own completion; retain the earlier
65
+ event and report rather than rewriting them. For a still-completed Task whose
66
+ authorized post-completion integration produced a different candidate, record
18
67
  its exact local commit, then read `task publication diff <task>/<publication>`.
19
68
  Inspect the complete delta against the original acceptance, including removals,
20
69
  conflict resolutions and additional changes. Only when that candidate still
@@ -36,6 +85,8 @@ decision. Archived history is read-only to these adopt/verify operations.
36
85
  Use `yui task remote-delivery <task>` to explain external delivery. Publication
37
86
  is not Candidate acceptance, Review, Integration or Task completion.
38
87
 
88
+ ## Archive separately
89
+
39
90
  Completion does not authorize archive. The Operator obtains authorization for
40
91
  the exact Task, checks archive eligibility, then uses `--integrated` for verified
41
92
  merged delivery or `--abandon` for deliberate non-delivery. General archive
@@ -35,8 +35,12 @@ configured Agent identity. Native settings files and credentials are still read
35
35
  currently, not copied into error history. A historical error without a recorded
36
36
  configuration, or a changed Agent command/bindings, returns a diagnosis instead
37
37
  of borrowing today's Role configuration. To inspect the desired next launch
38
- explicitly, omit `--error`. Distinguish live, cached and unavailable metadata.
39
- Do not treat an alias list as a complete Provider whitelist.
38
+ explicitly, omit `--error`. Distinguish live enumeration, identity-matched cached
39
+ observations, declared static adapter inputs, and unavailable fields. Read field
40
+ reasons, warnings, observation/attempt times and the current query error: a live
41
+ query can contain static or unavailable fields, and a cache hit is not current
42
+ Provider confirmation. Do not treat an alias list as a complete Provider
43
+ whitelist or a static/custom choice as proven native support.
40
44
 
41
45
  Reconcile the original user requirement with exact native IDs and alias
42
46
  mappings. Correcting the name of the same authorized model is routine recovery;
@@ -130,6 +134,12 @@ If exact native stop or inspection fails, read the persisted diagnostic and
130
134
  resolve that resource boundary; do not kill arbitrary processes, clear unknown
131
135
  execution records, or modify managed refs, tmux Sessions or state files.
132
136
 
137
+ Breaking upgrades require a clean runtime environment; Yui does not discover,
138
+ convert or inherit historical Hosts and processes. Storage migration is a
139
+ separate explicit operation, not proof of runtime continuity. Do not interpret
140
+ missing compatibility diagnostics as permission to reuse an old process,
141
+ discard pending intent or bypass exact ownership and stop confirmation.
142
+
133
143
  After repeated failure of the same bounded recovery, report the observed
134
144
  cause, impact and smallest remaining options. Do not broaden cleanup or add
135
145
  a private retry loop. A failed recovery does not erase the pending requirement.
@@ -1,127 +0,0 @@
1
- import { lstatSync, readdirSync, readFileSync } from "node:fs";
2
- import { basename, dirname, join } from "node:path";
3
- import { agentHostControlSocketPath, inspectAgentHostSocket } from "./agentHost.js";
4
- import { AGENT_HOST_CONTROL_PROTOCOL, AGENT_HOST_EVENT_PROTOCOL } from "./agentHostProtocol.js";
5
- import { FILE_TASK_CONTROLLER_PROTOCOL_VERSION } from "../core/protocol.js";
6
- import { readHomeFilesystemId } from "../core/homeFilesystemIdentity.js";
7
- import { readLinuxProcessIdentity } from "./sessionOwnerIdentity.js";
8
- /** Inspect the concrete Home's existing control sockets, independently of the
9
- * database layout. No discovery write, process signal, input replay or repair.
10
- * Idle legacy Hosts are not safe: their next event still opens their old schema.
11
- */
12
- export async function inspectAgentHostCompatibility(home) {
13
- const sample = agentHostControlSocketPath({ home, scope: "global", roleName: "compatibility-probe" });
14
- const directory = dirname(sample);
15
- const prefix = `${basename(sample).split("-")[0]}-`;
16
- let names;
17
- try {
18
- names = readdirSync(directory).filter(name => name.startsWith(prefix) && /^[a-f0-9]{16}-[a-f0-9]{16}\.sock$/.test(name));
19
- }
20
- catch (error) {
21
- if (error.code === "ENOENT")
22
- names = [];
23
- else
24
- return [{ socket: directory, reason: `Host inventory is unreadable: ${messageOf(error)}` }];
25
- }
26
- // A launch can have redeemed its payload but not yet bound its socket.
27
- // It is still a loaded Host implementation. Do not miss it just because
28
- // preflight happened in that short startup interval.
29
- const processes = liveHostProcesses(home);
30
- const sockets = new Set([...names.map(name => join(directory, name)), ...processes.map(p => p.socket)]);
31
- const results = await Promise.all([...sockets].map(async (socket) => {
32
- const live = processes.filter(p => p.socket === socket);
33
- try {
34
- const stat = lstatSync(socket);
35
- if (!stat.isSocket() || (stat.mode & 0o077) !== 0
36
- || (process.getuid !== undefined && stat.uid !== process.getuid())) {
37
- return { socket, reason: "Host socket ownership cannot be verified." };
38
- }
39
- const snapshot = await inspectAgentHostSocket(socket);
40
- if (live.some(p => snapshot.hostProcess?.pid !== p.pid
41
- || snapshot.hostProcess?.startIdentity !== p.startIdentity)) {
42
- return {
43
- socket, pid: live[0].pid,
44
- nativeSessionId: snapshot.nativeSessionId,
45
- reason: "The live Host process has no exact matching compatibility response (legacy or still starting)."
46
- };
47
- }
48
- const compatibility = snapshot.compatibility;
49
- if (compatibility?.control === AGENT_HOST_CONTROL_PROTOCOL
50
- && compatibility.events === AGENT_HOST_EVENT_PROTOCOL
51
- && compatibility.rpc === FILE_TASK_CONTROLLER_PROTOCOL_VERSION
52
- && compatibility.storage === "controller-owned")
53
- return undefined;
54
- return {
55
- socket,
56
- ...(snapshot.owner === undefined ? {} : { owner: snapshot.owner }),
57
- ...(snapshot.nativeSessionId === undefined ? {} : { nativeSessionId: snapshot.nativeSessionId }),
58
- ...(snapshot.attemptId === undefined ? {} : { attemptId: snapshot.attemptId }),
59
- state: snapshot.state,
60
- reason: compatibility === undefined
61
- ? "Legacy Host has no schema-independent event capability; its loaded code cannot be upgraded in place."
62
- : "Host control/event/RPC compatibility is outside this Controller's supported range."
63
- };
64
- }
65
- catch (error) {
66
- const stillLive = live.find(p => readLinuxProcessIdentity(p.pid)?.startIdentity === p.startIdentity);
67
- if (["ENOENT", "ECONNREFUSED"].includes(error.code ?? "")
68
- && stillLive === undefined)
69
- return undefined;
70
- return { socket, ...(stillLive === undefined ? {} : { pid: stillLive.pid }),
71
- reason: `Live Host compatibility is unconfirmed: ${messageOf(error)}` };
72
- }
73
- }));
74
- return results.filter((entry) => entry !== undefined);
75
- }
76
- export function describeAgentHostUpgradeBlockers(blockers) {
77
- return blockers.map(blocker => [
78
- blocker.owner === undefined ? blocker.socket
79
- : `${blocker.owner.taskId ?? blocker.owner.scope}/${blocker.owner.roleName}`,
80
- blocker.nativeSessionId === undefined ? "" : `Session=${blocker.nativeSessionId}`,
81
- blocker.attemptId === undefined ? "" : `input=${blocker.attemptId}`,
82
- blocker.state === undefined ? "" : `Host=${blocker.state}`,
83
- blocker.pid === undefined ? "" : `PID=${blocker.pid}`,
84
- blocker.reason
85
- ].filter(Boolean).join("; ")).join("\n");
86
- }
87
- function liveHostProcesses(home) {
88
- if (process.platform !== "linux")
89
- return [];
90
- const expected = readHomeFilesystemId(home);
91
- const hosts = [];
92
- for (const name of readdirSync("/proc")) {
93
- if (!/^[1-9][0-9]*$/.test(name))
94
- continue;
95
- const pid = Number(name);
96
- try {
97
- const status = readFileSync(`/proc/${pid}/status`, "utf8");
98
- if (Number(/^Uid:\s+([0-9]+)/mu.exec(status)?.[1]) !== process.getuid?.())
99
- continue;
100
- const args = readFileSync(`/proc/${pid}/cmdline`, "utf8").split("\0");
101
- if (!args.some((arg, i) => /(?:^|\/)cli\.js$/.test(arg)
102
- && args[i + 1] === "internal" && args[i + 2] === "agent-host"))
103
- continue;
104
- const env = readFileSync(`/proc/${pid}/environ`, "utf8").split("\0");
105
- const value = (key) => env.find(entry => entry.startsWith(`${key}=`))?.slice(key.length + 1);
106
- const processHome = value("YUI_HOME");
107
- if (processHome === undefined || readHomeFilesystemId(processHome) !== expected)
108
- continue;
109
- const identity = readLinuxProcessIdentity(pid);
110
- if (identity === undefined || identity.state === "Z")
111
- continue;
112
- hosts.push({ pid, startIdentity: identity.startIdentity,
113
- socket: agentHostControlSocketPath({
114
- home, scope: value("YUI_SESSION_SCOPE") ?? "task",
115
- taskId: value("YUI_TASK_ID"), roleName: value("YUI_ROLE") ?? "unknown-role"
116
- }) });
117
- }
118
- catch {
119
- // Other owners and processes that exited while being read are not this
120
- // Home's proven Hosts. No PID is ever acted on by this read-only inventory.
121
- }
122
- }
123
- return hosts;
124
- }
125
- function messageOf(error) {
126
- return error instanceof Error ? error.message : String(error);
127
- }