Skip to content
Merged
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
108 changes: 99 additions & 9 deletions docs/development/v021-ledger.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ Automated results here are not physical-terminal validation.
| 5 | `/track` | #393 (#394) | `feature/v021-track` / [#416](https://github.com/raiseCatError/notMyShell/pull/416) → #415 | | PR open, CI green |
| 6 | Modules and diagnostics | #364, #365 | `feature/v021-modules` / [#417](https://github.com/raiseCatError/notMyShell/pull/417) → #416 | | PR open, CI green (one rerun) |
| 7 | Themes and controls | #401, #336 | `feature/v021-themes` / [#418](https://github.com/raiseCatError/notMyShell/pull/418) → #417 | | PR open, CI green |
| 8 | Checkpoint (this ledger) | #410 | `docs/v021-checkpoint` → #418 | | PR open, CI green |
| 8 | Checkpoint ledger | #410 | `docs/v021-checkpoint` / [#419](https://github.com/raiseCatError/notMyShell/pull/419) → #418 | | PR open, CI green |
| 9 | `/track` refresh and finalization lifecycle | #393 | `fix/v021-track-review-hardening` / [#420](https://github.com/raiseCatError/notMyShell/pull/420) → #419 | | PR open, CI green |
| 10 | `/track` review: repetition safety gate, process cleanup, presentation | #393 | `fix/v021-stabilize` / [#421](https://github.com/raiseCatError/notMyShell/pull/421) → #420 | | PR open, CI green |
| 11 | Flaky CI at the cause | #410 | `fix/v021-flaky-tests` / [#422](https://github.com/raiseCatError/notMyShell/pull/422) → #421 | | PR open, CI green |
| 12 | Bugs: #388 wrapped rows, command colors after a slow zshrc, #365 width | #388, #408, #365 | `fix/v021-bugs` / [#423](https://github.com/raiseCatError/notMyShell/pull/423) → #422 | | PR open, CI green |
| 13 | Stabilization ledger (this) | #410 | `docs/v021-stabilization` → #423 | | PR open |

## Decisions

Expand Down Expand Up @@ -58,11 +63,11 @@ toggle, copy flags, Off). Slice 5: section 5 (`/track` block, refresh, copy, sto

## Open risks

- Merging into `dev` needs the maintainer (the agent's merge was refused by its permission policy). Slices are
stacked PRs; merge them in order, each squashed.
- #388: programs that position rows absolutely inline (rare) still append; recorded in the design.
- Merging into `dev`: see "Ordered integration" below. Use regular merge commits, in order.
- #388: absolute rows (`CSI H/f/d`) are deliberately not mapped and scroll regions are not emulated (a program's
status row below its region is not stored); the contract is explicit and tested (stabilization).
- Nothing in v0.21 has had a physical-terminal pass yet. Every slice issue stays open until its pass is recorded.
- Three CI flakes outside v0.21's changes were seen once each (below); none reproduced on rerun.
- The three CI flakes seen during the stack were fixed at their cause in #422 (two were product defects).

## Integration verification (stack head, 2026-10-18)

Expand Down Expand Up @@ -93,9 +98,94 @@ Run on `feature/v021-themes` (all eight slices) in a T7 worktree, `NMSH_TEST_TMP
loads (8 MiB / 200,000 lines), `/edit` (1 MiB), Semantic Output recognizers (linear, 2 MiB scanned, 20 items),
`/track` samples (200 kB, 12 live rows, at most 8 trackers).

## Stabilization (2026-10-18)

A second pass after the stack: every open `type:bug` issue, a joint review of `/track` (#416 and #420), the CI
flakes, and the v0.21 integration. Linux evidence comes from a Debian container (Node 26.12, zsh 5.9, Fish 3.6,
Bash 5.2) whose disk is on the T7 (Colima, `/Volumes/T7Projects/.colima-suma`); macOS from this Mac (Node 26.10,
Fish 4.9.3). Every new regression test was run against the unfixed code first and failed there.

**`/track` review (#421).** Commands started at once and repeated without asking: `echo x > ~/.zshrc 2>/dev/null`
(the shared classifier excused every redirect once `>/dev/null` appeared; paste review called it read-only),
`env rm …`, `npm publish`/`login`/`audit fix`, `npm x`/`pnpm dlx`/`bun x`, `ssh host rm …`, `scp`, `rsync`,
`curl -X POST`/`-d`/`-o`, plain `wget`, `git -c core.fsmonitor=… status`, `git log --output=…`; `npm test 2>&1` was
wrongly refused. A repetition gate (`src/tasks/repeatSafety.ts`) now sits on top of the classifier, and `&>` stays
refused (dash reads it as a background job). A TERM-ignoring child survived `/track stop` because the close handler
cancelled the KILL fallback; leftovers in a sample's process group are now ended. #420's refresh event fires after
the child is wired; a vanished directory is named; many trackers share one summary row; Safe glyphs; result rows
cached per result (1–3 ms to ~0.5 ms per frame with eight large trackers). #420 itself: no re-entrancy, stale
reference or duplicate finalization found.

**Flaky CI (#422).** `backgroundSession.test.ts:92` was a product defect: a cleanly exiting background task showed
"exited, processes left" (and Delete was refused) until its guard confirmed the group empty; the supervisor now
finishes on the guard's verdict. `configuredCompletion.test.ts:89` was a product defect: removing the helper's
private root raced the helper's own `rm -rf` and late pid writes (rmSync threw ENOTEMPTY on macOS, returned with the
directory present on Linux); the root is renamed away first, then removed entry by entry. The 6-minute Ubuntu hang
was a test that stalled past its timeout with a live shell PTY: the runner now preloads a file teardown that ends,
and names, what a file left running. `nativeCaptureLifecycle`: its tight bound no longer covers a cold `tsx` start. A fourth
flake appeared once on `dev` itself (dispatched CI): `codexAdapter.test.ts:84` read the fake Codex server's log when
the turn settled, before the server had read the client's last response; the fixture now forces that order every run
and the helper waits for what the test asserts.

**Bugs (#423).** #388: the live region moved by stored lines while programs count terminal rows, so a redraw over a
wrapped line erased the program's earlier output at narrow widths (parser, real PTY at 40 columns, and through the
frontend); rows are now the terminal's rows. Found verifying #408: a zsh configuration slower than 1.5 s made the
first semantic lookup time out and end the helper, so commands lost their known/unknown color for the session;
lookups are now timed from when the helper reads them. #365: `/modules explain` says when the Rail or Strip left a
module out, or shortened it, for width in the last frame.

**Investigated, not reproducible.** #356 (Fish typeahead after a read): 40/40 on macOS Fish 4.9.3 under 8× parallel
load; 22/22 Linux Fish 3.6 runs that got past startup under 2× load (the other 2 stalled on VM I/O before drawing).
#403: every interactive Fish in tests has a home marked generated; non-interactive uses never start the generator.
#408's generation/re-ask synchronization holds.

**Also checked.** Semantic Output: 99 adversarial input/recognizer combinations up to a 2 MB single line, none over
150 ms. Docker-specific `/track` checks were not run against a Docker daemon of NMSh's own (the only one available
runs the maintainer's containers); `docker system df` stays the one Docker verb allowed at once, by unit test.

**Verification (stabilization).**
- CI on each new PR (#420–#423: macOS and Ubuntu shards, Node 22 compatibility, Quality): green at their heads.
- Full CI dispatched on the stack head, which also runs the Fedora portability subset and both timing smokes:
`bb210ce5` and the final head `e8411e1a` (test-only changes since), all jobs green on both.
- Timing smoke against `dev` in the same window (dispatched pair, CI runners): Ubuntu `pty-ready` p50 415 vs 416 ms,
`service-ready` 580 vs 580 ms, `transcript/wrap-present-100000` 811 vs 848 ms; macOS `pty-ready` 28 vs 33 ms,
`transcript/wrap-present-100000` 1,132 vs 1,165 ms. No consistent regression; single runs vary by more than that.
- The paired `dev` run failed a fourth flake (`codexAdapter.test.ts:84`), fixed in #422 (above).
- Local `npm run verify:release` on this 8 GB Mac could not give a clean full-suite result during the session: the
machine was shared with other workloads (two container queue workers at about 120% CPU each in the Colima VM, other
agent sessions, a browser), with load averages of 35–167 and 4.6 GB of swap in use. One run (`bb210ce5`, load 35–67)
had 3,127 of 3,142 passing, 2 skipped and 13 failures, all live tests timing out (tmux, screen, service lifecycle,
per-frame budgets) plus two capture tests whose windows included the owner's cold `tsx` start (fixed in #422). All
seven failing files then passed 69/69 three times in a row at normal load. A second run on `e8411e1a` (load
3–13): 3,138 of 3,142 passing, 2 skipped, 2 failed, both timing bounds in code v0.21 does not change that pass
alone 5/5 (a Node stand-in for zoxide whose cold start exceeded the 1.5 s query limit, and a 4 s startup budget
for a 5,000-candidate compinit); both tests were hardened in #422. Typecheck of the benchmarks and the timing smoke
ran only in CI (verify stops at the first failing step). A clean local run on `dev` after integration remains a
gate.

## Ordered integration

`dev` is unprotected and allows merge commits; merged branches are not deleted automatically. Merge with regular merge
commits, in order: #411 into `dev`; then for each of #412 … #423 and this ledger PR, retarget it to `dev`
(`gh pr edit N --base dev`), check that its diff shows only its own changes, and merge it (`gh pr merge N --merge`).
Then let `dev` CI pass (push runs include Fedora and both timing smokes) and run `npm run verify:release` on `dev`.

## Release readiness

Ready for the maintainer's decision, not for release. Before a v0.21 tag: merge #411→#418 in order (then this
checkpoint), let `dev` CI pass, run the [physical QA](../testing/v021-physical-qa.md) passes and record them, then
close the slice issues whose passes succeed. Tagging, the GitHub release, the Homebrew tap and the website deploy
stay with the maintainer.
Not ready to release; ready for integration. Exact-head CI on the stack head `e8411e1a` is green in every job, including
Fedora portability and both timing smokes. Remaining gates, in order:

1. **Integration** (maintainer, or the agent where its permission policy allows): the ordered merges above, #411 to
#423 and this ledger PR, with regular merge commits; then `dev` CI green on push.
2. **Local `npm run verify:release` on `dev`** at normal machine load (the in-session runs were overloaded; see above).
3. **Physical QA, mandatory and not run**: every pass in the [checklist](../testing/v021-physical-qa.md), in Ghostty
and Terminal.app, recorded in its results table. Headless PTY tests and CI do not count.
4. Then close the issues whose acceptance is met (#388, #393, #397, #401, #402 viewer and editor phases, #403, #408,
#364, #365, #386 first phase, #336 where applicable), move `[Unreleased]` to `[0.21.0]` in the changelog, and
prepare the tag, release notes and distribution. Tagging, the GitHub release, the Homebrew tap and the website
deploy stay with the maintainer.

Known limitations shipped deliberately: `/track` is window-owned (stops on detach); Semantic Output is its first
phase (no `jc`/`delta` providers); inline absolute cursor positioning is not mapped and scroll regions are not
emulated (#388 contract); the Main Prompt has no per-segment truncation trace (#365); four theme families deferred
(#401); type-ahead *during* a Fish read stays subject to Fish's own editor queries (#356).
Loading