Symptom
/update-gaia three-way merge silently fails to seed files when local (L) equals the baseline cache (B) but the original ancestor (A) was never present in the tracked tree. Because B==L, the merger treats it as "no upstream change" and skips, without detecting that A is absent. The skipped file therefore stays missing on disk despite being declared "owned" in .gaia/manifest.json and shipping in .gaia/cache/v<version>/. Downstream CI workflows that depend on the missing file break with no diagnostic from the merger.
Classification
class: update
evidence: "three-way merge" + .gaia/manifest.json
Capture
gaia_version: 1.3.3
node: v24.14.1
pnpm: 10.33.0
claude_code: 2.1.150
branch: chore/update-deps-2026-05-26-13-58
dirty: false
class_state_files:
- .gaia/manifest.json: present, version 1.3.3
- (conflicted paths): none — the failure is silent file-absence, not a merge conflict
Reproduction context
During a routine /update-deps run on a GAIA-managed project (v1.3.3), the resulting PR hit a code-review-audit CI failure unrelated to the dependency bump:
bash: .github/audit/check-trailer.sh: No such file or directory
##[error]Process completed with exit code 127.
Investigation showed that .github/workflows/code-review-audit.yml:141 runs bash .github/audit/check-trailer.sh, but .github/audit/ did not exist in the tracked tree. The script and its companion .bats test are declared "owned" in .gaia/manifest.json:150-151 and present in .gaia/cache/v1.3.3/.github/audit/. They had never been seeded into the project.
A prior manual remediation PR (chore: seed GAIA shared-class CI workflows) had named the underlying merger bug in its commit message — "/update-gaia three-way merge skipped them (B==L, no upstream change) without detecting that A was absent" — and seeded the workflow YAML manually. But that remediation was itself incomplete: it seeded .github/workflows/code-review-audit.yml without also seeding its companion helper script, leaving the workflow pointing at a non-existent file on every subsequent PR.
Expected behavior: /update-gaia should detect the case "file is owned in the manifest, present in the upstream baseline cache, but absent from the tracked tree" and seed it from the cache, regardless of whether B equals L. The current short-circuit on B==L assumes the file already exists in L, which is not guaranteed.
Suggested fix surface: the merger's per-file dispatch in /update-gaia. Before the B==L early-return path, check whether L actually has the file. If absent, fall through to a seed action (write B into L). This keeps the normal "no change" fast-path for files that do exist, while closing the silent-skip gap for files that don't.
Workaround used in the encountered case: manually copy the missing file(s) from .gaia/cache/v<installed-version>/<path> into the tracked tree and commit. Tedious because the symptom only surfaces when a downstream consumer (a workflow, a hook, a script) tries to use the missing file.
Symptom
/update-gaiathree-way merge silently fails to seed files when local (L) equals the baseline cache (B) but the original ancestor (A) was never present in the tracked tree. Because B==L, the merger treats it as "no upstream change" and skips, without detecting that A is absent. The skipped file therefore stays missing on disk despite being declared"owned"in.gaia/manifest.jsonand shipping in.gaia/cache/v<version>/. Downstream CI workflows that depend on the missing file break with no diagnostic from the merger.Classification
class: update
evidence: "three-way merge" + .gaia/manifest.json
Capture
gaia_version: 1.3.3
node: v24.14.1
pnpm: 10.33.0
claude_code: 2.1.150
branch: chore/update-deps-2026-05-26-13-58
dirty: false
class_state_files:
Reproduction context
During a routine
/update-depsrun on a GAIA-managed project (v1.3.3), the resulting PR hit acode-review-auditCI failure unrelated to the dependency bump:Investigation showed that
.github/workflows/code-review-audit.yml:141runsbash .github/audit/check-trailer.sh, but.github/audit/did not exist in the tracked tree. The script and its companion.batstest are declared"owned"in.gaia/manifest.json:150-151and present in.gaia/cache/v1.3.3/.github/audit/. They had never been seeded into the project.A prior manual remediation PR (
chore: seed GAIA shared-class CI workflows) had named the underlying merger bug in its commit message — "/update-gaia three-way merge skipped them (B==L, no upstream change) without detecting that A was absent" — and seeded the workflow YAML manually. But that remediation was itself incomplete: it seeded.github/workflows/code-review-audit.ymlwithout also seeding its companion helper script, leaving the workflow pointing at a non-existent file on every subsequent PR.Expected behavior:
/update-gaiashould detect the case "file isownedin the manifest, present in the upstream baseline cache, but absent from the tracked tree" and seed it from the cache, regardless of whether B equals L. The current short-circuit on B==L assumes the file already exists in L, which is not guaranteed.Suggested fix surface: the merger's per-file dispatch in
/update-gaia. Before the B==L early-return path, check whether L actually has the file. If absent, fall through to a seed action (write B into L). This keeps the normal "no change" fast-path for files that do exist, while closing the silent-skip gap for files that don't.Workaround used in the encountered case: manually copy the missing file(s) from
.gaia/cache/v<installed-version>/<path>into the tracked tree and commit. Tedious because the symptom only surfaces when a downstream consumer (a workflow, a hook, a script) tries to use the missing file.