Skip to content

sync-models: unrecognized arguments are silently ignored — a typo'd --dry-rnu rewrites the live OpenCode config in place (and reloads opencode) #3297

Closed

Description

@dezren39

sync-models: unrecognized arguments are silently ignored — a typo'd --dry-rnu rewrites the live OpenCode config in place (and reloads opencode)

Summary

bin/sync-models.mjs — the legacy model sync that, per bin/provider-catalog-sync.mjs's header, "rewrites the deployed config in place (and auto-removes)" and is still the script the sync-models service maintains the deployed user config with — parses its CLI flags by membership only and never rejects an argument it does not recognize:

  • bin/sync-models.mjs:6-7 — const DRY_RUN = process.argv.includes('--dry-run'), const VERBOSE = process.argv.includes('--verbose') || …. There is no allowlist check over process.argv anywhere in the file.

So sync-models.mjs --dry-rnu (or any unknown flag, e.g. --bogus-flag) is silently treated as a full APPLY run: it rewrites the target OpenCode config in place (bin/sync-models.mjs:693-696, after writing a .backup), including removals, and then triggers opencode reload (:700) — exiting 0 and printing "Successfully updated". The operator who typo'd the dry-run flag gets no signal the live config was just rewritten.

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 a different script 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-syncmodels/ (sync-models.mjs + sync-models.policy.json copied verbatim; sha256 f53c214ae40f9358113c19c9458b517a7859932f2e5cbbedee49b3d328d3ca5e / 73807ce822c1d477f02e9a9b9456141a5fcacc8f905954792204bba5b0a70590, matching main b56ccda5). Deterministic change source: temp HOME whose .codex/models_cache.json holds one model (probe-model-1) that the temp target config lacks; agy stubbed off via PATH; target config pointed at a temp file via OPENCODE_CONFIG_PATH:

  • Control — --dry-run: Mode: DRY-RUN (no files will be changed), + Adding openai-codex/probe-model-1, Dry run complete. No files written., exit 0; config unchanged, no .backup.
  • --dry-rnu: Mode: APPLY, same addition, then Created backup at …/config.jsonc.backup and Successfully updated …/config.jsonc!, exit 0; the config on disk now contains probe-model-1.
  • --bogus-flag: exit 0, identical APPLY outcome (backup written, config rewritten).

Why it matters

Unlike its PR-based successor (provider-catalog-sync.mjs, dry-run by default, changes land through a reviewable PR), this script edits the deployed config directly and auto-removes models the sources no longer list. A typo in the one safety flag turns a preview into an unreviewed rewrite of the live config plus an opencode reload, with a success exit code — the class of surprise the successor tool was built to eliminate, still reachable through the legacy path the service actually runs.

Acceptance criteria

  • Any argument that is not --dry-run, --verbose or -v makes the script exit non-zero with a usage error naming the offending argument, before any fetch, discovery, or file write.
  • --dry-run, --verbose/-v, and bare (APPLY) behavior is unchanged.
  • A stubbed/temp-HOME test (or equivalent) pins: unknown flag → non-zero exit + config untouched + no .backup; --dry-run → no writes even when changes exist.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    effort/sSmall: expected under 2 hours of work
    app/sync-modelsbin/sync-models.mjs model catalog sync
    on Nov 1, 2026
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    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).

  4. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  5. 6 remaining items

  6. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 1, 2026
  7. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 2, 2026
  9. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · PR opened

    • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane
    • Session / ID: queue task 5880 (attempt 1)
    • Work: strict argv validation added at startup in bin/sync-models.mjs (only --dry-run, --verbose, -v accepted; anything else exits 2 with a usage line naming the argument, before any fetch/discovery/backup/write). Tests in bin/sync-models.test.mjs add temp-HOME probes for --bogus-flag, --dry-rnu, and a positional arg (fail non-zero, config byte-identical, no backup) plus --dry-run still exits 0 writing nothing.
    • Verification (2026-11-02T13:53:00Z): node --test bin/sync-models.test.mjs — 10 pass, 0 fail. Manual temp-HOME probe: --bogus-flag exit 2 config unchanged; --dry-run exit 0 config unchanged.
    • PR: fix(sync-models): strict argv validation before any write (#3297) #4379 (queue/5880-3297-sync-models-argv → main, commit 4aaeeff62). No other sync behavior changed; service units untouched.
    • Next: watch CI briefly per the 5-minute rule; merge only on green checks with diff matching intent, else park.
  10. added a commit that references this issue on Nov 2, 2026
  11. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done — fixed and merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/sync-modelsbin/sync-models.mjs model catalog synceffort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobsource/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions