Skip to content

Release 2.1.102 (2026-07-02)

Bug fixes

  • exclude release-tracking issues from roadmap/activity-log/audit (#2089)
  • fix(reporting): exclude release-tracking issues from roadmap/activity-log/audit

Release-tracking issues (release: X.Y.Z, marked by the checklist block) are vrg-release bookkeeping, not epic/task work, and must never appear in the epic/task observability outputs. Previously vrg-epic-audit flagged an open release issue behind a merged release PR as task-drift (e.g. vergil-containers#373 during the migration), and a closed release issue would surface in the activity-log ledger.

Add is_release_tracking_issue(title, body) to lib/release — body checklist marker primary, release: X.Y.Z title secondary — and filter it out in three reporting paths: activity_log.gather (ledger), epic_audit.task_drift (the merged-PR/open-task audit), and roadmap.gather (defense in depth; also covers epic_drift, which reads the same gather). The task-drift issue view now fetches title/body alongside state to classify the tracking issue.

  • test(reporting): cover unexpected issue-view shape in task-drift; wrap long line

Restore the multi-line TaskDrift construction to satisfy ruff (E501/format) and add a test exercising the defensive guard where gh issue view returns a non-object, so epic_audit stays at 100% coverage.

  • retry transient IAP/SSH transport-connect failures (#1992) (#2091) A burst of short-lived IAP tunnels (readiness + credentials + tooling) can trip a Google-side IAP backend blip ("4003: failed to connect to backend", ssh exit 255) that clears in seconds. The post-readiness stages (credentials, tooling, bootstrap-volume) called the transport with no retry, so one blip aborted a multi-minute rebuild. Reproduced as ~2/16 parallel IAP connects failing against a demonstrably healthy box (sshd NRestarts=0, no SYN-flood, no listen-drops) — the failure is in the IAP tunnel layer, not the guest.

Add bounded exponential-backoff retry (keyed on exit 255 only) in the off-platform transports' run/pipe, shared by IapTransport and SshTransport. quiet probe callers (the readiness gate, which owns its own poll loop) opt out so their boot-race cadence is unchanged. A real remote-command failure (any non-255 exit) is never retried (no-silent-failures).

  • retry transient IAP connect failures on cloud spec-fingerprint read (#2092)
  • fix(vm): retry transient IAP connect failures on cloud spec-fingerprint read

await_readiness's fingerprint read caught every CalledProcessError and reported it as a missing/unreadable marker ("rebuild the VM"), including an exit-255 IAP connect blip (4003) that commonly hits the single cat call right as cloud-init finishes and sshd restarts. The box is healthy; the transport just failed to connect for that one command.

Extract the read into _read_fingerprint, which mirrors _wait_for_ssh: retry exit-255 connect failures on the same bounded cadence/timeout while emitting a heartbeat, and reserve the unreadable-marker error for a command that actually ran and exited nonzero (exit != 255). The fingerprint-mismatch path is unchanged.

  • style(vm): normalize test line wrapping to satisfy ruff format

ruff format collapses the monkeypatch call in the new fingerprint-read timeout test onto a single line; apply it so vrg-validate's format check passes.

Chores

  • default new-repo license to MIT (#2090) Standing decision (2026-06-30): new repos use MIT, not GPL-3.0. Changes the vrg-github-repo-init wizard default: the RepoInitContext.license_type field default and the License prompt default are now MIT, and MIT leads the options list. No repo-config audit expects a specific license (the remaining GPL references are dependency-license allowlists), so nothing else to reconcile. Existing repos are not retroactively relicensed. Ref vergil-project/vergil-tooling#1990.