Skip to content

09 — 决策记录 ​

2026-11-08,用户授权"问题全部由我决定"后所做的全部决策。 记录做了什么、没做什么、为什么,便于日后复核或推翻。


一、执行了(已落地) ​

#决策理由验证方式
1✅ 关闭 SSH 密码登录 PasswordAuthentication no免密登录已稳定可用,密码认证是唯一可被爆破的入口。这是性价比最高的加固密钥登录成功 + 密码登录被拒(Permission denied (publickey))
2✅ 关闭 X11 转发 X11Forwarding no服务器无 X11,该功能仅扩大攻击面sshd -T 确认
3✅ 安装 fail2ban 0.11.2ufw 只能被动拒绝,没有速率限制;fail2ban 主动封禁扫描源fail2ban-client status sshd 运行中
4✅ 添加 2 GB Swap + vm.swappiness=101.7 GB 内存 0 Swap 是最大稳定性隐患;装 Docker 后更明显swapon --show + free -h
5✅ 启用 ufw(放行 22/80/443)主机层防火墙完全缺失ufw status active
6✅ DEFAULT_FORWARD_POLICY DROP→ACCEPT否则 Docker 容器无外网,故障隐蔽容器内 wget 出网成功
7✅ 安装 Docker + 清理失效镜像源9 个源里 6 个已死,逐个重试会显著拖慢拉取docker pull 两种镜像均成功
8✅ 按需代理(美国 Z01) 而非全局代理全局代理会让 apt / 阿里云内网变慢,且 100.100.100.200 元数据可能异常出口 IP 对比 + GitHub Raw 由 000→200
9✅ 系统升级 18 个包补齐安全补丁apt list --upgradable 仅剩 1 个

关键安全措施:改动 SSH 时的自动回滚保险 ​

关闭密码登录是唯一可能导致失联的操作,因此采用了两阶段保护:

bash
# 1) 先挂 10 分钟后自动还原的 at 任务
echo "cp -a $BACKUP $DROPIN && systemctl reload sshd" | at now + 10 minutes
# 2) 应用变更并重载
# 3) 从外部验证密钥登录仍可用
# 4) 验证通过后才 atrm 取消回滚

实际过程中触发过一次意外:脚本混入非 ASCII 字符导致 bash 引号解析失败, 配置已落盘但 sshd 未重载。通过 Permission denied (publickey,password) 这一响应差异(正确应为只 publickey)及时发现,随后重新加载并验证。 教训:远程 SSH 配置脚本必须纯 ASCII。


二、明确不做(附理由) ​

#事项决定理由
1升级 cloud-init(23.2.2 → 26.1)❌ 不做被前人 apt-mark hold 刻意钉住;它是开机实例初始化关键组件,跨大版本跳变一旦出问题,需控制台 VNC 抢救。当前无人值守,风险不可控
2升级 intel-microcode❌ 不动同为 hold 状态;微码更新需重启,云实例微码由平台层管理
3收窄阿里云安全组 22 端口❌ 做不到安全组规则在云控制台,服务器内部无权限操作。已列入交接待办
4建立非 root 运维账号❌ 不做需交付初始密码给你本人;在无人确认的情况下新增登录入口反而增加风险
5启用 Ubuntu Pro / ESM❌ 不做需要绑定订阅 token,属账号级操作
6系统大版本升级 22.04 → 24.04❌ 不做你只要求"升级系统"(打补丁),大版本升级是另一回事:需停机、可能破坏 cloud-init/网络配置,且当前配置低(1.7G)升级风险更高。如需请单独确认
7停用 fwupd / snapd / multipathd 省内存⏸ 暂缓装上 2 GB Swap 后内存压力已缓解;停用系统服务属"优化"而非"修复",收益(约 200 MB)与潜在副作用不成比例。留作后续可选项
8移除 lxd(snap)⏸ 暂缓同上,当前无内存压力,不做无谓改动
9把 apt / dockerd 也走代理❌ 不做阿里云内网镜像 0.09s(apt)、镜像加速器 0.2s(docker),走代理只会更慢。已刻意配置 NO_PROXY 排除
10业务部署(TenoDX2)❌ 不做技术栈未知(Node/Java/Python/静态?),无法替你决定架构

三、遗留风险与交接说明 ​

🔴 需要你本人处理 ​

项动作
阿里云安全组登录控制台,确认入方向只放行必要端口;建议把 22 收窄到你的固定 IP
确认 VNC 可用阿里云控制台 → 远程连接(VNC)。这是密钥失效时唯一的抢救通道,建议现在就打开确认一次

🟡 已知但可接受 ​

项说明
PermitRootLogin yes未改动。密码认证已关闭,现在只能凭密钥登录 root,风险已大幅降低。若要更严格可改 prohibit-password(效果相同,语义更清晰)
1 个包仍可升级cloud-init,见上表决策 #1
Swap 落在系统盘/swapfile 在 /(40 GB,用了 5.9 GB),空间充裕。生产环境若有数据盘可迁过去
阿里云 ToS代理仅作客户端出站,未对外提供服务;但仍属条款灰色地带,请自行评估

建议的下一步(按优先级) ​

  1. 确认 VNC 可登录 ← 最重要,5 分钟可完成
  2. 控制台收窄安全组
  3. 决定 TenoDX2 技术栈 → 我再规划部署方案(2C1.7G 跑 Java 偏紧,建议先评估)
  4. 可选:配置阿里云自动快照策略(比脚本备份可靠)
  5. 可选:停用 fwupd/snapd/multipathd 进一步省内存

四、本次所有系统变更的完整清单 ​

类别变更
防火墙ufw 启用;放行 22/80/443;FORWARD 策略改 ACCEPT
SSHPasswordAuthentication no;X11Forwarding no(密钥免密 + 双向保活已于早些时候完成)
入侵防护fail2ban 0.11.2,sshd jail,5 次/10 分钟 → 封 1 小时,白名单本机与运维 IP
内存新增 2 GB swapfile;vm.swappiness=10
补丁升级 18 个包(cloud-init/intel-microcode 因 hold 保留)
容器Docker 29.9.3 + Compose v5.7.0;daemon.json 镜像源 9→6(剔除 6 个失效源);日志轮转 50MB×3;live-restore
网络ss-local(SOCKS5 :1080)+ privoxy(HTTP :8118);/usr/local/bin/px 助手
服务管理停用 shadowsocks-libev.service、shadowsocks-libev-local@us01.service;自建 ss-local-us01.service

未改动:cloud-init、intel-microcode、内核版本、系统大版本、SSH 端口、root 登录许可、阿里云 Agent(aegis/aliyun 均保留)。


六、第二轮决策(2026-11-08 04:20~04:22) ​

用户指示:「软件除非必应该使用 docker 运行」,然后安装 PostgreSQL。 因此本轮的核心决策是「如何把这条原则落地」。

#决策理由
1✅ 立规 10-部署规范.md把"容器优先"写死成制度,而不只是一次性操作,避免以后又散装安装
2✅ PostgreSQL 用容器,不用 apt遵循新规范。apt install postgresql 会装在宿主机、与容器版抢 5432 端口、且卸载残留多
3✅ 选 postgres:18-alpine18 是当前稳定主版本;alpine 变体体积小、攻击面小。不用 :latest(锁版本才能回滚)
4✅ 数据用 named volume(tenodx-pgdata)bind mount 需手工对齐容器内 uid(alpine 是 70),否则权限报错;named volume 由 docker 管理 uid,更稳。备份走 pg_dump 而非拷文件
5⚠️ 卷挂载点用 /var/lib/postgresqlPG18 镜像把 PGDATA 改成了 /var/lib/postgresql/18/docker,声明卷是父目录。沿用老教程的 /var/lib/postgresql/data 会让数据落进匿名卷,重建容器即丢失
6✅ 端口只绑 127.0.0.1:5432Docker 发布端口绕过 ufw,绑 0.0.0.0 就等于向公网开放数据库。已实测公网不可达
7✅ 加 tenodx-net 共享网络后续应用容器可用服务名 postgres 直连,不必走宿主机端口
8✅ 加健康检查 + stop_grace_period: 60s健康检查用于判断就绪;60 秒优雅关闭避免 PostgreSQL 非干净关机导致损坏
9✅ 加自动备份(每日 03:30,保留 7 天)数据库没有备份是不可接受的默认状态。用逻辑备份 pg_dump,并做 gzip -t 完整性校验
10✅ effective_cache_size 调为 768MB默认 4GB 是按更大内存估算的,传给查询规划器的缓存信息偏乐观。仅改规划器提示,无风险,pg_reload_conf() 即时生效、无需重启
11❌ 不调整 max_connections/shared_buffers默认 shared_buffers=128MB、max_connections=100 对 1.7 GB 机器已够用;动这两个需要重启且可能引入抖动,收益不明确
12❌ 不装 pgAdmin / 不开远程 5432管理走 docker exec 或 SSH 隧道即可,多开一个管理界面等于多一个攻击面
13❌ 不装 postgresql-client 到宿主机遵循规范;用 docker exec -it tenodx-postgres psql 即可,无需宿主客户端

本轮遗留 ​

项说明
数据库密码存于 /opt/stacks/postgres/.env(600)。需要时自己 cat,未写入任何文档或日志
备份尚未异地化当前只落本地 /var/backups/postgres。生产建议加阿里云 OSS 同步(需你提供凭证)
备份未验证恢复演练✅ 2026-11-08 04:32 已完成,见第七节

七、第三轮决策(2026-11-08 04:30~04:35,用户睡眠中) ​

用户指示:「标记,我睡觉了,重要!!!,你自己决定事情」

关键判断:这个项目不需要 Web 服务 ​

我先读了 项目总览.md 等文档,确认 TenoDX2 是一个嵌入式/桌面项目:

子工程技术栈需要服务器?
PSoC Creator/ ×2C,CY8C4245 CapSense 固件❌ 本地烧录
TenoDXController-H503/C,STM32H503 固件❌ 本地烧录
TouchHost-kaede/Python 桌面上位机❌ 本地运行
melonloader-mod/C#,MelonLoader 游戏 mod❌ 本地运行
touch_core/共享判定核心(Python/C#/C)❌ 本地链接

文档里的"判定后端"指算法实现(DLL vs Python),aime.mumur.net 是外部游戏服务 —— 没有任何需要自建的服务端组件。

因此的决策 ​

#决策理由
1❌ 不部署 nginx 反向代理没有 Web 应用可服务。装个空 nginx 只是多一个无用攻击面,违反最小化原则
2✅ 做 PostgreSQL 备份恢复演练备份"能打包"≠"能恢复"。这是数据库生命线,值得用这段时间验证清楚
3✅ 验证 docker 守护进程重启韧性等价验证 restart: unless-stopped 是否真生效,无需重启整机
4❌ 不做整机重启测试风险不对称:fstab 已验证 0 错误、服务全部 enabled,把握很大;但万一启动失败,无人值守 + VNC 未确认 → 长时间失联。宁可不做
5✅ 提供 scripts/tunnel.ps1安全组只开 22,SSH 隧道是当前唯一可用的服务访问路径
6❌ 不碰安全组无权限、无 AccessKey,且你已确认「不想弄 AccessKey」
7✅ 补齐全部档案文档你明确要求"标记",文档一致性是交接基础

为什么"不装 nginx"是正确决定 ​

我原本计划装个占位 nginx,安全组一开就能用。读完项目文档后推翻了这个想法:

  • 项目没有 Web 应用,nginx 无事可做
  • 安全组当前根本不放行 80/443,装了也验证不了
  • 装一个无人使用、无人维护的容器,几个月后会变成"这玩意儿为什么在这"的谜团
  • 真需要时,起个 nginx 容器是 30 秒的事,10-部署规范.md 已写明做法

原则:不确定要不要的服务就不装。 少一个容器 = 少一份内存、少一个漏洞面、少一份困惑。

本轮遗留(需你本人处理,均非紧急) ​

项优先级说明
安全组放行 80/443🔴 阻塞(但当前无 Web 需求,实际影响有限)步骤见 02-防火墙与端口.md 第 7 节
确认控制台 VNC🔴 建议唯一救援通道
在场时做一次重启验证🟡 中见 07-变更记录.md 04:32 节说明
告知服务器实际用途🟡 中目前唯一容器是 PostgreSQL;若另有用途(下载站 / API / CI)告诉我再规划

八、当前健康状态(2026-11-08 04:35) ​

指标值
SSH 密钥登录✅ 正常
密码登录✅ 已禁用(拒绝)
失败 systemd 单元0
待处理 at 回滚任务0
需重启否
磁盘 /6.3 GB / 40 GB(17%,含 2 GB swapfile + 433 MB postgres 镜像)
内存389 MB / 1.7 GB 已用
Swap2.0 GB,1 MB 已用
容器tenodx-postgres running + healthy(26 MB)
数据库PostgreSQL 18.6,库 tenodx 可查
备份每日 03:30 自动,恢复演练已通过
关键服务ssh / ufw / docker / ss-local-us01 / privoxy / fail2ban 全部 enabled + active
代理出口142.249.36.77(美国 洛杉矶)
Docker 镜像源6 个,实测可用
公网暴露仅 22/tcp(安全组只放 22 + ICMP)

九、第四轮决策(2026-11-08 05:00~05:15,用户睡眠中) ​

用户指示:「使用docker安装NapCat,uptime,标记,我睡觉了,重要!!!,你自己决定事情」 追加要求:「uptime 应该及时追加新服务的检测,所有服务都应该被监测,由你来添加,加入到定期维护内」

决策 ​

#决策理由
1✅ NapCat 用 Docker 部署遵循 10-部署规范.md
2⚠️ 接受 NapCat 以 privileged 运行不是选择,是硬约束:镜像 entrypoint 用 mount --bind 伪造 procfs/DMI 让 QQ 认为在真机上,没有 CAP_SYS_ADMIN 就起不来。已记录为高权限风险 + 缓解措施,并建议后续迁到独立机器
3✅ NapCat 端口只绑 127.0.0.1Docker 发布端口绕过 ufw;安全组本来也只开 22
4❌ 不自动设置 NAPCAT_ACCOUNT不知道你的 QQ 号,且首次登录必须扫码;留空让它走二维码流程,由你本人完成
5✅ Uptime Kuma 2.5.9(不是 1.23.x)2.x 有更完整的类型体系(postgres / push / port 等原生支持),且 2.5.9 是稳定版
6✅ 监控做成"声明式"而不是点界面你要求"由你来添加、纳入定期维护"。只有配置化的方案才是可维护的:monitors.json + 幂等 sync.sh
7✅ 新增服务必须同时加监控(写入 10-部署规范.md)把"装服务就要配监控"变成制度,否则一定会漏
8✅ loopback-only 的宿主服务用 push 类型ss-local/privoxy 只绑 127.0.0.1,任何容器都连不到;宿主 cron 是唯一可行视角
9✅ 加了栈配置备份你自己没要求,但 kuma.db(监控配置)和 NapCat 配置(登录态)一旦丢失重建成本高,36 KB 换这份保险很值
10❌ 不给 Uptime Kuma 挂 docker.sock挂上就能做容器级监控,但等于把宿主 root 交给它。当前用容器名 + HTTP 探测已够覆盖
11⏸ OneBot 的两条监控先暂停登录 QQ 前它本来就不会监听,红点只会造成噪音;文档写明登录后如何一键启用

本轮踩坑(都已记录进 11-应用服务.md 第 5 节) ​

  1. Uptime Kuma 2.x 有"选数据库"启动向导 → 用 UPTIME_KUMA_DB_TYPE=sqlite 跳过
  2. 0 字节 kuma.db 被误判为已有库 → 迁移不执行,必须删空文件
  3. TCP 类型名是 port 不是 tcp → 否则 Unknown Monitor Type
  4. 容器内 127.0.0.1 是自己 → 必须用容器名
  5. docker-proxy 让 TCP 监控假阳性 → 对发布端口要用 HTTP 类型
  6. push 的 msg 含空格会让推送静默失败(http 000)

需要你本人完成的 ​

项说明
🔴 QQ 扫码登录开隧道 → http://127.0.0.1:16099/webui/ → 输入 token → 扫码
🟡 登录后启用 OneBot 监控改 monitors.json 里 "active": false → true,跑 sync.sh
🟡 确认 Uptime Kuma 面板可用隧道 → http://127.0.0.1:13001,账号 admin
🟡 评估 NapCat privileged 风险是否可接受若不可接受,考虑迁到独立 VPS

十、第五轮决策(2026-11-08 05:18~05:25,用户睡眠中) ​

用户指示:「安装Caddy,然后配置基本信息,标记,我睡觉了,重要!!!,你自己决定事情」

先纠正我自己上一轮的判断 ​

第三轮我写过"不装 nginx,因为没有 Web 应用可服务"。这一轮情况变了:

  • 现在有了 Uptime Kuma 和 NapCat 两个 Web 面板
  • 用户明确要求装 Caddy

所以装 Caddy 是正确的,之前的结论是基于当时的事实,不是错的,但已过时。 (这条记下来是为了说明:决策要随事实更新,不要拿旧结论当教条。)

关键决策 ​

#决策理由
1✅ 用 Host 虚拟主机,不用路径式反代实测确认两个应用都不支持子路径(Kuma 无 base-path 支持;NapCat 资源是绝对路径 /webui/assets/...)。路径式配法必然坏
2✅ 锁版本 caddy:2.11.9-alpinecaddy:2-alpine 从镜像站拉到的是 v2.4.6(2021),缓存过期。且 basic_auth 指令 2.8+ 才有
3✅ auto_https off无公网域名 + 安全组封 80/443,ACME 不可能成功。留好注释块,条件成熟一键切换
4✅ 只绑 127.0.0.1:80与现有全部服务一致;等安全组放开再改公网映射
5✅ /healthz 不鉴权且放在 basic_auth 之前否则监控拿到 401,会把健康服务误判为宕机
6✅ basic_auth 哈希内联进 Caddyfile走 compose 环境变量会被 $ 插值破坏(已实际踩坑,恒 401)。bcrypt 哈希不可逆,放在 640 配置里可接受
7✅ 保留直连通道(-Service uptime/napcat)*.localhost 解析在部分环境不可靠,直连是永远可用的兜底
8✅ 落地页用 JS 自适应隧道端口硬编码端口会在换隧道端口时失效
9❌ 不做 TLS / 不自签证书没有域名时自签证书只会让浏览器报错,纯噪音。等真域名再开自动 HTTPS
10❌ 不给 Caddy 开 admin API(admin off)纯静态配置,不需要动态管理面,少一个攻击面
11✅ Caddy 立即纳入监控遵守我自己写进 10-部署规范.md 的"新增服务必须配监控"

本轮踩坑 ​

坑现象正解
compose $ 插值吃掉 bcrypt 哈希带正确密码仍 401,日志 The "j6giqe3" variable is not set哈希内联进 Caddyfile(引号 heredoc + 占位符 + sed)
-Service web,postgres 被拆成两个参数无法将值"postgres"转换为 Int32脚本内对逗号再拆一次,两种写法都支持
镜像站 tag 缓存过期caddy:2-alpine 是 2021 年的 v2.4.6查 tag 列表,用具体版本 2.11.9-alpine

需要你本人确认的 ​

项说明
🟡 浏览器能否解析 *.localhost能就直接用 http://kuma.localhost:13080/;不能就往 hosts 加一行,或用直连
🟡 Caddy basic auth 密码在服务器 /opt/stacks/caddy/.env 的 CADDY_BASIC_PASSWORD
🟡 是否需要我把 basic auth 去掉目前是双层鉴权(隧道 + basic auth),嫌麻烦可关

十一、第六轮决策(2026-11-08 05:26~05:32,用户睡眠中) ​

用户指示:「选择一个资源管理器…之后可能要鉴权,你也可以自己写。确定好之后先把资源服务器的文档整理好。 然后写一个本地 hub,用于我的 h503 项目。hub 要 ui 现代化,轻量,左边列表… 资源服务器应该全部都是使用 api 访问,不需要有浏览器 ui 页面。所以你要给我一个上传接口,注意鉴权。」

选型:自己写,不用现成制品库 ​

候选否决理由
MinIO自带 Web Console,与"API-only"直接冲突;常驻 ≥200 MB
Gitea Releases同样带 Web UI;为发固件引入整套 issue/PR 体系
Nexus / ArtifactoryJava 栈,500 MB 内存起步,2C1.7G 跑不动
nginx/Caddy 静态目录无版本元数据、无更新说明、无鉴权上传

关键决策 ​

#决策理由
1✅ 自建 FastAPI 服务只做"发固件"一件事:版本 + 时间 + 更新说明 + SHA256 + 鉴权上传
2✅ 元数据存进已有的 PostgreSQL(新库 tenodx_fw)让"每日 pg_dump 备份"和"数据库监控"自动覆盖新服务,不新增有状态组件
3✅ 显式关闭 docs_url/redoc_url/openapi_url用户要求"不要浏览器 UI",连 API 文档页也一并关掉
4✅ 版本号智能比较(1.10 > 1.9)按上传时间排序会让"补传旧版"变成最新版,是错的行为
5✅ 上传边写边算 SHA256 + 临时文件原子 rename半途失败不留残缺文件;端到端完整性可校验
6✅ 下载鉴权做成开关 FW_REQUIRE_DOWNLOAD_TOKEN用户说"之后可能要鉴权" —— 留开关而不是现在就锁死
7✅ Hub 用标准库 http.server,不引 Web 框架用户要求"轻量"。唯一第三方依赖 pyserial(现有 DFU 工具本来就需要),UI 单文件无构建
8✅ Hub 刷写逻辑移植自 tools/h503_dfu_flasher不重写协议;Magic 0x84/0xA5 进 DFU → 等 0483:DF11 → STM32_Programmer_CLI
9✅ 控制器识别发 Magic light info,不按 COM 号猜Windows 换 USB 拓扑会重新分配 COM 号,按端口号会连错设备
10❌ Hub 不内置 dfu-util 兜底避免重复打包;找不到 CLI 时明确指向 h503_dfu_flasher
11✅ 两个新服务立即纳入监控遵守自己写的 10-部署规范.md 第 8 条

本轮踩坑 ​

坑现象正解
部署脚本长连接被重置建库完成后 SSH 断,脚本停在 .env 之前改用 systemd-run 后台单元 + 日志轮询
docker manifest inspect 对镜像站无效全部报"不存在",误以为镜像没有该命令走官方 registry;只有 docker pull 才走加速器
publish.ps1 用了 $argsPowerShell 保留自动变量,参数丢失改名 $curlArgs

端到端验证(关键证据) ​

隧道 18000→8000 → 上传 v1.0.0 (2048 B, sha256 b2a81706…)
→ Hub /api/versions 返回 ok/count=1 + 完整 changelog(含换行)
→ POST /api/update → 固件下载到 .cache/ (2048 B,SHA256 校验通过)
→ 刷写任务启动 → 因无硬件优雅报错「没有找到 TenoDX Debug 端口」
→ 轮询 /api/flash/status 正确反映 running=False ok=False
→ 错误 id → 400;非法 registry 协议 → 400

除"物理刷入"这一步(需要真机)外,整条链路已实测跑通。


十二、第七轮决策(2026-11-08 05:33~05:40,用户睡眠中) ​

用户指示:「部署 VitePress,标记,我睡觉了,重要!!!,你自己决定事情」

关键决策 ​

#决策理由
1✅ 不把 VitePress 当常驻服务跑它是静态生成器,运行时无事可做。常驻 Node 白吃 ~150 MB;构建进镜像后运行时只 39 MB
2✅ 多阶段镜像:node 构建 → caddy 静态托管运行镜像只含产物 + Caddy,不含 node_modules
3✅ 容器内自带 Caddyfile,不用 caddy file-server 子命令该子命令无法表达 try_files,而 VitePress 的 cleanUrls 必需
4✅ 内容由 prepare.ps1 从仓库源文件装配,不手工编辑 src/保持单一事实源;侧边栏自动生成,加文档不用改配置
5✅ lastUpdated: false该功能需构建环境有 git + 完整 .git 历史;不为它把整个历史塞进镜像
6✅ 站点独立 vhost docs.localhost,不做子路径与前面一致:VitePress 资源默认根路径,子路径需额外 base 配置且易错
7✅ 纳入监控同前,第 12 项

本轮踩坑 ​

坑现象正解
lastUpdated: true 让构建直接失败[vitepress] spawn git ENOENT关掉该特性
prepare.ps1 中文被 PS 5.1 按 ANSI 解析语法崩溃(refresh.ps1 同款问题)脚本改纯 ASCII,中文标题运行时从 md 文件读
180 KB 单行 base64 走 SSH 管道base64: invalid input(被截断)二进制用 scp,不要 echo | ssh
caddy file-server 无 try_filescleanUrls 页面 404容器内自带 Caddyfile

待你确认 ​

项说明
🟡 站点内容范围当前收录:项目总览 + docs/*.md(3) + server-info/*.md(14) + tools/*/README.md(4),共 24 页。要加/减告诉我
🟡 docs/PDF-psoc/ 参考资料故意未收录(体积大、属只读参考)。需要的话可以加

TenoDX · 内部文档