Skip to content

E4/E5: lint gates (ruff+SwiftFormat) and README screenshots#66

Merged
LegalMarc merged 8 commits into
mainfrom
chore/e4-lint-gates-e5-readme-visuals
Jul 15, 2026
Merged

E4/E5: lint gates (ruff+SwiftFormat) and README screenshots#66
LegalMarc merged 8 commits into
mainfrom
chore/e4-lint-gates-e5-readme-visuals

Conversation

@LegalMarc

Copy link
Copy Markdown
Owner

Summary

  • E4: fixed all 288 outstanding ruff violations (E/F/B rule sets), applied a one-time SwiftFormat pass across the Swift source tree, and tightened both CI gates to enforce cleanly going forward.
  • E5: added 4 real screenshots of the running app to the README (idle, live AI-progress, finished, settings), captured against a purely synthetic demo document.
  • Two incidental fixes surfaced and closed along the way: a real NameError crash bug in gui.py's download-error dialogs (caught by the new ruff gate), and stale assets/help.md vs the Swift Resources copy (now resynced, with a CI check added so it can't drift again silently).
  • Closed a test-coverage gap in test_all_fields_have_cli_args (only checked one direction of the CLI-arg mapping).

Test plan

  • PYTHONPATH=src/python python3 -m pytest -q — 555 passed, 6 skipped
  • swift test --package-path src/swift/MarcutApp — 108 passed
  • ruff check src/python tests — clean
  • swiftformat --lint src/swift/MarcutApp/Sources src/swift/MarcutApp/Tests — clean
  • New CI check for assets/help.md drift verified both ways (passes clean, fails on injected stale content)
  • New bidirectional test assertion verified to have teeth (injected an unmapped field, confirmed failure, reverted)

🤖 Generated with Claude Code

Marc Mandel and others added 8 commits July 14, 2026 21:39
Conservative rule set (preserve existing wrap/collection style, 4-space
indent, 120-col max) chosen to minimize churn while still catching real
issues (trailing whitespace, inconsistent brace spacing, etc).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
One-time reformat -- the codebase never had a formatter run against it.
Purely mechanical (verified: builds clean, all 108 Swift tests pass,
no logic changes). Adding the commit SHA to .git-blame-ignore-revs next
so `git blame` still resolves through this reformat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ruff gate widened from a narrow error-tier subset (E9,F63,F7,F82) to the
full configured rule set, now that the 288 pre-existing violations are
fixed. Adds a SwiftFormat --lint step to the macOS smoke job. Also adds
.git-blame-ignore-revs so `git blame` skips the one-time SwiftFormat
reformat commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Auto-fixed unused imports/f-strings/unused-variables where safe (verified
each removal against real usage, not just ruff's say-so), then manually
resolved the categories ruff won't autofix:

- E712: assert x == True/False -> assert x / assert not x (all against
  plain-bool-returning predicates, no numpy ambiguity)
- E701/E702: split multi-statement lines (if x: y, a=1; b=2) onto
  separate lines
- E402: moved genuinely-misplaced imports to the top; kept sys.path-fixup
  imports where the ordering is load-bearing, marked with noqa + reason
- B904: chained exceptions with `from e` where the original error is
  useful context, `from None` where the wrapper message is self-contained
- B007: renamed/removed unused loop-control variables
- E722: bare `except:` -> `except Exception:`
- B017: kept broad `pytest.raises(Exception)` where multiple exception
  types are legitimately expected (malformed-input corpus tests), with
  noqa + reason rather than fabricating a narrower type
- B023/E731: fixed a real loop-variable-closure risk in docx_io.py and a
  lambda-assignment in native_setup.py

Full suite verified after every batch (555 passed, 6 skipped throughout).
One incidental finding spun off separately rather than fixed here: a dead
expression removed in test_docx_io.py exposed a real test-coverage gap
(only one direction of a bidirectional field-mapping check was wired up).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The test only checked that every CLI_ARG_MAP entry maps to a real
settings field, not the reverse -- a new bool field on
MetadataCleaningSettings could ship without a CLI arg mapping and
nothing would catch it. Surfaced by dead-code removal during the
ruff cleanup (a computed-but-never-asserted set from an earlier,
incomplete attempt at this same check).

Verified the new assertion has teeth: temporarily injected an
unmapped bool field, confirmed the test fails with a clear message
naming the field, then reverted the injection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
assets/help.md (the documented canonical source, per CLAUDE.md) had
gone stale relative to src/swift/MarcutApp/Sources/MarcutApp/Resources/help.md:
PR #65's doc sweep (df99203) edited the Swift-side copy directly instead
of the canonical source, so assets/help.md never got the new pre-flight
checks, streaming-progress, fail-closed-extraction, and sleep/wake
sections. scripts/render_help_html.py (invoked by
scripts/sh/build_swift_only.sh) treats assets/help.md as authoritative
and regenerates the Swift copy from it on every build -- so building
after PR #65 silently reverted the in-app help text, which is how this
was discovered (while producing a build for E5 README screenshots).

Fix: copied the current (good) content back to assets/help.md so
`python3 scripts/render_help_html.py` is now a no-op against both
copies -- verified via diff and by re-running the script.

Added a CI check (regenerate from assets/*.md, fail if the tracked
Swift Resources/*.md copies then show a git diff) so this exact
regression class can't land silently again. Verified the check both
ways: passes clean on the current state, and correctly fails when the
old stale assets/help.md content is re-injected (tested, then reverted).
Only the .md fallback copies are compared -- Resources/*.html is
gitignored generated output, not tracked.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Built a real, ad-hoc-signed app bundle (scripts/sh/build_swift_only.sh
preset dev_fast + create_dmg), installed it, and captured 4 screenshots
of actual running states against a purely synthetic demo NDA (fabricated
names/companies/.example addresses -- never real sample-files content):
idle drag-and-drop, live AI-analysis progress, finished-processing
status, and the redaction settings panel.

Along the way: found the raw SwiftPM debug binary crashes on launch
(UNUserNotificationCenter asserts when called from an unbundled/unsigned
binary -- fixed by building a real .app via the project's own dev_fast
preset instead); found computer-use's screenshot save-to-disk isn't
reachable from this shell's filesystem, so screenshots were captured
directly via screencapture(1) once Screen Recording permission was
granted, then cropped to the app window via a color-based bounding-box
detection (Pillow) rather than guessed pixel coordinates.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The macOS CI runner image ships SwiftFormat 0.61.1 pre-cached, so the
`brew install swiftformat` step was a no-op and never picked up the
0.62.1 I tested locally -- CI failed on 4 real violations 0.62.1 doesn't
flag: redundant explicit `Sendable` conformance on two non-public enums
(DocumentModels.swift), a comment style mismatch, and a string-literal
indent/trailing-space conflict inside a multi-line alert message that
0.61.1's indent and trailingSpace rules disagreed on for blank lines --
resolved by using explicit `\n\n` instead of literal blank lines in the
string, sidestepping the whole blank-line-in-multiline-string ambiguity.

Verified all fixes clean under both 0.61.1 and 0.62.1 (downloaded both
release binaries directly rather than trusting brew's ambient version).
CI now pins to a specific downloaded release (0.62.1) instead of
whatever the runner image happens to have cached, so this can't
silently drift again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@LegalMarc
LegalMarc merged commit 4eb1ada into main Jul 15, 2026
3 checks passed
@LegalMarc
LegalMarc deleted the chore/e4-lint-gates-e5-readme-visuals branch July 15, 2026 04:01
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