Surfaced by the capstone URL-conformance guard (#3642). Not a bug — a documented hole, filed so it doesn't read as "audited and fine."
What the sweep found
The guard drives every ObjectStackClient method and matches the URL it builds against the union of all four in-repo ledgers. 196 of ~219 methods matched. Every single unmatched one was in projects.* — 23 methods, all targeting /api/v1/cloud/*:
projects.list → GET /api/v1/cloud/environments
projects.create → POST /api/v1/cloud/environments
projects.get → GET /api/v1/cloud/environments/:id
projects.packages.* → …/environments/:id/packages…
…23 in total
Why they legitimately match nothing here
/api/v1/cloud/* is the control plane, served by the sibling cloud repo. This repo not only doesn't mount those routes, it actively refuses them — packages/runtime/src/http-dispatcher.ts:
// Guard against matching control-plane routes like /cloud/environments.if(path.includes('/cloud/environments/'))returnundefined;So no ledger in this repository can honestly carry a row for them, and the guard exempts the /api/v1/cloud/ prefix.
Why it still deserves tracking
This is the same posture the whole #3563 audit exists to eliminate — 23 SDK methods that are expressed, presumably working, and guarded by nothing. The audit just cannot reach them from this side of the repo boundary. projects.updateVisibility could be renamed on the cloud side tomorrow and nothing here would notice.
The exemption is bounded from both ends in the guard so it can't quietly widen: only projects.* may use the prefix (a non-projects method reaching /cloud/ fails the suite), and the sweep asserts the namespace is still reaching it at all.
Options
- A ledger in the
cloud repo, mirroring the tranche-1/2/3 shape, with its client half importing @objectstack/client and asserting the same URL conformance from that side. Correct, and the only option that actually closes it. - A published route manifest from
cloud that this repo can pin against — weaker (a manifest can drift from the routes it describes) but cheap, and it would at least catch a rename. - Leave it exempt and accept that the control-plane SDK surface is unguarded.
Recommendation: option 1, scoped as its own tranche in the cloud repo, since that is where the routes are declared and the tranche-1 lesson (each package verifies its own half) applies across the repo boundary the same way.
Refs: #3642 (the guard), #3563 / #3587 / #3636 (the three in-repo tranches).
Surfaced by the capstone URL-conformance guard (#3642). Not a bug — a documented hole, filed so it doesn't read as "audited and fine."
What the sweep found
The guard drives every
ObjectStackClientmethod and matches the URL it builds against the union of all four in-repo ledgers. 196 of ~219 methods matched. Every single unmatched one was inprojects.*— 23 methods, all targeting/api/v1/cloud/*:Why they legitimately match nothing here
/api/v1/cloud/*is the control plane, served by the siblingcloudrepo. This repo not only doesn't mount those routes, it actively refuses them —packages/runtime/src/http-dispatcher.ts:So no ledger in this repository can honestly carry a row for them, and the guard exempts the
/api/v1/cloud/prefix.Why it still deserves tracking
This is the same posture the whole #3563 audit exists to eliminate — 23 SDK methods that are expressed, presumably working, and guarded by nothing. The audit just cannot reach them from this side of the repo boundary.
projects.updateVisibilitycould be renamed on the cloud side tomorrow and nothing here would notice.The exemption is bounded from both ends in the guard so it can't quietly widen: only
projects.*may use the prefix (a non-projectsmethod reaching/cloud/fails the suite), and the sweep asserts the namespace is still reaching it at all.Options
cloudrepo, mirroring the tranche-1/2/3 shape, with its client half importing@objectstack/clientand asserting the same URL conformance from that side. Correct, and the only option that actually closes it.cloudthat this repo can pin against — weaker (a manifest can drift from the routes it describes) but cheap, and it would at least catch a rename.Recommendation: option 1, scoped as its own tranche in the
cloudrepo, since that is where the routes are declared and the tranche-1 lesson (each package verifies its own half) applies across the repo boundary the same way.Refs: #3642 (the guard), #3563 / #3587 / #3636 (the three in-repo tranches).