diff --git a/docs/development/v021-ledger.md b/docs/development/v021-ledger.md index e182f66b..69a3cc08 100644 --- a/docs/development/v021-ledger.md +++ b/docs/development/v021-ledger.md @@ -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 @@ -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) @@ -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).