Skip to content

Let no decline the restart prompts, and check attach's publication first - #217

Merged
myobie merged 1 commit into
mainfrom
agent/no-declines-and-attach-checks-first
Nov 4, 2026
Merged

myobie merged 1 commit into
mainfrom
agent/no-declines-and-attach-checks-first

Conversation

@myobie

@myobie myobie commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Two follow-ups from #216, as Factory decided. Both apply to attach's dead-session prompt and restart's running-session prompt (decision 0020).

1. no declines.

  • A lone n or no, in any case, now declines at a terminal and off one, and exits 0.
  • ask::declined is shared by both prompts through ask_consent.
  • Before this change only a lone n declined, as in Node (answer.toLowerCase() === "n"). At a terminal a typed no restarted the session; restart stopped a running one. Off a terminal, no counted as no answer and exited 1.
  • Words that only start with n still don't decline: nope, no thanks, n.
  • This departs from Node, which restarts on no. Decision 0020 has an addendum, parity.md a row, and divergences.toml two entries (side node, intended).

2. attach checks publication before it asks.

  • attach now refuses a revoked or unverifiable managed launch before Restart? [Y/n], as restart does since Leave a running session alone when restart's prompt gets no answer #216. So it never asks a question whose yes it would then refuse.
  • The refusal is the same with no answer, with y and with -r: exit 1, operation-revoked on stderr, no prompt, the record unchanged, no daemon started.
  • The restart parameters are now built before the prompt. That's safe because the record is checked unchanged under the locks before they're used.
  • The check under the locks stays, as the second look after the answer.
  • A dead managed session that isn't revoked still prompts and restarts.

Release note. no now declines pty attach's and pty restart's restart prompts, as n does. pty attach refuses a revoked managed session before asking whether to restart it.

Tests.

  • Unit, ask::tests:
    • a_lone_n_or_no_declines: n, N, no, No and NO decline. "", y, nope, no thanks and n don't.
    • consent_needs_an_answer_and_off_a_terminal_a_yes now counts no as a decline at a terminal and off one. Both prompts ask through ask_consent, so this covers both.
  • Conformance:
    • attach_no_restart::no_declines_the_restart_prompt: types no at a terminal, then pipes No. Each exits 0, the stored command doesn't run, and the record is kept.
    • restart_prompt::no_leaves_the_running_session_alone: types no at a terminal, then pipes NO. Each exits 0, and the same daemon keeps running.
    • Both fail on Node and are recorded as intended.
  • CLI, crates/pty/tests/publication_fence.rs:
    • attach_refuses_a_revoked_dead_session_before_asking: a managed session that ran once and ended, then had its binding revoked. Attach runs with no answer, with y and with -r.
    • attach_still_restarts_a_dead_managed_session_that_is_not_revoked: with y it prompts, restarts and runs the command again.

Measured on Linux at this head, based on main 79b96c30:

  • cargo test -p pty --no-fail-fast: all 47 test files ran. 478 passed and 1 failed: interactive::typing_filters_the_list_and_escape_clears_it, which fails in my checkout (the fuzzy filter matches the checkout path) and passes in CI.
  • cargo test -p pty-conformance --no-fail-fast against this head's binary: 699 passed, 0 failed.
  • scripts/conformance-both.sh attach_no_restart restart_prompt against the pinned Node build:
  • Controls:
    • Main's binary on the conformance cases fails the two no tests and passes the rest.
    • Main's code with this PR's publication_fence.rs fails attach_refuses_a_revoked_dead_session_before_asking, because it asks and then refuses. It passes attach_still_restarts_a_dead_managed_session_that_is_not_revoked, the unchanged behavior.

Two follow-ups from #216, as Factory decided.

A lone n or no, in any case, now declines attach's dead-session prompt
and restart's running-session prompt, at a terminal and off one, and
exits 0. The Node tool declines only on a lone n, so its no restarts; so
did ours. At a terminal a typed no restarted the session, and off one it
read as no answer and exited 1.

attach now refuses a revoked or unverifiable managed launch before its
Restart? [Y/n], as restart does, so it never asks a question whose yes
it would then refuse. The refusal is the same with no answer, with y and
with -r. The check under the locks before the respawn stays, as the
second look after the answer.

Decision 0020 gains two addenda, parity.md a row and the conformance
ledger two intended Node entries.
@myobie

myobie commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

Independent read GO at exact head 93b09606983b12b70c8f6ca96b66ad42fda338ec. All 9 checks are SUCCESS on this head and the PR is CLEAN.

Read:

  • no declines. The restart prompts of attach (dead session) and restart (running session) treated every line but a lone n as yes at a terminal, so typing the word no restarted the session. A decline is now a lone n or no, in any case, at a terminal and off one; it exits 0 and changes nothing. Longer answers such as nope, no thanks or n do not decline. Both prompts share the one rule through the consent helper, so the unit test covers both, and each has a conformance case that types no at a terminal and then pipes No or NO. This departs from Node, which declines only on a lone n; it is recorded in decision 0020 (addendum), a parity row and two intended divergence entries.
  • Refusal before asking. attach on a dead managed session now builds its launch parameters and checks the publication binding before it shows Restart? [Y/n], so a revoked or unverifiable launch is refused without a question whose yes it would then refuse; -r is refused the same way. It checks again under the locks after an answer, because an answer can take any time. This is the same order restart already uses.
  • Tests (publication fence): an ended managed session that was then revoked, with no answer, with y and with -r, exits 1 with operation-revoked, shows no prompt, leaves the record bytes unchanged, starts no daemon and does not rerun the command. An ended managed session that is not revoked still restarts on y. The author ran the full suite with --no-fail-fast (conformance 699 passed; the pty crate's one failure is a checkout-path test that passes in CI).
  • No wire-format change and no tier-1 file (events.jsonl, <id>.json, docs/disk-layout.md).

Release note: typing no at the attach or restart prompt now declines instead of restarting, and attach refuses a revoked managed dead session before asking.

Risks (low): the word no now declines even at a terminal, which differs from Node on purpose; a revoked dead session never shows the prompt.

@myobie
myobie merged commit 8dd3fd4 into main Nov 4, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant