Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
64dd461
feat(adapters): add earned AQE provider bridge
pacphi Aug 26, 2026
cade3e2
feat(providers): project admitted providers into Agentic-QE
pacphi Aug 26, 2026
4fac025
docs: describe external AQE provider lifecycle
pacphi Aug 26, 2026
d4f3f44
fix(adapters): harden external provider boundaries
pacphi Aug 26, 2026
215fd62
fix(adapters): close QE-Court runtime charges
pacphi Aug 26, 2026
fec9cc0
fix(providers): preserve external provider lifecycle
pacphi Aug 26, 2026
6d44d8c
fix(host): keep admitted providers selectable
pacphi Aug 26, 2026
2fa6804
fix(adapters): reauthorize external providers at execution
pacphi Aug 26, 2026
9ff7fdd
fix(providers): close external ownership lifecycle gaps
pacphi Aug 26, 2026
09dc5c0
fix(host): refresh external providers during selection
pacphi Aug 26, 2026
a35f917
docs: record hardened provider boundary
pacphi Aug 26, 2026
cd9c33c
fix(adapters): converge provider intent on grant revocation
pacphi Aug 26, 2026
f5e2867
fix(sync): surface external provider convergence failures
pacphi Aug 26, 2026
e8aac65
fix(providers): keep converged projections stable
pacphi Aug 26, 2026
f296131
fix(providers): retire explicitly deselected external default
pacphi Aug 26, 2026
a10d386
fix(host): propagate AQE router failures
pacphi Aug 26, 2026
86e084b
fix(config): avoid rewriting converged intent
pacphi Aug 26, 2026
e36b5fa
fix(providers): retire empty managed fallback
pacphi Aug 26, 2026
67bb0fb
fix(providers): preserve user fallback replacements
pacphi Aug 26, 2026
a0e06a3
test(providers): pin AQE fixture in CLI selection
pacphi Aug 27, 2026
f83ee84
test(ci): isolate grant stores on Windows
pacphi Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MAINTAINER.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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/<session-id>`, `#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). |
Expand Down
3 changes: 2 additions & 1 deletion bin/agentic-kit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down Expand Up @@ -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()) {
Expand Down
24 changes: 14 additions & 10 deletions docs/ADAPTER-CONTRACT-DOSSIER.html
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ <h2 id="evidence">2 · Evidence base</h2>
<td>Every load-bearing adapter fact holds unchanged. New: a native ACP server (third driving
surface), a <code>--tui</code> statusline, three-tier hooks with consent allowlists. PyPI is
stale; the npm bridge now ships three bins.</td></tr>
<tr><td>agentic-qe</td><td>agentic-qe 3.13.10 (local = latest published)</td>
<td>Provider set closed at every layer; its real plugin system reaches QE domains only; the
<tr><td>agentic-qe</td><td>agentic-qe 3.13.12 (external-provider contract from ADR-127)</td>
<td>Built-in providers remain upstream-owned, while admitted CLI subprocess providers can
now be projected through <code>externalProviders</code>; plugin domains remain separate; the
<code>vendorOf</code> mirror is in sync; quality-gate anchors are a content-authoring task,
not a flag.</td></tr>
</table></div>
Expand Down Expand Up @@ -270,13 +271,14 @@ <h3>3.5 Conformance means black-box subprocess tests against the installed layou

<h2 id="constraints">4 · Hard constraints the design inherits</h2>
<ul>
<li><strong>AQE's provider set is closed at every layer</strong> — 11 declared types, 10
constructible (<code>onnx</code> is declared-but-unconstructible); its real plugin system
(<code>aqe plugin install</code>) reaches QE domains only. No adapter may ever project into
any AQE surface. Phase 1's asymmetry decision already encodes this.</li>
<li><strong>AQE's built-in provider set remains upstream-owned</strong> — 3.13.12 adds the
ADR-127 <code>externalProviders</code> contract for CLI subprocess providers without making
plugin domains into provider extensions. Agentic-kit may project only an admitted, hash-pinned
adapter through that public contract; it must not mutate AQE's built-in provider definitions.</li>
<li><strong>Two AQE "host" surfaces exist and must not be conflated</strong>: LLM-execution
binding (spawns <code>claude</code>/<code>codex</code>; closed) vs. platform/MCP installers
(8 hardcoded; closed). ak's extension point extends neither — it extends ak's own host axis.</li>
binding (built-ins plus declared external CLI providers) vs. platform/MCP installers
(8 hardcoded). Agentic-kit's extension point projects only into the former after admission;
it does not extend AQE's platform installer catalog.</li>
<li><strong>Driving surfaces are plural now.</strong> Hermes ships a native ACP
(Agent Client Protocol) server alongside CLI oneshot — the contract must express <em>how</em>
a host is driven (cli-subprocess, ACP, MCP) as declared capability data, not assume
Expand Down Expand Up @@ -607,9 +609,11 @@ <h3>An adapter is data plus consented subprocess hooks. No third-party code runs
consent time, re-consented on change, executed with ak supervising (timeout, captured output,
independent verify after).</li>
<li><strong>Capability caps are structural, not runtime:</strong> the adapter manifest
<em>schema</em> cannot express <code>canBePrimary</code>, <code>aqeProvider</code>, or
<em>schema</em> cannot self-claim <code>canBePrimary</code>, <code>host.legacy.aqeProvider</code>, or
managed-statusline claims — a cap enforced by shape is stronger than any runtime check, and
is precisely where ruflo's honor-system caps failed.</li>
is precisely where ruflo's honor-system caps failed. Since Agentic-QE 3.13.12, separate
<code>aqe.provider</code> candidate data may be declared, but it gains no authority until a real
<code>aqe-provider</code> tier and explicit hash-pinned grant both exist.</li>
<li><strong>Fail-closed admission, isolated failure:</strong> a manifest that fails
validation, hash check, or contract version is refused with a message naming adapter and
reason; a refused or broken adapter never affects built-ins or other adapters (the F-01 merge
Expand Down
Loading
Loading