Skip to content

fix: backport pre-release fixes to v1.0.x - #3586

Merged
EItanya merged 7 commits into
release/v1.0.xfrom
backport/v1.0.x-pre-release-fixes
Nov 9, 2026
Merged

EItanya merged 7 commits into
release/v1.0.xfrom
backport/v1.0.x-pre-release-fixes

Conversation

@EItanya

@EItanya EItanya commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Backports seven PRs from main to release/v1.0.x for the 1.0 release. Each is cherry-picked with -x in its original merge order, and none needed changes. Every file these commits touch now matches main exactly.

PR Commit Why
#3558 2e2acf58c fix(ci): restore upgrade tests from RC3
#3545 7c9c52105 fix(ui): show when the Substrate lists were read, not a running age
#3395 aaf1ca882 feat(session): revert crashed runtimes through RevertSession (needed for a customer)
#3562 5c490d83b refactor: remove helpers orphaned by the KMCP removal (low risk; keeps the branch close to main)
#3563 c6adf72f9 refactor(api): move MCP header resolution out of v1alpha3, so the 1.0 API package describes only data
#3340 347acbe55 fix(controller): move a ModelConfig condition's transition time only on a status change (labeled cherrpick-1.0)
#3560 ccb2dd350 adk/mcp: defer tool discovery until invocation, so slow MCP discovery no longer fails agent resumes

Please use Rebase and merge so each backported PR stays its own commit on the release branch.

Validation before #3560 was added (CI covers the full set):

  • go build ./... and go vet ./...
  • go test -race with envtest for api, core/cli, core/internal/{controller,database,grpcserver,mcp,service,substrate}, core/pkg/migrations, and pkg/logging
  • make -C go lint: 0 issues
  • UI tsc --noEmit and substrateReadAge.test.tsx

🤖 Generated with Claude Code

EItanya and others added 6 commits November 9, 2026 13:20
Upgrade tests on `main` now select `v1.0.0-rc3`, which already installs
Atelet as a separate Helm release. The regular upgrade test was blocked
by a missing optional migration table, then by missing Harness fixtures
when it tried to invoke the previous release.

Check for the optional tracking table in a separate statement:
PostgreSQL resolves table references before evaluating `CASE`. Keep
readiness polling for the required core migration table.

Before each invocation phase, apply the four Harness fixtures used by
`TestSessionInteraction` from the matching source checkout. Resolve
their images from the installed controller's runtime catalog so the
previous release, current build, and application rollback each exercise
their own runtime images. Reuse the existing lifecycle manifest without
creating its unrelated smoke Agents or opaque BYO fixture.

Validated with PostgreSQL query checks, fixture rendering tests for
released and locally built images, upgrade-package configuration tests,
and Go lint. Both required upgrade checks passed on `9bd2ab0fe`,
including invocation before and after the upgrade, schema comparison,
application rollback, and schema rollback.

<details>
<summary>Runtime fixtures across upgrade and rollback</summary>

```mermaid
flowchart LR
    source["Matching release or PR checkout"] -->|Lifecycle manifest| fixtures["Invocation Harness fixtures"]
    controller["Installed controller configuration"] -->|Runtime image digests| fixtures
    fixtures -->|Apply| cluster["Upgrade test cluster"]
    cluster -->|Invoke all four Harnesses| test["TestSessionInteraction"]
```

</details>

---------

Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
(cherry picked from commit 2e2acf5)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
…3545)

---
*Written by 🤖 (start)*

The Substrate page's actor and worker lists now show `Read at 4:41:02
PM` instead of `read 12.3s ago`, which re-rendered twice a second and
pulled the eye off the rows. While polling, a list that goes 3 intervals
(at least 5s) without a new read adds its age in the warning colour,
e.g. `Read at 4:41:02 PM, 12s ago`.

# Testing

1. Open Substrate. Each list shows `Read at <time>`, which changes only
when the list refreshes.
2. Turn polling on, then make the API hang. After about 5s, each list
reads `Read at <time>, <n>s ago` in amber.

---
*Written by 🤖 (end)*

---------

Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
(cherry picked from commit 7c9c521)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
## Summary

When Substrate reports a Session's Actor `CRASHED`, a caller can revert
it to its last durable snapshot through `SessionService.RevertSession`.
Recovery runs only when a client asks: an admitted recovery is a durable
`RUNTIME_OPERATION_REVERT` operation, and a retried `RevertSession`
joins it, the same way Create and Delete retries work.

### How a revert works

1. **Observe.** `observeCrash` reads the Session's generation (lifecycle
operation ID, recorded Actor UID, Actor template) in one statement, then
reads the Actor from Substrate. A missing, replaced, or retemplated
Actor is unrecoverable, never a crash.
2. **Admit.** `BeginCrashedSessionRecovery` runs one transaction under
the Session lock. It:
- checks the Actor UID and generation, and that no checkpoint is being
created;
- fails the interrupted turn with a timeline-positioned crash note,
keeping waits the snapshot captured. Publishing saved results and
retiring idle-work markers reuse the helpers Session deletion uses;
   - starts a REVERT operation.
3. **Execute.** The shared `execute` path reverts the Actor in place.
Substrate restores the last completed durable snapshot. Every suspend of
a kagent Actor is synchronous, so that is the snapshot admission settled
against. `applyRevert` requires the same Actor back, SUSPENDED. If
preparation fails, the REVERT is kept for a retry.

### API

- `RevertSession` validates `session_id` as a UUID and needs
`AccessUpdate`, so a read-only share cannot invoke it.
- A runtime that is not crashed returns the Session unchanged. That is
also what a retry sees after a revert whose response was lost.
- A missing or replaced Actor returns `FAILED_PRECONDITION`. Contention
returns `ABORTED`, and transient failures return `UNAVAILABLE`.
- Delete supersedes a recovery even after a revert was issued. A revert
restores the recorded Actor in place and creates nothing that Delete
could miss.

### Schema

`000002_session_revert_operation.sql` adds `RUNTIME_OPERATION_REVERT` to
the `runtime_instance` operation CHECK.

## Testing

- `make -C go lint`, `make proto-generate`
- `go test` for `service/session`, `substrate`, `grpcserver` (revert),
and `pkg/migrations` (up/down round trip)
- PostgreSQL store tests, including `TestInlineSQLPrepares`
- E2E: `go/core/test/e2e/session_revert_test.go`

Stack: this PR → #3399 (GetSession recovery report and chat).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Ada Lundhe <adalundhe@lundhe.audio>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit aaf1ca8)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
# Description

Removing the KMCP integration and the `kagent mcp` scaffolder in #3223
left the shared CLI helpers it used without callers. This removes the
Docker executor, project generator, filesystem, Kubernetes config, and
input prompt helpers, trims the kubectl executor to what `kagent
bug-report` still uses, and drops the `logging.FromLogr` adapter whose
only caller was the MCPServer catalog check.

No behavior change. The remaining `deadcode` findings are public STS
helpers and the `WithGRPCTransportCredentials` client option, which are
intentionally kept as consumer-facing extension points.

Signed-off-by: timflannagan <timflannagan@gmail.com>
(cherry picked from commit 5c490d8)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
# Description

`go/api/v1alpha3` is the public API that external clients and wrapper
types import, but it pulled in controller-runtime and `database/sql` for
a few helpers that do I/O. This moves those helpers out so the API
package only describes data.

`RemoteMCPServerSpec` loses its `sql.Scanner`/`driver.Valuer` methods,
which nothing used. `RemoteMCPServer.ResolveHeaders`,
`ValueRef.Resolve`, and `ValueSource.Resolve` move into the tool
service's MCP client, their only caller, and `go/api/utils` is removed.
The translator keeps its existing `HeadersFrom` handling, which compiles
Secret-backed headers into egress credentials rather than reading them.

Header resolution behaves the same, except errors are now wrapped and
name the failing header. Go consumers that called the removed methods
need to read the referenced Secret or ConfigMap themselves.

Signed-off-by: timflannagan <timflannagan@gmail.com>
(cherry picked from commit c6adf72)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
…on a status change (#3340)

## Problem
The ModelConfig status writer moves a condition's `lastTransitionTime`
whenever its reason, message or observedGeneration changes. Agent
conditions, and SandboxTemplate through `apimeta.SetStatusCondition`,
move it only when the status changes, as the API conventions define it.
A ModelConfig that stays `False` therefore reports a new transition time
every time its error text or generation changes.

## Change
Agent and ModelConfig share one helper that keeps the transition time
while a condition's status holds. A new test covers a changed reason,
message and generation under an unchanged status, and a status change.

This PR previously wrote Harness `Ready`/`Booted` conditions; #3454
removed `Harness.status`, so it is reduced to the transition-time rule
that part shared with Agent and ModelConfig.

Signed-off-by: QuentinBisson <quentin@giantswarm.io>
(cherry picked from commit 347acbe)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
@EItanya
EItanya requested a review from a team as a code owner November 9, 2026 13:30
@github-actions github-actions Bot added the bug Something isn't working label Nov 9, 2026
@EItanya
EItanya enabled auto-merge November 9, 2026 14:17
# Description

Slow MCP discovery can exceed router timeouts and fail agent resumes,
holding worker reservations and capacity while startup waits. Separate
classification also duplicates MCP connections and paginated listings.

This fixes it by:

- Deferring HTTP, SSE, and stdio MCP connections until invocation
preparation.
- Classifying and filtering ADK's own discovery responses before the SDK
caches
  them, preserving server TTLs and catalog notification handling.
- Omitting failed toolsets for the execution regardless of prior
discovery success,
keeping healthy tools available and retrying on later executions without
exposing
  unclassified tools.
- Serializing discovery and classification publication per toolset, with
cancellation
  support for queued invocations.
- Preserving MCP App result compaction through a single callback,
alongside rich
stored results, credentials, approvals, and tracing. Tools reclassified
as ordinary
keep their real output; removed app names remain available for
historical compaction.
- Documenting discovery, SDK caching, pagination guards, and failure
handling in
  `docs/architecture/mcp.md`.

# Change Type

```
/kind fix
```

# Testing

- Added unit coverage for zero startup requests, one paginated
discovery,
filtered SDK cache hits, TTL expiry, catalog notifications, partial
failures,
execution-scoped retries after initial and later failures, cancellation,
concurrent
  discovery, reclassification, and stdio startup.
- Added app-result coverage for cached tools, approvals, and historical
results
  after catalog removal, preserving the original rich payloads.
- Added E2E coverage for slow MCP discovery across repeated resumes and
initial
discovery failure and recovery; extended app-history E2E coverage to
verify SDK
  caching across model steps and rediscovery after restore.

# Changelog

```release-note
MCP discovery no longer delays startup or resume and caches filtered tools safely.
```

---------

Signed-off-by: Shashank Ram <shashank.ram@solo.io>
(cherry picked from commit ccb2dd3)
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
@EItanya
EItanya disabled auto-merge November 9, 2026 14:18
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Nov 9, 2026
@EItanya
EItanya enabled auto-merge November 9, 2026 14:34
@blacksmith-sh

This comment has been minimized.

@EItanya
EItanya added this pull request to the merge queue Nov 9, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 9, 2026
@EItanya
EItanya added this pull request to the merge queue Nov 9, 2026
Merged via the queue into release/v1.0.x with commit a08cde7 Nov 9, 2026
56 of 57 checks passed
@EItanya
EItanya deleted the backport/v1.0.x-pre-release-fixes branch November 9, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

⌂ 换网址