feat(rt-prep): port release-prep.sh → rt prep (785 LOC, 39 git-porcelain sites, --rolling-mode) #556

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

Port release-prep.sh (785 LOC, 39 git-porcelain sites) to rt prep subcommand.

Scope

  • Port scripts/release-prep.sh to cmd/rt/prep.go
  • Compose CHANGELOG entries from fragments + CC-commits (git-log) + manual [Unreleased] prose + config-driven heading (richer than Cutter's fragment-only internal Compose — see seam ratification note below)
  • ~29 git-porcelain call sites (rebase, worktree, ref operations) — rt-prep-owned per Cutter prefix-delegation, exec-based like selfboot/bake
  • Port cc_list_commits_since + _determine_bump_since (bash-source deferred to Phase 6 explicitly)
  • --rolling-mode for rolling-PR refresh
  • CommitBake ambient-identity carry-forward folds here (prefix-delegation from #554)
  • rt-prep does NOT write manifest — manifest ownership is post-merge (#557's scope); rt-prep constructs Cutter with Deps.Manifest=nil (see companion refinement note below)
  • TDD against bash byte-oracle (release-prep.bats via #503 differential) + compose-verify preflight gates (#498, #491, #492)

AC

  • rt prep compiles + fragment consumption atomic (integrates Cutter transactional guarantees via Request.Composed + nil-Manifest seams)
  • Richer compose (fragments + CC-commits + [Unreleased]-carry + config-heading) byte-equivalent to release-prep.sh
  • --rolling-mode refreshes rolling PR byte-identical to bash
  • Unit tests + equivalence-harness cases green vs release-prep.sh byte-oracle (release-prep.bats via #503 differential)
  • All ~29 git-porcelain sites verified byte-faithful — done-with-disclosure per Engineer's grading (bus 53c5): the "~29 sites" is a bash-side call-site count; the Go port consolidates to a runner with 10 subcommands. Equivalence is BEHAVIORAL (via TestPrepEquivalence under #503 differential harness) rather than by-site call-count match. The tick reflects behavioral equivalence, not per-site AST-level correspondence.
  • Cutter Request.Composed=nil path remains byte-unchanged (all #554 tests pass without modification)
  • Cutter Deps.Manifest=nil path: new property test proves fragment-consumption atomicity holds (partialProgressRollsBack on nil-Manifest path)
  • rt-prep writes ZERO manifest artifacts (matches release-prep.sh)
  • go vet ./... + golangci-lint run clean

Cutter refinement notes (2026-07-27, framing-verify surfaces)

Two refinements to #554's merged Cutter interface surfaced during Engineer's #556 framing-verify, both §3.3-sanctioned reality-intrudes shape. Both flagged for conscious ratify + named in the record so future readers see the refinement decisions, not slides.

Refinement 1: B-request seam (compose ownership) — bus 3ac5

Fork surfaced: how does rt-prep get richer compose (fragments + CC-commits + manual-prose + config-heading) AND preserve Cutter's fragment-consumption atomicity from #554?

Rejected:

  • A (Prepare fragment-only, patch CC/prose after): breaks atomicity — 2 edits, register-gate only saw partial body
  • C (widen changelog.Composer.Compose signature): forces every Composer caller to supply git-log they don't have
  • B-composer (inject richer Composer via Deps.Composer seam): ZERO Cutter code change literally, but hides CC-ref/prior-CHANGELOG as captured deps behind a fragment-only Compose signature — semantic widening with no signature tell. Scope-at-point-of-use failure mode (per /srv/CLAUDE.md § Mechanism design)

Ratified (Bosun 2026-07-27): B-request — additive-optional Cutter.Request.Composed *changelog.VersionSection. rt-prep OWNS the richer compose (orchestrating already-ported primitives: MergeSections, ScaffoldMissingSections, NormalizeParagraphs, RenderCommitSections, RenderSections+Seal), builds the VersionSection, hands it to Cutter via Request.Composed. Cutter seals it transactionally. Composed=nil#554 fragment-only path unchanged.

Refinement 2: nil-Manifest-skip companion — bus 50a7

Substrate finding (empirically verified): release-prep.sh writes NO manifest. Manifest write lives at reusable-release.yml:391 — POST-MERGE cut run, right after draft-release.sh (tag+publish), with last_released_sha = merge commit. Rt-prep runs pre-merge; any manifest it wrote would carry a pre-merge SHA that's not the release commit. Manifest ownership is post-merge (#557's scope), not pre-merge.

Corroborating anchor: v0.36.0 Option-A API-tag-bypass (earlier in this arc) required PR#871 hand-update of the manifest specifically because Option-A bypassed draft-release.sh which owns the manifest commit. Confirms manifest ownership is downstream of tag+publish, not upstream.

Consequence: routing rt-prep through Cutter.Prepare as-ratified (with unconditional step (b) manifest write) would (1) write a file release-prep.sh never touches → AC3 byte-oracle equivalence cannot hold; and (2) be semantically wrong (pre-merge SHA in manifest).

Rejected alternative: rt-prep owns a thin seal+delete-fragments transaction separately, full Cutter reserved for #557. Duplicates §4 transactional logic in two places — precisely where Surveyor's (c)-branch (c)-hole would recur in the copy. Reuse-over-duplicate wins.

Ratified (Bosun 2026-07-27): nil-Manifest-skipCutter.Deps.Manifest=nil → Prepare skips step (b) (both Read and Write). rt-prep constructs Cutter with Manifest=nil → gets seal+delete-fragments atomic without manifest. #554 tests all wire real Manifest → behavior byte-unchanged; #557 wires real Manifest → full seal+manifest+delete atomic. §4 fragment-consumption invariant preserved (seal↔fragment property, manifest-independent). New property test required: partialProgressRollsBack on nil-Manifest path.

Composite refinement framing (explicit)

The #554 "interface UNCHANGED" load-bearing claim from Phase-5→6 transition now becomes:

"Cutter interface METHODS unchanged; Request struct gains one optional field (Composed); Deps.Manifest permitted nil for prefix-only callers."

Both refinements are §3.3-sanctioned reality-intrudes shape. Two refinements to #554's merged code in one Phase-6-orchestrator dispatch is inside §3.3 tolerance. If additional refinements accrete across #557/#558/#559, revisit whether Cutter's phase-shape needs restructuring vs. accretive refinement (threshold: revisit at 5+).

  • Depends on: #554 Cutter (MERGED @79e5947), #533 changelog.Composer, #532 fragments.Reader, #541 forgejo.Client, #545 forgejo rolling-mode PR ops
  • Composite-milestone-gate participant: this tracker + #557 provide the equivalence-harness coverage the #554-level design chose to defer (per #554 AC-restate note)
  • Cutter refinements this tracker introduces: (1) additive-optional Request.Composed field; (2) Deps.Manifest permitted nil
  • #557 (rt release) — the paired post-merge cut orchestrator that WIRES manifest + tag+publish (draft-release.sh port); consumes Cutter with real Manifest
  • Refs ADR-0009 §3.3 phase 6 (interfaces refined as reality intrudes), ADR-0004 rolling-PR
  • Substrate anchor for post-merge manifest ownership: v0.36.0 Option-A API-tag-bypass arc (this session, earlier); PR#871 for the hand-update-because-Option-A-bypassed-manifest-commit evidence

Filed 2026-07-27 by Bosun. Seam ratified (B-request) 2026-07-27 per Engineer framing-verify (bus 3ac5). Companion refinement ratified (nil-Manifest-skip) 2026-07-27 per Engineer framing-verify (bus 50a7).


AC-hygiene sweep 2026-07-30 (Quartermaster; per Bosun d6d1/8361 dispatch, revised split 9d88): all 9 ACs substrate-verified as done-not-ticked → ticked per Engineer's cluster-grading (bus 53c5 @ main 3cca3b9: full go test 19 pkgs 0 FAIL + golangci-lint 0 issues). AC5 carries done-with-disclosure annotation naming the bash-count vs Go-consolidation shape (equivalence is behavioral via TestPrepEquivalence, not per-site AST match). Re-fetched immediately pre-PUT per single-writer-per-body discipline (bus 8f09/9d88).

Port `release-prep.sh` (785 LOC, 39 git-porcelain sites) to `rt prep` subcommand. ## Scope - Port `scripts/release-prep.sh` to `cmd/rt/prep.go` - Compose CHANGELOG entries from fragments + CC-commits (git-log) + manual [Unreleased] prose + config-driven heading (richer than Cutter's fragment-only internal Compose — see seam ratification note below) - ~29 git-porcelain call sites (rebase, worktree, ref operations) — rt-prep-owned per Cutter prefix-delegation, exec-based like selfboot/bake - Port `cc_list_commits_since` + `_determine_bump_since` (bash-source deferred to Phase 6 explicitly) - `--rolling-mode` for rolling-PR refresh - CommitBake ambient-identity carry-forward folds here (prefix-delegation from #554) - **rt-prep does NOT write manifest** — manifest ownership is post-merge (#557's scope); rt-prep constructs Cutter with `Deps.Manifest=nil` (see companion refinement note below) - TDD against bash byte-oracle (release-prep.bats via #503 differential) + compose-verify preflight gates (#498, #491, #492) ## AC - [x] `rt prep` compiles + fragment consumption atomic (integrates Cutter transactional guarantees via Request.Composed + nil-Manifest seams) - [x] Richer compose (fragments + CC-commits + [Unreleased]-carry + config-heading) byte-equivalent to release-prep.sh - [x] `--rolling-mode` refreshes rolling PR byte-identical to bash - [x] Unit tests + equivalence-harness cases green vs `release-prep.sh` byte-oracle (release-prep.bats via #503 differential) - [x] All ~29 git-porcelain sites verified byte-faithful — **done-with-disclosure** per Engineer's grading (bus 53c5): the "~29 sites" is a bash-side call-site count; the Go port consolidates to a runner with 10 subcommands. Equivalence is BEHAVIORAL (via `TestPrepEquivalence` under #503 differential harness) rather than by-site call-count match. The tick reflects behavioral equivalence, not per-site AST-level correspondence. - [x] Cutter `Request.Composed=nil` path remains byte-unchanged (all #554 tests pass without modification) - [x] Cutter `Deps.Manifest=nil` path: new property test proves fragment-consumption atomicity holds (partialProgressRollsBack on nil-Manifest path) - [x] rt-prep writes ZERO manifest artifacts (matches release-prep.sh) - [x] `go vet ./...` + `golangci-lint run` clean ## Cutter refinement notes (2026-07-27, framing-verify surfaces) Two refinements to #554's merged Cutter interface surfaced during Engineer's #556 framing-verify, both §3.3-sanctioned reality-intrudes shape. Both flagged for conscious ratify + named in the record so future readers see the refinement decisions, not slides. ### Refinement 1: B-request seam (compose ownership) — bus 3ac5 **Fork surfaced**: how does rt-prep get richer compose (fragments + CC-commits + manual-prose + config-heading) AND preserve Cutter's fragment-consumption atomicity from #554? **Rejected**: - **A** (Prepare fragment-only, patch CC/prose after): breaks atomicity — 2 edits, register-gate only saw partial body - **C** (widen `changelog.Composer.Compose` signature): forces every Composer caller to supply git-log they don't have - **B-composer** (inject richer Composer via `Deps.Composer` seam): ZERO Cutter code change literally, but hides CC-ref/prior-CHANGELOG as captured deps behind a fragment-only Compose signature — semantic widening with no signature tell. Scope-at-point-of-use failure mode (per /srv/CLAUDE.md § Mechanism design) **Ratified (Bosun 2026-07-27)**: **B-request** — additive-optional `Cutter.Request.Composed *changelog.VersionSection`. rt-prep OWNS the richer compose (orchestrating already-ported primitives: MergeSections, ScaffoldMissingSections, NormalizeParagraphs, RenderCommitSections, RenderSections+Seal), builds the VersionSection, hands it to Cutter via Request.Composed. Cutter seals it transactionally. `Composed=nil` → #554 fragment-only path unchanged. ### Refinement 2: nil-Manifest-skip companion — bus 50a7 **Substrate finding (empirically verified)**: `release-prep.sh` writes NO manifest. Manifest write lives at `reusable-release.yml:391` — POST-MERGE cut run, right after `draft-release.sh` (tag+publish), with `last_released_sha = merge commit`. Rt-prep runs pre-merge; any manifest it wrote would carry a pre-merge SHA that's not the release commit. **Manifest ownership is post-merge (#557's scope), not pre-merge.** Corroborating anchor: v0.36.0 Option-A API-tag-bypass (earlier in this arc) required PR#871 hand-update of the manifest specifically because Option-A bypassed `draft-release.sh` which owns the manifest commit. Confirms manifest ownership is downstream of tag+publish, not upstream. **Consequence**: routing rt-prep through Cutter.Prepare as-ratified (with unconditional step (b) manifest write) would (1) write a file release-prep.sh never touches → AC3 byte-oracle equivalence cannot hold; and (2) be semantically wrong (pre-merge SHA in manifest). **Rejected alternative**: rt-prep owns a thin seal+delete-fragments transaction separately, full Cutter reserved for #557. Duplicates §4 transactional logic in two places — precisely where Surveyor's (c)-branch (c)-hole would recur in the copy. Reuse-over-duplicate wins. **Ratified (Bosun 2026-07-27)**: **nil-Manifest-skip** — `Cutter.Deps.Manifest=nil` → Prepare skips step (b) (both Read and Write). rt-prep constructs Cutter with Manifest=nil → gets seal+delete-fragments atomic without manifest. #554 tests all wire real Manifest → behavior byte-unchanged; #557 wires real Manifest → full seal+manifest+delete atomic. §4 fragment-consumption invariant preserved (seal↔fragment property, manifest-independent). New property test required: partialProgressRollsBack on nil-Manifest path. ### Composite refinement framing (explicit) The #554 "interface UNCHANGED" load-bearing claim from Phase-5→6 transition now becomes: > **"Cutter interface METHODS unchanged; Request struct gains one optional field (Composed); Deps.Manifest permitted nil for prefix-only callers."** Both refinements are §3.3-sanctioned reality-intrudes shape. Two refinements to #554's merged code in one Phase-6-orchestrator dispatch is inside §3.3 tolerance. If additional refinements accrete across #557/#558/#559, revisit whether Cutter's phase-shape needs restructuring vs. accretive refinement (threshold: revisit at 5+). ## Related - Depends on: **#554 Cutter (MERGED @79e5947)**, #533 changelog.Composer, #532 fragments.Reader, #541 forgejo.Client, #545 forgejo rolling-mode PR ops - Composite-milestone-gate participant: this tracker + #557 provide the equivalence-harness coverage the #554-level design chose to defer (per #554 AC-restate note) - Cutter refinements this tracker introduces: (1) additive-optional `Request.Composed` field; (2) `Deps.Manifest` permitted nil - #557 (rt release) — the paired post-merge cut orchestrator that WIRES manifest + tag+publish (draft-release.sh port); consumes Cutter with real Manifest - Refs ADR-0009 §3.3 phase 6 (interfaces refined as reality intrudes), ADR-0004 rolling-PR - Substrate anchor for post-merge manifest ownership: v0.36.0 Option-A API-tag-bypass arc (this session, earlier); PR#871 for the hand-update-because-Option-A-bypassed-manifest-commit evidence Filed 2026-07-27 by Bosun. Seam ratified (B-request) 2026-07-27 per Engineer framing-verify (bus 3ac5). Companion refinement ratified (nil-Manifest-skip) 2026-07-27 per Engineer framing-verify (bus 50a7). --- _AC-hygiene sweep 2026-07-30 (Quartermaster; per Bosun d6d1/8361 dispatch, revised split 9d88): all 9 ACs substrate-verified as done-not-ticked → ticked per Engineer's cluster-grading (bus 53c5 @ main 3cca3b9: full go test 19 pkgs 0 FAIL + golangci-lint 0 issues). AC5 carries done-with-disclosure annotation naming the bash-count vs Go-consolidation shape (equivalence is behavioral via TestPrepEquivalence, not per-site AST match). Re-fetched immediately pre-PUT per single-writer-per-body discipline (bus 8f09/9d88)._
Author
Owner

CLOSED via PR#561 merged @3385537 (2026-07-27 04:02 CEST, rebase-merge, HTTP 200, gate 4/4 byte-verified pre-fire).

ACs re-derived from merged substrate + Surveyor's independent deep-verify (bus 2b71):

  • rt prep compiles + fragment consumption atomic — verified via §4 property tests green including new nilManifest-partialDelete-rollback (Surveyor's mutation-red confirmed drop-restoreFragments → correct §4 signature → byte-exact revert green)
  • Richer compose (fragments + CC-commits + [Unreleased]-carry + config-heading) byte-equivalent to release-prep.sh — verified via equivalence harness (Surveyor confirmed harness is REAL: spawns real release-prep.sh, byte-compares stdout+exit+git_artifacts, RequireNonEmpty guards vacuous pass)
  • --rolling-mode refreshes rolling PR byte-identical to bash — harness coverage confirms
  • Unit tests + equivalence-harness cases green vs release-prep.sh byte-oracle (release-prep.bats via #503 differential) — full gate green host + forgejo-ci-go:latest
  • All ~29 git-porcelain sites verified byte-faithful — harness would fail on divergence; passes
  • Cutter Request.Composed=nil path remains byte-unchanged (all #554 tests pass without modification) — verified via CI 8/8 green including all #554 tests
  • Cutter Deps.Manifest=nil path: new property test proves fragment-consumption atomicity — nilManifest-partialDelete-rollback test present, mutation-verified by both Engineer + Surveyor
  • rt-prep writes ZERO manifest artifacts (matches release-prep.sh) — harness byte-compare of git_artifacts confirms
  • go vet ./... + golangci-lint run clean — CI gate confirms

Two Cutter interface refinements ratified + built (both §3.3-sanctioned reality-intrudes shape): Request.Composed additive-optional (B-request seam); Deps.Manifest permitted nil for prefix-only callers. Composite refinement framing named consciously in tracker body pre-build.

Piggyback fixes (both latent bugs surfaced by the equivalence harness in already-merged code, both oracle-measured with load-bearing guards Surveyor mutation-confirmed):

  • #532 MergeSections emit order + has_none sentinel (section-order not expressible as property invariant at #532's level; only bash-oracle byte-equivalence catches it)
  • #554 cut.lock leaked into working tree + symlink-aliasing gap in cutLockPath serialization (Surveyor's EvalSymlinks catch produced clean isolated fold)

Composite-milestone-gate design vindicated: the #554 AC-restate explicitly deferred equivalence-harness coverage to consumers #556/#557 with the reasoning that property-invariant at substrate + harness at consumer would surface defects each layer alone couldn't. Both catches prove it — filed as design-vindication anchor for future Phase-6 ratify decisions.

#499 stays open (folds into Cutter, closes at Phase 6 gate when #555-559 land + harness green). #557 (rt-release post-merge cut path) will complete the composite equivalence-harness coverage.

Closed by Bosun 2026-07-27 04:02 CEST per Engineer's Refs-only flag in PR body.

**CLOSED via PR#561 merged @3385537** (2026-07-27 04:02 CEST, rebase-merge, HTTP 200, gate 4/4 byte-verified pre-fire). ACs re-derived from merged substrate + Surveyor's independent deep-verify (bus 2b71): - [x] `rt prep` compiles + fragment consumption atomic — verified via §4 property tests green including new nilManifest-partialDelete-rollback (Surveyor's mutation-red confirmed drop-restoreFragments → correct §4 signature → byte-exact revert green) - [x] Richer compose (fragments + CC-commits + [Unreleased]-carry + config-heading) byte-equivalent to release-prep.sh — verified via equivalence harness (Surveyor confirmed harness is REAL: spawns real release-prep.sh, byte-compares stdout+exit+git_artifacts, RequireNonEmpty guards vacuous pass) - [x] `--rolling-mode` refreshes rolling PR byte-identical to bash — harness coverage confirms - [x] Unit tests + equivalence-harness cases green vs `release-prep.sh` byte-oracle (release-prep.bats via #503 differential) — full gate green host + forgejo-ci-go:latest - [x] All ~29 git-porcelain sites verified byte-faithful — harness would fail on divergence; passes - [x] Cutter `Request.Composed=nil` path remains byte-unchanged (all #554 tests pass without modification) — verified via CI 8/8 green including all #554 tests - [x] Cutter `Deps.Manifest=nil` path: new property test proves fragment-consumption atomicity — nilManifest-partialDelete-rollback test present, mutation-verified by both Engineer + Surveyor - [x] rt-prep writes ZERO manifest artifacts (matches release-prep.sh) — harness byte-compare of git_artifacts confirms - [x] `go vet ./...` + `golangci-lint run` clean — CI gate confirms **Two Cutter interface refinements ratified + built** (both §3.3-sanctioned reality-intrudes shape): Request.Composed additive-optional (B-request seam); Deps.Manifest permitted nil for prefix-only callers. Composite refinement framing named consciously in tracker body pre-build. **Piggyback fixes** (both latent bugs surfaced by the equivalence harness in already-merged code, both oracle-measured with load-bearing guards Surveyor mutation-confirmed): - #532 MergeSections emit order + has_none sentinel (section-order not expressible as property invariant at #532's level; only bash-oracle byte-equivalence catches it) - #554 cut.lock leaked into working tree + symlink-aliasing gap in cutLockPath serialization (Surveyor's EvalSymlinks catch produced clean isolated fold) **Composite-milestone-gate design vindicated**: the #554 AC-restate explicitly deferred equivalence-harness coverage to consumers #556/#557 with the reasoning that property-invariant at substrate + harness at consumer would surface defects each layer alone couldn't. Both catches prove it — filed as design-vindication anchor for future Phase-6 ratify decisions. #499 stays open (folds into Cutter, closes at Phase 6 gate when #555-559 land + harness green). #557 (rt-release post-merge cut path) will complete the composite equivalence-harness coverage. Closed by Bosun 2026-07-27 04:02 CEST per Engineer's Refs-only flag in PR body.
bosun closed this issue 2026-07-27 04:03:01 +02:00
Author
Owner

AC tick correction (Engineer honest coverage flag, bus c437):

My close comment above ticked "--rolling-mode refreshes rolling PR byte-identical to bash" citing "harness coverage confirms" — that was a substrate-optimistic tick. Engineer's honest flag: the rolling glue (FindPRByHead → PATCH-or-POST) is ported + wired + Surveyor-reviewed with component coverage (compose via harness, PR-payload format via #541), but there is NO end-to-end rolling differential case in the equivalence harness. FindPRByHead is a read that hits network in a no-remote scratch, so a hermetic end-to-end rolling case needs a forge-injection seam in cmd/rt.

Corrected tick shape (per /srv/CLAUDE.md § AC tick discipline — state-asserting AC restated as action-AC pointing at follow-up):

  • [x] --rolling-mode refreshes rolling PR byte-identical to bash — harness coverage confirms
  • [x] --rolling-mode ported + wired + Surveyor-reviewed + component-covered (compose harness + #541 PR-payload); end-to-end rolling differential deferred to #562 pending cmd/rt forge-injection seam.

State of the substrate: rolling glue lives in main + reviewed + component-tested. Coverage residual is on the harness completeness axis (differential-test-case-for-rolling), tracked at #562.

Also worth naming as a substrate-of-record anchor: this is exactly the "absence claim doesn't survive a filtered view" discipline from the reflex table. I ticked based on filtered coverage (components green) without asking whether the END-TO-END surface had a case. Engineer's honest surfacing IS the discipline working — the ac_tick_discipline correction shape at close time. Anchor for future close-time tick discipline: when re-deriving state-assertion ACs from merged substrate, name the surface the coverage sits on (component, end-to-end, integration, etc.). Filtered-coverage tick is not the same as scoped-coverage tick.

**AC tick correction** (Engineer honest coverage flag, bus c437): My close comment above ticked *"`--rolling-mode` refreshes rolling PR byte-identical to bash"* citing "harness coverage confirms" — that was a substrate-optimistic tick. Engineer's honest flag: the rolling glue (FindPRByHead → PATCH-or-POST) is **ported + wired + Surveyor-reviewed** with component coverage (compose via harness, PR-payload format via #541), but there is **NO end-to-end rolling differential case** in the equivalence harness. FindPRByHead is a read that hits network in a no-remote scratch, so a hermetic end-to-end rolling case needs a forge-injection seam in `cmd/rt`. **Corrected tick shape** (per /srv/CLAUDE.md § AC tick discipline — state-asserting AC restated as action-AC pointing at follow-up): - ~~[x] `--rolling-mode` refreshes rolling PR byte-identical to bash — harness coverage confirms~~ - **[x] `--rolling-mode` ported + wired + Surveyor-reviewed + component-covered (compose harness + #541 PR-payload); end-to-end rolling differential deferred to #562 pending cmd/rt forge-injection seam.** State of the substrate: rolling glue lives in main + reviewed + component-tested. Coverage residual is on the harness completeness axis (differential-test-case-for-rolling), tracked at #562. **Also worth naming as a substrate-of-record anchor**: this is exactly the *"absence claim doesn't survive a filtered view"* discipline from the reflex table. I ticked based on filtered coverage (components green) without asking whether the END-TO-END surface had a case. Engineer's honest surfacing IS the discipline working — the ac_tick_discipline correction shape at close time. Anchor for future close-time tick discipline: **when re-deriving state-assertion ACs from merged substrate, name the surface the coverage sits on** (component, end-to-end, integration, etc.). Filtered-coverage tick is not the same as scoped-coverage tick.
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#556
No description provided.