Repository navigation
Description
proxy-supervise: unrecognized arguments are silently ignored — a typo'd --dry-rnu starts/rolls real proxies, and a typo'd --statuz reconciles instead of reporting status
Summary
bin/proxy-supervise.mjs (the supervisor that starts/stops/rolls the local proxy instances on its timer) parses its CLI flags by membership only and never rejects an argument it does not recognize:
bin/proxy-supervise.mjs:603-629—const args = process.argv.slice(2); flags are read withargs.indexOf('--config')/args.indexOf('--only')(:604-608),args.includes('--status')(:620) andargs.includes('--dry-run')(:629). There is no allowlist check overargsanywhere inmain(); the only validation is that--configis present.
So proxy-supervise.mjs --config <cfg> --dry-rnu is silently treated as a real reconcile: it acquires the per-proxy lock and starts a new proxy instance (or rolls/stops the existing one). Worse, the read-only path has the same flaw in reverse: --statuz (a typo of --status) falls through to a full reconcile instead of printing status. Both exit 0.
This is the same defect class already filed for the sibling deploy/install scripts — #3264 (pkarr-worker deploy.mjs), #3278 (opencode-claimant install.mjs), #3281 (id-mail worker deploy.mjs), #3287 (github-backup worker deploy.mjs) — but this script is a different, long-lived operator tool none of them covers. The repo's shell tools already meet the stricter standard: lib/bws-to-sops.sh dies on unknown argument and scripts/stage-docs.sh exits 1 on an unknown option.
Evidence (verified this run)
Laptop probe ~/git/fleet/probe-2026-10-31-laneB-supervise/ (proxy-supervise.mjs copied verbatim; sha256 1926654cf1148a65a59e6b0c05f66a42552307de68d194153fcefbe25e7252bb, matching main b56ccda5), with a fixture config in a temp dir (one proxy whose command is a tiny HTTP server answering /health, stateDir/endpointDir inside the probe dir, port 18999):
- Control —
--dry-run: exit 0, actionwould-start, port stays FREE, no state or endpoint files written. --dry-rnu: exit 0, actionstarted— a real server process (pid recorded instate/probeproxy.json), port 18999 HEALTHY afterwards.--bogus-flag: exit 0, identical real start (new pid, state file written, port healthy).--statuz: exit 0, actionstarted— the intended read-only status check reconciled and started the proxy instead.
(The probe cleaned up every instance it started; final port check FREE.)
Why it matters
This supervisor owns the lifecycle of the local proxy fleet: a real reconcile can start, roll, drain and stop live proxy processes. A one-character typo in either safety flag — the preview flag --dry-run or the read-only --status — silently becomes the mutating operation, with a success exit code and a normal JSON result line, so the operator has no signal anything beyond a preview/status just happened.
Acceptance criteria
- Any argument that is not
--config <path>,--only <name>,--statusor--dry-runmakes the script exit non-zero with a usage error naming the offending argument, before any lock is taken or any reconcile runs. --config/--onlywith a missing value or a value that is another flag are rejected the same way.--status,--dry-run, and bare reconcile behavior is unchanged.- A test (the script already has importable exports / a test file pattern in
bin/) pins: unknown flag → non-zero exit + zero spawned processes;--dry-run→would-startonly;--statuz-style typos do not fall through to reconcile.
Activity
dezren39 commentedon Nov 1, 2026
🤖 Agent note · filed
bin/proxy-supervise.mjs(mainb56ccda5, sha2561926654c…) reads flags byindexOf/includesonly (proxy-supervise.mjs:603-629) and never rejects unknown arguments. Laptop probe~/git/fleet/probe-2026-10-31-laneB-supervise/with a fixture proxy (tiny /health server, temp state/endpoint dirs):--dry-run→would-start, port free, no state;--dry-rnuand--bogus-flag→ exit 0 after actionstarted(real process, pid in state file, port healthy);--statuz→ alsostartedinstead of a status report. Same defect class as pkarr-worker(deploy): unrecognized arguments are silently ignored — a typo'd --dry-rnu or --deploy-version=<id> performs a real deploy of HEAD #3264 / opencode-claimant(install): unrecognized arguments are silently ignored — a typo'd --dry-rnu performs a real install, and a typo'd --stor writes the real OpenChamber store #3278 / id-mail(worker deploy): unrecognized arguments are silently ignored — a typo'd --dry-rnu enters the real deploy sequence and force-deletes the retired 'id-mail' Worker #3281 / github-backup(worker deploy): unrecognized arguments are silently ignored — a typo'd --dry-rnu performs a real deploy (upload + secret reset) #3287, but a different operator tool none of them covers.dezren39 commentedon Nov 1, 2026
Adopted as Phase 1 of design #3352. The design records the contract this issue's fix must follow: every argument is accounted for before any side effect; unknown/typo'd arguments are a usage error naming the argument (exit non-zero, 2 where no usage code is established) before any subprocess/network/file/lock/deploy step. Triage: do NOT re-file, re-scope or split this issue — record the phase structure and verdict, and keep this issue's own acceptance criteria as the phase's acceptance. Design doc: files/designs/code-operator-argument-contract.md (keep-the-four-repos-healthy goal workspace).
dezren39 commentedon Nov 1, 2026
agent-note:v1 — state=picked_up; task_id=4882; worker=repo-worker-code; lane=openchamber-scheduled-lane; note=Claimed for fresh triage of current-main argv handling and routing. Issue is OPEN; no matching PR found; no held, user/owned, do-not-merge, or do-not-auto-edit labels.
15 remaining items
developing-today commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
developing-today commentedon Nov 3, 2026
🤖 Agent note · picked up + done (triage verdict: ALREADY DONE — closing)
Evidence (fresh, 2026-11-03, current main):
bin/proxy-supervise.mjson main now opensmain()with a strictparseArgsallowlist (line 808ff): only--config <path>,--only <name>,--status,--dry-runare accepted; anything else throwsunknown argument: <arg>, prints the usage line, and exits with code 2 — beforeloadConfig, before any lock, before any reconcile. Missing values and flag-as-value are rejected (missing value for --config/--only), duplicates are rejected, and a missing--configis rejected.bin/proxy-supervise.test.mjs(line 462ff): unknown arguments rejected before proxy side effects, including the exact--dry-rnuand--statuztypos from this issue, and unknown-arg rejection ordered before config-file reads. Task 5885 recordednode --test bin/proxy-supervise.test.mjs18/18 pass at PR time.(Note: posted via the developing.today GitHub App — the user-token content-creation secondary rate limit is still active this shift.)