Files
group_fqcd_jr/客服agent/_build/_shell_tail.html
T
张胜宇 bc61d5c579 docs: 入库权威文档目录(客服agent/ 24 份 + 开发文档/ 50 份,替换旧命名的过期副本)
## 为什么做这一步

权威文档 74 份此前**只在本机**,评审者 clone 分支后看不到任何设计文档;而仓库里那两份同名目录
是 **2026-09-16 之前的过期副本,连文件名都是旧的**(无体系编号)。本次按「**权威覆盖过期**」入库。

## 入库内容

| 目录 | 文件数 | 体积 | 说明 |
|---|---|---|---|
| `客服agent/` | 24 | 0.77 MB | `D2.1`~`D2.6` 对外交付四件套 + 演示脚本/答辩报告 + `_build` 构建工具 |
| `开发文档/` | 50 | 2.16 MB | `D1.x` 索引与决策、`D3.x` 方案、`D4.x` 清除与重构留痕、`D5.x` 业务流程、`D6.x` 业务事实基座、`D7.x` 交付物、`D8.x` 规范 |

**旧的过期副本整体移除**(`客服Agent执行Todolist.md` → `D2.1-客服Agent执行Todolist.md` 之类
的改名 + 新增 `D2.5`/`D2.6`),入库后目录内容与权威副本**逐文件一致(零差异,已复核)**。

## 入库前的安全扫描(必须留痕)

- 扫描规则:`sk-` 类密钥 / `Bearer` 长串 / `password=`、`api_key=` 赋值 / 会话中出现过的两把明文 key 片段。
- 结论:**真实密钥只出现在 `.env`**(已被 `.gitignore` 命中,未入库);`.env.example` 与
  `config/risk.env.example` 只有**空占位**。
- 文档内唯一命中是 `D3.1` 里一处**截断的示例 JWT**(`Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`),
  末尾带省略号,是接口文档的示意值,**不是可用凭据**。
2026-09-20 15:03:15 +08:00

83 lines
2.4 KiB
HTML

</div><!-- end doc-container -->
</main>
<script>
mermaid.initialize({
startOnLoad: true,
theme: 'base',
themeVariables: {
primaryColor: '#e3f2fd',
primaryTextColor: '#1e293b',
primaryBorderColor: '#1976d2',
lineColor: '#64748b',
secondaryColor: '#fff3e0',
tertiaryColor: '#f4f1eb',
fontFamily: 'Inter, sans-serif',
fontSize: '14px',
},
flowchart: { curve: 'basis', padding: 15 },
securityLevel: 'loose',
});
// ── Progress bar ──
const bar = document.getElementById('progress-bar');
function updateProgress() {
const h = document.documentElement;
const pct = ((h.scrollTop) / (h.scrollHeight - h.clientHeight)) * 100;
bar.style.width = Math.min(100, pct) + '%';
}
window.addEventListener('scroll', updateProgress);
// ── Topbar title ──
const topbarTitle = document.getElementById('topbar-title');
const headings = document.querySelectorAll('.doc-container h1[id], .doc-container h2[id], .doc-container h3[id], .doc-container h4[id]');
function updateTopbar() {
let current = '';
headings.forEach(h => {
if (h.getBoundingClientRect().top <= 120) current = h.textContent;
});
if (current) topbarTitle.textContent = current;
}
window.addEventListener('scroll', updateTopbar);
// ── TOC active state ──
const tocLinks = document.querySelectorAll('.toc-item');
function updateToc() {
let activeId = '';
headings.forEach(h => {
if (h.getBoundingClientRect().top <= 120) activeId = h.id;
});
tocLinks.forEach(link => {
link.classList.toggle('active', link.getAttribute('href') === '#' + activeId);
});
}
window.addEventListener('scroll', updateToc);
// ── Collapsible TOC groups ──
document.querySelectorAll('.toc-toggle').forEach(btn => {
btn.addEventListener('click', () => {
const kids = btn.nextElementSibling;
const arr = btn.querySelector('.arr');
btn.classList.toggle('active');
kids.classList.toggle('open');
arr.classList.toggle('open');
});
});
// ── TOC search ──
const tocSearch = document.getElementById('toc-search');
tocSearch.addEventListener('input', () => {
const q = tocSearch.value.toLowerCase();
document.querySelectorAll('.toc-item, .toc-toggle').forEach(item => {
item.style.display = (!q || item.textContent.toLowerCase().includes(q)) ? '' : 'none';
});
});
// ── Initial ──
updateProgress();
updateTopbar();
updateToc();
</script>
</body>
</html>