Adds docs/decisions/labels-and-abuse.md — a documented decision (ADR) with concrete, implementable values. Doc-only; no code or labels created (creating the labels is #14's implementation job).
Decisions
GitHub labels applied to every auto-published issue on JMR-dev/LibreMail (all three; #14 must create any that are missing — none exist today):
bug-report — origin marker: came from the app's opt-in debug ingest pipeline (distinct from the human-triaged bug).
automated — provenance: created by the weekly publish job, not a human.
needs-triage — workflow state: not yet reviewed; maintainer clears it.
50 issues/run cap, oldest-first, alert on cap hit.
Serial creation, 1s spacing, honour Retry-After, exponential backoff (base 1s, cap 60s, full jitter, max 5 attempts/issue), mark-published-only-on-confirmed-201 for de-dup. Sits well under GitHub primary (5k/h) and secondary content-creation limits.
Plus a "Consequences" section and a short list of values for the maintainer to confirm at review (three labels vs. leaner set; 256 KiB; per-IP numbers; 50/run cap + alert destination).
Adds `docs/decisions/labels-and-abuse.md` — a documented decision (ADR) with concrete, implementable values. Doc-only; no code or labels created (creating the labels is #14's implementation job).
## Decisions
**GitHub labels** applied to every auto-published issue on `JMR-dev/LibreMail` (all three; #14 must create any that are missing — none exist today):
- `bug-report` — origin marker: came from the app's opt-in debug ingest pipeline (distinct from the human-triaged `bug`).
- `automated` — provenance: created by the weekly publish job, not a human.
- `needs-triage` — workflow state: not yet reviewed; maintainer clears it.
**Ingest endpoint (informs #7):**
- Payload cap **256 KiB** (`Content-Length` fast-path + streamed hard cap) → **413**.
- Per-IP rate limit: **>15 req/60s** (block 10 min) and **>100 req/1h** (block 1h) → **429 + `Retry-After`**; optional global 1,000/h shed → 503.
- Mechanism: **Cloudflare Rate Limiting rules via Pulumi** (edge, pre-Worker, fits existing IaC); DO token-bucket / Workers rate-limit binding documented as alternatives; KV rejected (eventually consistent). Worker still owns size + schema checks.
- Response contract: 202 accepted / 400 malformed / 413 too large / 415 wrong type / 405 wrong method / 429 rate-limited / 500 / 503, plus client retry rules.
**Weekly publish job (#14):**
- **50 issues/run** cap, oldest-first, alert on cap hit.
- Serial creation, **1s spacing**, honour `Retry-After`, exponential backoff (base 1s, cap 60s, full jitter, **max 5 attempts/issue**), mark-published-only-on-confirmed-201 for de-dup. Sits well under GitHub primary (5k/h) and secondary content-creation limits.
Plus a "Consequences" section and a short list of values for the maintainer to confirm at review (three labels vs. leaner set; 256 KiB; per-IP numbers; 50/run cap + alert destination).
Closes #6
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds
docs/decisions/labels-and-abuse.md— a documented decision (ADR) with concrete, implementable values. Doc-only; no code or labels created (creating the labels is #14's implementation job).Decisions
GitHub labels applied to every auto-published issue on
JMR-dev/LibreMail(all three; #14 must create any that are missing — none exist today):bug-report— origin marker: came from the app's opt-in debug ingest pipeline (distinct from the human-triagedbug).automated— provenance: created by the weekly publish job, not a human.needs-triage— workflow state: not yet reviewed; maintainer clears it.Ingest endpoint (informs #7):
Content-Lengthfast-path + streamed hard cap) → 413.Retry-After; optional global 1,000/h shed → 503.Weekly publish job (#14):
Retry-After, exponential backoff (base 1s, cap 60s, full jitter, max 5 attempts/issue), mark-published-only-on-confirmed-201 for de-dup. Sits well under GitHub primary (5k/h) and secondary content-creation limits.Plus a "Consequences" section and a short list of values for the maintainer to confirm at review (three labels vs. leaner set; 256 KiB; per-IP numbers; 50/run cap + alert destination).
Closes #6