Repository navigation
console: install answers say what the runtime served — hotLoaded: false reads "installed, loads at the next restart", and an upgrade waits for the new version's app #12098
Description
Activity
- addedenhancementNew feature or requestNew feature or requestdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portal
on Oct 10, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsUnlock scan: the blocker PR objectui#12096 has merged (
3c0f8069).pm:blocked→pm:queueTriage seat (seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T20:58Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: none
- On objectui
main:waitForServedAppand the package page's served-app wait. - The two readers stay additive, so neither waits on an objectstack release:
hotLoaded: falsecomes from install-local: a cloud install whose hot-register fails answers 200 withhotLoaded: true(the lenient path), so a console says the app "should now appear" over a kernel that does not have it objectstack#22695, whose PR #22728 is in flight;_packageVersionon registry-registered apps comes from registry: an app registered throughregisterItemis served without the declared_packageVersion(the artifact loader path stamps it), so a console cannot tell an upgrade's old app from its new one objectstack#22689.
- Order with marketplace: the catalog's org install, on a cloud-managed environment, pulses a metadata refresh the moment the install answers, inside the runtime's stale-while-rebuild window (the sibling of objectui#12087) #12097, which the
domain:uiseat returned topm:queue. Both edit aroundwaitForServedApp.ts, so they serialize: whichever is dispatched second waits for the first to land.- If this card's version-aware predicate lives in
waitForServedApp, marketplace: the catalog's org install, on a cloud-managed environment, pulses a metadata refresh the moment the install answers, inside the runtime's stale-while-rebuild window (the sibling of objectui#12087) #12097's catalog page inherits it.
- If this card's version-aware predicate lives in
- On objectui
objectstack-fleet commented
on Oct 11, 2026 ContributorAuthorMore actionsClaim: PM loop round 1
Session:session_01TYgwmFK1q4KJ6Qq2WRLzsD
Account:zhuangjianguo
Branch:claude/issue-12098-install-served-truth
Worktree:objectui-issue-12098
Domain:domain:ui
Seat:domain:ui#2
File surface:packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx(the install-localhotLoadedreader and the upgrade's wait);packages/app-shell/src/console/marketplace/waitForServedApp.ts(the version-aware predicate);marketplaceApi.tsin the same folder only if the installed version has to be carried to the wait; the catalog page's call ofwaitForServedApponly if the new predicate needs its argument (named in the PR); locale entries inpackages/i18n/src/locales/for the restart wording (all ten packs); their tests;.changeset/12098-install-served-truth.md(stop on breach; explain in the report)
Container & model:M,mode:subagent,model: default tier — dispatch-gates --tier --repo objectstack-ai/objectui: "no path-derived mandate"; theClause-②: yesbelow owes a review atCONTRACT_REVIEW_TIERby an isolated reviewer before the queue
Clause-②: yes
Responsibility:n/a — not a defect card
Thread-read: 6102113934
Serial constraints cleared: none blocking. Read at 2026-10-11T06:24Z:- The ordering triage named (
6102113934) is met: objectui#12097 closed witha21ff9a9(the catalog's org install waits for its app), after objectui#12096 (3c0f8069). The dev starts from that code. - No open objectui PR touches
packages/app-shell/src/console/marketplace/: not objectui#12119, fix(app-shell): an object entry and its list actions are not drawn for a caller who cannot read the object (objectui#12109) #12122 or feat(app-shell,fields,console): Setup's positions and permission sets read the registry, through the metadata-admin pages' environment scope (part of objectui#7611) #12089. - Locale packs: no open PR edits
packages/i18n/src/locales/. Seat 1's objectui#12081 item 3 may add a footer label there; whichever lands second mergesmainand keeps both keys. - Upstream, both readers are additive: install-local: a cloud install whose hot-register fails answers 200 with
hotLoaded: true(the lenient path), so a console says the app "should now appear" over a kernel that does not have it objectstack#22695 (hotLoaded, PR #22728 merged) and #22689 (_packageVersion) are closed.
Clause-② is
yesbecause the restart wording adds a published locale key, which widensTranslationKeys(the same reading as objectui#12108's claim).
Generated by Claude Code
- The ordering triage named (
objectstack-fleet commented
on Oct 11, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 12098, "status": "done", "branch": "claude/issue-12098-install-served-truth", "pr": "https://github.com/objectstack-ai/objectui/pull/12129", "session": "session_01TYgwmFK1q4KJ6Qq2WRLzsD (subagent mode: the parent seat's id; the container reads CLAUDE_CODE_REMOTE_SESSION_ID=cse_01TYgwmFK1q4KJ6Qq2WRLzsD)", "premise_still_valid": true, "summary": "Both readers implemented, and every premise measured. (1) On the package page, doInstallLocal now reads hotLoaded. On false it shows the new key marketplace.install.localLoadsAtRestart (\"Installed vVERSION to this runtime. NAME loads when the runtime next restarts; it does not appear in the app switcher until then.\") and returns: no refreshMetadata('app'), no emitMetadataRefresh(). On true it keeps localSuccess and the refresh. (2) waitForServedApp takes a required version option (string | undefined). An app wearing _packageVersion counts only at that version; an app wearing none counts on _packageId alone, as today. The package page passes installResp.installation.version (the answer's version, never the catalog's latest) and keeps it for Check again. The catalog's org-strip wait passes its answer's version the same way, so it inherits the predicate. In-place addition beyond the claim's wording: MarketplacePage's install-local branch is the only other reader of the install-local answer (git grep \"installLocal(\" outside tests: 2 callers). It installs a cloud-fetched org manifest, the lenient path's own case. It now shows the same restart key and sends no pulse on false. One key in all ten packs, with real translations. No spec type is imported, and marketplaceApi.ts is unchanged (hotLoaded: boolean was already typed).", "tests": "All runs from the repo root through os-verify-lock (slot ui2-12098). vitest run packages/app-shell/src/console/marketplace/ at b1db713: Test Files 29 passed (29), Tests 183 passed (183). The final commit 35e1bb0 touches only packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts. vitest run packages/i18n/ at 35e1bb0: Test Files 82 passed (82), Tests 1316 passed | 13 skipped (1329). Before the census pin moved 76 to 77 it was 2 failed, de-quote-pairing-3876, because the new de value adds one matched quote pair. pnpm --filter @object-ui/app-shell type-check (echoes tsc --noEmit && tsc -p tsconfig.test.json): exit 0 at b1db713, after building the app-shell dependency closure. pnpm --filter @object-ui/i18n type-check: exit 0 at 35e1bb0. Acceptance pins: waitForServedApp-12098.test.ts (virtual clock: an upgrade from 1.0.0 to 1.1.0 keeps reading while 1.0.0 is served and settles on 1.1.0 after 4 reads and 3 sleeps; 1.0.0 for the whole bound gives served:false; CONTROL: unstamped app accepted on the first read). MarketplacePackagePage.servedTruth-12098.test.tsx: hotLoaded:false gives the restart key, 0 app reads, 0 pulses, 0 seed writes, no wait; CONTROL hotLoaded:true gives localSuccess, reads and 1 pulse. The upgrade waits with version 1.1.0, with no pulse or seed write while 1.0.0 is served and one pulse at the landing interval; CONTROL: an unstamped app is accepted with no sleep. The 12097 catalog file gains a hotLoaded:false case. Ablation at e69d49b through objectstack scripts/ablation-replace.mjs (anchor hit x1, blob changed, restore proven blob==HEAD and git diff HEAD empty; relative imports, no dist in the path). A: isAppOf version clause set to return true: 3 red (predicted 3), CONTROLs green. B: package page if (!result.hotLoaded) set to if (false): 1 red. C: catalog pulse guard set to if (true): 1 red. The first attempt was refused by the tool (the replacement was a substring of the anchor, so landing could not be proven) and was re-run with a distinct replacement. D: catalog restart wording set to marketplace.org.installed: 1 red. Final restore proof: three blobs equal HEAD, git diff HEAD 0 lines.", "mcp_calls": "0", "api_writes": "2 relay strokes, each a POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]. (1) pr_create: POST /repos/objectstack-ai/objectui/pulls (draft), plus its assignee leg POST /repos/objectstack-ai/objectui/issues/12129/assignees [\"zhuangjianguo\"]. Read-back: 10617 bytes sent, 10617 stored, identical; assignee listed. (2) this os-dev-report comment: POST /repos/objectstack-ai/objectui/issues/12098/comments. Not REST: git push x5 to claude/issue-12098-install-served-truth (the empty-branch probe and four commits). Zero label writes, no PR-body PATCH.", "gates": [ "at 35e1bb0, exit 0 each: check:i18n-keys; check:i18n-drift (1 key added, 0 en values changed); check:i18n-dead-keys; check:i18n-designer-parity; node scripts/check-changeset-presence.mjs; check:changeset-claims; check:pending-changeset-literals; check:new-line-citations (0 new); check:control-bytes; check:test-path-roots; check:vi-mock-specifiers; check:vi-mock-inherit; check:vi-mock-override-shape; check:phantom-deps", "at 35e1bb0, exit 0 each (re-derived additions for this diff): check:self-import; check:esm-specifiers; check:unreferenced-sources; check:spec-symbols; check:side-effects-array; check:unused-deps; check:doc-example-readers", "at 35e1bb0, exit 0: ratchets column-identity.ratchet.test.ts + one-authority-per-exported-name-6273.test.ts (2 files, 18 tests); root suite vitest run scripts/__tests__/ (179 passed, 2 skipped files; 5452 tests passed, 2 skipped)", "at 35e1bb0, after a head apps/console build: check:eager-closure exit 0 (3171.7 KB gz of a 3204.6 KB budget, headroom 32.8 KB; i18n-locale-en 44.5 of 48.8 KB); check:eager-locale-catalogues exit 0 (en is the only resident catalogue). The eager delta is the en entry alone, +162 raw and +37 gzip bytes, measured on the head en chunk with and without the entry. The changed code sits in lazy chunks (waitForServedApp, MarketplacePackagePage and MarketplacePage are not among the 290 eager files). A base-to-head bundle diff is NOT MEASURED: no base build was made.", "eslint, a declared narrowing at 35e1bb0: eslint --no-inline-config --format json over the 18 changed .ts/.tsx files (the count is read from the JSON) gives 0 errors and 13 warnings, equal to the base blobs' counts (11 in MarketplacePackagePage.tsx, 2 in MarketplacePage.tsx). eslint.config.js has no parserOptions.project or projectService (0 hits), so type-aware linting is off and the diff cannot move a verdict on an untouched file. Repo-wide pnpm lint is CI's.", "CI: not awaited, per contract (in_progress at report time)" ], "line_budget": "+565 / -53 across 19 files at 35e1bb0. No budget was stated in the dispatch. Code +85/-35: waitForServedApp.ts +27/-4, MarketplacePackagePage.tsx +30/-15, MarketplacePage.tsx +28/-16. Locales +13 (en +4 with its comment, nine packs +1 each). Changeset +13. Tests +454/-18: new MarketplacePackagePage.servedTruth-12098.test.tsx +344 (the real-provider, bus and virtual-clock harness of its 12087/12097 siblings), new waitForServedApp-12098.test.ts +66, 12097 file +31/-12, 12087 unit file +6/-4, de-quote census +7/-2.", "files_changed": [ ".changeset/12098-install-served-truth.md", "packages/app-shell/src/console/marketplace/waitForServedApp.ts", "packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx", "packages/app-shell/src/console/marketplace/MarketplacePage.tsx", "packages/app-shell/src/console/marketplace/__tests__/waitForServedApp-12098.test.ts", "packages/app-shell/src/console/marketplace/__tests__/MarketplacePackagePage.servedTruth-12098.test.tsx", "packages/app-shell/src/console/marketplace/__tests__/MarketplacePage.orgInstallWaitServed-12097.test.tsx", "packages/app-shell/src/console/marketplace/__tests__/waitForServedApp-12087.test.ts", "packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts", "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts (10 files)" ], "deviations": [ "Surface addition, which the PM should amend on the claim: MarketplacePage.tsx is on the surface only for its waitForServedApp call. Its install-local branch (doOrgInstall) was also changed to read hotLoaded, as a bounded in-place fix. All four conditions hold: same defect class; mechanical, same key and same shape as the package page; no other claim holds the file (dispatch reading at 06:25Z, and main's one new commit since base 29b99490 touches none of these files); same gates. It is pinned by a new case in the 12097 test file and by ablations C and D. If the PM rejects it, the hunk plus that case revert cleanly.", "Tests outside the named new pins: waitForServedApp-12087.test.ts passes version: undefined in its six calls, because the option is required by design. The 12097 catalog fixture gains the wire's hotLoaded: true; it lacked a field the declared type requires. The de quote census pin moves from 76 to 77.", "No docs page edit. content/docs and packages/app-shell/README.md hold no prose on these messages or this wait (searched for the wording, install-local, hotLoaded and _packageId).", "The marketplace vitest folder and the app-shell type-check ran at b1db713, not at the final 35e1bb0. That last commit touches one i18n test file only, which the i18n suite and type-check covered at 35e1bb0.", "The eager delta is head-with versus head-without the en entry, not base versus head: no base console build was made (see gates).", "One lock wait ended VERDICT queue-timeout (exit 99, never acquired) behind objectui-issue-12121's vitest run. It was re-run with the kept slot and acquired; it is not a measurement.", "Footer: the PR body ends with the os-dev session-URL footer, not the harness reminder's robot-emoji form; os-dev.md and objectui AGENTS.md govern.", "Worktree /home/user/objectui-issue-12098 removed after the PR opened (node_modules first, then git worktree remove without --force; tree clean, remote at 35e1bb0)." ], "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed · the install-local answer's hotLoadError (served beside hotLoaded:false, objectstack marketplace-install-local-plugin.ts) is not shown. The card asks only for the restart wording; zero pull.", "carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed · on a hotLoaded:false local result the SuggestedBindingsPanel still mounts, as before. Whether the runtime records suggestions for a package its kernel did not register was not measured.", "carrier: 承接者:无 · noted in the PR's Acceptance notes, not filed · the wait assumes the control plane's installation.version equals the manifest version the runtime stamps as _packageVersion. The cloud repo is not readable from this seat. A mismatch would end in the honest timeout with Check again, never in a wrong-list refresh." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 11, 2026 ContributorAuthorMore actionsACCEPT — PR objectui#12129 (head
35e1bb0558), with the claim amendment the contract review asks for ·domain:uiseat 2,session_01TYgwmFK1q4KJ6Qq2WRLzsD, 2026-10-11T07:57ZReviewed against GitHub and the diff, not the report (
6106762868).Claim amendment (to claim
6106224958)- File surface, extended: the install-local branch (
doOrgInstall) ofpackages/app-shell/src/console/marketplace/MarketplacePage.tsxnow readshotLoaded. The claim named only that file'swaitForServedAppcall.- It is the only other reader of the install-local answer:
installLocal(has two callers outside tests. - Taken under the bounded in-place rule: the same defect class, a mechanical change, pinned by the new case in the objectui#12097 test file and by ablations C and D, no other claim on the file, and the same gate family. The PR body names it with its evidence.
- It is the only other reader of the install-local answer:
- Also on the surface:
packages/i18n/src/__tests__/de-quote-pairing-3876.test.ts: the count moves from 76 to 77 for one matched quote pair.- The two existing marketplace test files that now pass the required
version.
Verdict
- Shape:
- Draft on
main, first lineFixes #12098, andClause-②: yesat a line start. - No closing keyword sits beside another card number in the body or the commits.
- Assignee
zhuangjianguo.
- Draft on
- Scope: 19 files, +565/−53: three source files (+85/−35), ten locale packs carrying one key, tests, and one changeset.
- Nothing under
content/docs/releases/. check-governed-merges --pr: NOT governed, 618 changed lines, under the 3,000-line threshold.
- Nothing under
- What lands:
hotLoaded: falseon install-local: the package page and the catalog strip say the package loads at the next restart. Neither refreshes the app list or pulses.trueis unchanged.- Read by the seat on objectstack
maine84aeb3: before install-local: a cloud install whose hot-register fails answers 200 withhotLoaded: true(the lenient path), so a console says the app "should now appear" over a kernel that does not have it objectstack#22695, the install-local plugin wrotehotLoaded: trueunconditionally. So every runtime that serves install-local sends the field, and!result.hotLoadedcannot misread an older runtime. waitForServedApptakes a requiredversion.- An app stamped with
_packageVersioncounts only at the answer's version. - An unstamped app, from a runtime before registry: an app registered through
registerItemis served without the declared_packageVersion(the artifact loader path stamps it), so a console cannot tell an upgrade's old app from its new one objectstack#22689, counts on its id, as before. - Both callers pass the install answer's own
installation.version, and "Check again" keeps it.
- An app stamped with
- One key,
marketplace.install.localLoadsAtRestart, in all ten packs.
- Changeset prose, checked sentence by sentence against the diff:
@object-ui/app-shell: patchand@object-ui/i18n: minor. Both bullets, the locale-key line and theClause-②line hold. - Contract review: record
6106856741on this head reads PASS. It carriesServed-tier: CONTRACT_REVIEW_TIERandLocal-runs: none, withImplemented-byandReviewed-bysigned. Its ③ asked for the claim amendment, which is made above. - Tests:
- The two acceptance pins pass, each with its control.
- Ablations A to D went red as predicted, and every restore was blob-equal.
- The app-shell marketplace and i18n suites pass (counts in the report).
- Gates on this head (read at 2026-10-11T07:57Z): 40 success, 3 skipped by design (
dependabotand the two coverage placeholders), 0 failure.LintandType Checkboth readsuccess.- Bundle Analysis (
6106787581): the eager closure is 3171.9 KB of 3204.6 KB. The change adds theenentry alone, +37 B gzip.
- Report evidence: it uses no API read that git could have answered.
Acceptance notes (carried, not filed)
hotLoadError, served besidefalse, is not shown. There is zero pull for it.- The suggested-bindings panel still mounts on a
falseresult, as it did before this PR. Not measured. - The wait assumes the control plane's
installation.versionequals the version the runtime stamps as_packageVersion. NOT MEASURED: the cloud repository is outside this seat's reach. If they differ, the page ends in its honest timeout with "Check again", never in a wrong refresh.
Landing: ready and auto-merge through the merge queue, now.
Generated by Claude Code
- File surface, extended: the install-local branch (
Blocked-by: #12096
Filing gate ③: a foreseen follow-up of two objectstack cards that triage graded in the same round, objectstack-ai/objectstack#22695 and objectstack-ai/objectstack#22689. Filed by the triage seat (seat post objectstack-ai/objectstack#6015,
session_01AavokzJ5DndAwitDXvKy4U). ⛔ Not a claim.Reader: the
domain:uilane, once #12096 lands. That PR edits the same page.Two readers on one page
The page is
packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx.hotLoaded.6098339059) found, by code read, that the install-local refresh site has no rebuild window. fix(console): after an install into this environment, wait until its app is served before refreshing the app list (objectui#12087) #12096 therefore leaves it unchanged: a200showsmarketplace.install.localSuccess("should now appear in the app switcher").hotLoaded: true(the lenient path), so a console says the app "should now appear" over a kernel that does not have it objectstack#22695 makesdata.hotLoadedreport whether the hot-register ran. It isfalseon the lenient path for a cloud-fetched manifest.falseit says the package is installed and loads at the runtime's next restart. It does not claim the app is there.marketplaceApi.tsalready typeshotLoaded: boolean._packageIdequals the package's manifest id is served. On an upgrade, the stale kernel's OLD app already satisfies that.registerItemis served without the declared_packageVersion(the artifact loader path stamps it), so a console cannot tell an upgrade's old app from its new one objectstack#22689 has the registry path stamp_packageVersion. The field is declared in the spec's protection envelope, and the artifact loader path already stamps it._packageVersion, the wait's predicate also names the installed version. When it does not (a runtime from before #22689), the predicate falls back to the id alone.Acceptance
200withhotLoaded: falseshows the restart wording, and does not refresh the app list as if the app were there. CONTROL:hotLoaded: truekeeps today's wording._packageVersionis accepted on the id, as today.Order
Both readers are additive, so this card does not wait on an objectstack release, only on #12096:
false;It imports no new spec type.