docs: D48 — ADR 0008 Phase 3 design draft (Dashboard + audit query layer) (#25)

* docs: D48 — ADR 0008 Phase 3 design draft (Dashboard + audit query layer, design-only)

First Phase 3 D-day. Design-only. Ratifies the storage / query model /
rotation / dashboard / refresh / scope decisions ahead of D49+
implementation D-days. Opens ADR 0007 § 12 deferral for Dashboard +
audit query layer + rotation.

NEW docs/adr/0008-dashboard-and-audit-query.md (~368 lines): 13 sections
+ Consequences + Authority citations. Per maintainer-pinned lanes
A/A/B/A/B from Phase 3 kickoff brief 2026-05-25:

  Lane 1 (tech stack): A — static HTML + vanilla JS + fetch; no build
    step; matches OLP "no bundler" ethos.
  Lane 2 (query model): A — in-memory scan of audit ndjson per request;
    O(N) per call; family-scale acceptable; defers SQLite hybrid to
    Option 3 trigger per ADR 0007 § 13 (requires engines bump as
    separate prior PR).
  Lane 3 (rotation): B — daily rotation, audit-YYYY-MM-DD.ndjson on
    first append after UTC midnight + optional bin/olp-audit-rotate.mjs
    external cron.
  Lane 4 (refresh): A — 30s page poll (no SSE infra at v0.3.0;
    pause when document.visibilityState is hidden).
  Lane 5 (dashboard scope): B — full per spec § 4.6: 4 panels (per-
    provider quota / 24h request+cache+fallback / 30d spend trend /
    top-N fallback chains).

ADR sections:

  §1 Context (what Phase 3 closes; what stays out)
  §2 Decision (5 lanes pinned)
  §3 Storage layout (~/.olp/logs/ with rotated date files)
  §4 lib/audit-query.mjs API (readAuditWindow, aggregateRequests,
     topFallbackChains, spendTrendDaily, cacheHitRateWindow)
  §5 Audit rotation (first-append-after-UTC-midnight trigger + cron
     alternative + concurrent-safety per-process lock)
  §6 Dashboard panels (4 panels per spec § 4.6, refresh + localhost-
     bound notes)
  §7 Server endpoints (/dashboard, /v0/management/dashboard-data, /v0/
     management/quota, /cache/stats — owner-only gated)
  §8 Auth gating (reuses ADR 0007 § 7 owner_only_endpoints config)
  §9 Failure modes + degradation (per-panel error states)
  §10 Acceptance criteria (15 testable items for D49-D54)
  §11 Forward path (Phase 4+ — SQLite migration, SSE push, key-mgmt UI)
  §12 Out of scope (explicitly NOT in Phase 3)
  §13 Phase 3 sprint shape (D48-D55)

CHANGED:

  - docs/adr/README.md: added ADR 0008 row with one-paragraph summary.
  - CHANGELOG.md Unreleased: D48 entry per release_kit overlay
    phase_rolling_mode discipline. Includes Phase 3 sprint shape table.

NOT IN D48 scope:

  - lib/audit-query.mjs (D49)
  - server.mjs endpoints (D50)
  - dashboard.html (D51)
  - lib/audit.mjs rotation extension + bin/olp-audit-rotate.mjs (D52)
  - tried_providers schema fix (D53; D45 P2 deferral)
  - Phase 3 close (D55; v0.3.0; maintainer-triggered)

Test count: 544 / 544 pass (design-only, no test change). Verified
locally via npm test before commit.

AUTHORITY:

  - ADR 0007 § 12 (opens Phase 3 Dashboard + audit query deferral).
  - ADR 0007 § 13 (rejects SQLite at Phase 3 per Node baseline +
    documents forward-path trigger).
  - OLP v0.1 spec § 4.6 + § 4.7 (Dashboard + observability endpoints
    planning authority).
  - OCP dashboard.html (prior-art reference for multi-panel HTML
    structure).
  - ADR 0002 (Provider.quotaStatus contract — Panel 1 data source).
  - ADR 0005 § Cache stats (/cache/stats endpoint pre-existing design).
  - CC 开发铁律 v1.6 § 10 — fresh-context opus reviewer required for
    design ADR.
  - Phase 3 kickoff via maintainer "go" 2026-05-25 + standing-autopilot
    grant (~/.cc-rules/memory/auto/standing_autopilot_phase_2.md in
    cc-rules bf0ed9a — Phase 3+ requires new authorization; the "go"
    supplied that).

ALIGNMENT.md scope check: this PR introduces a new ADR with full
authority citations per Rule 1 (Cite First). No provider plugin /
entry surface / IR change in this commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs: D48 fold-in — opus reviewer findings (1 P2 + 2 P3, all ADR-text polish)

Fresh-context opus reviewer (PR #25) returned APPROVE_WITH_MINOR with 3
findings, all ADR-text polish. No design semantic change beyond the
clarifications.

P2 — § 8 + § 10 #9 gating-mode wording

  Original § 8 implied a new "block non-owner identities" behaviour
  without naming it; § 10 #9 tested only the universal
  allow_anonymous: false 401 case. Fix:
  - § 8 now formalizes two gating modes — owner_only_trim (Phase 2
    /health pattern) vs owner_only_block (new Phase 3 management-
    endpoints pattern) — and explains the management endpoints are
    owner_only_block because the entire payload is sensitive.
  - § 10 #9 now covers both 401 paths: (a) allow_anonymous: true
    + no header → anonymous identity → STILL 401 because management
    endpoints are owner_only_block; (b) allow_anonymous: false + no
    header → 401 at the authenticate middleware itself.

P3 #1 — /cache/stats citation accuracy

  Original § 7.4 + Authority block cited "ADR 0005 § Cache stats"
  which is not a real section. Corrected: planning authority is OLP
  v0.1 spec § 4.6; ADR 0005 references the endpoint in
  Consequences/Mitigations (~line 279) for the per-(provider, model)
  cache-hit-rate breakdown surface.

P3 #2 — cacheStore.stats() shape gap

  § 7.4 now explicitly acknowledges the current shape
  ({ hits, misses, size, inflightCount } global aggregate) lacks the
  per-(provider, model) breakdown spec § 4.6 implies; Phase 3 Panel 2
  sources per-provider counts from aggregateRequests (audit-side)
  instead. If a future panel needs the breakdown, D50 amends the
  store shape + an ADR 0005 amendment fires at that time. Phase 3
  acceptance criteria do not require the breakdown.

CHANGELOG.md Unreleased D48 entry: fold-in bullet added enumerating
the 3 fixes.

Test count: 544 / 544 pass (design-only, no test change). Verified
locally via npm test.

Authority: PR #25 fresh-context opus reviewer findings; CLAUDE.md
release_kit overlay phase_rolling_mode — under Unreleased.

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:
dtzp555-max
2026-05-25 15:41:26 +10:00
committed by GitHub
co-authored by taodeng Claude Opus 4.7
parent e87b6b73ec
commit c0b696984f
3 changed files with 392 additions and 1 deletions
+19 -1
View File
@@ -4,7 +4,25 @@ All notable changes to OLP land here. Per `CLAUDE.md` release_kit overlay, this
## Unreleased
(empty — Phase 3 entries land here once Phase 3 opens)
### D48 — ADR 0008 Phase 3 design draft (Dashboard + audit query layer)
First Phase 3 D-day. Design-only. Ratifies the storage / query model / rotation / dashboard / refresh / scope decisions ahead of D49+ implementation D-days. Opens ADR 0007 § 12 deferral for Dashboard + audit query layer + rotation.
- **New file `docs/adr/0008-dashboard-and-audit-query.md`** (~390 lines): 13 sections + Consequences + Authority citations. Decisions per maintainer-pinned lanes:
- Lane 1 (tech stack): static HTML + vanilla JS + fetch (no build step; matches OLP "no bundler" ethos)
- Lane 2 (query model): in-memory scan of audit ndjson per request (defers SQLite hybrid per ADR 0007 § 13)
- Lane 3 (rotation): daily rotation, `audit-YYYY-MM-DD.ndjson` on first append after UTC midnight + optional `bin/olp-audit-rotate.mjs` external cron
- Lane 4 (refresh): 30s page poll (no SSE infra at v0.3.0)
- Lane 5 (dashboard scope): full per spec § 4.6 — 4 panels (quota / per-provider 24h counts / 30d spend trend / top fallback chains)
- **`docs/adr/README.md` index**: added ADR 0008 row with one-paragraph summary.
- **CHANGELOG.md** Unreleased: this entry.
- **Phase 3 sprint shape:** D49 `lib/audit-query.mjs` + Suite 23 → D50 `/v0/management/*` endpoints + Suite 24 → D51 `dashboard.html` → D52 daily audit rotation + Suite 25 → D53 `tried_providers` schema fix (D45 P2 deferral) → D54 E2E + docs → D55 Phase 3 close → v0.3.0 (maintainer-triggered).
- **Fold-in (fresh-context opus reviewer findings — 1 P2 + 2 P3, all ADR-text polish):**
- **P2 § 8 + § 10 #9 gating-mode wording** — original § 8 implied a new "block non-owner identities" behaviour without naming it; § 10 #9 tested only the universal `allow_anonymous: false` 401 case. Fix: § 8 now formalizes two gating modes — `owner_only_trim` (Phase 2 /health pattern) vs `owner_only_block` (new Phase 3 management-endpoints pattern) — and explains the management endpoints are `owner_only_block` because the entire payload is sensitive. § 10 #9 now covers both 401 paths (with `allow_anonymous: true` + no header → anonymous identity → still 401 because management endpoints are `owner_only_block`; AND with `allow_anonymous: false` + no header → 401 at the authenticate middleware itself).
- **P3 `/cache/stats` citation accuracy** — original § 7.4 + Authority block cited "ADR 0005 § Cache stats" which is not a real section. Corrected: planning authority is OLP v0.1 spec § 4.6; ADR 0005 references the endpoint in `Consequences/Mitigations` (~line 279) for the per-`(provider, model)` cache-hit-rate breakdown surface.
- **P3 `cacheStore.stats()` shape gap** — § 7.4 now explicitly acknowledges the current shape (`{ hits, misses, size, inflightCount }` global aggregate) lacks the per-`(provider, model)` breakdown spec § 4.6 implies; Phase 3 Panel 2 sources per-provider counts from `aggregateRequests` (audit-side) instead. If a future panel needs the breakdown, D50 amends the store shape + an ADR 0005 amendment fires at that time. Phase 3 acceptance criteria do not require the breakdown.
- **Test count:** 544 → 544 (design-only, no test change).
- **Authority:** ADR 0007 § 12 (opens deferral) + § 13 (rejects SQLite at Phase 3 per Node baseline); v0.1 spec § 4.6 / § 4.7 (Dashboard + observability endpoints planning authority); OCP `dashboard.html` (prior art); CC 开发铁律 v1.6 § 10 — fresh-context opus reviewer required for design ADR; Phase 3 kickoff via maintainer "go" 2026-05-25 + standing-autopilot grant; PR #25 fresh-context opus reviewer findings (3 polish items).
## v0.2.0 — 2026-05-25