carlos / platform Public

console: read-only retention line on the Releases tab

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell ace4de0d216f90d47da54abf22f4588f92819398 parent 85d8135
2 files changed, +16 −4
  • internal/console/server.go +12 −4
  • internal/console/templates/app_releases.html +4 −0
diff --git a/internal/console/server.go b/internal/console/server.go
index d249e3c39..8d8a9eb69 100644
--- a/internal/console/server.go
+++ b/internal/console/server.go
@@ -446,10 +446,11 @@ type page struct {
Flash string // one-shot success notice (cookie-carried across a redirect)
FlashErr string // one-shot error notice
- Apps []appRow // account home
- Detail *AppView // /a/{sqid}/apps/{app}
- Versions []VersionView // app page: shipped releases, newest first
- Tags []release.Tag // releases tab: every tag this app has cut, changelog and all
+ Apps []appRow // account home
+ Detail *AppView // /a/{sqid}/apps/{app}
+ Versions []VersionView // app page: shipped releases, newest first
+ Tags []release.Tag // releases tab: every tag this app has cut, changelog and all
+ RetentionKeep int // releases tab: >0 when an ambient retention policy is set (spec 2026-08-10-releases-retention-design.md §7)
// ReleaseSummary is the Releases tab's lede strip: what is live and
// what is next, folded from Detail.Channels once the tab has them.
ReleaseSummary ReleaseSummary
@@ -1564,6 +1565,13 @@ func (s *Server) handleAppReleases(w http.ResponseWriter, r *http.Request) {
p.Tags = tags
}
p.Versions = versions
+ // Read-only in v1: the policy is set via `carlos releases retention`;
+ // this line just keeps the page honest about why old versions vanish.
+ if ret, err := release.GetRetention(r.Context(), s.cfg.Releases, acct.Sqid, p.AppName); err != nil {
+ log.Printf("console: retention %s: %v", p.AppName, err)
+ } else if ret != nil {
+ p.RetentionKeep = ret.Keep
+ }
// The "how do I give this a URL" copy — not shared chrome (it's computed
// per app page, not carried by appPage), but the same fill the Instances
// tab's empty state shows: attachHint below.
diff --git a/internal/console/templates/app_releases.html b/internal/console/templates/app_releases.html
index 6c8074365..d26a8a4ad 100644
--- a/internal/console/templates/app_releases.html
+++ b/internal/console/templates/app_releases.html
@@ -38,6 +38,10 @@
</section>
{{end}}
+{{if .RetentionKeep}}
+<p class="small">Retention: the newest {{.RetentionKeep}} releases are kept; older releases not promoted, tagged, or recently shipped are pruned automatically.</p>
+{{end}}
+
{{if .Versions}}
<details class="reveal" open>
<summary>All versions ({{len .Versions}})</summary>