Skip to content

SW-02 spec_sha 分域哈希:spec 小编订不再使全量内容缓存失效 - #9

Merged
randypanding merged 2 commits into
mainfrom
sw/sw-02-spec-sha-domains
Aug 22, 2026
Merged

SW-02 spec_sha 分域哈希:spec 小编订不再使全量内容缓存失效#9
randypanding merged 2 commits into
mainfrom
sw/sw-02-spec-sha-domains

Conversation

@randypanding

Copy link
Copy Markdown
Owner

这个 PR 改的是哪一层?(必选其一)

  • A 资产层spec/ profiles/ brands/ cases/export/)→ 必须打标签 asset-change 并附 ADR
  • B 生成物层src/ tests/)→ 无需 ADR(未改 spec/ 内容,只加了指纹计算函数)
  • 文档 / CI

工单

Closes # · 工单号:SW-02(上游依赖卡,Lab 仓 docs/WORK_ORDERS.md §上游依赖卡)

问题

_make_ctx / eval/l1.py 此前把 全量 spec 指纹(spec//*.py + *.yaml 联合 sha256)放进每个 pass 的缓存键:任何一处 spec 小编订(如改一条 rubric、一个 budget)都会使全量**内容缓存失效,重跑整季 LLM 编译。

改动

  • provenance.spec_domain_fingerprints():按 spec 顶层子域(checks/ir/passes/rubrics/feedback/rules/brand/root)分别取 sha256[:12]
  • PassContext.spec_shas 新字段(默认空 dict = 旧语义原样回退,既有调用方/测试不受影响);cache_versions() 的 spec_sha 改用 scoped_spec_sha():只含 ir + passes(CACHE_SPEC_DOMAINS,影响生成结构的域)
  • 域职责不重叠:checks 域编辑仍经既有 ruleset_ver 使缓存失效;rubrics/feedback/rules 等与生成无关的域不再牵连
  • provenance 不弱化:runs 表的 spec_sha 仍记录全量指纹
  • 接线点:cli._make_ctxeval/l1.py 两处编译入口

验收命令(贴出你本地跑通的输出)

uv run pytest tests/test_spec_domains.py -q   # 4 passed
uv run ruff format --check . && uv run ruff check .   # All checks passed
uv run pyright   # 0 errors
uv run pytest -m "not llm" -n auto   # 525 passed, 1 failed

注:唯一失败 test_db_export_fresh 源于本机工作树一份未提交的 cases/cases.db 改动(禁止提交的运行现场);origin/main 干净 worktree 上该测试通过,本 PR 未触碰该文件。

检查表

  • 测试先红后绿(先见 ImportError: cannot import name 'spec_domain_fingerprints'
  • 没有在 Python 里写业务规则
  • 未新增 check 规则(不适用)
  • 没有手改 prompts/
  • 手写行数仍在预算内(净增 ~30 行)
  • 未改 IR
  • 未改 rubric

影响生成结果吗?

  • 否(只改缓存键组成与指纹计算;同输入同模型的生成路径不变。注意:缓存键变化本身会让旧缓存条目一次性失效,之后恢复增量命中)

- provenance.spec_domain_fingerprints:按 spec 顶层子域取 sha256[:12]
- PassContext.spec_shas 新字段(默认空 = 旧语义回退),cache_versions 的
  spec_sha 缩域为 ir+passes(CACHE_SPEC_DOMAINS);checks 由既有
  ruleset_ver 单独覆盖,rubrics/feedback/rules 等不进缓存键
- runs 表 provenance 仍是全量 spec_sha,不弱化
- 接线:cli._make_ctx + eval/l1.py 两处编译入口
- 测试:tests/test_spec_domains.py(4 例,先红后绿)
Copilot AI lite review requested due to automatic review settings August 21, 2026 20:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Address the missing rules cache dependency for p5_dialogue and safely fall back when required spec domains are incomplete.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds domain-scoped spec fingerprints to reduce unrelated cache invalidation while preserving full provenance hashes.

Changes:

  • Adds per-domain SHA-256 fingerprints.
  • Uses ir and passes domains for cache keys.
  • Wires fingerprints into CLI and evaluation paths with tests.
File summaries
File Summary
tests/test_spec_domains.py Tests domain hashing and cache behavior.
src/nsc/runtime/provenance.py Implements per-domain fingerprints.
src/nsc/passes/__init__.py Adds scoped cache-key support.
src/nsc/eval/l1.py Wires fingerprints into evaluation contexts.
src/nsc/cli.py Wires fingerprints into CLI contexts.
Review details

Suppressed comments (1)

src/nsc/cli.py:37

  • SW-02 的接线仍漏掉了 scripts/stress_generalize.py::_ctx_for:它也创建 PassContext 并运行带 @cached_pass 的完整 pipeline,但没有传 spec_shas,所以压测入口仍会因 rubrics/feedback/rules 等无关 spec 编辑而回退到全量缓存失效。请将该编译入口纳入同样的分域接线,或明确把它排除在本 PR 的缓存语义之外。
        spec_shas=spec_domain_fingerprints(),  # SW-02:缓存键分域;provenance 仍全量
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +50 to +51
#: 进缓存键的 spec 域(SW-02):只含影响生成结构的域;checks 由 ruleset_ver 覆盖。
CACHE_SPEC_DOMAINS = ("ir", "passes")

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(fae8bae):采纳"按 pass 声明域"方案——新增 PASS_EXTRA_SPEC_DOMAINS = {"p5_dialogue": ("rules",)}scoped_spec_sha(pass_name) 取基础域 ∪ 该 pass 的额外域。现在 spec/rules/L3_canonical 的编辑会使 p5 缓存失效、不牵连 p3 等不读该域的 pass。回归测试 test_rules_domain_only_invalidates_p5(规则编辑 → p5 键变、p3 键不变)。关于建议中的 p5 cache miss 回归测试:键级断言(cache_versions 的 spec_sha 组成变化)与 cache miss 是同义变形(cached_pass 用 cache_versions 组键),已由 test_cache.py 的失效语义测试 + 本测试共同覆盖。

Comment thread src/nsc/passes/__init__.py Outdated
Comment on lines +84 to +86
if not self.spec_shas:
return self.spec_sha
return "|".join(f"{d}:{self.spec_shas.get(d, '')}" for d in CACHE_SPEC_DOMAINS)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(fae8bae):scoped_spec_sha 在任一必需域(含该 pass 的额外域)缺失时回退全量 spec_sha——宁可多失效、不可少失效。回归测试 test_partial_domain_map_falls_back_to_full_sha(只给 {ir: ...} 时 p3/p5 都用 full123)。

Copilot review(PR #9):
- p5 self-check 经 revision_brief 读 spec/rules/L3_canonical(VOICE RULES),
  ruleset_ver 只覆盖 spec/checks → 规则编辑后 p5 命中旧缓存。新增
  PASS_EXTRA_SPEC_DOMAINS = {p5_dialogue: (rules,)},scoped_spec_sha 按 pass
  取并集(review 建议的按 pass 声明域)
- spec_shas 缺任一必需域时回退全量 spec_sha,不再拼 'ir:|passes:'
  式弱化失效条件的键
- 回归:test_rules_domain_only_invalidates_p5 /
  test_partial_domain_map_falls_back_to_full_sha
@randypanding
randypanding merged commit 6b809c7 into main Aug 22, 2026
10 checks passed
@randypanding
randypanding deleted the sw/sw-02-spec-sha-domains branch August 22, 2026 03:53
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.

2 participants