Track 4 — Platform Operations¶
A capability that runs on your laptop is not the same as a capability that runs in production. This track covers the operational layer:
- Linting in CI to keep specs deterministic and consistent
- The Control Port for health, metrics, and traces
- Binds that swap across
dev,staging, andprod
⚓ Prerequisites. A working capability from Track 1, plus Polychro installed.
📂 Source files referenced in this track:
- The governance and AI-safety rulesets live in
polychro-rulesets/src/main/resources/rulesets/— seegovernance.yml.- The reusable GitHub Action lives at
naftiko/polychro/action.yml.- The capability YAML you'll bind across environments is any file from
ikanos-docs/tutorial/— e.g.step-3-shipyard-auth.ymlfor the binds section.
Lesson 1 — Lint before you ship¶
Run Polychro on every capability change. The bundled polychro:governance
ruleset catches:
- Missing required descriptions on tools and operations
- Namespace collisions across adapters
- Trailing-slash and query-string-in-path mistakes
- Port collisions across multiple
exposes - Insecure descriptions (raw
<script>oreval(patterns)
polychro lint capabilities/*.naftiko.yml \
--ruleset polychro:governance \
--ruleset polychro:ai-safety
Try it against a tutorial capability:
curl -L -o step-3-shipyard-auth.yml \
https://raw.githubusercontent.com/naftiko/ikanos/main/ikanos-docs/tutorial/step-3-shipyard-auth.yml
polychro lint step-3-shipyard-auth.yml \
--ruleset polychro:governance \
--ruleset polychro:ai-safety
In GitHub Actions¶
# .github/workflows/lint.yml
name: Lint capabilities
on: [push, pull_request]
jobs:
polychro:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: naftiko/polychro@v1
with:
paths: 'capabilities/*.naftiko.yml'
rulesets: 'polychro:governance,polychro:ai-safety'
The action emits SARIF, so violations surface in the GitHub Code Scanning UI.
The action source is at naftiko/polychro/action.yml.
See Components → Polychro → Getting Started for the full ruleset reference and the legacy MegaLinter setup.
Lesson 2 — The Control Port¶
Every Ikanos process can declare a type: control adapter that exposes
operational endpoints:
exposes:
- type: control
port: 9090
namespace: control
observability:
tracing:
exporter: otlp
endpoint: http://otel-collector:4317
metrics:
exporter: prometheus
This activates:
| Endpoint | Purpose |
|---|---|
GET /health |
Liveness + readiness, suitable for Kubernetes probes |
GET /metrics |
Prometheus scrape (RED metrics — rate, errors, duration) |
GET /status |
Runtime diagnostics — adapters, ports, configuration digest |
GET /traces |
Recent in-memory trace summary (for development) |
OpenTelemetry traces are emitted automatically with one span per consumed HTTP call and one parent span per exposed operation. Connect to any OTLP collector (Tempo, Honeycomb, Datadog Agent) and you have end-to-end visibility.
Try it¶
Add the snippet above to any tutorial capability (or copy
step-3-shipyard-auth.yml
and append the type: control block under exposes:), then:
ikanos validate step-3-shipyard-auth.yml
ikanos serve step-3-shipyard-auth.yml &
# Probe the four control endpoints
curl http://localhost:9090/health
curl http://localhost:9090/metrics
curl http://localhost:9090/status
curl http://localhost:9090/traces
Lesson 3 — Multi-environment binds¶
The same capability YAML should run unchanged across dev, staging, and
prod. Achieve that by externalizing every secret and environment-specific
value through binds.
# capability.yml — committed to git
binds:
- namespace: env
location: "${BINDS_LOCATION}" # resolved at startup
keys:
REGISTRY_TOKEN: registry-token
REGISTRY_BASEURI: registry-baseuri
capability:
consumes:
- namespace: registry
type: http
baseUri: "{{REGISTRY_BASEURI}}"
authentication:
type: bearer
token: "REGISTRY_TOKEN"
In dev, point BINDS_LOCATION at a file:
# Provision a dev binds file
mkdir -p secrets
cat > secrets/dev.yaml <<'EOF'
registry-token: "dev-registry-token"
registry-baseuri: "https://mocks.naftiko.net/rest/naftiko-shipyard-maritime-registry-api/1.0.0-alpha3"
EOF
BINDS_LOCATION="file:///./secrets/dev.yaml" ikanos serve capability.yml
In production, point it at a vault URI:
The capability YAML never changes — only the resolved values do.
Recap¶
You now have:
- Pre-commit / CI linting for every spec change
- Health, metrics, and traces through the Control Port
- One spec, many environments through externalized binds
That's the operational floor for running capabilities in production. For fleet-wide governance — policy enforcement across many capabilities and clusters — see Components → Skipper (planned).