Skip to content

[Epic] Package-level override: every customization of an installed package lives in its paired <base>.custom package, one declared override shared by code and Studio (supersedes #28130) #28236

Closed
46 of 46 issues completed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ④ coordination parent, opened on the maintainer's direct instruction (③) in a desktop session on 2026-10-30, verbatim: 「方向定为包级覆盖:代码和 Studio 用同一机制,定制都进 .custom。」 · 「现在用fable规划新的epic 任务清单。原来的你可以考虑直接关闭」 · 「等我拍板的 8 个问题,全部同意」. Supersedes #28130.

Epic (coordination parent) · no pm:epic on this parent or any child — the children are fleet work: each carries pm:queue (or its own state) and its domain:* lane, and the domain seats claim them under the normal protocol. Maintainer, 2026-10-31, verbatim: 「这些卡都可以放回车队开发吧」 · 「注意不能写epic车队才会认领」. Coordinating session: 040dfd80-c4c9-411b-895c-698e785a6848 (desktop, hotlong) · ⛔ not a claim on any child.

Territory (declared): docs/adr/0146-*.md (rewritten in place) and the status lines of ADR-0005/0009/0048/0126/0131/0141 · packages/spec (override declaration, .custom pairing constants, field-patch whitelist) · packages/metadata-protocol/src/{protocol-environment-rows.ts,protocol-packaged-base-refusal.ts,protocol-authoring-gate.ts,protocol.ts} (read/write doors) · packages/runtime/src/domains/{packages.ts,automation.ts}, packages/runtime/src/flow-clone.ts · packages/services/service-automation/src/{flow-precedence.ts,run-resume.ts,engine.ts} · packages/objectql/src/registry.ts (extension merge) · ui/packages/app-shell/src/views/{studio-design,metadata-admin,setup}/**.

维护者速读

  • 改了什么: 已安装软件包(如 HotCRM)的一切定制——改原有的、加新的、扩展对象——都进配对的可写包 <base>.custom;「改原有的」= 在 .custom 的同名项正文里显式声明覆盖,整份替换。写代码和 Studio 用同一机制,定制随包导出、进 git、跨环境部署。
  • 为什么改: 10-30 浏览器走查:Studio 改不了只读包;Setup 写的是不随包走的「无包覆盖行」;克隆即双跑;依赖包的同名视图会静默盖掉基础包(Studio 看 6 列、用户看 2 列)。ADR-0146 还没开工,直接改写。
  • 风险与回滚: 需推翻 ADR-0126 D1/D4 墙 1、ADR-0131 D6、ADR-0005 五型、ADR-0048 §3.3、ADR-0009 未兑现的版本固定、ADR-0141 D3 的卸载保护推迟——都在 ADR-0146 改写里逐条写明。每张子卡独立 PR,可单独回退。
  • 先看: N-01(ADR-0146 改写);P0 六张现在可并行,全部进车队(pm:queue,各车道认领;整棵子树不挂 pm:epic)。
  • 两分钟验证: HotCRM 视图「定制」→ 三处读取同一列集、导出带声明、「恢复包原版」回原样;流程定制只跑新定义、挂起运行按旧版完成;对象加字段落 .custom、名为 xxx__c;卸载 HotCRM 被拒并点名 hotcrm.custom。
  • 需要你做的: 审 N-01 的 ADR PR 并亲手合并。

Rulings this epic carries (maintainer, 2026-10-30, verbatim)

P0 — start now (cut with this epic)

# Card Lane Size Depends on
N-01 Rewrite ADR-0146 in place for package-level override (+ status-line pointers on ADR-0005/0009/0048/0126/0131/0141; folds PR #28145) domain:skills M —
N-03 Defect: a same-named item in a dependent package replaces the base's item for package-less reads and in the base app domain:server M —
N-04 Studio: ledger switch "off for this deployment" on a read-only package's flow — #28148 re-scoped domain:ui S–M —
N-05 Studio: one item toolbar (layers, references, history with rollback, audit, source) on every pillar item domain:ui L —
N-07 Studio: object pickers offer only objects inside the package's dependency closure; the dependencies editor is reachable domain:ui S —
N-27 Setup: position holders and permission-set assignment as people-and-organization pages domain:ui M —

Cut after N-01 merges (plan of record, not cards yet)

Each is filed into its domain lane's pm:queue when cut, with Blocked-by: where the order below says so.

Old cards

#28130 closed as superseded by this epic · #28147 closed, replaced by N-17 (WIP claude/project-thread-3c7skj@cd0ae0d156 kept as reference) · #28148 re-scoped as N-04 and re-parented here — its claim (os-tesla, pm:dispatched) stands and the pause is lifted · #28149 re-scoped as N-21 and re-parented here, pm:blocked (its door needs N-13, which is cut after N-01) · PR #28145 folds into N-01.

Not in this epic

Per-organization overrides (ADR-0131 D6 environment scope stands) · upgrade diff / basedOn checking (recorded only) · clone lineage (ADR-0126 §9 second bullet) · overriding permission sets, positions, capabilities · code-only types (hook, job, field, …) · structural changes to base fields · the action ledger switch (#27842, #27504).

Dedupe

Searched open and closed issues: "package-level override" (4 hits, none on this topic; #28149 is a child here), customize installed package override (12; #28149, #27356, #11665 related), "item toolbar" Studio (6, none), "outside the closure" picker (15; #24669 closed is the lint-side refusal, related). None covers this plan.

Links back: #28130, ADR-0146 (cdbf08d1), #27356, ADR-0005/0009/0048/0070/0126/0131/0141.


Generated by Claude Code

Activity

  1. added
    enhancementNew feature or request
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 30, 2026
  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

    Checklist, 2026-10-30T18:41Z. Every child is lane work; nothing in this subtree carries pm:epic (maintainer, verbatim: 「这些卡都可以放回车队开发吧」 · 「注意不能写epic车队才会认领」).

    P0 — in the fleet now

    Waiting

    Old cards: #28130 closed not planned (superseded) · #28147 closed not planned, replaced by N-17 (WIP claude/project-thread-3c7skj@cd0ae0d156 kept as reference) · PR #28145 left open, folds into #28237.

    Next cut: P1 (N-06, N-08…N-16) after #28237 merges, each filed into its lane's pm:queue.

  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · epic routing read · 2026-10-30T18:58Z

    ⛔ Not a claim.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-10-31T09:36Z

    N-09 card riders — recorded before the card is cut. ADR-0146 rewrite merged in #28295 (head 04aa72e7, 2026-10-31T08:28Z). The maintainer directed in the desktop PM session, verbatim: 「落卡:缺口一和三写进 N-09 的卡面(合并后切卡时),缺口二开决策卡;三处文字残留随 N-09 顺手修。」 When N-09 (write gate) is cut, its body carries all of the following; the seat that cuts it copies this list, ⛔ does not re-derive it.

    1. Gap 1 — gate points. D2 states the undeclared-same-name and second-declarer refusals only "when its package publishes"; D10 gives __c three points (publish, os validate, the install door). A partner package installed from the marketplace, or a <base>.custom deployed from git, never publishes, so it bypasses the rule. N-09 enforces the same three points as __c: publish, os validate, and installPackage. Tests cover an install that carries an undeclared same-name item and an install that would be a second declarer.
    2. Gap 3 — base upgrade adds a name a dependent already uses. No door judges a base upgrade (ADR-0141 D3 deferred). If a base version adds a name that a dependent or .custom item already holds, under D8 item 2 that item stops being served by base address and is not the dependent's own item either — it silently disappears from the UI, and its next publish is refused. Only fields are protected (__c). N-09 at minimum: (a) the upgrade/install door names every such collision in its result instead of passing silently; (b) the cost is added to ADR-0146's cost list in the same PR. Surfacing the orphan in the layered read is N-10's half — N-10's card links here.
    3. Wording residues, fixed in the N-09 PR (carried from the docs(adr): rewrite ADR-0146 as the package-level override record — paired <base>.custom, one declared override shared by code and Studio; dated pointers on six Status lines #28295 contract-review ACCEPT):
    4. Gap 2 is not N-09's to decide. "Any closure package may declare" × "one declarer per base item" lets a partner override block the customer's .custom customization (and vice versa), with no chain or precedence. It goes to a separate decision card (being prepared); N-09 carries Blocked-by: that card until it is Ruled:, because the second-declarer check is shaped by the answer.

    Also from the ruling record (6540351677, rider 5): N-09's dispatch first counts existing closure same-name rows across examples and test deployments; zero ⇒ proceed, non-zero ⇒ report the list before migrating.

  5. 39 remaining items

  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-01T07:15Z

    P2/P3 cut · schedule reviewed · audit

    On the maintainer's instructions in the epic PM's direct session, verbatim: 「四项提速措施全部按推荐执行:现在切 P2/P3 全部卡并用 Fable 审核、N-09 由你直接派 os-dev、设置卡住巡查。」 · 「用fable 先审核一下这个计划」

    Schedule review (Fable) found two release-unsafe windows: after N-13 #28407 and before #28511 (both have since merged, so this window is closed), and after a close of the package-less write and before Studio's replacement. ⇒ #28413 split. #28413 is rewritten to N-16a, the os migrate ceremony only (title and body replaced; hold note 6553667890). The close half is N-16b #28576, which waits on #28413, N-17 and N-25, and carries a major changeset.

    20 new children (all priority:p1, lane-labelled, drafted by three agents, reviewed card by card by Fable, filed as sub-issues of this epic; none carries pm:epic):

    card # lane state at filing
    M-1 decision #28559 — needs-user-decision → ruled A (6554738464), closed
    N-23a #28560 spec pm:queue
    N-26a #28561 ui pm:queue
    N-17 #28562 ui pm:blocked
    N-20a #28563 server pm:blocked → pm:queue (6554636923)
    N-23b #28564 server pm:blocked
    N-23d #28565 server pm:blocked
    N-24 #28566 ui pm:blocked
    N-22 #28567 ui pm:blocked
    N-26b #28568 ui pm:blocked
    N-25 #28569 ui pm:blocked
    N-18 #28570 ui pm:blocked
    N-19 #28572 ui pm:blocked
    N-20b #28573 ui pm:blocked
    N-23e #28574 server pm:blocked (the object-extension write path into .custom, a gap the review found)
    N-23c #28575 ui pm:blocked
    N-16b #28576 server pm:blocked
    N-30 #28577 skills pm:blocked
    N-28 #28578 ui pm:blocked (item 2 settled by M-1 A)
    N-29 #28579 devx pm:blocked

    Not done by the PM: N-09 #28410 was not dispatched by this seat. domain:server#2 (os-project-manager) had already claimed it at 2026-11-01T04:17Z, and a second dispatch would double-write the card.

    Riders: #28410, comment 6553666595: the marketplace install door (marketplace-install-local-plugin.ts#handleInstall, which registers through manifestService.register and never calls installPackage) gets the same install-time judgement. #28149, comment 6554259755: Setup's "Open the clone in Studio" link is fixed in N-21's own PR.

    Stall patrol: a seat-local check every 2 hours flags a pm:dispatched child that has gone 4 hours with no push, no PR movement and no seat comment, and runs the unblock scan. First run: nothing stalled; #28149 and #28563 were unblocked when #28407 closed.

  7. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Triage: the epic seat cannot be rung · 2026-11-01T13:45Z

    ⛔ Not a claim. A knock to the epic seat epic:#28130#1 (hotlong), which dispatches this epic's N-cards.


    Generated by Claude Code

  8. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: tracking added · 2026-11-02T01:54Z

    ⛔ Not a claim.

    • This epic's own body puts its children in pm:queue, for each lane to claim, and keeps the whole subtree off pm:epic. That left the epic card itself with no state (check-half-states H13). It stays open as the umbrella until its children land, which is the tracking shape. The children's labels are unchanged. check-half-states also flagged it as a P0 suspect; that is a false reading: "P0" in this body names the epic's first phase, not a severity.

    Generated by Claude Code

  9. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-02T23:52Z

    Acceptance re-run on main at 322cf9068f: #29648, 6 PASS / 1 FAIL over the seven ADR-0146 items, after #29563–#29569 landed.

    Two product defects filed as children, priority:p1, pm:queue, domain:server: #29649 (a published dashboard or report override removes the item from the base's export; ADR-0146 D8 item 3) and #29650 (New similar on a flow with a live override answers 403). #29600 raised to p1.

    Provenance: the maintainer, direct chat, 2026-11-03: 「发记录并立卡」, 「相关卡 p1, 让车道处理」. Standing instruction for this epic, same chat: 「等 #29564 落地、验收 FAIL 项核对后,关闭 epic #28236 并停掉卡住巡查。」 That condition is not met, so the epic and the stall patrol stay open.

  10. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-03T00:55Z

    Studio full run on main at 3482f3d8d2: #29672, 33 PASS / 3 PARTIAL / 7 FAIL / 1 BLOCKED over 44 items, on the maintainer's 「然后 studio 相关的功能再完整的测试一下」 and 「发记录并立卡」.

    New child of this epic, priority:p1, pm:queue: #29674 (a New similar copy of a permission set reads as empty in its pair). #29673 (zh-CN object publish) is also p1 and queued for the lane, but is not an ADR-0146 card, so it is not a child. The epic's closing condition is still unmet: #29649, #29650 and #29674 are open.

  11. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-03T02:52Z

    Closing condition, measured on main at c9636f1e50: the one acceptance FAIL of #29648 is fixed live (#29649 acceptance[4]), and the off-clause refusal #29650 is fixed live. Remaining open child: #29674. The maintainer's rule stands: 「等 #29564 落地、验收 FAIL 项核对后,关闭 epic #28236 并停掉卡住巡查。」 #29674 was attached after that rule, so whether it holds the close is the maintainer's to say; the epic stays open until they answer.

  12. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-03T03:08Z

    Ruled: the maintainer, direct chat with the epic PM seat, 2026-11-03: 「等 #29674」, answering whether the close waits for #29674.

    The close is held until #29674 lands and the epic PM seat has measured it live. Then this epic closes and the stall patrol stops, on the standing word 「等 #29564 落地、验收 FAIL 项核对后,关闭 epic #28236 并停掉卡住巡查。」. #29673 is outside this epic and does not hold the close.

  13. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-03T04:58Z

    Closing on the maintainer's words in direct chat with the epic PM seat, 2026-11-03: 「等 #29564 落地、验收 FAIL 项核对后,关闭 epic #28236 并停掉卡住巡查。」 and 「等 #29674」. All 46 children are closed.

    #29674, measured live on main at 601832b1a6 (contains 10e4a774), fresh database, showcase app, zh-CN console:

    • POST /api/v1/security/permission-sets/showcase_contributor/clone: 200. The server read of the copy holds 8 objects and 3 fields.
    • /_console/studio/com.example.showcase/access?surface=permission%3Ashowcase_contributor_verify reads 已授权 8 个对象 · 3 个字段覆盖, and the eight rows' C, R, U, D, E, Tr, VA and MA boxes match the server's read, row by row.
    • Granting read on a base object from the page (showcase_announcement) writes a draft: draft read 9 objects, published read still 8, header 已授权 9 个对象. After publish and reload, the published read and the header both say 9, and the box stays on. The base set showcase_contributor is unchanged: 8 objects, none on showcase_announcement.

    The one acceptance FAIL of #29648 (#29649) and the off-clause refusal #29650 were measured fixed live on c9636f1e50, recorded above on this thread.

    Outside this close, by the maintainer's ruling or by scope: #29673 (zh-CN object publish, not an ADR-0146 card, pm:dispatched) and #29679 (checklist re-point, pm:queue) stay open in their lanes. Not re-measured here: the #29673 defect. The stall patrol stops with this close.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:uienhancementNew feature or requestpriority:p1High: required for production / M2tracking

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions