Skip to content

feat: research template workflows + fins/storage phase, with post-merge integrity fixes#168

Open
KUIGE22 wants to merge 4 commits into
noho:mainfrom
KUIGE22:fins/storage-phase-setup
Open

feat: research template workflows + fins/storage phase, with post-merge integrity fixes#168
KUIGE22 wants to merge 4 commits into
noho:mainfrom
KUIGE22:fins/storage-phase-setup

Conversation

@KUIGE22

@KUIGE22 KUIGE22 commented Jul 9, 2026

Copy link
Copy Markdown

概述

本分支在上游 main 基础上引入三部分内容(共 4 个 commit):

commit 内容
4d19f69 feat(fins):对 fins/storage 应用 phase 方法论
7579e0d feat:可复用的研究模板工作流(research-template)
e981cb2 fix:研究模板 bundle/plan/workbook 完整性加固(评审后修复)
f9fb224 docs:记录 Opus 4.8 评审与修复结论

评审后修复(本次新增)

7579e0d 做了一轮独立代码评审(Claude Opus 4.8),无 P0,但发现多处“校验信任内嵌/自报状态、而非从源头重算”的完整性缺口,已逐条修复并补回归测试:

  • validate-bundle 改为从引用的 rules/source-map 文件重算监控完整性,并要求任何 bound 数据源携带 binding_approval 授权凭据——手动把 unbound 翻成 bound 的篡改不再报“健康”。
  • validate-monitoring-plan 将任务 bound_data_sources 与指纹匹配的 source-map 交叉核对,拒绝伪造的 ready_for_review(例如声称不可绑定的外部占位源 market_data 已绑定)。
  • write --research-template auto 的 infer 引导改为按“公司级 facet 是否存在”判断,而非仅看 manifest.json 是否存在;company_facets: null 的历史 manifest 现在会重新推断,而不是 SystemExit(2) 硬失败。
  • 组合物化(portfolio materialize)与 write --materialize-research 现在把单目标的退化失败(RuntimeError/AssertionError)记为失败目标 / 返回退出码 2,而不是整批中断抛 traceback。
  • Workbook:ID 加入 section/item 位置索引(重复行不再碰撞);模板/报告按 utf-8-sig 读取(BOM 不再吞掉首个 section);live_summary 只统计良构条目;回滚改为对备份做鉴权,当前文件损坏时也能恢复,且不再把损坏字节存成无法回滚的“垃圾 redo 备份”。
  • refresh-workspace 把状态快照写到回滚边界内的路径,而非一个在非规范 bundle 深度下会偏离的重新推导路径。

验证

  • 全仓测试:5410 passed, 83 skipped, 0 failed(基线 7579e0d 为 5397,净增 13 条测试)。
  • 受影响源文件 Ruff / Pyright:0 error。
  • 真实 CLI 端到端跑通:materialize → validate-bundle → source-bindings 审批 → refresh-workspace → validate-bundle/validate-monitoring-plan,合法审批后仍健康、篡改被拒。

说明

评审与修复由 Claude Opus 4.8 辅助完成,相关 commit 带有 Co-Authored-By 标注。研究模板功能全程保持本地、只读、dry-run 语义,不启用外部 provider,也不放开自动化执行(scheduler job 恒为 enabled=false)。

KUIGE22 and others added 4 commits June 23, 2026 06:57
Replicate the conversation_memory phase setup pattern to fins/storage,
producing 3 methodology documents and 3 spec-test files plus one
production-code fix surfaced by the new tests.

Documents
- docs/fins_storage_design.md (~750 lines): 6 protocol × 30 invariants,
  4-phase batch journal state machine, cross-document accounting,
  config knobs and known test gaps.
- docs/fins_storage_test.md (~450 lines): 8 hands-on test groups with
  A-N=A-M consistency assertions matching test_doc pattern from
  conversation_memory phase.
- docs/fins_storage_code_review.md (~500 lines): deepreview prompt
  template with 12 categories, grep -rn executable checks, and
  back-references to existing + new test names.

Spec tests
- tests/fins/test_blob_handle_path_traversal.py: 19 tests covering
  6 path traversal attacks against read/store/delete + 1 reverse
  assertion that no attack degrades to FileNotFoundError.
- tests/fins/test_storage_spec_gaps.py: 9 tests filling P0/P1/P2 gaps
  from design_doc (processed clear idempotency, blob delete edge cases,
  maintenance cleanup count semantics, clear-filing isolation,
  missing handle behavior).
- tests/fins/test_storage_cross_process_recovery.py: cross-process
  crash + auto recovery — worker subprocess exits via os._exit(7)
  after writing staging, main process build_fs_repository_set triggers
  ensure_batch_recovery, asserting orphan cleanup + target isolation.

Finding 001 fix
- dayu/fins/storage/_fs_blob_core.py: store_file now validates
  filename via _normalize_entry_name, matching read/delete which
  go through _resolve_handle_child_path. Without this, 5/6 path
  traversal attacks bypassed normalization (`..` even caused
  PermissionError when .part tried to replace the filings dir).
  One-line semantic fix plus docstring Raises clause for ValueError.

Test results: 1899 passed, 2 skipped in 95s (no regressions).
…st-merge review

Independent Opus 4.8 review of the research-template workflows (7579e0d) found no
P0 but several integrity gaps where validation trusted embedded/self-reported
state instead of recomputing from source. Fixes, each with regression tests:

- validate-bundle recomputes monitoring integrity from the referenced
  rules/source-map files and requires binding_approval provenance on any bound
  source, so a hand-flipped unbound->bound source-map no longer reports healthy.
- validate-monitoring-plan cross-checks task bound_data_sources against the
  fingerprint-matched source-map, rejecting forged ready_for_review tasks that
  claim an unbindable placeholder is bound.
- write --research-template auto keys the infer bootstrap off company-facet
  presence, not manifest existence, so a null-facets manifest re-infers instead
  of failing SystemExit(2).
- Portfolio materialize and write --materialize-research record degenerate
  target failures (RuntimeError/AssertionError) as failed targets / exit 2
  instead of aborting with an uncaught traceback.
- Workbook: index section/item positions into IDs (no collisions on duplicate
  lines); read templates/reports as utf-8-sig (BOM no longer drops sections);
  count only well-formed items in live_summary; rollback authenticates against
  the backup so it recovers a corrupt current file, and does not save corrupt
  bytes as a junk redo backup.
- refresh-workspace writes status snapshots inside the rollback boundary rather
  than a re-derived path that can diverge for non-canonical bundle depths.

Full repository suite: 5410 passed, 83 skipped. Affected-source Ruff/Pyright clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tions

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@KUIGE22
KUIGE22 marked this pull request as ready for review July 9, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant