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.
289 lines
15 KiB
Markdown
289 lines
15 KiB
Markdown
# Maintainer Report — 2026-09-06 — POS CLI convention sweep (AI tools)
|
||
|
||
## TL;DR
|
||
|
||
- Objective: comprehensive convention/maintenance sweep over the POS CLI AI tooling
|
||
after several AI-tool changes (`bin/pos-ai-llamacpp` forwarder, enhanced
|
||
`bin/pos-ai-hf`, enhanced `bin/pos-ai-server`, `bin/pos-ai` shorthand,
|
||
`bin/pos` INTERACTIVE_CMDS) + llamacpp doc drift. Restore the established
|
||
standard; do not redesign.
|
||
- Verified-clean (no changes needed): `bin/pos-ai-llamacpp` (shebang, strict-mode,
|
||
`# POS:` style, `# POS_SUBCMDS:` = actual adapter support, mode 100755,
|
||
`-h|--help`, exec body — byte-mirror of gemini), `bin/pos-ai-hf` (all headers vs
|
||
implementation, 11 unique examples, no dupes), `bin/pos-ai-server` (all headers
|
||
vs implementation; config keys already registered in the `ai` scope via
|
||
`bin/pos-ai` POS_CONFIG, commit adf88cc), `bin/pos` (INTERACTIVE_CMDS entry
|
||
format + lint expectation; usage EXAMPLES has no factual provider list).
|
||
- Corrected 7 factual provider-list omissions (llamacpp is a real provider:
|
||
`lib/ai-providers/llamacpp.sh` + wired in `bin/pos-ai` resolve/require/model
|
||
paths): `bin/pos-ai` usage() ×2, `DOC/POS.md` AI_PROVIDER config row,
|
||
`DOC/howto/ai.md` ×4 (adapter list, `--provider` backend list, backward-compat
|
||
shorthand, "Available providers" table row).
|
||
- Ledger: 1 dated Done entry added to `AGENT_TODO.md`.
|
||
- Validation: `bash -n` all `bin/pos*` OK; `make gen` idempotent (byte-identical
|
||
before/after — no header changes); `make check` → `check-sync: OK`;
|
||
`make lint` → **0 FAIL, 0 WARN (convention lint)**; smoke:
|
||
`pos-ai --help` shows llamacpp lists, `pos-ai llamacpp --help`/`providers`
|
||
dispatch correctly to provider llamacpp.
|
||
- No commit (per brief — Orchestrator integrates).
|
||
|
||
## Step 1: `bin/pos-ai-llamacpp` (new forwarder) — verify only
|
||
|
||
Evidence (`bin/pos-ai-llamacpp:1-7`):
|
||
- `#!/usr/bin/env bash` + `set -euo pipefail` (lines 1-2) ✓
|
||
- `# POS: ai llamacpp — Forward to pos ai --provider llamacpp (backward compat)`
|
||
(line 3) — same style as `bin/pos-ai-gemini:3` / `bin/pos-ai-openrouter:3` ✓
|
||
- `# POS_SUBCMDS: ask chat models sessions capture` (line 4) — mirrors gemini;
|
||
verified against `lib/ai-providers/llamacpp.sh`: it implements
|
||
`provider_generate` (drives `cmd_ask`/`cmd_chat`/`cmd_sessions`/`cmd_capture`
|
||
in `bin/pos-ai`) and `provider_models_list` (drives `cmd_models`) — so all 5
|
||
listed subcommands are supported by the adapter. No invented subcommands ✓
|
||
- mode `755` (100755) via `stat` ✓
|
||
- `-h|--help` case (line 6) present, same as gemini; no deps guards to order
|
||
against ✓
|
||
- exec forward body `exec pos ai --provider llamacpp "$@"` (line 7) ✓
|
||
- Lint gate cross-check (`scripts/lint-conventions.sh`): shebang/strict-mode for
|
||
all shell files; exec-bit for `bin/pos-*`; `# POS:` + em-dash; `-h|--help`
|
||
regex; `uses_stdin` → forwarded tool reads stdin via `pos ai chat`, so
|
||
`ai-llamacpp` must be in INTERACTIVE_CMDS (it is, see Step 5) — and the reverse
|
||
lint rule (`INTERACTIVE_CMDS` entry needs matching executable `bin/pos-ai-llamacpp`)
|
||
is satisfied.
|
||
|
||
No changes. Status: [DONE]
|
||
|
||
## Step 2: `bin/pos-ai-hf` (enhanced) — verify only
|
||
|
||
Evidence vs implementation:
|
||
- `# POS: ai hf — …` (`bin/pos-ai-hf:3`) ✓
|
||
- `# POS_FLAGS: --branch --gguf --list --output --quant --include --exclude --revision`
|
||
(line 4) — every flag is parsed in the arg loop (lines 122-145: `--branch`,
|
||
`--gguf`, `--list`, `--quant`, `--output`, `--include`, `--exclude`,
|
||
`--revision`); no stale/duplicated flags ✓
|
||
- `# POS_DEPS: curl jq` (line 5) — both `command -v` guards sit before `--help`
|
||
(lines 18-19) ✓
|
||
- `# POS_CONFIG: ai | ai.env | HF_TOKEN=secret:… | HF_DOWNLOAD_DIR=:…` (line 6) —
|
||
script reads `HF_TOKEN` (lines 27, 167-168, 183-184) and `HF_DOWNLOAD_DIR`
|
||
(lines 28, 164) ✓
|
||
- `# POS_EXAMPLES:` — 11 unique lines (7-17), no duplicate lines; every example
|
||
maps to an implemented subcommand (search / download variants / list / remove /
|
||
info / files) ✓
|
||
- usage() (lines 48-97) lists subcommands `search download list remove info files
|
||
cache` — dispatch (lines 813-823) implements exactly those (`cmd_search`,
|
||
`cmd_download`, `cmd_list`, `cmd_remove`, `cmd_info`, `cmd_files`, `cmd_cache`);
|
||
all 8 flags documented in usage match the parse loop ✓
|
||
|
||
No changes (the 3 duplicate examples were already removed by the previous
|
||
maintainer pass `2026-09-06_restore-cleanup.md`). Status: [DONE]
|
||
|
||
## Step 3: `bin/pos-ai-server` (enhanced) — verify only
|
||
|
||
Evidence vs implementation (full read of `bin/pos-ai-server`):
|
||
- `# POS: ai server — llama.cpp local inference server (start, stop, status, models, logs)` (line 3) ✓
|
||
- `# POS_SUBCMDS: start stop status models logs` (line 4) — dispatch (lines 605-613:
|
||
`start`, `stop`, `status`, `models`, `logs`) matches exactly ✓
|
||
- `# POS_FLAGS:` (line 5) — all 23 listed flags are parsed in the arg loop
|
||
(lines 262-340: `--port --host --model --ctx --gpu --threads --gpu-layers
|
||
--gpu-threads --tensor-split --n-gpu-layers --batch-size --ubatch-size
|
||
--temperature --top-k --top-p --repetition-penalty --mmap --mlock --kv-cache
|
||
--ctx-size --metrics --health --slots`); no extra/missing flags ✓
|
||
- `# POS_DEPS: curl jq` (line 6) — both guarded before `--help` (lines 11-12) ✓
|
||
- usage() (lines 174-233): commands, all flags, and the `LLAMACPP_*` config-key
|
||
block (lines 222-228) match the implementation (reads `LLAMACPP_PORT/HOST/MODEL/
|
||
CTX_SIZE/GPU_LAYERS/THREADS` from `~/.config/linux_post_install/ai.env`) ✓
|
||
- POS_CONFIG: the tool itself has no `# POS_CONFIG:` header, but the `LLAMACPP_*`
|
||
keys it reads are ALREADY registered in the `ai` scope by `bin/pos-ai:6`
|
||
POS_CONFIG (committed `adf88cc fix: pos config ai splits llamacpp into its own
|
||
section`), same env file. Adding a header here would duplicate the registration
|
||
and is a feature add, not drift restoration → left untouched per "smallest safe
|
||
change" + Do-not-redesign.
|
||
|
||
No changes. Status: [DONE]
|
||
|
||
## Step 4: `bin/pos-ai` (modified) — shorthand case OK; 2 stale usage() lines fixed
|
||
|
||
- New `llamacpp` dispatch case (`bin/pos-ai:701-704`):
|
||
`llamacpp) exec "$0" --provider llamacpp "${args[@]}" ;;` — matches the
|
||
gemini/openrouter forwarder semantics (`pos ai llamacpp <subcmd> … == pos ai
|
||
--provider llamacpp <subcmd> …`); sits with the other parallel cases in the
|
||
final `case "${cmd:-}"` dispatch, `*)` error still last. Verified behavior:
|
||
`bin/pos-ai llamacpp --help` and `llamacpp providers` both resolve to provider
|
||
llamacpp (`llamacpp configured (model: … ) ← active`).
|
||
- STALE usage() provider lists — FACTUALLY WRONG about supported providers
|
||
(llamacpp is wired: `lib/ai-providers/llamacpp.sh` exists; `bin/pos-ai`
|
||
`resolve_key`/`require_key`/`resolve_model` handle `llamacpp` cases; POS_CONFIG
|
||
line 6 already lists "gemini, openrouter or llamacpp"; POS.md row 72 lists
|
||
llamacpp):
|
||
- `bin/pos-ai:42` `AI assistant with pluggable providers (gemini, openrouter).`
|
||
→ `AI assistant with pluggable providers (gemini, openrouter, llamacpp).`
|
||
- `bin/pos-ai:59` `--provider <name> Provider to use (gemini|openrouter; default: gemini).`
|
||
→ `--provider <name> Provider to use (gemini|openrouter|llamacpp; default: gemini).`
|
||
- Line 81 (`AI_PROVIDER … (gemini|openrouter|llamacpp, default gemini)`) was
|
||
already correct — untouched.
|
||
- Headers: `# POS_SUBCMDS: ask chat sessions capture models providers` (line 4)
|
||
vs dispatch (ask/capture/chat/models/providers/sessions) — same 6, complete ✓;
|
||
`# POS_FLAGS: --provider --model --session --system --full --last --trust`
|
||
(line 5) — all 7 parsed in the arg loop (lines 655-680) ✓; POS_CONFIG (line 6)
|
||
includes llamacpp + `LLAMACPP_*` keys ✓.
|
||
|
||
Status: [DONE]
|
||
|
||
## Step 5: `bin/pos` (modified) — INTERACTIVE_CMDS verified; EXAMPLES verdict
|
||
|
||
- `ai-llamacpp` added to INTERACTIVE_CMDS (`bin/pos:269`) after `ai-openrouter`,
|
||
byte-consistent with `ai-gemini`/`ai-openrouter` (space-separated in the same
|
||
string). Lint gate (`scripts/lint-conventions.sh:174-180`) requires each entry
|
||
to have a matching executable `bin/pos-$entry` — `bin/pos-ai-llamacpp` exists
|
||
(100755) → the entry is required AND correct. The stdin rule
|
||
(lint lines 162-167) is satisfied via the INTERACTIVE_CMDS registration
|
||
(`pos ai llamacpp chat` reads stdin → must skip the logging tee pipe).
|
||
- usage() EXAMPLES block (`bin/pos:201-204`): showcases `pos ai gemini …`, shows
|
||
no factual provider list → no change (matches the Builder's judgment; adding a
|
||
llamacpp line would be inconsistent with openrouter having none).
|
||
|
||
No changes. Status: [DONE]
|
||
|
||
## Step 6: `DOC/POS.md` — AI_PROVIDER row fixed; Builder's 3 edits verified
|
||
|
||
- Builder's 3 hand-edits verified consistent end-to-end:
|
||
- line 58 file list now includes `bin/pos-ai-llamacpp` ✓
|
||
- line 72 `--provider <name>` row `(gemini\|openrouter\|llamacpp)` ✓
|
||
- line 82 backward-compat sentence includes `pos ai llamacpp` ✓
|
||
- line 59 adapters list already includes `lib/ai-providers/llamacpp.sh` ✓
|
||
- Remaining staleness fixed: line 90 config table
|
||
`| AI_PROVIDER | no | gemini | Active provider (gemini\|openrouter) |`
|
||
→ `Active provider (gemini\|openrouter\|llamacpp)` — llamacpp is a real provider
|
||
adapter, and the row lists provider values for the other two, so llamacpp must
|
||
be mentioned (brief's explicit criterion).
|
||
- Also verified no duplicate/stale `pos ai hf` / `pos ai server` rows elsewhere
|
||
in the section.
|
||
|
||
Status: [DONE]
|
||
|
||
## Step 7: `DOC/howto/ai.md` — 4 provider-list fixes (brief lines 29-30 + same root cause)
|
||
|
||
Same root cause as Step 6 (provider/shorthand lists omit llamacpp); fixed all
|
||
instances minimally, facts from `lib/ai-providers/llamacpp.sh`:
|
||
1. line 5 `pluggable provider adapters (gemini, openrouter)` →
|
||
`(gemini, openrouter, llamacpp)`.
|
||
2. lines 19-20 `--provider <name>` backend list `(gemini|openrouter;` →
|
||
`(gemini|openrouter|llamacpp;` (wrap preserved).
|
||
3. lines 29-30 backward-compat shorthand sentence (brief's named instance):
|
||
`pos ai gemini` / `pos ai openrouter` → adds `pos ai llamacpp` as shorthand
|
||
for `pos ai --provider llamacpp`.
|
||
4. "Available providers" table (lines 134-137) gains a row:
|
||
`| llamacpp | Local llama.cpp (OpenAI-compatible) | loaded on the running server | LLAMACPP_MODEL |`
|
||
— facts verified: OpenAI-compatible `/v1/chat/completions` (llamacpp.sh:3,31),
|
||
`provider_default_model()` reads the loaded model from the running server via
|
||
`/v1/models` (llamacpp.sh:11-16), config key `LLAMACPP_MODEL`
|
||
(llamacpp.sh:7 `PROVIDER_CONFIG:`).
|
||
|
||
Terse-but-correct statements left alone (e.g. line 3 "Gemini, OpenRouter, and
|
||
more", line 10 openrouter-only example rows — the doc's example style, not
|
||
factual provider enumerations).
|
||
|
||
Status: [DONE]
|
||
|
||
## Step 8: `bin/pos` usage() EXAMPLES — no factual provider list → no change
|
||
|
||
Verified `bin/pos:201-204`: the ai EXAMPLES show `pos ai gemini …` as a usage
|
||
showcase only (openrouter has no line either) — no provider enumeration to
|
||
update. Per brief, no change. Status: [DONE]
|
||
|
||
## Step 9: Global gates (`bash -n` / `make gen` / `make check` / `make lint`)
|
||
|
||
- `bash -n` across every `bin/pos*` file → all OK.
|
||
- `make gen` → `gen-docs: write OK`; second run byte-identical (md5sums of
|
||
`DOC/AGENT_Context_Project.md` + `completions/pos.bash` match the pre-edit
|
||
baseline) → idempotent, no gen drift introduced (no `# POS_*` headers changed).
|
||
- `make check` → `check-sync: OK`.
|
||
- `make lint` → `0 FAIL, 0 WARN (convention lint)`.
|
||
- Smoke: `bin/pos-ai --help` prints the corrected provider lists;
|
||
`bin/pos-ai llamacpp --help` → usage exit 0; `bin/pos-ai llamacpp providers` →
|
||
`llamacpp … ← active` (no "Unknown ai subcommand").
|
||
|
||
Status: [DONE]
|
||
|
||
## Step 10: `AGENT_TODO.md` ledger
|
||
|
||
- Added one dated Done one-liner (2026-09-06, convention sweep — llamacpp
|
||
doc/usage sync) at the top of `## Done`, established style (newest batch at
|
||
top; single entry this pass). Existing entries untouched.
|
||
|
||
Status: [DONE]
|
||
|
||
## Remaining drift found but NOT fixed (with reason)
|
||
|
||
- `DOC/POS.md:124` `pos ai server` "Flags:" line enumerates only 7 of the 23
|
||
implemented flags (omits the 16 advanced flags from commit 0856b25); same for
|
||
`DOC/POS.md:108` `pos ai hf` "Options:" line (omits `--include`/`--exclude`/
|
||
`--revision`). This is the established terse-summary style of POS.md flag rows
|
||
(both sections predate the enhanced work), the statements are correct as far as
|
||
they go, and the sweep brief names only llamacpp-caused drift for docs — the
|
||
tool usage() help documents all flags. Reason: out of named scope; fixing would
|
||
require a doc-completeness decision (Architect/Writer), not drift restoration.
|
||
- `bin/pos-ai-server` has no `# POS_CONFIG:` header. NOT a gap: the `LLAMACPP_*`
|
||
keys it reads are already registered in the `ai` scope via `bin/pos-ai:6`
|
||
POS_CONFIG (commit adf88cc), same env file `ai.env` — `pos config ai` already
|
||
edits them. Adding a header would be a duplicate registration / feature add.
|
||
- Untracked plan documents in the working tree (`AUDIT.md`, `AUDIT_TABLE.md`,
|
||
`FINAL_SUMMARY.md`, `IMPLEMENTATION_PLAN.md`) and untracked
|
||
`AgentsReport/maintainer/2026-09-06_restore-cleanup.md` +
|
||
`AgentsReport/builder/*.md` reports — noted in Step 1 of the previous
|
||
maintainer pass; Orchestrator decision (commit/delete), not this brief.
|
||
|
||
## Completion handoff
|
||
|
||
Status: MAINTENANCE_COMPLETE
|
||
|
||
Maintenance objective:
|
||
- Convention sweep over the POS AI CLI tooling after the AI-tool changes;
|
||
verify/fix conventions only, restore the established standard, do not redesign.
|
||
|
||
Findings addressed:
|
||
- 7 factual provider-list omissions fixed (llamacpp omitted): `bin/pos-ai`
|
||
usage() ×2, `DOC/POS.md` AI_PROVIDER row ×1, `DOC/howto/ai.md` ×4.
|
||
- Verified clean (no changes): `bin/pos-ai-llamacpp`, `bin/pos-ai-hf`,
|
||
`bin/pos-ai-server`, `bin/pos` INTERACTIVE_CMDS + EXAMPLES, all `# POS_*`
|
||
headers vs implementations.
|
||
|
||
Standard enforced:
|
||
- `templates/pos-tool.sh` convention + AGENTS.md header rules; provider list
|
||
claims in docs/help must match the real adapters
|
||
(`lib/ai-providers/{gemini,openrouter,llamacpp}.sh`); generated blocks only via
|
||
`make gen`; `pos config` scope registry via `# POS_CONFIG:`.
|
||
|
||
Files changed (this pass):
|
||
- `bin/pos-ai` (+2 lines: usage() provider lists)
|
||
- `DOC/POS.md` (+1 row edit: AI_PROVIDER)
|
||
- `DOC/howto/ai.md` (4 edits: adapter list, backend list, backward-compat, table row)
|
||
- `AGENT_TODO.md` (+1 Done entry)
|
||
- `AgentsReport/maintainer/2026-09-06_convention-sweep.md` (this report)
|
||
|
||
Verification performed:
|
||
- `bash -n` all `bin/pos*` OK; `make gen` idempotent (byte-identical);
|
||
`make check` → `check-sync: OK`; `make lint` → 0 FAIL, 0 WARN;
|
||
smoke: llamacpp shorthand/usage paths live.
|
||
|
||
Records updated:
|
||
- `AGENT_TODO.md` Done ledger (1 dated entry); this report.
|
||
|
||
Scope compliance:
|
||
- In-scope corrections only; no behavior changes; no redesign; no commit.
|
||
- Out-of-scope changes: none. `README.md`, `lib/ai-providers/*.sh`, `bin/pos`,
|
||
`bin/pos-ai-hf`, `bin/pos-ai-server`, `bin/pos-ai-llamacpp` untouched by me
|
||
(working-tree changes from Builder preserved).
|
||
|
||
Remaining / deferred items:
|
||
- POS.md flag rows are terse partial enumerations (established style; tool
|
||
usage() is complete) — noted, out of named scope.
|
||
- Untracked plan docs + agent reports awaiting Orchestrator decision.
|
||
|
||
Recommended next agent:
|
||
- Orchestrator
|
||
|
||
Reason:
|
||
- All sweep items verified, gates green, docs synchronized; per the brief no
|
||
commit was made — Orchestrator integrates and commits.
|
||
|
||
Changes made by Maintainer:
|
||
- 7 minimal factual provider-list corrections (usage + docs) and 1 ledger entry. |