Skip to content

Release 2.1.37 (2026-06-16)

Bug fixes

  • distinguish unreachable VM from spec drift in preflight (#1666)
  • fix(vm): distinguish unreachable VM from spec drift in preflight

vrg-vm session/start collapsed an SSH transport failure into the same None as a missing spec marker, so a VM that Lima reports Running but whose SSH connection is refused was misreported as 'no longer meets spec' with a wrong rebuild remediation.

read_fingerprint now masks the in-guest read (cat ... 2>/dev/null || true) so an absent marker yields empty stdout, leaving any shell round-trip failure as an unambiguous transport failure that raises VmUnreachableError. vm_spec_status grows a third state, 'unreachable', and _preflight_target / _st_spec_check handle it with a reachability message (restart, not rebuild) instead of a spec-drift one.

  • style(vm): collapse read_fingerprint shell_run call onto one line

ruff format normalization of the masked in-guest read introduced in the preceding fix; no behavior change.

Documentation

  • add vergil-forge observability design (#1661) (#1662) Co-located Prometheus + Grafana stack inside the vergil-forge VM. v1 covers infra (node_exporter + cAdvisor), Postgres internals (the parallel-agent write-concurrency wager made visible), and Forgejo native metrics, in one layered Grafana tab. Carries the mq-cluster-tooling observability DNA (provisioned-as-code, fail-loud, layered dashboard) while dropping its multi-node renderer and separate-observer machinery. Durable host-mounted TSDB with bounded retention. Pipeline, AI-gate, and Loki layers are named and contract-sketched but deferred. Ref #1653.

Features

  • derive the Claude marketplace ref from the vergil.toml version (#1663)
  • docs(specs): add design spec for version-derived Claude marketplace ref (#1654)

Capture the design for treating the Claude plugin marketplace ref as a version-derived reference on equal footing with workflow pins: written by VergilUpdater, asserted by the repo_config audit, with the plugin repo exempt to develop. Refs #1654.

  • docs(specs): add implementation plan for version-derived Claude marketplace ref (#1654)

Phased TDD plan: shared vergil_refs derivation module, JSON-aware normalize_claude_ref writer wired into VergilUpdater, unified repo_config audit (marketplace ref + workflow pins), repo_init seeding, a blocking moving-tag refresh smoke test, and the per-repo fleet sweep. Refs #1654.

  • feat(deps): add shared vergil ref derivation helpers (#1654)

  • refactor(deps): source vergil ref derivation from shared module (#1654)

  • feat(deps): add JSON-aware claude marketplace ref writer (#1654)

  • feat(deps): normalize claude marketplace ref in VergilUpdater (#1654)

  • feat(audit): assert claude marketplace ref matches vergil.toml (#1654)

  • feat(audit): assert workflow pins match vergil.toml (#1654)

  • feat(init): seed claude marketplace ref from vergil version (#1654)

  • chore(lint): satisfy ruff lint/format and complete branch coverage (#1654)

Reorder vergil_eco imports, move Path to TYPE_CHECKING in the new test, apply ruff format across the touched files, and add two normalize_claude_ref edge-case tests (missing marketplace entry, non-dict source) to restore 100% branch coverage. Refs #1654.

  • borrow another repo's VM via [vm] shared_from (#1669)
  • docs(specs): add vm shared-from borrowing design

Design for a [vm] shared-from key letting one repo borrow another repo's identity-VM: vrg-vm session redirects instance + spec to the lender while the working directory stays on the borrower's checkout. Covers config schema, mutual exclusivity, USE/MANAGE command policy, and edge cases (chains, self-reference, missing lender). Refs #1668.

  • docs(plans): add vm shared-from implementation plan

TDD task breakdown for the [vm] shared_from borrowing feature: config parsing + validation, borrow resolution helpers, USE redirect for session/start, MANAGE block for create/stop/restart/update/destroy/rebuild, docs, and validation. Refs #1668.

  • feat(config): parse and validate [vm] shared_from

Add VmStanza.shared_from (org, repo), parsed from a fully-qualified 'org/repo' string. Mutually exclusive with every other [vm] key and rejected inside role overlays. Refs #1668.

  • feat(vm): add borrow resolution helpers for [vm] shared_from

Add BorrowError, Borrow, _read_repo_vm, resolve_borrow, and _borrow_block_msg. resolve_borrow turns a borrowing repo into its lender and rejects self-reference, chains, and a lender with no VM. Refs #1668.

  • feat(vm): redirect session/start to the lender VM on [vm] shared_from

When the requested repo borrows a VM, _resolve_target with borrow_allowed=True resolves the instance, spec, fingerprint, and host override to the lender. session and start pass borrow_allowed=True. The session working directory still derives from args.workspace. Refs #1668.

  • feat(vm): block manage commands on a borrowing repo

create, stop, restart, update, destroy, and rebuild raise BorrowError when the requested repo borrows a VM, pointing the user at the lender. main() catches BorrowError and exits 1. Refs #1668.

  • docs(vm): document [vm] shared_from borrowing

Add the shared_from key to the VM spec reference and align the design spec with the underscore key name (shared_from) and the implemented exception name (BorrowError). Refs #1668.

  • chore(vm): satisfy validation for [vm] shared_from

Fixups from vrg-validate: annotate eff_vm as VmStanza | None (mypy), match the document's asterisk emphasis style in the shared_from keys-table row (markdownlint MD049/consistent), and apply ruff format to the new config tests. Refs #1668.