feat(bake): implement Baker + byte-exactness invariant against #505 interface (TDD against bash byte-oracle if central; disclose if scattered/absent) #546

Closed
opened 2026-07-26 14:51:00 +02:00 by bosun · 1 comment
Owner

Implement internal/bake.Baker satisfying the Go interface landed in #505 (byte-exactness invariant per ADR-0009 §3.2 property invariants).

Motivation

Phase 5 continues contract-driven TDD-per-phase per ADR-0009 §3.1. internal/bake is one of two Phase 5 packages (sibling: #547 self-bootstrap). Interface (Baker + byte-exactness invariant) is Surveyor-approved in #505; implementation lands here.

Scope

  • internal/bake/*.go — implementation satisfying #505 interface (Baker with byte-exactness property)
  • Byte-exactness invariant (per ADR-0009 §3.2): given the same inputs, Baker MUST produce byte-identical output. Verified via property test.
  • Bash byte-oracle: existing bash bake logic (verify on-disk before starting; may be in lib/bake.sh OR embedded in release-prep.sh / draft-release.sh OR distributed across reusable-workflow render logic — deep-read per Phase-4 substrate-check-design-claim-before-pr discipline that has fired 4× so far)
  • TDD approach (contract-driven per ADR-0009 §3.1):
    1. Test against interface first
    2. Oracle harness case using internal/harness (reuse Phase-1 vehicle: Go oracleshim + bash dispatcher + PREBUILT BINARY per substrate-of-record memo)
    3. Implementation to green
  • Fixture corpus at testdata/fixtures/bake/ — real bake input/output pairs from consumer scenarios

AC

  • internal/bake implementation compiles + all #505 interface methods satisfied — verified in PR#548 9e77994; interface.go UNTOUCHED (no correction needed unlike #541 BranchProtection); 3 files (marker.go byte-exact kernel + baker.go PURE throwaway-index + bake.go doc)
  • Byte-exactness property invariant test green — TestBakerByteExactness (determinism) plus dual-mode 32-case equivalence (4 fixtures × 4 refs × 2 bash mechanisms) EMPIRICALLY PROVES design-call-2: both bash mechanisms (create_detached_bake_commit + bake_toolkit_ref+write-tree) AND the pure Go Baker yield the SAME tree
  • Unit tests green — verified in PR#548 gate run (all packages green in forgejo-ci-go image)
  • Equivalence-harness cases against bash oracle green — bash surface is CENTRAL (scripts/lib/build_bake.sh, 2 fns) so real byte-oracle (NOT contract-authority-when-no-oracle-exists class). 32 harness cases + 2 mutation axes (broad trailing-newline + narrow first-per-line→all-matches, mutation-verified reverted byte-identical). Surveyor independently reproduced (review 4585 @ 9e77994). CI-red interlude root-caused as apparatus-not-world (bake-oracle.sh depended on passwd gecos for auto-git-identity; dev host had it, CI container bare root did not); harness-only fix (export GIT_AUTHOR_/COMMITTER_), Go Baker + build_bake.sh untouched
  • go vet ./... + golangci-lint run clean — verified: gate own instrument (golangci-lint 2.12.1) fired 0 issues; shellcheck+keyword-scan clean
  • Depends on: #505 (Baker interface), #503 (harness vehicle)
  • Sibling: #547 (self-bootstrap wiring — consumes Baker)
  • Downstream: Phase 6 orchestrators (#508) fire Baker as part of release-cut flow
  • Refs ADR-0009 §3.1 (contract-driven TDD), §3.2 (bake byte-exactness invariant), §3.3 phase 5 row, §5 (fail-loud + trivalent-verdict discipline)

Anchor

Filed 2026-07-26 by Bosun on operator continuation direction for Phase 5 dispatch. Engineer natural continuation-in-domain per Phase 0-4 authorship.

Implement `internal/bake.Baker` satisfying the Go interface landed in #505 (byte-exactness invariant per ADR-0009 §3.2 property invariants). ## Motivation Phase 5 continues contract-driven TDD-per-phase per ADR-0009 §3.1. `internal/bake` is one of two Phase 5 packages (sibling: [[#547 self-bootstrap]]). Interface (`Baker` + byte-exactness invariant) is Surveyor-approved in #505; implementation lands here. ## Scope - `internal/bake/*.go` — implementation satisfying #505 interface (Baker with byte-exactness property) - **Byte-exactness invariant** (per ADR-0009 §3.2): given the same inputs, Baker MUST produce byte-identical output. Verified via property test. - **Bash byte-oracle**: existing bash bake logic (verify on-disk before starting; may be in `lib/bake.sh` OR embedded in `release-prep.sh` / `draft-release.sh` OR distributed across reusable-workflow render logic — deep-read per Phase-4 substrate-check-design-claim-before-pr discipline that has fired 4× so far) - **TDD approach** (contract-driven per ADR-0009 §3.1): 1. Test against interface first 2. Oracle harness case using `internal/harness` (reuse Phase-1 vehicle: Go oracleshim + bash dispatcher + PREBUILT BINARY per substrate-of-record memo) 3. Implementation to green - Fixture corpus at `testdata/fixtures/bake/` — real bake input/output pairs from consumer scenarios ## AC - [x] `internal/bake` implementation compiles + all `#505` interface methods satisfied — verified in PR#548 9e77994; interface.go UNTOUCHED (no correction needed unlike #541 BranchProtection); 3 files (marker.go byte-exact kernel + baker.go PURE throwaway-index + bake.go doc) - [x] Byte-exactness property invariant test green — TestBakerByteExactness (determinism) plus dual-mode 32-case equivalence (4 fixtures × 4 refs × 2 bash mechanisms) EMPIRICALLY PROVES design-call-2: both bash mechanisms (create_detached_bake_commit + bake_toolkit_ref+write-tree) AND the pure Go Baker yield the SAME tree - [x] Unit tests green — verified in PR#548 gate run (all packages green in forgejo-ci-go image) - [x] Equivalence-harness cases against bash oracle green — bash surface is CENTRAL (scripts/lib/build_bake.sh, 2 fns) so real byte-oracle (NOT contract-authority-when-no-oracle-exists class). 32 harness cases + 2 mutation axes (broad trailing-newline + narrow first-per-line→all-matches, mutation-verified reverted byte-identical). Surveyor independently reproduced (review 4585 @ 9e77994). CI-red interlude root-caused as apparatus-not-world (bake-oracle.sh depended on passwd gecos for auto-git-identity; dev host had it, CI container bare root did not); harness-only fix (export GIT_AUTHOR_*/COMMITTER_*), Go Baker + build_bake.sh untouched - [x] `go vet ./...` + `golangci-lint run` clean — verified: gate own instrument (golangci-lint 2.12.1) fired 0 issues; shellcheck+keyword-scan clean ## Related - Depends on: #505 (Baker interface), #503 (harness vehicle) - Sibling: #547 (self-bootstrap wiring — consumes Baker) - Downstream: Phase 6 orchestrators (#508) fire Baker as part of release-cut flow - Refs ADR-0009 §3.1 (contract-driven TDD), §3.2 (bake byte-exactness invariant), §3.3 phase 5 row, §5 (fail-loud + trivalent-verdict discipline) ## Anchor Filed 2026-07-26 by Bosun on operator continuation direction for Phase 5 dispatch. Engineer natural continuation-in-domain per Phase 0-4 authorship.
bosun closed this issue 2026-07-26 15:39:22 +02:00
Author
Owner

Closed by hand — PR#548 merged as 9e77994c90eb3fde39178af95b416838f800a6c1 on v2/next (fast-forward). All 5 ACs ticked with substrate anchors above.

Substrate landed:

  • internal/bake.Baker PURE throwaway-index implementation (no working-copy mutation per design-call-3 endorsed lean)
  • marker.go byte-exact kernel (sed-faithful first-per-line + trailing-newline-preserving)
  • 32-case dual-mode harness empirically PROVES design-call-2: 2 bash mechanisms + Go Baker all yield SAME tree
  • interface.go UNTOUCHED (no correction needed unlike #541 BranchProtection — contract shape was already right)

All 6 design calls landed as endorsed (Bosun 28f0):

  1. ★ SCOPE #546 vs #547: Baker produces TREE, commit-wrap goes to #547 — verified
  2. One phase-invariant tree computation — empirically proven by 32-case dual-mode harness
  3. ★ Bake is PURE — throwaway-index, no working-copy mutation
  4. Source = RepoDir working copy + write-tree — matches interface docstring
  5. File set = hardcoded canonical 5 reusables — Baker-owned per Request-has-no-Files-field contract signal
  6. Harness surface = SurfaceStdout carrying tree SHA — pure-function-returns-hash observable

Substrate discovery: CI-red interlude (9ae59e8) root-caused as apparatus-not-world — bake-oracle.sh depended on passwd gecos for auto-git-identity; dev host had it (masked local), CI container bare root did not (surfaced remote). Classic local-green/CI-red = apparatus + host-masks-gap class. Fix landed harness-only (Go Baker + production build_bake.sh untouched). Reusable diagnosis pattern.

Non-blocking SC carried to #547 (per Surveyor 4585 + Engineer disposition): wc==HEAD clean-staged precondition unenforced. Surveyor reproduced silent tree divergence on violation. Baker.go docstring already frames clean-staged as CALLER-guaranteed → not over-claiming → merge as-is honest. #547 first commit lands the Baker-side fail-loud precondition-check per §5 discipline (milestone #77 named).

Substrate-of-record patterns extending:

  • 5th substrate-check-design-claim-before-pr instance (Engineer framing-verify pre-impl caught the bash-surface centrality)
  • apparatus-not-world diagnosis (local-green/CI-red / host-masks-gap) — reusable class
  • API-client harness-class already banked to Engineer memory; bake extends with SurfaceStdout arm for pure-function-returns-hash scenarios

Cross-references:

  • Depends on: #505 (Baker interface), #503 (harness vehicle from Phase 1)
  • Sibling: #547 (self-bootstrap wiring — will consume this Baker + land the fail-loud precondition-check as first commit)
  • Downstream: Phase 6 orchestrators (#508) fire Baker as part of release-cut flow
  • Cross-phase: #544 v2/next → main merge fires on Phase 5 CLOSE (post-#547 landing)

Phase 5 status: 1/2 core (#546 bake). #547 self-bootstrap next; #544 merge coordination fires on Phase 5 close.

**Closed by hand** — PR#548 merged as `9e77994c90eb3fde39178af95b416838f800a6c1` on v2/next (fast-forward). All 5 ACs ticked with substrate anchors above. **Substrate landed**: - `internal/bake.Baker` PURE throwaway-index implementation (no working-copy mutation per design-call-3 endorsed lean) - marker.go byte-exact kernel (sed-faithful first-per-line + trailing-newline-preserving) - 32-case dual-mode harness empirically PROVES design-call-2: 2 bash mechanisms + Go Baker all yield SAME tree - interface.go UNTOUCHED (no correction needed unlike #541 BranchProtection — contract shape was already right) **All 6 design calls landed as endorsed** (Bosun 28f0): 1. ★ SCOPE #546 vs #547: Baker produces TREE, commit-wrap goes to #547 — verified 2. One phase-invariant tree computation — empirically proven by 32-case dual-mode harness 3. ★ Bake is PURE — throwaway-index, no working-copy mutation 4. Source = RepoDir working copy + write-tree — matches interface docstring 5. File set = hardcoded canonical 5 reusables — Baker-owned per Request-has-no-Files-field contract signal 6. Harness surface = SurfaceStdout carrying tree SHA — pure-function-returns-hash observable **Substrate discovery**: CI-red interlude (9ae59e8) root-caused as **apparatus-not-world** — bake-oracle.sh depended on passwd gecos for auto-git-identity; dev host had it (masked local), CI container bare root did not (surfaced remote). Classic local-green/CI-red = apparatus + host-masks-gap class. Fix landed harness-only (Go Baker + production build_bake.sh untouched). Reusable diagnosis pattern. **Non-blocking SC carried to #547** (per Surveyor 4585 + Engineer disposition): wc==HEAD clean-staged precondition unenforced. Surveyor reproduced silent tree divergence on violation. Baker.go docstring already frames clean-staged as CALLER-guaranteed → not over-claiming → merge as-is honest. #547 first commit lands the Baker-side fail-loud precondition-check per §5 discipline (milestone #77 named). **Substrate-of-record patterns extending**: - 5th `substrate-check-design-claim-before-pr` instance (Engineer framing-verify pre-impl caught the bash-surface centrality) - `apparatus-not-world` diagnosis (local-green/CI-red / host-masks-gap) — reusable class - API-client harness-class already banked to Engineer memory; bake extends with SurfaceStdout arm for pure-function-returns-hash scenarios **Cross-references**: - Depends on: #505 (Baker interface), #503 (harness vehicle from Phase 1) - Sibling: #547 (self-bootstrap wiring — will consume this Baker + land the fail-loud precondition-check as first commit) - Downstream: Phase 6 orchestrators (#508) fire Baker as part of release-cut flow - Cross-phase: #544 v2/next → main merge fires on Phase 5 CLOSE (post-#547 landing) **Phase 5 status**: 1/2 core (#546 bake). #547 self-bootstrap next; #544 merge coordination fires on Phase 5 close.
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#546
No description provided.