fix(audit): 修复深度审计 P2 问题 — 自主授权后端守卫、反思历史累积、心跳持久化
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- M5-补: hand_execute/skill_execute 接收 autonomy_level 参数,后端三层守卫
(supervised 全部审批 / assisted 尊重 needs_approval / autonomous 跳过)
- M3: hand_approve/hand_cancel 移除 _hand_name 下划线,添加审计日志
- M4-补: 反思历史累积存储到 reflection:history:{agent_id} 数组(最多20条)
get_history 优先读持久化历史,保留 latest key 向后兼容
- 心跳历史: VikingStorage 持久化 HeartbeatResult 数组,tick() 也存历史
heartbeat_init 恢复历史,重启后不丢失
- L2: 确认 gatewayStore 仅注释引用,无需修改
- 身份回滚: 确认 IdentityChangeProposal.tsx 已实现 HistoryItem + restoreSnapshot
- 更新 DEEP_AUDIT_REPORT.md 完成度 72% (核心 92%, 真实可用 80%)
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
*/
|
||||
import { create } from 'zustand';
|
||||
import type { GatewayClient } from '../lib/gateway-client';
|
||||
import { canAutoExecute, getAutonomyManager } from '../lib/autonomy-manager';
|
||||
import type { AutonomyDecision } from '../lib/autonomy-manager';
|
||||
|
||||
// === Re-exported Types (from gatewayStore for compatibility) ===
|
||||
|
||||
@@ -139,7 +141,7 @@ interface HandClient {
|
||||
listHands: () => Promise<{ hands?: Array<Record<string, unknown>> } | null>;
|
||||
getHand: (name: string) => Promise<Record<string, unknown> | null>;
|
||||
listHandRuns: (name: string, opts?: { limit?: number; offset?: number }) => Promise<{ runs?: RawHandRun[] } | null>;
|
||||
triggerHand: (name: string, params?: Record<string, unknown>) => Promise<{ runId?: string; status?: string } | null>;
|
||||
triggerHand: (name: string, params?: Record<string, unknown>, autonomyLevel?: string) => Promise<{ runId?: string; status?: string } | null>;
|
||||
approveHand: (name: string, runId: string, approved: boolean, reason?: string) => Promise<{ status: string }>;
|
||||
cancelHand: (name: string, runId: string) => Promise<{ status: string }>;
|
||||
listTriggers: () => Promise<{ triggers?: Trigger[] } | null>;
|
||||
@@ -161,6 +163,8 @@ export interface HandStateSlice {
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
client: HandClient | null;
|
||||
/** Latest autonomy decision (set when action requires approval) */
|
||||
autonomyDecision: AutonomyDecision | null;
|
||||
}
|
||||
|
||||
// === Store Actions Slice ===
|
||||
@@ -169,7 +173,7 @@ export interface HandActionsSlice {
|
||||
setHandStoreClient: (client: HandClient) => void;
|
||||
loadHands: () => Promise<void>;
|
||||
getHandDetails: (name: string) => Promise<Hand | undefined>;
|
||||
triggerHand: (name: string, params?: Record<string, unknown>) => Promise<HandRun | undefined>;
|
||||
triggerHand: (name: string, params?: Record<string, unknown>, autonomyLevel?: string) => Promise<HandRun | undefined>;
|
||||
loadHandRuns: (name: string, opts?: { limit?: number; offset?: number }) => Promise<HandRun[]>;
|
||||
approveHand: (name: string, runId: string, approved: boolean, reason?: string) => Promise<void>;
|
||||
cancelHand: (name: string, runId: string) => Promise<void>;
|
||||
@@ -181,6 +185,7 @@ export interface HandActionsSlice {
|
||||
loadApprovals: (status?: ApprovalStatus) => Promise<void>;
|
||||
respondToApproval: (approvalId: string, approved: boolean, reason?: string) => Promise<void>;
|
||||
clearError: () => void;
|
||||
clearAutonomyDecision: () => void;
|
||||
}
|
||||
|
||||
// === Combined Store Type ===
|
||||
@@ -195,6 +200,7 @@ export const useHandStore = create<HandStore>((set, get) => ({
|
||||
approvals: [],
|
||||
isLoading: false,
|
||||
error: null,
|
||||
autonomyDecision: null,
|
||||
client: null,
|
||||
|
||||
// Client injection
|
||||
@@ -322,8 +328,21 @@ export const useHandStore = create<HandStore>((set, get) => ({
|
||||
const client = get().client;
|
||||
if (!client) return undefined;
|
||||
|
||||
// Autonomy check before executing hand
|
||||
const { canProceed, decision } = canAutoExecute('hand_trigger', 5);
|
||||
if (!canProceed) {
|
||||
// Store decision for UI to display approval prompt
|
||||
set(() => ({
|
||||
autonomyDecision: decision,
|
||||
}));
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Pass current autonomy level to backend for defense-in-depth enforcement
|
||||
const autonomyLevel = getAutonomyManager().getConfig().level;
|
||||
|
||||
try {
|
||||
const result = await client.triggerHand(name, params);
|
||||
const result = await client.triggerHand(name, params, autonomyLevel);
|
||||
if (!result) return undefined;
|
||||
|
||||
const run: HandRun = {
|
||||
@@ -498,6 +517,7 @@ export const useHandStore = create<HandStore>((set, get) => ({
|
||||
},
|
||||
|
||||
clearError: () => set({ error: null }),
|
||||
clearAutonomyDecision: () => set({ autonomyDecision: null }),
|
||||
}));
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user