Skip to content

fix(cli): the six residual pasteable-hint sites must survive a real shell - #894

Merged
Kyzcreig merged 2 commits into
mainfrom
daedalus-opus/t_e587758d-residual-hint
Sep 23, 2026
Merged

Kyzcreig merged 2 commits into
mainfrom
daedalus-opus/t_e587758d-residual-hint

Conversation

@Kyzcreig

@Kyzcreig Kyzcreig commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

fix(cli): the six residual pasteable-hint sites must survive a real shell

Residual of the #889/#891 unreachable-remedy class. Eight sites across six
subsystems interpolated a HERMES_HOME-derived path -- or an interpreter or
executable path resolved under one -- bare into a backticked span the operator
is told to paste. For a home holding a space (Google Drive's "My Drive", or
the Windows C:/Users/ default where a space is the NORM) the
printed remedy does something other than what the message says.

Measured before the fix, each through its REAL printer under a real spaced
HERMES_HOME, with the printed span handed to a REAL /bin/bash:

self_repo_guard git clone --shared '' /t_123
-> ['git','clone','--shared','',
'/tmp/.../My','Drive/hermes/scratch/t_123']
#889 fixed {root} and left {scratch} bare in the SAME span.

whatsapp adapter cd && install
-> bash rc=127: /tmp/.../My: No such file or directory
(refuses outright; the remedy cannot even start)

runtime-parity git -C log --oneline HEAD...fork/main
-> ['git','-C','/tmp/.../My','Drive/.../hermes-agent', ...]

doctor / run.py <sys.executable> -m pip install ...
-> ['/tmp/.../My','Drive/venv/bin/python','-m','pip', ...]

run.py skills hermes skills install official/My Category/demo-skill
-> [...,'official/My','Category/demo-skill']

plugins_cmd x2 hermes plugins install --force --ref
-> [...,'file:///tmp/.../My','Drive/.../demo-plugin', ...]

Routed each through hermes_cli.cli_hint.hint_value, the choke point #889
established. Import direction was checked per file; five import hermes_cli
directly. staging/scripts/runtime-parity-check.py cannot: it deploys STANDALONE
to ~/.hermes/scripts/ and runs under /usr/bin/python3, where hermes_cli is not
importable (verified), so it carries a verbatim local copy with a test pinning
it to the shared implementation over six token shapes.

TESTS drive the REAL print path and judge with a REAL shell; no assertion is on
the string's shape, and the paste is never simulated with shlex (the tautology
the grandparent card was blocked for). The whatsapp span is a COMPOUND command
(cd X && Y install), not a word list, so printf would execute rather than lex
it -- that oracle instead RUNS the span and has the callee report the argv and
cwd bash actually handed it.

Verified:
tests/test_residual_cli_hint_pasteable.py 12 passed
mutation: 10 mutants, 10 KILLED -- each of the 8 sites reverted individually
reds its OWN assertion; M10 (always-quote) reds the three readable-form
guards, proving the over-fix control bites
adjacency: 468 passed across test_self_repo_guard, test_terminal_task_cwd,
test_plugins_cmd, test_plugin_install_ref, test_doctor, test_voice_command,
test_cli_hint, test_whatsapp_send_message_media
staging/tests/test_pending_restart_redrive.py green under /usr/bin/python3,
confirming the standalone shim does not break the real deploy path
ruff 0.15.20 clean; git diff --check clean

#889 has MERGED (fb52b05); this is rebased onto fork/main and stands alone.

Card: t_e587758d


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…hell

Residual of the #889/#891 unreachable-remedy class. Eight sites across six
subsystems interpolated a HERMES_HOME-derived path -- or an interpreter or
executable path resolved under one -- bare into a backticked span the operator
is told to paste. For a home holding a space (Google Drive's "My Drive", or
the Windows C:/Users/<First Last> default where a space is the NORM) the
printed remedy does something other than what the message says.

Measured before the fix, each through its REAL printer under a real spaced
HERMES_HOME, with the printed span handed to a REAL /bin/bash:

  self_repo_guard   git clone --shared '<root>' <scratch>/t_123
                    -> ['git','clone','--shared','<root>',
                        '/tmp/.../My','Drive/hermes/scratch/t_123']
                    #889 fixed {root} and left {scratch} bare in the SAME span.

  whatsapp adapter  cd <bridge> && <npm> install
                    -> bash rc=127: /tmp/.../My: No such file or directory
                    (refuses outright; the remedy cannot even start)

  runtime-parity    git -C <TREE> log --oneline HEAD...fork/main
                    -> ['git','-C','/tmp/.../My','Drive/.../hermes-agent', ...]

  doctor / run.py   <sys.executable> -m pip install ...
                    -> ['/tmp/.../My','Drive/venv/bin/python','-m','pip', ...]

  run.py skills     hermes skills install official/My Category/demo-skill
                    -> [...,'official/My','Category/demo-skill']

  plugins_cmd x2    hermes plugins install <source> --force --ref <sha>
                    -> [...,'file:///tmp/.../My','Drive/.../demo-plugin', ...]

Routed each through hermes_cli.cli_hint.hint_value, the choke point #889
established. Import direction was checked per file; five import hermes_cli
directly. staging/scripts/runtime-parity-check.py cannot: it deploys STANDALONE
to ~/.hermes/scripts/ and runs under /usr/bin/python3, where hermes_cli is not
importable (verified), so it carries a verbatim local copy with a test pinning
it to the shared implementation over six token shapes.

TESTS drive the REAL print path and judge with a REAL shell; no assertion is on
the string's shape, and the paste is never simulated with shlex (the tautology
the grandparent card was blocked for). The whatsapp span is a COMPOUND command
(`cd X && Y install`), not a word list, so printf would execute rather than lex
it -- that oracle instead RUNS the span and has the callee report the argv and
cwd bash actually handed it.

Verified:
  tests/test_residual_cli_hint_pasteable.py       12 passed
  mutation: 10 mutants, 10 KILLED -- each of the 8 sites reverted individually
    reds its OWN assertion; M10 (always-quote) reds the three readable-form
    guards, proving the over-fix control bites
  adjacency: 468 passed across test_self_repo_guard, test_terminal_task_cwd,
    test_plugins_cmd, test_plugin_install_ref, test_doctor, test_voice_command,
    test_cli_hint, test_whatsapp_send_message_media
  staging/tests/test_pending_restart_redrive.py green under /usr/bin/python3,
    confirming the standalone shim does not break the real deploy path
  ruff 0.15.20 clean; git diff --check clean

Stacked on #889 (hint_value lands there); do not merge before it.

Card: t_e587758d
@Kyzcreig
Kyzcreig force-pushed the daedalus-opus/t_e587758d-residual-hint branch from c113b32 to 4eee812 Compare September 23, 2026 02:10
…uplicated span can't hide a revert

Review finding (argus, run 7285): plugins/platforms/whatsapp/adapter.py:626
was UNGATED. Reverting only that site left the committed suite at 12-passed
while the remedy genuinely broke under a real bash.

Root cause is a CLASS, not that one site. The class guard asserted
`needle in source` -- PRESENCE. :612 (returncode arm) and :626
(except Exception arm) carry BYTE-IDENTICAL spans, so reverting one leaves
the needle present and the guard green.

Class sweep over EVERY expectation needle (needle_sweep.py), counting
occurrences per file. Exactly two needles have count>1:

  2  plugins/platforms/whatsapp/adapter.py  'cd {hint_value(str(bridge_dir))} && {hint_value(_npm_bin)} install'
  2  hermes_cli/plugins_cmd.py              'hermes plugins install {recorded_source} --force'

plugins_cmd already carried a behavioural test on both sites; whatsapp
covered :612 only. Both are now covered two ways:

- the whatsapp paste oracle is parametrized over both reachable arms.
  [exception] drives the `except Exception` branch (OSError, patched only
  across connect() so the oracle's own subprocess calls stay real) and
  judges the printed span with the same real /bin/bash.
- the class guard asserts an expected COUNT per needle, not presence, so
  reverting one of a duplicated pair is visible for every needle in the
  table -- not just the two that happen to be duplicated today.

Verified:
- suite 12 -> 13 passed (tests/test_residual_cli_hint_pasteable.py)
- mutation, 4 mutants each reverting ONE occurrence of a duplicated span:
  4/4 KILLED (was: :626 SURVIVED). Files restored byte-identical (sha256).
- the behavioural gate specifically: revert ONLY :626 with the class guard
  DESELECTED -> rc=1, exactly
  test_..._pastes_as_one_dir_and_one_binary[exception] FAILED,
  "bash refused ...: cd: too many arguments". Not a count-assert artifact.
- adjacency by changed symbol: 276 passed, 1 skipped over 6 suites
- ruff 0.15.20 clean; git diff --check clean
- `pytest plugins/ -k whatsapp` collection errors are INHERITED (identical
  with this diff stashed) and are mem0 capture_* imports, unrelated.

Diff is one test file, +58/-25. No implementation file touched.
@Kyzcreig
Kyzcreig force-pushed the daedalus-opus/t_e587758d-residual-hint branch from 0f55a7d to 1e1f0a3 Compare September 23, 2026 03:00
@Kyzcreig

Copy link
Copy Markdown
Collaborator Author

🤖 merged-by: apollo · lane: landing-stack · gate: BYPASS: FleetReview DISABLED by operator (Ace 09:30 PT, 'Fleet reviews currently paused'); landing on kanban approval + green CI per Ace 19:30 PT 'handle all of these yourself until landed and merged'. · why: t_e587758d APPROVED r2 EXECUTION (Argus): 6 measured remedy groups / 8 sites routed through cli_hint.hint_value; round-2 closed the ungated whatsapp/adapter.py:626 site. CI 38/0 CLEAN on 1e1f0a3, verified via check-runs API.

@Kyzcreig
Kyzcreig added this pull request to the merge queue Sep 23, 2026
Merged via the queue into main with commit e1de835 Sep 23, 2026
54 checks passed
@Kyzcreig
Kyzcreig deleted the daedalus-opus/t_e587758d-residual-hint branch September 23, 2026 04:29
Kyzcreig added a commit that referenced this pull request Sep 26, 2026
Reverts e1de835. Fork-PR audit UNRESOLVED ruling (t_63023f77,
#1186): the trigger is whitespace in a
home/interpreter/skill-category/plugin path; measured 0 occurrences on
both fleet hosts, so the hints never needed quoting here. The gateway/run.py
hunk conflicted in all 3 upstream syncs.

Kept: #889's hermes_cli.cli_hint.hint_value and its callers (KEEP row).
gateway/run.py conflict resolved by keeping current main's
_skill_slug_index loop and dropping only the hint_value() wrap.

Card: t_ceb111f9
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