Finish the Go forge cutover: close the snapshot drift, then deploy and retire the bash tool #155

Closed
opened 2026-08-24 21:09:12 +01:00 by allod-agent · 5 comments
Member

Bring the Go forge up to the bash tool's current command surface and finish deploying it, so the Phase 1 cutover can land without removing a command that dev VMs already depend on.

Primary goals:

  • Close the drift — port forge pr snapshot and its scenario tests to Go so both implementations expose the same command surface.
  • Unblock the cutover — resolve the flake.lock conflict on allod/archetypes#40 so it merges onto current master.
  • Deploy and verify on dev VMs — advance the archetypes pin in allod/deploy, rebuild, and record the acceptance witness.
  • Deploy and verify on the host — merge the nexus cutover and advance the archetypes nexus pin.
  • Retire the bash tool — delete the bash forge and its shell suite once both cutovers are deployed.

Current state

The Go implementation merged in allod/tools#145 and is inert: every machine still runs the bash tool, whose store path is a writeShellApplication output rather than a versioned buildGoModule one. Both cutover pull requests are open and unmerged — allod/archetypes#40 for dev VMs and allod/nexus#25 for the host.

Since that merge, three commits extended the bash tool and were never mirrored into Go: 0e768fb added stable pull request snapshots, 44d9347 bound snapshot URLs to the repository identity they claim, and 9e4b157 normalized AGit-created head refs. The result is a real gap: forge pr snapshot <number> exists in bash with a 126-line tests/forge/snapshot.sh, and cmd/forge/ contains no snapshot implementation, so forge --help itself now differs between the two.

This is not cosmetic. allod pr explain is built on snapshots: pr-explain/explain resolves and verifies one per run, and pr-explain/validate-report consumes snapshot.json. Merging the cutover as it stands would remove forge pr snapshot from every dev VM and break the PR explanation tool. The dev plan already anticipated this class of drift by requiring mid-migration bash fixes to be mirrored into the Go scenario matrix; that did not happen here because the port had already merged.

The only two consumers reading the bash file are archetypes/modules/dev-home-shared.nix:34 and nexus/nix/home.nix:27, both replaced by the cutover pull requests, so nothing references it once they merge. One resolution path needs checking at deletion time: pr-explain/lib.sh:37 prefers the forge sitting beside the resolved tools root and only then falls back to PATH.

Sequence

  1. Port forge pr snapshot to Go, including the repository-identity and AGit head-ref behavior from the two follow-up commits, port tests/forge/snapshot.sh, and regenerate the frozen usage text in cmd/forge/usage.go from the current bash tool.
  2. Merge current master into agent/forge-go-cutover in allod/archetypes to resolve the flake.lock conflict, then merge allod/archetypes#40.
  3. Advance the archetypes input in allod/deploy, rebuild dev VMs, and confirm the deployed binary resolves to a versioned Go package with its wrapper beside it.
  4. Merge allod/nexus#25 and advance the archetypes nexus pin, then rebuild the host and run the host-side smoke check. Once that pin carries the wrapper, the archetypes wrapper commit and the nexus pin roll back together.
  5. Delete the bash forge and tests/forge/*.sh, confirm the pr-explain PATH fallback still resolves, refresh docs/forge.md where it describes behavior specific to the shell implementation, and close allod/tools#144, whose bug disappears with the bash tool.

Further forge changes landing in bash before step 3 completes must mirror into the Go implementation and its tests within the same pull request, otherwise the cutover reintroduces exactly this gap.

Scope

In scope: the snapshot port and usage regeneration, the cutover merges and pin advances, post-rebuild acceptance, and the Phase 4 deletion for forge only.

Out of scope and tracked separately: Phase 2 (allod) and Phase 3 (flake tools) of allod/tools#98; retiring the bash quirks the port replicated deliberately, which are individual interface decisions for after the bash tool is gone; adding the git wrapper to the tools dev flake so a local nix build matches the deployed binary; and narrowing src for the Go package so an unrelated commit to this repository does not rebuild forge on every machine.

Part of allod/tools#98.

Bring the Go `forge` up to the bash tool's current command surface and finish deploying it, so the Phase 1 cutover can land without removing a command that dev VMs already depend on. Primary goals: - **Close the drift** — port `forge pr snapshot` and its scenario tests to Go so both implementations expose the same command surface. - **Unblock the cutover** — resolve the `flake.lock` conflict on allod/archetypes#40 so it merges onto current master. - **Deploy and verify on dev VMs** — advance the `archetypes` pin in `allod/deploy`, rebuild, and record the acceptance witness. - **Deploy and verify on the host** — merge the nexus cutover and advance the archetypes `nexus` pin. - **Retire the bash tool** — delete the bash `forge` and its shell suite once both cutovers are deployed. ### Current state The Go implementation merged in allod/tools#145 and is inert: every machine still runs the bash tool, whose store path is a `writeShellApplication` output rather than a versioned `buildGoModule` one. Both cutover pull requests are open and unmerged — allod/archetypes#40 for dev VMs and allod/nexus#25 for the host. Since that merge, three commits extended the bash tool and were never mirrored into Go: `0e768fb` added stable pull request snapshots, `44d9347` bound snapshot URLs to the repository identity they claim, and `9e4b157` normalized AGit-created head refs. The result is a real gap: `forge pr snapshot <number>` exists in bash with a 126-line `tests/forge/snapshot.sh`, and `cmd/forge/` contains no snapshot implementation, so `forge --help` itself now differs between the two. This is not cosmetic. `allod pr explain` is built on snapshots: `pr-explain/explain` resolves and verifies one per run, and `pr-explain/validate-report` consumes `snapshot.json`. Merging the cutover as it stands would remove `forge pr snapshot` from every dev VM and break the PR explanation tool. The dev plan already anticipated this class of drift by requiring mid-migration bash fixes to be mirrored into the Go scenario matrix; that did not happen here because the port had already merged. The only two consumers reading the bash file are `archetypes/modules/dev-home-shared.nix:34` and `nexus/nix/home.nix:27`, both replaced by the cutover pull requests, so nothing references it once they merge. One resolution path needs checking at deletion time: `pr-explain/lib.sh:37` prefers the `forge` sitting beside the resolved tools root and only then falls back to PATH. ### Sequence 1. Port `forge pr snapshot` to Go, including the repository-identity and AGit head-ref behavior from the two follow-up commits, port `tests/forge/snapshot.sh`, and regenerate the frozen usage text in `cmd/forge/usage.go` from the current bash tool. 2. Merge current master into `agent/forge-go-cutover` in allod/archetypes to resolve the `flake.lock` conflict, then merge allod/archetypes#40. 3. Advance the `archetypes` input in `allod/deploy`, rebuild dev VMs, and confirm the deployed binary resolves to a versioned Go package with its wrapper beside it. 4. Merge allod/nexus#25 and advance the archetypes `nexus` pin, then rebuild the host and run the host-side smoke check. Once that pin carries the wrapper, the archetypes wrapper commit and the `nexus` pin roll back together. 5. Delete the bash `forge` and `tests/forge/*.sh`, confirm the `pr-explain` PATH fallback still resolves, refresh `docs/forge.md` where it describes behavior specific to the shell implementation, and close allod/tools#144, whose bug disappears with the bash tool. Further forge changes landing in bash before step 3 completes must mirror into the Go implementation and its tests within the same pull request, otherwise the cutover reintroduces exactly this gap. ### Scope In scope: the snapshot port and usage regeneration, the cutover merges and pin advances, post-rebuild acceptance, and the Phase 4 deletion for `forge` only. Out of scope and tracked separately: Phase 2 (`allod`) and Phase 3 (flake tools) of allod/tools#98; retiring the bash quirks the port replicated deliberately, which are individual interface decisions for after the bash tool is gone; adding the `git` wrapper to the tools dev flake so a local `nix build` matches the deployed binary; and narrowing `src` for the Go package so an unrelated commit to this repository does not rebuild `forge` on every machine. Part of allod/tools#98.
Author
Member

Phase 1 implementation is ready in allod/tools#156.

It ports forge pr snapshot and all 19 Bash snapshot scenarios into Go, preserves the fail-closed URL/repository/ref/object-ID checks, and passed Go tests/vet, every Bash forge suite, nix build, nix flake check, and a live byte-for-byte snapshot comparison against Forgejo.

Human gate: #156 needs review and merge before either cutover is refreshed. After it merges, the remaining sequence is:

  1. merge current allod/archetypes master into allod/archetypes#40, refresh its allod-tools pin to the merged rev, and rerun the snapshot/package checks;
  2. refresh the host-side consumer pin for allod/nexus#25;
  3. have a human rebuild a dev VM and the host, then verify forge pr snapshot on each;
  4. retire the Bash command/source only after both deployed binaries pass.

I have not advanced the cutover pins to the unmerged tools commit, so the rollback path remains unchanged.

Phase 1 implementation is ready in allod/tools#156. It ports `forge pr snapshot` and all 19 Bash snapshot scenarios into Go, preserves the fail-closed URL/repository/ref/object-ID checks, and passed Go tests/vet, every Bash forge suite, `nix build`, `nix flake check`, and a live byte-for-byte snapshot comparison against Forgejo. Human gate: #156 needs review and merge before either cutover is refreshed. After it merges, the remaining sequence is: 1. merge current `allod/archetypes` master into allod/archetypes#40, refresh its `allod-tools` pin to the merged rev, and rerun the snapshot/package checks; 2. refresh the host-side consumer pin for allod/nexus#25; 3. have a human rebuild a dev VM and the host, then verify `forge pr snapshot` on each; 4. retire the Bash command/source only after both deployed binaries pass. I have not advanced the cutover pins to the unmerged tools commit, so the rollback path remains unchanged.
Author
Member

The dev-VM cutover refresh is complete on allod/archetypes#40 at 66f2342. Current archetypes master is merged, the lock conflict is resolved, allod-tools is pinned to merged snapshot revision 5649cec, the real allod-dev Forge package builds, and its live snapshot output matches Bash byte for byte. Forgejo reports the PR mergeable.

Next human gate: merge allod/archetypes#40. After that, advance the archetypes input in allod/deploy and rebuild a dev VM before proceeding to the host cutover.

The dev-VM cutover refresh is complete on allod/archetypes#40 at `66f2342`. Current archetypes master is merged, the lock conflict is resolved, `allod-tools` is pinned to merged snapshot revision `5649cec`, the real `allod-dev` Forge package builds, and its live snapshot output matches Bash byte for byte. Forgejo reports the PR mergeable. Next human gate: merge allod/archetypes#40. After that, advance the `archetypes` input in allod/deploy and rebuild a dev VM before proceeding to the host cutover.
Author
Member

Dev-VM deployment witness passed on allod-dev after the rebuild. The installed command resolves to /nix/store/bvwm2lm8z9ik91lgcyqwknfjidif1l58-forge-0.1.0/bin/forge; its wrapper sits beside a Go ELF payload, authentication and Git repository inference work, and live pr snapshot 156 returned schema version 1 with the expected repository/ref projection. No dev cutover issue was found.

I am rolling forward to the host cutover now by refreshing and revalidating allod/nexus#25 against current nexus master and the snapshot-enabled tools pin. The host rebuild remains a human-only gate after that PR and its consumer pin land.

Dev-VM deployment witness passed on `allod-dev` after the rebuild. The installed command resolves to `/nix/store/bvwm2lm8z9ik91lgcyqwknfjidif1l58-forge-0.1.0/bin/forge`; its wrapper sits beside a Go ELF payload, authentication and Git repository inference work, and live `pr snapshot 156` returned schema version 1 with the expected repository/ref projection. No dev cutover issue was found. I am rolling forward to the host cutover now by refreshing and revalidating allod/nexus#25 against current nexus master and the snapshot-enabled tools pin. The host rebuild remains a human-only gate after that PR and its consumer pin land.
Author
Member

Rolled forward to the host cutover. allod/nexus#25 is refreshed at 1e201ea, includes current nexus master, and is mergeable. Through current allod/archetypes it builds the exact same forge-0.1.0 store output already verified on the rebuilt dev VM; the nexus architecture check passes.

Next human gate: merge allod/nexus#25. After that I can advance the allod/archetypes nexus pin and validate the committed host composition; the actual host rebuild and smoke test remain human-only.

Rolled forward to the host cutover. allod/nexus#25 is refreshed at `1e201ea`, includes current nexus master, and is mergeable. Through current allod/archetypes it builds the exact same `forge-0.1.0` store output already verified on the rebuilt dev VM; the nexus architecture check passes. Next human gate: merge allod/nexus#25. After that I can advance the allod/archetypes `nexus` pin and validate the committed host composition; the actual host rebuild and smoke test remain human-only.
Author
Member

Host deployment witness passed on nexus after rebuild. The installed command resolves to /nix/store/bvwm2lm8z9ik91lgcyqwknfjidif1l58-forge-0.1.0/bin/forge, authentication succeeds, and repository inference plus live pr snapshot 156 returned the expected schema-version-1 allod/tools projection.

Both deployed cutovers have now passed. I am proceeding to the final Bash-source and shell-suite retirement step.

Host deployment witness passed on `nexus` after rebuild. The installed command resolves to `/nix/store/bvwm2lm8z9ik91lgcyqwknfjidif1l58-forge-0.1.0/bin/forge`, authentication succeeds, and repository inference plus live `pr snapshot 156` returned the expected schema-version-1 `allod/tools` projection. Both deployed cutovers have now passed. I am proceeding to the final Bash-source and shell-suite retirement step.
vnprc closed this issue 2026-08-25 00:13:05 +01:00
Sign in to join this conversation.
No description provided.