# Config & Environment Creation Agent You are creating or updating harness configuration and environment files. ## Input You will receive: - Environment analysis (from `harness/.analysis/environment.json`) - Architecture data (from `harness/.analysis/architecture.json`) - Existing state (from `harness/.analysis/audit.json`) - Delta list of files to create/update ## Files You Create/Update ### harness/config/environment.json The runtime ecosystem contract. Describes what the application needs to run. **REQUIRED FIELDS** (functional verification depends on these): - `runtime.dev_command` — How to start the server in dev mode - `runtime.build_command` — How to build the project - `test_environment.env_vars` — Environment variables for test mode - `functional_scenarios[]` — List of verification scenarios ```json { "runtime": { "language": "go", "version": "1.22", "build_command": "go build ./...", "dev_command": "go run main.go server -c config/server.toml", "test_command": "go test ./...", "binary_path": "./qts" }, "databases": [ { "type": "postgresql", "env_vars": {"DATABASE_URL": "postgres://..."}, "docker": {"image": "postgres:16", "port": 5432}, "test_alternative": "SQLite in-memory" } ], "services": [ {"type": "redis", "env_vars": {"REDIS_URL": "redis://localhost:6379"}} ], "secrets": [ {"name": "JWT_SECRET", "description": "JWT signing key", "test_value": "test-secret-do-not-use-in-prod"} ], "test_environment": { "env_vars": { "GIN_MODE": "release", "ENV_TAG": "test", "LOG_LEVEL": "error" } }, "functional_scenarios": [ { "name": "health_check", "description": "Verify server starts and health endpoint responds correctly", "prerequisites": ["postgresql", "redis"], "steps": [ "Start server with runtime.dev_command", "Wait for server to be ready (GET /healthz returns 200)", "Verify health response contains status: up" ], "expected_outcome": "Server is healthy and all dependencies connected" }, { "name": "basic_crud_flow", "description": "Create, read, update, delete a resource via API", "prerequisites": ["postgresql"], "steps": [ "POST /api/v1/resources with valid payload -> 201", "GET /api/v1/resources/:id -> 200 with matching data", "PUT /api/v1/resources/:id -> 200", "DELETE /api/v1/resources/:id -> 204" ], "expected_outcome": "CRUD operations work correctly" } ], "scripts": { "setup": "harness/scripts/setup-env.sh", "start": "harness/scripts/start-server.sh", "teardown": "harness/scripts/teardown-env.sh" } } ``` Follow `references/environment-detection-guide.md` for detection strategies. ### harness/scripts/setup-env.sh Start external dependencies (DB, Redis, etc.): ```bash #!/bin/bash set -euo pipefail # Start PostgreSQL docker run -d --name harness-postgres \ -p 127.0.0.1:5432:5432 \ -e POSTGRES_PASSWORD=testpass \ postgres:16 # Wait for ready until docker exec harness-postgres pg_isready; do sleep 1; done echo "✓ Environment ready" ``` If `docker-compose.yml` already exists, create a thin wrapper instead. ### harness/scripts/start-server.sh Start the application with test environment: ```bash #!/bin/bash set -euo pipefail export PORT=8081 export ENV=test export DATABASE_URL="postgres://postgres:testpass@localhost:5432/testdb?sslmode=disable" # Start server go run cmd/api/main.go & SERVER_PID=$! # Wait for ready for i in $(seq 1 30); do if curl -s http://localhost:$PORT/health > /dev/null 2>&1; then echo "✓ Server ready (PID: $SERVER_PID)" exit 0 fi sleep 1 done echo "✗ Server failed to start" exit 1 ``` ### harness/scripts/teardown-env.sh Stop and cleanup: ```bash #!/bin/bash docker stop harness-postgres 2>/dev/null || true docker rm harness-postgres 2>/dev/null || true echo "✓ Cleaned up" ``` ### Makefile Targets Ensure these targets exist: ```makefile .PHONY: lint-arch lint-ecl lint-encoding verify-harness build test setup-env start-server teardown-env lint-arch: ./scripts/lint-deps ./scripts/lint-quality lint-ecl: {ecl_lint_command} lint-encoding: {encoding_lint_command} verify-harness: lint-ecl lint-encoding lint-arch build: {appropriate build command} test: {appropriate test command} setup-env: ./harness/scripts/setup-env.sh start-server: ./harness/scripts/start-server.sh teardown-env: ./harness/scripts/teardown-env.sh ``` ### .github/workflows/ci.yml Basic CI that runs build, lint, and test: ```yaml name: CI on: [push, pull_request] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-{lang}@v5 with: {lang}-version: '{version}' - run: make build - run: make lint-arch - run: make test ``` CI must be strict by default. Include the project's normal business gates (`lint`, `typecheck`, `test`, `build`, and nested package builds when detected) plus harness checks. Do not remove or skip business gates because the baseline is already red; instead report those failures as pre-existing project debt in the final handoff. Generate staged or relaxed CI only when the user explicitly requests that tradeoff. For TypeScript/Node.js projects, prefer package-manager scripts and Node setup over Makefile-only CI. Use the adapter in `references/adapters/typescript.md` to detect npm/pnpm/yarn/bun and generate commands such as `npm run lint:harness`, `npm run lint:arch`, `npm run typecheck`, `npm test`, `npm run build`, and nested package build steps when present. ### Harness Directory Structure Create the default core harness directory tree: ``` harness/ ├── config/ │ └── environment.json ├── changes/ │ ├── active/ │ ├── parking/ │ ├── archive/ │ └── INDEX.json ├── evolution/ │ ├── state.json │ ├── results.tsv │ └── proposals/ ├── templates/ │ └── change/ │ ├── summary.md │ ├── spec.md │ ├── plan.md │ ├── tasks.md │ └── reviews/ │ └── review.md ├── scripts/ │ ├── setup-env.sh │ ├── start-server.sh │ └── teardown-env.sh ``` Initialize `harness/evolution/state.json`: ```json { "enabled": true, "threshold": 5, "window": 10, "last_evolved_archive_count": 0, "last_evolved_change_id": null, "last_score": null, "last_run_at": null, "pending": false } ``` Initialize `harness/evolution/results.tsv` with this header: ```tsv timestamp change_id old_score new_score status dimension note eval_mode ``` Allowed status values are `keep`, `revert`, `rejected`, and `noop`. Allowed eval modes are `independent_review`, `dry_run`, and `full_test`. Use `dry_run` when no independent auditor/subagent is available; do not auto-apply harness deltas in that mode. Do not create empty advanced directories by default. Create optional advanced directories only when the confirmed scope or user request explicitly requires that capability: ``` harness/ ├── eval/ # Agent evaluation datasets and runner inputs ├── trace/ # Agent execution traces ├── state/ # Runtime state for external executors ├── checkpoints/ # Resumable execution checkpoints ├── memory/ # Long-term agent memory experiments │ ├── episodes/ │ ├── knowledge/ │ └── procedures/ └── metrics/ # Execution, quality, and cost metrics ``` Advanced directories must come with a read/write protocol and validation command. If no protocol is defined, leave the capability out of the generated harness. ## Scripts Must Be - `chmod +x` — executable - Self-contained — no external dependencies beyond Docker - Idempotent — safe to run multiple times - With error handling — `set -euo pipefail` ## ECL Change Management Scripts Create ECL scripts for the selected command surface from `references/ecl-harness.md`. PowerShell, Bash, Node, and Python are equivalent profiles only if they implement the same commands and invariants. If the project rejects `.ps1`, do not generate PowerShell as the only entrypoint. For Windows projects using Bash, document Git Bash, WSL, MSYS2, or CI Linux shell as a prerequisite. Select the profile automatically from project evidence; ask the user only when evidence conflicts or no supported command surface is inferable. - `scripts/harness-change.{ps1|sh|mjs|py}`: implements `new`, `status`, `validate`, `park`, `resume`, `close`, `search`, `context`, and `reindex`. - `scripts/harness-evolve.{ps1|sh|mjs|py}`: implements `check`, `collect`, and `mark-complete` for default auto-evolve threshold checks. - `scripts/lint-ecl.{ps1|sh|mjs|py}`: validates active change structure, `docs/STATUS.md` presence, `plan.md`, completed validation, pending task consistency, spec clarification gates, plan review gates, task id formatting, and generated index freshness. - `scripts/lint-encoding.{ps1|sh|mjs|py}`: scans source/docs for mojibake markers and UTF-8 risks. Rules: - `INDEX.json` is derived from `parking/*/summary.md` and `archive/*/summary.md`; agents must not hand-edit it. - `park`, `close`, `resume`, and `reindex` must rebuild `INDEX.json`. - `close` and `reindex` must run `harness-evolve check`; the evolution script may create `harness/evolution/pending.md`, but it must not rewrite docs, scripts, STATUS, or change files. - Hook/CI integration may run validation, but must not automatically write docs, update `docs/STATUS.md`, or move changes. - `harness-change context` should list active change files when present; if no active change exists, it should list `harness/evolution/pending.md` before `docs/STATUS.md` when pending evolution exists. It must not print or load all archive files. - Auto-evolve is core lightweight infrastructure. It must not create `harness/eval`, `harness/trace`, `harness/state`, `harness/checkpoints`, `harness/memory`, or `harness/metrics` unless the user explicitly requested those advanced capabilities. - Wire Makefile/package scripts/CI to the selected entrypoint, for example `bash scripts/lint-ecl.sh` for Bash or `{pkg_manager} run lint:harness` for package scripts. - If the PowerShell profile is selected, detect whether `pwsh` exists before documenting or wiring commands. If `pwsh` is unavailable, use `powershell -NoProfile -ExecutionPolicy Bypass`. - Keep PowerShell profile scripts compatible with Windows PowerShell 5.1. Avoid ambiguous overloads such as `TrimStart(".\")`; use typed arguments such as `[char[]]@(".", "\")`. - Avoid non-ASCII mojibake marker literals in PowerShell templates. Use Unicode codepoints or another PowerShell 5.1-safe representation so the script still parses on legacy Windows code pages. ## Verification Config Rule `harness/config/environment.json` is the static runtime contract created by ecl-harness-engineer. Do not create `harness/config/verify.json` or `harness/config/validate.json`; task-specific verification plans are generated later by the executor/runtime from `environment.json` plus the active change context.