Packages

Elixir/OTP runtime for supervised coding-agent sessions with ACP, Subagents, Workflows, and replayable evidence.

Current section

Files

Jump to
pixir CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to Pixir are recorded here. Issue and PR references
(`#N`) point to the private development repository; this public mirror
carries curated history, so those references may not resolve here. Pixir is a developer preview;
the CLI/ACP runtime is the public surface, and there is no stable Elixir library
API yet. Versions follow [Semantic Versioning](https://semver.org/) with the
caveat that pre-1.0 minor versions may still change behavior.
## [Unreleased]
## [0.1.8]
### Added
- **Anthropic (Claude) as a second provider**, built evidence-first behind the
existing provider seam (epic #243, design in ADR 0037):
- Messages API transport core with streaming SSE and a fail-closed error
taxonomy (#249).
- `pa1` prompt contract: a frozen, cache-maximal prefix with a deliberate
`cache_control` breakpoint planner (#254). The planner is unit-tested but
not yet wired into the live request path — the integration is tracked in
#272, found by this release's audit.
- Provider-owned usage as durable evidence: an explicit cache map
(`usage_summary.cache` with `creation_tokens` / `read_tokens`) on
`provider_usage` events, `pa1` family identity stamped alongside, costs
reconciled from Logs rather than estimates (#258).
- Thinking replay: reasoning events are dialect-labeled at record time and
re-injected verbatim next to their `tool_use` blocks on the next turn,
guarded by model identity so a dialect never replays into the wrong
provider (#262).
- Tool-use mapping: Pixir tools project to Anthropic `tools` specs and the
session history folds to Messages with correctly grouped `tool_result`
blocks (#261).
- Provider registry: `claude-*` model ids route to the Anthropic provider,
auth checks are provider-scoped, and `pixir doctor` reports honestly per
provider — `ANTHROPIC_API_KEY` guidance and data-retention notes only where
they apply (#265).
- Threaded the opt-in hosted `web_search` knob through effective config, CLI parsing,
Turn request assembly, delegate validation, spawn-agent stripping, and Anthropic
fail-closed rejection so Provider-hosted search remains default-off and explicit
(#255).
- Delegate/CLI attachments channel (#250, ADR 0021): a `tasks[]` entry may be an
object `{"task": ..., "attachments": [...]}` and one-shot/resume take a
repeatable `--attach <path>`; each local path becomes a durable Session
Resource in the child, dry-run plans confess a per-child `attachment_count`,
unknown task-object keys reject fail-closed, and the model-facing
`spawn_agent` tool strips caller-authored attachments (operator knob, not a
model capability).
- Workflow steps accept per-step `model`, `reasoning_effort`, and `attachments`
(#270): validated at plan time, threaded through the runtime-owned opts
channel only, and reported honestly in plans (`attachment_count`, omission
over null); `virtual_overlay` steps reject the knobs, and the model-facing
`run_workflow` tool strips them from step objects so a workflow-spawning
model cannot smuggle provider knobs to children.
### Fixed
- Provider `output_items` order is preserved through Turn recording (ADR 0007):
interleaved reasoning/message/tool items no longer regroup by type (#246).
- Workflow dry-run now validates the DAG through the runner's own path (#263):
cycles, unknown dependencies, and duplicate step ids are rejected identically
in attached, async, and dry-run modes — rehearsal parity by construction, not
by a second copy of the rules.
- Subagent identity is runtime-owned (#234): child ids are always generated and
task-position `index` arrives via the runtime opts channel, so caller-authored
`id`/`index` args are ignored and can no longer influence workspace paths or
forge position evidence in durable logs.
- Attachment URI handling is centralized and hardened (ADR 0021): case-variant
`FILE://` schemes normalize, `file:` without `//` and URIs carrying query or
fragment parts are rejected with specific reasons, and paths percent-encode
correctly on the way in.
## [0.1.7]
### Added
- Delegate subagent children now carry durable `children[].index` task-position
evidence across attached envelopes, async snapshots, tree projection, and retry
lineage (#227). The delegate envelope `schema_version` is now `2` to signal the
additive `children[].index` / `children_order` keys; the
`pixir.delegate.envelope.v1` family name is unchanged (reserved for breaking
shape changes).
- Delegate specs are validated fail-closed (#223): unknown top-level or
`subagents` keys are rejected as structured `invalid_spec` with `field`,
`json_pointer`, `path`, and `next_actions`, in dry-run and real runs alike,
so a typo can no longer pass the rehearsal silently.
- New delegate spec provider knobs mirroring ACP `session/prompt` `_meta`
(#223): `subagents.model` and `subagents.reasoning_effort`
(`low|medium|high|xhigh`) thread to every child's provider calls with
spec > config > default resolution; effective values are evidenced by child
`provider_usage` events, not echoed in the envelope. The model-facing
`spawn_agent` tool strips caller-authored `model`/`reasoning_effort` args:
provider knobs are operator decisions, not a capability a spawning model
grants its children.
### Fixed
- Delegate `--dry-run` now mirrors the runner's task normalization exactly:
malformed or blank `tasks[]` entries are rejected as `invalid_spec` instead of
silently planned, and a list-valued `tasks` field owns validation (even when
empty) before any legacy `task` fallback, matching real-run branch precedence.
- The model-facing `spawn_agent` tool strips caller-authored `index` args so
task-position evidence in durable `subagent_event` data cannot be forged.
- Workspace confinement no longer misreads leading POSIX environment
assignments as path arguments (#188): `TMPDIR=/tmp mix test` and
`PREFIX=/usr/local ./configure` pass, while literal outside paths,
redirection targets, and non-leading `NAME=VALUE` arguments keep failing
closed; the window resets after `;`, `&&`, `||`, and `|`. The residual
runtime-expansion vector (`VAR=/outside cmd $VAR`) is documented in
SECURITY.md: confinement is a defense-in-depth tripwire, not a sandbox.
## [0.1.6]
### Added
- Published the proc-pressure kernel-pressure evidence bundle (23 files,
gate-hardened) at `docs/benchmarks/scale/`, and the matching /scale
kernel-tax section: marginal threads/processes/RSS/kernel-CPU/involuntary
context switches per additional worker under two labeled machine
conditions, per-provider-call normalization from durable usage evidence,
the spawn-tax microbench, and the completion audits with the negative
result (199/205 loaded) published as the headline. The /scale hero line
and the N=8 transport-table cause cell were corrected to claims the
published bundles can back.
### Fixed
- `pixir delegate --help` (and the main help) now document `--timeout-ms` on
the attached form; the flag was always accepted there but only listed under
`delegate start`, so contract-of-record readers concluded it was invalid
(#204).
### Added
- Subagents-strategy delegate result envelopes now give every non-completed
child the same ready-made recovery commands the one-shot contract ships:
conditional `children[].resume_command` and `children[].diagnose_command`,
including children reported `running` at the collection horizon (their
writer lease fails closed if anything is genuinely alive). Start/lifecycle
snapshots stay terminal-only, and workflow-strategy children keep their
step-based evidence without these commands. Without `--json`, per-child
resume hints print on stderr, matching the one-shot mode contract (#204).
### Changed
- A `bash` call denied because the bounded write policy disables the shell now
surfaces as `kind: "bash_disabled"` ("shell is disabled by the bounded write
policy") instead of the misleading `write_policy_denied` ("write denied"),
with shell-free `next_actions` (`use_native_read_tools`,
`use_edit_or_write_within_allowed_globs`). The denial keeps exit code 3 but
is no longer terminal for the child's Turn: the model can adapt with native
tools instead of dying on a read-only command. Write-allowlist denials keep
`write_policy_denied` and remain terminal (#218).
### Added
- Delegate spec transport knob: `subagents.transport` (or top-level
`transport`) accepts `auto` | `websocket` | `http_sse`; invalid values fail
`--dry-run` with a structured error and the effective value is surfaced as
`limits.transport` (#205).
- Manager-level bounded auto-retry for read-only subagent children killed by
mid-stream websocket drops or provider-declared-retryable server errors,
with jittered re-queueing, an observable `retrying` lifecycle event, and a
retry confession on delegate envelopes (`children[].retry_attempts`,
`retry_max_attempts`, `current_attempt_index`, `retry_history`; present only
when a retry happened) (#205).
- `usage_summary.model` is now populated on provider usage events, and
subagent session ids are aliased in `pixir tree` projections (#216).
- Isolated subagent workspace snapshots accept extra exclusion directory names
(directory basenames, byte-exact, matched at any depth) via
`config :pixir, :subagents, snapshot_excluded_dir_names: [...]` or the
`:excluded_dir_names` snapshot option; built-in defaults (`.git`, `.pixir`,
`_build`, ...) always stay in effect, invalid names and a non-keyword
`:subagents` application env fail closed with structured errors, and the
effective list is confessed as `excluded_dir_names` in snapshot metadata and
runtime failure envelopes (never on validation failures, where no effective
policy ran) (#221).
## [0.1.5]
### Fixed
- Clean CLI exits now release Session writer leases across one-shot, `resume`,
and attached delegate (parent and children); stale leases from crashed runs
remain fail-closed behind `--force-release-writer-lease`. Headless
orchestrators no longer need the force flag on the happy path.
- `Subagents.Manager` survives late timeouts or cancels racing an
already-terminated child Session; the recorded timeout/cancel evidence is the
honest record either way.
### Added
- `pixir-delegate` skill family for orchestrating agents
(`.agents/skills/pixir-delegate*`): a host-neutral delegation judgment core,
real blind-run demonstrations, deterministic `fanout.sh`/`steer.sh` scripts,
and variants for Claude Code, Codex root agents, and Pixir-native
orchestration. Discoverable by Claude Code via `.claude/skills/`.
- Site route `/scale` with measured scale evidence (up to 64 concurrent
workers) and bounded public claims.
- Delegate CLI contract documentation for expensive orchestrators
(`docs/examples/delegate-cli-live/README.md`): a per-subcommand exit-code table,
the read/scope vs write-policy denial distinction (`outside_workspace` vs
`write_policy_denied`), and honest caveats for `next_actions` and
`observed_applied_writes`.
- `SECURITY.md` with private vulnerability reporting and a clear
tripwire-not-a-sandbox disclaimer, and `CONTRIBUTING.md` describing the real
workflow and invariants.
- Partial-write observability: bounded-write delegate envelopes now report
`observed_applied_writes` from child Session Logs as an at-least lower bound,
without changing existing `writes_applied_to` / `contract_status` fields.
### Changed
- Elixir requirement moved to `~> 1.20`; CI runs on Elixir 1.20.2 / OTP 29.
- Delegate error locations now carry machine-readable metadata (`json_pointer`,
`path`, `step_index`) alongside the human-facing 1-based field label.
### Fixed
- `mix check` no longer hangs after the test phase. The test step nested a BEAM
node under `cmd env MIX_ENV=test mix ...` that did not exit cleanly on teardown;
it now shells out with `MIX_ENV` as an environment variable and returns cleanly.
- Bash tool workspace confinement now rejects path escapes beyond `..` — absolute
out-of-workspace paths, `$HOME`/`~`, and symlink prefixes resolving outside the
workspace — before crossing the host boundary, surfaced honestly as
`outside_workspace` rather than a write-policy denial.
## [0.1.4] and earlier
See the release notes at
`docs/release-notes/open-beta-developer-preview.md` for the 0.1.0–0.1.4 developer
preview history (runtime truth and fanout honesty, ACP Registry readiness, and
runtime diagnostics).