Repository navigation
Conversation
| except (TypeError, ValueError) as error: | ||
| raise _InvalidMemoryCommitError("vector") from error | ||
| if canonical != projection.embedding or expected_hash != projection.embedding_content_hash: | ||
| raise _InvalidMemoryCommitError("vector") |
There was a problem hiding this comment.
[P1] 不要用精确浮点相等判断单位向量已经规范化
MemoryService._embed_texts() 已先执行一次 canonical_embedding();这里再次归一化后再做 tuple 精确比较。单位归一化不是位级幂等的:公开 MemoryService.remember() 探针让模型返回 (0.2407121489724894, -0.9705965492093231),服务层得到 (0.24071214897248938, -0.9705965492093231),这里二次归一化又把首项改成 0.24071214897248935,于是合法的有限非零向量被抛为 _InvalidMemoryCommitError("vector"),整个 Memory 写入失败。现有向量测试只使用 (1, 0, 0) 这类轴向量,无法覆盖该舍入路径。请改为校验维度、有限性和带容差的单位范数(或确保只规范化一次并复用结果),并补一个非轴向量的公开 MemoryService.remember() 回归测试。
There was a problem hiding this comment.
感谢指正。我使用你给出的非轴向量复现并确认了这个问题:二次归一化后的精确浮点比较确实会误拒绝合法写入。现已修复为校验维度、有限性和带容差的单位范数,同时保留 profile/content hash 校验,并补充了公开 MemoryService.remember() 稠密向量回归测试及非单位向量拒绝测试。
There was a problem hiding this comment.
done. Please take a moment to review again to see if there are any other issues.
6a633d2 to
0fb92d1
Compare
34ca39f to
d258721
Compare
|
Closing this PR because #1857 replaced the code it was meant to fix. The original issue in #1297 was valid, but the old Memory service and backend have now been removed in favor of Atomic Memory. The current migration rejects broken version chains and content/hash mismatches, and Atomic Memory search checks results against authoritative records. These scenarios were verified on SQLite. The core changes in this PR are therefore no longer needed on master. Any remaining integrity issues should be addressed separately in the current Atomic Memory or migration implementation. |
Which issue or RFC does this PR close?
Closes #1297. Retains the Memory compaction contract in RFC #1718.
Rationale for this change
MemoryUnitOfWork.commit() is the final persistence trust boundary. A malformed SPI writer could persist illegal predecessor links or body/hash mismatches, and search could return text that authoritative entry reads rejected. The boundary must validate complete revisions while accepting supported service transitions, including audited inactive compaction.
What changes are included in this PR?
Are there any user-facing changes?
Malformed public Memory SPI commits fail with MemoryBackendConfigurationError rather than becoming durable state. Existing SQLite/OceanBase schemas receive the scope-global entry-version unique index during startup; legacy duplicates require repair before startup succeeds.
Valid service workflows, inactive compaction, historical readback and documented no-vector degradation remain supported. No HTTP API changes or automatic physical history deletion are added.
How was this change tested?
Validated head: 288b86b, based on master 77cf867.
Desktop Windows CI passed at this head, including native CLI diagnostics, fixture-qualified installer creation and installed WebView2 acceptance.
Real OceanBase integrity CI passed: 3 passed, zero skips, covering the two-writer identity race/rollback, hydrated dense-embedding reuse and inactive compaction.
Windows CPython 3.12 Memory service, persistence, integrity, backend profiles, capacity, concurrency, vector and usage-recorder regressions — 151 passed, 20 skipped. HTTP observability regressions — 18 passed. The Memory/runtime source and regression-test trees are unchanged by the Desktop fixture preparation.
Desktop qualification regressions — 5 passed.
Genuine Rust 1.95.0 MSVC native CLI probe against the isolated built wheel passed for fixed version, service-status and integrations commands. The original fixture reproduced the native service projection Timeout. The report records the byte-compiled fixture; native command deadlines, executable pinning, isolated user directories and system-only PATH remain enforced.
Local cold-fixture measurements: the first version call took 24.533 seconds; wheel bytecode preparation took 4.323 seconds and the prepared version call took 8.173 seconds. These measurements characterize the disposable fixture on this host, not installed-release startup performance.
Whole-project Linux-target types, changed-file Windows/Linux types, Ruff, formatting, all non-type pre-commit hooks, lock and diff checks passed. The type hook was checked separately with the platform targets above.
uv run --locked python -X utf8 -m pytest -q tests/builtin/artifacts/memory tests/builtin/persistence/test_memory.py tests/builtin/persistence/test_memory_integrity.py tests/builtin/persistence/test_sqlite_profile.py tests/builtin/persistence/test_oceanbase_profile.py tests/e2e/test_memory_search_concurrency.py tests/e2e/test_memory_vector_round_trip.py tests/e2e/test_memory_capacity.py tests/builtin/runtime/test_model_usage_recorder.py --tb=short
uv run --locked python -X utf8 -m pytest -q tests/e2e/test_observability.py --tb=short
uv run --no-sync python -X utf8 -m pytest -q tests/test_desktop_fixture_qualification.py --tb=short
cargo build --locked --manifest-path desktop/src-tauri/Cargo.toml --example diagnostic_cli_probe
uv build --wheel --out-dir desktop/.artifacts/server-wheel
uv run --no-sync python -X utf8 desktop/tests/real_cli.py
uv run --locked ty check --python-platform linux
OceanBase tests are opt-in locally because this host has no dedicated database URL. The dedicated disposable OceanBase CI job requires collision rollback, hydrated-vector reuse and inactive compaction to execute with zero skips. The Desktop native test validates CLI process and response handling; it does not qualify installed GUI behavior, accessibility or release startup budgets.
AI usage statement
OpenAI Codex assisted with implementation, review feedback analysis, regression design, validation and PR preparation. Open Code Review was used in delegation mode for deterministic file selection and rule resolution; Codex performed the review.