carlos / platform Public

README: name plan 4's new listing-failure freeze in the release notes

The per-instance config layer's sweeps now list
apps/<acct>/<app>/instances-config/ before converging an app's routes.
A failed listing (S3 throttling, an IAM prefix-condition change, a
transient 503) freezes every route of that app on its last-good config
file until the listing recovers -- this call did not exist before this
release, and it holds for the whole app, not just routes with an overlay.

Names the log string to grep for and notes that the in-repo IAM policies
grant ListBucket on the whole deployment bucket with no prefix condition,
so platform boxes are unaffected; a hand-edited or self-hosted policy
should be checked before this rolls there.

Final review, plan 4 (tenant email senders, per-instance config layer).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev 47989a2d832ffb92c97420b2eaef8aa36b8f278e parent 823e620
1 file changed, +28 −0
  • README.md +28 −0

CI passed — run details

diff --git a/README.md b/README.md
index e8c1c817a..0386f2718 100644
--- a/README.md
+++ b/README.md
@@ -257,6 +257,34 @@ sender record (design spec `2026-09-15-tenant-email-senders-design.md`).
drops the database's `mail_counts` table. do not set it until the
release after this one has been live for a while.
+### Tenant email senders, plan 4 of 5 (2026-09-22)
+
+This release adds the per-instance config layer (design spec
+`2026-09-15-tenant-email-senders-design.md` §6.2): a third config bundle,
+layered over an app's default and named-environment config, scoped to one
+route's host rather than the whole app.
+
+- a new failure mode comes with this layer. every config sweep now also
+ lists `apps/<acct>/<app>/instances-config/` before it converges that
+ app's routes. s3 throttling, an iam policy change that adds a prefix
+ condition to `s3:ListBucket`, or a transient 503 on that call all look
+ the same from a box: the listing fails, and every route of that app
+ freezes on its last-good config file until the listing succeeds again.
+ this holds for the whole app, not just routes with an overlay of their
+ own, because the listing runs once per app regardless of who uses the
+ layer.
+- grep the box's log for `instance config unresolved` to find it. it
+ prints once per app, naming the account, the app and one route the pass
+ reached. every other route of that app is covered by the same line and
+ the same cause.
+- it clears itself. once the listing succeeds again, the next pass
+ converges normally, with nothing to clean up by hand.
+- the in-repo iam policies grant `s3:ListBucket` on the whole deployment
+ bucket with no prefix condition, so a platform box is unaffected by this
+ on its own account's policy. check a hand-edited or self-hosted
+ deployment's policy before this rolls there, since a narrower grant is
+ exactly what would trip it.
+
## App config & secrets
Per-app config lives in the deployment bucket