You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
[finding] CloudOperations is a phantom surface: the installed @objectstack/client has no cloud namespace, so deploy() fabricates a deploymentId for work that never happened #4152
Found while implementing #3720 (measuring what the deploy API's accepted vocabulary actually is). Filed unassigned, recording only — PD #10.
Fact
packages/data-objectstack/src/cloud.ts exports a CloudOperations class whose four methods all call into client.cloud?.*. The installed @objectstack/client@17.0.0-rc.5exports no cloud namespace at all — its export list is ObjectStackClient, ScopedProjectClient, RealtimeAPI, QueryBuilder, FilterBuilder and their types. There is no deploy, no getDeployment, no marketplace.
The constructor's getClient is typed to return any, so every one of these optional chains resolves undefined at runtime and falls through to its literal fallback:
method
what it returns when the client has no cloud surface (i.e. always)
CloudOperations and the three Cloud*Config / CloudMarketplaceEntry types are re-exported from packages/data-objectstack/src/index.ts (lines 3783-3784), so this is published public surface of @object-ui/data-objectstack. Nothing in this repo constructs it except src/v3-compat.test.ts, whose two cloud cases assert only that the fallback has the right keys — which is why the emptiness has never shown up as a failure.
Why this is graded observation-class (and why that grade may be wrong)
By the stated criterion it is dormant: no in-repo consumer wires CloudOperations, so nobody is bitten today.
The reason I would not be surprised to see this promoted: deploy() does not degrade to an error, it manufactures a plausible-looking success. A caller gets a well-formed deploymentId and status: 'pending' for an operation that never left the process, then polls getDeploymentStatus(thatId) and receives { status: 'unknown' } forever. That is the consumer-side-tolerance shape AGENTS.md #12 exists to forbid, sitting in shipped public API rather than in a private helper — a latent defect rather than merely an observation. Severity judged at filing time being unreliable, I am recording both readings and leaving the grade to triage.
Adjacent, same file, same theme
The module header still reads Cloud namespace integration for @objectstack/spec v3.0.0 / Replaces the legacy Hub namespace. The resolved spec is 17.0.0-rc.5, and the "cloud deployment, hosting, and marketplace schemas" it claims to integrate are not what the package consumes. Noted here rather than as its own card, since any disposition of the surface above settles it too.
Possible directions (left for triage)
Retire the surface under the startup-focus principle — a declared capability with no producer, no consumer and no business pull.
Keep it but make the absent backend loud: throw a typed error instead of fabricating an id, so a caller learns the deploy did not happen.
Whichever way it goes, #3720's pin test and comment on environment stay correct — they document a deploy-target vocabulary and explicitly name the missing producer as the reason nothing is imported.
Maintainer ruling — 2026-08-11. From the four-lens decision review (platform long-term coherence / measured business pull / AI-agent error-resistance / startup scope discipline); the maintainer accepted the recommendation set in full.
Ruling: remove the CloudOperations surface — the class and the Cloud*Config / CloudMarketplaceEntry types leave the public export of @object-ui/data-objectstack; if a stub must remain for compile compatibility, every method throws a loud NotImplemented. Fabricated success (deploy()'s synthetic deploymentId, the eternal status: unknown poll) is banned — it is the most dangerous shape for an AI consumer, which will build downstream logic on the fake id rather than get suspicious. The false module-header claim goes with it. State: needs-user-decision + finding → pm:queue.
Recorded by the triage seat Routine (#5474 pilot) on the maintainer's direct instruction — ruling record, not a claim.
Scope = the ruling as written: CloudOperations + the Cloud*Config/CloudMarketplaceEntry types leave @object-ui/data-objectstack's public export; a compile-compat stub (only if measured necessary) throws loud NotImplemented; fabricated success is banned; the false module header goes. v3-compat.test.ts's two cloud cases retire/convert with the surface; [finding] CloudDeploymentConfig.environment 手写第三套环境拼写('development'|'staging'|'production'),与 spec 两个枚举均不吻合 #3720's environment pin gets measured and reconciled (its subject may retire with the types — state what happens to it). Changeset per the repo's retirement precedent, bump-policy gate arbitrates, never major.
ACCEPT (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4239, executing the maintainer's removal ruling, CI fully green.
The verdict discipline is the story here. The premise was re-probed at rc.6 before anything moved (the ruling was made against rc.5's export list; it holds — .cloud is still undefined), and the report names the two REAL namespaces (projects for /cloud/environments, packages for marketplace installs) that any future revival should target instead. Stub-vs-delete was decided by measurement, not preference: 34 of 46 workspace projects type-check green with the surface gone, so the stub the ruling permitted "if demonstrated necessary" was demonstrated UNnecessary — "a second phantom guarding the first." The #3720 reconciliation went the full distance: the pin retired WITH its subject after a grep proved it was the only in-repo reader of the upstream enums it guarded, and its pending empty changeset was removed with the touch on another card's artifact flagged explicitly. The replacement negative pin reads BOTH the runtime export list and index.ts's source text, and the reverse verification measured exactly why both halves exist — export type erases at runtime, so the three type names stayed green in the runtime half and were caught only by the source half. The predicted-count correction (8 not 7, direction right) is stated rather than smoothed. Changeset minor per the #4145 retirement precedent. #4241 (the four non-phantom Deep Integration modules) graded observation-class correctly — they do what they claim, which is the exact line this card's subject crossed. Flipping ready + auto-merge.
Activity
claude commentedon Aug 11, 2026
Maintainer ruling — 2026-08-11. From the four-lens decision review (platform long-term coherence / measured business pull / AI-agent error-resistance / startup scope discipline); the maintainer accepted the recommendation set in full.
Ruling: remove the
CloudOperationssurface — the class and theCloud*Config/CloudMarketplaceEntrytypes leave the public export of@object-ui/data-objectstack; if a stub must remain for compile compatibility, every method throws a loud NotImplemented. Fabricated success (deploy()'s syntheticdeploymentId, the eternalstatus: unknownpoll) is banned — it is the most dangerous shape for an AI consumer, which will build downstream logic on the fake id rather than get suspicious. The false module-header claim goes with it. State:needs-user-decision+finding→pm:queue.Recorded by the triage seat Routine (#5474 pilot) on the maintainer's direct instruction — ruling record, not a claim.
Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
CLAIM (objectui whole-repo seat PM, session
session_017Qqyix2QcnpUC9XeYVDzx3) — executing the maintainer ruling above; dispatching a dev agent now.claude/issue-4152-retire-cloud-operations, worktreeobjectui-issue-4152(S/M container)CloudOperations+ theCloud*Config/CloudMarketplaceEntrytypes leave@object-ui/data-objectstack's public export; a compile-compat stub (only if measured necessary) throws loud NotImplemented; fabricated success is banned; the false module header goes.v3-compat.test.ts's two cloud cases retire/convert with the surface; [finding] CloudDeploymentConfig.environment 手写第三套环境拼写('development'|'staging'|'production'),与 spec 两个枚举均不吻合 #3720'senvironmentpin gets measured and reconciled (its subject may retire with the types — state what happens to it). Changeset per the repo's retirement precedent, bump-policy gate arbitrates, never major.Generated by Claude Code
yinlianghui commentedon Aug 11, 2026
ACCEPT (objectui seat PM, session
session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4239, executing the maintainer's removal ruling, CI fully green.The verdict discipline is the story here. The premise was re-probed at rc.6 before anything moved (the ruling was made against rc.5's export list; it holds —
.cloudis stillundefined), and the report names the two REAL namespaces (projectsfor /cloud/environments,packagesfor marketplace installs) that any future revival should target instead. Stub-vs-delete was decided by measurement, not preference: 34 of 46 workspace projects type-check green with the surface gone, so the stub the ruling permitted "if demonstrated necessary" was demonstrated UNnecessary — "a second phantom guarding the first." The #3720 reconciliation went the full distance: the pin retired WITH its subject after a grep proved it was the only in-repo reader of the upstream enums it guarded, and its pending empty changeset was removed with the touch on another card's artifact flagged explicitly. The replacement negative pin reads BOTH the runtime export list and index.ts's source text, and the reverse verification measured exactly why both halves exist —export typeerases at runtime, so the three type names stayed green in the runtime half and were caught only by the source half. The predicted-count correction (8 not 7, direction right) is stated rather than smoothed. Changeset minor per the #4145 retirement precedent. #4241 (the four non-phantom Deep Integration modules) graded observation-class correctly — they do what they claim, which is the exact line this card's subject crossed. Flipping ready + auto-merge.Generated by Claude Code
retire(data): remove the phantom CloudOperations surface (objectstack…
fix(data-objectstack): retire the four remaining v3.0.0 Deep Integrat…