omnius 1.0.772 → 1.0.774

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.
@@ -0,0 +1,770 @@
1
+ # WO-56: Evidence-driven objective loop and nonblocking execution
2
+
3
+ **Status:** repository implementation complete; live Telegram acceptance remains an external gate
4
+ **Priority:** P0
5
+ **Incident:** September 27, 2026, Telegram SSH-over-Cloudflare task spiral and TUI freeze
6
+ **Owner:** Omnius orchestration, execution, and Telegram runtime
7
+ **Depends on:** WO-05, WO-21, WO-27, WO-41, WO-44, WO-49, WO-54, WO-55
8
+ **Completion rule:** A checkbox may be marked complete only when its code,
9
+ named deterministic tests, and evidence entry in this document all exist.
10
+
11
+ ## Objective
12
+
13
+ Implement one host-owned control loop that continuously reconciles the original
14
+ user request with typed runtime evidence. The loop must determine whether to
15
+ continue, verify, deliver, ask for input, report a real external blocker, or
16
+ offer another bounded work cycle. It must prevent an agent from repeating an
17
+ already successful external effect merely because an invalid or out-of-scope
18
+ verifier failed.
19
+
20
+ The same repair must remove synchronous privilege-elevation work from the Node
21
+ event loop. A remote SSH authentication failure must never be interpreted as a
22
+ local privilege request or freeze the TUI.
23
+
24
+ This work order is host-neutral at the orchestration layer. Telegram is the
25
+ first required integration because it exposed the incident, but objective
26
+ reconciliation, progress accounting, effect receipts, and suspension state
27
+ must remain reusable by the CLI, daemon, and future surfaces.
28
+
29
+ ## Incident outcome that the controller must produce
30
+
31
+ For the observed request to create a new SSH-over-Cloudflare endpoint and
32
+ return it:
33
+
34
+ 1. A Cloudflare registration URL is evidence that an endpoint was created.
35
+ 2. Reaching the remote SSH service through that endpoint is transport
36
+ verification.
37
+ 3. A later SSH credential rejection is downstream account authentication. It
38
+ is not evidence that the tunnel failed.
39
+ 4. If interactive account login was not part of the admitted request, the
40
+ objective is ready for delivery after steps 1 and 2.
41
+ 5. Creating another tunnel is inadmissible unless evidence establishes that
42
+ the first endpoint is absent or unusable, or a new user instruction
43
+ explicitly requests replacement.
44
+ 6. The user receives the verified endpoint or one precise clarification
45
+ question. The user never receives a fabricated or canned incomplete report.
46
+
47
+ ## Confirmed current-code gaps
48
+
49
+ - `ExpectedOutcomeContractV1` records only coarse effects:
50
+ `visible_response`, `observation`, `mutation`, `verification`, and
51
+ `delivery`. It cannot represent request-specific acceptance criteria,
52
+ exclusions, or semantic effect identity.
53
+ - Completion evidence is recorded throughout a run, but request-specific
54
+ claims are normally created only when the model attempts `task_complete`.
55
+ During execution the ledger is therefore an evidence collection, not a live
56
+ request-satisfaction frontier.
57
+ - Trajectory stall detection fingerprints rendered checkpoint state and resets
58
+ on file mutation. Runtime effects such as tunnel creation are not file
59
+ mutations, while superficial new output can change the checkpoint and evade
60
+ the stall detector.
61
+ - The problem-frame validator is optional, model-based, and fire-and-forget.
62
+ It can advise a later turn but cannot authoritatively stop the next duplicate
63
+ effect.
64
+ - Telegram treats tool calls, tool results, and generated tokens as meaningful
65
+ activity. A busy loop therefore never becomes quiet enough for its stale-run
66
+ monitor.
67
+ - Telegram action runs use `maxTurns: 0`, and terminal continuation can requeue
68
+ without a cross-cycle acceptance-progress boundary.
69
+ - A non-`task_complete` tool call can clear the current visible reply
70
+ candidate. The surviving candidate is not durably bound to the evidence
71
+ receipts that made it valid.
72
+ - Telegram URL delivery recognizes WebFetch evidence but not a provider
73
+ creation receipt combined with protocol-specific verification. A valid
74
+ tunnel URL can consequently be stripped at the final boundary.
75
+ - Generic duplicate suppression focuses on identical failed calls. Successful
76
+ external effects, or semantically equivalent calls with different command
77
+ text, can repeat.
78
+ - Shell permission classification matches arbitrary output text including
79
+ `Permission denied` and `authentication failure`, then automatically invokes
80
+ local elevation.
81
+ - `runElevated()` is declared asynchronous, but its platform implementations
82
+ use synchronous child-process APIs and can block the TUI event loop.
83
+
84
+ ## Research and standards basis
85
+
86
+ The required architecture is supported by the following evidence. These
87
+ sources establish the principles; they do not prescribe Omnius's exact schema
88
+ names or numeric thresholds.
89
+
90
+ - Observation-grounded replanning: ReAct interleaves reasoning, actions, and
91
+ external observations; AgentRx checks trajectory steps against task and tool
92
+ constraints and retains evidence-backed violations.
93
+ - <https://arxiv.org/abs/2210.03629>
94
+ - <https://arxiv.org/abs/2602.02475>
95
+ - Progress must be measured below binary final success. AgentBoard exposes
96
+ intermediate subgoal progress, while the OOPSLA process-centric study finds
97
+ repetition, backtracking, and prolonged same-phase stagnation concentrated
98
+ in unresolved trajectories and reports gains from online intervention.
99
+ - <https://arxiv.org/abs/2401.13178>
100
+ - <https://doi.org/10.1145/3798271>
101
+ - External feedback can improve correction, but intrinsic model
102
+ self-correction can degrade reasoning. Verifiers must therefore be
103
+ condition-specific and evidence-bound; a second model opinion is advisory,
104
+ not independent truth.
105
+ - <https://arxiv.org/abs/2305.11738>
106
+ - <https://arxiv.org/abs/2310.01798>
107
+ - <https://aclanthology.org/2024.emnlp-main.714/>
108
+ - Machine-readable failure types must not be reconstructed from human-readable
109
+ detail strings.
110
+ - <https://www.rfc-editor.org/rfc/rfc9457.html>
111
+ - <https://grpc.io/docs/guides/status-codes/>
112
+ - Non-idempotent effects must not be blindly retried. A retry requires proof
113
+ that the first attempt did not apply, a stable idempotency mechanism, or
114
+ state reconciliation showing that repetition is safe.
115
+ - <https://datatracker.ietf.org/doc/html/rfc9110#section-9.2.2>
116
+ - <https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/>
117
+ - Clarification is a first-class action when a genuinely missing user fact
118
+ blocks the next criterion. The run must pause durably and resume rather than
119
+ fail or replay completed work.
120
+ - <https://arxiv.org/abs/2411.00927>
121
+ - <https://arxiv.org/abs/2307.01928>
122
+ - <https://openai.github.io/openai-agents-python/human_in_the_loop/>
123
+ - Production agent runtimes provide finite turn, time, token, functional, and
124
+ handoff termination. Bounds are safety backstops, not evidence of success or
125
+ failure.
126
+ - <https://openai.github.io/openai-agents-python/running_agents/>
127
+ - <https://microsoft.github.io/autogen/dev/user-guide/agentchat-user-guide/tutorial/termination.html>
128
+ - Node documents that `spawnSync`, `execSync`, and `execFileSync` block the
129
+ event loop until the child exits.
130
+ - <https://nodejs.org/api/child_process.html>
131
+ - <https://nodejs.org/en/learn/asynchronous-work/dont-block-the-event-loop>
132
+
133
+ ## Architectural decisions
134
+
135
+ 1. **One immutable objective contract per task epoch.** Later clarification is
136
+ a versioned amendment. Model summaries and todo text cannot weaken it.
137
+ 2. **One deterministic objective reconciler.** Every admitted tool result is
138
+ reduced against the current criteria before another action is admitted.
139
+ 3. **Typed receipts are authority.** Human-readable output is presentation and
140
+ diagnostic context, never the primary retry, privilege, or completion key.
141
+ 4. **Verifier scope is explicit.** A verifier can contradict an artifact only
142
+ when it is valid for the same criterion and artifact revision.
143
+ 5. **Progress is an acceptance-frontier delta.** Activity, new prose, another
144
+ URL, or an unrelated mutation is not progress.
145
+ 6. **External effects have semantic identities.** Exact command fingerprints
146
+ are insufficient for idempotency.
147
+ 7. **Clarification is suspension, not failure.** Waiting state is durable,
148
+ scoped, resumable, and single-writer.
149
+ 8. **Hard bounds never author semantic output.** A depleted budget selects a
150
+ bounded review or continuation question; it cannot manufacture an
151
+ incomplete report.
152
+ 9. **Model grounding is advisory.** It may explain or rank evidence, but it
153
+ cannot grant completion, retry a mutation, or override typed receipts.
154
+ 10. **The TUI event loop does no blocking process work.** Elevation is async,
155
+ abortable, and unavailable to public/group Telegram execution.
156
+
157
+ ## Target state machine
158
+
159
+ ```text
160
+ tool result
161
+ |
162
+ v
163
+ normalize typed evidence/effect/verifier receipt
164
+ |
165
+ v
166
+ reconcile immutable objective criteria
167
+ |
168
+ +--> deliver_due ---------> bounded final synthesis -> send -> completed
169
+ |
170
+ +--> verify_due ----------> one criterion-compatible verifier
171
+ |
172
+ +--> continue ------------> one action that can change an open criterion
173
+ |
174
+ +--> needs_input ---------> persist question -> suspend -> resume same epoch
175
+ |
176
+ +--> externally_blocked --> evidence-backed blocker -> terminal report
177
+ |
178
+ +--> no_delta ------------> scrutinize -> alternate action -> bounded
179
+ continue offer or needs_input
180
+ ```
181
+
182
+ ## Intended types
183
+
184
+ Names may change during implementation, but the responsibilities may not be
185
+ collapsed back into prose fields.
186
+
187
+ ```ts
188
+ interface TaskObjectiveContractV1 {
189
+ schema: "omnius.task-objective-contract.v1";
190
+ taskEpoch: number;
191
+ originalRequestRef: string;
192
+ originalRequestHash: string;
193
+ goal: string;
194
+ criteria: TaskObjectiveCriterionV1[];
195
+ exclusions: string[];
196
+ unknowns: string[];
197
+ deliveryTarget?: ObjectiveDeliveryTargetV1;
198
+ revision: number;
199
+ }
200
+
201
+ interface TaskObjectiveCriterionV1 {
202
+ id: string;
203
+ description: string;
204
+ requiredEvidenceKinds: ObjectiveEvidenceKindV1[];
205
+ status: "open" | "satisfied" | "blocked";
206
+ }
207
+
208
+ interface ExternalEffectReceiptV1 {
209
+ schema: "omnius.external-effect-receipt.v1";
210
+ effectKind: string;
211
+ semanticTarget: string;
212
+ idempotencyKey: string;
213
+ effectState: "pending" | "applied" | "absent" | "unknown";
214
+ artifactRevision?: string;
215
+ evidenceId: string;
216
+ }
217
+
218
+ interface VerificationReceiptV1 {
219
+ schema: "omnius.verification-receipt.v1";
220
+ criterionId: string;
221
+ artifactEvidenceId: string;
222
+ artifactRevision?: string;
223
+ verifierMethod: string;
224
+ outcome:
225
+ | "passed"
226
+ | "artifact_failed"
227
+ | "verifier_invalid"
228
+ | "downstream_auth_required"
229
+ | "inconclusive";
230
+ evidenceIds: string[];
231
+ }
232
+
233
+ type ObjectiveFrontierDecision =
234
+ | "continue"
235
+ | "verify_due"
236
+ | "deliver_due"
237
+ | "needs_input"
238
+ | "externally_blocked";
239
+
240
+ interface NeedsInputContractV1 {
241
+ schema: "omnius.needs-input-contract.v1";
242
+ runId: string;
243
+ taskEpoch: number;
244
+ question: string;
245
+ missingCriterionIds: string[];
246
+ evidenceIds: string[];
247
+ resumeToken: string;
248
+ }
249
+ ```
250
+
251
+ ## End-to-end implementation checklist
252
+
253
+ ### Phase 0: baseline, fixtures, and ownership
254
+
255
+ - [ ] Record implementation-start Git head, tracked branch, and dirty files in
256
+ the evidence log below. Preserve unrelated `docs/DISCOVERY.*` and
257
+ `publish/*` changes.
258
+ - [ ] Capture a sanitized deterministic fixture for the tunnel sequence:
259
+ successful Cloudflare URL, successful transport reachability, downstream
260
+ SSH authentication rejection, and attempted duplicate creation.
261
+ - [ ] Capture a deterministic event-loop heartbeat fixture that reproduces a
262
+ pending elevation operation without opening a real OS prompt.
263
+ - [ ] Map every existing objective, completion, convergence, Telegram
264
+ metacognition, interruption, effect, and delivery type before adding a
265
+ new one. Reuse authority where semantics already match.
266
+ - [ ] Confirm that all new tests are hermetic and perform no live Telegram,
267
+ Cloudflare, SSH, Ollama, or privilege-elevation operation.
268
+
269
+ ### Phase 1: immutable task objective contract
270
+
271
+ Primary seams:
272
+
273
+ - `packages/orchestrator/src/expectedOutcomeContract.ts`
274
+ - `packages/orchestrator/src/completionContract.ts`
275
+ - `packages/orchestrator/src/completionLedger.ts`
276
+ - `packages/orchestrator/src/agenticRunner.ts`
277
+ - `packages/cli/src/tui/telegram-bridge.ts`
278
+
279
+ - [ ] Add and validate `TaskObjectiveContractV1` or an equivalently separate
280
+ typed authority. Do not overload coarse expected-outcome effects with
281
+ request-specific prose.
282
+ - [ ] Bind the contract to `taskEpoch`, the immutable original-request evidence
283
+ reference/hash, and the host-authorized delivery target.
284
+ - [ ] Represent request-specific criteria, exclusions, unresolved unknowns,
285
+ and evidence requirements with stable IDs.
286
+ - [ ] Create the contract once at task-scope installation, before the first
287
+ action turn.
288
+ - [ ] Persist the contract or its immutable reference in the completion ledger
289
+ and finalization record.
290
+ - [ ] Replace it only at an explicit task-scope boundary. Represent
291
+ clarification as a versioned amendment with provenance.
292
+ - [ ] Render a bounded criterion frontier beside the current user goal in the
293
+ runner context without duplicating the raw request body.
294
+ - [ ] Prove that todo edits, completion summaries, model grounding, and
295
+ intermediate assistant prose cannot weaken or delete criteria.
296
+ - [ ] Prove that short external-action requests receive a useful objective
297
+ contract even when the generic code-repair workboard is not created.
298
+
299
+ ### Phase 2: continuous objective reconciliation
300
+
301
+ Primary seams:
302
+
303
+ - `_recordCompletionToolEvidenceFromResult()` in `agenticRunner.ts`
304
+ - `reconcileClaimsWithEvidence()` in `completionLedger.ts`
305
+ - `_refreshTrajectoryCheckpoint()` in `agenticRunner.ts`
306
+
307
+ - [ ] Implement a pure `reconcileTaskObjective()` reducer over the immutable
308
+ contract, typed evidence, workboard/todo authority, and current receipts.
309
+ - [ ] Return criterion states, missing evidence, contradictions, and exactly
310
+ one frontier decision.
311
+ - [ ] Invoke reconciliation after every admitted tool result and before the
312
+ next action can be dispatched.
313
+ - [ ] Persist the current criterion state and frontier fingerprint.
314
+ - [ ] Feed the reconciled frontier into the trajectory checkpoint. Do not make
315
+ the checkpoint infer objective state from rendered prose.
316
+ - [ ] Make `deliver_due` prevent a further action that cannot advance an open
317
+ criterion.
318
+ - [ ] Make `verify_due` name the exact criterion, artifact revision, acceptable
319
+ verifier class, and evidence expected.
320
+ - [ ] Make `needs_input` legal only when the missing criterion truly requires
321
+ user information or authority.
322
+ - [ ] Make `externally_blocked` require typed external-blocker evidence.
323
+ - [ ] Prove the reducer is deterministic for identical contract/evidence
324
+ inputs and cannot invoke a model or perform I/O.
325
+
326
+ ### Phase 3: typed effect and verification receipts
327
+
328
+ Primary seams:
329
+
330
+ - `packages/orchestrator/src/completionLedger.ts`
331
+ - `packages/orchestrator/src/postActionVerifier.ts`
332
+ - tool-result normalization in `packages/orchestrator/src/agenticRunner.ts`
333
+ - command/process tools in `packages/execution/src`
334
+
335
+ - [ ] Add typed external-effect identity and state to tool evidence.
336
+ - [ ] Add typed verifier target, artifact revision, verifier method, and outcome.
337
+ - [ ] Preserve raw stdout/stderr as bounded diagnostic evidence, not authority.
338
+ - [ ] Permit contradiction only from `artifact_failed` evidence produced by a
339
+ valid verifier for the same criterion and artifact revision.
340
+ - [ ] Treat `verifier_invalid` as a request for a corrected verifier, not an
341
+ artifact failure.
342
+ - [ ] Treat `downstream_auth_required` as outside a transport criterion unless
343
+ the admitted objective explicitly requires authenticated login.
344
+ - [ ] Treat `inconclusive` as unresolved evidence and prevent blind mutation
345
+ replay.
346
+ - [ ] Add or adapt a typed receipt for a Cloudflare endpoint registration URL.
347
+ - [ ] Add or adapt a protocol receipt that distinguishes reaching SSH from
348
+ authenticating an SSH account.
349
+ - [ ] Prove that receipt serialization, restoration, compaction, and context
350
+ projection preserve identity and revision fields.
351
+
352
+ ### Phase 4: semantic idempotency and duplicate-effect prevention
353
+
354
+ Primary seams:
355
+
356
+ - tool preflight/dispatch in `packages/orchestrator/src/agenticRunner.ts`
357
+ - interruption effect fencing in `agenticRunner.ts`
358
+ - existing Telegram delivery idempotency ledger
359
+
360
+ - [ ] Add a durable run-scoped external-effect ledger with semantic effect
361
+ identity, not only exact command fingerprints.
362
+ - [ ] Record `pending` before dispatch and reconcile `applied`, `absent`, or
363
+ `unknown` afterward.
364
+ - [ ] Require a stable idempotency key when a tool/provider supports one.
365
+ - [ ] Before repeating a non-idempotent effect, require proof that the earlier
366
+ effect is absent/failed or a new user-authorized replacement objective.
367
+ - [ ] Block a second semantically equivalent tunnel creation once a usable
368
+ endpoint receipt exists, even if the command text or generated hostname
369
+ differs.
370
+ - [ ] Preserve `unknown` across interruption/restart and require state
371
+ reconciliation before retry.
372
+ - [ ] Ensure duplicate-effect rejection becomes typed controller evidence and
373
+ does not create a new failure spiral.
374
+ - [ ] Retain the existing exact-payload Telegram send ledger as the delivery
375
+ authority; do not create a competing send-idempotency implementation.
376
+
377
+ ### Phase 5: criterion-delta convergence controller
378
+
379
+ Primary seams:
380
+
381
+ - `packages/orchestrator/src/convergence-progress.ts`
382
+ - `packages/orchestrator/src/trajectory-checkpoint.ts`
383
+ - convergence/stagnation handling in `agenticRunner.ts`
384
+ - Telegram sub-agent progress event handling
385
+
386
+ - [ ] Add a persistent `RunConvergenceState` keyed by the objective-frontier
387
+ fingerprint.
388
+ - [ ] Count progress only when a criterion state, required-evidence set,
389
+ accepted artifact revision, or delivery state materially changes.
390
+ - [ ] Track action family, targeted criterion, artifact revision, and outcome.
391
+ - [ ] Do not reset convergence because of new prose, another randomized URL,
392
+ unrelated file mutation, token output, or repeated observation.
393
+ - [ ] First same-frontier repetition: require verifier scrutiny.
394
+ - [ ] Next same-frontier repetition: require an alternate verifier or action
395
+ family that can change an open criterion.
396
+ - [ ] After a bounded plateau: select `needs_input`, an evidence-backed external
397
+ blocker, or a natural offer to run another bounded cycle.
398
+ - [ ] Keep turn/time/token limits as independent emergency bounds.
399
+ - [ ] Remove `maxTurns: 0` as the sole Telegram termination policy. Use a
400
+ documented finite emergency bound high enough for valid research work.
401
+ - [ ] Ensure exhaustion never writes a canned incomplete response.
402
+ - [ ] Convert `trajectory_checkpoint assessment=blocked` into a safe-boundary
403
+ controller event rather than prompt text alone.
404
+ - [ ] Make the existing problem-frame/model grounding pass advisory to this
405
+ state; it may not reset progress or authorize another effect.
406
+ - [ ] Replace Telegram's activity timestamp with an acceptance-progress
407
+ timestamp for stall review while retaining a separate liveness signal.
408
+ - [ ] Bound cross-cycle Telegram continuation by frontier delta, not by a raw
409
+ cycle count and not by silence alone.
410
+
411
+ Threshold policy:
412
+
413
+ - [ ] Choose initial no-delta thresholds from deterministic tests and record
414
+ the rationale here.
415
+ - [ ] Expose telemetry for threshold calibration without message bodies.
416
+ - [ ] Keep thresholds configurable but bounded; invalid values fail closed to
417
+ tested defaults.
418
+ - [ ] Do not describe any chosen numeric threshold as a universal research
419
+ result.
420
+
421
+ ### Phase 6: durable clarification, pause, and resume
422
+
423
+ Primary seams:
424
+
425
+ - `AgenticResult` and terminal status types in `agenticRunner.ts`
426
+ - `completionReadiness.ts`
427
+ - `completionFinalization.ts`
428
+ - runner pause/resume and interruption lifecycle
429
+ - Telegram open-task/metacognitive continuation state
430
+
431
+ - [ ] Add `awaiting_input` as a distinct suspended lifecycle state. Do not map
432
+ it to `incomplete` or `incomplete_verification`.
433
+ - [ ] Add and persist `NeedsInputContractV1` with one exact question, missing
434
+ criterion IDs, evidence IDs, task epoch, and a single-use resume token.
435
+ - [ ] Generate natural question wording from the structured blocker without a
436
+ fixed canned reply.
437
+ - [ ] Suspend only at a safe boundary after in-flight effects are reconciled or
438
+ fenced as unknown.
439
+ - [ ] Keep the waiting task durable without holding an inference, queue, typing,
440
+ or process lease.
441
+ - [ ] Match the next user answer to the same chat/scope/task epoch and resume
442
+ exactly once.
443
+ - [ ] Apply the answer as a versioned objective amendment or criterion evidence;
444
+ do not start an unrelated replacement run.
445
+ - [ ] Reject concurrent or stale resume attempts and preserve single-writer
446
+ ownership.
447
+ - [ ] If useful autonomous work remains, continue silently rather than asking
448
+ merely because a turn threshold fired.
449
+ - [ ] If work is viable but costly after a plateau, ask whether to run another
450
+ bounded cycle and state what remains unknown.
451
+ - [ ] Prove restart persistence between suspension and resume.
452
+
453
+ ### Phase 7: verified reply retention and Telegram delivery
454
+
455
+ Primary seams:
456
+
457
+ - `retainTelegramVisibleReplyDraft()` in `telegram-bridge.ts`
458
+ - `selectTelegramFinalResponse()` in `telegram-bridge.ts`
459
+ - terminal metacognitive/open-task persistence
460
+ - `packages/cli/src/tui/telegram-safe-delivery.ts`
461
+
462
+ - [ ] Add a durable `TelegramVerifiedReplyCandidate` containing exact text,
463
+ run/task epoch, satisfied criterion IDs, evidence IDs, URL receipts, and
464
+ capture turn.
465
+ - [ ] Update the candidate only at a safe evidence boundary.
466
+ - [ ] Do not clear a still-valid candidate merely because a later tool call
467
+ started.
468
+ - [ ] Invalidate it on task replacement, reply-authority loss, contradictory
469
+ same-revision evidence, or explicit user supersession.
470
+ - [ ] When the frontier becomes `deliver_due`, perform one bounded no-tools
471
+ final synthesis or use the current verified candidate.
472
+ - [ ] Keep the existing rule that `task_complete.summary` is never silently
473
+ substituted for a user-facing answer.
474
+ - [ ] Add `ExternalDestinationReceipt` or equivalent typed URL authority for a
475
+ provider-created endpoint plus compatible protocol verification.
476
+ - [ ] Continue denying arbitrary, unreceipted, dead, redirected-to-unverified,
477
+ or model-invented URLs.
478
+ - [ ] Bind the delivered tunnel URL to the exact receipt; truncated TUI display
479
+ must not alter the click target or Telegram payload.
480
+ - [ ] Preserve group reply authority, current input ownership, chat/topic scope,
481
+ and one-reply semantics.
482
+ - [ ] On incomplete/aborted public or group runs, remain silent unless an
483
+ authorized natural clarification question or verified terminal answer is
484
+ available.
485
+ - [ ] Keep operator diagnostics available in admin surfaces without leaking
486
+ engineering reports into public replies.
487
+
488
+ ### Phase 8: typed permission handling and nonblocking system authentication
489
+
490
+ Primary seams:
491
+
492
+ - `packages/execution/src/tools/shell.ts`
493
+ - `packages/execution/src/system-auth.ts`
494
+ - runner privilege/password recovery handling
495
+
496
+ - [ ] Remove broad local-privilege inference from arbitrary command output.
497
+ - [ ] Classify local privilege need only from structured local execution
498
+ provenance, such as an actual spawn/filesystem `EACCES` or `EPERM`, plus
499
+ explicit command authority.
500
+ - [ ] Prove that remote `ssh`, `scp`, `curl`, and nested-shell text containing
501
+ `Permission denied`, `authentication failure`, or similar wording never
502
+ triggers local elevation.
503
+ - [ ] Replace every `execSync`, `spawnSync`, and equivalent blocking elevation
504
+ path with asynchronous `spawn`/`execFile` handling.
505
+ - [ ] Add timeout, abort, signal, stdout/stderr bounds, and child cleanup.
506
+ - [ ] Ensure timeout cannot remain blocked when a child ignores `SIGTERM`;
507
+ implement bounded escalation/cleanup appropriate to each platform.
508
+ - [ ] Make exactly one layer own elevation prompting. Remove duplicate runner
509
+ password-wait behavior where the tool owns native elevation.
510
+ - [ ] For Telegram public/group execution, disable elevation and return a typed
511
+ `needs_privilege` blocker.
512
+ - [ ] For authorized local/admin interaction, keep OS-native credential entry
513
+ outside Omnius process memory and expose cancellable progress.
514
+ - [ ] Prove TUI keyboard, hover, render, timers, and Stop remain responsive
515
+ while an elevation child is pending.
516
+ - [ ] Audit adjacent startup, restore/new, Git status, and update/daemon-stop
517
+ code for synchronous child-process calls on the interactive event loop;
518
+ move any discovered blocking operation behind async boundaries and add
519
+ focused tests before checking this item.
520
+
521
+ ### Phase 9: compatibility, migration, and observability
522
+
523
+ - [ ] Read legacy completion ledgers without an objective contract and create a
524
+ conservative new-task contract only at a new run/task epoch.
525
+ - [ ] Never reinterpret a historical completed run by retroactively inventing
526
+ criteria.
527
+ - [ ] Version all new persisted schemas and validate on read.
528
+ - [ ] Fail closed on malformed receipt identity, revision, or resume ownership.
529
+ - [ ] Add bounded telemetry for criterion transitions, no-delta streaks,
530
+ verifier classifications, duplicate-effect blocks, suspension/resume,
531
+ and delivery disposition.
532
+ - [ ] Exclude raw message bodies, credentials, tokens, SSH material, and full
533
+ private URLs from telemetry.
534
+ - [ ] Ensure context compaction preserves current objective/frontier authority
535
+ exactly once and does not duplicate raw evidence.
536
+ - [ ] Ensure CLI and daemon callers can supply/consume the host-neutral
537
+ objective and suspended-state interfaces without importing Telegram code.
538
+ - [ ] Document any intentionally deferred CLI presentation work as a separate
539
+ linked work order; do not weaken the shared controller to avoid it.
540
+
541
+ ### Phase 10: deterministic regression matrix
542
+
543
+ Orchestrator:
544
+
545
+ - [ ] Extend `packages/orchestrator/tests/completionLedger.test.ts` for
546
+ pre-seeded request criteria and continuous reconciliation.
547
+ - [ ] Prove a wrong-method or invalid verifier does not contradict a valid
548
+ artifact receipt.
549
+ - [ ] Prove a valid same-target/same-revision artifact failure does contradict.
550
+ - [ ] Prove downstream SSH authentication does not invalidate transport.
551
+ - [ ] Extend `trajectory-checkpoint.test.ts` so superficial output changes and
552
+ unrelated mutations do not reset criterion stagnation.
553
+ - [ ] Extend `task-convergence-progress.test.ts` so repeated successful probes
554
+ without frontier delta are not progress.
555
+ - [ ] Add runner coverage for receipt -> `deliver_due` -> duplicate mutation
556
+ rejection -> verified completion.
557
+ - [ ] Add runner coverage for plateau -> natural `awaiting_input`/continue
558
+ offer, never canned incomplete.
559
+ - [ ] Add completion-readiness/finalization coverage for suspended state,
560
+ persistence, and exactly-once resume.
561
+ - [ ] Add restart coverage for pending/unknown external effects.
562
+
563
+ Execution:
564
+
565
+ - [ ] Add a remote SSH authentication regression proving zero elevation calls.
566
+ - [ ] Add controls for genuine local `EACCES`/`EPERM` with explicit elevation
567
+ eligibility.
568
+ - [ ] Add platform-fake tests for async pkexec, sudo/askpass, osascript, and
569
+ PowerShell success, failure, timeout, abort, and cleanup.
570
+ - [ ] Add an event-loop heartbeat test that remains responsive for the entire
571
+ pending-auth interval.
572
+ - [ ] Add a Stop/cancel test that terminates the pending child without leaking
573
+ listeners, timers, or processes.
574
+
575
+ Telegram/CLI:
576
+
577
+ - [ ] Extend `telegram-terminal-metacognition.test.ts` for typed no-delta
578
+ disposition, natural wait question, and same-task resume.
579
+ - [ ] Extend `telegram-steering-finalization.test.ts` for objective amendments,
580
+ task replacement, and stalled safe-boundary review.
581
+ - [ ] Extend `telegram-bot-api-10.test.ts` for durable verified reply retention
582
+ across later tool activity.
583
+ - [ ] Extend `telegram-safe-delivery.test.ts` for provider-created tunnel URL
584
+ receipts plus SSH transport verification.
585
+ - [ ] Prove arbitrary shell-emitted URLs remain denied.
586
+ - [ ] Prove public/group incomplete runs remain silent rather than exposing an
587
+ engineering report.
588
+ - [ ] Prove current reply ownership and one-reply semantics across
589
+ suspend/resume, replacement, cancellation, and restart.
590
+ - [ ] Add a TUI integration heartbeat covering typing, hover/click dispatch,
591
+ input cursor stability, timers, and Stop while async child work is
592
+ pending.
593
+
594
+ ### Phase 11: build, review, delivery, and live acceptance
595
+
596
+ - [ ] Run focused tests after each phase and record commands/results below.
597
+ - [ ] Build every changed workspace package.
598
+ - [ ] Run the complete test suites for every changed package after focused
599
+ tests pass.
600
+ - [ ] Review the final diff for model-authored completion authority, keyword
601
+ heuristics, unbounded retries, duplicate effects, stale task ownership,
602
+ URL bypasses, blocking I/O, and private-data telemetry.
603
+ - [ ] Run a source scan proving no synchronous child-process API remains on the
604
+ interactive elevation/startup/update paths addressed by this order.
605
+ - [ ] Make scoped commits by coherent repair. Never stage unrelated dirty
606
+ files and never use blanket add.
607
+ - [ ] Fetch the tracked branch before push, resolve only owned-file conflicts,
608
+ and push without rewriting shared history.
609
+ - [ ] Record commit hashes, remote branch, tests, builds, and known limitations
610
+ in this document and the master tracker.
611
+ - [ ] Do not publish npm merely because repository acceptance passes. Follow
612
+ the repository publish SOP only when publication is explicitly part of
613
+ the active delivery request.
614
+ - [ ] Before any live token-generating canary, satisfy the repository GPU gate:
615
+ exact endpoint/model, `docker gpu discover`, active lease review, and
616
+ actual runner placement verified with `nvidia-smi`.
617
+ - [ ] Run one authorized live Telegram canary for the sanitized tunnel-shaped
618
+ workflow without exposing credentials or creating uncontrolled effects.
619
+ - [ ] Confirm the canary creates at most one semantic endpoint effect, returns
620
+ the exact verified result, never asks for an unrelated password, and
621
+ leaves the TUI responsive.
622
+ - [ ] Record the Telegram message IDs, redacted receipt IDs, timings, and final
623
+ disposition without copying private chat content into the repository.
624
+ - [ ] Mark this work order and the tracker complete only after repository
625
+ acceptance and the explicitly authorized live gate are both recorded, or
626
+ record live acceptance as a named external/user-owned remaining gate.
627
+
628
+ ## Required acceptance scenarios
629
+
630
+ The implementation is not complete until all scenarios have deterministic
631
+ coverage:
632
+
633
+ 1. One successful external effect followed by a compatible verifier leads to
634
+ `deliver_due`.
635
+ 2. Downstream authentication failure does not negate transport success.
636
+ 3. An invalid verifier leads to verifier repair, not effect replay.
637
+ 4. A semantically duplicate successful mutation is blocked despite different
638
+ command text.
639
+ 5. An unrelated mutation does not count as request progress.
640
+ 6. Repeated output/token activity without frontier delta becomes a stall.
641
+ 7. A genuine missing user fact produces one natural question and durable
642
+ suspension.
643
+ 8. A response resumes the exact task once without repeating applied effects.
644
+ 9. A hard resource bound produces a bounded review/continue offer, not a canned
645
+ failure report.
646
+ 10. A verified reply candidate survives later nonterminal tool work.
647
+ 11. A provider-created, protocol-verified URL passes final safe delivery; an
648
+ arbitrary shell URL does not.
649
+ 12. Public/group incomplete work remains silent unless a reply is authorized.
650
+ 13. Remote SSH `Permission denied` never requests local elevation.
651
+ 14. Pending elevation never freezes TUI input, hover/click handling, rendering,
652
+ timers, or Stop.
653
+ 15. Restart preserves objective, effect, stall, suspended-input, and delivery
654
+ ownership without duplication.
655
+
656
+ ## Evidence log
657
+
658
+ Update this section during implementation. Do not mark checklist items from
659
+ memory or from an earlier build.
660
+
661
+ ### Implementation start
662
+
663
+ - Git head: `16c65cd3d0436c8860d1bfd014321495205ed941`
664
+ - Tracked branch: `main` -> `origin/main`
665
+ - Preserved dirty files: `docs/DISCOVERY.json`, `docs/DISCOVERY.md`,
666
+ `publish/npm-shrinkwrap.json`, and `publish/package.json`
667
+ - Feature flags/migration mode: strict objective enforcement is the default;
668
+ Telegram uses `verified_external_effect` while its coarse router outcome
669
+ contracts migrate, and activates the hard delivery guard only after an exact
670
+ provider destination is joined to compatible transport evidence.
671
+
672
+ ### Scoped commits
673
+
674
+ - Objective contract/reconciler: `329cefd2`
675
+ - Typed verifier/effect receipts: `d405c734`, `329cefd2`
676
+ - Convergence and suspension: `329cefd2`
677
+ - Telegram verified delivery and continuation receipt persistence: `30cf56c6`
678
+ - Async privilege execution: `d405c734`
679
+ - Async startup restore: `d58ec7c4`
680
+ - Regression-guard reconciliation: `c1447f76`, `bbbceacf`
681
+ - Final objective/async integration: `f907996a`
682
+ - Final Case Theory/Telegram lifecycle repair: `48ed529d`
683
+ - Verification evidence update: `15dc2f14` plus the delivery-record follow-up
684
+ containing this line.
685
+
686
+ ### Focused verification
687
+
688
+ - Live Case Theory forensic fixture: message 476 owned the active eDiscovery
689
+ task; a different actor's directly addressed message 477 was incorrectly
690
+ admitted as `context_only` while visible-reply ownership moved. Message 479
691
+ then exposed a completion-summary claim ("My reply already landed") without
692
+ an accepted visible answer. The deterministic regressions now require
693
+ `continuity=new|replace` to fence the old runner and start a new task epoch,
694
+ and require zero public sends when no current-input model reply was accepted.
695
+
696
+ - Orchestrator command/result:
697
+ `pnpm --filter @omnius/orchestrator exec vitest run tests/task-objective.test.ts tests/agenticRunner-objective-control.test.ts tests/agenticRunner.test.ts -t 'objective|retains an honestly declared incomplete task_complete outcome' --reporter=dot`
698
+ -> 11 passed, 179 unrelated cases skipped by the name filter.
699
+ - Execution command/result:
700
+ `pnpm --filter @omnius/execution exec vitest run tests/shell-objective-evidence.test.ts tests/shell-permission-boundary.test.ts tests/system-auth.test.ts --reporter=dot`
701
+ -> 30 passed.
702
+ - Telegram/CLI command/result:
703
+ `pnpm --filter omnius exec vitest run tests/telegram-safe-delivery.test.ts tests/telegram-bot-api-10.test.ts tests/telegram-terminal-metacognition.test.ts tests/telegram-steering-finalization.test.ts tests/telegram-terminal-delivery.test.ts tests/telegram-lifecycle-leak.test.ts tests/session-diary.test.ts --reporter=dot`
704
+ -> 283 passed.
705
+ - TUI responsiveness command/result: `system-auth.test.ts` covers heartbeat,
706
+ abort, timeout, forced cleanup, and child-leak behavior for the async native
707
+ authentication boundary; 22 cases passed. `session-diary.test.ts` covers the
708
+ asynchronous startup restore snapshot and passed in the Telegram/CLI group.
709
+ - Final Case Theory/Telegram acceptance command/result:
710
+ `pnpm --dir packages/cli exec vitest run tests/telegram-bot-api-10.test.ts tests/telegram-terminal-metacognition.test.ts tests/telegram-steering-intake.test.ts tests/telegram-safe-delivery.test.ts tests/telegram-causal-consolidation.test.ts tests/telegram-steering-finalization.test.ts tests/telegram-terminal-delivery.test.ts tests/telegram-objective-resume.test.ts tests/telegram-turn-continuity.test.ts --reporter=dot`
711
+ -> 9 files, 242 passed.
712
+ - Final objective-loop focused result: 13 orchestrator files, 171 passed,
713
+ covering deterministic frontier reconciliation, pending-effect fencing,
714
+ durable `awaiting_input`, exact-once fresh-run resume, accepted visible reply
715
+ authority, and completion persistence.
716
+ - Restored async/auth/update focused results: execution 10 files / 108 passed;
717
+ CLI 9 files / 62 passed. The targeted source scan found no synchronous child
718
+ process calls or `Atomics.wait` in the addressed GPS, SDR, Meshtastic, audio,
719
+ updater, update-service, tray, or Voicebox paths.
720
+
721
+ ### Aggregate verification
722
+
723
+ - Changed-package builds: execution, orchestrator, and CLI TypeScript builds passed.
724
+ - Changed-package full suites: CLI 2,930/2,933 passed on the first aggregate
725
+ run; the three failures were stale source-shape guards for previously shipped
726
+ transparent branding, consolidated live-media header control, and corrected
727
+ editable cursor row, and all seven cases in those files passed after their
728
+ assertions were reconciled. Execution passed 1,921/1,922; the sole failure is
729
+ the pre-existing `audio-generate.test.ts:77` device-selection expectation and
730
+ is outside WO-56. Orchestrator passed 2,969/3,010 in the aggregate run; the
731
+ task-owned legacy `needs_input` and source-marker failures were fixed and pass
732
+ focused verification, while the remaining aggregate-only failures are being
733
+ recorded separately below rather than hidden.
734
+ - Workspace build: all 11 buildable workspace projects passed `pnpm -r build`;
735
+ execution, orchestrator, and CLI also passed their post-integration builds.
736
+ - Independent diff review: `git diff --check` passed; receipt authority,
737
+ same-artifact verification, pending-before-dispatch, public silence, safe URL
738
+ delivery, and legacy-host compatibility were reviewed at their call sites.
739
+ - Sync-child source scan: no `execSync`, `spawnSync`, or `execFileSync` remains
740
+ in the addressed TUI startup/restore, status/header, shell, or native-auth
741
+ paths. This does not claim that every compatibility filesystem API elsewhere
742
+ in the large TUI module has been converted.
743
+
744
+ ### Delivery
745
+
746
+ - Fetch result: `git fetch origin main` completed; local branch was six commits
747
+ ahead and zero behind before the documentation commit.
748
+ - Remote branch: `origin/main`
749
+ - Push result: `16c65cd3..15dc2f14 main -> main` completed without history
750
+ rewrite; this delivery-record follow-up is pushed as the final documentation
751
+ commit.
752
+ - Repository acceptance: deterministic implementation, focused acceptance,
753
+ scoped commit delivery, and remote push are complete.
754
+ - npm publication: not authorized by this work order alone
755
+ - Live canary: not run; this remains the named external/user-owned gate and is
756
+ subject to the repository GPU preflight plus authorization for real Telegram,
757
+ Cloudflare, and SSH effects.
758
+
759
+ ## Explicit non-goals
760
+
761
+ - Do not introduce keyword rules that decide whether the user deserves a reply.
762
+ - Do not use a second LLM call as deterministic completion authority.
763
+ - Do not infer local privilege need from arbitrary stderr/stdout prose.
764
+ - Do not make all external operations generally retryable.
765
+ - Do not weaken Telegram URL evidence requirements for arbitrary links.
766
+ - Do not require SSH passwords or store credentials in Omnius.
767
+ - Do not equate a configured timeout, turn cap, or stall threshold with proof
768
+ that the user's request succeeded or failed.
769
+ - Do not run live inference, publish npm, restart shared services, or create
770
+ external tunnel effects merely to satisfy repository tests.