Studio: repin the permission-mode contract to behaviour, not a declaration by danielhanchen · Pull Request #8986 · unslothai/unsloth · GitHub
Skip to content

Studio: repin the permission-mode contract to behaviour, not a declaration - #8986

Merged
danielhanchen merged 3 commits into
mainfrom
fix-permission-mode-contract
Aug 16, 2026
Merged

Studio: repin the permission-mode contract to behaviour, not a declaration#8986
danielhanchen merged 3 commits into
mainfrom
fix-permission-mode-contract

Conversation

@danielhanchen

Copy link
Copy Markdown
Member

Repo tests (CPU) is red on main with a single failure:

FAILED tests/studio/test_deep_research_frontend_contract.py::test_research_presentation_is_integrated
  AssertionError: assert 'const permissionMode = loadPermissionMode();' in '...'

Cause

#8686 (5bb0bc6f7) hoisted the two per-call const permissionMode = loadPermissionMode(); reads in chat-runtime-store.ts up to a single module-level constant:

const INITIAL_PERMISSION_MODE: PermissionMode = loadPermissionMode();
...
permissionMode: INITIAL_PERMISSION_MODE,

The store still reads the persisted level out of storage, and still refuses to restore "full" across sessions, so nothing the assertion was written to protect changed. #8686 is correct; the test was pinned to the spelling of a declaration rather than to the behaviour, so a pure refactor turned it red.

Fix

Assert the contract:

  1. some const <name> = loadPermissionMode(); exists, so the level comes out of storage
  2. the store's initial permissionMode binds to that constant (or calls loadPermissionMode() inline), so it is never a hardcoded level

This is strictly stronger than what it replaces. Both are mutation checked against the real file:

mutation old assertion new assertion
const INITIAL_PERMISSION_MODE = "ask"; (drops the storage read) caught caught
permissionMode: "ask", in the initial state missed caught

Verification

tests/studio locally on a CPU-only shape: 3877 passed, 6 skipped. The 8 errors in test_chat_thread_title_cas.py are a missing structlog in my local venv, not related; CI installs it and that file is green on main.

danielhanchen and others added 2 commits August 16, 2026 11:19
…ation

#8686 hoisted the per-call `const permissionMode = loadPermissionMode();` in
chat-runtime-store.ts up to a module-level INITIAL_PERMISSION_MODE. The store
still reads the persisted level and still refuses to restore "full", so the
behaviour is unchanged, but test_research_presentation_is_integrated pinned the
old declaration's exact text and went red on main.

Assert the contract instead: the level is read through loadPermissionMode(),
and the store's initial permissionMode binds to that read rather than a
hardcoded level. That also covers a case the literal never did.
Re-checked what #8686 actually did. It did not hoist the per-call read: it put
a chat-scoped override in front of it,

    const permissionMode =
      threadScopedOverride("permissionMode") ?? loadPermissionMode();

at both call sites, so the read is still per call. The module-level
INITIAL_PERMISSION_MODE it also added is a separate thing, used only for the
store's initial state.

That matters here. The assertion this file lost sat in the deep-research block
and guarded setDeepResearchEnabled re-resolving the level. My first
replacement asserted the initial state instead, which is a different property:
it would still pass if the setter stopped re-reading and used the cached
constant.

Scope the assertion to setDeepResearchEnabled and pin the read that is
actually the contract. Mutation checked against the real file:

    permissionMode = INITIAL_PERMISSION_MODE      caught (missed before)
    threadScopedOverride(...) ?? "ask"            caught
@danielhanchen

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

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