hunter-harness 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/bin.js +3356 -0
- package/package.json +34 -0
- package/resources/bootstrap-ir/manifest.json +19 -0
- package/resources/bootstrap-ir/skills/harness-apidoc.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-archive.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-codebase-map.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-knowledge-ingest.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-package.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-plan.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-review.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-run.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-skill-optimizer.yaml +28 -0
- package/resources/bootstrap-ir/skills/harness-submit.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-sync.yaml +24 -0
- package/resources/bootstrap-ir/skills/harness-test.yaml +24 -0
- package/resources/bootstrap-ir/templates/claude-code-skill.md +12 -0
- package/resources/harness/general/.harness-build.json +5 -0
- package/resources/harness/general/CONTEXT.md +65 -0
- package/resources/harness/general/README.md +478 -0
- package/resources/harness/general/agents/harness-evaluator.md +96 -0
- package/resources/harness/general/agents/harness-explorer.md +72 -0
- package/resources/harness/general/agents/harness-reviewer.md +69 -0
- package/resources/harness/general/harness-archive/SKILL.md +215 -0
- package/resources/harness/general/harness-archive/checklist.md +52 -0
- package/resources/harness/general/harness-archive/reference.md +103 -0
- package/resources/harness/general/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/general/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/general/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/general/harness-codebase-map/SKILL.md +112 -0
- package/resources/harness/general/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/general/harness-codebase-map/reference.md +364 -0
- package/resources/harness/general/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/general/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/general/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/general/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/general/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/general/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/general/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/general/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/general/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/general/harness-knowledge-ingest/SKILL.md +246 -0
- package/resources/harness/general/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/general/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/general/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/general/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/general/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/general/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/general/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-01-10-ledger-reconciliation/reports/final/summary-data.json +43 -0
- package/resources/harness/general/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-02-14-ledger-snapshot-followup/reports/final/summary-data.json +38 -0
- package/resources/harness/general/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-03-05-webhook-contract/reports/final/summary-data.json +36 -0
- package/resources/harness/general/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/project.yaml +1 -0
- package/resources/harness/general/harness-knowledge-ingest/tests/test_harness_knowledge.py +1792 -0
- package/resources/harness/general/harness-knowledge-query/SKILL.md +164 -0
- package/resources/harness/general/harness-plan/SKILL.md +127 -0
- package/resources/harness/general/harness-plan/checklist.md +243 -0
- package/resources/harness/general/harness-plan/protocols.md +124 -0
- package/resources/harness/general/harness-plan/reference.md +376 -0
- package/resources/harness/general/harness-review/SKILL.md +156 -0
- package/resources/harness/general/harness-review/checklist.md +124 -0
- package/resources/harness/general/harness-review/protocols.md +68 -0
- package/resources/harness/general/harness-review/reference.md +86 -0
- package/resources/harness/general/harness-run/SKILL.md +132 -0
- package/resources/harness/general/harness-run/checklist.md +259 -0
- package/resources/harness/general/harness-run/protocols.md +78 -0
- package/resources/harness/general/harness-run/reference.md +834 -0
- package/resources/harness/general/harness-submit/SKILL.md +159 -0
- package/resources/harness/general/harness-submit/checklist.md +407 -0
- package/resources/harness/general/harness-submit/reference.md +152 -0
- package/resources/harness/general/harness-sync/SKILL.md +82 -0
- package/resources/harness/general/harness-sync/reference.md +153 -0
- package/resources/harness/general/harness-test/SKILL.md +180 -0
- package/resources/harness/general/harness-test/checklist.md +319 -0
- package/resources/harness/general/harness-test/pitfalls.md +260 -0
- package/resources/harness/general/harness-test/reference.md +791 -0
- package/resources/harness/general/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/general/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/general/protocols/ledger-protocol.md +270 -0
- package/resources/harness/general/protocols/powershell-protocol.md +181 -0
- package/resources/harness/general/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/general/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/general/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/general/protocols/submit-protocol.md +78 -0
- package/resources/harness/general/scripts/harness_archive.py +2319 -0
- package/resources/harness/general/scripts/harness_deploy.py +613 -0
- package/resources/harness/general/scripts/harness_events.py +680 -0
- package/resources/harness/general/scripts/harness_ledger.py +671 -0
- package/resources/harness/general/scripts/harness_preflight.py +780 -0
- package/resources/harness/general/scripts/harness_service.py +1331 -0
- package/resources/harness/java/.harness-build.json +5 -0
- package/resources/harness/java/CONTEXT.md +65 -0
- package/resources/harness/java/README.md +478 -0
- package/resources/harness/java/agents/harness-evaluator.md +96 -0
- package/resources/harness/java/agents/harness-explorer.md +72 -0
- package/resources/harness/java/agents/harness-reviewer.md +69 -0
- package/resources/harness/java/harness-apidoc/SKILL.md +86 -0
- package/resources/harness/java/harness-apidoc/checklist.md +142 -0
- package/resources/harness/java/harness-apidoc/reference.md +233 -0
- package/resources/harness/java/harness-archive/SKILL.md +215 -0
- package/resources/harness/java/harness-archive/checklist.md +52 -0
- package/resources/harness/java/harness-archive/reference.md +103 -0
- package/resources/harness/java/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/java/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/java/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/java/harness-codebase-map/SKILL.md +112 -0
- package/resources/harness/java/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/java/harness-codebase-map/reference.md +364 -0
- package/resources/harness/java/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/java/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/java/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/java/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/java/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/java/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/java/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/java/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/java/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/java/harness-knowledge-ingest/SKILL.md +246 -0
- package/resources/harness/java/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/java/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/java/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/java/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/java/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/java/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/java/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-01-10-ledger-reconciliation/reports/final/summary-data.json +43 -0
- package/resources/harness/java/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-02-14-ledger-snapshot-followup/reports/final/summary-data.json +38 -0
- package/resources/harness/java/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/archive/2026-03-05-webhook-contract/reports/final/summary-data.json +36 -0
- package/resources/harness/java/harness-knowledge-ingest/tests/fixtures/mcp-eval-project/.harness/project.yaml +1 -0
- package/resources/harness/java/harness-knowledge-ingest/tests/test_harness_knowledge.py +1792 -0
- package/resources/harness/java/harness-knowledge-query/SKILL.md +164 -0
- package/resources/harness/java/harness-package/SKILL.md +87 -0
- package/resources/harness/java/harness-package/checklist.md +322 -0
- package/resources/harness/java/harness-package/reference.md +210 -0
- package/resources/harness/java/harness-plan/SKILL.md +127 -0
- package/resources/harness/java/harness-plan/checklist.md +243 -0
- package/resources/harness/java/harness-plan/protocols.md +124 -0
- package/resources/harness/java/harness-plan/reference.md +376 -0
- package/resources/harness/java/harness-review/SKILL.md +156 -0
- package/resources/harness/java/harness-review/checklist.md +124 -0
- package/resources/harness/java/harness-review/protocols.md +68 -0
- package/resources/harness/java/harness-review/reference.md +86 -0
- package/resources/harness/java/harness-run/SKILL.md +148 -0
- package/resources/harness/java/harness-run/checklist.md +250 -0
- package/resources/harness/java/harness-run/protocols.md +78 -0
- package/resources/harness/java/harness-run/reference.md +814 -0
- package/resources/harness/java/harness-submit/SKILL.md +166 -0
- package/resources/harness/java/harness-submit/checklist.md +407 -0
- package/resources/harness/java/harness-submit/reference.md +152 -0
- package/resources/harness/java/harness-sync/SKILL.md +82 -0
- package/resources/harness/java/harness-sync/reference.md +153 -0
- package/resources/harness/java/harness-test/SKILL.md +192 -0
- package/resources/harness/java/harness-test/checklist.md +317 -0
- package/resources/harness/java/harness-test/pitfalls-java.md +16 -0
- package/resources/harness/java/harness-test/pitfalls.md +260 -0
- package/resources/harness/java/harness-test/reference.md +788 -0
- package/resources/harness/java/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/java/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/java/protocols/ledger-protocol.md +270 -0
- package/resources/harness/java/protocols/powershell-protocol.md +181 -0
- package/resources/harness/java/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/java/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/java/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/java/protocols/submit-protocol.md +78 -0
- package/resources/harness/java/scripts/harness_archive.py +2319 -0
- package/resources/harness/java/scripts/harness_deploy.py +613 -0
- package/resources/harness/java/scripts/harness_events.py +680 -0
- package/resources/harness/java/scripts/harness_ledger.py +671 -0
- package/resources/harness/java/scripts/harness_preflight.py +780 -0
- package/resources/harness/java/scripts/harness_service.py +1331 -0
- package/resources/harness/manifests/general.json +296 -0
- package/resources/harness/manifests/java.json +324 -0
- package/resources/manifest.json +19 -0
- package/resources/skills/harness-apidoc/SKILL.md +50 -0
- package/resources/skills/harness-archive/SKILL.md +48 -0
- package/resources/skills/harness-codebase-map/SKILL.md +53 -0
- package/resources/skills/harness-knowledge-ingest/SKILL.md +48 -0
- package/resources/skills/harness-package/SKILL.md +48 -0
- package/resources/skills/harness-plan/SKILL.md +51 -0
- package/resources/skills/harness-review/SKILL.md +50 -0
- package/resources/skills/harness-run/SKILL.md +48 -0
- package/resources/skills/harness-skill-optimizer/SKILL.md +54 -0
- package/resources/skills/harness-submit/SKILL.md +47 -0
- package/resources/skills/harness-sync/SKILL.md +48 -0
- package/resources/skills/harness-test/SKILL.md +50 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// render-summary.mjs
|
|
3
|
+
// Deterministic UTF-8 renderer for harness archive final-summary.html.
|
|
4
|
+
// Input: summary-data.json (schemaVersion 2.2). Output: final-summary.html.
|
|
5
|
+
// Keeps UTF-8, avoids PowerShell string interpolation issues.
|
|
6
|
+
// All numbers come from summary-data.json or manifest — never re-inferred here.
|
|
7
|
+
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
function getArg(name, fallback) {
|
|
13
|
+
const i = args.indexOf(name);
|
|
14
|
+
return i >= 0 && args[i + 1] ? args[i + 1] : fallback;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const summaryPath = getArg('--summary', args[0]);
|
|
18
|
+
const outPath = getArg('--out', args[1] || 'final-summary.html');
|
|
19
|
+
if (!summaryPath) {
|
|
20
|
+
console.error('Usage: node render-summary.mjs --summary summary-data.json --out final-summary.html');
|
|
21
|
+
process.exit(2);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const data = JSON.parse(fs.readFileSync(summaryPath, 'utf8'));
|
|
25
|
+
const esc = (v) => String(v ?? '').replace(/[&<>"']/g, (c) => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
|
26
|
+
const arr = (v) => Array.isArray(v) ? v : [];
|
|
27
|
+
const obj = (v) => v && typeof v === 'object' ? v : {};
|
|
28
|
+
const num = (v) => Number(v) || 0;
|
|
29
|
+
const badgeClass = (s) => {
|
|
30
|
+
const v = String(s ?? '').toUpperCase();
|
|
31
|
+
if (v.includes('FAIL') || v.includes('ERROR')) return 'bad';
|
|
32
|
+
if (v.includes('WARN') || v.includes('BLOCK') || v.includes('SKIP') || v.includes('CONDITIONAL') || v.includes('PARTIAL') || v.includes('NOT_RUN')) return 'warn';
|
|
33
|
+
if (v.includes('ADVISORY') || v.includes('REUSED')) return 'info';
|
|
34
|
+
return 'ok';
|
|
35
|
+
};
|
|
36
|
+
const badge = (s) => `<span class="badge ${badgeClass(s)}">${esc(s || 'N/A')}</span>`;
|
|
37
|
+
|
|
38
|
+
// pass-rate progress bar: parses "183/185" style strings
|
|
39
|
+
const parseRate = (rate) => {
|
|
40
|
+
if (!rate) return null;
|
|
41
|
+
const m = String(rate).match(/(\d+)\s*\/\s*(\d+)/);
|
|
42
|
+
return m ? { passed: +m[1], total: +m[2] } : null;
|
|
43
|
+
};
|
|
44
|
+
const rateBar = (rateStr, status) => {
|
|
45
|
+
const r = parseRate(rateStr);
|
|
46
|
+
if (!r || r.total <= 0) return `<span class="muted">N/A</span>`;
|
|
47
|
+
const pct = Math.round(r.passed / r.total * 100);
|
|
48
|
+
const cls = badgeClass(status || (r.passed >= r.total ? 'OK' : 'WARN'));
|
|
49
|
+
return `<div class="rate"><div class="bar-track"><div class="bar-fill ${cls}" style="width:${pct}%"></div></div><span class="muted small">${esc(rateStr)} · ${pct}%</span></div>`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const stageRows = Object.entries(obj(data.stageStatus)).map(([k,v]) => `<tr><td>${esc(k)}</td><td>${badge(v)}</td></tr>`).join('\n') || `<tr><td colspan="2" class="muted">未记录阶段状态</td></tr>`;
|
|
53
|
+
|
|
54
|
+
const verification = obj(data.verification);
|
|
55
|
+
const unit = obj(verification.unitTests);
|
|
56
|
+
const api = obj(verification.apiTests);
|
|
57
|
+
const unitStatus = (num(unit.failures) + num(unit.errors)) > 0 ? 'WARN' : 'OK';
|
|
58
|
+
const verificationRows = [
|
|
59
|
+
['Unit Tests', `${rateBar(unit.passRate, unitStatus)}<div class="muted small">${esc(unit.run ?? 0)} run · ${esc(unit.failures ?? 0)} fail · ${esc(unit.errors ?? 0)} err · ${esc(unit.skipped ?? 0)} skip · ${esc(unit.source || 'not recorded')}</div>`],
|
|
60
|
+
['API Tests', `${rateBar(api.passRate, api.status)}<div class="muted small">${esc(api.passed ?? 0)}/${esc(api.total ?? 0)} · ${esc(api.status || data.stageStatus?.test || 'N/A')}</div>`],
|
|
61
|
+
['DB Compat', badge(verification.dbCompatibility || 'N/A')],
|
|
62
|
+
['Coverage', esc(verification.coverageDisplay || 'N/A')],
|
|
63
|
+
['Overall', badge(data.finalStatus || data.overallStatus || 'N/A')]
|
|
64
|
+
].map(([a,b]) => `<tr><td>${a}</td><td>${b}</td></tr>`).join('\n');
|
|
65
|
+
|
|
66
|
+
const diffStat = obj(data.diffStat);
|
|
67
|
+
const changedRows = arr(data.changedFiles).map(f => `<tr><td><code>${esc(f.path || f.file || '')}</code></td><td>${esc(f.summary || f.change || '')}</td><td class="ins">+${esc(f.insertions ?? 0)}</td><td class="del">-${esc(f.deletions ?? 0)}</td></tr>`).join('\n') || `<tr><td colspan="4" class="muted">未记录变更文件</td></tr>`;
|
|
68
|
+
const artifactList = arr(data.artifacts);
|
|
69
|
+
const artifactRows = artifactList.map(a => `<tr><td>${esc(a.name || '')}</td><td><code>${esc(a.path || '')}</code></td><td>${esc(a.size || '')}</td><td><code>${esc(a.sha256 || '')}</code></td></tr>`).join('\n');
|
|
70
|
+
const artifactCard = artifactList.length > 0 ? `<div class="card"><h2>📦 产物清单</h2><table><tr><th>名称</th><th>路径</th><th>大小</th><th>SHA-256</th></tr>${artifactRows}</table></div>` : '';
|
|
71
|
+
const notes = arr(data.maintenanceNotes).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无额外维护说明</li>`;
|
|
72
|
+
const risks = arr(data.knownRisks).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无已知遗留风险</li>`;
|
|
73
|
+
const manual = arr(data.manualActions).map(n => `<li>${esc(n)}</li>`).join('\n') || `<li class="muted">无人工后续动作</li>`;
|
|
74
|
+
const uncommittedList = arr(data.uncommittedTestEvidence);
|
|
75
|
+
const uncommittedTests = uncommittedList.map(n => `<li>${esc(n)}</li>`).join('\n');
|
|
76
|
+
const uncommittedCard = uncommittedList.length > 0 ? `<div class="card"><h2>🧪 未提交测试证据</h2><ul>${uncommittedTests}</ul></div>` : '';
|
|
77
|
+
const review = obj(data.reviewSummary);
|
|
78
|
+
const manifest = obj(data.archiveManifest);
|
|
79
|
+
const timeline = arr(data.timeline).map(t => `<tr><td>${esc(t.stage || '')}</td><td>${badge(t.result || '')}</td><td>${esc(t.evidence || '')}</td></tr>`).join('\n');
|
|
80
|
+
|
|
81
|
+
// durations + skillCalls (schema 2.1); fall back to timeline when absent
|
|
82
|
+
const durations = obj(data.durations);
|
|
83
|
+
const durStages = arr(durations.stages);
|
|
84
|
+
const maxMin = durStages.reduce((m, s) => Math.max(m, num(s.minutes)), 0);
|
|
85
|
+
const durRows = durStages.map(s => {
|
|
86
|
+
const min = num(s.minutes);
|
|
87
|
+
const pct = maxMin > 0 ? Math.round(min / maxMin * 100) : 0;
|
|
88
|
+
return `<div class="dur-row"><div class="dur-label">${esc(s.skill || s.stage || '')} <span class="muted small">${esc(s.result || '')}</span></div><div class="dur-track"><div class="dur-bar" style="width:${pct}%"></div></div><div class="dur-min">${esc(min)}m</div></div>`;
|
|
89
|
+
}).join('\n');
|
|
90
|
+
const skillCallsHtml = arr(data.skillCalls).map(s => `${esc(s.skill)}×${esc(s.count)} ${badge(s.result)}`).join(' ') || '<span class="muted">未记录</span>';
|
|
91
|
+
|
|
92
|
+
const durCard = durStages.length > 0
|
|
93
|
+
? `<div class="card"><h2>⏱️ 阶段耗时与 Skill 调用</h2>${durRows}<div class="muted small" style="margin-top:10px">Skill 调用:${skillCallsHtml}</div></div>`
|
|
94
|
+
: (timeline ? `<div class="card"><h2>阶段时间线</h2><table><tr><th>阶段</th><th>结果</th><th>证据</th></tr>${timeline}</table></div>` : '');
|
|
95
|
+
|
|
96
|
+
const totalLabel = durations.totalLabel || (durations.totalMinutes ? durations.totalMinutes + 'm' : 'N/A');
|
|
97
|
+
|
|
98
|
+
const html = `<!doctype html>
|
|
99
|
+
<html lang="zh-CN">
|
|
100
|
+
<head>
|
|
101
|
+
<meta charset="utf-8" />
|
|
102
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
103
|
+
<title>变更最终报告 - ${esc(data.changeName || '')}</title>
|
|
104
|
+
<style>
|
|
105
|
+
:root { color-scheme: dark; }
|
|
106
|
+
* { box-sizing: border-box; }
|
|
107
|
+
body { font-family: -apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei',sans-serif; margin: 0; background: #0b1020; color: #e5e7eb; }
|
|
108
|
+
main { max-width: 1120px; margin: 0 auto; padding: 32px; }
|
|
109
|
+
.card { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); border-radius: 16px; padding: 20px; margin: 16px 0; box-shadow: 0 12px 40px rgba(0,0,0,.18); }
|
|
110
|
+
h1 { margin: 0 0 8px; font-size: 30px; }
|
|
111
|
+
h2 { margin: 0 0 12px; font-size: 20px; }
|
|
112
|
+
h3 { margin: 18px 0 8px; }
|
|
113
|
+
.muted { color: #94a3b8; }
|
|
114
|
+
.small { font-size: 12px; }
|
|
115
|
+
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
|
116
|
+
th, td { border-bottom: 1px solid rgba(255,255,255,.12); padding: 10px; text-align: left; vertical-align: top; overflow-wrap: anywhere; }
|
|
117
|
+
th { color: #cbd5e1; font-weight: 600; }
|
|
118
|
+
tbody tr:nth-child(even) { background: rgba(255,255,255,.03); }
|
|
119
|
+
tbody tr:hover { background: rgba(96,165,250,.08); }
|
|
120
|
+
code { color: #bfdbfe; word-break: break-all; }
|
|
121
|
+
.ins { color: #86efac; font-weight: 600; }
|
|
122
|
+
.del { color: #fca5a5; font-weight: 600; }
|
|
123
|
+
.badge { display: inline-block; padding: 4px 8px; border-radius: 999px; font-weight: 700; font-size: 12px; }
|
|
124
|
+
.badge.ok { background: rgba(34,197,94,.16); color: #86efac; }
|
|
125
|
+
.badge.warn { background: rgba(245,158,11,.18); color: #fcd34d; }
|
|
126
|
+
.badge.bad { background: rgba(239,68,68,.18); color: #fca5a5; }
|
|
127
|
+
.badge.info { background: rgba(59,130,246,.18); color: #93c5fd; }
|
|
128
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(200px,1fr)); gap: 16px; }
|
|
129
|
+
.kpi { font-size: 18px; font-weight: 700; margin-top: 4px; word-break: break-all; }
|
|
130
|
+
.hero { border-color: rgba(96,165,250,.35); background: linear-gradient(135deg, rgba(59,130,246,.12), rgba(255,255,255,.04)); }
|
|
131
|
+
ul { margin-top: 8px; }
|
|
132
|
+
.bar-track { background: rgba(255,255,255,.08); border-radius: 999px; height: 8px; overflow: hidden; margin: 4px 0; }
|
|
133
|
+
.bar-fill { height: 100%; border-radius: 999px; }
|
|
134
|
+
.bar-fill.ok { background: #22c55e; }
|
|
135
|
+
.bar-fill.warn { background: #f59e0b; }
|
|
136
|
+
.bar-fill.bad { background: #ef4444; }
|
|
137
|
+
.bar-fill.info { background: #3b82f6; }
|
|
138
|
+
.rate { display: flex; flex-direction: column; gap: 2px; min-width: 160px; }
|
|
139
|
+
.dur-row { display: grid; grid-template-columns: 150px 1fr 50px; align-items: center; gap: 10px; padding: 6px 0; }
|
|
140
|
+
.dur-label { color: #93c5fd; font-size: 13px; }
|
|
141
|
+
.dur-track { background: rgba(255,255,255,.06); border-radius: 4px; height: 18px; overflow: hidden; }
|
|
142
|
+
.dur-bar { height: 100%; background: linear-gradient(90deg, #3b82f6, #60a5fa); border-radius: 4px; }
|
|
143
|
+
.dur-min { color: #94a3b8; font-size: 13px; text-align: right; }
|
|
144
|
+
@media (max-width: 640px) { main { padding: 16px; } .grid { grid-template-columns: 1fr; } .dur-row { grid-template-columns: 100px 1fr 40px; } }
|
|
145
|
+
</style>
|
|
146
|
+
</head>
|
|
147
|
+
<body><main>
|
|
148
|
+
<div class="card hero">
|
|
149
|
+
<h1>变更最终报告:${esc(data.changeName || '')}</h1>
|
|
150
|
+
<p class="muted">${esc(data.businessGoal || '未记录业务目标')}</p>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="grid">
|
|
153
|
+
<div class="card"><div class="muted">🎯 最终状态</div><div class="kpi">${badge(data.finalStatus || data.overallStatus || 'N/A')}</div></div>
|
|
154
|
+
<div class="card"><div class="muted">🔒 Final Commit</div><div class="kpi"><code>${esc(data.finalCommit || 'N/A')}</code></div><div class="muted small">${esc(data.finalCommitBranch || '')}</div></div>
|
|
155
|
+
<div class="card"><div class="muted">📊 代码变更</div><div class="kpi">${esc(diffStat.filesChanged ?? 'N/A')} 文件</div><div class="muted small"><span class="ins">+${esc(diffStat.insertions ?? 0)}</span> <span class="del">-${esc(diffStat.deletions ?? 0)}</span></div></div>
|
|
156
|
+
<div class="card"><div class="muted">⏱️ 总耗时</div><div class="kpi">${esc(totalLabel)}</div><div class="muted small">${esc(durStages.length)} 个阶段</div></div>
|
|
157
|
+
<div class="card"><div class="muted">📝 Review</div><div class="kpi">${esc(review.status || 'N/A')}</div><div class="muted small">RED ${esc(review.red ?? 0)}(修${esc(review.redFixed ?? 0)}/确${esc(review.redConfirmed ?? 0)}) · YEL ${esc(review.yellow ?? 0)}(修${esc(review.yellowFixed ?? 0)}/留${esc(review.yellowDeferred ?? 0)})</div></div>
|
|
158
|
+
<div class="card"><div class="muted">📦 Archive</div><div class="kpi">${esc(manifest.totalArchiveFiles ?? 'N/A')} 文件</div><div class="muted small">${esc(manifest.checksumStatus || 'N/A')}</div></div>
|
|
159
|
+
</div>
|
|
160
|
+
<div class="card"><h2>📋 阶段状态</h2><table><tr><th>阶段</th><th>状态</th></tr>${stageRows}</table></div>
|
|
161
|
+
${durCard}
|
|
162
|
+
<div class="card"><h2>🛡️ 验证明细</h2><table><tr><th>类型</th><th>结果</th></tr>${verificationRows}</table></div>
|
|
163
|
+
<div class="card"><h2>📁 变更文件</h2><table><tr><th>文件</th><th>说明</th><th>+</th><th>-</th></tr>${changedRows}</table></div>
|
|
164
|
+
${artifactCard}
|
|
165
|
+
${uncommittedCard}
|
|
166
|
+
<div class="card"><h2>👨🔧 给后续维护者</h2><ul>${notes}</ul></div>
|
|
167
|
+
<div class="card"><h2>⚠️ 已知风险 / 人工确认项</h2><ul>${risks}</ul><h3>人工后续动作</h3><ul>${manual}</ul></div>
|
|
168
|
+
</main></body></html>`;
|
|
169
|
+
|
|
170
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
171
|
+
fs.writeFileSync(outPath, html, 'utf8');
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "2.2",
|
|
3
|
+
"changeName": "<change-name>",
|
|
4
|
+
"businessGoal": "本次变更为了做什么",
|
|
5
|
+
"finalStatus": "OK | WARN | CONDITIONAL_OK | FAIL",
|
|
6
|
+
"finalCommit": "<commit-hash>",
|
|
7
|
+
"finalCommitBranch": "<origin/branch>",
|
|
8
|
+
"baseCommit": "<base-commit-hash>",
|
|
9
|
+
"diffStat": {
|
|
10
|
+
"filesChanged": 0,
|
|
11
|
+
"insertions": 0,
|
|
12
|
+
"deletions": 0,
|
|
13
|
+
"range": "<base>..<head>"
|
|
14
|
+
},
|
|
15
|
+
"stageStatus": {
|
|
16
|
+
"plan": "OK",
|
|
17
|
+
"run": "OK | WARN",
|
|
18
|
+
"test": "OK | PARTIAL | USER_SKIPPED | BLOCKED_BY_DBA",
|
|
19
|
+
"review": "ADVISORY",
|
|
20
|
+
"submit": "OK",
|
|
21
|
+
"archive": "OK"
|
|
22
|
+
},
|
|
23
|
+
"durations": {
|
|
24
|
+
"totalLabel": "约 N 分",
|
|
25
|
+
"totalMinutes": 0,
|
|
26
|
+
"stages": [
|
|
27
|
+
{
|
|
28
|
+
"stage": "plan",
|
|
29
|
+
"skill": "harness-plan",
|
|
30
|
+
"startedAt": "YYYY-MM-DD HH:mm:ss",
|
|
31
|
+
"endedAt": "YYYY-MM-DD HH:mm:ss",
|
|
32
|
+
"minutes": 0,
|
|
33
|
+
"result": "OK | WARN | FAIL"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"skillCalls": [
|
|
38
|
+
{ "skill": "harness-plan", "count": 1, "result": "OK" }
|
|
39
|
+
],
|
|
40
|
+
"verification": {
|
|
41
|
+
"unitTests": {
|
|
42
|
+
"run": 0,
|
|
43
|
+
"failures": 0,
|
|
44
|
+
"errors": 0,
|
|
45
|
+
"skipped": 0,
|
|
46
|
+
"passRate": "183/185",
|
|
47
|
+
"source": "committed | uncommitted-archived | not-run"
|
|
48
|
+
},
|
|
49
|
+
"apiTests": {
|
|
50
|
+
"status": "OK | PARTIAL | USER_SKIPPED | NOT_RUN",
|
|
51
|
+
"total": 0,
|
|
52
|
+
"passed": 0,
|
|
53
|
+
"failed": 0,
|
|
54
|
+
"blocked": 0,
|
|
55
|
+
"passRate": "34/35"
|
|
56
|
+
},
|
|
57
|
+
"dbCompatibility": "OK | BLOCKED_BY_DBA | NOT_RUN",
|
|
58
|
+
"coverageDisplay": "例如 29/29 或 USER_SKIPPED"
|
|
59
|
+
},
|
|
60
|
+
"timeline": [],
|
|
61
|
+
"changedFiles": [
|
|
62
|
+
{ "path": "src/...", "summary": "说明", "insertions": 0, "deletions": 0 }
|
|
63
|
+
],
|
|
64
|
+
"artifacts": [],
|
|
65
|
+
"reviewSummary": {
|
|
66
|
+
"status": "ADVISORY",
|
|
67
|
+
"red": 0,
|
|
68
|
+
"yellow": 0,
|
|
69
|
+
"redFixed": 0,
|
|
70
|
+
"redConfirmed": 0,
|
|
71
|
+
"yellowFixed": 0,
|
|
72
|
+
"yellowDeferred": 0,
|
|
73
|
+
"summary": ""
|
|
74
|
+
},
|
|
75
|
+
"archiveManifest": {
|
|
76
|
+
"movedFiles": 0,
|
|
77
|
+
"generatedFiles": 0,
|
|
78
|
+
"totalArchiveFiles": 0,
|
|
79
|
+
"checksumStatus": "OK | WARN | FAIL"
|
|
80
|
+
},
|
|
81
|
+
"reportPipeline": {
|
|
82
|
+
"schema_version": 1,
|
|
83
|
+
"generated_at": "YYYY-MM-DDTHH:mm:ss.sssZ",
|
|
84
|
+
"event_count": 0,
|
|
85
|
+
"sources": [
|
|
86
|
+
"events.ndjson",
|
|
87
|
+
"evidence/verification-ledger.json",
|
|
88
|
+
"logs/execution-log.md"
|
|
89
|
+
],
|
|
90
|
+
"phases": {
|
|
91
|
+
"plan": { "duration_ms": null, "event_count": 0 },
|
|
92
|
+
"run": { "duration_ms": null, "event_count": 0 },
|
|
93
|
+
"test": { "duration_ms": null, "event_count": 0 },
|
|
94
|
+
"review": { "duration_ms": null, "event_count": 0 },
|
|
95
|
+
"submit": { "duration_ms": null, "event_count": 0 },
|
|
96
|
+
"archive": { "duration_ms": null, "event_count": 0 }
|
|
97
|
+
},
|
|
98
|
+
"commands": [
|
|
99
|
+
{
|
|
100
|
+
"command": "npm test",
|
|
101
|
+
"exit_code": 0,
|
|
102
|
+
"duration_ms": 0,
|
|
103
|
+
"phase": "run",
|
|
104
|
+
"timestamp": "YYYY-MM-DDTHH:mm:ss.sssZ"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"verificationChecks": [
|
|
108
|
+
{
|
|
109
|
+
"name": "unit tests",
|
|
110
|
+
"status": "passed | failed | skipped | unknown",
|
|
111
|
+
"command": "npm test",
|
|
112
|
+
"source": "events.ndjson | evidence/verification-ledger.json"
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"artifacts": [
|
|
116
|
+
{
|
|
117
|
+
"path": "reports/final/final-summary.html",
|
|
118
|
+
"kind": "final-report",
|
|
119
|
+
"phase": "archive"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"validationIssues": []
|
|
123
|
+
},
|
|
124
|
+
"uncommittedTestEvidence": [],
|
|
125
|
+
"maintenanceNotes": [],
|
|
126
|
+
"knownRisks": [],
|
|
127
|
+
"manualActions": []
|
|
128
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-codebase-map
|
|
3
|
+
description: "分析现有代码库并生成 .harness/codebase/map/ 下的结构化代码库地图。用于陌生项目理解、重大改造前梳理、harness-sync 提示 map 过期后的人工刷新。"
|
|
4
|
+
argument-hint: "[--fast] [--focus tech|arch|quality|concerns|tech+arch] [--paths <p1,p2,...>] [--status|--diff|--refresh]"
|
|
5
|
+
effort: high
|
|
6
|
+
allowed-tools: [Read, Glob, Grep, Write, Edit, Agent, Bash(powershell.exe:*)]
|
|
7
|
+
disallowed-tools:
|
|
8
|
+
- Bash(git *)
|
|
9
|
+
- Bash(mvn *)
|
|
10
|
+
- Bash(ls *)
|
|
11
|
+
- Bash(find *)
|
|
12
|
+
- Bash(grep *)
|
|
13
|
+
- Bash(cat *)
|
|
14
|
+
- Bash(cp *)
|
|
15
|
+
- Bash(mv *)
|
|
16
|
+
- Bash(rm *)
|
|
17
|
+
- Bash(mkdir *)
|
|
18
|
+
- Bash(touch *)
|
|
19
|
+
- Bash(sed *)
|
|
20
|
+
- Bash(awk *)
|
|
21
|
+
- Bash(curl *)
|
|
22
|
+
---
|
|
23
|
+
<!-- generated by harness_deploy.py; core=8917528f7dfdc5ca; overlay=java; do not edit -->
|
|
24
|
+
# harness-codebase-map — 代码库地图
|
|
25
|
+
|
|
26
|
+
## Purpose
|
|
27
|
+
|
|
28
|
+
生成 hunter-harness 自有代码库地图 → `.harness/codebase/map/`(7 类文档)+ `map-summary.md` + `map-manifest.json`。供 plan/run/review 快速理解项目结构。
|
|
29
|
+
|
|
30
|
+
## 核心边界
|
|
31
|
+
|
|
32
|
+
- **只写** `.harness/codebase/map/`、`map-summary.md`、`map-manifest.json`、`.harness/reports/codebase-map-*.md`
|
|
33
|
+
- **禁止** `.planning/`、Git 写操作、修改 `.codegraph/`、自动 commit/push
|
|
34
|
+
- `harness-sync` 只**建议**刷新,不自动跑全量 map
|
|
35
|
+
|
|
36
|
+
## When to Use
|
|
37
|
+
|
|
38
|
+
首次接入、map 过期(sync 提示)、大型重构前、用户说「刷新 codebase map」。跳过:空项目(<5 源文件)、纯符号查询(用 CodeGraph)。
|
|
39
|
+
|
|
40
|
+
## Arguments
|
|
41
|
+
|
|
42
|
+
| 参数 | 含义 |
|
|
43
|
+
|------|------|
|
|
44
|
+
| (无) | 全量 7 文档 |
|
|
45
|
+
| `--fast` | STACK + STRUCTURE + CONCERNS |
|
|
46
|
+
| `--focus *` | tech / arch / quality / concerns / tech+arch |
|
|
47
|
+
| `--paths p1,p2` | 增量路径(非法路径 → WARN,全非法须确认) |
|
|
48
|
+
| `--status` / `--diff` | 只检查,不刷新 |
|
|
49
|
+
| `--refresh` | 显式全量刷新 |
|
|
50
|
+
|
|
51
|
+
## Workflow(薄编排)
|
|
52
|
+
|
|
53
|
+
| Phase | 动作 |
|
|
54
|
+
|-------|------|
|
|
55
|
+
| 0 | 读 SKILL + `reference.md` / `checklist.md` / `templates/` + protocols |
|
|
56
|
+
| 1 | 解析 `$ARGUMENTS` → 模式与扫描范围 |
|
|
57
|
+
| 2 | 检查现有 map / manifest → `--status` 可在此结束 |
|
|
58
|
+
| 3 | `New-Item` 确保输出目录(PowerShell,禁止 Bash mkdir) |
|
|
59
|
+
| 4 | Glob/Grep/Read 扫描;git 只读查询经 PowerShell |
|
|
60
|
+
| 5 | 写 7 文档(`templates/` + frontmatter)— 可并行 mapper agents |
|
|
61
|
+
| 6 | 写 summary + manifest(schema → `templates/map-manifest.schema.json`) |
|
|
62
|
+
| 7 | 更新 `.harness/context-index.json` codebase 入口(若存在) |
|
|
63
|
+
| 8 | 控制台 + `.harness/reports/codebase-map-*.md` 报告 |
|
|
64
|
+
|
|
65
|
+
逐步细节、frontmatter 字段、git 允许列表 → `reference.md` / `checklist.md`
|
|
66
|
+
|
|
67
|
+
## Mapper Agent 策略
|
|
68
|
+
|
|
69
|
+
优先并行 mapper(tech/arch/quality/concerns);Agent 直写文档,主会话汇总。不可用 → 主会话顺序扫描 + 🟡WARN。
|
|
70
|
+
|
|
71
|
+
## P0 执行可信度规则
|
|
72
|
+
|
|
73
|
+
- 命令结果不得靠猜测;普通 Bash 被拒 → 立即改用等价 PowerShell 重试一次
|
|
74
|
+
- 仅 PowerShell 成功且有明确证据(构建/git/测试输出、文件存在、exit 0)时可标 ✅OK;否则 ❌FAIL 或 🟡WARN
|
|
75
|
+
- 禁止把 hook 拒绝、静态验证、无输出、用户跳过说成成功 → 详见 [[../protocols/powershell-protocol.md|powershell-protocol]]、[[../protocols/evidence-based-reporting-protocol.md|evidence-based-reporting-protocol]]
|
|
76
|
+
|
|
77
|
+
## 关键规则
|
|
78
|
+
|
|
79
|
+
| # | 规则 |
|
|
80
|
+
|---|------|
|
|
81
|
+
| 1 | 唯一输出 `.harness/codebase/map/` |
|
|
82
|
+
| 2 | `generated_reviewable`,不建议手工改 map 正文 |
|
|
83
|
+
| 3 | 不 Git 写操作、不改业务代码 |
|
|
84
|
+
| 4 | 不管理 CodeGraph |
|
|
85
|
+
| 5 | 敏感信息脱敏 → `sensitive-info-protocol` |
|
|
86
|
+
| 6 | 证据化输出 → `evidence-based-reporting-protocol` |
|
|
87
|
+
|
|
88
|
+
## Output Format
|
|
89
|
+
|
|
90
|
+
模式、范围、7/7 文档路径与行数、manifest/summary、context-index 状态、WARN/FAIL → `reference.md` 报告模板
|
|
91
|
+
|
|
92
|
+
## 渐进披露
|
|
93
|
+
|
|
94
|
+
- **Read `checklist.md`** — 执行前后检查
|
|
95
|
+
- **Read `reference.md`** — manifest、mapper、扫描模式
|
|
96
|
+
- **Read `templates/*`** — 各文档模板
|
|
97
|
+
|
|
98
|
+
## 交互白名单
|
|
99
|
+
|
|
100
|
+
**无** AskUserQuestion;参数/默认值 + `decision` 事件
|
|
101
|
+
|
|
102
|
+
## 执行日志
|
|
103
|
+
|
|
104
|
+
`events.ndjson` 为唯一事实源(schema_version 2,`note` 承载人类可读摘要);`logs/execution-log.md` 由 `harness_events.py` 渲染,**禁止手工 Edit**。结构 → [[../protocols/report-pipeline-protocol.md|report-pipeline-protocol]]
|
|
105
|
+
|
|
106
|
+
```powershell
|
|
107
|
+
python <skills-root>/scripts/harness_events.py append --change-dir ".harness/changes/<change-name>" --phase <phase> --type phase.start --note "<触发指令>"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> **脚本接线**:`harness_events.py append`;`harness_archive.py finalize`;`harness_preflight.py check`;`harness_ledger.py can-reuse`;`harness_service.py ensure/stop`(须 `--files`/`serviceStart.inputFiles`)。JSON 输出按 D13 护栏解读。
|
|
111
|
+
|
|
112
|
+
> **Task 4 §6.1 写入契约**:普通 `append` = 加锁 -> 追加一行 -> fsync -> 解锁,**不 load 历史、不渲染**(O(1),跨进程锁 `events.ndjson.lock`,UUID 用完整 `uuid4().hex` 无需去重扫描)。仅 `--type phase.end` append 在追加成功后渲染一次 `execution-log.md`;显式 `harness_events.py render` 随时从完整 events 重建;`harness_archive.py finalize` 在 collect 前强制 render 一次。高频 command append 期间 log 可能滞后,phase 边界保持最新。
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# harness-codebase-map 检查清单
|
|
2
|
+
|
|
3
|
+
## 执行前检查
|
|
4
|
+
|
|
5
|
+
| 检查项 | 必须 | 说明 |
|
|
6
|
+
|---|:---:|---|
|
|
7
|
+
| 当前目录是项目根或已给出项目路径 | 是 | 需要能定位源码、配置和 `.harness/` |
|
|
8
|
+
| 参数已解析 | 是 | 识别 full / fast / focus / paths / status / diff |
|
|
9
|
+
| `--paths` 已做安全校验 | 条件 | 拒绝 `..`、绝对路径、shell 元字符 |
|
|
10
|
+
| 已读取 `.harness/project.yaml` | 否 | 不存在时 profile 记为 unknown |
|
|
11
|
+
| 已读取 `.harness/context-index.json` | 否 | 不存在时可创建最小结构 |
|
|
12
|
+
| 已检查旧 map 状态 | 是 | 判断首次、缺失、过期、部分刷新 |
|
|
13
|
+
| 已确认输出路径为 `.harness/codebase/map/` | 是 | 禁止 `.planning/codebase/` |
|
|
14
|
+
| 已确认不执行 Git 写操作 | 是 | 禁止 add/commit/pull/merge/push/reset/checkout/rebase/clean;只允许 status / diff --name-only / rev-parse |
|
|
15
|
+
|
|
16
|
+
## 参数模式检查
|
|
17
|
+
|
|
18
|
+
| 模式 | 需要生成/检查 |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `--status` | 只检查 map 完整性、manifest、summary、stale 状态 |
|
|
21
|
+
| `--diff` | 对比 manifest 与当前代码状态,输出可能过期范围 |
|
|
22
|
+
| full / `--refresh` | 生成或刷新 7 个文档 |
|
|
23
|
+
| `--fast` | 默认刷新 `STACK.md`、`STRUCTURE.md`、`CONCERNS.md` |
|
|
24
|
+
| `--focus tech` | `STACK.md`、`INTEGRATIONS.md` |
|
|
25
|
+
| `--focus arch` | `ARCHITECTURE.md`、`STRUCTURE.md` |
|
|
26
|
+
| `--focus quality` | `CONVENTIONS.md`、`TESTING.md` |
|
|
27
|
+
| `--focus concerns` | `CONCERNS.md` |
|
|
28
|
+
| `--paths` | 只扫描合法 repo-relative 路径,仍按 focus 决定输出文档 |
|
|
29
|
+
|
|
30
|
+
## 输出文件检查
|
|
31
|
+
|
|
32
|
+
全量模式必须存在:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
.harness/codebase/map/STACK.md
|
|
36
|
+
.harness/codebase/map/INTEGRATIONS.md
|
|
37
|
+
.harness/codebase/map/ARCHITECTURE.md
|
|
38
|
+
.harness/codebase/map/STRUCTURE.md
|
|
39
|
+
.harness/codebase/map/CONVENTIONS.md
|
|
40
|
+
.harness/codebase/map/TESTING.md
|
|
41
|
+
.harness/codebase/map/CONCERNS.md
|
|
42
|
+
.harness/codebase/map-summary.md
|
|
43
|
+
.harness/codebase/map-manifest.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
模板目录必须包含:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
templates/STACK.md
|
|
50
|
+
templates/INTEGRATIONS.md
|
|
51
|
+
templates/ARCHITECTURE.md
|
|
52
|
+
templates/STRUCTURE.md
|
|
53
|
+
templates/CONVENTIONS.md
|
|
54
|
+
templates/TESTING.md
|
|
55
|
+
templates/CONCERNS.md
|
|
56
|
+
templates/map-summary.md
|
|
57
|
+
templates/map-manifest.schema.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
局部刷新模式中,未刷新文件如果已存在,可以保留;如果不存在,必须在报告中标记 WARN。
|
|
61
|
+
|
|
62
|
+
## 文档质量检查
|
|
63
|
+
|
|
64
|
+
每个生成文档必须满足:
|
|
65
|
+
|
|
66
|
+
- 有 YAML frontmatter。
|
|
67
|
+
- 标明 `generator: harness-codebase-map`。
|
|
68
|
+
- 标明 `file_kind: generated_reviewable`。
|
|
69
|
+
- 包含实际文件路径,路径使用反引号包裹。
|
|
70
|
+
- 不包含明文 token、password、secret、Authorization、Cookie、API key。
|
|
71
|
+
- 不把猜测写成事实;不确定内容用“推测 / 待验证”。
|
|
72
|
+
- 至少包含 “Analysis Date” 或 “Mapped At”。
|
|
73
|
+
|
|
74
|
+
## Manifest 检查
|
|
75
|
+
|
|
76
|
+
`map-manifest.json` 必须包含:
|
|
77
|
+
|
|
78
|
+
- `generator`
|
|
79
|
+
- `generated_at`
|
|
80
|
+
- `mode`
|
|
81
|
+
- `profile`
|
|
82
|
+
- `last_mapped_commit`
|
|
83
|
+
- `path_scope`
|
|
84
|
+
- `documents[]`
|
|
85
|
+
- 每个文档的 `path` / `document_type` / `sha256` / `line_count`
|
|
86
|
+
- `warnings[]`
|
|
87
|
+
|
|
88
|
+
## Context Index 检查
|
|
89
|
+
|
|
90
|
+
如果 `.harness/context-index.json` 存在:
|
|
91
|
+
|
|
92
|
+
- 必须保留未知字段。
|
|
93
|
+
- 只更新 `codebase.map` 相关字段。
|
|
94
|
+
- 不得覆盖 rules、knowledge、skills 其他索引。
|
|
95
|
+
|
|
96
|
+
如果不存在:
|
|
97
|
+
|
|
98
|
+
- 可创建最小结构。
|
|
99
|
+
- 报告中标记 `context-index: created-minimal`。
|
|
100
|
+
|
|
101
|
+
## 失败判定
|
|
102
|
+
|
|
103
|
+
以下情况必须标记 `❌FAIL`:
|
|
104
|
+
|
|
105
|
+
- 无法写入 `.harness/codebase/map/`。
|
|
106
|
+
- 全量模式下 7 个文档未全部生成,且不是用户明确选择局部模式。
|
|
107
|
+
- manifest 无法生成或 JSON 不可读。
|
|
108
|
+
- 写入后的文件无法 Read 验证。
|
|
109
|
+
|
|
110
|
+
以下情况标记 `🟡WARN`:
|
|
111
|
+
|
|
112
|
+
- Agent 工具不可用,降级为顺序扫描。
|
|
113
|
+
- 部分路径非法,被剔除。
|
|
114
|
+
- 无法获取 git commit,使用 `unknown`。
|
|
115
|
+
- context-index 不存在并创建了最小结构。
|
|
116
|
+
- 局部刷新导致部分文档仍缺失。
|
|
117
|
+
- 检测到可能敏感信息并已脱敏。
|
|
118
|
+
|
|
119
|
+
## 结束前必检
|
|
120
|
+
|
|
121
|
+
- [ ] 输出目录是 `.harness/codebase/map/`。
|
|
122
|
+
- [ ] 没有创建 `.planning/`。
|
|
123
|
+
- [ ] 没有修改 `.codegraph/`。
|
|
124
|
+
- [ ] 没有执行 Git 写操作。
|
|
125
|
+
- [ ] 所有写入文件已通过 Read 或文件存在检查验证。
|
|
126
|
+
- [ ] 最终回复中列出生成文件、行数、状态和 warnings。
|