Distilled habits that get a PR merged in one review round instead of several:
four root causes + ten rules + show-your-work PR-description contract. Full doc
in docs/GUIDELINES.md, compressed 10-point form in AGENTS.md (agent entry point),
pointer added to CONTRIBUTING.md reading list.
Gate review follow-ups for the #6022 no-leak rule: every non-deliberate
newSession/session-new call site passes worktree:false; only deliberate
New Chat inherits the config default.
- Strict boolean config read: only YAML true enables the default;
quoted strings/ints/lists/dicts/null fall to the safe no-worktree
default instead of truthiness-coercing.
- Presence-based explicit detection: 'worktree' in body — an explicit
worktree:null is an opt-out, never a fall-through to config.
- Guarded remaining auto-mint call sites with explicit worktree:false:
profile switch (panels.js), promptWorkspacePath + switchToWorkspace
blank-page binds (panels.js), promptNewFile + promptNewFolder
(ui.js), terminal auto-session (commands.js).
- Tests: worktree:null vs config-true (factory must not be called),
strict-boolean malformed-shape matrix, static regression gates for
every auto-mint site + a bare-body sweep so future auto-mint paths
can't silently omit the key; updated the cmdTerminal preflight
assertion for the new call shape.
/api/session/new treated an absent 'worktree' key as false, so the
agent's config-level 'worktree: true' default was never consulted for
WebUI sessions even though the WebUI reuses the agent's own worktree
helper. Both callers should agree on same-agent/same-repo isolation.
Three-value model:
- body 'worktree' absent -> agent config default applies (profile-aware
via get_config_for_profile_home, so a user with worktree:true in one
profile but not another gets per-profile behavior)
- explicit true/false -> honored verbatim; explicit always wins
Non-git workspaces: a config-default request degrades to a plain
session and surfaces 'worktree_skipped' in the payload; an explicit
worktree:true keeps the hard 400.
Frontend (same change, load-bearing): newSession() forwards explicit
true/false and omits the key otherwise; the boot-time auto-bind
(_maybeBindFreshDefaultWorkspaceSession) and the onboarding session
send worktree:false explicitly so a config default can never mint a
worktree + branch from merely opening the UI. Deliberate 'New Chat'
sends nothing and inherits the default.
Tests: route matrix (config on/off x body absent/true/false), non-git
fallback vs explicit 400, explicit-false-beats-config-true, config
helper (ambient/named-profile/fail-soft), static UI assertions that
auto-bind and onboarding opt out and New Chat paths don't pin a value.
Fixes#6022
Maintainer revision of #5806: the localization refactor (all profile-concept
help text now goes through t() so it's translatable via the documented
English fallback) is the core value, and the concrete Example row genuinely
clarifies how profiles + workspaces work together. The Binding row restated
the Together row + added scheduled-task edge-case trivia that muddied a concept
explainer, so it's dropped (row + its 2 i18n keys + its test).
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
- workspace 'scopes file access' -> 'keeps chat, terminal, and file browsing
pointed at that project' (terminal/agent tools can access outside the workspace).
- scheduled tasks 'run under the profile that created them' -> 'run under the
profile selected on the task, or the WebUI server default when none selected'.
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>
The Cmd/Ctrl+/ predicate keyed off e.code==='Slash' + !e.shiftKey, which on
QWERTZ layouts (a) stole Ctrl/Cmd+- browser zoom-out (physical Slash there is
the minus/zoom key) and (b) missed the real shifted-'/' chord. Match e.key==='/'
instead — layout-correct on every keyboard. Tests updated to assert the physical
code isn't used and a layout-shifted '/' still matches.
Co-authored-by: nesquena-hermes <agent@nesquena-hermes>