Skip to content

Cloud: recover completed repository attachments - #30887

Merged
teamleaderleo merged 5 commits into
feat-cmux-nextfrom
lane/cloud-repo-completed-jobs
Nov 1, 2026
Merged

teamleaderleo merged 5 commits into
feat-cmux-nextfrom
lane/cloud-repo-completed-jobs

Conversation

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Leo asked for “this kind of recovery” when attaching a repository to a Cloud chat.

A completed clone now persists its result until the chat attachment is recorded. Retrying after a record failure reuses that saved result even when the seed job has expired, and attachment recording clears the job atomically.

Follow-up 4 to #30361; replaces closed #30452 at its restored and reviewed head. A regression test injects record failure, shuts down the fake seed socket, and verifies retry records the completed clone without another start or status call. Attachment recording clears the saved job in the same projection transaction.

Repository discovery also retains pages already fetched if authentication expires on a later page. An unsafe installation link is omitted without hiding the repositories; disconnected state is tracked separately so it cannot falsely complete the Connect GitHub wait. Fake socket tests check that partial catalog and the actual pending clone progress before completion, addressing the recovery review follow-ups.

Validation: the full stack at 7dca439 passed the Rust cloud_repo suite on the fleet (step 9e6433bb9eb7ac166da6d706). Formatting and static diff checks pass.

Agent session: agent session

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review (claude-opus-5-5-medium): SHIP at 75d7f2a

This restores the completed-jobs change from closed #30452.

Review (subagent claude-opus-5-5 medium): SHIP at 75d7f2a

#30452 completed-jobs, rebase review. Old: 6bf7cb2..4c982df (3 commits). New: 54c63f9..75d7f2a (4 commits). I compared the added/removed lines of both whole diffs.

Differences, classified:

  • Commit 2 (keep fetched repos during reconnect and test live progress) is patch-identical.
  • (a) Commit 1: the completed-result check completed["repo"] != repo || completed["folder"] != json!(folder) || completed["state"] != "done" || !completed["head"].as_str()... is now in get() form. It is equivalent for missing keys and non-string values: Null != "x" matches None != Some("x"), and Null != json!(folder) matches None != Some(&json!(folder)). The progress write's inversion (== "running" && throttled) is kept, in get() form. existing["job"] and recent.insert(... repo["repo"] ...) were converted the same way.
  • (a) Commit 3: self.optional_install_url(&answer["connect"]) became optional_install_url(connect) inside base's if let Some(connect). catalog.disconnected = true is kept.
  • (a) New commit 75d7f2a: store::record's job retirement. The old code nested three ifs: name from repo, then doc["jobs"][session][name]["repo"] == repo["repo"], then get_mut and remove. The new code is one let-chain with jobs.get(name).and_then(|j| j.get("repo")) == repo.get("repo"). That is equivalent: a missing job or a job without a repo was Null == "owner/x" (false) and is now None == Some (false). It removes only on a matching repo, still inside the same CAS write.
  • No (b) or (c) items.

Base not reverted: no stack file overlaps the newer base commits, and the stack-file diff against the current base equals the three-dot diff.

Follow-ups: none new. I did not run a compile.

@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 5 files

You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="cmux-tui/crates/cmux-tui-core/src/cloud_repos/store.rs">

<violation number="1" location="cmux-tui/crates/cmux-tui-core/src/cloud_repos/store.rs:257">
P3: This retires any job for the repo, including a `running` one. Limit the removal to completed jobs so a forwarded `remember` cannot delete an in-flight clone's progress.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

.get_mut("jobs")
.and_then(|jobs| jobs.get_mut(session))
.and_then(Value::as_object_mut)
&& jobs.get(name).and_then(|job| job.get("repo")) == repo.get("repo")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: This retires any job for the repo, including a running one. Limit the removal to completed jobs so a forwarded remember cannot delete an in-flight clone's progress.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At cmux-tui/crates/cmux-tui-core/src/cloud_repos/store.rs, line 257:

<comment>This retires any job for the repo, including a `running` one. Limit the removal to completed jobs so a forwarded `remember` cannot delete an in-flight clone's progress.</comment>

<file context>
@@ -246,6 +246,18 @@ pub(super) fn record(mux: &Mux, session: &str, repo: &Value) -> Result<(), Failu
+                .get_mut("jobs")
+                .and_then(|jobs| jobs.get_mut(session))
+                .and_then(Value::as_object_mut)
+            && jobs.get(name).and_then(|job| job.get("repo")) == repo.get("repo")
+        {
+            jobs.remove(name);
</file context>
Suggested change
&& jobs.get(name).and_then(|job| job.get("repo")) == repo.get("repo")
&& jobs.get(name).is_some_and(|job| job.get("state").and_then(Value::as_str) == Some("done") && job.get("repo") == repo.get("repo"))

@teamleaderleo
teamleaderleo force-pushed the lane/cloud-repo-session-binding branch from 54c63f9 to 964ceb9 Compare November 1, 2026 12:32

@teamleaderleo teamleaderleo left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review (claude-opus-5-5-medium): SHIP at c24d19f

Review (claude-opus-5-5 medium): SHIP at c24d19f (#30887)
Carried from 75d7f2a (r-rebase-30452.md). The one-commit delta in cloud_repos/runtime.rs rewrites !x.is_some_and(|h| !h.is_empty()) as x.is_none_or(|h| h.is_empty()). That is the same boolean (None or empty, so the result is refused), changed only to satisfy clippy nonminimal_bool.

Base automatically changed from lane/cloud-repo-session-binding to feat-cmux-next November 1, 2026 12:34
@teamleaderleo
teamleaderleo force-pushed the lane/cloud-repo-completed-jobs branch from c24d19f to 0d3088a Compare November 1, 2026 12:34
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 0d3088a: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30887 -f ref=lane/cloud-repo-completed-jobs -f platform=macos -f backend_mode=local

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium, carried): SHIP at 0d3088a

Carried from the SHIP at c24d19f. The restack onto 71f7bae (#30434's squash) leaves the PR's own diff unchanged: git diff 71f7bae5..0d3088a1 and git diff 54c63f99..c24d19fb have the same patch-id --stable (45591b4e), and all five commits range-diff =.

@teamleaderleo
teamleaderleo merged commit 91dbc64 into feat-cmux-next Nov 1, 2026
73 of 83 checks passed
@teamleaderleo
teamleaderleo deleted the lane/cloud-repo-completed-jobs branch November 1, 2026 12:35
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant