feat: enable GrowthBook local gate defaults for P0/P1 features#153
Conversation
Add LOCAL_GATE_DEFAULTS mapping in growthbook.ts with 27 feature gate defaults (25 boolean + 2 object config). Insert local defaults into the fallback chain of all getter functions so they work regardless of whether GrowthBook is enabled or disabled: env overrides → config overrides → in-memory cache → disk cache → LOCAL_GATE_DEFAULTS → caller defaultValue P0 (local): keybindings, streaming tool exec, cron, JSON tools, ultrathink, explore/plan agents, deep link, immediate model switch P1 (API): session memory, auto memory, prompt suggestions, brief mode, verification agent, away summary, auto dream, idle return prompt Kill switches: 10 gates kept true to prevent remote disable New compile flags: AGENT_TRIGGERS, ULTRATHINK, BUILTIN_EXPLORE_PLAN_AGENTS, LODESTONE, EXTRACT_MEMORIES, VERIFICATION_AGENT, KAIROS_BRIEF, AWAY_SUMMARY Bypass all local defaults: CLAUDE_CODE_DISABLE_LOCAL_GATES=1
📝 WalkthroughWalkthroughThe PR implements GrowthBook local gate defaults and enables P0/P1 features by extending the feature flag set across build and dev configurations, establishing a fallback chain for gate evaluation (env/config → GrowthBook → cache → LOCAL_GATE_DEFAULTS → defaultValue), and providing verification tooling and documentation for the enablement strategy. Changes
Sequence DiagramsequenceDiagram
participant App as Application
participant Env as Environment/<br/>Config
participant GB as GrowthBook
participant Cache as In-Memory/<br/>Disk Cache
participant Defaults as LOCAL_GATE_<br/>DEFAULTS
participant Fallback as defaultValue<br/>(Caller-provided)
App->>Env: Check env/config overrides
alt env/config override exists
Env-->>App: Return override value
else proceed to GrowthBook
App->>GB: Fetch gate value
alt GrowthBook enabled & responds
GB-->>App: Return GB value
else GrowthBook disabled/fails
App->>Cache: Check cached value
alt cache hit
Cache-->>App: Return cached value
else cache miss
App->>Defaults: Check LOCAL_GATE_DEFAULTS
alt local default exists
Defaults-->>App: Return local default
else use caller default
Fallback-->>App: Return defaultValue
end
end
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
DEV-LOG.md (1)
20-23: Add language specifier to fenced code block.The code block showing the fallback chain is missing a language identifier, which helps with syntax highlighting and accessibility.
📝 Suggested fix
-``` +```text env overrides → config overrides → [GrowthBook 启用?] → 内存缓存 → 磁盘缓存 → LOCAL_GATE_DEFAULTS → defaultValue</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@DEV-LOG.mdaround lines 20 - 23, Update the fenced code block that contains
the fallback chain "env overrides → config overrides → [GrowthBook 启用?] → 内存缓存 →
磁盘缓存 → LOCAL_GATE_DEFAULTS → defaultValue" to include a language specifier
(e.g., use ```text) so the block has proper syntax highlighting and
accessibility; locate the triple-backtick block in the DEV-LOG.md and change the
opening fence to include the language identifier.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In@scripts/verify-gates.ts:
- Around line 30-66: The gates array in verify-gates.ts is missing checks for
two object-type local gates from LOCAL_GATE_DEFAULTS: add entries for gate
'tengu_kairos_brief_config' (expected value { enable_slash_command: true }) and
'tengu_onyx_plover' (expected value { enabled: true }) so the verification
covers object-typed gates; update the gates constant (the GateCheck[] array)
with these two new objects referencing the existing naming pattern and include
appropriate category (e.g., 'P1' for tengu_kairos_brief_config and 'P1' or 'KS'
for tengu_onyx_plover) and any compileFlag if applicable.
Nitpick comments:
In@DEV-LOG.md:
- Around line 20-23: Update the fenced code block that contains the fallback
chain "env overrides → config overrides → [GrowthBook 启用?] → 内存缓存 → 磁盘缓存 →
LOCAL_GATE_DEFAULTS → defaultValue" to include a language specifier (e.g., usethe triple-backtick block in the DEV-LOG.md and change the opening fence to include the language identifier.🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID:
b94c63a4-3079-4da7-85ff-5a2b0f293ae2📒 Files selected for processing (7)
DEV-LOG.mdbuild.tsdocs/features/feature-flags-audit-complete.mddocs/features/growthbook-enablement-plan.mdscripts/dev.tsscripts/verify-gates.tssrc/services/analytics/growthbook.ts
| const gates: GateCheck[] = [ | ||
| // P0: Pure local | ||
| { name: 'Custom keybindings', gate: 'tengu_keybinding_customization_release', expected: true, category: 'P0' }, | ||
| { name: 'Streaming tool exec', gate: 'tengu_streaming_tool_execution2', expected: true, category: 'P0' }, | ||
| { name: 'Cron tasks', gate: 'tengu_kairos_cron', expected: true, category: 'P0' }, | ||
| { name: 'JSON tools format', gate: 'tengu_amber_json_tools', expected: true, category: 'P0' }, | ||
| { name: 'Immediate model cmd', gate: 'tengu_immediate_model_command', expected: true, category: 'P0' }, | ||
| { name: 'MCP delta', gate: 'tengu_basalt_3kr', expected: true, category: 'P0' }, | ||
| { name: 'Leaf pruning', gate: 'tengu_pebble_leaf_prune', expected: true, category: 'P0' }, | ||
| { name: 'Message smooshing', gate: 'tengu_chair_sermon', expected: true, category: 'P0' }, | ||
| { name: 'Deep link', gate: 'tengu_lodestone_enabled', expected: true, category: 'P0', compileFlag: 'LODESTONE' }, | ||
| { name: 'Auto background', gate: 'tengu_auto_background_agents', expected: true, category: 'P0' }, | ||
| { name: 'Fine-grained tools', gate: 'tengu_fgts', expected: true, category: 'P0' }, | ||
|
|
||
| // P1: API-dependent | ||
| { name: 'Session memory', gate: 'tengu_session_memory', expected: true, category: 'P1' }, | ||
| { name: 'Auto memory extract', gate: 'tengu_passport_quail', expected: true, category: 'P1', compileFlag: 'EXTRACT_MEMORIES' }, | ||
| { name: 'Memory skip index', gate: 'tengu_moth_copse', expected: true, category: 'P1' }, | ||
| { name: 'Memory search section', gate: 'tengu_coral_fern', expected: true, category: 'P1' }, | ||
| { name: 'Prompt suggestions', gate: 'tengu_chomp_inflection', expected: true, category: 'P1' }, | ||
| { name: 'Verification agent', gate: 'tengu_hive_evidence', expected: true, category: 'P1', compileFlag: 'VERIFICATION_AGENT' }, | ||
| { name: 'Brief mode', gate: 'tengu_kairos_brief', expected: true, category: 'P1', compileFlag: 'KAIROS_BRIEF' }, | ||
| { name: 'Away summary', gate: 'tengu_sedge_lantern', expected: true, category: 'P1', compileFlag: 'AWAY_SUMMARY' }, | ||
| { name: 'Idle return prompt', gate: 'tengu_willow_mode', expected: 'dialog', category: 'P1' }, | ||
|
|
||
| // Kill switches | ||
| { name: 'Ultrathink', gate: 'tengu_turtle_carbon', expected: true, category: 'KS', compileFlag: 'ULTRATHINK' }, | ||
| { name: 'Explore/Plan agents', gate: 'tengu_amber_stoat', expected: true, category: 'KS', compileFlag: 'BUILTIN_EXPLORE_PLAN_AGENTS' }, | ||
| { name: 'Agent teams', gate: 'tengu_amber_flint', expected: true, category: 'KS' }, | ||
| { name: 'Slim subagent CLAUDE.md', gate: 'tengu_slim_subagent_claudemd', expected: true, category: 'KS' }, | ||
| { name: 'Bash security', gate: 'tengu_birch_trellis', expected: true, category: 'KS' }, | ||
| { name: 'macOS clipboard', gate: 'tengu_collage_kaleidoscope', expected: true, category: 'KS' }, | ||
| { name: 'Compact cache prefix', gate: 'tengu_compact_cache_prefix', expected: true, category: 'KS' }, | ||
| { name: 'Durable cron', gate: 'tengu_kairos_cron_durable', expected: true, category: 'KS' }, | ||
| { name: 'Attribution header', gate: 'tengu_attribution_header', expected: true, category: 'KS' }, | ||
| { name: 'Agent progress', gate: 'tengu_slate_prism', expected: true, category: 'KS' }, | ||
| ] |
There was a problem hiding this comment.
Missing verification for object-type gates.
The LOCAL_GATE_DEFAULTS in growthbook.ts (lines 456-458) includes two object-type gates that are not covered by this verification script:
tengu_kairos_brief_config: { enable_slash_command: true }tengu_onyx_plover: { enabled: true }
These gates should be added to ensure complete coverage.
🔧 Suggested additions to the gates array
{ name: 'Brief mode', gate: 'tengu_kairos_brief', expected: true, category: 'P1', compileFlag: 'KAIROS_BRIEF' },
+ { name: 'Brief config', gate: 'tengu_kairos_brief_config', expected: { enable_slash_command: true }, category: 'P1' },
{ name: 'Away summary', gate: 'tengu_sedge_lantern', expected: true, category: 'P1', compileFlag: 'AWAY_SUMMARY' },
+ { name: 'Auto dream', gate: 'tengu_onyx_plover', expected: { enabled: true }, category: 'P1' },
{ name: 'Idle return prompt', gate: 'tengu_willow_mode', expected: 'dialog', category: 'P1' },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/verify-gates.ts` around lines 30 - 66, The gates array in
verify-gates.ts is missing checks for two object-type local gates from
LOCAL_GATE_DEFAULTS: add entries for gate 'tengu_kairos_brief_config' (expected
value { enable_slash_command: true }) and 'tengu_onyx_plover' (expected value {
enabled: true }) so the verification covers object-typed gates; update the gates
constant (the GateCheck[] array) with these two new objects referencing the
existing naming pattern and include appropriate category (e.g., 'P1' for
tengu_kairos_brief_config and 'P1' or 'KS' for tengu_onyx_plover) and any
compileFlag if applicable.

Summary
LOCAL_GATE_DEFAULTSmapping (27 gates) ingrowthbook.tsto enable features when GrowthBook remote server is unavailableULTRATHINK,BUILTIN_EXPLORE_PLAN_AGENTS,LODESTONE,AGENT_TRIGGERS,EXTRACT_MEMORIES,VERIFICATION_AGENT,KAIROS_BRIEF,AWAY_SUMMARYscripts/verify-gates.tsfor programmatic gate verification (30/30 PASS)Features Enabled
P0 — Pure local: keybindings, streaming tool exec, cron, JSON tools (~4.5% savings), ultrathink, explore/plan agents, deep link, immediate model switch, MCP delta, leaf pruning, message smooshing, auto-background agents
P1 — API-dependent: session memory, auto memory extraction, prompt suggestions, brief mode, verification agent, away summary, auto dream, idle return prompt
Kill switches (10): kept true to prevent remote disable
Fallback Chain Fix
Safety
CLAUDE_CODE_DISABLE_LOCAL_GATES=1Test plan
bun run build— 481 filesbun test— 2106 pass / 23 fail (pre-existing) / 0 new failuresNODE_ENV=test bun run scripts/verify-gates.ts— 30/30 PASS/briefmanual test — visible and functional after fallback fix/effort maxmanual test — working🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation