elastic / elastic/ai-github-actions

[autonomy-atomicity] Makefile compiler bootstrap writes shared binaries non-atomically

Open
#1,502 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
11
Forks
16
Avg merge
22h 9m
Merged PRs (30d)
31

Description

## Autonomy / Atomicity Findings

### 1. Shared gh-aw compiler binaries are updated in place during `make compile`
**Category:** Global state / Config hotspot
**File(s):** `Makefile`

**Problem:**
`make compile` depends on `setup-gh-aw` and `setup-gh-aw-compat`, then immediately executes the shared binaries from the repository-local `.bin/` directory. The release install path downloads directly into `.bin/gh-aw` and `.bin/gh-aw-compat`, and the non-release path writes/moves into the same shared paths before updating the corresponding version files.

Evidence:
- `Makefile:29-60` defines `download-file` and `install-gh-aw-from-release`; the release helper writes directly to the output path passed by the caller.
- `Makefile:140-147` creates `.bin`, checks `.bin/gh-aw` plus `.bin/.gh-aw-version`, then calls `install-gh-aw-from-release` with `.bin/gh-aw` as the final output path and writes `.bin/.gh-aw-version` afterward.
- `Makefile:155-160` installs non-release builds with `GOBIN="$(CURDIR)/.bin" go install ./cmd/gh-aw`, then writes `.bin/.gh-aw-version` afterward.
- `Makefile:166-187` repeats the same shared-path pattern for `.bin/gh-aw-compat` and `.bin/.gh-aw-compat-version`.
- `Makefile:193-199` then runs `.bin/gh-aw compile` and `.bin/gh-aw-compat compile` from those same shared paths.

When two agents or developers run `make compile` in the same checkout during a version bump or a cold bootstrap, both invocations can write the same compiler path concurrently, or one invocation can execute a binary while another invocation is replacing it. That creates a subtle, workspace-local race that is hard to diagnose and can make otherwise independent workflow changes fail or produce inconsistent generated output.

**Suggested fix:**
Make compiler bootstrap atomic and isolated. Install each compiler into a versioned temporary path under `.bin/` (for example `.bin/gh-aw-v0.80.9.tmp.`), verify it, then atomically `mv` it into a versioned final path or update a symlink under a `flock`-protected lock. Run `make compile` against the versioned executable path selected for that invocation, and update `.bin/.gh-aw-version` only after the executable is fully installed.

Duplicate check: this is distinct from the existing autonomy findings for the runtime setup fragment (#897), Makefile actionlint whitelist (#1319), fixed quick-setup branch name (#806), dogfood registries (#683), and duplicated workflow registries (#777). The other candidates from this run were not filed because the CI path-filter issue is already tracked by #1221 and the docs catalog/nav registry overlaps a prior finding (#560).

## Suggested Actions
- [ ] Install `gh-aw` and `gh-aw-compat` through versioned temporary files instead of writing directly to `.bin/gh-aw*`.
- [ ] Protect compiler installation/version-file updates with a lock or atomic symlink swap.
- [ ] Have `make compile` execute the resolved versioned compiler path for the current invocation instead of a mutable shared path.

---
[What is this?](https://ela.st/github-ai-tools) | [From workflow: Trigger Autonomy Atomicity Analyzer](https://github.com/elastic/ai-github-actions/actions/runs/28672904288)

Give us feedback! React with 🚀 if perfect, 👍 if helpful, 👎 if not.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.