Skip to content

feat(harness): connect assistant lifecycle server actions [SAP-3292] - #1026

Closed
ynadge wants to merge 1 commit into
assistant-continue-controlsfrom
assistant-server-wiring
Closed

ynadge wants to merge 1 commit into
assistant-continue-controlsfrom
assistant-server-wiring

Conversation

@ynadge

@ynadge ynadge commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Primary change type

  • Feature

Problem and motivation

The assembled Studio server did not yet connect the implemented lifecycle actions to one context owner. Accepted-context recovery and continuation provenance must use the same authorized stores as ordinary Send.

Summary and scope

Wire history, Resume and Continue into startServer with one shared delivery instance. Hide unfinished continuation children across restart, publish only prepared children, and revalidate attachment leases after provenance reads. Default legacy delivery stays available; Continue requires the existing owner's explicit verified activation capability.

Related work

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

Depends on #1025. Native stack target: main.

Validation

pnpm --filter @sapiom/harness exec vitest run src/server/opencode.test.ts src/core/assistant-history.test.ts src/server/assistant-lifecycle.test.ts — 39 tests passed.

pnpm --filter @sapiom/harness exec tsc --noEmit and scoped server ESLint — passed. Full assembled-server coverage follows in the next test-only increment; the combined Harness suite passed 4,780 unit tests and 10 performance tests (2 skipped).

Tests and documentation

Adds attachment provenance and End-during-receipt-read regressions. Updated assistant-history.md. Increment: 159 changed lines including tests/docs/changeset; SDK pr:size is absent.

Compatibility and release impact

  • Existing verified context owner controls activation; this does not publish or pin a native runtime. Ordinary legacy delivery remains the default.
  • Changeset: @sapiom/harness patch.
  • Fix-forward: correct the shared server wiring in a focused follow-up while leaving owner activation unavailable until its own gates pass.

Security

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

AI assistance

  • AI assistance used: Codex implemented and 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.

@coderabbitai

coderabbitai Bot commented Sep 14, 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: 1db3b461-4f8e-489c-a035-4d4be9631211

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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 3 potential issues.

Devin Review

});
const authorizeAssistantHistory = assistantHistoryAccess({ access: assistantAccess, authorize: authorizeAssistantWorkspace, store: assistantSessions });
const assistantHistory = new AssistantHistory({ sessions: sessionManager, authorize: authorizeAssistantHistory, records: assistantRecords, lifecycle: assistantLifecycle });
const assistantHistory = new AssistantHistory({ sessions: sessionManager, authorize: authorizeAssistantHistory, records: assistantRecords, lifecycle: assistantLifecycle, isVisible: (id) => assistantContinuations.canAttach(id) });

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.

🟡 Pending continuation children remain visible

After Continue allocates an unfinished child, isVisible hides it only from Assistant history. Generic session projections still expose the exited child, allowing Studio to start its dormant Terminal.

Learn more

Continuation allocation persists an exited, dormant HarnessSession before native preparation completes. This filter removes that row only from AssistantHistory; it does not affect the session arrays returned by the boot state and session-list endpoints. The history menu treats an exited session absent from Assistant history as an ordinary Terminal row in pastRows. Its normal Start Terminal action reaches activateDormant without checking continuation preparation. A crash or failed Continue therefore exposes a child that must remain private until its receipt reaches prepared.

Example: Continue allocates child child-1, then native seeding fails. After reload, /api/state includes child-1 with status: "exited", while Assistant history filters it out. Studio renders an ordinary past session and can start its dormant Terminal, instead of hiding the child until retry completes preparation.

Recommended fix: Apply one continuation-visibility projection to every public session source, including /api/state, /api/sessions, and relevant history/session actions. Reject terminal/start and other direct child operations while assistantContinuations.canAttach(id) is false. Preserve internal SessionManager visibility so the continuation coordinator can recover the allocation.

Devin Review

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

Comment on lines +311 to +312
/** Explicit verified capability supplied by the existing context runtime owner. */
assistantContextRuntime?: ActivatedAssistantContextRuntime;

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.

🔍 No shipping host activates Continue

Neither the CLI nor Electron supplies assistantContextRuntime, so Continue returns context_unavailable. Verify that the stack intentionally defers host activation.

Devin Review

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

Comment on lines 3673 to +3689
res.setHeader("Cache-Control", "no-store");
res.json(assistantAccess.getBrowserState());
});
const authorizeAssistantHistory = assistantHistoryAccess({ access: assistantAccess, authorize: authorizeAssistantWorkspace, store: assistantSessions });
const assistantHistory = new AssistantHistory({ sessions: sessionManager, authorize: authorizeAssistantHistory, records: assistantRecords, lifecycle: assistantLifecycle });
const assistantHistory = new AssistantHistory({ sessions: sessionManager, authorize: authorizeAssistantHistory, records: assistantRecords, lifecycle: assistantLifecycle, isVisible: (id) => assistantContinuations.canAttach(id) });
app.use("/api", createAssistantLifecycleRouter({
bootToken: options.bootToken,
history: assistantHistory,
native: assistantNativeHistory,
getSession: (id) => sessionManager.get(id),
resume: (id, revision, operationId) => assistantNativeHistory.resume(id, revision, operationId),
continue: async (id, request) => {
const prepared = await assistantContinue.continue(id, request);
// Publish only the verified child. Pending receipt allocation is private.
bus.publish({ type: "session.status", session: prepared.session });
return prepared;
},
}));

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.

🔍 Server wiring lacks integration coverage

Tests exercise the router, not the new startServer composition. Add assembled-server coverage for Continue publication, restart visibility, Resume, and inactive activation.

(Refers to this code)

Devin Review

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

@ynadge ynadge closed this Sep 15, 2026
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