claude-dev-env 1.38.1 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/CLAUDE.md +10 -36
  2. package/_shared/pr-loop/audit-reply-template.md +147 -0
  3. package/_shared/pr-loop/fix-protocol.md +25 -4
  4. package/_shared/pr-loop/gh-payloads.md +37 -50
  5. package/_shared/pr-loop/scripts/code_rules_gate.py +0 -60
  6. package/_shared/pr-loop/scripts/config/post_audit_thread_constants.py +189 -0
  7. package/_shared/pr-loop/scripts/post_audit_thread.py +947 -0
  8. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -19
  9. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +923 -0
  10. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +127 -0
  11. package/_shared/pr-loop/state-schema.md +1 -1
  12. package/agents/clean-coder.md +2 -2
  13. package/bin/install.mjs +6 -7
  14. package/bin/install.test.mjs +8 -0
  15. package/commands/doc-gist.md +16 -0
  16. package/commands/plan.md +0 -2
  17. package/commands/review-plan.md +1 -1
  18. package/docs/CODE_RULES.md +122 -2
  19. package/hooks/blocking/bot_mention_comment_blocker.py +75 -0
  20. package/hooks/blocking/code_rules_enforcer.py +1143 -129
  21. package/hooks/blocking/convergence_gate_blocker.py +130 -0
  22. package/hooks/blocking/destructive_command_blocker.py +74 -0
  23. package/hooks/blocking/gh_body_arg_blocker.py +30 -0
  24. package/hooks/blocking/md_to_html_blocker.py +119 -0
  25. package/hooks/blocking/test_bot_mention_comment_blocker.py +131 -0
  26. package/hooks/blocking/test_code_rules_enforcer.py +21 -0
  27. package/hooks/blocking/test_code_rules_enforcer_any_exempt_files.py +70 -0
  28. package/hooks/blocking/test_code_rules_enforcer_any_imports_and_cast.py +92 -0
  29. package/hooks/blocking/test_code_rules_enforcer_banned_import_alias.py +143 -0
  30. package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +152 -0
  31. package/hooks/blocking/test_code_rules_enforcer_bare_except.py +120 -0
  32. package/hooks/blocking/test_code_rules_enforcer_boundary_types.py +175 -0
  33. package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +0 -1
  34. package/hooks/blocking/test_code_rules_enforcer_collection_prefix.py +50 -0
  35. package/hooks/blocking/test_code_rules_enforcer_docstring_format.py +255 -0
  36. package/hooks/blocking/test_code_rules_enforcer_inline_tuple_string_magic.py +130 -0
  37. package/hooks/blocking/test_code_rules_enforcer_stub_implementations.py +141 -0
  38. package/hooks/blocking/test_code_rules_enforcer_test_branching.py +143 -0
  39. package/hooks/blocking/test_code_rules_enforcer_thin_wrapper_files.py +169 -0
  40. package/hooks/blocking/test_code_rules_enforcer_todo_markers.py +99 -0
  41. package/hooks/blocking/test_code_rules_enforcer_typed_dict_pairs.py +141 -0
  42. package/hooks/blocking/test_convergence_gate_blocker.py +63 -0
  43. package/hooks/blocking/test_destructive_command_blocker.py +146 -0
  44. package/hooks/blocking/test_destructive_command_blocker_no_verify.py +102 -0
  45. package/hooks/blocking/test_gh_body_arg_blocker.py +45 -0
  46. package/hooks/blocking/test_md_to_html_blocker.py +317 -0
  47. package/hooks/config/any_type_config.py +7 -0
  48. package/hooks/config/banned_identifiers_constants.py +11 -0
  49. package/hooks/config/blocking_check_limits.py +38 -0
  50. package/hooks/config/bot_mention_comment_blocker_constants.py +20 -0
  51. package/hooks/config/code_rules_enforcer_constants.py +53 -0
  52. package/hooks/config/convergence_branch_constants.py +9 -0
  53. package/hooks/config/doc_gist_auto_publish_constants.py +18 -0
  54. package/hooks/config/html_companion_constants.py +20 -0
  55. package/hooks/config/inline_tuple_string_magic_constants.py +22 -0
  56. package/hooks/config/test_banned_identifiers_constants.py +17 -0
  57. package/hooks/hooks.json +28 -20
  58. package/hooks/pyproject.toml +69 -0
  59. package/hooks/validators/mypy_integration.py +47 -1
  60. package/hooks/validators/run_all_validators.py +3 -3
  61. package/hooks/validators/test_mypy_integration.py +50 -1
  62. package/hooks/workflow/doc_gist_auto_publish.py +144 -0
  63. package/hooks/workflow/md_to_html_companion.py +365 -0
  64. package/hooks/workflow/test_doc_gist_auto_publish.py +117 -0
  65. package/hooks/workflow/test_md_to_html_companion.py +452 -0
  66. package/package.json +1 -1
  67. package/rules/gh-body-file.md +2 -0
  68. package/scripts/Install-SweepEmptyDirs.ps1 +111 -0
  69. package/scripts/check.ps1 +106 -0
  70. package/scripts/config/timing.py +11 -0
  71. package/scripts/sweep_empty_dirs.py +138 -0
  72. package/scripts/sync_to_cursor/rules.py +1 -1
  73. package/scripts/test_sweep_empty_dirs.py +183 -0
  74. package/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +323 -0
  75. package/skills/_shared/pr-loop/scripts/_cli_utils.py +22 -0
  76. package/skills/_shared/pr-loop/scripts/_path_resolver.py +165 -0
  77. package/skills/_shared/pr-loop/scripts/_xml_utils.py +20 -0
  78. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +182 -0
  79. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +185 -0
  80. package/skills/_shared/pr-loop/scripts/config/__init__.py +0 -0
  81. package/skills/_shared/pr-loop/scripts/config/path_resolver_constants.py +78 -0
  82. package/skills/_shared/pr-loop/scripts/init_loop_state.py +135 -0
  83. package/skills/_shared/pr-loop/scripts/teardown_worktrees.py +175 -0
  84. package/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +182 -0
  85. package/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +206 -0
  86. package/skills/bugteam/CONSTRAINTS.md +21 -22
  87. package/skills/bugteam/EXAMPLES.md +3 -3
  88. package/skills/bugteam/PROMPTS.md +227 -67
  89. package/skills/bugteam/SKILL.md +114 -455
  90. package/skills/bugteam/reference/README.md +1 -1
  91. package/skills/bugteam/reference/audit-and-teammates.md +112 -39
  92. package/skills/bugteam/reference/audit-contract.md +4 -22
  93. package/skills/bugteam/reference/copilot-gap-analysis.md +8 -5
  94. package/skills/bugteam/reference/design-rationale.md +2 -2
  95. package/skills/bugteam/reference/github-pr-reviews.md +50 -57
  96. package/skills/bugteam/reference/obstacles/audit-assign-ids.md +13 -0
  97. package/skills/bugteam/reference/obstacles/audit-capture-excerpts.md +13 -0
  98. package/skills/bugteam/reference/obstacles/audit-walk-categories.md +13 -0
  99. package/skills/bugteam/reference/obstacles/audit-write-xml.md +13 -0
  100. package/skills/bugteam/reference/obstacles/fix-append-summary.md +13 -0
  101. package/skills/bugteam/reference/obstacles/fix-apply-fixes.md +13 -0
  102. package/skills/bugteam/reference/obstacles/fix-git-add-commit.md +13 -0
  103. package/skills/bugteam/reference/obstacles/fix-git-push.md +13 -0
  104. package/skills/bugteam/reference/obstacles/fix-post-reply.md +13 -0
  105. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +13 -0
  106. package/skills/bugteam/reference/obstacles/fix-py-compile.md +13 -0
  107. package/skills/bugteam/reference/obstacles/fix-read-files.md +13 -0
  108. package/skills/bugteam/reference/obstacles/fix-resolve-thread.md +13 -0
  109. package/skills/bugteam/reference/obstacles/fix-test-suite.md +13 -0
  110. package/skills/bugteam/reference/obstacles/fix-violation-count.md +13 -0
  111. package/skills/bugteam/reference/obstacles/fix-write-xml.md +13 -0
  112. package/skills/bugteam/reference/team-setup.md +106 -9
  113. package/skills/bugteam/reference/teardown-publish-permissions.md +39 -8
  114. package/skills/bugteam/scripts/README.md +60 -0
  115. package/skills/bugteam/scripts/_claude_permissions_common.py +358 -0
  116. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +976 -0
  117. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +375 -0
  118. package/skills/bugteam/scripts/bugteam_preflight.py +294 -0
  119. package/skills/bugteam/scripts/config/bugteam_code_rules_gate_constants.py +25 -0
  120. package/skills/bugteam/scripts/config/bugteam_fix_hookspath_constants.py +26 -0
  121. package/skills/bugteam/scripts/config/bugteam_preflight_constants.py +35 -0
  122. package/skills/bugteam/scripts/config/claude_permissions_common_constants.py +20 -0
  123. package/skills/bugteam/scripts/config/probe_code_rules_enforcer_check_constants.py +12 -0
  124. package/skills/bugteam/scripts/config/windows_safe_rmtree_constants.py +7 -0
  125. package/skills/bugteam/scripts/grant_project_claude_permissions.py +175 -0
  126. package/skills/bugteam/scripts/probe_code_rules_enforcer_check.py +107 -0
  127. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +220 -0
  128. package/skills/bugteam/scripts/test__claude_permissions_common.py +112 -0
  129. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +400 -0
  130. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +384 -0
  131. package/skills/bugteam/scripts/test_bugteam_preflight.py +268 -0
  132. package/skills/bugteam/scripts/test_claude_permissions_common.py +195 -0
  133. package/skills/bugteam/scripts/test_grant_project_claude_permissions.py +55 -0
  134. package/skills/bugteam/scripts/test_probe_code_rules_enforcer_check.py +76 -0
  135. package/skills/bugteam/scripts/test_revoke_project_claude_permissions.py +55 -0
  136. package/skills/bugteam/scripts/test_windows_safe_rmtree.py +108 -0
  137. package/skills/bugteam/scripts/windows_safe_rmtree.py +100 -0
  138. package/skills/bugteam/test_skill_additions.py +1 -11
  139. package/skills/code/SKILL.md +176 -0
  140. package/skills/doc-gist/SKILL.md +99 -0
  141. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +453 -0
  142. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +515 -0
  143. package/skills/doc-gist/references/examples/03-code-review-pr.html +638 -0
  144. package/skills/doc-gist/references/examples/04-code-understanding.html +491 -0
  145. package/skills/doc-gist/references/examples/05-design-system.html +629 -0
  146. package/skills/doc-gist/references/examples/06-component-variants.html +605 -0
  147. package/skills/doc-gist/references/examples/07-prototype-animation.html +455 -0
  148. package/skills/doc-gist/references/examples/08-prototype-interaction.html +396 -0
  149. package/skills/doc-gist/references/examples/09-slide-deck.html +592 -0
  150. package/skills/doc-gist/references/examples/10-svg-illustrations.html +492 -0
  151. package/skills/doc-gist/references/examples/11-status-report.html +528 -0
  152. package/skills/doc-gist/references/examples/12-incident-report.html +596 -0
  153. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +395 -0
  154. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +381 -0
  155. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +368 -0
  156. package/skills/doc-gist/references/examples/16-implementation-plan.html +702 -0
  157. package/skills/doc-gist/references/examples/17-pr-writeup.html +595 -0
  158. package/skills/doc-gist/references/examples/18-editor-triage-board.html +573 -0
  159. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +663 -0
  160. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +722 -0
  161. package/skills/doc-gist/references/examples/README.md +5 -0
  162. package/skills/doc-gist/scripts/config/__init__.py +0 -0
  163. package/skills/doc-gist/scripts/config/gist_upload_constants.py +16 -0
  164. package/skills/doc-gist/scripts/gist_upload.py +177 -0
  165. package/skills/doc-gist/scripts/test_gist_upload.py +51 -0
  166. package/skills/findbugs/SKILL.md +68 -2
  167. package/skills/monitor-open-prs/SKILL.md +13 -32
  168. package/skills/monitor-open-prs/test_skill_contract.py +0 -11
  169. package/skills/pr-consistency-audit/SKILL.md +112 -0
  170. package/skills/pr-consistency-audit/reference/detection-rules.md +96 -0
  171. package/skills/pr-consistency-audit/reference/illustrations.md +78 -0
  172. package/skills/pr-converge/SKILL.md +227 -23
  173. package/skills/pr-converge/config/__init__.py +0 -0
  174. package/skills/pr-converge/config/constants.py +62 -0
  175. package/skills/pr-converge/reference/convergence-gates.md +138 -44
  176. package/skills/pr-converge/reference/examples.md +43 -11
  177. package/skills/pr-converge/reference/fix-protocol.md +6 -5
  178. package/skills/pr-converge/reference/ground-rules.md +5 -3
  179. package/skills/pr-converge/reference/multi-pr-orchestration.md +44 -19
  180. package/skills/pr-converge/reference/obstacles/fix-post-replies.md +13 -0
  181. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +13 -0
  182. package/skills/pr-converge/reference/obstacles/fix-push.md +13 -0
  183. package/skills/pr-converge/reference/obstacles/fix-read-filelines.md +13 -0
  184. package/skills/pr-converge/reference/obstacles/fix-reset-state.md +13 -0
  185. package/skills/pr-converge/reference/obstacles/fix-resolve-threads.md +13 -0
  186. package/skills/pr-converge/reference/obstacles/fix-spawn-clean-coder.md +13 -0
  187. package/skills/pr-converge/reference/obstacles/fix-stage-commit.md +13 -0
  188. package/skills/pr-converge/reference/obstacles/fix-trigger-bugbot.md +13 -0
  189. package/skills/pr-converge/reference/obstacles/fix-write-test.md +13 -0
  190. package/skills/pr-converge/reference/per-tick.md +90 -31
  191. package/skills/pr-converge/reference/state-schema.md +22 -1
  192. package/skills/pr-converge/reference/stop-conditions.md +9 -7
  193. package/skills/pr-converge/scripts/README.md +34 -46
  194. package/skills/pr-converge/scripts/check_bugbot_ci.py +174 -0
  195. package/skills/pr-converge/scripts/check_convergence.py +497 -0
  196. package/skills/pr-converge/scripts/check_pending_reviews.py +154 -0
  197. package/skills/pr-converge/scripts/config/pr_converge_constants.py +118 -0
  198. package/skills/pr-converge/scripts/fetch_copilot_reviews.py +134 -0
  199. package/skills/pr-converge/scripts/post_fix_reply.py +168 -0
  200. package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -12
  201. package/skills/qbug/SKILL.md +132 -27
  202. package/skills/session-log/SKILL.md +216 -114
  203. package/skills/session-tidy/SKILL.md +1 -1
  204. package/skills/skill-builder/SKILL.md +138 -56
  205. package/skills/skill-builder/references/delegation-map.md +72 -113
  206. package/skills/skill-builder/references/progressive-disclosure.md +122 -0
  207. package/skills/skill-builder/references/self-audit-checklist.md +92 -0
  208. package/skills/skill-builder/references/skill-types.md +228 -0
  209. package/skills/skill-builder/references/thariq-x-post-skills.json +33 -0
  210. package/skills/skill-builder/templates/gap-analysis.md +15 -8
  211. package/skills/skill-builder/workflows/improve-skill.md +86 -57
  212. package/skills/skill-builder/workflows/new-skill.md +80 -168
  213. package/skills/skill-builder/workflows/polish-skill.md +78 -54
  214. package/skills/structure-prompt/SKILL.md +50 -0
  215. package/skills/structure-prompt/reference/adversarial-tuning.md +62 -0
  216. package/skills/structure-prompt/reference/block-classification.md +27 -0
  217. package/skills/structure-prompt/reference/canonical-case.md +48 -0
  218. package/skills/structure-prompt/reference/citation-depth.md +70 -0
  219. package/skills/structure-prompt/reference/cleanup.md +33 -0
  220. package/skills/structure-prompt/reference/constraints.md +33 -0
  221. package/skills/structure-prompt/reference/directives.md +37 -0
  222. package/skills/structure-prompt/reference/examples.md +72 -0
  223. package/skills/structure-prompt/reference/instantiation.md +51 -0
  224. package/skills/structure-prompt/reference/output-contract.md +72 -0
  225. package/skills/structure-prompt/reference/per-category.md +23 -0
  226. package/skills/structure-prompt/reference/persona.md +38 -0
  227. package/skills/structure-prompt/reference/research.md +33 -0
  228. package/skills/structure-prompt/reference/structure.md +28 -0
  229. package/agents/code-standards-agent.md +0 -93
  230. package/agents/groq-coder.md +0 -113
  231. package/agents/plan-executor.md +0 -226
  232. package/agents/project-docs-analyzer.md +0 -53
  233. package/agents/project-structure-organizer-agent.md +0 -72
  234. package/agents/skill-to-agent-converter.md +0 -370
  235. package/agents/skill-writer-agent.md +0 -470
  236. package/agents/user-docs-writer.md +0 -67
  237. package/agents/workflow-visual-documenter.md +0 -82
  238. package/commands/readability-review.md +0 -20
  239. package/hooks/mypy.ini +0 -2
  240. package/hooks/notification/attention_needed_notify.py +0 -71
  241. package/hooks/notification/claude_notification_handler.py +0 -67
  242. package/hooks/notification/notification_utils.py +0 -267
  243. package/hooks/notification/subagent_complete_notify.py +0 -381
  244. package/hooks/notification/test_attention_needed_notify.py +0 -47
  245. package/hooks/notification/test_claude_notification_handler.py +0 -54
  246. package/hooks/notification/test_notification_utils.py +0 -91
  247. package/hooks/notification/test_subagent_complete_notify.py +0 -79
  248. package/scripts/config/groq_bugteam_config.py +0 -230
  249. package/scripts/config/test_groq_bugteam_config.py +0 -83
  250. package/scripts/config/test_spec_implementer_prompt.py +0 -32
  251. package/scripts/groq_bugteam.README.md +0 -131
  252. package/scripts/groq_bugteam.py +0 -647
  253. package/scripts/groq_bugteam_dotenv.py +0 -40
  254. package/scripts/groq_bugteam_spec.py +0 -226
  255. package/scripts/test_groq_bugteam.py +0 -529
  256. package/scripts/test_groq_bugteam_apply_fix_from_spec.py +0 -426
  257. package/scripts/test_groq_bugteam_dotenv.py +0 -66
  258. package/scripts/test_groq_bugteam_spec.py +0 -338
  259. package/skills/bugteam/SKILL_EVALS.md +0 -309
  260. package/skills/dream/SKILL.md +0 -118
  261. package/skills/ingest/SKILL.md +0 -40
  262. package/skills/npm-creator/SKILL.md +0 -187
  263. package/skills/readability-review/SKILL.md +0 -127
  264. package/skills/resume-review/SKILL.md +0 -261
  265. package/skills/rule-audit/SKILL.md +0 -307
  266. package/skills/rule-creator/SKILL.md +0 -150
  267. package/skills/searching-obsidian-vault/SKILL.md +0 -131
  268. package/skills/skill-writer/REFERENCE.md +0 -284
  269. package/skills/skill-writer/SKILL.md +0 -222
  270. package/skills/tdd-team/SKILL.md +0 -128
@@ -0,0 +1,596 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>INC-2025-0412 — Elevated 502s on task sync</title>
7
+ <style>
8
+ :root {
9
+ --ivory: #FAF9F5;
10
+ --slate: #141413;
11
+ --clay: #D97757;
12
+ --oat: #E3DACC;
13
+ --olive: #788C5D;
14
+ --rust: #B04A3F;
15
+ --gray-100: #F0EEE6;
16
+ --gray-300: #D1CFC5;
17
+ --gray-500: #87867F;
18
+ --gray-700: #3D3D3A;
19
+ --white: #FFFFFF;
20
+
21
+ --serif: ui-serif, Georgia, serif;
22
+ --sans: system-ui, -apple-system, sans-serif;
23
+ --mono: ui-monospace, 'SF Mono', Menlo, monospace;
24
+
25
+ --radius-panel: 12px;
26
+ --radius-row: 8px;
27
+ --border: 1.5px solid var(--gray-300);
28
+ }
29
+
30
+ * { box-sizing: border-box; }
31
+
32
+ html { scroll-behavior: smooth; }
33
+
34
+ body {
35
+ margin: 0;
36
+ padding: 56px 24px 120px;
37
+ background: var(--ivory);
38
+ color: var(--slate);
39
+ font-family: var(--sans);
40
+ font-size: 15px;
41
+ line-height: 1.6;
42
+ -webkit-font-smoothing: antialiased;
43
+ }
44
+
45
+ .page {
46
+ max-width: 820px;
47
+ margin: 0 auto;
48
+ }
49
+
50
+ /* ---------- Header ---------- */
51
+ header {
52
+ margin-bottom: 32px;
53
+ }
54
+ .inc-id {
55
+ font-family: var(--mono);
56
+ font-size: 13px;
57
+ color: var(--gray-500);
58
+ letter-spacing: 0.02em;
59
+ margin-bottom: 8px;
60
+ }
61
+ h1 {
62
+ font-family: var(--serif);
63
+ font-weight: 500;
64
+ font-size: 36px;
65
+ letter-spacing: -0.01em;
66
+ margin: 0 0 18px;
67
+ line-height: 1.2;
68
+ }
69
+ .meta-row {
70
+ display: flex;
71
+ flex-wrap: wrap;
72
+ align-items: center;
73
+ gap: 10px 12px;
74
+ }
75
+ .pill {
76
+ display: inline-flex;
77
+ align-items: baseline;
78
+ gap: 6px;
79
+ font-family: var(--sans);
80
+ font-size: 12px;
81
+ font-weight: 600;
82
+ border-radius: 999px;
83
+ padding: 5px 12px;
84
+ line-height: 1;
85
+ }
86
+ .pill .k {
87
+ font-weight: 400;
88
+ opacity: 0.75;
89
+ }
90
+ .pill.sev {
91
+ background: var(--clay);
92
+ color: var(--white);
93
+ letter-spacing: 0.03em;
94
+ }
95
+ .pill.resolved {
96
+ background: var(--olive);
97
+ color: var(--white);
98
+ }
99
+ .pill.neutral {
100
+ background: var(--gray-100);
101
+ color: var(--gray-700);
102
+ border: var(--border);
103
+ }
104
+ .pill.neutral .v {
105
+ font-family: var(--mono);
106
+ }
107
+
108
+ /* ---------- TL;DR ---------- */
109
+ .tldr {
110
+ background: var(--slate);
111
+ color: var(--ivory);
112
+ border-radius: var(--radius-panel);
113
+ padding: 22px 26px;
114
+ margin-bottom: 48px;
115
+ }
116
+ .tldr-label {
117
+ font-family: var(--mono);
118
+ font-size: 11px;
119
+ text-transform: uppercase;
120
+ letter-spacing: 0.1em;
121
+ color: var(--oat);
122
+ margin-bottom: 10px;
123
+ }
124
+ .tldr p {
125
+ margin: 0;
126
+ font-size: 15.5px;
127
+ line-height: 1.65;
128
+ }
129
+ .tldr code {
130
+ font-family: var(--mono);
131
+ font-size: 13.5px;
132
+ background: rgba(250, 249, 245, 0.12);
133
+ padding: 1px 5px;
134
+ border-radius: 4px;
135
+ }
136
+
137
+ /* ---------- Sections ---------- */
138
+ section {
139
+ margin-bottom: 52px;
140
+ scroll-margin-top: 24px;
141
+ }
142
+ h2 {
143
+ font-family: var(--serif);
144
+ font-weight: 500;
145
+ font-size: 24px;
146
+ letter-spacing: -0.01em;
147
+ margin: 0 0 6px;
148
+ }
149
+ hr.rule {
150
+ border: none;
151
+ border-top: 1px solid var(--gray-300);
152
+ margin: 0 0 22px;
153
+ }
154
+ p { margin: 0 0 14px; }
155
+ code.inline {
156
+ font-family: var(--mono);
157
+ font-size: 13px;
158
+ background: var(--gray-100);
159
+ padding: 1.5px 5px;
160
+ border-radius: 4px;
161
+ }
162
+
163
+ /* ---------- Timeline ---------- */
164
+ .timeline {
165
+ position: relative;
166
+ padding: 4px 0 4px 16px;
167
+ }
168
+ .timeline::before {
169
+ content: "";
170
+ position: absolute;
171
+ left: 16px;
172
+ top: 8px;
173
+ bottom: 8px;
174
+ width: 2px;
175
+ background: var(--gray-300);
176
+ }
177
+ .tl-entry {
178
+ position: relative;
179
+ padding: 0 0 22px 28px;
180
+ }
181
+ .tl-entry:last-child {
182
+ padding-bottom: 0;
183
+ }
184
+ .tl-dot {
185
+ position: absolute;
186
+ left: -5px;
187
+ top: 6px;
188
+ width: 12px;
189
+ height: 12px;
190
+ border-radius: 50%;
191
+ background: var(--gray-500);
192
+ border: 2px solid var(--ivory);
193
+ box-sizing: content-box;
194
+ }
195
+ .tl-dot.impact { background: var(--clay); }
196
+ .tl-dot.mitigated { background: var(--olive); }
197
+ .tl-time {
198
+ display: inline-block;
199
+ font-family: var(--mono);
200
+ font-size: 12px;
201
+ color: var(--gray-700);
202
+ background: var(--gray-100);
203
+ border: 1px solid var(--gray-300);
204
+ border-radius: 6px;
205
+ padding: 2px 8px;
206
+ margin-bottom: 6px;
207
+ }
208
+ .tl-body {
209
+ font-size: 14px;
210
+ color: var(--gray-700);
211
+ }
212
+ .tl-body strong {
213
+ color: var(--slate);
214
+ font-weight: 600;
215
+ }
216
+
217
+ /* ---------- Code diff ---------- */
218
+ .code-panel {
219
+ background: var(--slate);
220
+ color: var(--gray-100);
221
+ border-radius: var(--radius-panel);
222
+ padding: 18px 20px;
223
+ font-family: var(--mono);
224
+ font-size: 13px;
225
+ line-height: 1.7;
226
+ overflow-x: auto;
227
+ margin: 8px 0 4px;
228
+ }
229
+ .code-panel .path {
230
+ color: var(--gray-500);
231
+ font-size: 12px;
232
+ margin-bottom: 10px;
233
+ display: block;
234
+ }
235
+ .diff-line { white-space: pre; }
236
+ .diff-line.ctx { color: var(--gray-300); }
237
+ .diff-line.del { color: #E0897A; }
238
+ .diff-line.add { color: #A3B88A; }
239
+
240
+ /* ---------- Impact table ---------- */
241
+ table.impact {
242
+ width: 100%;
243
+ max-width: 460px;
244
+ border-collapse: separate;
245
+ border-spacing: 0;
246
+ background: var(--white);
247
+ border: var(--border);
248
+ border-radius: var(--radius-panel);
249
+ overflow: hidden;
250
+ }
251
+ table.impact th,
252
+ table.impact td {
253
+ text-align: left;
254
+ padding: 12px 18px;
255
+ font-size: 14px;
256
+ border-bottom: 1px solid var(--gray-100);
257
+ }
258
+ table.impact tr:last-child th,
259
+ table.impact tr:last-child td {
260
+ border-bottom: none;
261
+ }
262
+ table.impact th {
263
+ font-weight: 400;
264
+ color: var(--gray-500);
265
+ width: 55%;
266
+ }
267
+ table.impact td {
268
+ font-family: var(--mono);
269
+ color: var(--slate);
270
+ }
271
+
272
+ /* ---------- Action items ---------- */
273
+ .actions {
274
+ background: var(--white);
275
+ border: var(--border);
276
+ border-radius: var(--radius-panel);
277
+ overflow: hidden;
278
+ }
279
+ .ai-row {
280
+ display: grid;
281
+ grid-template-columns: 36px 36px 1fr 96px;
282
+ align-items: center;
283
+ gap: 14px;
284
+ padding: 14px 18px;
285
+ border-bottom: 1px solid var(--gray-100);
286
+ }
287
+ .ai-row:last-child { border-bottom: none; }
288
+ .ai-check {
289
+ width: 18px;
290
+ height: 18px;
291
+ border: 1.5px solid var(--gray-300);
292
+ border-radius: 5px;
293
+ background: var(--white);
294
+ position: relative;
295
+ }
296
+ .ai-row.done .ai-check {
297
+ background: var(--olive);
298
+ border-color: var(--olive);
299
+ }
300
+ .ai-row.done .ai-check::after {
301
+ content: "";
302
+ position: absolute;
303
+ left: 4px;
304
+ top: 1px;
305
+ width: 5px;
306
+ height: 9px;
307
+ border: solid var(--white);
308
+ border-width: 0 2px 2px 0;
309
+ transform: rotate(40deg);
310
+ }
311
+ .ai-row.done .ai-desc {
312
+ color: var(--gray-500);
313
+ text-decoration: line-through;
314
+ text-decoration-color: var(--gray-300);
315
+ }
316
+ .ai-avatar {
317
+ width: 30px;
318
+ height: 30px;
319
+ border-radius: 50%;
320
+ background: var(--oat);
321
+ color: var(--gray-700);
322
+ font-size: 11px;
323
+ font-weight: 600;
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ letter-spacing: 0.02em;
328
+ }
329
+ .ai-desc {
330
+ font-size: 14px;
331
+ color: var(--slate);
332
+ }
333
+ .ai-due {
334
+ font-family: var(--mono);
335
+ font-size: 12px;
336
+ color: var(--gray-500);
337
+ text-align: right;
338
+ }
339
+
340
+ /* ---------- Fixed TOC ---------- */
341
+ .toc {
342
+ display: none;
343
+ }
344
+ @media (min-width: 1100px) {
345
+ .toc {
346
+ display: block;
347
+ position: fixed;
348
+ top: 72px;
349
+ right: max(24px, calc(50vw - 410px - 200px));
350
+ width: 170px;
351
+ font-size: 13px;
352
+ }
353
+ .toc-title {
354
+ font-family: var(--mono);
355
+ font-size: 10px;
356
+ text-transform: uppercase;
357
+ letter-spacing: 0.1em;
358
+ color: var(--gray-500);
359
+ margin-bottom: 12px;
360
+ }
361
+ .toc a {
362
+ display: block;
363
+ color: var(--gray-500);
364
+ text-decoration: none;
365
+ padding: 5px 0 5px 12px;
366
+ border-left: 1.5px solid var(--gray-300);
367
+ line-height: 1.3;
368
+ }
369
+ .toc a:hover {
370
+ color: var(--slate);
371
+ border-left-color: var(--clay);
372
+ }
373
+ }
374
+
375
+ footer {
376
+ margin-top: 64px;
377
+ padding-top: 20px;
378
+ border-top: 1px solid var(--gray-300);
379
+ font-family: var(--mono);
380
+ font-size: 12px;
381
+ color: var(--gray-500);
382
+ }
383
+ </style>
384
+ </head>
385
+ <body>
386
+
387
+ <nav class="toc">
388
+ <div class="toc-title">On this page</div>
389
+ <a href="#tldr">TL;DR</a>
390
+ <a href="#timeline">Timeline</a>
391
+ <a href="#root-cause">Root cause</a>
392
+ <a href="#impact">Impact</a>
393
+ <a href="#actions">Action items</a>
394
+ </nav>
395
+
396
+ <div class="page">
397
+
398
+ <header>
399
+ <div class="inc-id">INC-2025-0412</div>
400
+ <h1>Elevated 502s on task sync</h1>
401
+ <div class="meta-row">
402
+ <span class="pill sev">SEV-2</span>
403
+ <span class="pill resolved">Resolved</span>
404
+ <span class="pill neutral"><span class="k">Duration</span> <span class="v">47 min</span></span>
405
+ <span class="pill neutral"><span class="k">Detected</span> <span class="v">Apr 12 &middot; 14:07</span></span>
406
+ <span class="pill neutral"><span class="k">Owner</span> <span class="v">Devon Park</span></span>
407
+ </div>
408
+ </header>
409
+
410
+ <div class="tldr" id="tldr">
411
+ <div class="tldr-label">TL;DR</div>
412
+ <p>
413
+ A config rollout lowered the database connection-pool limit on the
414
+ <code>sync-worker</code> tier from 64 to 8, exhausting connections under
415
+ normal afternoon load. The sync API returned 502s for roughly 21% of
416
+ requests over 47 minutes. We mitigated by reverting the config and
417
+ cycling the worker fleet; no data was lost.
418
+ </p>
419
+ </div>
420
+
421
+ <!-- Timeline -->
422
+ <section id="timeline">
423
+ <h2>Timeline</h2>
424
+ <hr class="rule">
425
+ <div class="timeline">
426
+
427
+ <div class="tl-entry">
428
+ <span class="tl-dot"></span>
429
+ <span class="tl-time">14:02</span>
430
+ <div class="tl-body">
431
+ Config change <code class="inline">cfg-9a12</code> promoted to
432
+ production via the standard rollout pipeline.
433
+ </div>
434
+ </div>
435
+
436
+ <div class="tl-entry">
437
+ <span class="tl-dot impact"></span>
438
+ <span class="tl-time">14:06</span>
439
+ <div class="tl-body">
440
+ <strong>Impact starts.</strong> Sync workers begin queueing on pool
441
+ checkout; p95 latency climbs past 4s and the load balancer starts
442
+ returning 502s.
443
+ </div>
444
+ </div>
445
+
446
+ <div class="tl-entry">
447
+ <span class="tl-dot"></span>
448
+ <span class="tl-time">14:07</span>
449
+ <div class="tl-body">
450
+ Alert fires: <code class="inline">sync_5xx_rate &gt; 2%</code> for 60s.
451
+ On-call (Devon) acknowledges.
452
+ </div>
453
+ </div>
454
+
455
+ <div class="tl-entry">
456
+ <span class="tl-dot"></span>
457
+ <span class="tl-time">14:18</span>
458
+ <div class="tl-body">
459
+ Initial hypothesis is a bad deploy of the API service; last two
460
+ application deploys are rolled back with no effect.
461
+ </div>
462
+ </div>
463
+
464
+ <div class="tl-entry">
465
+ <span class="tl-dot"></span>
466
+ <span class="tl-time">14:31</span>
467
+ <div class="tl-body">
468
+ Mira joins and notices pool-wait saturation in the worker dashboard.
469
+ Investigation pivots to infra config rather than app code.
470
+ </div>
471
+ </div>
472
+
473
+ <div class="tl-entry">
474
+ <span class="tl-dot mitigated"></span>
475
+ <span class="tl-time">14:44</span>
476
+ <div class="tl-body">
477
+ <strong>Mitigated.</strong> <code class="inline">cfg-9a12</code>
478
+ reverted; worker fleet cycled. 5xx rate drops below 0.2% within
479
+ three minutes.
480
+ </div>
481
+ </div>
482
+
483
+ <div class="tl-entry">
484
+ <span class="tl-dot"></span>
485
+ <span class="tl-time">14:49</span>
486
+ <div class="tl-body">
487
+ Monitors green for 5 minutes. Incident declared resolved; status
488
+ page updated.
489
+ </div>
490
+ </div>
491
+
492
+ </div>
493
+ </section>
494
+
495
+ <!-- Root cause -->
496
+ <section id="root-cause">
497
+ <h2>Root cause</h2>
498
+ <hr class="rule">
499
+ <p>
500
+ PR <code class="inline">#4888</code> made connection-pool limits
501
+ configurable per worker tier. The default for the new
502
+ <code class="inline">sync-worker</code> key was meant to inherit the
503
+ global value (64) but was hard-coded to 8 during a local test and
504
+ committed. The config linter only validates type, not magnitude, so the
505
+ change passed CI.
506
+ </p>
507
+ <p>
508
+ Because config rollouts and code deploys go through separate pipelines,
509
+ the on-call's first instinct &mdash; rolling back the most recent
510
+ application deploys &mdash; had no effect and cost roughly 13 minutes of
511
+ diagnosis time.
512
+ </p>
513
+
514
+ <div class="code-panel">
515
+ <span class="path">infra/config/workers.yaml</span>
516
+ <div class="diff-line ctx"> pool:</div>
517
+ <div class="diff-line ctx"> global_max_connections: 64</div>
518
+ <div class="diff-line ctx"> tiers:</div>
519
+ <div class="diff-line del">- sync-worker: { max_connections: 64 }</div>
520
+ <div class="diff-line add">+ sync-worker: { max_connections: 8 } # debug value, do not ship</div>
521
+ <div class="diff-line ctx"> webhook-worker: { max_connections: 32 }</div>
522
+ </div>
523
+ </section>
524
+
525
+ <!-- Impact -->
526
+ <section id="impact">
527
+ <h2>Impact</h2>
528
+ <hr class="rule">
529
+ <table class="impact">
530
+ <tr>
531
+ <th>Requests failed (502)</th>
532
+ <td>~41,200</td>
533
+ </tr>
534
+ <tr>
535
+ <th>Peak error rate</th>
536
+ <td>21.4%</td>
537
+ </tr>
538
+ <tr>
539
+ <th>Users affected</th>
540
+ <td>~2,300 workspaces</td>
541
+ </tr>
542
+ <tr>
543
+ <th>Data loss</th>
544
+ <td>None &mdash; clients retried</td>
545
+ </tr>
546
+ <tr>
547
+ <th>SLA breach</th>
548
+ <td>No (within monthly budget)</td>
549
+ </tr>
550
+ </table>
551
+ </section>
552
+
553
+ <!-- Action items -->
554
+ <section id="actions">
555
+ <h2>Action items</h2>
556
+ <hr class="rule">
557
+ <div class="actions">
558
+
559
+ <div class="ai-row done">
560
+ <span class="ai-check"></span>
561
+ <span class="ai-avatar" title="Devon Park">DP</span>
562
+ <span class="ai-desc">Revert cfg-9a12 and restore pool limit to 64</span>
563
+ <span class="ai-due">Apr 12</span>
564
+ </div>
565
+
566
+ <div class="ai-row">
567
+ <span class="ai-check"></span>
568
+ <span class="ai-avatar" title="Mira Okafor">MO</span>
569
+ <span class="ai-desc">Add config-linter range check for <code class="inline">max_connections</code> (warn &lt; 32)</span>
570
+ <span class="ai-due">Apr 18</span>
571
+ </div>
572
+
573
+ <div class="ai-row">
574
+ <span class="ai-check"></span>
575
+ <span class="ai-avatar" title="Sam Reyes">SR</span>
576
+ <span class="ai-desc">Surface &ldquo;recent config rollouts&rdquo; alongside deploys in the on-call dashboard</span>
577
+ <span class="ai-due">Apr 25</span>
578
+ </div>
579
+
580
+ <div class="ai-row">
581
+ <span class="ai-check"></span>
582
+ <span class="ai-avatar" title="Priya Anand">PA</span>
583
+ <span class="ai-desc">Canary config changes to one worker AZ for 10 min before fleet-wide promote</span>
584
+ <span class="ai-due">May 02</span>
585
+ </div>
586
+
587
+ </div>
588
+ </section>
589
+
590
+ <footer>
591
+ Authored from on-call notes + alert history &middot; reviewed by Devon Park, Mira Okafor
592
+ </footer>
593
+
594
+ </div>
595
+ </body>
596
+ </html>