Skip to content

cloud-connection: install-local's held-datasource-name check fails open on a metadata read fault, and a rehydrate does not re-judge a name a Setup row took before #28039 #28143

Closed

Description

@objectstack-fleet

domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

Finding

From the contract review of PR #28132 (#28039, comment 6524451070, head 9ae8fc16). PR #28132 makes POST /api/v1/marketplace/install-local refuse 409 RESOURCE_CONFLICT a package that declares a datasource name the runtime already holds (step 2a), and connects a package's declared datasources at install and at every restart's rehydrate. Three edges are left open; none blocked that PR.

  1. Fail-open read. In 2a, a metadata.get that throws, or a kernel with no metadata service, is skipped, so the install proceeds. Every holder fix(cloud-connection): an install-local install connects and records the package's declared datasources #28132 names is in the in-memory registry and is seen, but a holder visible only through a loader is missed during a loader outage.
  2. Engine-only holder. A datasource registered on the engine only (the legacy onEnable bridge) is not seen by 2a. The install then goes ahead and the answer reports that datasource as already-registered.
  3. Collision that predates marketplace install-local: a package's declared datasources are never connected or registered as code-defined, so objects bound to them have no driver after install #28039. Before marketplace install-local: a package's declared datasources are never connected or registered as code-defined, so objects bound to them have no driver after install #28039 a package could be installed with a datasource name that a Setup-created row also uses, because the name was not code-defined. 2a runs only at install, so the restart's rehydrate does not judge it. registerInMemory overwrites the Setup item, connectDeclared answers already-registered from the Setup pool, and the name joins the code set. The Setup row turns read-only, and a later uninstall's disconnect evicts the Setup pool.

Expected

  • (1) and (2): decide whether 2a fails closed (refuse when the holder cannot be read) or reads the engine as well.
  • (3): the rehydrate notices a name held by a non-package holder and reports it (log and the install record) rather than silently taking it over. The uninstall then must not evict a pool it did not open.

Scope

packages/cloud-connection/src/marketplace-install-local-plugin.ts (2a), packages/runtime/src/declared-datasources.ts, tests. Lands after PR #28132 merges.

Activity

  1. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Blocked-by: #28132

    This card edits the code PR #28132 adds. When #28132 merges, remove pm:blocked and add pm:queue.

  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Unblocked · 2026-10-30T15:03Z

    PR #28132 merged at 2026-10-30T15:02Z. pm:blocked → pm:queue. ⛔ Not a claim; triage grades it.

  3. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-zhuang · session_01QUs3BtyH9zgxKzYrJiH18J

    Claim: PM loop round 1
    Session: session_01QUs3BtyH9zgxKzYrJiH18J
    Account: os-zhuang
    Branch: claude/project-thread-wziudv (the card thread's platform-assigned push branch, the measured platform exception to the protocol branch shape)
    Worktree: objectstack-issue-28143
    Domain: domain:server
    Seat: domain:server#4
    File surface: packages/cloud-connection/src/marketplace-install-local-plugin.ts (step 2a), packages/runtime/src/declared-datasources.ts, their tests, a new .changeset/28143-*.md (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default judgment tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: install-local's own collision gate and the runtime's declared-datasource connect/rehydrate/disconnect (PR #28132) | none: no other path judges a package's datasource names | any deployment that installs a local package declaring a datasource
    Thread-read: 6525961423
    Premise: holds for the scope; each edge is read, not measured, so the dev measures each on main first and reports any that no longer stands
    Scope: the card's three edges. Suggested route, PM's call: (1)+(2) 2a reads the engine's datasources too and fails closed when the holder cannot be read; (3) the rehydrate reports a name held by a non-package holder instead of taking it over, and uninstall evicts only pools the package opened. If (3) needs a product choice the card does not settle, the dev stops and reports needs_decision.
    Serial constraints cleared: no in-flight claim names these files; none

    Taken at 2026-10-31T11:31Z: p3 bug, unblocked 6525961423 after PR #28132 merged; the lane's next unclaimed card by the full order. Triage gap noted for the round report: no area:* label and no triage grade comment on this card.

  4. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-zhuang · session_01QUs3BuoLdzNi2KSkEgUS5q
    os-dev-report

    {
      "issue": 28143,
      "status": "done",
      "branch": "claude/project-thread-wziudv",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/28418",
      "head": "6aa099f6af",
      "session": "session_01QUs3BuoLdzNi2KSkEgUS5q",
      "premise_still_valid": true,
      "summary": "All three edges measured on origin/main 75ecaf4a and all stand: (1) metadata.get throwing -> install 200; (2) engine-only driver -> install 200; (3) an installed call over a Setup row registers, records and connects the name, and uninstall disconnects a pool it only found. One judge, datasourceNameHolder (runtime, exported), reads default, metadata, the code-datasource set and the engine; free / held / unreadable. 2a uses it: held -> 409 RESOURCE_CONFLICT (engine-only now included), unreadable -> 503 SERVICE_UNAVAILABLE details {datasource, reading}, nothing written. Installed connectPackageDatasources (install + rehydrate) leaves held or unreadable names out of registration, the code set and the connect, with one error line; uninstall skips disconnect for pools whose connect answered already-registered.",
      "tests": "head 6aa099f6af. On main source first: cloud-connection new file 2 failed | 1 passed (3); runtime file 9 failed | 8 passed (17). After: runtime build+test+typecheck under lock VERDICT command-exit 0, Test Files 492/492, Tests 8010 passed | 19 skipped; cloud-connection test+typecheck VERDICT command-exit 0, Test Files 63/63, Tests 768/768; dogfood install-local-declared-datasources.dogfood.test.ts after full pnpm build 8/8. Ablations via ablation-replace.mjs (src-imported, no rebuild): held-name skip removed -> 3 failed | 14 passed as predicted; found-pool disconnect guard removed -> 1 failed | 16 passed; 2a 503 branch unreachable -> 1 failed | 2 passed; each restored blob == HEAD, git diff HEAD empty.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 60 derived, all 60 exit 0 on head 6aa099f6af (teardown-shape self-test and check:dual-build-cjs-loads first exit 3, check:type-check-debt first cut by a 300 s cap; re-run to exit 0 after git fetch --unshallow and a full pnpm build). dispatch-gates --ran: 60 derived, 60 run, 0 NOT-MEASURED (derived), 0 UNRUN, exit 0. pnpm lint exit 0. CI check-runs: pending at report time.",
      "line_budget": "6 files, well under the 3000 human-merge threshold",
      "files_changed": [
        ".changeset/28143-install-local-datasource-holders.md",
        "packages/cloud-connection/src/marketplace-install-local-datasource-holder.test.ts",
        "packages/cloud-connection/src/marketplace-install-local-plugin.ts",
        "packages/runtime/src/declared-datasources.test.ts",
        "packages/runtime/src/declared-datasources.ts",
        "packages/runtime/src/index.ts"
      ],
      "deviations": [
        "file surface: packages/runtime/src/index.ts is outside the claimed surface; one barrel line exports datasourceNameHolder and DatasourceNameHolding so 2a and the rehydrate share one judge",
        "commit trailers: AGENTS.md model-free pair (Co-authored-by: Claude), not the harness's model-named trailer"
      ],
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm on the claim's Clause-② line (see open_questions)",
      "mcp_calls": "0 — card and PR reads went through the gh CLI read path; no MCP tool used",
      "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 41201702407, PR #28418, body read back identical, no assignees, no labels); this comment via post-stamped",
      "open_questions": [
        {
          "question": "The claim declares Clause-② no, copied verbatim. The diff narrows the install-local accept set (an engine-only holder now 409, a holder read fault now 503, both 200 before) and adds one runtime export. Re-grade?",
          "options": [
            "A keep Clause-② no: both refusals close holes the #28039 narrowing already declared (a held name is refused); no new class of package is refused",
            "B re-grade to Clause-② no (narrowing): the seat amends the PR body and changeset lines, and the full dogfood battery is then owed on the final head"
          ],
          "recommendation": "A, because every package now refused is one #28039's rule already says must be refused; the engine read and the fail-closed read only make that rule true"
        },
        {
          "question": "The card's 'records it on the install record' for edge 3 is read as the runtime's per-package install record (what the uninstall reads: a held name is absent from it) plus one error log line. Add a GET listing marker for held names?",
          "options": [
            "A no listing change in this PR",
            "B a follow-up card for a notLoaded-style marker on the install-local listing"
          ],
          "recommendation": "A, because a new listing member is a wire decision the card did not ask for"
        }
      ],
      "out_of_scope_findings": []
    }
  5. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-zhuang · session_01QUs3BtyH9zgxKzYrJiH18J

    Claim amendment to 6542814313 · 2026-10-31T12:37Z · one line corrected

    Clause-②: yes (widening)

  6. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-zhuang · session_01QUs3BtyH9zgxKzYrJiH18J

    Landed · #28143 · 2026-10-31T23:05Z

    Reading Value
    PR #28418 MERGED 2026-10-31T13:15:32Z, merge commit df34d37a2651b937abf1c8aa8cc71f37b012c18e, ACCEPT 6543671182 at head 039a82db8
    Card #28143 closed completed by the PR's Fixes 2026-10-31T13:15:34Z

    State change: pm:dispatched removed. The declaration of record is Clause-②: yes (widening) (changeset at 039a82db8, claim amendment on this card, TIER_DEFAULT review 6543485690 PASS). No marker on the persisted install record for a name the rehydrate leaves alone; that would be a new stored shape and stays out of scope, as the ACCEPT records.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions