Source of truth for Claude-Throne architecture invariants and CI-enforced rules.
interface ProviderMap {
reasoning: string; // Primary reasoning model
completion: string; // Canonical completion model (primary storage key)
value: string; // Value-focused model
}
// Comment 5: 'coding' is DEPRECATED - read-only fallback for backward compatibility
// NEVER write 'coding' key to storage - always use 'completion'
// Migration: On save, delete any legacy 'coding' keys from provider maps- Before Apply: Always hydrate legacy globals (
reasoningModel,completionModel,valueModel) from the active provider's map - Never Apply Stale Globals: If globals don't match current provider, hydrate first
- Atomic Operations: Apply operation must include both legacy globals and provider-specific selections
- Cache Key: Always cache models by
payload.provider - Token Generation: Every
requestModelsmessage must include incremented sequence token - Token Validation: Responses with mismatched tokens must be ignored
- Render Condition: Only render when
payload.provider === state.providerANDresponseToken === state.currentRequestToken - Late Response Protection: Late responses must not re-render or overwrite state
- Per-Provider Caching (Comment 7): Cache is keyed by provider; only clear stale provider's cache on switch
- No Duplicates: Never bind duplicate event listeners
- Cleanup Required: Always remove listeners when component unmounts or provider changes
- Throttle Input: Filter input must be throttled/debounced to prevent excessive re-renders
- postConfig Contract: Must include legacy keys +
modelSelectionsByProvider - saveModels Contract: Must include
providerIdfield - Key Normalization: Storage keys must use 'completion' (never 'coding')
- Strict Isolation:
ProviderContextinstances must remain strictly isolated per request tier. The proxy must not leak headers or credentials between mixed providers. - Graceful Degradation: If
MIXED_PROVIDERS_CONFIGis not set or disabled, routing must gracefully fall back to the genericeffectiveProviderlogic. - Smart Validation: Before routing starts, all unique providers defined in the mixed config must have securely validated keys in VS Code
SecretStorage.
Schema Files (Comment 15: Corrected paths):
extensions/thronekeeper/src/schemas/messages.ts- All webview ↔ extension message schemasextensions/thronekeeper/src/schemas/config.ts- Configuration and provider map schemas
Current Schema Version: 1.0.0 (established 2025-10-28, updated 2025-10-29)
Schema Versioning Policy:
- Patch (1.0.X): Add optional fields, fix validation bugs, documentation updates
- Minor (1.X.0): Add new message types, deprecate (but don't remove) fields
- Major (X.0.0): Remove deprecated fields, change required fields, breaking changes
Backward Compatibility Rules:
- Never remove fields without major version bump
- Mark deprecated fields with
@deprecatedJSDoc and.optional()in schema - Add deprecation warnings in DEBUG mode when legacy fields are used
- Maintain read fallbacks for deprecated keys (e.g.,
completion || coding) - All new required fields must have reasonable defaults
// Location: extensions/thronekeeper/src/schemas/messages.ts
interface WebviewMessage {
type: 'modelsLoaded' | 'providerChanged' | 'configSaved' | 'error';
payload: {
provider?: string;
models?: ModelInfo[];
token?: string; // Sequence token for request validation
error?: string;
// Additional fields per message type
};
}
interface ExtensionMessage {
type: 'loadModels' | 'saveConfig' | 'startProxy' | 'stopProxy';
payload: {
provider?: string;
modelSelections?: ProviderMap;
token?: string;
// Additional fields per message type
};
}// Location: extensions/thronekeeper/src/schemas/config.ts
interface ConfigurationPayload {
provider: string;
modelSelectionsByProvider: Record<string, ProviderMap>;
reasoningModel: string; // Legacy global
completionModel: string; // Legacy global
valueModel: string; // Legacy global
}Fail Closed Policy: Any message or payload that doesn't conform to schemas must be rejected and logged as error. Tests must fail for invalid contracts.
Validation Modes:
- Strict Mode: Throws ZodError on validation failure (use in tests)
- Safe Mode: Returns null and logs error on validation failure (use in production with DEBUG flag)
- Feature Flag:
featureFlags.enableSchemaValidationcan disable validation if critical issues arise
- Provider Switch Isolation: Switching providers clears previous state and loads correct models
- Tokened Model Loading:
handleModelsLoadedvalidates sequence tokens and ignores late responses - Key Normalization: Storage operations always use 'completion' key, never 'coding'
- Fallback Hydration: Triggers
saveModelsexactly once when legacy globals are missing - Single Listener Checks: Verify no duplicate event listeners are bound
- Start/Stop Hydration: First start after provider switch uses active provider's models
- Settings.json Reflection: Applied configuration reflects active provider in settings.json
- Provider Restoration: Switching providers and back restores correct model selections
- Configuration Persistence: Model selections persist correctly across extension restarts
- Message Validation: All webview ↔ extension messages conform to schemas
- Payload Validation: Configuration payloads include all required fields
- Provider Map Keys: Provider maps always contain canonical keys (reasoning, completion, value)
area:model-selection- Changes to model selection UI or logicarea:provider- Changes to provider detection or switchingarea:proxy- Changes to proxy server configuration or startuparea:webview- Changes to React webview componentsarea:config- Changes to configuration persistence or loading
- Guarded Areas: PRs touching
webview/main.js,PanelViewProvider.ts, orAnthropicApply.tsmust run matching tests - Test Coverage: New functionality must include corresponding unit/integration tests
- Schema Validation: All message/config contracts must pass schema validation
- Invariant Preservation: No change may break documented invariants
Guarded Files:
extensions/thronekeeper/webview/main.jsextensions/thronekeeper/src/PanelViewProvider.tsextensions/thronekeeper/src/AnthropicApply.ts
Required Actions:
- Read and understand relevant invariants in Constitution.md
- Add or update tests for changed functionality
- Update schemas if contracts change
- Apply appropriate area labels to PR
- Manual smoke test of provider switching and model selection
- Verify no duplicate event listeners
- Validate configuration persistence
- Any change to message/config payloads requires schema version bump
- Update corresponding Zod/TypeScript interfaces
- Add contract tests for new fields
- Document backward compatibility if applicable
# Via VS Code Settings
"claudeThrone.proxy.debug": true
# Via Environment Variable
DEBUG=1 npm start
# Via Extension Launch Configuration
Add "--debug" to extension development launch args# Reset extension settings
code --reset-extension-settings claude-throne
# Clear cached configuration
rm -rf ~/.vscode/extensions/thronekeeper-*/user-data/
# Restart VS Code to ensure clean state- Extension Developer Console logs (Help → Toggle Developer Tools)
- Proxy server logs (when DEBUG=1)
- VS Code workspace settings (.vscode/settings.json)
- Claude Code settings (.claude/settings.json)
All architectural decisions, schema changes, or invariant modifications must:
- Be recorded in core memory with reference to PR/Bead ID
- Include rationale and impact assessment
- Link to affected test files and documentation
- Note any backward compatibility considerations
- Maintain CHANGELOG.md with architectural decisions
- Tag invariant changes with
[INVARIANT]prefix - Cross-reference schema versions with release notes
- Document any migration requirements
Enforcement: These rules are enforced by CI checks. Any violation will block merge until resolved. When in doubt, ask for clarification before making changes to guarded areas.