Skip to content

fix(config): retire WORKSPACE_ENABLED — ent#438 removed the surface it gated - #2836

Merged
vybe merged 1 commit into
devfrom
fix/workspace-enabled-vestigial
Sep 16, 2026
Merged

vybe merged 1 commit into
devfrom
fix/workspace-enabled-vestigial

Conversation

@trinity-ability

Copy link
Copy Markdown
Contributor

Summary

workspace_available was still computed by GET /api/settings/feature-flags, still shipped false in .env.example and all three compose files, and was still described as the Workspace opt-in by settings.py's own docstring, the endpoint catalog, the voice-chat flow's env table and the single-server deploy guide — while nothing in src/ gated on it. ent#438 merged the per-agent workspace page into the Workspace and removed every consumer.

That is worse than a dead key. An operator following the docs sets WORKSPACE_ENABLED=true and changes nothing, or reads the default false and concludes the Workspace ships dark when it does not — and a release note could repeat the claim.

Found by /release-plan as the one forgotten item in the 0.9.5 payload — not a forgotten flip, a forgotten removal.

Removed

Where What
routers/settings.py the workspace_available key + its docstring bullet
services/settings_service.py is_workspace_enabled() (27 lines)
stores/sessions.js the workspaceAvailable field and its two writers
.env.example, docker-compose{,.prod,.hosted}.yml the WORKSPACE_ENABLED declaration
4 docs the live claims (endpoint catalog, voice-chat flow env table, single-server guide, user-docs voice-chat row)

Deliberately kept

Historical references in observability.md, requirements/core-agent.md, feature-flows/agent-canvas.md, router/index.js and AgentHeader.vue. Each narrates the retirement in the past tense — that is how a future reader learns why the knob went away. I read all seven doc hits rather than pattern-deleting; three of them were already correct.

voice_available is also reader-less but is a separate #2559 follow-up and stays. Its sessions.js comment justified itself by the workspace_available derivation, so that sentence is corrected.

config.py / requirements/runtimes.md described VOIP_ENABLED's default as "mirrors the workspace_available opt-in". VoIP is independent (VOIP_ENABLED and gemini_key), so the stale cross-reference is dropped.

Test Plan

  • New tests/unit/test_workspace_flag_retired.py — 7 tests pinning the removal four ways: key absent from the handler payload, resolver gone, no shipped config declares the variable, no live source reads it
  • Written red first — all 7 failed before the change
  • Mutation-verified — re-adding the key as code turns 2 of 7 red; restoring turns them green. The guard is not vacuous
  • The source scan strips comment regions, not line prefixes: the reference that motivated it sits on a continuation line of a multi-line <!-- --> block in AgentHeader.vue
  • The two feat: gate Agent Workspace behind admin feature flag (off by default) #860 tests that asserted the key must be PRESENT (the contract ent#438 invalidated) replaced by one asserting its absence over the wire — so the live-backend tier stays meaningful instead of silently breaking
  • Two dangling is_workspace_enabled stubs dropped from the bug: canary harness left disabled on a retired constraint, and nothing reports whether it is running #2217 / feat: record install provenance (DO Marketplace) + first-run HTTPS/VPN hardening guide #2380 unit tests
  • 155 backend unit tests pass across all touched files
  • ⚠️ Frontend vitest NOT run locally — Docker is not running and this clone forbids falling back to local npm. frontend-build covers it in CI. No frontend test references the removed field (grepped tests/ and e2e/)

Scope note

The enterprise submodule carries two planning-doc mentions (ENTERPRISE_ARCHITECTURE.md, OSS_ENTERPRISE_SPLIT_RESEARCH.md). No enterprise code reads the flag, so they are out of scope here.

Release context

MUST-LAND item 4 of 7 in the 0.9.5 freeze work order.

🤖 Generated with Claude Code

…t gated

`workspace_available` was still computed by GET /api/settings/feature-flags,
still shipped `false` in `.env.example` and all three compose files, and was
still described as *the* Workspace opt-in by `settings.py`'s docstring, the
endpoint catalog, the voice-chat flow's env table and the single-server deploy
guide — while nothing in `src/` gated on it. ent#438 merged the per-agent
workspace page into the Workspace and removed every consumer.

That is worse than a dead key. An operator following the docs sets
WORKSPACE_ENABLED=true and changes nothing, or reads the default `false` and
concludes the Workspace ships dark when it does not — and a release note could
repeat the claim. Found by /release-plan as the one *forgotten* item in the
0.9.5 payload: not a forgotten flip, a forgotten removal.

Removed: the flag key and its docstring bullet (`routers/settings.py`), the
`is_workspace_enabled()` resolver (`settings_service.py`), the store field and
its two writers (`stores/sessions.js`), the declaration in `.env.example` and
the three compose files, and the four LIVE doc claims.

Deliberately kept: the historical references in `observability.md`,
`requirements/core-agent.md`, `feature-flows/agent-canvas.md`,
`router/index.js` and `AgentHeader.vue`. Each narrates the retirement in the
past tense and is how a future reader learns why the knob went away. Also kept:
`voice_available`, which has no reader either but is a separate #2559
follow-up — its `sessions.js` comment justified itself by the
`workspace_available` derivation, so that sentence is corrected here.

`config.py` and `requirements/runtimes.md` described VOIP_ENABLED's default as
"mirrors the workspace_available opt-in"; VoIP is independent
(`VOIP_ENABLED and gemini_key`), so the stale cross-reference is dropped.

Tests: `tests/unit/test_workspace_flag_retired.py` pins the removal four ways —
the key is absent from the handler payload, the resolver is gone, no shipped
config declares the variable, and no live source reads it. The source scan
strips comment REGIONS rather than testing line prefixes, because the reference
that motivated it sits on a continuation line of a multi-line `<!-- -->` block
in `AgentHeader.vue`. Verified by mutation: re-adding the key as code turns two
of the seven red, and restoring turns them green.

The two #860 tests in `tests/test_platform_default_model.py` asserted the key
must be PRESENT — the contract ent#438 invalidated — and are replaced by one
that asserts its absence over the wire. Two now-dangling
`is_workspace_enabled` stubs dropped from the #2217 and #2380 unit tests.

Verification: 155 backend unit tests pass across the touched files. The
frontend vitest suite was NOT run locally (Docker is not running and this clone
forbids falling back to local npm); `frontend-build` covers it in CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@vybe vybe 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.

merge-train: batch validated on train/20260916-0919 (train PR #2839)

@vybe
vybe merged commit a85bb7f into dev Sep 16, 2026
29 checks passed
vybe pushed a commit that referenced this pull request Sep 16, 2026
…ers/settings/

dev changed the deleted monolith twice since the last merge (0bddbc9):

| dev hunk | now lives in |
|---|---|
| #2836 (ent#438) retire `workspace_available` + its docstring bullet | `routers/settings/flags.py` |
| #2702 (#2696) `describe(cap, api_key=...)` + comment | `routers/settings/integrations.py` |

dev's copy of `routers/settings.py` is removed, as in the previous merge.
The #2836 port is load-bearing: dev removed
`settings_service.is_workspace_enabled`, so the unported `flags.py` would
raise AttributeError on GET /api/settings/feature-flags whenever voice is
available.

Checked with an AST pass: all 79 functions in dev's monolith exist in the
package. Only three bodies differ, and those are the split's own
cross-module references (`credentials.mask_api_key`, and
`credentials._ANTHROPIC_KEY_ALIASES` / `_adopt_after_instance_key_removed`).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants