Skip to content

chore: cut 2.3.0 (#363) - #366

Merged
rappdw merged 1 commit into
mainfrom
chore/cut-2.3.0
Sep 21, 2026
Merged

rappdw merged 1 commit into
mainfrom
chore/cut-2.3.0

Conversation

@rappdw

@rappdw rappdw commented Sep 21, 2026

Copy link
Copy Markdown
Owner

Drops the -dev suffix: SANDY_VERSION 2.2.1-dev → 2.3.0. Tag v2.3.0 follows the merge; a second PR then bumps to 2.3.1-dev.

What is in it

#363 — agent_args composes in the argv sandy BUILDS, which is not the same as composing in EFFECT.

For a flag the agent's parser reads once, the second contributor silently discards the first. That shipped, and was found in the field: two features each contributed --append-system-prompt-file, claude kept the last, and the first feature's prompt never reached the system prompt — while every observable read healthy, mounts present and :ro, and the session marker faithfully recording both features, because the marker records what was passed.

Sandy now consults a published policy table (--print-schema → manifest.agent_args_compose) and, at two or more contributors of a listed flag, merges them into a file it owns and mounts :ro, passing the flag once. A flag that replaces rather than appends is never merged — the collision and the loser are named instead. At one contributor nothing happens and the argv is byte-identical to 2.2.0.

agent_args_composed (session marker + --print-state) answers the question agent_args structurally cannot: that one records what was passed, this one whether it can have taken effect.

The launch also says which features applied, without SANDY_VERBOSE — before this a selected feature printed nothing and a skip was verbose-only, so "installed" and "applied to this sandbox" were indistinguishable at launch.

Also on main since 2.2.0 and therefore in this release: #362 and #365, two acceptance harnesses that still installed the relay via the config key removed in 2.2.0. Test-only; neither changes the shipped script.

Semver

Minor. Additive throughout: new emitted fields, a new --print-schema block, and a new mount in a case that previously lost data.

  • Nothing removed → schema_version stays 3, and README's ## Deprecated table is unchanged. No entry is added there, which the rules only permit in an X.0.0 anyway.
  • SANDY_SANDBOX_MIN_COMPAT stays 2.0.0 — within a major it may never advance above X.0.0, and nothing here touches persistent sandbox layout. Existing 2.x sandboxes are unaffected and need no recreation.
  • The one behaviour change for an existing fleet is the case that previously lost a contribution; a single-contributor launch is unchanged.

Verification

Known red, not fixed here

run-integration-tests.sh §14 below-floor sandbox is hard-refused at launch has been failing since 2.0.0: it greps sandy output for "refuses to launch against it", a phrase that last existed in v1.15.0. Its sibling, below-floor refusal happens before container launch, is vacuous — it greps for the absence of a launch banner, so it passes whether or not the refusal fires. Both should assert the property (non-zero exit before docker run; message names the remediation). Deliberately out of scope for a version-bump PR.

🤖 Generated with Claude Code

Drops the -dev suffix. Tagged as v2.3.0; a follow-up bumps to 2.3.1-dev.

One feature, and it is a correction to something 2.1.0 got wrong about
its own new capability.

- #363 -- agent_args composes in the argv sandy BUILDS, and that is not
  the same as composing in EFFECT. For a flag the agent's parser reads
  once, the second contributor silently discards the first. It shipped:
  two features each contributed --append-system-prompt-file, claude kept
  the last, and the first feature's prompt never reached the system
  prompt while every observable read healthy -- mounts present and :ro,
  and the marker recording BOTH features, because the marker records
  what was PASSED.

  Sandy now consults a published policy table (--print-schema ->
  manifest.agent_args_compose) and, at TWO OR MORE contributors of a
  listed flag, merges them into a file it owns and mounts :ro, passing
  the flag once. A flag that REPLACES rather than appends is never
  merged -- the collision and the loser are named instead. At ONE
  contributor nothing happens and the argv is byte-identical to 2.2.0.

  agent_args_composed (session marker + --print-state) is the half that
  makes it visible, and answers a different question from agent_args:
  that one records what was passed, this one whether it can have taken
  effect.

  The launch also SAYS which features applied, without SANDY_VERBOSE.
  Before this a selected feature printed nothing and a skip was
  verbose-only, so "installed" and "applied to this sandbox" were
  indistinguishable at launch.

Additive throughout: new emitted fields, a new --print-schema block, and
a new mount in a case that previously lost data. Nothing was removed, so
schema_version stays at 3 and README's ## Deprecated table is unchanged.

SANDY_SANDBOX_MIN_COMPAT stays 2.0.0 -- within a major it may never
advance above X.0.0, and nothing here touches persistent sandbox layout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rappdw
rappdw merged commit 9122bfa into main Sep 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant