Files
Linux_post_install/AgentsReport/builder/2026-09-06_review-fixes.md
T
Your Name 528b16676e
gates / consistency-and-conventions (push) Successful in 2m16s
fix: review-driven hardening of pos ai hf/server + llamacpp provider
Adversarial review of the AI tools (commits 387f23f/0856b25) found 2
BLOCKING + 5 REQUIRED defects; all fixed:

- pos-ai-hf --include/--exclude: bash-case glob filtering (array-safe,
  no jq regex interpolation, composes gguf->filename->include->exclude)
- pos-ai-server: ExecStart rebuilt as single-line properly-quoted command
  (systemd_quote for executable + model path; systemd-analyze verify rc=0)
- --branch/--revision aliased (last wins), dead BRANCH variable removed
- parallel download drains all jobs: per-pid wait, honest
  'X of Y files, N failed' summary, rc=1 on partial failure, no .hf-meta
  for half-downloaded models, EXIT-trap temp cleanup
- detect_llama_version guarded; validate_requested_flags errors on
  unsupported explicit flags with version-aware message
- pos ai hf cache [status|clear]: real implementation, fail-closed confirm
- new bin/pos-ai-llamacpp thin forwarder + llamacpp shorthand in bin/pos-ai
  (pos ai llamacpp <subcmd> = pos ai --provider llamacpp <subcmd>)
- docs synced: bin/pos-ai usage(), DOC/POS.md AI_PROVIDER row, howto/ai.md
  (adapter list, --provider backends, shorthand, providers table); gen
  regenerated (tree/dispatch/completions)

Verified: bash -n all bin/pos*; make gen idempotent; make check green;
make lint 0 FAIL, 0 WARN. Reviewer acceptance: APPROVE_WITH_NOTES
(0 REQUIRED). Audit deliverables + agent reports included for context.
2026-09-06 03:45:53 -04:00

9.1 KiB
Raw Blame History

Builder Report — POS AI review fixes (F1F6)

Date: 2026-09-06 Builder: big-pickle

TL;DR

  • Status: IMPLEMENTED
  • Fixes F1F6 from AgentsReport/reviewer/2026-09-06_pos_ai_full_review.md implemented in bin/pos-ai-hf, bin/pos-ai-server, DOC/POS.md (hf + server detail), generated docs via make gen.
  • Scope: exactly the approved fixes; no changes to bin/pos-ai, bin/pos-ai-llamacpp, bin/pos, README.md, AGENT_TODO.md, lib/ (AGENT_TODO.md not updated on purpose — out of scope, has pre-existing worktree edits).
  • Verification: bash -n clean; make gen idempotent (3rd run md5-identical); make check → check-sync: OK; make lint0 FAIL, 0 WARN; targeted probe matrix below (all passed).
  • Deviation from reviewer wording: destroy-confirmation for cache clear reads /dev/tty (same pattern as pos-ai-server pick_model) instead of sourcing lib/common.sh confirm()pos-ai-hf is NOT in bin/pos INTERACTIVE_CMDS and bin/pos is off-limits, so a plain stdin read/confirm would hang-or-trip the uses_stdin lint rule. Fail-closed default n, EOF/invalid denies (verified via setsid/pty probes).

Step 1: F1 — include/exclude glob filtering (pos-ai-hf)

[DONE]

  • Removed the --include/--exclude + --gguf erroring pre-check (bin/pos-ai-hf cmd_download) — patterns now compose, not conflict.
  • Removed the old jq match() regex branch (regex semantics despite "supports glob" docs) from the elif chain; single composition point after gguf/filename filter, order: gguf/filename → include → exclude.
  • New hf_apply_patterns() (bin/pos-ai-hf:422-447): bash case glob semantics, always yields a JSON array ([] when no match) preserving {"rfilename","size"} shape.
  • Added error path No files match include/exclude patterns in <repo> (branch: <branch>) (rc 1) when patterns filter everything out.

Probes (fake curl serving canned repo):

  • --include "model.gguf" (single file, sequential): rc 0, only model.gguf fetched, .hf-meta files array is a JSON array of 1.
  • --include "*.gguf" (parallel): rc 0, model.gguf + Q8_0/model-q8.gguf fetched, meta files array length 2.
  • --include "*.bin"ERROR: No files match include/exclude patterns in org/model (branch: main), rc 1.
  • --gguf --include "*.gguf" composes: rc 0, same 2 gguf files.
  • exclude-only --exclude "*.safetensors" → rc 0, 3 files remain.

Step 2: F2 — systemd unit single-line ExecStart (pos-ai-server)

[DONE]

  • cmd_start now builds ONE exec_cmd string with binary + model + all resolved flags (bin/pos-ai-server:431-477); unit written via heredoc with ExecStart=$exec_cmd on a single line (bin/pos-ai-server:488-504) — no more multi-line echo >> appends that systemd rejects.
  • Dry-run prints the same $exec_cmd it would write into the unit (previously the dry-run line missed all optional flags).
  • Real (non-dry) start: unit written, then systemctl --user daemon-reload (container has no systemd user session → fails after write, expected; unit itself verified).

Probes:

  • dry-run with all flags: single ExecStart line containing every flag, rc 0.
  • real run wrote the unit; systemd-analyze verify <unit>RC=0, no warnings (executable path resolves, EnvironmentFile=-%h/... accepted).

Step 3: F3 — --branch/--revision alias (pos-ai-hf)

[DONE]

  • Removed the separate BRANCH variable; --branch and --revision both set REVISION (bin/pos-ai-hf:127-148), last flag wins (usage documents the alias).
  • hf_resolve_branch unchanged: explicit revision or API default branch, falls back main.

Probes:

  • --branch main, --revision v1.0, and --revision v2.0 --branch main (later wins → main) all rc 0.

Step 4: F4 — parallel download failure handling (pos-ai-hf)

[DONE]

  • Rewrote the parallel path (bin/pos-ai-hf:638-692): per-pid wait with ! wait failure capture, parallel job_pids/job_names arrays, failed_files collection, per-job log files under mktemp -d temp dir (no interleaved output), individual job reaped as batch limit reached AND full drain at the end, per-file Failed to download <file> warns after the batch (same style as sequential path), trap 'rm -rf "$temp_dir"' EXIT + explicit rm -rf + trap - EXIT so temp dirs never survive.
  • Removed dead helpers err_with_context, hf_download_file, run_parallel_download.

Probes (poisoned fake curl failing only Q8_0/model-q8.gguf):

  • 2-file parallel download: 1 success + 1 failure — batch rc 0, [!] Failed to download Q8_0/model-q8.gguf reported at end, successful file on disk, zero stray /tmp/tmp.* dirs after exit.
  • Known limit (pre-existing, noted not in review scope): summary line counts attempted files (2 files, 40 B) even when one fails — same optimistic counting as the sequential path.

Step 5: F5 — version/feature validation guard (pos-ai-server)

[DONE]

  • detect_llama_version <binary> guarded: missing binary or unreadable --versionunknown, never errexit (previously called llama-server --version directly → crash when binary absent).
  • Replaced no-op validate_server_features with validate_requested_flags <binary> <version> <flag...>: greps the binary's actual --help output for each explicitly requested flag token; first unsupported one errors installed llama.cpp <version> does not expose <flag> — remove it or upgrade llama.cpp; unreadable --help → warn once and proceed (no hard-fail). Alias-mapped requests dedupe (--gpu/--gpu-layers/--n-gpu-layers all validate --n-gpu-layers).
  • Parse loop records canonical request tokens in REQUESTED_FLAGS (defaults/config-derived values NOT validated — only what the user typed).
  • cmd_status: binary guard with actionable error before version probe; version printed via the resolved binary path.

Probes (fake llama-server v0.1.0 whose --help omits --kv-cache and --slots):

  • start --model fake.gguf --slots 4ERROR: installed llama.cpp 0.1.0 does not expose --slots — remove it or upgrade llama.cpp, rc 1 (also proves validation runs before dry-run return).
  • status without llama-server on PATH → ERROR: llama-server not found — install llama.cpp (...), rc 1, no crash.
  • status with shim → service: stopped, version: 0.1.0, rc 0.

Step 6: F6 — hf cache real implementation (pos-ai-hf)

[DONE]

  • cmd_cache {status|clear} with default status (bin/pos-ai-hf:887-894); bad action → usage error. Top-level indent of cmd_cache() fixed (reviewer style nit).
  • cmd_cache_status: cache dir + model count + total on-disk size (excludes .hf-meta — same discovery as list/remove); empty dir → Models: 0 (nothing downloaded yet), rc 0.
  • cmd_cache_clear: lists models to be removed, then confirm Remove all downloaded models? [y/N]: read from /dev/tty (see TL;DR deviation), fail-closed — anything but y/Y (including EOF) → Aborted — nothing removed, rc 0; on y removes all model dirs and prints freed size.

Probes:

  • cache status empty cache: rc 0, Models: 0 (nothing downloaded yet).
  • cache status 2 fake models: Models: 2 / Size: 5 B, rc 0.
  • cache clear under setsid (EOF, no tty): prompt shown, Aborted — nothing removed, rc 0, models intact; clean stderr (the /dev/tty open error is suppressed: read -r yn 2>/dev/null </dev/tty — redirection order matters).
  • cache clear via pty (script -qec feeding y): list shown, prompt, Cache cleared (freed 9 B), rc 0, model dirs gone.

Step 7: Docs (DOC/POS.md) + make gen/check/lint

[DONE]

  • DOC/POS.md: hf download row updated (--revision alias, include/exclude glob composition order, example), new pos ai hf cache [status|clear] row, server flags+validation detail extended.
  • make gen after touching bin files: tree/dispatch/filetable/completions regenerated (also repairs the pre-existing stale _pos_flags for ai-hf/ai-server and picks up the maintainer's untracked pos-ai-llamacpp forwarder).
  • Gates (final state): bash -n bin/pos-ai-hf bin/pos-ai-server → OK; make gen twice after edits → second run byte-identical (idempotent); make check → check-sync: OK; make lint0 FAIL, 0 WARN.

Files changed (this task)

  • bin/pos-ai-hf — F1/F3/F4/F6 (+ dead code removal, style fix)
  • bin/pos-ai-server — F2/F5
  • DOC/POS.md — hf download row, cache row, server flags/validation
  • DOC/AGENT_Context_Project.md, completions/pos.bash — generated by make gen (auto-rows, flags, subcmd completion)

Pre-existing worktree drift NOT touched (confirmed untouched in final diff): AGENT_TODO.md, DOC/howto/ai.md, bin/pos, bin/pos-ai, untracked bin/pos-ai-llamacpp, AUDIT.md etc.

Remaining risks / deferrals

  • systemctl --user daemon-reload/enable --now cannot complete inside this container (no systemd user session) — real start verified only up to unit write + systemd-analyze verify RC 0; the systemctl calls themselves are otherwise standard.
  • Summary line after a partially failed parallel download counts attempted files, not successes (pre-existing, matches sequential path; not flagged in review).
  • validate_requested_flags warns-and-proceeds if --help cannot be read (deliberate: silent-basic-defaults behavior lost, actionable warning kept).