Skip to content

fix(plugins,edge): a Cron run that doesn't apply its bundle fails, and /readyz says the bundle served is stale - #1128

Merged
alexmercerpo merged 6 commits into
fix/sdk-duplicate-plugin-entriesfrom
fix/skilled-refresh-outcomes
Nov 5, 2026
Merged

alexmercerpo merged 6 commits into
fix/sdk-duplicate-plugin-entriesfrom
fix/skilled-refresh-outcomes

Conversation

@frontegg-david

@frontegg-david frontegg-david commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Stacks on #1127.

What and why

Managed edge (createEdgeMcp({ managed })) and Node both refresh the saas bundle on a schedule: a Worker's Cron Trigger calls scheduled(), and Node polls. Two things hid a refresh that left an older bundle serving:

  • The Cron run reported success. The plugin's refresh resolved once the pulled bundle was applied, or refused. A start that couldn't pull served the cached bundle without saying so. Only a pull that threw (such as a rejected pull token) failed the run. So a bad signature, an older bundle, a schema error, or an outage when an isolate started all showed as ok in the Cron logs and metrics, and operators couldn't see that updates had stopped.
  • /readyz reported plain healthy. The plugin's check only looked at whether a bundle was loaded.

The refresh returns an outcome. BundleSyncService.refresh(), which a scheduler calls, now resolves with a BundleSyncOutcome, and so does the scheduler's start():

  • applied, or unchanged when the pull brought the bundle already served (same version and content), with the bundle id and version.
  • refused, with the refused bundle's id and version and the reason: its signature, its checks, older than the served one, or a rolled-back apply.
  • failed, with the reason, and cacheFallback: true when a start served the cached bundle because its pull failed.

Each outcome carries at, an ISO time. A failed pull resolves as failed instead of rejecting.

How the plugin learns about each sync.

  • When the pull at start fails, the saas source hands the cached bundle to its listeners with { pullFailure }. BundleSourceListener takes this as a new optional origin argument.
  • A poll that fails is reported to the source's new onPullFailure listeners. Until now it was only logged. A start or a refresh that fails still throws to its caller.
  • The sync service records the outcome of every bundle it applies or refuses, pulled or pushed, and of every failed pull.

The Worker fails the run. scheduled() throws for a refused or failed outcome, so Cloudflare records the run as an exception and counts it as a failed invocation. The error says why:

  • [frontmcp/edge] Cron refresh: bundle billing@4.2.0 was not applied: digest mismatch (...)
  • [frontmcp/edge] Cron refresh: the bundle pull failed, so the cached bundle serves: pull responded 503

An applied or unchanged run succeeds.

/readyz names the stale bundle. While the last sync was refused or failed, the skilled-openapi check is degraded, with details: { state: 'stale', bundleId, bundleVersion, lastSync }: the bundle served, and the refusal or failure with its reason and time. The server stays ready, since it serves the last good bundle. The next sync that applies a bundle, or pulls the one served again, makes the check healthy. With no bundle loaded, the check is still unhealthy and /readyz answers 503.

Why degraded: HealthProbeResult.status already has healthy | degraded | unhealthy, and the SDK's HealthService answers not_ready (503) only for unhealthy. Remote apps already use degraded before their first check. So degraded keeps the Worker or pod in rotation, which is right while it serves the last good bundle, and still tells a monitor that it is stale. unhealthy would take a server that still serves out of rotation, and one bad publish would take out every replica. No SDK change was needed.

Redaction. Every reason goes through publicLoadFailureReason, as the tools' errors already do: the first line, URLs cut to scheme, host and path, tokens removed, 500 characters at most.

Scenarios covered:

  • B2: the saas source on Node, a poll that fails, and a start that serves the cache.
  • B3: a refused bundle leaves the served one, and now says so.
  • B4: a failure is visible beyond the logs, in /readyz and in the Cron run.
  • B6 and J2: Cron refresh on a managed Cloudflare Worker.

Known limits:

  • The outcome is kept in memory, per process or isolate. On Cloudflare, /readyz answers for the isolate that serves it, which may not be the one that ran the Cron.
  • A BundleStore pinned in code (pin()) refuses pulled bundles, so its pulls count as refused.

User-facing change

  • What changed:
    • A managed Worker's Cron run fails when the bundle it pulled is refused, or when its pull fails, also when the isolate serves the cached bundle instead.
    • The Skilled OpenAPI /readyz check is degraded, with state: 'stale' and lastSync, while the bundle served is stale. The server stays ready.
    • The scheduler that SkilledOpenApiRuntimeDeps.attach receives resolves with a BundleSyncOutcome, a new exported type of @frontmcp/plugin-skilled-openapi.
    • @frontmcp/adapters/skills: BundleSourceListener takes an optional origin (BundleOrigin), and SkillBundleSource has an optional onPullFailure (BundlePullFailureListener).
  • Before → after:
    • A Cron run that pulls a bundle with a bad signature, an older version or a schema error, or that starts an isolate during an outage: ok → exception, with the reason in the error.
    • The /readyz check while a newer bundle was refused, or the last pull failed: healthy with state: 'loaded' → degraded with state: 'stale' and lastSync: { status, reason, at, ... }. /readyz stays ready (200).
    • The attach scheduler's start() and refresh(): resolved void, and start() rejected while no bundle was loaded → both resolve with a BundleSyncOutcome and don't reject for a failed pull.
  • frontmcp.dev pages affected (if known): /reference/deployment/edge (managed mode, Cron runs, /readyz), /reference/plugins/skilled-openapi (the health check), and the health and readiness page.
  • Skills catalog entries updated:
    • frontmcp-deployment/references/deploy-to-cloudflare-skills-only.md
    • frontmcp-production-readiness/references/health-readiness-endpoints.md

The plugin's and the edge's READMEs are updated too.

Tests

Added:

  • @frontmcp/adapters, saas-pull.source.spec.ts: the cached bundle served at start carries the pull's failure; a pulled bundle carries none; a poll that fails reaches the onPullFailure listeners, and a failed start or refresh doesn't; a listener that throws is logged and polling goes on.
  • Plugin, bundle-sync.service.spec.ts: each outcome (applied, unchanged, refused for an older bundle, failed on a cold or warm refresh, failed with cacheFallback, a refused cached bundle), a failed poll and the push applied after it, a refused push, reasons redacted, and a source that starts without a bundle.
  • Plugin, bundle-load-state.spec.ts: the check stays healthy after an applied or unchanged sync, is degraded with the stale details after a refusal, a failed pull or a cache fallback, and stays unhealthy with no bundle.
  • Plugin, last-good-bundle.integration.spec.ts (a real server, read through the SDK's health service): a refresh that pulls a bundle changed after signing resolves refused, and the check is degraded; a restart during an outage is degraded with cacheFallback; a newer bundle makes it healthy.
  • Edge, index-wiring.spec.ts: scheduled() resolves for applied and unchanged, and throws, naming the reason, for refused, failed and a cache fallback, on the run that builds the server and on the next.
  • Edge, index.spec.ts (a real scope): a Cron run that pulls an older bundle fails, and so does the first run of an isolate that starts during an outage and serves the cache; /readyz stays ready and says the bundle is stale.
  • demo-e2e-cloudflare, managed Worker in workerd: Cron runs that pull a bundle changed after signing, or an older signed one, fail, and /readyz shows the refusal while the old bundle serves; a replica whose first event is a Cron run during an outage fails it and shows the cache fallback; an applied push makes the check healthy again. The test that expected ok for a refused bundle now expects exception.
  • demo-e2e-skilled-openapi, saas on Node: /readyz shows a bundle refused for its signature, a poll that fails the schema, an older bundle, and an outage start on the cache, and is healthy again once a poll applies a newer version.

Run:

  • npx nx run-many -t build -p sdk,adapters,plugin-skilled-openapi,edge,testing: passed.
  • npx nx test adapters: 63 suites, 1109 tests, passed.
  • npx nx test plugin-skilled-openapi: 51 suites, 766 tests, passed. One test that does a real DNS lookup (ssrf-guard.spec.ts, "rejects when DNS lookup fails entirely") sometimes times out at 5 s under a full parallel run; it passes alone, and this PR doesn't touch it.
  • npx nx test edge: 10 suites, 107 tests, passed.
  • npx nx test skills: 3 suites, 249 tests, passed.
  • npx nx test demo-e2e-cloudflare: 3 suites, 31 tests, passed.
  • npx nx test demo-e2e-skilled-openapi: 10 suites, 87 tests, passed.
  • npx nx run <project>:typecheck and npx tsc --noEmit -p <lib>/tsconfig.lib.json for adapters, plugin-skilled-openapi and edge: no errors.
  • Prettier and ESLint on the changed files: clean.

The SDK is unchanged, so the bundle-size e2e doesn't apply.

Summary by CodeRabbit

  • New Features

    • Sync operations now report whether bundles were applied, unchanged, refused, or failed.
    • Readiness checks show when the active bundle is stale or a recent sync failed, while the service continues serving the last good bundle.
    • Cloudflare scheduled runs now fail when a sync is refused or fails, including when a cached bundle remains available.
    • Pull failures can be monitored, and bundle update notifications include their origin.
  • Documentation

    • Updated guidance for readiness status, stale bundles, and scheduled sync outcomes.

…d /readyz says the bundle served is stale

A managed Worker's Cron run reported success when the bundle it pulled was
refused (signature, schema, older than the served one) or when an isolate's
start served the cached bundle because the pull failed, and the plugin's
/readyz check stayed healthy. Operators couldn't see that updates had stopped.

The plugin's refresh now resolves with what the sync came to: applied,
unchanged, refused with the reason, or failed, with cacheFallback when the
cached bundle serves. The saas source tells its listeners when a bundle is the
cached one, and reports failed polls. scheduled() throws for a refused or
failed outcome, so Cloudflare records the run as failed. The /readyz check is
degraded, which keeps the server ready, with the bundle served and the last
refusal or failure, its reason (redacted as the tools' errors are) and time.
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The change adds typed bundle sync outcomes and propagates pull-failure details through bundle sources. Health probes report degraded state for stale bundles, and managed Cron handlers fail when a sync is refused or fails. Tests and documentation cover these outcomes and readiness responses.

Changes: Bundle Sync and Readiness

Layer / File(s) Summary
Source failure metadata and notifications
libs/adapters/src/skills/sources/skill-bundle-source.interface.ts, libs/adapters/src/skills/sources/saas-pull.source.ts, libs/adapters/src/skills/sources/index.ts, libs/adapters/src/skills/index.ts, libs/adapters/src/skills/__tests__/saas-pull.source.spec.ts
Bundle listeners can receive origin metadata, and sources can report background pull failures through a subscription. Cached fallback bundles carry the pull-failure reason. Tests cover successful pulls, failure notifications, listener errors, and unsubscribe behavior.
Sync outcome recording
plugins/plugin-skilled-openapi/src/sync/bundle-load-state.ts, plugins/plugin-skilled-openapi/src/sync/bundle-sync.service.ts, plugins/plugin-skilled-openapi/src/index.ts, plugins/plugin-skilled-openapi/src/__tests__/bundle-sync.service.spec.ts, plugins/plugin-skilled-openapi/src/__tests__/bundle-version-order.integration.spec.ts, plugins/plugin-skilled-openapi/src/__tests__/runtime-deps-injection.spec.ts
BundleSyncService returns and records applied, unchanged, refused, and failed outcomes. The tests cover pull and push results, version ordering, cached fallback, and sanitized failure reasons.
Health state and runtime integration
plugins/plugin-skilled-openapi/src/sync/bundle-load-state.ts, plugins/plugin-skilled-openapi/src/skilled-openapi.plugin.ts, plugins/plugin-skilled-openapi/src/index.ts, plugins/plugin-skilled-openapi/src/__tests__/bundle-load-state.spec.ts, plugins/plugin-skilled-openapi/src/__tests__/last-good-bundle.integration.spec.ts, plugins/plugin-skilled-openapi/README.md, libs/skills/catalog/frontmcp-production-readiness/references/health-readiness-endpoints.md, apps/e2e/demo-e2e-skilled-openapi/e2e/saas-source.e2e.spec.ts
A loaded bundle is degraded when its latest sync was refused or failed; a failed load remains unhealthy. The plugin supplies the latest outcome to the health probe. Tests and documentation cover stale details, recovery, and readiness responses.
Managed Cron failures and readiness coverage
libs/edge/src/index.ts, libs/edge/src/__tests__/index-wiring.spec.ts, libs/edge/src/index.spec.ts, libs/edge/README.md, libs/skills/catalog/frontmcp-deployment/references/deploy-to-cloudflare-skills-only.md, apps/e2e/demo-e2e-cloudflare/e2e/helpers/managed-worker.ts, apps/e2e/demo-e2e-cloudflare/e2e/managed-edge-autoupdate.e2e.spec.ts, apps/e2e/demo-e2e-cloudflare/fixture-managed/worker.ts
Managed Cron handlers resolve for applied or unchanged syncs and throw for refused or failed syncs, including cache fallback. Edge and Cloudflare E2E tests check Cron failures and readiness details. The Cloudflare fixture enables the readiness endpoint.

Estimated code review effort: 4 (Complex) | ~50 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CloudflareCron
  participant EdgeMcp
  participant BundleSyncService
  participant SaasPullSource
  CloudflareCron->>EdgeMcp: Invoke scheduled handler
  EdgeMcp->>BundleSyncService: Start or refresh bundle sync
  BundleSyncService->>SaasPullSource: Pull bundle
  SaasPullSource-->>BundleSyncService: Bundle, pull failure, or cached fallback
  BundleSyncService-->>EdgeMcp: Return sync outcome
  EdgeMcp-->>CloudflareCron: Complete or throw for refused or failed outcome
Loading

Possibly related PRs

  • agentfront/frontmcp#1094: Adds the SaaS push receiver and managed Worker test harness used by the bundle-sync flow extended here.
  • agentfront/frontmcp#1100: Adds SaaS caching and scheduler lifecycle operations used by the sync outcomes and Cron behavior in this change.
  • agentfront/frontmcp#1119: Adds forward-only bundle ordering; this change handles refused older bundles in Cron results and readiness.

Suggested reviewers: alexmercerpo

Merge Risk: Minimal · up to 27452

The refresh and readiness changes are mergeable after normal checks; no confirmed issue requires a fix before merging.

Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title clearly and concisely describes the two main changes: failed Cron runs for unapplied bundles and stale-bundle reporting through /readyz.
Description check Passed The description includes the required What and why, User-facing change, and Tests sections. It provides detailed behavior changes, affected documentation, catalog entries, test coverage, and validatio…
Docstring Coverage Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 65.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentati…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description includes the required What and why, User-facing change, and Tests sections. It provides detailed behavior changes, affected documentation, catalog entries, test coverage, and validation results.

Full details: Docstring Coverage

Explanation

Docstring coverage is 87.50% which is sufficient. The required threshold is 65.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 8 functions across 21 files. (4 skipped: 4 unsupported.)

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 28e07f9 and 2745280.

Files selected for processing: 25

  • apps/e2e/demo-e2e-cloudflare/e2e/helpers/managed-worker.ts
  • apps/e2e/demo-e2e-cloudflare/e2e/managed-edge-autoupdate.e2e.spec.ts
  • apps/e2e/demo-e2e-cloudflare/fixture-managed/worker.ts
  • apps/e2e/demo-e2e-skilled-openapi/e2e/saas-source.e2e.spec.ts
  • libs/adapters/src/skills/__tests__/saas-pull.source.spec.ts
  • libs/adapters/src/skills/index.ts
  • libs/adapters/src/skills/sources/index.ts
  • libs/adapters/src/skills/sources/saas-pull.source.ts
  • libs/adapters/src/skills/sources/skill-bundle-source.interface.ts
  • libs/edge/README.md
  • libs/edge/src/__tests__/index-wiring.spec.ts
  • libs/edge/src/index.spec.ts
  • libs/edge/src/index.ts
  • libs/skills/catalog/frontmcp-deployment/references/deploy-to-cloudflare-skills-only.md
  • libs/skills/catalog/frontmcp-production-readiness/references/health-readiness-endpoints.md
  • plugins/plugin-skilled-openapi/README.md
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-load-state.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-sync.service.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-version-order.integration.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/last-good-bundle.integration.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/runtime-deps-injection.spec.ts
  • plugins/plugin-skilled-openapi/src/index.ts
  • plugins/plugin-skilled-openapi/src/skilled-openapi.plugin.ts
  • plugins/plugin-skilled-openapi/src/sync/bundle-load-state.ts
  • plugins/plugin-skilled-openapi/src/sync/bundle-sync.service.ts

Included review availability: This review used your included allowance. Your plan provides up to 5 included reviews per hour; 0 remain after this review.

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Performance Test Results

Status: ✅ All tests passed

Summary

Project Tests Passed Warnings Failed Leaks
✅ demo-e2e-agents 4 4 0 0 0
✅ demo-e2e-cache 11 11 0 0 0
✅ demo-e2e-codecall 4 4 0 0 0
✅ demo-e2e-config 4 4 0 0 0
✅ demo-e2e-direct 3 3 0 0 0
✅ demo-e2e-elicitation 1 1 0 0 0
✅ demo-e2e-errors 4 4 0 0 0
✅ demo-e2e-hooks 3 3 0 0 0
✅ demo-e2e-multiapp 4 4 0 0 0
✅ demo-e2e-notifications 3 3 0 0 0
✅ demo-e2e-openapi 2 2 0 0 0
✅ demo-e2e-providers 4 4 0 0 0
✅ demo-e2e-public 4 4 0 0 0
✅ demo-e2e-redis 15 15 0 0 0
✅ demo-e2e-remember 4 4 0 0 0
✅ demo-e2e-remote 5 5 0 0 0
✅ demo-e2e-serverless 2 2 0 0 0
✅ demo-e2e-skills 15 15 0 0 0
✅ demo-e2e-standalone 2 2 0 0 0
✅ demo-e2e-transport-recreation 3 3 0 0 0
✅ demo-e2e-ui 4 4 0 0 0

Total: 101 tests across 21 projects

📊 View full report in workflow run


Generated at: 2026-11-05T12:07:52.353Z
Commit: 7a44b346

@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

The two refreshes resolve a millisecond apart on a slow runner, so comparing the outcomes whole failed on their 'at'.
@frontegg-david

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional comments: 1

libs/edge/src/index.ts-111-111: 1

111-111: Major · Data Integrity & Integration · Heavy lift

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Do not report success before the bundle is kept.

If the cache write fails, BundleSyncService still returns applied: it records the outcome before calling keepAppliedBundle, then catches the write error. This line therefore lets the Cron run succeed while another isolate can load the older cached bundle. Make cache persistence failure visible in the sync outcome, and handle it here without claiming the in-memory apply was refused. (raw.githubusercontent.com)

Review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 28e07f9 and 2745280.

Files selected for processing: 25

  • apps/e2e/demo-e2e-cloudflare/e2e/helpers/managed-worker.ts
  • apps/e2e/demo-e2e-cloudflare/e2e/managed-edge-autoupdate.e2e.spec.ts
  • apps/e2e/demo-e2e-cloudflare/fixture-managed/worker.ts
  • apps/e2e/demo-e2e-skilled-openapi/e2e/saas-source.e2e.spec.ts
  • libs/adapters/src/skills/__tests__/saas-pull.source.spec.ts
  • libs/adapters/src/skills/index.ts
  • libs/adapters/src/skills/sources/index.ts
  • libs/adapters/src/skills/sources/saas-pull.source.ts
  • libs/adapters/src/skills/sources/skill-bundle-source.interface.ts
  • libs/edge/README.md
  • libs/edge/src/__tests__/index-wiring.spec.ts
  • libs/edge/src/index.spec.ts
  • libs/edge/src/index.ts
  • libs/skills/catalog/frontmcp-deployment/references/deploy-to-cloudflare-skills-only.md
  • libs/skills/catalog/frontmcp-production-readiness/references/health-readiness-endpoints.md
  • plugins/plugin-skilled-openapi/README.md
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-load-state.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-sync.service.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/bundle-version-order.integration.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/last-good-bundle.integration.spec.ts
  • plugins/plugin-skilled-openapi/src/__tests__/runtime-deps-injection.spec.ts
  • plugins/plugin-skilled-openapi/src/index.ts
  • plugins/plugin-skilled-openapi/src/skilled-openapi.plugin.ts
  • plugins/plugin-skilled-openapi/src/sync/bundle-load-state.ts
  • plugins/plugin-skilled-openapi/src/sync/bundle-sync.service.ts

Included review availability: This review used your included allowance. Your plan provides up to 5 included reviews per hour; 0 remain after this review.

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor
Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Cherry-picked with its stack

This PR is part of stack #1121. Its cherry-pick to main is made as one PR for the whole stack when the stack's top PR, #1142, merges.

If #1142 does not merge, run the Cherry-pick to main workflow by hand with stack: 1121.

frontegg-david added a commit that referenced this pull request Nov 5, 2026
* Cherry-pick: fix(adapters,plugins,edge): an older saas bundle, pulled or pushed, doesn't roll the server back

Cherry-picked from #1119 (merged to release/1.11.x)
Original commit: d88f422

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,plugins): an @app's Skilled OpenAPI credential resolver reaches execute_action and this.callTool() of an operation

Cherry-picked from #1120 (merged to release/1.11.x)
Original commit: 00a3b00

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(adapters,plugins,edge): a push token replayed to another replica or Worker isolate is refused

Cherry-picked from #1122 (merged to release/1.11.x)
Original commit: 1341026

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(plugins): a skill a skills:filter hook hides can't be run by naming its actions

Cherry-picked from #1123 (merged to release/1.11.x)
Original commit: a081fbf

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk): a plugin listed twice in one plugins list is refused at startup instead of keeping only its last entry

Cherry-picked from #1127 (merged to release/1.11.x)
Original commit: 3dbadd3

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(plugins,edge): a Cron run that doesn't apply its bundle fails, and /readyz says the bundle served is stale

Cherry-picked from #1128 (merged to release/1.11.x)
Original commit: 4938d21

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk): connect() with an authToken connects an anonymous caller again on a server without auth

Cherry-picked from #1129 (merged to release/1.11.x)
Original commit: 3d238da

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(auth,adapters,plugins,edge): operators can tell why a pull or push token was refused, while callers still get the generic answer

Cherry-picked from #1130 (merged to release/1.11.x)
Original commit: 913f4f5

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,auth,plugins): this.authProviders works: the SDK wires the AuthProviders vault from a new authProvidersVault option

Cherry-picked from #1131 (merged to release/1.11.x)
Original commit: e14c30c

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,auth): /oauth/connect connects a verified caller who has no vault yet, and asks an anonymous one to sign in

Cherry-picked from #1132 (merged to release/1.11.x)
Original commit: f46a87a

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,plugins): the SDK skill surfaces say a plugin's skills haven't loaded yet, retryable, and carry bundleVersion

Cherry-picked from #1133 (merged to release/1.11.x)
Original commit: 0d1dc94

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,auth,cli,plugins): the credentials-required error keeps its connect link out of the message, and asks through URL elicitation where the client supports it

Cherry-picked from #1134 (merged to release/1.11.x)
Original commit: 6d8ea24

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk): a health check registered after startup runs in /readyz, and registerHealthProbe returns a remover

Cherry-picked from #1135 (merged to release/1.11.x)
Original commit: 7f2f48f

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,plugins): a bundle swap sends one list_changed per list it changed, not one per entry

Cherry-picked from #1136 (merged to release/1.11.x)
Original commit: 0296291

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(adapters,plugins,edge): a restarted server serves its cached bundle in place of an older or refused pull, and doesn't write it back

Cherry-picked from #1137 (merged to release/1.11.x)
Original commit: 358d114

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,adapters,plugins,edge): a push token with a body_sha256 claim can't carry another bundle

Cherry-picked from #1138 (merged to release/1.11.x)
Original commit: b870325

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(plugins,edge): managed mode takes confirm, and the audit log says whether the user confirmed a call

Cherry-picked from #1139 (merged to release/1.11.x)
Original commit: 588289f

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(cli): the generated CLI says unknown command, prints an MCP error prefix once, and offers load_skill only the run lines it has

Cherry-picked from #1140 (merged to release/1.11.x)
Original commit: 4cfe9a2

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(plugins): load_skill's outputSchema describes a loaded skill once

Cherry-picked from #1141 (merged to release/1.11.x)
Original commit: 470010e

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

* Cherry-pick: fix(sdk,cli): skills/load's default answer sends formattedContent again, as 1.11.0 did; format: 'markdown' is the opt-in for the smaller one

Cherry-picked from #1142 (merged to release/1.11.x)
Original commit: a680fe7

Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com>

---------

Co-authored-by: agentfront[bot] <agentfront[bot]@users.noreply.github.com>
Co-authored-by: frontegg-david <69419539+frontegg-david@users.noreply.github.com>
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.

2 participants