Skip to content

fix(platform): remove the Environment page and unenforced feature flags - #3203

Merged
larryro merged 3 commits into
mainfrom
fix/remove-unbacked-settings-promises
Sep 4, 2026
Merged

fix(platform): remove the Environment page and unenforced feature flags#3203
larryro merged 3 commits into
mainfrom
fix/remove-unbacked-settings-promises

Conversation

@larryro

@larryro larryro commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Why

Two settings surfaces promised behaviour no code delivered. Larry's call: remove the promise, do not build the feature.

A. Settings > Environment (per-user sandbox env/secrets). The page told users their variables are "injected into all of your sandboxes". Zero-consumer proof: resolveUserEnvForInjection had exactly one definition and no call site; the only readers of app.sandbox_user_env were the CRUD module (domains/sandbox/user-env.ts), its three routes (GET/POST/DELETE /api/app/sandbox/user-env), the Settings page, and the itest lane. No sandbox session, agent turn, automation script, or run_code lane referenced the table, the module, or the constants (services/sandbox/src/config.ts#userEnv is an unrelated uid:gid parser). Verdict: removed.

B. Governance feature flags webSearch / codeExecution / fileUpload. Stored in the feature_flags policy file, resolved by evaluateFeatureFlags, echoed by GET /governance/my/feature-flags — and read nowhere else. Server: the only consumer of the resolved flags is getContextCapForUser, which reads maxContextTokens. Client: useMyFeatureFlags has zero callers and no app/ code reads .webSearch / .codeExecution / .fileUpload outside the editor that rendered the toggles. Verdict: the three toggles removed; maxContextTokens (enforced in the chat budget) and inputGuardrailsActive kept.

What changed

Removed (promise A)

  • Route app/routes/dashboard/$id/settings/environment.tsx (+ regenerated routeTree.gen.ts), features/settings/user-env/**, components/env/use-env-editor-controller.ts (only the removed page used it; the shared EnvVarListEditor stays — project secrets use it).
  • Settings rail + mobile menu "Environment" entries; frontend contract rows sandbox/user_env:* and their adapter rows in lib/backend/settings.ts.
  • Backend domains/sandbox/user-env.ts (incl. the never-called resolveUserEnvForInjection), core/sandbox/user_env_constants.ts (+ test), the three /user-env routes.
  • Locale keys in en/de/fr: userEnv.*, metadata.environment.*, navigation.environment, settings.menu.environment.*.
  • Itest lane "sandbox user-env CRUD"; docs-screenshots seed step + DEMO_ENV_VARS; manual test plan rows (F10, B8, route table).

Removed (promise B)

  • The three switches and three table columns in feature-flags-editor.tsx; emptyRule() no longer seeds them; rules are persisted through toPersistedRule, so a rule still carrying the keys from an older policy file loses them on its next save.
  • ResolvedFeatureFlags is now { maxContextTokens?: number }; GET /governance/my/feature-flags no longer echoes the three booleans; the frontend contract dropped them.
  • Locale keys governance.featureFlags.webSearch|codeExecution|fileUpload in en/de/fr; section copy reworded to what the section does (cap the context window).
  • REST v1: not exposed (no user-env / feature-flag fields in backend/rest/** or the spec) — nothing to change.

Deprecated, not dropped

  • app.sandbox_user_env (migration 0050) stays; a comment-only deprecation note was added to the migration header (the runner tracks migrations by filename, no checksum). No migration ships.
  • featureFlagRuleSchema.webSearch|codeExecution|fileUpload stay optional with @deprecated JSDoc so existing feature-flags.yml files keep parsing; a schema test locks that.

Guards added

  • feature_enforcement.test.ts: a rule carrying the deprecated toggles resolves to {} (no property reappears).
  • feature-flags-editor.test.tsx: the rule dialog offers no toggle; a loaded rule with the deprecated keys is saved without them.
  • Itest: the /my/feature-flags wire is parsed .strict() — the retired keys cannot come back unnoticed.

Docs

  • Edited here: docs/{en,de,fr}/platform/member/preferences.md — dropped the hand-off sentence to the Environment page.
  • Owned by draft docs: align ghost-feature pages with the 0.5 product #3199 (docs/align-ghost-feature-pages), NOT touched here — to be appended there:
    • docs/{en,de,fr}/platform/member/environment.md: delete; add "platform/member/environment": "platform/member/preferences" to docs/redirects.json; remove the entry from docs/nav.json (member group); drop the three *:platform/member/environment entries from services/docs/app/content/frontmatter.json (or regenerate it).
    • docs/{en,de,fr}/platform/member/overview.md line 19: drop "and Environment variables & secrets, the keys and variables injected into the sandboxes you run" — the personal group is Account and Personalization (+ Notifications).
    • docs/{en,de,fr}/platform/agents/harnesses.md line 62: delete the sentence "Your own environment variables and secrets are set in the container too, which is how a personal token or endpoint reaches the work without anyone else's session seeing it." (nothing sets them).
    • docs/{en,de,fr}/platform/admin/governance/policies-and-limits.md lines 6 and 22: "feature controls toggle web search, code execution, and file upload by scope" → "feature controls cap the context window per scope"; line 22 → "Feature controls cap the max context tokens for AI replies per user, team, or role. There are no per-feature toggles."
    • services/platform/tests/docs-screenshots/manifest.ts: remove the settings-environment shot (route no longer exists); services/docs/public/images/manifest.json: remove its entry; delete services/docs/public/images/platform/settings-environment.webp (the docs image-manifest test requires every image to be referenced by a page).

Gates (observed)

  • bunx tsc --noEmit: 0 errors.
  • bunx oxlint --type-aware: exit 0, no findings.
  • vitest server (governance, schemas, sandbox + governance domains, agent_secrets, lib/i18n incl. messages parity/usage + e2e-keys): 15 files, 244 tests green.
  • vitest ui project (settings governance + components, project secrets tab, env editor, lib/backend): 43 files, 439 tests green (run through a transient fs-allow wrapper because the worktree's node_modules is a symlink; wrapper deleted).
  • bunx knip: exit 0 (one pre-existing cron-parser config hint, unrelated).
  • bunx oxfmt --check on every touched file: clean.
  • @tale/docs vitest: 30 files, 194 tests green.
  • backend:integration on fresh throwaway tale-db + MinIO: base (origin/main 078ab62) and this branch, each on its own fresh tale-db + MinIO with an identical env. Both runs stop at the same pre-existing [itest] fatal: SyntaxError in checkAutomations (the two-factor lane rotates the shared session and every later lane 401s — the open draft test(platform): make a truncated itest run fail loudly #3198 fixes the harness). Up to that point: base 175 PASS / 7 FAIL, branch 174 PASS / 7 FAIL — the one fewer PASS is exactly the removed sandbox user-env CRUD lane, and the 7 FAIL names are byte-identical on both trees (all downstream of the rotated session). The governance core: policy write/read + guards + flags/budget/models lane, which now parses the flags wire .strict(), PASSes on the branch. To prove the lanes the fatal hides, a verification-only worktree of this branch with test(platform): make a truncated itest run fail loudly #3198's two harness commits cherry-picked on top (applied cleanly; my strict flags parse and the removed lane both intact) ran on another fresh tale-db + MinIO: 390/390 checks passed across 119/119 lanes, exit 0, zero FAIL ([itest] 390/390 checks passed across 119/119 lanes). Nothing from that overlay is committed here.

@larryro
larryro marked this pull request as ready for review September 4, 2026 02:52
Settings > Environment told users their variables and secrets are
"injected into all of your sandboxes". Nothing ever did:
`resolveUserEnvForInjection` had one definition and no caller, and the
only readers of `app.sandbox_user_env` were the page's own CRUD module,
its three `/api/app/sandbox/user-env` routes, and the itest lane. No
sandbox session, agent turn, automation script or run_code lane touched
the rows.

Remove the promise instead of building the feature: the route, feature
folder, rail/menu entries, contract + adapter rows, the backend module,
constants and routes, the locale keys in en/de/fr, the itest lane, the
docs-screenshot seed step and the manual test-plan rows. The shared
EnvVarListEditor stays (project secrets use it). The table stays too —
applied schema is never dropped — with a deprecation note on the
migration header.
… flags

The feature_flags policy stored `webSearch`, `codeExecution` and
`fileUpload` per rule, the editor rendered a toggle and a table column
for each, and `GET /governance/my/feature-flags` echoed them — but no
server or client code ever read them. The only enforced field is
`maxContextTokens` (the chat turn's context cap), and
`inputGuardrailsActive` rides the same wire.

Remove the toggles, the columns, the three locale keys (en/de/fr) and
the three fields from the resolved flags and the frontend contract; word
the section for what it does (cap the context window). The schema keeps
the three keys optional and `@deprecated` so policy files written by
earlier releases keep parsing, and the editor drops them from a rule on
its next save. Guards: the resolver ignores the keys, the dialog offers
no toggle, a legacy rule saves without them, and the itest parses the
flags wire strictly.
The personal Environment page is gone (nothing injected its variables),
so the "Where this fits" paragraph no longer points at it — en, de, fr.
@larryro
larryro force-pushed the fix/remove-unbacked-settings-promises branch from 103f742 to 87a6c3b Compare September 4, 2026 05:46
@larryro
larryro merged commit b643fd1 into main Sep 4, 2026
48 checks passed
@larryro
larryro deleted the fix/remove-unbacked-settings-promises branch September 4, 2026 06:05
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