diff --git a/MAINTAINER.md b/MAINTAINER.md index 770ac43..9f85ac2 100644 --- a/MAINTAINER.md +++ b/MAINTAINER.md @@ -98,6 +98,7 @@ docs/ `docs/adr/0015-managed-codex-native-statusline.md`, `docs/adr/0032-model-lifecycle-intelligence.md`, `docs/adr/0033-retire-codex-mcp-and-bound-qe-court-participants.md`, +`tests/live/aqe-external-provider-transport.test.mjs`, `tests/live/qe-court-participant-transport.test.mjs`, and `docs/ddd/model-lifecycle-intelligence.md`. Generated workspace state under the shipped source trees is explicitly excluded. Nothing else ships — verify with diff --git a/README.md b/README.md index c495192..32aafe8 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,9 @@ or catalogue evidence. A **binding** connects a host to a provider through a sup and transport. Those axes do not imply one another. OpenRouter is a provider behind a host, not another host. -Ollama can have independent bindings through Claude and Codex. OpenCode is an opt-in, explicitly -routable host through `ak run`, but it is never a primary host or AQE provider. Provider, model, +Ollama can have independent bindings through Claude and Codex. Built-in OpenCode is an opt-in, +explicitly routable host through `ak run`, but it is not primary and has no built-in AQE provider +identity. A separate external adapter may earn its own AQE 3.13.12+ identity. Provider, model, and billing claims state whether they are observed, configured, inferred, or unknown. Design record: [docs/adr/0016-capability-driven-integration-adapters.md](docs/adr/0016-capability-driven-integration-adapters.md). @@ -124,8 +125,8 @@ command always works.) | Verb | What it does | | ------ | -------------- | | **setup** | Installs/updates ruflo + agentic-qe + the **agentdb** CLI globally (handling npm ≥11.17's `allow-scripts` so natives build; agentdb is pinned to ruflo's bundled version so the shared learning store stays coherent), installs the **RuvNet Brain** (an offline knowledge base over the rUv stack, powering the `search_ruvnet` MCP — a ~2 GB one-time download, prompted; skip with `--no-ruvnet-brain`), deploys the token-audit skill, merges the managed guidance blocks into the machine-wide guidance files (`~/.claude/CLAUDE.md`, plus `~/.codex/AGENTS.md` on codex machines), offers one-time MCP registration (user scope, with a tool-family picker), and — inside a repo — initializes the project: sanitized `ruflo init`, absolute memory-path pin, a **verified** store→disk write, statusline footer, and a background daemon with **local-only ($0) workers** (token-spending AI workers stay opt-in behind upstream's machine-wide budget). Project scope triggers on a `.git` entry in the current folder; without one it's skipped with a note. `--project` forces the same project setup in the current directory (e.g. a not-yet-`git init`-ed folder); it does not locate an ancestor repository. Project initialization runs `ruflo init --full --force` and can replace existing agent configuration, so read the [setup scope and project mutation contract](docs/SETUP.md) before using it on an existing project. `--minimal` skips it, `--yes` accepts all prompts (non-interactive), `--no-aqe` / `--no-ruvnet-brain` / `--no-security` disable those subsystems, and `--reconfigure` re-offers MCP registration. `--codex` enables + installs the Codex host during setup (ambidextrous dual-host mode; both hosts then run at once), and `--primary-host claude\|codex` picks which host leads (codex implies `--codex`). | -| **status** | Per-subsystem ✓/⚠/✗ (versions, the kit's own version, **ruvnet-brain** (present + release drift, or "not installed"), natives (agentdb copies **and** ruflo's own memory runtime — the one `npx ruflo memory` loads — load-tested for a native better-sqlite3, not just the agentdb dirs), **memory-pin** (warns when `CLAUDE_FLOW_DB_PATH` points off the live DB), security, learning, aqe/RVF, **agentdb** (CLI present + coherent with ruflo's bundled version, or a store-skew warning), MCP, **hosts** (claude/codex/opencode version + install method; the Claude/Codex **primary** marked and failed when absent), **providers** (host wiring + aqe fallback chain, or "drifted"/claude-only default), **routing** (the persisted activity host+model policy; only Claude/Codex routes project into AQE), daemons, guidance-file blocks (`~/.claude/CLAUDE.md`, project `AGENTS.md`, and `~/.codex/AGENTS.md` on codex machines), statusline), each drift row naming what `sync` would do about it — plus a **health-history** line that flags regressions since the last sync (learning shrank, native slots dropped, drift/security backslid). | -| **sync** | The one convergence verb: upgrades first when a new release exists, then re-heals everything an upgrade wipes, then re-checks and reports. Included in that heal: it **installs any enabled frontier host** (claude/codex/opencode) that's entirely absent — never touching an external (mise/brew/native) install — and **re-applies provider wiring** (the `ENABLE_*` host env, OpenCode's native configuration, the aqe fallback chain, and ruflo API providers) whenever it has drifted — and, on a dual-host project, **seeds/heals the Claude/Codex default routing policy** (materializing eligible routes into agentic-qe's `agentOverrides`, e.g. after an aqe upgrade first makes it eligible). It also **installs/repins the standalone `agentdb` CLI** to ruflo's bundled version (keeping the shared cognitive store coherent) and appends a **health-history snapshot** so `status` can flag regressions across syncs. It also **re-runs the RuvNet Brain installer** to pull the latest release when the on-disk KB has drifted (or installs it if absent, when enabled). It also **self-updates the kit**: when a newer `@pacphi/agentic-kit` exists it installs it as the *last* step (the new code applies from the next `ak` run, never mid-sync). Prerelease installs (`4.0.0-alpha.*`) track the `next` npm dist-tag as well as `latest`, so alphas see their successors; stable installs only ever follow `latest`. `--no-upgrade` skips the self-update along with the package upgrades. Model refresh/diff/plan findings remain advisory: sync never contacts a model catalogue or applies a model plan. | +| **status** | Per-subsystem ✓/⚠/✗ (versions, the kit's own version, **ruvnet-brain** (present + release drift, or "not installed"), natives (agentdb copies **and** ruflo's own memory runtime — the one `npx ruflo memory` loads — load-tested for a native better-sqlite3, not just the agentdb dirs), **memory-pin** (warns when `CLAUDE_FLOW_DB_PATH` points off the live DB), security, learning, aqe/RVF, **agentdb** (CLI present + coherent with ruflo's bundled version, or a store-skew warning), MCP, **hosts** (claude/codex/opencode version + install method; the Claude/Codex **primary** marked and failed when absent), **providers** (host wiring, AQE fallback chain, and exact admitted external-provider projection/ownership receipts), **routing** (the persisted activity host+model policy; Claude, Codex, and an admitted `aqeProvider` route can project into AQE), daemons, guidance-file blocks (`~/.claude/CLAUDE.md`, project `AGENTS.md`, and `~/.codex/AGENTS.md` on codex machines), statusline), each drift row naming what `sync` would do about it — plus a **health-history** line that flags regressions since the last sync (learning shrank, native slots dropped, drift/security backslid). | +| **sync** | The one convergence verb: upgrades first when a new release exists, then re-heals everything an upgrade wipes, then re-checks and reports. Included in that heal: it **installs any enabled frontier host** (claude/codex/opencode) that's entirely absent — never touching an external (mise/brew/native) install — and **re-applies provider wiring** (the `ENABLE_*` host env, OpenCode's native configuration, the AQE default/fallback/agent overrides, admitted Agentic-QE 3.13.12+ `externalProviders`, and ruflo API providers) whenever it has drifted. External-provider reconciliation preserves foreign entries, refuses same-id conflicts, and prunes only entries whose exact value still matches an agentic-kit ownership receipt. On a dual-host project, sync also **seeds/heals the Claude/Codex default routing policy**. It installs/repins the standalone `agentdb` CLI to ruflo's bundled version, appends a health-history snapshot, refreshes RuvNet Brain when enabled, and self-updates the kit last. `--no-upgrade` skips self-update and package upgrades. Model refresh/diff/plan findings remain advisory. | | **dashboard** | Opens an observation-only local web dashboard (`127.0.0.1:7431`, localhost-only, never detaches) with five primary areas: **About · Overview · Usage · Observability · System**. About is a plain-words directory of everything the kit installed and why (the same content as `ak about`); Overview covers readiness, hosts & routing, providers, runtime, and machine-wide intelligence; Usage turns local Claude/Codex/OpenCode transcripts into scorecards, limits, findings, per-session detail, and privacy-projected model lifecycle evidence. The Models inventory is lazy, paged, filterable, sortable, and internally scrollable; source-proven public catalogue names remain readable while private deployment identity stays keyed. Observability follows live and historical agent activity with masked evidence; System reports what the stack occupies on the machine (the same data as `ak system`). Deep links are hierarchical (`#about`, `#overview/summary`, `#usage/models`, `#usage/`, `#observability/live`, `#system/storage`). No dashboard action mutates agents or repositories; ruflo and agentic-qe stores are opt-in through repeatable `--live-source 'surface=path'`. The page is self-contained, offline-first, and protected by a per-session token. Full navigation, keyboard behavior, and per-view semantics: [Dashboard guide](docs/DASHBOARD.md) and [Observability guide](docs/OBSERVABILITY.md). **Auto-opens your browser** (`--no-open` for headless/SSH); `--port N` changes the port. Stop with Ctrl-C. (Also available as `ak x dashboard`.) | | **usage** | Reads provider-account analytics from local cache (`ak usage status`) or performs one explicit OpenRouter management-API refresh (`ak usage refresh openrouter`). Refresh requires `OPENROUTER_MANAGEMENT_KEY`, writes a credential-free mode-`0600` cache, and discards endpoint/user/key/session identifiers. `status` and dashboard reads make no network request. OpenRouter account rows have no grounded host/session/project correlation and are never merged into transcript totals. | | **models** | Builds a private, host-scoped model inventory from Claude, Codex, OpenCode, Ollama, bounded local usage evidence, and a dated bundled record of Anthropic's public model/lifecycle facts. `status`, `diff`, `explain`, and `plan` are cache-only and read-only; `refresh --online` is the sole online-catalogue boundary. Public facts never imply account or OpenRouter routability. Swap plans enumerate routes plus Agentic QE/Ruflo consumers and print a copyable canonical action without executing it. The CLI exposes exact local evidence deliberately; the Dashboard exposes source-proven public catalogue identity and pseudonymizes private identifiers. See [Model lifecycle intelligence](docs/MODELS.md). | diff --git a/bin/agentic-kit.mjs b/bin/agentic-kit.mjs index eed88bc..9c61020 100755 --- a/bin/agentic-kit.mjs +++ b/bin/agentic-kit.mjs @@ -32,6 +32,7 @@ const PORCELAIN = Object.assign(Object.create(null), { const PLUMBING = Object.assign(Object.create(null), { 'admin': () => import('../src/commands/x/admin.mjs'), + 'aqe-provider': () => import('../src/commands/x/aqe-provider.mjs'), 'daemon-gc': () => import('../src/commands/x/daemon-gc.mjs'), 'dashboard': () => import('../src/commands/x/dashboard.mjs'), 'harvest': () => import('../src/commands/x/harvest.mjs'), @@ -179,7 +180,7 @@ async function main() { // setup and host own complete mutation/reporting flows. Running the generic // nudge after a declined trust preflight could write version-cache state and // violate their "before any changes" boundary. - if (!values.json && !values['dry-run'] && !['sync', 'usage', 'models', 'setup', 'host', 'ruflo-mcp'].includes(cmd)) { + if (!values.json && !values['dry-run'] && !['sync', 'usage', 'models', 'setup', 'host', 'ruflo-mcp', 'aqe-provider'].includes(cmd)) { try { const { driftReport } = await import('../src/lib/versions.mjs'); for (const r of await driftReport()) { diff --git a/docs/ADAPTER-CONTRACT-DOSSIER.html b/docs/ADAPTER-CONTRACT-DOSSIER.html index ca0dd2e..5298947 100644 --- a/docs/ADAPTER-CONTRACT-DOSSIER.html +++ b/docs/ADAPTER-CONTRACT-DOSSIER.html @@ -205,8 +205,9 @@

2 · Evidence base

Every load-bearing adapter fact holds unchanged. New: a native ACP server (third driving surface), a --tui statusline, three-tier hooks with consent allowlists. PyPI is stale; the npm bridge now ships three bins. - agentic-qeagentic-qe 3.13.10 (local = latest published) - Provider set closed at every layer; its real plugin system reaches QE domains only; the + agentic-qeagentic-qe 3.13.12 (external-provider contract from ADR-127) + Built-in providers remain upstream-owned, while admitted CLI subprocess providers can + now be projected through externalProviders; plugin domains remain separate; the vendorOf mirror is in sync; quality-gate anchors are a content-authoring task, not a flag. @@ -270,13 +271,14 @@

3.5 Conformance means black-box subprocess tests against the installed layou

4 · Hard constraints the design inherits