# Upstream provider tracking

This directory tracks the upstream CLIs the gateway shells out to (Claude Code,
Codex, Gemini, Grok, Mistral Vibe) so flag/output/session/permission drift is
caught before it reaches a user.

## Single mechanical source of truth

`src/upstream-contracts.ts` (`UPSTREAM_CLI_CONTRACTS`) is the **only** place that
defines and enforces each provider's argv/env behaviour — flags, arities, enum
values, output modes, session/resume rules, permission modes, forbidden flags,
env contracts, positional limits. Enforcement happens through
`validateUpstreamCliArgs` / `validateUpstreamCliEnv`. Nothing in this directory
re-encodes those rules.

## Files

| Path                          | Role                                                                                                                                                                                    |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `release-targets.md`          | Exact upstream CLI versions and artifact SHA-256 values each gateway release was validated against. This is release evidence, not a dependency lock or minimum-supported-version claim. |
| `provider-sources.dag.toml`   | **Scanner input only.** Maps each canonical `CliType` to its changelog/release URLs and a scan policy. Never consulted for contract enforcement.                                        |
| `snapshots/<cli>.json`        | Generated by `npm run upstream:scan -- --live --write-snapshot`. Content hashes of fetched sources, used to detect changes on the next live scan.                                       |
| `reports/YYYY-MM-DD-<cli>.md` | Generated by `npm run upstream:scan -- --write-report`. Human-readable advisory report.                                                                                                 |

`snapshots/` and `reports/` only contain generated artifacts; they are written
exclusively by `scripts/upstream-scan.mjs` under the `--write-snapshot` /
`--write-report` flags.

## Detection channels

The detector has two complementary legs (both advisory only):

1. **Web changelog pages** — SHA-256 of the tracked `sourceUrls` (from each
   provider's `upstreamMetadata`). A change emits a `watched-category-changed`
   finding. This works well for providers that publish detailed release notes
   (Claude, Codex, Gemini, Mistral).

2. **Installed binary help surface** (the improvement that makes the detector
   reliable for vendor / fast-moving CLIs) — when you pass `--probe-installed`
   to either an offline or live scan (or use the MCP/CLI `upstream_contracts` / `contracts`
   surfaces with `probeInstalled: true`), the scanner runs the provider's
   documented `--help` (respecting multi-command cases like Codex), extracts
   the long flags it actually advertises, and reports:
   - `extraFlags` / `installed-help-surface-drift`: flags the binary knows
     about that the contract in `src/upstream-contracts.ts` neither declares
     nor acknowledges.
   - `missingFlags` / `binary-missing-declared-flags`: the reverse
     (regressions). Contract flags marked `hiddenFromHelp` (real, accepted,
     but deliberately absent from the binary's `--help` — e.g. Claude's
     `--max-turns`) are excluded; if such a flag reappears in the help text
     the probe emits a stale-marker warning instead.
   - `acknowledgedExtraFlags`: installed-binary flags listed in the contract's
     `acknowledgedUpstreamFlags` (upstream-only surface the gateway
     deliberately never emits — long-form aliases, interactive-only switches).
     Filtered out of `extraFlags` so genuinely new upstream flags stand out;
     acknowledged flags that vanish from the help text produce a stale-entry
     warning. This list is probe-only and never loosens the argv allowlist.
   - Hash + set diffs against the previous help surface snapshot (if any).

   This is the primary reliable signal for Grok (vendor channel, high-level
   release notes page) and any future CLIs whose public changelogs lag the
   actual `--help` / behavior.

Both channels feed the same findings list and can be persisted together in
the per-CLI snapshot JSON when `--write-snapshot` is used.

## How the TOML and the TypeScript metadata stay in sync

The chosen model is **TOML-is-scanner-input + report-enriched-from-TS**:

1. `CliContract.upstreamMetadata` in `src/upstream-contracts.ts` carries the
   authoritative `sourceUrls` and `watchCategories` (plus `packageName`,
   `repo`, `installDocsUrl`, `releaseChannel`). The contract **report** is
   enriched from these fields.
2. `provider-sources.dag.toml` mirrors `source_urls` and `watch_categories`
   for the scanner's offline scan plan only.
3. `src/__tests__/upstream-sources.test.ts` asserts the two are identical for
   every provider, so editing one without the other fails CI.

The TOML is **never** loaded for mechanical contract enforcement — only the
scanner reads it. To change a source URL or watch category, edit
`src/upstream-contracts.ts` first, then mirror it into the TOML.

## Commands

```bash
# Blocking, offline, network-free gate (fixtures + report + TOML-sync).
npm run upstream:contracts

# Offline scanner summary (no network, no writes).
npm run upstream:scan

# Advisory live changelog check (manual; network required).
npm run upstream:scan -- --live --fail-on-critical

# Persist source hashes / write a report (manual).
npm run upstream:scan -- --live --write-snapshot --write-report

# Recommended for vendor / fast-moving CLIs (e.g. grok): probe the installed
# binary's --help surface without requiring network access.
npm run upstream:scan -- --provider grok --probe-installed --fail-on-critical

# Persist source hashes / reports while also including installed help-surface data.
npm run upstream:scan -- --live --provider grok --probe-installed --write-snapshot --write-report
```

The default release gate is `npm run check && npm run upstream:contracts`.
Neither requires network access nor installed provider CLIs. Live scans are
advisory and run manually; `--probe-installed` is an opt-in local probe that
works in offline and live scan modes.

## Release target matrix

Every release must update `release-targets.md` with the exact upstream CLI
versions and SHA-256 values observed in the release validation environment.
Treat those rows as the concrete provider behavior baseline for agent guidance
and support triage. Do not describe a target/probed version or artifact hash as
a minimum, maximum, pinned, installed-for-users, or guaranteed-compatible
version unless a separate compatibility gate proves that claim.

## Per-provider skills

Process guidance for tracking each upstream CLI lives under `.agents/skills/`,
keyed by canonical CliType. Each skill points back to `src/upstream-contracts.ts`
as the mechanical source of truth and documents the scan + update procedure:

| Skill              | CliType   |
| ------------------ | --------- |
| `provider-claude`  | `claude`  |
| `provider-codex`   | `codex`   |
| `provider-gemini`  | `gemini`  |
| `provider-grok`    | `grok`    |
| `provider-mistral` | `mistral` |
