Skip to content
This repository was archived by the owner on Aug 22, 2026. It is now read-only.

fix(tui): resolve PR #3 review findings — constant sync, username-mode strength-bar removal - #4

Merged
j-kemble merged 3 commits into
developmentfrom
feature/pr3-remediation-fixes
Aug 17, 2026
Merged

j-kemble merged 3 commits into
developmentfrom
feature/pr3-remediation-fixes

Conversation

@j-kemble

Copy link
Copy Markdown
Owner

Overview

Remediate the 6 actionable findings from PR #3 review rejection, plus a follow-up security recommendation: drop the meaningless entropy/strength bar from username mode entirely (usernames are not entropy-regulated).

Changes Made

Round 1 (3c79b72):

  • constants.py:70 — USERNAME_ALPHANUMERIC now lowercase-only, matching generator.py runtime value
  • tui_render.py:859 — MAX_PASSWORD_CHARS → MAX_USERNAME_LENGTH for username max-entropy (semantic fix; both equaled 64 but wrong constant)
  • tui.py:2066-2068 — stale comment updated: tui_render redefines state helpers locally, not aliases them
  • tests/test_constants_sync.py — new file: 16 assertions guarding constants.py ↔ generator.py drift

Round 2 (cd2e316):

  • tui_render.py:831-860 — dropped entropy computation + strength bar entirely from username mode; the displayed value was computed from passphrase state fields (wrong)
  • tests/test_constants_sync.py — removed dead SHARED_INTS dict; added trailing newline

Verification & Safety

  • Code Review Approved (review-APPROVED-pr3-remediation-fixes-20260817-0115.md) — covers round 1 (3c79b72)
  • Security Review Passed (security-PASSED-pr3-remediation-round2-20260817-1707.md) — covers both rounds incl. line-by-line round-2 verification (cd2e316)
  • pytest: 506 passed (main-repo venv, Python 3.11.15)
  • bandit: 0 issues (-ll)
  • mypy: 0 issues (tui_render.py, tui_helpers.py)
  • git diff --check: clean

Not included (deferred)

  • CLIPBOARD_AUTO_CLEAR_OPTIONS / AUTO_LOCK_OPTIONS duplication between tui.py and constants.py (deferred to constants single-source-of-truth migration)
  • Constants single-source-of-truth migration (scope risk for this round)
  • Hybrid identity enhancement (optional, not a regression fix)

Impact / Risks

  • Low risk; cosmetic UI change (username mode no longer shows a strength bar computed from wrong state fields)
  • No API, storage, or behavior changes
  • 4 files touched, 131 insertions, 36 deletions

…ntic, stale comment

- fix(constants): USERNAME_ALPHANUMERIC lowercase-only (was mixed-case)
- fix(tui_render): MAX_USERNAME_LENGTH for username strength bar (was
  MAX_PASSWORD_CHARS, which happens to equal 64 but is semantically wrong)
- fix(tui): stale comment says tui_render 'aliases' helpers when it now
  redefines them locally
- test: add test_constants_sync.py as a guard against future constant drift

Gates: pytest 490/490, bandit 0, mypy 0 (verified at fe8e532 baseline).
…not entropy-regulated)

- Guard the entropy computation, strength label, and strength bar with
  state.mode != "username" in _render_info_box()
- Move bits/label/kind/kind_attr computation inside the guard so
  _estimate_entropy_bits is never called with username mode
- Remove the else (username) branch from the max_bits computation
- Remove dead SHARED_INTS dict from test_constants_sync.py
- Add missing trailing newline to test_constants_sync.py
@j-kemble j-kemble added type: bug Security fix scope: tui TUI/curses interface changes status: ready-for-review Gates passed, awaiting reviewer risk: low Low risk — trivial or config-only change labels Aug 17, 2026
…ce-of-truth debt

Documents the two known-debt items acknowledged in the PR #3 remediation
round-2 review (review-APPROVED-pr3-remediation-round2-20260817-2217.md §6):
CLIPBOARD_AUTO_CLEAR_OPTIONS / AUTO_LOCK_OPTIONS are defined independently in
tui.py and constants.py (byte-identical, unguarded), and the intended fix is
a single-source-of-truth migration making generator.py and tui.py import from
constants.py. Cosmetic only; no behavior change.
@j-kemble
j-kemble merged commit 3e296a7 into development Aug 17, 2026
11 of 14 checks passed
j-kemble added a commit that referenced this pull request Aug 21, 2026
… wordlist, CSV/backup (#5)

* Add vault explorer filtering by service/username

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add vault credential editing support

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add s hotkey for saving generated credentials

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add live slash-based vault quick search

Co-Authored-By: Oz <oz-agent@warp.dev>

* Require double Esc to quit application

Co-Authored-By: Oz <oz-agent@warp.dev>

* Adjust README vault paths

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add duplicate-safe save flow for credentials

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add configurable security settings for clipboard and vault

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add note field to credentials

* Update WARP.md with note field support

* Update workflows to include development branch

* Update Python version requirements to include 3.14

* Fix failing test_parse_import_row_bitwarden_type_handling

* Add hidden note feature with encryption and hotkeys

- Add note_is_hidden column to credentials table for note visibility
- Add prompts for hiding notes when creating/editing credentials
- Show masked text for hidden notes in details view
- Add 'n' hotkey to copy note to clipboard
- Add 'h' hotkey to toggle note visibility
- Add 27 new tests for edge cases and new functionality
- Fix storage bugs with row.get() on sqlite3.Row

* Add comprehensive security suite: Bandit, pip-audit, mypy, pre-commit, Dependabot

Security improvements:
- Add Bandit security linting (SAST for Python)
- Add pip-audit for dependency vulnerability scanning
- Add mypy for static type checking
- Add pre-commit hooks with TruffleHog secrets detection
- Configure Dependabot for automated dependency updates
- Add reproducible builds support

Testing:
- Add comprehensive security test suite (entropy, randomness, weak patterns)

CI/CD:
- Consolidate workflows into security.yml with all checks

Co-Authored-By: Oz <oz-agent@warp.dev>

* Fix CI failures: relax mypy settings and fix security tests

Changes:
- Relax mypy settings to not require full type annotations
- Security tests now allow for randomness (sequential chars, repeats)
- Set bandit/mypy to continue-on-error for gradual adoption
- Adjusted passphrase entropy threshold to match actual wordlist size
- Fixed security tests to use statistical checks instead of strict assertions

Co-Authored-By: Oz <oz-agent@warp.dev>

* Update README with banner, badges, security section, and dev docs

Changes:
- Added banner image at top of README
- Added CI badges (security, python versions, license)
- Added comprehensive Security section documenting the security suite
- Updated wordlist count from 1000 to ~7,700 words
- Added Development section with setup, pre-commit hooks, testing, and security tools

Co-Authored-By: Oz <oz-agent@warp.dev>

* Add banner image and update README path

- Added generate-it-banner.png to assets/ directory
- Updated README.md to reference correct banner filename

Co-Authored-By: Oz <oz-agent@warp.dev>

* Fix auto-lock vault unlock bug and add regression test

Root cause: unlock_vault() had overly broad exception handling that
converted ANY exception (including database reconnection issues) into
InvalidPasswordError. This masked the actual problem when auto-lock
closed the DB connection.

Changes:
- Fixed exception handling in unlock_vault() to distinguish between
  actual password errors and storage/database errors
- Added test test_vault_unlock_after_close_reconnects to prevent regression
- Proper error propagation now helps diagnose vault unlock issues

Co-Authored-By: Oz <oz-agent@warp.dev>

* Fix hotkey UI wrapping and cramped layout

Changes:
- Actions box: Stack hotkeys vertically on 3 lines instead of one cramped line
- Footer: Now uses 2 stacked lines for better readability
- Credential Details modal: Increased height from 12 to 14 rows
  - Hotkeys now stacked on 2 lines at bottom
- Vault Explorer modal: Footer hotkeys now stacked on 2 lines

Improves readability and prevents text wrapping issues on smaller terminals.

Co-Authored-By: Oz <oz-agent@warp.dev>

* refactor: add Credential dataclass in models.py

* refactor: extract pure helpers into tui_helpers.py

* refactor: extract modal input dialogs into tui_modal.py

* refactor: extract presentation/render layer into tui_render.py

* refactor: extract vault/security input into tui_security.py

* refactor: relocate flat AppState into tui_state.py

* refactor: extract file/import-export helpers into tui_files.py

* refactor: extract CSV export/import logic into tui_csv.py

* refactor: extract top-level action handlers into tui_flow.py

* test: add curses smoke test for TUI entrypoint

* perf: Phase 1 quick wins (generator + storage)

- generator: lru_cache wordlist load, frozenset separators, simplify dedupe
- storage: hoist commit out of CSV import loop, extract _require_unlocked guard

* security: harden PBKDF2 (480k iters, 32-byte salt), persist params for backward-compatible unlock

* refactor: remove redundant _require_unlocked() call in list_credentials

* test: cover Phase 1/2 with edge cases (lru_cache, dedupe, persistence, PBKDF2 negative)

* perf: cache TUI modal windows and search results

* perf: avoid blocking details-modal feedback

* perf: cache dashboard focus items

* perf: share secure word sampling

* perf: normalize CSV headers once

* fix: prevent vault reinitialization

* feat: support storage context management

* refactor: centralize credential decryption

* perf: wait briefly for SQLite locks

* perf: bound passphrase dedupe set with LRU eviction

* refactor: remove dead seen_usernames and unused imports

* refactor: centralize credential encryption

* refactor: narrow storage exception handling

* feat: add rotating file logging module

* feat: wire logging into StorageManager lifecycle

* feat: log CSV I/O from TUI

* perf: skip dashboard redraw on idle frames

* refactor: narrow TUI exception handling

* test: fix probabilistic flakes and add generator edge-case coverage

* test: add storage error-path and branch coverage

* test: add end-to-end credential lifecycle integration test

* test: add security regression test structure

* fix: remove implicit cwd wordlist override

* fix: mask password entry in username save flow

* fix: enforce master password policy in storage

* fix: enforce custom wordlist entropy floor

* fix: mask stored passwords in vault views

* fix: enforce private vault file permissions

* fix: revoke copied secrets on vault lock

* fix: create csv exports atomically and privately

* fix: use secure clipboard and auto-lock defaults

* fix: sanitize untrusted text before curses rendering

* fix: bound and atomically import csv credentials

* docs: warn about spreadsheet handling of csv exports

* fix: guard modal geometry on small terminals

* fix: validate persisted kdf parameters strictly

* docs: specify versioned vault format migration

* refactor: decrypt vault secrets only on demand

* ci: enforce blocking security gates

* build: constrain audited ci and release dependencies

* docs: align security claims with implementation

* ci: secure pypi publishing with oidc

* docs: add security acceptance matrix

* feat: implement vault v2 with Argon2id, KEK/DEK, and AEAD

* docs: add gemini workflow security design and read-only analysis

* build: add hash-locked ci and release constraint files

* docs: add review-to-commit mapping, remove stale review files

* docs: fix stale review-file references in vault v2 spec

* ci: repair immutable publish action pins

* ci: enforce locked release security gates

* fix: keep logs private and metadata free

* fix: sanitize all modal rendering

* fix: clear plaintext ui state promptly

* ci: repair immutable publish action pins, enforce locked gates

* build: pin contributor hooks immutably

* fix: secure export and migration file creation

* fix: bound all csv import rows

* fix: validate vault v2 configuration strictly

* feat: bind vault v2 secrets to credential metadata

* feat: make hardened vault v2 the default

* feat: add spreadsheet-safe csv export

* docs: reconcile security controls with implementation

* docs: map round 2 findings to commits in review-commit.md

* fix: remediate all 10 security findings (F-015–F-024)

Phase 1 — Crypto & Data Integrity:
- F-015: AAD v2 default for fresh and migrated vaults; auto-migrate on
  unlock with confirmation prompt; migration re-encrypts with metadata-bound AAD
- F-021: v1→v2 migration now verifies password against existing vault
- F-022: Remove scrypt from _VALID_KDF_ALGORITHMS (was accepted but unimplemented)

Phase 2 — TUI Rendering & Input Safety:
- F-017: Fix edit flow KeyError — load decrypted secret via get_credential_secret()
- F-018: Sanitize error text in details modal footer
- F-019: Sanitize filesystem paths in file browser/fuzzy picker
- F-020: Extend sanitizer for Unicode bidi/zero-width characters

Phase 3 — CSV & Export:
- F-016: Apply formula injection sanitization to all export formats

Phase 4 — CI & Supply Chain:
- F-023: Remove Windows from CI matrix (placeholder lockfile); add windows-todos.md

Phase 5 — Documentation:
- F-024: Expand packaged wordlist from 1,005 to 5,800 words (~50 bits entropy)

Verification: 383 tests pass, mypy clean, bandit 7 Low (all FP),
22/22 adversarial probes pass. Also completes Gemini workflow removal cleanup.

* chore: add .hermes/ to gitignore

* fix: resolve all 7 bandit false positives (0 issues remaining)

B105 (hardcoded_password_string) — 4 findings:
- csv_formats.py: 'nordpass' is a format name, not a credential (nosec)
- generator.py: PASSPHRASE_SPECIALS is a character pool, not a credential (nosec)
- storage.py: '<DECRYPTION_ERROR>' is an error sentinel, not a credential (nosec)

B110 (try_except_pass) — 3 findings:
- storage.py:787,889: Replace silent pass with _log.debug for rollback
  failures during migration cleanup — failures now observable
- tui_modal.py:140: Replace silent pass with _log.debug for tab generation
  failures — failures now observable

* fix: resolve CI dependency installation failures

- Downgrade stevedore 5.9.0→5.8.0 in ci.txt and release.txt:
  5.9.0 requires Python >=3.11 but CI matrix includes 3.10
- Pin SecretStorage==3.5.0 and jeepney==0.8.0 in release.txt:
  transitive deps from keyring on Linux, were missing from lockfile
  causing --require-hashes to fail (all deps must be pinned)

* fix: pin missing transitive deps for CI hash-locked constraints

- Add exceptiongroup==1.3.1 to ci.txt: pytest backport for Python 3.10
  (built-in in 3.11+, only needed on 3.10)
- Add setuptools==80.9.0 to release.txt: required by build backend
  (setuptools.build_meta) during package validation

* fix: pin wheel==0.45.1 in release.txt for package build validation

* docs: fix banner link, wordlist stats, and CSV escape docs in README

- Update banner link to new generateit-banner.png (no hyphen)
- Fix wordlist count: ~7,700 EFF → 5,800 from /usr/share/dict/words
- Update CSV security warning: all formats now escape formula chars
- Update spreadsheet-safe format description to reflect F-016 fix

* docs: rename WARP.md to AGENTS.md for multi-agent framework use

* docs: update AGENTS.md intro and refresh report references after rename

* ci: restore Windows test matrix with hashed lockfile

* fix(ci): make Windows lockfile Python 3.10 compatible

* docs: mark Windows CI setup complete

* docs: correct Windows lockfile counts

* docs: enable Windows virtualenv activation

* fix: improve master password policy, UI, and entropy rendering

- Strengthen master password validation: min 8 chars, require uppercase,
  lowercase, digit, and special character (was: empty 12-char min/no class checks)
- Fix passphrase mode: remove blank line so strength bar fits in info box
- Fix entropy bar: scale from 100→256 max for meaningful bars at high entropy
- Fix init error UI: call touchwin after erase to clear orphaned modal subwindows
- Update all test password literals to meet new policy requirements

* fix: exact entropy bar scaling and clean modal cleanup

- Replace shared 256-bit bar cap with mode-specific caps:
  character mode: 500-bit max (411-bit chars now show ~82% instead of always 100%)
  passphrase mode: 200-bit max (138-bit passphrases show ~69% instead of 54%)
- Fix stale modal subwindows: _run_modal now cleans up (del + touchwin +
  refresh) before every return, preventing ERROR modals from bleeding through
  into the next SETUP prompt

* fix: proportional entropy bars, wordlist diversity, hotkeys layout

- Entropy bar now computes theoretical max from actual generator constants:
  characters: 64*log2(90)=411.3 bits, passphrase: 10*log2(7690)+13=138 bits
- Username mode no longer shows entropy or strength bar
- Wordlist replaced: was 5800 a-only words, now 7690 a-z diverse words
  (EFF large wordlist, CC0-licensed, purpose-built for passphrases)
- Hotkey help consolidated to single full-width footer row, removed from
  ACTIONS section to free vertical space

* Improve vault unlock and AAD migration flow

* feat: implement development branch improvements (phases 1-6)

- Fix CSV preview transaction handling (dry-run isolation)
- Centralize canonical credential identity (NFC + strip + casefold) and indexed lookups
- Stream storage reads and migrations (cursor iteration)
- Introduce AAD v3 length-delimited serialization and migration
- Make wordlist cache source-aware and freshness-aware
- Configure black/isort tool sections and CI whitespace check

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(security): update cryptography to 50.0.0 in constraints

Remediates PYSEC-2026-3552 vulnerability in pip-audit CI job.

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(ci): add exceptiongroup and setuptools>=83.0.0 to constraint lockfiles

- Fixes pip --require-hashes failure on Python 3.10 CI jobs where
  exceptiongroup was required by pytest but missing from constraints/ci.txt
- Upgrades setuptools to 83.0.0 in constraints

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(ci): add SecretStorage to release constraints

- Fixes pip --require-hashes failure in Package validation CI job on
  Linux runners where SecretStorage is required by keyring/twine.

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(ci): pin setuptools with hashes in constraints for package validation

- Re-compiles constraints with --allow-unsafe so setuptools is pinned with
  hashes in release.txt, ensuring setuptools.build_meta is available during
  isolated/no-isolation builds in Package validation CI job.

Co-Authored-By: Oz <oz-agent@warp.dev>

* fix(security): phase1 Round 3 remediation — AAD v4 migration decoupling, atomic post-auth lock, TUI v4 alignment

* chore(version): bump to 0.2.3 (0.2.2 consumed by March 2026 production release on PyPI)

* fix(logging): support Windows log file setup

* fix(ci): enforce main-only publish policy in publish.yml

Add ancestry guard: publish.yml validate job now rejects tags on
commits not reachable from main. PyPI publishes only from the
production branch.

* chore: consolidate remediation stack with development security model (#3)

* fix: repair package discovery and migration exceptions

* fix: enforce encrypted field boundaries

* fix: canonicalize identities and reject repeated passwords

* fix: harden logging and storage permissions

* fix: improve generator cache and username boundaries

* fix: harden TUI unlock and clipboard flows

* fix: bound TUI detail rendering

* fix: support authenticated legacy rekey migration

* fix: preserve crypto migration compatibility

* fix: harden legacy migration cleanup

* fix: harden identity and password policies

* fix: harden storage corruption boundaries

* fix: harden storage integrity paths

* fix: harden logging integrity and permission rollback

* fix: preserve identity AAD compatibility

* fix: validate generator cache content

* test: strengthen legacy cleanup coverage

* fix: make CI diff and package checks effective

* fix: install locked dependencies for wheel smoke test

* fix: harden TUI details and username metrics

* fix: harden TUI unlock and clipboard flows

* fix: harden CI range and wheel checks

* refactor: delegate identity migration to canonical module

* refactor: remove empty storage v1/v2/csv shells

* feat: persist failed-unlock lockout state across restarts

* fix(storage): remove dead-code final raise in master password character-class fallback

The unconditional raise after the four character-class checks made the
fallback accept-path unreachable — any password below 64 bits entropy was
always rejected even when all character classes were present.

Fix: reject predictable repeated patterns explicitly at the top of the
fallback (preserving three existing regression tests), then accept after
all character-class checks pass.  Updated the docstring to document the
pattern rejection.

Added regression test: Pass123! (8 chars, all four classes, ~52 bits)
is now accepted via the fallback where it was previously rejected.

Gate: 515 tests pass, bandit 0, mypy 0.

* fix(consolidation): resolve auto-merge drift on TUI helpers and storage

git's 3-way auto-merge silently kept origin/development's canonical_identity_stripped
import in tui_helpers.py while the stack renamed it to canonical_identity.  Reset
tui_helpers.py, tui_flow.py, and storage/core.py to the stack-tip versions and
re-applied the master-password fallback fix.

* consolidate: resolve conflicts in favor of origin/development

Per Josh's direction, the already-merged development branch is the source of
truth for all conflicts.  Reverted the overlapping files (crypto, identity,
logging, tui, storage) to origin/development's versions:
- AAD v4 (with make_associated_data_v4) wins over stack's AAD v3.
- Zero-width strip model wins over stack's reject model.
- Monolithic storage.py wins over the stack's storage/ package refactor.
- Dropped stack-only tests that depended on the removed package.

Security-model reconciliation is deferred; Josh will revisit after cleanup.

* consolidate: align test files with development source versions

Dropped stack-only tests for reverted modules (crypto-compat, legacy-migration,
legacy-unlock, lockout, logging-integrity, TUI-lockout, TUI-render, TUI-security).
Kept stack tests for non-conflicting modules (generator, crypto-boundaries, CI,
identity-aad, logging-security-regressions).

* fix(tui): resolve PR #3 review findings — constant sync, username-mode strength-bar removal (#4)

* fix: resolve PR #3 review findings — constant sync, strength-bar semantic, stale comment

- fix(constants): USERNAME_ALPHANUMERIC lowercase-only (was mixed-case)
- fix(tui_render): MAX_USERNAME_LENGTH for username strength bar (was
  MAX_PASSWORD_CHARS, which happens to equal 64 but is semantically wrong)
- fix(tui): stale comment says tui_render 'aliases' helpers when it now
  redefines them locally
- test: add test_constants_sync.py as a guard against future constant drift

Gates: pytest 490/490, bandit 0, mypy 0 (verified at fe8e532 baseline).

* fix(ui): drop entropy/strength bar from username mode (usernames are not entropy-regulated)

- Guard the entropy computation, strength label, and strength bar with
  state.mode != "username" in _render_info_box()
- Move bits/label/kind/kind_attr computation inside the guard so
  _estimate_entropy_bits is never called with username mode
- Remove the else (username) branch from the max_bits computation
- Remove dead SHARED_INTS dict from test_constants_sync.py
- Add missing trailing newline to test_constants_sync.py

* docs(test): document policy-tuple duplication + constants single-source-of-truth debt

Documents the two known-debt items acknowledged in the PR #3 remediation
round-2 review (review-APPROVED-pr3-remediation-round2-20260817-2217.md §6):
CLIPBOARD_AUTO_CLEAR_OPTIONS / AUTO_LOCK_OPTIONS are defined independently in
tui.py and constants.py (byte-identical, unguarded), and the intended fix is
a single-source-of-truth migration making generator.py and tui.py import from
constants.py. Cosmetic only; no behavior change.

* fix(security): complete hardening 0.2.4 — persistent lockout, Argon2 minima, wordlist validation, CSV/backup hardening

- Persistent lockout (config lockout_* keys, survives restart) with escalation preserved
- Argon2id minima 19456/2 (OWASP low) + downgrade warning, v1 PBKDF2 legacy flag + migrate prompt
- Wordlist: lstat symlink/size (5MiB/1M) + TOCTOU, lgamma entropy, bounded cache
- CSV: formula triggers +|+% , spreadsheet-safe, URL preserved, spreadsheet escaping
- Export chmod 0600 after replace, backup ctime ordering, B608 allow-list, LIKE limit noted
- Password lifetime: explicit overwrite/del in TUI/CLI, cache clear on lock
- Optimization: heapq for fuzzy limit, keyset pagination, lgamma, caches
- Bump 0.2.3 → 0.2.4, README Known Limitations, twine check passed

Co-Authored-By: internal

* fix(security): address PR #5 review — wordlist TOCTOU, lockout clock docs, ctime/LIKE naming, cache eviction

- generator: use lstat + O_NOFOLLOW for wordlist hash/read to close
  TOCTOU symlink window (lstat re-validation after signature, fstat
  on O_NOFOLLOW fd, ELOOP->WordlistSecurityError), warn on missing
  GENERATE_IT_WORDLIST fallback
- storage: fix backup ctime doc (POSIX inode change vs creation),
  clarify _VAULT_SEARCH_SQL_LIKE_LIMIT vs _VAULT_SEARCH_SQL_LIMIT
  and search_credential_metadata LIMIT semantics
- constants: clarify search limit constants purpose
- tui: _lock_vault now clears wordlist + file-picker caches
- tui_security/storage: document wall-clock vs monotonic lockout
  persistence limitation and attempt-counter preservation, annotate
  downgrade warning as detection vs _validate_kdf_config prevention
- tests: update signature-cache test to count secure read path

Co-authored-by: Muse Spark

* fix(ci): resolve PR #5 check failures — trailing whitespace, mypy, windows

- strip trailing whitespace across generate_it/ and tests/ to satisfy
  git diff --check (storage, tui, tui_render, tui_state, csv, security)
- tui: restore missing focus_items/focus_id definition in main loop
  (fixes mypy name-defined for focus_id and focus_items)
- tui_render: correct _ENTROPY_CACHE key type (str→bool at position 7)
  and remove stale type:ignore[arg-type] (fixes index error, unused-ignore)
- storage/tui/tui_security/__main__: remove unused type:ignore[assignment]
  and attr-defined/dict-item ignores (fixes warn_unused_ignores)
- tests: windows — make signature-cache test count only secure read
  (avoids double-count on nt where secure read falls back to Path.read_text)
  and skip POSIX-only logging checks on win32 (symlink/directory/chmod)
- tests: fix blank line at EOF in test_security_tui.py

Co-authored-by: Muse Spark

---------

Co-authored-by: Oz <oz-agent@warp.dev>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

risk: low Low risk — trivial or config-only change scope: tui TUI/curses interface changes status: ready-for-review Gates passed, awaiting reviewer type: bug Security fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant