From 567271a269e5fabf4d96ae5639417058cd16e580 Mon Sep 17 00:00:00 2001 From: cppenloglou Date: Thu, 11 Jun 2026 21:58:46 +0300 Subject: [PATCH 1/2] Add Phase B analysis scripts and update documentation - Introduced `phase_b_runner.py` for submitting Docker artifacts to the analysis platform and handling results. - Added `phase_b_aggregate.py` to compile and generate statistics from analysis results. - Created `phase_b_stats_final.md` and `phase_b_stats.md` for detailed reporting of analysis outcomes. - Updated `.gitignore` to include new directories and files related to the analysis process. - Enhanced `README.md` and `README-evaluation.md` to document the Phase B evaluation methodology and results. - Removed obsolete hook scripts and rules related to backend checks to streamline the project. --- .cursor/hooks.json | 12 - .cursor/hooks/run-strict-gates.sh | 65 - .cursor/rules/backend-api-routers.mdc | 40 - .cursor/rules/backend-infrastructure.mdc | 48 - .cursor/rules/backend-plugins.mdc | 56 - .cursor/rules/backend-python-conventions.mdc | 51 - .cursor/rules/creative-frontend-animation.mdc | 41 - .cursor/rules/docker-and-devops.mdc | 48 - .cursor/rules/frontend-react-patterns.mdc | 74 - .cursor/rules/frontend-styling.mdc | 66 - .cursor/rules/frontend-typescript.mdc | 51 - .cursor/rules/project-architecture.mdc | 63 - .cursor/rules/project-runtime-safety.mdc | 35 - .cursor/rules/project-workflow.mdc | 28 - .cursor/rules/research-privacy.mdc | 35 - .cursor/rules/results-and-monitoring.mdc | 32 - .cursor/rules/rule-governance.mdc | 32 - .cursor/rules/testing-conventions.mdc | 66 - .gitignore | 5 +- README-compose.md | 118 +- README-evaluation.md | 138 + README.md | 309 +- backend/README.md | 138 +- .../alembic/versions/0001_initial_schema.py | 5 +- .../application/services/analysis_service.py | 24 +- .../app/plugins/compose_runnability_plugin.py | 2 +- .../app/plugins/security_scanner_plugin.py | 113 +- backend/tests/test_analysis_service.py | 22 +- backend/tests/test_compose_runnability.py | 55 + backend/tests/test_plugins.py | 126 + context/add-delete-refactor-playbook.md | 48 - context/chat-knowledge-index.md | 33 - context/chat-transcript-retention.md | 51 - context/continuous-optimization-loop.md | 42 - context/master-task-prompt.md | 80 - context/refactor-backlog.md | 43 - context/transcript-grouping-commands.sh | 52 - context/transcript-groups-archive.txt | 14 - .../transcript-groups-delete-candidates.txt | 8 - context/transcript-groups-keep.txt | 14 - context/ui-and-jobs.md | 52 - .../README.md | 66 + .../compose/apache__superset__compose.yml | 292 ++ .../compose/appwrite__appwrite__compose.yml | 1302 ++++++++ .../compose/awesome-compose__angular.yml | 10 + .../compose/awesome-compose__apache-php.yml | 9 + .../compose/awesome-compose__aspnet-mssql.yml | 22 + .../compose/awesome-compose__django.yml | 7 + ...compose__elasticsearch-logstash-kibana.yml | 48 + .../compose/awesome-compose__fastapi.yml | 11 + .../compose/awesome-compose__flask-redis.yml | 18 + .../compose/awesome-compose__flask.yml | 10 + .../awesome-compose__gitea-postgres.yml | 31 + .../compose/awesome-compose__minecraft.yml | 13 + .../awesome-compose__nextcloud-postgres.yml | 27 + ...esome-compose__nextcloud-redis-mariadb.yml | 45 + .../awesome-compose__nginx-aspnet-mysql.yml | 46 + .../awesome-compose__nginx-flask-mongo.yml | 29 + .../awesome-compose__nginx-flask-mysql.yml | 62 + .../awesome-compose__nginx-golang-mysql.yml | 51 + ...awesome-compose__nginx-golang-postgres.yml | 48 + .../compose/awesome-compose__nginx-golang.yml | 17 + .../awesome-compose__nginx-nodejs-redis.yml | 27 + .../awesome-compose__nginx-wsgi-flask.yml | 29 + ...wesome-compose__pihole-cloudflared-DoH.yml | 55 + .../compose/awesome-compose__plex.yml | 10 + .../compose/awesome-compose__portainer.yml | 14 + .../awesome-compose__postgresql-pgadmin.yml | 21 + .../awesome-compose__prometheus-grafana.yml | 25 + ...awesome-compose__react-express-mongodb.yml | 47 + .../awesome-compose__react-express-mysql.yml | 68 + .../awesome-compose__react-java-mysql.yml | 58 + .../compose/awesome-compose__react-nginx.yml | 7 + .../awesome-compose__react-rust-postgres.yml | 52 + .../awesome-compose__sparkjava-mysql.yml | 28 + .../compose/awesome-compose__sparkjava.yml | 5 + .../awesome-compose__spring-postgres.yml | 30 + .../awesome-compose__traefik-golang.yml | 18 + .../compose/awesome-compose__vuejs.yml | 10 + .../compose/awesome-compose__wireguard.yml | 27 + .../awesome-compose__wordpress-mysql.yml | 33 + .../compose/directus__directus__compose.yml | 175 ++ .../getsentry__self-hosted__compose.yml | 911 ++++++ .../healthchecks__healthchecks__compose.yml | 29 + .../hoppscotch__hoppscotch__compose.yml | 257 ++ .../compose/immich-app__immich__compose.yml | 76 + .../mailcow__mailcow-dockerized__compose.yml | 687 +++++ .../compose/mastodon__mastodon__compose.yml | 141 + .../compose/monicahq__monica__compose.yml | 116 + ...tbox-community__netbox-docker__compose.yml | 87 + .../compose/outline__outline__compose.yml | 15 + ...s-ngx__paperless-ngx__compose.postgres.yml | 63 + .../compose/requarks__wiki__compose.yml | 59 + .../compose/supabase__supabase__compose.yml | 577 ++++ .../compose/wekan__wekan__compose.yml | 1032 +++++++ .../dockerfiles/apache__airflow.Dockerfile | 2259 ++++++++++++++ .../dockerfiles/apache__superset.Dockerfile | 294 ++ .../appsmithorg__appsmith.Dockerfile | 67 + .../dockerfiles/appwrite__appwrite.Dockerfile | 118 + ...awesome-compose__apache-php_app.Dockerfile | 22 + .../awesome-compose__django_app.Dockerfile | 24 + .../awesome-compose__fastapi.Dockerfile | 26 + .../awesome-compose__flask-redis.Dockerfile | 27 + .../awesome-compose__flask_app.Dockerfile | 27 + ...ose__nginx-aspnet-mysql_backend.Dockerfile | 42 + ...pose__nginx-flask-mysql_backend.Dockerfile | 35 + ...ose__nginx-golang-mysql_backend.Dockerfile | 41 + ...__nginx-golang-postgres_backend.Dockerfile | 41 + ...e-compose__nginx-golang_backend.Dockerfile | 41 + ...compose__nginx-nodejs-redis_web.Dockerfile | 11 + ...__react-express-mongodb_backend.Dockerfile | 33 + ...se__react-express-mysql_backend.Dockerfile | 49 + ...mpose__react-java-mysql_backend.Dockerfile | 40 + .../awesome-compose__react-nginx.Dockerfile | 61 + ...se__react-rust-postgres_backend.Dockerfile | 49 + ...ompose__sparkjava-mysql_backend.Dockerfile | 31 + ...ompose__spring-postgres_backend.Dockerfile | 39 + ...compose__traefik-golang_backend.Dockerfile | 29 + .../benphelps__homepage.Dockerfile | 63 + .../dockerfiles/directus__directus.Dockerfile | 74 + .../dockerfiles/drone__drone.Dockerfile | 96 + .../dockerfiles/etcd-io__etcd.Dockerfile | 17 + .../excalidraw__excalidraw.Dockerfile | 20 + .../gethomepage__homepage.Dockerfile | 65 + .../dockerfiles/getredash__redash.Dockerfile | 122 + .../dockerfiles/go-gitea__gitea.Dockerfile | 86 + .../dockerfiles/gogs__gogs.Dockerfile | 56 + .../dockerfiles/gohugoio__hugo.Dockerfile | 101 + .../dockerfiles/grafana__grafana.Dockerfile | 396 +++ .../home-assistant__core.Dockerfile | 59 + .../dockerfiles/kanboard__kanboard.Dockerfile | 35 + .../linkwarden__linkwarden.Dockerfile | 70 + .../linuxserver__docker-plex.Dockerfile | 64 + .../dockerfiles/mastodon__mastodon.Dockerfile | 416 +++ .../meilisearch__meilisearch.Dockerfile | 46 + .../dockerfiles/metabase__metabase.Dockerfile | 69 + .../dockerfiles/minio__minio.Dockerfile | 18 + .../dockerfiles/outline__outline.Dockerfile | 47 + .../paperless-ngx__paperless-ngx.Dockerfile | 255 ++ .../prometheus__prometheus.Dockerfile | 32 + .../dockerfiles/qdrant__qdrant.Dockerfile | 246 ++ .../dockerfiles/traefik__traefik.Dockerfile | 12 + .../dockerfiles/wallabag__docker.Dockerfile | 91 + .../dockerfiles/wekan__wekan.Dockerfile | 233 ++ .../manifest.csv | 103 + examples/README.md | 194 +- .../compose-exits-after-start/README.md | 48 +- frontend/README.md | 71 +- frontend/src/components/IssueCard.tsx | 55 +- frontend/src/pages/ResultsDashboard.tsx | 57 +- phase_b_aggregate.py | 143 + phase_b_results/_summary.csv | 103 + .../apache__airflow__dockerfile.json | 287 ++ .../apache__superset__compose__compose.json | 564 ++++ .../apache__superset__dockerfile.json | 176 ++ .../appsmithorg__appsmith__dockerfile.json | 55 + .../appwrite__appwrite__compose__compose.json | 2457 +++++++++++++++ .../appwrite__appwrite__dockerfile.json | 80 + .../awesome-compose__angular__compose.json | 83 + .../awesome-compose__apache-php__compose.json | 74 + ...e-compose__apache-php_app__dockerfile.json | 39 + ...wesome-compose__aspnet-mssql__compose.json | 105 + .../awesome-compose__django__compose.json | 65 + ...esome-compose__django_app__dockerfile.json | 39 + ...lasticsearch-logstash-kibana__compose.json | 223 ++ .../awesome-compose__fastapi__compose.json | 65 + .../awesome-compose__fastapi__dockerfile.json | 47 + ...awesome-compose__flask-redis__compose.json | 114 + ...some-compose__flask-redis__dockerfile.json | 47 + .../awesome-compose__flask__compose.json | 73 + ...wesome-compose__flask_app__dockerfile.json | 47 + ...some-compose__gitea-postgres__compose.json | 136 + .../awesome-compose__minecraft__compose.json | 105 + ...-compose__nextcloud-postgres__compose.json | 126 + ...ose__nextcloud-redis-mariadb__compose.json | 189 ++ ...-compose__nginx-aspnet-mysql__compose.json | 210 ++ ...ginx-aspnet-mysql_backend__dockerfile.json | 39 + ...e-compose__nginx-flask-mongo__compose.json | 163 + ...e-compose__nginx-flask-mysql__compose.json | 274 ++ ...nginx-flask-mysql_backend__dockerfile.json | 72 + ...-compose__nginx-golang-mysql__compose.json | 218 ++ ...ginx-golang-mysql_backend__dockerfile.json | 56 + ...mpose__nginx-golang-postgres__compose.json | 219 ++ ...x-golang-postgres_backend__dockerfile.json | 56 + ...wesome-compose__nginx-golang__compose.json | 106 + ...ose__nginx-golang_backend__dockerfile.json | 56 + ...-compose__nginx-nodejs-redis__compose.json | 171 ++ ...e__nginx-nodejs-redis_web__dockerfile.json | 30 + ...me-compose__nginx-wsgi-flask__compose.json | 139 + ...pose__pihole-cloudflared-DoH__compose.json | 293 ++ .../awesome-compose__plex__compose.json | 82 + .../awesome-compose__portainer__compose.json | 104 + ...-compose__postgresql-pgadmin__compose.json | 170 ++ ...-compose__prometheus-grafana__compose.json | 163 + ...mpose__react-express-mongodb__compose.json | 165 ++ ...t-express-mongodb_backend__dockerfile.json | 39 + ...compose__react-express-mysql__compose.json | 303 ++ ...act-express-mysql_backend__dockerfile.json | 39 + ...me-compose__react-java-mysql__compose.json | 228 ++ ..._react-java-mysql_backend__dockerfile.json | 39 + ...awesome-compose__react-nginx__compose.json | 73 + ...some-compose__react-nginx__dockerfile.json | 39 + ...compose__react-rust-postgres__compose.json | 188 ++ ...act-rust-postgres_backend__dockerfile.json | 47 + ...ome-compose__sparkjava-mysql__compose.json | 185 ++ ...__sparkjava-mysql_backend__dockerfile.json | 39 + .../awesome-compose__sparkjava__compose.json | 73 + ...ome-compose__spring-postgres__compose.json | 186 ++ ...__spring-postgres_backend__dockerfile.json | 39 + ...some-compose__traefik-golang__compose.json | 113 + ...e__traefik-golang_backend__dockerfile.json | 39 + .../awesome-compose__vuejs__compose.json | 83 + .../awesome-compose__wireguard__compose.json | 117 + ...ome-compose__wordpress-mysql__compose.json | 168 ++ .../benphelps__homepage__dockerfile.json | 47 + .../directus__directus__compose__compose.json | 625 ++++ .../directus__directus__dockerfile.json | 80 + phase_b_results/drone__drone__dockerfile.json | 112 + .../etcd-io__etcd__dockerfile.json | 55 + .../excalidraw__excalidraw__dockerfile.json | 38 + .../gethomepage__homepage__dockerfile.json | 63 + .../getredash__redash__dockerfile.json | 80 + ...sentry__self-hosted__compose__compose.json | 2625 +++++++++++++++++ .../go-gitea__gitea__dockerfile.json | 63 + phase_b_results/gogs__gogs__dockerfile.json | 56 + .../gohugoio__hugo__dockerfile.json | 64 + .../grafana__grafana__dockerfile.json | 224 ++ ...hecks__healthchecks__compose__compose.json | 106 + .../home-assistant__core__dockerfile.json | 47 + ...pscotch__hoppscotch__compose__compose.json | 957 ++++++ .../immich-app__immich__compose__compose.json | 177 ++ .../kanboard__kanboard__dockerfile.json | 56 + .../linkwarden__linkwarden__dockerfile.json | 39 + .../linuxserver__docker-plex__dockerfile.json | 96 + ..._mailcow-dockerized__compose__compose.json | 1109 +++++++ .../mastodon__mastodon__compose__compose.json | 233 ++ .../mastodon__mastodon__dockerfile.json | 38 + .../meilisearch__meilisearch__dockerfile.json | 63 + .../metabase__metabase__dockerfile.json | 144 + phase_b_results/minio__minio__dockerfile.json | 47 + .../monicahq__monica__compose__compose.json | 462 +++ ...nity__netbox-docker__compose__compose.json | 195 ++ .../outline__outline__compose__compose.json | 121 + .../outline__outline__dockerfile.json | 80 + ...erless-ngx__compose.postgres__compose.json | 162 + ...erless-ngx__paperless-ngx__dockerfile.json | 104 + .../prometheus__prometheus__dockerfile.json | 39 + .../qdrant__qdrant__dockerfile.json | 39 + .../requarks__wiki__compose__compose.json | 212 ++ .../supabase__supabase__compose__compose.json | 807 +++++ .../traefik__traefik__dockerfile.json | 39 + .../wallabag__docker__dockerfile.json | 63 + .../wekan__wekan__compose__compose.json | 194 ++ phase_b_results/wekan__wekan__dockerfile.json | 128 + phase_b_runner.py | 89 + phase_b_stats.md | 54 + phase_b_stats_final.md | 86 + scripts/README.md | 75 + scripts/start.sh | 4 +- 259 files changed, 34824 insertions(+), 1649 deletions(-) delete mode 100644 .cursor/hooks.json delete mode 100644 .cursor/hooks/run-strict-gates.sh delete mode 100644 .cursor/rules/backend-api-routers.mdc delete mode 100644 .cursor/rules/backend-infrastructure.mdc delete mode 100644 .cursor/rules/backend-plugins.mdc delete mode 100644 .cursor/rules/backend-python-conventions.mdc delete mode 100644 .cursor/rules/creative-frontend-animation.mdc delete mode 100644 .cursor/rules/docker-and-devops.mdc delete mode 100644 .cursor/rules/frontend-react-patterns.mdc delete mode 100644 .cursor/rules/frontend-styling.mdc delete mode 100644 .cursor/rules/frontend-typescript.mdc delete mode 100644 .cursor/rules/project-architecture.mdc delete mode 100644 .cursor/rules/project-runtime-safety.mdc delete mode 100644 .cursor/rules/project-workflow.mdc delete mode 100644 .cursor/rules/research-privacy.mdc delete mode 100644 .cursor/rules/results-and-monitoring.mdc delete mode 100644 .cursor/rules/rule-governance.mdc delete mode 100644 .cursor/rules/testing-conventions.mdc create mode 100644 README-evaluation.md delete mode 100644 context/add-delete-refactor-playbook.md delete mode 100644 context/chat-knowledge-index.md delete mode 100644 context/chat-transcript-retention.md delete mode 100644 context/continuous-optimization-loop.md delete mode 100644 context/master-task-prompt.md delete mode 100644 context/refactor-backlog.md delete mode 100644 context/transcript-grouping-commands.sh delete mode 100644 context/transcript-groups-archive.txt delete mode 100644 context/transcript-groups-delete-candidates.txt delete mode 100644 context/transcript-groups-keep.txt delete mode 100644 context/ui-and-jobs.md create mode 100644 dataset_public_docker_artifacts_github/README.md create mode 100644 dataset_public_docker_artifacts_github/compose/apache__superset__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/appwrite__appwrite__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__angular.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__apache-php.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__aspnet-mssql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__django.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__elasticsearch-logstash-kibana.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__fastapi.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__flask-redis.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__flask.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__gitea-postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__minecraft.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nextcloud-postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nextcloud-redis-mariadb.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-aspnet-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-flask-mongo.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-flask-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-golang-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-golang-postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-golang.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-nodejs-redis.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__nginx-wsgi-flask.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__pihole-cloudflared-DoH.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__plex.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__portainer.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__postgresql-pgadmin.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__prometheus-grafana.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__react-express-mongodb.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__react-express-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__react-java-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__react-nginx.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__react-rust-postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__sparkjava-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__sparkjava.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__spring-postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__traefik-golang.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__vuejs.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__wireguard.yml create mode 100644 dataset_public_docker_artifacts_github/compose/awesome-compose__wordpress-mysql.yml create mode 100644 dataset_public_docker_artifacts_github/compose/directus__directus__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/getsentry__self-hosted__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/healthchecks__healthchecks__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/hoppscotch__hoppscotch__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/immich-app__immich__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/mailcow__mailcow-dockerized__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/mastodon__mastodon__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/monicahq__monica__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/netbox-community__netbox-docker__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/outline__outline__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/paperless-ngx__paperless-ngx__compose.postgres.yml create mode 100644 dataset_public_docker_artifacts_github/compose/requarks__wiki__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/supabase__supabase__compose.yml create mode 100644 dataset_public_docker_artifacts_github/compose/wekan__wekan__compose.yml create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/apache__airflow.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/apache__superset.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/appsmithorg__appsmith.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/appwrite__appwrite.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__apache-php_app.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__django_app.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__fastapi.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__flask-redis.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__flask_app.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-aspnet-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-flask-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-golang-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-golang-postgres_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-golang_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__nginx-nodejs-redis_web.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__react-express-mongodb_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__react-express-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__react-java-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__react-nginx.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__react-rust-postgres_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__sparkjava-mysql_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__spring-postgres_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/awesome-compose__traefik-golang_backend.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/benphelps__homepage.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/directus__directus.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/drone__drone.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/etcd-io__etcd.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/excalidraw__excalidraw.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/gethomepage__homepage.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/getredash__redash.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/go-gitea__gitea.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/gogs__gogs.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/gohugoio__hugo.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/grafana__grafana.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/home-assistant__core.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/kanboard__kanboard.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/linkwarden__linkwarden.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/linuxserver__docker-plex.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/mastodon__mastodon.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/meilisearch__meilisearch.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/metabase__metabase.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/minio__minio.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/outline__outline.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/paperless-ngx__paperless-ngx.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/prometheus__prometheus.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/qdrant__qdrant.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/traefik__traefik.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/wallabag__docker.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/dockerfiles/wekan__wekan.Dockerfile create mode 100644 dataset_public_docker_artifacts_github/manifest.csv create mode 100644 phase_b_aggregate.py create mode 100644 phase_b_results/_summary.csv create mode 100644 phase_b_results/apache__airflow__dockerfile.json create mode 100644 phase_b_results/apache__superset__compose__compose.json create mode 100644 phase_b_results/apache__superset__dockerfile.json create mode 100644 phase_b_results/appsmithorg__appsmith__dockerfile.json create mode 100644 phase_b_results/appwrite__appwrite__compose__compose.json create mode 100644 phase_b_results/appwrite__appwrite__dockerfile.json create mode 100644 phase_b_results/awesome-compose__angular__compose.json create mode 100644 phase_b_results/awesome-compose__apache-php__compose.json create mode 100644 phase_b_results/awesome-compose__apache-php_app__dockerfile.json create mode 100644 phase_b_results/awesome-compose__aspnet-mssql__compose.json create mode 100644 phase_b_results/awesome-compose__django__compose.json create mode 100644 phase_b_results/awesome-compose__django_app__dockerfile.json create mode 100644 phase_b_results/awesome-compose__elasticsearch-logstash-kibana__compose.json create mode 100644 phase_b_results/awesome-compose__fastapi__compose.json create mode 100644 phase_b_results/awesome-compose__fastapi__dockerfile.json create mode 100644 phase_b_results/awesome-compose__flask-redis__compose.json create mode 100644 phase_b_results/awesome-compose__flask-redis__dockerfile.json create mode 100644 phase_b_results/awesome-compose__flask__compose.json create mode 100644 phase_b_results/awesome-compose__flask_app__dockerfile.json create mode 100644 phase_b_results/awesome-compose__gitea-postgres__compose.json create mode 100644 phase_b_results/awesome-compose__minecraft__compose.json create mode 100644 phase_b_results/awesome-compose__nextcloud-postgres__compose.json create mode 100644 phase_b_results/awesome-compose__nextcloud-redis-mariadb__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-aspnet-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-aspnet-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-flask-mongo__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-flask-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-flask-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-golang-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-golang-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-golang-postgres__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-golang-postgres_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-golang__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-golang_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-nodejs-redis__compose.json create mode 100644 phase_b_results/awesome-compose__nginx-nodejs-redis_web__dockerfile.json create mode 100644 phase_b_results/awesome-compose__nginx-wsgi-flask__compose.json create mode 100644 phase_b_results/awesome-compose__pihole-cloudflared-DoH__compose.json create mode 100644 phase_b_results/awesome-compose__plex__compose.json create mode 100644 phase_b_results/awesome-compose__portainer__compose.json create mode 100644 phase_b_results/awesome-compose__postgresql-pgadmin__compose.json create mode 100644 phase_b_results/awesome-compose__prometheus-grafana__compose.json create mode 100644 phase_b_results/awesome-compose__react-express-mongodb__compose.json create mode 100644 phase_b_results/awesome-compose__react-express-mongodb_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__react-express-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__react-express-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__react-java-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__react-java-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__react-nginx__compose.json create mode 100644 phase_b_results/awesome-compose__react-nginx__dockerfile.json create mode 100644 phase_b_results/awesome-compose__react-rust-postgres__compose.json create mode 100644 phase_b_results/awesome-compose__react-rust-postgres_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__sparkjava-mysql__compose.json create mode 100644 phase_b_results/awesome-compose__sparkjava-mysql_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__sparkjava__compose.json create mode 100644 phase_b_results/awesome-compose__spring-postgres__compose.json create mode 100644 phase_b_results/awesome-compose__spring-postgres_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__traefik-golang__compose.json create mode 100644 phase_b_results/awesome-compose__traefik-golang_backend__dockerfile.json create mode 100644 phase_b_results/awesome-compose__vuejs__compose.json create mode 100644 phase_b_results/awesome-compose__wireguard__compose.json create mode 100644 phase_b_results/awesome-compose__wordpress-mysql__compose.json create mode 100644 phase_b_results/benphelps__homepage__dockerfile.json create mode 100644 phase_b_results/directus__directus__compose__compose.json create mode 100644 phase_b_results/directus__directus__dockerfile.json create mode 100644 phase_b_results/drone__drone__dockerfile.json create mode 100644 phase_b_results/etcd-io__etcd__dockerfile.json create mode 100644 phase_b_results/excalidraw__excalidraw__dockerfile.json create mode 100644 phase_b_results/gethomepage__homepage__dockerfile.json create mode 100644 phase_b_results/getredash__redash__dockerfile.json create mode 100644 phase_b_results/getsentry__self-hosted__compose__compose.json create mode 100644 phase_b_results/go-gitea__gitea__dockerfile.json create mode 100644 phase_b_results/gogs__gogs__dockerfile.json create mode 100644 phase_b_results/gohugoio__hugo__dockerfile.json create mode 100644 phase_b_results/grafana__grafana__dockerfile.json create mode 100644 phase_b_results/healthchecks__healthchecks__compose__compose.json create mode 100644 phase_b_results/home-assistant__core__dockerfile.json create mode 100644 phase_b_results/hoppscotch__hoppscotch__compose__compose.json create mode 100644 phase_b_results/immich-app__immich__compose__compose.json create mode 100644 phase_b_results/kanboard__kanboard__dockerfile.json create mode 100644 phase_b_results/linkwarden__linkwarden__dockerfile.json create mode 100644 phase_b_results/linuxserver__docker-plex__dockerfile.json create mode 100644 phase_b_results/mailcow__mailcow-dockerized__compose__compose.json create mode 100644 phase_b_results/mastodon__mastodon__compose__compose.json create mode 100644 phase_b_results/mastodon__mastodon__dockerfile.json create mode 100644 phase_b_results/meilisearch__meilisearch__dockerfile.json create mode 100644 phase_b_results/metabase__metabase__dockerfile.json create mode 100644 phase_b_results/minio__minio__dockerfile.json create mode 100644 phase_b_results/monicahq__monica__compose__compose.json create mode 100644 phase_b_results/netbox-community__netbox-docker__compose__compose.json create mode 100644 phase_b_results/outline__outline__compose__compose.json create mode 100644 phase_b_results/outline__outline__dockerfile.json create mode 100644 phase_b_results/paperless-ngx__paperless-ngx__compose.postgres__compose.json create mode 100644 phase_b_results/paperless-ngx__paperless-ngx__dockerfile.json create mode 100644 phase_b_results/prometheus__prometheus__dockerfile.json create mode 100644 phase_b_results/qdrant__qdrant__dockerfile.json create mode 100644 phase_b_results/requarks__wiki__compose__compose.json create mode 100644 phase_b_results/supabase__supabase__compose__compose.json create mode 100644 phase_b_results/traefik__traefik__dockerfile.json create mode 100644 phase_b_results/wallabag__docker__dockerfile.json create mode 100644 phase_b_results/wekan__wekan__compose__compose.json create mode 100644 phase_b_results/wekan__wekan__dockerfile.json create mode 100644 phase_b_runner.py create mode 100644 phase_b_stats.md create mode 100644 phase_b_stats_final.md create mode 100644 scripts/README.md diff --git a/.cursor/hooks.json b/.cursor/hooks.json deleted file mode 100644 index 2f21a45..0000000 --- a/.cursor/hooks.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": 1, - "hooks": { - "stop": [ - { - "command": "bash .cursor/hooks/run-strict-gates.sh", - "timeout": 3600, - "failClosed": true - } - ] - } -} diff --git a/.cursor/hooks/run-strict-gates.sh b/.cursor/hooks/run-strict-gates.sh deleted file mode 100644 index 424639b..0000000 --- a/.cursor/hooks/run-strict-gates.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# Read hook payload (unused for now, but consumed to avoid broken pipes) -HOOK_INPUT="$(cat || true)" -export HOOK_INPUT - -REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -cd "$REPO_ROOT" -LOG_FILE="context/quality-gate-feedback.log" -mkdir -p "$(dirname "$LOG_FILE")" - -CHANGED_FILES="$(git status --porcelain | awk '{print $2}')" - -if [[ -z "$CHANGED_FILES" ]]; then - echo "[strict-gates] No changed files detected; skipping checks." - printf "%s | skip | no-changes\n" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> "$LOG_FILE" - exit 0 -fi - -RUN_BACKEND=0 -RUN_FRONTEND=0 - -while IFS= read -r file; do - [[ -z "$file" ]] && continue - [[ "$file" == backend/* ]] && RUN_BACKEND=1 - [[ "$file" == frontend/* ]] && RUN_FRONTEND=1 -done <<< "$CHANGED_FILES" - -EXIT_CODE=0 - -if [[ $RUN_BACKEND -eq 1 ]]; then - echo "[strict-gates] Running backend tests: pytest -q" - if ! (cd backend && pytest -q); then - echo "[strict-gates] Backend quality gate failed." - EXIT_CODE=1 - fi -fi - -if [[ $RUN_FRONTEND -eq 1 ]]; then - echo "[strict-gates] Running frontend lint: npm run lint" - if ! (cd frontend && npm run lint); then - echo "[strict-gates] Frontend lint gate failed." - EXIT_CODE=1 - fi - - echo "[strict-gates] Running frontend build: npm run build" - if ! (cd frontend && npm run build); then - echo "[strict-gates] Frontend build gate failed." - EXIT_CODE=1 - fi -fi - -if [[ $RUN_BACKEND -eq 0 && $RUN_FRONTEND -eq 0 ]]; then - echo "[strict-gates] No backend/frontend source changes detected; skipping checks." - printf "%s | skip | non-app-changes\n" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> "$LOG_FILE" -fi - -if [[ $EXIT_CODE -eq 0 ]]; then - printf "%s | pass | backend=%s frontend=%s\n" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$RUN_BACKEND" "$RUN_FRONTEND" >> "$LOG_FILE" -else - printf "%s | fail | backend=%s frontend=%s\n" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$RUN_BACKEND" "$RUN_FRONTEND" >> "$LOG_FILE" -fi - -exit "$EXIT_CODE" diff --git a/.cursor/rules/backend-api-routers.mdc b/.cursor/rules/backend-api-routers.mdc deleted file mode 100644 index 81d7856..0000000 --- a/.cursor/rules/backend-api-routers.mdc +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: FastAPI router conventions — dependency injection, auth, and response patterns -globs: backend/app/api/**/*.py -alwaysApply: false ---- - -# API Router Conventions - -## Handler Signature - -All route handlers must be `async def` with explicit `response_model`: - -```python -@router.post("/analyze", response_model=AnalysisEnqueueResponse) -async def analyze( - file: UploadFile = File(...), - user: UserModel = Depends(get_current_user), - session: AsyncSession = Depends(get_db_session), -): -``` - -## Dependency Injection - -- **Auth**: `Depends(get_current_user)` — Bearer JWT only. -- **Database**: `Depends(get_db_session)` — yields an `AsyncSession`. -- **Services**: Instantiated in the handler body, not injected: - ```python - svc = AnalysisService(session) - result = await svc.enqueue_job(...) - ``` - -## Rules - -- Routers **may** import lightweight SQLAlchemy model types or enums (e.g. `UserModel` for `Depends` typing, `JobType` / `JobStatus` for comparisons). -- Routers **must not** run raw SQLAlchemy queries, `session.execute`, or ad-hoc ORM loads—**DB access goes through repositories/services**. -- Return Pydantic schema instances directly (FastAPI serializes them). -- File uploads use `File(...)` / `UploadFile` with manual size checks before handing off to services. -- For project uploads, keep behavior consistent with current product flow: safe scan + queue analysis of detected files, and preserve explicit compose deploy gating in deploy endpoints. -- Each router file: `router = APIRouter(prefix=..., tags=[...])` at module level. -- All routers aggregated in `app/api/router.py` via `api_router.include_router(...)`. diff --git a/.cursor/rules/backend-infrastructure.mdc b/.cursor/rules/backend-infrastructure.mdc deleted file mode 100644 index 1efe24a..0000000 --- a/.cursor/rules/backend-infrastructure.mdc +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Infrastructure layer — repositories, DB access, Docker gateway, Redis event bus -globs: backend/app/infrastructure/**/*.py -alwaysApply: false ---- - -# Infrastructure Layer - -## Repositories - -- Constructor takes `AsyncSession` — instantiated inside services, not injected by FastAPI. -- All queries enforce **user-scoped access**: `WHERE user_id = :user_id` on every read/write. -- Pattern: `UserRepository`, `JobRepository` in `db/repositories.py`. - -## Database Access - -- Fully async: `sqlalchemy[asyncio]` + `asyncpg`. -- Engine: `create_async_engine` with `pool_pre_ping=True`. -- Session: `async_sessionmaker` with `expire_on_commit=False`. -- `get_db_session()` is an async generator yielding from `SessionLocal()` — used as `Depends()`. -- UUID primary keys, JSONB columns for flexible data (`input_metadata`, `result`). - -## Docker Gateway (`docker/client.py`) - -- Wraps the synchronous Docker SDK behind **`asyncio.to_thread()`** for **all** SDK calls—never block the event loop inside async code. -- **`build_image`** — image builds from context + Dockerfile path. -- **`inspect_image`** — metadata after build/pull. -- **`inspect_container_metrics`** — CPU, memory, network, I/O, PIDs, and container info while running. -- **`inspect_container_final_state`** — post-exit / final inspection (exit code, OOM, restart counts, logs summary as implemented). - -## Redis Event Bus (`events/bus.py`) - -- `publish_event(DomainEvent)` publishes to multiple channels based on event context. -- `subscribe(channel)` returns an `AsyncIterator[dict]` with `try/finally` cleanup. -- Channel patterns: `user:{id}:events`, `job:{id}:events`, `container:{id}:metrics`, `user:{id}:container:{id}:metrics`. - -## Deploy State in Redis - -- Key: `deploy:{user_id}:{job_id}` — JSON payload with 6-hour TTL. -- Payload should include **`containers`**, aggregates **`running_count`**, **`exited_count`**, **`unhealthy_count`**, plus **`runtime_state`** when tracked (overall deploy/monitor rollup). -- Runtime state values can include: `none`, `running`, `partial`, `unhealthy`, `exited`, `failed`, `stopping`, `stopped_by_user`, `cleanup_completed`. -- Stop signal: `deploy-stop:{user_id}:{job_id}` — flag key. - -## Subprocess Tools (`tools/process.py`) - -- `run_command(command, timeout=45)` — wraps `asyncio.create_subprocess_exec`. -- Returns stdout on success or non-zero exit with stdout (for linters that exit non-zero on findings). -- Raises `HTTPException(504)` on timeout, `HTTPException(500)` on missing binary. diff --git a/.cursor/rules/backend-plugins.mdc b/.cursor/rules/backend-plugins.mdc deleted file mode 100644 index c1eee48..0000000 --- a/.cursor/rules/backend-plugins.mdc +++ /dev/null @@ -1,56 +0,0 @@ ---- -description: Plugin system — BasePlugin interface, registry, and implementation patterns -globs: backend/app/plugins/**/*.py -alwaysApply: false ---- - -# Plugin System - -## Creating a New Plugin - -1. Subclass `BasePlugin` from `app/plugins/base.py`: - -```python -from app.plugins.base import BasePlugin - -class MyPlugin(BasePlugin): - name = "my_plugin" - - async def run(self, context: dict[str, Any]) -> dict[str, Any]: - # Return a dict — keys with list values named "findings" are treated as issues - # All other keys go into the job's meta dict - return {"findings": [...]} -``` - -2. Register in `PLUGIN_MAP` in `app/plugins/registry.py`: - -```python -PLUGIN_MAP["my_plugin"] = MyPlugin -``` - -## Context Dict Keys - -The `context` dict passed to `run()` may contain: -- `dockerfile_content` — raw Dockerfile text -- `compose_content` — raw docker-compose YAML text -- `filename` — original uploaded filename -- `project_path` — path to extracted project archive - -## Two Plugin Flavors - -- **Subprocess plugins** (hadolint): Use `run_command()` from `infrastructure/tools/process.py`. Write content to a tempfile, invoke the binary, parse JSON stdout. 45-second timeout. -- **Pure Python plugins** (`compose_validator`, `compose_runnability`, `security_scanner`, `resource_estimation`): Analyze content in-process with no external dependencies. - -## Issue Normalization - -`AnalysisService._normalize_issue()` handles multiple output formats (hadolint JSON and generic dict outputs). Plugin findings just need to be a list of dicts — normalization happens in the service layer. - -## Current Registry - -`PLUGIN_MAP` currently includes: - -- `hadolint` -- `compose_validator` -- `compose_runnability` -- `security_scanner` -- `resource_estimation` diff --git a/.cursor/rules/backend-python-conventions.mdc b/.cursor/rules/backend-python-conventions.mdc deleted file mode 100644 index d10fc83..0000000 --- a/.cursor/rules/backend-python-conventions.mdc +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: Python coding conventions — type hints, Pydantic, config, error handling -globs: backend/**/*.py -alwaysApply: false ---- - -# Python Conventions - -## Type Hints (Python 3.12+) - -Use modern built-in generics and union syntax: - -```python -# Good -def get_user(user_id: uuid.UUID) -> UserModel | None: ... -def process(items: list[str], meta: dict[str, Any]) -> None: ... - -# Bad — do not use -from typing import Optional, Dict, List -def get_user(user_id: uuid.UUID) -> Optional[UserModel]: ... -``` - -## Pydantic - -- All request/response schemas live in `app/application/schemas.py`. -- Use Pydantic v2 `BaseModel` with `Field()` constraints. -- Use `Literal["error", "warning", "info"]` for enum-like fields — no Python enums in schemas. -- Serialize with `model_dump()`. - -## Configuration - -- `pydantic-settings` `BaseSettings` in `app/core/config.py`. -- `@lru_cache` on `get_settings()` for singleton access. -- Three environments: `dev`, `test`, `prod` (via `Literal`). -- All secrets/URLs from env vars or `backend/.env`. - -## Error Handling - -- Raise `HTTPException` directly — no custom exception hierarchy. -- Services catch exceptions, persist failure state to DB, publish failure events, then re-raise. -- `run_command()` raises `HTTPException(504)` on timeout, `HTTPException(500)` on binary not found. - -## IDs and Data - -- UUID primary keys on all entities, generated server-side. -- JSONB columns (`input_metadata`, `result`) for flexible/evolving data structures. - -## Async - -- All I/O-bound operations are `async`. Synchronous Docker SDK calls use `asyncio.to_thread()`. -- Worker tasks manage their own `SessionLocal()` sessions (separate from request lifecycle). diff --git a/.cursor/rules/creative-frontend-animation.mdc b/.cursor/rules/creative-frontend-animation.mdc deleted file mode 100644 index 7c059f4..0000000 --- a/.cursor/rules/creative-frontend-animation.mdc +++ /dev/null @@ -1,41 +0,0 @@ ---- -description: Motion & animation — Motion (default), CSS/Tailwind, accessibility -globs: frontend/src/**/*.{tsx,ts,css} -alwaysApply: false ---- - -# Frontend Motion & Animation - -## Default stack - -**Motion** (`motion`, formerly Framer Motion) is the default library for UI motion—use it for layout transitions, gestures, and enter/exit unless a lighter CSS-only transition is enough. - -**Also use:** - -- **Tailwind**: `transition-[colors,opacity,…]`, `duration-200`, `ease-out`. -- **`motion-safe:`** / **`motion-reduce:`** (and `motion-reduce:animate-none`). -- **CSS** `@keyframes` when Motion is unnecessary. - -Do **not** add **GSAP**, **React Three Fiber**, **Rive**, or **Lottie/dotLottie** unless the user explicitly asks for that stack. - -## Heavy libraries (only when requested) - -| Need | Library | -|------|---------| -| Timelines, ScrollTrigger, SVG morph | GSAP | -| WebGL / 3D | React Three Fiber | -| Designer-export loops | Lottie / dotLottie | -| Stateful vector mascots | Rive | - -## Performance - -- Prefer **transform** and **opacity** over layout properties (`width`, `height`, `top`, `margin`). -- Avoid **`transition-all`**—list properties explicitly. -- Use **`will-change` sparingly** and only during active animation. -- Respect **`prefers-reduced-motion`**. -- Lazy-load heavy animation modules/routes. - -## Design - -- Motion supports hierarchy and feedback; it should not obstruct readability or contrast (see `frontend-styling.mdc`). -- Glassmorphism / heavy gradients only when they aid comprehension—not as default chrome. diff --git a/.cursor/rules/docker-and-devops.mdc b/.cursor/rules/docker-and-devops.mdc deleted file mode 100644 index ad08622..0000000 --- a/.cursor/rules/docker-and-devops.mdc +++ /dev/null @@ -1,48 +0,0 @@ ---- -description: Docker Compose stack, service topology, and DevOps conventions -alwaysApply: true ---- - -# Docker & DevOps - -## 6-Service Compose Stack - -Compose stack is split across `compose.yaml` (base) with overlays `compose.dev.yaml` and `compose.prod.yaml` at the repo root. - -| Service | Role | Port | -|---|---|---| -| frontend | Nginx-served React SPA + reverse proxy | 3000:80 | -| api | FastAPI HTTP server | 8000:8000 | -| worker | arq task worker (same image as api, different CMD) | — | -| dind | Docker-in-Docker daemon (privileged) | — | -| redis | Job queue (arq) + pub/sub event bus | 6379 | -| postgres | Primary relational DB | 5432 | - -## Dependency Chain (health-check gated) - -`frontend → api → redis, postgres` and `worker → dind, redis, postgres` - -## Key Patterns - -- **Single-image, dual-role backend**: Same Dockerfile produces `api` (uvicorn) and `worker` (arq CMD override). -- **Shared volume**: `uploads_data` mounted in both `api` and `worker` for uploaded file access. -- **DinD isolation**: Worker talks to DinD over TLS (`DOCKER_HOST=tcp://docker:2376`, certs via `DOCKER_CERT_PATH`, `DOCKER_TLS_VERIFY=1`). Never exposes host Docker socket. - -## Essential Commands - -```bash -cp .env.example .env # one-time setup -mkdir -p secrets && cp secrets/postgres_password.txt.example secrets/postgres_password.txt && cp secrets/jwt_secret.txt.example secrets/jwt_secret.txt -docker compose --env-file .env -f compose.yaml -f compose.dev.yaml up --build -docker compose exec api alembic upgrade head # run DB migrations -docker compose logs -f frontend api worker # tail logs -docker compose down -v # stop + wipe volumes -``` - -## Configuration - -Backend settings loaded by `pydantic-settings` from env vars or `backend/.env`. Key toggles: -Backend settings loaded by `pydantic-settings` from env vars/secrets. Key toggles: -- `APP_ENV=dev` enables permissive CORS (`allow_origins=["*"]`) -- `APP_ENV=prod` restricts CORS -- `JWT_SECRET_KEY` is loaded from secrets in Compose deployments and must be strong in production diff --git a/.cursor/rules/frontend-react-patterns.mdc b/.cursor/rules/frontend-react-patterns.mdc deleted file mode 100644 index 7c374dc..0000000 --- a/.cursor/rules/frontend-react-patterns.mdc +++ /dev/null @@ -1,74 +0,0 @@ ---- -description: React patterns — exports, auth, api.ts clients, state, WS, forms, a11y -globs: frontend/src/**/*.tsx -alwaysApply: false ---- - -# React Patterns - -## Component exports - -- **Named exports only**: `export function ComponentName() { … }` -- **Default export** only for `App.tsx`. -- Prefer function components; handlers as inline arrows or named functions inside the component. - -## Auth - -- `useAuth()` from `src/auth/AuthProvider.tsx`. -- Routes wrapped with `` in `routes.tsx`. -- While `isBooting`, show `DockerLoader` (same as token validation). - -## API layer (`src/utils/api.ts`) - -All HTTP goes through exported clients—**never** raw `fetch()` in pages/components. - -```typescript -import { jobs, dockerfile, compose, project, research } from "../utils/api"; - -const list = await jobs.list(); -const job = await jobs.get(jobId); -await dockerfile.analyze(file); -await compose.deploy({ job_id: id, run_stack: true }); -await research.summary(90); -await research.jobs({ limit: 20, offset: 0 }); -``` - -Also exported: `auth`, `project`, `ws`, `checkHealth`, shared types (`Job`, `ApiError`, etc.). - -## Project upload UX assumptions - -- Current project upload flow queues analysis for all detected Dockerfiles/Compose files. -- Current project upload flow communicates automatic image builds in UX copy. -- Compose runtime start/deploy remains an explicit follow-up action from results/deploy controls. - -## WebSocket - -- Hold socket in `useRef`. -- Open in `useEffect`, close in cleanup. -- Pass JWT as `?token=` when connecting (see existing monitoring/progress pages). - -## State - -- **No Redux/Zustand** — auth via Context; local state via `useState`. -- **sessionStorage**: uploads, job IDs, execution flow. -- **localStorage**: auth (`dpa_*`), notifications (`dqa:` prefix). -- **URL**: `jobId` query; `containerId` route params where applicable. - -## Pages & layout - -- Authenticated flows wrap content in `` (standalone: Login/Register). - -## Forms & native controls - -- **Labels**: visible, `htmlFor` matched to control `id`; spacing **`gap-3`** between label group and input/select. -- **Selects**: prefer **`NativeSelectField`** (`components/ui/native-select.tsx`). -- **Keyboard**: modals/dialogs—Escape closes, focus returns to trigger; trap Tab within dialog content when practical. - -## Overlays (modals) - -- `role="dialog"`, `aria-modal="true"`, `aria-labelledby` pointing at title `id`. -- Provide visible **Close** + backdrop click policy consistent with existing pages. - -## Charts - -- Use **Recharts** where needed; follow styling rule: **`currentColor`** ticks/grid inside a tinted wrapper—do not rely on SVG `var(--muted-foreground)` alone for axis labels. diff --git a/.cursor/rules/frontend-styling.mdc b/.cursor/rules/frontend-styling.mdc deleted file mode 100644 index 829374d..0000000 --- a/.cursor/rules/frontend-styling.mdc +++ /dev/null @@ -1,66 +0,0 @@ ---- -description: Styling — Tailwind v4, semantic design tokens, contrast, shadcn/ui, forms & charts -globs: frontend/src/**/*.{css,tsx} -alwaysApply: false ---- - -# Frontend Styling Standards - -## Tailwind CSS v4 - -- Utilities + `@import "./tailwind.css"` (see `src/styles/index.css`). -- Theme colors map to CSS variables (`--background`, `--foreground`, `--card`, `--border`, `--primary`, `--destructive`, etc.) via `@theme inline`. -- Prefer **semantic utilities** (`bg-card`, `text-foreground`, `border-border`) over raw `slate-*` on new UI. Legacy pages may still mix slate on layout chrome; migrate toward tokens when touching a file. - -## Theme Mode - -- `App.tsx` adds `dark` to `document.documentElement`. Tokens in `.dark { … }` define the live palette. -- `html.dark { color-scheme: dark; }` (in `index.css`) keeps native controls (select menus) readable—do not strip this. -- UI code should remain **theme-token-driven** so removing forced dark or adding a toggle does not require rewriting components. - -## Color & Contrast (required) - -- **Never** hardcode `text-black`, `border-black`, or `hover:bg-black/*` on shared primitives—it breaks dark backgrounds (see `Button` in `components/ui/button.tsx`: uses `text-primary-foreground`, `text-foreground`, `border-input`, etc.). -- **`text-muted-foreground`** on near-black panels can fail WCAG at small sizes. For critical secondary copy (table headers, chart axes, captions, pagination), use explicit readable pairs, e.g. `text-slate-600 dark:text-slate-400` or `text-slate-700 dark:text-slate-300`, or lighten `--muted-foreground` in `index.css` with intent—not random one-offs. -- **Charts (Recharts):** avoid `fill: "var(--muted-foreground)"` on SVG ticks—many browsers resolve this poorly. Wrap the chart in a container with a readable `text-*` color and use `tick={{ fill: "currentColor" }}` plus `CartesianGrid` with `stroke="currentColor"` and controlled opacity. - -## Semantic Roles (reference) - -| Role | Tailwind / token | -|------|-------------------| -| Page background | `bg-background` | -| Surfaces / cards | `bg-card`, `text-card-foreground` | -| Borders | `border-border` | -| Primary CTA | `bg-primary`, `text-primary-foreground` | -| Muted secondary | `bg-muted`, `text-muted-foreground` (with contrast checks) | -| Destructive | `bg-destructive`, `text-destructive-foreground` | -| Focus ring | `focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background` | - -Accent hues (blue for primary nav, emerald/sky/destructive for status) stay **semantic**, not rainbow decoration. - -## Layout & rhythm - -- **8px grid**: spacing via `gap-4`, `p-4`, `py-6`, etc. -- **Touch targets**: interactive controls ≥ **44px** height where practical (`min-h-[44px]`, `h-11`). -- **Forms**: label stack uses clear separation (`gap-3` between label block and control); labels ≥ `text-sm font-medium text-foreground`; hints use readable muted slate utilities—not cramped `text-xs` glued to controls without spacing. - -## Class merging - -Use `cn()` from `src/components/ui/utils.ts` (relative imports from pages, e.g. `../components/ui/utils`): - -```tsx -import { cn } from "../components/ui/utils"; - -
-``` - -## UI primitives (`components/ui/`) - -- **Button**, **Badge**, **Card**, **Tabs**: CVA variants; extend with tokens, not raw black/white. -- **Native selects**: use **`NativeSelectField`** from `components/ui/native-select.tsx` (chevron, spacing, popover-aligned trigger). Avoid bare `