carlos / platform Public

settings-3: apply Paul's approved copy and pin it (2026-10-11)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 5ad6aa8f00ff565ebe1e433c057dd08e2e35ca38 parent a558765
3 files changed, +112 −62
  • docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json +30 −0
  • internal/updatewords/words_approved_test.go +79 −36
  • internal/updatewords/words_console.go +3 −26
diff --git a/docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json b/docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json
new file mode 100644
index 000000000..54a2c060a
--- /dev/null
+++ b/docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json
@@ -0,0 +1,30 @@
+{
+ "approved_by": "Paul",
+ "approved_on": "2026-10-11",
+ "entries": [
+ {"id": "settings.console.bad-updates", "file": "internal/updatewords/words_console.go", "text": "updates must be auto or manual"},
+ {"id": "settings.console.bad-major", "file": "internal/updatewords/words_console.go", "text": "major must be a whole number, 0 or more, or empty to clear it"},
+ {"id": "settings.console.major-off-stable", "file": "internal/updatewords/words_console.go", "text": "a major hold applies only to instances on the stable channel. %s is on %s"},
+ {"id": "settings.console.named-unit", "file": "internal/updatewords/words_console.go", "text": "%s is run by its own systemd unit, so it always takes its channel's builds. Update settings do not apply to it"},
+ {"id": "settings.console.not-instance", "file": "internal/updatewords/words_console.go", "text": "update settings apply to instances. %s is a %s route"},
+ {"id": "settings.console.channel-elsewhere", "file": "internal/updatewords/words_console.go", "text": "change the channel with carlos instances set --channel, which applies the app's pipeline rules"},
+ {"id": "settings.console.bad-pin", "file": "internal/updatewords/words_console.go", "text": "%s is not a build version"},
+ {"id": "settings.console.pin-unpromoted", "file": "internal/updatewords/words_console.go", "text": "%s cannot be pinned: it has no promotion record. Pick a newer build, or ask an operator to authorize this one"},
+ {"id": "settings.console.pin-check-failed", "file": "internal/updatewords/words_console.go", "text": "could not check the promotion record of %s. Try again"},
+ {"id": "settings.console.not-enforced", "file": "internal/updatewords/words_console.go", "text": "pin, manual and major can be turned on once every box runs a release that applies them. %d boxes are not ready yet"},
+ {"id": "settings.console.enforcement-unknown", "file": "internal/updatewords/words_console.go", "text": "could not check whether every box applies update settings, so pin, manual and major stay off for now. Try again"},
+ {"id": "settings.console.pinned", "file": "internal/updatewords/words_console.go", "text": "%s is pinned to %s, so Update now would not move it. Clear the pin first"},
+ {"id": "settings.console.fast-track-owner", "file": "internal/updatewords/words_console.go", "text": "only an account owner can skip the safety delay"},
+ {"id": "settings.console.app-keeps", "file": "internal/updatewords/words_console.go", "text": "%s is kept by the app for itself. Ask someone who can change the app's settings"},
+ {"id": "settings.console.no-manifest", "file": "internal/updatewords/words_console.go", "text": "this app does not create instances yet. Run carlos instances enable first"},
+ {"id": "settings.console.unknown-policy-key", "file": "internal/updatewords/words_console.go", "text": "%s is not an app update setting. The app sets instance_control, default_updates, default_channel and default_major; there is no default pin"},
+ {"id": "settings.console.bad-control", "file": "internal/updatewords/words_console.go", "text": "instance_control may name updates, channel, major and pin, each once"},
+ {"id": "settings.console.changed", "file": "internal/updatewords/words_console.go", "text": "this instance changed while the request was in flight. Try again"},
+ {"id": "settings.console.store-failed", "file": "internal/updatewords/words_console.go", "text": "could not save the update settings. Try again"},
+ {"id": "settings.console.read-failed", "file": "internal/updatewords/words_console.go", "text": "could not read this instance. Try again"},
+ {"id": "settings.console.policy-read-failed", "file": "internal/updatewords/words_console.go", "text": "could not read the app's update policy. Try again"},
+ {"id": "settings.console.audit-set", "file": "internal/updatewords/words_console.go", "text": "changed the update settings of %s: %s"},
+ {"id": "settings.console.audit-install", "file": "internal/updatewords/words_console.go", "text": "asked %s to update now (request %d)"},
+ {"id": "settings.console.audit-policy", "file": "internal/updatewords/words_console.go", "text": "changed the instance update policy of %s: %s"}
+ ]
+}
diff --git a/internal/updatewords/words_approved_test.go b/internal/updatewords/words_approved_test.go
index 64aecbb5d..7e73ab107 100644
--- a/internal/updatewords/words_approved_test.go
+++ b/internal/updatewords/words_approved_test.go
@@ -8,57 +8,100 @@ import (
"testing"
)
-// The settings-2 copy Paul approved (2026-10-09). The record must name exactly
-// the IDs of All(), each text must be what Text returns byte for byte, and the
-// CLI docs page must carry the authorize paragraph verbatim.
-func TestApprovedCopyIsApplied(t *testing.T) {
- raw, err := os.ReadFile("../../docs/superpowers/plans/2026-10-07-instance-settings-2-copy.json")
+type approvedEntry struct{ ID, File, Text string }
+
+type approvedRecord struct {
+ ApprovedBy string `json:"approved_by"`
+ ApprovedOn string `json:"approved_on"`
+ Entries []approvedEntry
+}
+
+func loadApproved(t *testing.T, path string) approvedRecord {
+ t.Helper()
+ raw, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
- var rec struct {
- ApprovedBy string `json:"approved_by"`
- ApprovedOn string `json:"approved_on"`
- Entries []struct{ ID, File, Text string }
- }
+ var rec approvedRecord
if err := json.Unmarshal(raw, &rec); err != nil {
t.Fatal(err)
}
- if rec.ApprovedBy == "" || rec.ApprovedOn == "" {
- t.Fatal("the record has no approval")
+ return rec
+}
+
+// The copy Paul approved lives in two records: plan 2's (2026-10-09, the
+// authorize strings) and plan 3's (2026-10-11, the settings.console.*
+// strings). Each record must name exactly its own IDs, each text must be what
+// Text returns byte for byte, each entry must name the file that holds it, and
+// together the two records must name exactly the IDs of All(), so a new draft
+// with no approved record fails.
+func TestApprovedCopyIsApplied(t *testing.T) {
+ const console = "settings.console."
+ records := []struct {
+ path string
+ file string
+ in func(id string) bool
+ }{
+ {"../../docs/superpowers/plans/2026-10-07-instance-settings-2-copy.json",
+ "internal/updatewords/words_authorize.go",
+ func(id string) bool { return !strings.HasPrefix(id, console) }},
+ {"../../docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json",
+ "internal/updatewords/words_console.go",
+ func(id string) bool { return strings.HasPrefix(id, console) }},
}
- var got, want []string
+ var union []string
docs := ""
- for _, e := range rec.Entries {
- got = append(got, e.ID)
- if e.Text == "" {
- t.Errorf("%s: the approved text is empty", e.ID)
- continue
- }
- if e.File != "internal/updatewords/words_authorize.go" {
- t.Errorf("%s: unexpected file %s", e.ID, e.File)
+ for _, r := range records {
+ rec := loadApproved(t, r.path)
+ if rec.ApprovedBy == "" || rec.ApprovedOn == "" {
+ t.Fatalf("%s: the record has no approval", r.path)
}
- if e.ID == "settings.authorize.docs" {
- docs = e.Text
+ var got, want []string
+ seen := map[string]bool{}
+ for _, e := range rec.Entries {
+ got = append(got, e.ID)
+ if seen[e.ID] {
+ t.Errorf("%s: %s appears twice", r.path, e.ID)
+ }
+ seen[e.ID] = true
+ if e.Text == "" {
+ t.Errorf("%s: the approved text is empty", e.ID)
+ continue
+ }
+ if e.File != r.file {
+ t.Errorf("%s: unexpected file %s, want %s", e.ID, e.File, r.file)
+ }
+ if e.ID == "settings.authorize.docs" {
+ docs = e.Text
+ }
+ if !has(e.ID) {
+ continue // reported by the ID comparison below
+ }
+ if txt := Text(e.ID); txt != e.Text {
+ t.Errorf("%s: text is %q, approved %q", e.ID, txt, e.Text)
+ }
}
- if !has(e.ID) {
- continue // reported by the ID comparison below
+ for _, d := range All() {
+ if r.in(d.ID) {
+ want = append(want, d.ID)
+ }
}
- if txt := Text(e.ID); txt != e.Text {
- t.Errorf("%s: text is %q, approved %q", e.ID, txt, e.Text)
+ sort.Strings(got)
+ sort.Strings(want)
+ if strings.Join(got, "\n") != strings.Join(want, "\n") {
+ t.Errorf("%s: record IDs %v, want %v", r.path, got, want)
}
+ union = append(union, got...)
}
+
+ var all []string
for _, d := range All() {
- // Plan 3's settings.console.* drafts get their own approved record after Paul's copy review.
- if strings.HasPrefix(d.ID, "settings.console.") {
- continue
- }
- want = append(want, d.ID)
+ all = append(all, d.ID)
}
- sort.Strings(got)
- sort.Strings(want)
- if strings.Join(got, "\n") != strings.Join(want, "\n") {
- t.Errorf("record IDs %v, want the IDs of All() %v", got, want)
+ sort.Strings(union)
+ sort.Strings(all)
+ if strings.Join(union, "\n") != strings.Join(all, "\n") {
+ t.Errorf("the approved records name %v, want exactly the IDs of All() %v", union, all)
}
if docs == "" {
diff --git a/internal/updatewords/words_console.go b/internal/updatewords/words_console.go
index 71d7a92f9..d4c2e749f 100644
--- a/internal/updatewords/words_console.go
+++ b/internal/updatewords/words_console.go
@@ -1,80 +1,57 @@
package updatewords
// Plan 3's member-facing strings: the console's update settings doors, the
-// install request and the app policy. Every one is a draft until Paul's copy
-// review; plan 3's approved record pins them after that.
+// install request and the app policy. Paul approved every one on 2026-10-11,
+// and docs/superpowers/plans/2026-10-07-instance-settings-3-copy.json pins
+// them. Do not edit a text here without a new copy review.
func init() {
add(
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.bad-updates", Text: "updates must be auto or manual",
Context: "Returned by carlos instances set and the console when updates is anything else."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.bad-major", Text: "major must be a whole number, 0 or more, or empty to clear it",
Context: "Returned when the major hold is not a number."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.bad-pin", Text: "%s is not a build version",
Context: "Returned when the pin is not a build version: not text, or text no build could be named. %s is the value sent, printable characters only, or the word that when none are left."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.major-off-stable", Text: "a major hold applies only to instances on the stable channel. %s is on %s",
Context: "Returned when major is set on an instance that follows another channel. Host, channel."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.pin-unpromoted", Text: "%s cannot be pinned: it has no promotion record. Pick a newer build, or ask an operator to authorize this one",
Context: "Returned when the pin names a build that was never promoted, or was promoted before records existed. %s is the version. Only an operator can run carlos releases authorize."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.pin-check-failed", Text: "could not check the promotion record of %s. Try again",
Context: "Returned when the console could not read or verify the promotion record of the build being pinned. %s is the version."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.not-enforced", Text: "pin, manual and major can be turned on once every box runs a release that applies them. %d boxes are not ready yet",
Context: "Returned when someone turns on pin, manual or major before every box is upgraded. %d is how many boxes are still on an older release. Clearing these settings is always allowed."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.enforcement-unknown", Text: "could not check whether every box applies update settings, so pin, manual and major stay off for now. Try again",
Context: "Returned when someone turns on pin, manual or major and the console could not read which release each box runs. Clearing these settings is always allowed."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.named-unit", Text: "%s is run by its own systemd unit, so it always takes its channel's builds. Update settings do not apply to it",
Context: "Returned for an instance whose process the platform does not start, such as a console. %s is the host."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.not-instance", Text: "update settings apply to instances. %s is a %s route",
Context: "Returned for a static site or a service route. Host, kind."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.channel-elsewhere", Text: "change the channel with carlos instances set --channel, which applies the app's pipeline rules",
Context: "Returned when a request to the settings door names channel. The channel has its own door with passkey and approval rules."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.app-keeps", Text: "%s is kept by the app for itself. Ask someone who can change the app's settings",
Context: "Returned, once instances can act for themselves, when an instance tries to change a setting the app's policy keeps. %s is the setting. Not reachable until instance credentials ship."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.pinned", Text: "%s is pinned to %s, so Update now would not move it. Clear the pin first",
Context: "Returned by carlos instances update and the Update now button on a pinned instance. Host, pinned version."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.fast-track-owner", Text: "only an account owner can skip the safety delay",
Context: "Returned when someone who is not an account owner asks Update now to skip the bake window."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.changed", Text: "this instance changed while the request was in flight. Try again",
Context: "Returned when two people changed the same instance at once and this request lost."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.store-failed", Text: "could not save the update settings. Try again",
Context: "Returned when the console could not write the record."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.read-failed", Text: "could not read this instance. Try again",
Context: "Returned by the update settings doors when the console could not read the instance's record."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.policy-read-failed", Text: "could not read the app's update policy. Try again",
Context: "Returned by the update settings doors when the console could not read the app's instances manifest, which holds its update policy."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.no-manifest", Text: "this app does not create instances yet. Run carlos instances enable first",
Context: "Returned by carlos apps set's update flags for an app with no instance provisioning."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.unknown-policy-key", Text: "%s is not an app update setting. The app sets instance_control, default_updates, default_channel and default_major; there is no default pin",
Context: "Returned by the app policy door for any other key, for example a default pin. %s is the key."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.bad-control", Text: "instance_control may name updates, channel, major and pin, each once",
Context: "Returned by carlos apps set --instance-control for anything else."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.audit-set", Text: "changed the update settings of %s: %s",
Context: "Activity line after a settings change. Host, then what changed, for example updates manual, pin cleared."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.audit-install", Text: "asked %s to update now (request %d)",
Context: "Activity line after Update now. Host, request number."},
- // TODO-COPY: draft, awaiting Paul's copy review
Draft{ID: "settings.console.audit-policy", Text: "changed the instance update policy of %s: %s",
Context: "Activity line after an app policy change. App, then what changed."},
)