From fc8a369cee94ff8bf054e889f016e6de4e590421 Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Sat, 10 Oct 2026 14:27:59 +0100 Subject: [PATCH 1/3] chore(release): prepare @aictrl/cli 0.4.8 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019gASjVHuvN9AxK5WT8jzsN --- RELEASING.md | 39 +++++++++++++++++++++++++++++---------- bun.lock | 2 +- packages/cli/package.json | 2 +- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 11ee8c2..8b9908a 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -36,16 +36,35 @@ `sandbox` before `main`; verify a sandbox review persists MCP findings and a stalled stream reports a timeout rather than waiting for the job limit. -## 0.4.7 candidate - -- Output-schema review follow-ups (#134): - - schemas are bounded by bytes (64 KiB) and structure (depth 64, 10,000 nested objects), on every path; - - configuration errors lead with the reason and name the resolved path; - - every rejected attempt is reported and counted; - - `retryCount` is capped at 10 (wire values clamp; the flag rejects above 10); - - queued telemetry drains before terminal failure, and failures settle in a single terminal path. -- Provider hints (#134): the StructuredOutput tool description embeds the canonical schema (constraints that the Vertex adapter drops); the corrective turn after a prose-only finish forces StructuredOutput by name (GLM). -- Executor adoption: bump the aictrl `docker/executor/Dockerfile` pin (application #5960 follow-up). +## 0.4.8 candidate + +- **BREAKING for `--output-schema` callers (#142, closes #140):** `StructuredOutput` + takes only `{ "path": "" }`. The model writes its final result as JSON to a + file in the working directory and passes the path. The CLI validates that file with + Ajv and publishes the parsed file. Result objects passed as tool arguments are + rejected. Callers must change prompts that say "call StructuredOutput with the + result" to say "write a file and pass its path". +- Only `{ path }` reaches the provider, so provider schema conversion can no longer + drop result fields. On 0.4.7, Gemini emptied map-typed fields (#139). +- The result file must: + - resolve inside the working directory (symlinks are followed when checking, and a + post-open inode re-check also covers swap races; `O_NOFOLLOW`/`O_NONBLOCK` are + used where the platform defines them); + - be a regular file of at most 2 MiB (reads are bounded). +- Every failure is a fixed, counted `structured_output_rejected` diagnostic; EVENTS.md + lists them verbatim. The prose-only `missing` diagnostic and reminder now say + "write the final result as JSON to a file in the working directory, then call + StructuredOutput with its path". +- Evidence (#139 reproduction, 6-key map): + - 0.4.7: Gemini 3.8 Flash published `elements: {}` 7/7 (silent on 2, exit 3 on 5). + - #142 builds (POC and first PR head): Gemini 10/10 and GLM 4/4 published all 6 keys identically. + - Gemini output + reasoning tokens fell from 2.5–3.9k to 1.0–1.8k. +- Executor adoption, in one aictrl PR: + - bump the `docker/executor/Dockerfile` pin; + - update the prompts that ask for the result as tool arguments: `prompt-builder.ts` + structured paragraph, `pr-explanation-output-contract.ts`, and the `explain-change` + skill step that says to call StructuredOutput "with the contents of `$RESULT`"; + - confirm `$RESULT` lies inside the CLI's `--dir`. Publication and executor promotion are separate gates. Preparing this candidate PR does not publish npm packages or deploy an executor image. diff --git a/bun.lock b/bun.lock index 4ebe4a9..063c590 100644 --- a/bun.lock +++ b/bun.lock @@ -25,7 +25,7 @@ }, "packages/cli": { "name": "@aictrl/cli", - "version": "0.4.7", + "version": "0.4.8", "bin": { "aictrl": "./bin/aictrl", }, diff --git a/packages/cli/package.json b/packages/cli/package.json index 55d2e03..1e0df4d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "0.4.7", + "version": "0.4.8", "name": "@aictrl/cli", "description": "Headless execution engine for AI agent skills", "type": "module", From 55efa9197b082590f46105c2ec81513ae783819d Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Sat, 10 Oct 2026 14:38:51 +0100 Subject: [PATCH 2/3] docs(release): cut CHANGELOG for 0.4.8 and explain the patch bump (#143 review) - CHANGELOG: the Unreleased entries move under the releases that shipped them (0.4.8, 0.4.4, 0.4.3, 0.4.1, from `git tag --contains`) - RELEASING step 1 retitles `## Unreleased` as part of the version bump - RELEASING and CHANGELOG say why the breaking schema-mode change ships as 0.4.8: only the aictrl executor uses schema mode and it pins exact versions; caret-range consumers must update prompts before upgrading Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019gASjVHuvN9AxK5WT8jzsN --- CHANGELOG.md | 12 ++++++++++-- RELEASING.md | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d1ad4..373a46e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,32 @@ # Changelog -## Unreleased +## 0.4.8 (2026-10-10) ### Breaking changes -- **StructuredOutput publishes the validated result file** — In `--output-schema` mode the `StructuredOutput` tool now takes only `{ "path": "" }`. The model writes its final result as JSON to a file in the working directory and passes the path; the CLI follows symlinks, keeps the file inside the working directory, caps it at 2 MiB, validates it with Ajv and publishes the parsed file. Passing the result object as tool arguments is no longer accepted. Callers whose prompts say "call StructuredOutput with the result" must say to write a file and pass its path. Only `{ path }` reaches the provider, so provider schema conversion can no longer drop result fields (Gemini emptied map-typed fields, #139), and the model no longer re-emits the whole result as output tokens. Rejected files are counted corrective turns that ask the model to fix the file; their fixed diagnostics are listed in EVENTS.md. The prose-only `missing` diagnostic and reminder now read "write the final result as JSON to a file in the working directory, then call StructuredOutput with its path". (#140) +- **StructuredOutput publishes the validated result file** — In `--output-schema` mode the `StructuredOutput` tool now takes only `{ "path": "" }`. The model writes its final result as JSON to a file in the working directory and passes the path; the CLI follows symlinks, keeps the file inside the working directory, caps it at 2 MiB, validates it with Ajv and publishes the parsed file. Passing the result object as tool arguments is no longer accepted. Callers whose prompts say "call StructuredOutput with the result" must say to write a file and pass its path. Only `{ path }` reaches the provider, so provider schema conversion can no longer drop result fields (Gemini emptied map-typed fields, #139), and the model no longer re-emits the whole result as output tokens. Rejected files are counted corrective turns that ask the model to fix the file; their fixed diagnostics are listed in EVENTS.md. This ships as a patch because schema mode is used only by the aictrl executor, which pins exact versions; consumers on a caret range (`^0.4.x`) must update their schema-mode prompts to the file+path form before upgrading. The prose-only `missing` diagnostic and reminder now read "write the final result as JSON to a file in the working directory, then call StructuredOutput with its path". (#140) + +## 0.4.4 (2026-09-30) ### Fixes - **Provider error finishes fail headless execution** — Normal streams ending in `error` or `content-filter` now persist a structured provider failure, emit consistent failure events, and exit nonzero while retaining partial output and usage. Empty successful responses remain successful. (#108) +## 0.4.3 (2026-08-20) + ### Features - **GPT-5.6 Codex models** — Added OpenAI's Sol, Terra, and Luna models with API and subscription-backed reasoning effort variants, including the Codex-only `ultra` alias for Sol and Terra. - **GLM-5.3 model support** — Added the latest Z.AI Coding Plan model with its 1M-token context window and native `low`, `high`, and `max` reasoning efforts. +## 0.4.1 (2026-07-21) + ### Compatibility - **NDJSON v1 terminal reasons are an open set** — `session_error.reason` now includes `interrupted` for `SIGINT` and `terminated` for `SIGTERM`, and `code` may contain the conventional signal-derived exit code (`130` or `143`). Schema v1 consumers should treat unknown event types, fields, and enum-like string values as forward-compatible additions. +Releases 0.3.3–0.4.7 not listed here have notes on [GitHub Releases](https://github.com/aictrl-dev/cli/releases) only. + ## 0.3.2 (2026-04-11) ### Fixes diff --git a/RELEASING.md b/RELEASING.md index 8b9908a..7b2678c 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -2,7 +2,8 @@ 1. Prepare a PR against `main` with the fixes, the version bump in `packages/cli/package.json`, and the matching `packages/cli` workspace - version in `bun.lock`. Run `bun install --frozen-lockfile`. + version in `bun.lock`. Run `bun install --frozen-lockfile`. In `CHANGELOG.md`, + retitle `## Unreleased` to `## ()`. 2. Run the release regressions from `packages/cli`: ```bash @@ -44,6 +45,9 @@ Ajv and publishes the parsed file. Result objects passed as tool arguments are rejected. Callers must change prompts that say "call StructuredOutput with the result" to say "write a file and pass its path". +- **Why a patch bump (0.4.8):** schema mode is used only by the aictrl executor, + which pins exact versions. Consumers on a caret range (`^0.4.x`) must update their + schema-mode prompts to the file+path form before upgrading. - Only `{ path }` reaches the provider, so provider schema conversion can no longer drop result fields. On 0.4.7, Gemini emptied map-typed fields (#139). - The result file must: From bf3f9afce0a2434197e7a3c547c4cb47945ba4ce Mon Sep 17 00:00:00 2001 From: Bulat Yapparov Date: Sat, 10 Oct 2026 14:46:45 +0100 Subject: [PATCH 3/3] docs(changelog): note that 0.4.2 was never published (#143 review 2) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019gASjVHuvN9AxK5WT8jzsN --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 373a46e..84e778c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ - **NDJSON v1 terminal reasons are an open set** — `session_error.reason` now includes `interrupted` for `SIGINT` and `terminated` for `SIGTERM`, and `code` may contain the conventional signal-derived exit code (`130` or `143`). Schema v1 consumers should treat unknown event types, fields, and enum-like string values as forward-compatible additions. -Releases 0.3.3–0.4.7 not listed here have notes on [GitHub Releases](https://github.com/aictrl-dev/cli/releases) only. +Releases 0.3.3–0.4.7 not listed here (0.4.2 was never published) have notes on [GitHub Releases](https://github.com/aictrl-dev/cli/releases) only. ## 0.3.2 (2026-04-11)