feat: update caserun aggregation and v02 deploy config

This commit is contained in:
Codex Agent
2026-06-08 12:20:34 +08:00
parent d07565c6f1
commit 916838bde4
43 changed files with 1836 additions and 395 deletions
+7 -7
View File
@@ -1,16 +1,16 @@
# Deploy Contract
`deploy.schema.json` defines the future `deploy/deploy.json` manifest shape.
`deploy.schema.json` defines the future `deploy/deploy.yaml` manifest shape.
The MVP acceptance environment is DEV only. Public endpoint source fields live in
`deploy/deploy.json`: frontend `http://74.48.78.17:16666` and API/edge
`deploy/deploy.yaml`: frontend `http://74.48.78.17:16666` and API/edge
`http://74.48.78.17:16667`. PROD profile fields may be represented in schema
for future compatibility, but PROD deployment is not part of MVP acceptance.
## L5 DEV Skeleton
- `deploy/deploy.json` is the DEV-only deploy manifest.
- `deploy/deploy.json` is the single source for `health.path`,
- `deploy/deploy.yaml` is the DEV-only deploy manifest.
- `deploy/deploy.yaml` is the single source for `health.path`,
`publicEndpoints`, `frp.proxies`, and `k3s.serviceMappings`.
- `deploy/k8s/base` contains parseable k3s resource skeletons for the frozen
HWLAB service IDs rendered from the manifest contract.
@@ -67,9 +67,9 @@ node scripts/deploy-desired-state-plan.mjs --target-tag <tag> --pretty
node scripts/deploy-desired-state-plan.mjs --promotion-commit <sha> --check
```
The desired-state plan reads `deploy/deploy.json`,
The desired-state plan reads `deploy/deploy.yaml`,
`deploy/artifact-catalog.dev.json`, `deploy/k8s/base/workloads.yaml`, and the
optional artifact report snapshot. `deploy/deploy.json` is the human-authored
optional artifact report snapshot. `deploy/deploy.yaml` is the human-authored
runtime config truth source. Published image identity lives in
`G14-gitops:deploy/artifact-catalog.dev.json`; the source branch catalog is only
a seed contract for local checks. GitOps render overlays catalog image fields and
@@ -101,7 +101,7 @@ Next DEV deploy smoke commands, for a separately authorized deployment task:
```sh
npm run check
node -e "JSON.parse(require('node:fs').readFileSync('deploy/deploy.json','utf8'))"
node -e "JSON.parse(require('node:fs').readFileSync('deploy/deploy.yaml','utf8'))"
KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl apply --dry-run=server -k deploy/k8s/dev
curl -fsS http://74.48.78.17:16667/health/live
node scripts/dev-edge-health-smoke.mjs --live --report /tmp/hwlab-dev-gate/report.json
+2 -2
View File
@@ -244,8 +244,8 @@
],
"serviceInventory": {
"version": "v2",
"serviceCount": 8,
"requiredServiceCount": 8,
"serviceCount": 5,
"requiredServiceCount": 5,
"disabledServiceCount": 0,
"requiredServiceIds": [
"hwlab-cloud-api",
+91
View File
@@ -136,6 +136,97 @@
"hwlab-edge-proxy": "deploy/runtime/boot/hwlab-edge-proxy.sh",
"hwlab-agent-skills": "deploy/runtime/boot/hwlab-agent-skills.sh"
},
"serviceDeclarations": {
"hwlab-cloud-api": {
"runtimeKind": "bun-command",
"entrypoint": "cmd/hwlab-cloud-api/main.ts",
"artifactKind": "bun-command",
"healthPath": "/health/live",
"healthPort": 6667,
"componentPaths": [
"cmd/hwlab-cloud-api/",
"cmd/hwlab-codex-api-responses-forwarder/",
"cmd/hwlab-deepseek-responses-bridge/",
"deploy/runtime/boot/hwlab-codex-api-responses-forwarder.sh",
"deploy/runtime/boot/hwlab-deepseek-responses-bridge.sh",
"internal/cloud/",
"internal/db/",
"internal/audit/",
"internal/agent/agentrun-dispatch.mjs",
"internal/agent/prompts/",
"skills/hwlab-agent-runtime/"
],
"env": {},
"observable": true
},
"hwlab-cloud-web": {
"runtimeKind": "cloud-web",
"entrypoint": "web/hwlab-cloud-web/index.html",
"artifactKind": "cloud-web",
"healthPath": "/health/live",
"healthPort": 8080,
"componentPaths": [
"web/hwlab-cloud-web/",
"internal/dev-entrypoint/cloud-web-runtime.mjs",
"internal/dev-entrypoint/cloud-web-proxy.mjs",
"internal/dev-entrypoint/cloud-web-routes.mjs",
"tools/src/hwlab-cli/trace-renderer.ts"
],
"env": {},
"observable": true
},
"hwlab-gateway": {
"runtimeKind": "bun-command",
"entrypoint": "cmd/hwlab-gateway/main.ts",
"artifactKind": "bun-command",
"healthPath": "/health/live",
"healthPort": 7001,
"componentPaths": ["cmd/hwlab-gateway/", "internal/sim/"],
"env": {},
"observable": false
},
"hwlab-edge-proxy": {
"runtimeKind": "bun-command",
"entrypoint": "cmd/hwlab-edge-proxy/main.ts",
"artifactKind": "bun-command",
"healthPath": "/health",
"healthPort": 6667,
"componentPaths": ["cmd/hwlab-edge-proxy/", "internal/dev-entrypoint/http.mjs"],
"env": {},
"observable": true
},
"hwlab-agent-skills": {
"runtimeKind": "skills-bundle",
"entrypoint": "skills/hwlab-agent-runtime/SKILL.md",
"artifactKind": "skills-bundle",
"healthPath": "/health/live",
"healthPort": 7430,
"componentPaths": ["skills/"],
"env": {},
"observable": true
}
},
"envRecipe": {
"osPackages": ["ca-certificates", "git"],
"bunVersion": "1.3.13",
"launcherPath": "deploy/runtime/launcher/hwlab-env-reuse-launcher.ts",
"runtimeNodeModulesPath": "/opt/hwlab-env/node_modules",
"additionalEnvPaths": [
"internal/dev-entrypoint/artifact-runtime.mjs",
"scripts/artifact-publish.mjs",
"scripts/g14-artifact-publish.mjs",
"scripts/src/dev-artifact-services.mjs"
],
"hwpodAliases": [
{ "command": "hwpod", "script": "tools/hwpod-cli.ts" },
{ "command": "hwpod-ctl", "script": "tools/hwpod-ctl.ts" },
{ "command": "hwpod-compiler", "script": "tools/hwpod-compiler-cli.ts" }
]
},
"bootConfig": {
"template": "default",
"overrides": {}
},
"services": [
{
"serviceId": "hwlab-cloud-api",
+135
View File
@@ -48,6 +48,9 @@
},
"additionalProperties": false
},
"lanes": {
"$ref": "#/$defs/lanes"
},
"services": {
"type": "array",
"minItems": 1,
@@ -303,6 +306,138 @@
},
"additionalProperties": false
},
"lanes": {
"type": "object",
"properties": {
"v02": {
"$ref": "#/$defs/v02Lane"
}
},
"additionalProperties": false
},
"v02Lane": {
"type": "object",
"required": ["name", "sourceBranch", "gitopsBranch", "namespace", "envReuseServices", "bootScripts", "serviceDeclarations", "envRecipe", "bootConfig"],
"properties": {
"name": { "type": "string", "const": "v0.2" },
"sourceBranch": { "type": "string", "const": "v0.2" },
"gitopsBranch": { "type": "string", "const": "v0.2-gitops" },
"namespace": { "type": "string", "const": "hwlab-v02" },
"endpoint": { "type": "string" },
"publicEndpoints": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"artifactCatalog": { "type": "string" },
"runtimePath": { "type": "string" },
"imageTagMode": { "type": "string", "enum": ["short", "full"] },
"sourceRepo": { "type": "string" },
"envReuseServices": {
"type": "array",
"items": { "$ref": "#/$defs/serviceId" },
"uniqueItems": true
},
"bootScripts": {
"type": "object",
"minProperties": 1,
"additionalProperties": { "$ref": "#/$defs/repoPath" }
},
"serviceDeclarations": {
"type": "object",
"minProperties": 1,
"additionalProperties": { "$ref": "#/$defs/serviceDeclaration" }
},
"envRecipe": { "$ref": "#/$defs/envRecipe" },
"bootConfig": { "$ref": "#/$defs/bootConfig" },
"services": {
"type": "array",
"items": { "$ref": "#/$defs/laneService" }
}
},
"additionalProperties": false
},
"serviceDeclaration": {
"type": "object",
"required": ["runtimeKind", "entrypoint", "componentPaths"],
"properties": {
"runtimeKind": { "type": "string", "enum": ["bun-command", "cloud-web", "skills-bundle", "node-command"] },
"entrypoint": { "$ref": "#/$defs/repoPath" },
"artifactKind": { "type": "string", "enum": ["bun-command", "cloud-web", "skills-bundle", "node-command"] },
"healthPath": { "type": "string", "pattern": "^/" },
"healthPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
"componentPaths": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#/$defs/repoPath" }
},
"env": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"observable": { "type": "boolean" }
},
"additionalProperties": false
},
"envRecipe": {
"type": "object",
"required": ["osPackages", "bunVersion", "launcherPath", "runtimeNodeModulesPath", "additionalEnvPaths", "hwpodAliases"],
"properties": {
"osPackages": {
"type": "array",
"minItems": 1,
"items": { "type": "string", "minLength": 1 },
"uniqueItems": true
},
"bunVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+" },
"launcherPath": { "$ref": "#/$defs/repoPath" },
"runtimeNodeModulesPath": { "type": "string", "pattern": "^/" },
"additionalEnvPaths": {
"type": "array",
"items": { "$ref": "#/$defs/repoPath" },
"uniqueItems": true
},
"hwpodAliases": {
"type": "array",
"items": { "$ref": "#/$defs/hwpodAlias" }
}
},
"additionalProperties": false
},
"hwpodAlias": {
"type": "object",
"required": ["command", "script"],
"properties": {
"command": { "type": "string", "minLength": 1 },
"script": { "$ref": "#/$defs/repoPath" }
},
"additionalProperties": false
},
"bootConfig": {
"type": "object",
"required": ["template"],
"properties": {
"template": { "type": "string", "enum": ["default"] },
"overrides": { "type": "object" }
},
"additionalProperties": false
},
"laneService": {
"type": "object",
"required": ["serviceId"],
"properties": {
"serviceId": { "$ref": "#/$defs/serviceId" },
"env": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"additionalProperties": false
},
"repoPath": {
"type": "string",
"minLength": 1,
"not": { "pattern": "(^/|(^|/)\\.\\.(/|$))" }
},
"service": {
"type": "object",
"required": ["serviceId", "namespace", "healthPath", "profile"],
+292
View File
@@ -0,0 +1,292 @@
manifestVersion: v1
environment: dev
namespace: hwlab-dev
endpoint: http://74.48.78.17:16667
health:
method: GET
path: /health/live
responseFormat: json
publicEndpoints:
frontend:
url: http://74.48.78.17:16666
protocol: http
host: 74.48.78.17
port: 16666
serviceId: hwlab-cloud-web
frpProxy: hwlab-dev-cloud-web
api:
url: http://74.48.78.17:16667
protocol: http
host: 74.48.78.17
port: 16667
serviceId: hwlab-edge-proxy
frpProxy: hwlab-dev-edge-proxy
frp:
server:
address: 74.48.78.17
bindPort: 7000
proxies:
- name: hwlab-dev-cloud-web
endpointId: frontend
type: tcp
localServiceId: hwlab-cloud-web
localHost: hwlab-cloud-web.hwlab-dev.svc.cluster.local
localPort: 8080
remotePort: 16666
- name: hwlab-dev-edge-proxy
endpointId: api
type: tcp
localServiceId: hwlab-edge-proxy
localHost: hwlab-edge-proxy.hwlab-dev.svc.cluster.local
localPort: 6667
remotePort: 16667
k3s:
serviceMappings:
- serviceId: hwlab-cloud-api
name: hwlab-cloud-api
namespace: hwlab-dev
port: 6667
targetPort: http
- serviceId: hwlab-cloud-web
name: hwlab-cloud-web
namespace: hwlab-dev
port: 8080
targetPort: http
- serviceId: hwlab-gateway
name: hwlab-gateway
namespace: hwlab-dev
port: 7001
targetPort: http
- serviceId: hwlab-agent-skills
name: hwlab-agent-skills
namespace: hwlab-dev
port: 7430
targetPort: http
- serviceId: hwlab-edge-proxy
name: hwlab-edge-proxy
namespace: hwlab-dev
port: 6667
targetPort: http
profiles:
dev:
name: dev
enabled: true
namespace: hwlab-dev
endpoint: http://74.48.78.17:16667
notes: DEV-only k3s deployment skeleton. D601 reaches the master edge through frp reverse tunnel.
prod:
name: prod
enabled: false
namespace: hwlab-prod
notes: Reserved placeholder only. PROD deployment and acceptance are explicitly out of scope.
lanes:
v02:
name: v0.2
sourceBranch: v0.2
gitopsBranch: v0.2-gitops
namespace: hwlab-v02
endpoint: https://hwlab.74-48-78-17.nip.io
publicEndpoints:
frontend: https://hwlab.74-48-78-17.nip.io
api: https://hwlab.74-48-78-17.nip.io
legacyFrontend: http://74.48.78.17:19666
legacyApi: http://74.48.78.17:19667
artifactCatalog: deploy/artifact-catalog.v02.json
runtimePath: deploy/gitops/g14/runtime-v02
imageTagMode: full
envReuseServices:
- hwlab-cloud-api
- hwlab-cloud-web
- hwlab-gateway
- hwlab-edge-proxy
- hwlab-agent-skills
bootScripts:
hwlab-cloud-api: deploy/runtime/boot/hwlab-cloud-api.sh
hwlab-cloud-web: deploy/runtime/boot/hwlab-cloud-web.sh
hwlab-gateway: deploy/runtime/boot/hwlab-gateway.sh
hwlab-edge-proxy: deploy/runtime/boot/hwlab-edge-proxy.sh
hwlab-agent-skills: deploy/runtime/boot/hwlab-agent-skills.sh
serviceDeclarations:
hwlab-cloud-api:
runtimeKind: bun-command
entrypoint: cmd/hwlab-cloud-api/main.ts
artifactKind: bun-command
healthPath: /health/live
healthPort: 6667
componentPaths:
- cmd/hwlab-cloud-api/
- cmd/hwlab-codex-api-responses-forwarder/
- cmd/hwlab-deepseek-responses-bridge/
- deploy/runtime/boot/hwlab-codex-api-responses-forwarder.sh
- deploy/runtime/boot/hwlab-deepseek-responses-bridge.sh
- internal/cloud/
- internal/db/
- internal/audit/
- internal/agent/agentrun-dispatch.mjs
- internal/agent/prompts/
- skills/hwlab-agent-runtime/
env: {}
observable: true
hwlab-cloud-web:
runtimeKind: cloud-web
entrypoint: web/hwlab-cloud-web/index.html
artifactKind: cloud-web
healthPath: /health/live
healthPort: 8080
componentPaths:
- web/hwlab-cloud-web/
- internal/dev-entrypoint/cloud-web-runtime.mjs
- internal/dev-entrypoint/cloud-web-proxy.mjs
- internal/dev-entrypoint/cloud-web-routes.mjs
- tools/src/hwlab-cli/trace-renderer.ts
env: {}
observable: true
hwlab-gateway:
runtimeKind: bun-command
entrypoint: cmd/hwlab-gateway/main.ts
artifactKind: bun-command
healthPath: /health/live
healthPort: 7001
componentPaths:
- cmd/hwlab-gateway/
- internal/sim/
env: {}
observable: false
hwlab-edge-proxy:
runtimeKind: bun-command
entrypoint: cmd/hwlab-edge-proxy/main.ts
artifactKind: bun-command
healthPath: /health
healthPort: 6667
componentPaths:
- cmd/hwlab-edge-proxy/
- internal/dev-entrypoint/http.mjs
env: {}
observable: true
hwlab-agent-skills:
runtimeKind: skills-bundle
entrypoint: skills/hwlab-agent-runtime/SKILL.md
artifactKind: skills-bundle
healthPath: /health/live
healthPort: 7430
componentPaths:
- skills/
env: {}
observable: true
envRecipe:
osPackages:
- ca-certificates
- git
bunVersion: 1.3.13
launcherPath: deploy/runtime/launcher/hwlab-env-reuse-launcher.ts
runtimeNodeModulesPath: /opt/hwlab-env/node_modules
additionalEnvPaths:
- internal/dev-entrypoint/artifact-runtime.mjs
- scripts/artifact-publish.mjs
- scripts/g14-artifact-publish.mjs
- scripts/src/dev-artifact-services.mjs
hwpodAliases:
- command: hwpod
script: tools/hwpod-cli.ts
- command: hwpod-ctl
script: tools/hwpod-ctl.ts
- command: hwpod-compiler
script: tools/hwpod-compiler-cli.ts
bootConfig:
template: default
overrides: {}
services:
- serviceId: hwlab-cloud-api
env:
HWLAB_CLOUD_DB_URL: secretRef:hwlab-cloud-api-v02-db/database-url
HWLAB_CLOUD_DB_CONTRACT: v02-redacted-presence-only
HWLAB_ACCESS_CONTROL_REQUIRED: "1"
HWLAB_BOOTSTRAP_ADMIN_ID: usr_v02_admin
HWLAB_BOOTSTRAP_ADMIN_USERNAME: admin
HWLAB_BOOTSTRAP_ADMIN_DISPLAY_NAME: HWLAB v0.2 Admin
HWLAB_BOOTSTRAP_ADMIN_PASSWORD_HASH: secretRef:hwlab-v02-bootstrap-admin/password-hash
HWLAB_BOOTSTRAP_ADMIN_API_KEY_ID: key_master_server_admin
HWLAB_BOOTSTRAP_ADMIN_API_KEY: secretRef:hwlab-v02-master-server-admin-api-key/api-key
HWLAB_KEYCLOAK_ISSUER: https://auth.74-48-78-17.nip.io/realms/hwlab
HWLAB_KEYCLOAK_CLIENT_ID: hwlab-cloud-web
HWLAB_KEYCLOAK_CLIENT_SECRET: secretRef:hwlab-cloud-web-client/client-secret
HWLAB_CODE_AGENT_ADAPTER: agentrun-v01
AGENTRUN_MGR_URL: http://agentrun-mgr.agentrun-v01.svc.cluster.local:8080
HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: G14
HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE: agentrun-v01
HWLAB_CODE_AGENT_AGENTRUN_SECRET_NAMESPACE: agentrun-v01
HWLAB_CODE_AGENT_AGENTRUN_REPO_URL: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
services:
- serviceId: hwlab-cloud-api
namespace: hwlab-dev
healthPath: /health/live
profile: dev
replicas: 1
env:
HWLAB_ENVIRONMENT: dev
HWLAB_PUBLIC_ENDPOINT: http://74.48.78.17:16667
HWLAB_CLOUD_API_PORT: "6667"
HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN: unidesk-backend,provider-gateway,microservice-proxy
HWLAB_CLOUD_DB_URL: secretRef:hwlab-cloud-api-dev-db/database-url
HWLAB_CLOUD_DB_SSL_MODE: disable
HWLAB_CLOUD_DB_CONTRACT: dev-redacted-presence-only
HWLAB_CLOUD_RUNTIME_ADAPTER: postgres
HWLAB_CLOUD_RUNTIME_DURABLE: "true"
HWLAB_M3_IO_CONTROL_ENABLED: "false"
HWLAB_CODE_AGENT_PROVIDER: codex-stdio
HWLAB_CODE_AGENT_MODEL: gpt-5.5
HWLAB_CODE_AGENT_TIMEOUT_MS: "1200000"
HWLAB_CODE_AGENT_OPENAI_BASE_URL: http://127.0.0.1:49280/responses
HWLAB_CODE_AGENT_CODEX_STDIO_ENABLED: "1"
HWLAB_CODE_AGENT_CODEX_STDIO_SUPERVISOR: repo-owned
HWLAB_CODE_AGENT_WORKSPACE: /workspace/hwlab
HWLAB_CODE_AGENT_CODEX_WORKSPACE: /workspace/hwlab
HWLAB_CODE_AGENT_CODEX_SANDBOX: danger-full-access
HWLAB_CODE_AGENT_CODEX_COMMAND: /app/node_modules/.bin/codex
CODEX_HOME: /codex-home
NO_PROXY: hyueapi.com,.hyueapi.com,hyui.com,.hyui.com,127.0.0.1,localhost,::1,api.minimaxi.com,.minimaxi.com
no_proxy: hyueapi.com,.hyueapi.com,hyui.com,.hyui.com,127.0.0.1,localhost,::1,api.minimaxi.com,.minimaxi.com
OPENAI_API_KEY: secretRef:hwlab-code-agent-provider/openai-api-key
HWLAB_CODE_AGENT_SKILLS_DIRS: /app/skills:/data/user-skills
HWLAB_PREINSTALLED_SKILLS_DIR: /app/skills
HWLAB_USER_SKILLS_DIR: /data/user-skills
HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: deepseek
HWLAB_CODE_AGENT_DEEPSEEK_MODEL: deepseek-chat
HWLAB_CODE_AGENT_DEEPSEEK_BASE_URL: http://hwlab-deepseek-proxy.hwlab-dev.svc.cluster.local:4000/v1/responses
HWLAB_CODE_AGENT_CODEX_API_MODEL: gpt-5.5
HWLAB_CODE_AGENT_CODEX_API_BASE_URL: http://127.0.0.1:49280/responses
HWLAB_CODE_AGENT_CODEX_API_UPSTREAM_BASE_URL: https://hyueapi.com
HWLAB_CODE_AGENT_CODEX_API_FORWARDER_PORT: "49280"
- serviceId: hwlab-cloud-web
namespace: hwlab-dev
healthPath: /health/live
profile: dev
replicas: 1
env:
HWLAB_ENVIRONMENT: dev
HWLAB_API_BASE_URL: http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667
HWLAB_CLOUD_WEB_PROXY_TIMEOUT_MS: "1260000"
- serviceId: hwlab-gateway
namespace: hwlab-dev
healthPath: /health/live
profile: dev
replicas: 0
env:
HWLAB_GATEWAY_MODE: hardware-boundary
HWLAB_ENVIRONMENT: dev
- serviceId: hwlab-edge-proxy
namespace: hwlab-dev
healthPath: /health/live
profile: dev
replicas: 1
env:
HWLAB_EDGE_LISTEN: 0.0.0.0:6667
HWLAB_EDGE_UPSTREAM: http://hwlab-cloud-api.hwlab-dev.svc.cluster.local:6667
HWLAB_EDGE_PROXY_TIMEOUT_MS: "1260000"
- serviceId: hwlab-agent-skills
namespace: hwlab-dev
healthPath: /health/live
profile: dev
replicas: 1
env: {}
createdAt: 2026-05-21T00:00:00Z
+1 -1
View File
@@ -9,7 +9,7 @@ The DEV reverse link is D601 to master edge through frp.
- `frps.dev.toml` reserves D601 `16666` / `16667`, G14 DEV `17666` / `17667`, and G14 PROD `18666` / `18667`
as TCP `remotePort` values; do not also bind them as `vhostHTTPPort`, because that collides with
the DEV TCP proxy.
- `deploy/deploy.json` is the source for the public endpoints and FRP proxy
- `deploy/deploy.yaml` is the source for the public endpoints and FRP proxy
mapping. Run `node scripts/deploy-contract-plan.mjs --check` to detect drift
such as public `6666`/`6667` reuse before any future apply command.
- No secret values are stored in this repository. Operators must provide auth
+1 -1
View File
@@ -21,6 +21,6 @@ Health ownership:
PROD is intentionally gated off for this task.
`deploy/deploy.json` is the source for the public endpoints, FRP proxy ports,
`deploy/deploy.yaml` is the source for the public endpoints, FRP proxy ports,
k3s service mappings, and health path. The dry-run renderer validates these
files only and does not perform a real edge apply or restart.