- control-plane default listen addr is now :3452 (was :8080). An
unusual port to avoid collisions on the VM.
- agent-micro and agent-gateway default SDP_CP_URL points at
ws://localhost:3452/ws/agent. docker-compose.yml updates the
control plane command, host port mapping, and agent -cp URLs.
- nginx/nginx.conf (the legacy root-mount reference) uses
127.0.0.1:3452 for the upstream. nginx/sandbox.conf is the new
deployment config: four location blocks for the /sandbox/credit-card
mount — _next/static serves cached chunks, /api/ and /ws/ proxy
to 127.0.0.1:3452, /sandbox/credit-card serves the static
dashboard with try_files for SPA routing.
- scripts/patch-nginx.sh: deleted. The user configures nginx on 186
by hand. scripts/deploy.sh no longer calls it.
- AGENTS.md: new file. Documents the build/lint/test commands
(with the golang:1.24-alpine container — local Go can't fetch
the toolchain), the wire protocol, the Slice-2 conventions
(sdp-<repo> container naming, snapshot persistence,
PreGitReset/AfterStart hooks), the repo-path gotcha, and the
build-artifacts-in-git rationale.
- dashboard/out: now tracked in git, alongside bin/. The dashboard
static export is scp'd to 186 on deploy; the VMs have no
internet so they can't regenerate it. .gitignore comment
explains this and warns against re-ignoring.
- README.md / REQUIREMENTS.md: status updated to 'Slice 2 done',
per-feature checklist marked. Erangel repo path corrected to
/var/www/html/erangel-ocean (was wrongly ~/SDP in earlier docs).
- store: add tables and CRUD for sandboxes (with services), templates
(with services, clone-into-sandbox), environments (named key/value
sets), and routes (per-sandbox <service>_url overrides).
- api: split into one file per resource. handleSandboxes/handleSandboxByID
covers CRUD + 'clone from template' + 'deploy one service in a sandbox'
(which merges the sandbox's env into the request, picks the port,
and dispatches the deploy frame to the right node).
handleTemplates/handleTemplateByID, handleEnvironments/handleEnvironmentByID,
handlePushRoutes cover the rest. The control plane's repo->node
resolution still lives in resolveNode (api-gateway -> gateway,
everything else -> micro).
- protocol: add RepoInfo, RouteOverride; add HostPort, SandboxID to DeployRequest.
- ws hub: add CallAgent for sync request/response RPCs over the agent WS,
and DeliverAgentReply to route {op:reply} frames back to the caller.
UnregisterAgent now also fails any pending RPCs so callers don't hang.
- agent-micro: new op handlers list_repos, list_branches, probe.
Wire protocol.Event frames use json.RawMessage so each op decodes
its own data shape.
- agent-gateway: same op handlers (list_repos/list_branches/probe) plus
push_routes, which the gateway uses to rewrite the api-gateway
config.php. Detailed in a later commit.
- control-plane login: validateViaAgent now calls CallAgent('probe')
against the gateway agent (git ls-remote), replacing the
accept-any-creds stub.
- control-plane repos: handleListRepos and handleListBranches forward
to the agents via list_repos / list_branches RPCs, replacing the
hardcoded fixtures.
- control-plane deployments: split into its own file. handleListDeployments
reads from SQLite (was hardcoded []). handleCreateDeployment now
supports sandbox-scoped deploys with a host port + env merge.
handleStopDeployment looks up the node from the deployment row.
- store: split into store.go + deployments.go. The Deployment type
adds sandboxId, containerId, hostPort. StartDeploymentInSandbox,
SetContainerID, ListDeployments, GetDeployment, LatestDeploymentBySandboxService
are new.
- store_test.go: round-trips every Slice-2 path (env, sandbox,
template, clone, routes, deployment).
- .gitignore: track bin/ — the build runs on a separate Linux box
with the golang:1.24 toolchain, and the binaries are SCPed from
there to the company VMs (92 / 186). The VMs have no internet.
- Tracked bin/{control-plane,agent-micro,agent-gateway}.
- New agentlib module (gitutil + deployer with NewGo / NewPHP) replaces
agent-micro/internal so both agents can share it (Go's internal/ rule
was blocking agent-gateway from importing agent-micro's packages).
- Migrate agents from legacy github.com/docker/docker/client to the
current github.com/moby/moby/client v0.5.0 / moby/moby/api v1.55.0.
- Fix compile errors in the original committed code: missing
gorilla/websocket import in control-plane/internal/ws/handlers.go,
unaliased dockerclient reference, wrong SQLite driver name
(sqlite3 -> sqlite), Dialer.Dial 3-return-value mismatch.
- scripts/build.sh: Go 1.23 -> 1.24, apk add git, safe.directory for
bind-mounted host tree, chmod inside container (host can't chmod
files owned by container root).
- README and REQUIREMENTS updated to reflect the actual architecture
(Go + SQLite, no Spring Boot, moby SDK, per-deploy no image build)
with a per-feature status checklist at the end of REQUIREMENTS.
Sandbox Deployment Platform — Go control plane + agents, NextJS dashboard,
nginx reverse proxy. Cross-compile via Docker; deploy via sshpass to
172.18.136.92 (micro) and 172.18.139.186 (gateway).
- control-plane: HTTP API, WS hub, SQLite (modernc.org/sqlite) for
progress, .log files for log persistence
- agent-micro / agent-gateway: alpine:3.20 + bind-mounted repo,
binary exec'd in container, no Dockerfile build step
- dashboard: NextJS static export + shadcn/ui components, single
WebSocket hook
- docker-compose.yml: three services on alpine:latest with docker
socket bind for agents
- scripts/: build.sh (golang:1.23-alpine cross-compile), deploy.sh,
patch-nginx.sh (idempotent nginx splice), ssh wrappers
Runtime model: pass-through Bitbucket creds per deploy, never logged or
persisted on the agent. Control plane never touches git or docker
directly — agents do all the work locally.