Skip to content

🤖 refactor: expose pending history transactions - #4181

Merged
ThomasK33 merged 1 commit into
mainfrom
codex/effect-pending-history-transactions
Sep 10, 2026
Merged

ThomasK33 merged 1 commit into
mainfrom
codex/effect-pending-history-transactions

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Summary

Adds the inactive history transaction adapter needed to bind compaction attachments to their exact history boundary. It holds the existing local and process locks through pending-file work, returns verified raw boundary evidence, and exposes the physical ownership check for the dependent atomic-publication layer. Runtime consumers remain unactivated.

Review focus

  • The scanner reuses the provider reader's verified chat/archive snapshot. Known absence requires exhausting both files; unreadable reset evidence cannot authorize older attachments. Existing deletion-floor projection remains intact.
  • Exact partial retirement compares the complete captured snapshot, so a successor or a newer flush under the same ID survives. Physical ownership is rechecked after I/O, followed by the synchronous logical guard and unlink.
  • Exact follow-up cleanup delivers its optional synchronous receipt immediately after rename. Missing history alone cannot authorize restoring pending attachments. Truncate recovery receives the existing physical guard, with one provenance transaction.

This is G2a, the first layer of the pending-state phase, based on main. Atomic pending/history publication belongs to G2b; activation follows separately. Implementation scope is frozen to review, CI, and necessary integration fixes. Merge remains coordinated with the complete phase.

Validation

Validation of the combined five-layer replay: 2,321 tests and 18,866 assertions pass across 40 files on runtime 013d22c6d68c50be1370e1c4df6b1ccbe776f304 over lifecycle 29b43c63f53040d43feecf38a36f2ff14b53aa41, based on pinned main a0a2dab98da8efe7e659fb0cb8b9897f376d9641. The final runtime candidate b0abd1481d5dbfb025c484fbf5efc7fdaef73689 adds only a mechanical Error-type-guard correction to a diagnostic assertion; its 12 affected rollover controls and targeted ESLint pass, with production unchanged. This covers pending/history ownership, publication, rollback, partial recovery, all runtime compaction paths, token-budget and model-requested new_context rollover, session_history, and append provenance. Tests use real local storage with outbound provider traffic blocked. These are combined-phase results, not a separate test run at each intermediate layer. Canonical make static-check passes on the final runtime candidate; Nix formatting skips because Nix is unavailable. Final coordinated PR readiness remains pending.

Risks

The shared scanner and recovery wrapper also serve existing history operations. A regression could expose stale context or overwrite successor history; the focused privacy, deletion, publication, and cancellation suites cover these affected paths. No persistence format changes or runtime activation are included.

Integration: candidate 8e5bc5a8824ef821bb189319030057ce6adeda44 replays this PR's complete owning interval onto a0a2dab98da8efe7e659fb0cb8b9897f376d9641 without conflicts or manual resolutions. Range-diff is unchanged, and source authors and complete commit messages are preserved. Main's strict partial-read option and newer history behavior remain in the prepared chain. Runtime activation remains owned by #4190.


Generated with xum • Model: unavailable • Thinking: unavailable • Cost: $unavailable

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-10T18:52:03.288514Z 8e5bc5a Manual request
🔒 Security Review Completed 2026-09-10T18:52:22.598578Z 8e5bc5a Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ThomasK33
ThomasK33 added this pull request to stack #4184 September 9, 2026 13:20
@ThomasK33
ThomasK33 force-pushed the codex/effect-pending-history-transactions branch from cefc407 to 6449fab Compare September 9, 2026 13:52

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6449fab601

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/compactionPendingState.ts
@ThomasK33

Copy link
Copy Markdown
Member Author

This ownership requirement is implemented in the dependent PRs in the same phase stack:

This bottom layer only exposes the existing history transaction/ownership capability. CompactionPendingState has no production runtime callers here; runtime activation is a later layer. These PRs will be merged as one completed phase only after all members are ready, so no runtime path is enabled with the guard omitted. Keeping the producer and consumer guards in their owning layers avoids duplicating/reordering the reviewed changes.

The concern is valid for activation and is covered before that activation. Please reassess this bottom-layer boundary with #4183 and #4186 as its explicit dependents.


Generated with xum • Model: unavailable • Thinking: unavailable • Cost: $unavailable

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

Please reassess the ownership finding with the phase boundary and implemented dependent coverage documented above. #4183 guards publication/rollback and #4186 guards load/consume/discard; the bottom layer has no active runtime consumers.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 6449fab601

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 6449fab601

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Provide a recovery-aware locked pending-state view with verified boundary provenance, exact partial retirement and synchronous cleanup receipts. Keep all runtime consumers unchanged.

Signed-off-by: Thomas Kosiewski <tk@coder.com>

---

_Generated with `xum` • Model: `unavailable` • Thinking: `unavailable` • Cost: `$unavailable`_

<!-- mux-attribution: model=unavailable thinking=unavailable costs=unavailable -->

Change-Id: I7c4844dedd565aa942d28029d96e22c1863cc0ae
@ThomasK33
ThomasK33 force-pushed the codex/effect-pending-history-transactions branch from 6449fab to 8e5bc5a Compare September 10, 2026 18:47
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

Please review current head 8e5bc5a8824ef821bb189319030057ce6adeda44. The five-layer phase has been replayed onto main with all owning fixes preserved. Combined validation passed 2,321 tests; the final test-only typing correction passed its 12 affected controls, and full static checks pass on the final phase head. Addressed findings have published replies and resolved threads. The description records the complete layer scope and exact validation.


Generated with xum • Model: unavailable • Thinking: unavailable • Cost: $unavailable

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 8e5bc5a882

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 8e5bc5a882

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Sep 10, 2026
Merged via the queue into main with commit b8b7e23 Sep 10, 2026
35 of 38 checks passed
@ThomasK33
ThomasK33 deleted the codex/effect-pending-history-transactions branch September 10, 2026 20:29
yermakoffivan pushed a commit to yermakoffivan/mux that referenced this pull request Sep 11, 2026
…oder#4183)

Separate pending-state preparation and history publication can let
another backend replace the fallback before the boundary commits. This
adds an inactive publisher that holds the pending queue and both history
locks through preparation, final row/partial admission, boundary
publication, synchronous receipt delivery, and exact rollback.

Mandatory history publication succeeds independently of optional
attachment enrichment. Unsupported future-version sidecars retain their
exact bytes on success and failure. Physical ownership checks cover
preparation, history rename, rollback, eager archive rotation, and the
inherited provenance finalization. Caller sequence metadata changes only
at commit, so failed attempts can retry the same prepared rows;
duplicate appended object references are rejected before allocation.

This is G2b, stacked on G2a (coder#4181). The publisher remains inactive
until C2 adopts every producer and consumer together, including reset
and restart restoration.

Validation of the combined five-layer replay: 2,321 tests and 18,866
assertions pass across 40 files on runtime
`013d22c6d68c50be1370e1c4df6b1ccbe776f304` over lifecycle
`29b43c63f53040d43feecf38a36f2ff14b53aa41`, based on pinned main
`a0a2dab98da8efe7e659fb0cb8b9897f376d9641`. The final runtime candidate
`b0abd1481d5dbfb025c484fbf5efc7fdaef73689` adds only a mechanical
Error-type-guard correction to a diagnostic assertion; its 12 affected
rollover controls and targeted ESLint pass, with production unchanged.
This covers pending/history ownership, publication, rollback, partial
recovery, all runtime compaction paths, token-budget and model-requested
`new_context` rollover, `session_history`, and append provenance. Tests
use real local storage with outbound provider traffic blocked. These are
combined-phase results, not a separate test run at each intermediate
layer. Canonical `make static-check` passes on the final runtime
candidate; Nix formatting skips because Nix is unavailable. Final
coordinated PR readiness remains pending.

Risk is concentrated in the shared history-writer extraction and eager
rotation path. Existing public behavior remains covered by the history
regression suites; this layer does not activate the new publisher.

Integration: candidate `94de3b46d58149075b845ab995a88d471c9b7296`
replays this PR's complete owning interval onto
`8e5bc5a8824ef821bb189319030057ce6adeda44` without conflicts or manual
resolutions. Range-diff is unchanged, and source authors and complete
commit messages are preserved. Main's strict partial-read option and
newer history behavior remain in the prepared chain. Runtime activation
remains owned by coder#4190.

---

_Generated with `xum` • Model: `unavailable` • Thinking: `unavailable` •
Cost: `$unavailable`_

<!-- mux-attribution: model=unavailable thinking=unavailable
costs=unavailable -->
yermakoffivan pushed a commit to yermakoffivan/mux that referenced this pull request Sep 11, 2026
Adds a local lifecycle for compaction preparation and attachment
consumption. Admission is claimed before asynchronous work; only the
history commit callback installs a publication. Captured requests share
consumption facts so delayed completion, failed enrichment, and
heartbeat rollback cannot revive discarded attachments. Runtime
activation is isolated in coder#4190.

Each publication receives a fresh `compactionPublicationId` committed
with its history boundary and reused as the existing pending V1
`writeId`. It distinguishes foreign replacements even when boundary ID,
sequence, timestamp, and summary content match. Same-boundary
finalization, follow-up clearing, and rotation preserve that occurrence.
Loading, acknowledged warmth, request adoption, suppression, and
rollback cleanup use this exact identity. Compatible unmarked rows still
load persisted attachments; absent-file warmth needs occurrence proof,
except for proven initial history.

History-only publications retain cleanup authority for attachments they
omitted. The store captures private predecessor provenance under the
publication lock. Consumption can recover the matching receipt after a
failed preparation read, using one queued sidecar read for the retained
chain and the existing exact-identity cleanup. A stale cached owner
cannot substitute for the locked predecessor. Already authenticated
legacy receipts retain their authority; newly inferred cleanup requires
a marked occurrence. Copied or mutated callback metadata cannot enlarge
the store's authority. Consecutive history-only publications carry
unresolved predecessors only through an exact matching local
publication, and pruning follows the reachable rollback horizon.

Acknowledging an empty request retires omitted attachments without
granting them acknowledgment; independently acknowledged warmth remains
eligible. Before rollback removes history, a checkpoint under the same
locks durably retires already-consumed ownership. If a required read or
retirement is unavailable, rollback leaves history unchanged for retry.
A consumption epoch makes final admission skip when acknowledgement or
discard changes during staging. Older heartbeat rollback skips while a
successor owns the boundary, preserving that successor's fallback and
payload.

Ordinary captures probe sidecar existence in the store queue after
earlier publications settle. Local ownership is checked at execution, so
a queued history-only publication cannot be missed. Only ENOENT with no
local owner skips the extra locked history scan, and every call probes
again. Present or uncertain storage, probe errors, warmth, and
history-only tokens retain full qualification; there is no negative
cache.

The merge queue also exposed a lost-abort race in the plugin-install
watchdog fixtures. Both fake checkout callbacks now check an
already-aborted signal after awaited file creation and before
registering their listener. A count-quota regression forces this
ordering using the real watchdog. Production quotas, watchdog code, and
timeouts are unchanged.

Validation:

- The foreign-predecessor, queued-capture, and absent-probe FIFO
regressions fail before their respective fixes. Queued successful and
history-only publications are covered while ordinary absence still
avoids history locks and scans. The final
lifecycle/store/runtime-preparation run passes 171 tests and 752
assertions, covering restart rollback, legacy receipts, history-only
chains, fallback preservation, foreign replacements, resets, future
formats, failed cleanup, pruning, and authority mutation.
- Canonical `make static-check` passes on combined tree
`4638cf400821ae9e9bb3d18ef48fd12b35ff5809`, including both TypeScript
configurations, lint, formatting, and documentation checks. Nix is
unavailable locally.
- The watchdog suite passes 130 tests. The current-main provider/MCP
integration passed 411 tests. Earlier combined compaction coverage
passed 2,321 tests across 40 files; these groups overlap and are not a
unique total.

Risk: uncertain storage conservatively withholds attachment context.
Failed disk retirement remains local debt until successful cleanup; the
in-memory capability does not persist discard intent across a crash.
Unknown future formats remain untouched. The pending file stays V1; no
new journal, migration, or sidecar version is introduced.

This is the remaining pair of the pending-state phase: coder#4181, coder#4183, and
coder#4186 have merged. Keep coder#4189 and coder#4190 together through review, CI, and
the merge queue.

---

_Generated with `xum` • Model: `unavailable` • Thinking: `unavailable` •
Cost: `$unavailable`_

<!-- mux-attribution: model=unavailable thinking=unavailable
costs=unavailable -->

---------

Signed-off-by: Thomas Kosiewski <tk@coder.com>
yermakoffivan pushed a commit to yermakoffivan/mux that referenced this pull request Sep 11, 2026
…er#4190)

Activates the compaction preparation lifecycle across ordinary, idle,
heartbeat, continuous, and recovery compaction. Producers capture
admission before asynchronous work and publish boundaries through the
same pending-state owner. Immediate and periodic attachments retain
their exact qualified receipt for acknowledgement or discard; metadata
reads use that qualification too. This completes activation above coder#4189
and removes the handler's duplicate pending-file parser, writer queue,
rollback protocol, and skill/read caches. The pending file remains V1.

Boundary admission compares the privacy-filtered, archive-aware provider
history used to prepare the summary. Restored source history can remain
eligible after heartbeat rollback; changed history, generations,
partials, or ownership prevent publication. Reset decisions and
generation fences share the recovered history locks and physical lease,
including explicit clear or replacement of empty history. Successful
destructive cleanup removes recognized legacy V1 bytes so preceding
versions cannot reload pre-reset attachments. Unknown future formats and
current-generation successors remain intact.

All compaction producers retire malformed partial content before strict
publication. Empty directories at `partial.json` recover through
nonrecursive removal after final ownership checks. Nonempty directories,
symlinks, valid replacement partials, lost logical or physical
ownership, and unrelated I/O failures remain protected. Disposal and
carryover fixtures use real history and store publication, including the
occurrence identity required for acknowledged warmth.

Ordinary-send and emergency-retry rollovers retire carryover after the
history writer settles, so cleanup observes the committed generation.
Reconciliation also runs when an append commits before reporting an
error. Failed appends and current-generation successors retain their
protection. If an append succeeds but cleanup fails, the diagnosis is
logged and the successful writer result continues through reset and
acceptance. Original append errors remain authoritative when both
operations fail. Kernel and local reset effects remain ordered before
publication.

Metadata fetches use a fresh reader and skip the extra history proof
only when the sidecar is absent, retaining the normal history fallback
and tracked-file data. Every fetch probes again, so later foreign
publication is discovered without a negative cache.

Ordinary completion continues accounting, acknowledgement, continuous
observation, queue drain, and goal work when compaction generation
storage is unreadable. `handleCompletion` captures admission and
generation before its first history read, retains capture as a Result,
and propagates an error only after confirming a compaction request.
Successful compaction still publishes against that early generation,
preserving the foreign-reset fence.

The runtime changes are unchanged by the latest parent repairs. The
parent contains exact predecessor retirement for history-only
publications and the watchdog-fixture CI repair; this child preserves
runtime activation on that corrected foundation and current main
`bad3c4f2`.

Validation: canonical static checks pass on final tree
`4638cf400821ae9e9bb3d18ef48fd12b35ff5809`; the final
lifecycle/store/runtime-preparation run passes 171 tests. The new-main
provider/MCP integration passed 411 tests. Earlier evidence includes 229
completion/admission tests, all 509 WorkspaceService tests, and 2,321
combined tests across 40 files plus actual preceding-handler
compatibility controls. CI is re-evaluated on each published head;
earlier passing runs do not establish readiness for this revision. Test
groups overlap. Local provider calls were blocked, with loopback HTTP
allowed for local MCP fixtures; Nix was unavailable locally.

Risk: publication and carryover ownership affect every compaction path;
regressions can omit or repeat context. Tests use real files,
deterministic barriers, multiple store/service instances, and restart
behavior. If durable cleanup remains unavailable after a committed
reset, current generation checks exclude stale attachments, but
compatible bytes can remain readable by a preceding version after
downgrade. Cleanup errors stay logged without misclassifying a committed
send.

This is the remaining pair of the pending-state phase: coder#4181, coder#4183, and
coder#4186 have merged. Keep coder#4189 and coder#4190 together through review, CI, and
the merge queue.

---

_Generated with `xum` • Model: `unavailable` • Thinking: `unavailable` •
Cost: `$unavailable`_

<!-- mux-attribution: model=unavailable thinking=unavailable
costs=unavailable -->

Signed-off-by: Thomas Kosiewski <tk@coder.com>
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.

1 participant