feat(tok,acr): v5.6 B2 — load-pattern column in token-hotspots
Annotate every ranked TOK hotspot with the load-pattern triple (loadPattern/survivesCompaction/derivationConfidence): - hotspotLoadPattern() maps each discovery `type` → a deriveLoadPattern kind. Rules reuse activeConfig.rules for precise `scoped` handling; claude-md maps by scope. Two new deriveLoadPattern kinds back the rest: `command` (on-demand — body loads on /invoke) and `harness-config` (external — settings/keybindings/.mcp.json/hooks.json/plugin.json configure the CLI, not the model context, so they cost no per-turn context tokens). Honest split: the .mcp.json FILE is external; the MCP server's tool schemas are a separate `always` hotspot. Byte-stability — the opposite of B1's manifest. token-hotspots IS a byte-equal SC-6/SC-7 CLI, and its hotspots ride inside scan-orchestrator + posture, so the change touched SIX frozen-v5.0.0 comparisons across five test files. Resolved by preserving the frozen baselines: a shared tests/helpers/strip-hotspot-load-pattern.mjs strips the additive triple before each byte-equal compare (proves the original schema is byte-identical). SC-5 default-output snapshots (scan-orchestrator + token-hotspots) regenerated — diff reviewed as additive-only. Tests 1008→1012. Self-audit A/A, scanner count unchanged at 13 (C bumps to 14). Completes v5.6 B (B1 manifest + B2 token-hotspots). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bb647ce35f
commit
778b517e6f
17 changed files with 236 additions and 40 deletions
|
|
@ -99,6 +99,14 @@ export function deriveLoadPattern(kind, opts = {}) {
|
|||
// MCP tool schemas are part of the per-turn payload (no explicit
|
||||
// compaction-survival row → 'inferred').
|
||||
case 'mcp': return mk('always', 'yes', 'inferred');
|
||||
// Slash-command body loads when the command is invoked (on-demand). No
|
||||
// primary-doc row pins the always-loaded command listing cost → 'inferred'.
|
||||
case 'command': return mk('on-demand', 'n/a', 'inferred');
|
||||
// Harness-config files (settings.json, keybindings.json, .mcp.json, hooks.json,
|
||||
// plugin.json, ~/.claude.json) are read by the CLI to configure the harness —
|
||||
// they are NOT injected into the model context, so they cost no per-turn
|
||||
// context tokens. 'external' = outside the context window (like hooks).
|
||||
case 'harness-config': return mk('external', 'n/a', 'inferred');
|
||||
default: return mk('unknown', 'n/a', 'inferred');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,64 @@ import { readTextFile } from './lib/file-discovery.mjs';
|
|||
import { finding, scannerResult } from './lib/output.mjs';
|
||||
import { SEVERITY } from './lib/severity.mjs';
|
||||
import { findImports, parseJson, parseFrontmatter } from './lib/yaml-parser.mjs';
|
||||
import { estimateTokens, readActiveConfig } from './lib/active-config-reader.mjs';
|
||||
import { estimateTokens, readActiveConfig, deriveLoadPattern } from './lib/active-config-reader.mjs';
|
||||
|
||||
const SCANNER = 'TOK';
|
||||
|
||||
// v5.6 B2 — map a discovery `type` to a deriveLoadPattern kind so each ranked
|
||||
// hotspot can be annotated with its load pattern. `claude-md` and `rule` are
|
||||
// handled specially (by scope / scoped); the synthetic 'mcp-server' → 'mcp'.
|
||||
// Harness-config files (settings/manifests) configure the CLI, not the model
|
||||
// context, so they cost no per-turn context tokens (deriveLoadPattern maps
|
||||
// 'harness-config' → external).
|
||||
const HOTSPOT_TYPE_TO_KIND = {
|
||||
'skill-md': 'skill-body',
|
||||
'agent-md': 'agent',
|
||||
'command-md': 'command',
|
||||
'mcp-server': 'mcp',
|
||||
'settings-json': 'harness-config',
|
||||
'mcp-json': 'harness-config',
|
||||
'hooks-json': 'harness-config',
|
||||
'plugin-json': 'harness-config',
|
||||
'claude-json': 'harness-config',
|
||||
'keybindings-json': 'harness-config',
|
||||
};
|
||||
|
||||
const CLAUDE_MD_SCOPE_KIND = {
|
||||
project: 'claude-md-root',
|
||||
local: 'claude-md-root',
|
||||
user: 'claude-md-user',
|
||||
managed: 'claude-md-managed',
|
||||
import: 'claude-md-import',
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive the load-pattern triple for a ranked hotspot. Rules reuse the
|
||||
* active-config enumeration (which parsed `paths:` to set `scoped`) for precise
|
||||
* scoped/unscoped handling; everything else maps by type.
|
||||
*
|
||||
* @param {{type:string, scope?:string, absPath?:string}} h
|
||||
* @param {Map<string, {loadPattern:string, survivesCompaction:string, derivationConfidence:string}>} ruleMap
|
||||
*/
|
||||
function hotspotLoadPattern(h, ruleMap) {
|
||||
if (h.type === 'claude-md') {
|
||||
return deriveLoadPattern(CLAUDE_MD_SCOPE_KIND[h.scope] || 'claude-md-root');
|
||||
}
|
||||
if (h.type === 'rule') {
|
||||
const r = ruleMap.get(h.absPath);
|
||||
if (r) {
|
||||
return {
|
||||
loadPattern: r.loadPattern,
|
||||
survivesCompaction: r.survivesCompaction,
|
||||
derivationConfidence: r.derivationConfidence,
|
||||
};
|
||||
}
|
||||
return deriveLoadPattern('rule', { scoped: false });
|
||||
}
|
||||
// Unmapped types fall through to deriveLoadPattern's safe 'unknown' default.
|
||||
return deriveLoadPattern(HOTSPOT_TYPE_TO_KIND[h.type] || h.type);
|
||||
}
|
||||
|
||||
const VOLATILE_TOP_LINES = 30;
|
||||
const VOLATILE_PATTERNS = [
|
||||
/\{timestamp\}/i,
|
||||
|
|
@ -241,14 +295,25 @@ async function buildHotspots(discovery, targetPath, activeConfig) {
|
|||
}
|
||||
ranked.sort((a, b) => b.estimated_tokens - a.estimated_tokens);
|
||||
|
||||
// v5.6 B2 — precise rule load-pattern lookup: the active-config enumeration
|
||||
// already parsed `paths:` and derived the pattern, keyed by absolute path.
|
||||
const ruleMap = new Map();
|
||||
if (activeConfig && Array.isArray(activeConfig.rules)) {
|
||||
for (const r of activeConfig.rules) ruleMap.set(r.path, r);
|
||||
}
|
||||
|
||||
const top = ranked.slice(0, HOTSPOTS_MAX);
|
||||
const out = [];
|
||||
for (let i = 0; i < top.length; i++) {
|
||||
const h = top[i];
|
||||
const lp = hotspotLoadPattern(h, ruleMap);
|
||||
const entry = {
|
||||
source: h.relPath || h.absPath,
|
||||
estimated_tokens: h.estimated_tokens,
|
||||
rank: i + 1,
|
||||
loadPattern: lp.loadPattern,
|
||||
survivesCompaction: lp.survivesCompaction,
|
||||
derivationConfidence: lp.derivationConfidence,
|
||||
recommendations: hotspotRecommendations(h),
|
||||
};
|
||||
// Expose the on-disk path for file-backed hotspots so the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue