// The healthy history — builds this box has run well (spec // 2026-10-06-console-release-defences-design.md §4.5). A sha256 in an app's // history is adopted with no proof, which is what lets a requiring box roll // back to a build it ran before without waiting on the prover. // // Root writes it from two places in internal/host: when D1's settle check // passes for a restarted named unit (How "settle"), and when a root pass finds // a named-unit route's live build bound, active in one invocation for the // policy's after, hashed from its running executable and ready (How "live"). // Every sha256 here was hashed from bytes, never copied from a manifest. It // lives in the bake directory, which the sandboxed agent can read. package release import ( "encoding/json" "fmt" "log" "path/filepath" "time" "github.com/carlosframework/platform/internal/safefile" ) const healthyMax = 50 type HealthyBuild struct { SHA256 string `json:"sha256"` Version string `json:"version,omitempty"` How string `json:"how"` At time.Time `json:"at"` } type healthyFile struct { Schema int `json:"schema"` Builds []HealthyBuild `json:"builds"` } func healthyPath(bakeDir, acct, app string) (string, error) { if bakeDir == "" || !ValidAccount(acct) || !ValidApp(app) { return "", fmt.Errorf("healthy history: invalid %q/%q", acct, app) } return filepath.Join(bakeDir, "healthy", acct, app+".json"), nil } func ReadHealthy(bakeDir, acct, app string) []HealthyBuild { if bakeDir == RootHealthyDir { return readRootHealthy(acct, app) } p, err := healthyPath(bakeDir, acct, app) if err != nil { return nil } b, err := safefile.ReadFile(p) if err != nil { return nil } var f healthyFile if err := json.Unmarshal(b, &f); err != nil || f.Schema != 1 { log.Printf("healthy history: %s does not parse (%v), treating it as empty", p, err) return nil } return f.Builds } func IsHealthy(bakeDir, acct, app, sha string) bool { if sha == "" { return false } for _, b := range ReadHealthy(bakeDir, acct, app) { if b.SHA256 == sha { return true } } return false } // RecordHealthy adds b, newest first, keeping the first record of a sha256 // and the newest healthyMax builds. Written atomically and world-readable, // because the reader is the sandboxed agent. func RecordHealthy(bakeDir, acct, app string, b HealthyBuild) error { if bakeDir == RootHealthyDir { return recordRootHealthy(acct, app, b) } p, err := healthyPath(bakeDir, acct, app) if err != nil { return err } if !sha256Re.MatchString(b.SHA256) { return fmt.Errorf("healthy history: sha256 %q is not 64 lower-case hex digits", b.SHA256) } have := ReadHealthy(bakeDir, acct, app) for _, h := range have { if h.SHA256 == b.SHA256 { return nil } } builds := append([]HealthyBuild{b}, have...) if len(builds) > healthyMax { builds = builds[:healthyMax] } body, err := json.MarshalIndent(healthyFile{Schema: 1, Builds: builds}, "", " ") if err != nil { return err } if err := safefile.MkdirAll(filepath.Dir(p), 0o755); err != nil { return err } return safefile.WriteFile(p, append(body, '\n'), 0o644) }