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:
KRATOS
2026-04-04 21:23:17 +05:30
committed by GitHub
parent 01acc4c10e
commit 75d2543854
6 changed files with 12 additions and 50 deletions

View File

@@ -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/)

View File

@@ -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', {

View File

@@ -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.

View File

@@ -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',
})
}

View File

@@ -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',

View File

@@ -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