Skip to content

Add workspace affinity - #86

Open
michaelmwu wants to merge 39 commits into
getpaseo:mainfrom
michaelmwu:workspace-affinity-20260829
Open

Add workspace affinity#86
michaelmwu wants to merge 39 commits into
getpaseo:mainfrom
michaelmwu:workspace-affinity-20260829

Conversation

@michaelmwu

@michaelmwu michaelmwu commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Add explicit, custom workspace_affinity.key routing so related trigger arrivals can share checkout/files without sharing an agent session. Hub renders and persists the trusted key and workflow deadline; an optional daemon capability owns atomic workspace reuse, restoration, and expiry.

Usage

In the trigger form, open Workspace affinity under Where it runs and enter a custom key. Empty disables reuse. The equivalent complete single-run trigger is:

name: linear-triage
on:
  linear.comment_created:
    connection: company-linear
    filters:
      from_users: [your-linear-user-id]
run:
  target: { daemon: build-server, cwd: /workspace/project }
  agent: { provider: codex, mode: full-access }
  max_runtime: 2h
  idle_timeout: 10m
  auto_archive: true
  workspace_affinity:
    key: "triage:${{ paseo.trigger.conversation_key }}"
  prompt: |
    Handle this request: ${{ paseo.prompt }}
    Use hub.reply for your response, then call hub.finish_execution.

The full workflow/bundle format uses the same workspace_affinity: { key: ... } object on a step. Both authoring paths use the existing authority validator. Single-step startup migration now preserves the key in the supported single_run representation, with unchanged workflow/step deadlines and archive policy; multistep workflows still retain their lossless legacy lane.

paseo.trigger.conversation_key comes from authenticated provider routing: Slack connection/workspace/channel/root thread; Discord connection/guild/channel/thread or starter message; GitHub connection/repository/issue-or-PR/number; or Linear connection/organization/stable issue UUID. Linear exposes it for linear.issue_entered_scope, linear.issue_assigned, and linear.comment_created. Issue names, comment IDs, delivery IDs, and session IDs are not workspace identity. Unsupported events such as github.push and manual triggers cannot use this expression.

Keys can instead be literals or expressions composed from finite declared inputs, values, and outputs (values/step outputs belong to the full workflow format). Prompt text, ambient context, execution IDs, and unbounded values cannot select an existing workspace. Validation follows transitive named values; rendered keys preserve exact bytes and must be nonblank and 1–512 characters. The editor preserves surrounding whitespace and comments, rejects whitespace-only keys, and removes affinity only when explicitly cleared. A workflow-specific prefix keeps different workflows separate when desired.

Lifecycle and compatibility

  • A capable daemon reuses the active workspace or restores the archived workspace. Each execution gets its own agent; affinity does not serialize executions or resume an earlier agent session.
  • Retention extends to the latest arriving workflow's max_runtime deadline, including gaps after agents finish. Single-run triggers use top-level max_runtime if authored, otherwise run.max_runtime. idle_timeout remains execution liveness, not workspace expiry between arrivals.
  • With auto_archive: true, finished agents archive while the workspace remains retained. At expiry, daemon-owned cleanup archives it when safe; unrelated agents prevent destructive cleanup. With auto_archive: false, affinity introduces no workspace archival.
  • Matching keys require a stable daemon target, cwd, worktree target, and archive policy. Execution-ID-derived worktree branches are rejected.
  • Restoration uses ordinary Paseo recovery: a removed worktree is recreated from its recorded branch, not a snapshot of arbitrary uncommitted files. Commit/export durable results before expiry; affinity is not a backup mechanism.
  • The mapping survives restart; an acknowledged cleanup deadline remains daemon-owned after Hub disconnect/revocation.
  • No mandatory daemon upgrade: older daemons ignore the optional request and keep fresh-workspace behavior. Actual affinity still requires the supporting daemon. This is compatible degradation, not Hub-only reuse.

Why daemon changes are necessary

The existing restricted hub.execute API cannot select an arbitrary existing workspace or restore an archived one. Implementing that from Hub would require broader workspace authority and duplicate daemon-local lifecycle state. The daemon owns worktrees, workspace/agent registration, restoration, persistence, and archive safety. It must bind key-to-workspace atomically and exclude concurrent activation during destructive cleanup.

The companion hashes keys before persistence and optionally acknowledges workspaceAffinityApplied: true. Hub accepts both response shapes. Companion implementation and served public docs: getpaseo/paseo#3994, including public-docs/hub/configuration/hub-yml.md.

Integration and strategy

This update reconciles current main while preserving its provider-catalog baseline. CI independently pins the baseline daemon (c16d4f14a3ec95485f37aa7fb6201b7c239d9d2a) and affinity-capable companion (bb3a46346c7e781bc963ffb2e0fdbd3f5ed3efa3). The new source-built matrix proves legacy fallback and capable retention/reuse/manual-archive restoration/key isolation, with separate agents. Normal browser/Hub integration tests stay on main's baseline. This avoids repeatedly coupling unrelated daemon changes to the unmerged affinity companion.

Design re-review and scoped improvements:

  • Added supported single-run YAML + form authoring and lossless migration, instead of leaving affinity only in the legacy lane.
  • Added trusted Linear issue identity and dynamic-provider forwarding. No daemon implementation changes or daemon SHA repins in this follow-up.
  • Checked Linear Agent Sessions #88 at 24571b978fd4e205813e2696ba63b3cbe9714810: its context already includes connection/organization/issue. Keep workspace identity issue-scoped and Linear session ID as reply/stop identity. Follow up Linear triggers with Agent Sessions, team routing, and replies #88 still needs to enable its implemented session event names and test same-issue/different-session reuse with session-scoped replies/cancellation. This PR does not silently enable unimplemented session events or resume provider agents.
  • The form explains older-daemon fallback, retention across gaps, and concurrent access. See the identity/authority rationale.

Remaining separate work:

  • Persist/expose workspaceAffinityApplied per execution. The optional acknowledgement is accepted on the wire but currently dropped; successful execution alone is not proof of reuse. Preserve an unconfirmed state after missing acknowledgement/reconnect.
  • An affinity key shares files, not a write queue. Provider-session continuation and single-writer serialization must be explicit policies.
  • Independently review the companion's broad archive/activation fencing and resolve its current-main conflicts. Its new docs-only follow-up does not change daemon behavior, and the exact capable implementation pin remains valid.

Validation

September 7 design follow-up, Linux:

npm run typecheck
# Node, Start, and browser E2E typechecks passed
npm run lint
# Both repository lint passes: 0 warnings, 0 errors
npm run format:check
# All matched files use the correct format
npm run build
# Production Node/client/server builds passed
actionlint .github/workflows/ci.yml
# passed
vitest run <configuration, migration, affinity, Linear, store, runtime-owner, compiler, workflow, typography files>
Test Files  13 passed (13)
Tests       218 passed (218)

playwright test e2e/triggers.spec.ts --workers=1
5 passed (1.4m)

The browser journey proves create → save/reload → unrelated edit → YAML → explicit removal without altering key bytes. Desktop and 390px phone-width screenshots are captured at e2e/screenshots/triggers/affinity-{desktop,mobile}.png; fresh CI attaches them as workspace-affinity-editor. This tests browser layouts on Linux, not native mobile apps.

The new complete public-doc YAML example was compiled against this Hub build. Companion follow-up is documentation-only (formatter + example validation); no Paseo runtime code or dependencies changed.

Local browser setup initially lacked the Playwright-pinned Chromium binary; installing that exact headless browser resolved the environment blocker. A new Linear test fixture initially omitted its mandatory project filter; corrected the fixture without changing production validation.

The authoring commit excludes only the known broken staged-file lint wrapper for root browser tests, after both full lint commands passed independently; formatting and full typecheck hooks remain enabled. The Linear follow-up uses normal hooks.

Previous reconciliation: 193 focused contract tests, both exact source-built daemon affinity journeys, and all 11 CI checks passed on 684716d7. Fresh CI validates this follow-up separately. The daemon compatibility implementation and immutable baseline/capable pins are unchanged.

@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: 7c59ca8d2d

ℹ️ 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/workflows/engine.ts
@michaelmwu michaelmwu changed the title Add progressive workspace affinity Add workspace affinity Aug 28, 2026
@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: bcc5e74d1b

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 63cbf688d4

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor 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: 906ef33eeb

ℹ️ 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/workflows/engine.ts Outdated
@michaelmwu

Copy link
Copy Markdown
Contributor 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: 5f02d216c5

ℹ️ 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/triggers/index.ts
Comment thread src/config/compiler.ts
@michaelmwu

Copy link
Copy Markdown
Contributor 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: ce3eedd9ca

ℹ️ 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/workflows/engine.ts Outdated
Comment thread src/triggers/workspace-affinity.ts Outdated
@michaelmwu

Copy link
Copy Markdown
Contributor 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: 09978bb4de

ℹ️ 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/config/compiler.ts
@michaelmwu

Copy link
Copy Markdown
Contributor 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: 0abcc6e028

ℹ️ 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 docs/public-api.md
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: e33abae66b

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 669249102e

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 9414ebc984

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 49e9c11569

ℹ️ 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".

@michaelmwu

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 4af46cd07f

ℹ️ 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".

@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: eef0f54358

ℹ️ 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/config/compiler.ts Outdated

@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: 18678bfb14

ℹ️ 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/config/compiler.ts Outdated
Comment thread docs/public-api.md

@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: d6d8bae57a

ℹ️ 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/config/compiler.ts
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