Pull Request已成功合入, 合并人@urandon
(感谢 urandon 的贡献)[P1] Origin-only jobs cannot complete. AdmitDispatch now creates a WorkerJob with only Origin, but worker completion still always constructs a TelegramDeliveryOutbox; PutTelegramDeliveryOutbox rejects zero ChatID/ReplyToMessageID. Any canonical frontend run will execute and then fail terminal commit/retry/dead-letter. Gate these dispatches until result projection exists, or add a canonical completion path.


[P1] Deduplication after /new is broken. The stable idempotency key is reused, but the origin and Object Storage prefix are rebuilt from the current session/binding revision. A delayed duplicate after a binding switch therefore writes new refs and fails the store's exact Payload/Origin checks with ErrEventIdempotencyConflict instead of returning the original result. Resolve the dedup record before writing objects, or reuse the original persisted refs and origin.


[P2] An idempotency hit bypasses authorization. This branch returns before authorizeTenantWriteTx and authorizeSessionWriteTx, so a revoked tenant member or removed session participant can replay an old request and still receive a successful result. The documented contract requires current membership and writable participation even when the dedup row exists; perform those checks before this early return, while keeping the delayed-duplicate binding-revision exception.


[P1] Concurrent retries can overwrite the canonical blob. Both requests derive the same event/run IDs and object prefix here, then each calls BlobStore.Put before the YDB dedup transaction. PutObject is unconditional (and the in-memory store overwrites too), so a loser with a different payload can replace message.json or an attachment after the winner commits; the stored BlobRef.SHA256 then no longer describes the bytes read from Object Storage. Use content-addressed/staging keys with conditional create, or verify the existing object digest before allowing the retry.


Outcome
Implements SESSION-03: authenticated frontends can create or switch canonical sessions and atomically ingest a canonical user event plus its first workload records without transport-specific IDs in the ingress contract.
What changed
Verification
The merged-main CI for prerequisite !22 is green: GitHub Actions run #67 on 2aa2c7f.
Closes #22.