Skip to content

workspace: tool routing (precedence/engine-probes) ignores the IDE extension's pin, so a pinned session can name one workspace and route to another #1337

Description

@sahrizvi

Problem

#1320 makes the IDE extension's pin (ALTIMATE_PINNED_WORKSPACE_{ID,NAME,ROOT}) outrank the project's stored binding inside resolveBindingOutcome, so skill-sync, memory-sync and (since #1330) the identity section all follow the pinned workspace. Warehouse tool routing does not. precedence.ts currentBinding() (~line 441) and engine-probes.ts resolveBinding() (~line 42) read the on-disk binding cache directly through readLocalBindingScopedStrict and never consult the pin; neither file changed in #1320, and the pin is deliberately never persisted, so routing cannot see it.

Observable in a pinned serve session (found in the v0.12.1 release review by two reviewers independently):

  • Fresh pin, no prior local link (pin → 42): identity says "This project is linked to Altimate Workspace id 42"; derive() sees no binding → unbound → the routing section is silent and every warehouse call goes to the local tools. The pin changes what is remembered and which skills load, not what executes.
  • Returning user, local cache still names workspace 7 (pin → 42): identity names 42, the routing section names 7 ("Altimate workspace "…" (id 7) serves the warehouse tools named below"), or — if the live engine is attributed to 42 — the attribution check fails and routing settles unattributed. Two different datamate ids in one prompt, with nothing telling the model which governs execution.

Routing behaviour is unchanged from v0.12.0 (the pin never affected it), so this is not a regression and nothing executes against a workspace the project was not already linked to — but it defeats the stated purpose of the pin for warehouse queries, and #1330 now makes the contradiction visible to the model every turn. v0.12.1's identity copy states the limitation for pinned sessions ("warehouse tool routing follows the project's own link, not the pin") as a stop-gap.

Expected

currentBinding() in precedence.ts and resolveBinding() in engine-probes.ts honour a valid pin the same way resolveBindingOutcome does (pin outranks the cached binding and auto-adoption; invalid/non-member pin fails closed to unbound routing), so identity, routing, skills and memory agree on one workspace within a turn. The redirect-guard and attribution tests in precedence.test.ts need the pinned case added.

Related: #1335 (workspace name in the system prompt), and the #1320 known gaps (no backfill on pin, no purge-before-fetch in skill-sync).

🤖 Generated with Claude Code

https://claude.ai/code/session_012Q51zFUmPg1WwtS5CrGJE6

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions