Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3d46047
Merge pull request #37 from dynamder/main
dynamder Sep 27, 2026
ffd6dbc
chore(deps): bump actions/cache from 4 to 6
dependabot[bot] Sep 27, 2026
75bfb85
chore(deps): bump actions/checkout from 4 to 7
dependabot[bot] Sep 27, 2026
cf22e71
chore(deps): bump actions/github-script from 7 to 9
dependabot[bot] Sep 27, 2026
b09974d
chore(deps): bump actions/upload-artifact from 4 to 7
dependabot[bot] Sep 27, 2026
3dd6498
chore(deps): bump text-splitter from 0.29.3 to 0.32.0
dependabot[bot] Sep 27, 2026
b83e362
chore(deps): bump flutter_rust_bridge from 2.12.0 to 2.13.0
dependabot[bot] Sep 27, 2026
a2592eb
Merge pull request #28 from dynamder/dependabot/github_actions/action…
dynamder Sep 27, 2026
482a522
Merge pull request #27 from dynamder/dependabot/github_actions/action…
dynamder Sep 27, 2026
e1fb605
Merge pull request #35 from dynamder/dependabot/cargo/text-splitter-0…
dynamder Sep 27, 2026
977087a
chore(deps): bump serde from 1.0.228 to 1.0.229
dependabot[bot] Sep 27, 2026
b119d2c
chore(deps): bump tokio from 1.52.3 to 1.53.1
dependabot[bot] Sep 27, 2026
16e7e2e
Merge pull request #29 from dynamder/dependabot/github_actions/action…
dynamder Sep 27, 2026
3a5c3b6
Merge pull request #30 from dynamder/dependabot/github_actions/action…
dynamder Sep 27, 2026
f5247fb
Merge pull request #33 from dynamder/dependabot/cargo/flutter_rust_br…
dynamder Sep 27, 2026
7a5b724
chore(deps): bump log from 0.4.30 to 0.4.34
dependabot[bot] Sep 27, 2026
ec2a5d4
docs(convention): 新增 docs/dev-convention.md 作为协作规范唯一权威
dynamder Sep 27, 2026
fdcdc26
ci(commits): 新增提交信息门禁并接入 Quality job
dynamder Sep 27, 2026
8759ae6
Merge pull request #31 from dynamder/dependabot/cargo/serde-1.0.229
dynamder Sep 27, 2026
1f3400d
Merge pull request #34 from dynamder/dependabot/cargo/tokio-1.53.1
dynamder Sep 27, 2026
912d7b1
ci(test): 纯文档改动跳过三平台测试
dynamder Sep 27, 2026
c473761
Merge pull request #32 from dynamder/dependabot/cargo/log-0.4.34
dynamder Sep 27, 2026
55321e3
Merge pull request #38 from dynamder/docs/dev-convention
dynamder Sep 27, 2026
eef53df
Merge pull request #39 from dynamder/ci/docs-only-fast-path
dynamder Sep 27, 2026
cf420bb
docs(convention): 补充纯文档改动跳过 Test 矩阵的说明
dynamder Sep 27, 2026
92a88b9
Merge pull request #42 from dynamder/docs/fast-path-note
dynamder Sep 27, 2026
5d99530
docs(convention): 补上首个可用版本之前的同步路径
dynamder Sep 27, 2026
37f2e18
Merge pull request #43 from dynamder/docs/pre-release-sync
dynamder Sep 27, 2026
8a67e6d
chore(deps): bump tokenizers from 0.21.4 to 0.22.2
dependabot[bot] Sep 27, 2026
302d2ba
chore(deps): bump futures from 0.3.32 to 0.3.34
dependabot[bot] Sep 27, 2026
2003244
feat(algo): 动作检索改为按 ActionType 每类贪心取一席
dynamder Sep 30, 2026
08924eb
chore(gitignore): ignore gh cache directory
dynamder Sep 30, 2026
b19ee46
chore(reasonix): drop tracked desktop topic state
dynamder Sep 30, 2026
2e69f40
feat(core): 新增 MemoryNote 的 render 对外契约
dynamder Sep 30, 2026
16c9119
feat(core): 增强render测试
dynamder Sep 30, 2026
cbaf736
Merge pull request #51 from dynamder/feature/memory-render
dynamder Oct 1, 2026
f350e86
chore(deps): bump uuid from 1.23.1 to 1.26.1
dependabot[bot] Oct 1, 2026
e683c93
ci(mutants): 让杀灭率门禁裁决 cargo-mutants 的退出码
dynamder Oct 1, 2026
a9a6c39
refactor(soul-tune): bin 复用 lib 的 mod 树,消除重复变异体
dynamder Oct 1, 2026
c305d78
test(algo): 补 ActionTypeSlots 贪心与 tiebreak 的顺序无关断言
dynamder Oct 1, 2026
1200368
test(soul-tune): 抽出动作分流与 PPR 配置构造成可测纯函数
dynamder Oct 1, 2026
d977f17
Merge pull request #49 from dynamder/dependabot/cargo/dev/futures-0.3.34
dynamder Oct 4, 2026
2897bef
Merge pull request #48 from dynamder/dependabot/cargo/dev/tokenizers-…
dynamder Oct 4, 2026
37d9cbe
Merge pull request #47 from dynamder/dependabot/cargo/dev/uuid-1.26.1
dynamder Oct 4, 2026
b3a5a12
chore(deps): bump paw-rs from 0.2.2 to 0.3.0
dependabot[bot] Oct 4, 2026
a1dc44b
chore(deps): bump chrono from 0.4.44 to 0.4.45
dependabot[bot] Oct 4, 2026
9c1b63d
chore(deps): bump tokenizers from 0.22.2 to 0.23.2
dependabot[bot] Oct 4, 2026
0c1449d
fix(storage): 出边同步改为差分删除,避免全量重建丢边
dynamder Oct 6, 2026
b9935ee
Merge pull request #56 from dynamder/fix/edge-sync-upsert
dynamder Oct 6, 2026
f6327b8
Merge pull request #50 from dynamder/feature/action-slots
dynamder Oct 6, 2026
9cda409
Merge pull request #54 from dynamder/dependabot/cargo/dev/tokenizers-…
dynamder Oct 6, 2026
7bcc7a6
Merge pull request #46 from dynamder/dependabot/cargo/dev/paw-rs-0.3.0
dynamder Oct 6, 2026
fbbe998
Merge pull request #52 from dynamder/dependabot/cargo/dev/chrono-0.4.45
dynamder Oct 6, 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
17 changes: 17 additions & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ exclude_re = [
# 对 f32/f64 与 F::zero() 同为 0.0。
# 现有断言 zero().into_inner() == 0.0 对两者都成立。
'UnitMeasure for OrdFloat<F>>::zero',
# best_per_action_type 的 tiebreak `*id < current.id` 改成 `<=` 是等价的:
# `*id` 与 `current.id` 都是 `scores: &HashMap<MemoryId, f64>` 的键,而 `current`
# 由同一次遍历里更早的一个键插入,二者必不相等(HashMap 的键唯一,且 `MemoryId`
# 的 Eq/Ord/Hash 全部派生自内部的 `Uuid`);`<` 与 `<=` 只在两侧相等时才有区别。
# 结论:没有测试能区分该变异体。
# 同一位点的其余算子(`>` → `==` / `>=`、`<` → `==`)**不排除**:它们只在
# 「遍历顺序」上与原实现不同,由 test_greedy_and_tiebreak_are_order_independent
# 反复重建 HashMap 来杀灭。
'replace < with <= in best_per_action_type',

# ---------------------------------------------------------------- 调优参数
# similarity_fetch 的 ef = k * 2:HNSW 搜索广度调优参数(ef 越大召回越准越慢),
Expand Down Expand Up @@ -112,4 +121,12 @@ exclude_re = [
# 把 `exclude_re` 设为 `["e"]`(匹配所有名字)仍会剩下恰好这些 24 行。
# 若那几个变异体确实杀不掉,应改用源码内的 `#[mutants::skip]` 标注,
# 并把 `exclude_re` 的覆盖缺口反馈上游。
#
# 本仓库当前唯一命中该缺口的**存活**变异体是 `crates/soul-tune/src/engine/retrieve/suite.rs`
# 里 `<impl TestSuite for RetrieveSuite>::run_case` 的
# `delete field association from struct AssociateWithActionConfig expression`:
# 它删掉 `association: Default::default()`,而 `..Default::default()` 恰好给出
# 同一个 `AssociationConfig::default()`(见 `AssociateWithActionConfig::default`),
# 属**等价变异体**,任何测试都无法区分。它被接受为一次固定 MISSED——
# 90% 门槛留有余量,不值得为此给 test harness 引入 `mutants` crate 依赖。
# ---------------------------------------------------------------------------
4 changes: 2 additions & 2 deletions .github/workflows/branch-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# 需要完整历史才能数提交数
fetch-depth: 0
Expand All @@ -43,7 +43,7 @@ jobs:
echo "main 落后 dev $behind 个提交(阈值 $DRIFT_THRESHOLD)"

- name: 超阈值开 issue,回到阈值内自动关闭
uses: actions/github-script@v7
uses: actions/github-script@v9
env:
BEHIND: ${{ steps.count.outputs.behind }}
THRESHOLD: ${{ env.DRIFT_THRESHOLD }}
Expand Down
57 changes: 52 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,41 +24,77 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# 文档分类要读区间内的改动文件,浅克隆拿不到区间历史(仓库约 37 MiB,代价可忽略)。
fetch-depth: 0

# 纯文档改动无法影响编译或测试,没必要付三平台全量测试的时间:先分类,再决定下面的
# 重步骤跑不跑。
#
# 为什么必须留在 **job 内、用步骤级 if**,而不能给 job 加 `if`,也不能给
# `on.pull_request` 加 `paths-ignore`:
# - workflow 级路径过滤会让必需检查根本不被创建,PR 永久停在 "Expected — Waiting";
# - **job 级 `if` 在 matrix 展开之前求值**:被跳过时只上报未插值的模板名
# `Test (${{ matrix.os }})`,而分支保护要的是 `Test (ubuntu-latest)` 等三个具体
# 名字——它们永远不会被创建,同样死锁。
# 步骤级跳过不影响 job 自身完成,三个名字照常上报。
#
# 输出只有三种可能:`false`(改动全是文档 → 跳过重步骤)、`true`(有代码改动 → 全跑)、
# 空(非 PR 事件,或本步骤被跳过 → 全跑)。条件写成 `!= 'false'` 是为了让最后一种
# 落到"全跑",fail-safe。
#
# 这里**不要**写成 `>> "$GITHUB_OUTPUT"`:Windows 上 Python 以文本模式写 stdout 会把
# `\n` 变成 `\r\n`,尾随的 CR 混进输出值后 `!= 'false'` 就不再成立,重步骤会在最贵的
# 那个平台上照跑(首版实测:ubuntu 5s / macos 8s 跳过,windows 编译并跑完测试)。
# 脚本自己以显式 LF 写输出文件,屏蔽掉这个平台差异。
- name: Classify changed paths
id: classify
if: github.event_name == 'pull_request'
run: python3 scripts/classify_changes.py "${{ github.event.pull_request.base.sha }}..${{ github.sha }}"

- uses: dtolnay/rust-toolchain@stable
if: steps.classify.outputs.code != 'false'
with:
components: rustfmt, clippy

- uses: Swatinem/rust-cache@v2
if: steps.classify.outputs.code != 'false'

# bge-small-zh 模型在测试时由 hf-hub 下载,缓存避免三平台重复下载。
- name: Cache embedding model
uses: actions/cache@v4
if: steps.classify.outputs.code != 'false'
uses: actions/cache@v6
with:
path: ~/.cache/huggingface
key: hf-${{ runner.os }}-bge-small-zh

- name: Build all targets
if: steps.classify.outputs.code != 'false'
run: cargo build --workspace --all-targets

- name: Run tests
if: steps.classify.outputs.code != 'false'
run: cargo test --workspace

quality:
name: Quality (fmt + clippy)
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# 提交信息门禁要沿 PR 范围回溯(base.sha..head),默认的浅克隆拿不到区间历史。
# 只有 quality 这一个 job 需要完整历史,其余 job 保持默认。
fetch-depth: 0

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- uses: Swatinem/rust-cache@v2

# 两个纯文本门禁放在最前面:不需要工具链、秒级返回,而且——关键——它们必须在
# 三个纯文本门禁放在最前面:不需要工具链、秒级返回,而且——关键——它们必须在
# `cargo fmt` 之前运行。此前它们排在 fmt 之后,于是 fmt 一红这两步就被 skip,
# 门禁等于没装(正是这条注释原本想表达的意思,但位置写错了)。
#
Expand All @@ -70,6 +106,17 @@ jobs:
- name: Check module layout
run: python3 scripts/check_layout.py

# 提交信息:Conventional Commits,只查本次 PR 新增提交的首行(docs/dev-convention.md §2)。
#
# 只在「目标分支是 dev」的 PR 上跑。dev → main 的 release PR 会把 dev 上成百个历史
# 提交一起带进范围,其中包含规范生效前的旧写法——那批历史按约定**不追溯、不重写**,
# 在 release PR 上重跑只会制造一批无解的假红。
- name: Check commit messages
if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'dev'
env:
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.sha }}
run: python3 scripts/check_commit_messages.py "$COMMIT_RANGE"

- name: Check formatting
run: cargo fmt --all --check

Expand All @@ -81,7 +128,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- uses: EmbarkStudios/cargo-deny-action@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deny-drift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
# 定时任务本身由 main 上的本文件触发,但检查的必须是 dev 的工作树与
# dev 的 deny.toml。
Expand All @@ -50,7 +50,7 @@ jobs:
arguments: --workspace

- name: 漂移开 issue,恢复后自动关闭
uses: actions/github-script@v7
uses: actions/github-script@v9
env:
OUTCOME: ${{ steps.deny.outcome }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
Expand Down
52 changes: 39 additions & 13 deletions .github/workflows/mutants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && needs.decide-weekly.outputs.run == 'true'
timeout-minutes: 360
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
fetch-depth: 0

Expand All @@ -55,15 +55,27 @@ jobs:
- name: Install cargo-mutants
run: cargo install cargo-mutants --version 27.1.0

# 归一化规则见下方注释与 scripts/mutants_gate.py 的 --cargo-mutants-exit-code:
# 这一步只如实带出 cargo-mutants 的退出码,是否合格全部由门禁裁决。
- name: Run cargo mutants (full)
run: cargo mutants --workspace
id: mutants
run: |
set +e
cargo mutants --workspace
code=$?
echo "exit_code=$code" >> "$GITHUB_OUTPUT"
if [ "$code" -ne 0 ]; then
echo "::warning::cargo mutants 退出码 $code(0=全部杀灭 2=有 MISSED 3=有 TIMEOUT;其余为工具故障)"
fi

- name: Check kill rate
run: python3 scripts/mutants_gate.py --out-dir mutants.out --threshold 90
run: >-
python3 scripts/mutants_gate.py --out-dir mutants.out --threshold 90
--cargo-mutants-exit-code "${{ steps.mutants.outputs.exit_code }}"

- name: Upload mutants report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: mutants-out-weekly
path: mutants.out
Expand All @@ -75,7 +87,7 @@ jobs:
if: github.event_name == 'pull_request'
timeout-minutes: 360
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
fetch-depth: 0

Expand All @@ -95,20 +107,34 @@ jobs:
run: |
git -c core.quotepath=false diff "${{ github.event.pull_request.base.sha }}...${{ github.sha }}" > "$RUNNER_TEMP/pr.diff"

# 退出码语义(cargo-mutants 27.1.0)里只有三个是「结果」:0=全部杀灭、2=有 MISSED、
# 3=有 TIMEOUT;其余(1 用法错误 / 4 基线失败 / 5 --in-diff 不匹配 / 6 diff 非法 /
# 70 内部错误)是工具故障。裸跑 `cargo mutants` 会让 exit 2 在门禁之前就把 job 判红,
# 于是 `--threshold 90` 永远无法生效——哪怕杀灭率 98% 也红;而 `continue-on-error: true`
# 又会连工具故障一起吞掉。所以这里只如实带出退出码,把裁决权完全交给门禁:
# 工具故障由门禁按「结果不可读」硬失败(exit 2),结果类退出码则按杀灭率判定。
- name: Run cargo mutants (PR diff)
run: cargo mutants --workspace --in-diff "$RUNNER_TEMP/pr.diff"
id: mutants
run: |
set +e
cargo mutants --workspace --in-diff "$RUNNER_TEMP/pr.diff"
code=$?
echo "exit_code=$code" >> "$GITHUB_OUTPUT"
if [ "$code" -ne 0 ]; then
echo "::warning::cargo mutants 退出码 $code(0=全部杀灭 2=有 MISSED 3=有 TIMEOUT;其余为工具故障)"
fi

# cargo-mutants 在「没有变异体可测」时(例如 PR 只往 .rs 里加文档注释)**不会创建**
# mutants.out/,而 mutants_gate.py 把「输出缺失」判为硬错误(exit 2)—— 那个判定要保留,
# 它用来抓 cargo-mutants 崩溃。所以这里只在确实有产物时才跑门禁;上一步失败时 job 已经
# 红了,不存在漏判。
# 不加 `if: hashFiles(...)` 守卫:`if` 里不含状态检查函数时会被隐式加上 `success()`,
# 而「没有变异体可测」(例如 PR 只往 .rs 里加文档注释)这一情形由脚本按
# 「退出码 0 且报告缺失/为空」自行判 PASS,见 mutants_gate.py。
- name: Check kill rate
if: hashFiles('mutants.out/**') != ''
run: python3 scripts/mutants_gate.py --out-dir mutants.out --threshold 90
run: >-
python3 scripts/mutants_gate.py --out-dir mutants.out --threshold 90
--cargo-mutants-exit-code "${{ steps.mutants.outputs.exit_code }}"

- name: Upload mutants report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: mutants-out-pr
path: mutants.out
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
.LSOverride
.opencode

/.gh-cache
/mutants.out/
/mutants.out.old/
graph_stats.json
Expand Down
3 changes: 0 additions & 3 deletions .reasonix/desktop-topic-created-at.json

This file was deleted.

4 changes: 0 additions & 4 deletions .reasonix/desktop-topic-title-sources.json

This file was deleted.

4 changes: 0 additions & 4 deletions .reasonix/desktop-topic-titles.json

This file was deleted.

8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ SoulMem 是**角色扮演用的记忆系统**,本质是一个"向量检索 +
| `docs/` | 架构与规范文档(见 §6) |
| `scripts/check_encoding.py` | 编码门禁(CI 中执行) |
| `scripts/check_layout.py` | 模块布局门禁(CI 中执行) |
| `scripts/check_commit_messages.py` | 提交信息门禁(Conventional Commits,CI 中执行) |
| `scripts/classify_changes.py` | 纯文档改动分类器(CI 据此跳过 `Test` 矩阵;不是门禁) |

依赖方向:`core → query/runtime/llm → algo → soul-tune → soul-tune-api`。
`runtime → algo` 仅存在于 **dev-dependencies**,生产依赖图中没有反向边。
Expand Down Expand Up @@ -78,6 +80,7 @@ cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
python3 scripts/check_encoding.py # 编码门禁
python3 scripts/check_layout.py # 模块布局门禁
python3 scripts/check_commit_messages.py # 提交信息门禁(Conventional Commits)
cargo mutants --workspace # 杀灭率 ≥90%,门禁见 scripts/mutants_gate.py
```

Expand Down Expand Up @@ -106,6 +109,10 @@ cargo mutants --workspace # 杀灭率 ≥90%,门禁见 scripts
> **不要批量改写、重排或"优化"书正文**——那不是可以自动化的区域。需要文档改动时改 `docs/` 或 crate 内注释。
> 书源码保留在 `doc/book` 分支,当前分支**不含**书源码(磁盘上的 `book/book/` 只是 HTML 构建产物)。

**分支模型、提交信息、推进与发布流程、文档规范以
[`docs/dev-convention.md`](docs/dev-convention.md) 为唯一权威**([`CONTRIBUTING.md`](CONTRIBUTING.md)
为简版入口)。改文档前另见该文件 §6。

**取用文档时的三条规则**:

- **测试数据集**以 [`docs/测试数据规范.md`](docs/测试数据规范.md) 为准。
Expand All @@ -127,6 +134,7 @@ cargo mutants --workspace # 杀灭率 ≥90%,门禁见 scripts
- **`.cargo/mutants.toml` 的每个排除项都要写原因**。另注意两个坑:`exclude_re` **不作用于结构体字面量字段变异体**(cargo-mutants 27.1.0 实测);"行为可观测但没有测试覆盖"应当补测试,而不是加排除项。
- **编码由 `.editorconfig` 约束为 UTF-8**:中文注释被 GBK 保存会变成乱码且部分字节永久丢失(不可逆)。提交前跑 `python3 scripts/check_encoding.py`。
- **行尾不一致是已知现状**:`core.autocrlf=true` 而索引里部分 blob 本身含 CRLF,工作区因此 CRLF/LF 混杂。`.gitattributes` 目前只统一 `*.md`。**要统一 `.rs` 请单独提一个只改行尾的提交**,不要混在功能改动里。
- **提交信息**用 Conventional Commits:`<type>(<scope>): <description>`。type 取白名单,描述用祈使/陈述式、不加句号;正文用子弹列表列摘要(3~5 条),不写长段落。完整规则与参考见 [`docs/dev-convention.md`](docs/dev-convention.md) §2。

---

Expand Down
14 changes: 8 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

感谢你愿意为 SoulMem 贡献代码、文档或想法!

**协作规范以 [`docs/dev-convention.md`](docs/dev-convention.md) 为唯一权威**(分支模型、提交信息、
推进流程、发布节奏、文档规范);冲突以它为准。以下各节为摘要。

## 分支模型

本仓库有两条长期分支。下面的规则是硬性的,它们来自一次真实的教训——`main` 曾经在无人察觉的
Expand Down Expand Up @@ -53,14 +56,10 @@ git worktree add ../SoulMem-book doc/book

## CI 说明

- push 到 `main` / `dev`,以及所有 Pull Request,会在 Windows、Ubuntu、macOS 三平台执行编译与测试。
- push 到 `main` / `dev`,以及所有 Pull Request,会在 Windows、Ubuntu、macOS 三平台执行编译与测试;**纯文档改动**(全部改动落在 `docs/**` 或 `*.md`)跳过测试矩阵,只跑 `Quality` 与 `Security`。
- PR 还会按本次改动范围运行 cargo-mutants,杀灭率低于 90% 会直接失败。
- 每周(每隔一周)自动执行一次全量 mutants,并上传报告 artifact。
- 依赖安全由 Dependabot(自动更新 PR)和 cargo-deny(安全公告 + 许可证)把关。
- `Deny drift` workflow 每周在 `dev` 上单独跑一次同一份 cargo-deny。上游 advisory 库
漂移(新增公告、crate 被 yank)时它会开 issue 并让 run 变红。**这类失败与具体 PR 无关**:
advisory 检查是全局的,基于 `dev` 的所有 PR 会一起红在同一个 `Security (cargo-deny)` 上,
所以先看 issue 正文的处理步骤,不要靠往 `deny.toml` 的 `ignore` 里塞条目让它变绿。

## 测试要求

Expand All @@ -72,5 +71,8 @@ git worktree add ../SoulMem-book doc/book

## 提交规范

- 提交信息建议遵循 `type(scope): 描述` 的格式,例如 `fix(retrieve): 修复PPR传播截断`。
- 提交信息**必须**遵循 Conventional Commits:`<type>(<scope>): <描述>`,其中 `type` 只能取
`feat` `fix` `refactor` `perf` `docs` `test` `chore` `ci` `build` `style` `revert`。
例:`fix(retrieve): 修复PPR传播截断`。CI 会检查本次 PR 新增提交的**首行**——完整规则见
[`docs/dev-convention.md`](docs/dev-convention.md) §2。
- 保持小步提交,一个提交只做一件事。
Loading
Loading