carlos / platform Public

hostrelocate: a configured key's adoption record again needs the env item present and readable, and adoptedKey names the residual that a source with no env file refuses because platform items have no tombstone

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev a8dbe34211e2f7092bd24dc3fca65c2e0340c2c3 parent bd4d935
2 files changed, +15 −18
  • internal/hostrelocate/pin.go +8 −7
  • internal/hostrelocate/pin_envkey_test.go +7 −11
diff --git a/internal/hostrelocate/pin.go b/internal/hostrelocate/pin.go
index 272031c63..60ea0393b 100644
--- a/internal/hostrelocate/pin.go
+++ b/internal/hostrelocate/pin.go
@@ -488,15 +488,16 @@ func (p StorePinner) adoptedKey(ctx context.Context, writer instancekey.Binding,
return nil, err
}
own, _ := instancekey.Effective(nil, instancekey.ParseEnv(env))
- // A configured key needs positive evidence that the own file supplies
- // none: the env item with no key of its own, or the release flush's
- // deletion entry for it. An env item never published is not evidence
- // that nothing overrides the configuration (absence is never evidence).
- envEntry, listed := m.Platform[hostfiles.EnvItem]
- envDeleted := listed && envEntry.Deleted
+ // A configured key needs the env item, present and readable, with no
+ // key of its own: a manifest without host.env is not evidence that
+ // nothing overrides the configuration (absence is never evidence).
+ // Residual: a source with no <host>.env and a configured key refuses,
+ // because platform items have no tombstone (StagePlatformDelete drops
+ // the item), so a deleted env reads as one never published. That is
+ // rare: <host>.env holds CARLOS_ADMIN_TOKEN on every exec instance.
switch {
case a.Source == instancekey.SourcePlatform && own != "" && instancekey.Digest(own) == a.SHA256:
- case a.Source == instancekey.SourceConfig && (haveEnv || envDeleted) && own == "":
+ case a.Source == instancekey.SourceConfig && haveEnv && own == "":
default:
return refuse("its adoption record does not name the key the env delivers")
}
diff --git a/internal/hostrelocate/pin_envkey_test.go b/internal/hostrelocate/pin_envkey_test.go
index b6b8ff7f8..8659750bd 100644
--- a/internal/hostrelocate/pin_envkey_test.go
+++ b/internal/hostrelocate/pin_envkey_test.go
@@ -127,11 +127,11 @@ func TestStorePinnerKeyEvidence(t *testing.T) {
var errUnreadable = errors.New("sentinel: any read error")
-// A configured key's record vouches only beside positive evidence that the
-// instance's own file supplies no key: the env item with no key of its
-// own, or the release flush's deletion entry for it. A manifest that never
-// published host.env is not evidence that nothing overrides the
-// configuration at launch (absence is never evidence): the pin refuses.
+// A configured key's record vouches only beside the env item that shows
+// the instance's own file supplies no key. A manifest without host.env is
+// not evidence that nothing overrides the configuration at launch (absence
+// is never evidence): the pin refuses, and the same record beside an env
+// item with no key of its own pins.
func TestStorePinnerConfigRecordNeedsTheEnvItem(t *testing.T) {
ctx := context.Background()
at := time.Date(2026, 10, 7, 9, 0, 0, 0, time.UTC)
@@ -139,12 +139,11 @@ func TestStorePinnerConfigRecordNeedsTheEnvItem(t *testing.T) {
record := string(instancekey.AdoptionRecord(writer, instancekey.SourceConfig, instancekey.Digest("configured-A")))
for _, tc := range []struct {
name string
- env string // "", "item" or "deleted"
+ env string // "" or "item"
want error
}{
{"an env item never published", "", ErrFilesUnevidenced},
{"an env item with no key of its own", "item", nil},
- {"the flush's deletion entry for the env item", "deleted", nil},
} {
t.Run(tc.name, func(t *testing.T) {
claims, data := release.NewDirStore(t.TempDir()), release.NewDirStore(t.TempDir())
@@ -161,11 +160,8 @@ func TestStorePinnerConfigRecordNeedsTheEnvItem(t *testing.T) {
m.Platform[name] = hostfiles.Entry{Object: obj, SHA256: sha, Size: int64(len(body)), Mode: 0o600, Seq: 4}
}
item(instancekey.AdoptionItem, record)
- switch tc.env {
- case "item":
+ if tc.env == "item" {
item(hostfiles.EnvItem, "CARLOS_ADMIN_TOKEN=t\n")
- case "deleted":
- m.Platform[hostfiles.EnvItem] = hostfiles.Entry{Seq: 4, Deleted: true}
}
putManifest(t, data, "g3", m)
p := StorePinner{Claims: claims, Data: data, Release: routeRelease, Bucket: "data", Region: "ie", SelectDB: selectAt(41)}