Repository navigation
Codex Security 0.1.22: finalization resurrects resolved checkpoint deferrals and produces inconsistent durable coverage #741
Description
Activity
bclandry commented
on Sep 18, 2026 More actionsRelated symptom on Windows in the Codex desktop app with the Codex Security plugin version 0.1.24, but importantly BEFORE finalization. I am not claiming the same root cause as this issue.
Retained sequence:
- An interim semantic checkpoint was accepted with complete=false, partial coverage and a temporary closeout deferral.
- After the remaining review was completed, record_codex_security_scan_draft accepted a final semantic checkpoint with complete=true, complete coverage and no deferred entries. The response was draft_written / operation replace.
- Canonical coverage nevertheless retained the earlier partial state and stale closeout deferral. The scan remains running and unsealed.
No finalization was attempted, so there is no finalization error. No canonical artifacts were manually edited, and no rerun, forced failure/cancellation, replacement scan or plugin modification was performed. Zero findings are not being treated as proof of complete coverage.
Expected: accepted checkpoint replacement and canonical coverage should agree while preserving history and any genuinely unresolved items. If this sequence is unsupported, please identify the supported contract.
Please provide a maintainer-supported, owner-bound in-place recovery procedure for this running/unsealed state, including preconditions and evidence-preservation requirements, or confirm that no such procedure exists. Any recovery will be reviewed and separately authorized before execution.
This is a metadata-only report based on retained evidence, not a new reproduction or a claim about the latest release. The desktop-app build and package version were not collected for this report. No private scan/session identifiers, artifacts, source, logs or attachments are included.
Additional observation in desktop plugin 0.1.31
We observed a related historical-deferral reconciliation problem in the Codex Security desktop plugin 0.1.31 on macOS, during a Standard Scan. The observation and local recovery occurred on 2026-09-30.
This is a sanitized reliability report, not disclosure of a vulnerability in the scanned repository or a claimed security-boundary bypass. No private repository source, findings, scan identifiers, customer data, credentials, or raw scan artifacts are attached.
Expected behavior
After review is complete, an authoritative, consistent final parent checkpoint with
complete=true, coveragecompleteness=complete,deferred=[], andopenQuestions=[]should not be overridden by obsolete interim deferrals.Historical evidence should remain available without counting resolved work as unresolved terminal coverage. Genuinely unresolved work, ambiguous checkpoints, and mismatched finding/review inventories must remain incomplete.
Observed behavior and diagnostic evidence
- The final semantic parent checkpoint explicitly reported complete coverage, with no deferred work or open questions.
- Earlier Node-side draft reconciliation retained 49 historical coverage rows in canonical coverage: 37 candidate-deferred rows and 12 batch-closure rows.
- A read-only completion-merge projection against a temporary copy of the captured state retained
completeness=partialand those 49 deferred rows, despite the complete checkpoint. The diagnostic reported no merge warnings. - In the locally inspected Python completion path,
scripts/workbench_saved_results.py, the unsealed canonical parent was preferred and parent checkpoints were treated as superseded when the manifest was not explicitly incomplete. The complete checkpoint therefore could not repair canonical coverage.
This is an observation of the captured 0.1.31 state, not a claim that every scan or the current release reproduces the defect.
Reproduction outline and limits
The observed lifecycle was:
- Run a Standard Scan that records interim deferred coverage/checkpoints.
- Resolve the required review and retain a final complete semantic parent checkpoint with empty deferred/open-question lists.
- Reconcile drafts into an unsealed canonical parent that still contains historical deferred rows.
- Run the normal completion preparation/merge path.
- Inspect canonical coverage and whether the unique consistent final checkpoint is treated as superseded.
The before/after merge behavior was checked on a temporary copy of the actual state. We have not reduced it to a fresh, standalone, synthetic reproduction package or reproduced it on the current public version. The outline above is not an independently tested fresh-start fixture. Private scan state is not being uploaded.
Local workaround evidence and caveat
A narrowly gated local hotfix restored the unique explicit complete root checkpoint only when substantive findings, coverage surfaces, fully reviewed files, and relevant inventory counts matched the canonical parent. It retained workbench-owned coverage-envelope fields.
The copied-state projection then reported complete coverage, no deferred work, and no open questions. Negative controls retained the original incomplete state for a stopped scan, explicitly incomplete manifest, mismatched findings, and multiple complete checkpoints. An already-complete parent remained unchanged. Copied preparation/contract validation and normal live completion subsequently succeeded.
The hotfix is not an upstream fix, release, or recommended broad workaround. Plugin reinstall/update may overwrite it. The shipped integrity manifest was not changed; the one local script mismatch was deliberately left visible. Neither deleting deferred rows manually nor weakening validation was used.
Installed 0.1.31 target identity:
- Official base SHA-256 recorded in the shipped integrity manifest:
db445b651bd677359ef0a5c2bbb70e896eccd60becbd80e8c7a77aa3010f289c - Locally patched file SHA-256:
9b8d5786acda87229ca4ad76200f01e7bfeb93e1d708dbc68735f5f42766532c
The pristine original file was not retained, so this report does not claim to provide an exact upstream unified diff. No patched payload is attached.
Maintainer request
Please confirm whether the current supported release addresses this complete-parent-checkpoint/historical-deferral interaction and, if so, identify the fixing release and the supported recovery path for affected existing scans. Please preserve fail-closed behavior for ambiguous, mismatched, explicitly incomplete, and stopped scan states.
Merged #1036 looks relevant: it adds explicit deferred-task closure and preserves task identities during recovery. Could you check whether it covers the remaining legacy-checkpoint cases here?
- addedarea:artifactsSaved scan state, storage, sealing, recovery, history, and artifact integrity.Saved scan state, storage, sealing, recovery, history, and artifact integrity.bugSomething isn't workingSomething isn't working
on Oct 8, 2026 Summary
Thanks — #1036's explicit ID-based closeout works, but it does not establish automatic migration of the captured legacy checkpoint history. I also reproduced a separate
complete+ retained-deferredinconsistency on current main and submitted a narrow fix: #1497. Its two-case regression needs only the upstream Python test environment, not a model/native scan.The PR preserves unresolved tasks and fixes only projected completeness. Broader closure/identity work remains with #771/#978/#1296/#1310; it does not add a competing migration API.
Remaining policy question
For old parent-owned candidate IDs later consolidated into findings, what supported mapping/terminal-outcome path should contributors use? I have not treated worker-owned
sourceFindingsas arbitrary aliases, fabricated rejections, duplicated findings, or cleared tasks just to force completion. Likewise, which old parent/checkpoint histories are intended to migrate automatically, versus requiring explicit saved-ID closure? Ambiguous, stopped, mismatched and independently pending work must remain protected.Results behind that conclusion
- Authority/supersession: the unmodified recovery component hash-matching the earlier 0.1.31 component reproduced the captured priority issue. An archived narrow workaround changed the same-input outcome. fix(plugin): close saved review tasks and simplify recovery #1036 changes head/source-order selection, but current main did not automatically reconcile that same legacy history. The entire old desktop cache/full DB is not attested.
- Generic closeout: current main's documented
resolvedDeferred: [{id, reason}]succeeds. Old empty-list input alone leaves a saved task pending. The pinned fix(artifacts): keep resolved checkpoint deferrals closed #771 head0a60d3a272c51f1d4deb498da23f9845f9713b88closes its linked-surface synthetic case through its older documented route, not all rows in the captured history. fix(artifacts): close resolved generic deferrals #978 proposes a different receipt contract. - Candidate consolidation: the captured parent candidate IDs and later consolidated findings lack native linkage. A supported many-to-one migration policy is still a question, not a completed fix.
- Diagnostics: the same legacy merge returned
warnings=[]while retaining pending work. This is an array observation, not an established independent warning bug or a claim about all logs. This PR does not add warnings. - Report/status: resolved surfaces and pending generic tasks coexist, but canonical JSON and the report agree on the partial result.
completedwith partial coverage is valid. A separate renderer bug and every original live-UI/0.1.22 fixture detail have not been established; fix(coverage): distinguish finished scans from complete requested coverage #586 is related display work, not proof of closure. - Recovery scope: new closure success is not automatic legacy migration. The original scan is already completed/sealed and was preserved, not resumed or resealed. These checks used isolated copies and deterministic component/native paths; they do not establish natural AI/Jisou workflow causality.
The separate invariant fixture has a complete canonical parent/terminal checkpoint but unresolved older work and no accepted head. Main
5ebe48db0585c5e582b0494236a01a739af13709and the tested #1310 head projectcompletewith retained tasks; strict finalization rejects it without sealing/replacing canonical files. The submitted patch yields truthful partial coverage without removing tasks. Identical generic/candidate regression inputs produce two completeness-assertion failures on the base and two passes after the patch. This is not a live/sealed corruption claim.Only the small synthetic three-file contribution is public. No private scan payloads/raw logs or optional caller adapter are attached.
Summary
Codex Security 0.1.22 reproducibly retains an interim deferred checkpoint in terminal durable coverage after that checkpoint has been explicitly resolved before completion.
This was reproduced with a minimal synthetic target consisting of one 214-byte file. It does not depend on the original application repository.
No durable artifacts were manually edited.
Environment
Minimal reproduction
Synthetic target:
3d06033bffeb0b451f0d1360430b46e281e4ef78bcdeb8487fca9a8ed44e4838Scan ID:
71fee081-86ab-4d7a-9125-aa28f01b3321Checkpoint ID:
synthetic-fixture-full-readLifecycle
complete=falsecompleteness=partialdeferred=[synthetic-fixture-full-read]complete=truecompleteness=completedeferred=[]openQuestions=[]RESOLVED_COVEREDExpected result
The resolved checkpoint should remain preserved in historical checkpoint evidence, but it should no longer count as a terminal deferral.
Expected terminal state:
complete0synthetic-fixture-full-read:RESOLVED_COVEREDreport.md,coverage.json, andscan-manifest.jsonshould agree.Actual result
After normal finalization:
coverage.jsonreportspartialsynthetic-fixture-full-readis reintroduced as a terminal deferred itemRESOLVED_COVEREDreport.mdrenders both the resolved state and an open follow-upThe final semantic draft immediately before completion was explicitly:
complete=truecompleteness=completedeferred=[]openQuestions=[]So the resolved deferred ID is reintroduced during terminal finalization/projection.
Observed invariant violation
An interim checkpoint may remain in historical evidence, but once its terminal state is
RESOLVED_COVERED, it should not remain in the final:A genuinely unresolved terminal item should still remain deferred; the expected behavior is terminal-state reconciliation, not unconditional deletion of deferrals.
Additional notes
I have a sanitized minimal reproduction package and final report available if useful.