Files
rose-ash/docker-compose.dev.yml
giles ae0e87fbf8 VM aser-slot → sx-page-full: single-call page render, 0.55s warm
Compiler fixes:
- Upvalue re-lookup returns own position (uv-index), not parent slot
- Spec: cek-call uses (make-env) not (dict) — OCaml Dict≠Env
- Bootstrap post-processes transpiler Dict→Env for cek_call

VM runtime fixes:
- compile_adapter evaluates constant defines (SPECIAL_FORM_NAMES etc.)
  via execute_module instead of wrapping as NativeFn closures
- Native primitives: map-indexed, some, every?
- Nil-safe HO forms: map/filter/for-each/some/every? accept nil as empty
- expand-components? set in kernel env (not just VM globals)
- unwrap_env diagnostic: reports actual type received

sx-page-full command:
- Single OCaml call: aser-slot body + render-to-html shell
- Eliminates two pipe round-trips (was: aser-slot→Python→shell render)
- Shell statics (component_defs, CSS, pages_sx) cached in Python,
  injected into kernel once, referenced by symbol in per-request command
- Large blobs use placeholder tokens — Python splices post-render,
  pipe transfers ~51KB instead of 2MB

Performance (warm):
- Server total: 0.55s (was ~2s)
- aser-slot VM: 0.3s, shell render: 0.01s, pipe: 0.06s
- kwargs computation: 0.000s (cached)

SX_STANDALONE mode for sx_docs dev (skips fragment fetches).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 11:06:04 +00:00

515 lines
19 KiB
YAML

# Dev override: bind-mount source code + auto-reload
# Usage: docker compose -f docker-compose.yml -f docker-compose.dev.yml up [service...]
#
# Changes from production:
# - Source code bind-mounted (edit code → auto-reload)
# - Hypercorn runs with --reload
# - No deploy constraints (runs locally, not Swarm)
# - Ports exposed to host for direct access
x-dev-env: &dev-env
RELOAD: "true"
WORKERS: "1"
SX_USE_REF: "1"
SX_BOUNDARY_STRICT: "1"
SX_USE_OCAML: "1"
SX_OCAML_BIN: "/app/bin/sx_server"
x-sibling-models: &sibling-models
# Every app needs all sibling __init__.py + models/ for cross-domain SQLAlchemy imports
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
services:
blog:
restart: unless-stopped
ports:
- "8001:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./blog/alembic.ini:/app/blog/alembic.ini:ro
- ./blog/alembic:/app/blog/alembic:ro
- ./blog/app.py:/app/app.py
- ./blog/sx:/app/sx
- ./blog/sxc:/app/sxc
- ./blog/bp:/app/bp
- ./blog/services:/app/services
- ./blog/templates:/app/templates
- ./blog/models:/app/models
- ./blog/path_setup.py:/app/path_setup.py
- ./blog/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
market:
restart: unless-stopped
ports:
- "8002:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- /root/rose-ash/_snapshot:/app/_snapshot
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./market/alembic.ini:/app/market/alembic.ini:ro
- ./market/alembic:/app/market/alembic:ro
- ./market/app.py:/app/app.py
- ./market/sx:/app/sx
- ./market/sxc:/app/sxc
- ./market/bp:/app/bp
- ./market/services:/app/services
- ./market/templates:/app/templates
- ./market/models:/app/models
- ./market/path_setup.py:/app/path_setup.py
- ./market/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
cart:
restart: unless-stopped
ports:
- "8003:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./cart/alembic.ini:/app/cart/alembic.ini:ro
- ./cart/alembic:/app/cart/alembic:ro
- ./cart/app.py:/app/app.py
- ./cart/sx:/app/sx
- ./cart/sxc:/app/sxc
- ./cart/bp:/app/bp
- ./cart/services:/app/services
- ./cart/templates:/app/templates
- ./cart/models:/app/models
- ./cart/path_setup.py:/app/path_setup.py
- ./cart/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
events:
restart: unless-stopped
ports:
- "8004:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./events/alembic.ini:/app/events/alembic.ini:ro
- ./events/alembic:/app/events/alembic:ro
- ./events/app.py:/app/app.py
- ./events/sx:/app/sx
- ./events/sxc:/app/sxc
- ./events/bp:/app/bp
- ./events/services:/app/services
- ./events/templates:/app/templates
- ./events/models:/app/models
- ./events/path_setup.py:/app/path_setup.py
- ./events/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
federation:
restart: unless-stopped
ports:
- "8005:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./federation/alembic.ini:/app/federation/alembic.ini:ro
- ./federation/alembic:/app/federation/alembic:ro
- ./federation/app.py:/app/app.py
- ./federation/sx:/app/sx
- ./federation/sxc:/app/sxc
- ./federation/bp:/app/bp
- ./federation/services:/app/services
- ./federation/templates:/app/templates
- ./federation/models:/app/models
- ./federation/path_setup.py:/app/path_setup.py
- ./federation/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
account:
restart: unless-stopped
ports:
- "8006:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./account/alembic.ini:/app/account/alembic.ini:ro
- ./account/alembic:/app/account/alembic:ro
- ./account/app.py:/app/app.py
- ./account/sx:/app/sx
- ./account/sxc:/app/sxc
- ./account/bp:/app/bp
- ./account/services:/app/services
- ./account/templates:/app/templates
- ./account/models:/app/models
- ./account/path_setup.py:/app/path_setup.py
- ./account/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
relations:
restart: unless-stopped
ports:
- "8008:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./relations/alembic.ini:/app/relations/alembic.ini:ro
- ./relations/alembic:/app/relations/alembic:ro
- ./relations/app.py:/app/app.py
- ./relations/bp:/app/bp
- ./relations/services:/app/services
- ./relations/models:/app/models
- ./relations/path_setup.py:/app/path_setup.py
- ./relations/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
likes:
restart: unless-stopped
ports:
- "8009:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./likes/alembic.ini:/app/likes/alembic.ini:ro
- ./likes/alembic:/app/likes/alembic:ro
- ./likes/app.py:/app/app.py
- ./likes/bp:/app/bp
- ./likes/services:/app/services
- ./likes/models:/app/models
- ./likes/path_setup.py:/app/path_setup.py
- ./likes/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
orders:
restart: unless-stopped
ports:
- "8010:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./orders/alembic.ini:/app/orders/alembic.ini:ro
- ./orders/alembic:/app/orders/alembic:ro
- ./orders/app.py:/app/app.py
- ./orders/sx:/app/sx
- ./orders/sxc:/app/sxc
- ./orders/bp:/app/bp
- ./orders/services:/app/services
- ./orders/templates:/app/templates
- ./orders/models:/app/models
- ./orders/path_setup.py:/app/path_setup.py
- ./orders/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
test:
restart: unless-stopped
ports:
- "8011:8000"
environment:
<<: *dev-env
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./test/app.py:/app/app.py
- ./test/sx:/app/sx
- ./test/bp:/app/bp
- ./test/services:/app/services
- ./test/runner.py:/app/runner.py
- ./test/path_setup.py:/app/path_setup.py
- ./test/entrypoint.sh:/usr/local/bin/entrypoint.sh
# sibling service code + tests
- ./blog:/app/blog:ro
- ./market:/app/market:ro
- ./cart:/app/cart:ro
- ./events:/app/events:ro
- ./federation:/app/federation:ro
- ./account:/app/account:ro
- ./relations:/app/relations:ro
- ./likes:/app/likes:ro
- ./orders:/app/orders:ro
sx_docs:
restart: unless-stopped
ports:
- "8012:8000"
environment:
<<: *dev-env
SX_STANDALONE: "true"
volumes:
- /root/rose-ash/_config/app-config.yaml:/app/config/app-config.yaml:ro
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./sx/app.py:/app/app.py
- ./sx/sxc:/app/sxc
- ./sx/bp:/app/bp
- ./sx/services:/app/services
- ./sx/content:/app/content
- ./sx/sx:/app/sx
- ./sx/path_setup.py:/app/path_setup.py
- ./sx/entrypoint.sh:/usr/local/bin/entrypoint.sh
- ./sx/__init__.py:/app/__init__.py:ro
# sibling models
- ./blog/__init__.py:/app/blog/__init__.py:ro
- ./blog/models:/app/blog/models:ro
- ./market/__init__.py:/app/market/__init__.py:ro
- ./market/models:/app/market/models:ro
- ./cart/__init__.py:/app/cart/__init__.py:ro
- ./cart/models:/app/cart/models:ro
- ./events/__init__.py:/app/events/__init__.py:ro
- ./events/models:/app/events/models:ro
- ./federation/__init__.py:/app/federation/__init__.py:ro
- ./federation/models:/app/federation/models:ro
- ./account/__init__.py:/app/account/__init__.py:ro
- ./account/models:/app/account/models:ro
- ./relations/__init__.py:/app/relations/__init__.py:ro
- ./relations/models:/app/relations/models:ro
- ./likes/__init__.py:/app/likes/__init__.py:ro
- ./likes/models:/app/likes/models:ro
- ./orders/__init__.py:/app/orders/__init__.py:ro
- ./orders/models:/app/orders/models:ro
test-unit:
build:
context: .
dockerfile: test/Dockerfile.unit
volumes:
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./artdag/core:/app/artdag/core
- ./artdag/l1/tests:/app/artdag/l1/tests
- ./artdag/l1/sexp_effects:/app/artdag/l1/sexp_effects
- ./artdag/l1/app:/app/artdag/l1/app
entrypoint: >
python -m pytest_watch
--runner "python -m pytest -v --tb=short"
--
shared/
artdag/core/tests/
artdag/core/artdag/sexp/
artdag/l1/tests/
artdag/l1/sexp_effects/
--ignore=artdag/l1/tests/test_jax_primitives.py
--ignore=artdag/l1/tests/test_jax_pipeline_integration.py
-k "not gpu and not cuda"
profiles:
- test
test-integration:
build:
context: .
dockerfile: test/Dockerfile.integration
volumes:
- ./shared:/app/shared
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
- ./spec:/app/spec:ro
- ./web:/app/web:ro
- ./artdag:/app/artdag
profiles:
- test
networks:
appnet:
driver: bridge
externalnet:
driver: bridge
volumes:
db_data_1:
redis_data:
redis_auth_data: