@zq-silk/yui 2.10.0 → 2.12.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 (90) hide show
  1. package/dist/artifacts/artifactCapability.js +14 -8
  2. package/dist/artifacts/artifactCommitLock.js +7 -5
  3. package/dist/artifacts/jobArtifact.js +93 -0
  4. package/dist/artifacts/jobArtifactTransport.js +13 -0
  5. package/dist/artifacts/taskArtifactRepository.js +58 -10
  6. package/dist/cli/callerDiscovery.js +18 -0
  7. package/dist/cli/commandCatalog.js +45 -14
  8. package/dist/cli/commandDiscovery.js +2 -3
  9. package/dist/commands/durableJobCommands.js +31 -6
  10. package/dist/commands/globalRoleCommands.js +5 -0
  11. package/dist/commands/scheduleCommands.js +14 -3
  12. package/dist/commands/taskCommands.js +5 -2
  13. package/dist/context/taskCatalog.js +6 -1
  14. package/dist/controlPlaneCli.js +12 -12
  15. package/dist/controller/agentJobControl.js +391 -0
  16. package/dist/controller/controller.js +24 -3
  17. package/dist/controller/fileSchedulerStoreAdapter.js +12 -1
  18. package/dist/controller/globalInputDelivery.js +8 -1
  19. package/dist/controller/jobArtifactControl.js +111 -0
  20. package/dist/controller/jobControl.js +4 -0
  21. package/dist/controller/jobDefinitionControl.js +191 -19
  22. package/dist/controller/jobSupervisor.js +83 -3
  23. package/dist/controller/jobTaskDelegationControl.js +193 -0
  24. package/dist/controller/runtime.js +7 -1
  25. package/dist/controller/scheduleControl.js +83 -20
  26. package/dist/integration/gitIntegrationService.js +2 -0
  27. package/dist/job/agentJob.js +131 -0
  28. package/dist/job/agentJobObservation.js +61 -0
  29. package/dist/job/agentRoleScope.js +33 -0
  30. package/dist/job/durableJob.js +63 -28
  31. package/dist/job/jobAssignmentScope.js +1 -0
  32. package/dist/job/jobBusinessResult.js +72 -0
  33. package/dist/job/jobCleanupInspection.js +4 -0
  34. package/dist/job/jobDefinition.js +26 -2
  35. package/dist/job/jobRunner.js +4 -3
  36. package/dist/job/projectRefreshRunner.js +54 -18
  37. package/dist/job/projectSync.js +162 -0
  38. package/dist/job/scheduleService.js +55 -0
  39. package/dist/job/taskDelegation.js +48 -0
  40. package/dist/message/messageContinuation.js +1 -1
  41. package/dist/resources/projectResourceService.js +1 -1
  42. package/dist/resources/resourceGc.js +1 -1
  43. package/dist/role/role.js +22 -12
  44. package/dist/runtime/managedIdentity.js +5 -3
  45. package/dist/runtime/sessionCaller.js +9 -10
  46. package/dist/schedule/schedule.js +65 -15
  47. package/dist/scheduler/wakeReason.js +4 -0
  48. package/dist/storage/agentJobSchema.js +10 -0
  49. package/dist/storage/maintenanceCaller.js +17 -25
  50. package/dist/storage/nativeSessionLookup.js +23 -0
  51. package/dist/storage/recordValidation.js +2 -0
  52. package/dist/storage/sessionHistorySchema.js +17 -0
  53. package/dist/storage/sqliteSchema.js +96 -11
  54. package/dist/storage/sqliteStore.js +71 -4
  55. package/dist/storage/storageVersions.js +1 -1
  56. package/dist/storage/storeRpc.js +4 -0
  57. package/dist/storage/taskCatalog.js +10 -2
  58. package/dist/storage/upgrade/jobBusinessResultMigration.js +20 -0
  59. package/dist/storage/upgrade/scheduleDispatchMigration.js +15 -0
  60. package/dist/task/archivePreflight.js +15 -0
  61. package/dist/task/completionReadiness.js +7 -0
  62. package/dist/task/task.js +17 -1
  63. package/dist/verification/verificationGateService.js +4 -0
  64. package/dist/web/assets/client/app/catalog.js +16 -0
  65. package/dist/web/assets/client/i18n/en.js +29 -2
  66. package/dist/web/assets/client/i18n/zh-CN.js +29 -2
  67. package/dist/web/assets/client/layout/manageShell.js +9 -0
  68. package/dist/web/assets/client/layout/router.js +1 -0
  69. package/dist/web/assets/client/views/jobs.js +166 -37
  70. package/dist/web/assets/client/views/task/files.js +5 -4
  71. package/dist/web/assets/client/views/task/page.js +5 -1
  72. package/dist/web/taskPreviews.js +2 -2
  73. package/dist/web/webJobs.js +36 -11
  74. package/dist/web/webMaterials.js +21 -9
  75. package/dist/web/webServer.js +6 -5
  76. package/dist/web/webTaskSurface.js +1 -0
  77. package/docs/authorization.md +130 -0
  78. package/docs/job-runs.md +392 -17
  79. package/docs/managed-turn-and-session-runtime.md +10 -5
  80. package/docs/managed-turn-and-session-runtime.zh-CN.md +12 -5
  81. package/docs/release-workflow.md +79 -0
  82. package/docs/release-workflow.zh-CN.md +58 -0
  83. package/docs/schedules.md +69 -15
  84. package/docs/storage-baseline.md +45 -1
  85. package/docs/storage-baseline.zh-CN.md +33 -1
  86. package/docs/testing/verification-levels.md +2 -2
  87. package/docs/testing/verification-levels.zh-CN.md +2 -2
  88. package/package.json +1 -1
  89. package/skills/yui-runtime/SKILL.md +12 -5
  90. package/skills/yui-runtime/VERSION +1 -1
package/docs/job-runs.md CHANGED
@@ -2,11 +2,78 @@
2
2
 
3
3
  A Job is a stable, scoped definition. A JobRun is one execution, with its own
4
4
  ID, configuration revision, trigger, immutable execution specification,
5
- process identity, artifacts and terminal result. Changing a definition never
5
+ process or exact Agent execution identity, artifacts and terminal result. Changing a definition never
6
6
  changes an admitted Run. No Schedule is needed for immediate execution.
7
7
 
8
8
  ## CLI and ownership
9
9
 
10
+ ### Optional Agent execution
11
+
12
+ An Agent configuration selects a logical target, never a permanent native
13
+ Session: `{kind:"operator"}`, `{kind:"task",taskId,roleName,ownerRunId?}`, or
14
+ `{kind:"job",agentId}`. Non-Leader Task targets require the current Assignment's
15
+ exact `ownerRunId`; this does not create or delegate a Task. Task-owned Jobs
16
+ cannot target Operator or another Task. Job-owned Agents reuse ordinary Global
17
+ Role transport but have only their own Job's read/report authority, not
18
+ Operator or Project authority.
19
+
20
+ ```sh
21
+ yui job define --global --job analyze --title "Saved analysis" \
22
+ --input '{"kind":"agent","target":{"kind":"job","agentId":"codex"},"input":"Analyze the saved evidence."}'
23
+ yui job session-create --global --job analyze
24
+ yui job run --global --job analyze --request-id first
25
+ yui job run-context --global --job analyze --run <run-id>
26
+ yui job run-evidence --global --job analyze --run <run-id>
27
+ yui job session-inspect --global --job analyze
28
+ ```
29
+
30
+ `session-create` prepares the logical Role; the normal Host creates its Session
31
+ on delivery. Launch messages contain exact context pointers. The executing Agent
32
+ uses `run-claim`, reads `run-context`, then `run-report --result <JSON>` with the
33
+ normal `JobBusinessResult` envelope (`schemaVersion`, exact `sourceRun`,
34
+ `outcome`, `summary`, `evidence`). Reports require that caller's current accepted
35
+ native Turn to own the original message. The Provider observation path retains
36
+ actual attempts and terminals even when no report is returned. Delivery, native
37
+ terminal and explicit business result remain separate facts. `run-confirm`
38
+ only collects existing evidence; it never replays work.
39
+
40
+ Default execution is serial per Job, reusing its Role Session across Runs.
41
+ Explicit `concurrency:"isolated"` is supported only for Job-owned Agents and
42
+ creates a distinct Role/workspace for each Run; sibling Run contexts remain
43
+ inaccessible to that executor. Existing Provider single-writer and bounded
44
+ classified retry rules still apply. Agent Jobs currently use explicit
45
+ manual/retry admission; a Schedule service grant for engineering actions is
46
+ not authority to execute an Agent.
47
+
48
+ `run-cancel` records a cooperative request on that exact Run. It does not
49
+ interrupt a shared Operator/Task Role or imply that work stopped. Check
50
+ `cancelRequestedAt` before effects and report the actual outcome. An unfinished
51
+ business Run can use `run-continue --expected-attempt <prior-attempt-id>` only
52
+ after its exact native terminal; this
53
+ adds an original continuation message to the same Run, not a new failed-Run
54
+ retry. Repeating the same expected attempt returns the existing successor
55
+ without submitting another message. Inspect prior effects first: terminal does not undo them.
56
+
57
+ For a Job-owned Session, `session-stop --expected-session <native-id>` requests
58
+ existing lifecycle cleanup only after the current native Turn is terminal.
59
+ It returns acceptance, not proof of stop. Inspect until the original Session
60
+ is ended, then `session-new --expected-session <native-id>` preserves its
61
+ history and clears the current Session for the next normal launch.
62
+ Isolated Jobs also require `--run <run-id>` on Session operations.
63
+ Unknown delivery and unproven old writers block replacement/continuation;
64
+ replacement never resubmits input. Definition snapshots, Run requirements,
65
+ explicit results and fixed artifact references survive independently of the
66
+ transcript. Shared targets use their existing Role lifecycle, not Job-owned
67
+ Session operations. CLI and `job.definition` RPC expose the same operations.
68
+ Changing the executor kind requires a new Job ID; revisions can change its
69
+ configuration without hiding another executor's original history.
70
+ Task-owned Agent Jobs participate in Task completion/ordinary archive settlement.
71
+ Archive also requires exact native-terminal evidence; an explicit business
72
+ report alone never proves quiescence. Idle Job-owned Role Sessions and their
73
+ separate scratch workspaces are retained, not silently deleted by Task archive.
74
+
75
+ ### Engineering execution
76
+
10
77
  Commands operate through the Controller's `job.definition` RPC:
11
78
 
12
79
  ```sh
@@ -15,6 +82,9 @@ yui job define --global --job probe --title "Local probe" \
15
82
  yui job run --global --job probe --request-id first
16
83
  yui job runs --global --job probe
17
84
  yui job run-get --global --job probe --run <exact-run-id>
85
+ yui job run-result --global --job probe --run <exact-run-id>
86
+ yui job run-evidence --global --job probe --run <exact-run-id>
87
+ yui job run-confirm --global --job probe --run <exact-run-id>
18
88
  yui job logs --global --job probe --run <exact-run-id>
19
89
  yui job run-cancel --global --job probe --run <exact-run-id>
20
90
  ```
@@ -27,11 +97,23 @@ with `job show`, listed with `job list`, and revised with `job update --revision
27
97
  <observed-revision> --title ... --input ...`. A definition ID is required on
28
98
  creation; replaying an identical creation is idempotent. Scope cannot be updated.
29
99
 
30
- Global Job management requires the current authenticated Operator Session.
100
+ Global Job management accepts public local callers or the current authenticated
101
+ Operator Session. A public caller uses `scope:user` with no managed identity
102
+ fields. The normal CLI first resolves native conversation identity against the
103
+ selected Home: unknown provider conversations remain public, while known
104
+ managed, historical, partial or revoked identities never fall back to user.
105
+ The local Controller socket is a single-user Home boundary, not a remote
106
+ authentication endpoint; `scope:user` is not a token granting Task or shell access.
31
107
  Other GlobalRoles cannot inspect or manage Task Job definitions either, matching
32
108
  the existing Task Context authorization boundary.
33
- Users can request it through Operator. Literal `caller.scope=user` is not a
34
- credential on the existing Controller socket. Task Sessions cannot inspect,
109
+ Public immediate admissions bind the exact Home, Run, definition revision,
110
+ target/input and trigger; they need no Agent configuration, Operator, Session
111
+ or empty Task. They do not enqueue an Agent wake on completion. This is not a
112
+ persistent Schedule grant: public `source:schedule` admission is rejected.
113
+ The separate [Schedule management API](schedules.md) offers an explicit
114
+ revocable service grant without an Operator Session; existing plans retain
115
+ their Session authority until deliberately rebound.
116
+ Task Sessions cannot inspect,
35
117
  create, modify or run global Jobs. The initial global action is `system.noop`,
36
118
  a fixed local no-op implemented by the same standalone runner. It accepts only
37
119
  empty input and no Project; it does not call a model or external service.
@@ -67,7 +149,8 @@ authoritative Task Run table, with `definitionId`, `definitionRevision` and
67
149
  `trigger` added to each payload. This retains every Task-local Run ID and
68
150
  artifact location. Global Runs have `scope:"global"` and no `taskId`, Task or
69
151
  Assignment. They use the same execution state machine and supervisor; their
70
- terminal notices enter the Operator mailbox, never a Task Leader mailbox.
152
+ Operator-admitted terminal notices enter the Operator mailbox, never a Task
153
+ Leader mailbox. Public immediate Runs are read directly without Agent delivery.
71
154
 
72
155
  The centralized transactional migration maps each old DurableJob to one
73
156
  definition with the same local ID and one preserved Run. Equal commands are
@@ -79,6 +162,135 @@ dual-format reader. A failed migration rolls back without advancing storage.
79
162
  Actual Home upgrades require their own authorization and backup; this change
80
163
  does not authorize or perform one.
81
164
 
165
+ Storage **1.14 → 1.15** adds `businessResult` to terminal Run payloads and public
166
+ immediate authority bindings to new Runs. Original terminal payload bytes are
167
+ archived under migration 15; the migration derives only the recorded outcome
168
+ and a versioned reference to the unchanged process result. It never parses logs,
169
+ invents domain data, rewrites Integration references or changes active Run
170
+ identities. Ordinary readers use only the current contract.
171
+
172
+ ## Business outcome and evidence
173
+
174
+ `run-result` returns the admitted snapshot, `acceptedAt`, `startedAt`,
175
+ `confirmedAt`, current `status` and nullable `result`. Acceptance is not start;
176
+ start is not confirmation. The snapshot is derived exclusively from the immutable
177
+ Run fields, never a mutable current Job definition. Scope, executor (`shell` or
178
+ controlled `builtin`, or `task`), target and trigger are separate concepts. Task
179
+ delegation is available in either management scope; shell remains Task-only and
180
+ builtin remains global-only. There is no extensible empty
181
+ executor/plugin configuration or arbitrary global shell.
182
+
183
+ ## Delegating delivery to a Task
184
+
185
+ Job scope answers **who manages the definition**, Run delegation answers **which
186
+ delivery is requested**, and immutable `Task.source` answers **why it was created**.
187
+ Neither relation is an authority parent. A global Job remains global; a Job
188
+ owned by A can create B without appearing in B's managed Jobs list.
189
+
190
+ An explicit Task executor configuration creates a new Draft per independent Run:
191
+
192
+ ```json
193
+ {"kind":"task","goal":"delivery","target":{"kind":"new","title":"Deliver report","description":"Requirements and acceptance here.","projectBindings":[]}}
194
+ ```
195
+
196
+ `target.type` is optional business metadata, not an automation discriminator.
197
+ Project bindings use the ordinary Draft `{projectId,directory,baseRef}` contract.
198
+ `goal:"task-created"` is the explicit alternative when creation really is the
199
+ entire goal. It must never be used as a shortcut for delivery.
200
+
201
+ Use ordinary `job define` / `job run`. Task, configured Leader, exact scoped
202
+ Run and its immutable relation are committed in the **same SQLite transaction**.
203
+ Repeating the same admitted trigger returns the original Run/Task, including
204
+ after restart or completion; conflicting definition revisions are refused.
205
+ New independent Runs create new Tasks, never reopen an old cycle.
206
+ Missing Leader configuration or failed persistence rolls back the whole admission.
207
+ Creation does not authorize execution: the target starts Draft; use existing
208
+ Task submit/develop and Activation with the caller's own target authority.
209
+ The Task owns its Leader, optional WorkItems, acceptance, Integration and archive.
210
+ There is no Job Leader, JobWorkItem or second delivery state.
211
+
212
+ For an existing ordinary Task, first create an explicit open WorkItem through
213
+ its ordinary authorized interface, then bind it precisely:
214
+
215
+ ```json
216
+ {"kind":"task","goal":"work-item","target":{"kind":"work-item","taskId":"task-12","workItemId":"work-item-3","revision":1}}
217
+ ```
218
+
219
+ The Job does not rewrite the Task's source. Admission captures the WorkItem's
220
+ requirements digest and observed revision. Execution/candidate revisions can
221
+ advance; changed requirements yield `unknown-needs-attention`, never guessed
222
+ acceptance. Only its exact accepted Candidate settles the Run, not an Agent
223
+ terminal, an unaccepted Candidate or the entire shared Task.
224
+ Unscoped actions, arbitrary existing-Task completion waits and ambiguous targets
225
+ are rejected. A Task Leader can bind only its own Task's exact WorkItem under
226
+ its current writable delivery Session. Cross-Task creation/selection requires
227
+ the existing Operator authority; public immediate global requests use actual
228
+ user scope, never an invented Operator. Schedule service grants for builtin
229
+ actions do not authorize Task delegation.
230
+
231
+ The supervisor and `job run-confirm` collect existing delivery facts only.
232
+ Delivery success pins the first exact `task.completed` event of the new target;
233
+ WorkItem success pins its accepted Candidate. `task-result`/`work-item-result`
234
+ evidence retains source Run, Task owner, relative locator and SHA256 of the
235
+ original JSON object. Later reopen cannot rewrite a settled Run. These are result
236
+ references, not copied Task bodies or an authorization to read arbitrary Context.
237
+ Task executors use a distinct Run variant without process configuration,
238
+ workspace or process evidence. They never spawn a runner and expose
239
+ `execution:null` in snapshots.
240
+
241
+ Select formal materials separately using the existing `artifact-register`
242
+ interface and its source-Task plus Run authorization. Artifacts remain in their
243
+ Task repository and pin owner, commit, path, digest and consuming Run. Only
244
+ selected immutable objects become readable; no HEAD, directory or source-Task
245
+ write access is inherited.
246
+
247
+ `job run-delegation (--global|--task A) --job ID --run RUN` reports the exact
248
+ target, state, open-input count and result reference. `task show B --json` exposes
249
+ immutable source and a bounded incoming-delegation projection (with `complete`);
250
+ `task list --source ordinary|job` filters creation origin. Incoming Run waits and
251
+ uncertainty join the existing catalog `pendingOperations`/`unknownOperations`
252
+ attention; target InputRequests remain in `openInputs`. These are current
253
+ projections, not independent lifecycle records. Complete UI belongs elsewhere.
254
+
255
+ `run-cancel` requests cancellation of this Run's delegation. Confirmation
256
+ settles that wait as cancelled and explicitly reports **target resources not
257
+ stopped**. It does not cancel/retire the shared WorkItem, stop the target Leader,
258
+ or prove quiescence. Inspect/stop exact target resources through their normal
259
+ authority if needed. Disabling a Schedule still affects future admissions only.
260
+ Source never grants merge, publishing, cleanup or archive authority.
261
+
262
+ Storage **1.18 → 1.19** adds optional immutable Task provenance and Run delegation
263
+ and the new result-reference kinds without changing SQL layout or historical
264
+ payload bytes. Ordinary historical Tasks remain source-less; unknown process
265
+ effects, fixed artifacts and existing Schedule authorization stay untouched.
266
+
267
+ `JobBusinessResult` has `schemaVersion:1`, exact `sourceRun:{scope,runId}`, an
268
+ `outcome`, human-readable `summary`, optional JSON `data`, and `evidence`.
269
+ Each evidence reference carries `kind`, `owner`, `sourceRun`, a SHA-256 `version`
270
+ of the referenced bytes, and `locator`. These are evidence references, not a file
271
+ artifact library; future file artifacts must preserve their own owner/version
272
+ and source Run rather than treating a path as identity. Results are bounded to
273
+ 256 KiB. Shell results describe the process contract only; they cannot infer
274
+ domain success from arbitrary log text. `system.noop` reports its controlled
275
+ action. Project refresh reports observed commits/tracking and domain failures.
276
+
277
+ `run-evidence` returns the exact operation receipts, PID/start identity,
278
+ checkpoint, `processResult` and artifact location. The existing Run `result`
279
+ field remains the original process evidence for Integration and existing readers;
280
+ `businessResult` and `status` represent business outcome. A successful process
281
+ does not prove a builtin business effect: missing/invalid business receipts yield
282
+ `unknown-needs-attention` and block overlap/retry. Historical results contain
283
+ only what their saved evidence proved, without invented structured data.
284
+
285
+ The Project action writes `business-result.json` separately from stdout.
286
+ Failure to save it after an effect is unknown, not an automatically retryable
287
+ failure. A database collection failure leaves the original receipt and active Run
288
+ available for later collection. `run-confirm` authenticates the exact Run and
289
+ collects only retained ready/exit/checkpoint/business evidence; it never admits,
290
+ spawns, retries or cancels an action. Repeated confirmation is idempotent.
291
+ Terminal outcomes remain immutable; acknowledging an unknown is not success
292
+ and does not authorize replay. There is no caller-supplied outcome override.
293
+
82
294
  IntegrationAttempt and verification consumers still use
83
295
  `getDurableJob(taskId, exactRunId)`. Existing Task Context `job` entries,
84
296
  execution audit, readiness/archive checks and HTTP preview tickets likewise
@@ -87,13 +299,123 @@ Task completion. Started Runs and retained unknown process evidence keep the
87
299
  existing Task lifecycle and physical-cleanup boundaries. The management UI
88
300
  retains exact references rather than replacing them with latest.
89
301
 
302
+ ## Formal file artifacts
303
+
304
+ Jobs can save formal material without a Task or Session. The existing
305
+ `job.definition` RPC also accepts `artifact-save`, `artifact-list`,
306
+ `artifact-read`, `artifact-preview` and `artifact-register`, with the same
307
+ `scope`, definition `id`, exact `runId` and authenticated `caller` boundaries.
308
+ The CLI resolves that caller; do not supply or fabricate one:
309
+
310
+ ```sh
311
+ yui job artifact-save --global --job probe --run <run-id> \
312
+ --artifact '{"relativePath":"reports/result.md","content":"# Result\n\nEvidence","message":"Record result"}'
313
+ yui job artifact-list --global --job probe --run <run-id>
314
+ yui job artifact-read --global --job probe --run <run-id> \
315
+ --reference '<exact reference object returned by save/list>'
316
+ yui job artifact-preview --global --job probe --run <run-id> \
317
+ --reference '<exact registered reference object>' --offset 0
318
+ yui job artifact-register --global --job probe --run <run-id> \
319
+ --reference '<exact already-saved reference object>'
320
+ ```
321
+
322
+ Save input also accepts `expectedHead` for optimistic concurrency and
323
+ `encoding:"base64"` for static PNG/JPEG/WebP. The shared repository accepts
324
+ text up to 8 MiB and decoded images up to 4 MiB, with dimension/format
325
+ validation; Job reference paths are limited to 512 characters.
326
+ The **Job CLI/RPC save payload is additionally limited to 256 KiB of encoded
327
+ JSON; read/preview responses allow 512 KiB** to include the added reference and
328
+ presentation metadata. Both count JSON escaping/base64 inside the Controller's
329
+ 1 MiB envelope. The CLI checks saves before
330
+ transmission. Larger producer-saved or delegated Task material may still be
331
+ registered by its small exact reference: use paged preview for large text,
332
+ or the owning Task's surface for larger images. No file is truncated.
333
+ Preview otherwise shares the Task preview rules: whole Markdown up to
334
+ 256 KiB, paged text (12,000 characters with `nextOffset`), static raster
335
+ metadata/base64, and no SVG or executable HTML. HTML is text data, never
336
+ executed; clients must use the existing safe renderer.
337
+
338
+ Save/register returns `{status:"registered",reference}` only after the file is
339
+ committed **and** the Run reference is recorded. If the commit exists but
340
+ publication fails, it instead returns
341
+ `{status:"saved-unregistered",reference,error,recovery}`. This is partial
342
+ success, not a published result. Inspect the exact Run and `artifact-list`,
343
+ then explicitly register the retained reference. Never retry the business
344
+ action to repair missing material registration. A lost RPC reply is unknown:
345
+ inspect first. Git save failures preserve written working files and existing
346
+ commits; expected-HEAD conflicts write nothing.
347
+
348
+ A reference is:
349
+
350
+ ```json
351
+ {
352
+ "kind": "artifact",
353
+ "owner": {"kind": "job", "scope": {"kind": "global"}, "jobId": "probe"},
354
+ "sourceRun": {"scope": {"kind": "global"}, "runId": "<exact-run-id>"},
355
+ "version": "<full Git commit>",
356
+ "relativePath": "reports/result.md",
357
+ "digest": "<SHA-256 of file bytes>"
358
+ }
359
+ ```
360
+
361
+ Unlike process-evidence `version` (SHA-256), an artifact's `version` is a full
362
+ Git commit; its separate `digest` checks content. Reads require a registered
363
+ exact reference, never HEAD, an ambient Task, or a bare filename. A Run's
364
+ `artifacts` is an append-only list: later saves cannot replace earlier entries.
365
+ The original `businessResult`, `result`, outcome and terminal evidence remain
366
+ unchanged when material is collected after execution.
367
+
368
+ Repositories live under
369
+ `YUI_HOME/job-artifacts/global/<job-id>/<run-id>/` or
370
+ `YUI_HOME/job-artifacts/task/<task-id>/<job-id>/<run-id>/`.
371
+ Each Run has a distinct worktree and scoped commit lock, so even the same
372
+ definition/path in concurrent Runs or different scopes cannot overwrite one
373
+ another. They reuse the Task repository's local-only Git, path/symlink guards,
374
+ size limits and commit protocol. Task repositories stay at their existing
375
+ `task-artifacts/<task-id>` paths; all old commit-pinned Candidate, Review and
376
+ completion references remain valid.
377
+
378
+ `artifact-list.artifacts` lists **published** references.
379
+ `repository.saved` describes the retained current Git snapshot for diagnosis
380
+ and explicit registration; it is not publication. `repository.workingChanges`
381
+ distinguishes uncommitted files. `job runs` and `run-result.artifacts` retain
382
+ history; `job show`/`list` derive `results.latest` and
383
+ `results.latestSuccessful` independently from readable Runs. A later failure
384
+ does not hide the last success. Same-name versions are the entries with that
385
+ `relativePath` across these Run histories, not a separately writable final file.
386
+
387
+ For delegated Task material, an authorized Leader or Operator explicitly
388
+ registers `owner:{"kind":"task","taskId":"task-N"}` with the selected original
389
+ commit/path/digest and the consuming Run's `sourceRun`. Registration must pass
390
+ both the Run's existing Assignment checks and the source Task's authorization.
391
+ An Assignment reader cannot mint this selection. Subsequent Run readers may
392
+ read **only that selected immutable object**, not the Task's HEAD, other
393
+ files, or writes. The file stays in the Task repository; no copy or authority
394
+ transfer occurs. The old same-Task `git:<commit>:<path>` shorthand is not
395
+ accepted as a cross-entity reference. Task delegation admission itself belongs
396
+ to its separate feature; this is the selected-material seam.
397
+
398
+ Storage **1.16 → 1.17** declares the optional append-only Run references and
399
+ Job-owned repository layout. It preserves existing payload bytes, process
400
+ history, Task repositories and frozen references, and invents no historical
401
+ artifacts. This is not a package-version release or an automatic Home upgrade.
402
+
403
+ Formal repositories and referenced objects are retained by default. Replacing
404
+ a Session, removing execution workspaces/logs, disabling a Schedule or ordinary
405
+ Task archive does not delete them. There is no automated artifact GC or delete
406
+ command. Manual cleanup requires separately authorized inspection of exact
407
+ owners and references; do not remove repositories/commits still referenced by
408
+ Runs, Candidates, Reviews or completion evidence. Retain uncertain ownership
409
+ and unregistered/dirty evidence for diagnosis. This does not turn logs,
410
+ heartbeats, checkpoints, Knowledge or Project state into formal artifacts.
411
+
90
412
  ## Extension seams for Schedule, Project refresh and management UI
91
413
 
92
414
  - `src/job/jobDefinition.ts`: `JobDefinition`, `JobScope`, `JobConfiguration`
93
415
  and `JobTrigger`. Definition revision is optimistic concurrency, not a Run
94
416
  status. Project targets stay in configuration.
95
417
  - `src/controller/jobDefinitionControl.ts`: `admitJobRun(store, home, scope,
96
- definitionId, caller, trigger, now, retryOf?)` returns `RunAdmission`.
418
+ definitionId, caller, trigger, now, retryOf?, service?)` returns `RunAdmission`.
97
419
  It authenticates current scope, rechecks domain prerequisites, finds exact
98
420
  trigger replay and excludes overlap inside the Store transaction. Schedule
99
421
  can call it inside its own `store.transaction` with advancement in that same
@@ -101,7 +423,11 @@ retains exact references rather than replacing them with latest.
101
423
  A rollback discards both. `source:"schedule"` is an internal seam, not an
102
424
  accepted manual RPC assertion. Schedule must supply a legitimate current
103
425
  authority; it must not invent a Session or reuse a revoked identity. Any
104
- additional durable scheduled-intent authorization belongs to that feature.
426
+ service reference is internal only and must match a current stored Schedule
427
+ grant; RPC never accepts it. `instantiateJobRun` owns deterministic instance
428
+ creation from an exact definition revision and composes the same admission
429
+ inside the caller's transaction. Instance creation, first Run and Schedule
430
+ advancement either all commit or all roll back.
105
431
  - `src/job/builtinJob.ts`: controlled action compilation. Add a narrowly
106
432
  validated builtin here; snapshot its target/input and compile runner steps
107
433
  from trusted code, never caller-supplied shell. Revalidate before spawn.
@@ -120,7 +446,7 @@ daemon, cross-Task dependency engine or release behavior.
120
446
 
121
447
  ## Controlled Project refresh
122
448
 
123
- An authenticated Operator can explicitly install one maintenance definition
449
+ A public local caller or authenticated Operator can explicitly install one maintenance definition
124
450
  per registered managed Project, inspect it, and request independent Runs:
125
451
 
126
452
  ```sh
@@ -185,8 +511,9 @@ remote observation. Missing exit evidence, timeout or cancellation must not be
185
511
  presented as successful synchronization; inspect retained evidence before retry.
186
512
  The Run's all-zero `head` is not a Project revision; use the action's observations.
187
513
 
188
- No persistent envelope/table change is needed: action input and output use the
189
- existing JobDefinition/JobRun JSON and logs. Schedule should reference this same
514
+ Action input uses the existing JobDefinition configuration; structured output
515
+ uses the 1.15 business result alongside unchanged process evidence/logs.
516
+ Schedule should reference this same
190
517
  global definition and use its existing admission seam, never a second Project
191
518
  automation state. The isolated core scenario covers interval-triggered refresh
192
519
  Runs, missed-period coalescing and disable behavior against a local Git remote.
@@ -197,9 +524,12 @@ This does not enable a cadence for any real Project.
197
524
  The Task's **Jobs** tab manages only that Task. **Settings → Jobs & schedules**
198
525
  manages global definitions. Both use the same component and public services.
199
526
  Create/edit a definition, run it immediately, select an exact historical Run
200
- and read its snapshot/results/logs, or request cancellation of that Run.
527
+ and read its snapshot/results/diagnostics, or request cancellation of that Run.
201
528
  Task shell configuration uses the same explicit managed-workspace specification
202
- as the CLI; global creation offers only `system.noop` and `project.refresh`.
529
+ as the CLI. Global controlled actions remain `system.noop` and `project.refresh`;
530
+ Task-delegation and Agent definitions use their documented configuration, without
531
+ inventing process fields. Executor kind cannot be changed on an existing definition.
532
+ Builtin definitions have no arbitrary configuration editor.
203
533
  Creating or reading a Job never executes it.
204
534
 
205
535
  The HTTP routes are `/api/tasks/:taskId/jobs|schedules` and
@@ -207,11 +537,10 @@ The HTTP routes are `/api/tasks/:taskId/jobs|schedules` and
207
537
  takes the corresponding public operation fields, with `requestId` for manual
208
538
  Run admission. Routes fix scope. Browser-supplied `caller`, `scope` or trigger
209
539
  authority is rejected. The loopback token authenticates the local-user ingress,
210
- and writes additionally require an exact same Origin. The adapter resolves the
211
- current Operator Session from the server store on every call; if none is
212
- available, management reports that prerequisite rather than fabricating one.
213
- Its accepted Jobs/Schedules retain the normal Operator binding/revocation
214
- semantics. Managed RPC callers retain their existing authentication and cannot
540
+ and writes additionally require an exact same Origin. Global management uses the
541
+ authenticated local user, without requiring an Operator Session. Task-scoped
542
+ management resolves the current Operator binding, preserving existing Task and
543
+ Assignment checks. Managed RPC callers retain their authentication and cannot
215
544
  borrow this local-user adapter.
216
545
 
217
546
  Schedule forms support once, anchored interval and five-field cron with an
@@ -222,3 +551,49 @@ successful. Errors retain the draft; an unknown write is not automatically
222
551
  resent. Refresh only reads facts and keeps the selected Run exact. No new
223
552
  tables, scheduling loop, Project switch, implicit refresh or deletion semantics
224
553
  are introduced.
554
+
555
+ ### Product navigation and fixed evidence
556
+
557
+ The daily Task list defaults to ordinary Tasks. Its ordinary / Job execution /
558
+ all selector uses the existing server-side `source` catalog filter. Searching
559
+ or opening an attention category searches across both categories; source is
560
+ creation provenance, not Task business type. The CLI and Operator catalog
561
+ defaults are unchanged.
562
+
563
+ An execution Task links back to its immutable `Task.source` Job/Run. A delegated
564
+ Run links to its actual target Task, whose Jobs tab still lists only definitions
565
+ owned by that target. Links use `/?task=A&section=jobs&job=J&jobRun=R` or
566
+ `/settings/jobs?job=J&jobRun=R`. A Schedule's last admission links to the recorded
567
+ instance Job, which can differ from its template.
568
+
569
+ Run details separate business results, structured evidence, registered artifacts
570
+ and process logs. Agent diagnostics use Agent-aware evidence, not process logs;
571
+ a diagnostic failure does not hide the Run's business result. Most recent Run,
572
+ most recent successful Run, Project refresh observations and Schedule admission
573
+ checks remain distinct. Refresh errors label retained facts as stale.
574
+
575
+ Read-only `artifact-list` and `artifact-preview` are exposed on the same
576
+ scope-fixed GET route. Preview requires `runId`, a JSON `reference`, and optional
577
+ nonnegative `offset`; duplicate/unknown query fields are rejected. The existing
578
+ artifact controller rechecks authorization after Git I/O and reads only a
579
+ registered exact owner/Run/commit/path/digest. Text pagination, raster validation,
580
+ Markdown limits and transport bounds are unchanged. The shared Task viewer
581
+ renders Job evidence, but linked images must also be individually registered;
582
+ there is no directory or HEAD fallback. Selected artifact references survive
583
+ refresh/reload in the `artifact` view parameter and are matched against the
584
+ selected Run's registered references before reading.
585
+
586
+ `artifact-register` POST publishes one explicit saved reference. Inspecting
587
+ unregistered saved files does not make them formal results. A partial
588
+ `saved-unregistered` receipt is shown as such; it never starts business work.
589
+ Artifact I/O runs outside synchronous SQLite transactions, retaining the
590
+ controller's short publication transaction and original partial-result contract.
591
+
592
+ `session-inspect` GET and `session-stop`/`session-new` POST are only offered for
593
+ Job-owned Agent targets. Mutations include the observed `expectedSessionId`
594
+ (and exact Run for isolated execution); the domain rejects unknown writers,
595
+ unsettled input or stale identities. Stop requests cleanup, replacement requires
596
+ confirmed termination, and neither replays input. Run cancellation is cooperative
597
+ and does not stop a delegated Task or interrupt a shared Operator/Leader.
598
+ Task stopping remains an explicit action on the target Task. Archive/cleanup
599
+ are separate operations, not consequences of disabling, cancelling or replacing.
@@ -42,14 +42,19 @@ automatically create Runs. Explicit dispatch loads one exact Run Context Pack.
42
42
  ### Current caller and durable handling
43
43
 
44
44
  Desktop and TUI use the same current-Session authority. A Desktop command carrying
45
- only `CODEX_THREAD_ID` resolves its owner from the selected Home's existing active
46
- Session inventory, then verifies the current Role/Agent binding, revocation and
45
+ only `CODEX_THREAD_ID` resolves its owner from the selected Home's current and
46
+ historical Session records, then verifies the current Role/Agent binding, revocation and
47
47
  captured workspace. Codex's native ID takes precedence over an inherited transport
48
- ID, so a native child cannot borrow its parent's identity. Unknown native IDs,
49
- wrong Homes and conflicting hints fail closed; only a terminal with no managed or
50
- native identity is a plain user. Environment variables and a Manifest locate
48
+ ID, so a native child carrying inherited Yui hints cannot borrow its parent's identity.
49
+ An unknown provider ID alone is an ordinary public caller; partial Yui identity,
50
+ known historical identities and conflicting hints fail closed. A wrong Home with
51
+ Yui hints is rejected. A thread known only in another Home cannot be distinguished
52
+ from an ordinary thread without those hints; Yui does not scan other Homes.
53
+ Environment variables and a Manifest locate
51
54
  context, not continuing authority. A replaced Session retains only its bounded
52
55
  self-diagnostic reads, not inbox or mutation permission.
56
+ See [authorization responsibilities and matrix](authorization.md) for the public
57
+ surface, discovery semantics and resource boundaries.
53
58
 
54
59
  `yui inbox list` exposes the current identity, delivery evidence, handling state
55
60
  and blockers separately. Reads never consume input. Automatically accepted
@@ -5,11 +5,18 @@
5
5
  ## 当前身份与持久处理回执
6
6
 
7
7
  桌面与 TUI 使用相同的当前 Session 授权。只有 `CODEX_THREAD_ID` 的桌面命令
8
- 先在所选 Home 的现有活动 Session 索引中定位角色,再校验当前绑定、撤销状态、
9
- 工作域和 Assignment。Codex 原生线程 ID 优先于继承的 transport ID,原生子
10
- Agent 不能借用父身份。错误 Home、未知线程和冲突提示会明确拒绝,不降为公共
11
- 用户;只有不带受管或原生身份的终端才是普通用户。环境变量和 Manifest 是
12
- 定位提示,不是持续授权。旧 Session 仅保留限定的自身诊断读取。
8
+ 先在所选 Home 的当前及历史 Session 记录中定位角色,再校验当前绑定、撤销状态、
9
+ 工作域和 Assignment。Codex 原生线程 ID 优先于继承的 transport ID,携带父会话
10
+ Yui 提示的原生子 Agent 不能借用父身份。只有未知原生线程 ID、没有 Yui 专属身份
11
+ 提示的普通会话,与用户终端共享现有公共入口,无需 Manifest 即可读取公共信息和
12
+ 创建 Draft;不会因此启动讨论/开发,也不会获得内部受管能力。
13
+ 部分受管身份、已知历史身份、冲突提示,以及带 Yui 提示的错误 Home 保持拒绝。
14
+ 仅在其他 Home 登记、当前 Home 完全未知的裸线程 ID 无法与普通线程区分,必须
15
+ 保留受管会话的正确 Home/Manifest 上下文,不能清空身份字段或切换 Home 绕权。
16
+ 环境变量和 Manifest 是定位提示,不是持续授权。旧 Session 仅保留限定的自身诊断读取。
17
+ 完整角色提示仍可生成离线帮助模板;只有原生 ID 时需只读查询本地登记,失败则显示
18
+ 有限的 unbound 模板。帮助均不是精确授权。职责和权限矩阵见
19
+ [authorization.md](authorization.md)。
13
20
 
14
21
  `yui inbox list` 分别返回当前身份、投递事实、处理状态和阻断原因。自动接受的
15
22
  Global 消息、已投递的 Leader 窗口及当前 Assignment 续接消息仍须显式 claim,
@@ -51,6 +51,85 @@ 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.12.0 compatibility and migration notes
55
+
56
+ This minor completes the scoped Job platform: explicit business results and fixed
57
+ artifacts, Schedule targets and service authorization, controlled Project refresh,
58
+ Task delegation, optional Agent execution, and shared Task/global Web management.
59
+ The Task Jobs tab and Settings → Jobs & schedules expose exact historical Runs,
60
+ their immutable configuration, execution evidence and authorized artifact previews.
61
+
62
+ Consumers must distinguish definition ownership, execution target, process/native
63
+ terminal evidence and the explicit `businessResult`; delivery or exit alone is
64
+ not business success. Branch on the executor kind instead of assuming every Run
65
+ is a shell process. Fixed artifact references retain their exact source identity
66
+ and scope; a readable preview is not execution authority. Task delegation preserves
67
+ immutable provenance and does not implicitly activate a Draft Task. Agent Session
68
+ replacement preserves Run requirements/results without replaying input; unknown
69
+ delivery or unproven old writers still block replacement.
70
+ See [Jobs and Runs](job-runs.md).
71
+
72
+ Schedules retain their existing admission path, not a second execution state.
73
+ Service authorization is explicit and does not inherit an old Session's authority
74
+ or authorize Agent execution. Controlled `project.refresh` binds the current
75
+ managed Project target and uses the existing clean, verified fast-forward path;
76
+ publication does not enable synchronization for any registered Project.
77
+ See [Schedules](schedules.md).
78
+
79
+ Storage advances from **1.14 to 1.20** through the centralized contiguous chain:
80
+ **1.15** business results; **1.16** Schedule targets/service authorization;
81
+ **1.17** fixed Run artifacts; **1.18** controlled Project refresh;
82
+ **1.19** Task delegation/provenance; **1.20** Agent Run/Session evidence.
83
+ Supported **1.0–1.19** Homes use the declared same-major migrations, preserving
84
+ historical evidence rather than inventing results or grants. With separate update
85
+ authorization, use `yui update --version 2.12.0`; the updater owns preflight,
86
+ backup, migration and Controller handover. Do not open upgraded Homes with an
87
+ older binary or edit storage manually. Minor numbering is not a SemVer
88
+ backward-compatibility promise.
89
+
90
+ Release gates require exact-commit Core CI and fresh installation of the same
91
+ runtime tarball on Linux x64 and macOS x64/arm64 with Node 20/22/24/26 before
92
+ publication. These are deterministic isolated checks, not real-model validation.
93
+ Publishing does not update the global CLI, migrate a production Home, replace
94
+ its Controller or run a real Project synchronization.
95
+
96
+ ### 2.11.0 compatibility and migration notes
97
+
98
+ This minor lets ordinary, unmanaged native Agent conversations use the same
99
+ public operations as a local terminal, including general information reads and
100
+ Draft Task creation. A native thread ID alone is a lookup hint, not proof of a
101
+ managed Role. Draft creation preserves configured Agent, model, permissions and
102
+ Profile inheritance; it does not start discussion or development.
103
+
104
+ Current ID-only managed Desktop conversations retain their Role, Task,
105
+ Assignment and Grant checks. Known historical, stopped, conflicting or
106
+ incompletely specified managed identities are refused, never downgraded to
107
+ public authority. Unbinding a Session or deleting a Role retains stopped
108
+ identity history. Help and completion share caller discovery; offline Role
109
+ templates are guidance, not authorization. Exact capability assessment and
110
+ execution continue to use current resource and Grant boundaries.
111
+ See the [authorization responsibility and permission matrices](authorization.md).
112
+
113
+ Identity lookup is local to the selected Home. A bare ID known only in another
114
+ Home, or whose history was already deleted by an older version, cannot be
115
+ distinguished from an ordinary thread without Yui hints. Managed conversations
116
+ must retain the correct Home/Manifest; this release neither scans other Homes
117
+ nor reconstructs deleted history.
118
+
119
+ Storage advances from **1.13 to 1.14** through an explicit centralized migration
120
+ that allows global Session history to survive Role deletion while preserving
121
+ existing payloads. Supported **1.0–1.13** Homes use the contiguous same-major
122
+ upgrade path. With separate update authorization, use
123
+ `yui update --version 2.11.0`; the updater owns preflight, backup, migration and
124
+ Controller handover. Do not open upgraded Homes with an older binary or edit
125
+ storage manually. Package minor numbering is not a compatibility promise.
126
+
127
+ Release gates reuse exact-commit Core CI and exercise one runtime tarball on
128
+ Linux x64 and macOS x64/arm64 with Node 20/22/24/26 before npm publication.
129
+ These are deterministic, isolated checks, not real-model validation. Publication
130
+ does not update a global CLI, migrate a production Home, replace a production
131
+ Session or start a Web listener.
132
+
54
133
  ### 2.10.0 compatibility and migration notes
55
134
 
56
135
  This stable minor includes exact-turn inbox handling and successor recovery