mirror of
https://github.com/dtzp555-max/olp.git
synced 2026-07-21 21:15:10 +00:00
docs: D79 — Phase 5 constitutional layer (ADR 0012 + ADR 0002 Amendment 8 + ADR 0013) (#50)
* docs: D79 — Phase 5 constitutional layer (ADR 0012 + ADR 0002 Amendment 8 + ADR 0013)
Three coupled governance documents land together as the Phase 5 constitutional
layer (Iron Rule 11 IDR — reviewing them separately cannot verify
consumer-producer alignment). Phase 5 opens 2026-05-26; D79 is governance-only,
no code changes.
- ADR 0012 (Phase 5 charter) — port OCP's plan-usage probe to
`lib/providers/anthropic.mjs:quotaStatus()` (D80) + extend
`/v0/management/dashboard-data` for new shape (D81) + Claude.ai-style
dashboard restructure with 1-min auto-refresh + manual refresh (D82) +
Suite 38/39 tests (D83) + optional mistral probe at D84 (codex skipped —
no public API) + v0.5.0 close (maintainer-triggered). ~6 D-days.
- ADR 0002 Amendment 8 (direct-API READ-ONLY exemption) — plugin contract
amendment permitting quotaStatus() to call provider HTTP APIs directly,
subject to three constraints: READ-ONLY (no mutating calls),
subscription-scope (reuses spawn-path credentials), idempotent failure
(returns null on any error, never throws). No other contract method gains
this permission.
- ADR 0013 (OAuth READ-ONLY consumption + schema-drift mitigation) —
implementation discipline for ADR 0002 Amendment 8. Seven rules: (1)
credential reuse via plugin's readAuthArtifact(), (2) READ-ONLY at wire
(max_tokens:1, headers-only parse, body discarded), (3) cache TTL 5min +
60s-3600s exponential refresh backoff + stale-cache-on-failure, (4)
opt-in via `~/.olp/config.json providers.<name>.quota_probe_enabled`
(default false), (5) schema-drift mitigation via dual-path verification
(compiled-binary `strings` + live API probe diff), (6) failure
transparency through `olp doctor` + dashboard staleness markers, (7)
explicit out-of-scope clarifications.
Pre-flight institutional-knowledge audit (Iron Rule 12 prior-art search)
captured at `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`
(cross-machine git-sync). Findings:
- OCP probe (server.mjs:842-1109) still works against current
api.anthropic.com — tested live from PI231 OAuth credentials 2026-05-26.
- 13 `anthropic-ratelimit-unified-*` response headers confirmed
(3 new since OCP 2026-04 capture: 5h-status, 7d-status, overage-reset;
no removals or renames).
- Claude Code v2.1.x is now distributed as compiled native binary
(Mach-O on macOS, ELF on Linux) — OCP's "grep cli.js" verification is no
longer applicable. ADR 0013 Rule 5 replaces with dual-path verification
(`strings` over the binary + live API probe diff).
- OAuth refresh path (platform.claude.com/v1/oauth/token + client_id
9d1c250a-...) all unchanged.
Authority:
- ALIGNMENT.md Rule 1 (citation): audit memory + OCP server.mjs:842-1109 +
live `/v1/messages` probe transcript 2026-05-26.
- ALIGNMENT.md Rule 2 (provider-CLI-as-authority): Amendment 8 documents the
exemption; the probe mirrors observed CLI behaviour.
- ALIGNMENT.md Rule 5 (CI alignment.yml): not triggered (docs/ excluded by
workflow `paths:` filter); blacklisted `/api/oauth/usage` token referenced
only as meta-references ("must continue to blacklist").
- CLAUDE.md release_kit overlay: Phase 5 open; D-day commits stay under
"Unreleased" until maintainer-triggered v0.5.0 close.
Iron Rule 10: fresh-context reviewer required before merge per CLAUDE.md
hard requirement #3.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: D79 fold-in — 6 in-PR nits from fresh-context reviewer (PR #50)
Reviewer verdict: APPROVE_WITH_MINOR (0 blocking, 9 nits — 6 in-PR, 3 outside-PR).
Folding in the 6 in-PR nits here; the 3 outside-PR ones (audit-memory chronology,
audit-memory D80/D81 mapping, ALIGNMENT.md cross-ref to Amendment 8) are deferred.
Folded-in nits:
1. ADR 0002 Amendment 8: added a 5th "does NOT permit" bullet making per-endpoint
containment explicit. Amendment 8 permits the kind of call; ADR 0013 Rule 2
enumerates which specific endpoint. Re-opening per-endpoint scope requires an
ADR 0013 amendment, not a Amendment-8-only interpretation.
2. ADR 0013 Rule 5: added "Path A prerequisites" paragraph documenting that
strings (GNU/BSD binutils/coreutils) + Claude Code v2.1.x install are required
for compiled-binary verification. Windows reviewers need WSL or binutils-mingw.
3. ADR 0013 Rule 5: added "Trigger for re-running the diff" paragraph naming three
explicit hooks for major-version-bump detection: Annual Alignment Audit
(14 May), olp doctor anthropic.quota_probe_reachable failure, manual
maintainer attention. Documented graceful-degradation failure mode.
4. ADR 0012 D80 estimate: 1.5d → 2d. Reviewer flagged 1.5d as optimistic
compared to D61-D63 (2.5d for narrower SSE heartbeat scope). Aligning.
5. ADR 0012 D84: moved Mistral GO/NO-GO spike to D79 close (before D80 starts),
not mid-phase. Reduces mid-phase scope drift risk. Outcome will be amended
into this charter as a D79-close amendment.
6. ADR 0012 Authority + cross-references: replaced "Claude Code <version> §
OAuth bearer + ratelimit headers" with "compiled-binary strings evidence
per audit memory § Path A". Claude Code v2.1.x has no traditional section
structure because it is a Mach-O / ELF compiled binary.
Deferred (outside-PR) nits documented in PR review thread:
- Audit memory historical-table chronology error (cb6c2a8 placed last; was
second chronologically — narrative arc still holds, dates need correction).
- Audit memory D80/D81 mapping mismatch (memory says D81 adds new fields;
ADR 0012 says D80 parses all 13).
- ALIGNMENT.md cross-reference to Amendment 8 (Class-specific Exceptions
subsection should name Amendment 8 explicitly).
All three outside-PR items are docs-only and not load-bearing for D80
implementation. Will fold in either at D80 commit (audit-memory updates)
or as a tiny constitutional cleanup PR (ALIGNMENT.md cross-ref).
Iron Rule 10: reviewer was a fresh-context opus subagent; their full review
is recorded in PR #50 thread.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+17
-1
@@ -4,7 +4,23 @@ All notable changes to OLP land here. Per `CLAUDE.md` release_kit overlay, this
|
||||
|
||||
## Unreleased
|
||||
|
||||
(empty — Phase 5 entries land here once Phase 5 opens)
|
||||
### D79 — Phase 5 constitutional layer: charter ADR 0012 + ADR 0002 Amendment 8 + ADR 0013
|
||||
|
||||
Three coupled governance documents land together as the D79 constitutional layer (Iron Rule 11 IDR — reviewing them separately cannot verify consumer-producer alignment). Phase 5 opens 2026-05-26; no code changes yet.
|
||||
|
||||
- **ADR 0012 (Phase 5 charter).** Scope: port OCP's plan-usage probe to `lib/providers/anthropic.mjs:quotaStatus()` (D80) + extend `/v0/management/dashboard-data` for the new shape (D81) + Claude.ai-style dashboard restructure with 1-min auto-refresh + manual refresh button (D82) + Suite 38/39 quota-probe + dashboard tests (D83) + optional mistral probe at D84 (codex skipped — no public API) + v0.5.0 close (maintainer-triggered). D-day plan covers ~6 D-days.
|
||||
- **ADR 0002 Amendment 8 (direct-API READ-ONLY exemption).** Plugin contract amendment permitting `quotaStatus()` to call provider HTTP APIs directly, subject to three constraints: READ-ONLY (no mutating calls), subscription-scope (reuses spawn-path credentials), idempotent failure (returns `null` on any error, never throws). No other contract method gains this permission. Cites OCP `server.mjs:842-1109` as the port reference + `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md` as the live schema pin.
|
||||
- **ADR 0013 (OAuth READ-ONLY consumption + schema-drift mitigation).** Implementation discipline for ADR 0002 Amendment 8. Seven rules: (1) credential reuse via plugin's `readAuthArtifact()` — no new OAuth grant, (2) READ-ONLY at the wire — one probe per cache miss with `max_tokens:1`, headers-only parse, body discarded, (3) cache TTL 5min + 60s-3600s exponential refresh backoff + stale-cache-on-failure, (4) opt-in via `~/.olp/config.json providers.<name>.quota_probe_enabled` (default false), (5) schema-drift mitigation via dual-path verification (compiled-binary `strings` + live API probe diff), (6) failure transparency through `olp doctor` + dashboard staleness markers, (7) explicit out-of-scope clarifications.
|
||||
|
||||
**Pre-flight institutional-knowledge audit.** Phase 5 was unblocked by a 2026-05-26 audit per Iron Rule 12 (prior-art search before brainstorming). The audit verified:
|
||||
- OCP's plan-usage probe (`server.mjs:842-1109`) still works against current `api.anthropic.com` — tested live from PI231 OAuth credentials.
|
||||
- 13 `anthropic-ratelimit-unified-*` response headers confirmed (3 new fields since OCP's 2026-04 capture: `5h-status`, `7d-status`, `overage-reset`; no removals or renames).
|
||||
- Claude Code v2.1.x is now distributed as compiled native binary (Mach-O / ELF) — OCP's "grep cli.js" verification is no longer applicable. ADR 0013 Rule 5 replaces it with dual-path verification (compiled-binary `strings` + live API probe diff).
|
||||
- OAuth refresh path (`platform.claude.com/v1/oauth/token`, client_id `9d1c250a-...`, 60s-3600s exponential backoff) all unchanged.
|
||||
|
||||
Audit memory persists at `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md` (cross-machine git-sync).
|
||||
|
||||
**Authority cited at D79 commit body:** ALIGNMENT.md Rules 1 + 2 + 5; CLAUDE.md release_kit (Phase 5 open); audit memory; OCP server.mjs:842-1109 as port reference; live `/v1/messages` probe transcript from 2026-05-26.
|
||||
|
||||
## v0.4.4 — 2026-05-26
|
||||
|
||||
|
||||
@@ -9,6 +9,30 @@
|
||||
|
||||
> **Note on numbering.** Sequence is 1, 3, 4, 5, 6, 7 — Amendment 2 was never written. The reserved slot was originally planned for a separate `maxConcurrent` ratification, but that content was folded into Amendment 1 (the retroactive contract-sync amendment) at filing time and the gap was not backfilled. The gap is intentional and load-bearing — no missing content; do not renumber Amendments 3+ to close it (cross-references to Amendment N from other docs would silently break).
|
||||
|
||||
### Amendment 8 — 2026-05-26: Permit `quotaStatus()` direct-API access (READ-ONLY exemption) for plan-usage probes (D79–D80 — Phase 5)
|
||||
|
||||
- **Context:** ADR 0012 (Phase 5 charter) opens 2026-05-26 to port OCP's plan-usage probe (`ocp/server.mjs:842-1109`) into `lib/providers/anthropic.mjs:quotaStatus()`. The probe calls `POST https://api.anthropic.com/v1/messages` directly with an OAuth bearer and parses `anthropic-ratelimit-unified-*` response headers. This violates the plugin contract's implicit assumption that ALL provider interaction goes through `spawn` (the binary CLI). `ALIGNMENT.md` Rule 2 (provider-CLI-as-authority) further constrains plugins to operations the provider CLI itself performs. The OCP-derived plan-usage probe satisfies neither of these — it bypasses `claude -p` and hits the public API directly. **Without an explicit exemption Amendment, D80 is unalignable.**
|
||||
- **Why the exemption is sound:** The probe is strictly **READ-ONLY** (one `POST /v1/messages` with `max_tokens: 1`; the response body is discarded; only response headers are parsed) AND **subscription-scope** (the OAuth bearer is the same one Claude Code uses for `claude -p`; no extra grant is requested) AND **idempotent** (probe failure returns `null`, never throws to a caller). The "what authority backs this?" answer is: Anthropic's CLI internally makes the same `/v1/messages` call (verified 2026-05-26 by `strings` on the compiled binary — see `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`); the probe is mirroring an established CLI behaviour rather than introducing a new wire format. Under `ALIGNMENT.md` Rule 2, mirroring observed CLI behaviour is permitted; the Rule's intent is "don't invent wire formats Anthropic's CLI does not perform", which the probe respects.
|
||||
- **Change — extend the Provider contract description:**
|
||||
- `quotaStatus(authContext): { quotaInfo }` is now permitted to call provider HTTP APIs directly, subject to **all three** constraints:
|
||||
1. **READ-ONLY** — the API call must not mutate provider-side state. POST is acceptable when the response is what's needed (Anthropic returns ratelimit headers on `POST /v1/messages`); the request body MUST minimise side-effects (`max_tokens: 1`, dummy `messages`).
|
||||
2. **Subscription-scope reuse** — the credentials used MUST be the same auth artifact the spawn path already reads via `readAuthArtifact()`. No new OAuth grant, no new API-key registration, no separate scopes.
|
||||
3. **Idempotent failure** — if the probe fails for any reason (network error, 401, 429, schema parse failure), the function returns `null` rather than throwing. The caller (server.mjs / dashboard / `olp usage` CLI) interprets `null` as "quota data unavailable" and continues gracefully.
|
||||
- `healthCheck()` and other contract methods are NOT extended by this Amendment. Only `quotaStatus()` may make direct API calls. A plugin that wants live data for any other contract method must continue to use `spawn` or `readAuthArtifact`.
|
||||
- The probe MUST cache its result. Recommended TTL: 5 minutes (mirrors OCP `USAGE_CACHE_TTL`). Tighter TTLs (e.g. dashboard's 1-minute refresh) are served from the cached value if fresh; cache miss triggers a real probe.
|
||||
- The probe MUST implement exponential backoff on refresh failures: minimum 60s, maximum 3600s (mirrors OCP `OAUTH_REFRESH_MIN_BACKOFF` / `OAUTH_REFRESH_MAX_BACKOFF`). Tight loop on failure has historically burned through Anthropic's rate limit in seconds (OCP institutional lesson 2026-04).
|
||||
- The probe MUST be opt-in via `~/.olp/config.json` (`providers.<name>.quota_probe_enabled: true`; default `false`). Reasoning: a fresh OLP install on a machine without OAuth credentials should not bombard `api.anthropic.com` with 401-bound probes; the operator opts in once the credentials are configured.
|
||||
- **What this Amendment does NOT permit:**
|
||||
- Mutating API calls (e.g. POST/PATCH/DELETE that change provider-side state). Still forbidden.
|
||||
- API calls for any contract method other than `quotaStatus()`. `spawn` / `healthCheck` / `doctorChecks` / `estimateCost` / `models` / `hints` / `name` / `displayName` / `auth` remain spawn-and-filesystem-only.
|
||||
- Per-provider new auth grants. The probe uses the spawn path's existing credentials.
|
||||
- Bypassing the alignment.yml blacklist. The hallucinated `/api/oauth/usage` token stays blacklisted; the probe uses `/v1/messages` (real endpoint).
|
||||
- **API calls to endpoints not explicitly enumerated by the companion ADR 0013 § Rule 2.** Amendment 8 permits the *kind* of call (READ-ONLY direct API for quota probing); ADR 0013 Rule 2 enumerates *which specific endpoint* is permitted. A future reader of Amendment 8 alone should NOT infer that any READ-ONLY/idempotent endpoint is fair game — the per-endpoint containment is locked to ADR 0013. Re-opening per-endpoint scope requires an ADR 0013 amendment, not a new plugin-level interpretation of Amendment 8.
|
||||
- **Backwards compatibility:** Plugins whose `quotaStatus()` still returns `null` (mistral at v0.5.0 pending D84 audit, codex permanently per Phase 5 charter) are NOT affected. No existing behaviour changes for them.
|
||||
- **Authority cited at the implementation:** D80 commit cites this Amendment + `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md` + `Claude Code v2.1.x § OAuth bearer + ratelimit-unified headers` + live-probe transcript from 2026-05-26 in the commit body. ALIGNMENT.md Rule 1 + Rule 5 (CI) both satisfied.
|
||||
- **Tests:** Suite 38 (Phase 5 D83) covers the probe: mock HTTP server returning all 13 `anthropic-ratelimit-unified-*` headers; assert parse correctness for each; assert 5min cache; assert 60s-3600s exponential backoff on simulated 429; assert stale-cache-on-failure (`null` is returned only when no cache entry exists; if a stale entry exists it's returned with a `stale: true` marker).
|
||||
- **Procedural mechanism:** Iron Rule 11 (IDR) — this Amendment, ADR 0012 (Phase 5 charter), and ADR 0013 (OAuth READ-ONLY consumption rules) land together at D79 as a single coupled commit. Reviewing them separately cannot verify consumer-producer alignment. Iron Rule 10 fresh-context reviewer per CLAUDE.md hard requirement #3.
|
||||
|
||||
### Amendment 7 — 2026-05-26: Add OPTIONAL `doctorChecks()` to the Provider contract (D67 — Phase 4 operator UX)
|
||||
|
||||
- **Context:** ADR 0010 § Phase 4 D64-D67 ships `bin/olp.mjs` operator CLI + `olp doctor` framework. `olp doctor` runs a set of `Check` objects (id / category / async `run()` returning `{ status, message, evidence? }`) and discriminates the next remediation step via a `kind` field (`noop` / `fix_server` / `fix_oauth` / `fix_provider` / `fresh_install`). The framework needs per-provider checks so a user with a broken `claude` install gets a different fix recipe than a user with a broken `vibe` install. Hardcoding the recipes in `bin/olp.mjs` would re-introduce the kind of per-provider knowledge drift that ADR 0002 § Decision exists to prevent — when a new provider plugin lands, the operator CLI would have to be edited too.
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# ADR 0012 — Phase 5 Charter: Provider Quota Probes + Dashboard Enrichment
|
||||
|
||||
**Status:** Accepted (Phase 5 open as of 2026-05-26)
|
||||
**Date:** 2026-05-26
|
||||
**D-day:** D79 (charter + ADR 0002 Amendment 8 + ADR 0013 land together as the constitutional layer of Phase 5)
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Phase 4 (ADR 0010) shipped OLP's operator + client UX layer — `bin/olp` operator CLI, `olp doctor` framework, `olp-connect` zero-config IDE wiring, OpenClaw `/olp` slash commands, anonymous-key deployment-context limits, SSE heartbeat. v0.4.4 is the current shipped state. Phase 4 closed every gap on the OCP-feature-parity matrix EXCEPT one: **live quota / plan-usage surfacing**.
|
||||
|
||||
Today `lib/providers/anthropic.mjs:445` has a stub `quotaStatus()` returning `null` (D4 placeholder). The OLP dashboard's quota panel renders "—" for all providers. OCP, in contrast, exposes a live "39% session / 30% weekly" panel — the maintainer uses this multiple times per day to decide when to throttle voluntary `claude -p` traffic away from interactive sessions. OLP cannot become an OCP successor in practice (vs. just feature-parity-on-paper) until quota surfacing works.
|
||||
|
||||
A pre-flight institutional-knowledge audit (2026-05-26 — see `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`) confirmed:
|
||||
|
||||
1. **The OCP probe still works today** — Anthropic returns the same `anthropic-ratelimit-unified-*` headers on every `POST /v1/messages` call. Tested live 2026-05-26 from PI231 OAuth credentials.
|
||||
2. **Schema added 3 fields since OCP's 2026-04 capture** — `5h-status`, `7d-status` (per-window status), `overage-reset` (only on active overage). No fields removed or renamed.
|
||||
3. **Verification protocol has shifted** — Claude Code v2.1.x is now a **compiled binary** (Mach-O / ELF), not bundled JS. OCP's "grep cli.js" approach no longer applies; the replacement protocol is `strings` against the binary + periodic live probe diff.
|
||||
4. **OAuth refresh path unchanged** — `platform.claude.com/v1/oauth/token` + `9d1c250a-...` client_id + 60s-3600s exponential backoff.
|
||||
|
||||
The audit makes Phase 5 implementation low-risk: this is a port of a working OCP function, not a re-derivation. The work is mechanical + adapter-layer plumbing into OLP's plugin contract.
|
||||
|
||||
A parallel maintainer request (2026-05-26, with reference screenshot of claude.ai/settings/usage) asked for Claude.ai-style dashboard enrichment: per-row utilization bars, reset countdown, 1-minute auto-refresh, manual refresh button. P5-1 (probe) + P5-2 (dashboard) together unlock both: the data plus the surface. v1.x roadmap #8 is closed by P5-2.
|
||||
|
||||
---
|
||||
|
||||
## Decision
|
||||
|
||||
Phase 5 scope is **Provider quota probes + dashboard enrichment**. The phase opens 2026-05-26 with D79 (this charter + ADR 0002 Amendment 8 + ADR 0013 OAuth READ-ONLY consumption rules). Phase 5 close ships v0.5.0; per `CLAUDE.md release_kit.phase_rolling_mode`, the close PR is maintainer-triggered.
|
||||
|
||||
### In scope — Phase 5 D-day plan (~6 D-days)
|
||||
|
||||
| D-day | Deliverable | Authority | Estimate |
|
||||
|---|---|---|---|
|
||||
| **D79** | This charter ADR 0012 + ADR 0002 Amendment 8 (direct-API READ-ONLY) + ADR 0013 (OAuth READ-ONLY consumption rules + schema-drift mitigation) + `package.json` `current_pre_release_identifier` → `0.5.0-phase5` + `CLAUDE.md release_kit.phase_rolling_mode.current_phase` → Phase 5 | This charter + audit memory | 0.5d |
|
||||
| **D80** | `lib/providers/anthropic.mjs:quotaStatus()` ported from OCP `server.mjs:842-1109` — full probe with macOS-keychain auth read added (existing OLP reader only handles env + `.credentials.json`) + 5min cache + 60s-3600s refresh backoff + stale-cache-on-429 + all 13 headers parsed (including new 5h-status / 7d-status / overage-reset) | Port OCP probe + ALIGNMENT.md Rule 2 exemption per ADR 0002 Amendment 8 + audit memory | 2d |
|
||||
| **D81** | `lib/audit-query.mjs` + `/v0/management/dashboard-data` extended to surface the new quota shape per provider (utilization, reset, representative-claim, fallback-percentage, overage-status). Audit-query stays in-memory scan per ADR 0008 Lane 2 = A (no SQLite). Schema migration documented in ADR 0008 § Amendment | ADR 0008 + this charter | 1d |
|
||||
| **D82** | `dashboard.html` Claude.ai-style restructure — per-provider rows replace the current single Quota panel; each row: provider badge, model placeholder, utilization bar (5h + 7d), reset countdown ("Your limit will reset at HH:MM AM/PM" format from the user-shared claude.ai screenshot), status badge, representative-claim hint. 1-minute auto-refresh via `setInterval` with `document.visibilityState` guard. Manual refresh button calls `/v0/management/dashboard-data` directly | v1.x roadmap #8 + maintainer reference screenshot | 1.5d |
|
||||
| **D83** | Test coverage — Suite 38 quota-probe unit tests (mock HTTP server returning the 13 headers; assert parse + cache + backoff + stale-on-429); Suite 39 dashboard rendering smoke (curl `/dashboard` after pre-seeding mock quota cache; assert HTML contains expected utilization strings); update Suite 33 doctor checks for new `anthropic.quota_probe_reachable` check | Test convention from existing suites | 1d |
|
||||
| **D84** | (optional) `lib/providers/mistral.mjs:quotaStatus()` — Mistral GO/NO-GO decided at D79 close (30-min docs spike before D80 starts), NOT mid-phase. If Mistral exposes `/v1/usage` or equivalent → D84 ports the probe with a parallel ADR 0002 Amendment 8 invocation. If NOT exposed → D84 is dropped from the plan and mistral row shows "spend tracking only" badge sourced from audit-query. Codex explicitly skipped — `openai/codex` CLI has no public quota API. GO/NO-GO outcome documented in this charter as a D79-close amendment | Live audit at D79 close (~30 min spike) | 0.5d if GO; 0d if NO-GO |
|
||||
| **close** | v0.5.0 release PR — `package.json` `0.4.4 → 0.5.0`, CHANGELOG promotion, `release_kit.phase_rolling_mode.current_pre_release_identifier` advance to Phase 6 token | `CLAUDE.md release_kit overlay` | maintainer-triggered |
|
||||
|
||||
### Out of Phase 5 scope (with explicit triggers)
|
||||
|
||||
#### `X-OLP-Cost-USD` per-request response header
|
||||
|
||||
**Status:** Deferred to Phase 6. Was listed in ADR 0010 § Out-of-scope as "Phase 5 prerequisite". The prerequisite (provider-cost weights table) is non-trivial — needs per-(provider, model) `input_cost_per_1k_tokens` / `output_cost_per_1k_tokens` / `cache_read_discount` data sourced from each provider's published pricing page. Phase 5 already pulls in two new ADRs; adding a third data-onboarding ADR is scope creep.
|
||||
|
||||
**Re-open condition.** Phase 6 unless a maintainer reports a cost-attribution debugging need that warrants pulling forward.
|
||||
|
||||
#### `context_window_exceeded` fallback trigger (LiteLLM prior-art)
|
||||
|
||||
**Status:** Deferred. ADR 0010 listed this as opportunistic-in-Phase-5 unless the trigger fires sooner. The trigger has not fired in Phase 4 production traffic. Continue to defer.
|
||||
|
||||
#### per-(provider, model) live stats Map (replacing audit-query scan)
|
||||
|
||||
**Status:** Deferred. Current scan latency is ~20ms at 7-day depth. Acceptable until volume grows (>100k requests/day). Re-evaluate at Phase 6 if dashboard latency degrades.
|
||||
|
||||
#### Anthropic interactive-mode P0 (ADR 0009)
|
||||
|
||||
**Status:** Still trigger-gated on Anthropic's 2026-06-15 billing-split rollout. Phase 5 does NOT depend on P0 — the quota probe reads `anthropic-ratelimit-unified-*` headers regardless of which billing pool the spawn path consumes. If P0 succeeds Phase 7+ Phase 5's probe code remains unchanged; if P0 fails Phase 5's probe code remains unchanged. The probe is billing-pool-agnostic because the headers are subscription-pool metadata, not Agent-SDK-Credit metadata.
|
||||
|
||||
#### `/v1/messages` Anthropic-shape entry surface
|
||||
|
||||
**Status:** Still deferred per ADR 0010 § Out-of-scope. No change in Phase 5.
|
||||
|
||||
#### v1.x roadmap #3 / #5 / #6
|
||||
|
||||
**Status:** Still trigger-gated per `docs/v1x-roadmap.md`. None has fired. Continue to defer.
|
||||
|
||||
### Opportunistic Phase 5 micro-additions (not blocking)
|
||||
|
||||
Items small enough to land alongside a planned D-day without scope creep, if encountered:
|
||||
|
||||
- README § Dashboard screenshot update (post-P5-2 enrichment) — capture from MacBook test path per `~/.cc-rules/memory/feedback/mac_mini_never_for_testing.md`.
|
||||
- `olp usage` CLI subcommand (bin/olp.mjs) surfaces the parsed quota shape in terminal form. Already partially exists (cmdUsage in bin/olp.mjs); confirm payload alignment after D80.
|
||||
- Add `claude_code_oauth_client_id` config override in `~/.olp/config.json` so power users can override the hardcoded `9d1c250a-...` UUID without env-var fiddling. Mirrors compiled binary's `CLAUDE_CODE_OAUTH_CLIENT_ID` env support.
|
||||
- `docs/provider-audits/anthropic.md` re-capture with current `claude --version` (v2.1.142 MacBook / v2.1.150 PI231) + binary distribution layout note.
|
||||
|
||||
### Exit gate — v0.5.0 close criteria
|
||||
|
||||
1. D79 — D84 all merged with fresh-context opus reviewer APPROVE per Iron Rule 10.
|
||||
2. CI green on every D-day merge commit and on the v0.5.0 release commit head. `alignment.yml` blacklist re-confirmed (no new hallucinated tokens introduced).
|
||||
3. README § Quota / Plan Usage section present with screenshot of the enriched dashboard. README § Supported Providers table updated to note "quota probe: anthropic ✅, mistral ⚠️/✅ (D84 outcome), codex ❌ (no public API)".
|
||||
4. ADR 0012 (this charter) + ADR 0002 Amendment 8 + ADR 0013 (OAuth READ-ONLY consumption) on disk.
|
||||
5. `CHANGELOG.md "Unreleased"` promoted to `"## v0.5.0 — <date>"` with D79 — D84 entries.
|
||||
6. `package.json` bumped to `0.5.0`.
|
||||
7. `CLAUDE.md release_kit.phase_rolling_mode.current_phase` advances `Phase 5 → Phase 6`; `current_pre_release_identifier` advances `0.5.0-phase5 → 0.6.0-phase6`.
|
||||
8. Standing autopilot grant covers D-day-by-D-day execution; v0.5.0 close PR is maintainer-triggered.
|
||||
9. Live MacBook E2E verification — dashboard renders enriched panel with real quota data (probe live, not mocked).
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive.**
|
||||
|
||||
- OLP finally has the load-bearing observability OCP had — maintainer can see live "39% session / 30% weekly" and decide whether voluntary `claude -p` traffic stays or moves.
|
||||
- Family members on the LAN see real reset times instead of "—", which makes the "wait 2 hours" guidance concrete vs. abstract.
|
||||
- The institutional-knowledge audit captured the schema in a memory file pinned with date stamps — future ports (mistral, future provider) re-use the verification protocol without re-deriving.
|
||||
- v1.x roadmap #8 (Dashboard enrichment per Claude.ai-style usage page) closes inside Phase 5 rather than waiting for a separate phase.
|
||||
- Compiled-binary-distribution awareness ("no more cli.js to grep") is now codified in OLP governance; the next time Anthropic ships a major CC version, the verification protocol is already written.
|
||||
|
||||
**Negative.**
|
||||
|
||||
- ADR 0002 gains another amendment (Amendment 8). The constitution surface area for `anthropic.mjs` grows. Counter-pressure: the alternative (probe lives in `server.mjs`, like OCP) violates the plugin-architecture principle that per-provider knowledge stays in `lib/providers/`. Amendment 8 is the smaller violation.
|
||||
- The probe makes one `/v1/messages` call per 5min cache miss. That's ~12 calls/hour worst case across the whole proxy (probe is per-credentials, not per-key). With `max_tokens: 1` the cost is < $0.01/day at family-scale traffic. Negligible but not zero.
|
||||
- Schema-drift risk over the long horizon. Anthropic could rename or remove headers in a future version. The mitigation protocol (strings + live probe diff) is in place, but it's a manual check — needs to be invoked by the maintainer or scheduled.
|
||||
- Dashboard refactor introduces a breaking-change risk for the existing dashboard.html consumers (none today, but conceptually). Bumping to v0.5.0 signals this clearly.
|
||||
|
||||
**Neutral.**
|
||||
|
||||
- Phase 5 has more ADR work than Phase 4 (3 governance docs vs. 2). The constitutional layer is deliberately heavier because direct-API access is the single biggest authority decision since the plugin contract itself.
|
||||
|
||||
---
|
||||
|
||||
## Authority + cross-references
|
||||
|
||||
- **Iron Rule 11 (IDR)** — Phase 5 ships across 6 D-days, each a minimum reviewable unit. The governance trio (this ADR + Amendment 8 + ADR 0013) lands at D79 as a single coupled commit (reviewing them separately cannot verify consumer-producer alignment), per ADR 0002 Amendment 7's precedent.
|
||||
- **Iron Rule 12 (prior-art search)** — discharged via the audit memory at `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`. Memory committed prior to D80 implementation.
|
||||
- **ALIGNMENT.md Rule 1 (citation)** — D80 commit must cite compiled-binary `strings` evidence per audit memory § Path A (Claude Code v2.1.x has no traditional `§ section` structure because it is a Mach-O / ELF compiled binary) plus the audit memory file path. Live-probe transcript MUST be included in the commit body.
|
||||
- **ALIGNMENT.md Rule 2 (provider-CLI-as-authority)** — direct-API access bypasses the spawn-binary contract. Amendment 8 is the explicit exemption. Without Amendment 8, the D80 commit is unalignable.
|
||||
- **ALIGNMENT.md Rule 5 (CI alignment.yml)** — must continue to pass. `api.anthropic.com/v1/messages` is NOT on the blacklist (correct — that's the real endpoint). The hallucinated `/api/oauth/usage` IS on the blacklist (transitive from OCP) and must remain.
|
||||
- **ADR 0002 Amendment 8** — companion ADR. Direct-API access scoping; READ-ONLY constraint; opt-in via config flag (default off).
|
||||
- **ADR 0013** — companion ADR. OAuth credentials shared between spawn path + probe path; refresh backoff; schema-drift mitigation protocol.
|
||||
- **CLAUDE.md release_kit** — Phase boundary triggers maintainer-led version bump. D-day commits within Phase 5 stay under "Unreleased". `0.5.0-phase5` is the pre-release identifier during the phase.
|
||||
@@ -0,0 +1,186 @@
|
||||
# ADR 0013 — OAuth READ-ONLY Consumption Rules + Schema-Drift Mitigation Protocol
|
||||
|
||||
**Status:** Accepted (2026-05-26)
|
||||
**Date:** 2026-05-26
|
||||
**D-day:** D79 (lands alongside ADR 0012 Phase 5 charter + ADR 0002 Amendment 8 as the constitutional trio of Phase 5)
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
ADR 0002 Amendment 8 permits `quotaStatus()` to call provider HTTP APIs directly, subject to a READ-ONLY constraint. That Amendment opens the door but does not specify HOW READ-ONLY discipline is preserved across credential lifecycle events (refresh, expiry, revocation), nor how OLP detects when the upstream API schema drifts. ADR 0013 fills both gaps.
|
||||
|
||||
The motivating concern: a provider that ships its CLI as a **compiled native binary** (Anthropic Claude Code v2.1.x is now Mach-O on macOS, ELF on Linux) closes off the previous schema-verification path (grep `cli.js`). If OLP's probe parser silently breaks because a header was renamed, the dashboard shows stale or wrong numbers, and the maintainer's load-bearing throttling decision is based on bad data. This ADR establishes the verification protocol that survives the binary-distribution shift.
|
||||
|
||||
A second motivating concern: the OAuth credentials used by the probe are the SAME credentials the spawn path uses for `claude -p`. Both paths consume them; the probe must not interfere with the spawn path's ability to refresh or invalidate them. Concretely: the probe must not write to the credentials artifact, must not race the spawn path on refresh, and must not amplify a 429 into a refresh storm.
|
||||
|
||||
---
|
||||
|
||||
## Decision
|
||||
|
||||
### Rule 1 — Credential reuse is mandatory
|
||||
|
||||
The probe MUST consume the same OAuth artifact the spawn path reads via the plugin's `readAuthArtifact()`. No new OAuth grant. No alternate credential store. No environment-variable-only fallback (env var `CLAUDE_CODE_OAUTH_TOKEN` is supported as an override consistent with the spawn path, but is not the probe's primary source).
|
||||
|
||||
Precedence order (mirrors OCP `getOAuthCredentials` 2026-04-stable):
|
||||
|
||||
1. `process.env.CLAUDE_CODE_OAUTH_TOKEN` if non-empty (manual override; common in CI / dev / one-off debugging).
|
||||
2. `~/.claude/.credentials.json` → `claudeAiOauth.accessToken` (Linux + macOS without keychain access).
|
||||
3. macOS Keychain: `security find-generic-password -a "${USER}" -s "Claude Code-credentials" -w` (preferred on macOS — current `lib/providers/anthropic.mjs` only covers (1) + (2); D80 adds (3)).
|
||||
|
||||
Rationale: a separate OAuth grant would require the maintainer to repeat `claude setup-token` against an OLP-specific scope, doubling credential exposure and divergence risk. Reusing the spawn path's credentials guarantees the probe never has more permission than the spawn path itself.
|
||||
|
||||
### Rule 2 — READ-ONLY at the wire
|
||||
|
||||
The probe MUST issue exactly one HTTP request per cache miss. Method MAY be POST (Anthropic's ratelimit headers come back on `POST /v1/messages`; this is the only way to read them). Request body MUST minimise side effects:
|
||||
|
||||
- `max_tokens: 1` (cost: ~$0.000001 per probe)
|
||||
- `messages: [{role: "user", content: "hi"}]` (any minimal valid payload)
|
||||
- Model: cheapest available in the plan (`claude-haiku-4-5` at v0.5.0)
|
||||
- Do NOT include `system` prompts, `tools[]`, `tool_choice`, large content arrays, or anything that the upstream might bill differently.
|
||||
|
||||
The probe MUST discard the response body. Only response headers are parsed.
|
||||
|
||||
The probe MUST NOT call any other HTTP path on the provider's API. No `/v1/models` enumeration, no admin endpoints, no `/v1/messages/<id>` retrievals. The only permitted endpoint is `POST /v1/messages`.
|
||||
|
||||
### Rule 3 — Cache TTL and refresh discipline
|
||||
|
||||
- Cache TTL: 5 minutes. Cache miss triggers a real probe. Cache hit returns the cached value.
|
||||
- The dashboard refreshes every 1 minute; that's served from the cache between probes. A manual refresh button MAY force-clear the cache (per maintainer request 2026-05-26); ADR 0012 D82 documents the button.
|
||||
- On refresh failure (token expired, 401/403/429, network error), the probe schedules an exponential backoff: minimum 60s, maximum 3600s. The cache entry is NOT invalidated during backoff; `quotaStatus()` returns the stale cache marked `{ stale: true, last_fresh_at: <epoch> }`. If no stale entry exists, returns `null`.
|
||||
- Successive successful probes reset the backoff to the minimum.
|
||||
- Token refresh (`POST https://platform.claude.com/v1/oauth/token`) follows the same backoff discipline. The probe MUST NOT refresh a token more than once per backoff window. The refresh path is shared with the spawn path; both observe the same backoff.
|
||||
|
||||
### Rule 4 — Opt-in via config
|
||||
|
||||
A new config field at `~/.olp/config.json` controls per-provider opt-in:
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"anthropic": {
|
||||
"enabled": true,
|
||||
"quota_probe_enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Default: `false`. The maintainer must explicitly opt in after credentials are configured. Reasoning: a fresh install on a machine without OAuth credentials should not bombard `api.anthropic.com` with 401-bound probes.
|
||||
|
||||
`olp doctor` adds a per-provider check `<provider>.quota_probe_reachable` (only runs if `quota_probe_enabled: true`). Failed check provides a `next_action.ai_executable[]` recipe to either re-authenticate or disable the probe.
|
||||
|
||||
### Rule 5 — Schema-drift mitigation protocol
|
||||
|
||||
The CC binary-distribution shift means OCP's "grep cli.js" verification is no longer applicable. OLP adopts a two-path protocol:
|
||||
|
||||
**Path A — Compiled-binary string extraction.** Run `strings` over the platform-specific binary in the claude-code distribution. Captures all hardcoded header names the binary expects:
|
||||
|
||||
```bash
|
||||
BIN_DIR=$(npm root -g)/@anthropic-ai/claude-code/node_modules/@anthropic-ai/claude-code-*
|
||||
strings "$BIN_DIR/claude" | grep -iE "anthropic-ratelimit|/v1/(messages|oauth)|platform\.claude\.com"
|
||||
```
|
||||
|
||||
**Path A prerequisites.** GNU or BSD `strings` (part of binutils/coreutils on Linux + macOS — always present on a normal developer machine; Windows requires WSL or `binutils-mingw`). A locally installed Claude Code v2.1.x (npm-global or volta-managed). A reviewer without `claude` installed can still run Path B but Path A is gated on having the binary on disk. A future Claude Code version that ships as a different distribution shape (e.g. Rust binary, statically linked Go) keeps the protocol valid: `strings` works on any ELF/Mach-O regardless of compile source.
|
||||
|
||||
**Path B — Live API probe.** Run the actual probe against `api.anthropic.com` with valid OAuth credentials. Captures what the server returns today:
|
||||
|
||||
```bash
|
||||
curl -s -i -m 10 -X POST https://api.anthropic.com/v1/messages \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "anthropic-beta: oauth-2025-04-20" \
|
||||
-H "anthropic-version: 2023-06-01" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"model":"claude-haiku-4-5","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}' \
|
||||
| grep -iE "^anthropic-ratelimit"
|
||||
```
|
||||
|
||||
Path A tells you what the client expects. Path B tells you what the server actually emits. The diff is the actionable schema delta.
|
||||
|
||||
**Required cadence.** The diff MUST be re-run at every major `claude --version` bump (v2.x → v3.x is the next trigger). The current pinned schema lives at `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`. After re-verification, that memory file MUST be updated (or a successor file written with a new date stamp; the old one cross-linked).
|
||||
|
||||
**Trigger for re-running the diff.** There is no automated detector for a major `claude --version` bump at v0.5.0. Three explicit hooks share this responsibility:
|
||||
|
||||
1. **Annual Alignment Audit** (`ALIGNMENT.md` § Annual Alignment Audit, every 14 May) — diff is mandatory as part of the audit checklist.
|
||||
2. **`olp doctor anthropic.quota_probe_reachable` failure** — if the probe returns non-2xx for any reason other than 401/403/429/network (typical schema breaks manifest as 422 or 400), `olp doctor` surfaces a `kind: fix_provider` recipe whose first step is "re-run the Rule 5 dual-path diff".
|
||||
3. **Manual maintainer attention at a major Claude Code release** — if the maintainer sees a major version bump in `claude --version`, kick off the diff before the next Phase opens. Rolling-mode discipline (CLAUDE.md release_kit) means major-version bumps usually intersect with Phase boundaries.
|
||||
|
||||
If the diff is missed across a major version bump, the failure mode is graceful degradation: the parser silently drops unknown headers; the dashboard shows older values (cached stale) or `null` per Rule 3; `olp doctor` surfaces the staleness.
|
||||
|
||||
**Required action on drift detection.** If a header is renamed or removed:
|
||||
|
||||
1. File a Phase-N issue tagging the maintainer.
|
||||
2. Update the parser in `lib/providers/anthropic.mjs:quotaStatus()` to handle both names (graceful migration), prefer the new name.
|
||||
3. Update the audit memory file with a "drift event" section recording: date, old field, new field, evidence URLs.
|
||||
4. Bump the `models-registry.json` `quota_probe.schema_version` (NEW field added at D80) so downstream consumers can detect.
|
||||
|
||||
If a new header appears in the live response that the parser doesn't read: low-priority enhancement; add to the parser, document in the audit memory, no schema_version bump required.
|
||||
|
||||
### Rule 6 — Failure transparency
|
||||
|
||||
The probe's failure modes are visible to the operator:
|
||||
|
||||
- `/v0/management/dashboard-data` includes per-provider `{ quota_probe: { status: 'ok' | 'stale' | 'failed' | 'disabled', last_fresh_at, last_error?, backoff_until? } }`.
|
||||
- `olp doctor` surfaces probe failure as `kind: fix_oauth` (if 401/403) or `kind: fix_provider` (if 429 with no stale cache or network error).
|
||||
- The dashboard row badge shows the status; clicking a failed row shows the last error (truncated to 200 chars, no full credential traces).
|
||||
|
||||
### Rule 7 — Out-of-scope
|
||||
|
||||
This ADR does NOT govern:
|
||||
|
||||
- Spawn-path OAuth refresh (the spawn path's refresh logic predates this ADR and is governed by the underlying CLI). The probe shares the credential artifact but does not own the refresh.
|
||||
- Anthropic-specific bearer revocation (Anthropic side). Revocation manifests as 401 to the probe, which falls into Rule 6.
|
||||
- Non-Anthropic provider OAuth flows. Mistral / future providers MAY adopt this protocol via plugin-specific ADRs; ADR 0013 establishes the template.
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive.**
|
||||
|
||||
- The probe is bounded — Rule 2 caps the wire traffic, Rule 3 caps the refresh rate, Rule 4 caps activation surface.
|
||||
- Schema-drift detection is procedural and reproducible — Rule 5 gives the maintainer a runbook that doesn't depend on Anthropic publishing a deprecation notice.
|
||||
- Failure is visible — Rule 6 means a broken probe shows up in `olp doctor` and the dashboard, not as a silent "—" in the quota row.
|
||||
- Credential reuse (Rule 1) keeps the security surface area minimal.
|
||||
|
||||
**Negative.**
|
||||
|
||||
- The `quota_probe_enabled` opt-in adds a configuration step. Mitigated by `olp doctor` surfacing the recipe when credentials are present but the probe is off.
|
||||
- The schema-drift protocol is manual. Anthropic could ship a v3.x binary tomorrow and the verification only happens when the maintainer or a doctor probe failure prompts it. Counter-pressure: drift events at OCP scale (~12 months) suggest manual verification on major version bumps is sufficient.
|
||||
- Stale-cache-on-failure (Rule 3) means the dashboard could show 30-minute-old data without an obvious "stale" indicator unless the UI explicitly renders the `stale: true` marker. ADR 0012 D82 requires the dashboard to surface staleness; reviewing that during P5-2 implementation.
|
||||
|
||||
**Neutral.**
|
||||
|
||||
- The protocol is portable. Future provider plugins adopting direct-API probes (mistral if its `/v1/usage` exists) can reuse the same six rules with provider-specific endpoint substitution.
|
||||
|
||||
---
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
### A — Probe lives in `server.mjs` (OCP-style)
|
||||
|
||||
OCP's probe is in `server.mjs:842-1109` because OCP is single-provider and pre-plugin-architecture. Porting that pattern to OLP would violate ADR 0002 (per-provider knowledge stays in `lib/providers/`). Rejected.
|
||||
|
||||
### B — Spawn `claude -p --dry-run` and parse ratelimit headers
|
||||
|
||||
`claude -p` does not expose response headers; the CLI consumes and discards them. Even if it did, parsing CLI stdout is fragile. Rejected.
|
||||
|
||||
### C — Wait for Anthropic to publish a public quota API
|
||||
|
||||
The 2026-06-15 Agent SDK Credit billing-split announcement does not include a public quota API. Anthropic may publish one in the future; this ADR is forward-compatible (Rule 7 explicitly notes "if Anthropic publishes a public ratelimit API, this entire workaround becomes obsolete — re-evaluate"). Rejected for v0.5.0 (no ETA).
|
||||
|
||||
### D — Mandate token-rotation in OLP
|
||||
|
||||
Tempting (auditability), but OCP's experience shows token rotation breaks the spawn path more often than it improves security at family-scale deployment. The credential rotation cadence is Anthropic-side (token TTL); OLP respects whatever Claude Code does. Rejected.
|
||||
|
||||
---
|
||||
|
||||
## Authority + cross-references
|
||||
|
||||
- **ADR 0002 Amendment 8** — the contract-level permission. ADR 0013 is the implementation discipline for that permission.
|
||||
- **ADR 0012** — Phase 5 charter that schedules D80 implementation.
|
||||
- **ADR 0011** — anonymous-key deployment-context (LAN-only). Separate scope; this ADR does not amend it.
|
||||
- **`~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md`** — the live schema pin. Updated on every drift event per Rule 5.
|
||||
- **`alignment.yml`** — must continue to blacklist `/api/oauth/usage` and related hallucinated tokens. Must NOT add `/v1/messages` to the blacklist (legitimate endpoint).
|
||||
- **OCP `server.mjs:842-1109`** — the source-of-truth port reference for D80.
|
||||
- **OCP `ALIGNMENT.md`** — the institutional precedent (2026-04-11 drift → ALIGNMENT introduction) this ADR consolidates for OLP.
|
||||
@@ -25,6 +25,8 @@ New ADRs increment from the highest existing number. Filenames are `NNNN-<short-
|
||||
| [0009](0009-interactive-mode-path-placeholder.md) | Anthropic Interactive-Mode Path (Placeholder) | Placeholder ADR (2026-05-25, Draft) — blocked on OCP ADR 0007 P0 experiment outcome. Records the maintainer's "wait + port" decision: do NOT independently implement; ride OCP's P0 result. If P0 confirms Transport A (stdio NDJSON) or B (PTY) bills as subscription rather than Agent SDK credit, port to OLP `lib/providers/anthropic.mjs` (Option 1 parallel impl, or Option 2 OCP-as-backend; decision deferred to P0-resolution time). If P0 fails on both, shelve. No Phase 4 D-day scheduled until P0 lands AND maintainer issues explicit "go" naming this ADR. |
|
||||
| [0010](0010-phase-4-charter-operator-and-client-ux.md) | Phase 4 Charter — Operator + Client UX | Phase 4 scope ratification (2026-05-26, Accepted). Phase 4 = operator + client UX (SSE heartbeat / `olp` CLI + doctor / `olp-connect` zero-config + Telegram-Discord plugin + IDE docs bundle). ~13 D-days, D60 → v0.4.0. Records the explicit decision to DEFER `/v1/messages` (Anthropic-shape entry surface) on the rationale that under ADR 0009 P0 failure it provides no billing benefit AND degrades worse on fallback than OpenAI-shape clients. Re-open trigger: ADR 0009 P0 success + maintainer-named family CC user. Also closes the OCP-OLP port co-host ambiguity from ADR 0001 (default `OLP_PORT` 3456 → 4567). |
|
||||
| [0011](0011-anonymous-key-deployment-context.md) | Anonymous-Key Deployment-Context Limits (Trusted-LAN Invariant) | D70 (2026-05-26, Accepted). Codifies the trust posture for `/health.anonymousKey` opt-in field (D69) + `bin/olp-connect` zero-config consumer (D68). Three-prerequisite gate (`auth.advertise_anonymous_key=true` + `auth.allow_anonymous=true` + an active key with `plaintext_advertise` field). Guest-tier-only restriction (`createKey()` + CLI reject owner+advertise). Trusted-LAN deployment invariant (loopback / RFC1918 / tailnet / `.local` / `.internal` — soft constraint at v0.4.0; hard enforcement deferred until OLP gains a public-deployment recipe). Re-evaluation trigger: any "expose to public internet" README mode. |
|
||||
| [0012](0012-phase-5-charter-quota-probes-dashboard.md) | Phase 5 Charter — Provider Quota Probes + Dashboard Enrichment | Phase 5 scope ratification (2026-05-26, Accepted). Phase 5 = port OCP's plan-usage probe to `lib/providers/anthropic.mjs:quotaStatus()` + Claude.ai-style dashboard enrichment (1-min auto-refresh + manual refresh + per-provider rows with utilization bars, reset countdowns, status badges) + optional mistral probe at D84 (codex explicitly skipped — no public API). ~6 D-days, D79 → v0.5.0. Companion to ADR 0002 Amendment 8 (direct-API READ-ONLY exemption) + ADR 0013 (OAuth READ-ONLY consumption rules). Closes v1.x roadmap #8 (dashboard enrichment). Re-confirmed schema 2026-05-26 via compiled-binary `strings` + live API probe; 3 new fields since OCP 2026-04 capture, no removals. |
|
||||
| [0013](0013-oauth-read-only-consumption-and-schema-drift.md) | OAuth READ-ONLY Consumption Rules + Schema-Drift Mitigation Protocol | D79 (2026-05-26, Accepted). Implementation discipline for ADR 0002 Amendment 8. Seven rules covering: credential reuse with spawn path (no new OAuth grant); READ-ONLY at the wire (one probe per cache miss, `max_tokens:1`, headers-only parse, discard body); cache TTL 5min + 60s-3600s exponential refresh backoff + stale-cache-on-failure; opt-in via `~/.olp/config.json providers.<name>.quota_probe_enabled` (default false); schema-drift mitigation via dual-path verification (compiled-binary `strings` + live API probe diff); failure transparency through `olp doctor` + dashboard staleness markers; out-of-scope clarifications. Bound by `~/.cc-rules/memory/learnings/anthropic_plan_usage_probe_schema_2026_05_26.md` as the live schema pin. |
|
||||
|
||||
## When to write a new ADR
|
||||
|
||||
|
||||
Reference in New Issue
Block a user