Files
Linux_post_install/AgentsReport/builder/2026-09-06_netprobe-fix.md
T
Your Name d817c37652
gates / consistency-and-conventions (push) Successful in 26s
fix: stabilization pass — fail-closed auth, ai flag validation, lint/config/security hardening, regression tests
17-point code-level audit executed via Explorer->Architect->Builder->Tester->Reviewer;
Reviewer accepted (APPROVE_WITH_NOTES; 3 block-list items resolved):

- security: telegram sender-owner AND-gate + TELEGRAM_OWNER_ID, matrix
  MATRIX_ROOM_ID fail-closed, gpg --passphrase-fd 3 (no argv secret),
  /dev/tcp positional-arg form (checkport/smb-client/share-lib/NET_PROBE),
  eval deny-by-default + --no-command-execution carried by both chat bridges,
  tty-gated --trust; config/{telegram,matrix}.env reference templates
- ai: all ExecStart flags validated against installed llama.cpp
  (requested->error, default->omit+warn, CONFIG_REQUESTED_FLAGS); single-file
  hf download failure rc=1 + no .hf-meta; LLAMACPP_HOST coherent;
  POS_SUBCMDS + metadata gaps closed
- tooling: lint-conventions Bash-native rewrite (~24-30x faster, rules and
  output byte-identical, :num restored); pos system uninstall covers all 12
  libs + scale-tail + flags dir + systemd user units (|| true) + plugin
  markers; anchored .bash_completion/.bashrc removal replaces sed -i '/pos/d'
- config: canonical load_env_file in lib/config-ui.sh (CRLF strip, env-wins,
  XDG, LOADED_ENV_KEYS); 9 tools migrated; entertainment-lib collapsed to
  wrappers; docker-compose deliberately unmigrated (source semantics)
- tests: first committed regression suite — tests/run-tests.sh zero-dep
  runner + make test; 12 files / 179 checks / 0 skip / ~52s; hard skip
  contract; systemd-analyze verify on generated unit PASS

Verified: make gen idempotent; make check green; make lint 0 FAIL, 0 WARN;
make test green; bash -n clean; git diff --check clean. Audit deliverables +
agent reports + AGENT_TODO Done entry included.
2026-09-06 07:25:44 -04:00

53 lines
4.3 KiB
Markdown

# Builder Report — 2026-09-06: NET_PROBE unbound-variable fix
## TL;DR
- **Status:** IMPLEMENTED (one-line scope, verified)
- **Root cause:** `NET_PROBE="${NET_PROBE:-timeout 3 bash -c 'exec 3<>/dev/tcp/$1/$2' _ 8.8.8.8 53}"` — inside the double-quoted assignment the OUTER shell expanded `$1`/`$2` at assignment time. Under `set -u` with no positional args this is an unbound-variable crash on every `pos network download` run (unless `NET_PROBE` is already exported).
- **Fix:** escape the positional markers so only the inner `bash -c` sees them — `\$1`/`\$2` in the default string. Env-var override contract (`NET_PROBE` = full command string) unchanged.
- **File changed (only):** `bin/pos-network-download` — line 31 (NET_PROBE default). Nothing else.
- **Verification:** `bash -n` OK; bare `--help` and non-network `info` path reach the assignment with `NET_PROBE` UNSET → no unbound crash; `NET_PROBE='true'` override returns 0; static inspection confirms outer shell does not expand `$1/$2`; gates green (`make gen` idempotent, `make check` OK, `make lint` `0 FAIL, 0 WARN`).
- **Not committed** (per brief).
## Step 1: Confirm bug & scope
`bin/pos-network-download` line 31 holds the double-quoted default; `net_up()` (line 379) runs `bash -c "$NET_PROBE"`, which relies on the inner bash receiving the trailing positional args `_ 8.8.8.8 53` (`$0=_, $1=8.8.8.8, $2=53`).
Reproduced: `set -u; NET_PROBE="${NET_PROBE:-...$1/$2...}"``/bin/bash: line 1: $1: unbound variable`.
Confirmed the pre-existing HEAD default was `'</dev/tcp/8.8.8.8/53>'` (no `$1/$2`) — a prior security change to the probe introduced the regression.
[DONE]
## Step 2: Apply fix (escaped literal default)
Changed only line 31:
`NET_PROBE="${NET_PROBE:-timeout 3 bash -c 'exec 3<>/dev/tcp/\$1/\$2' _ 8.8.8.8 53}"`
The `\$` escapes keep the outer assignment from expanding `$1`/`$2`; the string stored is the literal `.../dev/tcp/$1/$2...`, so the inner `bash -c` receives the proper positional args. `net_up()` unchanged — it already passes the whole command string to the inner bash. Env override contract preserved and documented in usage() ("NET_PROBE override defaults (test seams)").
[DONE]
## Probes (report output)
1. **`set -u; bash -n bin/pos-network-download`** → OK (no error).
2. **Bare help, NET_PROBE UNSET** (stubbed `aria2c`/`jq`/`curl`, isolated `HOME`/`CONFIG_DIR`): `--help` exits 0, no `unbound` in output → assignment reached without crash.
**Non-network path, NET_PROBE UNSET:** `info` (no gid) → graceful `ERROR: info: gid required`, no unbound-variable crash (assignment ran at source time before dispatch).
3. **`NET_PROBE='true'` env override** → `net_up()` returns 0 (override still honored).
4. **Static default string inspection** → default stored as `timeout 3 bash -c 'exec 3<>/dev/tcp/$1/$2' _ 8.8.8.8 53` (literal `$1/$2`, NOT expanded by outer shell). Simulated probe with `echo inner sees $1 $2` → inner bash prints `8.8.8.8 53`, proving positional probe still correct.
5. **`--dry-run`/usage unaffected** — neither references NET_PROBE; usage() unchanged by this fix.
[DONE]
## Step 3: Repo gates
- `bash -n bin/pos-network-download` → OK.
- `make gen` → ran; re-ran: **idempotent** (byte-identical diff before/after), i.e. no new output. Net-probe is an env var, not a `# POS:` header, so it feeds nothing.
- `make check` (`scripts/check-sync.sh`) → OK.
- `make lint` (`scripts/lint-conventions.sh`) → `0 FAIL, 0 WARN`.
[DONE]
## Scope compliance
- Approved scope: `bin/pos-network-download` ONLY (NET_PROBE lines + net_up).
- Change made: exactly the NET_PROBE default string (line 31). `net_up` confirmed correct, no change required.
- Out-of-scope changes: none made by Builder. (Working tree contains pre-existing unstaged changes from prior agents — not authored here.)
- Not committed (per brief).
## Remaining risks / follow-up
- None for this fix. The env-var override string is operator-controlled; passing an invalid command there is the operator's responsibility (unchanged behavior).
## Recommended next agent
Orchestrator — task is complete, targeted verification and all gates pass; no cross-track coordination needed.
## Changes made by Builder
- `bin/pos-network-download`: escaped `$1`/`$2` to `\$1`/`\$2` in the `NET_PROBE` default so the inner `bash -c` (not the outer shell) performs the probe-host positional expansion.