Skip to content

chore(engine): remove the lyrashield-local terminal TUI - #204

Merged
ecryptoguru merged 3 commits into
mainfrom
chore/remove-lyrashield-local-tui
Oct 8, 2026
Merged

ecryptoguru merged 3 commits into
mainfrom
chore/remove-lyrashield-local-tui

Conversation

@ecryptoguru

@ecryptoguru ecryptoguru commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Remove the lyrashield-local terminal TUI

Summary

Local mode launches as Desktop only. The terminal version of it, shipped as the
lyrashield-local console script, is therefore dead surface. This PR removes it.

Deleted:

  • lyrashield/tui — 6 Python files, 2,156 lines.
  • tests/tui — 6 files, 1,580 lines (5 test modules plus __init__.py).

Edited:

  • pyproject.toml — removed the lyrashield-local console script (was line 82) and the
    tests/tui/*.py Ruff per-file-ignore block (was line 412).
  • UPGRADES.md — line 109 named lyrashield/lyrashield-local as the shipped entry points.
    It now names only lyrashield.
  • tests/test_package_artifacts.py — asserted lyrashield/tui/app.py ships in the wheel and
    imports from it. Those assertions now cover lyrashield/interface/tui/app.py, the TUI that
    remains.
  • scripts/customer-branding-allowlist.json — dropped the 6 keys that exempted the removed
    files. The allowlist matches exact source lines per file, so leaving keys for deleted files
    would leave the allowlist asserting things about files that no longer exist.

Not touched, deliberately:

  • lyrashield/interface/tui — 22 files, 5,225 lines. It is the default interactive mode of the
    lyrashield CLI (lyrashield/interface/main.py:466-471 selects it whenever
    -n/--non-interactive is absent) and the founder kept it.
  • lyrashield/interface/tui/live_view.py — the viewer imports it at
    lyrashield/interface/viewer/transcript.py:56. It stays in place.
  • textual — still a base dependency. Moving it to an optional extra changes the CLI install
    story and is out of scope.
  • strix/** — untouched. The controlled-derivative footprint is unchanged.

Total: 16 files changed, 4 insertions, 3,769 deletions.

Per-change safety proof

git grep over the whole repository at the new head. Three patterns, all clean.

Nothing references the removed modules, the removed tests or the removed console script:

$ git grep -n -E "lyrashield[./]tui" -- lyrashield lyrashield_adapter strix tests \
    scripts pyproject.toml strix.spec Makefile .github containers .pre-commit-config.yaml
NONE

$ git grep -n -F "lyrashield-local"
NONE

$ git grep -n -F "tests/tui" -- lyrashield lyrashield_adapter strix tests \
    scripts pyproject.toml strix.spec Makefile .github containers
NONE

Searched surfaces: lyrashield, lyrashield_adapter, strix, tests, scripts,
pyproject.toml, strix.spec, Makefile, .github/**, containers/**,
.pre-commit-config.yaml, .trivyignore.yaml, docs/**, README.md, CONTRIBUTING.md,
uv.lock, benchmarks/**.

Two references existed before the change and are handled, not ignored:

  1. tests/test_package_artifacts.py asserted lyrashield.tui.app is importable from a built
    wheel, that lyrashield/tui/app.py is in the wheel and that it is in the sdist wheel. All
    three now point at lyrashield/interface/tui/app.py. This test is the reason the removal
    needed a code change and is the strongest proof that the wheel contents still cover a
    product TUI. It passes (see gates).
  2. scripts/customer-branding-allowlist.json carried 6 exact-line exemptions for the removed
    files. Removed with them.

The only surviving mentions of lyrashield/tui are in
docs/superpowers/plans/2026-09-25-deep-code-review.md and
docs/superpowers/plans/2026-09-25-engine-improvements-plan.md. These are dated working notes
from an earlier review that already quote drifted line numbers and reference paths that no
longer exist. They are not in docs/docs.json navigation and no code reads them. They are not
in this PR's scope and editing history to hide a deletion would be the wrong call.

The lyrashield binary is unchanged

Console entry points, before and after:

before: console_scripts :: lyrashield       -> lyrashield_adapter.cli:main
        console_scripts :: lyrashield-local -> lyrashield.tui:run_tui
after:  console_scripts :: lyrashield       -> lyrashield_adapter.cli:main

lyrashield is byte-for-byte the same entry point. The .venv/bin/lyrashield shim is present
and lyrashield --help runs. .venv/bin/lyrashield-local is gone, which is the point.

Frozen build. uv build --wheel succeeds and the wheel is checked directly:

  • lyrashield/tui/** — absent from the wheel.
  • lyrashield/interface/tui/** — 22 files present.
  • entry_points.txt — contains only lyrashield = lyrashield_adapter.cli:main.
  • The wheel's own import smoke (the same module list the packaging test uses) passes:
    lyrashield_adapter.cli, lyrashield.interface.main, lyrashield.interface.tui.app,
    lyrashield.interface.viewer.server, strix.interface.tui.runtime.

The PyInstaller spec needed no change and gets none. strix.spec never listed
lyrashield.tui — that module was never in the frozen release, which is consistent with the
sweep. Its lyrashield.interface.tui.app and lyrashield.interface.tui.renderers hidden
imports still resolve, every one of its 16 lyrashield.* hidden imports still resolves, and
its datas globs (skills/**/*.md, **/*.jinja, **/*.xml, **/*.tcss) surface no removed
path. A full pyinstaller build could not run here: PyInstaller requires objdump from
binutils, which is absent from this sandbox and not installable in it. That is environmental,
and it is why the wheel was inspected directly and the spec's imports were resolved instead.

No license or doctor expectation is lost

lyrashield-local shipped a doctor command whose only license check was
check_license_cache (lyrashield/tui/doctor.py:213-249). Its own docstring says what it
did: "The desktop shell owns the ed25519 license cache; the TUI only checks that a cached
license blob exists and is not expired. Full signature verification lives in the Tauri
license.rs module." It confirmed presence and minimum size, nothing more.

That check is not lost, because Desktop performs it. The Tauri side verifies the ed25519
signature — verify_license in apps/desktop/src-tauri/src/license/mod.rs:173, exercised by
the golden-vector tests in apps/desktop/src-tauri/src/license/golden_vectors.rs including the
tampered-blob signature_mismatch case — and it enforces expiry with an offline grace window
at apps/desktop/src-tauri/src/license/mod.rs:138-143. The engine now contains no license
check at all, so nothing in the engine depends on the removed path.

Tests added

No test was added, because this PR removes a feature rather than fixing one. There is no
regression to write: the behaviour being deleted is the behaviour that is gone.

What stands in for it is a test that had to change and therefore proves the removal landed
cleanly. tests/test_package_artifacts.py::test_wheels_exclude_go_inputs_and_retain_product_python_imports
builds the wheel and the sdist, asserts lyrashield/tui/app.py is present in both and imports
five product modules from the wheel. Before this PR that test pinned the removed module. It now
pins lyrashield/interface/tui/app.py, so the wheel is still asserted to carry a product TUI
and to import it. Left unedited, this test fails on the deletion, which is the failing state
that justified the edit.

tests/tui had 78 test cases. The suite drops from 3,087 to 3,009 collected cases, exactly the
78 removed, with no other change in count.

Gates run

All commands run in /agent/workspace/repos/eng-b at head 8f71a8f, with uv on PATH.

Gate Command Result
Sync uv sync --frozen exit 0, lyrashield-engine==1.2.1 reinstalled
Lint uv run ruff check . exit 0, "All checks passed!"
Format uv run ruff format --check . exit 0, 434 files already formatted (was 446; exactly the 12 removed files)
Types uv run mypy strix lyrashield_adapter lyrashield exit 0, "Success: no issues found in 244 source files" (was 250; exactly the 6 removed modules)
Security uv run bandit -r strix lyrashield_adapter lyrashield -q -c pyproject.toml exit 0, nosec-comment warnings only, identical to baseline
Tests pytest (full suite, split into three disjoint chunks so each fits the sandbox's 120 s per-command cap) 3001 passed, 6 skipped, 2 failed
Branding python scripts/verify-customer-branding.py exit 0, "Customer branding gate passed (exact compatibility allowlist)."
Derivative scripts/verify-controlled-derivative.sh strix invariants pass: "Footprint: 4 files, +22/-201 lines (maximum: 4 files, +22/-201)" and the reviewed patch digest matches. See the note below.

Both failures are environmental and both are present at baseline. make is absent from this
sandbox, so tests/test_quality_environments.py::test_precommit_and_make_run_the_same_type_check
fails on its shutil.which("make") assertion. tests/test_local_sources.py::test_clone_repository_checks_out_a_full_commit_sha_detached
fails in the guarded-clone path. Neither reads any file this PR touches and both fail
identically at baseline 93b5517.

Baseline comparison, same three chunks and the same environment (uv on PATH) at 93b5517:
3079 passed, 6 skipped, 2 failed — the same two environmental failures. The counts
reconcile exactly: 3079 - 3001 = 78, which is precisely the 78 test cases in tests/tui that
this PR removes. Skipped and failed are unchanged.

scripts/verify-controlled-derivative.sh note. The script's tail runs uv sync --frozen --extra viewer, Ruff, format, the whole pytest suite, mypy and bandit. The full script exceeds
this sandbox's 120 s per-command cap, so it timed out here partway through its pytest step with
every test it had reached passing. Its deterministic part — the upstream base fetch, the
strix/** allowlist diff, the footprint ceiling and the reviewed patch digest — was run
directly and passed. The five gates the script invokes were then each run individually above
and all pass except the environmental make failure. This is an environmental limit of the
sandbox, not a result of the change: the script's strix/** invariants are unaffected by a
lyrashield/** deletion and the digest check confirms that.

PROTECTED

Protected item How it was proved intact
Engine dependency caps (openai, litellm, openai-agents, cryptography) pyproject.toml dependency block untouched. uv.lock unchanged (git status clean on it).
strix/** footprint (4 files, +22/-201) Untouched. The derivative gate prints "Footprint: 4 files, +22/-201 lines" and the reviewed patch digest matches.
scripts/verify-controlled-derivative.sh passes Its strix invariants pass as above; the gates it invokes pass individually.
ENGINE_REVISION in workflows and .lyrashield-worker-pin No workflow file and no pin file is in this diff. No pin was bumped.
Registered Tauri commands and plugins No Tauri file is in this diff.
Local billing path No billing file is in this diff.
Published package exports The wheel builds, its entry_points.txt carries only lyrashield and the wheel import smoke passes.
Public badge and OG no-store caching No web file is in this diff.
SCA advisory cache upserts No web file is in this diff.
Platform-admin checks, affiliate clawback, license issue route, buildScorecardPayload, WORKSPACE_SCOPED_MODELS No web file is in this diff.
Social-portrait images, webhook recovery tooling No web file is in this diff.
packages/myra, RLS policies, Myra migration area No web file is in this diff.

Additionally, the two things this PR could most easily have broken were checked directly:

  • The interface TUI still works as the CLI's default mode: 22 files present, live_view.py
    present, lyrashield/interface/main.py:466-471 still selects run_tui(args) when
    --non-interactive is absent and its dedicated tests (test_tui_product_runtime.py,
    test_proxy_renderer.py, test_shell_renderer.py) pass.
  • The viewer still reaches its projection: lyrashield/interface/viewer/transcript.py:56 still
    imports lyrashield.interface.tui.live_view and test_viewer.py passes.

Not done

  • No test was added. Explained under "Tests added": this is a deletion, so there is no new
    behaviour to pin. The one test that had to change is the acceptance check.
  • textual was not moved to an optional extra. The brief puts this out of scope and it
    would change the CLI install story. Note for a later pass: after this PR keyring is
    declared in pyproject.toml with no importer left in the engine — the removed
    lyrashield/tui/results_store.py and lyrashield/tui/byok_config.py were its only users.
    cryptography is unaffected: lyrashield/runtime/target_relay_proxy.py still imports it, so
    the declared cryptography cap is still load-bearing. Dropping keyring was not requested and
    would be a separate dependency decision, so it was left alone.
  • docs/superpowers/plans/*.md were not edited. They are dated historical working notes
    that already reference paths that do not exist. Rewriting them to hide this deletion would
    misrepresent history.
  • No PyInstaller build. Environmentally blocked by the missing objdump/binutils. The
    wheel was inspected directly and the spec's hidden imports were resolved instead.
  • No pull request. The branch is pushed and this body is the deliverable; the orchestrator
    opens the PR as a draft.

Rollback

Revert this PR. Nothing here is forward-only: no schema change, no migration, no pin bump, no
data change. Reverting restores lyrashield/tui, tests/tui, the console script, the Ruff
per-file-ignore block, the allowlist keys and the UPGRADES.md line and returns the tree to
baseline 93b5517.

One caveat for anyone who already installed from this branch: uv sync --frozen after a
revert restores the lyrashield-local console script, so no manual cleanup is needed.

Generated with Claude Code

Summary by CodeRabbit

  • Removed Features
    • The local guided-scan interface and its lyrashield-local command are no longer available.
    • Local interface features—including provider setup, credential checks, scan progress and findings, saved scan results, report exports, and diagnostic checks—have been removed.
  • Documentation
    • Clarified that the retained upstream target-classification interface cannot be reached through the shipped lyrashield entry point.

Local mode launches as Desktop only, so the terminal version of it is dead
surface. Remove lyrashield/tui (6 files, 2156 lines) and tests/tui (6 files,
1580 lines), drop the lyrashield-local console script from pyproject.toml, drop
the now-empty tests/tui Ruff per-file-ignore block and fix the UPGRADES.md line
that named the removed entry point.

The interface TUI at lyrashield/interface/tui stays. It is the default
interactive mode of the lyrashield CLI and the founder kept it. Its live_view.py
stays too because the viewer imports it. textual stays a base dependency so the
CLI install story does not change.

tests/test_package_artifacts.py asserted lyrashield/tui/app.py ships in the
wheel and imports from it. That assertion now covers
lyrashield/interface/tui/app.py, the TUI that remains.

The six dead keys under scripts/customer-branding-allowlist.json that exempted
the removed files are dropped so the exact-line allowlist keeps matching real
files only.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6a6a4948-2910-4428-8133-52e2c0211805
📥 Commits

Reviewing files that changed from the base of the PR and between a591155 and 1d48a21.

📒 Files selected for processing (16)
  • UPGRADES.md
  • lyrashield/tui/__init__.py
  • lyrashield/tui/app.py
  • lyrashield/tui/byok_config.py
  • lyrashield/tui/doctor.py
  • lyrashield/tui/results_store.py
  • lyrashield/tui/scan_flow.py
  • pyproject.toml
  • scripts/customer-branding-allowlist.json
  • tests/test_package_artifacts.py
  • tests/tui/__init__.py
  • tests/tui/test_app.py
  • tests/tui/test_byok_config.py
  • tests/tui/test_doctor.py
  • tests/tui/test_results_store.py
  • tests/tui/test_scan_flow.py
💤 Files with no reviewable changes (13)
  • tests/tui/test_scan_flow.py
  • scripts/customer-branding-allowlist.json
  • pyproject.toml
  • tests/tui/test_byok_config.py
  • lyrashield/tui/byok_config.py
  • lyrashield/tui/scan_flow.py
  • lyrashield/tui/init.py
  • lyrashield/tui/app.py
  • lyrashield/tui/doctor.py
  • tests/tui/test_doctor.py
  • tests/tui/test_results_store.py
  • lyrashield/tui/results_store.py
  • tests/tui/test_app.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The PR removes the legacy lyrashield.tui application, its supporting modules, and their tests. It removes the lyrashield-local project entry point and updates package artifact expectations, the branding allowlist, and one documentation statement.

Changes

Legacy TUI removal

Layer / File(s) Summary
Remove TUI scan support
lyrashield/tui/byok_config.py, lyrashield/tui/doctor.py, lyrashield/tui/results_store.py, lyrashield/tui/scan_flow.py, tests/tui/test_byok_config.py, tests/tui/test_doctor.py, tests/tui/test_results_store.py, tests/tui/test_scan_flow.py
Removes TUI configuration, doctor checks, encrypted results storage, scan execution and export support, and the tests for those modules.
Remove the TUI application entry
lyrashield/tui/__init__.py, lyrashield/tui/app.py, tests/tui/test_app.py, pyproject.toml
Removes the guided TUI, its public re-exports, the lyrashield-local script entry, and the TUI app tests. The Ruff per-file ignore for tests/tui/*.py is also removed.
Update package and repository references
tests/test_package_artifacts.py, scripts/customer-branding-allowlist.json, UPGRADES.md
Package artifact expectations use lyrashield.interface.tui.app. The branding allowlist removes the legacy scan-flow entry and adds lyrashield/skills/__init__.py. The documentation now names only the shipped lyrashield entry point in its unreachable-copy statement.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Other

Merge Risk: ⚪ Minimal · up to 1d48a

The legacy lyrashield-local command is retired as intended; the shipped lyrashield CLI and its default TUI remain available, with no concrete current workflow regression identified.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely identifies the primary change: removal of the lyrashield-local terminal TUI.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ecryptoguru
ecryptoguru marked this pull request as ready for review October 8, 2026 23:31
@ecryptoguru
ecryptoguru merged commit 250392e into main Oct 8, 2026
5 checks passed
@ecryptoguru
ecryptoguru deleted the chore/remove-lyrashield-local-tui branch October 8, 2026 23:41
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.

2 participants