LearnNewsExamplesServices
Frontmatter
titletest: cover lease guard contention diagnostics
authortomatotomata
stateMerged
createdAtAug 8, 2026, 11:49 AM
updatedAtAug 8, 2026, 3:46 PM
closedAtAug 8, 2026, 3:45 PM
mergedAtAug 8, 2026, 3:45 PM
branchesdevcodex/lease-contention-tests
urlhttps://github.com/neomjs/neo/pull/16670
contentTrust
projected
quarantined0
signals[]
Merged
tomatotomata
tomatotomata commented on Aug 8, 2026, 11:49 AM

Summary

  • Add independent async and sync release and renewal tests for the four lifecycle-guard contention paths from #16632.
  • Hold the real lifecycle guard, assert the diagnostic contains the guard path, and release the guard in finally.
  • Keep production code unchanged. The test-only filesystem seam normalizes Windows EPERM to the POSIX-equivalent EEXIST when an atomic rename targets the held guard directory.

Verification

  • Red control: temporarily removing lifecycleGuardPath from the production import made all four new tests fail with lifecycleGuardPath is not defined.
  • Focused run: all four #16632 tests passed after restoring the import.
  • Owning spec: 42 passed and 7 existing lifecycle-guard recovery tests failed on Windows with EPERM during atomic directory rename. The failures are outside this change and reproduce in the existing spec paths.
  • Pre-commit checks passed, including parse, whitespace, shorthand, JSDoc, ticket archaeology, block alignment, and AI-config mutation checks.

AI assistance was used to help implement and verify this contribution; the final scope and changes are mine.

neo-opus-grace
neo-opus-grace commented on Aug 8, 2026, 12:12 PM

Thanks @tomatotomata — and an apology first: #16632 was never actually assigned to you. I told you in the issue that it was yours and then did not record it, so for the whole time you were building, the backlog showed it unclaimed and another contributor could have started the same work. That is my mistake, not an ambiguity in what we agreed. Assigned now.

Two process notes, both on us rather than on you:

  1. Drafts do not get reviewed here. It is a local convention rather than anything you could have known: our reviewers pick up PRs by review state, so a draft sits untouched indefinitely. When you want eyes on it, mark it Ready for review and it enters the queue. Nothing about the content needs to change for that.

  2. Your PR body already carries the thing that decides whether this work counts:

    Red control: temporarily removing lifecycleGuardPath from the production import made all four new tests fail with lifecycleGuardPath is not defined.

    That is the AC I flagged as the one that matters, and running it is what separates real coverage from four tests that would have passed against the original ReferenceError. Recording that you did it, in the PR body, is exactly right.

One thing I want to look at properly when you mark it ready — not a request to change anything yet:

The test-only filesystem seam normalizes Windows EPERM to the POSIX-equivalent EEXIST when an atomic rename targets the held guard directory.

That is a real platform difference and I would rather understand your seam than have you guess at our preference. Two questions when you get there: does the normalization apply only inside your four tests, or to the whole spec file — and does the guard's own production code path distinguish those codes anywhere? If it does, the normalization could mask a genuine difference rather than paper over an irrelevant one. Possibly it is fine; I have not read the diff yet and am not going to pre-judge it from a summary.

The 7 pre-existing Windows EPERM failures you reported in the existing lifecycle-guard recovery tests are worth their own issue, and that one is ours to file rather than yours to fix. Our CI is Linux, so you found something none of us would have.

Disclosing the AI assistance is appreciated and is the norm here, not a caveat — most of the commits in this repository carry the same disclosure.


Grace (Opus 5, Claude Code), maintainer.


neo-opus-vega
neo-opus-vega APPROVED reviewed on Aug 8, 2026, 2:46 PM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: Test-only, in scope, and red-controlled. It closes the coverage half of #16632 without touching production, which is the correct boundary for this change. My one substantive finding is a pre-existing production defect this PR surfaced, not one it introduced — asking a contributor to fix a portability bug inside a coverage PR would be scope-shifting onto the wrong person. I am taking that finding as maintainer work.

Peer-Review Opening: Thanks for this — the red control is the part that makes it reviewable rather than merely plausible, and reporting the seven pre-existing Windows failures instead of quietly working around them is exactly the right instinct. It turns out that observation is more important than the coverage, and I explain why below.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: #16632's framing, the diff, ai/daemons/shared/lifecycleGuard.mjs:86-98, the EEXIST handling across lifecycleGuard.mjs / fileLease.mjs / heavyMaintenanceLeasePrimitives.mjs, and this repo's Windows-support posture.
  • Expected Solution Shape: Four independent tests that hold the real guard, assert the diagnostic names the contended path, and release in finally — with production untouched and no shared-state leakage between tests.
  • Patch Verdict: Matches. Each test holds the real guard rather than a mock, and the finally release keeps them independent — which matters here because a leaked guard would make the next test pass for the wrong reason.
  • Premise Coherence: Coheres — verify-before-assert. The red control (removing lifecycleGuardPath from the production import, all four failing with lifecycleGuardPath is not defined) establishes the tests can fail, which is the property most new tests never demonstrate.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: #16632 (the body references it in prose rather than with a closing keyword — see Required Actions note)
  • Related Graph Nodes: lifecycleGuard.mjs, heavyMaintenanceLeasePrimitives.mjs, learn/agentos/tooling/WindowsSupport.md
  • Origin Session ID: 4141258c-36d3-4788-b0c2-ab3ebe0867be

🔬 Depth Floor

Challenge — and it is the reason this review took longer than the diff deserves. Your seam normalizes Windows EPERMEEXIST when the rename target exists. That is a defensible test-only shim, and the guard on fs.pathExistsSync(args[1]) correctly scopes it to the contention case. But production does not perform that normalization, and does not handle EPERM at all.

ai/daemons/shared/lifecycleGuard.mjs:95-97:

if (e.code !== 'EEXIST' && e.code !== 'ENOTEMPTY' && e.code !== 'ENOTDIR') {
    throw e;
}

EPERM is not in that set, so on Windows a contended guard throws instead of falling through to the "guard held by someone, observe its identity artifacts and defer" path at :100. The same three-code test repeats at :212.

So the seven pre-existing Windows failures you reported are not incidental to your change — they are that defect's live symptom, and your normalization is what lets the four new tests pass on a platform where the production path they cover would crash. The tests become green on Windows; the behaviour does not.

This is not a required change to your PR. It is pre-existing, it is production, and your PR explicitly and correctly keeps production unchanged. I am recording it here so the seam is never later read as a harmless platform detail, and I am taking the production fix as maintainer work rather than routing it to you.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description: framing matches the diff — "keep production code unchanged" is literally true, one test file
  • Anchor & Echo summaries: the seam comment states the platform difference mechanically
  • [RETROSPECTIVE] tag: N/A — none claimed
  • Linked anchors: #16632 does describe the four unreachable contention paths this covers

Findings: Pass. The AI-assistance disclosure is appreciated and correctly scoped ("the final scope and changes are mine").


🧠 Graph Ingestion Notes

  • [RETROSPECTIVE]: A test-only compatibility shim silently converts a platform behaviour difference into a platform test difference. The shim here is correct in isolation and still hides a real gap, because the normalization exists only on the test side of a boundary production also crosses. The transferable check: when a fixture normalizes an error code, grep production for that code before concluding the normalization is cosmetic — if production does not handle the raw code, the fixture is not adapting to the platform, it is masking it.

N/A Audits — 📑 📡 🪜

N/A across listed dimensions: no consumed contract surface, no OpenAPI, and the ACs are covered by the tests themselves with no runtime-effect residual.


🎯 Close-Target Audit

  • Close-targets identified: none as a magic keyword; the body references #16632 in prose
  • For each #N: N/A — no closing keyword present, so nothing auto-closes

Findings: Pass, with a note under Required Actions.


🧪 Test-Evidence & Location Audit

  • Execution evidence: red control (all four fail with lifecycleGuardPath is not defined), focused green run, and the owning spec's 42 passes plus an honest report of 7 pre-existing Windows failures attributed outside the change
  • Reviewer falsifier: run — see below
  • Test location: pass; the spec sits with its existing siblings under unit/ai/daemons/orchestrator/services/

Reviewer falsifier. My named concern was that the four tests might pass by exercising the shim rather than the guard. I checked the production error-handling set that the tests' diagnostic path depends on, and found the EPERM gap above — which confirms the tests exercise the real contention branch on POSIX (the codes match) and fails the platform-parity assumption on Windows. Both halves are informative: the coverage is real where the codes align, and the seam is load-bearing where they do not.

Findings: Pass.


📋 Required Actions

No required actions — eligible for human merge.

Two optional notes, neither blocking:

  • Consider adding Resolves #16632 (or Refs #16632) to the body so the graph links this to its ticket; prose references do not create the edge.
  • If you want the seam to carry its own warning, one clause noting that production handles EEXIST/ENOTEMPTY/ENOTDIR but not EPERM would stop a later reader treating the normalization as cosmetic. Entirely optional — the finding is recorded in this review either way.

📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 90 - Correct boundary: real guard, real diagnostic, production untouched, shim confined to the test's own fs seam.
  • [CONTENT_COMPLETENESS]: 92 - All four contention paths covered async and sync, each independent, each released in finally.
  • [EXECUTION_QUALITY]: 94 - The red control and the honest pre-existing-failure report are both above the bar for a first-time contribution, and above the bar generally.
  • [PRODUCTIVITY]: 90 - +108/-0 in one file for four previously untestable paths.
  • [IMPACT]: 85 - Closes #16632's coverage half, and surfaces a production portability defect that was invisible until someone ran it on Windows.
  • [COMPLEXITY]: 30 - One spec file; the fs seam is the only subtle part.
  • [EFFORT_PROFILE]: Quick Win - Small, well-controlled test addition.

Merge is @tobiu's gate, not mine. Thanks again for the Windows report — it is the most valuable thing in this PR and it is not the part you were aiming at.

🌿


tomatotomata
tomatotomata commented on Aug 8, 2026, 3:41 PM

Thanks, I read this carefully. I marked the PR ready for review. Your read of the Windows seam is right: the normalization is confined to these four tests, while production still lacks the EPERM handling and the seven existing failures expose that separate portability defect. I kept that out of this coverage PR and recorded it as maintainer work. The red-control evidence and the four focused green tests remain unchanged.


tobiu
tobiu commented on Aug 8, 2026, 3:46 PM

@tomatotomata Thanks, and welcome to the contributors list 🎉