Files
Linux_post_install/AgentsReport/builder/2026-09-06_r1r2-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

5.7 KiB
Raw Blame History

Builder Report — R1/R2 fixes (re-review findings)

Date: 2026-09-06 Builder: implementation pass on top of the re-review (AgentsReport/reviewer/2026-09-06_pos_ai_rereview.md) Approved scope: fix R1 (bin/pos-ai-server ExecStart quoting) and R2 (bin/pos-ai-hf partial-failure honesty). Files modified: only bin/pos-ai-server, bin/pos-ai-hf. Generated docs were refreshed by the mandated make gen gate.

TL;DR

  • Status: IMPLEMENTED — both REQUIRED findings fixed; all gates green; both targeted probes pass.
  • Files changed: bin/pos-ai-server (systemd_quote helper + quoted ExecStart tokens), bin/pos-ai-hf (honest failure count, .hf-meta gating, non-zero exit, honest progress labels).
  • Verification: bash -n clean; make gen idempotent (sha256-identical across runs); make checkcheck-sync: OK (rc 0); make lint0 FAIL, 0 WARN.
  • R1 probe: dry-run ExecStart with a spaced model path → systemd-analyze verify rc 0; systemd word-split == exactly [binary, --model, , each flag, each value] (16 tokens, asserted programmatically).
  • R2 probe: stub-curl 2-file parallel download with 1 failure → summary 📥 Downloaded: org/probe (1 of 2 files, 1 failed: model-fail.bin), NO .hf-meta written, list shows nothing, exit code 1.
  • AGENT_TODO.md intentionally NOT updated: the brief constrains modifications to the two files only ("Do not touch other files").

Step 1: R1 — systemd ExecStart quoting (bin/pos-ai-server)

Added systemd_quote() (bin/pos-ai-server:388-392): wraps a value in systemd double quotes and escapes embedded " as \" (verified: ${value//\"/\\\"} produces \"). cmd_start now builds the base line as:

exec_cmd="$(systemd_quote "$llamacpp_full") -m $(systemd_quote "$model") --port $PORT --host $HOST"

(bin/pos-ai-server:445). Only the executable path and the model path — the tokens that may legally contain spaces per the brief — are quoted; numeric/flag tokens (--port 8088, --n-gpu-layers 10, …) stay unquoted, so no over-quoting. The unit heredoc still writes ExecStart=$exec_cmd (bin/pos-ai-server:508) and the dry-run prints the same $exec_cmd (bin/pos-ai-server:491), so dry-run output is byte-identical to the unit by construction.

Probe (run with fake llama-server from /tmp/opencode/ai-probe/bin, model at /tmp/opencode/ai-probe/models/My Model/ggml-model-Q4_K_M.gguf, flags --port 9090 --gpu-layers 10 --ctx-size 2048 --temperature 0.7 --mmap):

[+] (dry-run) ExecStart: "/tmp/opencode/ai-probe/bin/llama-server" -m "/tmp/opencode/ai-probe/models/My Model/ggml-model-Q4_K_M.gguf" --port 9090 --host 127.0.0.1 --n-gpu-layers 10 --ctx-size 2048 --threads 4 --temperature 0.7 --mmap
rc=0
systemd-analyze verify → rc=0
word-split == [binary, --model, <spaced path>, each flag, each value] → True (16 tokens)

[DONE]

Step 2: R2 — partial-failure honesty (bin/pos-ai-hf)

Changes inside cmd_download only; the sequential single-file path (else branch) is byte-for-byte unchanged:

  • failed_files is now function-scoped (bin/pos-ai-hf:632), populated only by the parallel branch, so the sequential path is unaffected (empty array there).
  • Progress labels are honest: a reaped job that failed prints [n/m] Failed: <file> instead of Completed: (bin/pos-ai-hf:672, 686).
  • .hf-meta is written only when failed_files is empty; on partial failure a warn explains the skip (bin/pos-ai-hf:727-744). Consumers list/cache only discover models with .hf-meta (cmd_list/hf_cache_models), so an incomplete model is not advertised.
  • Summary is honest for the parallel path: 📥 Downloaded: <repo> (X of Y files, N failed: <f1> <f2>) where X = Y N (bin/pos-ai-hf:760-761). The all-success multi-file summary and the single-file summary are unchanged.
  • Exit: return 1 when failed_files is non-empty (bin/pos-ai-hf:773-775) — only reachable from the parallel path.

Probe (stub curl in /tmp/opencode/ai-probe/r2bin, canned 2-file listing, target containing fail exits 1; download org/probe --branch main with both files in one parallel batch):

[1/2] Completed: model-ok.bin
[2/2] Failed: model-fail.bin
[!] Failed to download model-fail.bin
[!] Not writing .hf-meta — org/probe is incomplete (1 file(s) failed)
📥 Downloaded: org/probe (1 of 2 files, 1 failed: model-fail.bin)
📁 /tmp/opencode/ai-probe/dl/org-probe/
rc=1

Post-checks: dir contains only model-ok.bin (no .hf-meta); pos ai hf listNo models downloaded yet; single-file sequential success → meta written, rc 0 (unchanged); single-file sequential failure → warn-and-continue, rc 0 (unchanged, pre-existing behavior preserved per constraint).

[DONE]

Step 3: Gates

  • bash -n bin/pos-ai-server bin/pos-ai-hf → clean.
  • make gen ×2 → gen-docs: write OK; sha256 of DOC/AGENT_Context_Project.md + completions/pos.bash identical across runs → idempotent. Filetable row counts now match wc -l exactly (pos-ai-hf 1004, pos-ai-server 659).
  • make checkcheck-sync: OK (rc 0).
  • make lint0 FAIL, 0 WARN (convention lint).

[DONE]

Scope compliance / residual notes

  • Only bin/pos-ai-server and bin/pos-ai-hf were edited by this pass; DOC/AGENT_Context_Project.md/completions/pos.bash were refreshed only by the mandated make gen gate (line counts/examples columns). No new flags/subcommands/config keys. AGENT_TODO.md not touched (brief forbids other files).
  • Residual risk (pre-existing, explicitly out of scope by the "keep sequential path unchanged" constraint): the single-file sequential failure path still warns-and-continues with rc 0 and writes .hf-meta including the failed file. Flagged for a future decision; not changed here.
  • Probes ran in this environment (real systemd-analyze, bash, make available); nothing was blocked.