fix(config): 身份文件 ASCII 化(\u 转义)修 PS5.1 GBK 读炸——10-06 21:00 xt_eod 生产实证: ConvertFrom-Json FormatException→BIGQMT_ACCOUNT_ID 未注入→桥 shim 硬错 account_id is required→universe ETF/基金=0→rc=1(对照 10-05 同假期班 rows=37301 正常, 30d 窗口拉取自愈无数据损失); 修=ensure_ascii 重写(值 round-trip 等值)+test_qmt_identity 第④钉(文件纯 ASCII, phase-③ wrapper 裸 Get-Content 安全性由钉担保)+落档案 §四④/§五①′(部署硬期限=10-08 复市 21:00 xt-daily 前, 理想 10-07 当天) [vps] [no-doc]
CI/CD / nas-deploy (push) Blocked by required conditions
CI/CD / nas-verify (push) Blocked by required conditions
CI/CD / test (push) Successful in 42s

This commit is contained in:
2026-10-07 11:45:00 +08:00
parent 95f1a458c8
commit 5d5a9f29f4
3 changed files with 27 additions and 4 deletions
+12 -3
View File
@@ -87,21 +87,30 @@ env SANGUO_QMT_ACCOUNT > env BIGQMT_ACCOUNT_ID(兼容别名,存量 wrapper 设
| `docs/deployment/vps-production-runbook.md` | 身份文件条目(CI 基建门:qmt_relogin/bridge_switch_ops 触发) | | `docs/deployment/vps-production-runbook.md` | 身份文件条目(CI 基建门:qmt_relogin/bridge_switch_ops 触发) |
| `docs/superpowers/specs/2026-10-03-monitoring-design.md` | gate 簇身份链一句话 + 坑台账 | | `docs/superpowers/specs/2026-10-03-monitoring-design.md` | gate 簇身份链一句话 + 坑台账 |
### 测试策略(tests/trader/test_qmt_identity.py 三组钉) ### 测试策略(tests/trader/test_qmt_identity.py 四组钉)
1. **装载链语义**:env 两名覆盖、`SANGUO_IDENTITY_JSON` 指空=RuntimeError、模块 `ACCOUNT` ≡ json。 1. **装载链语义**:env 两名覆盖、`SANGUO_IDENTITY_JSON` 指空=RuntimeError、模块 `ACCOUNT` ≡ json。
2. **单源一致性(anti-drift,休市表先例)**:identity ≡ live.yaml.account ≡ ∈ watch_accounts ≡ 2. **单源一致性(anti-drift,休市表先例)**:identity ≡ live.yaml.account ≡ ∈ watch_accounts ≡
gate_common.ACCOUNT ≡ xt_gateway/qmt_gateway_client 镜像解析值(env 清空)。 gate_common.ACCOUNT ≡ xt_gateway/qmt_gateway_client 镜像解析值(env 清空)。
3. **字面量 grep-pin**:`66639661` 只允许出现在 config 三件套 + tests/ + docs/ + audit/; 3. **字面量 grep-pin**:`66639661` 只允许出现在 config 三件套 + tests/ + docs/ + audit/;
生产码面(scripts/、sanguo_*/)零字面量——任何新增扩散直接被单测抓住。 生产码面(scripts/、sanguo_*/)零字面量——任何新增扩散直接被单测抓住。
4. **文件格式钉=纯 ASCII**(10-07 补,🔴 生产事故反向钉):PS5.1 `Get-Content` 默认按
ANSI/GBK 解无 BOM 文件,文件含 UTF-8 中文原始字节 → `ConvertFrom-Json`
FormatException → env 注入失败。10-06 21:00 xt_eod 实证全链:
`BIGQMT_ACCOUNT_ID` 未注入 → 桥 shim import 期硬错 `account_id is required`
→ universe ETF/基金=0 → rc=1(对照 10-05 同假期班 rows=37301 正常)。
修=文件中文一律 `\u` 转义(`ensure_ascii`),双端等值:Python `json.load`
与 PS5.1 `ConvertFrom-Json` 均原生解转义。**phase-③ 生产 wrapper 裸
`Get-Content` 读此文件的安全性由本钉担保**(改文件加中文必红)。
## 五、分阶段上线 ## 五、分阶段上线
| 阶段 | 时点 | 内容 | | 阶段 | 时点 | 内容 |
|------|------|------| |------|------|------|
| ① repo | 本班(10-05) | 上表全部 + 测试 + 两档更新;push 后 CI test 绿即达(nas-deploy 楔死=找 infra 手动 promote,既定协议) | | ① repo | 本班(10-05) | 上表全部 + 测试 + 两档更新;push 后 CI test 绿即达(nas-deploy 楔死=找 infra 手动 promote,既定协议) |
| ② VPS | **10-08 复市验证窗口后**班车 | promote 带上 json + 新脚本;10-08 07:50 relogin 首班跑旧码=纯净验证 | | ①′ ASCII 化修复 | **10-07(10-08 窗口前)** | json 改 `\u` 转义 + 第④钉;**紧急性=10-08 复市 21:00 xt-daily 必须能用**(10-06 起已断,30d 窗口拉取自愈无数据丢失);部署须在 10-08 21:00 前落地(理想=10-07 当天,当晚 21:00 班即真班验证) |
| ③ 生产 wrapper | ②后 | `run_shadow_bridge.ps1` 等库外资产改读 json(runbook 非代码资产流程报备 infra) | | ② VPS | **10-08 复市验证窗口后**班车 | promote 带上 json + 新脚本;10-08 07:50 relogin 首班跑旧码=纯净验证(注:①′ 若 10-07 发车则 ② 的 json 部分已随行,脚本部分仍候窗口后) |
| ③ 生产 wrapper | ②后 | `run_shadow_bridge.ps1` 等库外资产改读 json(runbook 非代码资产流程报备 infra);裸 `Get-Content` 安全性由第④钉担保,也可加 `-Encoding UTF8` 双保险 |
| ④ 可选增强 | 按需 | setx /M 机器级兜底;mini_path 接线;watch_accounts 多账号扩展 | | ④ 可选增强 | 按需 | setx /M 机器级兜底;mini_path 接线;watch_accounts 多账号扩展 |
## 六、回滚 ## 六、回滚
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"default_account": "66639661", "default_account": "66639661",
"kind": "simulated", "kind": "simulated",
"mini_path": "C:\\国金QMT交易端模拟\\userdata_mini" "mini_path": "C:\\\u56fd\u91d1QMT\u4ea4\u6613\u7aef\u6a21\u62df\\userdata_mini"
} }
+14
View File
@@ -60,6 +60,20 @@ def test_module_account_bound_to_identity():
assert gate.ACCOUNT == _ident()["default_account"] assert gate.ACCOUNT == _ident()["default_account"]
def test_identity_file_ascii_only():
"""④ 文件格式钉: 纯 ASCII(中文一律 \\u 转义)。
PS5.1 Get-Content 默认按 ANSI/GBK 解无 BOM 文件——文件含 UTF-8 中文
原始字节时 ConvertFrom-Json 直接 FormatException(2026-10-06 xt_eod
实证: BIGQMT_ACCOUNT_ID 注入失败→桥 shim import 期硬错 account_id
required→universe=0→rc=1)。纯 ASCII 双端等值: Python json.load 与
PS5.1 ConvertFrom-Json 都原生解 \\u 转义。phase-③ 生产 wrapper 读此
文件同样依赖本钉。
"""
raw = (_CFG / "qmt_identity.json").read_bytes()
raw.decode("ascii") # 非 ASCII 字节 = UnicodeDecodeError 直接红
# ---------------- ② 单源一致性 ---------------- # ---------------- ② 单源一致性 ----------------
def test_single_source_agreement(monkeypatch): def test_single_source_agreement(monkeypatch):