Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions promptbook/prompts.json
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,26 @@
],
"formatNotes": "All three. Point the tool at the Dockerfile or buildpack config, entrypoint scripts, the Deployment, Kustomize or Helm values that set resources and JVM env vars, and `application*.yml`, and paste `kubectl describe pod` last state, working-set graphs, GC logs, or NMT output if you have them. Copilot: the JVM container path instructions plus those files in agent mode (or save it as `.github/prompts/right-size-jvm-container-memory.prompt.md`). Claude Code: the jvm-container-memory-guardrails skill plus the files. Codex: AGENTS.md JVM in containers section, then the diff. The prompt measures before it raises any limit and marks every number as measured or estimated.",
"body": "Task: Right-size memory and GC for this Java service on Kubernetes so it stops getting OOMKilled (or stops wasting memory), the heap and non-heap fit the container limit with stated headroom, and the JVM sees the CPU it is given. Finish with a memory budget table, a manifest and image diff, a measurement plan, and alerts.\n\nContext placeholders (fill from the repo or ask only if missing):\n- Service: {{SERVICE}} (e.g. orders-api; Spring Boot version, web stack such as MVC, WebFlux, or Netty clients)\n- JDK and image: {{JDK}} (e.g. Temurin 21 JRE on Ubuntu, distroless Java 21, Paketo buildpack image)\n- Current resources: {{RESOURCES}} (requests and limits for CPU and memory, HPA min and max)\n- Current JVM flags: {{FLAGS}} (Dockerfile CMD/ENTRYPOINT, JAVA_TOOL_OPTIONS, JDK_JAVA_OPTIONS, Helm or Kustomize values)\n- Threads: {{THREADS}} (platform or virtual threads; known pool sizes such as Tomcat, Kafka consumers, executors)\n- Latency goal: {{SLO}} (e.g. p99 under 300 ms, batch throughput only)\n- Symptoms: {{SYMPTOMS}} (e.g. OOMKilled exit 137 every few days, OutOfMemoryError: Direct buffer memory, slow startup, long GC pauses, CPU throttling)\n- Evidence: {{EVIDENCE}} (pod events, `kubectl describe` last state, working-set graphs, GC logs, NMT output if any)\n\nRequirements:\n\n1. Find every JVM setting\n - List all places flags are set and which one wins (explicit `-Xmx` beats percentages; later flags override earlier ones)\n - Show the effective values: heap max, processor count, selected collector (from `PrintFlagsFinal`, `jcmd VM.flags`, or by reasoning from the limits if you cannot run them, marked as reasoning)\n - Flag accidental SerialGC (under 2 visible processors or about 1792 MiB) and a JVM that sees all node cores because there is no CPU limit\n\n2. Memory budget\n - Table: region | current | measured or estimated | cap flag | notes, for heap, metaspace, code cache, thread stacks, direct buffers, GC overhead, native and malloc, headroom\n - Mark every number as measured or estimated; do not invent measurements\n - Derive the limit as heap plus non-heap plus 10-20% headroom, and `MaxRAMPercentage` as heap divided by limit\n\n3. Diagnose the symptom\n - Kernel OOMKilled (exit 137, no Java stack trace) versus Java `OutOfMemoryError` (heap, Metaspace, Direct buffer memory, unable to create native thread): explain which it is from {{EVIDENCE}} and what that implies\n - If the gap between heap and working set is large, name the likely regions and how to confirm\n\n4. Changes\n - Heap from `MaxRAMPercentage` (and `InitialRAMPercentage` if a fixed heap suits {{SLO}}); remove `-Xmx` equal to or near the limit\n - Memory request equal to the limit\n - `ActiveProcessorCount` or a CPU limit so visible processors match the CPU given; justify the CPU limit choice\n - Collector choice with a reason tied to heap size and {{SLO}}\n - `MaxDirectMemorySize` if Netty, gRPC, or NIO buffers are used; bounded thread pools if {{THREADS}} is platform threads\n - `ExitOnOutOfMemoryError`; heap dumps to a sized `emptyDir` or volume with restricted access and a cleanup step\n - All flags in one environment variable; if the image uses the Paketo memory calculator, tune it instead of adding `-Xmx`\n - `startupProbe` sized from startup time measured under the CPU limit\n - GC logging to stdout at a level the log pipeline can afford\n\n5. Measurement plan\n - Load test with `-XX:NativeMemoryTracking=summary`: baseline after warm-up, peak traffic, `summary.diff`; compare NMT committed with the pod working set\n - Soak test long enough to catch slow native growth\n - Record heap after GC, GC pause p99, throughput, working set at peak, and startup time before and after\n\n6. Observability\n - Alerts: working set above 90% of the limit for 10 minutes; any OOMKilled restart; GC pause p99 above a threshold from {{SLO}}\n - Dashboard row: working set vs limit, heap used after GC, non-heap by pool, direct buffers, live threads, GC pause and overhead, CPU throttling\n - No memory-based autoscaling for this JVM; propose CPU or request-rate scaling if memory is used today\n\nConstraints:\n- Do not invent limits, measurements, or traffic numbers; use placeholders and list what must be measured.\n- Do not \"fix\" OOMKilled by only raising the limit; show what grew.\n- Do not move heap dumps off the cluster or into tickets; they can hold secrets and personal data.\n- Minimal diff; no unrelated refactors.\n- Optimize for GitHub Copilot, Claude Code, and Codex: give concrete files and a checklist.\n\nOutput format:\n1. Effective settings today (where set, which wins, values)\n2. Memory budget table with measured or estimated marked\n3. Diagnosis of the symptom\n4. Patch: Deployment or Kustomize patch, Dockerfile or buildpack env, probe changes\n5. Measurement plan with expected results\n6. Alerts and dashboard definitions\n7. Risks and follow-ups (e.g. leaks to chase, pools to bound, startup work such as CDS)\n\nStart with the effective settings. Measure before you raise any limit.\n"
},
{
"id": "add-idempotency-keys",
"title": "Add Idempotency-Key Support to a Spring Boot API",
"whenToUse": "Make retried POST and PATCH requests safe in a Spring Boot API: decide per endpoint whether an Idempotency-Key is required, validate and scope keys to the caller and route, fingerprint the request (422 on reuse with a different body), claim keys atomically in a Flyway-managed table (409 for a duplicate still in flight), commit the record with the business write, pass the key to payment providers or the outbox, replay the original response, clean up after the retention window, and prove it with concurrency, crash, and expiry tests before making the header required.",
"tools": [
"copilot",
"claude-code",
"codex"
],
"tags": [
"spring-boot",
"java",
"api",
"idempotency",
"reliability",
"http"
],
"formatNotes": "All three. Point the tool at the controllers for the POST/PATCH routes, the security and rate-limit filters, the service layer and transaction boundaries, outbound provider clients or the outbox, `db/migration/`, the OpenAPI document, and `application*.yml`, and paste incident notes or logs showing duplicates if you have them. Copilot: the idempotency path instructions plus those files in agent mode (or save it as `.github/prompts/add-idempotency-keys.prompt.md`). Claude Code: the api-idempotency-key-guardrails skill plus the files. Codex: AGENTS.md idempotency section, then the diff. The prompt ships the header as optional first and proves the concurrent-duplicate test before requiring it.",
"body": "Task: Add Idempotency-Key support to this Spring Boot API so a retried POST or PATCH runs its side effects once, the retry gets the original result, a reused key with a different request is refused, and concurrent duplicates cannot both run. Finish with an endpoint contract table, a code and migration diff, tests, and a rollout plan.\n\nContext placeholders (fill from the repo or ask only if missing):\n- Service and endpoints: {{SERVICE}} (e.g. payments-api; list POST/PATCH routes and what each one creates or triggers)\n- Caller identity: {{IDENTITY}} (e.g. JWT azp/appid claim, tenant claim, API key; how the principal is available in a filter)\n- Database: {{DATABASE}} (e.g. Azure Database for PostgreSQL with Flyway; where the business writes go)\n- Other store: {{STORE}} (e.g. Azure Cache for Redis, none)\n- Side effects that leave the process: {{SIDE_EFFECTS}} (e.g. payment provider call, email, Kafka publish via outbox)\n- Retry sources: {{RETRIES}} (e.g. mobile app, API Management retry policy, Resilience4j in calling services, workers)\n- Retention: {{RETENTION}} (e.g. 24 hours; longest client retry window)\n- Current symptoms: {{SYMPTOMS}} (e.g. duplicate orders after gateway timeouts, double charges, none yet)\n\nRequirements:\n\n1. Endpoint contract\n - Table: method + route | side effect | key required/optional/unsupported | fingerprint fields | stored outcomes | store-down behaviour\n - Justify each \"required\" from {{SIDE_EFFECTS}}; mark assumptions\n - Retention from {{RETENTION}}, written into the API docs\n\n2. Key handling\n - Read `Idempotency-Key`; accept the quoted structured-field form and a bare token; validate characters and length; 400 for malformed, and for missing when required\n - Scope: client identity from {{IDENTITY}} + method + route template + key; never a global key space\n - Fingerprint: SHA-256 of a canonical request (method, route, path variables, relevant query, body bytes or canonical JSON); exclude tracing and timestamp headers\n\n3. Store and claim\n - Flyway migration for an `idempotency_record` table in {{DATABASE}} (scope, key, fingerprint, status, locked_until, response status, selected headers, body or resource reference, created_at, expires_at; primary key on scope + key; index on expires_at)\n - Atomic claim with one insert under the unique constraint; no read-then-insert\n - Branches: fingerprint mismatch -> 422 problem+json; completed -> replay with `Idempotent-Replayed: true`; in progress with live lease -> 409 problem+json + `Retry-After`; expired lease -> conditional takeover only for transactional endpoints\n - If {{STORE}} is Redis and the business data is in {{DATABASE}}, explain the consistency gap and prefer the database unless there is a measured reason not to\n\n4. Execution and outcomes\n - Mark the record completed with the response in the same transaction as the business write\n - Pass the key (or a derived id) to each item in {{SIDE_EFFECTS}}: provider idempotency key, outbox dedup id\n - Store 2xx and final business errors; release the claim for validation and auth failures and for rolled-back 5xx; keep and flag the record when a side effect may have happened\n - Replays return stored status, body, `Content-Type`, `Location`, `ETag`; they do not re-run the handler or emit events\n\n5. Spring wiring\n - A filter or `HandlerInterceptor` ordered after authentication and the rate limiter, before the transaction and controller\n - Body cached once for the fingerprint; response captured with `ContentCachingResponseWrapper` and `copyBodyToResponse()`\n - An annotation such as `@Idempotent(required = true)` (or config per route) as the per-endpoint switch; streaming and SSE excluded\n - Scheduled cleanup of expired, completed records; never delete in-progress ones\n - Stored bodies size-capped and treated as sensitive; key hashed in logs\n\n6. Clients and docs\n - OpenAPI: header parameter per operation, required flag, retention, 400/409/422 problem types\n - Callers in {{RETRIES}}: generate the key before the first attempt, reuse it on every retry, only retry POST when a key is set, honor 409 Retry-After\n\n7. Observability\n - Counters by route: claimed, replayed, in-flight 409, mismatch 422, lease takeover, store error; store latency; no raw keys as tags\n - Alerts: lease takeovers or store errors above zero; replay rate jump\n\n8. Tests\n - Unit: fingerprint canonicalization, key validation, branch decisions with a fake clock\n - Integration (Testcontainers PostgreSQL): replay returns identical status and body; mismatch 422; two concurrent requests with one key run the handler once; crash between claim and commit; expiry starts a new request\n - Contract: problem+json shapes and headers match the OpenAPI document\n\n9. Rollout\n - Ship optional first, measure how many callers send keys, then make it required per endpoint with notice\n - Feature switch in config; rollback plan\n\nConstraints:\n- Do not invent retention windows, traffic numbers, or provider idempotency features; use placeholders and list what must be confirmed.\n- Do not rely on a business unique constraint as the only duplicate guard.\n- Do not cache pre-execution validation failures against the key.\n- Minimal diff; no unrelated refactors.\n- Optimize for GitHub Copilot, Claude Code, and Codex: give concrete files and a checklist.\n\nOutput format:\n1. Endpoint contract table with assumptions marked\n2. Patch: migration, record entity or repository, filter or interceptor, annotation, problem responses, cleanup job, application.yml\n3. Outbound key propagation changes\n4. OpenAPI changes and client retry changes\n5. Metrics, alerts, and log fields\n6. Tests\n7. Rollout plan, risks, and follow-ups\n\nStart with the contract table. Prove the concurrent-duplicate test passes before wiring more endpoints.\n"
}
]
}
Loading
Loading