Skip to content

Sync upstream v2 (cd6048d26) and version apps 0.0.1-beta.119.shuv.1 - #67

Open
shuv1337 wants to merge 139 commits into
v2from
sync/upstream-v2-2026-11
Open

shuv1337 wants to merge 139 commits into
v2from
sync/upstream-v2-2026-11

Conversation

@shuv1337

@shuv1337 shuv1337 commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Syncs the fork with upstream UsefulSoftwareCo/executor v2 and versions the fork's apps package on the new base. Draft until local and CI e2e pass. Not for merge/deploy without the Executor Owner's sign-off.

Commits and SHAs

SHA
Rollback target (origin/v2 before this PR) 6e3357b5031e3d6522d93e769cfdbd7a64420a69 (6e3357b)
Merge base of origin/v2 and upstream/v2 54bfc1a59bf558a3405d53a02d8e972c6cf506f2
Merge parent 1 (fork, origin/v2) 6e3357b5031e3d6522d93e769cfdbd7a64420a69
Merge parent 2 (upstream/v2) cd6048d26b618b6a349a945f96f65823153c6684
Merge commit a84cf12f6 — Merge upstream/v2 (cd6048d) into the fork
Version commit 534821d1e — apps 0.0.1-beta.119.shuv.1

Upstream brought 137 commits since 54bfc1a59; the fork had 147 of its own.

Conflicts: 34, not the expected 0

The 0-conflict expectation did not hold: git merge --no-ff upstream/v2 stopped with 34 conflicted files (~60 hunks). Each was resolved by keeping both sides' behavior:

  • apps/hosted/self-host/scripts/package-runtime.ts — fork's split product/apps process configs kept; upstream's no_brotli_content_encoding flag added to product, apps and workflows Workers.
  • apps/hosted/server/src/implementation/bearer-access.ts — imports unioned (fork ConnectionKeyRefused + upstream callerSpanAttributes).
  • apps/hosted/server/src/implementation/events.ts — fork patConnectionPolicy import kept with upstream's batched accountAccesses/resourceAuthorityForApp.
  • apps/hosted/server/src/implementation/mcp-http.ts — fork AuthenticationUnavailable/CurrentCaller/mcpCaller + connection-bound authenticate(…, address.connection) kept, wrapped in upstream's Effect.annotateSpans(caller).
  • apps/hosted/server/src/implementation/resource-policy.ts — fork visibleAppAccesses (also checks membership for an empty app list) kept over upstream's equivalent batched visibleApps; upstream's usableLinks/usableAppLinks rewrite merged cleanly beneath it.
  • apps/hosted/web/src/contracts/navigation.ts — fork "Review request" title for apps/<id>/approve kept; upstream's "App catalog" title for apps/add (the add/custom route is gone upstream).
  • apps/hosted/web/src/implementation/pages/add-app.tsx — fork publication install flow kept; upstream AddAppBack/MakeYourOwn components replace the inline back link and custom-service button.
  • apps/hosted/web/src/implementation/pages/approvals.tsx — fork AppApprovalFrame import kept alongside upstream's approvalsPageReads.
  • apps/hosted/web/src/implementation/pages/connect.tsx — upstream's shared useConnectionBindings; fork's mintKey and keys bindings added to it.
  • bun.lock — regenerated by bun install (fork workspace deps kept); apps version then set in the version commit.
  • e2e/test-plan.ts — both sides' new scenarios kept (fork syncro/native/team-registry/registry-migration + upstream storageMigrationDiagnostics).
  • e2e/tests/docker-release.spec.ts — fork's skip of the remote-registry failure checks kept (the fork's self-host serves an org-only registry).
  • e2e/tests/empty-states.spec.ts — upstream's Can’t reach Executor|Unable to complete… regex plus the fork's .first().
  • packages/app-management/src/cli.ts — upstream's Host/withHost local-server resolution; fork apps call command (callTool, AppLookupFailed) adapted to take a Host; upstream notSignedIn text.
  • packages/app-management/src/http.ts — a host that supplies the fork's narrowed org registry keeps it (copy/catalog/publicationSource and the fail-closed anonymous routes); otherwise upstream's wire-revision mapping (registryForRevision, packageNameFromRevision) applies.
  • packages/app-templates/src/implementation/executor-skill-digests.gen.ts — regenerated with bun run executor:intro.
  • packages/apps/package.json — upstream base 0.0.1-beta.119 taken in the merge, then 0.0.1-beta.119.shuv.1 in the version commit.
  • packages/mcp/src/contracts/execute.ts — fork AdvertisedInteractionId import kept; its ToolName import dropped because upstream removed ApprovalTooLarge, its only user.
  • packages/mcp/src/implementation/server.ts — upstream withOperationSpan("mcp.describe") plus the fork's personLink.
  • packages/sdk/src/contracts/runtime.ts (9 hunks) — both fork sharedRuntime and upstream hostApi fields kept on every invocation type.
  • packages/sdk/src/contracts/workflow-runtime.ts — both sharedRuntime and hostApi.
  • packages/sdk/src/implementation/account-health.ts (2) — both fields passed.
  • packages/sdk/src/implementation/app-runner.ts — Worker identity drops accounts for a shared runtime (fork) and appends the host-API revision (upstream).
  • packages/sdk/src/implementation/app-runtime.ts — migration invocations set hostApi: undefined and sharedRuntime: false.
  • packages/sdk/src/implementation/app-storage.ts — fork activeData superseded-version guard + sharesRuntime kept with upstream hostApi plumbing.
  • packages/sdk/src/implementation/declarations.ts — fork checksOf kept, now using upstream's batched accountsUsable.
  • packages/sdk/src/implementation/schedules.ts (2) — fork CurrentCaller (schedule system caller) plus upstream CallFailureSources/sources.source.
  • packages/sdk/src/implementation/skills.ts — both fields.
  • packages/sdk/src/implementation/tools.ts (2) — both fields; on resume, the fork's asRequester/approver wrapper kept and upstream's readOf, hostApi, executeRenewing(read), observeFailure and confirmed-read failure mapping re-applied inside it.
  • packages/sdk/src/implementation/webhooks.ts — imports unioned (sharesRuntime + declarationLimits).
  • packages/sdk/src/implementation/workflows.ts (3) — callerContext, sharedRuntime and hostApi all kept.
  • packages/ui/src/implementation/dashboard/catalog.tsx (2) — upstream CatalogPageFrame/MissingApp; fork "Published apps" section and PublishedApps kept inside it.
  • packages/ui/src/implementation/dashboard/scoped-connections.tsx (5) — upstream's connection cards + per-connection page as the base; fork's connection-key create dialog and key list/revoke moved onto the per-connection page.
  • scripts/e2e-npm-packages.ts — union of both apps beta lists (adds 35 and 95).

Outside the conflict hunks: e2e/tests/connection-keys.spec.ts now opens a connection through its card link (upstream turned the button into a link).

Upstream ancestors (all present)

git merge-base --is-ancestor <sha> HEAD: c089e1d yes · 0e8a57d yes · ffb55ee yes · fe1afa8 yes · a6f9b43 yes · fb49ec6 yes

Upstream UsefulSoftwareCo#2402 / UsefulSoftwareCo#2403 are not ported

UsefulSoftwareCo#2402 (56aec8b) and UsefulSoftwareCo#2403 are on upstream main, whose layout (packages/core/sdk, apps/cloud, apps/local, drizzle migrations) does not exist in v2: all 8 cherry-pick conflicts were modify/delete. UsefulSoftwareCo#2403's tests are unit tests, which this repo bans outside e2e/.

v2 already avoids the bug UsefulSoftwareCo#2402 fixes on main: it reuses a dynamically registered (DCR) client only when the full registration request matches, including the sorted scope set (packages/sdk/src/implementation/oauth.ts:1103, packages/sdk/src/implementation/stored-oauth-client-credentials.ts:184). A server that adds scopes therefore gets a new registration rather than an old client it would refuse with invalid_scope.

Not in v2: persisting the scopes the server actually registered (RFC 7591 §3.2.1) and limiting later sign-ins to them. That is a follow-up needing a storage migration and an e2e scenario; the Executor Owner will file the issue.

Does UsefulSoftwareCo#2403's bug apply to v2? No: v2 reuses a DCR client only when the full registration request, including the sorted scope set, matches (oauth.ts:1103 looks the client up by automaticKey; stored-oauth-client-credentials.ts:184 hashes [...new Set(scopes)].sort() into that key), so the stale-client invalid_scope reuse cannot happen. Scope persistence/limiting is the follow-up.

FYI (access policy): canUse lets an app's creator and the organization owner always use group-audience apps (apps/hosted/server/src/implementation/resource-policy.ts:91-99; comment at 91-92, expression 93-99). This is the fork's rule (present at 6e3357b), kept through the merge; upstream cd6048d grants group-audience use only via granted.

Versioning

packages/apps: 0.0.1-beta.119.shuv.1 — upstream's new base with the fork suffix. Existing fork tags are apps-v0.0.1-beta.100.shuv.1..3; no beta.119 fork release exists, so N = 1. apps/cli stays at upstream's 2.0.0-beta.34: the fork has never suffixed it, and ReleaseVersion (packages/utils/src/release-version.ts) accepts only 2.x.y(-beta.N). Nothing is published or tagged by this PR.

Staging smoke checklist

  • OAuth refresh
  • DCR scopes
  • MCP without an event stream (no SSE)
  • ?token= redaction in logs
  • Self-host ?token= redaction: c089e1d redacts only in Cloud Workers (git show --stat c089e1d touches only apps/hosted/cloud/src/edge.ts, infrastructure/app-outbound.ts, infrastructure/telemetry.ts, invocation-telemetry.ts), so self-host logs need their own check before deploy.
  • mcp-http connection-key sign-in check (connection-bound authenticate(…, address.connection), apps/hosted/server/src/implementation/mcp-http.ts:241).
  • batch-authentication.ts identity reuse across one dashboard batch request.
  • Runtime check of the usableLinks/usableAppLinks SQL against Postgres (apps/hosted/server/src/implementation/resource-policy.ts:217, :242).

Note: c089e1d strips query strings only in Cloud Worker logs. Self-host is not covered and needs its own ?token= redaction check before deploy.

Review risks

  • executor.user.id now in spans (apps/hosted/server/src/contracts/auth.ts:176, apps/hosted/server/src/implementation/mcp-http.ts:236).
  • Connection-key sign-in through the merged connection-bound authenticate near mcp-http.ts:240.
  • batch-authentication.ts reuses identity checks across one dashboard batch request.
  • usableLinks/usableAppLinks SQL rewrite (resource-policy.ts:~217) under the fork's resourceAuthorityForLinksOfApps: runtime check (SQL is not typechecked).
  • OAuth refresh keeps the redirect URI (0e8a57d).

Post-merge release step

  1. Tag apps-v0.0.1-beta.119.shuv.1 on the merged v2 commit.
  2. Create the GitHub pre-release for that tag with the apps tgz attached.
  3. executor-v2 pulls it.

Not done by this PR; needs the Executor Owner's go-ahead.

Verification

bun run check exits 0 on the head commit (format, oxlint, typecheck 9/9 projects with 0 errors, protocols, telemetry, boundary). Local and CI e2e results are reported in the PR comments.

leoisadev1 and others added 30 commits October 9, 2026 15:55
The sidebar's Connect becomes Connections. The list shows the full-access URL
and each scoped connection as a card with a Connect button. Clicking a scoped
card opens one page that replaces the old detail view and editor: the name is
edited in place, apps are turned on and scoped right on their rows, and Save
appears only after a change. Copy MCP URL, Rename and Revoke sit in a menu.

The shared app row no longer repeats an app's only account next to its
subtitle, and can show a host link to connect an account when an app has none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Logos rendered at 17px inside a bordered 34px box. They now fill a rounded
white tile with a hairline edge, like the integrations catalog, fetched at a
size that stays sharp in the largest tile. The package fallback keeps its
bordered box. Pages that shrank the logo image inside the tile no longer do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Self-host checks for due scheduled runs and for queued provisioning jobs every
second, and traced every check: a schedule.dispatch span with its storage and
SQL spans, plus a root sql.execute span. An instance with no traffic exported
about 800 spans a minute into the bundled Motel store, which reaches its 1 GiB
bound within hours and then evicts on every export, writing to disk constantly.

A check that finds nothing now records nothing. Each scheduled operation a
check finds runs in its own schedule.dispatch trace, so the background work
under it keeps its dispatcher root, and each provisioning job is traced as
before. Local runs the same scheduler and stops tracing its idle checks too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Self-host and local look for due event deliveries every two seconds, and traced
every pass: an events.dispatch span with its delivery, subscription and
retention statements, about 15 spans each. On an instance with no traffic that
is about 450 spans a minute in the bundled Motel store, the largest idle source
since the event worker arrived.

A pass that finds nothing to deliver now records nothing. Each delivery attempt
and each subscription a pass expires is still traced, in its own trace. Cloud's
coordinator calls the same delivery code with tracing on and is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schedule coordinator's database window stayed open for two minutes
after each pass, while the retired coordinator's heartbeat and the
recovery alarm woke it at least once a minute. The open sockets and the
pending idle timer kept the object from ever becoming eligible for
hibernation, so it billed duration for every second of the day.

An object database now takes the time its window lingers after the last
call. The schedules owner passes zero, so its window closes as soon as a
pass ends. MCP sessions keep the two-minute window.
The Streamable HTTP client opens a standalone GET event stream after
initialization. Some servers answer it with 401 even though every POST
succeeds, and transportFetch failed the whole session on that response,
so discovery reported the app's credentials as rejected. Hand the
refusal back to the SDK instead, which treats it as no stream, as it
does without Executor. POSTs and the legacy SSE GET are unchanged.

Fixes UsefulSoftwareCo#2306
Password-created owners had no UI path to link an SSO identity. The linking endpoint already existed. This adds a Connect SSO button that starts the same authenticated flow.
A NUL in an app name returned a 500 storage error, and names made only of invisible characters created an app that listed as blank. AppName now refuses control characters and line separators and requires a visible character, and quick-add uses the same schema. Stored names are read with NonEmptyString, so existing apps are unaffected.

Co-authored-by: Cursor <cursoragent@cursor.com>
RhysSullivan and others added 23 commits October 29, 2026 18:33
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cloudObservability already removes query strings from request URLs in
native logs and traces. The Edge, InvocationTelemetry and AppOutbound
Workers set no observability, so their invocation logs kept full URLs,
including unsubscribe links, sign-in codes and app outbound searches.
They now share the same redacted log settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… watcher

An app page's own files, such as its stylesheet, went through the whole page
route: caller account resolution, account health reads and an app_viewed usage
event, before the route noticed the path named a file. Files are now answered
right after the session check and version read. The version watcher, a constant
756-byte script that only went through the stack for the session check, is
inlined into the already authorized document as a module script, which keeps
its deferred timing and removes one request per page load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in 137 upstream commits since 54bfc1a. 34 files conflicted; each
was resolved by keeping both sides' behavior:

- Fork sharedRuntime + upstream hostApi on invocations (sdk runtime,
  workflow-runtime, account-health, app-runner, app-runtime, app-storage,
  skills, tools, webhooks, workflows): both fields kept; app Worker identity
  drops accounts for shared runtimes and appends the host API revision.
- tools.ts resume: fork's asRequester/approver wrapper kept; upstream's
  confirmed-read (readOf), hostApi, observeFailure and catch-with-read applied.
- declarations.ts: fork checksOf kept, using upstream's batched accountsUsable.
- schedules.ts: fork CurrentCaller plus upstream CallFailureSources/sources.
- hosted mcp-http.ts: fork connection-bound authenticate + CurrentCaller with
  upstream caller span attributes; bearer-access/events imports unioned.
- resource-policy.ts: fork visibleAppAccesses (empty-list membership check)
  kept over upstream's equivalent batched visibleApps.
- app-management http.ts: fork narrowed org registry kept when the host
  supplies one; otherwise upstream wire-revision mapping. cli.ts: fork
  `apps call` adapted to upstream's Host/withHost local-server resolution.
- UI: upstream connection cards + per-connection page, with fork connection
  key create/list/revoke moved onto the per-connection page; catalog keeps
  fork published-apps list inside upstream's CatalogPageFrame; add-app and
  approvals/navigation keep fork routes with upstream components/labels.
- package-runtime.ts: fork split product/apps processes, plus upstream
  no_brotli_content_encoding flags.
- e2e: test-plan union; docker-release keeps fork's skip of remote registry
  checks; empty-states combines both; connection-keys opens the card link.
- packages/apps version and bun.lock take upstream's (as earlier syncs did);
  skill digests regenerated; unused ToolName import dropped.
The fork carries its own apps releases as <upstream base>.shuv.N (tags
apps-v0.0.1-beta.100.shuv.1..3). The upstream/v2 merge moved the base to
0.0.1-beta.119, and no beta.119 fork release exists yet, so N is 1.
apps/cli stays at upstream's 2.0.0-beta.34: the fork never suffixes it and
ReleaseVersion accepts only 2.x.y(-beta.N). Version only; nothing is
published or tagged.
@shuv1337

shuv1337 commented Nov 3, 2026

Copy link
Copy Markdown
Owner Author

E2E results for head 534821d1e

CI (fork-ci run 41609433596): all green. check passed in 2m51s: bun run check, then e2e suites pglite (1), typecheck-runner (12), prepare-cache (5), emulator-failures (5), dashboard-file-names (1), release-archives (6) = 30/30. Socket Security: both pass.

Local, same six suites: 30/30 passed.

Local, targeted self-host scenarios (headless, OS-assigned ports, no display; selected from the changed paths: connection-keys, mcp-connections, mcp-event-stream, credential-placement, dashboard-batch-authentication, caller-identity, catalog-official-apps): 25 passed, 1 skipped (Cloud-only), 1 failed of 27.

  • Failed: mcp-connections.spec.ts › Members create and revoke a scoped connection from the dashboard, at step "Choose Grok Bot setup" (DriverFailed, 15 s timeout). The failure screenshot shows the Escape that closes the full-size screenshot also closed the Connect setup dialog beneath it. That is the Radix focus race the spec's own comment describes. The ConnectDialog, install instructions and spec are all upstream code, unchanged by this merge.
  • Rerun once on its own: passed (7.2 s). Treat it as a flake under 12-worker load. It is still a bug to fix separately, not with retries.

The PR stays draft: the local targeted run was not clean on the first pass.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants