Skip to content
Closed
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
4 changes: 2 additions & 2 deletions INVARIANTS.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/vrs/08-harness-context/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ number (HC-R02); where st2 computes it, the row says so.
| --- | --- | --- | --- | --- | --- |
| claude | 2.1.250 | `statusLine` command stdin JSON | `context_window.total_input_tokens` = `input + cache_creation + cache_read` of the last response | `context_window.context_window_size` | `context_window.used_percentage` — Claude's own integer, clamped 0..100 |
| codex | codex-cli 0.151.0 | app-server `thread/tokenUsage/updated` | `tokenUsage.last.totalTokens` | `tokenUsage.modelContextWindow` | st2 computes with the baseline rule below; equals `100 −` Codex's displayed "% context left" |
| pi | 0.84.2 | injected extension `ctx.getContextUsage()` | `.tokens` = last assistant `totalTokens` (input + output + cacheRead + cacheWrite) | `.contextWindow` | `.percent` (float) |
| pi | 0.84.4 | injected extension `ctx.getContextUsage()` | `.tokens` = last assistant `totalTokens` (input + output + cacheRead + cacheWrite) | `.contextWindow` | `.percent` (float) |
| omp | 18.0.9 (and 18.0.3) | injected extension `ctx.getContextUsage()` | `.tokens` = last assistant **`input`** only | `.contextWindow` | `.percent` (float) |
| opencode | 1.18.25 | SSE `message.updated` joined with `GET /config/providers` | last **non-summary** assistant `tokens.total` | `providers[].models[<modelID>].limit.context` | st2 computes `usedTokens / windowTokens`; the server displays none |

Expand Down Expand Up @@ -727,7 +727,7 @@ turn the measurement into a semantic-version promise. Every later Codex release
still requires its own source comparison and live delivery proof before the exact
launch gate moves.

### pi (0.84.2)
### pi (0.84.4)

One call answers everything, present on the `ctx` of every lifecycle event:
`getContextUsage()` returns `{ tokens, contextWindow, percent }`.
Expand Down Expand Up @@ -1126,7 +1126,7 @@ each only once a real test proves it (per `CLAUDE.md`):
baseline-free `last.totalTokens / window` reads 36, the truth is 33).

**Shipped for pi and omp**:
`src/pi_channel.rs::the_pi_0_84_2_fixture_pins_total_tokens_as_the_numerator`,
`src/pi_channel.rs::the_pinned_pi_fixture_pins_total_tokens_as_the_numerator`,
`src/pi_channel.rs::the_omp_18_0_9_fixture_pins_prompt_input_as_the_numerator`,
`src/pi_channel.rs::a_pi_compaction_withholds_the_reading_it_emptied_in_the_same_write`,
`src/pi_channel.rs::an_omp_compaction_yields_unknown_because_the_event_names_no_reason`,
Expand Down
4 changes: 2 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,10 @@
# without integrity hashes, which `fetchNpmDeps` cannot express.
checks.pi-extension-types =
let
piVersion = "0.84.2";
piVersion = "0.84.4";
piTarball = pkgs.fetchurl {
url = "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-${piVersion}.tgz";
hash = "sha256-lbiZzXsaDB8BdMe/M6tCdDXjVTp9H0dWZhqpx/Gmj/o=";
hash = "sha256-W852bRnDzroY8/uq2RxEnJ+dc5gfnjQA7O+TIAbwaWg=";
};
nodeTypesTarball = pkgs.fetchurl {
url = "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz";
Expand Down
2 changes: 1 addition & 1 deletion hooks/omp-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const terminalProviderError = (event: AgentEndFrame): ProviderError | undefined
* build whose telemetry surface moved still loads and still delivers mail, and a widened cast alone
* would make that tolerance absolute and silent. Erased at runtime.
*
* Note what this can and cannot prove for omp. It pins the SHAPE against pi 0.84.2's typings, which
* Note what this can and cannot prove for omp. It pins the SHAPE against pi 0.84.4's typings, which
* is all this asset compiles against — omp ships no typings of its own. It cannot prove omp's
* `tokens` still means prompt-only input, because that is a meaning and not a shape; the
* version-pinned fixture in `src/pi_channel.rs` is what bounds that (HC-R13, HC-T03).
Expand Down
233 changes: 211 additions & 22 deletions hooks/pi-channel.ts

Large diffs are not rendered by default.

274 changes: 265 additions & 9 deletions hooks/typecheck/smoke.mjs

Large diffs are not rendered by default.

883 changes: 863 additions & 20 deletions src/pi_channel.rs

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion src/pi_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ const EXTENSION: &str = "pi-channel.ts";
/// type-checks and runtime-smokes the shipped asset against exactly this tarball. That makes the
/// flake pin the gate for this constant, and `pi_channel`'s fixture asserts the two agree: a pi
/// bump that changes what `getContextUsage().tokens` means must move both together or fail.
pub const MEASURED_CONTEXT_VERSION: &str = "0.84.2";
///
/// Moved 0.84.2 -> 0.84.4 with the flake pin, and the arithmetic was re-verified rather than
/// assumed: `getContextUsage()` (`dist/core/agent-session.js`) and `calculateContextTokens`
/// (`dist/core/compaction/compaction.js:86-88`, `usage.totalTokens || input + output + cacheRead
/// + cacheWrite`) are byte-identical between the two published tarballs, so the recorded fixture
/// still means what it says under the newer pin.
pub const MEASURED_CONTEXT_VERSION: &str = "0.84.4";

/// The exact st2 executable the pi extension must spawn for its channel.
pub const CHANNEL_BIN: &str = "ST2_PI_CHANNEL_BIN";
Expand Down
Loading