Skip to content

console(marketplace): on an offline boot (OS_CLOUD_URL=off) Installed Apps → Details renders "App Marketplace is turned off" ahead of the install-local reseed / purge menu, so neither is reachable #11627

Description

@objectstack-fleet

QA-source: objectstack-ai/objectstack#21782 · platform-core.marketplace-console-honesty · acceptance[2]

Clause A3 of platform-core.marketplace-console-honesty fails in the ObjectStack 17.7 pre-release checklist run objectstack-ai/objectstack#21782 (framework subject 316be321e, console pin 2e818d0b51ec). An independent verifier (VF4, RUNNER rule 7; code at the pin) confirmed it: P3. It predates the 17.6.0 console pin 31971ff1e; no open duplicate was found. Owner: objectui.

Reproduction

  1. Boot a scratch copy of the showcase with OS_CLOUD_URL=off. Install-local caches under {cwd}/.objectstack, so do not use a shared tree.
  2. os package install examples/app-crm/dist/objectstack.json -r http://localhost:{port}.
  3. Server truth: /runtime/config reports marketplace:false, and Installed Apps lists com.example.crm v4.0.0.
  4. Browser, as admin: Setup → Installed Apps. The row offers Refresh / Details / Uninstall only. Click Details, which opens /system/marketplace/com.example.crm.
  5. Expected: reseed / purge affordances that issue POST /api/v1/marketplace/install-local/com.example.crm/{reseed,purge}-sample-data.
  6. Actual: "App Marketplace is turned off", with 0 install-local wire calls. Seen twice.

Note: the purge endpoint itself fails separately (objectstack-ai/objectstack#21728). This card is only about the console reaching it.

Mechanism

  • InstalledListWidget.tsx:155 links Details to /system/marketplace/:packageId.
  • MarketplacePackagePage.tsx:568 returns the MarketplaceDisabled card when !marketplaceEnabled, before the local reseed/purge menu (:752).
  • Offline (features.marketplace=false, offlineInstallLocal on), the two affordances therefore cannot be reached from the UI.
  • The code is identical at 31971ff1e.

Done when

The local-package page (or Installed Apps) offers reseed / purge on a marketplace-disabled boot that permits install-local.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 5, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: the road — publish and install | platform-core.marketplace-console-honesty | P4

    Triage: first grade — bug · priority:p3 · domain:ui · area:devpath · pm:queue. The local-package page reaches reseed and purge on a boot that permits install-local

    Triage: lands in packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx's disabled guard ⇒ domain:ui; rationale: the fix is a console page; the server's install-local doors already answer.

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-05T01:59Z. ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 5, 2026
  3. objectstack-fleet commented on Oct 5, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2
    Session: session_015W8GBu6sBiqus2L2xjMsAL
    Account: os-steve
    Branch: claude/issue-11627-offline-local-package-menu
    Worktree: objectui-issue-11627
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx (the disabled guard, about :568, and the local reseed / purge menu, about :752), the tests beside it, and .changeset/11627-*.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; floor sonnet · default opus · ceiling fable)
    Clause-②: no
    Thread-read: 5986822955
    Serial constraints cleared: none, read 2026-10-05T06:11Z. The open objectui PRs (#11641 plugin-detail + RecordDetailView.tsx and #11644 packages/components, both in the merge queue; #11069 packages/cli; #11600 the release PR) touch no console/marketplace file. The in-flight objectui#11626 (packages/layout, UnifiedSidebar.tsx) and objectui#11642 (ObjectView.tsx) declare other files. The purge endpoint's own failure, objectstack-ai/objectstack#21728, does not block this card (triage 5986822955).

    Why Clause-②: no: a console page's guard lets the local-package menu render on a boot that permits install-local. Nothing in a published accept set or public surface widens. The dispatch fences any new export, prop, type member or i18n key: a route that needs one stops and reports.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 5, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 11627,
    "status": "done",
    "branch": "claude/issue-11627-offline-local-package-menu",
    "pr": "#11648",
    "session": "session_015W8GBu6sBiqus2L2xjMsAL — subagent run; the id is the dispatching seat's (harness-stamped Claude-Session line of this transcript)",
    "premise_still_valid": true,
    "summary": "MarketplacePackagePage no longer answers a marketplace-off runtime with the MarketplaceDisabled notice alone: when features.installLocal is on (the existing getRuntimeConfig() read, served by RuntimeConfigPlugin from the install-local mount; no new loader) and the viewer is an admin, the page draws the local install's header and the same local menu (re-seed / purge / uninstall, one shared element) ABOVE the unchanged notice. The install is matched on the ledger entry's packageId (the field Installed Apps builds the Details link from, one field, no alias) and the menu acts on its manifest id; the catalog fetch, cloud-installation probe, install-to-cloud CTA, readme and version list stay refused, and non-admins, runtimes without install-local, and non-local packages see the notice alone. listLocalInstalls lost its features.marketplace gate (its answer now has a consumer) and keeps the installLocal and admin gates; the objectui#5620 case that pinned the removed branch was replaced, not respelled. Zone 2 measured: (1) Details links /system/marketplace/ENTRY.packageId and the early !marketplaceEnabled return held at origin/main; live offline runtime served marketplace:false, installLocal:true; (2) reused features.installLocal; (3) remote = catalog fetch, cloud probe, primary CTA, readme, versions, install dialog, cloud sample-data menu; local = installed badge + local dropdown; (4) purge pinned as issued; (5) live before/after measured on a private objectstack worktree at main 08adfead. Clause-② fence held: no export, prop, type member or i18n key added.",
    "tests": "All readings at b8dac39 (after the one origin/main merge, 76993f8). Live (offline showcase OS_CLOUD_URL=off --fresh from a private objectstack worktree at 08adfead; os package install examples/app-crm/dist/objectstack.json -r; console vite from this branch; Chromium via Setup, Installed Apps, Details): runtime config marketplace:false installLocal:true; Installed Apps lists com.example.crm v4.0.0, Details opens /apps/setup/system/marketplace/com.example.crm. | BEFORE (base page swapped in under a trap, restored, blob e06fd029 == HEAD, git diff HEAD empty): disabledNotice 1, h1 none, menu trigger 0, no detail-page install-local call. | AFTER: h1 com.example.crm, badge Installed v4.0.0, trigger More install options; items Re-seed sample data / Purge sample data / Uninstall from this runtime; wire POST /api/v1/marketplace/install-local/com.example.crm/reseed-sample-data (server 422 RESEED_NO_ROWS, see findings) and POST .../purge-sample-data (server 200, deleted 28); no catalog or /cloud-connection/installation request; no install-to-cloud button. | Pins: new MarketplacePackagePage.offlineLocalMenu-11627.test.tsx (8 cases, real marketplaceApi + real initRuntimeConfig over one path-routed fetch stub) + re-judged MarketplacePackagePage-5620.test.tsx (6 cases). | Reverse validation (fix committed first; base page swapped in; trap restore proved by hash + empty git diff HEAD; predicted 7 red / 1 green before running): observed Tests 7 failed | 1 passed (8); the green one is MUST NOT CHANGE without install-local. | Locked batch (os-verify-lock VERDICT command-exit 0, held 247s): turbo build --filter=@object-ui/app-shell^... --concurrency=2 exit 0 (Tasks 28 successful, 28 total); pnpm --filter @object-ui/app-shell type-check exit 0 (echoed type-check: tsc --noEmit && tsc -p tsconfig.test.json; --listFilesOnly of the test project lists all three touched files); vitest over the 17 test files naming MarketplacePackagePage: Test Files 17 passed (17), Tests 357 passed (357). | Lint narrowed to the 3 changed TS files, same root config and cwd as the package eslint . : 3 files linted (from --format json), 0 errors, 11 warnings == the base page blob via --stdin (10 no-explicit-any, 1 no-unused-vars); invariance: config extends tseslint.configs.recommended with no parserOptions.project (type-aware linting off) and no eslint-rules/ rule reads the disk, so the diff cannot move any untouched file verdict. | Light gates all exit 0: check:new-line-citations (0 new), check:control-bytes, check:i18n-keys, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals, check:shell-escape-residue, check:metadata-write-doors, check:handler-key-reads, check:unreferenced-sources, check:comment-mask-corpus, scripts/check-changeset-presence.mjs, scripts/check-changeset-no-major.mjs, check-governed-queue-guard --test (NOT GOVERNED). | NOT MEASURED: full pnpm exec vitest run packages/app-shell/ — reason: about 70 min queued on the shared verify lock behind same-size full app-shell runs; narrowed (declared) to the 17 page-naming test files; CI runs the full suite. CI convergence: in_progress at report time.",
    "gates": {
    "turbo build @object-ui/app-shell^... (closure)": "exit 0 @ b8dac39",
    "pnpm --filter @object-ui/app-shell type-check": "exit 0 @ b8dac39",
    "eslint, narrowed to 3 changed files": "exit 0, 0 errors, 11 pre-existing warnings @ b8dac39",
    "vitest, narrowed to 17 page-naming test files": "exit 0, 17/17 files, 357/357 tests @ b8dac39",
    "vitest run packages/app-shell/ (full)": "NOT MEASURED: lock queue about 70 min; declared to CI",
    "check:new-line-citations": "exit 0",
    "check:control-bytes": "exit 0",
    "check:i18n-keys": "exit 0",
    "check:test-path-roots": "exit 0",
    "check:vi-mock-specifiers": "exit 0",
    "check:vi-mock-inherit": "exit 0",
    "check:vi-mock-override-shape": "exit 0",
    "check:changeset-claims": "exit 0",
    "check:pending-changeset-literals": "exit 0",
    "check:shell-escape-residue": "exit 0",
    "check:metadata-write-doors": "exit 0",
    "check:handler-key-reads": "exit 0",
    "check:unreferenced-sources": "exit 0",
    "check:comment-mask-corpus": "exit 0",
    "scripts/check-changeset-presence.mjs": "exit 0",
    "scripts/check-changeset-no-major.mjs": "exit 0",
    "check-governed-queue-guard --test (4 paths)": "exit 0, NOT GOVERNED"
    },
    "line_budget": "n/a — no skills/** or governed ledger touched",
    "files_changed": [
    "packages/app-shell/src/console/marketplace/MarketplacePackagePage.tsx",
    "packages/app-shell/src/console/marketplace/tests/MarketplacePackagePage-5620.test.tsx",
    "packages/app-shell/src/console/marketplace/tests/MarketplacePackagePage.offlineLocalMenu-11627.test.tsx (new)",
    ".changeset/11627-offline-local-package-menu.md (new, @object-ui/app-shell patch)"
    ],
    "deviations": [
    "Declared narrowing: the dispatch gate pnpm exec vitest run packages/app-shell/ ran as the 17 test files that name MarketplacePackagePage (git grep -l over test files) after about 70 min of verify-lock queueing; full suite left to CI.",
    "Declared narrowing: pnpm --filter @object-ui/app-shell lint ran on the 3 changed TS files, with the three proofs in tests.",
    "One early 2-file vitest run (the new pin and the re-judged 5620 suite, --maxWorkers=1) ran outside the lock after about 29 min queued; superseded by the locked 17-file run at b8dac39.",
    "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a different PR footer; followed objectui AGENTS.md (model-free trailer pair) and os-dev.md (session-URL PR footer) instead, which that reminder defers to. The merge commit message was amended before its first push to carry the trailer pair (no force-push).",
    "PR assignee write (label-write --assign os-steve) was accepted: read back assignees os-steve; labels tests and package: app-shell came from the labeler and were not written by this run."
    ],
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "3 relay writes as objectstack-fleet[bot], each one POST /repos/objectstack-ai/objectstack/dispatches executing: (1) pr_create POST /repos/objectstack-ai/objectui/pulls (draft, objectui#11648; read back 8255 bytes identical); (2) label-write assign POST /repos//issues/11648/assignees (read back os-steve); (3) this os-dev-report POST /repos//issues/11627/comments. Plus 3 git pushes of the branch (empty probe, fix commit caed02e, merge b8dac39) and 0 card writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: public door — POST /api/v1/marketplace/install-local/com.example.crm/reseed-sample-data on objectstack main 08adfead (offline showcase --fresh) answered 422 RESEED_NO_ROWS with message Reseed wrote no rows. The package declares no seedable records for this runtime. right after the same call (following a purge) had inserted 28 rows; repeated: purge 200 deleted 28, reseed 200 inserted 28, reseed again 422 · evidence: the reseed handler in packages/cloud-connection/src/marketplace-install-local-plugin.ts emits that sentence whenever inserted+updated is 0 and errors is 0, which is also the shape of a run whose loader skipped every already-present row; console consequence: Re-seed sample data (the label while withSampleData is true) always ends in that false red banner while the data is present · lands in objectstack · dedupe words: RESEED_NO_ROWS, reseed-sample-data, declares no seedable records, install-local reseed 422, reseed again",
    "carrier: owner of objectstack-ai/objectstack#21728 · noted, not filed — that card's premise (the install-local purge endpoint fails) did not reproduce in this run: purge answered 200 with deleted 28 on objectstack main 08adfead (offline showcase --fresh, after os package install of app-crm); not graded by this PR",
    "carrier: 承接者:无 · noted, not filed — scripts/pm/os-verify-lock.sh slot continuity: twice a retake with the same OS_VERIFY_LOCK_SLOT=objectui-11627-dev printed queued: N ahead of you with no resumed slot line, right after the previous call's timeout printed Your place is KEPT as slot; other retakes did resume. Cause not diagnosed (possibly the slot ageing bound); internal tooling, no public door"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 5, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11648 → main 0baf86f, verified by content

    domain:ui execution seat 1 @ objectui · session_015W8GBu6sBiqus2L2xjMsAL (os-steve) · 2026-10-05T08:27Z.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions