bobframes 0.2.0__tar.gz → 0.2.7__tar.gz

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 (397) hide show
  1. bobframes-0.2.7/CHANGELOG.md +167 -0
  2. bobframes-0.2.7/PKG-INFO +237 -0
  3. bobframes-0.2.7/README.md +206 -0
  4. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/_default_config.toml +6 -2
  5. bobframes-0.2.7/bobframes/_version.py +1 -0
  6. bobframes-0.2.7/bobframes/aggregates.py +231 -0
  7. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/catalog.py +7 -0
  8. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/cli.py +95 -8
  9. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/config.py +77 -1
  10. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/global_entities.py +7 -0
  11. bobframes-0.2.7/bobframes/health.py +233 -0
  12. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/html/template.py +173 -215
  13. bobframes-0.2.7/bobframes/package.py +607 -0
  14. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/paths.py +13 -0
  15. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/__init__.py +2 -0
  16. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/_tokens.py +2 -2
  17. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/ab.py +18 -0
  18. bobframes-0.2.7/bobframes/reports/assets/chrome.css +353 -0
  19. bobframes-0.2.7/bobframes/reports/assets/components.css +153 -0
  20. bobframes-0.2.7/bobframes/reports/assets/components.js +186 -0
  21. bobframes-0.2.7/bobframes/reports/assets/container.css +34 -0
  22. bobframes-0.2.7/bobframes/reports/assets/design_tokens.css +79 -0
  23. bobframes-0.2.7/bobframes/reports/assets/icon_sprite.html +27 -0
  24. bobframes-0.2.7/bobframes/reports/assets/link_kind.css +75 -0
  25. bobframes-0.2.7/bobframes/reports/assets/per_drop.css +102 -0
  26. bobframes-0.2.7/bobframes/reports/assets/print.css +73 -0
  27. bobframes-0.2.7/bobframes/reports/assets/rdc_table.css +154 -0
  28. bobframes-0.2.7/bobframes/reports/assets/rdc_table.js +665 -0
  29. bobframes-0.2.7/bobframes/reports/assets/sticky.css +48 -0
  30. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/base.py +37 -5
  31. bobframes-0.2.7/bobframes/reports/chrome.py +1068 -0
  32. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/dashboard.py +173 -124
  33. bobframes-0.2.7/bobframes/reports/delta.py +223 -0
  34. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/design_tokens.toml +51 -29
  35. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/discovery.py +9 -0
  36. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/draws_by_class.py +50 -52
  37. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/formatters.py +22 -4
  38. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/instancing_opportunities.py +80 -72
  39. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/orchestrator.py +36 -6
  40. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/overdraw.py +65 -79
  41. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/pass_gpu.py +22 -10
  42. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/preview.py +76 -4
  43. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/shader_hotlist.py +108 -128
  44. bobframes-0.2.7/bobframes/reports/summary.py +307 -0
  45. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/trend_table.py +146 -114
  46. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/run.py +16 -4
  47. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/_render_util.py +18 -0
  48. bobframes-0.2.7/bobframes/tests/data/golden/_reports/draws_by_class.html +806 -0
  49. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/index.html +181 -403
  50. bobframes-0.2.7/bobframes/tests/data/golden/_reports/index.html +794 -0
  51. bobframes-0.2.7/bobframes/tests/data/golden/_reports/instancing_opportunities.html +796 -0
  52. bobframes-0.2.7/bobframes/tests/data/golden/_reports/overdraw.html +805 -0
  53. bobframes-0.2.7/bobframes/tests/data/golden/_reports/pass_gpu.html +806 -0
  54. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/draws_by_class.html +804 -0
  55. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/index.html +795 -0
  56. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/instancing_opportunities.html +793 -0
  57. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/overdraw.html +803 -0
  58. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/pass_gpu.html +802 -0
  59. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/shader_hotlist.html +793 -0
  60. bobframes-0.2.7/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/summary.html +793 -0
  61. bobframes-0.2.7/bobframes/tests/data/golden/_reports/shader_hotlist.html +796 -0
  62. bobframes-0.2.7/bobframes/tests/data/golden/_reports/summary.html +796 -0
  63. bobframes-0.2.7/bobframes/tests/data/golden/_reports/trend_table.html +807 -0
  64. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/index.html +157 -76
  65. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/README.txt +7 -0
  66. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_pagedata/catalog.js +1 -0
  67. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/draws_by_class.html +806 -0
  68. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  69. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  70. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  71. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  72. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  73. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  74. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  75. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  76. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  77. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  78. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  79. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  80. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  81. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  82. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  83. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  84. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  85. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  86. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  87. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  88. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  89. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  90. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  91. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  92. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  93. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  94. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +1842 -0
  95. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/index.html +794 -0
  96. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/instancing_opportunities.html +796 -0
  97. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/overdraw.html +805 -0
  98. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/pass_gpu.html +806 -0
  99. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +804 -0
  100. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/index.html +795 -0
  101. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +793 -0
  102. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/overdraw.html +803 -0
  103. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +802 -0
  104. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +793 -0
  105. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/summary.html +793 -0
  106. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/shader_hotlist.html +796 -0
  107. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/summary.html +796 -0
  108. bobframes-0.2.7/bobframes/tests/data/golden_package/redacted/_reports/trend_table.html +807 -0
  109. {bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565 → bobframes-0.2.7/bobframes/tests/data/golden_package/redacted}/index.html +1172 -198
  110. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/README.txt +7 -0
  111. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/catalog.css +1073 -0
  112. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/catalog.js +665 -0
  113. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/report.css +1 -0
  114. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_assets/report.js +751 -0
  115. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_pagedata/catalog.js +1 -0
  116. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/draws_by_class.html +56 -0
  117. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  118. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  119. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  120. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  121. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  122. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  123. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  124. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  125. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  126. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  127. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  128. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  129. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  130. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  131. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  132. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  133. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  134. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  135. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  136. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  137. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  138. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  139. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  140. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  141. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  142. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  143. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
  144. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/index.html +44 -0
  145. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/instancing_opportunities.html +46 -0
  146. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/overdraw.html +55 -0
  147. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/pass_gpu.html +56 -0
  148. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/draws_by_class.html +54 -0
  149. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/index.html +45 -0
  150. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/instancing_opportunities.html +43 -0
  151. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/overdraw.html +53 -0
  152. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/pass_gpu.html +52 -0
  153. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/shader_hotlist.html +43 -0
  154. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/summary.html +43 -0
  155. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/shader_hotlist.html +46 -0
  156. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/summary.html +46 -0
  157. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/_reports/trend_table.html +57 -0
  158. bobframes-0.2.7/bobframes/tests/data/golden_package/shared/index.html +24 -0
  159. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/README.txt +7 -0
  160. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.css +1073 -0
  161. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.js +665 -0
  162. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/report.css +1 -0
  163. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_assets/report.js +751 -0
  164. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_pagedata/catalog.js +1 -0
  165. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/draws_by_class.html +56 -0
  166. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  167. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  168. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  169. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  170. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  171. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  172. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  173. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  174. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  175. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  176. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  177. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  178. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  179. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  180. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  181. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  182. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  183. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  184. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  185. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  186. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  187. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  188. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  189. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  190. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  191. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  192. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
  193. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/index.html +44 -0
  194. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/instancing_opportunities.html +46 -0
  195. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/overdraw.html +55 -0
  196. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/pass_gpu.html +56 -0
  197. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +54 -0
  198. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/index.html +45 -0
  199. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +43 -0
  200. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/overdraw.html +53 -0
  201. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +52 -0
  202. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +43 -0
  203. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/summary.html +43 -0
  204. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/shader_hotlist.html +46 -0
  205. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/summary.html +46 -0
  206. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/_reports/trend_table.html +57 -0
  207. bobframes-0.2.7/bobframes/tests/data/golden_package/shared_redacted/index.html +24 -0
  208. bobframes-0.2.7/bobframes/tests/data/golden_preview/_chrome_preview.html +817 -0
  209. bobframes-0.2.7/bobframes/tests/make_package_golden.py +78 -0
  210. bobframes-0.2.7/bobframes/tests/test_aggregates.py +175 -0
  211. bobframes-0.2.7/bobframes/tests/test_assets.py +63 -0
  212. bobframes-0.2.7/bobframes/tests/test_browser_shots.py +90 -0
  213. bobframes-0.2.7/bobframes/tests/test_catalog_backup_dedup.py +70 -0
  214. bobframes-0.2.7/bobframes/tests/test_components.py +55 -0
  215. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_config.py +60 -1
  216. bobframes-0.2.7/bobframes/tests/test_contrast.py +102 -0
  217. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_design_tokens.py +56 -17
  218. bobframes-0.2.7/bobframes/tests/test_draws_by_class_kpis.py +34 -0
  219. bobframes-0.2.7/bobframes/tests/test_element_builder.py +88 -0
  220. bobframes-0.2.7/bobframes/tests/test_head_assets.py +126 -0
  221. bobframes-0.2.7/bobframes/tests/test_health.py +163 -0
  222. bobframes-0.2.7/bobframes/tests/test_js_coupled_classes.py +54 -0
  223. bobframes-0.2.7/bobframes/tests/test_multicapture_normalize.py +95 -0
  224. bobframes-0.2.7/bobframes/tests/test_package.py +559 -0
  225. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parity.py +3 -0
  226. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_report_polish.py +3 -2
  227. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_report_structure.py +41 -10
  228. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_run_model.py +32 -1
  229. bobframes-0.2.7/bobframes/tests/test_summary.py +136 -0
  230. bobframes-0.2.7/bobframes/tests/test_table_component.py +224 -0
  231. bobframes-0.2.7/bobframes/tests/test_theme.py +97 -0
  232. bobframes-0.2.7/bobframes/tests/test_token_guard.py +48 -0
  233. bobframes-0.2.7/bobframes/tests/test_trend_regression_basis.py +103 -0
  234. {bobframes-0.2.0 → bobframes-0.2.7}/pyproject.toml +13 -0
  235. bobframes-0.2.0/CHANGELOG.md +0 -77
  236. bobframes-0.2.0/PKG-INFO +0 -168
  237. bobframes-0.2.0/README.md +0 -137
  238. bobframes-0.2.0/bobframes/_version.py +0 -1
  239. bobframes-0.2.0/bobframes/reports/chrome.py +0 -2395
  240. bobframes-0.2.0/bobframes/reports/delta.py +0 -179
  241. bobframes-0.2.0/bobframes/tests/data/golden/_reports/draws_by_class.html +0 -844
  242. bobframes-0.2.0/bobframes/tests/data/golden/_reports/index.html +0 -787
  243. bobframes-0.2.0/bobframes/tests/data/golden/_reports/instancing_opportunities.html +0 -789
  244. bobframes-0.2.0/bobframes/tests/data/golden/_reports/overdraw.html +0 -798
  245. bobframes-0.2.0/bobframes/tests/data/golden/_reports/pass_gpu.html +0 -799
  246. bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/draws_by_class.html +0 -843
  247. bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/instancing_opportunities.html +0 -787
  248. bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/overdraw.html +0 -797
  249. bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/pass_gpu.html +0 -796
  250. bobframes-0.2.0/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/shader_hotlist.html +0 -787
  251. bobframes-0.2.0/bobframes/tests/data/golden/_reports/shader_hotlist.html +0 -789
  252. bobframes-0.2.0/bobframes/tests/data/golden/_reports/trend_table.html +0 -920
  253. bobframes-0.2.0/bobframes/tests/data/golden_preview/_chrome_preview.html +0 -804
  254. {bobframes-0.2.0 → bobframes-0.2.7}/.gitignore +0 -0
  255. {bobframes-0.2.0 → bobframes-0.2.7}/LICENSE +0 -0
  256. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/__init__.py +0 -0
  257. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derive_post_merge.py +0 -0
  258. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/__init__.py +0 -0
  259. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/classifier.py +0 -0
  260. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/draw_classifier.toml +0 -0
  261. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/pass_class_breakdown.py +0 -0
  262. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/custom-template.toml +0 -0
  263. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/godot.toml +0 -0
  264. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/presets/unity.toml +0 -0
  265. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/derives/texture_usage.py +0 -0
  266. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/discovery.py +0 -0
  267. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/errors.py +0 -0
  268. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/html/__init__.py +0 -0
  269. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/lint.py +0 -0
  270. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/lint_banlist.toml +0 -0
  271. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/manifest.py +0 -0
  272. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parquetize.py +0 -0
  273. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/__init__.py +0 -0
  274. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/derive_program_transitions.py +0 -0
  275. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/parsers/parse_init_state.py +0 -0
  276. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/probes/__init__.py +0 -0
  277. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/probes/whatif.py +0 -0
  278. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/qrd_harness.py +0 -0
  279. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/query_examples.py +0 -0
  280. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/rdcmd.py +0 -0
  281. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/replay/__init__.py +0 -0
  282. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/replay/replay_main.py +0 -0
  283. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/Inter-OFL.txt +0 -0
  284. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/README.md +0 -0
  285. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/assets/inter-subset.woff2 +0 -0
  286. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/cache.py +0 -0
  287. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/charts.py +0 -0
  288. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/reports/cli.py +0 -0
  289. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/resource_labels.py +0 -0
  290. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/schemas.py +0 -0
  291. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/stable_keys.py +0 -0
  292. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/__init__.py +0 -0
  293. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_pagedata/catalog.js +0 -0
  294. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +0 -0
  295. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +0 -0
  296. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +0 -0
  297. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +0 -0
  298. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +0 -0
  299. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +0 -0
  300. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +0 -0
  301. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +0 -0
  302. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +0 -0
  303. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +0 -0
  304. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +0 -0
  305. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +0 -0
  306. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +0 -0
  307. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +0 -0
  308. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +0 -0
  309. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +0 -0
  310. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +0 -0
  311. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +0 -0
  312. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +0 -0
  313. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +0 -0
  314. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +0 -0
  315. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +0 -0
  316. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +0 -0
  317. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +0 -0
  318. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +0 -0
  319. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +0 -0
  320. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/golden_parquet/digests.json +0 -0
  321. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/_manifest.json +0 -0
  322. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/buffers.parquet +0 -0
  323. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/clears.parquet +0 -0
  324. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/counters_per_event.parquet +0 -0
  325. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/descriptor_access.parquet +0 -0
  326. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/dispatches.parquet +0 -0
  327. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draw_bindings.parquet +0 -0
  328. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draws.parquet +0 -0
  329. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/events.parquet +0 -0
  330. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/fbos.parquet +0 -0
  331. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/frame_totals.parquet +0 -0
  332. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/ibo_samples.parquet +0 -0
  333. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/indirect_args.parquet +0 -0
  334. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/passes.parquet +0 -0
  335. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/pixel_history.parquet +0 -0
  336. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/post_vs_samples.parquet +0 -0
  337. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/program_transitions.parquet +0 -0
  338. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/programs.parquet +0 -0
  339. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/render_targets.parquet +0 -0
  340. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/resource_creation.parquet +0 -0
  341. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/rt_event_timeline.parquet +0 -0
  342. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/samplers.parquet +0 -0
  343. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/shaders.parquet +0 -0
  344. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/state_change_events.parquet +0 -0
  345. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/texture_samples.parquet +0 -0
  346. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/textures.parquet +0 -0
  347. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vbo_samples.parquet +0 -0
  348. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vertex_inputs.parquet +0 -0
  349. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/_manifest.json +0 -0
  350. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/buffers.parquet +0 -0
  351. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/clears.parquet +0 -0
  352. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/counters_per_event.parquet +0 -0
  353. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/descriptor_access.parquet +0 -0
  354. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/dispatches.parquet +0 -0
  355. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draw_bindings.parquet +0 -0
  356. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draws.parquet +0 -0
  357. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/events.parquet +0 -0
  358. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/fbos.parquet +0 -0
  359. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/frame_totals.parquet +0 -0
  360. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/ibo_samples.parquet +0 -0
  361. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/indirect_args.parquet +0 -0
  362. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/passes.parquet +0 -0
  363. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/pixel_history.parquet +0 -0
  364. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/post_vs_samples.parquet +0 -0
  365. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/program_transitions.parquet +0 -0
  366. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/programs.parquet +0 -0
  367. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/render_targets.parquet +0 -0
  368. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/resource_creation.parquet +0 -0
  369. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/rt_event_timeline.parquet +0 -0
  370. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/samplers.parquet +0 -0
  371. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/shaders.parquet +0 -0
  372. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/state_change_events.parquet +0 -0
  373. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/texture_samples.parquet +0 -0
  374. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/textures.parquet +0 -0
  375. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vbo_samples.parquet +0 -0
  376. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vertex_inputs.parquet +0 -0
  377. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_golden.py +0 -0
  378. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_parquet_golden.py +0 -0
  379. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_preview_golden.py +0 -0
  380. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/make_synthetic.py +0 -0
  381. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/smoke.py +0 -0
  382. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_cache.py +0 -0
  383. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_charts.py +0 -0
  384. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_classifier.py +0 -0
  385. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_delta.py +0 -0
  386. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_determinism.py +0 -0
  387. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_discovery.py +0 -0
  388. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_fonts.py +0 -0
  389. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_hardening.py +0 -0
  390. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_manifest_guard.py +0 -0
  391. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parquet_parity.py +0 -0
  392. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_parquetize.py +0 -0
  393. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_perf.py +0 -0
  394. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_replay_drift.py +0 -0
  395. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_schemas.py +0 -0
  396. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_schemas_unit.py +0 -0
  397. {bobframes-0.2.0 → bobframes-0.2.7}/bobframes/tests/test_stable_keys.py +0 -0
@@ -0,0 +1,167 @@
1
+ # Changelog
2
+
3
+ Changes to this project are documented here, newest first.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.7] - 2026-06-24
11
+
12
+ An aggregation-consistency pass plus four report/sharing correctness fixes. Every KPI now names its
13
+ estimator and rate KPIs read on one per-frame basis, so the same metric agrees across the summary,
14
+ dashboard, and trend. No schema change (still schema 3); parquet digests stay byte-identical on the
15
+ same captures. `_version` 0.2.6 -> 0.2.7.
16
+
17
+ ### Changed
18
+ - One canonical aggregation policy (ADR-46): every rendered KPI label names its estimator precisely --
19
+ `Pooled mean`, `Mean (per area)`, `Median`, `Total` -- and never a bare "avg". Rate KPIs (GPU, draws)
20
+ read per-frame on a single basis, so the same area's GPU now reads identically across the summary,
21
+ dashboard, and trend (previously e.g. `0.0356`/frame on the summary vs a raw `0.178` total on the
22
+ dashboard with no bridge). A naming gate (`test_no_vague_estimator_labels`) fails the build on any
23
+ vague estimator word. (D-13..D-16, Q-10..Q-13)
24
+ - Regression detection unified on the per-frame basis with config-driven thresholds: `trend_table`
25
+ reads every KPI per frame, so a regression flag is capture-count-independent and agrees with the
26
+ build-health verdict (a 7-vs-5-capture run no longer reports a false +40%); the per-KPI thresholds
27
+ (`draws`/`vbo`/`ibo`/`program_switches`) move from code literals to the `[report]` config, with
28
+ defaults that reproduce the prior values. (H-41)
29
+ - `draws_by_class` ratios use `statistics.median` (was the upper-middle `sorted[n//2]`, an off-by-one
30
+ on even N).
31
+ - `aggregates.frame_counts` is the single owner of every per-(drop, area) frame count; when the
32
+ GPU/draws denominator and the entity-rate denominator legitimately differ (a capture that replayed
33
+ but exported partial entity rows), the divergence is logged as a WARNING rather than silently
34
+ normalized away.
35
+
36
+ ### Fixed
37
+ - Run-selector dropdown did nothing on every report: the component JS runs in `<head>`, so the custom
38
+ element upgraded before its child `<select>` had parsed; initialization now defers to
39
+ `DOMContentLoaded`. (R-20)
40
+ - Exported standalone one-pager carried dead tree-relative navigation -- a run dropdown pointing at
41
+ siblings not in the bundle, a breadcrumb, the dashboard link, and a "viewing an older run" banner.
42
+ The detached summary now strips them; the in-tree summary keeps its working navigation. (R-21)
43
+ - Older-run report pages showed cross-drop graphs and tables spanning all runs, including ones newer
44
+ than the page's own run. Cross-drop renderers now scope to run history (up to and including the
45
+ current run) while the run picker keeps the full list. (R-22)
46
+
47
+ ## [0.2.6] - 2026-06-06
48
+
49
+ A build-health one-pager, a shareable `package` bundle, a server-side component system, and a full visual
50
+ redesign. No schema change (still schema 3); parquet digests stay byte-identical to 0.1.0/0.2.0 on the same
51
+ captures. Per ADR-43 there is no standalone 0.2.5 -- this release carries the c16q-c16x foundation AND the
52
+ redesign, so `_version` jumps `0.2.0 -> 0.2.6`.
53
+
54
+ ### Added
55
+ - Build-health one-pager (`bobframes report summary`): a presentation-independent verdict/trend module
56
+ (`health.py` -- ordered OK<UNKNOWN<AT_RISK<ALARM so a real alarm is never masked yet missing data is
57
+ never a false green) feeding a print-first exec summary (verdict bar, averaged KPIs with vs-prior pills +
58
+ sparklines, a baseline-gated movement card, a worst-first by-area table). (ADR-39)
59
+ - `bobframes package`: a non-mutating transform of a rendered tree into a shareable `<project>-<date>-report.zip`
60
+ (reproducible bytes) + a standalone self-contained `summary.html`. `--shared-assets` (the default) dedupes
61
+ chrome into `_assets/` linked per page (built at the render seam, not by scraping HTML); `--inline` opts out;
62
+ `--redact` scrubs device/host provenance at the data seam (whole-tree drop-sidecars excluded). (ADR-40/41)
63
+ - Server-side component system (`reports/chrome.py`): an escape-by-construction element builder (`el`/`raw`/
64
+ `el_void`/`classes`), a normalized table-component family (`Column`/`data_table`/`static_table` + a virtual
65
+ `table_controls`/`virtual_host`/`virtual_table_section` host), a delta-column factory, and a token-validity
66
+ guard (`undefined_tokens()` -- a typo'd `var(--x)` is a CI failure + a `preview` warning). CSS/JS now live as
67
+ real `reports/assets/*.{css,js}` files. A `bobframes preview` gallery documents every component. (ADR-42)
68
+ - User theme override for pip installs: a `.bobframes.toml [theme]` section + `render/preview --accent`/
69
+ `--accent-data` flags re-hue the accent/status/chart colors WITHOUT editing the packaged `design_tokens.toml`
70
+ (deep-merged through the existing config cascade; color-key allowlist; ASCII/injection-guarded). `export-tokens
71
+ --theme-template` emits a paste-ready starter; `--watch` polls `.bobframes.toml`. (ADR-45)
72
+ - Dev-only screenshot harness `tools/shoot.py` (headless-Chrome over CDP, light/dark/print; not shipped) + a
73
+ `-m browser` opt-in matrix + a dependency-free oklch->WCAG contrast test, for the redesign's visual gate.
74
+
75
+ ### Changed
76
+ - Visual redesign anchored on shadcn/ui + Grafana density (ADR-43/44): a neutral grayscale palette (chroma 0),
77
+ WCAG-AA tertiary text, FLAT border-led surfaces (reverses the ADR-34 depth -- a 1px border + a `--radius`
78
+ 6/8/10 token scale replaces the elevation shadows + the hardcoded 2/3/4px radii), `:focus-visible` rings,
79
+ reduced-motion-safe `:active`, container-query responsive, and a print pass. Restrained type tune with hero
80
+ numerals scoped to the summary one-pager; Grafana-dense rows/cards everywhere else; the catalog/drill data
81
+ browser widened (max data-per-screen).
82
+ - "Everything is a component": the summary, dashboard minis, the 6 detail reports, and the catalog/drill virtual
83
+ hosts all render through the component family; the remaining hand-written chrome leaves were migrated onto `el`
84
+ (the bespoke-markup long-tail is closed -- only the fixed page scaffold remains, by necessity). `data_table`
85
+ normalizes the previously hand-written report tables (the visual-parity gate is intentionally replaced by a
86
+ structural + data-preservation gate per ADR-43).
87
+ - Per-frame normalization for multi-capture runs (instancing repeat + shader cost read per distinct capture,
88
+ no-op for 1-capture data so it stays byte-identical) and a single `aggregates.py` data layer feeding the
89
+ dashboard/reports/verdict so they cannot disagree.
90
+ - Run model + sharing surfaced in the root catalog (build-health + dashboard chips, A/B pair lists).
91
+
92
+ ### Fixed
93
+ - Single-drop trend-table crash (`'str' object has no attribute 'get'`); `--force` rotation-backup
94
+ double-counting in the catalog + global-entities walkers (canonical-basename reconstruction).
95
+ - WCAG-AA contrast on tertiary text; print no longer hugs the paper edge.
96
+
97
+ ## [0.2.0] - 2026-06-03
98
+
99
+ De-hardcoding + a full report overhaul. No schema change (still schema 3); extraction output is stable
100
+ where the pipeline is unchanged, so parquet digests are byte-identical to 0.1.0 on the same captures.
101
+
102
+ ### Added
103
+ - Inline-SVG chart toolkit (`reports/charts.py`): a flagship chart per report (pass-GPU treemap,
104
+ draws-by-class donut, shader complexity-vs-cost scatter, overdraw reject-rate bars, instancing
105
+ wasted-index bars, per-KPI trend lines), deterministic and dependency-free (no `random`/`Date`).
106
+ - Report design language: hero KPI strip, callouts with config-driven severity, provenance/device
107
+ strip, section cards, sticky section headers, copy buttons on long IDs, vendored Inter subset font
108
+ (offline, base64-inlined), and an auto-tint heatmap on ranked numeric columns.
109
+ - Run model: per-run truth (each report names "run N of M"), a run picker, A/B compare, and a trend
110
+ table across runs; older runs are pre-rendered up to a configurable limit.
111
+ - One unified `rdc-table` engine (progressive enhancement, two modes): server-baked `static` for reports
112
+ (JS-off / print / Ctrl-F / golden all hold) and windowed `virtual` for the catalog + per-drop drill.
113
+ Shared natural-numeric sort, type-split, heatmap, column groups, search/filter, controllable cell
114
+ truncation with hover-reveal, and full sort/filter a11y (aria-sort + keyboard-operable headers + a
115
+ labelled filter input) across both modes.
116
+ - TOML config (`.bobframes.toml`, `[report]`/`[pipeline]` sections), `design_tokens.toml` token system,
117
+ and a state-capable draw classifier driven by table columns.
118
+ - Reports cache with a SHA256 sidecar (corrupt/missing/mismatch falls back to a live scan, never
119
+ silent-empty); manifest schema-version guard (`ingest --force` hint on mismatch).
120
+
121
+ ### Changed
122
+ - Catalog + drill readability: roomier rows, type-split mono/sans, and the heavy per-table row data moved
123
+ out of the HTML into `_pagedata/*.js` companions (the ~21 MB time-to-interactive fix) loaded via a
124
+ file://-safe `<script defer src>`.
125
+ - External tool resolution + clearer pipeline error messages and exit codes; environment variables
126
+ renamed `RDC_*` -> `BOBFRAMES_*` (one-release legacy fallback with a deprecation warning).
127
+ - Project paths, the report registry, and the drill-size budget are configurable rather than hardcoded.
128
+
129
+ ## [0.1.0] - 2026-05-31
130
+
131
+ First standalone release. v1 is Windows-only (the replay stage drives `qrenderdoc`).
132
+
133
+ ### Added
134
+ - Single `bobframes` binary with subcommands `ingest`, `render`, `ab`, `report`, `catalog`, `lint`,
135
+ `check`, `serve`, `smoke`, and `version`. Positional `root` (default `.`) across verbs; long-flag
136
+ only; exit codes `0`/`1`/`2`/`3`/`4`. stdlib `logging` at INFO by default, `--verbose` for DEBUG,
137
+ `[HH:MM:SS]` line format (G-8).
138
+ - Replay script located via `importlib.resources` (`bobframes.replay.replay_script_path`) so replay
139
+ works from an installed wheel, not just an in-tree checkout.
140
+ - Reliability hardening: atomic writes for `_manifest.json`, Parquet+CSV pairs, and `done.marker`
141
+ (`.tmp` + `os.replace`, rollback on failure); process-tree kill (`taskkill /T /F`) when a
142
+ `qrenderdoc` replay times out; per-capture replay-failure isolation
143
+ (`capture_status='replay_failed'` instead of aborting the whole drop); subprocess stderr logged on
144
+ convert-timeout and on every parse; manifest provenance fields `tool_versions` and `host_info`.
145
+ - Test gates: golden-snapshot parity, schema regression, determinism, performance, and a replay
146
+ column-drift guard against `schemas.py` (H-6); mocked-subprocess tests for the hardening branches
147
+ the GPU-less runner cannot exercise; a data-driven `smoke` (render-only against a bundled synthetic
148
+ fixture by default); unit tests for stable keys, schemas, and drop discovery.
149
+ - GitHub Actions CI across a Windows / Python / pyarrow matrix, with a tag-gated PyPI publish job.
150
+
151
+ ### Changed
152
+ - **Stable-key format upgrade:** stable keys now carry a `KEY_VERSION = 1` version byte in the hash
153
+ input. Keys produced before this release are not comparable with `0.1.0` keys; rebuild affected
154
+ data with `bobframes ingest --force`. `KEY_VERSION` bumps on any future key-derivation rule change.
155
+ - Timestamps unified to a single UTC `now_iso()` helper (`bobframes.manifest.now_iso`); the
156
+ local-time variant in `reports/cli` was dropped.
157
+
158
+ ### Removed
159
+ - The project-embedded `_analysis` package. `python -m _analysis.run` and the other
160
+ `python -m _analysis.*` entry points no longer work; switch to the `bobframes` commands (see the
161
+ migration table in the README). This is a hard rename with no compatibility shim.
162
+
163
+ [Unreleased]: https://github.com/altpsyche/bobframes/compare/v0.2.7...HEAD
164
+ [0.2.7]: https://github.com/altpsyche/bobframes/compare/v0.2.6...v0.2.7
165
+ [0.2.6]: https://github.com/altpsyche/bobframes/compare/v0.2.0...v0.2.6
166
+ [0.2.0]: https://github.com/altpsyche/bobframes/compare/v0.1.0...v0.2.0
167
+ [0.1.0]: https://github.com/altpsyche/bobframes/releases/tag/v0.1.0
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: bobframes
3
+ Version: 0.2.7
4
+ Summary: RenderDoc capture pipeline: ingest, analyze, render.
5
+ Project-URL: Homepage, https://github.com/altpsyche/bobframes
6
+ Project-URL: Issues, https://github.com/altpsyche/bobframes/issues
7
+ Project-URL: Changelog, https://github.com/altpsyche/bobframes/blob/main/CHANGELOG.md
8
+ Author-email: Siva Subramanyam <sivasubramanyam@mayhem-studios.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: gpu,parquet,profiling,renderdoc
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Multimedia :: Graphics
21
+ Classifier: Topic :: Software Development :: Debuggers
22
+ Requires-Python: <3.15,>=3.10
23
+ Requires-Dist: pyarrow<22,>=17
24
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
25
+ Provides-Extra: dev
26
+ Requires-Dist: build; extra == 'dev'
27
+ Requires-Dist: hatchling; extra == 'dev'
28
+ Requires-Dist: pytest; extra == 'dev'
29
+ Requires-Dist: twine; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # BobFrames
33
+
34
+ RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
35
+ produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
36
+ browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
37
+ hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
38
+ Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
39
+
40
+ > Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
41
+
42
+ ## Requirements
43
+
44
+ - Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
45
+ - Python 3.10 - 3.13.
46
+ - RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
47
+
48
+ ## Install
49
+
50
+ ```
51
+ pipx install bobframes
52
+ bobframes check
53
+ ```
54
+
55
+ `bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
56
+ either is missing, so you can confirm the toolchain before a long ingest.
57
+
58
+ ## Quickstart
59
+
60
+ ```
61
+ cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
62
+ bobframes ingest . # export, parse, replay, parquetize, derive, render
63
+ bobframes serve . # open a local static preview of the reports
64
+ ```
65
+
66
+ `ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
67
+ time to rebuild the HTML from existing Parquet without re-replaying captures.
68
+
69
+ ## Commands
70
+
71
+ | Command | Purpose |
72
+ |---|---|
73
+ | `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
74
+ | `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
75
+ | `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
76
+ | `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
77
+ | `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
78
+ | `lint <file>...` | Check HTML or markdown against the banlist. |
79
+ | `check` | Print resolved tool paths; non-zero when a tool is missing. |
80
+ | `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
81
+ | `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
82
+ | `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
83
+ | `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
84
+ | `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
85
+ | `version` | Print `bobframes`, schema, and pyarrow versions. |
86
+
87
+ `<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
88
+ `1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
89
+
90
+ ## Sharing a report
91
+
92
+ `bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
93
+ `<root>`):
94
+
95
+ - `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
96
+ opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
97
+ `_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
98
+ - `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
99
+ it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
100
+ the zip is shipped alongside.)
101
+
102
+ The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
103
+ and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
104
+ folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
105
+ standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
106
+ self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
107
+ + the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
108
+
109
+ ### Sharing externally -- `--redact`
110
+
111
+ `bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
112
+ scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
113
+ `redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
114
+ bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
115
+ downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
116
+
117
+ - `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
118
+ - `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
119
+ path remains in a rendered page, so a leak fails the build.
120
+
121
+ **Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
122
+ contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
123
+ leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
124
+
125
+ ## Customizing reports
126
+
127
+ The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
128
+
129
+ ### Pip installs -- re-hue without editing source (recommended)
130
+
131
+ `pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
132
+ re-hue the accent / status / chart colors through the config cascade instead:
133
+
134
+ - **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
135
+ `%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
136
+ starter with just the overridable color knobs.
137
+ - **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
138
+ precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
139
+ it with no capture data.
140
+
141
+ Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
142
+ spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
143
+ non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
144
+
145
+ ### Source checkouts -- edit the bundled tokens
146
+
147
+ The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
148
+ and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
149
+ `accent_primary` becomes `--accent-primary`.
150
+
151
+ ```
152
+ bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
153
+ # edit a value in design_tokens.toml
154
+ bobframes preview # under a second; reload the page in a browser
155
+ bobframes render C:\captures # apply the change to real reports from existing Parquet
156
+ ```
157
+
158
+ `bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
159
+ `.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
160
+ css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
161
+
162
+ ## External tools
163
+
164
+ The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
165
+ resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
166
+ install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
167
+ config entry at it. Run `bobframes check` to see what was resolved.
168
+
169
+ ## Output layout
170
+
171
+ ```
172
+ <root>/
173
+ index.html root catalog view
174
+ <area>/<drop>/ raw RDC inputs (left untouched)
175
+ _data/ pipeline outputs
176
+ _catalog.parquet (+ .csv, .json)
177
+ _global_entities.parquet (+ .csv)
178
+ _query_examples.md
179
+ <area>/<drop>/ per-drop data (29 Parquet tables)
180
+ *.parquet (+ matching .csv)
181
+ _manifest.json, _resource_labels.json
182
+ shader_src/*.glsl, jsonl sidecars
183
+ done.marker
184
+ _reports/ rendered HTML
185
+ *.html (dashboard + reports)
186
+ ab/<pair>/*.html
187
+ drill/<area>/<drop>/index.html per-drop browser
188
+ _cache/
189
+ ```
190
+
191
+ The catalog stores each drop's path relative to `<root>` for portability.
192
+
193
+ ## Migrating from `_analysis`
194
+
195
+ v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
196
+ `python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
197
+
198
+ | Old (`_analysis`) | New (`bobframes`) |
199
+ |---|---|
200
+ | `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
201
+ | `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
202
+ | `python -m _analysis.lint <file>` | `bobframes lint <file>` |
203
+ | `python -m _analysis.tests.smoke` | `bobframes smoke` |
204
+
205
+ ## Troubleshooting
206
+
207
+ | Symptom | Resolution |
208
+ |---|---|
209
+ | `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
210
+ | `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
211
+ | Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
212
+ | `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
213
+ | Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
214
+
215
+ ## Advanced
216
+
217
+ - A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
218
+ - Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
219
+ table lookups, drop discovery, and path resolution from your own scripts.
220
+ - `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
221
+ - TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
222
+ (`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
223
+ redacted bundles (see [Sharing a report](#sharing-a-report)).
224
+
225
+ ## Built for Mayhem Studios
226
+
227
+ BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
228
+ capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
229
+ graphics community.
230
+
231
+ If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
232
+ possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
233
+ A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
234
+
235
+ ## License
236
+
237
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,206 @@
1
+ # BobFrames
2
+
3
+ RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
4
+ produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
5
+ browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
6
+ hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
7
+ Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
8
+
9
+ > Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
10
+
11
+ ## Requirements
12
+
13
+ - Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
14
+ - Python 3.10 - 3.13.
15
+ - RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
16
+
17
+ ## Install
18
+
19
+ ```
20
+ pipx install bobframes
21
+ bobframes check
22
+ ```
23
+
24
+ `bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
25
+ either is missing, so you can confirm the toolchain before a long ingest.
26
+
27
+ ## Quickstart
28
+
29
+ ```
30
+ cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
31
+ bobframes ingest . # export, parse, replay, parquetize, derive, render
32
+ bobframes serve . # open a local static preview of the reports
33
+ ```
34
+
35
+ `ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
36
+ time to rebuild the HTML from existing Parquet without re-replaying captures.
37
+
38
+ ## Commands
39
+
40
+ | Command | Purpose |
41
+ |---|---|
42
+ | `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
43
+ | `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
44
+ | `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
45
+ | `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
46
+ | `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
47
+ | `lint <file>...` | Check HTML or markdown against the banlist. |
48
+ | `check` | Print resolved tool paths; non-zero when a tool is missing. |
49
+ | `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
50
+ | `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
51
+ | `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
52
+ | `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
53
+ | `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
54
+ | `version` | Print `bobframes`, schema, and pyarrow versions. |
55
+
56
+ `<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
57
+ `1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
58
+
59
+ ## Sharing a report
60
+
61
+ `bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
62
+ `<root>`):
63
+
64
+ - `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
65
+ opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
66
+ `_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
67
+ - `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
68
+ it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
69
+ the zip is shipped alongside.)
70
+
71
+ The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
72
+ and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
73
+ folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
74
+ standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
75
+ self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
76
+ + the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
77
+
78
+ ### Sharing externally -- `--redact`
79
+
80
+ `bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
81
+ scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
82
+ `redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
83
+ bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
84
+ downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
85
+
86
+ - `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
87
+ - `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
88
+ path remains in a rendered page, so a leak fails the build.
89
+
90
+ **Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
91
+ contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
92
+ leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
93
+
94
+ ## Customizing reports
95
+
96
+ The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
97
+
98
+ ### Pip installs -- re-hue without editing source (recommended)
99
+
100
+ `pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
101
+ re-hue the accent / status / chart colors through the config cascade instead:
102
+
103
+ - **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
104
+ `%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
105
+ starter with just the overridable color knobs.
106
+ - **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
107
+ precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
108
+ it with no capture data.
109
+
110
+ Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
111
+ spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
112
+ non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
113
+
114
+ ### Source checkouts -- edit the bundled tokens
115
+
116
+ The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
117
+ and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
118
+ `accent_primary` becomes `--accent-primary`.
119
+
120
+ ```
121
+ bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
122
+ # edit a value in design_tokens.toml
123
+ bobframes preview # under a second; reload the page in a browser
124
+ bobframes render C:\captures # apply the change to real reports from existing Parquet
125
+ ```
126
+
127
+ `bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
128
+ `.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
129
+ css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
130
+
131
+ ## External tools
132
+
133
+ The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
134
+ resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
135
+ install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
136
+ config entry at it. Run `bobframes check` to see what was resolved.
137
+
138
+ ## Output layout
139
+
140
+ ```
141
+ <root>/
142
+ index.html root catalog view
143
+ <area>/<drop>/ raw RDC inputs (left untouched)
144
+ _data/ pipeline outputs
145
+ _catalog.parquet (+ .csv, .json)
146
+ _global_entities.parquet (+ .csv)
147
+ _query_examples.md
148
+ <area>/<drop>/ per-drop data (29 Parquet tables)
149
+ *.parquet (+ matching .csv)
150
+ _manifest.json, _resource_labels.json
151
+ shader_src/*.glsl, jsonl sidecars
152
+ done.marker
153
+ _reports/ rendered HTML
154
+ *.html (dashboard + reports)
155
+ ab/<pair>/*.html
156
+ drill/<area>/<drop>/index.html per-drop browser
157
+ _cache/
158
+ ```
159
+
160
+ The catalog stores each drop's path relative to `<root>` for portability.
161
+
162
+ ## Migrating from `_analysis`
163
+
164
+ v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
165
+ `python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
166
+
167
+ | Old (`_analysis`) | New (`bobframes`) |
168
+ |---|---|
169
+ | `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
170
+ | `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
171
+ | `python -m _analysis.lint <file>` | `bobframes lint <file>` |
172
+ | `python -m _analysis.tests.smoke` | `bobframes smoke` |
173
+
174
+ ## Troubleshooting
175
+
176
+ | Symptom | Resolution |
177
+ |---|---|
178
+ | `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
179
+ | `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
180
+ | Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
181
+ | `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
182
+ | Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
183
+
184
+ ## Advanced
185
+
186
+ - A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
187
+ - Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
188
+ table lookups, drop discovery, and path resolution from your own scripts.
189
+ - `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
190
+ - TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
191
+ (`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
192
+ redacted bundles (see [Sharing a report](#sharing-a-report)).
193
+
194
+ ## Built for Mayhem Studios
195
+
196
+ BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
197
+ capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
198
+ graphics community.
199
+
200
+ If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
201
+ possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
202
+ A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
203
+
204
+ ## License
205
+
206
+ MIT. See [LICENSE](LICENSE).
@@ -56,6 +56,10 @@ preset = "ue" # draw_classifier.toml (UE default); "unity"/"godot"
56
56
  shader_complexity_high = 60.0 # fragment shaders at/above this complexity are flagged
57
57
  overdraw_reject_warn_pct = 40.0 # RT sample-rejection % -> warn callout
58
58
  overdraw_reject_alarm_pct = 70.0 # RT sample-rejection % -> alarm callout
59
- instancing_repeat_min = 4 # min mesh repeat to count as an instancing candidate
60
- gpu_regression_pct = 10.0 # latest-vs-previous GPU increase % -> regression callout
59
+ instancing_repeat_min = 4 # min mesh repeat PER FRAME to flag an instancing candidate (c16v: repeat + shader cost are per-frame rates, normalized by the drop's captured-frame count)
60
+ gpu_regression_pct = 10.0 # latest-vs-previous GPU/frame increase % -> regression (per frame, capture-count-independent)
61
+ draws_regression_pct = 10.0 # H-41 — per-KPI trend regression thresholds (were baked in trend_table.KPIS literals)
62
+ vbo_regression_pct = 15.0 # " vertex-buffer bytes / frame
63
+ ibo_regression_pct = 15.0 # " index-buffer bytes / frame
64
+ program_switches_regression_pct = 20.0 # " program switches / frame
61
65
  max_prerendered_runs = 10 # c16f — cap on pre-rendered older-run pages (run selector)
@@ -0,0 +1 @@
1
+ __version__ = "0.2.7"