From 3442ba149a9e3b65dda81e3db476e7568a9e0526 Mon Sep 17 00:00:00 2001 From: "developerz-ai[bot]" <286432749+developerz-ai[bot]@users.noreply.github.com> Date: Tue, 3 Nov 2026 20:08:17 +0000 Subject: [PATCH 1/3] refactor: move app and gem into apps/ruby2html (house layout) Move the 22 house-layout items (app, config, db, ext, lib, spec, bench, gemfiles, public, log, storage, vendor, Gemfile+lock, Rakefile, config.ru, ruby2html.gemspec, llms.txt, .rspec, .rubocop.yml, .ruby-version) under apps/ruby2html/, file by file. The root keeps the boundary: bin/, .github/, .dz/, .claude/, docs/, .devcontainer/, .gitignore, .dockerignore, .gitattributes, lefthook.yml, mise.toml, tmp/. Root Gemfile becomes a workspace stub eval_gemfile'ing apps/ruby2html/Gemfile; bundler always runs from the app dir (bin/check, bin/setup, lefthook root:, CI working-directory, dependabot /apps/ruby2html). Boundary references updated: bin/ scripts, CI workflows, dependabot, .dz policies and briefs, .claude skills/agents, AGENTS.md and docs. Packaging copies of README.md/LICENSE/CHANGELOG.md added beside the gemspec: bin/gem-smoke:43 requires them inside the built gem, which the gemspec selects via File.file? next to itself. .gitignore gains apps/ruby2html re-anchors; no existing rule removed; root .dockerignore untouched (devcontainer builds use root context). Dz-Task-Id: tsk_697d58676e6ed343d2e14497993be198 --- .claude/agents/perf-reviewer.md | 4 +- .claude/agents/xss-auditor.md | 4 +- .claude/commands/feature.md | 2 +- .claude/settings.json | 4 +- .claude/skills/add-html-tag/SKILL.md | 10 +- .claude/skills/benchmark/SKILL.md | 6 +- .claude/skills/debug-render/SKILL.md | 22 +- .claude/skills/release/SKILL.md | 4 +- .claude/skills/review/SKILL.md | 10 +- .claude/skills/upgrade-deps/SKILL.md | 6 +- .devcontainer/Dockerfile | 2 +- .dz/briefs/health.md | 2 +- .dz/briefs/improve.md | 2 +- .dz/briefs/release-due.md | 9 +- .dz/briefs/security-release.md | 4 +- .dz/maintainer/maintainer.yml | 14 +- .dz/maintainer/reviewer.md | 2 +- .gitattributes | 8 +- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/ISSUE_TEMPLATE/performance.yml | 2 +- .github/dependabot.yml | 4 +- .github/pull_request_template.md | 10 +- .github/workflows/benchmark.yml | 16 +- .github/workflows/canary.yml | 14 +- .github/workflows/ci.yml | 87 ++++-- .github/workflows/release.yml | 38 ++- .gitignore | 57 ++++ AGENTS.md | 105 +++---- CONTRIBUTING.md | 19 +- Gemfile | 51 +--- README.md | 21 +- SECURITY.md | 4 +- apps/ruby2html/.dockerignore | 48 ++++ .rspec => apps/ruby2html/.rspec | 0 .rubocop.yml => apps/ruby2html/.rubocop.yml | 0 .ruby-version => apps/ruby2html/.ruby-version | 0 apps/ruby2html/CHANGELOG.md | 216 ++++++++++++++ apps/ruby2html/Gemfile | 51 ++++ Gemfile.lock => apps/ruby2html/Gemfile.lock | 0 apps/ruby2html/LICENSE | 21 ++ apps/ruby2html/README.md | 263 ++++++++++++++++++ Rakefile => apps/ruby2html/Rakefile | 7 +- .../ruby2html/app}/assets/config/manifest.js | 0 .../ruby2html/app}/assets/images/.keep | 0 .../app}/assets/stylesheets/application.css | 0 .../channels/application_cable/channel.rb | 0 .../channels/application_cable/connection.rb | 0 .../app}/components/application_component.rb | 0 .../app}/components/benchmark_component.rb | 0 .../app}/components/first_component.html.rb | 0 .../app}/components/first_component.rb | 0 .../components/native_benchmark_component.rb | 0 .../components/native_user_card_component.rb | 0 .../app}/components/second_component.rb | 0 .../app}/components/third_component.rb | 0 .../third_component/third_component.html.rb | 0 .../controllers/application_controller.rb | 0 .../app}/controllers/benchmark_controller.rb | 0 .../ruby2html/app}/controllers/concerns/.keep | 0 .../app}/controllers/home_controller.rb | 0 .../app}/helpers/application_helper.rb | 0 .../ruby2html/app}/jobs/application_job.rb | 0 .../app}/mailers/application_mailer.rb | 0 .../app}/models/application_record.rb | 0 .../ruby2html/app}/models/concerns/.keep | 0 .../ruby2html/app}/phlex/phlex_view.rb | 0 .../app}/views/benchmark/normal_html.html.erb | 0 .../app}/views/benchmark/ruby_2html.html.rb | 0 .../app}/views/benchmark/slim_html.html.slim | 0 .../ruby2html/app}/views/home/form.html.rb | 0 .../ruby2html/app}/views/home/index.html.erb | 0 .../app}/views/home/rb_files.html.rb | 0 .../app}/views/layouts/application.html.erb | 0 .../app}/views/layouts/mailer.html.erb | 0 .../app}/views/layouts/mailer.text.erb | 0 .../app}/views/pwa/manifest.json.erb | 0 .../app}/views/pwa/service-worker.js | 0 .../app}/views/shared/_footer.html.rb | 0 .../app}/views/shared/_navbar.html.erb | 0 .../ruby2html/bench}/escape_bench.rb | 0 .../ruby2html/bench}/render_bench.rb | 0 {bench => apps/ruby2html/bench}/tag_bench.rb | 0 config.ru => apps/ruby2html/config.ru | 0 .../ruby2html/config}/application.rb | 0 {config => apps/ruby2html/config}/boot.rb | 0 .../ruby2html/config}/brakeman.yml | 0 {config => apps/ruby2html/config}/cable.yml | 0 .../ruby2html/config}/credentials.yml.enc | 0 .../ruby2html/config}/database.yml | 0 .../ruby2html/config}/environment.rb | 0 .../config}/environments/development.rb | 0 .../config}/environments/production.rb | 0 .../ruby2html/config}/environments/test.rb | 0 .../ruby2html/config}/initializers/assets.rb | 0 .../initializers/content_security_policy.rb | 0 .../initializers/filter_parameter_logging.rb | 0 .../config}/initializers/inflections.rb | 0 .../initializers/permissions_policy.rb | 0 .../ruby2html/config}/locales/en.yml | 0 {config => apps/ruby2html/config}/puma.rb | 0 {config => apps/ruby2html/config}/routes.rb | 0 {config => apps/ruby2html/config}/storage.yml | 0 {db => apps/ruby2html/db}/seeds.rb | 0 .../ext}/java/Ruby2htmlJrubyService.java | 0 .../ruby2html/ext}/ruby2html/attributes.c | 0 .../ruby2html/ext}/ruby2html/buffer.h | 0 .../ruby2html/ext}/ruby2html/content.c | 0 .../ruby2html/ext}/ruby2html/extconf.rb | 0 .../ruby2html/ext}/ruby2html/html_escape.c | 0 .../ruby2html/ext}/ruby2html/ruby2html.c | 0 .../ruby2html/ext}/ruby2html/ruby2html.h | 0 .../ruby2html/ext}/ruby2html/tag_render.c | 0 .../ruby2html/gemfiles}/rails.gemfile | 0 .../ruby2html/gemfiles}/rails_common.rb | 0 .../ruby2html/gemfiles}/standalone.gemfile | 0 {lib => apps/ruby2html/lib}/assets/.keep | 0 {lib => apps/ruby2html/lib}/gem/ruby2html.rb | 0 .../ruby2html/lib}/gem/ruby2html/component.rb | 0 .../lib}/gem/ruby2html/component_helper.rb | 0 .../ruby2html/html_beautifier_middleware.rb | 0 .../rails_components/base_component.rb | 0 .../ruby2html/rails_components/button_to.rb | 0 .../ruby2html/rails_components/form_with.rb | 0 .../ruby2html/rails_components/image_tag.rb | 0 .../gem/ruby2html/rails_components/link_to.rb | 0 .../rails_components/output_capture.rb | 0 .../rails_components/template_collector.rb | 0 .../rails_components/template_compiler.rb | 0 .../rails_components/template_helpers.rb | 0 .../lib}/gem/ruby2html/rails_helper.rb | 0 .../ruby2html/lib}/gem/ruby2html/railtie.rb | 0 .../ruby2html/lib}/gem/ruby2html/render.rb | 0 .../lib}/gem/ruby2html/render/pure_ruby.rb | 0 .../ruby2html/lib}/gem/ruby2html/version.rb | 0 {lib => apps/ruby2html/lib}/tasks/.keep | 0 llms.txt => apps/ruby2html/llms.txt | 0 {log => apps/ruby2html/log}/.keep | 0 {public => apps/ruby2html/public}/404.html | 0 .../public}/406-unsupported-browser.html | 0 {public => apps/ruby2html/public}/422.html | 0 {public => apps/ruby2html/public}/500.html | 0 {public => apps/ruby2html/public}/icon.png | Bin {public => apps/ruby2html/public}/icon.svg | 0 {public => apps/ruby2html/public}/robots.txt | 0 .../ruby2html/ruby2html.gemspec | 4 + .../spec}/benchmarks/requests_spec.rb | 0 .../ruby2html/spec}/bin/setup_spec.rb | 2 +- .../ruby2html/spec}/features/home_spec.rb | 0 .../spec}/features/native_component_spec.rb | 0 .../spec}/features/rails_integration_spec.rb | 0 .../spec}/gem/rails/component_helper_spec.rb | 0 .../spec}/gem/rails/component_spec.rb | 0 .../rails/html_beautifier_middleware_spec.rb | 0 .../spec}/gem/rails/rails_components_spec.rb | 0 .../gem/rails/support/template_rendering.rb | 0 .../spec}/gem/rails/template_capture_spec.rb | 0 .../spec}/gem/rails/template_compiler_spec.rb | 0 .../spec}/gem/rails/template_handler_spec.rb | 0 .../spec}/gem/rails/template_locals_spec.rb | 0 .../spec}/gem/rails/view_component_spec.rb | 0 .../spec}/gem/render_attributes_spec.rb | 0 .../ruby2html/spec}/gem/render_escape_spec.rb | 0 .../spec}/gem/render_hardening_spec.rb | 0 .../ruby2html/spec}/gem/render_parity_spec.rb | 0 .../ruby2html/spec}/gem/render_spec.rb | 0 .../ruby2html/spec}/gem/render_spec_helper.rb | 0 {spec => apps/ruby2html/spec}/rails_helper.rb | 0 {spec => apps/ruby2html/spec}/spec_helper.rb | 0 {storage => apps/ruby2html/storage}/.keep | 0 {vendor => apps/ruby2html/vendor}/.keep | 0 bin/bench-report | 2 +- bin/build-ext | 2 +- bin/bundle | 2 +- bin/check | 9 +- bin/console | 2 +- bin/gem-smoke | 2 +- bin/rails | 4 +- bin/rake | 4 +- bin/rubocop | 2 +- bin/setup | 15 +- docs/architecture.md | 24 +- docs/release.md | 8 +- lefthook.yml | 9 +- 183 files changed, 979 insertions(+), 263 deletions(-) create mode 100644 apps/ruby2html/.dockerignore rename .rspec => apps/ruby2html/.rspec (100%) rename .rubocop.yml => apps/ruby2html/.rubocop.yml (100%) rename .ruby-version => apps/ruby2html/.ruby-version (100%) create mode 100644 apps/ruby2html/CHANGELOG.md create mode 100644 apps/ruby2html/Gemfile rename Gemfile.lock => apps/ruby2html/Gemfile.lock (100%) create mode 100644 apps/ruby2html/LICENSE create mode 100644 apps/ruby2html/README.md rename Rakefile => apps/ruby2html/Rakefile (95%) rename {app => apps/ruby2html/app}/assets/config/manifest.js (100%) rename {app => apps/ruby2html/app}/assets/images/.keep (100%) rename {app => apps/ruby2html/app}/assets/stylesheets/application.css (100%) rename {app => apps/ruby2html/app}/channels/application_cable/channel.rb (100%) rename {app => apps/ruby2html/app}/channels/application_cable/connection.rb (100%) rename {app => apps/ruby2html/app}/components/application_component.rb (100%) rename {app => apps/ruby2html/app}/components/benchmark_component.rb (100%) rename {app => apps/ruby2html/app}/components/first_component.html.rb (100%) rename {app => apps/ruby2html/app}/components/first_component.rb (100%) rename {app => apps/ruby2html/app}/components/native_benchmark_component.rb (100%) rename {app => apps/ruby2html/app}/components/native_user_card_component.rb (100%) rename {app => apps/ruby2html/app}/components/second_component.rb (100%) rename {app => apps/ruby2html/app}/components/third_component.rb (100%) rename {app => apps/ruby2html/app}/components/third_component/third_component.html.rb (100%) rename {app => apps/ruby2html/app}/controllers/application_controller.rb (100%) rename {app => apps/ruby2html/app}/controllers/benchmark_controller.rb (100%) rename {app => apps/ruby2html/app}/controllers/concerns/.keep (100%) rename {app => apps/ruby2html/app}/controllers/home_controller.rb (100%) rename {app => apps/ruby2html/app}/helpers/application_helper.rb (100%) rename {app => apps/ruby2html/app}/jobs/application_job.rb (100%) rename {app => apps/ruby2html/app}/mailers/application_mailer.rb (100%) rename {app => apps/ruby2html/app}/models/application_record.rb (100%) rename {app => apps/ruby2html/app}/models/concerns/.keep (100%) rename {app => apps/ruby2html/app}/phlex/phlex_view.rb (100%) rename {app => apps/ruby2html/app}/views/benchmark/normal_html.html.erb (100%) rename {app => apps/ruby2html/app}/views/benchmark/ruby_2html.html.rb (100%) rename {app => apps/ruby2html/app}/views/benchmark/slim_html.html.slim (100%) rename {app => apps/ruby2html/app}/views/home/form.html.rb (100%) rename {app => apps/ruby2html/app}/views/home/index.html.erb (100%) rename {app => apps/ruby2html/app}/views/home/rb_files.html.rb (100%) rename {app => apps/ruby2html/app}/views/layouts/application.html.erb (100%) rename {app => apps/ruby2html/app}/views/layouts/mailer.html.erb (100%) rename {app => apps/ruby2html/app}/views/layouts/mailer.text.erb (100%) rename {app => apps/ruby2html/app}/views/pwa/manifest.json.erb (100%) rename {app => apps/ruby2html/app}/views/pwa/service-worker.js (100%) rename {app => apps/ruby2html/app}/views/shared/_footer.html.rb (100%) rename {app => apps/ruby2html/app}/views/shared/_navbar.html.erb (100%) rename {bench => apps/ruby2html/bench}/escape_bench.rb (100%) rename {bench => apps/ruby2html/bench}/render_bench.rb (100%) rename {bench => apps/ruby2html/bench}/tag_bench.rb (100%) rename config.ru => apps/ruby2html/config.ru (100%) rename {config => apps/ruby2html/config}/application.rb (100%) rename {config => apps/ruby2html/config}/boot.rb (100%) rename {config => apps/ruby2html/config}/brakeman.yml (100%) rename {config => apps/ruby2html/config}/cable.yml (100%) rename {config => apps/ruby2html/config}/credentials.yml.enc (100%) rename {config => apps/ruby2html/config}/database.yml (100%) rename {config => apps/ruby2html/config}/environment.rb (100%) rename {config => apps/ruby2html/config}/environments/development.rb (100%) rename {config => apps/ruby2html/config}/environments/production.rb (100%) rename {config => apps/ruby2html/config}/environments/test.rb (100%) rename {config => apps/ruby2html/config}/initializers/assets.rb (100%) rename {config => apps/ruby2html/config}/initializers/content_security_policy.rb (100%) rename {config => apps/ruby2html/config}/initializers/filter_parameter_logging.rb (100%) rename {config => apps/ruby2html/config}/initializers/inflections.rb (100%) rename {config => apps/ruby2html/config}/initializers/permissions_policy.rb (100%) rename {config => apps/ruby2html/config}/locales/en.yml (100%) rename {config => apps/ruby2html/config}/puma.rb (100%) rename {config => apps/ruby2html/config}/routes.rb (100%) rename {config => apps/ruby2html/config}/storage.yml (100%) rename {db => apps/ruby2html/db}/seeds.rb (100%) rename {ext => apps/ruby2html/ext}/java/Ruby2htmlJrubyService.java (100%) rename {ext => apps/ruby2html/ext}/ruby2html/attributes.c (100%) rename {ext => apps/ruby2html/ext}/ruby2html/buffer.h (100%) rename {ext => apps/ruby2html/ext}/ruby2html/content.c (100%) rename {ext => apps/ruby2html/ext}/ruby2html/extconf.rb (100%) rename {ext => apps/ruby2html/ext}/ruby2html/html_escape.c (100%) rename {ext => apps/ruby2html/ext}/ruby2html/ruby2html.c (100%) rename {ext => apps/ruby2html/ext}/ruby2html/ruby2html.h (100%) rename {ext => apps/ruby2html/ext}/ruby2html/tag_render.c (100%) rename {gemfiles => apps/ruby2html/gemfiles}/rails.gemfile (100%) rename {gemfiles => apps/ruby2html/gemfiles}/rails_common.rb (100%) rename {gemfiles => apps/ruby2html/gemfiles}/standalone.gemfile (100%) rename {lib => apps/ruby2html/lib}/assets/.keep (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/component.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/component_helper.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/html_beautifier_middleware.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/base_component.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/button_to.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/form_with.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/image_tag.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/link_to.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/output_capture.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/template_collector.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/template_compiler.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_components/template_helpers.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/rails_helper.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/railtie.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/render.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/render/pure_ruby.rb (100%) rename {lib => apps/ruby2html/lib}/gem/ruby2html/version.rb (100%) rename {lib => apps/ruby2html/lib}/tasks/.keep (100%) rename llms.txt => apps/ruby2html/llms.txt (100%) rename {log => apps/ruby2html/log}/.keep (100%) rename {public => apps/ruby2html/public}/404.html (100%) rename {public => apps/ruby2html/public}/406-unsupported-browser.html (100%) rename {public => apps/ruby2html/public}/422.html (100%) rename {public => apps/ruby2html/public}/500.html (100%) rename {public => apps/ruby2html/public}/icon.png (100%) rename {public => apps/ruby2html/public}/icon.svg (100%) rename {public => apps/ruby2html/public}/robots.txt (100%) rename ruby2html.gemspec => apps/ruby2html/ruby2html.gemspec (91%) rename {spec => apps/ruby2html/spec}/benchmarks/requests_spec.rb (100%) rename {spec => apps/ruby2html/spec}/bin/setup_spec.rb (95%) rename {spec => apps/ruby2html/spec}/features/home_spec.rb (100%) rename {spec => apps/ruby2html/spec}/features/native_component_spec.rb (100%) rename {spec => apps/ruby2html/spec}/features/rails_integration_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/component_helper_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/component_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/html_beautifier_middleware_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/rails_components_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/support/template_rendering.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/template_capture_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/template_compiler_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/template_handler_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/template_locals_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/rails/view_component_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_attributes_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_escape_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_hardening_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_parity_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_spec.rb (100%) rename {spec => apps/ruby2html/spec}/gem/render_spec_helper.rb (100%) rename {spec => apps/ruby2html/spec}/rails_helper.rb (100%) rename {spec => apps/ruby2html/spec}/spec_helper.rb (100%) rename {storage => apps/ruby2html/storage}/.keep (100%) rename {vendor => apps/ruby2html/vendor}/.keep (100%) diff --git a/.claude/agents/perf-reviewer.md b/.claude/agents/perf-reviewer.md index dbe74eb..c6cfc01 100644 --- a/.claude/agents/perf-reviewer.md +++ b/.claude/agents/perf-reviewer.md @@ -1,6 +1,6 @@ --- name: perf-reviewer -description: Reviews a diff in ruby2html for rendering-speed regressions and missed optimizations (allocations, buffer sizing, method dispatch, C hot paths). Use proactively after changes to lib/gem/ruby2html/render.rb, ext/ruby2html/*, or the template handler, and before merging perf claims. +description: Reviews a diff in ruby2html for rendering-speed regressions and missed optimizations (allocations, buffer sizing, method dispatch, C hot paths). Use proactively after changes to apps/ruby2html/lib/gem/ruby2html/render.rb, apps/ruby2html/ext/ruby2html/*, or the template handler, and before merging perf claims. tools: Read, Grep, Glob, Bash --- @@ -15,6 +15,6 @@ Check, citing file:line: - Caches: unbounded growth, keys that can collide (never cache by `Object#hash` alone). - Template handler / ComponentHelper: work done per render that could be done at compile time. -Run only read-only or benchmark commands: `bundle exec rake compile`, `bundle exec rake bench`, `bundle exec ruby -Ilib/gem -Ilib bench/