Skip to content

status: fix FSMonitor history and clean-proof gaps - #66

Closed
ttaylorr-oai wants to merge 6 commits into
codex-unstablefrom
ttaylorr/codex-unstable-feedback-fixes
Closed

status: fix FSMonitor history and clean-proof gaps#66
ttaylorr-oai wants to merge 6 commits into
codex-unstablefrom
ttaylorr/codex-unstable-feedback-fixes

Conversation

@ttaylorr-oai

@ttaylorr-oai ttaylorr-oai commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • retry a late Darwin synchronization cookie only after the existing one-second timeout, with the existing bounded fallback preserved
  • retain a deduplicated, sequence-aware overflow of old FSMonitor paths so private indexes cannot prune or replay history needed by the canonical index
  • preserve authenticated FSMonitor state across clean non-fast-forward merges while conflicts and alternate indexes continue to fail closed
  • publish a clean proof after a writable exact git status repairs the canonical index, without extending the path to optional-lock-disabled commands, option-bearing status calls, or linked worktrees

Performance

  • successful cookie queries keep the existing fast path; the extra flush and wait happen only after the original timeout
  • ordinary batch walks are unchanged; sequence filtering and pointer-identity deduplication are confined to overflow compaction
  • merge and repaired-index handoffs remain restricted to clean canonical-index operations
  • direct daemon-response A/B: 12 paired rounds of 50 requests over 5,251 paths; paired geometric change -0.88%, paired median change +0.15%, and no compaction in either arm
  • seven ordinary git status scenarios over 12,000 tracked paths reported zero compactions; wall-clock data was nonstationary and is retained as inconclusive

Validation

  • make -j8
  • ./t7519-status-fsmonitor.sh (107/107)
  • ./t7527-builtin-fsmonitor.sh (177/177)
  • ./t7530-status-clean-sidecar.sh (59/59)
  • make -C t test-lint
  • git diff --check

@ttaylorr-oai
ttaylorr-oai force-pushed the ttaylorr/codex-unstable-feedback-fixes branch from d17c9bf to 3b52212 Compare August 21, 2026 18:54
@ttaylorr-oai ttaylorr-oai changed the title fsmonitor: retry late FSEvents cookies after timeout fsmonitor: fix late cookies and preserve index history Aug 21, 2026
@ttaylorr-oai
ttaylorr-oai force-pushed the ttaylorr/codex-unstable-feedback-fixes branch from 490f4d4 to 678fb2d Compare August 21, 2026 20:02
@ttaylorr-oai
ttaylorr-oai force-pushed the ttaylorr/codex-unstable-feedback-fixes branch from a646dbf to 2f97399 Compare August 24, 2026 19:29
@ttaylorr-oai ttaylorr-oai added kind:review-only Reviewed topic; do not merge this pull request build:codex-unstable Preview Codex Git build codex:draft Draft; no review action requested codex:blocked Current state needs intervention before it can advance labels Aug 24, 2026
@ttaylorr-oai
ttaylorr-oai force-pushed the codex-unstable branch 2 times, most recently from 590d091 to fded12c Compare August 26, 2026 00:36
with_lock__wait_for_cookie() gives a filesystem provider one second to
report a synchronization cookie. A healthy FSEvents stream can miss
that deadline while macOS is under load. The daemon then returns a
trivial response, and status scans the entire index even though event
delivery is still making progress.

4b1c56a (fsmonitor: flush pending FSEvents before cookie wait,
2026-07-21) requested an asynchronous flush on every Darwin query but
kept the same one-second deadline. f439708 (Revert "fsmonitor: flush
pending FSEvents before cookie wait", 2026-08-17) reverted it after a
matched 48-query test still saw 12 timeouts in each arm. Avoid restoring
that unqualified hot-path request.

When the initial Darwin wait expires, request an asynchronous FSEvents
flush and wait one more bounded interval. Successful queries retain the
original wait and do not issue a flush or extend their deadline. The
asynchronous call cannot block on the callback while the client holds
main_lock. If the provider stays silent, retain the existing
trivial-response fallback after the retry.

Add a test-only callback delay to exercise both outcomes: a 1.2-second
delay is recovered, while a 2.5-second delay still reaches the bounded
fallback.
The daemon currently assumes that each client which advances an
FSMonitor token also updates the repository's canonical index. That
does not hold for commands using GIT_INDEX_FILE. A private index can
advance the daemon past the canonical index's token and cause the
canonical index's next query to receive a global invalidation.

Keep a deduplicated overflow batch instead of discarding old paths.
Clients at the overflow sequence still get an exact delta. Older
clients get a conservative union of paths, which may overreport but
cannot miss a change.

All paths are interned. Keep a pointer-identity hash set with the
overflow batch so later compactions hash only newly retired paths,
rather than rebuilding a set over the daemon's lifetime history.

Add a regression which advances a private index repeatedly, verifies
that compaction remains deduplicated, and then checks that a read-only
canonical status reports both changed files without a trivial response.
Retired batches are collapsed into a path-only overflow set.  That keeps
old indexes complete, but it loses the sequence in which each path was
last observed.  A client that consumed an inode event can therefore see
it again after another index compacts the batch list, causing repeated
hard-link scans.  Unpinned batches have a zero pinned time and are also
eligible for compaction immediately despite the default grace period.

Do not use unpinned batches as truncation boundaries.  Record the newest
original batch sequence for every overflow path, and filter overflow
responses against the client's requested sequence.  The normal batch
walk remains unchanged; sequence lookups are confined to overflow
responses.

Cover both the default retention grace and the cross-index hard-link
case.  The latter persists a nonzero checkpoint, compacts through a
private index, and verifies repeated canonical reads do not rescan or
fall back to global invalidation.
The delayed-cookie tests send the v1 timestamp token "0" and only check
that the response is nonempty.  Both recovery and fallback can satisfy
that assertion with the same trivial response, so the tests do not
distinguish a rescued cookie from a token-generation reset.

Send a deterministic valid v2 token instead.  Verify that the 1200ms
case preserves its token generation without a global invalidation, while
the 2500ms case changes generation and sends the fallback invalidation.
215845a (fsmonitor: preserve authenticated proofs across ordinary
commands, 2026-08-15) enabled the clean-status history handoff for
merges, but excluded invocations where fast_forward was FF_NO.
Requested merge topology does not determine whether the resulting index
is semantically safe.  A clean non-fast-forward merge can carry the same
authenticated FSUC/FSCF state as a fast-forward merge.

As a result, --no-ff, --no-ff --no-commit, and merge.ff=false all
dropped FSUC and reduced the FSCF flags from 15 to 9 after a clean
merge.  Each subsequent read-only status invalidated the external
history and rescanned the semantic manifest.

Enable the handoff for every merge using the canonical index.  Conflict
handling still invalidates unsafe proofs, and explicit alternate indexes
remain excluded.  Cover all three non-fast-forward forms, repeated
read-only status calls, conflicts, and alternate indexes.
An exact clean status can repair a stale FSMonitor checkpoint or cached
stat data while it scans.  The repair requires an index write, so the
existing issue path leaves no clean sidecar behind.  Read-only callers
then repeat the full scan until a second writable exact status publishes
the proof.

After the repair is written and resumable history is durable, install a
sidecar bound to the rewritten index.  Keep optional-lock-disabled
commands read-only, preserve the literal exact-command restriction, and
do not extend sidecar support to linked worktrees.

Cover repeated read-only scans after a legacy daemon replacement, the
single writable index repair in main and linked worktrees, and the next
read-only sidecar hit in the main worktree.  Keep option-bearing status
commands ineligible for proof publication.
@ttaylorr-oai
ttaylorr-oai force-pushed the ttaylorr/codex-unstable-feedback-fixes branch from 7ccad93 to 6314bd1 Compare August 26, 2026 17:12
@ttaylorr-oai ttaylorr-oai changed the title fsmonitor: fix late cookies and preserve index history status: fix FSMonitor history and clean-proof gaps Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build:codex-unstable Preview Codex Git build codex:blocked Current state needs intervention before it can advance codex:draft Draft; no review action requested kind:review-only Reviewed topic; do not merge this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant