Primary finding
`bucket.grant_read(fn)` grants Lambda read on the entire bucket while only `dashboard/*` is public — fine, but `grant_put` scoped only to `dashboard/*` means feedback.csv writes will be denied
- infra/stack.py:138-141
- infra/stack.py:101-102
The Lambda env declares `S3_FEEDBACK_KEY=geo-signals/feedback.csv`, implying the agent writes feedback CSV under the `geo-signals/` prefix. However, `grant_put` is scoped only to `dashboard/*`, so any `PutObject` to `geo-signals/feedback.csv` will be denied with AccessDenied at runtime. Unless the feedback file is only ever read (never written) by Lambda, this is a runtime authorization bug.
Recommendation
If Lambda writes feedback, add `bucket.grant_put(fn, "geo-signals/*")` (or use `grant_read_write` scoped appropriately). If Lambda only reads feedback, document that and remove the misleading env var implication.