Avoid rewriting Phase 2 selection on clean workspace (#19812)

## Why

Phase 2 can now claim the global consolidation lock on startup even when
the git-backed memory workspace is already clean. The clean-workspace
path still finalized through the normal Phase 2 success path, which
clears and re-marks `selected_for_phase2` rows. That made no-op startups
perform avoidable writes to `stage1_outputs`, creating unnecessary DB
I/O and contention when no memory files changed.

## What Changed

- Added a preserving-selection Phase 2 finalizer in `codex-state` that
only marks the global job row as succeeded.
- Kept the existing `mark_global_phase2_job_succeeded` behavior for real
consolidation runs, where the selected Phase 2 snapshot must be
rewritten.
- Switched the `succeeded_no_workspace_changes` branch in
`core/src/memories/phase2.rs` to use the preserving-selection finalizer.
- Added a regression test that installs a SQLite trigger on
`stage1_outputs` and verifies the clean finalizer performs zero updates
there.

## Testing

- `cargo test -p codex-state`
- `cargo test -p codex-core memories::tests::phase2`
This commit is contained in:
jif-oai
2026-04-27 15:14:16 +02:00
committed by GitHub
Unverified
parent 5d314f324c
commit 79b4f691a6
2 changed files with 186 additions and 24 deletions
+18 -2
View File
@@ -122,12 +122,11 @@ pub(super) async fn run(session: &Arc<Session>, config: Arc<Config>) {
if !workspace_diff.has_changes() {
tracing::error!("Phase 2 no changes");
// We check only after sync of the file system.
job::succeed(
job::succeed_preserving_selection(
session,
db,
&claim,
new_watermark,
&raw_memories,
"succeeded_no_workspace_changes",
)
.await;
@@ -291,6 +290,23 @@ mod job {
.await
.unwrap_or(false)
}
pub(super) async fn succeed_preserving_selection(
session: &Arc<Session>,
db: &StateRuntime,
claim: &Claim,
completion_watermark: i64,
reason: &'static str,
) -> bool {
session.services.session_telemetry.counter(
metrics::MEMORY_PHASE_TWO_JOBS,
/*inc*/ 1,
&[("status", reason)],
);
db.mark_global_phase2_job_succeeded_preserving_selection(&claim.token, completion_watermark)
.await
.unwrap_or(false)
}
}
mod agent {