fix(config): retire WORKSPACE_ENABLED — ent#438 removed the surface it gated - #2836
Merged
Merged
Conversation
…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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
workspace_availablewas still computed byGET /api/settings/feature-flags, still shippedfalsein.env.exampleand all three compose files, and was still described as the Workspace opt-in bysettings.py's own docstring, the endpoint catalog, the voice-chat flow's env table and the single-server deploy guide — while nothing insrc/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=trueand changes nothing, or reads the defaultfalseand concludes the Workspace ships dark when it does not — and a release note could repeat the claim.Found by
/release-planas the one forgotten item in the 0.9.5 payload — not a forgotten flip, a forgotten removal.Removed
routers/settings.pyworkspace_availablekey + its docstring bulletservices/settings_service.pyis_workspace_enabled()(27 lines)stores/sessions.jsworkspaceAvailablefield and its two writers.env.example,docker-compose{,.prod,.hosted}.ymlWORKSPACE_ENABLEDdeclarationDeliberately kept
Historical references in
observability.md,requirements/core-agent.md,feature-flows/agent-canvas.md,router/index.jsandAgentHeader.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_availableis also reader-less but is a separate #2559 follow-up and stays. Itssessions.jscomment justified itself by theworkspace_availablederivation, so that sentence is corrected.config.py/requirements/runtimes.mddescribedVOIP_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
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<!-- -->block inAgentHeader.vueis_workspace_enabledstubs 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 testsfrontend-buildcovers it in CI. No frontend test references the removed field (greppedtests/ande2e/)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