mirror of
https://github.com/dtzp555-max/olp.git
synced 2026-07-21 21:15:10 +00:00
feat+test+docs: D46 — owner-vs-guest gating for /health + X-OLP-Fallback-Detail (Phase 2) (#22)
* feat+test+docs: D46 — owner-vs-guest gating for /health + X-OLP-Fallback-Detail (Phase 2) Third Phase 2 implementation D-day. Closes ADR 0007 § 10 acceptance criteria #4 (/health payload trimming for non-owner) + #5 (X-OLP-Fallback-Detail emission gating per fallback_detail_header_policy). Phase 2 server surface now fully gated end-to-end; remaining D-days are keygen CLI surface (D47+) and Phase 2 close (v0.2.0, maintainer- triggered). server.mjs handleHealth identity-aware payload per § 7.1: - Auth gate at top — 401 for unauth + allow_anonymous=false; 200 with trimmed { ok, version } for non-owner; 200 with full payload for owner. - Trim controlled by _authConfig.owner_only_endpoints — operator removing /health from the list reverts to v0.1.1 full-payload-to- everyone (opt-out knob). - touchLastUsed fires on res.on('finish') for filesystem identities; no audit row on /health (high-volume monitoring; out of scope at Phase 2 per § 8). server.mjs withFallbackDetailHeader identity-aware emission per § 7.2: - New shouldEmitFallbackDetailHeader(olpIdentity) helper reads _authConfig.fallback_detail_header_policy: 'owner_only' (default) → emit only to owner 'all' → emit unconditionally (v0.1.1 opt-back-in) 'none' → suppress unconditionally - olpIdentity null on pre-auth paths → emit (preserves D40 v0.1.1 behaviour for pre-auth errors where identity is unknown). - withFallbackDetailHeader signature gains 3rd `olpIdentity` arg; both call sites in handleChatCompletions updated. Test surface — Suite 21, +9 tests; +1 in Suite 20 (20m); 515 → 524: 20m: /health with no auth + allow_anonymous=false → 401 (consistency with /v1/*) 21a-d: /health payload trimming (criterion #4): anonymous trimmed; guest trimmed; owner full; owner_only_endpoints: [] opts out 21e-h: X-OLP-Fallback-Detail emission gating (criterion #5): owner_only + guest → header absent owner_only + owner → header present + valid JSON 'all' + guest → header present (v0.1.1 opt-back) 'none' + owner → header absent (full suppression) Tests use 2-hop chain anthropic→openai with anthropic primary failing to produce non-empty fallbackDetail for header content. Test-mode setup updated: Global __setAuthConfig({ allow_anonymous: true }) extended to also pass owner_only_endpoints: [] + fallback_detail_header_policy: 'all' so pre-D46 tests (Suite 18, F5 /health tests, D40 fallback-detail tests, etc.) continue to pass; Suite 21 overrides per-case. DOCS: - AGENTS.md: lib/keys.mjs marker updated to reflect D46 ship; impl- status-note + shipped-set updated. - README.md: Implementation Status row + Known limitations "Multi-key auth" note rewritten to reflect D46 ship + remaining keygen CLI. - CHANGELOG.md: D46 entry under Unreleased per release_kit overlay. AUTHORITY: - ADR 0007 §§ 7.1 + 7.2 implementation contracts + § 10 criteria #4 + #5 covered. - ADR 0004 Amendment 5 (D40 — "Phase 2 will re-introduce owner-vs- non-owner gating when lib/keys.mjs lands"): this D-day fulfils the deferral. - CLAUDE.md release_kit overlay phase_rolling_mode — under Unreleased. - Standing autopilot grant (~/.cc-rules/memory/auto/ standing_autopilot_phase_2.md in cc-rules bf0ed9a). Verified: 524/524 pass via npm test (no regression in 515 pre-D46 tests; 9 new Suite 21 tests + 1 new Suite 20m test all green). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: D46 fold-in — opus reviewer P3 polish (constant import + comment tighten) Fresh-context opus reviewer (PR #22) returned APPROVE_WITH_MINOR with 2 P3 findings, both trivial polish. - server.mjs imports gain ENV_OWNER_KEY_ID from lib/keys.mjs (already used the namesake ANONYMOUS_KEY_ID import). handleHealth touchLastUsed guard now uses the imported constant for SPOT discipline. - handleHealth audit-deferral comment tightened: removed the "§ 8 schema doesn't mandate auditing" phrasing (overstates the ADR — § 8 doesn't enumerate paths); replaced with the operational rationale (high-volume noise, no observability value until Phase 3 Dashboard). No behaviour change. 524/524 tests pass (verified locally). Authority: PR #22 fresh-context opus reviewer findings. 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:
@@ -37,7 +37,7 @@ Runtime: Node.js (ESM, `.mjs` throughout). No build step. No bundler. `server.mj
|
||||
- `lib/ir/` — Intermediate Representation definition + serializers. Governed by ADR 0003.
|
||||
- `lib/cache/` — content-addressed cache layer (per-key isolation, `cache_control` bypass, chunked stream replay, singleflight). Governed by ADR 0005.
|
||||
- `lib/fallback/` — fallback engine (trigger detection, chain advancement, idempotent-failure safety, header annotation). Governed by ADR 0004.
|
||||
- `lib/keys.mjs` — multi-key auth, per-key namespacing, identity layer. Carries OCP's per-key isolation model into OLP. **🟡 Phase 2 — D44 core + D45 server integration shipped (validateKey is invoked on every /v1/* request; chain filtered by providers_enabled; touchLastUsed fires post-response). Remaining: D46 owner-vs-guest /health + X-OLP-Fallback-Detail gating; keygen CLI bootstrap surface (D46+).**
|
||||
- `lib/keys.mjs` — multi-key auth, per-key namespacing, identity layer. Carries OCP's per-key isolation model into OLP. **🟡 Phase 2 — D44 core + D45 server integration + D46 owner gating shipped (validateKey on every /v1/* + /health; chain filtered by providers_enabled; touchLastUsed fires post-response; /health payload trimmed for non-owner; X-OLP-Fallback-Detail gated by fallback_detail_header_policy). Remaining: keygen CLI bootstrap surface; Phase 2 close → v0.2.0.**
|
||||
- `lib/audit.mjs` — append-only ndjson audit per ADR 0007 § 6.2 + § 8. **🟡 D45 — appendAuditEvent + getAuditDropCount shipped. Fires per /v1/chat/completions + /v1/models request including 401/403/5xx paths. Warn+1-retry on append failure; no memory buffer at Phase 2 (forward path).**
|
||||
- `dashboard.html` — owner-only multi-provider dashboard (quota panels, fallback rate, cache hit rate). **📋 Planned (Phase 6) — not yet authored.**
|
||||
- `models-registry.json` — single source of truth for `(provider, model) → metadata`. SPOT.
|
||||
@@ -46,7 +46,7 @@ Runtime: Node.js (ESM, `.mjs` throughout). No build step. No bundler. `server.mj
|
||||
- `.github/workflows/alignment.yml` — CI blacklist grep + per-provider citation soft check; fails the build on known-hallucinated tokens.
|
||||
- `CLAUDE.md` — Claude-Code-specific session instructions + `release_kit` overlay (Iron Rule 5.5).
|
||||
|
||||
**Implementation status note (as of 2026-05-25):** Files marked 📋 above are designed and documented but not yet on disk; files marked 🟡 are partially shipped (specific components landed; others scheduled). For the full status table see `README.md § "Implementation status"`. The shipped set as of D45 is: `server.mjs` (with Phase 2 auth middleware + audit wire), `lib/ir/`, `lib/providers/{anthropic,codex,mistral}.mjs`, `lib/cache/{keys,store}.mjs`, `lib/fallback/engine.mjs`, `lib/keys.mjs` (core + loadAuthConfigSync — D44 + D45), `lib/audit.mjs` (D45), `models-registry.json`, `test-features.mjs` (Suites 19 + 20). Phase 2 in progress: D46 owner gating for /health + X-OLP-Fallback-Detail; keygen CLI bootstrap surface; Phase 2 close → v0.2.0.
|
||||
**Implementation status note (as of 2026-05-25):** Files marked 📋 above are designed and documented but not yet on disk; files marked 🟡 are partially shipped (specific components landed; others scheduled). For the full status table see `README.md § "Implementation status"`. The shipped set as of D46 is: `server.mjs` (with Phase 2 auth middleware + audit wire + owner-vs-non-owner gating), `lib/ir/`, `lib/providers/{anthropic,codex,mistral}.mjs`, `lib/cache/{keys,store}.mjs`, `lib/fallback/engine.mjs`, `lib/keys.mjs` (core + loadAuthConfigSync — D44 + D45), `lib/audit.mjs` (D45), `models-registry.json`, `test-features.mjs` (Suites 19 + 20 + 21). Phase 2 in progress: keygen CLI bootstrap surface; Phase 2 close → v0.2.0 (maintainer-triggered).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user