Question
How can an owner authorize framework changes in chat, followed automatically by build, stopping the old instance, App replacement, restart, acceptance Agent execution, and failure handling?
Runtime architecture · owner initiated · macOS v1
A user asks an Agent in OpenProgram to modify OpenProgram. The Agent edits, tests, and commits in an isolated worktree; a worker-independent controller builds and installs the complete App. After the new worker starts, it automatically creates an acceptance task to check the original objective. System-check or goal-acceptance failure restores the old App.
How can an owner authorize framework changes in chat, followed automatically by build, stopping the old instance, App replacement, restart, acceptance Agent execution, and failure handling?
Runtime, Desktop, Job/DAG, permission, and local-release maintainers.
Windows/Linux, remote stable Releases, unauthorized background edits, multi-machine deployment, and unlimited automatic repair loops.
The self-update control protocol, post-restart acceptance, controlled repair, and status UI are in the combined candidate. Full combined checks and default-App acceptance for success, pre-activation failure, and post-activation rollback remain release requirements; source existence does not prove an installed working feature.
self_update_prepare accepting committed candidates only; generic shell access must not implicitly grant deployment authority.package-and-install-app.sh already builds the runtime and Electron App and runs packaged smoke checks.install-app.sh already validates candidates, preserves previous.app, restores the old App on failure, and restores original App/worker/launchd state.openprogram upgrade already supports cold start, doctor, restart, and expected-revision checks.origin/main.openprogram/updater/ distinguishes managed release, source checkout, and unsupported installations, and prohibits applying updates directly during worker startup.self_update/ stores independent requests, state, controller, and acceptance evidence without reusing upgrade-state.The user requests work through a normal conversation. Messages and tool results describe that work. Installation state is maintained by the update subsystem, not by a separate conversation widget. Reopening the App restores the conversation without an update history panel, update recovery notice or temporary verification dialog.
Separate the controller from candidate runtime. The current worker prepares and hands off; the supervisor controls activation and restoration; the new worker runs fixed system checks and a new acceptance Agent.
Candidate builds may execute candidate code, but sandboxing must deny writes to default state, installation, and update-record directories. Only a supervisor generated by the currently installed version may activate or restore.
Preparation reuses the normal conversational Agent’s planning, implementation, and review process. After submission, self_update/ durable control logic transitions states, without a generic new Workflow engine. Acceptance, diagnosis, and repair use frozen stage prompts and structured outputs; model outputs cannot directly stop processes, install, roll back, or change transaction state.
request.json goal/assertionsrequest.jsonverifier-result-{attempt}.jsondiagnosis-result-{attempt}.jsonScheduler time triggers and user-task authority do not suit the update protocol. Once JobRunner, session store, and owner-auth are available, the new worker executes recover_pending_updates().
The Job ID uses self-update:{update_id}:verify:{attempt}. The claim stores owner, lease, attempt, and job_id. Repeated startup does not resubmit an existing Job or terminal state.
The implementation Agent cannot bypass installation approval; the acceptance Agent has no source-write tools; diagnostic and repair Agents are read-only and propose structured output.verifier_config.py, diagnosis.py, source_repair.py stores stage configurations. New plans share goal, assertions, verification plan, iteration policy, and deadlines; inherited context never expands tool permissions.
Ordinary Scheduler startup failure does not block acceptance; JobRunner or system-gate failure requests supervisor rollback.
approve_each_activation: roll back and diagnose after failure; reauthorize before activating a new candidate.bounded_auto: owner explicitly authorizes at most 3 attempts, a total deadline, allowed paths, and a test set.Service restoration, diagnosis, source repair, and activation approval are separate stages. Diagnosis does not authorize installation.
self-update:{update_id}:diagnose:{attempt}.Old updates without frozen diagnosis retain their original recovery behavior; never synthesize configuration from mutable profiles. Diagnostic requests, claims, and results live in the original update directory, with one pending pointer at self-updates root. A new update revokes the old pointer under the same storage lock. Execution rechecks durable Job, current worker claim, frozen inputs, and unexpired deadline, rejecting forged source or input drift while restoring an old queue. Owners stop diagnosis through existing Job cancellation, not activation-preceding self_update_cancel. Diagnosis must not overwrite verifier verdict, signed acceptance results, or rollback conclusion.
Repair likewise requires independently frozen configuration in the original request; old requests gain no source-write capability. Default initial authorization includes isolated-worktree repair and listed tests after rollback, but not reinstalling. Only new requests explicitly selecting bounded_auto and approving the complete iteration authorization below allow scoped reinstallation. Repair output allows at most 32 text edits totaling 1 MiB. Each old_text must uniquely match a regular UTF-8 file; null old_text creates only nonexistent files. null new_text permits deletion only when old_text equals the complete file. The repair Job uses wait=true, creates no ordinary follow-up Agent, and leaves the original head unchanged. After the model Job completes, the owner calls self_update_repair_cancel(update_id) in the original session to cancel still-running candidate tests. Record candidate_ready only after the new SHA, complete diff, all configured tests, and post-test checks pass; no required_tests means awaiting_tests. Missing/failed configured tests or failed post-test checks mean failed; explicit cancellation and expiry mean cancelled and expired. None means installed.
Every update retains independent requests and evidence; an iteration sequence shares the original goal, scope, attempt budget, and total deadline.
self_update_retry(update_id, candidate_sha) in the original session forces one-time approval for the exact SHA, displaying full changes, tests, and remaining budget. It cannot become a persistent allow rule. bounded_auto submits automatically from original authorization and real evidence, without another model tool call.self_update_iteration_cancel(update_id) persists a stop marker in the original owner session, stopping the sequence’s unsubmitted approvals/automatic submissions and cancelling running diagnosis/repair Jobs and candidate tests. Created but unactivated children use existing cancellation. Other sequences and ordinary tasks remain unaffected. State shows root, parent, current child, attempt/max_attempts, total deadline, and stop reason.This stage reuses SelfUpdateStore process locking, JobRunner, mandatory approval, trusted supervisor, and transactional installer, without another Scheduler or generic workflow executor.self_update/iteration.py remains a side-effect-free policy decision; the new submission coordinator validates evidence, reserves budget, persists state, and recovers. Source responsibility boundaries do not replace real restart, rollback, and multi-attempt acceptance.
V1 adds only boundaries required for the goal, without another Job system, plugin system, or update dependency.
Use macOS launchctl submit to launch a one-shot supervisor outside the worker process tree, allowing activation, verification timeout, and restoration after worker/App shutdown.
Candidates must come from dedicated clean worktrees with explicit bases. Reread HEAD during build; discard artifacts on drift rather than deploying directory snapshots.
Reuse complete runtime, Electron builder, and packaged smoke. Do not yet choose wheel, asar, or full-App paths by changed files, avoiding multiple completion semantics.
self_update_prepare only persists the request and starts the supervisor. After the assistant final, session commit, and change attribution are durable, dispatcher writes turn_released.
The new worker atomically claims the update and reuses JobRunner to create a background task with source=self_update_verify. Ordinary Scheduler neither creates, polls, nor retries it.
Retain previous.app until system checks and goal acceptance both pass. System errors, Agent fail/inconclusive verdicts, and timeouts restore the old App while preserving candidate worktree and evidence.
One directory per update id. Every transition uses temporary files, fsync, and replace; active.json stores only the current update id.
Authorization rejection, build failure, candidate drift, cancellation, or idle-wait timeout; the old App was never replaced.
Candidate activated but system/goal acceptance failed; old App restored and old revision reverified.
Unable to determine old/new App state automatically, or rollback failed; stop automatic actions and retain the entire transaction.
~/.openprogram/self-updates/ active.json # schema + update_id maintenance.json # admission ownership <update_id>/ request.json # immutable intent state.json # current phase + owner events.jsonl # append-only evidence verifier-config.json # frozen model / tools / optional plan diagnosis-config.json source-repair-config.json iteration-root.json # frozen root authority iteration-next.json # bound proposal + unique child reservation iteration-status.json # submission / stop evidence supervisor.sh # trusted copied controller supervisor.log artifact.json # path + hashes verifier-result-{attempt}.json diagnosis-result-{attempt}.json source-repair-result-{attempt}.json controller/ # trusted runtime and installer bootstrap.json recover.sh /Applications/.openprogram-app-install.*/ previous.app # transaction path bound in state.detail
request.json stable fieldsschema, update_id, created_atsession_id, origin_turn_id, origin_assistant_id, agent_idrepo, worktree_id, base_sha, candidate_shachanged_paths, pre_update_evidencegoal, assertions, timeout_seconds; acceptance goals reside directly in request, without separate acceptance.jsoniteration_policy: mode, max_attempts, deadline, allowed_paths, required_testspre_update_evidence binds the iteration-record digest containing root/parent update, original authorization digest, sequence attempt, and unique child ID. Every successor has its own directory; original requests and historical terminal states are immutable.app_path is fixed to normalized /Applications/OpenProgram.appstate.json mutable fieldsphase, revision, updated_at, detailattempt, dispatch.job_id, dispatch.claimed_by, dispatch.lease_untillast_event: deterministically repair the final event when state was persisted but event append was interruptedAccept no URL, arbitrary installer path, shell command, state-directory override, or port override. Candidates cannot choose the controller.
Build takes most of the time without affecting the old instance; only activation/restart causes temporary unavailability.
self_update_prepare recomputes base/candidate/changed paths from Git, saves acceptance, and shows exact authorization. Reject the current main checkout, dirty candidates, version mismatch, and a second active update.owner workerlaunchctl submit for a one-shot job. Pass only update id and state directory.launchd/chat, and expected revision. Sandbox the candidate build.supervisorturn_released=true.dispatcherself_update_verify. Ordinary Scheduler is uninvolved.new workerDeterministic system checks first establish identity, startup, and service availability; the Agent then assesses the requested behavior. Neither layer replaces the other.
Tool allowlist is read/glob/grep/list plus self_update_observe. Check IDs execute only frozen local API, CLI/test, or UI actions. No generic Browser/Computer Use, shell, source edits, commits, deployments, external messages, or second-update authority.
Candidate runtime cannot independently prove its own trustworthiness. Supervisor decides system gates; the Agent gives structured pass/fail/inconclusive for user goals with inspectable evidence.
System startup: 90 seconds; Agent acceptance: 10 minutes by default; entire update: 30 minutes by default. Timeout never means success.
Acceptance Agent uses the same JobRunner and frozen configuration. Added capabilities are bounded acceptance operations, not another Agent, Scheduler, or generic browser-control service.
/Applications/OpenProgram.app. Bind App process, window, owner, update_id, attempt, and current worker identity, rechecking before and after actions. The model cannot supply CDP addresses, arbitrary targets, JS, or file paths./chat HTML, DOM text, or an embedded Web-tab screenshot cannot prove main-App visual or interaction requirements.Each assertion binds evidence kind, check ID, allowed targets/actions, and budget. Bind the plan digest into request evidence and verifier configuration. Prepare checks dependencies and permissions; old configurations do not automatically gain new UI/test permissions.
Reuse the controller’s constrained observations and signed receipts, adding evidence kinds without accepting model-signed results. Bind each item to update, attempt, SHA, worker, check ID, time, and content digest. Bound screenshots/output; exclude authentication from logs, screenshot exports, and model context.
Record precise reasons for closed windows, identity changes, denied permissions, vanished objects, judgment-affecting truncation, provider failure, and timeout. Adapters release their own connections/test resources without closing user windows; cleanup failure is recorded and blocks pass. Reconnects/restarts never reset the total deadline.
Page content, test output, and candidate code are untrusted data and cannot expand tool authority. Allowed-action enforcement must cover UI, IPC, and backend write entries; DOM selectors, button text, or read-only prompts alone cannot prevent side effects. Automatic acceptance avoids other sessions and personal browser data. User activity in the target window stops automatic interaction while preserving evidence; waiting cannot exceed the original deadline.
Failure state must state whether the candidate activated, which revision is running, whether the old App remains, and whether acceptance executed.
quiescence-timeout and the still-running task list.Before candidate activation, the trusted current version saves controller/runtime/installer and generates update-specific ~/.openprogram/self-updates/<update_id>/recover.sh, with a matching one-shot login task in the local user’s ~/Library/LaunchAgents/. Script, state directory, and runtime all reside outside the App, independent of PATH OpenProgram, the damaged App, ordinary worker, and Scheduler. Without a complete verifiable saved copy, do not generate replacement control code or guess recovery.
recover.sh statusrecover.sh repairrecover.sh resumeLogin filename is ai.openprogram.self-update.recovery.<update_id>.plist, executed at most once per user login and removed when complete: RunAtLoad=true, without KeepAlive, schedules, or persistent daemons. Writing the plist does not immediately load another controller; normal updates retain the original one-shot supervisor and controller lock. If both App and controller are unavailable in the current login, the terminal script is the explicit entry. After reboot, automatic recovery requires this user to log in; no claim is made for logged-out or locked-disk execution.
Publish binding records for recovery entry, fixed arguments, and plist before supervisor submission and candidate activation. Operate only canonical user-owned directories and exact files for this update. Reject conflicting existing content, symlinks, nonregular files, or unsafe permissions without overwriting. Repeated preparation validates saved copies rather than copying from the replaced App. Startup failures retain independent diagnostics and never clear maintenance or extend authorization.
After the original update terminates and releases maintenance, remove only this login plist if its content still matches binding records. Retain saved runtime, scripts, original evidence, and recovery results for inspection. Cleanup failure records diagnosis without changing verified outcomes; rerunning a leftover one-shot task must not recover a completed update. A damaged entry, permission drift, or insufficient evidence still requires manual handling; no arbitrary file repair or forced maintenance clearing is provided.
On entering maintenance, the worker uses existing canonical pause commands to reach durable execution checkpoints. Each update saves execution id, pause command id, and observed version, resuming only tasks it paused. Previously paused, awaiting-input, cancelled, or completed tasks do not resume automatically. Queued Jobs that never ran retain queue identity and do not participate in active-execution waiting.
Supervisor replaces the App only after canonical active attempts and legacy running tasks finish. After commit or verified rollback and maintenance release, the new worker continues tasks through original continue commands and the Job resource queue. Fixed command ids prevent duplicate execution on repeated recovery. Failed pauses or unpausable tasks that miss the deadline abort the update and resume already paused work.
Checkpoint recovery retains execution-contract validation. Changed tool implementations or permissions prohibit replaying old operations and preserve the old checkpoint. Only a continue initiated by this update and rejected for contract change may create a fixed-identity replanning Job from the original task/history, retaining original tools/permissions and rechecking execution/update ownership before running. Unresolved side effects, user cancellation, or other session activity prevent automatic replanning. Task-recovery failure does not change installation acceptance. The initiating session gets a durable terminal follow-up reading original goal/history/update result; it neither replaces the verifier nor gains interactive reactivation authority. Old records do not retroactively create follow-ups.
Acceptance entries are supervisor waiting, worker reconciliation, and real canonical pause/continue. Cover queued tasks, checkpoint recovery, duplicate worker recovery, user pause/cancel, unreleased maintenance, failed updates, and exactly one original-session follow-up. Status: implementation and focused tests complete; independent reviews, full tests, and real-App acceptance pending.
openprogram self-update status [update_id] --json reads maintenance ownership, original terminal state, and recovery results without models, new updates, or App mutation.openprogram self-update repair <update_id> is an independent local-owner control entry, separate from chat/Scheduler. An interactive terminal must confirm displayed update id, target revision, recovery action, and plan digest; no skip-confirmation flag. Recompare original state, maintenance ownership, installation journal, and trusted controller at confirmation; reject stale confirmation after any change.
Each confirmation creates an independent durable recovery request bound to original update/transaction identity with a ten-minute deadline, never extended by retries/restarts. Reuse saved controller/runtime/installer only, launched under a one-shot launchd label including recovery request id; do not recopy control code from the damaged App. The recovery process uses the original installation transaction to validate canonical App, restarts the default worker, and verifies the new process so startup checks and ordinary Scheduler resume normally. Interruptions allow idempotent recovery/worker restart within the same deadline, but no verifier Job or second update.
Original terminal state, verdict, and deadline remain unchanged. Manual recovery writes a separate resolution receipt distinguishing old-version restoration, accepted-version restoration, and unactivated-update restoration. Atomically release this maintenance owner only when the receipt matches new system evidence. Failure, expiry, or no confirmation keeps ordinary tasks prohibited; another attempt needs fresh confirmation. This is not arbitrary shell, file repair, or forced maintenance clearing.
Permission to edit code and permission to replace the running product are separate. The latter grants one candidate SHA or an explicit bounded multi-attempt envelope.
The controller obtains pinned uv, managed Python, and dependencies from the saved trusted complete runtime. Before reuse, byte-compare candidate uv.lock and product-runtime.json; mismatches or missing inputs fail before activation, without silently reusing incompatible dependencies or allowing candidate network access. Dependency changes require matching complete-runtime inputs first; candidates cannot choose download sources or inherit owner credentials.
Copy runtime and existing npm/uv/Electron-builder/node-gyp caches into a private build-home; macOS uses independent copy-on-write copies, never shared writable caches. The trusted controller selects Electron platform ZIPs by fixed version, architecture, and release SHA-256, copies them into candidate-read-only update inputs, and uses them through electronDist. Cache hits never skip integrity checks. Candidates still rebuild Web, docs, wheel, and Desktop archive, installing only the new wheel into private runtime. Normal official-Release builds remain unchanged. Copy, build, and checks share the original deadline; cache hits are not acceptance evidence.
Build processes cannot access external networks, default App, or user state. Packaged worker smoke may bind/access only one controller-selected private loopback port, explicitly excluding 18100; sandboxing still denies all other networking. Fixed checks requiring host graphics do not widen candidate sandbox permissions: the controller invokes system sips with fixed arguments for four fixed icon sources, then runs a Playwright Chromium probe using fixed trusted-runtime Python. Before/after execution, candidate browser-resource tree hashes must match saved trusted resources. Worker, icon, and browser checks must complete and enter manifest/receipt before activation; no passing by exposing the default worker or skipping checks. Actual packaging/installed-App acceptance appears at the end.
Before activation, copy supervisor/installer from current runtime and pin hashes. Candidate supplies no supervisor, App path, state path, command, or recovery policy.
Candidate build/smoke executes source, so run sandboxed with minimal environment. Deny provider credentials, default session state, installation directory, and update records.
self_update_prepare joins mandatory approvals that bypass cannot skip. Default binds the candidate; bounded iteration binds goal, allowed paths, maximum attempts, deadline, and prohibited changes.
Automatic acceptance cannot edit source or update again. It may only read evidence, run constrained checks, and operate local UI; extra side effects require inconclusive.
Users still only need chat. Tool arguments remain structured; models receive no installation commands.
{worktree_id, candidate_sha, goal, assertions[], iteration_policy?, verification_plan?}. After mandatory approval, validate candidate, freeze configuration, write request, and start supervisor. Return update_id, phase, candidate_sha, base_sha, and changed_paths, not installation success.
{update_id?}. Return phase, steps, current/candidate revision, active App, rollback availability, and verifier verdict.
Effective only in PREPARING/STAGING/READY. Reject cancellation after ACTIVATING; supervisor completes commit or rollback.
{update_id}. The original owner session cancels post-rollback source repair or candidate tests without rewriting acceptance/rollback conclusions.
{update_id, candidate_sha}. Approve a repaired SHA in the original session after real-evidence verification; recheck identity, candidate, and budget before/after approval. Return fixed child ID and submission state, never fabricated installation success.
{update_id}. Stop the entire iteration sequence and pending/running repair tasks. Activated transactions finish necessary verification/recovery but cannot create another attempt.
# Job result; controller wraps it in a signed receipt
{
"schema": 1,
"update_id": "su_...",
"candidate_sha": "...",
"attempt": 1,
"verdict": "pass | fail | inconclusive",
"assertions": [
{
"id": "acceptance-1",
"status": "pass",
"entry": "default App",
"observation": "...",
"evidence_refs": ["observation-id"],
"observed_at": 1.0
}
]
}
The initiating assistant node records self_update_id. Post-restart verification branch uses:
source=self_update_verifycaller=origin_assistant_idpredecessor=null, without changing user main-branch HEADUI renders “Automatic post-update acceptance,” not a user message.
Installation, verification and rollback retain their durable update records. Conversations display their normal messages and tool results only. The message list does not mount a software-update history component, issue update-history polling requests, or expose update management forms. Desktop recovery retains its routing and acknowledgement protocol without adding update recovery notices to the conversation.
update_id, root/parent, origin session, attemptphase, state_revision, updated_atrevision, and time.state_revision is a state version, not a Git SHA.candidate_revision, changed pathslast_verified_runtimesystem_gate, committed_system_gate, restored_system_gate by phase; pre-activation old version comes from previous_system_gate. Manual recovery uses the corresponding validated recovery receipt.target_app and rollback stateopenprogram/self_update/control/projection.py provides shared read-only projections for dedicated tools, Web, and Running. Owner-auth route is GET /api/self-updates?session_id=… and GET /api/self-updates/{update_id}?session_id=…, validating origin session. History uses bounded stable-cursor pagination independent of the active pointer. Evidence is revalidated through the same update’s /evidence?session_id=…&evidence_id=… route, returning only observations referenced by signed results.
Projection includes only allowlisted fields, bounded summaries, and opaque evidence IDs, excluding configuration, tokens, signing keys, environment variables, and arbitrary log paths. Evidence reads recheck owner/session/update/receipt bindings and never permit arbitrary files. Read state and associated results consistently; if no coherent snapshot is possible, return retryable error. Reads trigger no claim, repair, Job, or Scheduler.
Update projection APIs remain read-only and session-scoped for explicit tool reads. Chat does not poll these APIs. Stored update status does not infer success or failure from a disconnected window.
Tool results and durable result delivery use the existing conversation message flow. No separate update history, pagination, evidence viewer or update request form is mounted in chat.
Controller persists terminal state first; worker delivers bounded results to the original session through existing Job completion/follow-up. Stable delivery keys use update, attempt, and result type; repeated startup or lost ACK creates no duplicate message. Deliver even if terminal state precedes verifier creation or the session is closed. Deleted sessions retain undelivered status, without redirecting or creating user tasks.
Show acceptance-task completion, goal pass, installation commit, rollback completion, and later repair separately. Deterministic code generates notices without another LLM or triggering installation. DAG retains origin-caller/verification-Job relations without changing main-branch HEAD.
Reuse apps/desktop/worker-start-url.js owner-auth startup and existing /s/{session_id} routes. Before App shutdown, supervisor saves a trusted reopen intent bound to update, attempt, origin session, owner, deadline, and startup action. Desktop receives only an opaque update ID; authenticated service validates the session and constructs a same-origin route. Candidate, model, CLI arguments, and renderer cannot choose arbitrary URLs, paths, or auth fragments.
Consume the intent only during this update-triggered reopen; preserve normal startup, current windows, center tabs, and stable Release updater. ACK only after authentication and original-session load. Crashes before ACK may retry navigation without reactivation or verifier recreation. Only the designated main window consumes it; repeated consumption navigates idempotently without duplicate tabs. After user navigation away, do not force a return or insert a special recovery prompt.
Owner changes, missing session, expiry, identity mismatch, or unavailable recovery APIs retain ordinary startup and internal reasons. Do not navigate elsewhere, create sessions, or claim installation success from navigation failure. If App was closed, follow saved startup state; prepare must show and authorize opening a window when visible-App acceptance requires it. Both update and rollback versions must support minimum read/recovery protocols; reject incompatibility before activation.
References establish process, update, and worktree boundaries; this design still defines candidate sources, permissions, and acceptance.
Use linked worktrees to isolate candidate HEAD/index/working directory; serving checkout and existing dirty user checkouts are not build inputs.
Use an independent process within the user login session. V1 uses one-shot launchctl submit, without a persistent updater daemon.
Adopt staged artifacts, restart, and explicit state; candidates come from local commits rather than remote feeds.
macOS automatic updates require signing and release feeds, which do not cover unpublished local candidates, Agent acceptance, or current unsigned development-App contracts.
Reuse complete artifacts, manifests, runtime probes, and platform installation boundaries without changing stable Release discovery, download, or user installation.
Reuse worktree ownership, commit, merge/discard, and approval semantics. Self-update reads candidates only and never automatically merges the user’s main branch.
Review each task independently; start the next only after specification and quality reviews pass. Production filenames are target locations; first check existing shared primitives.
Add openprogram/self_update/, using only stdlib JSON, fcntl, and atomic replace.
types.py: phase, request/result schemastore.py: create/load/transition/claim/event journalReuse Desktop build/install scripts without new updater dependencies.
package-and-install-app.sh: separate build-only outputinstall-app.sh: prepare/commit/rollback or equivalent defer-commit interfaceupgrade.py: extract shared identity/doctor probeTools submit durable intent without stopping execution.
programs/tools/system/self_update/: prepare/status/cancelagent/permissions/approval.py: forced owner approvalagent/dispatcher/: release after final becomes durableCurrent trusted version generates fixed controller; candidate supplies only commit content.
self_update/supervisor.py and fixed shell handoffDo not restore interrupted stacks; create new Jobs after restart, without ordinary Scheduler control.
self_update/recovery.py: system gates, lease, stable Job ID, exactly-once dispatchworker/runner.py: startup hook after JobRunner ready and before ordinary Scheduleragent/job/runner.py: source/authority/tool/model snapshotself_update/iteration.py: attempt budget, scope diff, stop conditionsVerification and recovery use application services; conversations retain ordinary messages and tool results.
self_update/projection.py , Web self-updates routes, existing status tool, and Running routeapps/desktop/main.js, worker-start-url.js and startup handoffself_update/verifier_config.py , existing constrained-observation/signature protocol, and App/test adaptersscripts/refresh-local-app.sh and verify success, pre-activation failure, and post-activation rollback. Record local commit, main, remote, and installed identity separately.Before each subtask, create an isolated worktree from an immutable reviewed commit and specify exact files, RED, and full test commands. Commit independent passing changes promptly; review pass is not release pass. Verified baseline failures remain failed, never substituted with smaller suites. Record machine docs checks, browser interaction, and desktop/narrow-screen visuals separately; add no duplicate design document.
Mark in-conversation self-update implemented only after every condition holds.
Owner requests a change in the default App; Agent edits/tests/commits a worktree and invokes the dedicated tool, without developer-run scripts.
Request, artifact, and live revision bind the same SHA; dirty worktree, HEAD drift, and version drift fail before stopping the old instance.
Supervisor survives worker/App shutdown; current turn is durable without permanently running nodes.
Other running work causes waiting or update abort, never implicit cancellation; maintenance does not lose submitted input.
App bundle, embedded Python, Web/docs, Programs, Browser assets, and capability manifest all come from the candidate and pass packaged smoke.
After restart, the default-18100 owner-auth challenge proves candidate revision; anonymous health alone is insufficient.
New worker creates exactly one self_update_verify Job; every required assertion has a result/evidence, otherwise inconclusive.
Ordinary Scheduler stoppage, delay, or duplicate ticks do not affect acceptance. Worker restart, lease takeover, and orphan reconciliation still permit at most one verifier per attempt.
Default reauthorization each time; bounded_auto strictly enforces attempts, total deadline, paths, and prohibited changes, pausing on any violation.
System-gate, goal-acceptance, and timeout failures restore previous.app with verifiable worker revision and original-session results.
Simulated process/machine restarts in READY, ACTIVATING, and VERIFYING recover deterministic terminal states without duplicate activation or Agent turns.
Design, tests, reviews, candidate commit, App source marker, live worker identity, and UI verdict reflect one implementation state.
This section describes mainline/installed-product integration. Feature-branch implementation/review evidence is separate and does not mean product availability; current gaps never weaken the target contract.
File/shell/worktree tools, approval, sandbox, read-before-edit, change attribution, and session DAG already exist.
Desktop runtime preparation, Electron builder, runtime manifest, and isolated smoke already exist.
Existing install-app transactions preserve previous App and restore original state on activation/startup failure.
Reuse installation detection, source probes, Job persistence, and orphan reconciliation. Startup claims use JobRunner; ordinary Scheduler controls neither updates nor fallback acceptance.
The combined candidate includes state machine, single-active lock, durable release, maintenance, external supervisor, deferred commit/rollback, owner repair, and App-independent login recovery. Offline private inputs, fixed-SHA Electron distribution, single-port packaged-worker smoke, fixed icon rendering, and trusted-runtime browser probes passed repaired full actual packaging. Browser probes execute only revalidated saved controller runtime inaccessible to candidate writes; the controller never executes writable build runtime. Independent reviews, final combined gates, mainline release, and actual install/recovery acceptance remain incomplete.
Startup claim, stable self_update_verify Job, signed results, rollback on goal failure, durable delivery, and Desktop reopen are integrated. An old App missing packaging protocols first requires explicit full refresh; source tests do not prove installed-App restart, original-session ACK, or automatic acceptance.
Post-rollback diagnosis, constrained edit proposals, isolated worktree/commit, frozen tests, reapproval, and bounded_auto are integrated. Restart never resets attempts/deadlines; full combined checks and real update sequences still await acceptance, without replacing original failure conclusions.
Ordinary result delivery, original-session navigation, and signed HTTP, CLI/test, screenshot, scroll, and view checks are integrated. Chat embeds no update-management interface; temporary test-object operations are unsupported. Capabilities are limited to frozen checks; arbitrary UI actions and real-data mutation are unauthorized. Overall completion remains pending the three default-App scenarios and actual goal evidence.
Opening, switching or reconnecting a conversation does not query software-update history. Normal tool output and existing result delivery remain available. Software-update loading, status, retry forms and recovery notices are absent from the chat UI. The production App does not mount a temporary verification rename dialog. Verification rejects test_object interactions before any UI request; screenshot, bounded scroll and perspective checks remain supported.
Acceptance: normal chat and App shell mount without software-update UI or history requests; desktop session acknowledgement still works; install and rollback behavior remains unchanged.