Skip to content

Packages page: offer Enable / Disable on a suite's type:module rows once the server allows disabling them #28118

Closed

Description

@objectstack-fleet

coordinator#1 · os-sales · session_01L6bhgV5XwfXsVDMWfbUvBv

Filing gate: ③ ordered by the maintainer. Ruling thread, quoted verbatim (not translated):

2026-10-30 13:05Z: 同意 (plan A of the suite-module analysis: customer admins switch modules; per environment; disabled = hidden + data-plane refusal + data kept — see #28117)
2026-10-30 13:07Z, asked whether the Console needs a NEW "suite modules" page: 最小做法:

"最小做法" = no new page, no new route, no new nav item. The existing Packages page gets the switch.

Business reason: once #28117 lets an admin disable a suite's module, the customer's admin needs a place to do it without calling the API. The Packages page already has the Disable / Enable button and a confirm dialog; today it shows Disable only on writable rows, so a module row (read-only for authoring) would never offer it.
Reader who acts: the ui lane, one small PR in ui/packages/app-shell/src/views/metadata-admin/PackagesPage.tsx (+ its tests).
Dedupe (open AND closed): semantic search "Packages page disable button module package read-only": 0 relevant hits (#7560 is the server gate). 0 open duplicates.

Blocked-by: #28117

Back-link: #28117 · ⛔ Not a claim.

Today (origin/main b6c2ed9c)

  • PackagesPage.tsx L1054: the Disable / Enable button renders when writable || !enabled; Disable opens the confirm dialog (pkg-detail-disable-dialog, L1272), then PATCH /api/v1/packages/:id/disable|enable (L876).
  • The confirm copy engine.packages.detail.disableDescription already says the consequence: en "The package is taken out of service for every user until it is enabled again. No records are deleted, and you can enable it again at any time." / zh 「在重新启用之前,此软件包将对所有用户停止服务。不会删除任何记录,您可以随时重新启用。」 (ui/packages/i18n/src/namespaces/studio/{en,zh}.ts).
  • Setup's "Installed Apps" entry (packages/cloud-connection/src/marketplace-ui.ts L47-80) opens this same developer:packages component filtered ?source=marketplace.
  • Whether a suite's type: module packages appear as their own rows in that view: not measured — measure first.

Expected

  1. A row the server marks as disableable (the served verdict packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117 adds next to writable) shows Enable / Disable, through the existing button and confirm dialog. ⛔ The Console does not re-derive the rule from manifest.type / scope ([Decision] OS_METADATA_WRITABLE unlocks a write on a read-only package while Studio renders a "Read-only" badge — which one is telling the truth? #8146: one answer, served by the server).
  2. The confirm dialog keeps one sentence of consequence: hidden for every user + no data deleted + can be re-enabled. The current copy already says this; reword only if a module row reads wrong with it, both locales.
  3. Every other write action on a module row stays hidden (it is still read-only for authoring).
  4. Permission: the existing manage_metadata door; no new permission.
  5. Tests: a module row with the verdict shows Disable and confirms; a read-only row without it does not; a disabled module row shows Enable.

Not in scope (ruled)

  • A new "suite modules" page, route or nav item (13:07Z 「最小做法」).
  • Organization-level scope (13:07Z 「不需要」); plans B / C.
  • If the module rows do not appear in the Installed Apps view at all, report it on this card first; ⛔ do not add a new page to work around it.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    coordinator#1 · os-sales · session_01L6bhgV5XwfXsVDMWfbUvBv

    Ordering addendum. This card may land after #28117. But the switch must not become customer-visible until the HotCRM-lane card that makes the app package tolerate a disabled module has landed. Today, disabling …hotcrm.service would make saving a task or event fail in the app's own hooks (see the addendum on #28117). That HotCRM card is filed once the maintainer agrees; its number is added here as a Blocked-by: line when it exists. Until then: build and test behind the server verdict, and do not ship it to customers.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo

    Serial note for this card · 2026-10-31T04:23Z · ⛔ not a claim

    Item 1 reads "the served verdict #28117 adds next to writable". #28117's PR #28308 does not add it: card item 4 routed the new key to the spec lane as a Seam. It is filed as #28318. So this card waits on both:

    Blocked-by: #28117
    Blocked-by: #28318

    When PR #28308 lands, the server accepts a module disable. The Packages page still cannot offer it until #28318 serves the verdict, because writable stays false for a module. The ordering addendum 6523692915 (HotCRM tolerance before the switch becomes customer-visible) is unchanged.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#1 · os-tesla · session_01L9qibwb6hBqszPTYJobitm

    Doc rider for this card. ⛔ Not a claim.

    PR #28371 (#28318) serves disableable beside writable on GET /packages and GET /packages/:id. Its PR body's Skills-docs: line names this card as the follow-up for one doc edit. When the Console reads the key, the same PR updates the "Disabling a module" section of content/docs/deployment/marketplace-handbook.mdx to name the key, so the handbook says what the Packages page now offers. No skills/** page names the package verdicts, so no skill edit is owed.

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Unblocked · 2026-11-02T02:10Z · pm:blocked → pm:queue


    Generated by Claude Code

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim: PM loop round 11 · 2026-11-02T03:04Z
    Session: session_01QsR2jSW86XpeUhXzbQFo4Z (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
    Account: zhuangjianguo
    Branch: claude/project-thread-hip8m4 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-28118
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/app-shell/src/views/metadata-admin/PackagesPage.tsx (the Disable / Enable gate), ui/packages/i18n/src/namespaces/studio/{en,zh}.ts only if the confirm copy reads wrong on a module row, their tests, and a root .changeset; server and packages/spec read only (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6567401553
    Premise: holds (at origin/main 7fa9873f: PackagesPage.tsx:1054 gates the button on writable || !enabled; disableable is declared at packages/spec/src/api/package-api-assembled.zod.ts:160 and served by GET /packages since #28318 / PR #28371)
    Serial constraints cleared: none known.


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim amended · 2026-11-02T03:08Z · after the dev's pre-code measurement. This amendment widens the file surface and records a landing hold. It adds to claim 6568047039. The branch, session, size and declaration lines are unchanged.

    • Measured (7fa9873f): module rows appear in Installed Apps for a marketplace-installed suite, because install-local restates each packages[] entry with source: 'marketplace'. A code-booted suite's modules appear on the unfiltered Packages page. Both get the button, since it is gated on disableable.
    • File surface (added or clarified):
      1. Two studio keys (en/zh) for a module row's read-only reason when disableable && !writable. Today the sheet says such a row "cannot be edited, disabled or deleted" right above its Disable button. Studio namespace is a Record<string, string>, so Clause-②: no holds.
      2. content/docs/deployment/marketplace-handbook.mdx: step 7 and "Disabling a module" name the Packages-page button and the disableable key (doc rider 6540426908).
    • Landing hold: ordering addendum 6523692915 says the switch must not become customer-visible until the HotCRM-lane card lands. That card makes the app package tolerate a disabled module (scope addendum 6523684730 on packages: an admin cannot disable a type:module sub-package of an installed app (422 WRITABLE_PACKAGE_REQUIRED), and a disabled package's nav contributions stay in the app #28117: hooks, lookups, actions and a tile that read module objects). No such card exists yet. The PR is built and tested behind the server verdict and stays draft. The card gets that card's Blocked-by: line once it is filed.

    Generated by Claude Code

  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    席位注记 · landing hold target · 2026-11-02T03:15Z

    Blocked-by: objectstack-ai/hotcrm#2383

    The landing hold recorded in amendment 6568088585 (ordering addendum 6523692915) now names its card. The HotCRM tolerance card already exists as objectstack-ai/hotcrm#2383, filed for the UI-side-reads scope that ruling A on #28117 (6545646924) left. No new card was filed.

    State on hotcrm main d4ffe99: the revenue dashboard tile is fixed (hotcrm PR #2390). What is left is Add to Campaign and Generate Quote, still drawn with their module off. Those wait on platform card #28877. So this card's PR stays draft until #28877 lands in the HotCRM pin and hotcrm#2383 closes. Coding on this card's branch goes on meanwhile.

  8. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jSW86XpeUhXzbQFo4Z
    os-dev-report

    {
      "issue": 28118,
      "status": "done",
      "branch": "claude/project-thread-hip8m4",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28903",
      "session": "session_01QsR2jSW86XpeUhXzbQFo4Z",
      "premise_still_valid": true,
      "summary": "PackageDetailSheet now gates Disable on the row's served `disableable` (the disable door's verdict, GET /packages since PR 28371) instead of `writable`; Enable stays offered on any disabled package, and every other write (Edit, Publish, Revert, Duplicate, Adopt, Delete) stays on `writable`, so a suite module row offers only Disable / Enable beside the reads. A disableable read-only row's note now says it cannot be edited or deleted but can be disabled (two studio keys, en/zh, per amendment 6568088585), and the marketplace handbook's step 7 and 'Disabling a module' name the button and the key (doc rider 6540426908). Measured before coding: install-local registers every package of the artifact with source 'marketplace', so a marketplace suite's modules are their own rows in Installed Apps; a code-booted suite's modules (source 'code') are on the unfiltered Packages page. PR is draft; landing waits on objectstack-ai/hotcrm#2383. No PR assignees (os-dev rule; the relay reports none).",
      "tests": "New PackagesPage.moduleDisable-28118.test.tsx: 10/10 (module row shows Disable + confirm + one PATCH disable; other writes hidden; disableable note scope-less and project; disableable false and absent offer no Disable; disabled module shows Enable; non-module row served disableable offers Disable; Installed Apps view lists the module row, app row control). Fixtures in 13157 / 27521 / 13339 / 11784 carry disableable as served. Ablation at 2d45950f via ablation-replace.mjs (gate back to `writable || !enabled`, anchor 1->0, blob 93d7556c->7ebf253c): 3 failed / 7 passed, (1), (5) and the Installed Apps case; restored blob == HEAD, git diff HEAD empty. On merge head 4775dfce: 25 Packages-page/i18n files + packages/i18n/ = 119 files, 1730 passed, 13 skipped; turbo type-check app-shell + i18n (tsc + tsconfig.test.json) 66 tasks exit 0; ui `vitest run scripts/` (at 2d45950f) 169 passed, 2 skipped, 4900 tests. ESLint on 8 changed files: 0 errors, 15 pre-existing warnings, none on changed lines.",
      "gates": "dispatch-gates --commands at 2d45950f: 66 derived, 66 run, all exit 0; --ran reconciles 66/66, 0 NOT-MEASURED. check:skill-examples first exit 3 (client-react dts not built), exit 0 after `pnpm --filter @objectstack/client-react build`. check:i18n-keys / i18n-drift / i18n-dead-keys, check-sdui-manifest, check:new-line-citations: exit 0 (re-run on 4775dfce except line citations). PR-body gates on the exact body: check-changeset-no-major exit 0, check-partof-closing-keyword exit 0, check-adr-0087-registration exit 0, check-closing-keyword-parity exit 0. CI on 4775dfce: in_progress at report time (18 in progress, 1 queued, 2 completed). Merge of main adds no file to the diff; derived sweep not re-run on the merge head.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "1 — subscribe_pr_activity (claude-code-remote, platform PR subscription); 0 GitHub MCP calls",
      "api_writes": "3 — git push (branch); fleet-write relay pr_create (run 41385202870, PR 28903, body read back byte-identical, 8819 bytes); post-stamped os-dev-report comment on 28118",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — `disableable` is optional on InstalledPackageRow and the list does not refuse a row without it (unlike source / writable); a missing key fails closed. Refusing it would touch every page-level fixture. In Acceptance notes."
      ]
    }
  9. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Landed · 2026-11-03T06:36Z · PR #28903 merged through the merge queue as 0afb1b2b at 2026-11-03T06:35Z (GitHub's clock). ACCEPT 6596823186 at head 263a3dd2. The seat's hold on objectstack-ai/hotcrm#2383 was released by os-zhuang's ruling 6596506876 on the PR: 「平台的开发先行,hotcrm随后」.

    probe before (0afb1b2b~1) now (origin/main)
    disableable in ui/packages/app-shell/src/views/metadata-admin/PackagesPage.tsx 0 10
    readOnlyDisableable in ui/packages/i18n/src/namespaces/studio/en.ts 0 1

    Fixes #28118 closed this card, and pm:dispatched comes off in the same stroke as this note. The follow-up is objectstack-ai/hotcrm#2383, still open. Until it ships, HotCRM's UI-side reads of a module an admin disabled meet 404 OBJECT_PACKAGE_DISABLED instead of hiding.

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, iteratedomain:uienhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions