Skip to content

fix(tui): hide eight dead settings and refuse flags the Python agent does not back - #60

Merged
zy1233 merged 1 commit into
test/tui-pty-settings-flags-probesfrom
fix/tui-dead-settings-and-flags
Oct 31, 2026
Merged

zy1233 merged 1 commit into
test/tui-pty-settings-flags-probesfrom
fix/tui-dead-settings-and-flags

Conversation

@zy1233

@zy1233 zy1233 commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

Acts on the two probes of #57 (plan decisions 8 and 14). An interactive zypi passes the Python agent no flag, and the agent ignores what goes over the ACP wire except the model and the yolo switch. So a part of the settings page and of --help did nothing, and --deny gave a false sense of safety (the agent still asked about a call that matched the rule, and never refused it). Now the page does not offer what changes nothing, and the start refuses what the agent does not back, with the reason. Python is not changed.

zypi (interactive start)
├── settings page            37 rows -> 29 rows
│     app/agent_settings.rs          UNBACKED: 8 keys, HIDE_UNBACKED = true
│     views/settings_modal/state.rs  setting_gated_off_by_agent() reads snapshot.hide_unbacked_settings
│                                    (false in PagerLocalSnapshot::default(): old fixtures see every row)
└── command line             21 flags -> exit 2 before anything starts
      pi-pager-bin/src/interactive_flags.rs   REFUSALS[21] + refused() + refusal()
      pi-pager-bin/src/main.rs                main(): ... version/doctor -> refuse_interactive_flags() -> start
      pi-pager/src/app/cli.rs                 19 of the 21 flags hidden from --help
 main()
   parse_cli()
   dispatch_python_print()          # -p keeps its own contract: it warns, it does not refuse
   dispatch_version / doctor
+  refuse_interactive_flags()       # only without -p and without a subcommand
   start the TUI

The eight settings: remember_tool_approvals, default_selected_permission, default_model, toolset.ask_user_question.timeout_enabled, fork_secondary_model, prompt_suggestions, hunk_tracker_mode, auto_update. The Models category goes with them. The code and the config.toml keys stay: default_selected_permission = "reject" still selects "Reject" in the first prompt (the one value that has an effect).

The 21 flags (the 19 hidden ones are also gone from --help): --allow, --deny, --verbatim, --output-format, --include-partial-messages, --json-schema, --reasoning-effort, --rules*, --system-prompt-override*, --worktree, --worktree-ref, --restore-code, --no-plan, --no-subagents, --agent, --agents, --tools, --disallowed-tools, --max-turns, --disable-web-search, --oauth. (* -p passes these two to the agent, so they stay in --help, with "-p only".) The hidden compatibility flags (--trust, --no-ask-user, --hunk-tracker-mode, --storage-mode, ...) stay accepted.

$ zypi --deny 'Bash(rm *)' --worktree w
error: zypi did not start. The Python agent does not support these flags:
  --deny (--disallowedTools): The Python agent gets no permission rules, so it does not refuse a call that matches. It asks about each tool call.
  --worktree (-w): The Python agent has no git worktree sessions.
Remove the flags and run zypi again. Run zypi --help to see the flags that work.
$ echo $?
2

Evidence

Built from this branch (debug zypi, Linux, WSL2), mock LLM, throw-away home. Before is the v0.7.0 binary with the probes of #57. After is the same probes against the new binary.

Flags (flags_probe.py, 63 cases):

Before (v0.7.0) After
the 21 flags and their other names (25 rows of the table) none changes the LLM call; --deny: question still asked; --worktree: toast, then the main checkout REFUSED, exit 2, one line with the reason (all 27 spellings run one by one, and all 21 in one start)
-m, --cwd, --debug, --always-approve family, --permission-mode, --session-id, positional prompt, hidden compatibility flags as in the table of #57 same rows, same results
-p hello --deny x --worktree w --max-turns 3 warns "has no effect with -p and was ignored" same three warnings, not refused
--version --deny x version version

Settings page (settings_probe.py): 37 rows -> 29 rows; headers Appearance, Mouse, Editor & Input, Agent & Approval, Advanced (Models is gone). The permission question, the cursor row and [models].default give the same results as before (Python and the wire are not touched).

Tests

  • pi-pager: 5,656 passed, 12 skipped (+5: 3 in app::agent_settings, 2 in settings_modal; one pins the 27 keys of the page with voice off). pi-pager-bin: 31 passed (+10: each flag found alone, other names, help order, message, table and --help agree). Run with scripts/tui_baseline.py test (nextest).
  • cargo check -p pi-pager -p pi-pager-bin --tests: no warning. tui_baseline.py gates: all pass (graph 970, leader 243, x.ai 297, grok agent 0).
  • PTY regressions against the new binary: smoke.py 23/23, exit_matrix.py 12/12, print_exit.py ok, resume_matrix.py 16 PASS / 0 FAIL.
  • ruff check ., ruff format --check ., scripts/tests (234 passed) on Windows.
  • The ratchets in scripts/tui_baseline.toml go up by the same numbers (5,651 -> 5,656; 21 -> 31). CHANGELOG.md: two entries under [Unreleased].

Merge Danger

Door: two-way. One revert brings back the old behaviour; a flag that must work again is one entry less in REFUSALS.

Blast Radius: the start of an interactive zypi and the settings page. Behaviour change: a script that starts an interactive zypi with one of the 21 flags now fails with status 2 (before: the flag did nothing). -p, the subcommands, the hidden compatibility flags, the Python packages and the config keys do not change.

Not in this PR (left as findings): /model <name> still saves a [models].default that the next start ignores; -m <unknown id> fails without a visible message; fork_secondary_model writes an xAI model id; the voice rows are xAI-only. The numbers in docs/baselines/tui.md are not changed here or in the docs PR (#64): that file records CI runs on main, so it gets the new numbers after the merge.

…does not back

An interactive zypi passes no flag to the Python agent, and the agent ignores what goes over the
ACP wire except the model and the yolo switch. So the settings page and the command line offered
things that did nothing. scripts/tui_pty/flags_probe.py and settings_probe.py measured it (plan,
decisions 8 and 14). This change acts on the measurement.

Settings page: eight settings are not offered (app/agent_settings.rs, UNBACKED): remember_tool_approvals,
default_selected_permission, default_model, toolset.ask_user_question.timeout_enabled,
fork_secondary_model, prompt_suggestions, hunk_tracker_mode, auto_update. The filter is the
existing setting_gated_off_by_agent, with a new gate hide_unbacked_settings (false in
PagerLocalSnapshot::default(), so old fixtures see every row; true in production). The Models
category goes with them. The page has 29 rows, was 37. The code and the config keys stay.

Command line: an interactive start with one of 21 flags (--allow, --deny, --verbatim,
--output-format, --include-partial-messages, --json-schema, --reasoning-effort, --rules,
--system-prompt-override, --worktree, --worktree-ref, --restore-code, --no-plan, --no-subagents,
--agent, --agents, --tools, --disallowed-tools, --max-turns, --disable-web-search, --oauth)
prints "error: zypi did not start." with one line for each flag (its reason and the way out) and
exits with status 2, before it starts anything (pi-pager-bin/src/interactive_flags.rs).
-p, the subcommands and the hidden compatibility flags do not change. 19 of the flags are
hidden from --help; --rules and --system-prompt-override stay, with "-p only", because -p passes
them to the agent.

Behaviour change: a script that starts an interactive zypi with one of these flags now fails.

Tests: +5 in pi-pager (5,656), +10 in pi-pager-bin (31). One test pins the table and --help
against each other. The ratchets in scripts/tui_baseline.toml go up by the same numbers.
CHANGELOG.md: two entries under [Unreleased].
@zy1233

zy1233 commented Oct 31, 2026

Copy link
Copy Markdown
Owner Author

Stack #66, bottom to top: #58, #59, #56, #57, #60, #61, #62, #63, #64, #65. One atomic squash merge (gh stack merge).

Position 5 of 10. Base: test/tui-pty-settings-flags-probes (#57). Head 67e1d5c -> 8ed04c7. The patch is the same (equal patch id). scripts/tui_baseline.toml merged without a conflict with the pi-sandbox suite of #59.

@zy1233
zy1233 merged commit cf5de08 into main Oct 31, 2026
8 of 14 checks passed
@zy1233
zy1233 deleted the fix/tui-dead-settings-and-flags branch October 31, 2026 03:17
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