Skip to content

fix(*): close the Mirasim preset nits that still apply - #1153

Open
LivXue wants to merge 8 commits into
mainfrom
fix/mirasim_preset_followups
Open

LivXue wants to merge 8 commits into
mainfrom
fix/mirasim_preset_followups

Conversation

@LivXue

@LivXue LivXue commented Oct 30, 2026

Copy link
Copy Markdown
Member

Summary

Closes #994, the thirteen nits the review of #971 left behind. Nine
apply to the tree today and are fixed here; one is already enforced on
main; three name code the Mirasim host rewrite removed.

Fixed:

  • Items 1 and 10, prompt text: adjacent text blocks now have a blank
    line between them, the way Raven's own ACP server joins them, while a
    text block beside a resource keeps the single newline it had. A prompt
    carrying a NUL or an unpaired surrogate is refused with a protocol
    error naming the prompt, instead of failing while the frame is sent.
  • Item 6, preset expansion: _launchable reads BUNDLED_SHIM_PRESETS
    instead of inferring a bundled shim from {PYTHON} in the command.
  • Item 7, MCP withholding: a Mirasim row is told the host takes no
    per-session servers, rather than to set sessionMcp true "once it
    isolates".
  • Item 8, docs: both integration pages name mirasim_presets.py.
  • Item 9, integration test: the startup backfill stubs
    _unconfigured_acp_preset_rows, so it cannot handshake a real Mirasim
    installed on the machine.
  • Item 11, ui-web model pick: the pick is cleared once the connect
    lands, and an add no longer sends a model the row's menu has dropped.
  • Item 12, ui-web mark: the family picker row now sizes both > img
    and > svg marks.
  • Item 13, catalogue: a route-prefixed id that an entry already takes is
    reported as a warning instead of dropped silently.

Item 5 is already enforced on main:
test_a_rows_budgets_cover_the_adapters_own_slowest_answers pins
readyTimeoutMs and the adapter's own limits.

No longer applicable: items 2, 3 and 4 referred to uicli.py (staged
arguments, a temporary directory, a version() subprocess), which the
Mirasim host rewrite removed. Prompts now travel over JSON-RPC.

Type

  • Fix
  • Feature
  • Docs
  • CI / tooling
  • Refactor
  • Other

Verification

  • uv run --no-sync pytest tests/test_acp_mirasim_input.py
    tests/test_acp_mirasim_catalog.py tests/test_subagent_mirasim.py
    tests/test_subagent_acp_mcp_lifecycle.py -q -n 0: 102 passed, 2
    skipped.

  • uv run --no-sync pytest tests/test_acp_mirasim_server.py -q -n 0
    with -k "not test_a_turn_stopped_from_the_app_ends_cancelled": 111
    passed, 3 failed, 1 deselected. The same command at origin/main
    gives 110 passed and 4 failed, the 3 head failures a subset of the
    base's set; the deselected test hangs at the base too. Both are this
    Windows host, not the changes.

  • tests/test_subagent_third_party.py and
    tests/test_rpc_subagents.py: 447 passed and 15 failed; the sorted
    failing ids are identical at origin/main.

  • tests/test_acp_mirasim_host.py, store.py, stream.py,
    interactions.py: 30, 9, 31 and 18 passed (3 Unix-socket skips).

  • tests/integration/test_research_subagent_smoke.py -m integration
    with -k statefulness: 1 passed.

  • tests/test_living_docs.py: 2 passed.

  • Mutation pass, one construct at a time, each reverted piece failing
    its test: the blank-line join, the surrogate refusal, the declared
    preset expansion, the Mirasim MCP branch, the catalogue warning, the
    ui-web pick clearing, the ui-web menu guard, and the CSS svg rule.
    Every file was restored and compared byte for byte.

  • ui-web, in ui-web/: npm test 263 files / 4520 passed; lint 0
    errors (4 pre-existing warnings);
    npx tsc --noEmit -p tsconfig.json; npm run build;
    python ui-web/build.py; check-page.mjs, check-css.mjs,
    check-class-namespace.mjs.

  • Repository gates: commitlint for each commit,
    check_commit_messages.py, check_source_language.py,
    check_large_files.py, and pre-commit run over the branch: all
    pass. ruff check, ruff format --check; ty reports only the two
    existing url2pathname deprecation warnings in server.py.

  • Not run: the full Python suite; CI runs on the pull request.

  • Relevant tests pass locally

  • Relevant lint / type checks pass locally

  • User-facing docs or screenshots are updated when needed

Risk

  • Prompt text: a multi-block ACP client now sees a blank line between
    text blocks; a text block beside a resource is unchanged. NUL and
    unpaired surrogates are refused, and neither is legitimate prompt
    text.

  • Preset expansion: every shipped preset behaves as before. Only a
    non-bundled preset whose command spells {PYTHON} would stop being
    expanded, and none exists.

  • ui-web: a picked model is dropped after a successful connect, when the
    row holds it, and a stale pick is not sent; that add runs the agent's
    default instead of being refused.

  • CSS: an svg mark in the family picker is now 19px; no current preset
    ships one.

  • Security impact considered: none; no path or credential handling
    changes.

  • Backward compatibility considered: the prompt separator is the only
    wire-visible change.

  • Rollback path: revert the branch.

  • Security impact considered

  • Backward compatibility considered

  • Rollback path is clear for risky changes

Related Issues

Closes #994

…ot carry

Two text blocks reached the host with no separator, and a lone surrogate
failed at send time as an internal error. Adjacent text blocks now have a
blank line between them, while a text block next to a resource keeps the
single newline it had. NUL and unpaired surrogates are refused with a
protocol error naming the prompt.
_launchable inferred a bundled shim from the command containing {PYTHON},
which CONTEXT.md retires. BUNDLED_SHIM_PRESETS now decides which rows get
Raven's interpreter; a command that happens to spell the placeholder no
longer qualifies.
A Mirasim row declares sessionMcp false because the host takes no
per-session servers. It was told to set sessionMcp true "once it isolates",
which that host cannot do. The note now names the host and its limit.
A catalog listing own:sonnet beside sonnet lost the colliding copy
silently. The collision is now logged as a warning naming the id.
The integration test let _unconfigured_acp_preset_rows probe whatever
Mirasim reported installed on the machine. It is stubbed to nothing, as
the unit tests already do.
The English and Chinese pages listed only presets.py and
acp_registry_presets.py; the Mirasim rows live in mirasim_presets.py.
The pick held for a preset survived the add that wrote the row, so a later
disconnect showed a stale model. It is cleared once the connect lands, and
an add no longer sends a model the row's menu has dropped.
The picker row sized only > img where the other three mark slots size
> img, > svg. A new gate keeps the two shapes in step.
@LivXue
LivXue requested review from 0xKT and gloryfromca October 30, 2026 16:51

@gloryfromca gloryfromca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers; this can merge as far as I am concerned.

I reviewed the full github/main...HEAD diff and the surrounding callers and history for prompt conversion, Mirasim catalog routing, preset expansion, MCP withholding, startup backfill, and the web family picker. I also checked AGENTS.md/CLAUDE.md, CONTEXT-MAP.md and the relevant ACP/Web UI architecture context, backward compatibility, and that the added tests exercise the changed behavior rather than weakening existing assertions.

Verification run on this revision:

  • uv run pytest tests/test_acp_mirasim_input.py tests/test_acp_mirasim_catalog.py tests/test_subagent_mirasim.py tests/test_subagent_acp_mcp_lifecycle.py -q -n 0: 104 passed.
  • uv run pytest tests/integration/test_research_subagent_smoke.py -m integration -k statefulness -q -n 0: 1 passed, 1 deselected.
  • npm test -- --run src/features/extAgents/store.test.ts scripts/gates/ext-agents-mark-css.test.mjs: 2 files / 21 tests passed.
  • Source-language and large-file gates over github/main..HEAD: passed.
  • uv run pytest tests/test_living_docs.py -q -n 0: 2 passed.

The initial Python attempt failed before collection because the fresh worktree environment lacked the declared everos-memory dev extra; after uv sync --frozen --extra dev --dev, the unchanged test command passed as reported above. make itself is unavailable on this runner, so I invoked the two gate scripts with their Makefile-equivalent uv commands.

@LivXue

LivXue commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

Windows compatibility review

Reviewed 9d9bec90..1d7f72bff (15 files, +198/−20) at head 1d7f72bffc8e9ae1771c37e67a9538a1c317be82.

Findings (Windows): none. This is display, prompt-validation, and preset-gating work; I found no platform-specific change to paths, process creation, encoding, or packaging that misbehaves on Windows.

Checks

  • raven/agent/subagent/presets.py::_launchable now expands {PYTHON} only for BUNDLED_SHIM_PRESETS == MIRASIM_SHIM_PRESETS. Verified on the head tree that the only preset command containing {PYTHON} is raven/agent/subagent/mirasim_presets.py:68 ({PYTHON} -P -m raven.acp.mirasim --agent {agent}) and that every Mirasim shim row is a member, so no shipped row loses expansion. resolve_subagent_command (raven/utils/commands.py:202, quote=True) is unchanged, so the interpreter path is quoted exactly as before on Windows. INSTALLED_QUERY and manifest-driven {PYTHON}/{SUBAGENT_DIR} substitution (raven/templates/agents_scaffold/install.py, other resolve_subagent_command callers) sit outside this gate.
  • raven/acp/mirasim/server.py::read_prompt's refusal of NUL and unpaired surrogates runs before serialization and is platform-neutral; joining adjacent text blocks with \n\n touches no file or console encoding.
  • raven/acp/mirasim/catalog.py's duplicate-id warning and raven/acp_client/acp_agent.py's withheld-MCP note are message-only; the ui-web changes are CSS sizing and store logic with no path/process semantics.

Verification (native Windows; detached worktrees D:/tmp/rv-1153 at head and D:/tmp/rv-base-9d9bec90 at base; uv sync --frozen --offline --all-extras --no-extra segmenter --dev; scratch HOME/USERPROFILE):

  • uv run --no-sync pytest tests/test_acp_mirasim_catalog.py tests/test_acp_mirasim_input.py tests/test_subagent_acp_mcp_lifecycle.py tests/test_subagent_mirasim.py tests/test_subagent_third_party.py tests/integration/test_research_subagent_smoke.py::test_the_startup_backfill_measures_statefulness_by_itself -q -n 0
    • head: 383 passed, 10 failed, 2 skipped; base: 377 passed, 10 failed, 2 skipped. The six added tests pass at head (383−377), and the 10 failing IDs are identical at base — all tests/test_subagent_third_party.py, the known Windows POSIX-fixture/process-group baseline — so they are inherited, not introduced here.
  • uv run --no-sync pytest tests/test_subagent_probe.py tests/test_config_loader.py tests/test_subagent_name_vocabulary.py -q -n 0 --tb=no: 31 failed / 177 passed / 4 skipped at head and at base, with byte-identical sorted FAILED ID lists (diff empty), so the preset-gating change adds no failure in the preset/probe/migration suites.

Coverage gaps

  • ui-web vitest, including the new ui-web/scripts/gates/ext-agents-mark-css.test.mjs, was not run: D:/projects/Raven/ui-web/node_modules is empty in this environment and vitest cannot resolve @vitejs/plugin-react. The gate and the store.ts pick-clearing logic were reviewed by reading only.
  • Existing Windows-only skips (Unix-socket tests) remain in these files and are unrelated to this PR.

@0xKT

0xKT commented Oct 30, 2026

Copy link
Copy Markdown
Member

Not a blocker (head 1d7f72bf merged onto main 9d9bec90). Two comments now say something the code no longer does. Behaviour is fine; this is wording only.

Severity of this one finding, not a verdict on the pull request. Any blocking findings from this pass are review threads on the changed files; GitHub renders those collapsed, as a file name with no text.

  1. raven/agent/subagent/mirasim_presets.py:80-82 still says the withheld note "gives isolation as its reason". With this PR, a Mirasim row gets its own note in acp_agent.py:1509-1513 ("runs on Mirasim's host, which takes no per-session servers"). Your new test test_a_mirasim_row_is_told_the_host_takes_no_per_session_servers pins that Mirasim wording. The file is not in this PR's diff, so the comment was left behind.
  2. tests/test_acp_mirasim_catalog.py:195: the docstring says "The literal entry wins". The assertion at :214 checks that own:sonnet is not offered at all, and the comment there says neither entry is offered. One of the two should change. As far as I can read _menu, the assertion is the true one.

Checked on the merged tree:

  • Changed Python tests via the board runner: all new tests pass. The 11 reds in test_subagent_mirasim.py / test_subagent_acp_mcp_lifecycle.py fail identically on main: the adapter child gets login_shell_env(), not the runner's PYTHONPATH.
  • Full ui-web vitest: 4520 passed. tsc clean.
  • Eight mutants, all killed:
    • the declared-set gate in _launchable;
    • the blank line between text blocks;
    • the surrogate refusal;
    • the NUL refusal;
    • the Mirasim MCP note;
    • the collision warning;
    • the pick cleared after a successful add;
    • the stale-pick menu check.

@gloryfromca

Copy link
Copy Markdown
Member

No blockers; suggestions only, and they are marked inline.

I agree with both wording mismatches in comment 6529142737: the preset comment still names isolation after this change gives Mirasim its host-specific reason, and the catalog test docstring says the literal entry wins while the assertion correctly keeps the contested spelling out of the menu. They are nonblocking documentation/test-description issues, so the code remains mergeable; they move my whole-record stance from clean to nonblocking.

Focused verification remains behavioral: uv run pytest tests/test_acp_mirasim_catalog.py::test_a_route_prefixed_id_that_collides_with_a_catalog_entry_is_reported tests/test_subagent_acp_mcp_lifecycle.py::test_a_mirasim_row_is_told_the_host_takes_no_per_session_servers -q -n 0 passed both tests.

@0xKT

0xKT commented Oct 30, 2026

Copy link
Copy Markdown
Member

Not a blocker - a correction to my note above (6529142737). It does not change the result.

Severity of this one finding, not a verdict on the pull request. Any blocking findings from this pass are review threads on the changed files; GitHub renders those collapsed, as a file name with no text.

I wrote that the 11 environment reds in test_subagent_mirasim.py / test_subagent_acp_mcp_lifecycle.py all come from the adapter child not seeing the runner's PYTHONPATH. I then read each failure, and that holds for 6 of them, not all 11:

  • 6 fail with the child's No module named 'raven'.
  • test_session_new_is_handed_a_live_bridge_endpoint fails because bridge_command() picked the raven installed on my machine instead of the test's build.
  • test_mcp_is_delivered_without_unix_sockets[...] (2) fails with IndexError.
  • The two stand-in-host timeouts I have not traced.

What does stand: all 11 fail the same way on main 9d9bec90 and on this PR's merged tree, so none of them is this PR's doing. Every test this PR added passes.

This branch has not been deployed

No deployments
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.

fix(*): thirteen nits left in the Mirasim presets after #971

3 participants