Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 46 additions & 44 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Changelog

## 0.233.0

**A released retained child now settles (#1247).** A child whose provider execution was RETAINED
— admitted durably, result read lost — settles `down` with its cursor slot open and its
reservation reconciled at the floor it had streamed (0.230.0, #1190), so that a later process
could resume the run and reconcile the paid execution. On the pursuit path no later process ever
comes: `supervisePursuit` writes a settle record that refuses re-entry and forces
`retainedAtSettlement: 'release'`, so every one of these children is released at root settlement
and none is ever recovered — by construction, not by accident. Measured 2026-09-15: on
`capability-per-parameter-cpp-glm-20260915c`, 0 of 35 reconciled children ever settled, and 185
of 223 lost sandbox children across 385 runs stopped at `reconciled`. Each one read as
`never-settled` to every journal reader and was charged its ceiling, while the pool had committed
the floor; Lab told them apart from ordinary downs by matching the reason string.

- The release sweep now writes the node's terminal record after the `environment-teardown`
receipt, once the executor confirms teardown: the settlement the driver received (reason,
`infra`, `trace`, `harnessTranscript`, `outRef`, `providerModel`), under the seq the driver
saw, marked `retainedExecution: 'released'`. Its `spent` is the node's child-work component
of the reconcile the pool committed — the streamed floor for a leaf, `accounting().reported`
for a recursive executor — never the reservation. A cancelled retained child keeps the
`cancelled` kind and its `source`. The overspend a retained reconcile returned, which the
open-slot surfaces withhold, is carried on this record, because when the run releases the node
the floor is its final charge. A refused release (`destroyed: false`, or an executor whose
teardown will not confirm) writes nothing: the environment may still exist, so the slot stays
open and the node stays in `teardownUnconfirmed`.
- `retainedExecution: 'pending' | 'released'` (new `RetainedExecutionState`) is stated on
`Settled`'s down arm (`'pending'` at the reconcile, `'released'` on replay of a closed node),
on the journal's `settled`/`cancelled` records (`'released'` only), on `NodeSnapshot` from
both the live and the materialized tree, on the `agent.child` payload (a second event per
released node, carrying `releasedAt`), and on `PursuitNodeProjection`. A reader never splits
the population on `reason` text again. `PursuitStatus` stays three-valued.
- `SupervisedResult` gains `fleetYield` on every arm (new `FleetYield`): `spawned`, `done`,
`down`, `cancelled`, `neverSettled`, `releasedUnrecovered`, counted by node id across the
whole journal forest, with `spawned === done + down + cancelled + neverSettled` asserted.
Always present; zeros are facts. It rides into `result.json`. `spendGaps` stays root-tree
scoped, so the two disagree on a nested run by design. A no-winner's `downCount` is unchanged:
the breaker skips released records, so a retained child is counted in `fleetYield.down` and
never in `downCount` — as it never was.
- `spentTotal.tokensKnown`/`usdKnown` stay `false` on a run with a released child: its record
carries the unknown-flagged floor, so the gap changes kind from `never-settled` (a ceiling) to
`unreported` (a floor), not presence. The one exception is a ticket already reconciled at a
measured terminal spend (a persistence failure after the artifact landed), whose released record
is known. The pool half — the refund at the reconcile (#1190) — is unchanged.
- A crash between the receipt and the terminal record leaves an open slot beside a destroyed
environment; the next process cannot self-heal it and this release does not try.

## 0.232.0

External directors can use `repromptOnUnmet: 'until-complete'` with a completion check and finite positive budget deadline.
Expand Down Expand Up @@ -75,50 +121,6 @@ blobs)`. Consequences, all deliberate:
Settlements recorded before this release carry no `harnessTranscript` on the record, which is not
the same fact as a recorded `unavailable`, and stays absent rather than defaulting.

**A released retained child now settles (#1247).** A child whose provider execution was RETAINED
— admitted durably, result read lost — settles `down` with its cursor slot open and its
reservation reconciled at the floor it had streamed (0.230.0, #1190), so that a later process
could resume the run and reconcile the paid execution. On the pursuit path no later process ever
comes: `supervisePursuit` writes a settle record that refuses re-entry and forces
`retainedAtSettlement: 'release'`, so every one of these children is released at root settlement
and none is ever recovered — by construction, not by accident. Measured 2026-09-15: on
`capability-per-parameter-cpp-glm-20260915c`, 0 of 35 reconciled children ever settled, and 185
of 223 lost sandbox children across 385 runs stopped at `reconciled`. Each one read as
`never-settled` to every journal reader and was charged its ceiling, while the pool had committed
the floor; Lab told them apart from ordinary downs by matching the reason string.

- The release sweep now writes the node's terminal record after the `environment-teardown`
receipt, once the executor confirms teardown: the settlement the driver received (reason,
`infra`, `trace`, `harnessTranscript`, `outRef`, `providerModel`), under the seq the driver
saw, marked `retainedExecution: 'released'`. Its `spent` is the node's child-work component
of the reconcile the pool committed — the streamed floor for a leaf, `accounting().reported`
for a recursive executor — never the reservation. A cancelled retained child keeps the
`cancelled` kind and its `source`. The overspend a retained reconcile returned, which the
open-slot surfaces withhold, is carried on this record, because when the run releases the node
the floor is its final charge. A refused release (`destroyed: false`, or an executor whose
teardown will not confirm) writes nothing: the environment may still exist, so the slot stays
open and the node stays in `teardownUnconfirmed`.
- `retainedExecution: 'pending' | 'released'` (new `RetainedExecutionState`) is stated on
`Settled`'s down arm (`'pending'` at the reconcile, `'released'` on replay of a closed node),
on the journal's `settled`/`cancelled` records (`'released'` only), on `NodeSnapshot` from
both the live and the materialized tree, on the `agent.child` payload (a second event per
released node, carrying `releasedAt`), and on `PursuitNodeProjection`. A reader never splits
the population on `reason` text again. `PursuitStatus` stays three-valued.
- `SupervisedResult` gains `fleetYield` on every arm (new `FleetYield`): `spawned`, `done`,
`down`, `cancelled`, `neverSettled`, `releasedUnrecovered`, counted by node id across the
whole journal forest, with `spawned === done + down + cancelled + neverSettled` asserted.
Always present; zeros are facts. It rides into `result.json`. `spendGaps` stays root-tree
scoped, so the two disagree on a nested run by design. A no-winner's `downCount` is unchanged:
the breaker skips released records, so a retained child is counted in `fleetYield.down` and
never in `downCount` — as it never was.
- `spentTotal.tokensKnown`/`usdKnown` stay `false` on a run with a released child: its record
carries the unknown-flagged floor, so the gap changes kind from `never-settled` (a ceiling) to
`unreported` (a floor), not presence. The one exception is a ticket already reconciled at a
measured terminal spend (a persistence failure after the artifact landed), whose released record
is known. The pool half — the refund at the reconcile (#1190) — is unchanged.
- A crash between the receipt and the terminal record leaves an open slot beside a destroyed
environment; the next process cannot self-heal it and this release does not try.

## 0.231.1

Allow Sandbox 0.40.x beside Runtime without a consumer dependency override.
Expand Down
2 changes: 1 addition & 1 deletion docs/api/primitive-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Primitive catalog — the never-stale anti-reinvention inventory

> **GENERATED** from `@tangle-network/agent-runtime@0.232.0` and `@tangle-network/agent-eval@0.182.0` by `scripts/gen-primitive-catalog.mjs`. Do NOT hand-edit — run `pnpm run docs:api`. This is the mechanical companion to the JUDGMENT in `canonical-api.md` (§2 decision table + §1.5 AgentProfile law): that doc says WHICH primitive to reach for and what NOT to build; this catalog proves WHAT exists. Per-symbol signatures + `file:line` live in the per-module pages under `docs/api/`.
> **GENERATED** from `@tangle-network/agent-runtime@0.233.0` and `@tangle-network/agent-eval@0.182.0` by `scripts/gen-primitive-catalog.mjs`. Do NOT hand-edit — run `pnpm run docs:api`. This is the mechanical companion to the JUDGMENT in `canonical-api.md` (§2 decision table + §1.5 AgentProfile law): that doc says WHICH primitive to reach for and what NOT to build; this catalog proves WHAT exists. Per-symbol signatures + `file:line` live in the per-module pages under `docs/api/`.

## 1. agent-runtime — own public surface

Expand Down
2 changes: 1 addition & 1 deletion docs/canonical-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Generated signatures and the complete export list live in docs/api/.
Run pnpm docs:freshness after editing this file. -->

> **Version 0.232.0.**
> **Version 0.233.0.**
> [`docs/api/primitive-catalog.md`](./api/primitive-catalog.md) lists every export and import path.
> `agent-eval` must satisfy `>=0.182.0 <0.183.0`.
> `sandbox` must satisfy `>=0.36.4 <0.41.0`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tangle-network/agent-runtime",
"version": "0.232.0",
"version": "0.233.0",
"description": "Shared task-lifecycle skeleton for agents: a recursive loop kernel for chat turns, one-shot tasks, and multi-attempt loops, with trace capture and eval-gated self-improvement. Domain behavior lives in adapters; scoring and ship-gates in @tangle-network/agent-eval.",
"homepage": "https://github.com/tangle-network/agent-runtime#readme",
"repository": {
Expand Down
10 changes: 5 additions & 5 deletions src/testing/fixtures/agent-improvement-proposal.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"changedSurfaces": ["prompt"],
"digest": "sha256:201a9a98fbdc078d03c35314e4e03f34abaa36d7db394a11c4b1110bd036521c",
"digest": "sha256:c955600d688a194cfb429c3c6165a5b8f16ca1634597cab757af0b05cd3290e3",
"evaluation": {
"decision": {
"contributingChecks": [
Expand Down Expand Up @@ -4882,7 +4882,7 @@
],
"metadata": {
"fixture": "agent-improvement-proposal",
"runtimeVersion": "0.232.0"
"runtimeVersion": "0.233.0"
},
"objectives": [
{
Expand Down Expand Up @@ -4993,8 +4993,8 @@
"baselineContentHash": "sha256:5c21ee53e513fc604cb09754e21c392b24a424da0ef37dbf8f1ee4a8a0b08f09",
"candidateContentHash": "sha256:60fcbb1c728194bd51d7d19cb732d1c3f1881dce7e0a6266b41c8b98cfd65693",
"kind": "agent-eval-loop",
"recordDigest": "sha256:d26f696c1a140606d4e75b1ade7a03f08ce13f4fc4fdfe0527d2fbb4717e438d",
"runId": "agent-runtime-0.232.0-proposal-fixture",
"recordDigest": "sha256:cbf8298e0f8dd8a60ef8fe8ce3cc4b5c214e35a3c40c05c167e22a4848c43a90",
"runId": "agent-runtime-0.233.0-proposal-fixture",
"schema": "agent-candidate-experiment"
}
},
Expand All @@ -5021,5 +5021,5 @@
],
"kind": "agent-improvement-proposal",
"proposedAt": "2026-07-10T01:00:00.000Z",
"runId": "agent-runtime-0.232.0-proposal-fixture"
"runId": "agent-runtime-0.233.0-proposal-fixture"
}
6 changes: 3 additions & 3 deletions src/testing/fixtures/agent-profile-improvement-proposal.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"changedSurfaces": ["prompt", "skills"],
"digest": "sha256:702dc1a85ce46804d67de7fd179bd69f6af0027dca7b6a99c46ab7f159bf7f5f",
"digest": "sha256:a28e23a8892b3d8ba6c66c374750e321b06bc036fad7aa76984e617cdc378ff3",
"evaluation": {
"decision": {
"contributingChecks": [
Expand Down Expand Up @@ -1715,7 +1715,7 @@
],
"metadata": {
"fixture": "agent-profile-improvement-proposal",
"runtimeVersion": "0.232.0"
"runtimeVersion": "0.233.0"
},
"objectives": [
{
Expand Down Expand Up @@ -1826,7 +1826,7 @@
"baselineContentHash": "sha256:21c495a37c418c10bde64fbaa188beddeed31f1f051ea60a6a6582a9ee0db704",
"candidateContentHash": "sha256:103f77bc8481601eef1ad5fe6ba84a40dffabc3a44f421f8c8559121edab84e9",
"kind": "agent-eval-loop",
"recordDigest": "sha256:6a55eeeef02f261ce41fa35063839ec37d0b64815dae2517e9d92c75dd2585ce",
"recordDigest": "sha256:1bcc70b1e1bb5a020da56e97fcc4a2d89824ecf8ca59b2e0232b868333daa4c4",
"runId": "profile-improvement-1",
"schema": "agent-profile-improvement-experiment"
}
Expand Down
Loading