Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
fa5b948
docs: design v0.3 adapter assistant
elexingyu Jul 20, 2026
54dec04
docs: plan v0.3 adapter assistant
elexingyu Jul 20, 2026
5d6e71c
fix: preserve decimal JSON position values
elexingyu Jul 20, 2026
f3dece7
feat: add position profile drafts
elexingyu Jul 20, 2026
a5d0bec
docs: distinguish source sampling from truncation
elexingyu Jul 20, 2026
b3daa0a
feat: inspect bounded position source structures
elexingyu Jul 20, 2026
d76ef6b
docs: remove adapter hash circularity
elexingyu Jul 20, 2026
685a30b
feat: add safe adapter pack catalog
elexingyu Jul 20, 2026
6b2fd04
feat: detect position adapters deterministically
elexingyu Jul 20, 2026
11fd21e
feat: add FDC3 and CCXT position adapters
elexingyu Jul 20, 2026
157171f
feat: add safe mapping assistant contract
elexingyu Jul 20, 2026
4ab890a
feat: add optional OpenAI mapping provider
elexingyu Jul 20, 2026
76bd208
feat: add adapter-first position CLI
elexingyu Jul 20, 2026
941ffca
docs: publish v0.3 adapter onboarding
elexingyu Jul 20, 2026
a7132ce
fix: harden adapter onboarding boundaries
elexingyu Jul 20, 2026
31a45b7
docs: sync v0.3 hardening notes
elexingyu Jul 20, 2026
c906a11
fix: load optional OpenAI SDK at runtime
elexingyu Jul 20, 2026
61695f2
docs: design v0.4 factor exposure monitoring
elexingyu Jul 20, 2026
9407514
docs: plan v0.4 factor exposure monitoring
elexingyu Jul 20, 2026
6069d46
feat: define factor model contracts
elexingyu Jul 20, 2026
0e9bc08
feat: preview canonical factor loading files
elexingyu Jul 20, 2026
25afbf5
fix: harden factor source boundaries
elexingyu Jul 20, 2026
5d6e96b
feat: store versioned factor model snapshots
elexingyu Jul 20, 2026
841e3c2
fix: harden factor model persistence
elexingyu Jul 20, 2026
d9b5463
fix: stream factor model loadings
elexingyu Jul 20, 2026
265a55e
fix: isolate factor loading cursors
elexingyu Jul 20, 2026
94a5281
docs: align factor plan with streaming storage
elexingyu Jul 20, 2026
ae1c7ea
feat: add factor model preview and import commands
elexingyu Jul 20, 2026
2a2a022
fix: harden factor CLI input handling
elexingyu Jul 20, 2026
60b2bd1
fix: preserve safe CLI usage semantics
elexingyu Jul 20, 2026
2d655ce
feat: calculate point-in-time factor exposure
elexingyu Jul 20, 2026
cc9706f
fix: make factor aggregation order invariant
elexingyu Jul 20, 2026
c8aa620
fix: separate factor decisions from display rounding
elexingyu Jul 20, 2026
46ae5ac
fix: keep zero-basis factor coverage partial
elexingyu Jul 20, 2026
c3f64c4
feat: add versioned factor risk policies
elexingyu Jul 20, 2026
3bf5f75
fix: harden factor policy boundaries
elexingyu Jul 20, 2026
375767e
fix: require non-null factor policy schema
elexingyu Jul 20, 2026
1015785
docs: preserve exact factor coverage for policies
elexingyu Jul 20, 2026
b4b9755
feat: evaluate deterministic factor risk health
elexingyu Jul 20, 2026
d0cdaf4
fix: fail closed on invalid factor health inputs
elexingyu Jul 20, 2026
795c318
feat: orchestrate portfolio factor monitoring
elexingyu Jul 20, 2026
ea4eac2
fix: harden factor service trust boundaries
elexingyu Jul 20, 2026
247fad1
feat: expose portfolio factor monitoring api
elexingyu Jul 20, 2026
a013277
fix: validate factor catalog responses
elexingyu Jul 20, 2026
7d2f8b1
fix: preserve safe factor source labels
elexingyu Jul 20, 2026
15d7607
feat: show factor exposure and risk health
elexingyu Jul 20, 2026
2ae7330
fix: clarify factor evidence semantics
elexingyu Jul 20, 2026
dcd4b82
fix: harden factor reason lookup
elexingyu Jul 20, 2026
73315fe
feat: report deterministic portfolio factor risk
elexingyu Jul 20, 2026
d1c89f9
fix: harden factor report output
elexingyu Jul 20, 2026
8cdda8e
feat: add factor monitoring demo and benchmark
elexingyu Jul 20, 2026
0360ab9
fix: harden factor demo and benchmark lifecycles
elexingyu Jul 20, 2026
111c224
fix: publish benchmark database atomically
elexingyu Jul 20, 2026
f5744d5
docs: release factor exposure monitoring v0.4
elexingyu Jul 20, 2026
eb80f97
fix: resolve v0.4 release review findings
elexingyu Jul 20, 2026
c400e2e
fix: enforce atomic revision and factor integrity semantics
elexingyu Jul 20, 2026
6b519c6
fix: harden point-in-time ingestion boundaries
elexingyu Jul 20, 2026
ad22860
fix: preserve resolved quarantine on reopen
elexingyu Jul 20, 2026
0ee9a12
fix: enforce version-stable JSON depth limits
elexingyu Jul 30, 2026
d9fd4be
feat: add risk intelligence workbench
elexingyu Jul 30, 2026
005a108
docs: refresh v0.4 workbench release notes
elexingyu Jul 30, 2026
c4a0fd5
docs: sync release documentation
elexingyu Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
# QUANTCOCKPIT_DB_PATH=./quantcockpit.duckdb
# QUANTCOCKPIT_DEMO_AS_OF=2026-07-20T18:00:00Z

# v0.2 has no AI provider integration and requires no model API key.
# v0.4 核心监控与因子分析不需要模型密钥,也不会把因子文件发送给 provider。
# 可选 OpenAI 仓位映射助手需先安装 ai-openai extra;仅在调用时从本地 shell
# 环境读取 OPENAI_API_KEY,不要把任何真实密钥写入此文件或提交到 Git。
92 changes: 92 additions & 0 deletions .superpowers/sdd/task-12-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Task 12 报告:合成演示与规模基准

## 结论

Task 12 已按正式导入、服务与公开 API 载荷路径完成。固定演示库能够稳定呈现 healthy、critical 和 partial/unavailable 三类因子风险结果;100,000 资产、20 因子、10,000 持仓的完整基准已真实运行并通过正确性断言。

## 测试先行证据

- 演示契约测试先写后跑,初次 RED 为 3 个失败,原因是旧版 `import_demo.py` 不认识因子目录参数;实现后相关测试通过。
- 基准测试先写后跑,初次 RED 为 9 个失败,原因是基准脚本尚不存在;实现后 9 个测试通过。
- 演示与基准定向回归:`17 passed`。
- 浏览器验收后重新执行最终回归:后端 `547 passed`;前端 `37 passed`;Python 类型检查、前端类型检查与构建、`git diff --check` 均通过。

## 固定演示结果

- `healthy-book`:快照 `2026-07-20T17:30:00Z` 只能看到旧模型 `as_of=2026-07-19T16:00:00Z`。AAPL 权重 `0.6`、MSFT 权重 `-0.4`,beta 载荷 `1.0/0.8`,暴露为 `0.6×1.0 + (-0.4)×0.8 = 0.28`,状态 `ready/healthy`。
- `critical-book`:快照 `2026-07-20T17:45:00Z` 可看到 `available_at=2026-07-20T17:40:00Z` 的当前模型。beta 暴露为 `0.25×1.0 + 0.2×0.8 = 0.41`,真实越过 critical 上限 `0.4`,状态 `ready/critical`。
- `partial-book`:AAPL 权重 `0.8`、`PARTIAL_MISSING` 权重 `0.2`;后者缺少 value loading,value 暴露 `0.8×0.2 = 0.16`,经济覆盖率 `0.8`、数量覆盖率 `0.5`,低于策略要求 `0.95`。分析状态 `partial`,规则状态 `unavailable`,原因 `insufficient_factor_coverage`,组合健康状态 `unavailable`。
- 两期模型属于同一 `model_id/model_version` family;选择同时受 `as_of <= snapshot_time`、`available_at <= snapshot_time` 和固定 `recorded_at <= evaluated_at` 约束。
- `DEMO_RECORDED_AT` 固定为 `2026-07-20T17:46:00Z`。连续导入两次后模型与策略返回 duplicate,组合因子结果逐字一致。

## 小规模基准

参数:100 资产、3 因子、20 持仓、2 组合,固定 seed `20260720`。

- 因子载荷:300 行
- 导入:`0.104409s`
- 分析:`0.029705s`
- 数据库:`5,255,168 bytes`
- API 载荷:`10,983 bytes`
- 存储读取操作:8
- 结果:`ready`,3 个因子,最小经济覆盖率 `1`
- 稳定摘要:`sha256:66795659189fd7f58c98ac97ccaebe2ab960ce02ad79d06faad6a8778aac2139`

当前脚本的阶段 `generate/import/analyze/publishing` 同时实时写入 stderr 和旁路日志;`publishing` 刷新并关闭成功后才发布数据库。

## 完整规模基准

参数:100,000 资产、20 因子、10,000 持仓、1 组合,固定 seed `20260720`。

- 因子载荷:2,000,000 行
- 导入:`506.250703s`
- 分析:`3.183548s`
- 实际 wall time:`509.77s`
- 最大常驻内存:`1,066,401,792 bytes`,约 `1.07 GB`
- DuckDB:`175,124,480 bytes`,关闭连接后测量
- API 载荷:`28,990 bytes`
- 存储读取操作:5
- 结果:`ready`,20 个因子,最小经济覆盖率 `1`
- 稳定摘要:`sha256:5ec08ed3a4944683e728658f9bd3973826360451aeddec8c0780d508bbb330bb`

这里最明显的成本在 CSV 解析与正式导入,而不是单组合分析。完整运行没有跳过产品路径,也没有用直接 SQL 注入测试数据。

## 多组合查询增长

同一组 100 资产、3 因子、20 持仓的小基准中:

- 1 组合:5 次存储读取操作
- 2 组合:8 次存储读取操作
- 3 组合:11 次存储读取操作

当前增长关系是 `3N + 2`,属于清晰的逐组合线性读取。它在 1 至 3 组合和本次单组合完整基准中不是主要耗时,但已构成可观测的 N+1 形态。Task 13 应在性能文档中明确记录;只有更大组合数的实测表明它成为瓶颈时,再批量化策略、模型元数据和 loading 读取。

## 浏览器验收

固定演示库通过 `QUANTCOCKPIT_DEMO_AS_OF=2026-07-20T18:00:00Z` 启动真实 API 与前端,并由浏览器读取真实接口:

- 1440px:三组组合均展示,健康徽章为 `CRITICAL/HEALTHY/UNAVAILABLE`;模型时点、覆盖率、阈值、贡献项和证据引用可见;无横向溢出。
- 900px:主界面和因子卡片正常显示,无横向溢出;critical beta `0.41` 及其阈值、贡献项可见。
- 899px:正确隐藏主界面并显示“支持 900px 及以上宽度”的边界提示。
- 控制台无错误;健康、仓位、敞口和因子风险请求均返回 200。
- 截图:`/tmp/quantcockpit-task12-factor-1440.png`、`/tmp/quantcockpit-task12-factor-900.png`、`/tmp/quantcockpit-task12-unsupported-899.png`。

## 边界与后续

- 基准是固定 seed 的单机产品路径测量,不代表不同硬件、文件系统或并发场景下的生产 SLA。
- `factor_query_count` 统计可审计的 store 读取操作,不等同于 DuckDB 内部执行的全部 SQL 语句。
- 本任务不修改 README 性能表;这些数字和 N+1 观察留给 Task 13 汇总。

## 正式审查修复

提交 `8cdda8e` 的正式审查发现了导入失败生命周期与基准日志创建的边界缺口。修复过程先得到有效 RED:`20 failed, 18 passed`;实现与补充软链、悬空链、开发异常测试后,定向结果为 `50 passed`。

- `import_demo.py` 对事件、仓位、因子和策略四类目录/fixture 使用固定 `stage/fixture/code`,不再回显用户路径;manifest 与 policy 预解析具有独立正确阶段。
- store 生命周期显式从 `None` 开始。预期主异常和 close 异常同时发生时保留主异常;单独 close 失败固定非零;`duckdb.ProgrammingError` 和其他开发异常在尽力关闭后原样抛出。
- 幂等测试现在在第一次导入后冻结公开 service payload、事件 ID、模型快照 ID、loading 身份和策略身份,第二次导入后逐项比较;stdout 的 duplicate 只作为辅助证据。
- 基准日志改为独占创建。显式与默认日志若已是常规文件、软链、悬空链或目录均拒绝且不修改原目标;数据库/日志规范化路径冲突和缺失父目录在写入前拒绝。
- progress 的 emit、write、flush、close 失败均返回固定安全码,不二次调用损坏的进度写入器;close 失败不会输出成功 metrics。主异常优先,ProgrammingError 在 store/progress 尽力关闭后仍保持可见。
- 数据库不再直接写入用户请求路径。脚本在目标父目录内创建私有临时工作目录,DuckDB 只写唯一 working path;store 关闭、`publishing` 日志刷新并关闭后,才用 `os.link(..., follow_symlinks=False)` 独占发布。竞争者抢占为常规 DB、软链或悬空链时,发布固定失败且不修改目标;文件系统不支持硬链接时不回退到 copy/replace。发布成功后的工作目录清理为 best-effort,不再制造假失败。
- 数据库发布修复先得到 `5 failed, 24 passed` 的有效 RED;实现后因子基准测试为 `30 passed`,Task 12 定向合计为 `55 passed`。
- 按要求只重跑 100 资产小基准,没有重复执行 10 万资产基准。小基准结果保持 `ready`、查询 8 次、稳定摘要不变。
- 最终回归:后端 `585 passed`,前端 `37 passed`,Python/TypeScript 类型检查、前端生产构建及 `git diff --check` 全部通过。
75 changes: 75 additions & 0 deletions .superpowers/sdd/task-13-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Task 13 报告:v0.4 发布文档、版本与最终门槛

## 结论

QuantCockpit 已从实现完成但文档仍停留在 v0.3 的状态,收口为一致的 v0.4.0 发布候选。README 现在提供固定演示与因子模型/策略两条可执行路径;独立因子指南覆盖输入契约、时点、normalization、覆盖率、风险策略、错误码和安全边界;架构、安全、贡献与变更日志均与实际代码一致。

## 文档与发布变更

- 新增 `docs/factors.md`,包含完整有效的 Factor Model Manifest 1.0、wide CSV、long JSONL 和 Portfolio Factor Policy 1.0 示例。
- README 新增 `factors preview/import`、`factor-policies validate/import`、三个只读 API、页面/报告入口和因子规模基线。
- 明确 `provided_weight` 直接使用输入 weight;`gross_exposure_value` / `gross_market_value` 使用对应绝对 gross 分母。所有结果都是用户给定载荷的线性聚合,不宣传收益回归、统计 beta 或交易建议。
- 架构增加因子 source → model/policy store → point-in-time 解析 → 纯 Decimal 分析器 → 独立风险健康度 → service/API/UI/report 的完整数据流,并记录局部失败和证据链。
- SECURITY 增加机构专有模型/载荷/policy、本地不发送 provider、路径/错误脱敏,以及 `loading_hash` 与数据库管理员威胁边界。
- CONTRIBUTING 增加全合成 fixture、可手算 exposure/coverage/闭区间、同模型家族时点测试和 benchmark 先小后大要求。
- CHANGELOG 只在顶部新增 0.4.0,旧版本内容和顺序未改动。
- Python project、runtime、前端、uv lock 与生成 OpenAPI 版本全部同步为 0.4.0;wheel 资源测试同步新版本文件名。
- Makefile 新增 `factor-benchmark-smoke` 与 `factor-benchmark`。每次运行创建新的临时数据库和旁路日志;完整 100k 目标不进入 `verify`。
- 安全扫描发现既有测试 fixture 使用了看似真实的 `sk-` 前缀,已改成等价的合成 token,保留脱敏覆盖并消除发布扫描误报。

## 示例与命令验证

- `docs/factors.md` 的两个 JSON block 分别通过 `FactorModelManifest` 和 `PortfolioFactorPolicy` 实际解析。
- 三行 JSONL 全部通过 `FactorLoadingRecord`;wide CSV 经 `preview_factor_model` 得到 3 个证券,`market_beta` 覆盖 3 个、`value` 覆盖 2 个。
- `factors` 与 `factor-policies` 的六个 help 路径全部成功。
- 仓库 fixture 的因子 preview、模型 import、policy validate/import 全部成功;写入使用新临时数据库。
- 全部渲染 Markdown 排除 fenced code 后检查了 29 个本地链接,目标均存在。旧 v0.1 计划中的 README 图片语句位于代码块,路径以 README 为基准正确,不是文档坏链接。
- 版本检查确认 `pyproject.toml`、`quantcockpit.__version__`、`frontend/package.json`、`uv.lock` 和 OpenAPI 均为 0.4.0。

## 基准证据

加入完整快照 `content_hash` 流式重算后,`make factor-benchmark-smoke` 再次实际通过:100 标的、3 因子、300 条载荷、每组合 20 仓位、2 组合;导入 0.10382 秒,分析 0.03025 秒,最小经济覆盖率 `1`,9 次高层 store 读取操作,稳定摘要仍为 `sha256:66795659189fd7f58c98ac97ccaebe2ab960ce02ad79d06faad6a8778aac2139`。修复前同规格单次分析为 0.02807 秒,绝对增加约 0.00218 秒;小样本单次百分比不用于外推。

Task 12 的 100,000 标的 × 20 因子历史测量发生在完整摘要扫描加入之前,已从 README 当前基线中撤下。旧的 3.18355 秒分析和 5 次读取不能代表当前正式路径;若需对外发布完整规模性能,必须重新运行 `make factor-benchmark`。

当前小测的 1 / 2 / 3 个组合分别是 6 / 9 / 12 次高层 store 读取操作,不宣称是 SQL 数量。摘要成功与失败状态均在单个 service 请求内缓存;共享一个模型的多个组合只触发一次完整载荷扫描。

## 浏览器与截图

固定演示数据库通过 `QUANTCOCKPIT_DEMO_AS_OF=2026-07-20T18:00:00Z` 启动真实 API 与前端:

- `/api/v1/factor-models`、`/api/v1/factor-policies` 和 critical-book 因子详情均返回 200。
- 1440 × 900 与 900 × 900 的 document/body scroll width 均等于 viewport width,无横向溢出。
- 页面同时显示 DEMO 水印与因子风险区块;浏览器控制台无错误。
- 更新 `docs/assets/quantcockpit-demo.png` 为 1440px 宽的当前整页截图,包含 healthy、critical、unavailable 三类合成因子状态,不含本机路径。

## 首次门槛失败与修复

首次 `make verify` 为 584 passed / 1 failed。唯一失败是 `tests/test_adapter_catalog.py` 仍查找 `quantcockpit-0.3.0-*.whl`,而实际 wheel 已正确生成 0.4.0。同步断言后定向测试通过,完整门槛恢复为:

- 后端:585 passed
- 前端:37 passed
- Python / TypeScript 类型检查:通过
- 前端生产构建:通过
- OpenAPI 生成:只产生预期的 0.4.0 info version 变化,生成 TypeScript 无漂移

## 发布审查修复

发布提交后的独立审查发现 4 个重要问题和 1 个轻微文档问题,已在独立修复提交中统一处理:

- README 的普通仓位 exposure curl 曾混用不存在的 `synthetic-book` 与 `healthy-demo` 身份,现改为演示库中真实存在的 `healthy-book` / `factor-demo`,并新增导入演示库后实际调用该文档 URL 的回归。
- 因子指南不再把同方法新一期数据描述为“只更新 `as_of`”:新一期必须写入新的 `as_of` 与该期真实 `available_at`,上游变化时同步更新 `source`;只有方法、定义或口径变化才提升 `model_version`。
- `FactorLimitRule` 现在按真正的区间包含校验 warning 与 critical:warning 某侧无界时 critical 同侧也必须无界,有限 critical 边界必须包住 warning。四类收窄反例、单侧/双侧正例、健康度不跳级和 CLI/文档示例均有回归。
- CLI manifest、CLI policy 与 `import_demo` 的 manifest/policy 改为复用一个公共有界 JSON reader:上限 1 MiB,仅普通文件,`O_NOFOLLOW`、`O_NONBLOCK`、单文件描述符、前后 `fstat` 快照、精确读长和重复键拒绝。超限、symlink、dangling symlink、目录、FIFO 与读取中变更均固定失败,不回显路径或载荷;正常演示导入保持通过。
- `.env.example` 已同步 v0.4:核心监控与因子路径不需要模型密钥;可选 OpenAI 映射助手只从本地 shell 读取密钥,示例文件不包含密钥值。
- 最终一致性 hardening 增加 rollback-only 嵌套事务;profile/draft 与事件 JSONL 统一使用有界、单 fd、无链接和竞态检测入口。事件 JSONL 明确 100 MiB 文件与含换行的 1 MiB 记录上限,资源、重复键、nonfinite、深层或竞态错误整批回滚。
- 事件、策略身份、收益和健康度以 `first_observed_at` 作为知识时间;仓位另要求业务 `recorded_at` 已到,普通与因子敞口因此选择同一 PIT 修订。隔离 active/resolved/reactivated 使用不可变 transition 回放,当前错误 API 仍读取 denormalized current 状态。
- `FactorModelManifest.source` 在领域 schema 内执行与公开 catalog 相同的 NFKC、控制符和路径分隔符规则,危险来源在导入前以固定 manifest invalid 拒绝,不再出现导入成功后 catalog 503。

依赖审计另发现 OpenAPI 生成链间接要求受 GHSA-52cp-r559-cp3m 影响的 `js-yaml 4.2.0`。Bun override 现固定到修复版 4.3.0,lockfile 已同步,SECURITY 记录覆盖原因和移除门槛。`bun why js-yaml` 确认实际解析 4.3.0,`bun audit` 无漏洞;Python `pip-audit` 无已知漏洞。

修复后的最终门槛为:后端 675 passed、前端 37 passed、Python/TypeScript 类型检查与生产构建通过;frozen install、OpenAPI 重新生成无漂移、无 OpenAI extra、敏感信息模式扫描、28 个本地文档链接和因子 benchmark smoke 全部通过。benchmark 稳定摘要仍为 `sha256:66795659189fd7f58c98ac97ccaebe2ab960ce02ad79d06faad6a8778aac2139`。

## 边界

v0.4.0 不包含因子协方差、特质风险、VaR、压力测试、收益回归、组合优化、交易、自动告警或 AI 风险报告。因子风险状态与策略运行健康度保持独立;因子文件默认全本地,不进入可选 AI mapping draft 路径。
Loading