Skip to content

release: promote dev to main (provider engines, setup contract, run-mode, AJV strict fix)#617

Merged
EivMeyer merged 263 commits into
mainfrom
dev
Jul 11, 2026
Merged

release: promote dev to main (provider engines, setup contract, run-mode, AJV strict fix)#617
EivMeyer merged 263 commits into
mainfrom
dev

Conversation

@EivMeyer

Copy link
Copy Markdown
Collaborator

Release promotion of devmain. semantic-release publishes the computed version to npm on merge.

Scope

259 commits accumulated on dev since the last promotion. Highlights:

All commits are already merged and CI-passed on dev; the merge queue re-runs CI on the rebased promotion before publish.

🤖 Generated with Claude Code

tomdps and others added 30 commits January 19, 2026 12:24
## Summary
- add state snapshot builder and publisher with durable STATE_SNAPSHOT
updates
- wire snapshotter into orchestrator start/load/resume and stop/kill
paths
- update base templates/context validation and add tests

## Testing
- npm run lint
- npm run test:all
## Summary
- document context selection, packs, state snapshot, and metrics with
Mermaid diagrams
- align contextStrategy sources to explicit latest semantics and add
STATE_SNAPSHOT for debug investigator
- update contributor example and link new docs

## Testing
- npm run lint (warnings only)
- npm run test:all
- npm run validate:templates
- npm run typecheck (pre-commit hook)
## Summary
- only apply provider override when explicitly set (CLI flag/env)
- add unit test covering provider override resolution

## Testing
- npx mocha tests/unit/cli-provider-override.test.js

Fixes #140
## Summary
- detect platform-mismatch CANNOT_VALIDATE results and retry validators
in docker isolation
- skip platform-mismatch reasons when validator runs in docker
- add platform mismatch detection tests

## Testing
- npm run lint
- npm run test

Fixes #142
)

## Summary
- Bump codex provider reasoning effort levels for better quality on
complex tasks
- level1: low → medium
- level2: medium → high  
- level3: high → xhigh

The `xhigh` reasoning effort allows the model to think longer for better
answers on complex tasks.

## Test plan
- [x] Existing tests pass (reasoning effort validation allows all four
values)
- [ ] Manual test with `zeroshot run --provider codex` to verify xhigh
is passed correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- fail fast on Windows in preflight with clear guidance
- document Windows deferral rationale in README

## Testing
- npm run typecheck
- npm run validate:templates
- npm run lint (warnings only)
## Summary\n- load persisted clusters before CLI resume fallback to
task\n- add unit test to guard resume loading\n\n## Testing\n- npx mocha
tests/unit/cli-resume-loads-clusters.test.js\n\nFixes #103
## Summary\n- detect "No messages returned" from Claude CLI in task
watchers, terminate the child, and mark the task failed\n- surface the
error in agent error context and grant a one-time retry for this
transient failure\n- add unit coverage for fatal error detection\n\n##
Testing\n- `npx mocha tests/unit/claude-fatal-error-detection.test.js`
(failed: mocha picked up the full suite due to .mocharc; failures
include missing better-sqlite3 and existing test failures in this
environment)
Adds PRD and multi-stage implementation plan for the Ink-based Zeroshot
TUI replacement.

Docs:
- docs/tui-v2/PRD.md
- docs/tui-v2/IMPLEMENTATION_PLAN.md
## Summary\n- log detailed diagnostics when Claude CLI returns "No
messages returned"\n- include latest Claude debug file path + tail,
status output tail, and task metadata\n\n## Testing\n- pre-commit hooks
(eslint/prettier, typecheck, template validation)\n- pre-push lint +
typecheck
…160)

## Summary

The `validator-requirements` agent was crashing with
`error_max_structured_output_retries` because its JSON schema was too
complex for Claude CLI's `--json-schema` structured output feature.

**Root cause:** The nested `criteriaResults` array (objects with nested
`evidence` object and enum constraints) was too hard for the model to
produce reliably. After 5 internal retries, the CLI threw the error.

**Fix:** Make `criteriaResults` optional (removed from `required` array)
in both:
- `full-workflow.json`
- `quick-validation.json`

This means:
- `approved` and `summary` are still required (model produces these
correctly)
- `criteriaResults` becomes best-effort (produced when model can,
gracefully omitted when not)
- Downstream consumers already handle missing/partial `criteriaResults`

Fixes #159

## Test plan
- [x] Validated templates pass (`npm run validate:templates`)
- [ ] Re-run a STANDARD task to verify validator-requirements completes
without crashing

---
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- Provider-level retryable error detection (Anthropic, OpenAI, Google)
- Orchestrator robustness improvements with proper error propagation
- Agent lifecycle improvements with better state management
- TUI renderer enhancements for error visibility
- Settings handling improvements

## Test plan
- [x] Unit tests for provider retryable errors
- [x] Orchestrator tests for error scenarios

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- avoid treating "Task not found"/"Process terminated" substrings inside
JSON logs as fatal
- only treat standalone fatal lines as no-output
- add output-extraction unit tests for fatal-string handling

## Testing
- npm test

Fixes #165
## Summary

- Replace `src/tui/` blessed implementation with minimal Ink TSX app
- Add `tsconfig.tui.json` for TUI-specific TypeScript compilation
- Add `build:tui` script to package.json, run in prepublishOnly
- Repoint `zeroshot watch` to `lib/tui` compiled entrypoint
- Remove blessed dashboard tests (tui-layout.test.js)
- Update AGENTS.md with Ink TUI entrypoint documentation

## Changes

The new TUI renders "Hello Ink TUI" and exits on keypress (or auto-exits
after delay). This is the foundation for the TUI v2 implementation per
PRD.

**Files added:**
- `src/tui/index.tsx` - Minimal Ink entrypoint with `start(options)`
export
- `tsconfig.tui.json` - TypeScript config targeting `lib/tui/`

**Files modified:**
- `package.json` - Added ink, react deps and build:tui script
- `cli/index.js` - `zeroshot watch` now uses `lib/tui`
- `AGENTS.md` - Updated docs
- `.gitignore` - Added `lib/tui/`

**Files removed:**
- All old blessed TUI files under `src/tui/`
- `tests/tui-layout.test.js`

## Validation

Both validators approved:
- ✅ `npm run build:tui` produces `lib/tui/index.js`
- ✅ Ink entrypoint runs and exits cleanly
- ✅ `zeroshot watch` points to compiled Ink entrypoint
- ✅ Package tarball includes `lib/tui/`
- ✅ No blessed code remains in `src/tui/`

Closes #172
Fixes #176.

- relax git-pusher evidence gating to allow CANNOT_VALIDATE/empty
outputs
- add regression test for trigger evaluation
## Summary
- Fix maxRetries to use settings.maxRetries ?? 3 (was ?? 1 - NO
RETRIES!)
- Add rate-limit-aware backoff (30s base for 429s vs 2s for others)
- Add Gemini "No capacity available" to retryable patterns

## Problem
Both `falling-totem-77` and `mystic-vertex-66` failed because
`agent-lifecycle.js:738` had `maxRetries ?? 1` which meant **no actual
retries**.

## Test plan
- [x] Unit tests for rate-limit-backoff module
- [x] Manual verification: `node -e` script confirmed detection works
- [ ] Resume failed clusters after merge

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Fixes eslint errors from generated TUI output by disabling rules for
lib/tui in eslint config.
Closes #183

---------

Co-authored-by: Eivind Meyer <eiv.meyer@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eivind Meyer <eivind.meyer@ksat.no>
Co-authored-by: Michael Eichelbeck <141341133+mkceichelbeck@users.noreply.github.com>
Co-authored-by: Michael Eichelbeck <michael.eichelbeck.ext@wtsde.onmicrosoft.de>
## Summary
- add typed command registry + dispatch wiring for TUI slash commands
- add CLI compatibility helpers for list/status output
- add tests for registry and dispatcher updates

## Testing
- npm test (via pre-commit)
- npm run lint (warnings only)

Fixes #185
## Summary
- add reusable start-cluster helper for TUI (text/issue/file)
- add TUI service wrapper for starting clusters
- add unit tests for helper

## Testing
- npm test (via pre-commit)
- npm run lint (warnings only)

Fixes #187
## Summary
- wire Launcher submit to start cluster from text
- treat numeric input as plain text
- optimistic cluster id + navigate to Cluster view
- tests for launcher behavior

## Testing
- npm test (via pre-commit)
- npm run lint (warnings only)

Fixes #189
## Summary
- implement /issue command to launch an issue cluster and move to
Cluster view
- add issue launch wiring + deps in dispatcher/context
- add cluster launch helper and tests

## Testing
- not run (eslint reports pre-existing issues in repo)
EivMeyer and others added 17 commits July 9, 2026 02:55
)

## What

Finishes the `RunPlan` consolidation started in #588. That change made
the plan own **delivery/autoMerge**, but left the **isolation** axis
half-done:

- `lib/start-cluster.js` still had its own
`resolveIsolation(mergedOptions, settings)` deciding Docker vs worktree
independently (and it, not the plan, knew about
`settings.defaultDocker`).
- The plan's `isolation` field was computed but **consumed nowhere** — a
decorative field while a competing resolver owned the real logic. That's
the exact "two parallel representations that can drift" defect #582
targeted, still live on the isolation axis.

## Changes

- Fold `resolveIsolation` (env + `settings.defaultDocker`) into a single
`resolveEffectiveRunPlan`; **delete the duplicate**.
- `buildStartOptions` now derives **every** mode field from that one
plan:
  - `isolation = plan.isolation === 'docker'`
- `worktree = plan.isolation === 'worktree'` (mutually exclusive by
construction)
  - `autoPr = plan.delivery !== 'none'`, `autoMerge = plan.autoMerge`
- `runMode = runModeFromPlan(plan)` — the label reflects the **same
effective plan** (settings included), not the raw flags.
- `lib/run-mode.js`: extract `runModeFromPlan` so a label can be
produced from an already-resolved plan.

`resolveIsolation` now exists in **exactly one place**
(`lib/run-plan.js`). `plan.isolation` is now genuinely consumed.

## Behavior

**No change** to `--pr` / `--ship` / `--worktree` / `--docker` /
`settings.defaultDocker`. Shape fix; guarded by tests.

## Tests

- New in `tests/unit/start-cluster-config.test.js`:
`settings.defaultDocker` flows through the plan (isolation without a CLI
flag), isolation/worktree mutual exclusion, label matches the effective
plan.
- `427 passing` in `tests/unit`; `eslint` 0 errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Record the current `main`/`v6.3.0` commit as ancestry of `dev` before
promoting `dev` back to `main`.

This is an ancestry-only merge:
- tree is identical to `origin/dev`
- no source files change
- unblocks the `dev` → `main` release PR without altering the release
payload

Verification:
- `git diff --exit-code origin/dev HEAD`

Co-authored-by: Tom Dupuis <60640908+tomdps@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eivind Meyer <eivind.meyer@ksat.no>
Co-authored-by: Michael Eichelbeck <141341133+mkceichelbeck@users.noreply.github.com>
Co-authored-by: Michael Eichelbeck <michael.eichelbeck.ext@wtsde.onmicrosoft.de>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-38-53.eu-north-1.compute.internal>
Co-authored-by: Eivind <eivind@covibes.ai>
Co-authored-by: CI Test <ci-test@covibes.ai>
Co-authored-by: Codex <codex@example.com>
Co-authored-by: Atharv Singh <132380045+atharvwasthere@users.noreply.github.com>
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Zeroshot Agent <agent@covibes.ai>
…elease-conflicts

chore(release): preserve v6.3.0 ancestry for dev promotion
Fixes #530.\n\n## Summary\n- detect opencode --dir support as
supportsDir\n- prefer --dir <cwd> over --cwd <cwd> so worktree runs stay
rooted in the isolated worktree\n- keep --cwd fallback for older
opencode CLIs\n\n## Verification\n- npm run build:agent-cli-provider\n-
npx mocha tests/provider-cli-builder.test.js\n- node --test
tests/agent-cli-provider/parity.test.js
tests/agent-cli-provider/executable-contract-option-validation.test.js\n-
npm run typecheck:agent-cli-provider\n- npx eslint
src/agent-cli-provider/adapters/opencode.ts
src/agent-cli-provider/contract-options.ts
src/agent-cli-provider/types.ts tests/agent-cli-provider/parity.test.js
tests/agent-cli-provider/executable-contract-option-validation.test.js
tests/provider-cli-builder.test.js\n- git push pre-push hook: npm run
lint (0 errors, existing warnings) and tsc --noEmit

Co-authored-by: Zeroshot Agent <agent@covibes.ai>
Closes #593

## Summary
- Add a provider-engine registry as the owning source for provider ids,
aliases, metadata, commands, Docker/auth/install data, and adapter
factories.
- Refactor provider names, runtime facade, settings/defaults, preflight,
provider CLI output, Docker presets, first-run messaging, and helper
contract errors to consume registry data.
- Add parity and architecture tests covering provider list drift, setup
output, Docker presets, parser instantiation, CLI TUI entrypoints, and
invalid-provider fail-closed behavior.

## Verification
- npm run check:agent-cli-provider
- node --test tests/agent-cli-provider/architecture.test.js
- npx eslint cli/index.js tests/agent-cli-provider/architecture.test.js
tests/agent-cli-provider/parity.test.js
tests/agent-cli-provider/providers-command-parity.test.js
tests/first-run.test.js
- push hook: npm run lint (warnings only) and npm run typecheck

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
## Summary
- add the registry-backed Pi provider adapter with JSON-mode args,
disabled discovery/session controls, conservative capabilities, and
help/version probing
- normalize Pi JSONL text/tool/result events and classify in-band
failure result events
- add Pi fixtures and provider-helper/preflight/parity regressions

## Verification
- npm run build:agent-cli-provider
- npm run typecheck:agent-cli-provider
- npm run test:agent-cli-provider
- npm run check:agent-cli-provider
- npx mocha tests/preflight.test.js
tests/unit/cli-invalid-command.test.js --timeout 120000

Closes #595

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Closes #594

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
…er/local models (#602)

Closes #596

---------

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
## Summary
Adds **GitHub Copilot** as a registry-backed provider engine
(`copilot`), modeled on the Pi provider: adapter + JSONL parser +
registry/type/contract wiring.

The parser is grounded in the **real** `copilot --output-format json`
schema (verified against CLI v1.0.69): dot-namespaced events with
payload under `data`, `phase:"commentary"` → thinking / `final_answer` →
text, and success derived from the terminal `exitCode`. Fail-open on
unknown event types.

Also makes two capabilities genuinely functional (verified, not
assumed):
- **thinkingMode** — commentary narration is surfaced as thinking, the
final answer as text.
- **dockerIsolation** — `--docker` now auto-activates the *running*
provider's credential preset (mount + env passthrough) in
`isolation-manager.js`, so `COPILOT_GITHUB_TOKEN` reaches the container
with no `dockerMounts` change (also auto-mounts codex/gemini/opencode/pi
creds; claude stays special-cased). A keychain-token provider with no
token warns loudly instead of failing silently.

## Verification
- `npm run check:agent-cli-provider` 100/100; full unit suite green;
adapter + docker preset/warning unit tests.
- Real-schema parser verified by replaying captured copilot output.
- A real `zeroshot run --provider copilot` cluster ran end-to-end
(parsed streamed JSONL, wrote the expected file, fired completion).
- Offline `fake-copilot` e2e (`tests/e2e/copilot-provider.test.js`) as
the committed regression.

## Follow-up (not blocking)
- No live `--docker` container round-trip was run (no image built
locally; keychain token extraction is interactive). Docker is verified
at the unit + direct-token-auth + mechanism level — a single live
container smoke test would fully close it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- add an explicit opt-in live provider smoke runner for real installed
CLIs/gateway endpoints
- document how to run Pi, Copilot, and gateway live smoke checks
- keep normal CI deterministic/offline while making paid/authenticated
provider checks available before release

## Verification
- node scripts/live-provider-smoke.js exits with usage when
ZEROSHOT_LIVE_PROVIDERS is missing
- PATH=<fake-copilot> ZEROSHOT_LIVE_PROVIDERS=copilot npm run
test:providers:live
- npx eslint scripts/live-provider-smoke.js
- npm run check:agent-cli-provider:ci
- npm run test:e2e -- --grep 'copilot provider'

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
## Summary
- trust noninteractive Gemini workspaces by setting
`GEMINI_CLI_TRUST_WORKSPACE=true`
- classify Gemini unsupported-client / `IneligibleTierError` failures as
permanent instead of retryable
- include provider error classification in live smoke summaries

## Live smoke evidence
- `claude` live smoke passed
- `codex` live smoke passed
- `opencode` live smoke passed
- `gemini` live smoke now fails as permanent `IneligibleTierError` due
external account/client eligibility, not workspace trust or a retryable
Zeroshot error
- `pi`, `copilot`, and `kiro` were attempted but the CLIs are not
installed on this machine
- `gateway` was attempted but gateway env vars are not configured here

## Verification
- `npm run build:agent-cli-provider && npx mocha
tests/provider-cli-builder.test.js --grep 'Gemini provider helper
builder' --timeout 120000`\n- `npm run build:agent-cli-provider && node
--test tests/agent-cli-provider/executable-contract-output.test.js`\n-
`npm run check:agent-cli-provider:ci`\n- `ZEROSHOT_LIVE_PROVIDERS=claude
npm run test:providers:live`\n- `ZEROSHOT_LIVE_PROVIDERS=codex npm run
test:providers:live`\n- `ZEROSHOT_LIVE_PROVIDERS=opencode npm run
test:providers:live`\n- `ZEROSHOT_LIVE_PROVIDERS=gemini npm run
test:providers:live` expected external failure: permanent
`IneligibleTierError`\n

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
## Summary
- add a manual/opt-in scheduled `Live Provider Smoke` workflow for real
provider CLI/gateway checks
- let `ZEROSHOT_LIVE_PROVIDERS=all` expand from the provider registry
- document release-gate provider smoke usage, required secrets, and
self-hosted-runner requirements

## Why
The normal CI suite proves the provider contract with fixtures and fake
providers. It does not prove real installed CLIs or gateway credentials
work. This workflow creates an explicit live gate: selected providers
fail if their CLI or credential is missing.

## Verification
- `npx prettier --check .github/workflows/live-provider-smoke.yml
docs/providers.md scripts/live-provider-smoke.js`
- registry matrix parse check for `all` -> all provider ids
- `npm run check:agent-cli-provider:ci`
- `ruby -e 'require "yaml";
YAML.load_file(".github/workflows/live-provider-smoke.yml"); puts "yaml
ok"'`\n\n## Notes\nThis does not claim every provider has now passed
live smoke. It adds the release gate needed to run those tests with real
secrets/runners. Earlier local live smoke passed for Claude, Codex, and
Opencode; Gemini reached a real permanent account/client eligibility
failure; Pi, Copilot, Kiro, and Gateway still require installed CLIs
and/or configured credentials/endpoints.\n

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
…ntract schema (1/5) (#612)

Closes #605

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
…undo conflict rules (2/5) (#613)

Closes #606

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
## Summary
- align source package metadata with the published 6.4.0 package
- add semantic-release changelog/git prepare steps so future release
tags include bumped package metadata

## Verification
- node -p "require('./package.json').version + ' ' +
require('./package-lock.json').version + ' ' +
require('./package-lock.json').packages[''].version"
- npx mocha tests/package-smoke.test.js --timeout 30000
- npm run typecheck
- npx semantic-release --dry-run (loads new plugins; stops locally on
missing NPM_TOKEN/GITHUB_TOKEN, expected outside CI)

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
…ts them (#616)

Fixes #614.

## Problem

The injected validator quality-gate schema declared
`completedAt`/`timestamp` as union `type: ['string', 'number']` arrays.
Strict-mode AJV consumers reject union `type` arrays:

```
strict mode: use allowUnionTypes to allow union type keyword
  at "#/properties/qualityGates/items/properties/completedAt" (strictTypes)
```

That threw during validator output validation before the validator's
output could be checked, marking the task failed and burning validator
retries until ship runs failed. Observed live killing an opcore ship run
in validation.

## Fix

Replace the union `type` arrays with `anyOf`, which strict mode accepts
with no `allowUnionTypes` flag and keeps the string|number constraint.
Instance-agnostic: works regardless of which AJV consumer compiles the
schema.

```js
completedAt: { anyOf: [{ type: 'string' }, { type: 'number' }], ... }
timestamp:   { anyOf: [{ type: 'string' }, { type: 'number' }], ... }
```

## Why tests didn't catch it

The prior tests only asserted whether the schema was *injected*, never
that it *compiles* under a strict AJV. And AJV's default `new Ajv()`
only **logs** `strictTypes` (it does not throw), so a naive compile test
would pass on the buggy schema too — that is the exact gap that let this
ship.

New `tests/quality-gate-schema.test.js` compiles under `{ strict: true
}` (which throws on the union shape) and includes a guard test proving
that config actually discriminates the bug, plus string/numeric
acceptance and a wrong-type rejection. Verified: the real schema
reverted to unions throws the exact `strictTypes` error; the `anyOf`
version passes all 5.

## Test

- `node tests/run-tests.js tests/quality-gate-schema.test.js` → 5
passing
- `node tests/run-tests.js tests/required-quality-gates-context.test.js`
→ 3 passing (no regression)
- `tsc --noEmit` clean (pre-push)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
EivMeyer and others added 4 commits July 10, 2026 01:15
Restores `main` ancestry into `dev` so the `dev → main` release (#617)
can merge cleanly. `main` had one divergent commit — `ac354df` (#591,
deterministic e2e + run-plan hardening) — that overlapped the same
run-plan refactor developed on `dev` (#588/#590).

## Conflicts resolved (2 files)

- `lib/start-cluster.js` — kept dev's `settings.defaultDelivery` pr/ship
resolution in `resolveEffectiveRunPlan` (feature from #606/#580; main's
older squash lacked it).
- `tests/unit/start-cluster-config.test.js` — kept dev's
`defaultDelivery` describe block and preserved main's net-new
`buildStartOptions() isolation` block.

Everything else auto-merged.

## Verification

- `node tests/run-tests.js tests/unit/start-cluster-config.test.js` → 17
passing (both branches' test blocks present and green)
- `git diff --check` clean, no residual conflict markers
- `tsc --noEmit` clean

Merge this, then #617 (dev → main) merges clean and semantic-release
publishes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eivind Meyer <eivind.meyer@ksat.no>
Co-authored-by: Michael Eichelbeck <141341133+mkceichelbeck@users.noreply.github.com>
Co-authored-by: tomdps <tom.dupuis24@gmail.com>
Co-authored-by: tomdps <60640908+tomdps@users.noreply.github.com>
Co-authored-by: Michael Eichelbeck <michael.eichelbeck.ext@wtsde.onmicrosoft.de>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-38-53.eu-north-1.compute.internal>
Co-authored-by: Eivind <eivind@covibes.ai>
Co-authored-by: CI Test <ci-test@covibes.ai>
Co-authored-by: Codex <codex@example.com>
Co-authored-by: Atharv Singh <132380045+atharvwasthere@users.noreply.github.com>
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Zeroshot Agent <agent@covibes.ai>
## Summary
- records current main as a true parent of dev so the dev -> main
release PR can merge cleanly
- no tree changes versus current dev; this preserves the conflict
resolutions already present on dev from #618

## Verification
- git merge-tree --write-tree origin/main HEAD -> clean locally after
the merge commit
- node tests/run-tests.js tests/unit/start-cluster-config.test.js
- npm run typecheck

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Eivind Meyer <eivind.meyer@ksat.no>
Co-authored-by: Michael Eichelbeck <141341133+mkceichelbeck@users.noreply.github.com>
Co-authored-by: tomdps <tom.dupuis24@gmail.com>
Co-authored-by: tomdps <60640908+tomdps@users.noreply.github.com>
Co-authored-by: Michael Eichelbeck <michael.eichelbeck.ext@wtsde.onmicrosoft.de>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-38-53.eu-north-1.compute.internal>
Co-authored-by: Eivind <eivind@covibes.ai>
Co-authored-by: CI Test <ci-test@covibes.ai>
Co-authored-by: Codex <codex@example.com>
Co-authored-by: Atharv Singh <132380045+atharvwasthere@users.noreply.github.com>
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Zeroshot Agent <agent@covibes.ai>
…se-image build fixes) (#622)

## Summary

Four related changes for the Copilot provider and Docker isolation mode:

1. **Copilot MCP support** — the copilot adapter now emits
`--additional-mcp-config`, so MCP servers configured for a run reach
Copilot.
2. **Cached per-provider Docker install** — the running provider's CLI
is installed into a per-provider image variant as a Docker-cached layer,
so `--docker --provider <p>` actually has the provider CLI available.
3. **ca-certificates regression guard** — a unit test that keeps the
cluster image buildable for Copilot's auth.
4. **Two pre-existing build-blocking fixes** — the base image could not
be built at all before this; both are fixed here so Docker mode works
end-to-end.

## Details

### 1. Copilot MCP (`--additional-mcp-config`)
- New validated `mcpConfig` field on `BuildProviderCommandOptions`
(array of JSON strings / `@file`), normalized in `contract-options`.
- `copilot.ts` emits one `--additional-mcp-config` per entry, gated on
feature detection (`supportsMcpConfig` from `--additional-mcp-config` in
help), with a warning when unsupported.
- Threaded end-to-end via **two** paths: (a) CLI `--mcp-config` → runner
→ adapter; (b) orchestrator agent spawn reads the repo
`.claude/.mcp.json` (the same source Claude uses), **inlines** it (so
the value survives host→container translation), and forwards it.
Registry flips copilot `mcpServers: true`.
- Copilot consumes MCP only from its own config locations, not the
worktree overlay, so the CLI-flag approach is the correct fit (unlike
Claude's `.mcp.json` convention).

### 2. Cached per-provider Docker install
- Docker mode previously baked **only** the Claude CLI into
`zeroshot-cluster-base`; copilot/codex/gemini were never installed, so
`--docker --provider <p>` failed with "command not found".
- Now: a per-provider image variant `zeroshot-cluster-base-<provider>` =
base + a single `RUN <install>` layer, driven by a new **registry**
field `docker.install` (no hardcoded provider names in logic). Claude
stays baked (variant = base); installer-less providers fall back to the
base image.
- `IsolationManager.imageForProvider` / `providerBuildArgs` resolve the
image + `--build-arg`; threaded through
`orchestrator._initializeIsolation` and validator isolation, and
**persisted for resume** (the resolved variant, not the base, is stored
in `cluster.isolation.image`).
- The `ARG PROVIDER_INSTALL` sits after all heavy layers, so the base
layers stay shared/Docker-cached across variants — building a second
provider variant reuses the whole base and only runs its install layer
(~70s vs a full build).

### 3. ca-certificates guard
- Copilot's Rust HTTP client uses the **system** CA store (Node bundles
its own, so `fetch` works but copilot doesn't). On the `node:20-slim`
base, a missing `ca-certificates` makes auth fail with a cryptic
`network fetch failed: builder error`. A unit test keeps the Dockerfile
line from being silently dropped.

### 4. Pre-existing build-blocking fixes
- `RUN npm install -g npm@latest` now pulls npm 12, which requires node
≥22 and fails `EBADENGINE` on `node:20-slim` → pinned to `npm@11`.
- `buildImage` inherited `runSync`'s 30s default timeout, killing every
heavy image build with `ETIMEDOUT` → `timeout: 0` for the build
subprocess.

## Testing
- `check:agent-cli-provider:ci` 127/127 · new unit tests (image
selection + ca-certs guard) 13/13 · `test:e2e` 7/7 (incl. asserting the
exact inlined `--additional-mcp-config` argv) · `copilot-mcp-docker`
integration 1/1 · full unit suite 1490 passing (4 failing are
pre-existing node-pty/better-sqlite3 environment issues).
- Real image builds verified: `zeroshot-cluster-base` (claude),
`-copilot` (copilot 1.0.70), `-codex` (codex 0.144.1); base-layer
caching confirmed.
- Live: copilot in the real image authenticates via
`COPILOT_GITHUB_TOKEN` and completes the MCP handshake through
`--additional-mcp-config` (the model turn itself was gated by an
exhausted Copilot quota, not code).
- Regression: claude still uses the unchanged base image; codex docker
was previously broken (not installed) and is now fixed; `claude -p` /
`codex exec` work non-docker.

## Reviewer notes (minor, non-blocking follow-ups)
- Validators use `DEFAULT_VALIDATOR_IMAGE`, so a custom `--docker-image`
would diverge between main container and validators (pre-existing —
validators already ignored `--docker-image`).
- `buildImage` always builds from the repo Dockerfile regardless of tag
(pre-existing).
- `timeout: 0` removes the build ceiling entirely (deliberate, to avoid
re-introducing the killed-slow-build bug).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- moves defaultDelivery application out of the release-conflicting
buildStartOptions hunk and into the production start path
- moves defaultDelivery regression coverage into a separate test file
- keeps behavior: defaultDelivery=ship still produces worktree +
autoMerge on start

## Verification
- node tests/run-tests.js tests/unit/start-cluster-config.test.js
tests/unit/start-cluster-default-delivery.test.js
tests/unit/setup-apply.test.js
- npm run typecheck
- git merge-tree --write-tree origin/main HEAD -> merge_tree_status=0

Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Comment thread lib/setup-journal.js
}
node = node[key];
}
node[keys[keys.length - 1]] = value;
@EivMeyer
EivMeyer added this pull request to the merge queue Jul 11, 2026
Merged via the queue into main with commit c242575 Jul 11, 2026
15 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 6.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

AtulWanve pushed a commit to AtulWanve/zeroshot that referenced this pull request Jul 12, 2026
…engine#625)

Release promotion of `dev` -> `main` after the-open-engine#624.

## Why this second promotion is needed

The previous promotion (the-open-engine#617) merged cleanly and CI/release passed, but
semantic-release did not publish because the squash commit type was
`release:` and the analyzer had no rule for that type.

the-open-engine#624 adds an explicit semantic-release rule mapping `release:` promotion
commits to a minor release. This promotion carries that rule to `main`;
the release workflow should then analyze this `release:` commit and
publish the next minor.

## Diff

- `.releaserc.json`: `release:` commits => minor release

## Verification

- the-open-engine#624 PR CI passed
- the-open-engine#624 merge-queue CI passed
- local analyzer probe: `release: promote dev to main` => `minor`
- `origin/main..origin/dev` diff is only `.releaserc.json`

---------

Co-authored-by: tomdps <60640908+tomdps@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: tomdps <tom.dupuis24@gmail.com>
Co-authored-by: Eivind Meyer <eivind.meyer@ksat.no>
Co-authored-by: Michael Eichelbeck <141341133+mkceichelbeck@users.noreply.github.com>
Co-authored-by: Michael Eichelbeck <michael.eichelbeck.ext@wtsde.onmicrosoft.de>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-38-53.eu-north-1.compute.internal>
Co-authored-by: Eivind <eivind@covibes.ai>
Co-authored-by: CI Test <ci-test@covibes.ai>
Co-authored-by: Codex <codex@example.com>
Co-authored-by: Atharv Singh <132380045+atharvwasthere@users.noreply.github.com>
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
Co-authored-by: Eivind <eivindcovibes.ai@Eivinds-MacBook-Pro.local>
Co-authored-by: Zeroshot Agent <agent@covibes.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validator runs fail: quality-gate schema uses union type arrays that AJV strict mode rejects (strictTypes/allowUnionTypes)

6 participants