mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-12 15:47:27 +08:00
docs: salvage zh-CN health security skill translations
This commit is contained in:
committed by
Affaan Mustafa
parent
5d53628d08
commit
c3246dbe34
182
docs/zh-CN/skills/agent-payment-x402/SKILL.md
Normal file
182
docs/zh-CN/skills/agent-payment-x402/SKILL.md
Normal file
@@ -0,0 +1,182 @@
|
||||
---
|
||||
name: agent-payment-x402
|
||||
description: 将 x402 支付执行添加到 AI 代理中——通过 MCP 工具实现每任务预算、支出控制和非托管钱包。当代理需要为 API、服务或其他代理付费时使用。
|
||||
origin: community
|
||||
---
|
||||
|
||||
# 代理支付执行 (x402)
|
||||
|
||||
让AI代理能够自主支付并内置消费控制。使用x402 HTTP支付协议和MCP工具,使代理能够为外部服务、API或其他代理支付,无需托管风险。
|
||||
|
||||
## 使用场景
|
||||
|
||||
适用于:代理需要支付API调用、购买服务、与其他代理结算、强制执行每项任务消费限额,或管理非托管钱包。与成本感知LLM流水线和安全审查技能自然搭配。
|
||||
|
||||
## 工作原理
|
||||
|
||||
### x402协议
|
||||
|
||||
x402将HTTP 402(需要付款)扩展为机器可协商的流程。当服务器返回`402`时,代理的支付工具会自动协商价格、检查预算、签署交易并重试——无需人工干预。
|
||||
|
||||
### 消费控制
|
||||
|
||||
每次支付工具调用都会强制执行`SpendingPolicy`:
|
||||
|
||||
* **每任务预算** — 单次代理操作的最大支出
|
||||
* **每会话预算** — 整个会话的累计限额
|
||||
* **白名单接收方** — 限制代理可支付的地址/服务
|
||||
* **速率限制** — 每分钟/小时的最大交易数
|
||||
|
||||
### 非托管钱包
|
||||
|
||||
代理通过ERC-4337智能账户持有自己的密钥。编排器在委托前设置策略;代理只能在限定范围内支出。无资金池,无托管风险。
|
||||
|
||||
## MCP集成
|
||||
|
||||
支付层暴露标准MCP工具,可无缝接入任何Claude Code或代理框架设置。
|
||||
|
||||
> **安全提示**:务必锁定包版本。此工具管理私钥——未锁定的`npx`安装会引入供应链风险。
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"agentpay": {
|
||||
"command": "npx",
|
||||
"args": ["agentwallet-sdk@6.0.0"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 可用工具(代理可调用)
|
||||
|
||||
| 工具 | 用途 |
|
||||
|------|---------|
|
||||
| `get_balance` | 检查代理钱包余额 |
|
||||
| `send_payment` | 向地址或ENS发送付款 |
|
||||
| `check_spending` | 查询剩余预算 |
|
||||
| `list_transactions` | 所有付款的审计追踪 |
|
||||
|
||||
> **注意**:消费策略由**编排器**在委托给代理之前设置——而非代理本身。这防止代理自行提高消费限额。通过编排层或任务前钩子中的`set_policy`配置策略,切勿将其作为代理可调用工具。
|
||||
|
||||
## 示例
|
||||
|
||||
### MCP客户端中的预算执行
|
||||
|
||||
在构建调用agentpay MCP服务器的编排器时,在分派付费工具调用前强制执行预算。
|
||||
|
||||
> **前提条件**:在添加MCP配置前安装包——`npx`不带`-y`会在非交互环境中提示确认,导致服务器挂起:`npm install -g agentwallet-sdk@6.0.0`
|
||||
|
||||
```typescript
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
||||
|
||||
async function main() {
|
||||
// 1. Validate credentials before constructing the transport.
|
||||
// A missing key must fail immediately — never let the subprocess start without auth.
|
||||
const walletKey = process.env.WALLET_PRIVATE_KEY;
|
||||
if (!walletKey) {
|
||||
throw new Error("WALLET_PRIVATE_KEY is not set — refusing to start payment server");
|
||||
}
|
||||
|
||||
// Connect to the agentpay MCP server via stdio transport.
|
||||
// Whitelist only the env vars the server needs — never forward all of process.env
|
||||
// to a third-party subprocess that manages private keys.
|
||||
const transport = new StdioClientTransport({
|
||||
command: "npx",
|
||||
args: ["agentwallet-sdk@6.0.0"],
|
||||
env: {
|
||||
PATH: process.env.PATH ?? "",
|
||||
NODE_ENV: process.env.NODE_ENV ?? "production",
|
||||
WALLET_PRIVATE_KEY: walletKey,
|
||||
},
|
||||
});
|
||||
const agentpay = new Client({ name: "orchestrator", version: "1.0.0" });
|
||||
await agentpay.connect(transport);
|
||||
|
||||
// 2. Set spending policy before delegating to the agent.
|
||||
// Always verify success — a silent failure means no controls are active.
|
||||
const policyResult = await agentpay.callTool({
|
||||
name: "set_policy",
|
||||
arguments: {
|
||||
per_task_budget: 0.50,
|
||||
per_session_budget: 5.00,
|
||||
allowlisted_recipients: ["api.example.com"],
|
||||
},
|
||||
});
|
||||
if (policyResult.isError) {
|
||||
throw new Error(
|
||||
`Failed to set spending policy — do not delegate: ${JSON.stringify(policyResult.content)}`
|
||||
);
|
||||
}
|
||||
|
||||
// 3. Use preToolCheck before any paid action
|
||||
await preToolCheck(agentpay, 0.01);
|
||||
}
|
||||
|
||||
// Pre-tool hook: fail-closed budget enforcement with four distinct error paths.
|
||||
async function preToolCheck(agentpay: Client, apiCost: number): Promise<void> {
|
||||
// Path 1: Reject invalid input (NaN/Infinity bypass the < comparison)
|
||||
if (!Number.isFinite(apiCost) || apiCost < 0) {
|
||||
throw new Error(`Invalid apiCost: ${apiCost} — action blocked`);
|
||||
}
|
||||
|
||||
// Path 2: Transport/connectivity failure
|
||||
let result;
|
||||
try {
|
||||
result = await agentpay.callTool({ name: "check_spending" });
|
||||
} catch (err) {
|
||||
throw new Error(`Payment service unreachable — action blocked: ${err}`);
|
||||
}
|
||||
|
||||
// Path 3: Tool returned an error (e.g., auth failure, wallet not initialised)
|
||||
if (result.isError) {
|
||||
throw new Error(
|
||||
`check_spending failed — action blocked: ${JSON.stringify(result.content)}`
|
||||
);
|
||||
}
|
||||
|
||||
// Path 4: Parse and validate the response shape
|
||||
let remaining: number;
|
||||
try {
|
||||
const parsed = JSON.parse(
|
||||
(result.content as Array<{ text: string }>)[0].text
|
||||
);
|
||||
if (!Number.isFinite(parsed?.remaining)) {
|
||||
throw new TypeError("missing or non-finite 'remaining' field");
|
||||
}
|
||||
remaining = parsed.remaining;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`check_spending returned unexpected format — action blocked: ${err}`
|
||||
);
|
||||
}
|
||||
|
||||
// Path 5: Budget exceeded
|
||||
if (remaining < apiCost) {
|
||||
throw new Error(
|
||||
`Budget exceeded: need $${apiCost} but only $${remaining} remaining`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
* **委托前设置预算**:生成子代理时,通过编排层附加SpendingPolicy。切勿让代理拥有无限支出权限。
|
||||
* **锁定依赖项**:始终在MCP配置中指定确切版本(例如`agentwallet-sdk@6.0.0`)。部署到生产环境前验证包完整性。
|
||||
* **审计追踪**:在任务后钩子中使用`list_transactions`记录支出内容和原因。
|
||||
* **故障关闭**:如果支付工具不可达,阻止付费操作——不要回退到无计量访问。
|
||||
* **配合安全审查**:支付工具是高权限操作。应用与shell访问相同的审查标准。
|
||||
* **先在测试网测试**:开发时使用Base Sepolia;生产环境切换到Base主网。
|
||||
|
||||
## 生产参考
|
||||
|
||||
* **npm**:[`agentwallet-sdk`](https://www.npmjs.com/package/agentwallet-sdk)
|
||||
* **合并到NVIDIA NeMo Agent Toolkit**:[PR #17](https://github.com/NVIDIA/NeMo-Agent-Toolkit-Examples/pull/17) — NVIDIA代理示例的x402支付工具
|
||||
* **协议规范**:[x402.org](https://x402.org)
|
||||
166
docs/zh-CN/skills/defi-amm-security/SKILL.md
Normal file
166
docs/zh-CN/skills/defi-amm-security/SKILL.md
Normal file
@@ -0,0 +1,166 @@
|
||||
---
|
||||
name: defi-amm-security
|
||||
description: Solidity AMM 合约、流动性池和交换流程的安全检查清单。涵盖重入、CEI 排序、捐赠或通胀攻击、预言机操纵、滑点、管理员控制和整数数学。
|
||||
origin: ECC direct-port adaptation
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# DeFi AMM 安全
|
||||
|
||||
Solidity AMM 合约、LP 金库和交换函数的关键漏洞模式及强化实现。
|
||||
|
||||
## 适用场景
|
||||
|
||||
* 编写或审计 Solidity AMM 或流动性池合约
|
||||
* 实现持有代币余额的交换、存款、提款、铸造或销毁流程
|
||||
* 审查任何在份额或储备金计算中使用 `token.balanceOf(address(this))` 的合约
|
||||
* 向 DeFi 协议添加费用设置器、暂停器、预言机更新或其他管理功能
|
||||
|
||||
## 工作原理
|
||||
|
||||
将其作为检查清单加模式库使用。对照以下类别审查每个用户入口点,并优先使用强化示例而非自行编写的变体。
|
||||
|
||||
## 执行安全
|
||||
|
||||
本技能中的 shell 命令是本地审计示例。仅在受信任的代码检出或一次性沙箱中运行,不要将不受信任的合约名称、路径、RPC URL、私钥或用户提供的标志拼接到 shell 命令中。在安装工具或运行可能消耗大量本地或付费资源的长时间模糊测试/静态分析任务前,请先询问。
|
||||
|
||||
切勿在命令示例、日志或报告中包含机密信息、私钥、助记词、API 令牌或主网签名凭证。
|
||||
|
||||
## 示例
|
||||
|
||||
### 重入攻击:强制遵循 CEI 顺序
|
||||
|
||||
存在漏洞:
|
||||
|
||||
```solidity
|
||||
function withdraw(uint256 amount) external {
|
||||
require(balances[msg.sender] >= amount);
|
||||
token.transfer(msg.sender, amount);
|
||||
balances[msg.sender] -= amount;
|
||||
}
|
||||
```
|
||||
|
||||
安全:
|
||||
|
||||
```solidity
|
||||
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
|
||||
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
function withdraw(uint256 amount) external nonReentrant {
|
||||
require(balances[msg.sender] >= amount, "Insufficient");
|
||||
balances[msg.sender] -= amount;
|
||||
token.safeTransfer(msg.sender, amount);
|
||||
}
|
||||
```
|
||||
|
||||
当存在经过验证的库时,不要自行编写防护措施。
|
||||
|
||||
### 捐赠或通胀攻击
|
||||
|
||||
直接使用 `token.balanceOf(address(this))` 进行份额计算,会让攻击者通过向合约发送代币(绕过预期路径)来操纵分母。
|
||||
|
||||
```solidity
|
||||
// Vulnerable
|
||||
function deposit(uint256 assets) external returns (uint256 shares) {
|
||||
shares = (assets * totalShares) / token.balanceOf(address(this));
|
||||
}
|
||||
```
|
||||
|
||||
```solidity
|
||||
// Safe
|
||||
uint256 private _totalAssets;
|
||||
|
||||
function deposit(uint256 assets) external nonReentrant returns (uint256 shares) {
|
||||
uint256 balBefore = token.balanceOf(address(this));
|
||||
token.safeTransferFrom(msg.sender, address(this), assets);
|
||||
uint256 received = token.balanceOf(address(this)) - balBefore;
|
||||
|
||||
shares = totalShares == 0 ? received : (received * totalShares) / _totalAssets;
|
||||
_totalAssets += received;
|
||||
totalShares += shares;
|
||||
}
|
||||
```
|
||||
|
||||
跟踪内部会计并衡量实际收到的代币。
|
||||
|
||||
### 预言机操纵
|
||||
|
||||
现货价格可通过闪电贷操纵。优先使用 TWAP。
|
||||
|
||||
```solidity
|
||||
uint32[] memory secondsAgos = new uint32[](2);
|
||||
secondsAgos[0] = 1800;
|
||||
secondsAgos[1] = 0;
|
||||
(int56[] memory tickCumulatives,) = IUniswapV3Pool(pool).observe(secondsAgos);
|
||||
int24 twapTick = int24(
|
||||
(tickCumulatives[1] - tickCumulatives[0]) / int56(uint56(30 minutes))
|
||||
);
|
||||
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(twapTick);
|
||||
```
|
||||
|
||||
### 滑点保护
|
||||
|
||||
每个交换路径都需要调用者提供的滑点和截止时间。
|
||||
|
||||
```solidity
|
||||
function swap(
|
||||
uint256 amountIn,
|
||||
uint256 amountOutMin,
|
||||
uint256 deadline
|
||||
) external returns (uint256 amountOut) {
|
||||
require(block.timestamp <= deadline, "Expired");
|
||||
amountOut = _calculateOut(amountIn);
|
||||
require(amountOut >= amountOutMin, "Slippage exceeded");
|
||||
_executeSwap(amountIn, amountOut);
|
||||
}
|
||||
```
|
||||
|
||||
### 安全的储备金计算
|
||||
|
||||
```solidity
|
||||
import {FullMath} from "@uniswap/v3-core/contracts/libraries/FullMath.sol";
|
||||
|
||||
uint256 result = FullMath.mulDiv(a, b, c);
|
||||
```
|
||||
|
||||
对于大型储备金计算,当存在溢出风险时,避免使用简单的 `a * b / c`。
|
||||
|
||||
### 管理控制
|
||||
|
||||
```solidity
|
||||
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
|
||||
|
||||
contract MyAMM is Ownable2Step {
|
||||
function setFee(uint256 fee) external onlyOwner { ... }
|
||||
function pause() external onlyOwner { ... }
|
||||
}
|
||||
```
|
||||
|
||||
所有权转移应优先使用显式接受,并对每个特权路径设置门控。
|
||||
|
||||
## 安全检查清单
|
||||
|
||||
* 暴露于重入攻击的入口点使用 `nonReentrant`
|
||||
* 遵循 CEI 顺序
|
||||
* 份额计算不依赖原始的 `balanceOf(address(this))`
|
||||
* ERC-20 转账使用 `SafeERC20`
|
||||
* 存款衡量实际收到的代币
|
||||
* 预言机读取使用 TWAP 或其他抗操纵源
|
||||
* 交换需要 `amountOutMin` 和 `deadline`
|
||||
* 对溢出敏感的储备金计算使用安全原语,如 `mulDiv`
|
||||
* 管理函数受访问控制
|
||||
* 存在紧急暂停功能并经过测试
|
||||
* 在生产前运行静态分析和模糊测试
|
||||
|
||||
## 审计工具
|
||||
|
||||
```bash
|
||||
pip install slither-analyzer
|
||||
slither . --exclude-dependencies
|
||||
|
||||
echidna-test . --contract YourAMM --config echidna.yaml
|
||||
|
||||
forge test --fuzz-runs 10000
|
||||
```
|
||||
130
docs/zh-CN/skills/evm-token-decimals/SKILL.md
Normal file
130
docs/zh-CN/skills/evm-token-decimals/SKILL.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
name: evm-token-decimals
|
||||
description: 防止跨EVM链的静默小数不匹配错误。涵盖运行时小数查找、链感知缓存、桥接代币精度漂移以及面向机器人、仪表盘和DeFi工具的安全归一化。
|
||||
origin: ECC direct-port adaptation
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# EVM 代币精度
|
||||
|
||||
静默的精度不匹配是导致余额或美元价值出现数量级偏差且不抛出错误的最常见原因之一。
|
||||
|
||||
## 适用场景
|
||||
|
||||
* 在 Python、TypeScript 或 Solidity 中读取 ERC-20 余额
|
||||
* 根据链上余额计算法币价值
|
||||
* 跨多条 EVM 链比较代币数量
|
||||
* 处理跨链桥接资产
|
||||
* 构建投资组合追踪器、机器人或聚合器
|
||||
|
||||
## 工作原理
|
||||
|
||||
切勿假设稳定币在所有链上使用相同的精度。在运行时查询 `decimals()`,按 `(chain_id, token_address)` 进行缓存,并使用精度安全的数学运算进行价值计算。
|
||||
|
||||
## 示例
|
||||
|
||||
### 运行时查询精度
|
||||
|
||||
```python
|
||||
from decimal import Decimal
|
||||
from web3 import Web3
|
||||
|
||||
ERC20_ABI = [
|
||||
{"name": "decimals", "type": "function", "inputs": [],
|
||||
"outputs": [{"type": "uint8"}], "stateMutability": "view"},
|
||||
{"name": "balanceOf", "type": "function",
|
||||
"inputs": [{"name": "account", "type": "address"}],
|
||||
"outputs": [{"type": "uint256"}], "stateMutability": "view"},
|
||||
]
|
||||
|
||||
def get_token_balance(w3: Web3, token_address: str, wallet: str) -> Decimal:
|
||||
contract = w3.eth.contract(
|
||||
address=Web3.to_checksum_address(token_address),
|
||||
abi=ERC20_ABI,
|
||||
)
|
||||
decimals = contract.functions.decimals().call()
|
||||
raw = contract.functions.balanceOf(Web3.to_checksum_address(wallet)).call()
|
||||
return Decimal(raw) / Decimal(10 ** decimals)
|
||||
```
|
||||
|
||||
不要硬编码 `1_000_000`,因为同名代币在其他链上通常有 6 位小数。
|
||||
|
||||
### 按链和代币缓存
|
||||
|
||||
```python
|
||||
from functools import lru_cache
|
||||
|
||||
@lru_cache(maxsize=512)
|
||||
def get_decimals(chain_id: int, token_address: str) -> int:
|
||||
w3 = get_web3_for_chain(chain_id)
|
||||
contract = w3.eth.contract(
|
||||
address=Web3.to_checksum_address(token_address),
|
||||
abi=ERC20_ABI,
|
||||
)
|
||||
return contract.functions.decimals().call()
|
||||
```
|
||||
|
||||
### 防御性处理异常代币
|
||||
|
||||
```python
|
||||
try:
|
||||
decimals = contract.functions.decimals().call()
|
||||
except Exception:
|
||||
logging.warning(
|
||||
"decimals() reverted on %s (chain %s), defaulting to 18",
|
||||
token_address,
|
||||
chain_id,
|
||||
)
|
||||
decimals = 18
|
||||
```
|
||||
|
||||
记录回退值并保持可见。旧版或非标准代币仍然存在。
|
||||
|
||||
### 在 Solidity 中归一化为 18 位 WAD 精度
|
||||
|
||||
```solidity
|
||||
interface IERC20Metadata {
|
||||
function decimals() external view returns (uint8);
|
||||
}
|
||||
|
||||
function normalizeToWad(address token, uint256 amount) internal view returns (uint256) {
|
||||
uint8 d = IERC20Metadata(token).decimals();
|
||||
if (d == 18) return amount;
|
||||
if (d < 18) return amount * 10 ** (18 - d);
|
||||
return amount / 10 ** (d - 18);
|
||||
}
|
||||
```
|
||||
|
||||
### 使用 ethers 的 TypeScript 示例
|
||||
|
||||
```typescript
|
||||
import { Contract, formatUnits } from 'ethers';
|
||||
|
||||
const ERC20_ABI = [
|
||||
'function decimals() view returns (uint8)',
|
||||
'function balanceOf(address) view returns (uint256)',
|
||||
];
|
||||
|
||||
async function getBalance(provider: any, tokenAddress: string, wallet: string): Promise<string> {
|
||||
const token = new Contract(tokenAddress, ERC20_ABI, provider);
|
||||
const [decimals, raw] = await Promise.all([
|
||||
token.decimals(),
|
||||
token.balanceOf(wallet),
|
||||
]);
|
||||
return formatUnits(raw, decimals);
|
||||
}
|
||||
```
|
||||
|
||||
### 快速链上检查
|
||||
|
||||
```bash
|
||||
cast call <token_address> "decimals()(uint8)" --rpc-url <rpc>
|
||||
```
|
||||
|
||||
## 规则
|
||||
|
||||
* 始终在运行时查询 `decimals()`
|
||||
* 按链加代币地址进行缓存,而非按代币符号
|
||||
* 使用 `Decimal`、`BigInt` 或等效的精确数学运算,避免使用浮点数
|
||||
* 在跨链桥接或代币包装变更后重新查询精度
|
||||
* 在比较或定价前,始终将内部记账归一化为一致精度
|
||||
245
docs/zh-CN/skills/healthcare-cdss-patterns/SKILL.md
Normal file
245
docs/zh-CN/skills/healthcare-cdss-patterns/SKILL.md
Normal file
@@ -0,0 +1,245 @@
|
||||
---
|
||||
name: healthcare-cdss-patterns
|
||||
description: 临床决策支持系统(CDSS)开发模式。药物相互作用检查、剂量验证、临床评分(NEWS2、qSOFA)、警报严重性分类以及集成到电子病历工作流程中。
|
||||
origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# 医疗CDSS开发模式
|
||||
|
||||
构建可集成至EMR工作流的临床决策支持系统的模式。CDSS模块关乎患者安全——对假阴性零容忍。
|
||||
|
||||
## 适用场景
|
||||
|
||||
* 实现药物相互作用检查
|
||||
* 构建剂量验证引擎
|
||||
* 实现临床评分系统(NEWS2、qSOFA、APACHE、GCS)
|
||||
* 设计异常临床值警报系统
|
||||
* 构建带安全校验的用药医嘱录入
|
||||
* 结合临床上下文解读检验结果
|
||||
|
||||
## 工作原理
|
||||
|
||||
CDSS引擎是一个**无副作用的纯函数库**。输入临床数据,输出警报。这使得它完全可测试。
|
||||
|
||||
三个核心模块:
|
||||
|
||||
1. **`checkInteractions(newDrug, currentMeds, allergies)`** — 检查新药物与现有用药及已知过敏的冲突。返回按严重程度排序的`InteractionAlert[]`。使用`DrugInteractionPair`数据模型。
|
||||
2. **`validateDose(drug, dose, route, weight, age, renalFunction)`** — 根据体重、年龄和肾功能调整规则验证处方剂量。返回`DoseValidationResult`。
|
||||
3. **`calculateNEWS2(vitals)`** — 基于`NEWS2Input`计算国家早期预警评分2。返回包含总分、风险等级和升级指导的`NEWS2Result`。
|
||||
|
||||
```
|
||||
EMR UI
|
||||
↓ (用户输入数据)
|
||||
CDSS 引擎(纯函数,无副作用)
|
||||
├── 药物相互作用检查器
|
||||
├── 剂量验证器
|
||||
├── 临床评分(NEWS2、qSOFA 等)
|
||||
└── 警报分类器
|
||||
↓ (返回警报)
|
||||
EMR UI(内联显示警报,严重时阻止操作)
|
||||
```
|
||||
|
||||
### 药物相互作用检查
|
||||
|
||||
```typescript
|
||||
interface DrugInteractionPair {
|
||||
drugA: string; // generic name
|
||||
drugB: string; // generic name
|
||||
severity: 'critical' | 'major' | 'minor';
|
||||
mechanism: string;
|
||||
clinicalEffect: string;
|
||||
recommendation: string;
|
||||
}
|
||||
|
||||
function checkInteractions(
|
||||
newDrug: string,
|
||||
currentMedications: string[],
|
||||
allergyList: string[]
|
||||
): InteractionAlert[] {
|
||||
if (!newDrug) return [];
|
||||
const alerts: InteractionAlert[] = [];
|
||||
for (const current of currentMedications) {
|
||||
const interaction = findInteraction(newDrug, current);
|
||||
if (interaction) {
|
||||
alerts.push({ severity: interaction.severity, pair: [newDrug, current],
|
||||
message: interaction.clinicalEffect, recommendation: interaction.recommendation });
|
||||
}
|
||||
}
|
||||
for (const allergy of allergyList) {
|
||||
if (isCrossReactive(newDrug, allergy)) {
|
||||
alerts.push({ severity: 'critical', pair: [newDrug, allergy],
|
||||
message: `Cross-reactivity with documented allergy: ${allergy}`,
|
||||
recommendation: 'Do not prescribe without allergy consultation' });
|
||||
}
|
||||
}
|
||||
return alerts.sort((a, b) => severityOrder(a.severity) - severityOrder(b.severity));
|
||||
}
|
||||
```
|
||||
|
||||
相互作用对必须**双向**:若药物A与药物B相互作用,则药物B与药物A相互作用。
|
||||
|
||||
### 剂量验证
|
||||
|
||||
```typescript
|
||||
interface DoseValidationResult {
|
||||
valid: boolean;
|
||||
message: string;
|
||||
suggestedRange: { min: number; max: number; unit: string } | null;
|
||||
factors: string[];
|
||||
}
|
||||
|
||||
function validateDose(
|
||||
drug: string,
|
||||
dose: number,
|
||||
route: 'oral' | 'iv' | 'im' | 'sc' | 'topical',
|
||||
patientWeight?: number,
|
||||
patientAge?: number,
|
||||
renalFunction?: number
|
||||
): DoseValidationResult {
|
||||
const rules = getDoseRules(drug, route);
|
||||
if (!rules) return { valid: true, message: 'No validation rules available', suggestedRange: null, factors: [] };
|
||||
const factors: string[] = [];
|
||||
|
||||
// SAFETY: if rules require weight but weight missing, BLOCK (not pass)
|
||||
if (rules.weightBased) {
|
||||
if (!patientWeight || patientWeight <= 0) {
|
||||
return { valid: false, message: `Weight required for ${drug} (mg/kg drug)`,
|
||||
suggestedRange: null, factors: ['weight_missing'] };
|
||||
}
|
||||
factors.push('weight');
|
||||
const maxDose = rules.maxPerKg * patientWeight;
|
||||
if (dose > maxDose) {
|
||||
return { valid: false, message: `Dose exceeds max for ${patientWeight}kg`,
|
||||
suggestedRange: { min: rules.minPerKg * patientWeight, max: maxDose, unit: rules.unit }, factors };
|
||||
}
|
||||
}
|
||||
|
||||
// Age-based adjustment (when rules define age brackets and age is provided)
|
||||
if (rules.ageAdjusted && patientAge !== undefined) {
|
||||
factors.push('age');
|
||||
const ageMax = rules.getAgeAdjustedMax(patientAge);
|
||||
if (dose > ageMax) {
|
||||
return { valid: false, message: `Exceeds age-adjusted max for ${patientAge}yr`,
|
||||
suggestedRange: { min: rules.typicalMin, max: ageMax, unit: rules.unit }, factors };
|
||||
}
|
||||
}
|
||||
|
||||
// Renal adjustment (when rules define eGFR brackets and eGFR is provided)
|
||||
if (rules.renalAdjusted && renalFunction !== undefined) {
|
||||
factors.push('renal');
|
||||
const renalMax = rules.getRenalAdjustedMax(renalFunction);
|
||||
if (dose > renalMax) {
|
||||
return { valid: false, message: `Exceeds renal-adjusted max for eGFR ${renalFunction}`,
|
||||
suggestedRange: { min: rules.typicalMin, max: renalMax, unit: rules.unit }, factors };
|
||||
}
|
||||
}
|
||||
|
||||
// Absolute max
|
||||
if (dose > rules.absoluteMax) {
|
||||
return { valid: false, message: `Exceeds absolute max ${rules.absoluteMax}${rules.unit}`,
|
||||
suggestedRange: { min: rules.typicalMin, max: rules.absoluteMax, unit: rules.unit },
|
||||
factors: [...factors, 'absolute_max'] };
|
||||
}
|
||||
return { valid: true, message: 'Within range',
|
||||
suggestedRange: { min: rules.typicalMin, max: rules.typicalMax, unit: rules.unit }, factors };
|
||||
}
|
||||
```
|
||||
|
||||
### 临床评分:NEWS2
|
||||
|
||||
```typescript
|
||||
interface NEWS2Input {
|
||||
respiratoryRate: number; oxygenSaturation: number; supplementalOxygen: boolean;
|
||||
temperature: number; systolicBP: number; heartRate: number;
|
||||
consciousness: 'alert' | 'voice' | 'pain' | 'unresponsive';
|
||||
}
|
||||
interface NEWS2Result {
|
||||
total: number; // 0-20
|
||||
risk: 'low' | 'low-medium' | 'medium' | 'high';
|
||||
components: Record<string, number>;
|
||||
escalation: string;
|
||||
}
|
||||
```
|
||||
|
||||
评分表必须严格符合皇家内科医师学会规范。
|
||||
|
||||
### 警报严重程度与UI行为
|
||||
|
||||
| 严重程度 | UI行为 | 临床医生操作要求 |
|
||||
|----------|--------|------------------|
|
||||
| 危急 | 阻止操作。不可关闭的模态框。红色。 | 必须记录覆盖原因才能继续 |
|
||||
| 主要 | 行内警告横幅。橙色。 | 必须确认后才能继续 |
|
||||
| 次要 | 行内信息提示。黄色。 | 仅需知晓,无需操作 |
|
||||
|
||||
危急警报**绝不能**自动关闭或实现为Toast通知。覆盖原因必须存储在审计追踪中。
|
||||
|
||||
### 测试CDSS(对假阴性零容忍)
|
||||
|
||||
```typescript
|
||||
describe('CDSS — Patient Safety', () => {
|
||||
INTERACTION_PAIRS.forEach(({ drugA, drugB, severity }) => {
|
||||
it(`detects ${drugA} + ${drugB} (${severity})`, () => {
|
||||
const alerts = checkInteractions(drugA, [drugB], []);
|
||||
expect(alerts.length).toBeGreaterThan(0);
|
||||
expect(alerts[0].severity).toBe(severity);
|
||||
});
|
||||
it(`detects ${drugB} + ${drugA} (reverse)`, () => {
|
||||
const alerts = checkInteractions(drugB, [drugA], []);
|
||||
expect(alerts.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
it('blocks mg/kg drug when weight is missing', () => {
|
||||
const result = validateDose('gentamicin', 300, 'iv');
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.factors).toContain('weight_missing');
|
||||
});
|
||||
it('handles malformed drug data gracefully', () => {
|
||||
expect(() => checkInteractions('', [], [])).not.toThrow();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
通过标准:100%。一次遗漏的相互作用即构成患者安全事件。
|
||||
|
||||
### 反模式
|
||||
|
||||
* 使CDSS检查变为可选或可跳过且无记录原因
|
||||
* 将相互作用检查实现为Toast通知
|
||||
* 使用`any`类型处理药物或临床数据
|
||||
* 硬编码相互作用对而非使用可维护的数据结构
|
||||
* 静默捕获CDSS引擎错误(必须大声暴露失败)
|
||||
* 在体重数据缺失时跳过基于体重的验证(必须阻止,而非通过)
|
||||
|
||||
## 示例
|
||||
|
||||
### 示例1:药物相互作用检查
|
||||
|
||||
```typescript
|
||||
const alerts = checkInteractions('warfarin', ['aspirin', 'metformin'], ['penicillin']);
|
||||
// [{ severity: 'critical', pair: ['warfarin', 'aspirin'],
|
||||
// message: 'Increased bleeding risk', recommendation: 'Avoid combination' }]
|
||||
```
|
||||
|
||||
### 示例2:剂量验证
|
||||
|
||||
```typescript
|
||||
const ok = validateDose('paracetamol', 1000, 'oral', 70, 45);
|
||||
// { valid: true, suggestedRange: { min: 500, max: 4000, unit: 'mg' } }
|
||||
|
||||
const bad = validateDose('paracetamol', 5000, 'oral', 70, 45);
|
||||
// { valid: false, message: 'Exceeds absolute max 4000mg' }
|
||||
|
||||
const noWeight = validateDose('gentamicin', 300, 'iv');
|
||||
// { valid: false, factors: ['weight_missing'] }
|
||||
```
|
||||
|
||||
### 示例3:NEWS2评分
|
||||
|
||||
```typescript
|
||||
const result = calculateNEWS2({
|
||||
respiratoryRate: 24, oxygenSaturation: 93, supplementalOxygen: true,
|
||||
temperature: 38.5, systolicBP: 100, heartRate: 110, consciousness: 'voice'
|
||||
});
|
||||
// { total: 13, risk: 'high', escalation: 'Urgent clinical review. Consider ICU.' }
|
||||
```
|
||||
161
docs/zh-CN/skills/healthcare-emr-patterns/SKILL.md
Normal file
161
docs/zh-CN/skills/healthcare-emr-patterns/SKILL.md
Normal file
@@ -0,0 +1,161 @@
|
||||
---
|
||||
name: healthcare-emr-patterns
|
||||
description: 医疗应用中EMR/EHR的开发模式。临床安全、就诊工作流程、处方生成、临床决策支持集成以及以可访问性为先的医疗数据录入用户界面。
|
||||
origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# 医疗电子病历开发模式
|
||||
|
||||
构建电子病历(EMR)和电子健康档案(EHR)系统的模式。优先考虑患者安全、临床准确性和医生工作效率。
|
||||
|
||||
## 使用场景
|
||||
|
||||
* 构建患者就诊工作流(主诉、检查、诊断、处方)
|
||||
* 实现临床记录(结构化文本 + 自由文本 + 语音转文字)
|
||||
* 设计含药物相互作用检查的处方/用药模块
|
||||
* 集成临床决策支持系统(CDSS)
|
||||
* 构建带参考范围高亮显示的检验结果展示
|
||||
* 实现临床数据审计追踪
|
||||
* 设计医疗场景下易用的临床数据录入界面
|
||||
|
||||
## 工作原理
|
||||
|
||||
### 患者安全优先
|
||||
|
||||
每个设计决策必须通过以下问题评估:"这会对患者造成伤害吗?"
|
||||
|
||||
* 药物相互作用**必须**发出警报,不能静默通过
|
||||
* 异常检验值**必须**以视觉方式标记
|
||||
* 关键生命体征**必须**触发升级工作流
|
||||
* 无审计追踪不得修改临床数据
|
||||
|
||||
### 单页就诊流程
|
||||
|
||||
临床就诊应在单页上垂直流动——无需切换标签页:
|
||||
|
||||
```
|
||||
患者头部信息(固定显示 — 始终可见)
|
||||
├── 人口学信息、过敏史、当前用药
|
||||
│
|
||||
就诊流程(垂直滚动)
|
||||
├── 1. 主诉(结构化模板 + 自由文本)
|
||||
├── 2. 现病史
|
||||
├── 3. 体格检查(按系统分类)
|
||||
├── 4. 生命体征(自动触发临床评分)
|
||||
├── 5. 诊断(ICD-10/SNOMED 搜索)
|
||||
├── 6. 用药(药品数据库 + 相互作用检查)
|
||||
├── 7. 检查(实验室/影像学医嘱)
|
||||
├── 8. 计划与随访
|
||||
└── 9. 签名 / 锁定 / 打印
|
||||
```
|
||||
|
||||
### 智能模板系统
|
||||
|
||||
```typescript
|
||||
interface ClinicalTemplate {
|
||||
id: string;
|
||||
name: string; // e.g., "Chest Pain"
|
||||
chips: string[]; // clickable symptom chips
|
||||
requiredFields: string[]; // mandatory data points
|
||||
redFlags: string[]; // triggers non-dismissable alert
|
||||
icdSuggestions: string[]; // pre-mapped diagnosis codes
|
||||
}
|
||||
```
|
||||
|
||||
任何模板中的危险信号必须触发可见且不可关闭的警报——而非通知提示。
|
||||
|
||||
### 用药安全模式
|
||||
|
||||
```
|
||||
用户选择药物
|
||||
→ 检查当前用药是否存在相互作用
|
||||
→ 检查就诊用药是否存在相互作用
|
||||
→ 检查患者过敏史
|
||||
→ 根据体重/年龄/肾功能验证剂量
|
||||
→ 若为严重相互作用:完全阻止开药
|
||||
→ 临床医生必须记录覆盖理由才能继续操作
|
||||
→ 若为重大相互作用:显示警告,要求确认
|
||||
→ 将所有警报和覆盖理由记录在审计追踪中
|
||||
```
|
||||
|
||||
关键相互作用**默认阻止开药**。临床医生必须明确覆盖,并在审计追踪中记录原因。系统绝不允许静默通过关键相互作用。
|
||||
|
||||
### 锁定就诊模式
|
||||
|
||||
临床就诊一旦签署:
|
||||
|
||||
* 不允许编辑——仅可添加附录(独立的关联记录)
|
||||
* 原始记录和附录均显示在患者时间线中
|
||||
* 审计追踪记录签署人、签署时间及所有附录记录
|
||||
|
||||
### 临床数据界面模式
|
||||
|
||||
**生命体征显示:** 当前值带正常范围高亮(绿/黄/红),与上次对比的趋势箭头,自动计算的临床评分(NEWS2、qSOFA),内联升级指导。
|
||||
|
||||
**检验结果展示:** 正常范围高亮,与上次值对比,关键值带不可关闭警报,采集/分析时间戳,待处理医嘱及预期周转时间。
|
||||
|
||||
**处方PDF:** 一键生成,包含患者基本信息、过敏史、诊断、药物详情(通用名+商品名、剂量、给药途径、频率、疗程)、临床医生签名栏。
|
||||
|
||||
### 医疗场景无障碍设计
|
||||
|
||||
医疗界面的要求比典型网页应用更严格:
|
||||
|
||||
* 最小对比度4.5:1(WCAG AA)——临床医生在不同光照条件下工作
|
||||
* 大触摸目标(最小44x44px)——适用于戴手套或快速操作
|
||||
* 键盘导航——供快速录入数据的熟练用户使用
|
||||
* 不使用纯颜色指示——始终将颜色与文字/图标配对(色盲临床医生)
|
||||
* 所有表单字段带屏幕阅读器标签
|
||||
* 临床警报不使用自动消失的提示——临床医生必须主动确认
|
||||
|
||||
### 反模式
|
||||
|
||||
* 在浏览器localStorage中存储临床数据
|
||||
* 药物相互作用检查静默失败
|
||||
* 关键临床警报使用可关闭提示
|
||||
* 基于标签页的就诊界面导致临床工作流碎片化
|
||||
* 允许编辑已签署/锁定的就诊记录
|
||||
* 无审计追踪显示临床数据
|
||||
* 使用`any`类型处理临床数据结构
|
||||
|
||||
## 示例
|
||||
|
||||
### 示例1:患者就诊流程
|
||||
|
||||
```
|
||||
医生为患者 #4521 开启接诊
|
||||
→ 固定头部显示:"Rajesh M, 58岁, 男性, 过敏史: 青霉素, 当前用药: 二甲双胍 500mg"
|
||||
→ 主诉:选择"胸痛"模板
|
||||
→ 点击标签:"胸骨后", "向左臂放射", "压榨性"
|
||||
→ 红色预警"压榨性胸骨后胸痛"触发不可关闭的警报
|
||||
→ 检查:心血管系统 — "S1 S2 正常,无杂音"
|
||||
→ 生命体征:心率 110, 血压 90/60, 血氧饱和度 94%
|
||||
→ NEWS2 自动计算:评分 8, 风险 高, 显示升级警报
|
||||
→ 诊断:搜索"ACS" → 选择 ICD-10 I21.9
|
||||
→ 用药:选择阿司匹林 300mg
|
||||
→ CDSS 检查与二甲双胍的相互作用:无相互作用
|
||||
→ 签署接诊 → 锁定,此后仅可添加补充说明
|
||||
```
|
||||
|
||||
### 示例2:用药安全工作流
|
||||
|
||||
```
|
||||
医生为患者 #4521 开具华法林处方
|
||||
→ CDSS 检测到:华法林 + 阿司匹林 = 严重相互作用
|
||||
→ 用户界面:红色不可关闭的模态框阻止开药
|
||||
→ 医生点击“输入理由并覆盖”
|
||||
→ 输入:“获益大于风险 — 已监测 INR 方案”
|
||||
→ 覆盖理由及警报记录在审计追踪中
|
||||
→ 处方在记录覆盖后继续执行
|
||||
```
|
||||
|
||||
### 示例3:锁定就诊 + 附录
|
||||
|
||||
```
|
||||
Encounter #E-2024-0891 signed by Dr. Shah at 14:30
|
||||
→ All fields locked — no edit buttons visible
|
||||
→ "Add Addendum" button available
|
||||
→ Dr. Shah clicks addendum, adds: "Lab results received — Troponin elevated"
|
||||
→ New record E-2024-0891-A1 linked to original
|
||||
→ Timeline shows both: original encounter + addendum with timestamps
|
||||
```
|
||||
207
docs/zh-CN/skills/healthcare-eval-harness/SKILL.md
Normal file
207
docs/zh-CN/skills/healthcare-eval-harness/SKILL.md
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
name: healthcare-eval-harness
|
||||
description: 用于医疗应用部署的患者安全评估工具。针对CDSS准确性、PHI暴露、临床工作流完整性和集成合规性的自动化测试套件。在安全故障时阻止部署。
|
||||
origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# 医疗评估框架 — 患者安全验证
|
||||
|
||||
医疗应用部署的自动化验证系统。单个严重故障将阻止部署。患者安全不容妥协。
|
||||
|
||||
> **注意:** 示例使用 Jest 作为参考测试运行器。请根据您的框架(Vitest、pytest、PHPUnit 等)调整命令——测试类别和通过阈值与框架无关。
|
||||
|
||||
## 使用场景
|
||||
|
||||
* 部署任何 EMR/EHR 应用之前
|
||||
* 修改 CDSS 逻辑(药物相互作用、剂量验证、评分)之后
|
||||
* 更改涉及患者数据的数据库模式之后
|
||||
* 修改身份验证或访问控制之后
|
||||
* 配置医疗应用 CI/CD 流水线期间
|
||||
* 解决临床模块合并冲突之后
|
||||
|
||||
## 工作原理
|
||||
|
||||
评估框架按顺序运行五个测试类别。前三个(CDSS 准确性、PHI 暴露、数据完整性)是严重关卡,要求 100% 通过率——单个故障即阻止部署。其余两个(临床工作流、集成)是高优先级关卡,要求 95% 以上通过率。
|
||||
|
||||
每个类别对应一个 Jest 测试路径模式。CI 流水线使用 `--bail`(首次失败即停止)运行严重关卡,并使用 `--coverage --coverageThreshold` 强制执行覆盖率阈值。
|
||||
|
||||
### 评估类别
|
||||
|
||||
**1. CDSS 准确性(严重 — 要求 100%)**
|
||||
|
||||
测试所有临床决策支持逻辑:药物相互作用对(双向)、剂量验证规则、临床评分与发布规范的对比、无假阴性、无静默故障。
|
||||
|
||||
```bash
|
||||
npx jest --testPathPattern='tests/cdss' --bail --ci --coverage
|
||||
```
|
||||
|
||||
**2. PHI 暴露(严重 — 要求 100%)**
|
||||
|
||||
测试受保护健康信息泄露:API 错误响应、控制台输出、URL 参数、浏览器存储、跨机构隔离、未认证访问、服务角色密钥缺失。
|
||||
|
||||
```bash
|
||||
npx jest --testPathPattern='tests/security/phi' --bail --ci
|
||||
```
|
||||
|
||||
**3. 数据完整性(严重 — 要求 100%)**
|
||||
|
||||
测试临床数据安全:锁定就诊记录、审计追踪条目、级联删除保护、并发编辑处理、无孤立记录。
|
||||
|
||||
```bash
|
||||
npx jest --testPathPattern='tests/data-integrity' --bail --ci
|
||||
```
|
||||
|
||||
**4. 临床工作流(高优先级 — 要求 95% 以上)**
|
||||
|
||||
测试端到端流程:就诊生命周期、模板渲染、用药集、药物/诊断搜索、处方 PDF、红色警报。
|
||||
|
||||
```bash
|
||||
tmp_json=$(mktemp)
|
||||
npx jest --testPathPattern='tests/clinical' --ci --json --outputFile="$tmp_json" || true
|
||||
total=$(jq '.numTotalTests // 0' "$tmp_json")
|
||||
passed=$(jq '.numPassedTests // 0' "$tmp_json")
|
||||
if [ "$total" -eq 0 ]; then
|
||||
echo "No clinical tests found" >&2
|
||||
exit 1
|
||||
fi
|
||||
rate=$(echo "scale=2; $passed * 100 / $total" | bc)
|
||||
echo "Clinical pass rate: ${rate}% ($passed/$total)"
|
||||
```
|
||||
|
||||
**5. 集成合规性(高优先级 — 要求 95% 以上)**
|
||||
|
||||
测试外部系统:HL7 消息解析(v2.x)、FHIR 验证、实验室结果映射、格式错误消息处理。
|
||||
|
||||
```bash
|
||||
tmp_json=$(mktemp)
|
||||
npx jest --testPathPattern='tests/integration' --ci --json --outputFile="$tmp_json" || true
|
||||
total=$(jq '.numTotalTests // 0' "$tmp_json")
|
||||
passed=$(jq '.numPassedTests // 0' "$tmp_json")
|
||||
if [ "$total" -eq 0 ]; then
|
||||
echo "No integration tests found" >&2
|
||||
exit 1
|
||||
fi
|
||||
rate=$(echo "scale=2; $passed * 100 / $total" | bc)
|
||||
echo "Integration pass rate: ${rate}% ($passed/$total)"
|
||||
```
|
||||
|
||||
### 通过/失败矩阵
|
||||
|
||||
| 类别 | 阈值 | 失败时操作 |
|
||||
|----------|-----------|------------|
|
||||
| CDSS 准确性 | 100% | **阻止部署** |
|
||||
| PHI 暴露 | 100% | **阻止部署** |
|
||||
| 数据完整性 | 100% | **阻止部署** |
|
||||
| 临床工作流 | 95% 以上 | 警告,允许经审查后部署 |
|
||||
| 集成 | 95% 以上 | 警告,允许经审查后部署 |
|
||||
|
||||
### CI/CD 集成
|
||||
|
||||
```yaml
|
||||
name: Healthcare Safety Gate
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
safety-gate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
- run: npm ci
|
||||
|
||||
# CRITICAL gates — 100% required, bail on first failure
|
||||
- name: CDSS Accuracy
|
||||
run: npx jest --testPathPattern='tests/cdss' --bail --ci --coverage --coverageThreshold='{"global":{"branches":80,"functions":80,"lines":80}}'
|
||||
|
||||
- name: PHI Exposure Check
|
||||
run: npx jest --testPathPattern='tests/security/phi' --bail --ci
|
||||
|
||||
- name: Data Integrity
|
||||
run: npx jest --testPathPattern='tests/data-integrity' --bail --ci
|
||||
|
||||
# HIGH gates — 95%+ required, custom threshold check
|
||||
# HIGH gates — 95%+ required
|
||||
- name: Clinical Workflows
|
||||
run: |
|
||||
TMP_JSON=$(mktemp)
|
||||
npx jest --testPathPattern='tests/clinical' --ci --json --outputFile="$TMP_JSON" || true
|
||||
TOTAL=$(jq '.numTotalTests // 0' "$TMP_JSON")
|
||||
PASSED=$(jq '.numPassedTests // 0' "$TMP_JSON")
|
||||
if [ "$TOTAL" -eq 0 ]; then
|
||||
echo "::error::No clinical tests found"; exit 1
|
||||
fi
|
||||
RATE=$(echo "scale=2; $PASSED * 100 / $TOTAL" | bc)
|
||||
echo "Pass rate: ${RATE}% ($PASSED/$TOTAL)"
|
||||
if (( $(echo "$RATE < 95" | bc -l) )); then
|
||||
echo "::warning::Clinical pass rate ${RATE}% below 95%"
|
||||
fi
|
||||
|
||||
- name: Integration Compliance
|
||||
run: |
|
||||
TMP_JSON=$(mktemp)
|
||||
npx jest --testPathPattern='tests/integration' --ci --json --outputFile="$TMP_JSON" || true
|
||||
TOTAL=$(jq '.numTotalTests // 0' "$TMP_JSON")
|
||||
PASSED=$(jq '.numPassedTests // 0' "$TMP_JSON")
|
||||
if [ "$TOTAL" -eq 0 ]; then
|
||||
echo "::error::No integration tests found"; exit 1
|
||||
fi
|
||||
RATE=$(echo "scale=2; $PASSED * 100 / $TOTAL" | bc)
|
||||
echo "Pass rate: ${RATE}% ($PASSED/$TOTAL)"
|
||||
if (( $(echo "$RATE < 95" | bc -l) )); then
|
||||
echo "::warning::Integration pass rate ${RATE}% below 95%"
|
||||
fi
|
||||
```
|
||||
|
||||
### 反模式
|
||||
|
||||
* 跳过 CDSS 测试,因为"上次通过了"
|
||||
* 将严重关卡阈值设为低于 100%
|
||||
* 在严重测试套件中使用 `--no-bail`
|
||||
* 在集成测试中模拟 CDSS 引擎(必须测试真实逻辑)
|
||||
* 安全关卡为红色时仍允许部署
|
||||
* 在 CDSS 套件中运行测试时不使用 `--coverage`
|
||||
|
||||
## 示例
|
||||
|
||||
### 示例 1:本地运行所有严重关卡
|
||||
|
||||
```bash
|
||||
npx jest --testPathPattern='tests/cdss' --bail --ci --coverage && \
|
||||
npx jest --testPathPattern='tests/security/phi' --bail --ci && \
|
||||
npx jest --testPathPattern='tests/data-integrity' --bail --ci
|
||||
```
|
||||
|
||||
### 示例 2:检查高优先级关卡通过率
|
||||
|
||||
```bash
|
||||
tmp_json=$(mktemp)
|
||||
npx jest --testPathPattern='tests/clinical' --ci --json --outputFile="$tmp_json" || true
|
||||
jq '{
|
||||
passed: (.numPassedTests // 0),
|
||||
total: (.numTotalTests // 0),
|
||||
rate: (if (.numTotalTests // 0) == 0 then 0 else ((.numPassedTests // 0) / (.numTotalTests // 1) * 100) end)
|
||||
}' "$tmp_json"
|
||||
# Expected: { "passed": 21, "total": 22, "rate": 95.45 }
|
||||
```
|
||||
|
||||
### 示例 3:评估报告
|
||||
|
||||
```
|
||||
## 医疗评估:2026-03-27 [commit abc1234]
|
||||
|
||||
### 患者安全:通过
|
||||
|
||||
| 类别 | 测试数 | 通过 | 失败 | 状态 |
|
||||
|----------|-------|------|------|--------|
|
||||
| CDSS 准确性 | 39 | 39 | 0 | 通过 |
|
||||
| PHI 暴露 | 8 | 8 | 0 | 通过 |
|
||||
| 数据完整性 | 12 | 12 | 0 | 通过 |
|
||||
| 临床工作流 | 22 | 21 | 1 | 95.5% 通过 |
|
||||
| 集成 | 6 | 6 | 0 | 通过 |
|
||||
|
||||
### 覆盖率:84%(目标:80%以上)
|
||||
### 结论:可安全部署
|
||||
```
|
||||
146
docs/zh-CN/skills/healthcare-phi-compliance/SKILL.md
Normal file
146
docs/zh-CN/skills/healthcare-phi-compliance/SKILL.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
name: healthcare-phi-compliance
|
||||
description: 医疗应用中受保护健康信息(PHI)和个人身份信息(PII)的合规模式。涵盖数据分类、访问控制、审计追踪、加密及常见泄露途径。
|
||||
origin: Health1 Super Speciality Hospitals — contributed by Dr. Keyur Patel
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# 医疗 PHI/PII 合规模式
|
||||
|
||||
用于保护医疗应用中患者数据、临床医生数据和财务数据的模式。适用于 HIPAA(美国)、DISHA(印度)、GDPR(欧盟)以及通用医疗数据保护。
|
||||
|
||||
## 何时使用
|
||||
|
||||
* 构建任何涉及患者记录的功能
|
||||
* 为临床系统实施访问控制或身份验证
|
||||
* 设计医疗数据的数据库模式
|
||||
* 构建返回患者或临床医生数据的 API
|
||||
* 实施审计追踪或日志记录
|
||||
* 审查代码中的数据泄露漏洞
|
||||
* 为多租户医疗系统设置行级安全(RLS)
|
||||
|
||||
## 工作原理
|
||||
|
||||
医疗数据保护在三个层面运作:**分类**(什么是敏感数据)、**访问控制**(谁能查看)和**审计**(谁查看了数据)。
|
||||
|
||||
### 数据分类
|
||||
|
||||
**PHI(受保护健康信息)** — 任何能够识别患者身份且与其健康相关的数据:患者姓名、出生日期、地址、电话、电子邮件、国家身份证号码(SSN、Aadhaar、NHS 号码)、病历号、诊断、药物、化验结果、影像资料、保险单和理赔详情、预约和入院记录,或上述任意组合。
|
||||
|
||||
**医疗系统中的 PII(非患者敏感数据)**:临床医生/员工个人详细信息、医生收费结构和支付金额、员工薪资和银行信息、供应商付款信息。
|
||||
|
||||
### 访问控制:行级安全
|
||||
|
||||
```sql
|
||||
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Scope access by facility
|
||||
CREATE POLICY "staff_read_own_facility"
|
||||
ON patients FOR SELECT TO authenticated
|
||||
USING (facility_id IN (
|
||||
SELECT facility_id FROM staff_assignments
|
||||
WHERE user_id = auth.uid() AND role IN ('doctor','nurse','lab_tech','admin')
|
||||
));
|
||||
|
||||
-- Audit log: insert-only (tamper-proof)
|
||||
CREATE POLICY "audit_insert_only" ON audit_log FOR INSERT
|
||||
TO authenticated WITH CHECK (user_id = auth.uid());
|
||||
CREATE POLICY "audit_no_modify" ON audit_log FOR UPDATE USING (false);
|
||||
CREATE POLICY "audit_no_delete" ON audit_log FOR DELETE USING (false);
|
||||
```
|
||||
|
||||
### 审计追踪
|
||||
|
||||
每次 PHI 访问或修改都必须记录:
|
||||
|
||||
```typescript
|
||||
interface AuditEntry {
|
||||
timestamp: string;
|
||||
user_id: string;
|
||||
patient_id: string;
|
||||
action: 'create' | 'read' | 'update' | 'delete' | 'print' | 'export';
|
||||
resource_type: string;
|
||||
resource_id: string;
|
||||
changes?: { before: object; after: object };
|
||||
ip_address: string;
|
||||
session_id: string;
|
||||
}
|
||||
```
|
||||
|
||||
### 常见泄露途径
|
||||
|
||||
**错误消息:** 切勿在发送给客户端的错误消息中包含患者身份识别数据。仅在服务器端记录详细信息。
|
||||
|
||||
**控制台输出:** 切勿记录完整的患者对象。使用不透明的内部记录 ID(UUID)——而不是病历号、国家身份证号或姓名。
|
||||
|
||||
**URL 参数:** 切勿在可能出现在日志或浏览器历史记录中的查询字符串或路径段中包含患者身份识别数据。仅使用不透明的 UUID。
|
||||
|
||||
**浏览器存储:** 切勿在 localStorage 或 sessionStorage 中存储 PHI。仅在内存中保留 PHI,按需获取。
|
||||
|
||||
**服务角色密钥:** 切勿在客户端代码中使用 service\_role 密钥。始终使用匿名/可发布密钥,并让 RLS 强制执行访问控制。
|
||||
|
||||
**日志和监控:** 切勿记录完整的患者记录。仅使用不透明的记录 ID(而不是病历号)。在发送到错误跟踪服务之前,清理堆栈跟踪。
|
||||
|
||||
### 数据库模式标记
|
||||
|
||||
在模式级别标记 PHI/PII 列:
|
||||
|
||||
```sql
|
||||
COMMENT ON COLUMN patients.name IS 'PHI: patient_name';
|
||||
COMMENT ON COLUMN patients.dob IS 'PHI: date_of_birth';
|
||||
COMMENT ON COLUMN patients.aadhaar IS 'PHI: national_id';
|
||||
COMMENT ON COLUMN doctor_payouts.amount IS 'PII: financial';
|
||||
```
|
||||
|
||||
### 部署检查清单
|
||||
|
||||
每次部署前:
|
||||
|
||||
* 错误消息或堆栈跟踪中无 PHI
|
||||
* console.log/console.error 中无 PHI
|
||||
* URL 参数中无 PHI
|
||||
* 浏览器存储中无 PHI
|
||||
* 客户端代码中无 service\_role 密钥
|
||||
* 所有 PHI/PII 表已启用 RLS
|
||||
* 所有数据修改均有审计追踪
|
||||
* 已配置会话超时
|
||||
* 所有 PHI 端点均需 API 身份验证
|
||||
* 已验证跨机构数据隔离
|
||||
|
||||
## 示例
|
||||
|
||||
### 示例 1:安全与不安全的错误处理
|
||||
|
||||
```typescript
|
||||
// BAD — leaks PHI in error
|
||||
throw new Error(`Patient ${patient.name} not found in ${patient.facility}`);
|
||||
|
||||
// GOOD — generic error, details logged server-side with opaque IDs only
|
||||
logger.error('Patient lookup failed', { recordId: patient.id, facilityId });
|
||||
throw new Error('Record not found');
|
||||
```
|
||||
|
||||
### 示例 2:多机构隔离的 RLS 策略
|
||||
|
||||
```sql
|
||||
-- Doctor at Facility A cannot see Facility B patients
|
||||
CREATE POLICY "facility_isolation"
|
||||
ON patients FOR SELECT TO authenticated
|
||||
USING (facility_id IN (
|
||||
SELECT facility_id FROM staff_assignments WHERE user_id = auth.uid()
|
||||
));
|
||||
|
||||
-- Test: login as doctor-facility-a, query facility-b patients
|
||||
-- Expected: 0 rows returned
|
||||
```
|
||||
|
||||
### 示例 3:安全日志记录
|
||||
|
||||
```typescript
|
||||
// BAD — logs identifiable patient data
|
||||
console.log('Processing patient:', patient);
|
||||
|
||||
// GOOD — logs only opaque internal record ID
|
||||
console.log('Processing record:', patient.id);
|
||||
// Note: even patient.id should be an opaque UUID, not a medical record number
|
||||
```
|
||||
78
docs/zh-CN/skills/hipaa-compliance/SKILL.md
Normal file
78
docs/zh-CN/skills/hipaa-compliance/SKILL.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: hipaa-compliance
|
||||
description: 针对医疗隐私和安全工作的HIPAA特定入口点。当任务明确围绕HIPAA、PHI处理、受保实体、BAA、违规态势或美国医疗合规要求时使用。
|
||||
origin: ECC direct-port adaptation
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# HIPAA 合规
|
||||
|
||||
当任务明确涉及美国医疗合规时,以此作为 HIPAA 专用入口。此技能刻意保持精简和规范:
|
||||
|
||||
* `healthcare-phi-compliance` 仍是处理 PHI/PII、数据分类、审计日志、加密和泄露防护的主要实施技能。
|
||||
* `healthcare-reviewer` 仍是当代码、架构或产品行为需要医疗感知的二次审查时的专业审核者。
|
||||
* `security-review` 仍适用于通用认证、输入处理、密钥、API 和部署加固。
|
||||
|
||||
## 使用时机
|
||||
|
||||
* 请求明确提及 HIPAA、PHI、受保实体、业务伙伴或 BAA
|
||||
* 构建或审查存储、处理、导出或传输 PHI 的美国医疗软件
|
||||
* 评估日志记录、分析、LLM 提示、存储或支持工作流是否产生 HIPAA 暴露风险
|
||||
* 设计面向患者或临床医生的系统时,需关注最小必要访问和可审计性
|
||||
|
||||
## 工作原理
|
||||
|
||||
将 HIPAA 视为覆盖在更广泛的医疗隐私技能之上的叠加层:
|
||||
|
||||
1. 从 `healthcare-phi-compliance` 开始,获取具体的实施规则。
|
||||
2. 应用 HIPAA 专用决策门:
|
||||
* 这些数据是否为 PHI?
|
||||
* 该行为者是否为受保实体或业务伙伴?
|
||||
* 供应商或模型提供商在接触数据前是否需要 BAA?
|
||||
* 访问权限是否限制在最小必要范围内?
|
||||
* 读/写/导出事件是否可审计?
|
||||
3. 如果任务影响患者安全、临床工作流或受监管的生产架构,则升级至 `healthcare-reviewer`。
|
||||
|
||||
## HIPAA 专用防护栏
|
||||
|
||||
* 切勿将 PHI 置于日志、分析事件、崩溃报告、提示或客户端可见的错误字符串中。
|
||||
* 切勿在 URL、浏览器存储、截图或复制的示例负载中暴露 PHI。
|
||||
* 要求对 PHI 的读写操作进行认证访问、范围授权并保留审计追踪。
|
||||
* 默认将第三方 SaaS、可观测性、支持工具和 LLM 提供商视为禁止状态,直至明确其 BAA 状态和数据边界。
|
||||
* 遵循最小必要访问原则:正确的用户应仅看到完成任务所需的最小 PHI 片段。
|
||||
* 优先使用不透明的内部 ID,而非姓名、病历号、电话号码、地址或其他标识符。
|
||||
|
||||
## 示例
|
||||
|
||||
### 示例 1:以 HIPAA 为框架的产品需求
|
||||
|
||||
用户请求:
|
||||
|
||||
> 为我们的临床医生仪表板添加 AI 生成的就诊摘要。我们服务美国诊所,需保持 HIPAA 合规。
|
||||
|
||||
响应模式:
|
||||
|
||||
* 激活 `hipaa-compliance`
|
||||
* 使用 `healthcare-phi-compliance` 审查 PHI 流动、日志记录、存储和提示边界
|
||||
* 在发送任何 PHI 前,验证摘要生成提供商是否受 BAA 覆盖
|
||||
* 如果摘要影响临床决策,则升级至 `healthcare-reviewer`
|
||||
|
||||
### 示例 2:供应商/工具决策
|
||||
|
||||
用户请求:
|
||||
|
||||
> 我们可以将支持对话记录和患者消息发送到分析平台吗?
|
||||
|
||||
响应模式:
|
||||
|
||||
* 假设这些消息可能包含 PHI
|
||||
* 除非分析供应商已获批准处理 HIPAA 约束的工作负载且数据路径已最小化,否则阻止该设计
|
||||
* 尽可能要求进行脱敏处理或采用非 PHI 事件模型
|
||||
|
||||
## 相关技能
|
||||
|
||||
* `healthcare-phi-compliance`
|
||||
* `healthcare-reviewer`
|
||||
* `healthcare-emr-patterns`
|
||||
* `healthcare-eval-harness`
|
||||
* `security-review`
|
||||
146
docs/zh-CN/skills/llm-trading-agent-security/SKILL.md
Normal file
146
docs/zh-CN/skills/llm-trading-agent-security/SKILL.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
name: llm-trading-agent-security
|
||||
description: 具有钱包或交易权限的自主交易代理的安全模式。涵盖提示注入、支出限制、发送前模拟、断路器、MEV保护和密钥处理。
|
||||
origin: ECC direct-port adaptation
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# LLM 交易代理安全
|
||||
|
||||
自主交易代理面临比普通 LLM 应用更严苛的威胁模型:一次注入或错误的工具路径可能直接导致资产损失。
|
||||
|
||||
## 适用场景
|
||||
|
||||
* 构建能够签署并发送交易的 AI 代理
|
||||
* 审计交易机器人或链上执行助手
|
||||
* 为代理设计钱包密钥管理方案
|
||||
* 授予 LLM 订单下达、代币兑换或资金操作权限
|
||||
|
||||
## 工作原理
|
||||
|
||||
构建多层防御体系。单一检查不足以保障安全。应将提示词卫生、支出策略、模拟执行、执行限制和钱包隔离视为独立控制措施。
|
||||
|
||||
## 示例
|
||||
|
||||
### 将提示注入视为金融攻击
|
||||
|
||||
```python
|
||||
import re
|
||||
|
||||
INJECTION_PATTERNS = [
|
||||
r'ignore (previous|all) instructions',
|
||||
r'new (task|directive|instruction)',
|
||||
r'system prompt',
|
||||
r'send .{0,50} to 0x[0-9a-fA-F]{40}',
|
||||
r'transfer .{0,50} to',
|
||||
r'approve .{0,50} for',
|
||||
]
|
||||
|
||||
def sanitize_onchain_data(text: str) -> str:
|
||||
for pattern in INJECTION_PATTERNS:
|
||||
if re.search(pattern, text, re.IGNORECASE):
|
||||
raise ValueError(f"Potential prompt injection: {text[:100]}")
|
||||
return text
|
||||
```
|
||||
|
||||
切勿将代币名称、交易对标签、网络钩子或社交信息流盲目注入具备执行能力的提示词中。
|
||||
|
||||
### 硬性支出限额
|
||||
|
||||
```python
|
||||
from decimal import Decimal
|
||||
|
||||
MAX_SINGLE_TX_USD = Decimal("500")
|
||||
MAX_DAILY_SPEND_USD = Decimal("2000")
|
||||
|
||||
class SpendLimitError(Exception):
|
||||
pass
|
||||
|
||||
class SpendLimitGuard:
|
||||
def check_and_record(self, usd_amount: Decimal) -> None:
|
||||
if usd_amount > MAX_SINGLE_TX_USD:
|
||||
raise SpendLimitError(f"Single tx ${usd_amount} exceeds max ${MAX_SINGLE_TX_USD}")
|
||||
|
||||
daily = self._get_24h_spend()
|
||||
if daily + usd_amount > MAX_DAILY_SPEND_USD:
|
||||
raise SpendLimitError(f"Daily limit: ${daily} + ${usd_amount} > ${MAX_DAILY_SPEND_USD}")
|
||||
|
||||
self._record_spend(usd_amount)
|
||||
```
|
||||
|
||||
### 发送前模拟执行
|
||||
|
||||
```python
|
||||
class SlippageError(Exception):
|
||||
pass
|
||||
|
||||
async def safe_execute(self, tx: dict, expected_min_out: int | None = None) -> str:
|
||||
sim_result = await self.w3.eth.call(tx)
|
||||
|
||||
if expected_min_out is None:
|
||||
raise ValueError("min_amount_out is required before send")
|
||||
|
||||
actual_out = decode_uint256(sim_result)
|
||||
if actual_out < expected_min_out:
|
||||
raise SlippageError(f"Simulation: {actual_out} < {expected_min_out}")
|
||||
|
||||
signed = self.account.sign_transaction(tx)
|
||||
return await self.w3.eth.send_raw_transaction(signed.raw_transaction)
|
||||
```
|
||||
|
||||
### 断路器机制
|
||||
|
||||
```python
|
||||
class TradingCircuitBreaker:
|
||||
MAX_CONSECUTIVE_LOSSES = 3
|
||||
MAX_HOURLY_LOSS_PCT = 0.05
|
||||
|
||||
def check(self, portfolio_value: float) -> None:
|
||||
if self.consecutive_losses >= self.MAX_CONSECUTIVE_LOSSES:
|
||||
self.halt("Too many consecutive losses")
|
||||
|
||||
if self.hour_start_value <= 0:
|
||||
self.halt("Invalid hour_start_value")
|
||||
return
|
||||
|
||||
hourly_pnl = (portfolio_value - self.hour_start_value) / self.hour_start_value
|
||||
if hourly_pnl < -self.MAX_HOURLY_LOSS_PCT:
|
||||
self.halt(f"Hourly PnL {hourly_pnl:.1%} below threshold")
|
||||
```
|
||||
|
||||
### 钱包隔离
|
||||
|
||||
```python
|
||||
import os
|
||||
from eth_account import Account
|
||||
|
||||
private_key = os.environ.get("TRADING_WALLET_PRIVATE_KEY")
|
||||
if not private_key:
|
||||
raise EnvironmentError("TRADING_WALLET_PRIVATE_KEY not set")
|
||||
|
||||
account = Account.from_key(private_key)
|
||||
```
|
||||
|
||||
使用仅包含所需会话资金的专用热钱包。切勿将代理指向主资金钱包。
|
||||
|
||||
### MEV 与截止时间保护
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
PRIVATE_RPC = "https://rpc.flashbots.net"
|
||||
MAX_SLIPPAGE_BPS = {"stable": 10, "volatile": 50}
|
||||
deadline = int(time.time()) + 60
|
||||
```
|
||||
|
||||
## 部署前检查清单
|
||||
|
||||
* 外部数据在进入 LLM 上下文前已完成清理
|
||||
* 支出限额独立于模型输出强制执行
|
||||
* 交易在发送前经过模拟
|
||||
* `min_amount_out` 为强制要求
|
||||
* 断路器在出现回撤或无效状态时触发
|
||||
* 密钥来自环境变量或密钥管理器,绝不写入代码或日志
|
||||
* 在适当时使用私有内存池或受保护路由
|
||||
* 根据策略设置滑点和截止时间
|
||||
* 所有代理决策均记录审计日志,不仅限于成功发送的交易
|
||||
75
docs/zh-CN/skills/safety-guard/SKILL.md
Normal file
75
docs/zh-CN/skills/safety-guard/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: safety-guard
|
||||
description: 使用此技能可防止在生产系统上工作或自主运行代理时进行破坏性操作。
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# 安全防护 — 防止破坏性操作
|
||||
|
||||
## 使用场景
|
||||
|
||||
* 在生产系统上工作时
|
||||
* 代理以全自动模式运行时
|
||||
* 希望将编辑限制在特定目录时
|
||||
* 敏感操作期间(迁移、部署、数据变更)
|
||||
|
||||
## 工作原理
|
||||
|
||||
三种保护模式:
|
||||
|
||||
### 模式 1:谨慎模式
|
||||
|
||||
在执行破坏性命令前进行拦截并发出警告:
|
||||
|
||||
```
|
||||
已监控的模式:
|
||||
- rm -rf(特别是 /、~ 或项目根目录)
|
||||
- git push --force
|
||||
- git reset --hard
|
||||
- git checkout .(丢弃所有更改)
|
||||
- DROP TABLE / DROP DATABASE
|
||||
- docker system prune
|
||||
- kubectl delete
|
||||
- chmod 777
|
||||
- sudo rm
|
||||
- npm publish(意外发布)
|
||||
- 任何带有 --no-verify 的命令
|
||||
```
|
||||
|
||||
检测到时:显示命令功能、请求确认、建议更安全的替代方案。
|
||||
|
||||
### 模式 2:冻结模式
|
||||
|
||||
将文件编辑锁定到特定目录树:
|
||||
|
||||
```
|
||||
/safety-guard freeze src/components/
|
||||
```
|
||||
|
||||
任何在 `src/components/` 之外的写入/编辑操作都会被阻止并附带说明。适用于希望代理专注于某个区域而不触及无关代码的场景。
|
||||
|
||||
### 模式 3:守护模式(谨慎+冻结组合)
|
||||
|
||||
双重保护同时生效。为自主代理提供最高安全性。
|
||||
|
||||
```
|
||||
/safety-guard guard --dir src/api/ --allow-read-all
|
||||
```
|
||||
|
||||
代理可读取任何内容,但仅能写入 `src/api/`。破坏性命令在所有位置均被阻止。
|
||||
|
||||
### 解锁
|
||||
|
||||
```
|
||||
/safety-guard off
|
||||
```
|
||||
|
||||
## 实现方式
|
||||
|
||||
通过 PreToolUse 钩子拦截 Bash、Write、Edit 和 MultiEdit 工具调用。在执行前根据活动规则检查命令/路径。
|
||||
|
||||
## 集成方案
|
||||
|
||||
* 默认在 `codex -a never` 会话中启用
|
||||
* 配合 ECC 2.0 的可观测性风险评分
|
||||
* 所有被阻止的操作记录至 `~/.claude/safety-guard.log`
|
||||
99
docs/zh-CN/skills/security-bounty-hunter/SKILL.md
Normal file
99
docs/zh-CN/skills/security-bounty-hunter/SKILL.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
name: security-bounty-hunter
|
||||
description: 在仓库中寻找可利用、值得赏金的安全问题。专注于远程可访问的漏洞,这些漏洞符合实际报告的条件,而不是嘈杂的仅本地发现。
|
||||
origin: ECC direct-port adaptation
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# 安全赏金猎人
|
||||
|
||||
当目标是针对负责任披露或赏金提交的实际漏洞发现,而非广泛的实践审查时使用此方法。
|
||||
|
||||
## 使用场景
|
||||
|
||||
* 扫描代码库以发现可利用漏洞
|
||||
* 准备 Huntr、HackerOne 或类似赏金平台的提交材料
|
||||
* 判断"这个漏洞是否真的能获得赏金"而非"理论上是否不安全"的优先级分类
|
||||
|
||||
## 工作原理
|
||||
|
||||
优先关注远程可达、用户可控的攻击路径,并剔除平台通常判定为信息性或超出范围的模式。
|
||||
|
||||
## 有效模式
|
||||
|
||||
以下是持续具有影响力的漏洞类型:
|
||||
|
||||
| 模式 | CWE | 典型影响 |
|
||||
| --- | --- | --- |
|
||||
| 通过用户可控URL的SSRF | CWE-918 | 内网访问、云元数据窃取 |
|
||||
| 中间件或API防护中的认证绕过 | CWE-287 | 未授权账户或数据访问 |
|
||||
| 远程反序列化或上传至RCE路径 | CWE-502 | 代码执行 |
|
||||
| 可达端点中的SQL注入 | CWE-89 | 数据泄露、认证绕过、数据破坏 |
|
||||
| 请求处理程序中的命令注入 | CWE-78 | 代码执行 |
|
||||
| 文件服务路径中的路径遍历 | CWE-22 | 任意文件读取或写入 |
|
||||
| 自动触发的XSS | CWE-79 | 会话窃取、管理员权限沦陷 |
|
||||
|
||||
## 跳过这些
|
||||
|
||||
除非项目另有说明,以下通常属于低信号或超出赏金范围:
|
||||
|
||||
* 仅限本地的 `pickle.loads`、`torch.load` 或等效且无远程路径的漏洞
|
||||
* 仅限CLI工具中的 `eval()` 或 `exec()`
|
||||
* 完全硬编码命令上的 `shell=True`
|
||||
* 单独缺失安全标头
|
||||
* 无利用影响的通用速率限制投诉
|
||||
* 需要受害者手动粘贴代码的自XSS
|
||||
* 不属于目标项目范围的CI/CD注入
|
||||
* 演示、示例或仅测试代码
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. 首先检查范围:项目规则、SECURITY.md、披露渠道和排除项。
|
||||
2. 寻找真实入口点:HTTP处理器、上传功能、后台任务、Webhook、解析器和集成端点。
|
||||
3. 在适用时运行静态工具,但仅将其作为分类输入。
|
||||
4. 从头到尾阅读实际代码路径。
|
||||
5. 证明用户控制能到达有意义的接收点。
|
||||
6. 使用最小安全PoC确认可利用性和影响。
|
||||
7. 在起草报告前检查重复项。
|
||||
|
||||
## 分类循环示例
|
||||
|
||||
```bash
|
||||
semgrep --config=auto --severity=ERROR --severity=WARNING --json
|
||||
```
|
||||
|
||||
然后手动过滤:
|
||||
|
||||
* 删除测试、演示、固定代码、供应商代码
|
||||
* 删除仅限本地或不可达路径
|
||||
* 仅保留具有明确网络或用户控制路由的发现
|
||||
|
||||
## 报告结构
|
||||
|
||||
```markdown
|
||||
## 描述
|
||||
[漏洞是什么及其重要性]
|
||||
|
||||
## 漏洞代码
|
||||
[文件路径、行号范围及代码片段]
|
||||
|
||||
## 概念验证
|
||||
[最小化可运行的请求或脚本]
|
||||
|
||||
## 影响
|
||||
[攻击者能够实现的目标]
|
||||
|
||||
## 受影响版本
|
||||
[已测试的版本、提交或部署目标]
|
||||
```
|
||||
|
||||
## 质量关卡
|
||||
|
||||
提交前需确认:
|
||||
|
||||
* 代码路径可从真实用户或网络边界到达
|
||||
* 输入确实由用户控制
|
||||
* 接收点有意义且可利用
|
||||
* PoC有效
|
||||
* 该问题尚未被公告、CVE或公开工单覆盖
|
||||
* 目标确实在赏金计划范围内
|
||||
Reference in New Issue
Block a user