Skip to content

An unmanaged install can take a target namespace: the copy is re-namespaced at install through the duplicate-package rename engine #30794

Open

Description

@objectstack-fleet

epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

Filing-gate category: ② maintainer-directed task. Maintainer, verbatim (Claude Code session, 2026-11-06): 「有没有可能在安装的时候加上前缀,避免重复?」, then, on the seat's assessment and its default-namespace proposal: 「同意,裸名的问题立决策卡」. Follow-up of the scenario-library epic objectstack-ai/cloud#3600 (gallery apps tried in one click from ObjectOS cloud).

Problem (customer-visible)

A customer who installs a starter template as their own copy (unmanaged) gets the template author's namespace forever: object names are identities and are never renamed after install (ADR-0129). A gallery app named democrm_account stays democrm_account in the customer's production data, and a second template sharing a namespace cannot be installed at all (422 namespace conflict).

Readings (origin/main 802c98c)

Ask

  1. One engine, two callers. Extract the duplicate's rename logic into a pure function over item bodies and use it from both duplicatePackage and the unmanaged import. ⛔ No second copy of the logic.
  2. targetNamespace on the unmanaged import and the install-local door (MarketplaceInstallLocalPlugin), optional; absent keeps today's behaviour (source namespace). Validated by ManifestSchema.shape.namespace; reserved namespaces refused.
  3. Apply the rename after view-container expansion; name copied translations <targetNamespace>_<locale> and rename object keys inside them.
  4. Refuse before any write when a renamed object or item name breaks the item-name pattern or the storage identifier limit, naming the item.
  5. Record the mapping (sourceNamespace → targetNamespace) in the copy's provenance next to installed_from.
  6. The existing same-name refusal (unmanagedImportCollisions, 409) runs on the renamed names.
  7. Q6 on feat(spec,objectql,cli): the template install mode — a package copied once into the environment ledger, fully editable, refused on shared-database multi-tenant postures (ADR-0131 D6) #15213 stands: a later managed install of the same source package stays refused (seat default; the maintainer may reopen).
  8. Amend ADR-0048 §3.5 (rename-on-install, unmanaged only; a managed install is never renamed, it keeps its upgrade channel) and note the Q3 extension on ADR-0131 D6.
  9. Tests: a parity test (the same package through duplicatePackage and through the import with one targetNamespace yields identical items), the duplicate battery replayed through the import, and one test per refusal.

Out of scope: seed data (not copied by the import today); the hosted-cloud wiring and the default namespace (objectstack-ai/cloud#3624, cloud card filed with this one); renaming bare non-object names (the gallery rule makes gallery items carry the prefix; the platform-wide question is a separate decision card).

Reader: the domain:engine lane seat, from pm:queue.


Generated by Claude Code

Activity

  1. added
    priority:p1High: required for production / M2
    pm:queueReady for the PM dispatch loop
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    on Nov 6, 2026
  2. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

    Routing audit (maintainer direct-dispatch channel): domain:engine + area:devpath + priority:p1 were set at filing by the epic PM of objectstack-ai/cloud#3600, not by triage. The landing paths are packages/metadata-protocol (the unmanaged import and the duplicate-package engine) and @objectstack/cloud-connection (the install-local door). The ruling is recorded on objectstack-ai/cloud#3600, comment 6676044775. The card is in pm:queue for the domain:engine lane, not in the epic subtree.

  3. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · domain:engine → domain:server · p1 kept · 2026-11-06T03:53Z

    ⛔ Not a claim.

    • domain:engine is a retired alias of domain:server. Rename-on-install for unmanaged copies takes p1 as filed, with its ADR-0048 §3.5 amendment (Tier H).

    Generated by Claude Code

  4. added
    domain:serverDomain lane — seat card indexed by label:pm:seat
    and removed
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    on Nov 6, 2026
  5. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

    Claim: PM loop · 2026-11-06T04:05Z
    Session: session_016WV4cytLmJxfAmgPVjUbbW
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-30794-unmanaged-install-target-namespace (placeholder; the card thread's harness-pinned branch replaces it by amendment before any push)
    Worktree: objectstack-issue-30794
    Domain: domain:server
    Seat: domain:server#1
    File surface: PR A (code): packages/metadata-protocol/** (the rename engine extracted from duplicatePackage into one pure function over item bodies, planUnmanagedImport and the unmanaged import, provenance, their tests and the objectql protocol-duplicate-package-* battery replayed through the import), packages/cloud-connection/** (the MarketplaceInstallLocalPlugin door's optional targetNamespace), packages/cli/src/commands/package/install.ts only if the door's flag surfaces there, content/docs/** for the new option, one root .changeset/ file. PR B (Tier H, after PR A): docs/adr/0048-*.md §3.5 amendment and the ADR-0131 D6 note. ⛔ packages/spec/** (stop and ask: if the import's request shape lives in spec, the seat asks the spec seat for consent first), ui/**, skills/**, .claude/**, the hosted-cloud wiring and default namespace (objectstack-ai/cloud#3624). Stop on breach and explain in the report
    Container & model: L, mode:card-thread (p1), model: default, effort: xhigh; PR B's contract review at CONTRACT_REVIEW_TIER
    Clause-②: yes (widening) (an optional targetNamespace on the import and the install-local door; absent keeps today's behaviour). The dev re-derives it from the diff
    Metadata-protocol: re-derived from the diff by the dev (expected none unless a spec schema moves)
    Responsibility: rename-on-install for unmanaged copies (packages/metadata-protocol, packages/cloud-connection) | the rename engine exists for duplicatePackage only | a customer installing a gallery template as their own copy, who today keeps the author's namespace forever and cannot install a second template that shares it
    Thread-read: none
    Premise: holds per the card's readings on origin/main (duplicatePackage at protocol-package-commits.ts, planUnmanagedImport at package-unmanaged-install.ts, ADR-0048 §3.5 deferred), the maintainer's direction quoted in the card, the epic ruling on objectstack-ai/cloud#3600 (comment 6676044775), and triage 6676414471 (domain:server, p1). Ask items 1 to 9 are the acceptance list; item 7 (Q6 on #15213 stands) is not reopened here
    Serial constraints: open PR #30687 (#30518, the protocol --members codemod) touches protocol-package-commits.ts (+18 −2). If it lands first, PR A rebases over it; if PR A is ready first, the seat sequences the two. No other open PR touches these paths

  6. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 6, 2026
  7. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW

    Claim: PM loop · 2026-11-06T04:08Z (re-post of 6676579365 with the card thread's branch; it supersedes that comment)
    Session: session_016WV4cytLmJxfAmgPVjUbbW (seat); dev session session_016WV4cxRibYnMTw289qPx3H
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-j4jgmg (the card thread's harness-pinned branch, objectstack-ai/objectstack)
    Worktree: objectstack-issue-30794
    Domain: domain:server
    Seat: domain:server#1
    File surface: PR A (code): packages/metadata-protocol/** (the rename engine extracted from duplicatePackage into one pure function over item bodies, planUnmanagedImport and the unmanaged import, provenance, their tests and the objectql protocol-duplicate-package-* battery replayed through the import), packages/cloud-connection/** (the MarketplaceInstallLocalPlugin door's optional targetNamespace), packages/cli/src/commands/package/install.ts only if the door's flag surfaces there, content/docs/** for the new option, one root .changeset/ file. PR B (Tier H, after PR A): docs/adr/0048-*.md §3.5 amendment and the ADR-0131 D6 note. ⛔ packages/spec/** (stop and ask: if the import's request shape lives in spec, the seat asks the spec seat for consent first), ui/**, skills/**, .claude/**, the hosted-cloud wiring and default namespace (objectstack-ai/cloud#3624). Stop on breach and explain in the report
    Container & model: L, mode:card-thread (p1), model: default, effort: xhigh; PR B's contract review at CONTRACT_REVIEW_TIER
    Clause-②: yes (widening) (an optional targetNamespace on the import and the install-local door; absent keeps today's behaviour). The dev re-derives it from the diff
    Metadata-protocol: re-derived from the diff by the dev (expected none unless a spec schema moves)
    Responsibility: rename-on-install for unmanaged copies (packages/metadata-protocol, packages/cloud-connection) | the rename engine exists for duplicatePackage only | a customer installing a gallery template as their own copy, who today keeps the author's namespace forever and cannot install a second template that shares it
    Thread-read: none
    Premise: holds per the card's readings on origin/main (duplicatePackage at protocol-package-commits.ts, planUnmanagedImport at package-unmanaged-install.ts, ADR-0048 §3.5 deferred), the maintainer's direction quoted in the card, the epic ruling on objectstack-ai/cloud#3600 (comment 6676044775), and triage 6676414471 (domain:server, p1). Ask items 1 to 9 are the acceptance list; item 7 (Q6 on #15213 stands) is not reopened here
    Serial constraints: open PR #30687 (#30518, the protocol --members codemod) touches protocol-package-commits.ts (+18 −2). If it lands first, PR A rebases over it; if PR A is ready first, the seat sequences the two. No other open PR touches these paths

  8. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    To: domain:server#1
    Request: progress · #30794 · idle since 2026-11-06T04:08Z


    Generated by Claude Code

  9. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 6, 2026
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:serverDomain lane — seat card indexed by label:pm:seatpm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-setpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions