Repository navigation
Report artifact GC in one JSON shape and count every rollback leg - #1273
Conversation
|
bugbot run Generated by Claude Code |
|
[agent] Follow-up on my earlier comment: I had the diagnosis half wrong, and the flip in 3e6153c trades one red for two others.
|
|
bugbot run Generated by Claude Code |
|
Burn-down agent: pushed
These pass locally: Generated by Claude Code |
|
Ready for review (burn-down agent).
Generated by Claude Code |
, #1066) GC was reported four ways. repair and remove buried the sweep in artifact-level event details with no byte count, while rollback and scan --prune printed a hand-built `gc` object. The contract documented summary.bytesFreed, summary.bytesDownloaded and events[].bytes, but no command emitted any of them, so its GC jq recipe returned null. - json_envelope::GcReport {removedBlobs, removedDiffArchives, removedPackageArchives, bytesFreed} is built from the three sweep passes and serialized identically everywhere: the envelope's new top-level `gc` (repair, remove), rollback's `gc` and scan's `gc`. The hand-written json! blocks are gone. - summary.bytesFreed is always present and mirrors gc.bytesFreed. events[].bytes is set on the GC carrier event and on --update's downloaded event. summary.bytesDownloaded is dropped from the contract. - repair's GC carrier event no longer bumps summary.removed/verified, matching remove: summary counters count patch entries, and the sweep totals live in `gc`. - remove's human output now names the diff/package archives it sweeps. - rollback --json: rolledBack and failed now span the agent, vendored and hosted legs (#1066). A run where something failed and nothing was rolled back, already original or not installed now reports status "error" with error.code rollback_failed instead of partial_failure. Exit codes are unchanged. - CLI_CONTRACT.md: the envelope and PatchEvent schemas, the PatchAction "Emitted by" column, the per-command action matrix and the GC jq recipe now match the emitters. New unit tests pin the documented summary/gc/PatchEvent key sets against what json_envelope serializes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The --dry-run preview of scan --prune/--sync used its own vocabulary (prunableManifestEntries, orphanBlobs, orphanDiffArchives, orphanPackageArchives, revertableVendoredEntries, vendorOrphanDirs, bytesReclaimable). It now prints the same keys as the wet pass and every other GC-running command, counting what the pass would remove, and leaves out only the keys a real pass alone can fill (keptVendoredEntries, failedVendoredEntries, skipped, warnings). v5.0 MAJOR. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
113c017 to
f7977fa
Compare
All packages refused and nothing rolled back is a failed run since #1066. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
[final reviewer] Not enqueuing. Tanmay Singla (@Tanmay182003), the commit you approved ( Generated by Claude Code |
Assisted-by: Claude Code:claude-opus-5-5
The shared bun.lockb rollback helper expected status "error" for every caller, so the hosted -> vendored -> hosted takeover leg went red: there a manifest record makes the agent leg report the copy already original, and the run is correctly a partial_failure. A branch rewrite had dropped the earlier fix for this. Each caller now states which outcome it expects, so the takeover leg checks partial_failure and the hosted-only alias/transitive shapes keep checking rollback_failed. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit bc9c9be. Configure here.
Resolve against main's removal of the diff download path (#1049) and the restore-blob GC fix (#1316): repair drops the created-file blob pass and keeps the GcReport carrier; remove keeps the archive noun loop; the contract keeps "update" and drops the removed paidRequired status; the envelope contract test uses AppliedVia::Blob. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
main's new test read gc.prunableManifestEntries, which this branch renamed to prunedManifestEntries for the dry-run preview. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in main through #1277 via #1273. Resolutions: - get keeps the envelope's paidRequired status and drops main's legacy {"status": "paid_required"} emitter; contract_paid_required.rs now pins the envelope row instead of the legacy one. - repair: main removed the diff download path, so the created-file blob pass is gone; the download event keeps details.downloadMode, now always "file". - scan: the envelope arms read main's lockfile_only_count; main's hoisted release-variant narrowing replaces the hosted-only copy in get. - CLI_CONTRACT.md: three-way merged per paragraph; main's new hosted warning rows point at the top-level warnings[] like their neighbours. - tests: main's new tests (cargo takeover refusal, #1127 human prune, bun.lockb already-original rollback) read the envelope shapes. - json_envelope contract tests normalize CRLF so they pass on a Windows checkout. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
….lockb e2e - json_envelope's contract tests read CLI_CONTRACT.md through one LF-normalized copy, so a Windows checkout (CRLF) no longer misses the ```jsonc fence (review thread on #1273; full-scope test windows). - e2e_bun_lockb's shared-bundled case also has an agent copy that fails (hash_mismatch on a bundled copy the patch never touched); with #1066's all-leg counter, `failed` is the hosted refusal plus those agent failures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Takes #1273's LF-normalized contract_doc(); the bun.lockb shared-bundled rollback counts agent failed events (no details.mode) on top of the refused hosted pin. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolve remove.rs imports: keep main's KeepCause and this branch's GcReport. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in main's latest via #1273. Conflicts: - CLI_CONTRACT.md: keep the envelope wording and port main's additions (cargo_build_cache_stale, cargo_cache_patch_kept, the Cargo shared-cache exemption in GC and rollback, redirect_cargo_dep_overridden, vendor_pypi_reinstall_required, vendor_revert_residual_reference, the pnpm keyless-yaml restore) onto it; GC warnings are top-level warnings[], a kept entry gets no preview event, and rollback's residual keep is its failed vendor_revert_kept event. - rollback.rs tests: keep both the envelope tests and the PyPI reinstall note test. Port main's new tests to the envelope: e2e_cargo reads pruned manifest entries from details.manifest events and cargo_cache_patch_kept from the top-level warnings; in_process_redirect and mode_migration_pypi count hosted pins from events and read redirect_vendored_revert_failed from the top-level warnings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
main's #1278 e2e (sync_keeps_entry_whose_shared_cache_copy_is_still_patched) reads the preview's prunableManifestEntries, which the one GC shape renamed to prunedManifestEntries; the contract text it brought gets the same rename. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Keep the envelope ports of e2e_cargo and the Cargo GC contract text (pruned entries are details.manifest events, so the preview key rename on #1273 does not apply here). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#1305's sync_keeps_entry_whose_shared_cache_copy_is_still_patched asserted the scan --sync --dry-run preview via gc.prunableManifestEntries, a key #1273 retires: under the one GC shape a dry run reports would-be prunes as gc.prunedManifestEntries. The keep logic itself merged intact (preview and wet pass both keep the still-patched itoa entry, and the wet pass reports cargo_cache_patch_kept in gc.warnings[] with the purl and the rollback remedy), so only the test read the wrong key. Assert the same ryu-only list under the new key. CLI_CONTRACT.md's scan --prune paragraph still named the retired preview keys (prunableManifestEntries, revertableVendoredEntries, vendorOrphanDirs); point it at the unified keys and note that the preview, like every warnings[] entry, carries no cargo_cache_patch_kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts: # crates/socket-patch-cli/CLI_CONTRACT.md
Keep the envelope wording for the Cargo shared-cache GC keep (no event and no warning in the preview) and take #1273's vendor_artifact_gitignored NuGet/JVM contract updates with the envelope's top-level warnings[]. e2e_cargo keeps the events-based prune read with #1273's message. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#1273 landed as squash e3eaa0c, whose tree is fix/gc-report-json-1257 (ff9704a, already merged here) plus #1342. Conflicts take this branch's side throughout (the squash adds nothing beyond ff9704a); #1342's nuget_feed.rs merges cleanly and its CLI_CONTRACT.md nuget drift note is ported. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closes #1257. Closes #1066.
Both are JSON-contract drift that should be fixed before v5.0.0 ships (#1194).
Artifact GC: one shape (#1257)
repair --jsonremovedevent,details: {count, checked}; no bytes; bumpedsummary.removedby 1gc+summary.bytesFreed; carrier event keepscount/checked, gainsbytes, bumps no counterremove --jsondetails: {blobsRemoved, rolledBack, archivesRemoved}; no bytesbytes; top-levelgc+summary.bytesFreedrollback --jsongcjsonGcReportscan --prune --jsongcjsonGcReport(plus scan's manifest/vendored keys)json_envelope::GcReport {removedBlobs, removedDiffArchives, removedPackageArchives, bytesFreed}, folded from the three sweep passes.summary.bytesFreedis always present (0 when no GC ran).events[].bytesis set on the GC carrier and on--update'sdownloadedevent.summary.bytesDownloadedwas never emitted, so it is removed from the contract.remove's human output now prints the diff/package archives it sweeps, likerepairdoes.--dry-runGC preview uses the same keys too (MAJOR):prunableManifestEntries/orphanBlobs/orphanDiffArchives/orphanPackageArchives/revertableVendoredEntries/vendorOrphanDirs/bytesReclaimablebecameprunedManifestEntries/removedBlobs/removedDiffArchives/removedPackageArchives/revertedVendoredEntries/removedVendorOrphanDirs/bytesFreed. The preview leaves out only the keys a real pass alone can fill (keptVendoredEntries,failedVendoredEntries,skipped,warnings).Rollback counters span every leg (#1066)
rolledBack= agent restores +vendoredReverted+vendoredPreserved+hosted.reverted.failed= agent failures +vendoredKept+vendoredFailed+hosted.failed+hosted.unsupported.status: "error"witherror.code: "rollback_failed"instead ofpartial_failure. Exit codes are unchanged (1).Contract
updatetocommand, plusrebuilt,bytesFreedandgc; dropsbytesDownloaded.PatchEventaction enum now includesrebuilt.applynever emitsupdated,discoveredislist-only,vexwas missing..gc.*and.summary.bytesFreed.summary,gc, top-level andPatchEventkey sets, and the action vocabulary rows, against whatjson_envelopeserializes.Tests
--lib(910), plus the rollback, repair, remove, scan, in_process_scan, covgap rollback/scan-hosted and in-process rollback hosted/vendored suites, all pass locally.cargo clippy --locked --workspace --all-features -- -D warningsis clean.summary.removed: 1and the oldpartial_failureon all-failed rollbacks. The mixed hosted case now assertsrolledBack: 1, failed: 1(was 0/0).e2e_bun_lockb(needs the real toolchain) is updated to the new status, but CI is the first to run it.v5 blocker agent update (bc9c9be)
e2e_bun_lockbwas red on9714d570:native_binary_hosted_vendored_takeover_roundtripexpectedstatus: "error", but a staged manifest makes the agent leg report the copyalreadyOriginal: 1, so the run ispartial_failure, as the contract says. The per-caller fix from113c0177was lost in the branch rewrite.rollback_refuses_binary_hosted_pin_then_checkoutnow takes acopy_already_originalflag from each caller: takeover and shared-bundled-record legs (manifest staged) expectpartial_failure+alreadyOriginal: 1; hosted-only alias/transitive shapes expecterror/rollback_failed+alreadyOriginal: 0. All expectfailed: 1.origin/main(merge, not rebase) at1e69b30.e2e_bun_lockbtests pass. The other 2 fail only because this sandbox can't reach patches-api.socket.dev / GitHub tarballs (proxy 403), not because of the change.cargo fmt --all -- --checkclean.🤖 Generated with Claude Code
Note
Medium Risk
MAJOR JSON shape changes (scan dry-run GC keys, rollback total-failure status) affect automation consumers; rollback counter semantics changed across vendored/hosted legs.
Overview
v5 JSON contract: artifact GC is reported through one shared
gcobject (removedBlobs,removedDiffArchives,removedPackageArchives,bytesFreed) on envelope commands (repair,remove) and aligned withrollback/scan --prune.summary.bytesFreedmirrorsgc.bytesFreed; GC carrier events carrybytesbut no longer inflatesummary.removed.summary.bytesDownloadedis dropped from the contract.Breaking (scan dry-run): GC preview keys are unified with the wet pass (
prunedManifestEntries,removedBlobs, …) instead of the oldprunable*/orphan*/bytesReclaimablenames.Rollback (#1066): top-level
rolledBack/failedcount agent, vendored, and hosted legs. When every targeted package fails and nothing is restored or already original, JSON isstatus: "error"witherror.code: "rollback_failed"(still exit 1), notpartial_failure.Docs & tests:
CLI_CONTRACT.mdupdated (envelope,updatecommand, action matrix, jq recipes); contract tests pin serialized keys; broad test updates for GC shape and rollback status.Reviewed by Cursor Bugbot for commit bc9c9be. Configure here.
Generated by Claude Code