Repository navigation
enh(docker): dynamic freeport for multi-worktree Docker cells (CMS/DTS/MySQL) #2001
Description
Summary
Track dynamic host-port allocation for Percussion Docker cells (CMS, DTS, MySQL, and other compose services) so multiple agent worktrees / concurrent local stacks on one machine do not collide on fixed published ports.
Parent / context: Human review on PR #1955 (feat/issue-1927-h2-docker-qa-entrypoint) — fixed QA_CMS_HOST_PORT = 9993 and fixed dev verify URLs (9992 / 9980) conflict when several worktrees run docker cells on the same host.
Problem
| Surface | Current behavior |
|---|---|
docker/scripts/perc-devctl.py QA cell |
Hardcoded QA_CMS_HOST_PORT = 9993 |
Dev verify probes |
Fixed localhost:9992 / 9980 |
| Compose / matrix cells | Typically fixed host port maps |
Multiple agent worktrees (or parallel overnight sessions) on one box bind the same host ports → second stack fails or clobbers the first.
Desired outcome
- Allocate free host ports per run (
mkd-freeport/ equivalent freeport helper — product or platform utility). - Apply consistently to all docker cells that publish host ports (CMS, DTS, MySQL, matrix products, not only H2 QA).
- Propagate chosen ports into:
- compose
-p/ env file /ports:host side TEST_CMS_URL/ probe URLs / Playwright base URL- any
matrix-install-smoke/ health-wait consumers
- compose
- Document operator/agent contract (how to discover the allocated port; tear-down frees it).
- Cross-platform (Windows + Linux + macOS) — freeport must work without assuming Unix-only tooling.
Out of scope for PR #1955
#1927 H2 Docker QA entrypoint + health wait + tear-down stays mergeable without implementing freeport in that PR. This issue is the residual so the freeport review thread can close.
Acceptance criteria (draft)
- Freeport (or documented equivalent) integrated into
perc-devctl(and compose/env generation) for published host ports - Concurrent two-worktree QA/dev stack smoke does not fail on
address already in use - Tests or scripted check for allocation + URL wiring
- Docs updated (
docker/README or AGENTS companion)
References
- PR feat(qa): #1927 H2 Docker QA entrypoint + health wait + tear-down #1955 review thread on
docker/scripts/perc-devctl.py(human: natechadwick) - Related: feat(qa): #1827 slice 1 — H2 Docker QA entrypoint + health wait + tear-down #1927 H2 Docker QA entrypoint
Labels suggestion: enhancement, docker, qa
Agent progress (night-issue-prs)
| Slice | Issue | Status | PR | Notes | Updated |
|---|---|---|---|---|---|
| Parent freeport epic closeout | #2001 | done | — (no residual PR; AC complete via children) | Static AC audit vs main; all children merged | 2026-08-05 |
| A perc-devctl freeport | #2003 | done | #2003 | QA CMS + verify probe freeport, unit tests, README | 2026-08-05 |
| B DTS/MySQL/matrix compose freeport | #2004 | done | #2060 | Compose DB host ports MYSQL/POSTGRES/MSSQL + perc-devctl | 2026-08-05 |
| C matrix-install-smoke + TEST_CMS_URL | #2005 | done | #2014 | resolve_host_port in matrix; probe/-p pin | 2026-08-05 |
| D two-worktree concurrent smoke checklist | #2006 | done | #2058 | freeport-concurrent-smoke.py + docker/README checklist | 2026-08-05 |
Activity
natechadwick-intsof commentedon Aug 5, 2026
Slice A shipped (Partial)
PR: #2003
Branch: \eat/issue-2001-devctl-freeport\
In this PR: perc-devctl freeport for QA CMS host port + dev verify probe URLs, unit tests, docker/README operator contract.
Residual child issues (unassigned):
Operator: Grok: night-issue-prs (model grok-4.5)
feat(docker): freeport for perc-devctl QA CMS and verify probe ports (#…
enh(docker): wire freeport into matrix-install-smoke (#2005) (#2014)
docs(docker): two-worktree concurrent freeport smoke checklist (#2006)
feat(docker): freeport compose DB host ports for multi-worktree (#2004)
docs(docker): two-worktree concurrent freeport smoke checklist (#2006) (
feat(docker): freeport compose DB host ports for multi-worktree (#2004)…
natechadwick-intsof commentedon Aug 5, 2026
Parent closeout — AC complete (static audit)
All four acceptance criteria for #2001 are satisfied on
mainvia merged child slices. No residual freeport PR — no missing env keys, docs, or unit coverage for published host ports. Live two-worktree Docker smoke not re-run underagent_safe_only(allocation smoke + unit suite green; design not reopened).AC → evidence map
perc-devctl(+ compose/env generation) for published host portsdocker/scripts/perc_host_ports.py(find_free_port/is_port_free/resolve_host_port). Callers:perc-devctl.py(QA CMS, verify CMS/DTS, MySQL/Postgres/MSSQL host pins onup),matrix-install-smoke.py(CMS/DTS + compose DB host publishes). Compose interpolates${CMS_PORT},${DTS_PORT},${MYSQL_PORT},${POSTGRES_PORT},${MSSQL_PORT}. PR #2003 (slice A), #2060 / issue #2004 (slice B).address already in usedocker/scripts/freeport-concurrent-smoke.py+ operator checklist indocker/README.md(Path A sequential live QA, Path B concurrent freeport under holder). PR #2058 / issue #2006. Documented non-freeport residual: fixed composecontainer_namestill limits true concurrent full stacks; freeport alone does not rename containers — out of freeport design scope.test_perc_devctl.py(freeport + VERIFY/TEST_CMS_URL wiring),test_matrix_install_smoke.py(host_port override + compose DB freeport),test_freeport_concurrent_smoke.py. Local verify this session: 121unittest discover -s docker/scriptsOK;freeport-concurrent-smoke.py→RESULT:OK. #2003, #2014 / #2005, #2060 / #2004, #2058 / #2006.docker/README or AGENTS companion)docker/README.md— Host ports / freeport contract, Playwright/TEST_CMS_URLtable, two-worktree checklist, script index. Companion notes indocs/developer-module/workbench-rest-and-qa-modes.md.Child slice status (all closed/merged)
Resolution order (contract, unchanged)
QA_CMS_HOST_PORT/CMS_HOST_PORT/DTS_HOST_PORT/CMS_PORT/DTS_PORT/MYSQL_PORT/POSTGRES_PORT/MSSQL_PORT)socketbind(0) — cross-platform, no Unix-only toolingClosing #2001 as complete. No residual freeport issue filed.
Operator: Grok: night-issue-prs (model grok-4.5)
natechadwick-intsof commentedon Aug 5, 2026
Closing: freeport epic AC complete on main via #2003/#2004/#2005/#2006 (PRs #2003, #2014, #2058, #2060). Full AC evidence in prior comment. No residual freeport PR.
fix(codeql): path-injection #2001 object-store app roots
fix(codeql): path-injection #2001 object-store app roots (#3980)