carlos / platform Public

settings-2: reconcile with main (held-stage authorization on the claim path)

Main's MaterializeHeldUnder (moves Plan 3 Task 5) is a new held staging
entry point. The merge routes it through stageHeld, so HeldAuthorized
answers first and the stage binds its digest. This pins it: a
never-promoted build is ErrHeldNotAuthorized and a replayed record over
other bytes is ErrManifestDigest, with no artifact read, nothing staged,
no selection entered and live/<host> untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev cf58b27b99b46f659ce3165dc08db0c6a8c3056f parent 04d5e38
1 file changed, +74 −0
  • internal/release/materializeheld_claim_test.go +74 −0

CI passed — run details

diff --git a/internal/release/materializeheld_claim_test.go b/internal/release/materializeheld_claim_test.go
index 2119b14d4..0601dcafe 100644
--- a/internal/release/materializeheld_claim_test.go
+++ b/internal/release/materializeheld_claim_test.go
@@ -3,6 +3,8 @@ package release
import (
"context"
"errors"
+ "os"
+ "strings"
"testing"
"github.com/carlosframework/platform/internal/hostwrite"
@@ -69,3 +71,75 @@ func TestMaterializeHeldUnderRefusals(t *testing.T) {
t.Fatal("a row no move holds was staged")
}
}
+
+// Settings spec rev 11 §4.3a on the claim path: MaterializeHeldUnder stages
+// only a build a promotion record or a ratchet-admitted pointer authorizes,
+// bound to that digest. A build nothing authorizes, or a replayed record over
+// other bytes under the same name, is refused before an artifact byte is read
+// or written: nothing staged, no selection entered, live/<host> untouched.
+func TestMaterializeHeldUnderStagesOnlyAnAuthorizedBuild(t *testing.T) {
+ t.Run("nothing authorizes it", func(t *testing.T) {
+ ctx, s, opt := heldFixture(t)
+ t.Setenv("CARLOS_HOST_CLAIM", "1")
+ shipRelease(t, s, "bab", "console", "v3", adoptPlatform, []byte("shipped, never promoted"))
+ rec := &heldRecordingStore{Store: s}
+ work := &heldClaimWork{}
+ if _, err := MaterializeHeldUnder(ctx, rec, heldPub, nr(t), opt, heldRoute(), "v3", offGate(t), work, nil); !errors.Is(err, ErrHeldNotAuthorized) {
+ t.Fatalf("MaterializeHeldUnder of a never-promoted build = %v; want ErrHeldNotAuthorized", err)
+ }
+ heldClaimNothingStaged(t, rec, work, opt, "v3", false)
+ })
+ t.Run("a replayed record over other bytes", func(t *testing.T) {
+ ctx, s, opt := heldFixture(t)
+ t.Setenv("CARLOS_HOST_CLAIM", "1")
+ saved, _, err := s.Get(ctx, PromotionRecordKey("bab", "console", "v1"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := DeleteVersion(ctx, s, "bab", "console", "v1"); err != nil {
+ t.Fatal(err)
+ }
+ shipRelease(t, s, "bab", "console", "v1", adoptPlatform, []byte("nobody promoted these"))
+ if _, err := s.Put(ctx, PromotionRecordKey("bab", "console", "v1"), saved, ""); err != nil {
+ t.Fatal(err)
+ }
+ rec := &heldRecordingStore{Store: s}
+ work := &heldClaimWork{}
+ if _, err := MaterializeHeldUnder(ctx, rec, heldPub, nr(t), opt, heldRoute(), "v1", offGate(t), work, nil); !errors.Is(err, ErrManifestDigest) {
+ t.Fatalf("MaterializeHeldUnder under a replayed record = %v; want ErrManifestDigest", err)
+ }
+ heldClaimNothingStaged(t, rec, work, opt, "v1", true)
+ })
+}
+
+// heldClaimNothingStaged fails the test if a claim-path held stage of version
+// read its artifact, staged it, entered the selection or pointed live/<host>.
+// manifestRead says whether the stage was allowed to read the manifest (to
+// check a digest) before refusing.
+func heldClaimNothingStaged(t *testing.T, rec *heldRecordingStore, work *heldClaimWork, opt, version string, manifestRead bool) {
+ t.Helper()
+ rel := ReleasesPrefix("bab", "console") + version + "/"
+ manifest := ManifestKey("bab", "console", version)
+ rec.mu.Lock()
+ for _, c := range rec.calls {
+ key, ok := strings.CutPrefix(c, "get ")
+ if !ok || !strings.HasPrefix(key, rel) {
+ continue
+ }
+ if manifestRead && key == manifest {
+ continue
+ }
+ rec.mu.Unlock()
+ t.Fatalf("the refused held stage read %s", key)
+ }
+ rec.mu.Unlock()
+ if _, err := os.Stat(VersionPath(opt, "bab", version, "console")); err == nil {
+ t.Fatalf("%s was staged", version)
+ }
+ if len(work.ids) != 0 {
+ t.Fatalf("the refused held stage entered the selection under %v", work.ids)
+ }
+ if got, _ := LiveVersion(opt, heldTestHost); got != "" {
+ t.Fatalf("live/<host> names %q", got)
+ }
+}