31 KiB
In-place OS updater migration — 2026-11-03
Current activation result (supersedes preparation-only status below)
Real no-ISO transition demonstrated in a disposable installed Debian system:
the accepted 2.0.0-alpha+uat backend was running before bootstrap, the protected
D09 owner was installed/admitted/activated, its real worker applied the complete
reviewed Debian transaction, and the actual 2.0.1-alpha candidate became healthy.
This is no longer a file-copy-only test. Production signature approval and actual
Framework/Yaya installation are not claimed. The current deployed Framework
layout still has the concrete custody prerequisite described below.
Final os-bootstrap-native-r7 and os-bootstrap-postboot-r7 both report exit 0.
Earlier os-bootstrap-native-r4 and os-bootstrap-native-r5 also report guest exit 0
under /home/archipelago/Reports/opencode-full-release-20261029/. They use accepted
backend SHA256 2cf004fcc7f207c65b3bbd1eac248f8c9556ec1cd0ec139011fb4b1e1ef96494
and independently built candidate
59e0a2091011e0770365ab5c61505d73abef59cdf3f284afa7b6aa1000d9c248.
The native candidate source inventory is
fca2e13e421523a9a3cc2940e7285a4c3b7e7c1b4af3913ad2b332b7dce9bea8;
its frozen Cargo.toml declares 2.0.1-alpha. Native artifact execution is not
replaced with Python in these native attempts. A subprocess inside the management
unit invokes the real D09 client; this is not dashboard/browser OTA acceptance.
The accepted old artifact is tied to source 33d61e94053f3b3dd1fb0d38026122cd6d9648b7,
whose tree was canonically accepted as c32a925647eab63ba0f1cac7e6bd135b857d5b7b;
the original UAT archive and embedded source receipt were independently hash-checked
before injecting the old executable into the disposable disk.
Actual effects: 12 package upgrades plus new
linux-image-6.12.115+deb13.1-amd64=6.12.115-2, zero removals, through the fixed
full-suite solver and real package locks/APT/libapt/dpkg. Three Debian pockets and
four components were authenticated by the executor. Status reached
PREPARE → DOWNLOAD → VERIFIED → APPLY_INTENT → VERIFY → REBOOT_REQUIRED;
the candidate reached D09 AWAITING_OBSERVATION. Native node key/public key,
passwd/group/shadow and synthetic wallet/identity/stopped-uninstalled canaries
were preserved. A forward wallet-canary write survived refused bootstrap replay.
Full app/container preservation and native terminal observer completion are not
inferred from these canaries.
The release-authentication substitution is explicit: a QEMU-only exact-manifest native fixture verifier and preappointed fixture verifier custody. No production signing key was used, no production verifier was changed, and production signature approval is false in every result. Actual production first custody must retain the already appointed native release-root verifier, or independently established protected verifier custody; arbitrary downloaded scripts cannot appoint it.
Actual-installed custody prerequisite
Framework inventory framework-installed-migration-inventory-r1.json, lines
8510–8519, records /var/lib/archipelago as UID/GID1000, mode0755, dev65024 inode2.
The executor ROOT used by r4/r5/r7, /var/lib/archipelago/os-update, is beneath an
application-owned ancestor. Root-custody checks correctly refuse that actual
layout. Do not chown the application's data root or weaken secure(). Executor
coordination requests a root-controlled sibling /var/lib/archipelago-os-update
(also outside application data rollback), or a separately qualified custody
transition. At that checkpoint bootstrap read the fixed ROOT literal from the hash-verified
executor package without executing it and recognized those two ABI locations,
with exact policy hashes and existing-authority checks at both. It
never silently relocates a ledger. The fixture will match the recorded UID1000
data-root ownership when the executor adopts the sibling. r4/r5/r7 used a root-owned
data-root model and do not close this installed-layout gap.
Executor continuation now fixes ROOT to /var/lib/archipelago-os-update, adds
protected-parent/live-path/journal continuity checks, and refuses any legacy entry
without explicit root migration/reconciliation. Bootstrap policy accepts only the
new ABI. Real isolated UID1000 custody integration passed 15 checks and actual
package closure passed, retaining c01_uplink.py. See
/home/archipelago/Reports/OS-OTA-CUSTODY-PATH-20261103.md for exact paths and
receipts. This corrects the source custody blocker; a fresh exact new-root native
artifact/boot run is still required, and the r4/r5/r7 evidence above is unchanged.
The recorded Framework administrator setup also explicitly says old privileges were not retired. Before production bootstrap, the separately owned guarded isolation/exclusion procedure must establish that the service/runtime cannot rewrite root custody through inherited administrative capabilities. The pinned D09 exclusion evidence is a prerequisite, not something this helper manufactures. An independently verified login alone does not prove that exclusion. Yaya's separate administrator receipt is not the Framework recreation exception.
Boot qualification progression
BIOS/GRUB on the same updated r4 disk actually booted
6.12.115+deb13.1-amd64, Debian build 6.12.115-2, retaining the old .107 boot
files and forward data. Fresh externally anchored D09 readmission reactivated
the candidate without another OS APPLY_INTENT. Initial postboot observer attempts
exposed a fixture binding-field error, then a real bootstrap sandbox omission:
the owner could not open its exact OS executor lock. Read-only kernel/package/
preservation verification passed outside the owner. The bootstrap-owned policy
now includes that lock file (not the whole OS state root). r6 exposed a separate
fixture issue: printing the entire kernel provenance map to the slow serial
console left the intentionally partial frontend/runtime fixture alive long enough
for the real candidate watchdog to submit AUTOMATIC_FAILURE. Reactivation correctly
refused the outstanding notice; it was not deleted or reset. The fixture now keeps
full provenance in evidence files and prints a bounded digest/phase summary.
Final r7 passed the actual owner callback with os_postboot_verified: true and
POSTBOOT_CONFIRMED. Boot ID c5fcea58-759b-4315-9ef4-906b1da36141; running
kernel 6.12.115+deb13.1-amd64, build Debian 6.12.115-2. The same disk booted
through BIOS/GRUB (no direct-kernel substitute). Old .107 image/initrd, actual
native identity, principal files and the forward-written wallet canary remained
exact. There was one OS APPLY_INTENT, and the candidate received a fresh
invocation through authenticated D09 readmission against history retained outside
the guest. OS postboot confirmation is not native terminal/UI observation or
routine Automatic-NTS boot acceptance. None of the failed attempts was relabelled.
Current no-reinstall support matrix
| Route / starting state | Evidence and current disposition |
|---|---|
| Root-custody-qualified Debian 13 amd64 fixture, accepted old native → new candidate | Passed real bootstrap, D09 owner/client/worker, 13-package transaction, actual BIOS/GRUB new-kernel boot and authenticated owner postboot confirmation; disposable auth adapter only |
| Legacy installed dashboard OTA self-installs its privileged owner | Not supported by this evidence; use the independent one-time administrator path |
| One-time independent administrator bootstrap | Implemented and exercised; pinned artifact/source/plan/backend/helper inputs, existing access, writer exclusion and custody required before admission |
| Actual recorded Framework UID1000-owned data root / old privileges retained | Blocked prerequisite, not an ISO requirement: fix executor state custody and qualify service/runtime exclusion through the existing migration lane; do not chown data or relax checks |
| Yaya | No installed transition qualification here; independently revalidate inventory/access/maintenance authority; Framework recreation exception does not transfer |
| Existing D09/OS ledger or interrupted bootstrap/activation | Refused; exact external reconciliation/readmission required; no state reset or financial rollback |
| Future native OTA with an installed qualified owner | Can request an independently admitted authenticated plan through D09; it does not gain generic root, appoint its own maintenance authority or bypass postboot checks |
| Production signing / immutable candidate install / physical UAT | Open; no signing, publication, physical-node apt/migration/reboot or commits performed |
| Bookworm, arm64, vendor kernels, Debian major upgrades, UEFI | No qualification claimed by this amd64 trixie/BIOS fixture; retain the executor contract's explicit limitations |
The administrator requirement is installation/admission of a privileged trust boundary using existing separately verified access, not reinstalling Debian or inventing new node identities. Production first verifier custody uses the already appointed native release-root verifier. Maintenance exclusion must be established and later reconciled by its appointed owner. Subsequent D09 requests can come from native OTA; the old software is not presumed able to grant itself these privileges. Fresh external postboot authority in this fixture is distinct from mandatory manual confirmation on every future boot; the existing trusted automatic recovery delegation must be qualified separately, not replaced here.
Verification commands and final receipts
Source checks: 19 tests passed; Python compile checks and scoped
git diff --check passed. Exact runtime bootstrap/activation/activation-fixture
bytes in the r7 source inventory match the current worktree hashes below.
python3 -B -m unittest discover -s scripts/tests -p 'test_os_updater*.py' -v
Recorded durable disposable activation command (use fresh unit/output names for another run; existing evidence is never overwritten):
sudo systemd-run --unit=os-bootstrap-native-20261103-r7 \
--property=CPUQuota=200% --property=MemoryMax=8G --property=MemorySwapMax=0 \
/usr/bin/python3 -B /home/archipelago/Projects/archy-uat-publication-20261031/scripts/tests/qualify_os_updater_activation.py \
--baseline /home/archipelago/Reports/opencode-full-release-20261029/os-bootstrap-vm-r1 \
--output /home/archipelago/Reports/opencode-full-release-20261029/os-bootstrap-native-r7 \
--native-artifact /home/archipelago/Reports/opencode-full-release-20261029/os-ota-native-candidate-r1 \
--accepted-payload /home/archipelago/Reports/opencode-full-release-20261029/uat-all-ngit-package/payload.tar
sudo systemd-run --unit=os-bootstrap-postboot-20261103-r7 \
--property=CPUQuota=200% --property=MemoryMax=8G --property=MemorySwapMax=0 \
/usr/bin/python3 -B /home/archipelago/Projects/archy-uat-publication-20261031/scripts/tests/qualify_os_updater_boot.py \
--wait-applied 1800 \
--applied /home/archipelago/Reports/opencode-full-release-20261029/os-bootstrap-native-r7 \
--output /home/archipelago/Reports/opencode-full-release-20261029/os-bootstrap-postboot-r7
Heavy operations take /tmp/opencode/release-heavy.lock inside the limited job.
No Framework/Yaya contact was made. Fixtures use owned disks, no writable host
shares, and preserve prior attempts. All this lane's test jobs have completed.
Paths below are relative to /home/archipelago/Reports/opencode-full-release-20261029/:
| Final evidence | SHA256 |
|---|---|
os-bootstrap-native-r7/result.json |
7bf3e9335847d8960a39a65ccc50f6da202ed37ab421824cbce596cda15e3433 |
os-bootstrap-native-r7/source-sha256.json (complete exercised package inventory) |
c1b3b72b94ffcba1f6a8bc6005df0b07bc39fca1f388cfa547310cce223fbe0c |
os-bootstrap-native-r7/activation/os-ota-stage/bootstrap-result.json |
00712469749fe1691222d83868606b2d257af976dfd54923f8809f1416107382 |
os-bootstrap-postboot-r7/result.json |
92166a6c9b6c6f64a32e1ace3f328d3a95378c48368d7fac19c667ff43ac200d |
os-bootstrap-postboot-r7/boot/os-ota-stage/bootstrap-postboot-result.json |
7e5d47164362a01cbb299db5a30275619a3948b25ce62bc8c580c6cb99b08c28 |
| Current lane source | SHA256 |
|---|---|
scripts/os_updater_activate.py |
00a0cac5c8076a9a8d3700697bf120f4076a1734e9a745278bce944b00262717 |
scripts/os_updater_bootstrap.py |
1bafbec2436b240f72d531f4658d0d5274058a1bb80cdac08543cbad4781fc6c |
scripts/tests/os_updater_activation_guest.py |
d86a49ada972ac5d9c3a1e23f3b32ed25166e85cfb90df577bd7ec1460e74177 |
scripts/tests/os_updater_postboot_guest.py |
59d06bb0b6c2c7adea389ffefc59fbeb9c2b4845753be7743daf76b910c83f6c |
scripts/tests/os_updater_baseline_guest.py |
5cee577f2caf75a8c1a6d4f18cb38ed4ce5e5df9124b187bbc19e23517ba6c6c |
scripts/tests/qualify_os_updater_bootstrap.py |
be7e81697a61dff2266eae855b6746ada318ab479fd04b5bd7a7b2eb1267b5fd |
scripts/tests/qualify_os_updater_activation.py |
7147a79c1f36aa1531535aa5f53625ef9aa98fd0ee5fb8a63694bdbc77e4552c |
scripts/tests/qualify_os_updater_boot.py |
4c065e3e64101b179801619e07ec1ee4ef27453dd9ec6db428abb490869f24d7 |
scripts/tests/test_os_updater_activate.py |
f61d358d6a88db3939444e8051f5c77d998c84a9aab2165b19ebe2f61c2b9862 |
scripts/tests/test_os_updater_bootstrap.py |
02bdb238154e671eb65ac2dc9519b4fcfb813b3707171f4abc64639911ad516e |
docs/system-level-ota-design.md |
d478f6488a5c2ffffe0cc67c27774a2aac1f64946b30bb4ea180a2d9da492544 |
The executor contract is now available at docs/OS-OTA-CONTRACT-20261103.md.
scripts/os_updater_activate.py implements one-shot activation through the actual
pinned D09 provisioner and lifecycle owner. It does not construct its own D09
ledger, issue APPLY directly or replace the OS executor. Local bootstrap/activation
guard tests and real installed-VM results are recorded separately. The earlier preparation-only
checkpoint and its hashes remain historical evidence, not current source pins.
Activation independently pins its approval and helper, the complete protected package inventory, exact current/new backend, D09 admission/workspace helper, OS plan/manifest/verifier and preservation inputs. It rechecks the independent administrator and service principals, machine ID, access receipts and externally drained manager. All unattended package-writer units must already be inactive and masked. Bootstrap does not create/change principals, keys, privileges or timer policy. Production prerequisites (including python3-apt) must already be installed through separately qualified authority.
It journals durable intent before installation, publishes the exact OS plan,
supplies the provisioner's fixed incoming OS input set, invokes
--install-package then --admission, starts the actual lifecycle owner and
submits grant A once. A pending systemd start is observed through the owner's
protected ledger without resubmitting it. Any failed/interrupted activation or
existing D09/OS transaction is refused on re-entry. Package files may have been
installed before interruption; the intent remains for independent reconciliation,
not automatic retry or rollback. There is no financial-data restore path.
The new activation approval has exactly version: 1, prepared_sha256,
package_root, package_files (complete relative-path → SHA256 map),
admission_sha256, os_inputs (plan.json/manifest.json/preservation.json → SHA256),
helper_sha256 (os_updater_activate.py), and owner_dropin_sha256 (the fixed
bootstrap-owned service policy). The additive 55-os-bootstrap.conf permits only
the two real dpkg lock files, the OS executor lock and OS transaction status directory to be writable
inside the owner sandbox. Existing policy is never overwritten. Approval and package must be in
independently established root custody. Before calling activation, the externally
appointed coordinator supplies protected D09 incoming old/new/restore snapshots,
exclusion and admission under /var/lib/archipelago-d09/incoming, and the exact
native release-root verifier at /usr/libexec/archipelago-os-release-verifier.
No existing-version updater is assumed able to appoint those authorities itself.
Prospective independently authorized administrator command (not run on a node):
sudo /usr/bin/python3 -I -B /root/reviewed/os_updater_activate.py \
--approval /root/reviewed/activation-approval.json \
--approval-sha256 "$INDEPENDENTLY_APPROVED_ACTIVATION_SHA256"
Successful bootstrap reports D09_PREREQUISITE_ACTIVATED, not OS completion.
Subsequent updates use the admitted native D09 path and authenticated OS plan.
The OS stage, postboot confirmation, existing installed-data migration and
physical/operator acceptance remain separately evidenced gates.
Read-only recorded access clarification: framework-admin-completed.json reports
existing archipelago-admin UID1001 with fresh SSH/root access and password
recovery verified, old effective sudo rules unchanged, old privileges not retired
and no cutover. yaya-admin-verified.json separately reports fresh key-only SSH,
UID1001, sudo-root and its existing route working. Those receipts mean a newly
created account is not inherently required for this bootstrap: use and freshly
revalidate existing independent access. They are historical observations, not
permission to mutate either node now. Yaya's admin receipt does not grant the
Framework-only container-recreation exception or authorize an OS maintenance run.
Historical preparation-only checkpoint
Superseded preparation-only scope and original source/evidence hashes
The following sections retain the earlier checkpoint and original hashes. They are superseded by the current activation results and custody gates above.
Answer at that checkpoint
An ISO reinstall is not inherently required for Debian/kernel updates or for installing a protected updater on an existing Debian installation. However, the actual deployed Archipelago → protected OS owner → OS transaction transition is NOT yet qualified. A one-time independent-administrator bootstrap is the proposed bridge when the old OTA path cannot safely install its own privileged owner. Administrator work and reinstalling the machine are different operations.
This lane delivered an inert preparation helper and ten filesystem/control tests, not a supported live migration or a successful OS transaction. There is no activation command in the helper. No no-reinstall acceptance is inferred from copying code. The OS executor contract was not available at this checkpoint.
Worktree: /home/archipelago/Projects/archy-uat-publication-20261031.
No GSD, delegation, live contact/change, apt, reboot, signing, publication or
commit was performed. Tests are small unprivileged temporary-directory tests;
no heavy shared resource or build/VM lock was needed.
Recorded deployed state, not a new live probe
Sources under /home/archipelago/Reports/:
OPENCODE-UAT-20261031.md: Framework accepted native/dashboard source33d61e94053f3b3dd1fb0d38026122cd6d9648b7, canonically merged atc32a925647eab63ba0f1cac7e6bd135b857d5b7bwith the same tree. Installed backend SHA2562cf004fcc7f207c65b3bbd1eac248f8c9556ec1cd0ec139011fb4b1e1ef96494; payload SHA256f7563b5e509280782adebb7b75608e45bd5628fa53c58dbccf83ceb954fd4be1. This is the accepted2.0.0-alphaUAT baseline, not the dirty candidate tree. A Git commit ID is not the executable hash or the source-inventory SHA256.opencode-full-release-20261029/FRAMEWORK-INSTALLED-MIGRATION-20261103.md: installed C01/D09 roots absent; two nonempty legacy pending rows, fourteen explicit uninstalls, data on a distinct filesystem, actual rootless overlay storage and subordinate IDs. Do not reinterpret absent D09 as empty app data. Python 3.13 shared library/GI prerequisites are missing for new owner machinery.framework-installed-migration-inventory-r1.jsonin that report directory: read-only collector exit 0, hostnameframework-pt, observed kernel6.12.113+deb13-amd64, boot IDb9aa6a8a-08ec-47bf-b6f4-774a57ae4d3f. This timestamped receipt cannot establish current quiescence, independent recovery access or transaction eligibility.AUTHORITY.md: Framework alone has guarded container-recreation and separate administrator exceptions. Existing access must be verified before any old shared-account privilege retirement. Neither exception automatically covers Yaya. The root query in the inventory is not proof of a separate working admin.
Inspected git show c32a925...:core/archipelago/src/update.rs: accepted apply and
rollback already route through D09; retained historical copy code is explicitly
not an admitted activation route. Unknown components are skipped by that legacy
copy implementation. Shipping an owner file in a runtime archive is therefore
not a verified bootstrap. Current package-d09-c01.py generates deterministic
owner files with hashes, but is not an authentication or admission authority.
provision-d09-lifecycle.py --install-package requires external management drain,
refuses existing authority, installs multiple paths and enables a service;
--admission separately pins prerequisite, release, exclusion and old/new/restore
objects. It must not be casually called from the old updater or substituted with
this inert helper. Existing C01/D09 migration/provision files were not edited.
No-reinstall support matrix
| Starting state / route | Current evidence | Status / required action |
|---|---|---|
| Accepted Framework UAT, no C01/D09 owner; dashboard OTA only | Accepted source requires D09; recorded authority absent | Automatic bootstrap unverified; do not claim supported |
| Same node, independent admin + authenticated pinned inputs | Inert preparation helper and ten tests | Proposed in-place bridge; actual installation/activation/OS transaction still blocked |
| Framework guarded C01 migration | Separate lane has nonempty-history/layout work; qualification incomplete | Preserve its full migration/admission gates; do not replace it |
| Yaya | No equivalent installed-state transition qualified in this lane | Reinventory separately; no inherited Framework recreation/admin-split permission |
| Any existing D09 binding or ledger / OS ledger | Helper refuses all, including apparently terminal ledgers | External authoritative reconciliation required; never delete/reinitialize to proceed |
| Interrupted bootstrap | Pending generation retained; retry refused | Independent reconciliation, no automatic cleanup/replay |
| Kernel/Debian package change after bootstrap | No composed actual OS transaction run | Not qualified; executor transaction/recovery/reboot gates remain |
| Debian major-version upgrade | No compatibility or upgrade qualification | Unsupported by this work; no blanket no-reinstall promise |
| Missing administrator access or untrusted privileged base | No safe custody established | Access/recovery intervention needed; no claim that an ISO is necessarily required |
Helper contract (preparation only)
scripts/os_updater_bootstrap.py requires effective root and a protected
administrator-provided approval file whose exact SHA256 arrived through an
independent authenticated channel. A digest downloaded alongside an untrusted
payload is NOT authentication. Root-owned bytes alone are not maintainer approval.
The helper, approval, payload and all ancestors must already have root custody;
the production reader rejects writable ancestors, symlinks and file hardlinks.
It never executes payload bytes or invokes a package manager/service manager.
The strict JSON approval has these fields:
schema: 1,machine_id_sha256: exact/etc/machine-idbytes, including newline.current:version,source_sha256,backend_sha256. An independent reviewed source/build receipt must establish the version/source ↔ executable relation; the helper hashes installed/usr/local/bin/archipelago, not updater state.candidate: same keys. Heresource_sha256is SHA256 of thefilesmap encoded as sorted compact JSON (sort_keys=True, separators=(',', ':')). Backend hash is a pinned future activation input; it is not installed by this helper.admin: positive distinctuid,service_uid,access_receipt_sha256. The independently verified access receipt must also occur inobservations. This records external verification; it does not itself log in or check sudoers.observations: root-relative path → exact SHA256 of protected inventory/access receipts, reread before staging. Receipts must be freshly issued at cutover; hashing a stale receipt cannot establish current access or writer exclusion.files: flat safe filename → SHA256, maximum 256 files. All source bytes are reread and checked; control filenames are reserved. No archive extraction, symlinks, arbitrary destination paths, financial databases or data restore.
Supported comparison grammar is intentionally limited to numeric
MAJOR.MINOR.PATCH-alpha[+uat]; candidate numeric version must strictly increase.
Same-version, malformed-channel and downgrade inputs refuse. This is not a
general SemVer or Debian package-version comparator.
Under its own exclusive lock, the helper refuses existing D09 authority and the
provisional OS ledger path. It durably writes a new pending-<approval-sha256>
directory containing exact code, approval and control, then atomically renames
it to /var/lib/archipelago-os-bootstrap/prepared. Its state is explicitly
PREPARED_NOT_ACTIVATED. Interrupted directories and existing prepared objects
are retained/refused. No installed code, units, permissions, wallets, identities,
app storage or financial data are rolled back or replaced. This is atomic
generation preparation, not atomic active-owner installation.
Commands and execution boundaries
Completed locally (10 passed, zero failed):
python3 -B -m unittest discover -s scripts/tests -p test_os_updater_bootstrap.py -v
git diff --check -- scripts/os_updater_bootstrap.py scripts/tests/test_os_updater_bootstrap.py docs/system-level-ota-design.md
Prospective preparation only, from independently verified administrator access, after deploying reviewed root-owned inputs; not run on any installed node:
sudo /usr/bin/python3 -I /root/reviewed/os_updater_bootstrap.py \
--approval /root/reviewed/bootstrap-approval.json \
--approval-sha256 "$INDEPENDENTLY_APPROVED_SHA256" \
--payload /root/reviewed/os-owner-payload
For a qualified disposable realm, --root /root/disposable-old-installation
redirects preparation paths only. It does not create isolation, perform a real
OS transaction or supply production custody evidence. Do not use a target root
containing symlink/bind aliases to installed-node data. There is intentionally no
proposed live activation, rollback or apt command before the executor contract.
Tests cover inert atomic visibility and preservation, interrupted write/retry, all listed authority blockers, source/backend/inventory drift, approval mismatch, non-root rejection, root-custody refusal, shared admin, traversal, duplicate JSON, same-version/downgrade and candidate source-map mismatch. Successful-path tests explicitly emulate root custody using mocks in temporary directories; these do not qualify privileged installation, namespace exclusion or actual old binaries.
OS-OTA-CONTRACT handoff and remaining exit gates
At inspection, OS-OTA-CONTRACT-20261103.md was absent both in /Reports/ and
/Reports/opencode-full-release-20261029/. The status integration coordination
note requests that contract and proposes signed-manifest component
os-update-plan.json. That name is a proposal, not an accepted executor ABI.
No worker, wire, core update or existing C01 migration/provision source was edited.
The independently progressing Reports/OS-OTA-INSTALLED-QUALIFICATION-20261103.md
now records a prepared real ext4 Debian guest and the same missing-contract
dependency. Its baseline preparation is not an OS transaction pass. A handoff at
Reports/INPLACE-OS-OTA-MIGRATION-20261103.md points that lane to this bootstrap
schema for the required old-artifact → bootstrap → actual executor composition.
Executor/coordinator must settle and qualify:
- Actual OS-owner entrypoint/module set, unit, control and ledger locations,
authenticated plan/inspect grammar and its lock. The helper's provisional
/var/lib/archipelago-os-update/ledger.jsonis not an established executor contract. Reconcile all actual blocker paths before any activation. - Atomic installation and control activation against pinned current version/source/executable, exact immutable candidate bytes and actual required Python/GI dependencies. Production package authenticity and source/build provenance are still gates; no unsigned candidate gets implicit fleet trust.
- Integrate the executor's real lock and current authoritative ledger checks; preparation's lock does not exclude D09/OS writers. Revalidate observations, operator access, runtime retirement and source bytes at activation time.
- Disposable old-installation replay using the accepted native artifact and nonempty representative preserved state, then the real new updater/owner and actual Debian package/kernel transaction. Test interrupted bootstrap, failed owner activation, concurrent requests, stale/altered plan, downgrade, apt/dpkg interruption and authoritative recovery; include reboot/boot selection where required. A stub executor, copied files or mocked package manager cannot pass.
- Explicit code-only recovery before OS mutation; after package mutation, use executor-owned reconciliation/recovery. Never advertise reversal of arbitrary maintainer scripts or restore old financial databases. Keep external ledger history and consumed grants outside the code rollback domain.
- Exact immutable-artifact qualification and separately authorized installed
Framework acceptance, preserving its access/wallets/identities/persistent data
and stop/uninstall decisions. Yaya requires its own inventory/authority gates.
Use the shared
/tmp/opencode/release-heavy.lockprotocol for heavy fixtures.
Until these pass, the precise answer is “in-place migration is the intended route, possibly with one administrator bootstrap; actual deployed no-reinstall OS OTA support remains unverified.” This report does not close release UAT.
Source and evidence SHA256 at this checkpoint
Other lanes may subsequently change inspected dependencies; these are point-in-time pins, not a frozen composed candidate. No file below was signed or published here.
| Input | SHA256 |
|---|---|
scripts/os_updater_bootstrap.py |
bb57ca43cd247be79a5b32f635c98dc10f2e20e0ee14dedfab4dfdd630cc08c6 |
scripts/tests/test_os_updater_bootstrap.py |
02bdb238154e671eb65ac2dc9519b4fcfb813b3707171f4abc64639911ad516e |
docs/system-level-ota-design.md |
3c877c3651b0bc06732c8a5bfed674a1f7b608ea5d2b181f3e4bae354902159f |
inspected scripts/package-d09-c01.py |
7f897936d245cdc85d21884a9133399ed8d7e1fa7515117f4e89cef90f58cbb5 |
inspected scripts/provision-d09-lifecycle.py |
061af2fea666e80b117b89d812a3fd82bad802a34626d45bf84a343ac1481d61 |
inspected current core/archipelago/src/update.rs |
0215858a23e1699fb0e2a0f80d8fc56d46782724aa7f6d23fad84087ac03648c |
AUTHORITY.md |
2f050dae0f5f33ad08e63c5a634a8974fb1b1ffaf295133a9a814de8dfa67410 |
FRAMEWORK-INSTALLED-MIGRATION-20261103.md |
cf602e41ad9c5e04ec42153d7f953d88f584a603b5db6bf50f889315fe9fb43e |
framework-installed-migration-inventory-r1.json |
4da8843aa6150c67105928fd4f84daae5405af74add08a2eb98f8730566876b2 |
OPENCODE-UAT-20261031.md |
1334a25d79b8ef4a7bdba8ac3cf6d217449c050eecf6f551e49ce42d9ea547b3 |