Skip to content
Draft
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
10 changes: 4 additions & 6 deletions docs/design/input-awareness.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,17 @@ first key of a draft and an Enter that would queue, and asks the session to look
The hold ends when the look answers or evidence arrives. Until then nothing typed is drawn, sent or queued: the keys
may be a hidden reply, and an Enter may answer the command or queue the next one (#426). The look says what it saw:
`hidden` (echo off for line input), `visible` (the terminal echoes), `unknown` (no sample said how it echoes: a probe
failed or timed out), `idle` (nothing runs) or `unavailable` (no way to look on this platform). `visible` routes the
keys as before (a terminal would show them too); `hidden` comes with a hidden request, so they go straight to the
failed or timed out), `idle` (nothing runs) or `unavailable` (no way to look on this platform). `visible` permits draft editing (a terminal would show it too), but says nothing about a reader. If the held keys include Enter and no reader was established, the entire draft moves into a confirmation hold, never the command-approval queue; `hidden` comes with a hidden request, so they go straight to the
program. Echo off with line input is a hidden request whatever else is known (confirmed when the group is idle,
likely when it computes or the kernel says it is blocked elsewhere), so NMSh never draws what the terminal would not
echo. An `unknown` answer gets one more look; if that is blind too, or no answer comes within 5 s, the keys stay held
and hidden: the activity rows say `Can't tell whether <program> is reading your typing` and Ctrl+S sends it to the
program, Tab shows it in the composer (for review; a final Enter is not replayed), Esc discards it. Later evidence
decides it the same way. A look still running after 800 ms says `Checking whether … · your typing is kept`.
program, Tab shows it in the composer (for review; a final Enter is not replayed), Esc discards it. Later reliable reader evidence can resolve an ordinary lookup hold. A held Enter with only later likely evidence requires confirmation; once Enter is in confirmation quarantine, no later result sends it automatically. Ctrl+S explicitly sends all captured bytes in order to the same still-running command. Tab or Ctrl+Q restores the editable text for queue review, without replaying the final Enter; a fresh Enter explicitly queues it. Esc and Ctrl+C discard the entire capture. Completion/done, a different command, terminal handover and shutdown invalidate confirmation holds; stale decisions cannot recover them. After completion/done, confirmation typing stays hidden in the existing prompt hold for Tab/Esc review, with Ctrl+S disabled; it is never sent to a later command. Existing approval-queue entries are never sent automatically. A look still running after 800 ms says `Checking whether … · your typing is kept`.

A command that ends while its typing was held past 800 ms never runs it: NMSh never learned whether it was a reply
An ordinary lookup hold (not confirmation quarantine) that ends while its typing was held past 800 ms never runs it: NMSh never learned whether it was a reply
(a timed `read -s` that gave up), so it is discarded with a note. A quick end (type-ahead after a short command) runs
it as before. Ctrl+C discards held typing, as a terminal flushes its input queue on an interrupt, and is itself
never held. A program that took the terminal meanwhile (Fish's reader) gets the keys as raw keys. An older service
never held. An ordinary lookup hold can follow authenticated native-reader ownership as raw keys. Confirmation quarantine is cancelled at terminal handover, before newer keys reach the new owner. An older service
does not say what its look saw; its answers are routed as before. Typing right after Ctrl+C or Ctrl+Z stays
type-ahead for the prompt. Both ends negotiate the feature; an older service is never asked and behaves as before.

Expand Down
23 changes: 23 additions & 0 deletions docs/performance/2026-10-28-resource-followup-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Deferred resource investigation

Execute separately after the input-ownership correction has completed review and validation. This is an investigation plan, not authorization for a broad memory optimization or a claim that the input gate has passed.

## Evidence to preserve

The actual original be3f6abe versus merged c690de05 benchmark raw data remains at `/Volumes/T7Tmp/ai-dev/nmsh-stabilization-followup-20261027/`, with provenance, samples, harnesses and measurements.json. The ownership checkpoint records their hashes; nothing is pooled or overwritten.

Warm median output/history results are substantial: 10k Unicode output 42503.28 to 269.84 ms, archive restore 684.59 to 251.93 ms, PageUp 872.55 to 40.11 ms, history typing 448.71 to 31.47 ms. Warm first-command output improves 1510.81 to 753.13 ms and durable completion 1643.01 to 858.59 ms. These are warm observations, not true-cold startup gains.

Costs remain visible: idle CPU 3.35% to 3.75% of one core; idle frontend RSS 129.28 to 152.78 MiB; idle service RSS 49.86 to 60.53 MiB; output-finish service RSS 20.38 to 70.62 MiB. Point-in-time RSS is not retained heap, peak memory or leak evidence. The output-finish snapshots differ in elapsed process lifetime: baseline 38–49 s, merged 0.27–0.30 s. Frontend after short typing is a different observation (155.17 to 153.95 MiB), not a reason to erase the idle increase.

Runtime/idle n=3 warm sessions; history n=4; long editing n=7 with correlated key samples. Small-n nearest-rank p95 is the observed maximum for runtime/history. Five-second CPU windows cover frontend/service/shell, omit other descendants, and are quantized by ps. No OS-cache purge, physical pixel latency, energy or sustained retention claim. Prior +6.7% history-typing p95 and +2.3% deletion p95 remain separate experiments without causal attribution.

## Investigation sequence

1. Reconstruct the matched benchmark environment with locked dependencies, built CLI, private HOME/service, fixed geometry/provider/shell and independently recorded exact heads. Keep original/raw results immutable. Alternate run order in a predefined bounded matrix, record all samples and external host activity, and separate source-loader costs from built runtime.
2. Idle CPU/memory: record all owned roles and descendants at common elapsed times and command lifecycle points over longer predefined windows. Collect CPU deltas, RSS, heap/GC/allocation evidence and timer/probe/render counts separately. Account for service backlog limits and sampler overhead. Do not attribute RSS differences to a leak without retained-object evidence.
3. Startup loading: measure authenticated shell readiness, first composer frame, first output and durable completion separately; record import/initialization paths and time spent starting shell/service/providers. Keep first-observed and warm samples separate. Define a reproducible cold-cache protocol before claiming any cold result; do not purge user caches or alter existing sessions.
4. Long sessions: use a bounded repeated output/history/edit workload with exact record/order checks, fixed idle checkpoints, detach/reattach and session closure. Measure retained heap and RSS across cycles, journals/backlogs, listener/process counts and reclamation after owned sessions close. Separate bounded caches from monotonic retention.
5. Form one evidence-backed hypothesis and a focused follow-up issue per cost. Agree acceptance budgets from the current milestone before code changes; validate any improvement against input safety and output/history performance. No broad cleanup or dependency churn.

All scratch and artifacts use verified T7 storage. Physical Ghostty/Zed QA remains a separate manual gate.
27 changes: 27 additions & 0 deletions docs/superpowers/plans/2026-10-28-input-ownership.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Input ownership implementation plan

> Implement inline using executing-plans; use independent review at the end.

**Goal:** safely recover ambiguous answers through explicit confirmation.
**Architecture:** localized TerminalApp ownership hold; unchanged InputWatch/protocol/service approval semantics.
**Tech stack:** existing TypeScript/Node/PTYS.
**Spec:** ../specs/2026-10-28-input-ownership-design.md

## Constraints and review focus
No automatic merge/release, no changes to PR513, no deadline/CI relaxation. Check combined and separate holds, late likely/hidden evidence, cancellation leaving editor drafts, owner/lifecycle invalidation, and explicit queue intent.

## Task 1: ownership quarantine
- [x] Add deterministic tests in inputOwnershipLook.test.ts for explicit confirmation, late inference, completion, cancellation, queue and ordering. Run on unchanged source and retain expected failures.
- [x] Add confirmation hold state and atomic draft capture in TerminalApp.ts. Guard late state routing and lifecycle transitions; preserve older-service behavior and explicit actions.
- [x] Run affected unit and real-PTY tests; document changed Enter semantics in input-awareness.md.

## Task 2: validation checkpoint
- [x] Controlled real-PTY old-red/new-green, immediate/delayed reads/password/non-reader/unknown cases; bounded stress.
- [x] Independent whole-change review and address safety findings; full npm run verify.
- [ ] Commit/push focused branch and open dev PR. Obtain exact-head hosted CI once, no retries for green. Keep unmerged.
- [ ] Report exact evidence/risks, unchanged PR513 and performance observations; leave separate deferred resource investigation plan.

## Ledger
Fresh dev c690de05; primary checkout unchanged. Design reviewed before implementation. Native owner change cancels quarantine before handover to preserve privacy/order.

Final local ledger: canonical `npm run verify` passed with TERM=xterm-256color, COLORTERM=truecolor, NO_COLOR unset and NMSH_TEST_TMPDIR=/Volumes/T7Tmp/ai-dev. The longer T7 path's two unchanged test failures were reproduced on exact dev and resolved by the shortest compliant root, without test changes. Fixed two-round/two-worker PTY stress passed; original source fails the controlled approval-enqueue assertion and corrected source recovers exactly once with Ctrl+S. Independent findings are addressed. Completion retains review-only typing rather than losing it; combined submissions are guarded after the real editor/action parser; merely likely hidden ownership never releases held bytes. Hosted results belong to the PR checkpoint. No automatic merge.
30 changes: 30 additions & 0 deletions docs/superpowers/specs/2026-10-28-input-ownership-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Ambiguous Enter ownership

Approved by the maintainer in this session, including explicit confirmation for ambiguous Enter.

Echo-visible evidence permits draft editing, not reader delivery. If a look resolves visible with no reader and the held keys include Enter, capture the entire draft and keys in the existing ownership hold, clear the composer, and require a user choice. Later visible/likely evidence never forwards it. Ctrl+S sends once only while the same command is live; Ctrl+Q explicitly queues after reviewable echo evidence; Tab reveals editing keys without final Enter; Esc/Ctrl+C discard. No approval-queue entry is recovered automatically. Unknown/hidden input remains private.

Completion/done retains the capture in the existing prompt hold for Tab/Esc review, with delivery invalidated. A different command, terminal ownership changes and shutdown invalidate pending delivery; stale asynchronous decisions do nothing. Native passthrough cancels the ambiguous capture before handing over rather than delaying the terminal UI or delivering old bytes. This is a conservative builder decision under the approved owner-change requirement. Existing non-ambiguous reader routing remains unchanged. No wire protocol/detector changes or new dependencies.

Alternatives: automatic late recovery from likely evidence is rejected because echo and likely reads are not proof of ownership. Sending service-owned approval entries would need a separate guarded removal/send transaction, so is deferred.

Validation: deterministic old-source red/corrected-source green with real key routing, controlled real-PTY immediate/delayed line and password reads, non-reader/false-positive/unknown/completion/order/queue/cancellation coverage, independent review, canonical verification and exact-head hosted CI. Physical Ghostty/Zed remains NOT RUN.

## State transitions

| Current state | Evidence or action | Result |
|---|---|---|
| First-key lookup hold | Echo visible, no Enter | Real composer edits may replay; echo is presentation evidence only |
| First-key hold including Enter | Real editor parses a known NMSh slash action | Existing NMSh action path; no program answer |
| Replayed program Enter / separate Enter lookup | No reader or merely likely reader | Capture entire draft into confirmation quarantine; no approval entry |
| Ordinary lookup hold | Merely likely hidden reader | Confirmation quarantine, including unfinished typing; nothing drawn or delivered |
| Ordinary lookup hold | Confirmed reader / authenticated native owner | Existing same-command routing; keys remain ordered |
| Confirmation quarantine | Any later lookup/request | Retain capture; no automatic delivery |
| Confirmation quarantine | Ctrl+S, same command live | Send captured bytes once, in typed order; clear capture |
| Confirmation quarantine | Tab / Ctrl+Q | Queue-composer review; final Enter is removed; new Enter is explicit queue intent |
| Confirmation quarantine | Done / prompt return | Existing prompt hold, hidden and review-only; sending permanently invalidated |
| Pending confirmation | New exec / native terminal handover / shutdown / detach | Discard pending capture before new owner receives typing |
| Prompt hold | Tab / Esc / Ctrl+C | Review without submission / discard; no later program receives it |
| Existing approval entry | New reader evidence | Existing quarantine semantics; never recovered automatically |

The submission guard runs after the real editor and NMSh action parser; no duplicate editor or slash parser was introduced. Queue-review drafts are excluded from later reader auto-transfer. The detector and wire protocol remain unchanged. Source review identified and tests reproduced the submitted-command passthrough callback bypass, stale queue-review draft transfer, and combined slash-action interception; the final boundaries cover each.
Loading
Loading