Skip to content

fix(harness): verify Assistant workspace aliases [SAP-3292] - #1043

Closed
ynadge wants to merge 1 commit into
packaged-assistant-lifecyclefrom
assistant-history-workspace-aliases
Closed

ynadge wants to merge 1 commit into
packaged-assistant-lifecyclefrom
assistant-history-workspace-aliases

Conversation

@ynadge

@ynadge ynadge commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Primary change type

  • Bug fix

Problem and motivation

A Studio launched through a workspace symlink retained the launch spelling, while Assistant history returned the canonical directory. Literal path comparisons rejected discovery and Resume or separated the same Studio's Terminal and Assistant records.

Summary and scope

Return verified launch/canonical path pairs for history queries and Studio entries, and echo the current pair on Resume. Keep canonical record identity and exact Studio/launch-path checks across inspection, Resume, Continue and mixed history. Empty and overlapping alias refreshes share canonical publication ordering while failures remain scoped to each requested directory.

Revalidate raw paths and their targets after asynchronous work. The existing history authorizer supplies a synchronous final authority assertion; no new context/source owner or runtime activation is introduced. Older responses without a path pair retain exact-cwd compatibility and uncertain operation tuples are unchanged.

Related work

Related issue: https://linear.app/sapiom/issue/SAP-3292

Depends on #1042. Native stack target: main.
Addresses #1040 (comment).

Validation

55 focused unit/server/client tests and all 30 history browser cases passed. The tests cover real directory aliases, different-cwd same-ID rejection, malformed proofs, unchanged retry tuples, empty alias refreshes, overlapping refresh ordering, raw/target changes and 12 held-filesystem authority schedules. Rebinding and final-authority cases were reproduced failing before their corrections.

The actual source-built browser → Studio server → corrected native → real PTY flow passed through a filesystem symlink in 16.23 seconds. History created no work; Continue created one paused child and one seed; only explicit Send called the loopback model. Resume retained the exact Studio/native identity and verified path pair. Explicit Start returned HTTP200 with one PTY and zero extra Assistant attachment/history requests. Final End stopped both child engines while a sibling survived. All five processes were confirmed absent afterward.

Full non-mock workspace build and the final Harness server rebuild passed. Harness/web typechecks and scoped core lint passed; explicit browser lint had zero errors and five existing unused-symbol warnings. This is source-built E2 with loopback fixtures, not signed activated production E3.

Final integrated checks: pnpm --filter @sapiom/harness test passed 4,849 unit tests (two skips) and 10 performance tests. Root pnpm typecheck and pnpm lint passed; root lint reports two existing test warnings. The unrelated unchanged agent-core unreadable-directory fixture still prevents claiming an all-repository test pass in this VM.

Browser evidence

The actual source-built symlink-workspace flow at 210cbdd6 is available as a 15.64-second video. Disposable loopback services supply account/model responses; the browser, Studio routes, native runtime and bash PTY are real.

Before explicit Resume Same Assistant resumed paused
Verified recorded Assistant before Resume Same Assistant paused after Resume

Terminal after explicit Start. These images show user-action states, not a historical implementation baseline. All uploaded files were visually inspected and their served bytes verified against the local SHA-256 manifest.

The final source was repackaged into the unsigned Linux desktop bundle and its smoke test passed 17 cases, with one Windows-only agent-shim skip. This covers the default activation path separately from the corrected-candidate E2 flow above; signed installed production E3 remains an external gate.

Tests and documentation

Added path-pair client validation and actual filesystem/browser regressions. Directory fixtures use junctions and canonicalized temporary roots for platform compatibility. Updated assistant-history.md. Increment: 943 changed lines including tests/docs/changeset. pnpm pr:size is absent in this SDK; measured the incremental Git diff.

Compatibility and release impact

  • Additive verified workspace metadata; canonical persisted identity and operation receipts retain their existing format. No dependency, default activation, native pin or source-store change.
  • Changeset: @sapiom/harness patch.
  • Fix-forward: Preserve exact identity and authority checks while correcting the alias proof or canonical publication fence; unavailable history remains retryable.

Security

  • No secrets, credentials, private data, or unsanitized logs included.
  • No suspected vulnerability disclosed publicly.

AI assistance

  • AI assistance used: Codex implemented and independently reviewed the change with the validation described above.

Checklist

  • CONTRIBUTING.md read; maintainer-authorized issue work.
  • One focused increment, checks, documentation and release impact addressed.
  • I can explain and maintain the submitted changes.

Devin Review

Review disposition

The stale selected-workspace action finding is addressed by #1044. It checks the selected pair before native work and preserves the original operation through an explicit history refresh, with a separate workspace-conflict recovery path.

@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 26dfebdc-b466-4c23-a6f5-b8e6fec25074

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 potential issue.

Devin Review

!session.success ||
session.data.id === entry.harnessSessionId ||
session.data.cwd !== entry.cwd ||
session.data.cwd !== assistantWorkspace(entry).cwd ||

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.

🔴 Stale aliases commit rejected operations

With a stale launch alias, continueAssistantRequest rejects a successful child because the request carries no expected workspace. Resume has the same post-commit rejection. Users see failure after work starts and can leave an unexpected paused session.

Learn more

The browser verifies the returned child against the launch spelling stored in the selected history entry. The Continue request sends only the operation ID and expected lifecycle and record revisions. The server therefore cannot reject a workspace spelling change before continue creates the child. The client discovers the mismatch only after that mutation returns. resumeAssistantRequest has the same ordering after Resume attaches the source session.

Example: History records { cwd: "/alias-a", canonicalCwd: "/project" }. Before the click, the same Studio changes to /alias-b, which still resolves to /project. Continue creates a paused child at /alias-b, but the client compares it with /alias-a and reports verification failure. The child remains even though the UI reports that Continue failed.

Recommended fix: Add the selected workspace pair to the inspected, Resume, and Continue request contracts. Recompute and compare that pair on the server before invoking native.inspect, resume, or continue; keep the existing post-operation checks as final fences.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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