ruvnet/ruflo · error

Git-visible source state changed before build evidence recom

Error message

Git-visible source state changed before build evidence recomputation

What it means

recomputeBuildEvidence first re-captures the repository source state and requires it to equal expected.sourceStateId — the id recorded when the evidence was created. If the repo has changed in any git-visible way since (commits, edited tracked files, changed untracked content), recomputation refuses to proceed because the stored evidence no longer describes these bytes.

Source

Thrown at v3/@claude-flow/codex/src/harness/build-evidence.ts:183

  const tools = toolchains.map((declaration): DeclaredToolchain => ({
    name: declaration.name,
    version: declaration.version,
    digest: digestPath(
      isAbsolute(declaration.path) ? declaration.path : resolve(repoRoot, declaration.path),
      true,
    ).digest,
  }));
  return createBuildEvidence(sourceState, inputs, tools);
}

export function recomputeBuildEvidence(
  repoPath: string,
  expected: BuildEvidence,
  toolchains: readonly ToolchainDeclaration[],
): BuildEvidence {
  const sourceState = captureRepositorySourceState(repoPath);
  if (sourceState.sourceStateId !== expected.sourceStateId) {
    throw new Error('Git-visible source state changed before build evidence recomputation');
  }
  return captureBuildEvidence(
    repoPath,
    sourceState,
    expected.buildInputs.map(({ name, path }) => ({ name, path })),
    toolchains,
  );
}

export function buildEvidenceMatches(expected: BuildEvidence, actual: BuildEvidence): boolean {
  return expected.evidenceDigest === actual.evidenceDigest
    && expected.sourceStateId === actual.sourceStateId;
}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Reproduce the exact source state first: check out the bound commit and restore tracked/untracked bytes the evidence recorded (git stash/clean/checkout as needed)
  2. If the current state is what you want to attest, re-create evidence from scratch with captureBuildEvidence instead of recomputing stale evidence
  3. Run recomputation against an isolated snapshot of the repo so nothing can mutate it in between

Example fix

// before
const evidence = recomputeBuildEvidence(repoPath, evidenceFromYesterday, tools); // repo moved on

// after
const fresh = captureRepositorySourceState(repoRoot);
const evidence = captureBuildEvidence(
  repoPath,
  fresh,
  evidenceFromYesterday.buildInputs.map(({ name, path }) => ({ name, path })),
  tools,
);
Defensive patterns

Strategy: retry

Validate before calling

import { captureRepositorySourceState } from './harness/repository-state.js';
const current = captureRepositorySourceState(repoRoot);
if (current.sourceStateId !== expected.sourceStateId) {
  // decide before calling: restore the expected state, or rebuild evidence from current
}

Try / catch

try { return recomputeBuildEvidence(repoPath, expected, tools); } catch (error) { if (error instanceof Error && error.message.includes('Git-visible source state changed')) { const fresh = captureRepositorySourceState(repoPath); return captureBuildEvidence(repoPath, fresh, expected.buildInputs.map(({ name, path }) => ({ name, path })), tools); } throw error; }

Prevention

When it happens

Trigger: Calling recomputeBuildEvidence after new commits or file edits relative to when expected was produced; verifying evidence created on a different machine or checkout whose dirty state differs; a verification step that runs after tooling mutated the tree (npm install updating a lockfile, a formatter).

Common situations: CI pipelines where a prepare step touches files between build and verification; local verification runs after a formatter or npm install mutated the tree; verifying evidence produced on a different machine or branch.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/17b1b48664441df8. Report an issue: GitHub.