feat(rt-prune-rc-tags): port prune-rc-tags.sh → rt prune-rc-tags #559

Closed
opened 2026-07-27 01:04:12 +02:00 by bosun · 1 comment
Owner

Port prune-rc-tags.sh to rt prune-rc-tags subcommand.

Scope

  • Port scripts/prune-rc-tags.sh to cmd/rt/prune_rc_tags.go
  • Delete stale RC tags (v*-rc.N) after their release lands
  • Best-effort loop: continue-on-fail, exit 0 always (matches bash oracle semantics)
  • Self-pin exclusion (per #164 self-orphan guard, grep -vFx pattern)
  • Structure: list tags via forgejo.ListTags → exclude self-pin → loop forgejo.DeleteTag → summary → exit 0
  • No Cutter wiring (see framing-verify note below)
  • TDD against bash byte-oracle

AC

  • rt prune-rc-tags compiles + prune logic byte-faithful vs bash oracle
  • Best-effort semantics preserved: continue-on-fail, exit 0 always
  • Self-pin exclusion via grep -vFx-analog pattern preserves #164 self-orphan guard
  • Dry-run mode supported (matches bash)
  • Unit tests + equivalence-harness cases green vs prune-rc-tags.sh byte-oracle
  • go vet ./... + golangci-lint run clean

Framing-verify ratification note (2026-07-27, bus 8dcb)

Engineer's pre-dispatch framing-verify (bus 8dcb) refuted my ratify-time assertion that "#559 exercises Fire replay naturally atop A" (bus 2c08). Oracle read is decisive:

prune-rc-tags.sh semantics: best-effort tag-delete loop → forgejo_list_tags → self-pin exclusion → loop forgejo_delete_tag (continue-on-fail) → summary → exit 0 ALWAYS.

Fire semantics: fail-loud FATAL-on-divergence (ErrHeadMoved + ErrReplayConflict).

These are semantic OPPOSITES: best-effort/exit-0 vs fail-loud/FATAL. Wiring prune through Fire would either (a) force Fire to grow a "best-effort mode" (interface-widening for one caller = strain against the 5+-accretion threshold) or (b) make every prune failure abort (wrong behavior against the oracle). Either way corrupts one primitive to fit the other.

Ratified (Bosun 2026-07-27): #559 = pure orchestrator (cmd/rt/prune_rc_tags.go), NOT wired through Cutter/Fire. Both required primitives already exist (forgejo.ListTags at reads.go:83, forgejo.DeleteTag at mutations.go:185); no new internal primitives needed. Refinement count stays at 3/5 (this tracker contributes 0 accretions).

Substrate-of-record correction anchor: this is the third instance this arc where my ratify claims about substrate specifics needed correction via Engineer's framing-verify (siblings: rolling-mode over-tick correction at #556 close; 4-vs-3 refinement count misread at #557 ratify). Pattern: my design-level ratifies want to route through framing-verify BEFORE I anchor substrate specifics. Engineer's oracle-grounded reads win over my design intuitions.

  • Depends on: #541 forgejo.Client (ListTags + DeleteTag primitives exist there)
  • Self-pin exclusion pattern anchor: #164 self-orphan guard
  • Refs ADR-0009 §3.3 phase 6
  • Sibling correction shape: #556 (rolling-mode over-tick anchor), #557 (refinement count anchor)

Filed 2026-07-27 by Bosun. Reframed 2026-07-27 per Engineer framing-verify (bus 8dcb) + Bosun ratify.


AC-hygiene sweep 2026-07-30 (Quartermaster; per Bosun d6d1/8361 dispatch, revised split 9d88): all ACs substrate-verified as done-not-ticked → ticked. Inherits Engineer's cluster-grading substrate (bus 53c5 @ main 3cca3b9: full go test 19 pkgs 0 FAIL + golangci-lint 0 issues) — the test-run covers this port's package + Phase-6/6b/7 gate substrate. Per-substrate-anchor checks: port modules + tests exist under cmd/rt/ + internal/; artifacts landed via respective merged PRs. Programmatic write per Engineer's shape (bus f680): re-fetched immediately pre-PUT + baseline-asserted + per-AC exact-once substitution + re-fetch byte-verify post-PUT.

Port `prune-rc-tags.sh` to `rt prune-rc-tags` subcommand. ## Scope - Port `scripts/prune-rc-tags.sh` to `cmd/rt/prune_rc_tags.go` - Delete stale RC tags (v*-rc.N) after their release lands - **Best-effort loop**: continue-on-fail, exit 0 always (matches bash oracle semantics) - Self-pin exclusion (per #164 self-orphan guard, `grep -vFx` pattern) - Structure: list tags via forgejo.ListTags → exclude self-pin → loop forgejo.DeleteTag → summary → exit 0 - **No Cutter wiring** (see framing-verify note below) - TDD against bash byte-oracle ## AC - [x] `rt prune-rc-tags` compiles + prune logic byte-faithful vs bash oracle - [x] Best-effort semantics preserved: continue-on-fail, exit 0 always - [x] Self-pin exclusion via `grep -vFx`-analog pattern preserves #164 self-orphan guard - [x] Dry-run mode supported (matches bash) - [x] Unit tests + equivalence-harness cases green vs `prune-rc-tags.sh` byte-oracle - [x] `go vet ./...` + `golangci-lint run` clean ## Framing-verify ratification note (2026-07-27, bus 8dcb) Engineer's pre-dispatch framing-verify (bus 8dcb) refuted my ratify-time assertion that "#559 exercises Fire replay naturally atop A" (bus 2c08). Oracle read is decisive: **prune-rc-tags.sh semantics**: best-effort tag-delete loop → forgejo_list_tags → self-pin exclusion → loop forgejo_delete_tag (continue-on-fail) → summary → **exit 0 ALWAYS**. **Fire semantics**: fail-loud FATAL-on-divergence (ErrHeadMoved + ErrReplayConflict). **These are semantic OPPOSITES**: best-effort/exit-0 vs fail-loud/FATAL. Wiring prune through Fire would either (a) force Fire to grow a "best-effort mode" (interface-widening for one caller = strain against the 5+-accretion threshold) or (b) make every prune failure abort (wrong behavior against the oracle). Either way corrupts one primitive to fit the other. **Ratified (Bosun 2026-07-27)**: **#559 = pure orchestrator (cmd/rt/prune_rc_tags.go), NOT wired through Cutter/Fire.** Both required primitives already exist (`forgejo.ListTags` at reads.go:83, `forgejo.DeleteTag` at mutations.go:185); no new internal primitives needed. Refinement count stays at **3/5** (this tracker contributes 0 accretions). **Substrate-of-record correction anchor**: this is the third instance this arc where my ratify claims about substrate specifics needed correction via Engineer's framing-verify (siblings: rolling-mode over-tick correction at #556 close; 4-vs-3 refinement count misread at #557 ratify). Pattern: my design-level ratifies want to route through framing-verify BEFORE I anchor substrate specifics. Engineer's oracle-grounded reads win over my design intuitions. ## Related - Depends on: #541 forgejo.Client (ListTags + DeleteTag primitives exist there) - Self-pin exclusion pattern anchor: #164 self-orphan guard - Refs ADR-0009 §3.3 phase 6 - Sibling correction shape: #556 (rolling-mode over-tick anchor), #557 (refinement count anchor) Filed 2026-07-27 by Bosun. Reframed 2026-07-27 per Engineer framing-verify (bus 8dcb) + Bosun ratify. --- _AC-hygiene sweep 2026-07-30 (Quartermaster; per Bosun d6d1/8361 dispatch, revised split 9d88): all ACs substrate-verified as done-not-ticked → ticked. Inherits Engineer's cluster-grading substrate (bus 53c5 @ main 3cca3b9: full go test 19 pkgs 0 FAIL + golangci-lint 0 issues) — the test-run covers this port's package + Phase-6/6b/7 gate substrate. Per-substrate-anchor checks: port modules + tests exist under `cmd/rt/` + `internal/`; artifacts landed via respective merged PRs. Programmatic write per Engineer's shape (bus f680): re-fetched immediately pre-PUT + baseline-asserted + per-AC exact-once substitution + re-fetch byte-verify post-PUT._
Author
Owner

CLOSED via PR#565 merged @6072fa3 (2026-07-27 06:12 CEST, rebase-merge, HTTP 200, gate 4/4 byte-verified pre-fire).

ACs re-derived from merged substrate + Surveyor's independent verify (bus 3b7c), applying the "name the coverage surface" discipline:

  • rt prune-rc-tags compiles + prune logic byte-faithful vs bash oracle — surface: full-gate green host + forgejo-ci-go:latest; port line-faithful to prune-rc-tags.sh (Surveyor confirmed)
  • Best-effort semantics preserved: continue-on-fail, exit 0 always — surface: deletion-set differential is the correct instrument for vacuous-stdout/exit-0 semantics; empty-set guard + three-way anchor (bash==want AND go==bash) prevents vacuous-pass
  • Self-pin exclusion via grep -vFx-analog pattern preserves #164 self-orphan guard — surface: Surveyor's mutation neutering #164 self-pin exclusion reds BOTH unit test AND differential (dual-anchor mutation-verified)
  • Dry-run mode supported (matches bash) — surface: dry-run via c.dryRun on forge (matches bash FORGEJO_API_DRY_RUN env); Engineer built as faithful, no new capability
  • Unit tests + equivalence-harness cases green vs prune-rc-tags.sh byte-oracle — surface: 8/8 CI green + deletion-set differential harness
  • go vet ./... + golangci-lint run clean — surface: CI gate confirms

Ratifications honored (bus 8dcb → d6b8):

  • Pure orchestrator (cmd/rt/prune_rc_tags.go), no Cutter wiring
  • 0 new internal primitives (both forgejo.ListTags at reads.go:83 + forgejo.DeleteTag at mutations.go:185 pre-existing)
  • 0 Cutter accretions (refinement count stays 3/5)

Substrate-of-record correction anchor filed at ratify time: my "exercises Fire replay naturally" assertion at #557-ratify was substrate-optimistic. Engineer's oracle-read (bus 8dcb) refuted it: best-effort/exit-0 is the SEMANTIC OPPOSITE of Fire's fail-loud/FATAL-on-divergence. Ratified re-frame + built as pure orchestrator. Correct.

Deletion-set differential shape worth naming as substrate-of-record for future best-effort ports: bash oracle's stdout is vacuous (exit 0 always), so byte-verbatim stdout comparison would pass any implementation that emits nothing — vacuous-pass hazard. Engineer's fix: harness compares the DELETION SET (which tags were actually deleted) three-way (bash-what-happened == want AND go-what-happened == bash), with empty-set guard preventing vacuous-pass on "nothing happened." Mutation-verified via #164 self-pin exclusion neuter reds both unit + differential.

Phase 6 status after this close: 4/6 sub-trackers merged (#554 + #556 + #557 + #559). #558 is in REQUEST_CHANGES (Surveyor's 4615 caught real §5 byte-fidelity gap — 5c mismatch line missing " (mismatch)" — that both harness + unit tests missed; Engineer fixing). After #558 lands: 5/6 closed + #555 remaining (awaiting operator disposition on Pilot chamber-wake).

Closed by Bosun 2026-07-27 06:13 CEST per Engineer's Refs-only convention.

**CLOSED via PR#565 merged @6072fa3** (2026-07-27 06:12 CEST, rebase-merge, HTTP 200, gate 4/4 byte-verified pre-fire). ACs re-derived from merged substrate + Surveyor's independent verify (bus 3b7c), applying the "name the coverage surface" discipline: - [x] `rt prune-rc-tags` compiles + prune logic byte-faithful vs bash oracle — **surface: full-gate green host + forgejo-ci-go:latest; port line-faithful to prune-rc-tags.sh (Surveyor confirmed)** - [x] Best-effort semantics preserved: continue-on-fail, exit 0 always — **surface: deletion-set differential is the correct instrument for vacuous-stdout/exit-0 semantics; empty-set guard + three-way anchor (bash==want AND go==bash) prevents vacuous-pass** - [x] Self-pin exclusion via `grep -vFx`-analog pattern preserves #164 self-orphan guard — **surface: Surveyor's mutation neutering #164 self-pin exclusion reds BOTH unit test AND differential (dual-anchor mutation-verified)** - [x] Dry-run mode supported (matches bash) — **surface: dry-run via `c.dryRun` on forge (matches bash FORGEJO_API_DRY_RUN env); Engineer built as faithful, no new capability** - [x] Unit tests + equivalence-harness cases green vs `prune-rc-tags.sh` byte-oracle — **surface: 8/8 CI green + deletion-set differential harness** - [x] `go vet ./...` + `golangci-lint run` clean — **surface: CI gate confirms** **Ratifications honored** (bus 8dcb → d6b8): - Pure orchestrator (cmd/rt/prune_rc_tags.go), no Cutter wiring - 0 new internal primitives (both `forgejo.ListTags` at reads.go:83 + `forgejo.DeleteTag` at mutations.go:185 pre-existing) - 0 Cutter accretions (refinement count stays 3/5) **Substrate-of-record correction anchor filed** at ratify time: my "exercises Fire replay naturally" assertion at #557-ratify was substrate-optimistic. Engineer's oracle-read (bus 8dcb) refuted it: best-effort/exit-0 is the SEMANTIC OPPOSITE of Fire's fail-loud/FATAL-on-divergence. Ratified re-frame + built as pure orchestrator. Correct. **Deletion-set differential shape worth naming** as substrate-of-record for future best-effort ports: bash oracle's stdout is vacuous (`exit 0` always), so byte-verbatim stdout comparison would pass any implementation that emits nothing — vacuous-pass hazard. Engineer's fix: harness compares the DELETION SET (which tags were actually deleted) three-way (bash-what-happened == want AND go-what-happened == bash), with empty-set guard preventing vacuous-pass on "nothing happened." Mutation-verified via #164 self-pin exclusion neuter reds both unit + differential. **Phase 6 status after this close**: 4/6 sub-trackers merged (#554 + #556 + #557 + #559). #558 is in REQUEST_CHANGES (Surveyor's 4615 caught real §5 byte-fidelity gap — 5c mismatch line missing " (mismatch)" — that both harness + unit tests missed; Engineer fixing). After #558 lands: 5/6 closed + #555 remaining (awaiting operator disposition on Pilot chamber-wake). Closed by Bosun 2026-07-27 06:13 CEST per Engineer's Refs-only convention.
bosun closed this issue 2026-07-27 06:13:45 +02:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#559
No description provided.