Execute reproducible suite runs on harness-managed Kubernetes or universal Docker infrastructure for Kuma service mesh features. Supports local k3d Kubernetes, remote kubeconfig-backed Kubernetes, and universal mode containers for tracked verification runs.
Execute reproducible suite runs on harness-managed Kubernetes or universal environments for any Kuma feature. Cluster creation, remote attachment, and teardown are managed through harness setup kuma cluster in Phase 2 and Phase 8. Before any unplanned cluster operation, ask the user with options:
Approve operation - proceed with the cluster changeReject - skip the operationStop run - halt the runTrack every manifest, command, and artifact for full run reproducibility.
Repo-local skill package. Hooks run through harness-owned entrypoints installed by SessionStart hooks. SessionStart also installs a repo-aware harness wrapper on PATH. Run harness --help for all subcommands.
After compaction, trust the SessionStart(compact) handoff as authoritative. Continue from the saved run directory and next-action guidance. Do not rerun or unless the handoff says to.
harness run startharness run preflightAfter resume, keep using tracked wrappers such as harness run apply, harness run record, harness run report, and harness run envoy. Never switch to raw kubectl --kubeconfig ....
If the active run looks stale, mismatched, or partially broken, use harness run doctor first and harness run repair second. Do not hand-edit run-status.json, suite-run-state.json, or current-run.json.
If a Stop hook summary appears with preventedContinuation: false, treat it as advisory. If a run was accidentally aborted while next_planned_group exists, use harness run resume --message "Recovered from unexpected stop" and continue.
Parse from $ARGUMENTS:
| Argument | Default | Purpose |
|---|---|---|
| (positional) | - | Suite path or bare name. Bare names (no /) are looked up in ${DATA_DIR}/ first. Prompt the user if omitted |
--profile | all | Cluster profile: single-zone, multi-zone, single-zone-universal, multi-zone-universal, or all. When all, runs one full run per required profile. |
--provider | auto | Kubernetes provider: local maps to k3d, remote maps to kubeconfig-backed remote clusters. Only applies to Kubernetes profiles. |
--repo | auto-detect cwd | Path to Kuma repo checkout |
--run-id | timestamp-based | Override run identifier |
--resume | - | Resume a partial run by its run ID |
echo "${XDG_DATA_HOME:-$HOME/.local/share}/harness/suites"echo "$HOME"date +%Y%m%d-%H%M%Sprintf '%s\n' "${HARNESS_CONTAINER_RUNTIME:-bollard}"printf '%s\n' "${HARNESS_KUBERNETES_RUNTIME:-kube}"command -v k3d >/dev/null 2>&1 && echo "installed" || echo "MISSING"command -v kubectl >/dev/null 2>&1 && echo "installed" || echo "MISSING"command -v helm >/dev/null 2>&1 && echo "installed" || echo "MISSING"DATA_DIR is the suites directory. The timestamp is the default RUN_ID suffix. If session ID is empty or literal ${, use standalone. Assume the effective container runtime backend is bollard unless HARNESS_CONTAINER_RUNTIME overrides it. k3d is required only for local Kubernetes provider runs.
Read references/agent-contract.md in full before starting any run. Top-level summary:
harness run apply --manifest g02/04.yaml, not SD=.... Exception: the Phase 0/1 harness run start setup block.harness run record for kubectl, kumactl, curl, and other cluster-touching shell commands; use the dedicated harness run apply, harness run report, and harness run envoy subcommands where they fit. No raw binaries, no python3 -c.python3. Use jq for JSON filtering or harness run envoy capture for Envoy admin data.--delay not sleep. harness run apply --delay 8 --manifest ... not sleep 8 && harness run apply.g13/01.yaml not /full/path/.... No /tmp, no --validate=false.harness run report group.harness run apply until preflight has completed. Preflight materializes baselines and group YAML into prepared manifests. The tool-result hook enforces this - harness run apply during bootstrap or before preflight completion is denied with KSR014.git add <files> && git commit -m 'fix: description'. Never iterate on uncommitted edits.make test, make check, cargo test, cargo clippy, harness commands, or any verification command through tail -N or head -N. Use full output or grep for specific markers (FAIL, error, PASS). Drawing conclusions from truncated output is unreliable - failures can be hidden above the truncation point.TaskOutput tool. Do not tail or cat the output file paths directly.Read references/workflow.md for the full procedure. The section below is the entrypoint checklist; load referenced files before acting.
Run harness setup capabilities and keep the JSON output as CAPABILITIES for all later phases.
readiness.profiles when present. Only run profiles whose ready field is true.blocking_checks.readiness.profiles may contain both k3d and remote variants for the same Kubernetes profile name. If both are ready and the user did not pass --provider, ask which provider to use before Phase 2.readiness.platforms and readiness.features to decide whether the environment is usable now.--project-dir or --repo-root as a last-resort debug override when state or cwd resolution is broken.readiness is absent (older harness binary), fall back to the older static logic based on cluster_topologies, platforms, and features.*.available.Set DATA_DIR from "Preprocessed context". If missing, ask the user with options:
Create suite with /suite:createProvide a different suite pathResolve REPO_ROOT: --repo flag > cwd go.mod with kumahq/kuma > user approval prompt with options:
Provide repo pathCancel runTreat harness setup capabilities as authoritative for Kubernetes and container readiness. Do not infer universal readiness from docker info alone. With the default HARNESS_KUBERNETES_RUNTIME=kube, missing kubectl alone does not block native Kubernetes operations such as harness run validate, harness run apply, harness run capture, or readiness checks. kubectl is still required when HARNESS_KUBERNETES_RUNTIME=kubectl-cli and whenever the run plan includes tracked harness run record -- kubectl ... commands. For local Kubernetes provider runs, k3d, helm, and the Kuma repo make contract must be ready. For remote Kubernetes provider runs, Helm plus the remote publish contract must be ready. For universal runs, the Docker Engine must be reachable; the Docker CLI is only required when HARNESS_CONTAINER_RUNTIME=docker-cli.
All cluster commands go through tracked wrappers, never raw kubectl or kumactl.
Read references/workflow.md Phase 1 for the full start and resume flow.
Resolve SUITE_PATH using the suite resolution order: bare names check ${DATA_DIR}/${name}/suite.md first, then literal path.
Fresh run: resolve RUN_ID, SUITE_PATH, SUITE_DIR, and PROFILE now. Keep them for Phase 3, where harness run start --suite <path> --run-id <id> --profile <profile> --repo-root <repo> will initialize the run, save current-run.json, and complete preflight for the active run after cluster bootstrap is ready.
Resume (via --resume): if SessionStart already restored the matching active run, keep that run id for Phase 3 and use harness run resume once the cluster context is ready. Otherwise plan to reattach with harness run resume --run-id <id> --run-root <suite-dir>/runs. Only unfinished runs can resume - start a new RUN_ID if the saved run has a final verdict.
After start or resume, use only context-driven harness commands. Do not pass --run-dir, --run-root, --repo-root, or --kubeconfig again unless debugging. Never switch to raw kubectl --kubeconfig ....
If the saved run cannot be attached cleanly, inspect it with harness run doctor before retrying. Use harness run repair only for deterministic state fixes such as stale pointers or derived status drift.
Error cases: if the suite path does not exist, search ${DATA_DIR}/ with Glob for partial matches. Present matches via a user approval prompt. If no matches, ask the user with options:
Provide suite pathCreate new suite with /suite:createGate: suite path, repo root, run id, and profile are resolved for the selected run path.
Read references/cluster-setup.md before starting this phase.
When --profile all (the default), read all group files and collect the set of required profiles. Sort groups by profile tier: standalone, single-zone Kubernetes, single-zone universal, multi-zone Kubernetes, multi-zone universal. Execute all groups for one profile before tearing down and moving to the next. Parallelizable groups within a profile can run concurrently. If suite profile ordering is non-contiguous, warn and propose a reorder.
For each profile, execute a full run (Phase 1-8) with only the groups matching that profile. When transitioning between profiles, wait for the old cluster's teardown to complete before starting the next cluster bootstrap. Do not run teardown and bootstrap in parallel - the teardown must finish first to avoid port conflicts and resource contention.
Present the execution plan via a user approval prompt with options:
Run all profiles - execute every required profile sequentiallySelect profiles - user picks which profiles to runSingle profile only - run only the first required profileSelect the cluster topology based on the profile being executed. For Kubernetes profiles, also select the provider:
# Kubernetes single-zone, local k3d (--profile single-zone --provider local):
harness setup kuma cluster single-up kuma-1
# Kubernetes multi-zone, local k3d (--profile multi-zone --provider local):
harness setup kuma cluster global-two-zones-up kuma-1 kuma-2 kuma-3 zone-1 zone-2
# Kubernetes single-zone, remote kubeconfigs (--profile single-zone --provider remote):
harness setup kuma cluster \
--provider remote \
--remote name=kuma-1,kubeconfig=/path/to/kuma-1.yaml[,context=kuma-1] \
--push-prefix ghcr.io/acme/kuma \
--push-tag branch-dev \
single-up kuma-1
# Kubernetes multi-zone, remote kubeconfigs (--profile multi-zone --provider remote):
harness setup kuma cluster \
--provider remote \
--remote name=kuma-1,kubeconfig=/path/to/kuma-1.yaml[,context=global] \
--remote name=kuma-2,kubeconfig=/path/to/kuma-2.yaml[,context=zone-1] \
--remote name=kuma-3,kubeconfig=/path/to/kuma-3.yaml[,context=zone-2] \
--push-prefix ghcr.io/acme/kuma \
--push-tag branch-dev \
global-two-zones-up kuma-1 kuma-2 kuma-3 zone-1 zone-2
# Universal single-zone (--profile single-zone-universal):
harness setup kuma cluster --platform universal single-up test-cp
# Universal multi-zone (--profile multi-zone-universal):
harness setup kuma cluster --platform universal global-zone-up global-cp zone-cp zone-1
Read references/universal-setup.md for the universal mode lifecycle, including Docker container management, harness run kuma token, and harness run kuma service for service containers.
If changes modify CRDs, re-run Phase 2 bootstrap and then re-run harness run preflight plus harness run capture --label "preflight" for the active run before continuing. If the suite references gateways (MeshGateway, GatewayClass, HTTPRoute, Gateway), install CRDs with harness setup gateway and verify with harness setup gateway --check-only. In remote mode, pass the tracked generated kubeconfig path to harness setup gateway --kubeconfig ... so teardown can uninstall what harness installed later.
Gate: cluster bootstrap is ready for harness run start or harness run resume.
Fresh run: call harness run start --suite <path> --run-id <id> --profile <profile> --repo-root <repo>, then save the preflight snapshot with harness run capture --label "preflight".
Resume: if SessionStart already restored the matching active run, use harness run resume directly. Otherwise reattach with harness run resume --run-id <id> --run-root <suite-dir>/runs. If the cluster topology was rebuilt or CRDs changed since the saved run last preflighted, re-run harness run preflight and harness run capture --label "preflight" before execution resumes.
If start, resume, or refresh preflight fails, ask the user with options:
Retry preflightFix the issue manuallyStop the runBefore choosing manual fixes for suspected run-state drift, check harness run doctor. If the findings are deterministic, run harness run repair and then retry the failing harness command.
Do not start tests until the active run is attached, the prepared-suite artifact exists, and the preflight snapshot is saved.
Read references/workflow.md Phase 4 section in full before starting tests - it has the complete step-by-step procedure with code blocks and per-group gates.
Read references/validation.md for the pre-apply checklist and safe apply flow before applying manifests.
Read references/mesh-policies.md for policy create rules when the suite tests any Mesh* policy.
Read examples/suite-template.md when creating a new suite. Read examples/example-motb-core-suite.md for a worked example of the expected format.
Key principles (workflow.md has the details):
Switch cluster profileFix prerequisitesSkip groupStop run## Consume, ## Debug, and expected outcomes. Read before executing, drop after completing.harness run apply, verify/cleanup through harness run record. harness run apply does NOT support --gid. The group context comes from the manifest path, not a flag - use --manifest g01/01-file.yaml only. During Phase 4 execution, every harness run record command must include --gid <group-id> so the command log and audit trail stay group-scoped. Use harness run report group --group-id <id> ... to finalize a group and harness run envoy for Envoy admin captures. Batch manifests with repeated --manifest or pass the group directory. Never mix resource kinds in one kubectl delete command. Always clean up group resources before reporting the group result - delete created CRDs in reverse order. If the suite does not specify cleanup, ask the user with options:
Run proposed cleanupSkip cleanupStop runharness run report group --group-id <id> --status <pass|fail|skip> --capture-label "after-<id>". Use --evidence-label for tracked artifacts.On any unexpected result or failure, stop and triage before continuing. This gate is mandatory because unclassified failures corrupt the run's audit trail.
Step 1 - Classify as: suite bug (wrong manifest/expectations), product bug (Kuma vs spec), harness bug (infra misconfiguration), or environment issue (timing/resources).
Step 2 - Report. harness run runner-state --event failure-manifest, then user approval prompt with suite:run/bug-found: [classification] - [description]. Options:
Fix now - pause run, fix based on classification, resumeContinue and fix later - record with classification, mark group failed, continueStop runDo not continue past a failure without presenting it to the user first. On first failure, go to Phase 5.
Gate: all planned tests have pass/fail entries in the report. Every artifact path in the report resolves to an existing file. run-status.json reflects final counts.
Read references/troubleshooting.md for known failure modes.
harness run capture, classify as manifest/environment/product bug.harness run runner-state --event failure-manifest), then user approval prompt with first line suite:run/manifest-fix: how should this failure be handled?. Include suite target path and error message. Options:
Fix for this run onlyFix in suite and this runSkip this stepStop runFix in suite and this run edits only the exact suite file plus amendments.md. After editing, use harness run apply which reads from suite source, not the stale prepared copy.harness run capture \
--label "postrun"
harness run report check
harness run finish
Gate: command log complete, manifest index complete, all tests have pass/fail, every artifact path resolves to an existing file, run-status.json has correct final counts, state captures exist for preflight + each group + postrun, compactness check passes.
After all gates pass, proceed to Phase 7 (retrospective) before tearing down clusters.
After harness run finish, that run is final. Do not reuse it for another cluster bootstrap or execution step. Start a new run with a new RUN_ID instead.
After closeout, spawn parallel subagents (compliance auditor, manifest reviewer, coverage analyzer, findings summarizer, process advisor) to analyze the completed run. Present the assembled retrospective to the user via a user approval prompt with options:
Save as-is - save to {run_dir}/retrospective.mdRequest changes - user provides feedback, regenerate specific sections. Loop until user confirms or 3 iterations are reached, then save current draftDiscard - do not saveRead references/workflow.md Phase 7 section for the full agent specifications and assembly procedure.
Gate: retrospective saved or explicitly discarded by user before proceeding to cluster teardown.
Tear down the clusters created in Phase 2. Use the matching harness setup kuma cluster teardown command for the active profile. Read references/workflow.md Phase 8 section for the per-profile teardown commands.
Prefer harness setup kuma cluster --no-build and --no-load for normal build/load skips. Harness maps local k3d --no-load to Kuma's current K3D_DONT_LOAD=1 contract internally. Keep env vars for lower-level overrides only: HARNESS_HELM_CLEAN=1 adds full isolation, HARNESS_DOCKER_PRUNE=0 skips image cleanup (not recommended), and HARNESS_BUILD_IMAGES=0 / HARNESS_LOAD_IMAGES=0 remain escape hatches. Remote provider runs do not support --no-load.
harness run report check enforces: max 220 lines, max 4 code blocks. Store raw output in artifacts/ and reference file paths.
Hook codes:
| Code | Hook | Meaning |
|---|---|---|
| KSR005 | tool-guard | Cluster binaries and Envoy admin calls must go through harness wrappers |
| KSR006 | tool-result | Expected artifact missing after command |
| KSR007 | guard-stop | Run closeout incomplete: missing state capture or pending verdict |
| KSR008 | tool-guard | Write path is outside the tracked run surface |
| KSR011 | audit | Suite-runner runs must stay user-story-first and tracked |
| KSR012 | tool-failure | Current run verdict status |
| KSR013 | runner state hooks | Runner state is missing or invalid |
| KSR014 | tool-guard/tool-result/context-agent | Required runner phase or approval is missing |
| KSR015 | validate-agent | Preflight worker reply or saved artifacts are invalid |
References (read when entering the relevant phase):
harness commands (context-aware after run start or run resume): setup capabilities, setup kuma cluster, setup gateway, run start, run finish, run resume, run doctor, run repair, run init, run preflight, run runner-state, run apply, run validate, run capture, run record, run report group, run envoy {capture,route-body,bootstrap}, run diff, run kuma cli {find,build}, and hook. All commands accept --delay <seconds> to wait before executing. Run harness --help for details.
Templates (in assets/): run-metadata.template.json, run-status.template.json, command-log.template.md, manifest-index.template.md, run-report.template.md