Hmbown / Hmbown/Codewhale

Pet conformance: Rust core diverges from the canonical TypeScript on six of eight channels (portable red)

Open
#6,227 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
41k
Forks
3.6k
Avg merge
14h 18m
Merged PRs (30d)
286

Description

`portable` (Pet conformance) has been red on `v0914-chunk2` since `a06d2296` and has never run on `main`. Reproduced locally with `./pet/verify.sh --no-swift` and narrowed to something more specific than "parity mismatch".

## The state machine agrees; the field does not

`verify.sh` has `set -e`, so it dies on the first v1 diff and never reports v2. Running both by hand:

| Expression | Frames differing |
| --- | --- |
| v1 (`--legacy`, `PetSim::legacy_whale()`) | **68 of 68** |
| v2 (`PetSim::whale()`) | **53 of 68** |

The label column is **byte-identical** between TypeScript and Rust on both — `6 reasoning, 5 tool, 7 code, 5 filesystem, 5 network, 3 error, 5 code, 10 agent, 7 human, 14 reasoning, final`. Same frames, same channel sequence, same ordering. Only the digests differ, and they differ from **frame 0**, so this is not accumulated drift.

`digest()` quantizes the particle field onto a 64×32 grid over [-0.66, 0.66]² and FNV-1a's the counts plus the frame RGB. So the two cores agree on *what the pet is doing* and disagree on *where the particles are or what colour the frame is*.

## It is channel-dependent, which is the useful part

Breaking v2's 68 frames down by channel:

| Channel | Match | Differ |
| --- | --- | --- |
| `filesystem` | **5** | 0 |
| `network` | **5** | 0 |
| `code` | 3 | 9 |
| `human` | 1 | 6 |
| `reasoning` | 1 | 19 |
| `agent` | 0 | 10 |
| `error` | 0 | 3 |
| `tool` | 0 | 5 |

`filesystem` and `network` are in exact agreement. Everything else has drifted. That is a strong hint the divergence is in per-channel field expression rather than anything global like a float-precision or grid-quantisation difference — those would break all eight channels uniformly.

## Which side is canonical

TypeScript. `verify.sh` diffs the committed fixture against the TS output *before* it diffs TS against Rust:

```sh
if [ "$expression" = v1 ]; then diff -u "tests/fixtures/v1-$name-$mode.txt" "$stem-ts.txt"; fi
diff -u "$stem-ts.txt" "$stem-rs.txt"
```

The fixture diff passes and the TS↔Rust diff fails. So `PetSim.ts` still matches the recorded v1 contract and `crates/tui/src/tui/ambient_life/pet_sim.rs` — which `rs/pet_sim.rs` includes directly, so the Rust core *is* the product implementation — is the side that moved.

Last touched by `334c720057` ("feat(pet): express work through versioned particle fields") and `5450b09ff3`. Given the v1 path (`legacy_whale()`) differs in *every* frame, the versioning work looks like it did not preserve legacy field expression, and the v2 path drifted on six of eight channels besides.

## Scope

This is product logic, not a test defect, and reconciling it means making two independent implementations of a particle simulation agree channel by channel. It needs the design intent behind "versioned particle fields" — specifically whether Rust or TypeScript holds the intended v2 behaviour, since the fixture only pins v1.

Not a merge blocker: `portable` is not in the `protect-main` required set (that is `Lint`, `Test (windows-latest)`, `npm wrapper smoke (ubuntu-latest)`).

Reproduce: `cd pet && npm ci --ignore-scripts && ./verify.sh --no-swift`, or for the per-version split, run `node run-tape.ts run [--legacy] < tape.tsv` against `(cd rs && ./petsim [--legacy] < ../tape.tsv)`.

Contributor guide

Open the contributing guide

Research direction

Run `cd pet && npm ci --ignore-scripts && ./verify.sh --no-swift`, then inspect `PetSim.ts` and `crates/tui/src/tui/ambient_life/pet_sim.rs`, including the `legacy_whale()` and `whale()` paths. Compare the per-channel outputs with the documented v1 and v2 splits; done means the fixture still passes and TypeScript and Rust digests agree across all frames and channels.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, shell, typescript
Domain
cli, testing
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.