diff --git a/.github/workflows/alignment.yml b/.github/workflows/alignment.yml index bd54ce0..7c4b389 100644 --- a/.github/workflows/alignment.yml +++ b/.github/workflows/alignment.yml @@ -89,7 +89,7 @@ jobs: for token in "${FORBIDDEN_PROVIDER_TOKENS[@]}"; do HITS="$(echo "$SOURCE_FILES" | xargs grep -n -F "$token" 2>/dev/null || true)" if [ -n "$HITS" ]; then - echo "::error::Tier-A-excluded provider token '$token' detected in OLP source. Per ALIGNMENT.md / ADR 0006, this provider is permanently excluded." + echo "::error::Tier-A-excluded provider token '$token' detected in OLP source. Per ALIGNMENT.md / ADR 0006, this provider is excluded by default; re-inclusion requires ADR 0006 supersession/amendment with new primary-source evidence." echo "$HITS" FAIL=1 fi @@ -101,7 +101,7 @@ jobs: echo "ALIGNMENT GUARDRAIL FAILURE" echo "============================================================" echo "OLP source contains a token on the alignment blacklist or" - echo "references a permanently excluded provider." + echo "references a Tier-A-excluded provider." echo "" echo "Blacklist tokens were introduced by LLM hallucinations and" echo "do not appear in the relevant authority (provider CLI," @@ -110,8 +110,10 @@ jobs: echo "record at https://github.com/dtzp555-max/ocp." echo "" echo "Excluded providers are listed in ALIGNMENT.md \xc2\xa7 Risk Tier" - echo "Framework and ADR 0006. Permanent exclusion means not" - echo "bundled, not pluggable, not added via opt-in." + echo "Framework and ADR 0006. Tier-A exclusion means not" + echo "bundled, not pluggable, not added via opt-in;" + echo "re-inclusion requires ADR 0006 amendment with new" + echo "primary-source evidence." echo "" echo "Required action:" echo " 1. Remove the token from source." @@ -191,8 +193,14 @@ jobs: exit 0 fi + # Use process substitution `< <(...)` rather than piping into the + # while loop. A piped while runs in a subshell, so `WARN=1` would + # never propagate back out to this scope — the if-check below would + # always report "clean" even when warnings were emitted. Classic + # Bash subshell trap; see commit history for the codex review that + # caught this. WARN=0 - git log --format="%H" "${BASE_SHA}..${HEAD_SHA}" | while read -r sha; do + while read -r sha; do BODY="$(git log -1 --format=%B "$sha")" if echo "$BODY" | grep -E -i -q '(provider|claude|codex|vibe|grok|kimi|minimax|glm|qwen|cli)[[:space:]]+(code[[:space:]]+)?uses'; then if echo "$BODY" | grep -E -i -q '(cli[[:space:]]+v[0-9]+|https?://|ADR[[:space:]]+[0-9]{4})'; then @@ -202,7 +210,7 @@ jobs: WARN=1 fi fi - done + done < <(git log --format="%H" "${BASE_SHA}..${HEAD_SHA}") if [ "$WARN" -ne 0 ]; then echo "Soft check raised warnings. Reviewer: please enforce per CLAUDE.md." diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a4db16..147a642 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,12 +46,12 @@ jobs: - name: Run npm test shell: bash run: | - # Bootstrap tolerance: if test-features.mjs does not exist yet (Phase 0 - # ships before Phase 1 lands the test harness), skip with a notice. - # The `npm test` script is configured in package.json from day one, so - # checking script presence is not a useful gate — the file must exist. - if [ ! -f test-features.mjs ]; then - echo "::notice::test-features.mjs not present yet (Phase 0 bootstrap phase). Skipping. Test harness lands with Phase 1 per docs/adr/0001 / spec §6." + # Bootstrap tolerance: skip if either test-features.mjs is absent OR + # package.json has no scripts.test entry. v0.1 founding ships + # neither — both land with Phase 1 per spec §6. Once one or both + # are present, this guard falls through to `npm test`. + if [ ! -f test-features.mjs ] || ! node -e "p=require('./package.json');process.exit(p.scripts&&p.scripts.test?0:1)" 2>/dev/null; then + echo "::notice::Phase 0 bootstrap: test-features.mjs absent OR scripts.test not declared in package.json. Skipping. Both land with Phase 1 per docs/adr/0001 / spec §6." exit 0 fi npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index 875538b..2e310b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,57 +2,68 @@ All notable changes to OLP land here. Per `CLAUDE.md` release_kit overlay, this file is the source of truth for GitHub release notes. -## Unreleased — 2026-05-23 (governance amendments per external codex review) - -External AI review (OpenAI Codex CLI) of the bootstrap governance surfaced six substantive findings beyond what the internal opus reviewer caught. All six folded in this turn: - -1. **Provider Inventory split into Candidate vs Enabled** — ALIGNMENT.md previously listed `anthropic` / `openai` / `mistral` as Tier D default-enabled while their Authority pins were still `TBD at Phase N spawn`. This violated Rule 1 (Cite First) and Rule 3 (Match the Implementation). The v0.1 founding commit now ships **zero Enabled Providers**; all 8 providers are Candidate. Enablement is a Phase audit deliverable, not a bootstrap claim. (ALIGNMENT.md § Provider Inventory; README.md § Supported Providers.) -2. **Antigravity Tier A evidence strength downgraded to "evidence-backed, pending primary-source pin"** — ADR 0006 previously framed the Antigravity exclusion as a closed case based on secondary reports. The reports actually disagree on blast radius (piunikaweb 03-02 says AI-tier only; piunikaweb 02-23, OpenClaw issue #14203, VentureBeat say broader). The Google FAQ language naming OpenClaw/OpenCode/Claude Code is cited from secondary sources only; the original FAQ URL or archival snapshot has not been primary-source-pinned. The exclusion is still active by default, but the constitutional weight now matches the evidence: secondary-sourced. Primary-source pinning is tracked as an open one-shot audit task with a 90-day Tier-reconsideration trigger. -3. **ADR 0001 supersession scope honesty** — ADR 0001 previously claimed OLP is "the structural shape ADR 0005 endorsed: a separate repo with multi-provider design baked in from day one." But ADR 0005's separate-repo recommendation came with two qualifiers OLP rejects: "BYOK from day one" and "no `cli.js` spawn." OLP rejects both — it is non-commercial and explicitly spawn-binary. The supersession is now narrowly scoped to "single-provider-sufficiency premise only"; the BYOK / no-spawn parts of ADR 0005 are not inherited. -4. **Anthropic post-2026-06-15 one-shot audit scheduled** — ALIGNMENT.md's annual 14 May audit would have left the Anthropic Tier re-evaluation almost a year late. Added a one-shot audit for 2026-06-16 (or first Anthropic billing-cycle close) that verifies the post-effective-date behaviour and updates ADR 0006 + Authority pin. -5. **Tier A "permanent" language unified across docs** — ALIGNMENT.md and ADR 0006 disagreed: one said "permanently excluded," the other said "amendment-procedure-revisable." Unified as "Excluded by default. Cannot be re-included unless ADR 0006 is superseded or amended with new primary-source evidence." The amendment procedure remains available; "Tier A" sets the bar for re-inclusion at constitutional-amendment level, not at routine PR level. -6. **OpenAI Tier D wording softened** — ADR 0006 previously described Codex Discussion #8338 as "maintainer confirmed permissive." The discussion is actually a maintainer posture statement ("OSS projects like OpenCode are doing things similar") with an explicit "I'm an engineer, not a lawyer" caveat. Now described as "maintainer signal indicates low risk; formal ToS pin pending" with the pin tracked as a follow-up audit task. - -Files changed: `ALIGNMENT.md`, `README.md`, `docs/adr/0001-project-founding.md`, `docs/adr/0006-provider-inclusion.md`. No code, no CI workflow, no PR template change. - -Reviewer for this amendment: OpenAI Codex CLI (external, fresh-context). Iron Rule 10 satisfied — the internal opus reviewer was not the source of the findings, and the maintainer is not the author of the underlying critique. The amendment's substantive changes are direct fold-ins of the reviewer's six findings; the internal opus reviewer's earlier APPROVE_WITH_MINOR verdict is therefore narrowed retroactively to "APPROVE conditional on these amendments" for the purposes of the v0.1 governance bootstrap. - ## v0.1.0-bootstrap — 2026-05-23 -### Phase 0 — Repo bootstrap +### Phase 0 — Repo bootstrap (founding + post-codex-review hardening) -This is the founding commit of OLP (Open LLM Proxy), a personal- and family-scale multi-provider LLM proxy that supersedes OCP. The trigger was Anthropic's 2026-05-14 announcement (effective 2026-06-15) splitting `claude -p` / Agent SDK / third-party agent traffic out of the Pro/Max subscription pool into a separate fixed monthly Agent SDK Credit pool. +This is the founding commit set of OLP (Open LLM Proxy), a personal- and family-scale multi-provider LLM proxy that supersedes OCP. The trigger was Anthropic's 2026-05-14 announcement (effective 2026-06-15) splitting `claude -p` / Agent SDK / third-party agent traffic out of the Pro/Max subscription pool into a separate fixed monthly Agent SDK Credit pool. -**What lands in this commit:** +**What lands at v0.1.0-bootstrap (final state on `main` as of 2026-05-23):** -- `ALIGNMENT.md` — OLP constitution. Three concurrent authorities (per-provider CLI / OpenAI spec / IR contract), 5 Rules, 4-tier Risk Tier Framework, 8-provider inventory. +- `ALIGNMENT.md` — OLP constitution. Three concurrent authorities (per-provider CLI / OpenAI spec / IR contract), 5 Rules, 4-tier Risk Tier Framework, Candidate-vs-Enabled provider inventory, one-shot triggered audits (2026-06-16 Anthropic post-split; 90-day Antigravity primary-source pin). - `AGENTS.md` — multi-tool agent guidelines (inherits `~/.cc-rules/AGENTS.md`). - `CLAUDE.md` — Claude-Code-specific session instructions + machine-readable `release_kit` overlay (Iron Rule 5.5). -- `README.md` — phase-aware skeleton with provider inventory, API endpoint table, environment-variables table, response-headers spec, architecture overview, phase plan, migration-from-OCP outline. Placeholder content marked as such per phase. +- `README.md` — phase-aware skeleton with Candidate-vs-Enabled provider tables, API endpoint table, environment-variables table, response-headers spec, architecture overview, phase plan, migration-from-OCP outline. Placeholder content marked as such per phase. - `docs/adr/` — 6 founding ADRs: - - `0001-project-founding.md` — Mission, non-mission, and supersession of OCP ADR 0005 (No Multi-Provider). - - `0002-plugin-architecture.md` — `lib/providers/.mjs` plug-in model with the Provider contract (name / models / auth / spawn / estimateCost / quotaStatus / healthCheck / hints). + - `0001-project-founding.md` — Mission, non-mission, narrow-scope supersession of OCP ADR 0005 (single-provider-sufficiency premise only; BYOK / no-spawn parts of ADR 0005 not inherited). + - `0002-plugin-architecture.md` — `lib/providers/.mjs` plug-in model with the Provider contract (name / models / auth / spawn / estimateCost / quotaStatus / healthCheck / hints). 8 candidate providers declared, 0 Enabled at v0.1. - `0003-intermediate-representation.md` — OLP-internal canonical IR between OpenAI-compat entry and provider plugins. - - `0004-fallback-engine.md` — Trigger taxonomy (Hard / Soft / Deterministic-deferred / Cost-aware-deferred), idempotent-failure safety, first-chunk rule, chain advancement. + - `0004-fallback-engine.md` — Trigger taxonomy (Hard / Soft / Deterministic-deferred / Cost-aware-deferred), idempotent-failure safety (first-chunk rule), chain advancement one-at-a-time, observability headers. - `0005-cache-cross-provider.md` — Cache key composition over `(provider, model, messages, ...)`, D1+D2+D3+D4 port from OCP v3.13.0. - - `0006-provider-inclusion.md` — 4-tier Risk Framework, 8-provider classification, Antigravity exclusion (named prohibition + no cost advantage + reinstatement friction; *not* whole-account ban — Google AI services tier only per piunikaweb 2026-03-02 OpenClaw exec confirmation). + - `0006-provider-inclusion.md` — 4-tier Risk Framework, Candidate-vs-Enabled distinction, 8-provider candidate classification, Antigravity Tier A (evidence-backed, pending primary-source pin) — exclusion rests on (named prohibition + no cost advantage + reinstatement friction) combination; primary-source URL not yet pinned, follow-up tracked. - `.github/PULL_REQUEST_TEMPLATE.md` — 8-radio Change Type taxonomy + per-type Authority Evidence sections + Iron Rule 10 reviewer checklist. -- `.github/workflows/alignment.yml` — CI blacklist (transitive `api.anthropic.com/api/oauth/usage` from OCP 2026-04-11 drift; Antigravity provider exclusion enforcement) + `models-registry.json` validator + commit-citation soft check. +- `.github/workflows/alignment.yml` — CI blacklist (transitive `api.anthropic.com/api/oauth/usage` from OCP 2026-04-11 drift; Antigravity provider exclusion enforcement) + `models-registry.json` validator + commit-citation soft check (process-substitution form, no Bash subshell trap). - `.github/workflows/release.yml` — Auto-release on tag push with `package.json`-vs-tag version match check (Iron Rule 5). -- `.github/workflows/test.yml` — Node 20/24 matrix; tolerates bootstrap-phase absence of `test-features.mjs`. -- `package.json`, `.gitignore`, `LICENSE` (MIT), `CHANGELOG.md` — standard project boilerplate. +- `.github/workflows/test.yml` — Node 20/24 matrix; tolerates bootstrap-phase absence of `test-features.mjs` AND `scripts.test`. +- `models-registry.json` — minimal v0.1 stub with empty `providers: {}`, matching the 0-Enabled posture; populated by Phase audits as providers transition Candidate → Enabled. +- `package.json` — minimal: no `main`, no `scripts.test`, no `scripts.start` (those entries land alongside the real files in Phase 1). +- `.gitignore`, `LICENSE` (MIT), `CHANGELOG.md` — standard project boilerplate. -**Provider inventory at bootstrap:** +**Provider posture at v0.1.0-bootstrap (per ALIGNMENT.md § Provider Inventory):** -| Tier | Providers | -|---|---| -| D (default-enabled) | Anthropic, OpenAI Codex, Mistral Vibe | -| C (opt-in, no consent) | xAI Grok, Moonshot Kimi | -| B (opt-in, explicit consent) | MiniMax, Zhipu GLM, Alibaba Qwen | -| A (permanently excluded) | Google Antigravity | +| Tier | Anticipated providers | v0.1 default state | +|---|---|---| +| D (eligible-for-default-enabled) | Anthropic, OpenAI Codex, Mistral Vibe | Candidate (transition gate: authority pin + plugin + Phase audit) | +| C (opt-in) | xAI Grok, Moonshot Kimi | Candidate | +| B (opt-in + consent) | MiniMax, Zhipu GLM, Alibaba Qwen | Candidate | +| A (excluded by default; constitutional-amendment-only re-inclusion) | Google Antigravity | Excluded; pending primary-source pin | -**Governance gate at bootstrap:** +**Total Enabled at v0.1.0-bootstrap: 0.** Enablement is a Phase audit deliverable, not a bootstrap claim. This explicit zero is intentional and codified — a constitution that names providers as "default-enabled" while their CLI versions, output shapes, auth artifacts, and exit-code semantics are still TBD would violate Rules 1 (Cite First) and 3 (Match the Implementation). -- Fresh-context independent reviewer (opus, Iron Rule 10) audited all 15 governance files against the OLP v0.1 spec and OCP precedent. Verdict: APPROVE_WITH_MINOR. Two minor findings folded in before this commit (alignment.yml heredoc indentation fix; AGENTS.md ADR-0003 reference clarification). +**Review history for this version:** -**Next:** Phase 1 lands `server.mjs` skeleton + IR + Anthropic provider plugin + cache D1+D4 port from OCP. Per the spec §6 phase plan. +1. **Initial internal review (Claude Opus, fresh-context, Iron Rule 10).** Verdict: APPROVE_WITH_MINOR — 2 minor items (alignment.yml heredoc indent breaking bash parse on failure path; AGENTS.md cross-reference to ADR 0003 imprecise). Both folded in before the founding commit. + +2. **External review #1 (OpenAI Codex CLI, no spec framing).** Verdict: 6 substantive findings beyond internal review. + - Provider Inventory split into Candidate vs Enabled (the v0.1 constitution had declared `anthropic` / `openai` / `mistral` as Tier D default-enabled while their Authority pins were still `TBD at Phase N spawn` — direct violation of Rule 1 / Rule 3 against the constitution's own text). + - Antigravity Tier A downgraded to "evidence-backed, pending primary-source pin" (secondary reports disagree on blast radius; Google FAQ URL not yet primary-source-pinned). + - ADR 0001 supersession scope narrowed (OLP rejects ADR 0005's "BYOK + no spawn" qualifiers, which originally applied to a commercial pivot; OLP is non-commercial and spawn-binary by design). + - Anthropic post-2026-06-15 one-shot audit scheduled (annual May 14 audit would leave Anthropic re-eval ~year late after the split takes effect). + - Tier A "permanent" language unified across docs (constitution and ADR 0006 had disagreed). + - OpenAI Tier D wording softened ("maintainer signal indicates low risk; formal ToS pin pending" — Discussion #8338 is a posture statement, not a formal ToS blessing). + +3. **External review #2 (OpenAI Codex CLI, second pass after review #1 fold-in).** Verdict: 6 additional substantive findings — the self-consistency trap recurred when fold-in of review #1 was scoped only to files codex explicitly named. Round #2 caught: + - ADR 0002 still claimed "three default-enabled" while ALIGNMENT.md said zero Enabled — accepted ADR contradicting constitution. + - `release.yml` would publish stale `## v0.1.0-bootstrap` notes that ignored the "Unreleased" amendments — fixed by consolidating amendments into the v0.1.0-bootstrap section (this entry). + - `package.json` advertised `main` / `scripts.test` / `scripts.start` for files that don't exist — `npm test` / `npm start` failed locally. Removed all three; will return in Phase 1 alongside the real files. + - `models-registry.json` documented as SPOT but missing — minimal stub added. + - `alignment.yml` commit-citation soft check had a Bash subshell trap (`while` in pipe loses `WARN=1` mutation) — fixed via process substitution `< <(...)`. + - Tier A "permanent" wording still inconsistent across `alignment.yml` workflow text, ADR 0006 Consequences section, and the rest of the docs — unified throughout. + + All 6 round-#2 findings folded in this consolidated v0.1.0-bootstrap state. + +**Reviewer framing learning (recorded permanently in `~/.cc-rules/memory/learnings/ai_reviewer_self_consistency_trap.md`):** Internal AI reviewers framed on a shared source-of-truth miss bugs in the source-of-truth itself. The self-consistency trap recurred during the fold-in of round #1 — when an external reviewer surfaces findings, the fold-in must grep the entire repo for the same concept, not only edit the files the reviewer named. Round #2 caught what round #1's fold-in missed for exactly this reason. Both lessons updated in the cross-machine memory. + +**Iron Rule 10 status:** Satisfied. Initial reviewer = internal opus (independent from drafters). Round #1 reviewer = external codex (independent from drafters and from internal opus). Round #2 reviewer = external codex (independent from the round #1 fold-in implementer). The maintainer's role across all three reviews was approver, not author. The drafting agents and fold-in agents were never the same as the reviewers for any of the three passes. + +**Next:** Phase 1 lands `server.mjs` skeleton + IR + Anthropic provider plugin + cache D1+D4 port from OCP. At that point, `package.json` regains `main` + `scripts.test` + `scripts.start`, `test-features.mjs` lands, `models-registry.json` populates its first `providers.anthropic` entry, and Anthropic transitions Candidate → Enabled. Per spec §6 phase plan. diff --git a/docs/adr/0001-project-founding.md b/docs/adr/0001-project-founding.md index 7331b2d..dc0a83f 100644 --- a/docs/adr/0001-project-founding.md +++ b/docs/adr/0001-project-founding.md @@ -23,7 +23,7 @@ Found OLP (Open LLM Proxy) as a new project, separate from OCP, with the followi **Non-mission (explicit).** Per spec §1, OLP is **not**: - A commercial multi-tenant SaaS. Helicone, OpenRouter, LiteLLM, Portkey, Cloudflare AI Gateway already serve that market with funding, SOC2, dashboards, and team features. OLP enters none of those races. -- A generic enterprise AI gateway competing on provider breadth. The provider set is intentionally narrow (currently 3 default + 2 optional tier-1 + 3 optional tier-2) and curated by subscription economics, not by "more is better." +- A generic enterprise AI gateway competing on provider breadth. The candidate provider set is intentionally narrow (8 total: 3 anticipated Tier D + 2 anticipated Tier C + 3 anticipated Tier B; v0.1 founding ships 0 Enabled per ALIGNMENT.md § Provider Inventory) and curated by subscription economics, not by "more is better." - A model-capability router. OLP does not auto-route to "the smartest model"; the user picks the model explicitly per chain in `config.routing.chains[]`. Capability routing is a separate problem with separate failure modes and is out of scope for v1.0 and beyond. - A conversation-state store. Memory and continuity are client-side concerns (Memory Continuity, Hermes equivalents, IDE-side context). OLP is a pure stateless proxy. diff --git a/docs/adr/0002-plugin-architecture.md b/docs/adr/0002-plugin-architecture.md index 2f1faa2..7adc813 100644 --- a/docs/adr/0002-plugin-architecture.md +++ b/docs/adr/0002-plugin-architecture.md @@ -7,7 +7,7 @@ ## Context -OLP supports a curated set of providers — three default-enabled (Anthropic, OpenAI Codex, Mistral Vibe) plus two optional tier-1 (xAI Grok, Moonshot Kimi) and three optional tier-2 (MiniMax, Zhipu GLM, Alibaba Qwen). Each provider has its own CLI binary, its own auth artifact location, its own request shape, its own response shape, its own quota-reporting endpoint (or none), and its own rate-limit posture. The maintainer's strong prior is that this set grows over the project's lifetime — provider economics will continue to shift, and "the right five providers" in 2027 will not be identical to today's five. +OLP declares a curated set of candidate providers — three anticipated Tier D (Anthropic, OpenAI Codex, Mistral Vibe), two anticipated Tier C (xAI Grok, Moonshot Kimi), and three anticipated Tier B (MiniMax, Zhipu GLM, Alibaba Qwen). Per ALIGNMENT.md § Provider Inventory, all 8 ship as **Candidate** at v0.1 founding; transition to **Enabled** requires authority pin filled + plugin landed + Phase audit passed. Each provider has its own CLI binary, its own auth artifact location, its own request shape, its own response shape, its own quota-reporting endpoint (or none), and its own rate-limit posture. The maintainer's strong prior is that this set grows over the project's lifetime — provider economics will continue to shift, and "the right five providers" in 2027 will not be identical to today's five. The naive architecture is a monolithic dispatcher inside `server.mjs`: @@ -86,7 +86,7 @@ Every provider plugin exports an object conforming to: ## Alternatives considered -**(a) Monolithic dispatch inside `server.mjs`.** A single function with `if/else if` per provider, each branch implementing spawn/quota/health inline. Rejected: this is the architectural shape that produced OCP's `server.mjs` length problem at *one* provider, and it does not survive contact with three default + two optional tier-1 + three optional tier-2 providers (eight code paths). Worse, it makes provider-disable a code change, which means fast-quarantine in response to a ToS announcement (spec §9) is a release event rather than a config flip. +**(a) Monolithic dispatch inside `server.mjs`.** A single function with `if/else if` per provider, each branch implementing spawn/quota/health inline. Rejected: this is the architectural shape that produced OCP's `server.mjs` length problem at *one* provider, and it does not survive contact with 8 candidate providers (anticipated 3 D + 2 C + 3 B, eight code paths once they all transition from Candidate to Enabled). Worse, it makes provider-disable a code change, which means fast-quarantine in response to a ToS announcement (spec §9) is a release event rather than a config flip. **(b) Full external plugin discovery (npm-installable, runtime-loaded, hot-discoverable).** Plugins are npm packages; OLP scans `node_modules/@olp-providers/*` at startup; users `npm install` to add a provider. Rejected for v1.0 on three grounds: (1) the provider set is curated for ToS-risk reasons (ADR 0006), and "anyone can install any provider" defeats that curation; (2) the discovery layer is itself non-trivial code (manifest validation, version compatibility, security review of third-party plugin code) that does not earn its complexity at three to eight providers; (3) the contract has not stabilized enough — locking it as a stable plugin API before v1.0 ships is premature commitment. diff --git a/docs/adr/0006-provider-inclusion.md b/docs/adr/0006-provider-inclusion.md index b235cc1..a360740 100644 --- a/docs/adr/0006-provider-inclusion.md +++ b/docs/adr/0006-provider-inclusion.md @@ -83,7 +83,7 @@ The inclusion ADR is a hard prerequisite for the plugin's merge — no ADR, no m **Negative** - Tier B's consent UX adds a step to first-enable. Users who already understand the risk perceive friction. The friction is intentional; the consent is the structural mechanism that protects the user. - The framework is provider-by-provider, not category-by-category. A new Chinese provider similar to MiniMax/GLM/Qwen gets its own ADR even though the pattern is shared. This is intentional — boilerplate-and-paste ADRs are still cheaper than the alternative of "we just classed them together once and now we have a category drift problem when their ToS shifts." -- Tier-A exclusion is *permanent* in the current framework, with no documented reinstatement path. If Google were to walk back the named-tool prohibition and the cost picture changed, Antigravity would need a fresh ADR superseding this one. The framework deliberately makes Tier A "needs a new decision to revisit," not "auto-reconsidered each release." +- Tier-A exclusion has **no routine reinstatement path** — re-inclusion requires this ADR to be superseded or amended with new primary-source evidence (per the Tier-A definition above). If Google were to walk back the named-tool prohibition and the cost picture changed, the path is "draft an ADR amendment citing the new primary-source evidence," not a routine config flip. The framework deliberately makes Tier A "needs a constitutional-level decision to revisit," not "auto-reconsidered each release." This is procedurally stricter than "permanent" (the amendment procedure is always available) but practically equivalent — the bar is constitutional, not operational. **Mitigations** - The README "Supported Providers" table is the user's first stop and surfaces tiers prominently. The dashboard (spec §4.6) shows tier per enabled provider so users see it on every dashboard load, not only at enable-time. diff --git a/docs/adr/README.md b/docs/adr/README.md index 0d0e1de..d69c6c1 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -19,7 +19,7 @@ New ADRs increment from the highest existing number. Filenames are `NNNN-=18" },