Skip to content

🤖 fix: unarchive ensured workspaces#3583

Merged
ThomasK33 merged 3 commits into
mainfrom
fix/workspace-ensure-unarchive
Jun 17, 2026
Merged

🤖 fix: unarchive ensured workspaces#3583
ThomasK33 merged 3 commits into
mainfrom
fix/workspace-ensure-unarchive

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Summary

Adds a built-in workspace.unarchive workflow host action and updates workspace.ensure so matching archived work-item workspaces are reactivated before being returned to workflow callers.

Background

Workflow callers expect workspace.ensure to provide a usable workspace for a requested work item. Previously, an archived workspace tagged with the requested workItemKey blocked creation but was returned as archived, leaving downstream message sends to deal with a non-active workspace.

Implementation

  • Added idempotent workspace.unarchive with the same host-action/reconcile pattern as workspace.archive.
  • Updated workspace.ensure to return explicit action values: created, reused, or unarchived.
  • Kept compatibility-friendly booleans in ensure output: created, archived, and unarchived.
  • Shared archive/unarchive transition boilerplate after running the simplify workflow.

Validation

  • bun test src/node/services/workflows/workspaceHostActions.test.ts
  • MUX_ESLINT_CONCURRENCY=1 make static-check
  • simplify workflow run: wfr_fcb698f4fe1679b2

Risks

Low. The change is limited to workflow host actions and targeted tests. The main behavior change is intentional: workspace.ensure now guarantees an active workspace by unarchiving an archived matching workspace rather than returning it archived.


Generated with mux • Model: openai:gpt-5.5 • Thinking: xhigh • Cost: $9.10

Add a workflow host action for workspace.unarchive and make workspace.ensure reactivate archived work-item matches before returning them to workflow callers.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$9.10`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=9.10 -->
Extract the shared idempotent archive/unarchive lookup and state-transition skeleton while preserving action outputs.
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9fd4462f59

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/workflows/workspaceHostActions.ts Outdated
Restore the existing workspace.ensure action description so completed external workflow steps keep the same host-action stub hash across upgrade/resume.

---

_Generated with `mux` • Model: `openai:gpt-5.5` • Thinking: `xhigh` • Cost: `$9.10`_

<!-- mux-attribution: model=openai:gpt-5.5 thinking=xhigh costs=9.10 -->
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review
Please take another look. I restored the existing workspace.ensure metadata description to preserve the host-action stub hash/replay identity while keeping the new unarchive behavior in the implementation and tests.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 21768ae270

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ThomasK33 ThomasK33 added this pull request to the merge queue Jun 17, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 17, 2026
@ThomasK33 ThomasK33 added this pull request to the merge queue Jun 17, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 17, 2026
@ThomasK33 ThomasK33 added this pull request to the merge queue Jun 17, 2026
Merged via the queue into main with commit 4772b82 Jun 17, 2026
40 of 42 checks passed
@ThomasK33 ThomasK33 deleted the fix/workspace-ensure-unarchive branch June 17, 2026 15:22
@mux-bot mux-bot Bot mentioned this pull request Jun 17, 2026
LeonidasZhak pushed a commit to LeonidasZhak/mux that referenced this pull request Jun 20, 2026
## Summary

Long-lived auto-cleanup PR maintained by the **Auto-Cleanup Agent**.
Each pass lands at most one extremely low-risk, behavior-preserving
cleanup drawn from recently merged `main` activity, then advances the
checkpoint below.

## This pass

Replaced an inline terminal-status check in
`WorkflowService.interruptRunOnAbort`
(`src/node/services/workflows/WorkflowService.ts`) with the
`isTerminalWorkflowRunStatus` helper introduced by coder#3587 ("show
workflow-only sidebar activity"). The guard

```ts
if (
  run == null ||
  run.status === "completed" ||
  run.status === "failed" ||
  run.status === "interrupted"
) {
  return;
}
```

now reads `if (run == null || isTerminalWorkflowRunStatus(run.status))`.

- **Behavior-preserving:** `isTerminalWorkflowRunStatus(status)` is
defined as `status === "completed" || status === "failed" || status ===
"interrupted"` — byte-for-byte the same three-status disjunction (same
short-circuit order, same boolean result), so the `run == null || ...`
early-return is unchanged.
- **Why it helps:** `isTerminalWorkflowRunStatus` is already the
canonical terminal-status predicate everywhere else (`taskService.ts`,
`tools/task_await.ts`); this was the only remaining hand-inlined copy in
`WorkflowService`, so the dedup keeps the terminal-status set defined in
exactly one place.
- **Scoped:** one file, one guard; the helper was already exported from
`@/common/types/workflow` and is now added to the existing import in
`WorkflowService.ts` (next to the already-imported
`isActiveWorkflowRunStatus`).

## Validation

- `bun test src/node/services/workflows/WorkflowService.test.ts` — 58
pass / 0 fail.
- `make static-check` — eslint, tsc (both configs), Prettier, and the
generated workflow-runtime bundle drift check all pass. The only failing
step is `fmt-shell-check`, which requires `shfmt` (not installed in this
environment); no shell scripts were touched, so CI (which has `shfmt`)
is unaffected.

<details>
<summary>Prior passes</summary>

- Deduplicated the identical `workspaceId`-only metadata JSON Schema
that three id-targeted host actions repeat in
`src/node/services/workflows/workspaceHostActions.ts` into a
module-level `WORKSPACE_ID_ONLY_INPUT_SCHEMA` constant (the third copy
was introduced by coder#3583 when it added `workspace.unarchive`).
Behavior-preserving: nothing mutates the metadata, and the shared
constant has identical key order/values so the generated stub bundle is
byte-identical (drift check passing).
- Extracted a shared `BlockedBadge` component in
`src/browser/features/Tools/WorkflowDefinitionToolCall.tsx` to
deduplicate the `<WorkflowBadge tone="danger">blocked</WorkflowBadge>`
markup that coder#3578 introduced verbatim in three spots. Also resolved a
trivial rebase conflict from coder#3582 in
`src/node/services/workflows/workflowArgs.ts`.
- Deduplicated the repeated `"Workflow metadata.argsSchema.properties
must be an object"` error string in
`src/node/services/workflows/workflowArgs.ts` (added in coder#3575) into a
module-level `ARGS_SCHEMA_PROPERTIES_ERROR_MESSAGE` constant.
- Deduplicated the four mocked-module specifier strings in
`src/browser/hooks/useModelsFromSettings.test.ts` into shared local
constants so `installUseModelsModuleMocks()` /
`restoreUseModelsModuleMocks()` can't drift (after coder#3574).
- Removed a redundant `toggleWorkflowExpanded` wrapper in
`src/browser/features/Tools/WorkflowRunToolCall.tsx`, left behind by
coder#3571.
- Deduplicated two repeated fallback error strings in
`src/browser/components/AutomationModal/AutomationModal.tsx` (after
coder#3560) into `SAVE_AUTOMATION_ERROR_MESSAGE` /
`REMOVE_AUTOMATION_ERROR_MESSAGE` module-level constants.
- Replaced a duplicated `"wfr_"` literal in
`src/node/services/workflows/WorkflowRunner.ts` with the canonical
`isWorkflowRunTaskId()` predicate from
`src/node/services/tools/taskId.ts` (after coder#3565).
- Removed a duplicated `"chat.jsonl"` literal in
`src/node/services/analytics/etl.ts` by re-exporting `CHAT_FILE_NAME`
from the canonical `src/common/constants/paths.ts` (after coder#3541).
- Extracted a `harvestRecordTime` helper in
`src/node/services/memoryConsolidationService.ts` so
`findNewestHarvestRecord` and `pruneHarvestRecords` derive the
`completedAt ?? startedAt` ordering key from one place (after coder#3558).

</details>

Auto-cleanup checkpoint: a7f047b

---

_Generated with `mux` • Model: `anthropic:claude-opus-4-8` • Thinking:
`xhigh` • Cost: `n/a`_

<!-- mux-attribution: model=anthropic:claude-opus-4-8 thinking=xhigh
costs=n/a -->

---------

Co-authored-by: mux-bot[bot] <264182336+mux-bot[bot]@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.

1 participant