Skip to content

cloud-connection: install-local's cloud branch accepts a package whose flow, webhook or other bare name another package holds #31296

Closed

Description

@objectstack-fleet

domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

Filing gate: ② routed from the contract review of PR #31093 (record 6714650391, should-fix 1: outside that PR's claimed surface). Read from code, not run. ⛔ Not a claim.
Reader: the seat that owns packages/cloud-connection/src/marketplace-install-local-plugin.ts (the cloud branch of POST /marketplace/install-local, refusesEnvironmentHeldCatalogName).
Dedupe (open AND closed): install-local BareNameConflictError, refusesEnvironmentHeldCatalogName bare-name, install-local cloud branch hotLoaded false conflict → none.
reach: every install-local of a control-plane package (cloud branch, inlineManifest false) that declares a name another installed package already holds for a bare-name type (#30803 series: dataset, mapping, the request family, flow, webhook, connector, email template); read from code.
class: a · type: Bug
Grade: p2 — self-graded by the server seat (Ruling-ref: the maintainer, 「定级你可以自己决定」): the same grade as the #30803 series whose refusal this door loses.

维护者速读

本地安装的云端分支在注册失败时,只把「环境已持有的目录名」当拒绝。#30803 系列的「同名只能一个包持有」冲突(BareNameConflictError,持有者是另一个包或内置)被当作可以晚点再加载:写入安装记录、回答成功(hotLoaded: false),下次启动在封印之前恢复这个包,冷启动只告警一次就接受了冲突。应当和内联分支一样直接拒绝(422),什么都不写。

What is wrong (read from code)

Expected

  • The cloud branch refuses a bare-name clash the way the inline branch does: 422, both holders and the rename named, nothing written to the ledger. One predicate on that branch (recognise the registry's bare-name refusal), never a copy of the holder rule.
  • Pins: cloud-branch install of a package declaring a held flow name → 422, ledger unchanged, nothing hot-loaded; CONTROL: an environment-held catalog name keeps its current answer; CONTROL: a fresh name installs.

Related: #30803, PR #30836, PR #31006, PR #31093, #22695.

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 7, 2026
  2. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p2 · domain:server · confirmed · 2026-11-08T00:01Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5o8PE7ZtVjcor51wBZ

    Claim: PM loop round 1 · 2026-11-08T04:06Z
    Session: session_01FEkQ5ktJb5rQ5n2GUXSQMR (card thread, dev) · seat session_01FEkQ5o8PE7ZtVjcor51wBZ
    Account: os-project-manager
    Branch: claude/project-thread-f6p2x0
    Worktree: objectstack-issue-31296
    Domain: domain:server
    Seat: domain:server#5
    File surface: packages/cloud-connection/src/marketplace-install-local-plugin.ts (the cloud branch's refusal predicate) + its test(s), root .changeset/
    Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: thread default
    Clause-②: no (narrowing) — a cloud-branch install that answered success (hotLoaded: false) is now refused 422; one contract-review-tier review owed before the queue
    Metadata-protocol: none
    Responsibility: cloud-connection install-local cloud branch (objectstack) | refusesEnvironmentHeldCatalogName recognises only an environment holder, so a bare-name refusal takes #22695's lenient path | every cloud-branch install-local of a package declaring a name another package or a built-in holds
    Thread-read: 6714782060
    Premise: holds (read, not run): on origin/main the cloud branch's catch still asks only existingHolder.kind === 'environment'; the dev re-measures red first
    Serial constraints cleared: cleared — install-local PRs #31243, #31280, #31286 merged; #31283 (same file) runs second in this thread

    Scope: Fixes #31296. One predicate recognising the registry's bare-name refusal, no type list, nothing written on refusal. Then #31283 in the same thread after this PR merges. Order: /mnt/project-files/pm-orders/server/order-31296.md. Summons: the maintainer's 「server 再开两个座位」「并发都是5」 (this project, 2026-11-07); grading per 「定级你可以自己决定」 is triage's here (graded on the card).

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

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-project-manager · session_01FEkQ5ktJb5rQ5n2GUXSQMR
    os-dev-report
    {
    "issue": 31296,
    "status": "done",
    "branch": "claude/project-thread-f6p2x0",
    "pr": "#31388",
    "session": "session_01FEkQ5ktJb5rQ5n2GUXSQMR",
    "premise_still_valid": true,
    "summary": "Premise measured red on main d0512c2: a cloud-branch install-local of a package declaring a flow name another package holds answered 200 with hotLoaded false and ledgered it. The cloud branch now asks one new predicate, refusesBareNameHeldElsewhere, beside #25366's, and answers 422 PLUGIN_REGISTER_FAILED with the registry's sentence before any write. The predicate reads the error's own brand (NAMESPACE_CONFLICT_CODE plus name BareNameConflictError, the code+name pair isGuestOrganizationUnresolvedError and the DuplicateRecordError readers use for an unexported class) and enumerates no types or holders, so PR #31375 (#30803 PR 4: agent and skill) is covered with no change here. Card assignee untouched; pr_create carried no assignees.",
    "tests": "New packages/cloud-connection/src/marketplace-install-local-bare-name-conflict.test.ts (real ObjectKernel + ObjectQLPlugin, holders sealed): fresh install 422 + upgrade 422 (both holders, flow, rename routing_assign_technician named; registry and ledger as before; holder's flow kept), CONTROL environment-held permission set still 422, CONTROL fresh flow name 200 hotLoaded true. RED on base d0512c2: 'Tests 2 failed | 2 passed (4)', 'expected 200 to be 422' with hotLoaded false. GREEN on head with the catalog-collision and hot-loaded suites: 'Test Files 3 passed (3) Tests 26 passed (26)'. ABLATION via scripts/ablation-replace.mjs (anchor 'if (refusesEnvironmentHeldCatalogName(err) || refusesBareNameHeldElsewhere(err)) {' -> without the bare-name arm): 'ok mutation landed: anchor 1 -> 0, blob 09ac8e820728 -> 2268f74afe54', 'Tests 2 failed | 2 passed (4)', 'ok restored: blob == HEAD (09ac8e820728) and git diff HEAD is empty'; the suite imports the plugin from src relatively, so no build or dist preflight applies. Package: pnpm --filter @objectstack/cloud-connection test 'Test Files 74 passed (74) Tests 973 passed (973)' VERDICT 0; typecheck (src + tsconfig.test.json, new file listed) exit 0; all on head 7b59e00.",
    "gates": "Head 7b59e00. dispatch-gates --commands --repo objectstack-ai/objectstack: 69 families, all exit 0 (record /mnt/project-files/pm-orders/server/31296-gates-ran.txt). First-run prerequisite exits rerun: check-plugin-teardown-shape --self-test 3 -> 0 (git fetch --depth=1 origin 621a487), check:dts-closure 1 -> 0 and check:dual-build-cjs-loads 3 -> 0 after pnpm turbo run build --concurrency=2 (VERDICT 0), check:type-check-debt 3 (lock queued behind dogfood) -> 0. --ran: '69 derived famil(ies) accounted for — 69 run, 0 NOT-MEASURED (a DERIVED zero — all 69 recorded an exit code and none of them is 3)'. eslint --no-inline-config on the two touched .ts files exit 0. CI families: PR #31388 check-runs in_progress at report time, read by the seat.",
    "dogfood_battery": "7b59e006 · os-verify-lock: VERDICT command-exit 0 (held 35m08s) · Test Files 437 passed | 3 skipped (440) · Tests 3618 passed | 41 skipped (3659) · no failures",
    "mcp_calls": "0",
    "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, fleet-write run 42450892873, read-back identical, PR #31388) and this report comment via post-stamped.mjs; git push is not a REST write",
    "open_questions": [],
    "security_findings": "none",
    "out_of_scope_findings": [
    "class: a · reach: POST /api/v1/marketplace/install-local cloud branch, measured with this PR's harness on a throwaway probe (not committed): a package shipping a permission set another installed package ships answers 200, hotLoaded false, not registered, ledgered; read from code: the package door's security catalog check (refuseSecurityCatalogNameConflicts) has no seal, so the rehydrate at the next boot is refused the same way and the package never loads, the false 'loads at next restart' #25366 closed for an environment holder only · evidence: refusesEnvironmentHeldCatalogName keeps existingHolder.kind === 'environment' · dedupe words: install-local security catalog package holder lenient, refusesEnvironmentHeldCatalogName package built-in, SecurityCatalogNameConflictError hotLoaded false"
    ],
    "deviations": "none on file surface (one source file, one new test file, one changeset). Merged origin/main once (8b90442) before the PR; main moved 11 commits after, not re-merged. PR #31375 (agent/skill) had not landed at report time, so no AI-family pin (seat note: not owed)."
    }


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions