···11+# ATCR Hold Service Quota Configuration
22+# Copy this file to quotas.yaml to enable quota enforcement.
33+# If quotas.yaml doesn't exist, quotas are disabled (unlimited for all users).
44+55+# Berths define quota tiers using nautical crew ranks.
66+# Each berth has a quota limit specified in human-readable format.
77+# Supported units: B, KB, MB, GB, TB, PB (case-insensitive)
88+berths:
99+ # Entry-level crew - suitable for new or casual users
1010+ deckhand:
1111+ quota: 5GB
1212+1313+ # Mid-level crew - for regular contributors
1414+ bosun:
1515+ quota: 50GB
1616+1717+ # Senior crew - for power users or trusted contributors
1818+ quartermaster:
1919+ quota: 100GB
2020+2121+ # You can add custom berths with any name:
2222+ # unlimited_crew:
2323+ # quota: 1TB
2424+2525+defaults:
2626+ # Default berth assigned to new crew members who don't have an explicit berth.
2727+ # This berth must exist in the berths section above.
2828+ new_crew_berth: deckhand
2929+3030+# Notes:
3131+# - The hold captain (owner) always has unlimited quota regardless of berths.
3232+# - Crew members can be assigned a specific berth in their crew record.
3333+# - If a crew member's berth doesn't exist in config, they fall back to the default.
3434+# - Quota is calculated per-user by summing unique blob sizes (deduplicated).
3535+# - Quota is checked when pushing manifests (after blobs are already uploaded).
+41-6
docs/QUOTAS.md
···507507- Email/webhook notifications
508508- Grace period before hard enforcement
509509510510-### 3. Tiered Quotas
510510+### 3. Berth-Based Quotas (Implemented)
511511+512512+ATCR uses nautical-themed "berths" for quota tiers, configured via `quotas.yaml`:
513513+514514+```yaml
515515+# quotas.yaml
516516+berths:
517517+ deckhand: # Entry-level crew
518518+ quota: 5GB
519519+ bosun: # Mid-level crew
520520+ quota: 50GB
521521+ quartermaster: # High-level crew
522522+ quota: 100GB
523523+524524+defaults:
525525+ new_crew_berth: deckhand # Default berth for new crew members
526526+```
527527+528528+| Berth | Limit | Description |
529529+|-------|-------|-------------|
530530+| deckhand | 5 GB | Entry-level crew member |
531531+| bosun | 50 GB | Mid-level crew member |
532532+| quartermaster | 100 GB | Senior crew member |
533533+| owner (captain) | Unlimited | Hold owner always has unlimited |
511534512512-| Tier | Limit |
513513-|------|-------|
514514-| Free | 10 GB |
515515-| Pro | 100 GB |
516516-| Enterprise | Unlimited |
535535+**Berth Resolution:**
536536+1. If user is captain (owner) → unlimited
537537+2. If crew member has explicit berth → use that berth's limit
538538+3. If crew member has no berth → use `defaults.new_crew_berth`
539539+4. If default berth not found → unlimited
540540+541541+**Crew Record Example:**
542542+```json
543543+{
544544+ "$type": "io.atcr.hold.crew",
545545+ "member": "did:plc:alice123",
546546+ "role": "writer",
547547+ "permissions": ["blob:write"],
548548+ "berth": "bosun",
549549+ "addedAt": "2026-01-04T12:00:00Z"
550550+}
551551+```
517552518553### 4. Rate Limiting
519554
···11+# ATCR Hold Service Quota Configuration
22+# Copy this file to quotas.yaml to enable quota enforcement.
33+# If quotas.yaml doesn't exist, quotas are disabled (unlimited for all users).
44+55+# Berths define quota tiers using nautical crew ranks.
66+# Each berth has a quota limit specified in human-readable format.
77+# Supported units: B, KB, MB, GB, TB, PB (case-insensitive)
88+berths:
99+ # Entry-level crew - suitable for new or casual users
1010+ deckhand:
1111+ quota: 5GB
1212+1313+ # Mid-level crew - for regular contributors
1414+ bosun:
1515+ quota: 50GB
1616+1717+ # Senior crew - for power users or trusted contributors
1818+ quartermaster:
1919+ quota: 100GB
2020+2121+ # You can add custom berths with any name:
2222+ # unlimited_crew:
2323+ # quota: 1TB
2424+2525+defaults:
2626+ # Default berth assigned to new crew members who don't have an explicit berth.
2727+ # This berth must exist in the berths section above.
2828+ new_crew_berth: deckhand
2929+3030+# Notes:
3131+# - The hold captain (owner) always has unlimited quota regardless of berths.
3232+# - Crew members can be assigned a specific berth in their crew record.
3333+# - If a crew member's berth doesn't exist in config, they fall back to the default.
3434+# - Quota is calculated per-user by summing unique blob sizes (deduplicated).
3535+# - Quota is checked when pushing manifests (after blobs are already uploaded).