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 }}
Repository navigation
[seam → repo:objectui] Retire DEFAULT_UPGRADE_URL = '/settings/billing' — the app-shell's tolerant default for the entitlement upgrade CTA points at a path no router serves (objectui half of cloud#1869) #10437
Seam card filed by the repo:cloud execution seat (seat post objectstack-ai/objectstack#6026, session session_017Wu48ZSjk7HJjyJmGNBtUk, R35): the fix lands in objectstack-ai/objectui, which this seat has no write access to, so per the cross-repo rule it lands here with repo:objectui. Named reader: the repo:objectui / domain:ui execution seat (seat post objectstack-ai/objectstack#6025), at its next candidate pass — this card is its dispatch entry. Triage: domain:ui / type are yours; only the routing pair is applied here.
What (objectui side)
packages/app-shell/src/environment/entitlements.ts:48 declares DEFAULT_UPGRADE_URL = '/settings/billing', used as the client-side fallback whenever the control plane omits upgrade_url / upgradeUrl (useEnvironmentEntitlements.ts twice, entitlements.ts twice). EnvironmentEntitlementDialog.tsx renders the CTA as a plain anchor resolved against apiBase, so the fallback is a full-page navigation to a path that no router serves — objectui's console declares settings only under /organizations/:slug, and the control plane serves its console under /_console. It has been wrong for as long as it has existed.
Ask: retire the default. Absent a server-provided value, render no CTA — the same contract objectui#7273 already adopted for the tenant Console's upgrade link. This is the contract-first half: a client-side default for a value only the server can know is the tolerant-consumer shape that fires exactly when the server is old or the field is dropped.
Triage — sweep repair. Added priority:p3; pm:queue and repo:objectui kept.
⛔ No domain:*, deliberately — the fix lands in objectui. repo:objectui is the routing field for a cross-repo seam; domain:* and repo:* are alternatives, not a pair. ⚠️ ⛔ Future sweeps must not re-flag this under disjunction ②; the full reasoning is on objectstack-ai/objectstack#14796, which carried the same shape and the same two-round debt.
p3: DEFAULT_UPGRADE_URL = '/settings/billing' pointing at a path no router serves is a real defect — a user who reaches the entitlement upgrade CTA lands nowhere — but it is a tolerant default, so it only bites a host that supplies no upgrade URL of its own. ⚠️ ⛔ If the objectui seat measures that the default is what real hosts actually get (rather than a fallback nobody hits), that is a p2 and worth saying so on the card rather than quietly fixing it as filed.
⚠️ It is the objectui half of cloud#1869. ⛔ Retiring the constant without confirming the cloud half's expectation is how a tolerant default gets replaced by a hard failure — check what cloud supplies before removing the fallback, not after.
Session session_01X7HwfPLpQtCixDMrRGkSbe, acting on the maintainer instruction 「objectui 你负责迁移。fleet 中继不支持 GitHub 的 issue transfer, 应该立 skills 卡解决」 (2026-09-23).
Routing rule 1 (cross-repo-coordination): this card's fix lands entirely in objectstack-ai/objectui, and nothing is left on the objectstack side, so it moves there. The fleet relay cannot transfer issues yet: there is no transfer op, and the minted token covers a single repo. The capability is filed as objectstack-ai/objectstack#19884. This card will be transferred rather than rebuilt, so its thread and history travel with it. pm:queue → pm:blocked until then. ⛔ Do not dispatch it here.
Migrated from objectstack-ai/objectstack#14831 — pm:blocked → pm:queue, lane domain:ui · 2026-09-25T01:03Z
Acting on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「迁移卡 帮我处理」; where — the maintainer's chat with session session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-25. ⛔ Not a claim and not a dispatch.
Why it moved: the migration comment on this thread (session session_01X7HwfPLpQtCixDMrRGkSbe, 2026-09-23) routed the card here under cross-repo routing rule 1: the fix lands entirely in objectui. It was parked only on the transfer door, Blocked-by: #19884.
Labels on arrival:repo:objectui has no counterpart in this repo, so the platform dropped it. pm:blocked is replaced with pm:queue: its only condition was the transfer. domain:ui is added because the landing site is objectui's published library/apps (the ui stream). Type and priority carried over unchanged.
Claim: PM loop round 4 — domain:ui execution seat 2
Session: session_014mXUNuFomfj24w7s1pZzhN
Branch: claude/issue-10437-retire-default-upgrade-url
Worktree: objectui-issue-10437
Domain: domain:ui
Seat: domain:ui#2
File surface: packages/app-shell/src/environment/entitlements.ts (DEFAULT_UPGRADE_URL and its two reads), packages/app-shell/src/environment/useEnvironmentEntitlements.ts (its three reads), EnvironmentEntitlementDialog.tsx only where the CTA must be withheld when no URL arrives; tests beside them; one .changeset/10437-…md (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus — dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; follows the objectui#7273 contract (no server value ⇒ no CTA)
Clause-②: no
Thread-read: 5824927652
Serial constraints cleared: open-PR file lists read 2026-09-25T05:43Z. No open PR touches packages/app-shell/src/environment/. Live pm:dispatched claims name no file there. DEFAULT_UPGRADE_URL is not re-exported from @object-ui/app-shell's entry (src/index.ts: 0 hits).
Clause-②: no — a client-side default for a value only the server knows is retired, and the CTA is withheld when no URL arrives. No exported symbol, schema or accept set moves.
DEFAULT_UPGRADE_URL ('/settings/billing') and all of its reads are gone: 0 hits at head, 10 lines in 3 files on base. The 403 path (entitlementDialogFromError) and the proactive prompt (upgradeDialogSpec) include an upgrade CTA only when the control plane sends a URL, and use it verbatim. This is the same x ? { label, url } : undefined shape as contact_url in the same function, and objectui#7273's "render no link at all". EnvironmentEntitlementsState.upgradeUrl is now optional
triage's guard
measured what can be read. objectstack runtime-config-plugin.ts treats upgradeUrl as absent by default and names a relative path as the control plane's current dialect. @objectstack/spec (origin/main and npm 17.4.0) declares neither spelling; the lit control ApiErrorSchema is present in both. objectstack-ai/cloud answers 403 from this session, so the emitter could not be read; that gap is declared in the PR. With no URL the dialog still opens with its title and body and only the link is withheld. That link went to a path no router serves: the Console declares settings only under /organizations/:slug (apps/console/src/App.tsx). So this is not a hard failure
p2 question
not measured, because it needs the cloud emitter. Structurally, the derived and unknown states never reach the upgrade prompt: decideEnvironmentCta returns upgrade_for_development only on canCreateDevelopmentEnv === false, which only the summary sets. Triage asked for a card note only if the answer were p2, so priority:p3 stands
pins
no-URL ⇒ no CTA, on the 403 builder, the proactive builder, the hook and the dialog. The implementer ran them red on base (11 failures, all on the retired default). The control is a distinct server URL rendered verbatim. The EnvironmentListToolbar.test.tsx edit is one fixture line; no assertion is weakened
Clause-②: no / semver patch
the retyped member is off the package face. The @object-ui/app-shell entry has 0 environment / entitlement exports on head source. Published 17.6.0 exports is . and ./styles.css only, so dist/environment/entitlements.d.ts cannot be reached by specifier
contract review
PASS at CONTRACT_REVIEW_TIER on this head, record 5828310887. The seat read the reviewer transcript: every turn ran at tier
governed
NOT GOVERNED (8 paths, check-governed-queue-guard.mjs --test at objectui origin/main; control AGENTS.md ⇒ GOVERNED)
CI
43 check-runs on 6bbeebf: 40 success, 3 skipped by design (coverage ×2, dependabot, also skipped on the merge-base), 0 red
closing keywords
Fixes #10437 only
Findings, each with its disposition
Reviewer: two changeset clauses ("the control plane mounts its console under /_console", "no router serves that path") state the cloud half as fact, while the PR body declares it unread. The card and objectui#7273 carry the same premise ⇒ Acceptance notes.
Reviewer: the summary path passes data.upgradeUrl through with no typeof guard, unlike the 403 path. Base did the same (data.upgradeUrl || DEFAULT), and contactSalesUrl matches ⇒ pre-existing, Acceptance notes.
Implementer observation: AppContent.inaccessibleAppStrand.test.tsx was once stopped by the network-escape guard in a full app-shell run, and passed 6/6 alone at the same head. The reviewer confirmed that this diff cannot reach it: AppContent.tsx imports nothing from environment/, and the test mocks ObjectView. There is no on-demand repro ⇒ recorded, not filed.
The implementer's report was delivered to this seat in-session. Two of its writes were refused by the permission classifier before they ran, and this seat did not re-issue either:
the os-dev-report comment on this card;
the PR assignee (label-write … --assign os-elon-musk on objectui#10517).
Both are with the maintainer.
State
ready and auto-merge (squash) go through the relay ops pr_ready + automerge_enable in the same dispatch as this ACCEPT's follow-up.
Activity
huangyiirene commentedon Sep 3, 2026
Triage — sweep repair. Added
priority:p3;pm:queueandrepo:objectuikept.⛔ No⚠️ ⛔ Future sweeps must not re-flag this under disjunction ②; the full reasoning is on objectstack-ai/objectstack#14796, which carried the same shape and the same two-round debt.
domain:*, deliberately — the fix lands inobjectui.repo:objectuiis the routing field for a cross-repo seam;domain:*andrepo:*are alternatives, not a pair.p3:DEFAULT_UPGRADE_URL = '/settings/billing'pointing at a path no router serves is a real defect — a user who reaches the entitlement upgrade CTA lands nowhere — but it is a tolerant default, so it only bites a host that supplies no upgrade URL of its own.objectuiseat measures that the default is what real hosts actually get (rather than a fallback nobody hits), that is ap2and worth saying so on the card rather than quietly fixing it as filed.objectuihalf ofcloud#1869. ⛔ Retiring the constant without confirming the cloud half's expectation is how a tolerant default gets replaced by a hard failure — check what cloud supplies before removing the fallback, not after.Generated by Claude Code
objectstack-fleet commentedon Sep 23, 2026
Migration to objectstack-ai/objectui — waiting on the transfer door · 2026-09-23T15:02Z
Blocked-by: objectstack-ai/objectstack#19884
Session
session_01X7HwfPLpQtCixDMrRGkSbe, acting on the maintainer instruction 「objectui 你负责迁移。fleet 中继不支持 GitHub 的 issue transfer, 应该立 skills 卡解决」 (2026-09-23).Routing rule 1 (cross-repo-coordination): this card's fix lands entirely in objectstack-ai/objectui, and nothing is left on the objectstack side, so it moves there. The fleet relay cannot transfer issues yet: there is no
transferop, and the minted token covers a single repo. The capability is filed as objectstack-ai/objectstack#19884. This card will be transferred rather than rebuilt, so its thread and history travel with it.pm:queue→pm:blockeduntil then. ⛔ Do not dispatch it here.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Migrated from objectstack-ai/objectstack#14831 —
pm:blocked→pm:queue, lanedomain:ui· 2026-09-25T01:03ZActing on the maintainer's instruction. Provenance: who — the maintainer; verbatim — 「迁移卡 帮我处理」; where — the maintainer's chat with session
session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-25. ⛔ Not a claim and not a dispatch.session_01X7HwfPLpQtCixDMrRGkSbe, 2026-09-23) routed the card here under cross-repo routing rule 1: the fix lands entirely in objectui. It was parked only on the transfer door,Blocked-by: #19884.transferop (GraphQLtransferIssue, token minted for source + target) and anissue-transferdoor, so cards filed in the wrong repo move with their history instead of being rebuilt objectstack#19884 closedcompletedon 2026-09-23, adding the fleet-writetransferop. This card was moved withscripts/pm/issue-transfer.mjsthrough the relay, so its thread and history travel with it, and the old URL redirects here.repo:objectuihas no counterpart in this repo, so the platform dropped it.pm:blockedis replaced withpm:queue: its only condition was the transfer.domain:uiis added because the landing site is objectui's published library/apps (the ui stream). Type and priority carried over unchanged.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 4 —
domain:uiexecution seat 2Session:
session_014mXUNuFomfj24w7s1pZzhNBranch:
claude/issue-10437-retire-default-upgrade-urlWorktree:
objectui-issue-10437Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/app-shell/src/environment/entitlements.ts(DEFAULT_UPGRADE_URLand its two reads),packages/app-shell/src/environment/useEnvironmentEntitlements.ts(its three reads),EnvironmentEntitlementDialog.tsxonly where the CTA must be withheld when no URL arrives; tests beside them; one.changeset/10437-…md(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus—dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; follows the objectui#7273 contract (no server value ⇒ no CTA)Clause-②: no
Thread-read: 5824927652
Serial constraints cleared: open-PR file lists read 2026-09-25T05:43Z. No open PR touches
packages/app-shell/src/environment/. Livepm:dispatchedclaims name no file there.DEFAULT_UPGRADE_URLis not re-exported from@object-ui/app-shell's entry (src/index.ts: 0 hits).Clause-②: no— a client-side default for a value only the server knows is retired, and the CTA is withheld when no URL arrives. No exported symbol, schema or accept set moves.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT: objectui#10517 at
6bbeebf; ready + auto-merge follow this ACCEPTdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim5827459553.DEFAULT_UPGRADE_URL('/settings/billing') and all of its reads are gone: 0 hits at head, 10 lines in 3 files on base. The 403 path (entitlementDialogFromError) and the proactive prompt (upgradeDialogSpec) include an upgrade CTA only when the control plane sends a URL, and use it verbatim. This is the samex ? { label, url } : undefinedshape ascontact_urlin the same function, and objectui#7273's "render no link at all".EnvironmentEntitlementsState.upgradeUrlis now optionalruntime-config-plugin.tstreatsupgradeUrlas absent by default and names a relative path as the control plane's current dialect.@objectstack/spec(origin/main and npm 17.4.0) declares neither spelling; the lit controlApiErrorSchemais present in both.objectstack-ai/cloudanswers 403 from this session, so the emitter could not be read; that gap is declared in the PR. With no URL the dialog still opens with its title and body and only the link is withheld. That link went to a path no router serves: the Console declaressettingsonly under/organizations/:slug(apps/console/src/App.tsx). So this is not a hard failuredecideEnvironmentCtareturnsupgrade_for_developmentonly oncanCreateDevelopmentEnv === false, which only the summary sets. Triage asked for a card note only if the answer were p2, sopriority:p3standsEnvironmentListToolbar.test.tsxedit is one fixture line; no assertion is weakenedClause-②: no/ semverpatch@object-ui/app-shellentry has 0environment/entitlementexports on head source. Published 17.6.0exportsis.and./styles.cssonly, sodist/environment/entitlements.d.tscannot be reached by specifierCONTRACT_REVIEW_TIERon this head, record5828310887. The seat read the reviewer transcript: every turn ran at tiercheck-governed-queue-guard.mjs --testat objectuiorigin/main; controlAGENTS.md⇒ GOVERNED)6bbeebf: 40 success, 3 skipped by design (coverage ×2, dependabot, also skipped on the merge-base), 0 redFixes #10437onlyFindings, each with its disposition
/_console", "no router serves that path") state the cloud half as fact, while the PR body declares it unread. The card and objectui#7273 carry the same premise ⇒ Acceptance notes.data.upgradeUrlthrough with notypeofguard, unlike the 403 path. Base did the same (data.upgradeUrl || DEFAULT), andcontactSalesUrlmatches ⇒ pre-existing, Acceptance notes.AppContent.inaccessibleAppStrand.test.tsxwas once stopped by the network-escape guard in a fullapp-shellrun, and passed 6/6 alone at the same head. The reviewer confirmed that this diff cannot reach it:AppContent.tsximports nothing fromenvironment/, and the test mocksObjectView. There is no on-demand repro ⇒ recorded, not filed.Deviations recorded
The implementer's report was delivered to this seat in-session. Two of its writes were refused by the permission classifier before they ran, and this seat did not re-issue either:
os-dev-reportcomment on this card;label-write … --assign os-elon-muskon objectui#10517).Both are with the maintainer.
State
readyand auto-merge (squash) go through the relay opspr_ready+automerge_enablein the same dispatch as this ACCEPT's follow-up.Generated by Claude Code
fix(app-shell): retire DEFAULT_UPGRADE_URL, so no server upgrade URL …