Skip to content

feat(installer): give Windows the same signed assets with its own binary provenance - #269

Closed
Alan-TheGentleman wants to merge 5 commits into
feat/release-assets-installfrom
feat/release-assets-windows
Closed

Alan-TheGentleman wants to merge 5 commits into
feat/release-assets-installfrom
feat/release-assets-windows

Conversation

@Alan-TheGentleman

Copy link
Copy Markdown
Collaborator

Fourth slice of the consumer chain, stacked on #268.

Windows is not a coverage gap

The release builds linux and darwin binaries only, so Windows builds its binary from Go SumDB source at the pinned tag. But the assets archive has no platform axis, so Windows downloads and verifies the same signed archive as everyone else, against the same locked digests.

One atomic bundle records both provenances with their distinct fields: SumDB source-build evidence for the binary, signed-archive evidence for the assets.

The cross-check observes, it never creates authority

A live review capabilities call on the source-built binary cross-checks semantic compatibility against the signed snapshot. It cannot become the source of truth.

That is proven two ways rather than described: the function body contains no write, rename or mkdir call at all, and it is placed strictly before staging, the integrity manifest write and the bundle publish. So any cross-check failure guarantees nothing was staged or published — asserted directly by tests confirming the binary, integrity.json and assets/ are all absent after every failure mode: non-zero exit, oversized output, non-JSON output, and semantic mismatch.

Subprocess discipline: fixed argv, no shell, bounded output, sealed environment, reusing the existing invocation seam.

Pruning, and a deviation worth naming

pruneSupersededBundles runs only after the new bundle's rename succeeds, never touches the live bundle, and its own failure is non-fatal and logged.

The policy implemented is keep the immediately previous bundle for rollback, prune the rest. That refines a literal reading of the design's prose, which could be read as removing every non-live version. It follows the maintainer's stated decision and is documented as a deviation rather than applied quietly.

Offline symmetry

GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1 skips binary and assets with the same loud disposition and leaves no partially configured bundle directory.

One task was already green

P2a had already threaded the assets keys through windowsSourceManifest, so task 4.6 needed no work. Noted rather than re-claimed as new.

Tests

64/64 on the focused installer, binary and entrypoint files. One failure in tests/native-review-cli.test.ts is environmental: this sandbox has no network, so the pinned binary was never installed. Verified independently by checking out the parent tip in the same worktree and getting an identical 47 pass / 1 fail. The diff did not cause it.

Rollback

Revert the installer and its test file to the parent tip and delete the new entrypoint test. No library, generated runtime, sync script, lock or CI file is touched.

D5 gives Windows a source-built binary with no goreleaser archive, but the
SAME signed assets archive every platform already verifies. Add a live
`gentle-ai.exe review capabilities` cross-check (fixed argv, no shell,
bounded output, sealed environment, reusing the existing go-install
invocation seam) that compares the freshly built binary against the
checked-in signed snapshot before anything is staged or published. The
check is read-only by construction and fails closed on subprocess failure,
oversized output, non-JSON output, or a semantic mismatch, so it can never
regenerate the snapshot or become a second authority.
…ollback, prune the rest

Bundle directories under .gentle-ai/ accumulated indefinitely across pin
bumps. Add pruneSupersededBundles(runtimeRoot), wired immediately after
publishBundle's rename succeeds on both the POSIX and Windows install
paths: it keeps exactly the highest-versioned non-live bundle for rollback
and removes every older one. It never runs on a cache-hit reuse (no rename
means nothing to prune), never touches the live bundle, and a removal
failure is logged and non-fatal rather than failing an install that
already succeeded.
…ps symmetrically

The postinstall entrypoint guards its single installGentleAi() call site
with GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1, so binary and assets are skipped
together by construction rather than through two checks that could
disagree. Add a subprocess-spawn test proving the runtime directory is
left byte-for-byte unchanged and the exact warning is logged, locking the
invariant rather than driving new production code.
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 346bfcb0-70a5-4261-9aa6-c7cee5d305a0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Alan-TheGentleman

Copy link
Copy Markdown
Collaborator Author

Closing as superseded in practice: gentle-pi 2.2.0 shipped by pinning the gentle-ai binary directly, and the producer side of the signed assets-archive channel (gentle-ai #2161/#2162) was closed as superseded today. This consumption chain has no upstream artifact to consume. If signed asset distribution returns, it should restart from a fresh design against the current pin-based release flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant