Files (per-file cap), secrets (64 KB default), and email (25 MB default)
already enforce limits; kv::set, docs::create/update, pubsub::publish_durable
and queue::enqueue accepted any JSON value straight to a JSONB column with
no size validation. An anonymous public-HTTP script could fill disk via
queue::enqueue or amplify a single publish into N outbox rows × payload bytes.
Adds four new error variants:
- KvError::ValueTooLarge { limit, actual }
- DocsError::ValueTooLarge { limit, actual }
- PubsubError::MessageTooLarge { limit, actual }
- QueueError::PayloadTooLarge { limit, actual }
Each stateful service grows a `max_value_bytes` field with:
- Conservative 256 KB default (DEFAULT_KV_MAX_VALUE_BYTES etc.).
- New `with_max_*` constructor preserving the old `new()` signature.
- Env-knob reader (`*_max_*_from_env()`) — mirrors SecretsConfig::from_env.
Validation runs at the entry point BEFORE authz so an anonymous DoS doesn't
pay a membership lookup per attempt.
Wired via env knobs:
- PICLOUD_KV_MAX_VALUE_BYTES
- PICLOUD_DOCS_MAX_VALUE_BYTES
- PICLOUD_PUBSUB_MAX_MESSAGE_BYTES
- PICLOUD_QUEUE_MAX_PAYLOAD_BYTES
Documented in CLAUDE.md runtime config table.
New unit test in queue_service verifying the cap fires before authz.
AUDIT.md anchor: F-S-001. Depends on F-Q-004 (Backend variant).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Migrations 0013_docs.sql + 0014_docs_triggers.sql land the docs table
(JSONB body + GIN-on-jsonb_path_ops index, PK keyed on (app_id,
collection, id) for cross-app isolation) and widen the triggers.kind
and outbox.source_kind CHECK constraints to include 'docs', plus the
docs_trigger_details detail table mirroring kv_trigger_details.
picloud-shared grows the DocsService trait + DocRow/DocsListPage/
DocsError + NoopDocsService, the TriggerEvent::Docs variant with the
prev_data change-data-capture surface, the DocsEventOp enum, the docs
field on the Services bundle, and the SDK_VERSION bump 1.2 -> 1.3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>