{"record":{"id":"e0f1c8cd7cdf8fba","repo":"Yeachan-Heo/oh-my-codex","slug":"refusing-durable-ultragoal-mutation-after-writable","errorCode":null,"errorMessage":"Refusing durable ultragoal mutation after writable lifecycle authority drift while waiting for the mutation lock: before lock ${describeWritableAuthority(beforeLock)}; after lock ${describeWritableAuthority(afterLock)}.","messagePattern":"Refusing durable ultragoal mutation after writable lifecycle authority drift while waiting for the mutation lock: before lock (.+?); after lock (.+?)\\.","errorType":"exception","errorClass":"UltragoalError","httpStatus":null,"severity":"critical","filePath":"src/ultragoal/artifacts.ts","lineNumber":964,"sourceCode":"      handle = await open(lockPath, 'wx');\n      await handle.writeFile(JSON.stringify({ pid: process.pid, createdAt: iso() }));\n      break;\n    } catch (error) {\n      const code = (error as NodeJS.ErrnoException).code;\n      if (code !== 'EEXIST') throw error;\n      await sleep(Math.min(25 + attempt * 5, 250));\n    }\n  }\n  if (!handle) {\n    throw new UltragoalError(`Timed out waiting for ultragoal mutation lock at ${repoRelative(cwd, lockPath)}.`);\n  }\n  try {\n    // The post-lock comparison addresses pointer changes while waiting for this\n    // lock only. A SessionStart publication can still land after it and before\n    // the operation's filesystem writes.\n    const afterLock = await assertUltragoalWritableLifecycleAuthority(cwd, options);\n    if (!writableAuthorityEquals(beforeLock, afterLock)) {\n      throw new UltragoalError(\n        `Refusing durable ultragoal mutation after writable lifecycle authority drift while waiting for the mutation lock: before lock ${describeWritableAuthority(beforeLock)}; after lock ${describeWritableAuthority(afterLock)}.`,\n      );\n    }\n    return await operation();\n  } finally {\n    await handle.close().catch(() => undefined);\n    await rm(lockPath, { force: true }).catch(() => undefined);\n  }\n}\n\nasync function appendLedger(cwd: string, entry: UltragoalLedgerEntry): Promise<void> {\n  await mkdir(ultragoalDir(cwd), { recursive: true });\n  const path = ultragoalLedgerPath(cwd);\n  await appendFile(path, `${JSON.stringify(entry)}\\n`);\n}\n\n/** Pure plan read: no durable writes, no migration. */\nasync function readUltragoalPlanFile(cwd: string): Promise<UltragoalPlan> {","sourceCodeStart":946,"sourceCodeEnd":982,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/ultragoal/artifacts.ts#L946-L982","documentation":"Before and after acquiring the mutation lock, the library snapshots the writable lifecycle authority (session binding). If they differ, a session publication (e.g. SessionStart) landed while this process waited for the lock, and the mutation would write into state whose ownership just changed — so it refuses with both before/after snapshots for diagnosis. This is a deliberate TOCTOU guard preserving durable-state integrity.","triggerScenarios":"A process acquires the mutation lock after waiting, and assertUltragoalWritableLifecycleAuthority returns a different authority than the pre-lock snapshot — typically because a concurrent SessionStart publication rewrote session.json/OMX_SESSION_ID authority in the gap between the two checks.","commonSituations":"Two sessions starting simultaneously against the same repo; a new bench bootstrapping (publishing SessionStart) while an old one is mid-mutation; orchestration scripts restarting agents without coordinating with in-flight ultragoal writes.","solutions":["Retry the whole mutation after re-reading the current session binding (export the new OMX_SESSION_ID) — the drift is usually a legitimate session rotation","Coordinate process lifecycle: do not start/restart sessions while ultragoal mutations are in flight (barrier or queue around SessionStart)","Inspect the before/after snapshots in the message to confirm which side is authoritative, then align the environment to it","If drift recurs, check for two competing session publishers (duplicate orchestrators) writing session.json"],"exampleFix":"// before\nawait appendStory(state, goal); // another session published while we waited -> refused\n\n// after\nawait refreshSessionBinding(); // re-read session.json -> OMX_SESSION_ID\nawait appendStory(state, goal); // now consistent under current authority","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isAuthorityDriftError(e: unknown): boolean {\n  return e instanceof UltragoalError && e.message.includes('authority drift while waiting for the mutation lock');\n}","tryCatchPattern":"try {\n  return await mutateUltragoalState(...);\n} catch (e) {\n  if (isAuthorityDriftError(e)) {\n    await refreshSessionBinding(); // align OMX_SESSION_ID to the 'after lock' snapshot in the message\n    return mutateUltragoalState(...); // safe: pre-lock check re-runs under new authority\n  }\n  throw e;\n}","preventionTips":["Do not start/restart sessions while ultragoal mutations are in flight; use a barrier","Retry once after re-reading the session binding — drift usually reflects a legitimate rotation","Ensure only one orchestrator publishes sessions per repo to avoid competing SessionStart writers"],"tags":["ultragoal","session","race-condition","toctou","state-integrity"],"backgroundTag":"session-rotation-race","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}