528b16676e
gates / consistency-and-conventions (push) Successful in 2m16s
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.
76 lines
5.7 KiB
Markdown
76 lines
5.7 KiB
Markdown
# 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 check` → `check-sync: OK` (rc 0); `make lint` → `0 FAIL, 0 WARN`.
|
||
- R1 probe: dry-run ExecStart with a spaced model path → `systemd-analyze verify` rc 0; systemd word-split == exactly [binary, --model, <spaced path>, 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:
|
||
|
||
```bash
|
||
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 list` → `No 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 check` → `check-sync: OK` (rc 0).
|
||
- `make lint` → `0 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. |