Skip to content

Update: one lazurio update brings content, builds and Lazurio itself up to date; Open synchronizes its module (DEV-6656, root 0212) - #622

Merged
immakermatty merged 8 commits into
mainfrom
agent/DEV-6656-update-everything
Oct 25, 2026
Merged

immakermatty merged 8 commits into
mainfrom
agent/DEV-6656-update-everything

Conversation

@immakermatty

@immakermatty immakermatty commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Based on main at 0cfd5b9a (#620, #626, #636, #629, #637, #640 and v0.1.11 are merged). Target: Platform v0.1.12; it goes into the next v0.1.12 candidate, which runs the canary. Plan DEV-6656; root decision 0212 (HumanAndMachines/Lazurio#625, in review), points 3, 4, 5 and 7. The tools part is DEV-6682's pre-warm (decision F62 point 9), with the semantics agreed with that thread. #624 (Nová karta's Aktualizovat) stacks on this branch.

DEV-6682's verdict (2026-10-25)

The DEV-6682 thread approved the tools part (f7503f78 and the F62 point 7 fix dc3bca54, the same patches it read as 3f777c34 and 12f233b0 before the rebases) and #624's texts. It also decided both open points, implemented in 73f94efb, under these conditions:

  1. One run, one answer about the network. Only runtime-unavailable, held in memory for that lazurio update run, never kept across runs. A build in the same run whose pin is neither in the cache nor the user's Bun refuses at once with runtime-unavailable; the next run builds it (F62 point 7 and the refreshBuilt fix). A pin in the cache or the user's Bun builds normally, after a local lookup only. A person's Open or start outside the run is not affected and still asks the registry.
  2. After the stop, a cache lookup without the network. The user's Bun or the cache answers cached; otherwise the pin is not-fetched.

Review round 1

Why

Root decision 0212 point 3: one lazurio update, with the same meaning on a computer and on an Environment, brings everything the user owns up to date, and agents run it before every task. Point 4: besides the Launchpad's hourly round (#620), the Open of a module synchronizes that module in the background. Until now lazurio update changed only the product, and content reached an Environment only through the hourly round or an explicit lazurio organization sync. Since #626 an App's pinned Bun is its runtime (F62); a module's new commit can pin a Bun the runtime cache does not hold yet, and its build should not be the first to wait for it.

What changes

  • One composition (src/update/everything.ts, updateEverything), in this order:
    1. content: syncContent for every Organization the Environment holds, waiting up to 2 minutes for another content operation;
    2. tools: the Bun each app of the module checkouts the content just fast-forwarded pins, made available before any build (details below);
    3. builds: refreshBuilt (new in src/modules/module-operations.ts) builds every built app with a build state whose checkout moved past its build, in the foreground, and swaps it in (decision F58's refresh). It gives an app nobody opened no first build, and it does not build a commit whose build failed again, unless what failed may pass by itself (its pinned Bun could not be fetched, F62 point 7, as the builder and the sweep already do);
    4. Lazurio itself (performUpdate), last, because its activation restarts the Launchpad.
  • The tools part (DEV-6682):
    • Pins. runtimePins (module core) reads, from the catalog and each app's package as the content left them, the packageManager of every app the fast-forwarded module checkouts declare, each pin once, and counts the ones it cannot read. A root, a data mount or a module that did not move adds none; nothing moved, nothing is read.
    • Pre-warm. prewarmModuleRuntimes with the module core's own resolver (resolveBun: createModuleBunResolver({ home, userBun, path, tmpdir }), the one its builds use, so they share fetches under way and the cache). One call per pin, so each pin is a fetching step and then an item as soon as it is known.
    • Items (part: "tools", packageManager): cached (the user's own Bun or the runtime cache had it; nothing fetched), fetched, refused with the reason a start would give (warning: true for runtime-integrity-failed), or not-fetched.
    • Offline. The first runtime-unavailable ends the fetches for the run: that pin is refused. Each pin after it is looked up without the network (the resolver's new fetch: false): cached when the user's Bun or the cache has it, otherwise not-fetched, never tried.
    • One run, one answer about the network. That runtime-unavailable, and no other reason, is held in memory for the rest of the run and handed to its builds (refreshBuilt(onProgress, { registryUnavailable })). A build of that run whose pin is neither the user's Bun nor in the cache answers failed with runtime-unavailable at once, after a local lookup, and the next run builds it; a pin that is there builds as always. Builds outside the run (a person's start, Open or build, the Launchpad's sweep) are never told and ask the registry themselves.
    • Never a failed update. Its items are findings, the exit status stays the product's. Pins that cannot be read (a moved app's package.json missing, unreadable or pinning something other than an exact Bun, or a moved module the catalog does not declare) make the part one failed item, after the pins that were read are pre-warmed. Only a package that was read and pins nothing adds nothing.
    • Only what moved. Apps with a build state whose checkout did not move are not pre-warmed, even when their pin is not cached. A pin changes only with a commit, and this run's commits are those the content brought. Every build resolves its own pin through the same resolver before its script runs (F62 point 6), and an app whose build is current needs no Bun of its own until it starts its own server. Pre-warming every opened app would fetch about 70 MB per version nothing in the run asked for.
    • On a computer's session Launchpad the CLI builds nothing, but its tools part fetches into the cache the Launchpad's watcher then reads.
  • Isolation. A part that fails or cannot run is one item and never stops the next. The exit status stays the product's.
  • lazurio update --json keeps the product's answer (updated / up-to-date / error with every existing key) and adds items, one per repository, pinned Bun, built app and the product. The human output adds lines for what moved, a content summary, each Bun fetched or not (Warning: first for one that did not verify; nothing for one that was there), what was built, then the product's lines as before. --version, --check and the pill stay Lazurio only.
  • The Launchpad runs the same composition as a job for Nová karta's Aktualizovat: POST /api/update/everything (202 {job, joined}; a click while one runs joins it) and GET /api/update/everything (the newest run with each line's step, then its answer), behind the existing admission. Lazurio goes last through the pill's own action (updateNow: a check, then the existing apply, whose unit outlives the restart). It is not offered on a public Environment.
  • The Open of one module (src/content/open-sync.ts). After the Launchpad answered a Start or Open, or the gateway's ensure of a navigation, syncContent({organization, repository}) runs for that module in the background. It runs at most once per module in 5 minutes, never for a checkout or root the last round left blocked, and never before the answer. The F58 watcher then builds and swaps.
  • SyncProgress carries to (the remote's commit) on fetching and fast-forwarding, for the progress lines.
  • Docs: docs/update.md (section "One lazurio update", the tools part included), docs/content-sync.md (the new callers), docs/decisions.md (F9's second amendment of 2026-10-24 with point 7 on the tools part, alternatives, tests and risks; F62 point 9 now points to it).

What stays

  • The product update's state machine, lock, activation, the pill and --version are unchanged. The existing update tests pass unchanged.
  • src/modules/bun-runtime.ts (Modules: the Bun an App pins is its runtime, resolved for every path that runs its code (F62, #618) #626) gains only fetch: false on the resolver's input: the user's Bun or the cache as it is, read without the version's exclusion, otherwise runtime-unavailable at once. Every other caller resolves as before.
  • The two cores stay separate, each with its own lock and outcome. The background (hourly round, Open) never checks, downloads or activates a product version, and does not pre-warm: its builds resolve their own pins.
  • No new daemon, state file or second state machine. The job lives in the Launchpad's memory.
  • No Folder text changes, so no template revision. Folder instruction texts (telling agents to run lazurio update before tasks) are another PR.

Decisions to confirm in review

  • Order. 0212 point 3 lists Lazurio first. This PR runs content, tools and builds first and Lazurio last, so the restart never interrupts them; the reasoning and alternatives are in F9's second amendment.
  • A computer's session Launchpad (macOS). It owns its apps' dependency trees until it ends, so the CLI does not build there: the Launchpad's watcher builds what the content brought. The CLI's JSON then has no build items there. On a Remote Environment (systemd-user) the CLI builds and swaps.
  • Tools only for what moved (above), not for every app with a build state.
  • The two offline decisions above are DEV-6682's; they are listed here so the review covers their implementation.

Verified

  • CI on the pushed head 2b3eefe7: green: check (ubuntu-24.04), static checks, tests (1/2), tests (2/2), scope (the macOS check and Macroscope are skipped by the workflow).
  • Locally (macOS): bun run check:static (lint, typecheck, check:public, build:proof, smoke:proof) passes on 802456f6. 2b3eefe7 is the same patches on main 0cfd5b9a, which changes only CI workflows; lint and typecheck pass there and pr:preflight reports ready_to_push.
  • tests/update-everything.test.ts tests/module-built.test.ts tests/bun-runtime.test.ts tests/launchpad-update.test.ts tests/content-sync.test.ts tests/recover-prompt.test.ts tests/module-bun-runtime.test.ts tests/update-cli.test.ts tests/launchpad-routes.test.ts tests/launchpad-buddy.test.ts, one run on 802456f6: 106 pass, 1 skip (the opt-in LAZURIO_TEST_NETWORK=1 case), 0 fail. All with a fake installer, no network.
  • New tests for the tools part, written first, with Modules: the Bun an App pins is its runtime, resolved for every path that runs its code (F62, #618) #626's seams and no network:
    • tests/update-everything.test.ts, with the real resolver and a fake installer:

      • a pin not cached is fetched after content and before the build that needs it, only for the module checkouts that moved, then found in the cache; nothing moved, nothing read;
      • offline stops fetching at the first runtime-unavailable; after it a pin the cache or the user's Bun has is cached, the rest not-fetched, one attempt at the registry only;
      • one run, one answer: the builds of that run are told the registry does not answer, by runtime-unavailable alone (not by a full disk), and never in the next run; nothing moved, no answer;
      • every other refusal is an item and the pre-warm goes on; integrity is a warning;
      • the user's own Bun is not fetched;
      • the update never fails because of tools (pins that throw, a resolver that throws or refuses); pins that cannot be read make one failed item after the readable ones are pre-warmed;
      • the CLI's words.
    • tests/bun-runtime.test.ts: the lookup without the network (fetch: false): the user's Bun or the cache, otherwise runtime-unavailable at once, never the installer, no wait for a version's exclusion held by another fetch, nothing written.

    • tests/module-built.test.ts, a real runtimePins on the module core: a pin read once, a package without one, npm@10.0.0, a package.json that is gone, and a moved path that is not declared.

    • tests/module-built.test.ts, on real git and real builds, with the fake installer:

      • a published commit pinning bun@1.4.99 is fast-forwarded, its Bun fetched by the tools part before the build began, and the build ran with exactly that Bun;
      • offline, a commit pinning another Bun: the pre-warm stops, and the run's build refuses with runtime-unavailable with no second attempt (the installer is asked once in that run, and no build begins); the old build keeps serving;
      • a person's build outside the run still asks the registry and records its failure;
      • online again, with nothing new to fast-forward, the build is built again (F62 point 7);
      • under the offline answer, a pin the cache holds builds as always, with no fetch.

      Reverting the build gate or the refreshBuilt alignment makes this test fail (checked for both). The CLI test now lists the user's own Bun as a cached tools item.

  • Earlier tests of this PR, still passing:
    • tests/update-everything.test.ts: the order and each line's steps; a failing product keeping the content's answers, and the reverse; the busy wait; the job a second start joins; the Open (exactly that module, debounced, never blocking, never for a blocked checkout or root); the catalog mapping.
    • tests/module-built.test.ts: lazurio update --json fast-forwards a module behind and lists every item with Lazurio last, and the Launchpad swaps the new build in; a failing Lazurio still answers the content; the Launchpad's own run builds and swaps at once, does not build a failed commit again, and gives an app nobody opened no first build.
    • tests/launchpad-update.test.ts: the routes behind admission, a joined second click, Lazurio last through the pill; updateNow when nothing is newer and when the check fails.

Risks

  • The Launchpad's job ends with the restart Lazurio's activation causes. What the run did stays in its owners' records; the page keeps the lines it last read (Nová karta: Aktualizovat runs lazurio update and shows its progress per module (DEV-6656, root 0212 point 7) #624).
  • A big app's build holds a lazurio update for its minutes.
  • When the CLI and the Launchpad's watcher react to the same fast-forward on a Remote Environment, they serialize on the build lock and the second finds the build there. A fetch of one Bun version is shared the same way, under the version's exclusion (F62 point 3).
  • Offline: the first pin of a run still waits for the registry up to the fetch bound where the network drops packets instead of refusing; everything after it in that run answers from the disk.
  • A build refused under the offline answer records no build failure (it never began); the item says so, and the next run or the Launchpad's sweep builds it.

Commits

  • 5e897479, affb6a36, 95aa4c85: the composition, the Open, the JSON without a Folder, and the order content → tools → builds.
  • 7d2d2fe0: contract tests for the tools part.
  • f7503f78: the tools part (DEV-6682 OK).
  • dc3bca54: refreshBuilt builds again a build whose pinned Bun could not be fetched (F62 point 7; DEV-6682 OK).
  • 73f94efb: DEV-6682's two decisions: one answer about the network per run, and a lookup without the network after the stop.
  • 2b3eefe7: review round 1, pins that cannot be read make the tools part a failed item.

The rebases onto d60e5119, ba769965 and 0cfd5b9a had no conflicts; git range-diff shows every commit unchanged.

Follow-up PR (stacked on this one): #624, Nová karta's Aktualizovat button with progress per module and the Bun rows.

🤖 Generated with Claude Code

Note

Add content synchronization and compose lazurio update from content, builds, and product update

  • Adds a content-sync core that fast-forwards existing clean checkouts to remote branches, refuses dirty or in-progress checkouts, and never materializes absent repositories. Sync runs in the Launchpad maintenance sweep (hourly), after module opens (throttled to once per 5 minutes), and via a new organization sync CLI command in cli.ts and sync.ts.
  • Plain lazurio update now composes content sync, built-app refresh, and Lazurio update as ordered parts, continuing after a failed part; --version updates stay product-only. Adds a Launchpad update-everything job endpoint in server.ts and part orchestration in everything.ts.
  • Sync results are persisted as atomic JSON records, surfaced in doctor as a new content-sync check, and shown as localized blocked notes in Launchpad module status views.
  • Git sync operations in git.ts run noninteractively (no hooks, no maintenance), use anonymous HTTPS access with an isolated temp home, and classify network failures as denied, unavailable, or failed.
  • Behavioral Change: plain lazurio update now performs content and build work before the product update, and the Launchpad sweep fast-forwards clean primary checkouts before building; dirty checkouts block sync and rebuilds rather than being touched.

Macroscope summarized 76a6a11.

immakermatty added a commit that referenced this pull request Oct 24, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 24, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 113993c to 76a6a11 Compare October 24, 2026 16:56
@immakermatty
immakermatty marked this pull request as ready for review October 24, 2026 17:04
immakermatty added a commit that referenced this pull request Oct 24, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 76a6a11 to 18e4671 Compare October 24, 2026 17:32
immakermatty added a commit that referenced this pull request Oct 24, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 18e4671 to 4d51db0 Compare October 24, 2026 17:42
immakermatty added a commit that referenced this pull request Oct 25, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 4d51db0 to 12f233b Compare October 25, 2026 11:51
immakermatty added a commit that referenced this pull request Oct 25, 2026
…s fetched (DEV-6682, F62)

lazurio update's tools part (#622) now makes the Bun the moved modules pin
available before any build, and its lines reach the page. Each pin is a row
named Bun after the modules and before Lazurio: "Stahuje se verze 1.4.3" /
"Fetching version 1.4.3" while it is made available, "Stažena verze 1.4.3" /
"Version 1.4.3 fetched" once it is, or a finding in plain words: not fetched
now (offline, or not tried after that), a download that failed its check, no
room on the disk, or not prepared. A Bun that was there already and the tools
part as a whole have no row; no code or path is shown.

The preview's scripted run pins a Bun for Deals, and a headless Chrome check
of the page shows the Bun row fetching while Deals waits and fetched before
Deals builds. F47's addendum of 2026-10-24 names the rows and the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 25, 2026
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 12f233b to 3dcee08 Compare October 25, 2026 12:34
immakermatty added a commit that referenced this pull request Oct 25, 2026
…s fetched (DEV-6682, F62)

lazurio update's tools part (#622) now makes the Bun the moved modules pin
available before any build, and its lines reach the page. Each pin is a row
named Bun after the modules and before Lazurio: "Stahuje se verze 1.4.3" /
"Fetching version 1.4.3" while it is made available, "Stažena verze 1.4.3" /
"Version 1.4.3 fetched" once it is, or a finding in plain words: not fetched
now (offline, or not tried after that), a download that failed its check, no
room on the disk, or not prepared. A Bun that was there already and the tools
part as a whole have no row; no code or path is shown.

The preview's scripted run pins a Bun for Deals, and a headless Chrome check
of the page shows the Bun row fetching while Deals waits and fetched before
Deals builds. F47's addendum of 2026-10-24 names the rows and the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGES_REQUESTED on 3dcee08. In src/modules/module-operations.ts:2262, runtimePins converts every readPinnedBun failure into null. A moved app with an unreadable, missing, invalid or unsupported package.json therefore contributes no pin and no tools failure item, although the update contract says pins that cannot be read produce one failed tools-part item. The next build may fail, but an unopened app has no build item either, so the update can appear clean while pre-warm silently skipped its declaration. Let the read failure propagate to updateEverything’s tools catch (or collect and report it explicitly), retaining null only for a successfully read package with no pin; add a real runtimePins test for a malformed/unreadable package. Independent focused checks on the stacked head: static checks passed; update-everything 14/14, module-built 24/24, bun-runtime 11 pass/1 opt-in skip, launchpad-update 3/3. Tests used Bun 1.4.4 on macOS; repository pins 1.4.2. No merge/release performed.

immakermatty and others added 8 commits October 25, 2026 14:04
…up to date; Open synchronizes its module

Root decision 0212 points 3, 4, 5 and 7 (plan DEV-6656), decision F9's
second amendment of 2026-10-24. Plain `lazurio update` now runs one
composition (`updateEverything`): the content (`syncContent` for every
Organization the Environment holds), the builds of what changed
(`refreshBuilt`: every built app with a build state whose checkout moved
past its build, built and swapped in through F58), a seam for the tools
modules declare (DEV-6682) and Lazurio itself last, because its activation
restarts the Launchpad. Each part keeps its core, lock and outcome; one that
fails never stops the next. `--json` keeps the product's answer and adds
`items`, one per repository, built app and the product; the exit status
stays the product's. `--version`, `--check` and the pill stay Lazurio only.

The installed Launchpad runs the same composition as a job for Nová
karta's Aktualizovat (`POST`/`GET /api/update/everything`, behind the
existing admission; a click while one runs joins it), with Lazurio last
through the pill's own action (`updateNow`). After a person's Start or
Open, or the gateway's `ensure` of a navigation, the module's checkout is
synchronized in the background (`createOpenSync`): once per module in 5
minutes, never for a checkout or root the last round left blocked, never
before the answer; the build watcher builds and swaps.

Tests: tests/update-everything.test.ts, the new cases in
tests/module-built.test.ts (real git and builds through the CLI and the
Launchpad's run) and tests/launchpad-update.test.ts. Docs: update.md,
content-sync.md, F9's second amendment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…em reasons stay out of the update's error contexts

CI on #622: the compiled product's update test reads the exact answer of
`lazurio update --json` where no Folder is known, and the guard of the
recover prompt finds every `reason:` literal in src/update as an error
context id. Without a Folder the command is now Lazurio's alone, with no
`items` (as the docs already said), and the items' reasons are typed
constants of the composition (`contentNotRun`, `partFailed`,
`productNotInstalled`), not context literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DEV-6682 thread and this plan agreed on the order sync → tools → builds,
so that a build never runs before the Bun its module pins is there. The tools
part is still a seam with nothing in it; it now sits between content and
builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pin (DEV-6682)

The tests come before the implementation, with #626's seams and no network:
the resolver a start uses with Bun's installer as a fake, and on the real
consumer (real git, real builds) a module whose published commit pins a
Bun the cache does not hold.

They fix the semantics agreed with the DEV-6682 thread. A pin not cached is
fetched after content and before the build that needs it, and only for the
module checkouts this run fast-forwarded. Offline, the first
runtime-unavailable ends the pre-warm and the pins after it are not-fetched,
never tried. Every other refusal is an item with its reason and the
pre-warm goes on; a download that did not verify is a warning. The user's
own Bun is not fetched. The update never fails because of tools. The
CLI's JSON now lists the user's own Bun as a cached tools item, and a build
whose pinned Bun could not be fetched is built again by a later update.

These tests fail until the next two commits land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…before any build (DEV-6682, F62 point 9)

The tools part was a no-op seam. It now reads the Bun each app of the
module checkouts the content part fast-forwarded in this run pins
(runtimePins in the module core, from the commits it brought, each pin
once) and makes it available with prewarmModuleRuntimes and the module
core's own resolver, the one its builds use. It runs after content and
before builds, one pin at a time, each pin a fetching step and then an
item with part "tools": cached (the user's Bun or the runtime cache had
it), fetched, refused with the reason a start would give (warning: true
for runtime-integrity-failed), or not-fetched after the first
runtime-unavailable, which ends the pre-warm for the run. It never fails
the update; the exit status stays the product's. Nothing moved, nothing is
read.

Apps whose checkout did not move are not pre-warmed, even with a build
state whose pin is not cached: a pin changes only with a commit, and each
build resolves its own pin through the same resolver before its script
runs (F62 point 6). The CLI prints a line per pinned Bun fetched or not;
the Launchpad's Aktualizovat job runs the same part with its own resolver.
docs/update.md, F9's second amendment (point 7, alternatives, tests,
risks) and F62 point 9 say the tools part is real now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t be fetched (F62 point 7)

refreshBuilt was written before decision F62 and skipped every checkout
whose last build failed. Since #626 the builder builds such a checkout
again when what failed may pass by itself (runtime-unavailable,
runtime-disk-full), and so does the background sweep; refreshBuilt now
agrees with it. Without this, an update after an offline one answered the
old runtime-unavailable failure instead of building the app now that the
registry answers. A failed build script still waits for an explicit build.

The real-consumer test of the tools part covers it: offline the build
fails for its runtime, and the next run, with nothing new to fast-forward,
builds it with its pinned Bun.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…un answers from the disk (DEV-6682 decisions, F62 point 9)

The DEV-6682 thread approved the tools part and decided its two open
points. First, one run gets one answer about the network. The pre-warm's
first runtime-unavailable, and no other reason, is held in memory for the
rest of that run and handed to its builds (refreshBuilt's
registryUnavailable). A build whose pinned Bun is neither the user's nor
in the runtime cache then refuses at once with runtime-unavailable after a
local lookup, and the next run builds it. A pin that is there builds as
always. A person's start, Open or build outside the run, and the sweep,
still ask the registry themselves. Second, after the stop each remaining
pin is looked up without the network, so a Bun the user or the cache
already has is cached, not not-fetched.

The lookup is the resolver's own: fetch: false reads the user's Bun and
the cache as they are, without the version's exclusion (a fetch under way
elsewhere is not waited for), and refuses runtime-unavailable otherwise.
Before, an offline update waited for the registry again in every build
whose pin it had not fetched, up to the fetch bound each on a network that
drops packets.

Tests: the lookup in bun-runtime (never the installer, no wait for a held
exclusion); the offline pre-warm with cached and not-fetched pins after
the stop; the run's answer reaching its builds by runtime-unavailable alone
and never the next run; and on real git and builds, no second attempt by
the run's build, a person's build still asking, a later run building, and
a cached pin building under the offline answer. F62 point 9 gains one
sentence; F9's second amendment point 7, alternatives, tests and risks,
and docs/update.md follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…art a failed item, never silently clean

The review of #622 on 3dcee08 found that runtimePins turned every
readPinnedBun failure into "no pin". A moved app whose package.json was
missing, unreadable or pinned something other than an exact Bun added no
pin and no item, although F9's second amendment point 7 says pins that
cannot be read are one failed item of the part. An app nobody opened has
no build item either, so the update looked clean while the pre-warm had
skipped its declaration.

runtimePins now answers the pins it read and how many it could not:
every app the module declares is read, only a package that was read and
pins nothing adds nothing, and a moved module the catalog does not declare
counts too. The composition pre-warms the pins that were read, then sets
the one failed tools item. The CLI says which part it was and that a
start or build of those apps names the reason.

Tests: a real runtimePins on the module core (a pin read once, a package
without one, a pin that is not an exact Bun, a package.json that is gone,
a moved path not declared), and the composition pre-warming the readable
pins before the failed item.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/DEV-6656-update-everything branch from 3dcee08 to 2b3eefe Compare October 25, 2026 13:06
immakermatty added a commit that referenced this pull request Oct 25, 2026
…s fetched (DEV-6682, F62)

lazurio update's tools part (#622) now makes the Bun the moved modules pin
available before any build, and its lines reach the page. Each pin is a row
named Bun after the modules and before Lazurio: "Stahuje se verze 1.4.3" /
"Fetching version 1.4.3" while it is made available, "Stažena verze 1.4.3" /
"Version 1.4.3 fetched" once it is, or a finding in plain words: not fetched
now (offline, or not tried after that), a download that failed its check, no
room on the disk, or not prepared. A Bun that was there already and the tools
part as a whole have no row; no code or path is shown.

The preview's scripted run pins a Bun for Deals, and a headless Chrome check
of the page shows the Bun row fetching while Deals waits and fetched before
Deals builds. F47's addendum of 2026-10-24 names the rows and the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 25, 2026
#622's review fix makes the tools part's pins an answer with how many
could not be read ({ pins, unreadable }). The preview's scripted run of
Aktualizovat follows it, so the script typechecks again; the page and its
rows are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty

Copy link
Copy Markdown
Contributor Author

Thank you for the review on 3dcee08 (#622 (review)). The finding is a real defect, a contradiction between the code and F9's second amendment point 7, and it is fixed in 2b3eefe. That is the reviewed head's commits plus the fix, rebased onto main 0cfd5b9, which changes only CI workflows (#640):

  • runtimePins (src/modules/module-operations.ts) now answers { pins, unreadable }. Every app a moved module declares is read. Only a package that was read and pins nothing adds nothing. A package.json that is missing, unreadable or pins something other than an exact Bun counts as unreadable, and so does a moved module the catalog does not declare.
  • updateEverything pre-warms the pins that were read, then sets the one failed tools item, so the update never looks clean while the pre-warm skipped a declaration. The CLI line now says the moved modules' pins could not all be read, and that a start or build of those apps names the reason.
  • New tests:
    • a real runtimePins on the module core in tests/module-built.test.ts: a pin read once, a package without one, npm@10.0.0, a package.json that is gone, and a moved path that is not declared;
    • the composition pre-warming the readable pins before the failed item, in tests/update-everything.test.ts.
  • docs/decisions.md (F9 second amendment point 7 and its tests) and docs/update.md say the same.

On the Bun version: my local runs used Bun 1.4.2, the repository's pin; CI uses the same pin.

#624 is rebased onto 2b3eefe with its two reviewed patches unchanged (git range-diff: both =). One small commit on top adapts its preview script to the new { pins, unreadable } answer, now at 1a829e8. A headless browser check of the preview shows the Bun row as before. The new heads get CI and then a new review request; nothing is merged.

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immakermatty APPROVED on 2b3eefe. The previous pin-read blocker is fixed: runtimePins distinguishes a successfully read package without a pin from missing/invalid/unreadable declarations and unknown moved modules; updateEverything pre-warms readable pins before reporting one failed tools item. The reviewed commits are patch-equivalent after the CI-only rebase (range-diff). In a clean detached checkout, check:static passed, the focused 10-file suite passed (106 pass, 1 opt-in network skip), and git diff --check passed. Local runner Bun 1.4.4; the repository pins 1.4.2 and exact-head CI is green. This approves #622 only. The stacked #624 UI needs a separate correction for display of the new tools failure. No merge or release.

immakermatty added a commit that referenced this pull request Oct 25, 2026
… finding, never a clean update

The review of #624 on 1a829e8 found that the page dropped every tools
line without a pin, the tools part's one failed item among them. #622
emits that item when the pins of the moved modules cannot all be read. A
moved app nobody opened has no build line either, so the run looked
clean: only Lazurio, up to date.

The page now reads that item and shows one more Bun row after the pins'
rows: "U některých aplikací se nepodařilo zjistit, jakou verzi
potřebují" / "For some apps, the version they need could not be
determined". It names no pin or path and shows no code. Other tools lines
without a pin are still left out.

A regression test feeds the real job answer, the composition with an
unreadable pin through createUpdateJobs, serialized as the route sends it,
through parseUpdateJob and updateView; it fails without this change. The
preview's scripted run includes one unreadable pin, and a headless Chrome
check shows the finding. F47's addendum says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty merged commit ee13932 into main Oct 25, 2026
7 checks passed
immakermatty added a commit that referenced this pull request Oct 25, 2026
…s fetched (DEV-6682, F62)

lazurio update's tools part (#622) now makes the Bun the moved modules pin
available before any build, and its lines reach the page. Each pin is a row
named Bun after the modules and before Lazurio: "Stahuje se verze 1.4.3" /
"Fetching version 1.4.3" while it is made available, "Stažena verze 1.4.3" /
"Version 1.4.3 fetched" once it is, or a finding in plain words: not fetched
now (offline, or not tried after that), a download that failed its check, no
room on the disk, or not prepared. A Bun that was there already and the tools
part as a whole have no row; no code or path is shown.

The preview's scripted run pins a Bun for Deals, and a headless Chrome check
of the page shows the Bun row fetching while Deals waits and fetched before
Deals builds. F47's addendum of 2026-10-24 names the rows and the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 25, 2026
#622's review fix makes the tools part's pins an answer with how many
could not be read ({ pins, unreadable }). The preview's scripted run of
Aktualizovat follows it, so the script typechecks again; the page and its
rows are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 25, 2026
… finding, never a clean update

The review of #624 on 1a829e8 found that the page dropped every tools
line without a pin, the tools part's one failed item among them. #622
emits that item when the pins of the moved modules cannot all be read. A
moved app nobody opened has no build line either, so the run looked
clean: only Lazurio, up to date.

The page now reads that item and shows one more Bun row after the pins'
rows: "U některých aplikací se nepodařilo zjistit, jakou verzi
potřebují" / "For some apps, the version they need could not be
determined". It names no pin or path and shows no code. Other tools lines
without a pin are still left out.

A regression test feeds the real job answer, the composition with an
unreadable pin through createUpdateJobs, serialized as the route sends it,
through parseUpdateJob and updateView; it fails without this change. The
preview's scripted run includes one unreadable pin, and a headless Chrome
check shows the finding. F47's addendum says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immakermatty added a commit that referenced this pull request Oct 25, 2026
…er module (DEV-6656, root 0212 point 7) (#624)

Root decision 0212 point 7. Nová karta's Aktualizovat runs `lazurio update`, the one composition of #622, and shows its progress per module:
- content per Organization;
- the Bun each moved App pins (fetching, fetched, offline, integrity, disk, and one finding when some pins could not be read);
- builds;
- Lazurio itself last.

A Bun that was already there has no row. The page shows no codes or paths. Agents keep Modules current with `lazurio update`; the button is optional.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty deleted the agent/DEV-6656-update-everything branch October 25, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants