Skip to content

cloud-binding: name the service in its spec contract, and give controlPlaneUrl one reading of an empty option (follow-up to #29920) #30762

Closed

Description

@objectstack-fleet

domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

Filing gate: ① two should-fix findings of the contract review on PR #30749 (#29920), comment 6673473934, items 1 and 2, kept out of that PR by the seat. ⛔ Not a claim. Suggested grade: p3.
Dedupe: CLOUD_BINDING_SERVICE, controlPlaneUrl empty — no open card. New.
Reader: domain:server (packages/cloud-connection, packages/services/service-push), with one export in packages/spec/src/contracts/cloud-binding-service.ts (the spec half is the triage's call to route).

1 · The service name has no single source

Since PR #30749, cloud-connection registers the cloud-binding service and service-push reads it, each spelling 'cloud-binding' on its own; nothing pins the two to each other. Six sibling contracts export their service name beside the interface (EMBEDDER_SERVICE, KNOWLEDGE_SERVICE, OWNERSHIP_QUEUE_SERVICE, RLS_MEMBERSHIP_RESOLVER_SERVICE, SEED_SETTLEMENT_SERVICE, FILE_ATTACHMENT_SERVICE).

Expected: export const CLOUD_BINDING_SERVICE = 'cloud-binding' from cloud-binding-service.ts, both packages read it, api-surface/ and export-origins/ regenerated. An added export: Clause-②: yes (widening) on the spec face.

2 · Two readers of one empty option inside cloud-connection

The contract's docblock says controlPlaneUrl() answers '' only when the deployment declared no control plane. createCloudBinding reads the option through resolveCloudUrl(option), which turns an explicit '' into the production default, while the plugin's own routes (cloud-connection-plugin.ts, ~L337) read the same '' as "cloud not configured". Unreachable under objectstack serve today (the plugin is composed only when resolveCloudUrl() is non-empty), so a hand-composed kernel is the only reach.

Expected: one reading. Either the routes derive their URL from binding.controlPlaneUrl(), with the binding reading '' the way the routes do, or the docblock says what '' answers; a pin for the empty option.

Related: #29920 (PR #30749), #30670.

Activity

  1. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p3 kept · domain:server · re-queued · 2026-11-06T12:47Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim: PM loop round 6 · 2026-11-06T13:14Z
    Session: session_016WV4cyvF7SP65frVFAYLv7
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: the card thread's designated claude/project-thread-* branch; this claim is re-posted whole with it once the thread reports it
    Worktree: objectstack-issue-30762
    Domain: domain:server
    Seat: domain:server#5 (this seat filed the card from PR #30749's review; asked of triage in 6685103313 and answered in 6685166387)
    File surface: packages/cloud-connection/src/{cloud-binding.ts,cloud-connection-plugin.ts,cloud-url.ts} and their tests; packages/services/service-push/src/transports/relay.ts and its tests; cross-seat line: packages/spec/src/contracts/cloud-binding-service.ts (one added export, CLOUD_BINDING_SERVICE) with packages/spec/api-surface/** and export-origins/** regenerated (triage kept the card whole on domain:server); one .changeset/*.md. ⛔ cloud-connection-ui.ts (open PR #30935)
    Container & model: M, mode:thread, model: default, effort: high
    Clause-②: yes (widening: one added spec export)
    Metadata-protocol: none
    Responsibility: the cloud-binding service name is spelled separately by its registrar and its reader with nothing pinning them, and cloud-connection reads an explicit empty controlPlaneUrl two ways (production default in createCloudBinding, "not configured" in the plugin's routes) | none | service-push's relay transport and anyone hand-composing a kernel with cloud-connection
    Thread-read: 6685166387
    Premise: holds on main 33043bd8: CLOUD_BINDING_SERVICE = 'cloud-binding' is declared twice, in cloud-connection/src/cloud-binding.ts L23 and service-push/src/transports/relay.ts L26, and not in the spec contract; cloud-connection-plugin.ts L337 reads controlPlaneUrl ?? OS_CLOUD_URL ?? '' while resolveCloudUrl (cloud-url.ts L35) maps it to the default
    Serial constraints cleared: open draft PR #30935 edits cloud-connection-ui.ts only, outside this surface. The dev re-checks open PRs on packages/cloud-connection/** and service-push/** before the first push. A contract review is owed (Clause-②: yes)

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

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim: PM loop round 6 · 2026-11-06T13:20Z (re-posted whole with the branch, superseding the claim above)
    Session: session_016WV4cyvF7SP65frVFAYLv7
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-ms359b (the card thread's designated branch, dev session session_016WV4cwsvPqjJfJthsRiYpt), branched from main 33043bd
    Worktree: objectstack-issue-30762
    Domain: domain:server
    Seat: domain:server#5 (this seat filed the card from PR #30749's review; asked of triage in 6685103313 and answered in 6685166387)
    File surface: packages/cloud-connection/src/{cloud-binding.ts,cloud-connection-plugin.ts,cloud-url.ts} and their tests; packages/services/service-push/src/transports/relay.ts and its tests; cross-seat line: packages/spec/src/contracts/cloud-binding-service.ts (one added export, CLOUD_BINDING_SERVICE) with packages/spec/api-surface/** and export-origins/** regenerated (triage kept the card whole on domain:server); one .changeset/*.md. ⛔ cloud-connection-ui.ts (open PR #30935)
    Container & model: M, mode:thread, model: default, effort: high
    Clause-②: yes (widening: one added spec export)
    Metadata-protocol: none
    Responsibility: the cloud-binding service name is spelled separately by its registrar and its reader with nothing pinning them, and cloud-connection reads an explicit empty controlPlaneUrl two ways (production default in createCloudBinding, "not configured" in the plugin's routes) | none | service-push's relay transport and anyone hand-composing a kernel with cloud-connection
    Thread-read: 6685166387
    Premise: holds on main 33043bd8: CLOUD_BINDING_SERVICE = 'cloud-binding' is declared twice, in cloud-connection/src/cloud-binding.ts L23 and service-push/src/transports/relay.ts L26, and not in the spec contract; cloud-connection-plugin.ts L337 reads controlPlaneUrl ?? OS_CLOUD_URL ?? '' while resolveCloudUrl (cloud-url.ts L35) maps it to the default
    Serial constraints cleared: open draft PR #30935 edits cloud-connection-ui.ts only, outside this surface. The dev re-checks open PRs on packages/cloud-connection/** and service-push/** before the first push. A contract review is owed (Clause-②: yes)

  5. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim: PM loop round 6 · 2026-11-06T13:23Z (re-posted whole: the branch, and the surface widened by one gate-forced line, superseding the claims above)
    Session: session_016WV4cyvF7SP65frVFAYLv7
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-ms359b (the card thread's designated branch, dev session session_016WV4cwsvPqjJfJthsRiYpt), branched from main 33043bd
    Worktree: objectstack-issue-30762
    Domain: domain:server
    Seat: domain:server#5 (this seat filed the card from PR #30749's review; asked of triage in 6685103313 and answered in 6685166387)
    File surface: packages/cloud-connection/src/{cloud-binding.ts,cloud-connection-plugin.ts,cloud-url.ts} and their tests; packages/services/service-push/src/transports/relay.ts and its tests (push-plugin.test.ts reads the contract constant); packages/services/service-push/vitest.config.ts (one anchored source alias for @objectstack/spec/contracts, forced by check:test-source-alias once relay.ts value-imports it); cross-seat line: packages/spec/src/contracts/cloud-binding-service.ts (one added export, CLOUD_BINDING_SERVICE) with packages/spec/api-surface/** and export-origins/** regenerated (triage kept the card whole on domain:server); one .changeset/*.md. ⛔ cloud-connection-ui.ts (open PR #30935)
    Container & model: M, mode:thread, model: default, effort: high
    Clause-②: yes (widening: one added spec export)
    Metadata-protocol: none
    Responsibility: the cloud-binding service name is spelled separately by its registrar and its reader with nothing pinning them, and cloud-connection reads an explicit empty controlPlaneUrl two ways (production default in createCloudBinding, "not configured" in the plugin's routes) | none | service-push's relay transport and anyone hand-composing a kernel with cloud-connection
    Thread-read: 6685166387
    Premise: holds on main 33043bd8: CLOUD_BINDING_SERVICE = 'cloud-binding' is declared twice, in cloud-connection/src/cloud-binding.ts L23 and service-push/src/transports/relay.ts L26, and not in the spec contract; cloud-connection-plugin.ts L337 reads controlPlaneUrl ?? OS_CLOUD_URL ?? '' while resolveCloudUrl (cloud-url.ts L35) maps it to the default
    Serial constraints cleared: open draft PR #30935 edits cloud-connection-ui.ts only, outside this surface. The dev re-checks open PRs on packages/cloud-connection/** and service-push/** before the first push. A contract review is owed (Clause-②: yes)

  6. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cwsvPqjJfJthsRiYpt
    os-dev-report

    {
     "issue": 30762,
     "status": "done",
     "branch": "claude/project-thread-ms359b",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/30956",
     "session": "session_016WV4cwsvPqjJfJthsRiYpt",
     "premise_still_valid": true,
     "summary": "Item 1: packages/spec/src/contracts/cloud-binding-service.ts exports CLOUD_BINDING_SERVICE = 'cloud-binding' beside ICloudBindingService; api-surface/contracts.json and export-origins/contracts.json regenerated, one row each. cloud-connection drops its local constant (never a public export of the package) and imports the contract's; service-push's relay.ts imports it and keeps CLOUD_BINDING_SERVICE as a re-export, because it was a public export of @objectstack/service-push (same name, same value). Item 2, route A: createCloudBinding's controlPlaneUrl() answers '' for an explicit empty or blank option (else resolveCloudUrl), and CloudConnectionPlugin's routes take cloudUrl from this.binding.controlPlaneUrl(). objectstack serve and the showcase are unchanged: they compose the plugin only with resolveCloudUrl()'s non-empty answer, which both readings return byte-for-byte. On a hand-composed kernel two more inputs align with the binding: absent option + declined OS_CLOUD_URL (routes used 'off' as a base URL, now CLOUD_UNCONFIGURED) and absent option + unset OS_CLOUD_URL (routes were CLOUD_UNCONFIGURED, now the default, as the binding and the marketplace plugins already read it). Surface widened by the seat's re-posted claim: service-push/vitest.config.ts (one anchored alias for @objectstack/spec/contracts, forced by check:test-source-alias) and push-plugin.test.ts (registers the binding under the contract constant). Declarations re-derived: Clause-② yes (widening), Metadata-protocol none, three packages patch.",
     "tests": "At 9fdd39ad (fix commit, carried unchanged to head d1e31826): pnpm --filter @objectstack/cloud-connection test → Test Files 72 passed (72), Tests 925 passed (925); typecheck exit 0. pnpm --filter @objectstack/service-push test → Test Files 5 passed (5), Tests 74 passed (74); typecheck exit 0. New pins: cloud-connection-plugin.test.ts describe 'the routes and the binding read the control-plane URL once' (6 cases via GET /installed + the registered binding), cloud-binding.test.ts (empty and blank option answer '' over OS_CLOUD_URL; CLOUD_BINDING_SERVICE is 'cloud-binding'), push-plugin.test.ts (binding registered under the contract constant). Ablations via scripts/ablation-replace.mjs, each mutation landed (anchor 1→0, blob moved) and restored (blob == HEAD, git diff HEAD empty): A1 routes read main's way → 1 of 17 red; A2 binding = resolveCloudUrl(option) → 4 of 26 red; B1 relay.ts declares its own 'cloud_binding' → 2 of 19 red; B2 plugin registers under 'cloud_binding' → 6 of 26 red. All ablated modules are imported from src/ (relative path or the service-push source alias), no dist between mutation and run.",
     "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at d1e31826: 88 families (11 paths vs merge base 3479c33d). 88 + pnpm lint + pnpm check:cli-command-ids + pnpm check:adr-symbol-anchors = 91 of 91 exit 0 on the final tree. First pass 84 exit 0; six packages/spec dist readers (check:api-surface, check:browser-reachable-entries, check:dual-source-exports, check:entry-nameability, check:exported-any exit 3; check:generated exit 1) read a spec dist built before the origin/main merge (declaration stamp mismatch) and exit 0 after pnpm --filter @objectstack/spec build; check:dual-build-cjs-loads exit 3 (no whole-tree dist) → exit 0 after turbo run build --concurrency=2 (82/82 tasks). --ran reconciliation: 88 derived, 88 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. check:test-source-alias exit 1 without the alias, 0 with it. CI check-runs on PR #30956: not yet concluded at report time (in_progress). Exit codes: /mnt/project-files/server-lane-seat5/30762/gates-ran-d1e31826.txt.",
     "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
     "mcp_calls": "4 — read only: issue_read get, issue_read get_comments, pull_request_read get_diff (PR #30749), pull_request_read get_comments (PR #30749)",
     "api_writes": "2 — relay pr_create (PR #30956, run 42232413889, 11949 bytes identical) and this os-dev-report comment via post-stamped.mjs; git push is not a REST write. Reads through gh api: search/issues x3, pulls/N/files x4 (serial check).",
     "open_questions": [],
     "security_findings": "none",
     "out_of_scope_findings": ["carrier: none · noted, not filed — MarketplaceProxyPlugin and MarketplaceInstallLocalPlugin still read an explicit '' controlPlaneUrl through resolveCloudUrl as the production default; never composed with '' by serve; outside this card's surface (PR #30956 Acceptance notes)"]
    }
  7. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Landed · 2026-11-06T15:44Z · PR #30956

    Probe Reading
    PR #30956 merged, merge commit 000a4c0d, through the merge queue (contract review PASS 6687101841 on d1e31826, delta PASS 6687302075 and seat ACCEPT 6687326985 on head 937d74e1; +158/-19; every check green or expected-skip before landing; the queue ejection reported in 6688649376 was as a bystander of the #30978 stack and the rebuilt group went green)
    #30762 closed by Fixes #30762

    Shipped: CLOUD_BINDING_SERVICE is exported from @objectstack/spec/contracts; cloud-connection registers the binding under it and service-push reads it (its own export stays as a re-export). The cloud-connection routes now take their URL from binding.controlPlaneUrl(), and the contract's docblock names an explicitly empty or blank configured value as a third way to ''. Declared and accepted in review: a hand-composed CloudConnectionPlugin({}) with no option and no env now uses the production default, as the sibling marketplace plugins already did.

    Carried, no card filed: MarketplaceProxyPlugin and MarketplaceInstallLocalPlugin read an explicit '' as the default, and RuntimeConfigPlugin reads it as "stay on this origin", so the package still has differing readings of an explicit empty controlPlaneUrl. Neither serve nor the showcase composes with ''; worth a card if a host ever does.

    State change: pm:dispatched removed, assignee cleared.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions