Add build and release lifecycle to ARCHITECTURE.md

Service definitions now include [build] config (path, uses_mcdsl,
images) so MCP owns the full build-push-deploy lifecycle, replacing
mcdeploy.toml. Documents mcp build, mcp sync auto-build, image
versioning policy (explicit tags, never :latest), and workspace
convention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 23:31:05 -07:00
parent e18a3647bf
commit 6465da3547

View File

@@ -192,6 +192,9 @@ for a service by prefix and derive component names automatically
```
mcp login Authenticate to MCIAS, store token
mcp build <service> Build and push images for a service
mcp build <service>/<image> Build and push a single image
mcp deploy <service> Deploy all components from service definition
mcp deploy <service>/<component> Deploy a single component
mcp deploy <service> -f <file> Deploy from explicit file
@@ -203,8 +206,8 @@ mcp list List services from all agents (registry,
mcp ps Live check: query runtime on all agents, show running
containers with uptime and version
mcp status [service] Full picture: live query + drift + recent events
mcp sync Push service definitions to agent (update desired
state without deploying)
mcp sync Push service definitions to agent; build missing
images if source tree is available
mcp adopt <service> Adopt all <service>-* containers into a service
mcp purge [service[/component]] Remove stale registry entries (--dry-run to preview)
@@ -235,11 +238,19 @@ Example: `~/.config/mcp/services/metacrypt.toml`
name = "metacrypt"
node = "rift"
active = true
path = "metacrypt"
[build]
uses_mcdsl = false
[build.images]
metacrypt = "Dockerfile.api"
metacrypt-web = "Dockerfile.web"
[[components]]
name = "api"
image = "mcr.svc.mcp.metacircular.net:8443/metacrypt:latest"
network = "docker_default"
image = "mcr.svc.mcp.metacircular.net:8443/metacrypt:v1.0.0"
network = "mcpnet"
user = "0:0"
restart = "unless-stopped"
ports = ["127.0.0.1:18443:8443", "127.0.0.1:19443:9443"]
@@ -247,8 +258,8 @@ volumes = ["/srv/metacrypt:/srv/metacrypt"]
[[components]]
name = "web"
image = "mcr.svc.mcp.metacircular.net:8443/metacrypt-web:latest"
network = "docker_default"
image = "mcr.svc.mcp.metacircular.net:8443/metacrypt-web:v1.0.0"
network = "mcpnet"
user = "0:0"
restart = "unless-stopped"
ports = ["127.0.0.1:18080:8080"]
@@ -334,6 +345,83 @@ Service definition files can be:
- **Generated by converting from mcdeploy.toml** during initial MCP
migration (one-time).
### Build Configuration
Service definitions include a `[build]` section that tells MCP how to
build container images from source. This replaces the standalone
`mcdeploy.toml` -- MCP owns the full build-push-deploy lifecycle.
Top-level build fields:
| Field | Purpose |
|-------|---------|
| `path` | Source directory relative to the workspace root |
| `build.uses_mcdsl` | Whether the mcdsl module is needed at build time |
| `build.images.<name>` | Maps each image name to its Dockerfile path |
The workspace root is configured in `~/.config/mcp/mcp.toml`:
```toml
[build]
workspace = "~/src/metacircular"
```
A service with `path = "mcr"` resolves to `~/src/metacircular/mcr`. The
convention assumes `~/src/metacircular/<path>` on operator workstations
(vade, orion). The workspace path can be overridden but the convention
should hold for all standard machines.
### Build and Release Workflow
The standard release workflow for a service:
1. **Tag** the release in git (`git tag -a v1.1.0`).
2. **Build** the images: `mcp build <service>` reads the service
definition, locates the source tree via `path`, and runs `docker
build` using each Dockerfile in `[build.images]`. Images are tagged
with the version from the component `image` field and pushed to MCR.
3. **Update** the service definition: bump the version tag in each
component's `image` field.
4. **Deploy**: `mcp sync` or `mcp deploy <service>`.
#### `mcp build` Resolution
`mcp build <service>` does the following:
1. Read the service definition to find `[build.images]` and `path`.
2. Resolve the source tree: `<workspace>/<path>`.
3. For each image in `[build.images]`:
a. Build with the Dockerfile at `<source>/<dockerfile>`.
b. If `uses_mcdsl = true`, include the mcdsl directory in the build
context (or use a multi-module build strategy).
c. Tag as `<registry>/<image>:<version>` (version extracted from the
matching component's `image` field).
d. Push to MCR.
#### `mcp sync` Auto-Build
`mcp sync` pushes service definitions to agents. Before deploying, it
checks that each component's image tag exists in the registry:
- **Tag exists** → proceed with deploy.
- **Tag missing, source tree available** → build and push automatically,
then deploy.
- **Tag missing, no source tree** → fail with error:
`"mcr:v1.1.0 not found in registry and no source tree at ~/src/metacircular/mcr"`.
This ensures `mcp sync` is a single command for the common case (tag,
update version, sync) while failing clearly when the build environment
is not available.
#### Image Versioning
Service definitions MUST pin explicit version tags (e.g., `v1.1.0`),
never `:latest`. This ensures:
- `mcp status` shows the actual running version.
- Deployments are reproducible.
- Rollbacks are explicit (change the tag back to the previous version).
---
## Agent