Skip to content

fix(memory): confirm CLI archive writes and preserve consolidation cooldown - #997

Merged
mergify[bot] merged 2 commits into
matrixorigin:mainfrom
loveRhythm1990:fix/memoria-session-finalization
Oct 14, 2026
Merged

mergify[bot] merged 2 commits into
matrixorigin:mainfrom
loveRhythm1990:fix/memoria-session-finalization

Conversation

@loveRhythm1990

@loveRhythm1990 loveRhythm1990 commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

CLI exit now persists a typed episode through the authenticated Server memory proxy before deleting its tracked working snapshot. The CLI transport also implements scene persistence and reflection instead of inheriting unsupported/no-op operations. It shares the direct transport's typed encoders, reflection decoder, and receipt validation.

Missing, empty, wrong-type, whitespace-only, and malformed write receipts cannot authorize working cleanup or a user-visible claim of storage. Unsupported persistence fails explicitly. Required episode/purge failures keep retry eligibility; optional reflection/scene failures remain diagnostic and do not prevent successful consolidation from starting the 15-minute debounce cooldown or cause those completed stages to replay. Successful backend reflection cooldown skips are accepted as empty optional results.

Related issue

Refs #996. This PR addresses write receipts, the CLI no-op archive/cleanup defect, and completion-cooldown classification. The issue remains open for its separate Astra/Memoria owner-namespace mismatch, cross-instance close/extraction coordination, and durable/idempotent retry concerns. This PR does not claim those broader lifecycle concerns are fixed.

Change type

  • Bug fix
  • Documentation
  • Test
  • Feature
  • Refactor or performance improvement
  • Build, CI, or maintenance

User and compatibility impact

  • CLI users with admitted memory access and a valid session snapshot can now archive the episode and complete working cleanup on normal exit.
  • Failed or unconfirmed archive writes preserve working memory. Existing fail-closed snapshot reads and owner/session validation are preserved.
  • An optional reflection failure no longer blocks consolidation cooldown. Scene receipt failures remain accurately counted without replaying episode/purge work.
  • Existing valid Memoria responses, credential policy, and timeout budgets remain compatible. No deployment, database, or secret changes.

Architecture and complexity delta

  • Canonical owners extended: astra-memoria owns reusable receipt-ID validation and reflection response decoding; runtime owns typed encoders and the one session-end governance sequence; CLI remains an authenticated transport adapter to that sequence.
  • Existing implementations and callers searched: direct/user-scoped Memoria ports, explicit memory gateway, CLI startup/exit, Server close scheduling, background extraction, and the session-end debouncer.
  • Removed empty successful write acknowledgments and inherited no-op CLI archive behavior. The receipt rule is defined once and reused for HTTP JSON responses and arbitrary port-returned IDs.
  • No new lifecycle state machine, credential fallback, table, or schema. Optional reflection is separated from required consolidation completion; no durable retry queue is introduced.

Verification

Passed locally:

  • cargo test -p astra-memoria --lib: 18 passed.
  • cargo test -p astra-tools --lib memoria::tests::: 49 passed.
  • cargo test -p astra-runtime --lib turn::cloud::session_end_governance::tests::: 20 passed.
  • Compiled runtime lib-test executable, filter turn::cloud::memoria_compact::tests::: 63 passed (including invalid receipts in all three HTTP store paths).
  • cargo test -p astra-cli --lib cli::session::session_startup::tests::cli_: 6 passed, including real CLI finalization through loopback HTTP mocks.
  • cargo test -p astra-cli --lib cli::session::session_cleanup::tests::: 8 passed.
  • make format-check and git diff --check: passed.
  • python3 scripts/ci/validate_repository.py: passed.

cargo clippy -p astra-memoria -p astra-tools -p astra-runtime -p astra-cli --all-targets -- -D warnings: passed. Repository CI is still running on the updated head; no failing check was reported when marking ready.

  • Public entrypoints exercised: CLI finalize_session_with_budget, canonical session-end governance, direct HTTP store operations, and explicit remember HTTP gateway.
  • Unhappy paths exercised: missing/empty/malformed receipts retain working state; unsupported transport persistence fails; optional reflection HTTP 503 and successful cooldown skips; unconfirmed scenes do not count as stored; required failures do not start successful cooldown.
  • Database verification: not applicable; no SQL, schema, or transaction changes.
  • Source review: 7/7 follow-up files reviewed, no skips, including the memory design/debounce documentation.

Final checklist

  • Added or updated tests at the behavior-owning layer.
  • Updated the memory design contract and cooldown documentation.
  • Checked the diff for credentials, private endpoints, customer data, and generated files.
  • Conventional Commit-style PR title.

Latest upstream main (365e313c) was merged into this feature branch with merge commit 935f7f2c; the review fixes were appended in 6dbeb704.

@loveRhythm1990 loveRhythm1990 changed the title fix(memory): validate write receipts and preserve cleanup retry eligibility fix(memory): confirm CLI archive writes and preserve consolidation cooldown Oct 13, 2026
@loveRhythm1990
loveRhythm1990 marked this pull request as ready for review October 13, 2026 13:33

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

评审结论:APPROVE。实际代码评审:GPT-6 Astra / xhigh。

提交前核验(2026-10-14T05:59:44.535Z):PR 为 OPEN,head 为 6dbeb704bf361b5ac8589a96a0fea40331a34982;完整 CI 与下文证据一致,适用检查全部通过;没有新增可见实质评审。以下保留完整发现、验证范围与限制。


PR #997 独立评审建议:APPROVE,限定本次补丁;没有发现足以要求修改的新增高置信度缺陷。 实际评审由指定的 GPT-6 Astra / xhigh 完成。

评审对象是 fix(memory): confirm CLI archive writes and preserve consolidation cooldown。2026-10-14 05:08:15 UTC 最后复核时,PR 为 OPEN、非 draft;head 未在评审期间变化。

  • 精确 head:6dbeb704bf361b5ac8589a96a0fea40331a34982。
  • PR API advertised base:365e313cba7e018edd8c35ab1552f8e67b85c5db。
  • 本地 Git 核实的 merge-base:365e313cba7e018edd8c35ab1552f8e67b85c5db。
  • 最后复核的当前 main:83c0281d16e21a7d0ce6337a0c2604f3f9a41b34;PR 的 mergeable_state=behind。下述 CI 是这个 head 的既有检查,不能视作与当前 main 集成后的验证。

CI 与重复评审检查。 首次检查于 05:00:57 UTC 开始,05:08:15 UTC 再次核验了 checks、commit statuses、workflow runs 和全部可见评审记录。

  • checks:39/39 已完成,36 success、2 skipped(Web、SDK)、1 neutral(Mergify Merge Queue),没有失败或进行中的检查。
  • Actions:5/5 success,包括 Test Suite、Static Checks、两次 PR Title 和 Supersede stale PR runs。Test Suite 于 2026-10-13 13:38:28 UTC 完成;Summary check 于 13:38:55 UTC 成功。
  • commit statuses:0 条。Combined status 返回的字面值 pending 对应空 statuses 集合,不存在一条正在等待的传统 status check。
  • reviews、inline review comments、issue conversation comments 均为 0。可见记录中没有当前 head 的进行中或已完成实质评审;未将空 approval/comment 或旧 head 记录当作完成依据。API 各集合均不足每页 100 条,check/workflow 的返回数与 total_count 一致,无遗漏分页。

设计和代码判断。 完整阅读了全部 8 个改动文件(614 additions / 72 deletions),并将本地评审快照的 8 个文件逐一与 GitHub head blob SHA 对齐。已阅读 AGENTS.md、CONTRIBUTING.md、架构和 memory 设计、测试指南;仓库没有适用的 .agents/skills。评审同时追踪了 CLI finalizer、ThinClient、Server memory proxy、UserScoped/HTTP MemoriaPort、working snapshot loader、显式 memory gateway 和 Server close/debouncer 调用链。

文件与定位 结论
session_startup.rs:491;501、516、535 CLI 的新增 episode/scene 写入复用 canonical typed encoder 和已认证 Server proxy;episode 收据验证成功后治理才可进入 purge。反射请求显式使用 candidates 模式。
astra-memoria/lib.rs:283;413、494 收据规则集中在共享边界;不支持的 episode/scene 操作显式失败;reflection decoder 在直接和代理传输间复用。
astra-tools/memoria.rs:1436;1657 remember 不再从空成功响应构造“已存储”确认,正常错误响应仍保留原错误。
memoria_compact.rs:109;870、993、1036、1074 typed 编码成为复用接口,三个直接 HTTP store 路径使用统一收据验证;反射 JSON 解析失败可观察。
session_end_governance.rs:212;283、350 对非 HTTP port 返回的 ID 也进行校验;未确认的 episode 不授权 purge,未确认的 scene 不计成功;必需阶段和可选阶段的结果分类清楚。
session_handlers.rs:1901 必需 episode/purge 失败不再提交成功冷却,permit drop 释放后续调用资格;失败 flags 进入结构化日志。
session_end_debounce.rs:25 本文件仅修改注释;既有 owner+session key、代际 permit 和有界完成记录保持一致。
docs/design/memory.md:99 文档覆盖收据、失败分类、CLI 五秒维护预算与取消;durable retry 的范围限制已明确。可选阶段超时还有下述既有边界。

数据库 I/O、并发与资源成本。 这次补丁没有 SQL/schema/transaction 变更,但 CLI 成功归档现在实际产生 episode 写请求、一次 reflection 请求以及每个候选一次串行 scene 写请求;各代理操作继续经过 session ownership 和当前 Memoria authority 检查,因此会有相应鉴权/权限解析成本。没有把“无 SQL diff”解释为零数据库成本。新增收据处理是本地字符串/JSON 校验;没有额外读取探测、批量后台任务或共享凭证缓存。CLI 仍受总计五秒退出维护预算限制;Server 仍为六十秒。既有 debouncer 隔离 owner/session 的能力经本地测试验证,但它只协调单进程治理调用,不构成跨实例锁或 extraction fence。没有运行真实数据库性能或多实例负载测试。

非阻塞遗留边界。 有一个可确定、但已存在于 base 的超时限制,建议继续在 #996 的生命周期后续工作中追踪:如果 episode/purge 已完成,而可选 reflection 或 scene 持久化耗尽外层总预算,session_handlers.rs:1885 的 timeout 会丢弃治理 future,代码无法到达 1901 的 consolidation_complete() 判断;permit 随后释放,成功冷却不会被记录。再次关闭可再次进入治理;是否产生重复 episode 还取决于后续 snapshot/facts 状态。本地探针确认了“必需阶段已执行、reflection pending、超时后可重新获取 permit”。base 中已有同一外层 timeout 和释放路径,因此不作为本 PR 新增缺陷或阻塞项。文档中“可选失败不会影响冷却”应理解为返回 Ok(report) 的完成路径,不能外推至总预算取消。

此外,#996 已披露且本 PR 明确未解决的 Astra/Memoria owner namespace 不一致、close 与 extraction/跨实例协调、耐久/幂等重试问题仍然存在。本次评审不把保留重试资格当作已建立自动重试,也不把一个 ID 收据当作跨请求原子性或 exactly-once 证明。

本地验证。 所有检查使用 /tmp/astra-pr-997 隔离快照和合成数据;未调用生产/共享服务或付费模型接口,未修改产品代码、推送、重跑远端 CI或合并。

  • 当前 head 的真实 astra-memoria/src/lib.rs 用 rustc 和环境现有只读依赖工件编译:18/18 单元测试通过,包括无效收据、unsupported persistence、scope 和状态隔离用例。
  • 当前 head 的真实 session_end_debounce.rs 独立编译:10/10 单元测试通过,包括相同 session 不同 owner、独占 permit、取消/失败释放、旧代际清理和有界缓存。
  • 直接包含当前 head 的治理与 debouncer 模块的隔离探针:9 个场景断言通过,覆盖 4 类无效 episode ID、读失败、purge 失败、可选 reflection 失败、空 scene 收据,以及上述可选阶段 pending 后取消边界。该探针明确使用成功空 snapshot seam,不能代替真实 snapshot parser 或 HTTP/数据库集成测试。
  • 正常 cargo test --offline --locked -p astra-memoria --lib 在 workspace 依赖解析阶段因缓存缺少 rand_pcg 退出,尚未开始编译。没有绕过离线约束;直接源码验证结果不等价于完整 Cargo workspace 构建。完整 CLI/Server HTTP 测试本地未重跑,其既有 head CI 成功作为独立证据。

支持证据均保存在本目录:github-evidence.json(状态、SHA、39 checks、5 workflows、分页和评审检查)、memoria-direct-tests.log、debounce-tests.log、governance-probe.log、memoria-tests.log(Cargo 阻塞原因)、governance-probe.rs 和 verify.py。重放隔离源码检查可运行 python3 /tmp/astra-pr-997/verify.py。

@mergify mergify Bot added the queued label Oct 14, 2026
@mergify

mergify Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • ✅ Entered queue — 2026-10-14 06:00 UTC · Rule: main · triggered by rule Automatic queue on approval for main
  • 🚫 Left the queue — 2026-10-14 06:00 UTC · at 6dbeb704bf361b5ac8589a96a0fea40331a34982

This pull request spent 7 seconds in the queue, with no time running CI.

Reason

The pull request can't be updated

GitHub response: refusing to allow a GitHub App to create or update workflow .github/workflows/harness-manual.yml without workflows permission
GitHub only lets Mergify write to .github/workflows/ with the workflows permission. An organization owner can accept Mergify's pending permissions at https://dashboard.mergify.com/orgs/matrixorigin/repositories.

Hint

You should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

Requeued — the merge queue status continues in this comment ↓.

@mergify mergify Bot added dequeued and removed queued labels Oct 14, 2026
@XuPeng-SH
XuPeng-SH force-pushed the fix/memoria-session-finalization branch from 6dbeb70 to 0dc2234 Compare October 14, 2026 06:34
@mergify mergify Bot added queued and removed dequeued labels Oct 14, 2026
@mergify

mergify Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • ✅ Entered queue — 2026-10-14 07:38 UTC · Rule: main · triggered by rule Automatic queue on approval for main
  • ✅ Checks skipped · PR is already up-to-date
  • ✅ Merged — 2026-10-14 07:39 UTC · at 62d5f03e2e22d41f89aee31055c5ded040ea0d0d · squash

This pull request spent 17 seconds in the queue, including 1 second running CI.

Required conditions to merge
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-approved [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Check PR title
    • check-neutral = Check PR title
    • check-skipped = Check PR title
  • any of [🛡 GitHub branch protection]:
    • check-success = check
    • check-neutral = check
    • check-skipped = check
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: core crates + bridge hooks
    • check-neutral = Test: core crates + bridge hooks
    • check-skipped = Test: core crates + bridge hooks
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-runtime
    • check-neutral = Test: astra-runtime
    • check-skipped = Test: astra-runtime
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-cli (edge-fs-tools)
    • check-neutral = Test: astra-cli (edge-fs-tools)
    • check-skipped = Test: astra-cli (edge-fs-tools)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-cli (edge-git-gix)
    • check-neutral = Test: astra-cli (edge-git-gix)
    • check-skipped = Test: astra-cli (edge-git-gix)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-cli (edge-rest)
    • check-neutral = Test: astra-cli (edge-rest)
    • check-skipped = Test: astra-cli (edge-rest)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-cli (edge-shell)
    • check-neutral = Test: astra-cli (edge-shell)
    • check-skipped = Test: astra-cli (edge-shell)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: astra-cli (non-edge)
    • check-neutral = Test: astra-cli (non-edge)
    • check-skipped = Test: astra-cli (non-edge)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: online (core)
    • check-neutral = Test: online (core)
    • check-skipped = Test: online (core)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: online (integration)
    • check-neutral = Test: online (integration)
    • check-skipped = Test: online (integration)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: turn-core + services + plan
    • check-neutral = Test: turn-core + services + plan
    • check-skipped = Test: turn-core + services + plan
  • any of [🛡 GitHub branch protection]:
    • check-skipped = web (typecheck, test, build)
    • check-neutral = web (typecheck, test, build)
    • check-success = web (typecheck, test, build)
  • any of [🛡 GitHub branch protection]:
    • check-skipped = Astra SDK (typecheck, test+coverage, build)
    • check-neutral = Astra SDK (typecheck, test+coverage, build)
    • check-success = Astra SDK (typecheck, test+coverage, build)
  • any of [🛡 GitHub branch protection]:
    • check-success = Test: macOS workspace coordination
    • check-neutral = Test: macOS workspace coordination
    • check-skipped = Test: macOS workspace coordination

@mergify
mergify Bot merged commit 62d5f03 into matrixorigin:main Oct 14, 2026
64 of 67 checks passed
@mergify mergify Bot removed the queued label Oct 14, 2026
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