Skip to content

staging → main: auto-promote 7cb8b47 - #2384

Merged
github-actions[bot] merged 2 commits into
mainfrom
staging
Apr 30, 2026
Merged

github-actions[bot] merged 2 commits into
mainfrom
staging

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated promotion of staging (7cb8b476) to main. All required staging gates green at this SHA: CI, E2E Staging Canvas, E2E API Smoke, CodeQL.

This PR is auto-generated by .github/workflows/auto-promote-staging.yml whenever every required gate completes green on the same staging SHA. It exists because main's branch protection requires status checks "set by the expected GitHub apps" — direct git push from a workflow can't satisfy that, only PR merges through the queue can.

Merge queue lands this; no human action needed unless gates fail. Reverse-direction sync (the merge commit on main → staging) is handled by auto-sync-main-to-staging.yml.

Hongming Wang and others added 2 commits April 30, 2026 06:39
Paired molecule-core change for the molecule-cli `molecule connect`
RFC (Molecule-AI/molecule-cli#10).

After this PR an `external`-runtime workspace's full lifecycle
matches the operator-driven model: it boots in awaiting_agent, the
CLI connects in poll mode without operator-side flag tuning, the
heartbeat-loss path lands back on awaiting_agent (re-registrable)
instead of the terminal-feeling 'offline'.

Two changes in workspace-server:

1) `resolveDeliveryMode` (registry.go) now reads `runtime` alongside
   `delivery_mode`. Resolution order:
     a. payload.delivery_mode if non-empty (operator override)
     b. row's existing delivery_mode if non-empty (preserves prior
        registration)
     c. **NEW:** "poll" if row.runtime = "external" — external
        operators run on laptops without public HTTPS; push-mode
        would hard-fail at validateAgentURL anyway. (`molecule connect`
        registers without --mode and expects this default.)
     d. "push" otherwise (historical default for platform-managed
        runtimes — langgraph, hermes, claude-code, etc.)

2) Heartbeat-loss for external workspaces lands them in
   `awaiting_agent` instead of `offline`. Two code paths:
   - `liveness.go` — Redis TTL expiration. Uses a CASE expression
     so the conditional is one UPDATE (no extra round-trip for
     non-external runtimes, no TOCTOU between runtime read and
     status write).
   - `healthsweep.go::sweepStaleRemoteWorkspaces` — DB-side
     last_heartbeat_at age scan. This sweep is already external-
     only by query filter, so the UPDATE just hard-codes the new
     status.

   The Docker-side `sweepOnlineWorkspaces` keeps `offline` —
   recovery there is "restart the container", not "re-register from
   the operator's box".

Why awaiting_agent over offline for external:
- Matches the status the workspace was created in (workspace.go:333).
- The CLI re-registers on every invocation; awaiting_agent → online
  is the natural transition. offline is a terminal-feeling status
  that implies operator intervention is needed.
- An operator who closed their laptop overnight should see
  awaiting_agent in canvas, not 'offline (something is wrong)'.

Test plan:
- Existing: 9 `resolveDeliveryMode` test sites updated to the new
  query shape. Sqlmock now reads `delivery_mode, runtime` columns.
- New: TestRegister_ExternalRuntime_DefaultsToPoll asserts the
  external→poll branch. TestRegister_NonExternalRuntime_StillDefaultsToPush
  guards against the new branch overshooting (langgraph keeps push).
- Liveness: regex updated to match the CASE expression.
- Healthsweep: `TestSweepStaleRemoteWorkspaces_MarksStaleAwaitingAgent`
  (renamed for grep-ability), Docker-side sweepOnlineWorkspaces test
  unchanged (verified to still match `'offline'`).
- Full handlers + registry suite green under -race (12.873s + 2.264s).

No migration needed — `status` is a free-form text column; both
'offline' and 'awaiting_agent' are existing values used elsewhere
(workspace.go uses awaiting_agent on initial external creation).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-and-awaiting

feat(external): default external runtime to poll-mode + awaiting_agent

@HongmingWang-Rabbit HongmingWang-Rabbit 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.

Auto-promote PR carrying the changes from #2382 (default external runtime to poll-mode + awaiting_agent) from staging to main. The underlying diff (196+/30- across registry.go, healthsweep.go, liveness.go + tests) was already five-axis-reviewed and endorsed on #2382 — see that PR's review comment for the analysis.

Net-new since staging review: nothing (identical commit). All 33 required checks green. MERGEABLE. No .github/workflows/* changes.

Holding the merge for a human eye since this is substantive logic landing on main, not a mechanical patch bump.

@github-actions
github-actions Bot merged commit 59dec57 into main Apr 30, 2026
50 of 52 checks passed
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…lifecycle (#2384 CR1)\n\nThe delegate_task_async implementation now writes:\n- queued (sync, on initial row insert)\n- delivered (async, on 2xx proxy response)\n- failed (async, on marshal error or non-2xx/transport error)\n\nUpdate the three affected async tests to expect the new contract:\n- TestMCPHandler_DelegateTaskAsync_RoutesThroughPlatformA2AProxy\n- TestMCPHandler_DelegateTaskAsync_WithAttachments\n- TestMCPHandler_DelegateTaskAsync_MarshalFailureDoesNotCallProxy\n\nFixes race between async goroutine and mock expectations by explicitly\nexpecting the async UPDATE calls before waitGlobalAsyncForTest.
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
Serialized merge by gitea-merge-queue after current-main, genuine approvals, and required CI checks were green.
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.

1 participant