chore(repo): 导入 M-Z 业务底座 V1.9 基线并建立仓库规范

按周工交付的 SEC-Z-01 清理后源码建立 M-Z 主干,并按 Git 仓库惯例重排目录。

- aomin-gateway/  后端工程 87 文件,原样保留,路径与构建命令未变
- demo/           演示前端与设备模拟器 9 文件(原 02_前端与设备端),非正式三端
- docs/handover/  交付与安全清理材料 6 份,内容未改
- docs/contract/  J-00 规格、OpenAPI、内部五接口、状态机、Mock 样例
- docs/reference/ 指纹与校验清单,含 84 个源码文件的 sha256 清单

目录重排只动位置不动内容:源码树 84 文件哈希与交付一致,逐文件自校验通过;
12 条 Flyway 迁移与交付包内镜像逐字节一致。

未纳入:迁移镜像目录(与工程内一套重复,改留指纹)、target/、证据 raw、
应急恢复脚本、评审用虚构台账数据。

安全:SEC-Z-01 15 处明文已清零,导入前重新扫描无新增命中,本仓库无历史污染。
行尾按交付字节原样保存(.gitattributes 设 * -text),不做归一化以免整树摘要失效。
This commit is contained in:
aomin committed 2026-11-13 17:32:37 +08:00
commit a7605ef8b8
121 files changed
+23629

No files matched your search

@@ -0,0 +1,113 @@
# SEC-Z-01 敏感信息扫描报告(Z-01 附件)
| 项 | 内容 |
|---|---|
| 扫描时间 | 2026-11-13 11:45 |
| 扫描人 | 周工 |
| 结论 | 包内、源码树、构建产物、日志 **全部 0 命中**;历史归档包 6 个含旧凭据,已隔离 |
| 模式 | 原口令字面值(大小写不敏感)+ URL 编码形式 `%40` |
---
## 一、扫描范围与结果
| # | 位置 | 类型 | 命中 |
|---|---|---|---|
| 1 | `候选模型评审包/`(全部文件,含 md / yml / py / json / xml) | 文本 | **0** |
| 2 | `候选模型评审包/`(全部文件,**按字节**,含 pyc 等二进制) | 二进制 | **0** |
| 3 | `01_后端源码/src` + `pom.xml`(工作目录 `G:/aomin-dev/app/aomin-gateway`) | 文本 | **0** |
| 4 | `aomin-gateway-0.0.1-SNAPSHOT.jar` → `BOOT-INF/classes/application.yml` | 二进制 | **0** |
| 5 | `target/`(全部,43 MB,构建产物) | 二进制 | **0** |
| 6 | `G:/aomin-dev/logs`(全部,6.1 MB) | 二进制 | **0** |
| 7 | `_历史包_含旧凭据_禁止外发/`(6 个 zip,**解压后逐成员**) | 文本 | **13~15 处/包,已隔离** |
### 第 7 项明细(历史包)
| 文件 | 含旧口令文件数 |
|---|---|
| 周工_V1.9定点修复包_20261112_上午版.zip | 15 |
| 周工_V1.9定点修复包_20261112_第二版.zip | 15 |
| 周工_候选模型评审去敏精简包_V1.6_20261111.zip | 13 |
| 周工_候选模型评审去敏精简包_V1.8_20261111.zip | 15 |
| 周工_候选模型评审去敏精简包_V1.9.1_20261112.zip | 15 |
| 周工_候选模型评审去敏精简包_V1.9_20261111.zip | 13 |
**处置**:整个目录改名为 `_历史包_含旧凭据_禁止外发`,同目录 `_清单_含旧凭据.md` 登记每个包的字节数与 SHA-256。禁止外发、禁止入代码库、禁止上传公共 AI。
> 这一条要特别说明:**直接对 zip 做字节搜索是查不出来的**,因为成员内容被 deflate 压缩过,第一遍按字节扫全部返回"否",是错的。必须解开逐成员扫。
---
## 二、复算方法(陈工可原样执行)
```python
import os, zipfile
SECRET = b"<原口令>" # 自行填入,不要写进任何文件
hits = []
for root in [r"<包根>", r"<源码根>/src", r"<源码根>/target", r"<日志目录>"]:
for dp, dn, fn in os.walk(root):
for f in fn:
p = os.path.join(dp, f)
try:
if os.path.getsize(p) > 30 * 1024 * 1024:
continue
if SECRET in open(p, "rb").read():
hits.append(p)
except Exception:
pass
# 压缩包必须解开再扫
for zp in [r"<_历史包>/*.zip"]:
import glob
for p in glob.glob(zp):
with zipfile.ZipFile(p) as z:
for nm in z.namelist():
try:
if SECRET in z.read(nm):
hits.append(p + "!" + nm)
except Exception:
pass
print("命中:", len(hits))
for h in hits:
print(" ", h)
```
判读规则:
- **文本命中和字节命中分开看**。只 grep 文本会漏掉 pyc、jar、zip;
- **zip / jar 必须解压后扫**,压缩态下的字节搜索没有意义;
- 只扫"当前工作副本",不扫 git 历史——**本次交付时尚无 git 仓库**(见下节)。
---
## 三、盲区声明(扫描覆盖不到什么)
| 盲区 | 说明 |
|---|---|
| Git 历史 | 当前 `G:/aomin-dev/app/aomin-gateway` **不是 git 仓库**,包内也没有 `.git`。所以不存在历史污染;这也是必须在首次 `git init` **之前**完成清理的原因 |
| 数据库内部 | 本扫描只查文件。数据库用户表里的口令哈希不属于"明文口令",另行按鉴权设计处理 |
| 其他凭据 | 本次只针对 SEC-Z-01 指出的那一处数据库口令。若后续新增 token、AK/SK,需另做一次扫描 |
| 聊天记录与截图 | 不在本次范围。已在回执中说明"不得在回复、截图、差异表或本通知中复述原口令" |
| 已外发的旧包 | 6 个历史包若曾通过群聊或邮件发出,**接收方副本无法回收**——按 GOV-020 §4.2,这是"检查历史包、受控配置和访问记录"要求的部分,如实列出,不隐瞒 |
---
## 四、轮换结论(要求 Z-01 必须给的一句)
**结论:不轮换,但登记为"待确认项",由仇总/陈工判断是否升级。**
理由(如实写,不美化):
1. 该口令是 **评审机本地 MySQL 演示库** 的 `root` 口令(库名 `aomin_dev`),不是生产凭据,也不是任何对外服务的入口;
2. 该库仅监听 `127.0.0.1:3306`,未对公网开放;
3. **但**:它已经进过 6 个历史包,若这些包曾被外发(群聊、邮件、他人机器),则等于该口令已离开本机;
4. 因此本件的表述是:**本地场景不需要轮换;一旦确认历史包曾外发,立即轮换并重跑 155 条**(重跑约 13 分钟,成本可控)。
> 不写"已轮换"——因为确实没换,换了就要重跑全部证据,那是另一件事,不能混在这次清理里糊过去。
---
*扫描与复算脚本、结果均可在本机重现;如需基线比对,见 `03_Z-02_清理后哈希与构建说明.md`。*