mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-09 16:35:27 +02:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The telemetry subsystem (`packages/shared/src/telemetry`) flushes event batches to an ingest endpoint; today the client drops batches silently on 429 / 413 / 400 / network error with no re-queue and no retry > - The current behaviour is uncharacterised — there are no regression tests pinning it, so any future retry work could accidentally change the drop semantics without a test failing > - Before adding retry logic it is critical to lock the current baseline as an explicit, documented contract so regressions are immediately visible > - Additionally, the retry/cap design needs a config surface (`maxEventsPerBatch`, `maxBodyBytes`, `maxPendingRetryBatches`, `backoff`) so operators can tune behaviour without forking; that surface should be defined and defaulted before the first consumer lands, not after > - This pull request adds characterisation tests that pin today's silent-drop baseline and adds an optional, additive config surface with resolved defaults — `client.ts` is untouched so no behaviour changes > - The benefit is that the retry work in the follow-up PR can build on a verified baseline, safe defaults, and a pre-wired config contract rather than specifying everything at once ## Linked Issues or Issue Description No pre-existing public GitHub issue. Underlying problem described below (feature-request template). **Problem or motivation** The telemetry client in `packages/shared/src/telemetry/client.ts` has no regression tests covering its error-path semantics. On 429 / 413 / 400 / network failure the current code drains the whole queue via `splice(0)` and discards the batch — silent drop, no retry. That behaviour is correct for a best-effort client today, but nothing verifies it. When retry logic lands, there is no safety net to confirm it does not accidentally re-queue already-dropped batches. In parallel, the retry design requires a typed config surface (`maxEventsPerBatch`, `maxBodyBytes`, `maxPendingRetryBatches`, `backoff`) that the client and its callers need to agree on before the first consumer is wired up. **Proposed solution** Two-phase additive scaffolding: 1. Lock the silent-drop baseline as pinned tests (temporary; Impl-2 replaces them when retry lands). 2. Add the config surface and defaults now so Impl-2 can consume them immediately. **Alternatives considered** Writing the tests and config surface inside the retry PR — rejected because it makes the retry diff much harder to review and loses the regression-safety benefit of a committed baseline. **Roadmap alignment** Maintenance / client-correctness improvement; not a core roadmap feature. ## What Changed - **`client.test.ts`** — 5 new Phase-1 characterisation tests pinning silent-drop on 429, 413, 400, and network-error. A `stubFetchStatus(status)` helper DRYs the four drop cases. These are temporary regression anchors: marked `TODO(impl-2): replace when retry lands`. - **`config.ts`** — `TELEMETRY_DEFAULTS` constant (frozen) + `resolveCaps()` + `resolveTelemetryConfig()`. Provides a single exported source of truth for defaults; nothing reads these yet. - **`types.ts`** — 4 optional, additive `TelemetryConfig` fields: `maxEventsPerBatch` (default 50), `maxBodyBytes` (default 524 288), `maxPendingRetryBatches` (default 20), `backoff` (exp-with-jitter shape). All optional and backward-compatible. - **`index.ts`** — re-exports `TELEMETRY_DEFAULTS` and `resolveTelemetryConfig` from the public package surface. - **`client.ts`** — no changes (verified via `git diff --stat`). ## Verification ```bash # Unit tests — 16 passed (5 new Phase-1 pins + 2 new Phase-2 config tests + 9 existing) pnpm --filter @paperclipai/shared exec vitest run src/telemetry # Type check — clean pnpm --filter @paperclipai/shared typecheck # Confirm client.ts untouched (zero output expected) git diff HEAD~1 -- packages/shared/src/telemetry/client.ts ``` All three commands verified locally before push. ## Risks **Low risk.** `client.ts` is untouched — no behaviour change. All four modified files are additive: - New tests cannot regress production behaviour. - New config fields are `optional` and their defaults match the current implicit constants in `client.ts`, so any future reader gets identical semantics until it overrides them. - `resolveTelemetryConfig` replaces no existing function; it is new. - No envelope / wire change; no new PII / crypto / sink. The `TODO(impl-2)` markers on the Phase-1 pins make their temporary nature explicit in code. ## Model Used - **Provider:** Anthropic - **Model:** Claude Sonnet 4.6 (`claude-sonnet-4-6`) - **Context window:** 200k tokens - **Capabilities:** Tool use, code execution, agentic task completion via Paperclip agent SDK - **Mode:** Standard (no extended thinking) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Harold Kim <harold@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing>