2026-05-11 03:14:43 +02:00
|
|
|
LOCUST_PORT ?= 10502
|
|
|
|
|
LOCUST_WEB_PORT ?= 10503
|
|
|
|
|
LOCUST_DB_DIR ?= /tmp/devplace_locust
|
|
|
|
|
LOCUST_DB ?= $(LOCUST_DB_DIR)/datastore.db
|
|
|
|
|
LOCUST_USERS ?= 20
|
|
|
|
|
LOCUST_SPAWN_RATE ?= 5
|
|
|
|
|
LOCUST_RUN_TIME ?= 120s
|
2026-06-14 16:46:36 +02:00
|
|
|
LOCUST_WEB_WORKERS ?= 4
|
|
|
|
|
WEB_WORKERS ?= $(shell nproc 2>/dev/null || echo 2)
|
2026-05-23 05:57:05 +02:00
|
|
|
DEVPLACE_RATE_LIMIT ?= 1000000
|
2026-05-11 03:14:43 +02:00
|
|
|
|
2026-06-13 18:27:41 +02:00
|
|
|
PYTHONDONTWRITEBYTECODE := 1
|
|
|
|
|
export PYTHONDONTWRITEBYTECODE
|
|
|
|
|
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
.PHONY: install dev clean tree tree-loc zip test test-headed test-unit test-api test-e2e test-fast test-failed test-first-failure test-slowest test-cache-clean coverage coverage-headed coverage-html locust locust-headless
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
install:
|
|
|
|
|
pip install -e .
|
2026-06-14 02:16:22 +02:00
|
|
|
python -m playwright install chromium
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
dev:
|
2026-06-09 06:41:27 +02:00
|
|
|
uvicorn devplacepy.main:app --reload --reload-dir devplacepy --host 0.0.0.0 --port 10500 --backlog 4096
|
2026-05-11 05:30:51 +02:00
|
|
|
|
|
|
|
|
prod:
|
2026-06-14 16:46:36 +02:00
|
|
|
DEVPLACE_STATIC_VERSION=$$(date +%s) DEVPLACE_TEMPLATE_AUTO_RELOAD=0 DEVPLACE_WEB_WORKERS=$(WEB_WORKERS) uvicorn devplacepy.main:app --host 0.0.0.0 --port 10500 --workers $(WEB_WORKERS) --backlog 8192 --proxy-headers --forwarded-allow-ips '*'
|
2026-05-10 09:08:12 +02:00
|
|
|
|
2026-06-14 09:48:10 +02:00
|
|
|
delete-pyc:
|
|
|
|
|
find . -name "__pycache__" -type d -prune -exec rm -rf {} + 2>/dev/null || true
|
|
|
|
|
find . -name "*.pyc" -delete
|
|
|
|
|
|
2026-06-13 18:27:41 +02:00
|
|
|
tree:
|
2026-06-13 20:34:47 +02:00
|
|
|
git ls-files | tree --fromfile --noreport
|
|
|
|
|
|
|
|
|
|
tree-loc:
|
|
|
|
|
@git ls-files | while IFS= read -r f; do \
|
|
|
|
|
loc=$$(wc -l < "$$f" 2>/dev/null || echo 0); \
|
|
|
|
|
printf '%s [%s LOC]\n' "$$f" "$$loc"; \
|
|
|
|
|
done | tree --fromfile --noreport
|
|
|
|
|
|
|
|
|
|
zip:
|
|
|
|
|
@rm -f $(notdir $(CURDIR)).zip
|
|
|
|
|
@git ls-files -z | xargs -0 zip -q $(notdir $(CURDIR)).zip
|
|
|
|
|
@printf 'Wrote %s (%s files)\n' "$(notdir $(CURDIR)).zip" "$$(git ls-files | wc -l)"
|
2026-06-13 18:27:41 +02:00
|
|
|
|
2026-05-10 09:08:12 +02:00
|
|
|
test:
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
PLAYWRIGHT_HEADLESS=1 python -m pytest tests/
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
test-headed:
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
PLAYWRIGHT_HEADLESS=0 python -m pytest tests/
|
2026-05-10 09:08:12 +02:00
|
|
|
|
2026-06-13 16:32:33 +02:00
|
|
|
test-unit:
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
python -m pytest tests/unit
|
2026-06-13 16:32:33 +02:00
|
|
|
|
|
|
|
|
test-api:
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
python -m pytest tests/api
|
2026-06-13 16:32:33 +02:00
|
|
|
|
|
|
|
|
test-e2e:
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
PLAYWRIGHT_HEADLESS=1 python -m pytest tests/e2e
|
|
|
|
|
|
|
|
|
|
test-fast:
|
|
|
|
|
python -m pytest tests/unit tests/api
|
|
|
|
|
|
|
|
|
|
test-failed:
|
|
|
|
|
PLAYWRIGHT_HEADLESS=1 python -m pytest tests/ --last-failed --last-failed-no-failures none
|
|
|
|
|
|
|
|
|
|
test-first-failure:
|
|
|
|
|
PLAYWRIGHT_HEADLESS=1 python -m pytest tests/ -x
|
|
|
|
|
|
|
|
|
|
test-slowest:
|
|
|
|
|
PLAYWRIGHT_HEADLESS=1 python -m pytest tests/ --durations=40
|
2026-06-13 16:32:33 +02:00
|
|
|
|
2026-06-05 20:33:35 +02:00
|
|
|
coverage:
|
|
|
|
|
rm -f .coverage .coverage.*
|
|
|
|
|
COVERAGE_PROCESS_START=$(CURDIR)/.coveragerc PLAYWRIGHT_HEADLESS=1 \
|
2026-06-12 07:43:33 +02:00
|
|
|
python -m coverage run -m pytest tests/
|
2026-06-05 20:33:35 +02:00
|
|
|
python -m coverage combine
|
|
|
|
|
python -m coverage report
|
|
|
|
|
|
|
|
|
|
coverage-headed:
|
|
|
|
|
rm -f .coverage .coverage.*
|
|
|
|
|
COVERAGE_PROCESS_START=$(CURDIR)/.coveragerc PLAYWRIGHT_HEADLESS=0 \
|
2026-06-12 07:43:33 +02:00
|
|
|
python -m coverage run -m pytest tests/
|
2026-06-05 20:33:35 +02:00
|
|
|
python -m coverage combine
|
|
|
|
|
python -m coverage report
|
|
|
|
|
|
|
|
|
|
coverage-html: coverage
|
|
|
|
|
python -m coverage html
|
|
|
|
|
@echo "Report written to htmlcov/index.html"
|
|
|
|
|
|
2026-05-11 03:14:43 +02:00
|
|
|
locust:
|
|
|
|
|
export DEVPLACE_DATABASE_URL="sqlite:///$(LOCUST_DB)"; \
|
2026-05-23 05:57:05 +02:00
|
|
|
export DEVPLACE_RATE_LIMIT=$(DEVPLACE_RATE_LIMIT); \
|
2026-06-05 17:44:12 +02:00
|
|
|
fuser -k $(LOCUST_PORT)/tcp 2>/dev/null || true; \
|
|
|
|
|
sleep 1; \
|
2026-05-11 03:14:43 +02:00
|
|
|
mkdir -p $(LOCUST_DB_DIR); \
|
|
|
|
|
rm -f $(LOCUST_DB); \
|
2026-06-14 16:46:36 +02:00
|
|
|
DEVPLACE_TEMPLATE_AUTO_RELOAD=0 DEVPLACE_WEB_WORKERS=$(LOCUST_WEB_WORKERS) uvicorn devplacepy.main:app --host 127.0.0.1 --port $(LOCUST_PORT) --workers $(LOCUST_WEB_WORKERS) --backlog 8192 > /tmp/devplace_locust_server.log 2>&1 & \
|
2026-05-11 03:14:43 +02:00
|
|
|
PID=$$!; \
|
2026-06-05 17:44:12 +02:00
|
|
|
while kill -0 $$PID 2>/dev/null && ! curl -s http://127.0.0.1:$(LOCUST_PORT)/ > /dev/null 2>&1; do sleep 0.5; done; \
|
|
|
|
|
if ! kill -0 $$PID 2>/dev/null; then echo "Server failed to start (port $(LOCUST_PORT) busy?). See /tmp/devplace_locust_server.log"; exit 1; fi; \
|
2026-05-11 03:14:43 +02:00
|
|
|
locust --host http://127.0.0.1:$(LOCUST_PORT) --web-port $(LOCUST_WEB_PORT); \
|
|
|
|
|
kill $$PID 2>/dev/null || true; \
|
|
|
|
|
rm -rf $(LOCUST_DB_DIR)
|
|
|
|
|
|
|
|
|
|
locust-headless:
|
|
|
|
|
export DEVPLACE_DATABASE_URL="sqlite:///$(LOCUST_DB)"; \
|
2026-05-23 05:57:05 +02:00
|
|
|
export DEVPLACE_RATE_LIMIT=$(DEVPLACE_RATE_LIMIT); \
|
2026-06-05 17:44:12 +02:00
|
|
|
fuser -k $(LOCUST_PORT)/tcp 2>/dev/null || true; \
|
|
|
|
|
sleep 1; \
|
2026-05-11 03:14:43 +02:00
|
|
|
mkdir -p $(LOCUST_DB_DIR); \
|
|
|
|
|
rm -f $(LOCUST_DB); \
|
2026-06-14 16:46:36 +02:00
|
|
|
DEVPLACE_TEMPLATE_AUTO_RELOAD=0 DEVPLACE_WEB_WORKERS=$(LOCUST_WEB_WORKERS) uvicorn devplacepy.main:app --host 127.0.0.1 --port $(LOCUST_PORT) --workers $(LOCUST_WEB_WORKERS) --backlog 8192 > /tmp/devplace_locust_server.log 2>&1 & \
|
2026-05-11 03:14:43 +02:00
|
|
|
PID=$$!; \
|
2026-06-05 17:44:12 +02:00
|
|
|
while kill -0 $$PID 2>/dev/null && ! curl -s http://127.0.0.1:$(LOCUST_PORT)/ > /dev/null 2>&1; do sleep 0.5; done; \
|
|
|
|
|
if ! kill -0 $$PID 2>/dev/null; then echo "Server failed to start (port $(LOCUST_PORT) busy?). See /tmp/devplace_locust_server.log"; exit 1; fi; \
|
2026-05-11 03:14:43 +02:00
|
|
|
locust --host http://127.0.0.1:$(LOCUST_PORT) --headless -u $(LOCUST_USERS) -r $(LOCUST_SPAWN_RATE) --run-time $(LOCUST_RUN_TIME) --html=$(LOCUST_DB_DIR)/report.html; \
|
|
|
|
|
kill $$PID 2>/dev/null || true; \
|
|
|
|
|
rm -rf $(LOCUST_DB_DIR)
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
clean:
|
|
|
|
|
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
|
|
|
|
find . -type f -name '*.pyc' -delete
|
|
|
|
|
rm -rf devplacepy.egg-info
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
rm -rf .pytest_cache
|
2026-05-10 09:08:12 +02:00
|
|
|
rm -rf .venv
|
2026-05-12 15:07:34 +02:00
|
|
|
|
Report every test failure in one pass and fix the whole suite
The suite ran with -x, so a run stopped at the first failure and finding N
failures cost N full runs. Move -rf into the pytest addopts so every run
lists each failure, and add the triage targets test-fast (unit + api, no
browser), test-failed (--last-failed), test-first-failure (the old -x),
test-slowest and test-cache-clean. A stale .pytest_cache holding node ids
from deleted files made --last-failed select everything; make clean and
test-cache-clean drop it.
Fix the fifteen failures this surfaced.
DeepSearch crawling raised AttributeError in its finally block on every run:
async_playwright().__aenter__() returns a Playwright, which has no __aexit__.
Use start()/stop() at both call sites.
Update the tests left behind by changed signatures: VectorStore is async now,
fetch_page takes a browser, _summary_payload takes dom_evidence, and the
messages/notifications page compounds take a user_uid.
Close four real flakes that fail-fast had been hiding, all of them late in
the run. Harvest assertions pinned crop.reward_coins while is_golden pays
five times on about five percent of harvests, so they now assert through
realizable_harvest_coins with the observed golden flag. Market saturation
fixtures assumed a single active farm and landed two tiers milder once the
api and e2e tiers had created farms, so they scale by active_farms(). The
primary-administrator container test raced the one second cross-worker cache
version window and now waits for the server to agree. The isslop tools test
matched the collapsed nav dropdown link instead of the tools grid card.
Stop burning ninety seconds waiting out server-side display caches:
DEVPLACE_RANKING_TTL and DEVPLACE_MARKET_SATURATION_TTL follow the existing
sitemap and home cache precedent and are zero for the suite, taking the
leaderboard test from 60.6s to 4.4s and the saturation test from 30.1s to
under a second.
2881 passed, 1 skipped in 15:13.
2026-07-26 16:02:36 +02:00
|
|
|
test-cache-clean:
|
|
|
|
|
rm -rf .pytest_cache
|
|
|
|
|
|
2026-06-09 06:41:27 +02:00
|
|
|
# Container Manager works out of the box: the overlay installs the docker CLI in
|
|
|
|
|
# the image and mounts the host socket. DOCKER_GID is read straight from the
|
chore: consolidate runtime data layout under single `data/` root directory
Migrate all runtime artifacts (database, uploads, VAPID keys, locks, bot state, container workspaces, zip staging) from scattered locations (`var/`, `devplacepy/static/uploads/`) into a unified `data/` directory. Update `config.py` as single source of truth with `DATA_PATHS` registry and `ensure_data_dirs()`, add `devplace migrate-data` CLI command with CRC verification and idempotent relocation, adjust `.dockerignore`, `.env.example`, `.gitignore`, `Dockerfile`, `Makefile`, `README.md`, `AGENTS.md`, `CLAUDE.md`, and all import paths in `attachments.py` to reference `config.UPLOADS_DIR`/`ATTACHMENTS_DIR` instead of computing from `STATIC_DIR`.
2026-06-13 21:06:43 +02:00
|
|
|
# socket so the UID-1000 app can use it; the data dir is the project's own data/
|
2026-06-09 06:41:27 +02:00
|
|
|
# at its real host path, so the DooD bind-mount (host == container path) holds
|
|
|
|
|
# with no /srv dir and no sudo.
|
|
|
|
|
COMPOSE := docker compose -f docker-compose.yml -f docker-compose.containers.yml
|
chore: consolidate runtime data layout under single `data/` root directory
Migrate all runtime artifacts (database, uploads, VAPID keys, locks, bot state, container workspaces, zip staging) from scattered locations (`var/`, `devplacepy/static/uploads/`) into a unified `data/` directory. Update `config.py` as single source of truth with `DATA_PATHS` registry and `ensure_data_dirs()`, add `devplace migrate-data` CLI command with CRC verification and idempotent relocation, adjust `.dockerignore`, `.env.example`, `.gitignore`, `Dockerfile`, `Makefile`, `README.md`, `AGENTS.md`, `CLAUDE.md`, and all import paths in `attachments.py` to reference `config.UPLOADS_DIR`/`ATTACHMENTS_DIR` instead of computing from `STATIC_DIR`.
2026-06-13 21:06:43 +02:00
|
|
|
DEVPLACE_DATA_DIR ?= $(CURDIR)/data
|
2026-06-09 06:41:27 +02:00
|
|
|
DOCKER_GID ?= $(shell stat -c '%g' /var/run/docker.sock 2>/dev/null)
|
|
|
|
|
export DEVPLACE_DATA_DIR
|
|
|
|
|
export DOCKER_GID
|
2026-05-12 15:07:34 +02:00
|
|
|
|
2026-06-09 16:06:02 +02:00
|
|
|
.PHONY: docker-build docker-up docker-down docker-logs docker-clean docker-prep ppy
|
|
|
|
|
|
|
|
|
|
# Build the single shared container image every instance runs. Build once;
|
|
|
|
|
# rebuild only when ppy.Dockerfile, the sudo shim, or pagent change.
|
|
|
|
|
ppy:
|
|
|
|
|
docker build --network=host -f ppy.Dockerfile -t ppy:latest devplacepy/services/containers/files
|
2026-05-12 15:07:34 +02:00
|
|
|
|
2026-06-09 06:41:27 +02:00
|
|
|
docker-prep:
|
|
|
|
|
mkdir -p $(DEVPLACE_DATA_DIR)
|
|
|
|
|
|
|
|
|
|
docker-build: docker-prep
|
|
|
|
|
$(COMPOSE) build
|
|
|
|
|
|
|
|
|
|
docker-up: docker-prep
|
|
|
|
|
$(COMPOSE) up -d
|
2026-05-12 15:07:34 +02:00
|
|
|
|
|
|
|
|
docker-down:
|
2026-06-09 06:41:27 +02:00
|
|
|
$(COMPOSE) down
|
2026-05-12 15:07:34 +02:00
|
|
|
|
|
|
|
|
docker-logs:
|
2026-06-09 06:41:27 +02:00
|
|
|
$(COMPOSE) logs -f
|
2026-05-12 15:07:34 +02:00
|
|
|
|
|
|
|
|
docker-clean:
|
2026-06-09 06:41:27 +02:00
|
|
|
$(COMPOSE) down -v
|
2026-05-23 08:27:04 +02:00
|
|
|
|
2026-06-09 16:06:02 +02:00
|
|
|
docker-bup: docker-build docker-up
|
|
|
|
|
|
2026-05-23 08:27:04 +02:00
|
|
|
deploy:
|
|
|
|
|
git checkout production
|
|
|
|
|
git merge master
|
|
|
|
|
git push origin production
|
feat: add autonomous maintenance agent fleet with shared engine and validator
Add the `agents/` directory containing a fleet of autonomous AI maintenance agents for codebase consistency, including a shared async engine (`agent.py`), a dependency-free validator (`validator.py`), and specialized agents for security, audit, docs, style, frontend, SEO, test coverage, and more. Wire the fleet into the Makefile with `--fix`/`--check` modes, document the architecture in `AGENTS.md`, `CLAUDE.md`, and `README.md`, and enforce a hard rule that the `agents/` directory itself is off-limits to any code modification to preserve detection data.
2026-06-12 01:35:31 +02:00
|
|
|
|