Hive Hive
Sign in

fix(infra): parse tart get’s string Size so the golden warm-path probe stops re-pulling

GitHub issue · Closed

Metadata
Source
tuist/tuist #11521
Updated
Jul 5, 2026
Domains
Compute
Details

What this fixes

The root cause of “the golden base re-materializes on every recycle” — found in production within minutes of the warm-path-miss logging from #11517 going live.

tart encodes a VM’s Size field inconsistently across subcommands:

  • tart list --format json"Size": 72 (integer)
  • tart get --format json"Size": "72.660" (quoted decimal string)

The Go VM struct declared Size int64, so json.Unmarshal of a tart get response errored on every call. Client.Get() returns that error, and ensureGolden treats any non-nil Get error as “golden absent” → cold path → full multi-GB re-pull. So the per-host golden was rebuilt on essentially every provision even though it was sitting on disk.

The asymmetry is why this was so hard to spot from metrics/static analysis: the GC and node-label path read tart list (integer Size) and parsed fine — goldens were correctly kept and advertised — while only the warm-path probe (tart get) failed. On-host, tart get <golden> “worked” when run by hand (I was reading the JSON myself); it’s the Go unmarshal that broke.

The new warm-path-miss log from #11517 surfaced it directly on the first updated host:

parse tart get tuist-golden-29a6ff6e...: json: cannot unmarshal string
into Go struct field VM.Size of type int64

The fix

Make Size a small custom type whose UnmarshalJSON accepts Tart’s integer, quoted-decimal, and bare-decimal forms (and null). Size is never read anywhere in the codebase — the type exists purely to keep VM unmarshal (and therefore Get) from failing on either encoding.

Impact

Once deployed, ensureGolden’s warm-path probe will actually find the on-disk golden, so recycles clone from it (APFS clonefile, no network) instead of re-pulling. This is the change that makes the golden-base scheme finally deliver: golden_base_reused_total should climb, golden_base_materialized_total should go flat, and provision delay should drop from minutes to seconds. (Combined with #11517, which already stopped the GC from deleting the cached OCI image and made the cold path cheap — verified on the fleet: OCI churn stopped, cached image now survives GC passes.)

Validation

  • go build, go vet, gofmt, full module test suite pass.
  • New TestVMUnmarshalSizeAcceptsListAndGetEncodings pins both real Tart encodings (72 and "72.660") plus quoted-integer and bare-decimal.

🤖 Generated with Claude Code

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments

No GitHub comments yet.