Mark Phase A complete, document $PORT convention, update next steps

PLATFORM_EVOLUTION.md: mark gaps #2 and #9 as done, Phase A complete,
Phase B in progress. Update sequencing and next steps.

engineering-standards.md: add Port Assignment and $PORT Convention
section documenting how MCP-deployed services receive assigned ports
via environment variables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-27 01:25:16 -07:00
parent 5baf12e303
commit b17472122b
2 changed files with 62 additions and 52 deletions

View File

@@ -5,7 +5,7 @@ from its current manually-wired state to fully declarative deployment.
It is a living design document — not a spec, not a commitment, but a It is a living design document — not a spec, not a commitment, but a
record of where we are, where we want to be, and what's between. record of where we are, where we want to be, and what's between.
Last updated: 2026-03-27 Last updated: 2026-03-27 (Phase A complete)
--- ---
@@ -188,21 +188,19 @@ mcdsl is already properly versioned and released:
- Docker builds use standard `go mod download` - Docker builds use standard `go mod download`
- `uses_mcdsl` eliminated from service definitions and docs - `uses_mcdsl` eliminated from service definitions and docs
#### 2. MCP Agent: Port Assignment #### 2. MCP Agent: Port Assignment — DONE
**Gap**: agent doesn't manage host ports. Service definitions specify Agent allocates host ports automatically at deploy time:
them manually. - Service definitions declare `[[components.routes]]` with name, port,
mode, and optional hostname
**Work**: - Agent picks random free ports (10000-60000, availability check,
- Agent picks free host ports at deploy time (random + availability mutex-serialized), records assignments in `component_routes` table
check). - Containers receive `$PORT` / `$PORT_<NAME>` env vars
- Agent records assignments in its registry. - Backward compatible: old-style `ports` strings still work unchanged
- Agent passes `$PORT` / `$PORT_<NAME>` to containers. - Proto: `RouteSpec` message, `routes` + `env` fields on `ComponentSpec`
- Agent releases ports on container stop/removal. - Servicedef: `RouteDef` parsing and validation from TOML
- New service definition format drops `ports` field, adds - Registry: `component_routes` table with `host_port` tracking
`[[components.routes]]`. - Runtime: `Env` field on `ContainerSpec`, `-e` flag generation
**Depends on**: nothing (can be developed standalone).
#### 3. MCP Agent: mc-proxy Route Registration #### 3. MCP Agent: mc-proxy Route Registration
@@ -287,19 +285,16 @@ is no API for dynamic record management.
wrapper, not a full service. This may be the right time to build the wrapper, not a full service. This may be the right time to build the
real MCNS. real MCNS.
#### 9. Application $PORT Convention #### 9. Application $PORT Convention — DONE
**Gap**: applications read listen addresses from their config files. mcdsl v1.1.0 adds `$PORT` and `$PORT_GRPC` env var support:
They don't check `$PORT` env vars. - `config.Load` checks `$PORT` → overrides `Server.ListenAddr`
- `config.Load` checks `$PORT_GRPC` → overrides `Server.GRPCAddr`
**Work**: - Takes precedence over TOML and generic env overrides
- Each service's config layer checks `$PORT` / `$PORT_<NAME>` and (`$MCR_SERVER_LISTEN_ADDR`) — agent-assigned ports are authoritative
overrides the configured listen address if set. - Handles both `config.Base` embedding (MCR, MCNS, MCAT) and direct
- This fits naturally into the existing `$SERVICENAME_*` env override `ServerConfig` embedding (Metacrypt) via struct tree walking
convention — it's just one more env var. - MCR, Metacrypt, MCNS upgraded to mcdsl v1.1.0
- Small change per service, but touches every service.
**Depends on**: nothing (can be done incrementally).
--- ---
@@ -308,15 +303,15 @@ They don't check `$PORT` env vars.
The dependencies form a rough order: The dependencies form a rough order:
``` ```
Phase A — Independent groundwork (parallel): Phase A — Independent groundwork: ✓ COMPLETE
#1 mcdsl proper module versioning ✓ DONE #1 mcdsl proper module versioning ✓ DONE
#2 MCP agent port assignment #2 MCP agent port assignment ✓ DONE
#5 mc-proxy route persistence ✓ DONE #5 mc-proxy route persistence ✓ DONE
#9 $PORT convention in applications #9 $PORT convention in applications ✓ DONE
Phase B — MCP route registration: Phase B — MCP route registration: ← IN PROGRESS
#3 Agent registers routes with mc-proxy #3 Agent registers routes with mc-proxy
(depends on #2 + #5) (depends on #2 + #5 — both done)
Phase C — Automated TLS: Phase C — Automated TLS:
#7 Metacrypt cert issuance policy #7 Metacrypt cert issuance policy
@@ -329,31 +324,24 @@ Phase D — DNS:
(depends on #8) (depends on #8)
``` ```
Phase A is partially complete. mcdsl (#1) and mc-proxy route **Phase A is complete.** Services can be deployed with agent-assigned
persistence (#5) are done. The remaining Phase A work (#2, #9) can ports and `$PORT` env vars. mc-proxy routes must still be registered
proceed in parallel. manually via `mcproxyctl` or the gRPC API.
After Phase A, services can be deployed with agent-assigned ports **Phase B is next.** The agent will call mc-proxy's gRPC API to
(manually registered in mc-proxy). register/remove routes automatically during deploy/stop. This
eliminates the last manual networking step — no more `mcproxyctl`
or TOML editing.
After Phase B, the manual steps are: cert provisioning and DNS. This After Phase C, cert provisioning is automatic. After Phase D,
is the biggest quality-of-life improvement — no more manual port `mcp deploy` is fully declarative.
picking or mc-proxy TOML editing.
After Phase C, only DNS remains manual.
After Phase D, `mcp deploy` is fully declarative.
Each phase is independently useful and deployable.
### Immediate Next Steps ### Immediate Next Steps
1. **MCP agent port assignment (#2)**new service definition parser, 1. **Phase B: MCP agent route registration (#3)**agent connects to
port allocation, `$PORT_*` injection. With #5 done, this is the mc-proxy via Unix socket, registers routes on deploy, removes on
remaining blocker for Phase B. stop. TLS certs are pre-provisioned (Phase C automates this later).
2. **$PORT convention (#9)** — small per-service config change. Can 2. **mcdoc implementation**fully designed, no platform evolution
start incrementally now, but only useful once #2 is deployed.
3. **mcdoc implementation** — fully designed, no platform evolution
dependency. Deployable with a manually assigned port today. dependency. Deployable with a manually assigned port today.
--- ---

View File

@@ -810,6 +810,28 @@ registry. If a tag is missing and the source tree is available, it
builds and pushes automatically. If the source tree is not available, builds and pushes automatically. If the source tree is not available,
it fails with a clear error directing the operator to build first. it fails with a clear error directing the operator to build first.
### Port Assignment and $PORT Convention
When deployed via MCP, the agent assigns host ports automatically and
passes them to containers via environment variables:
| Env var | When set | Example |
|---------|----------|---------|
| `$PORT` | Component has a single route | `PORT=8913` |
| `$PORT_<NAME>` | Component has multiple routes | `PORT_REST=8913`, `PORT_GRPC=9217` |
Route names come from the `name` field in `[[components.routes]]`.
Names are uppercased for the env var (e.g., `name = "rest"`
`$PORT_REST`).
Services using mcdsl v1.1.0+ get this automatically — `config.Load`
checks `$PORT` and `$PORT_GRPC` and overrides `Server.ListenAddr` and
`Server.GRPCAddr` respectively. These take precedence over TOML values
and generic env overrides (`$MCR_SERVER_LISTEN_ADDR`).
Services not using mcdsl must check `$PORT` manually in their config
loading.
### TLS ### TLS
- **Minimum TLS version: 1.3.** No exceptions, no fallback cipher suites. - **Minimum TLS version: 1.3.** No exceptions, no fallback cipher suites.