mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-31 06:04:11 +01:00
<!-- entire-trail-link-start --> https://entire.com/gh/paperclipai/-/trails/48/changes/paperclip/48 <!-- entire-trail-link-end --> ## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The server can export manual OpenTelemetry startup spans through `server/src/instrumentation.ts` (`resolveProtocol` plus the `getStartupTracer` / `getStartupTraceContext` accessors). > - Two suites covered that one module in every server Vitest run: `server/src/instrumentation.test.ts` (unit cases added with the manual-span seam in #10565) and `server/src/__tests__/instrumentation.test.ts` (the bootstrap machinery from #3735/#12249). > - `resolveProtocol` and the startup tracer accessors were registered twice per run with overlapping but unequal tables, so the same contracts were executed by two files while each held a few unique rows the other lacked. > - This pull request moves the unique assertions into the `__tests__` owner and retires the colocated file, so one suite exercises the full contract once. > - The benefit is one fewer suite registration per server run and one less duplicated unit surface to maintain, with no lost assertion. ## Linked Issues or Issue Description **What happened?** The server Vitest project ran two test files against `server/src/instrumentation.ts`. Both registered `resolveProtocol` and startup-tracer accessor cases. The colocated file held unique coverage (protocol input trimming, warn-once, the `getStartupTraceContext` accessor, the `setAttribute`/`setStatus` span surface) while the `__tests__` file held the bootstrap, peer-version, shutdown, and span-recording coverage. The split duplicated executions and made the contract's owner ambiguous. **Expected behavior** One suite (`server/src/__tests__/instrumentation.test.ts`) owns every `server/src/instrumentation.ts` unit contract. Every assertion from the retired file still runs, inside the owner. No production code changes. ## What Changed - Retired `server/src/instrumentation.test.ts` after migrating its unique assertions into `server/src/__tests__/instrumentation.test.ts`. - Added the `OTEL_EXPORTER_OTLP_PROTOCOL=" HTTP/PROTOBUF "` row, proving surrounding space is trimmed (previously only the letter-case row existed). - Strengthened the unknown-protocol case to assert the warning fires exactly once. - Extended the no-op tracer case to exercise `setAttribute` and `setStatus` before `end`. - Added the `getStartupTraceContext` accessor case (tracer surface plus the `contextWithSpan` helper), previously covered only by the retired file. Six production callers use this seam (heartbeat runtime execution, native run trace, duplex observability recorder, and others). ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/instrumentation.test.ts` — 21 passed, 2 skipped (SDK-gated span-recording cases skip without `@opentelemetry/*`, as before). The two new/extended cases pass inside the owner. - Deliberate failure controls, both restored byte-exact afterward and re-run green: - removing `.trim()` from `resolveProtocol` made exactly the migrated `" HTTP/PROTOBUF "` row fail; - making the no-op `contextWithSpan` throw made exactly the migrated accessor case fail. - The retired file's six remaining `resolveProtocol` rows and one `getStartupTracer` case were exact-value duplicates of owner rows (same inputs, same expected protocol/package pairs, same no-op tracer shape). - Full repository typecheck/test/build were not run locally (no Rust toolchain for the Runner build in this environment; server-wide `tsc --noEmit` exceeds the session window). CI is the authoritative gate for those; this diff touches only test code under `server/src`. ## Risks Low. Test-only change; no production behavior, routing, or CI configuration touched. Known stale mentions of the retired path are non-functional: `.devin/wiki.json` lists it as a non-exhaustive wiki anchor (its own instructions say to relocate removed anchors at generation time) and `scripts/general-server-shard-durations.json` keeps a historical duration key that no longer matches any selected file. ## Model Used - Provider: Z.ai via OpenRouter (agent: Paperclip Test Gardener) - Model ID: `openrouter/z-ai/glm-5.3` - Reasoning: standard chain-of-thought mode, tool use (shell, file edit, GitHub CLI) - Context window: 200k tokens (provider default for this model) ## 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 (none required: test-only change) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge