|
|
|
|
@ -0,0 +1,453 @@
|
|
|
|
|
# Repository Audit - 2026-07-03
|
|
|
|
|
|
|
|
|
|
Scope: repository-wide audit of the current `pmacs` worktree at
|
|
|
|
|
`/home/jeans/Repos/active/pmacs`.
|
|
|
|
|
|
|
|
|
|
This audit covers Rust crates, Lua built-ins and fixtures, package-manager code,
|
|
|
|
|
GPU frontend code, documentation, repository hygiene, and verification commands.
|
|
|
|
|
It audits the files currently on disk.
|
|
|
|
|
|
|
|
|
|
## Worktree Context
|
|
|
|
|
|
|
|
|
|
Excluding this newly added report, `git status --short` reported these
|
|
|
|
|
untracked worktree files at the end of the audit:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
?? #run.sh#
|
|
|
|
|
?? docs/pmacs-gpu-editing-perf-handoff.md
|
|
|
|
|
?? docs/semantic-frontend-protocol.md.local-bak
|
|
|
|
|
?? docs/session-5-stale-styling-handover.md
|
|
|
|
|
?? pmacs
|
|
|
|
|
?? python_experiment.md
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
The audit did not revert or normalize this state.
|
|
|
|
|
|
|
|
|
|
## Verification Summary
|
|
|
|
|
|
|
|
|
|
Commands run:
|
|
|
|
|
|
|
|
|
|
| Command | Result | Notes |
|
|
|
|
|
|---|---:|---|
|
|
|
|
|
| `cargo fmt --all --check` | Pass | Formatting is clean. |
|
|
|
|
|
| `cargo clippy --all-targets -- -D warnings` | Pass | This only checked the root default package from this workspace location. |
|
|
|
|
|
| `cargo clippy --workspace --all-targets -- -D warnings` | Fail | `pmacs-gpu` has 3 denied clippy warnings. See F-001. |
|
|
|
|
|
| `cargo test -p pmacs-gpu --bin pmacs-gpu` | Pass | 39 tests passed on the current worktree. |
|
|
|
|
|
| `cargo test -p pmacs-protocol` | Pass | 12 tests passed; 0 doctests. |
|
|
|
|
|
| `cargo test -p pmacs --no-default-features --features lua54 --lib` | Pass | 1431 passed, 0 failed, 3 ignored. |
|
|
|
|
|
| `cargo test -p pmacs --features crdt --lib` | Pass | 1601 passed, 0 failed, 3 ignored. |
|
|
|
|
|
| `cargo test --workspace --all-targets --all-features` | Fail | `mlua-sys` rejects enabling both `luajit` and `lua54`. See F-002. |
|
|
|
|
|
| `cargo run --quiet --bin pmacs-audit -- --pretty builtin tests/fixtures` | Pass with warnings | 0 errors, 3 warnings, 10 infos. |
|
|
|
|
|
|
|
|
|
|
Sandbox caveat: an initial `cargo test --workspace --all-targets` run failed in
|
|
|
|
|
three attach/socket tests with `PermissionDenied: Operation not permitted`.
|
|
|
|
|
Rerunning the attach lib-test group with normal socket permissions passed
|
|
|
|
|
(`44 passed`). I did not treat that sandbox failure as a product defect.
|
|
|
|
|
|
|
|
|
|
## Findings
|
|
|
|
|
|
|
|
|
|
### F-001 - High - Workspace clippy fails, while the documented clippy command misses workspace members
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `README.md:37-43` documents:
|
|
|
|
|
- `cargo test`
|
|
|
|
|
- `cargo fmt --check`
|
|
|
|
|
- `cargo clippy --all-targets -- -D warnings`
|
|
|
|
|
- `cargo metadata --no-deps --format-version 1` reports `workspace_default_members`
|
|
|
|
|
as only the root `pmacs` package.
|
|
|
|
|
- `cargo clippy --all-targets -- -D warnings` passed, but
|
|
|
|
|
`cargo clippy --workspace --all-targets -- -D warnings` failed.
|
|
|
|
|
- The workspace clippy failures are in `pmacs-gpu/src/main.rs`:
|
|
|
|
|
- `pmacs-gpu/src/main.rs:2712`: two `clippy::cast_possible_wrap` errors from
|
|
|
|
|
`centered as i64 - self.scroll_top as i64`.
|
|
|
|
|
- `pmacs-gpu/src/main.rs:2948`: `clippy::format_push_string` from
|
|
|
|
|
`readout.push_str(&format!(...))`.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
The documented release/developer clippy command can give a false green while
|
|
|
|
|
`pmacs-gpu` is not clippy-clean under the workspace's lint policy. This makes CI
|
|
|
|
|
and local release validation vulnerable to missing frontend regressions.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Fix the three `pmacs-gpu` lints, then update README and CI to use workspace-aware
|
|
|
|
|
commands, e.g. `cargo clippy --workspace --all-targets -- -D warnings` and
|
|
|
|
|
`cargo test --workspace --all-targets`. Alternatively set explicit workspace
|
|
|
|
|
`default-members` if the intent is for plain `cargo test` and `cargo clippy` to
|
|
|
|
|
cover all first-party crates.
|
|
|
|
|
|
|
|
|
|
### F-002 - Medium - `--all-features` is not buildable because Lua features are mutually exclusive
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `Cargo.toml:63-75` defines `default = ["luajit"]`, `luajit`, and `lua54`.
|
|
|
|
|
- `cargo test --workspace --all-targets --all-features` fails in `mlua-sys` with:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Generic CI, packaging automation, `cargo hack`, and distro tooling often starts
|
|
|
|
|
with `--all-features`. For this workspace, that produces a hard build failure
|
|
|
|
|
even though both Lua flavors pass independently.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Document the supported feature matrix explicitly and avoid `--all-features` in
|
|
|
|
|
CI. Prefer a matrix such as default LuaJIT, `--no-default-features --features
|
|
|
|
|
lua54`, and `--features crdt`. If possible, add a clearer crate-local compile
|
|
|
|
|
error for simultaneously enabled Lua flavors so users see a pmacs-specific
|
|
|
|
|
message before the `mlua-sys` failure.
|
|
|
|
|
|
|
|
|
|
### F-003 - Medium - `pmacs-gpu` can appear hung when attached to a non-CRDT daemon
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/src/attach.rs:119-128` documents the failure mode directly: without
|
|
|
|
|
daemon `crdt`, negotiation succeeds, no `BufferSnapshot` arrives, and the GPU
|
|
|
|
|
window sits on `(connecting...)` forever.
|
|
|
|
|
- `pmacs-gpu/src/attach.rs:129-148` sends an `AttachRequest` requesting
|
|
|
|
|
`multi_frontend`, `crdt_replica`, and `semantic_render`, but there is no
|
|
|
|
|
explicit capability rejection path in the GPU client after the request.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
This is a confusing operational failure. A user can start the daemon without the
|
|
|
|
|
right feature and get an inert GPU window instead of a clear compatibility error.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Make capability negotiation explicit. The daemon should reject required
|
|
|
|
|
capability mismatches with a structured `Goodbye` or handshake error, and the GPU
|
|
|
|
|
frontend should render a fatal status explaining that the daemon must be started
|
|
|
|
|
with `--features crdt`.
|
|
|
|
|
|
|
|
|
|
### F-004 - Medium - Current GPU command-chord forwarding can break AltGr/international text input
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/src/main.rs:4674-4688` reduces winit modifiers to Shift, Ctrl, Alt,
|
|
|
|
|
and Super/Meta. There is no AltGraph/AltGr distinction in the protocol
|
|
|
|
|
modifier set (`pmacs-protocol/src/message.rs:92-115`).
|
|
|
|
|
- `pmacs-gpu/src/main.rs:4775-4779` treats any `Char`, `Enter`, or `Tab` with
|
|
|
|
|
Ctrl or Alt held as a command chord.
|
|
|
|
|
- The current tests assert that this generalized command-chord path forwards
|
|
|
|
|
`Char` plus Ctrl/Alt combinations (`pmacs-gpu/src/main.rs:5822-5853`).
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
On many keyboard layouts, printable characters are entered through AltGr, which
|
|
|
|
|
toolkits may expose as Ctrl+Alt or as an Alt-related modifier. Those characters
|
|
|
|
|
can be misclassified as command chords and forwarded to the daemon keymap instead
|
|
|
|
|
of inserted as text. This affects non-US layouts and users typing characters
|
|
|
|
|
such as `@`, `[]`, `{}`, `\`, `|`, or currency symbols depending on layout.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Use winit's text/IME path or an explicit AltGraph signal to distinguish printable
|
|
|
|
|
text input from command chords. Add tests for AltGr-style printable input. If the
|
|
|
|
|
wire protocol needs it, add an AltGraph modifier bit rather than folding it into
|
|
|
|
|
Ctrl/Alt.
|
|
|
|
|
|
|
|
|
|
### F-005 - Medium - Package install paths collide for namespaced packages with the same basename
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/packages/installer.rs:44-49` states that install directories are named by
|
|
|
|
|
package basename and accepts collisions for v0.1.
|
|
|
|
|
- `src/packages/installer.rs:1040-1051` strips a namespace prefix with
|
|
|
|
|
`package_basename`.
|
|
|
|
|
- `src/packages/loader.rs:43-48` and `src/packages/loader.rs:164-176` route
|
|
|
|
|
require lookup by basename, with most-recent install winning on collisions.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Two distinct packages such as `owner/magit` and `other/magit` can target the same
|
|
|
|
|
install directory and require namespace. Depending on order, one can shadow or
|
|
|
|
|
block the other. A resolver can reason about canonical names while the installer
|
|
|
|
|
and loader collapse them to the same basename.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Reject duplicate basenames during resolution/install until a namespace-aware
|
|
|
|
|
install layout exists, or install under a namespace-preserving path. If basename
|
|
|
|
|
requires remain a compatibility goal, add an explicit aliasing rule rather than
|
|
|
|
|
silently collapsing distinct package names.
|
|
|
|
|
|
|
|
|
|
### F-006 - Medium - Atomic save has file-metadata and crash-durability gaps
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/file_io.rs:139-148` creates a new sibling temp file, writes bytes,
|
|
|
|
|
`sync_all`s the temp, then renames it over the target.
|
|
|
|
|
- The save path does not copy the existing file mode/permissions onto the temp
|
|
|
|
|
before rename.
|
|
|
|
|
- The save path does not fsync the parent directory after rename.
|
|
|
|
|
- `src/file_io.rs:156-174` uses PID plus subsecond nanoseconds for the temp name
|
|
|
|
|
and relies on `create_new` failing if a collision occurs; it does not retry.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Saving an existing executable or otherwise specially-permissioned file can replace
|
|
|
|
|
it with default temp-file permissions. On POSIX filesystems, a crash after rename
|
|
|
|
|
but before the parent directory entry is synced can lose the rename despite the
|
|
|
|
|
file bytes having been synced. The temp-name collision path is unlikely, but a
|
|
|
|
|
same-process collision would surface as a spurious save failure.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Before writing, read existing metadata and apply the target's mode to the temp
|
|
|
|
|
file where supported. After a successful rename, fsync the parent directory on
|
|
|
|
|
Unix. Add a bounded retry loop for temp-name collisions.
|
|
|
|
|
|
|
|
|
|
### F-007 - Medium - Minibuffer dropdown height is unbounded and can render off-screen
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/src/main.rs:3160-3164` computes dropdown `top_y` as
|
|
|
|
|
`band_top - n as f32 * MB_DROP_ROW_HEIGHT`.
|
|
|
|
|
- `pmacs-gpu/src/main.rs:3176-3193` draws a background rect and selected row for
|
|
|
|
|
all candidates without clipping/windowing the candidate list.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Large completion lists can extend above the top of the window. The selected row
|
|
|
|
|
can be outside the visible area, and hit testing/rendering can become inconsistent
|
|
|
|
|
with what the user can see.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Cap visible rows based on available height, keep a scroll/window offset around
|
|
|
|
|
the selected candidate, clamp `top_y`, and make hit testing use the same visible
|
|
|
|
|
window.
|
|
|
|
|
|
|
|
|
|
### F-008 - Medium - GPU attach outbound queue is unbounded
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/src/attach.rs:156` uses `std::sync::mpsc::channel`.
|
|
|
|
|
- `pmacs-gpu/src/attach.rs:186-199` writes queued events on a separate writer
|
|
|
|
|
thread to avoid blocking the UI thread.
|
|
|
|
|
- `pmacs-gpu/src/attach.rs:326-333` sends every `FrontendEvent` into that
|
|
|
|
|
unbounded queue.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
If the daemon or socket stalls, the UI thread can continue enqueueing key,
|
|
|
|
|
pointer, paste, viewport, and CRDT events without backpressure. This can grow
|
|
|
|
|
memory and can also deliver stale pointer/viewport traffic after the daemon
|
|
|
|
|
recovers.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Use a bounded channel with a clear policy. Coalesce superseded events such as
|
|
|
|
|
viewport and pointer motion. Consider failing fast or entering a degraded state
|
|
|
|
|
when the writer cannot keep up.
|
|
|
|
|
|
|
|
|
|
### F-009 - Low - Package fetch cache key uses non-cryptographic 64-bit FNV-1a
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/packages/fetcher.rs:161-165` derives the bare-repo cache path from a hash
|
|
|
|
|
of the normalized URL.
|
|
|
|
|
- `src/packages/fetcher.rs:510-518` implements 64-bit FNV-1a and describes it as
|
|
|
|
|
"collision-resistant enough for a cache key."
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
The package cache is keyed by potentially attacker-controlled repository URLs.
|
|
|
|
|
A deliberate or accidental hash collision could make two URLs share one bare
|
|
|
|
|
mirror path and lock file, mixing refs or producing confusing installs. This is
|
|
|
|
|
not a content-integrity bypass by itself, but it is avoidable risk in
|
|
|
|
|
security-adjacent package infrastructure.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Use SHA-256 or another cryptographic digest of the normalized URL for cache
|
|
|
|
|
directory names. Store the normalized URL in a sidecar file for diagnostics.
|
|
|
|
|
|
|
|
|
|
### F-010 - Low - Timed-out git subprocesses return before stdout/stderr drain threads are joined
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/packages/fetcher.rs:599-604` spawns stdout/stderr drain threads.
|
|
|
|
|
- `src/packages/fetcher.rs:611-617` kills and waits for the child on timeout,
|
|
|
|
|
then returns `FetchError::Timeout` immediately.
|
|
|
|
|
- `src/packages/fetcher.rs:630-631` only joins the drain threads on the normal
|
|
|
|
|
completion path.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Repeated fetch timeouts can leave short-lived detached reader threads behind
|
|
|
|
|
until their pipe reads finish. It is unlikely to leak permanently after the child
|
|
|
|
|
is killed, but it makes timeout behavior less deterministic and harder to test.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
After killing and waiting for the child, join the drain threads before returning
|
|
|
|
|
the timeout error, or restructure process execution around a timeout-aware
|
|
|
|
|
`wait_with_output` helper.
|
|
|
|
|
|
|
|
|
|
### F-011 - Low - `ResolvedPackage::commit` is documented as a SHA but can hold a tag string
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/packages/resolver.rs:143-144` documents `ResolvedPackage.commit` as a
|
|
|
|
|
"Full 40-character commit hash."
|
|
|
|
|
- `src/packages/resolver.rs:1036-1044` returns the tag string from
|
|
|
|
|
`TagCandidate::commit_for_tag`.
|
|
|
|
|
- `src/packages/lockfile.rs:573-610` compensates by resolving the commit-ish to a
|
|
|
|
|
SHA before writing the lockfile.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
The lockfile path is protected, but the internal type contract is misleading.
|
|
|
|
|
Downstream code that trusts `ResolvedPackage.commit` as a SHA can accidentally
|
|
|
|
|
re-resolve a moving commit-ish or use the field in error messages and markers as
|
|
|
|
|
if it were immutable.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Either resolve tags to SHA inside the resolver before constructing
|
|
|
|
|
`ResolvedPackage`, or rename the field to `revision`/`commitish` and update docs
|
|
|
|
|
and call sites to reflect the actual contract.
|
|
|
|
|
|
|
|
|
|
### F-012 - Low - Resolver topological sort contains dead/shadowed indegree work
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `src/packages/resolver.rs:705-715` builds and mutates an `indegree` map.
|
|
|
|
|
- `src/packages/resolver.rs:735-738` immediately shadows it with the actual
|
|
|
|
|
`indegree` map used by the algorithm.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
This is a small inefficiency and a readability hazard in dependency-ordering
|
|
|
|
|
code. The surrounding comments already show the algorithm was corrected in place,
|
|
|
|
|
but the abandoned block remains.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Delete the first `indegree` construction block and keep only the final outgoing
|
|
|
|
|
dependency-count implementation.
|
|
|
|
|
|
|
|
|
|
### F-013 - Low - GPU documentation and crate metadata are stale relative to implementation
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/Cargo.toml:6` still describes the crate as "session 2:
|
|
|
|
|
hello-world."
|
|
|
|
|
- `docs/pmacs-gpu-design.md:3-5` says the GPU work is pre-implementation with
|
|
|
|
|
sessions queued.
|
|
|
|
|
- The current GPU code has attach, CRDT, rendering, minimap, diagnostics,
|
|
|
|
|
minibuffer/menu, mouse, and editing code.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
New contributors and future audit passes start from incorrect project state.
|
|
|
|
|
This also makes it harder to decide which TODOs are live versus historical.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Update `pmacs-gpu` metadata and the top of the design note to point at the
|
|
|
|
|
current status and the active per-phase framing/audit docs.
|
|
|
|
|
|
|
|
|
|
### F-014 - Low - GPU visual behavior lacks a committed screenshot/pixel regression harness
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `pmacs-gpu/src/main.rs:5670-6750` contains 39 unit tests focused on helper
|
|
|
|
|
logic and vertex construction.
|
|
|
|
|
- The design note explicitly deferred acceptance-test shape to golden-frame or
|
|
|
|
|
screenshot comparison (`docs/pmacs-gpu-design.md:356-360`).
|
|
|
|
|
- I did not find an automated headless GPU screenshot/pixel test in `tests/` or
|
|
|
|
|
`pmacs-gpu/src`.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Layout and rendering regressions can pass the current unit suite. This matters
|
|
|
|
|
because the frontend has many pixel-local responsibilities: hit testing, dropdown
|
|
|
|
|
layout, minimap projection, diagnostic underlines, selection/current-line
|
|
|
|
|
backgrounds, and status/minibuffer composition.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Add at least one deterministic headless render smoke test or recorded-frame
|
|
|
|
|
pixel/golden harness. Start with narrow cases: nonblank frame, text visible,
|
|
|
|
|
dropdown visible and clipped, minimap visible, diagnostic underline visible, and
|
|
|
|
|
resize behavior.
|
|
|
|
|
|
|
|
|
|
### F-015 - Low - Repository contains backup/build artifacts and untriaged untracked files
|
|
|
|
|
|
|
|
|
|
Evidence:
|
|
|
|
|
|
|
|
|
|
- `find` located backup/editor artifacts:
|
|
|
|
|
- `#run.sh#`
|
|
|
|
|
- `docs/semantic-frontend-protocol.md.local-bak`
|
|
|
|
|
- `git status --short` also showed an untracked root-level `pmacs` file, which
|
|
|
|
|
appears likely to be a local build/run artifact.
|
|
|
|
|
- Several untracked docs are present and may be intentional, but they need
|
|
|
|
|
explicit triage before commit.
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
Backup and binary artifacts increase review noise and can be committed by
|
|
|
|
|
accident. Untracked docs make it unclear which design notes are canonical.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Remove or `.gitignore` editor backups and local binaries. Triage untracked docs
|
|
|
|
|
as either real project documents or local handoff notes.
|
|
|
|
|
|
|
|
|
|
### F-016 - Low - Very large source files are maintenance hotspots
|
|
|
|
|
|
|
|
|
|
Evidence from line counts:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
15202 src/lua_bindings.rs
|
|
|
|
|
7093 src/editor.rs
|
|
|
|
|
6761 pmacs-gpu/src/main.rs
|
|
|
|
|
3729 src/lsp.rs
|
|
|
|
|
3495 src/semantic_render.rs
|
|
|
|
|
3178 src/buffer.rs
|
|
|
|
|
2988 src/editor_core.rs
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Impact:
|
|
|
|
|
|
|
|
|
|
These files concentrate unrelated behavior, make review difficult, and increase
|
|
|
|
|
the chance of hidden coupling. `src/lua_bindings.rs` in particular combines many
|
|
|
|
|
Lua API domains, package management glue, LSP stores, theme bindings, attachment
|
|
|
|
|
bindings, and tests in one file.
|
|
|
|
|
|
|
|
|
|
Recommendation:
|
|
|
|
|
|
|
|
|
|
Split only along stable boundaries, not as a drive-by refactor. Good candidates:
|
|
|
|
|
Lua package APIs, Lua LSP APIs, Lua theme APIs, GPU input handling, GPU render
|
|
|
|
|
pipelines, GPU layout/dropdown logic, and editor command groups.
|
|
|
|
|
|
|
|
|
|
## Lua Audit Notes
|
|
|
|
|
|
|
|
|
|
The Lua audit command reported no errors. Warnings were:
|
|
|
|
|
|
|
|
|
|
- `builtin/packages/repl/init.lua:274`: `pmacs.process.spawn(spec)`.
|
|
|
|
|
- `tests/fixtures/pmacs-magit/gestures.lua:357`: `io.open(tmpfile, "w")`.
|
|
|
|
|
- `tests/fixtures/pmacs-magit/status.lua:55`: `pmacs.process.spawn { ... }`.
|
|
|
|
|
|
|
|
|
|
These are not automatically defects. The REPL package needs process access, and
|
|
|
|
|
fixture warnings are expected if those packages deliberately exercise filesystem
|
|
|
|
|
or process APIs. They should still be checked against package manifests whenever
|
|
|
|
|
fixtures graduate into real packages.
|
|
|
|
|
|
|
|
|
|
## Suggested Priority Order
|
|
|
|
|
|
|
|
|
|
1. Fix F-001 and update workspace verification commands.
|
|
|
|
|
2. Fix F-003 and F-004 before treating `pmacs-gpu` as user-ready.
|
|
|
|
|
3. Fix F-006 before relying on pmacs for editing permission-sensitive files.
|
|
|
|
|
4. Decide the package basename-collision policy in F-005 before wider package
|
|
|
|
|
ecosystem growth.
|
|
|
|
|
5. Add the GPU visual regression harness in F-014 before large layout changes.
|