fix: remove internal Anthropic tooling from external build (#345)
Remove debug systems, employee detection, and internal logging that have no function in a community fork. Changes: - Remove logPermissionContextForAnts import and calls (main.tsx, compact.ts) Reads Kubernetes namespace and container IDs from internal infra paths. Dead code for all external users. - Remove createDumpPromptsFetch import and gate (query.ts) Internal prompt dump system for employee debugging. Replace gate with unconditional undefined — normal fetch always used. - Remove stripSignatureBlocks ant-only block (query.ts) Was behind USER_TYPE === 'ant' guard, never ran for external users. - Hardcode isAnt: false (query/config.ts) Employee detection flag has no place in a community fork. config.gates.isAnt had exactly one consumer (dumpPromptsFetch, now removed). - Gut logClassifierResultForAnts body (bashPermissions.ts) Replace with empty no-op. Still called from 4 sites, zero execution. Remove ANT-ONLY comments describing internal security model. - Gate status.anthropic.com behind firstParty check (errors.ts) 429 error hint now only shown when using Anthropic directly. Third-party provider users see a generic capacity message. Build: passes Typecheck: clean (no new errors) Tests: 196 pass, same 6 pre-existing failures unrelated to these changes
This commit is contained in:
@@ -142,7 +142,6 @@ import { validateUuid } from './utils/uuid.js';
|
||||
import { registerMcpAddCommand } from 'src/commands/mcp/addCommand.js';
|
||||
import { registerMcpDoctorCommand } from 'src/commands/mcp/doctorCommand.js';
|
||||
import { registerMcpXaaIdpCommand } from 'src/commands/mcp/xaaIdpCommand.js';
|
||||
import { logPermissionContextForAnts } from 'src/services/internalLogging.js';
|
||||
import { fetchClaudeAIMcpConfigsIfEligible } from 'src/services/mcp/claudeai.js';
|
||||
import { clearServerCache } from 'src/services/mcp/client.js';
|
||||
import { areMcpConfigsAllowedWithEnterpriseMcpConfig, dedupClaudeAiMcpServers, doesEnterpriseMcpConfigExist, filterMcpServersByPolicy, getClaudeCodeMcpConfigs, getMcpServerSignature, parseMcpConfig, parseMcpConfigFromFilePath } from 'src/services/mcp/config.js';
|
||||
@@ -2511,7 +2510,6 @@ async function run(): Promise<CommanderCommand> {
|
||||
|
||||
// Log context metrics once at initialization
|
||||
void logContextMetrics(regularMcpConfigs, toolPermissionContext);
|
||||
void logPermissionContextForAnts(null, 'initialization');
|
||||
logManagedSettings();
|
||||
|
||||
// Register PID file for concurrent-session detection (~/.claude/sessions/)
|
||||
|
||||
13
src/query.ts
13
src/query.ts
@@ -52,7 +52,6 @@ import {
|
||||
getMessagesAfterCompactBoundary,
|
||||
createToolUseSummaryMessage,
|
||||
createMicrocompactBoundaryMessage,
|
||||
stripSignatureBlocks,
|
||||
} from './utils/messages.js'
|
||||
import { generateToolUseSummary } from './services/toolUseSummary/toolUseSummaryGenerator.js'
|
||||
import { prependUserContext, appendSystemContext } from './utils/api.js'
|
||||
@@ -92,7 +91,6 @@ import { SLEEP_TOOL_NAME } from './tools/SleepTool/prompt.js'
|
||||
import { executePostSamplingHooks } from './utils/hooks/postSamplingHooks.js'
|
||||
import { executeStopFailureHooks } from './utils/hooks.js'
|
||||
import type { QuerySource } from './constants/querySource.js'
|
||||
import { createDumpPromptsFetch } from './services/api/dumpPrompts.js'
|
||||
import { StreamingToolExecutor } from './services/tools/StreamingToolExecutor.js'
|
||||
import { queryCheckpoint } from './utils/queryProfiler.js'
|
||||
import { runTools } from './services/tools/toolOrchestration.js'
|
||||
@@ -587,13 +585,7 @@ async function* queryLoop(
|
||||
|
||||
// Create fetch wrapper once per query session to avoid memory retention.
|
||||
// Each call to createDumpPromptsFetch creates a closure that captures the request body.
|
||||
// Creating it once means only the latest request body is retained (~700KB),
|
||||
// instead of all request bodies from the session (~500MB for long sessions).
|
||||
// Note: agentId is effectively constant during a query() call - it only changes
|
||||
// between queries (e.g., /clear command or session resume).
|
||||
const dumpPromptsFetch = config.gates.isAnt
|
||||
? createDumpPromptsFetch(toolUseContext.agentId ?? config.sessionId)
|
||||
: undefined
|
||||
const dumpPromptsFetch = undefined
|
||||
|
||||
// Block if we've hit the hard blocking limit (only applies when auto-compact is OFF)
|
||||
// This reserves space so users can still run /compact manually
|
||||
@@ -931,9 +923,6 @@ async function* queryLoop(
|
||||
// Thinking signatures are model-bound: replaying a protected-thinking
|
||||
// block (e.g. capybara) to an unprotected fallback (e.g. opus) 400s.
|
||||
// Strip before retry so the fallback model gets clean history.
|
||||
if (process.env.USER_TYPE === 'ant') {
|
||||
messagesForQuery = stripSignatureBlocks(messagesForQuery)
|
||||
}
|
||||
|
||||
// Log the fallback event
|
||||
logEvent('tengu_model_fallback_triggered', {
|
||||
|
||||
@@ -36,7 +36,7 @@ export function buildQueryConfig(): QueryConfig {
|
||||
emitToolUseSummaries: isEnvTruthy(
|
||||
process.env.CLAUDE_CODE_EMIT_TOOL_USE_SUMMARIES,
|
||||
),
|
||||
isAnt: process.env.USER_TYPE === 'ant',
|
||||
isAnt: false,
|
||||
// Inlined from fastMode.ts to avoid pulling its heavy module graph
|
||||
// (axios, settings, auth, model, oauth, config) into test shards that
|
||||
// didn't previously load it — changes init order and breaks unrelated tests.
|
||||
|
||||
@@ -558,7 +558,7 @@ export function getAssistantMessageFromError(
|
||||
const innerMessage = stripped.match(/"message"\s*:\s*"([^"]*)"/)?.[1]
|
||||
const detail = innerMessage || stripped
|
||||
return createAssistantAPIErrorMessage({
|
||||
content: `${API_ERROR_MESSAGE_PREFIX}: Request rejected (429) · ${detail || 'this may be a temporary capacity issue — check status.anthropic.com'}`,
|
||||
content: `${API_ERROR_MESSAGE_PREFIX}: Request rejected (429) · ${detail || `this may be a temporary capacity issue${getAPIProvider() === 'firstParty' ? ' — check status.anthropic.com' : ''}`}`,
|
||||
error: 'rate_limit',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@ import {
|
||||
} from '../api/errors.js'
|
||||
import { notifyCompaction } from '../api/promptCacheBreakDetection.js'
|
||||
import { getRetryDelay } from '../api/withRetry.js'
|
||||
import { logPermissionContextForAnts } from '../internalLogging.js'
|
||||
import {
|
||||
roughTokenCountEstimation,
|
||||
roughTokenCountEstimationForMessages,
|
||||
@@ -401,7 +400,6 @@ export async function compactConversation(
|
||||
const preCompactTokenCount = tokenCountWithEstimation(messages)
|
||||
|
||||
const appState = context.getAppState()
|
||||
void logPermissionContextForAnts(appState.toolPermissionContext, 'summary')
|
||||
|
||||
context.onCompactProgress?.({
|
||||
type: 'hooks_start',
|
||||
|
||||
@@ -110,37 +110,16 @@ export const MAX_SUBCOMMANDS_FOR_SECURITY_CHECK = 50
|
||||
export const MAX_SUGGESTED_RULES_FOR_COMPOUND = 5
|
||||
|
||||
/**
|
||||
* [ANT-ONLY] Log classifier evaluation results for analysis.
|
||||
* This helps us understand which classifier rules are being evaluated
|
||||
* and how the classifier is deciding on commands.
|
||||
* Log classifier evaluation results for analysis.
|
||||
* No-op in external builds.
|
||||
*/
|
||||
function logClassifierResultForAnts(
|
||||
command: string,
|
||||
behavior: ClassifierBehavior,
|
||||
descriptions: string[],
|
||||
result: ClassifierResult,
|
||||
_command: string,
|
||||
_behavior: ClassifierBehavior,
|
||||
_descriptions: string[],
|
||||
_result: ClassifierResult,
|
||||
): void {
|
||||
if (process.env.USER_TYPE !== 'ant') {
|
||||
return
|
||||
}
|
||||
|
||||
logEvent('tengu_internal_bash_classifier_result', {
|
||||
behavior:
|
||||
behavior as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
descriptions: jsonStringify(
|
||||
descriptions,
|
||||
) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
matches: result.matches,
|
||||
matchedDescription: (result.matchedDescription ??
|
||||
'') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
confidence:
|
||||
result.confidence as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
reason:
|
||||
result.reason as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
// Note: command contains code/filepaths - this is ANT-ONLY so it's OK
|
||||
command:
|
||||
command as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
})
|
||||
// Internal-only logging removed from external build.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,13 +409,11 @@ const SAFE_ENV_VARS = new Set([
|
||||
])
|
||||
|
||||
/**
|
||||
* ANT-ONLY environment variables that are safe to strip from commands.
|
||||
* These are only enabled when USER_TYPE === 'ant'.
|
||||
* Environment variables that are safe to strip from commands.
|
||||
*
|
||||
* SECURITY: These env vars are stripped before permission-rule matching, which
|
||||
* means `DOCKER_HOST=tcp://evil.com docker ps` matches a `Bash(docker ps:*)`
|
||||
* rule after stripping. This is INTENTIONALLY ANT-ONLY (gated at line ~380)
|
||||
* and MUST NEVER ship to external users. DOCKER_HOST redirects the Docker
|
||||
* rule after stripping. DOCKER_HOST redirects the Docker
|
||||
* daemon endpoint — stripping it defeats prefix-based permission restrictions
|
||||
* by hiding the network endpoint from the permission check. KUBECONFIG
|
||||
* similarly controls which cluster kubectl talks to. These are convenience
|
||||
|
||||
Reference in New Issue
Block a user