feat: 压缩和权限gap功能增强 - PTL gap解析, 时间感知微压缩, token估算安全系数, PLAN模式, 拒绝追踪

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
liuzh
2026-04-02 23:17:29 +08:00
co-authored by Copilot
parent 730551cb3f
commit fa565d8c07
8 changed files with 165 additions and 6 deletions
@@ -0,0 +1,63 @@
package com.claudecode.permission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 拒绝追踪器 —— 跟踪连续和总计的权限拒绝次数。
* <p>
* 对应 claude-code 的 denialTracking.ts。
* 当连续拒绝达到阈值(3 次)或总计拒绝达到阈值(20 次)时,
* 建议回退到手动提示模式,避免 auto/plan 模式下的无限拒绝循环。
*/
public class DenialTracker {
private static final Logger log = LoggerFactory.getLogger(DenialTracker.class);
/** 连续拒绝阈值 —— 超过后建议回退 */
public static final int MAX_CONSECUTIVE_DENIALS = 3;
/** 总计拒绝阈值 —— 超过后建议回退 */
public static final int MAX_TOTAL_DENIALS = 20;
private int consecutiveDenials = 0;
private int totalDenials = 0;
/** 记录一次拒绝 */
public void recordDenial() {
consecutiveDenials++;
totalDenials++;
if (shouldFallbackToPrompting()) {
log.warn("Denial threshold reached: {} consecutive, {} total — consider switching to manual mode",
consecutiveDenials, totalDenials);
}
}
/** 记录一次成功(重置连续计数,但不重置总计) */
public void recordSuccess() {
consecutiveDenials = 0;
}
/**
* 是否应回退到手动提示模式。
* 当连续拒绝 >= 3 或总计拒绝 >= 20 时返回 true。
*/
public boolean shouldFallbackToPrompting() {
return consecutiveDenials >= MAX_CONSECUTIVE_DENIALS
|| totalDenials >= MAX_TOTAL_DENIALS;
}
/** 完全重置计数器 */
public void reset() {
consecutiveDenials = 0;
totalDenials = 0;
}
public int getConsecutiveDenials() {
return consecutiveDenials;
}
public int getTotalDenials() {
return totalDenials;
}
}
@@ -50,6 +50,14 @@ public class PermissionRuleEngine {
return PermissionDecision.allow("Bypass mode enabled");
}
// PLAN 模式:仅允许只读工具
if (mode == PermissionMode.PLAN) {
if (isReadOnly || READ_ONLY_TOOLS.contains(toolName)) {
return PermissionDecision.allow("Read-only tool allowed in plan mode");
}
return PermissionDecision.deny("Plan mode: execution disabled (analysis only)");
}
// 获取命令内容(用于 Bash/PowerShell 的命令匹配)
String command = extractCommand(toolName, input);
@@ -25,7 +25,9 @@ public final class PermissionTypes {
/** 跳过所有权限检查(不安全) */
BYPASS,
/** 自动拒绝而非询问用户(无头模式) */
DONT_ASK
DONT_ASK,
/** 计划模式:仅分析不执行(拒绝所有非只读工具) */
PLAN
}
/**