shellward 0.7.8 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -141,9 +141,10 @@ function computeProjectPenalty(scan) {
141
141
  return Math.min(MAX_PROJECT_PENALTY, p);
142
142
  }
143
143
  function checkControl(c, config, env, deployed) {
144
- // 静态扫描(未部署运行时)下,能力层/审计日志类控制项无法验证 —— 标为顾问态,绝不虚报"已合规"
144
+ // 静态扫描(未部署运行时)下,能力层/审计日志类控制项无法验证 —— 标为顾问态,绝不虚报"已合规"
145
+ // 「为何待核验」统一在报告区块开头说一次;这里每行只留"该做什么",避免 12 行重复同一句。
145
146
  if (!deployed && (c.method === 'capability' || c.method === 'config' || c.method === 'audit')) {
146
- return mk(c, 'manual', `ShellWard 运行时可提供此防护;当前为静态扫描、未部署,无法验证。整改:${c.remediation_zh}`, `Provided by ShellWard runtime; not verifiable in a static scan. ${c.remediation_en}`);
147
+ return mk(c, 'manual', c.remediation_zh, c.remediation_en);
147
148
  }
148
149
  switch (c.method) {
149
150
  case 'capability': return checkCapability(c, config);
@@ -137,7 +137,10 @@ export function renderHtmlReport(report, scan, locale, meta) {
137
137
  S.push(`<p class="note">💡 ${t('对使用 openai SDK 的项目:通常仅需把 base_url 与 api_key 换成上表任一境内模型即可,业务代码无需改动。', 'For openai-SDK projects: usually just swap base_url + api_key — no code change.')}</p>`);
138
138
  }
139
139
  // ===== 控制项明细 =====
140
- S.push(sectionHead('📋', t('合规控制项明细', 'Compliance Controls'), t('按法规分组;⚪ 项为运行时/人工核验', 'By regulation; ⚪ = runtime / manual review')));
140
+ S.push(sectionHead('📋', t('合规控制项明细', 'Compliance Controls'), t('按法规分组', 'By regulation')));
141
+ if (report.staticScan && report.manual > 0) {
142
+ S.push(`<div class="note manual-note">${t(`<b>⚪ 待核验 ≠ 不合规。</b> 下方 ${report.manual} 项是<b>运行时合规控制</b>(审计留存、内容过滤、注入拦截、数据外发管控等)——靠"看代码"的静态扫描判断不了,需把 ShellWard 接入你的 AI 应用(<code>npx shellward mcp</code> 或插件)作为运行时防护后才能验证,或人工核验。每项后面是"该做什么"。`, `<b>⚪ Review ≠ non-compliant.</b> The ${report.manual} items below are <b>runtime controls</b> a static scan cannot verify — deploy ShellWard as a runtime guard (<code>npx shellward mcp</code> / plugin) to validate them. Each row shows the remediation.`)}</div>`);
143
+ }
141
144
  const grouped = groupBy(report.results);
142
145
  for (const reg of REG_ORDER) {
143
146
  const items = grouped[reg];
@@ -312,6 +315,9 @@ table.tbl td.right{width:64px}
312
315
  .mtag.mid{background:var(--warn-bg);color:var(--warn)}
313
316
  .note{margin:8px 36px 4px;font-size:12.5px;color:var(--muted);background:#f8fafc;
314
317
  border-left:3px solid var(--brand);padding:10px 14px;border-radius:0 8px 8px 0}
318
+ .manual-note{margin:8px 36px 12px;font-size:13px;color:#475569;background:#eff6ff;
319
+ border-left:3px solid #3b82f6;line-height:1.6}
320
+ .manual-note code{background:#dbeafe;padding:1px 6px;border-radius:5px}
315
321
 
316
322
  /* 法规分组 */
317
323
  .reg{margin:14px 36px;padding:0;border:1px solid var(--line);border-radius:12px;overflow:hidden}
@@ -82,6 +82,12 @@ export function renderComplianceReport(report, locale) {
82
82
  // ===== 按法规分组明细 =====
83
83
  L.push(zh ? '## 分项明细' : '## Detailed Results');
84
84
  L.push('');
85
+ if (report.staticScan && report.manual > 0) {
86
+ L.push(zh
87
+ ? `> **⚪ 待核验 ≠ 不合规。** 下方 ${report.manual} 项是**运行时合规控制**(审计留存、内容过滤、注入拦截、数据外发管控等),静态扫描(看代码)判断不了,需把 ShellWard 接入你的 AI 应用(\`npx shellward mcp\` 或插件)作为运行时防护后验证,或人工核验。`
88
+ : `> **⚪ Review ≠ non-compliant.** The ${report.manual} items below are runtime controls a static scan cannot verify — deploy ShellWard as a runtime guard to validate.`);
89
+ L.push('');
90
+ }
85
91
  const grouped = groupByRegulation(report.results);
86
92
  for (const reg of REGULATION_ORDER) {
87
93
  const items = grouped[reg];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellward",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "mcpName": "io.github.jnMetaCode/shellward",
5
5
  "description": "AI agent security & MCP security middleware — prompt injection detection, AI firewall, runtime guardrails & data-loss prevention for LLM tool calls. 8-layer defense against data exfiltration & dangerous commands. Zero dependencies. SDK + OpenClaw plugin. Supports LangChain, AutoGPT, Claude Code, Cursor, OpenAI Agents, Hermes Agent.",
6
6
  "keywords": [
@@ -212,11 +212,10 @@ function computeProjectPenalty(scan: ProjectScanResult): number {
212
212
  }
213
213
 
214
214
  function checkControl(c: ComplianceControl, config: ShellWardConfig, env: EnvFacts, deployed: boolean): ControlResult {
215
- // 静态扫描(未部署运行时)下,能力层/审计日志类控制项无法验证 —— 标为顾问态,绝不虚报"已合规"
215
+ // 静态扫描(未部署运行时)下,能力层/审计日志类控制项无法验证 —— 标为顾问态,绝不虚报"已合规"
216
+ // 「为何待核验」统一在报告区块开头说一次;这里每行只留"该做什么",避免 12 行重复同一句。
216
217
  if (!deployed && (c.method === 'capability' || c.method === 'config' || c.method === 'audit')) {
217
- return mk(c, 'manual',
218
- `ShellWard 运行时可提供此防护;当前为静态扫描、未部署,无法验证。整改:${c.remediation_zh}`,
219
- `Provided by ShellWard runtime; not verifiable in a static scan. ${c.remediation_en}`)
218
+ return mk(c, 'manual', c.remediation_zh, c.remediation_en)
220
219
  }
221
220
  switch (c.method) {
222
221
  case 'capability': return checkCapability(c, config)
@@ -164,7 +164,12 @@ export function renderHtmlReport(
164
164
 
165
165
  // ===== 控制项明细 =====
166
166
  S.push(sectionHead('📋', t('合规控制项明细', 'Compliance Controls'),
167
- t('按法规分组;⚪ 项为运行时/人工核验', 'By regulation; ⚪ = runtime / manual review')))
167
+ t('按法规分组', 'By regulation')))
168
+ if (report.staticScan && report.manual > 0) {
169
+ S.push(`<div class="note manual-note">${t(
170
+ `<b>⚪ 待核验 ≠ 不合规。</b> 下方 ${report.manual} 项是<b>运行时合规控制</b>(审计留存、内容过滤、注入拦截、数据外发管控等)——靠"看代码"的静态扫描判断不了,需把 ShellWard 接入你的 AI 应用(<code>npx shellward mcp</code> 或插件)作为运行时防护后才能验证,或人工核验。每项后面是"该做什么"。`,
171
+ `<b>⚪ Review ≠ non-compliant.</b> The ${report.manual} items below are <b>runtime controls</b> a static scan cannot verify — deploy ShellWard as a runtime guard (<code>npx shellward mcp</code> / plugin) to validate them. Each row shows the remediation.`)}</div>`)
172
+ }
168
173
  const grouped = groupBy(report.results)
169
174
  for (const reg of REG_ORDER) {
170
175
  const items = grouped[reg]
@@ -349,6 +354,9 @@ table.tbl td.right{width:64px}
349
354
  .mtag.mid{background:var(--warn-bg);color:var(--warn)}
350
355
  .note{margin:8px 36px 4px;font-size:12.5px;color:var(--muted);background:#f8fafc;
351
356
  border-left:3px solid var(--brand);padding:10px 14px;border-radius:0 8px 8px 0}
357
+ .manual-note{margin:8px 36px 12px;font-size:13px;color:#475569;background:#eff6ff;
358
+ border-left:3px solid #3b82f6;line-height:1.6}
359
+ .manual-note code{background:#dbeafe;padding:1px 6px;border-radius:5px}
352
360
 
353
361
  /* 法规分组 */
354
362
  .reg{margin:14px 36px;padding:0;border:1px solid var(--line);border-radius:12px;overflow:hidden}
@@ -93,6 +93,12 @@ export function renderComplianceReport(report: ComplianceReport, locale: 'zh' |
93
93
  // ===== 按法规分组明细 =====
94
94
  L.push(zh ? '## 分项明细' : '## Detailed Results')
95
95
  L.push('')
96
+ if (report.staticScan && report.manual > 0) {
97
+ L.push(zh
98
+ ? `> **⚪ 待核验 ≠ 不合规。** 下方 ${report.manual} 项是**运行时合规控制**(审计留存、内容过滤、注入拦截、数据外发管控等),静态扫描(看代码)判断不了,需把 ShellWard 接入你的 AI 应用(\`npx shellward mcp\` 或插件)作为运行时防护后验证,或人工核验。`
99
+ : `> **⚪ Review ≠ non-compliant.** The ${report.manual} items below are runtime controls a static scan cannot verify — deploy ShellWard as a runtime guard to validate.`)
100
+ L.push('')
101
+ }
96
102
 
97
103
  const grouped = groupByRegulation(report.results)
98
104
  for (const reg of REGULATION_ORDER) {