> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase21-session03-authoritative-claude-usage-oauth/spec.md).

# Session Specification

**Session ID**: `phase21-session03-authoritative-claude-usage-oauth` **Phase**: 21 - Non-Hermes v2.3 Usage Accuracy **Status**: Not Started **Created**: 2026-06-02

***

## 1. Session Overview

This session closes Phase 21 by adding an authoritative Claude Code OAuth usage reader to AI OS. The current dashboard estimates Claude usage windows from local logs, which keeps the UI available offline but cannot match Claude Code's server-side plan usage exactly. This session adds a read-only, timeout-bounded path to Anthropic's OAuth `/usage` endpoint so the dashboard can prefer live percentage and reset data when it is safely available.

The implementation must preserve AI OS's modular aggregate architecture and privacy posture. The OAuth credential stays script-only, no token value or raw credential payload reaches generated data or browser state, and any credential, CLI, network, status, timeout, or parse failure returns `null` so local-log estimates continue to render without operator-visible breakage.

This is the natural next session because Phase 21 Sessions 01 and 02 already completed the adjacent pricing, daily activity, project-window, and ROI contract work. This session touches the more sensitive usage-window path after those local aggregate shapes have stabilized.

***

## 2. Objectives

1. Add a null-safe Claude OAuth usage helper under `scripts/lib/` for credential reads, Claude CLI version detection, and timeout-bounded usage fetches.
2. Extend the Claude usage-window contract so authoritative `pct`, `resetsAt`, `source`, and bounded payload fields are preferred only when valid.
3. Keep all OAuth credentials script-only and covered by aggregate/script redaction so tokens cannot leak into logs, generated data, tests, or UI.
4. Render a clear "live" versus "estimate" badge in the usage panel while preserving legacy generated-data compatibility.
5. Add focused tests for file credential reads, macOS Keychain reads, missing credentials, missing CLI, non-200 responses, timeouts, malformed payloads, source switching, and token redaction.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase15-session03-aggregate-orchestration-refactor` - Provides the modular aggregate script architecture this session must extend.
* [x] `phase21-session01-pricing-daily-activity-accuracy` - Provides the current pricing and daily activity usage contract.
* [x] `phase21-session02-project-windows-skill-roi-defaults` - Provides the settled Phase 21 aggregate shape before the sensitive OAuth usage work.

### Required Tools/Knowledge

* Bun 1.3.14 project commands from `package.json`.
* Existing credential read and timeout patterns in `scripts/lib/subscription-detection.ts`.
* Existing aggregate logging and redaction paths in `scripts/lib/aggregate-run-logger.ts` and `scripts/lib/ai-runtime/providers.ts`.
* v2.3 source anchors for `ClaudeAuthoritativeUsage`, `readClaudeCredential`, `detectClaudeCodeVersion`, `fetchClaudeOAuthUsage`, and Claude window rebuilding under `/home/aiwithapex/projects/claudeos/claude-os-v2.3/`.

### Environment Requirements

* AI OS repo checked out at `/home/aiwithapex/projects/aios`.
* v2.3 source checkout available for reference only.
* No live Claude credential or network availability is required for tests.
* macOS Keychain behavior must be unit-tested with mocks, not with the real operator Keychain.

***

## 4. Scope

### In Scope (MVP)

* An AI OS maintainer can read `~/.claude/.credentials.json` first using safe validators and accept either the nested `claudeAiOauth` payload or the direct credential object.
* An AI OS maintainer on macOS can fall back to Keychain via `security find-generic-password -s "Claude Code-credentials" -a "$USER" -w` using `Bun.spawn`, a short timeout race, raw-token handling, JSON handling, and cleanup on scope exit.
* An AI OS maintainer can detect `claude --version` safely for a Claude Code user agent when available, and return `null` when the CLI is missing or the output is invalid.
* The aggregate script can call `GET https://api.anthropic.com/api/oauth/usage` with the stored OAuth token, a six-second timeout, schema-validated response parsing, and silent fallback to estimates on any failure.
* Generated `usage.claudeWindow` can carry `source: "oauth" | "estimate"`, `resetsAt`, and a bounded `authoritative` payload without any credential or raw auth fields.
* The usage panel can badge Claude usage as live OAuth data or local estimate data without introducing heavy client dependencies or exposing credentials.
* Script, validation, UI, and redaction tests prove fallback behavior and token non-exposure.

### Out of Scope (Deferred)

* Any write or mutation to Anthropic or Claude Code - Reason: this is a read-only usage accuracy path.
* Browser-visible exposure of OAuth tokens, refresh tokens, raw credential JSON, or raw auth response payloads - Reason: credentials stay script-only.
* Hard-failing aggregate output when authoritative usage is unavailable - Reason: local-log estimates must remain the fallback.
* A generic third-party usage gateway - Reason: this session targets Claude Code's own stored OAuth credential and Anthropic usage endpoint only.
* Redesigning the usage panel or home dashboard - Reason: only the live versus estimate affordance is in scope.

***

## 5. Technical Approach

### Architecture

Create `scripts/lib/claude-oauth-usage.ts` as a focused script-only module. It should own the credential shape, authoritative usage shape, safe validators, file credential read, macOS Keychain fallback, Claude CLI version detection, and OAuth usage fetch. Use dependency injection or narrow helper seams where needed so tests can mock `Bun.spawn`, filesystem reads, `fetch`, timeouts, and platform state without touching real credentials.

Keep aggregate orchestration responsible for deciding whether authoritative usage participates in the emitted Claude window. `scripts/lib/usage-assembly.ts` should remain the pure projection layer for `buildClaudeWindow`: it receives local-log counts plus optional authoritative usage, then emits the same legacy fields alongside additive `source`, `resetsAt`, and bounded `authoritative` fields. `src/lib/live-data-types.ts` and `src/lib/validate-live-data.ts` keep browser compatibility additive.

Update the existing redaction path rather than adding a parallel sanitizer. Free-form aggregate logs already pass through `scripts/lib/ai-runtime/providers.ts` via `aggregate-run-logger.ts`; extend that coverage for Claude OAuth token shapes and add regression tests.

### Design Patterns

* Script-only runtime boundary: Credential reads and OAuth fetches stay under `scripts/lib/` and never move into browser code.
* Typed degradation over throws: Every missing or invalid OAuth condition maps to `null`, and aggregate output continues with estimates.
* Extract pure functions, then test, then wire: Validate credential parsing, response parsing, and window projection before orchestration wiring.
* Additive live-data contract: New fields must validate while old payloads without `source`, `resetsAt`, or `authoritative` still render.
* Bounded emission: The authoritative payload includes only safe usage percentages, reset timestamps, fetched timestamp, source, and plan-tier labels.

### Technology Stack

* Bun 1.3.14 runtime and test runner.
* TypeScript for script and browser code.
* Vitest for script, validation, and React component tests.
* Existing Vite/TanStack/React 19 frontend stack.
* No new production dependencies.

***

## 6. Deliverables

### Files to Create

| File                                                                                            | Purpose                                                   | Est. Lines |
| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ---------- |
| `scripts/lib/claude-oauth-usage.ts`                                                             | Safe Claude OAuth credential and usage reader             | \~220      |
| `scripts/lib/__tests__/claude-oauth-usage.test.ts`                                              | Credential, fetch, timeout, parse, and fallback tests     | \~240      |
| `.spec_system/specs/phase21-session03-authoritative-claude-usage-oauth/implementation-notes.md` | Baseline notes, changes made, commands, and residual gaps | \~120      |
| `.spec_system/specs/phase21-session03-authoritative-claude-usage-oauth/security-compliance.md`  | OAuth privacy, redaction, and fallback sign-off           | \~90       |

### Files to Modify

| File                                                    | Changes                                                                                        | Est. Lines |
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------- |
| `scripts/lib/usage-assembly.ts`                         | Add authoritative Claude usage input, source labels, reset fields, and bounded payload         | \~90       |
| `scripts/lib/aggregate-orchestration.ts`                | Call OAuth usage helper and pass authoritative data into the Claude window with sanitized logs | \~45       |
| `scripts/lib/ai-runtime/providers.ts`                   | Extend free-form secret redaction for Claude OAuth token shapes                                | \~15       |
| `src/lib/live-data-types.ts`                            | Add additive Claude usage-window source, reset, and authoritative fields                       | \~35       |
| `src/lib/validate-live-data.ts`                         | Validate and bound new Claude usage fields while preserving legacy payloads                    | \~70       |
| `src/data/live-data.example.json`                       | Add safe example fields for estimate/live-compatible Claude usage                              | \~25       |
| `src/components/usage-panel.tsx`                        | Render live versus estimate badge and reset labels from validated fields                       | \~55       |
| `scripts/lib/__tests__/usage-assembly.test.ts`          | Cover source switching, reset data, bounded payload, and estimate fallback                     | \~80       |
| `scripts/lib/__tests__/aggregate-orchestration.test.ts` | Cover aggregate fallback and sanitized authoritative wiring                                    | \~80       |
| `scripts/lib/__tests__/ai-runtime-providers.test.ts`    | Cover Claude OAuth token redaction                                                             | \~35       |
| `src/lib/__tests__/nested-validation.test.ts`           | Cover additive Claude usage validation and legacy compatibility                                | \~45       |
| `src/components/__tests__/usage-panel.test.tsx`         | Cover live/estimate badge rendering and reset labels                                           | \~60       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Missing credential, missing CLI, non-200 response, timeout, parse failure, and unexpected error all return `null` and preserve local-log estimates.
* [ ] Credential file and macOS Keychain reads are tested without printing or returning raw token values outside the script-only helper boundary.
* [ ] `claudeWindow.source` and per-window `source` switch between `oauth` and `estimate` correctly.
* [ ] `resetsAt` and authoritative percentage values are used only when the validated server payload provides safe values.
* [ ] `authoritative` is bounded to safe fields and never contains OAuth tokens, refresh tokens, raw credentials, authorization headers, or raw response bodies.
* [ ] The usage panel renders a live badge for authoritative OAuth usage and an estimate badge for fallback/local-log usage.

### Testing Requirements

* [ ] OAuth helper tests cover file credential, Keychain credential, raw token, JSON credential, missing credential, missing CLI, non-200, timeout, malformed payload, and parse failure.
* [ ] Usage assembly tests cover authoritative source switching and local estimate fallback.
* [ ] Aggregate orchestration tests prove authoritative usage wiring does not break generated output when the helper returns `null`.
* [ ] Validation and usage-panel tests cover new fields and legacy payloads.
* [ ] Redaction tests prove representative Claude OAuth token values are not emitted in free-form logs.

### Non-Functional Requirements

* [ ] OAuth fetch timeout is six seconds or less and cannot stall scheduled aggregate jobs beyond the session budget.
* [ ] No new client bundle-heavy dependencies are added.
* [ ] Browser-visible data remains sanitized, bounded, and credential-free.
* [ ] Aggregate remains available offline and for API-key-only Claude users.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] `bun run typecheck:scripts` passes.
* [ ] `bun run typecheck` passes.
* [ ] Focused tests and the full `bun run test` suite pass or any residual failure is documented with cause and next action.

***

## 8. Implementation Notes

### Key Considerations

* The session stub is stricter than v2.3 for failures: non-200 responses and missing CLI return `null` rather than emitting partial authoritative metadata.
* `Bun.spawn`, `IS_MACOS`, safe validators, and timeout races should match the AI OS `subscription-detection.ts` style; do not port v2.3's `execSync` pattern.
* Keep token-bearing values inside local helper scope. Do not place credentials into return objects, logs, warnings, thrown errors, test snapshots, generated data, or browser state.
* Treat the OAuth endpoint as an optional accuracy upgrade, not as a required aggregate dependency.

### Potential Challenges

* Mocking `Bun.spawn` cleanly in Vitest: Use narrow dependency injection in the helper rather than global mutation where possible.
* Response-shape drift from an undocumented endpoint: Validate every field and ignore unknown or invalid fields instead of passing through raw payloads.
* Reset timestamp handling: Accept only bounded ISO-like strings and emit `null` when invalid.
* Redaction false positives: Extend token-specific patterns while preserving existing legitimate count fields such as `tokens` and `tokenCount`.

### Relevant Considerations

* \[P02] **Typed degradation over throws**: OAuth and response failures must map to `null` and keep aggregate output healthy.
* \[P08] **Local agent privacy/readiness boundary**: Do not expose raw auth payloads, credentials, prompts, transcripts, paths, or command output.
* \[P15] **Aggregate collection must stay budgeted**: The remote usage fetch must use a short timeout and must not stall scheduled aggregate jobs.
* \[P01] **Extract pure functions, then test, then wire**: Credential parsing, response validation, and usage-window projection should be tested before aggregate wiring.
* \[P05] **Script-only runtime boundary**: Auth and transport code stays under `scripts/lib/` so browser UI consumes only generated safe data.

### Behavioral Quality Focus

Checklist active: Yes

Top behavioral risks for this session:

* A missing or expired OAuth credential could break aggregate output instead of falling back to estimates.
* A token value could leak through logs, generated data, validation fixtures, or UI state.
* Invalid authoritative data could overwrite good local estimates with misleading percentages or reset labels.
* A slow endpoint could stall scheduled aggregate jobs.

***

## 9. Testing Strategy

### Unit Tests

* Test credential parsing for nested file credentials, direct file credentials, raw Keychain token output, JSON Keychain output, invalid shapes, missing files, and non-macOS Keychain bypass.
* Test Claude CLI version detection for valid output, invalid output, spawn failure, and timeout.
* Test OAuth usage fetch for valid payload, missing credential, missing CLI, non-200, timeout, fetch throw, malformed JSON, invalid utilization, and invalid reset timestamps.
* Test `buildClaudeWindow` for authoritative source switching, estimate fallback, clamped percentages, reset propagation, and bounded payload.
* Test redaction helpers against representative `sk-ant-oat01-...` tokens, bearer headers, and raw credential strings.

### Integration Tests

* Test aggregate orchestration with the OAuth helper mocked to return valid data and `null`, proving generated usage output remains valid in both cases.
* Test live-data validation with new Claude usage fields and legacy payloads without those fields.

### Manual Testing

* Run aggregate without credentials and confirm the usage panel still shows estimate data.
* If a disposable local Claude credential is available, run aggregate and inspect generated data for live source labels and absence of token strings.
* Render the dashboard at desktop and mobile widths and confirm the badge and reset labels do not overlap or truncate awkwardly.

### Edge Cases

* Credential file exists but contains malformed JSON.
* Keychain command hangs or exits without output.
* `claude --version` is missing, hangs, or returns non-version text.
* OAuth response returns percentages as either 0-1 or 0-100.
* OAuth response includes extra unknown fields or raw auth-looking values.
* `resets_at` is missing, too long, or not timestamp-like.

***

## 10. Dependencies

### External Libraries

* None.

### Other Sessions

* **Depends on**: `phase15-session03-aggregate-orchestration-refactor`, `phase21-session01-pricing-daily-activity-accuracy`, `phase21-session02-project-windows-skill-roi-defaults`
* **Depended by**: Phase 22 and Phase 23 non-Hermes parity work.

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase21-session03-authoritative-claude-usage-oauth/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
