mirror of
https://github.com/dtzp555-max/olp.git
synced 2026-07-21 21:15:10 +00:00
0bdecd1235f8fec514ea201581bb6b051021bab3
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0bdecd1235 |
feat+test+docs: D68-D70 — bin/olp-connect + /health.anonymousKey + ADR 0011 (#43)
* feat+test+docs: D68+D69+D70 — bin/olp-connect + /health.anonymousKey + ADR 0011
Third substantive Phase 4 implementation. 3 D-days bundled per Iron Rule
11 IDR — olp-connect consumes /health.anonymousKey for zero-config
client setup, both governed by ADR 0011's trusted-LAN-only invariant.
## D68 — bin/olp-connect (zero-config client setup)
Ports OCP ocp-connect (721 lines) → OLP olp-connect (564 lines, pure bash).
Bash over Node (per ADR 0010 § Notes) because client machines may lack
recent Node; bash + curl + python3 = max portability.
CLI: `olp-connect <host-ip> [--port PORT] [--key API_KEY] [--no-system-env]
[--dry-run] [--help] [--version]`
Workflow:
1. Connectivity probe (curl /health, 5s timeout, distinguishes TCP
unreachable from auth-required)
2. Auth resolution: --key flag → /health.anonymousKey (D69) → interactive
prompt fallback
3. Smoke test (GET /v1/models with bearer)
4. IDE detection + per-IDE config:
- Claude Code: detect + warn (NOT supported as OLP client per ADR 0010)
- Cline: detect + print manual VSCode-settings snippet
- Continue.dev: detect (extension OR ~/.continue/config.yaml) + write
idempotent models: entry
- Cursor: detect + print snippet + WARNING (per prior-art known
base-URL fragility)
- Aider: detect + write OPENAI_API_BASE + OPENAI_API_KEY to rc files
- OpenClaw: detect + print "install /olp plugin (D71-D73 deliverable)"
5. System-level env: macOS launchctl setenv / Linux ~/.config/environment.d
(so VSCode/Cursor started via Dock inherit)
6. Summary + test command
Idempotent (bracketed `# OLP LAN (added by olp-connect)` ... `# /OLP LAN`
blocks in rc files). --dry-run exercises every state-change site without
modifying anything. Exit 0/1/2 conventions.
Installed via package.json bin so `npx olp-connect` works.
## D69 — /health.anonymousKey + auth.advertise_anonymous_key
server.mjs handleHealth emits OPTIONAL `anonymousKey: "olp_..."` field
when ALL THREE prerequisites hold:
1. config.json auth.advertise_anonymous_key === true
2. config.json auth.allow_anonymous === true (per ADR 0007 § 7)
3. At least one non-revoked key has plaintext_advertise field set
Default-off: field is ABSENT (not null) — preserves v0.3.x /health shape;
existing tests don't regress.
bin/olp-keys.mjs new flags: `keygen --anonymous --advertise` writes the
plaintext into the manifest's optional `plaintext_advertise` field AND
prints a WARNING about disk-storage + /health exposure + ADR 0011
pointer. Owner-tier --advertise rejected at BOTH CLI + lib layers.
Implementation note: reused existing guest tier (no new owner_tier:
'anonymous'); plaintext_advertise is a forward-compat optional manifest
field per ADR 0007 § 4 unknown-fields-allowed convention. Cleaner than
introducing a new tier.
anonymousKey appears in BOTH trimmed AND full /health payloads — the
trimmed payload's purpose is to be readable by anonymous clients so they
can self-bootstrap. Tested.
Startup warns on prereq failure (anonymous_key_advertised_but_denied /
anonymous_key_advertised_but_no_anonymous_key_exists) so the relaxed-
posture failure mode is observable. Graceful-degrade: server still
boots; handleHealth re-checks at request time and silently omits the
field when any prereq fails (defense-in-depth).
## D70 — ADR 0011 (anonymous-key deployment-context limits)
New ADR codifying the trusted-LAN-only invariant.
Trade-off documented: anonymous key advertised via /health = anyone who
can reach the server can read /health and use the key. Acceptable ONLY
when "anyone who can reach the server" ≈ "trusted family on the LAN".
Public-internet deployment = instant compromise.
Soft enforcement: server logs startup warn if BIND_ADDRESS resolves to
a public IP AND advertise_anonymous_key: true. No hard allowlist (TLS-
fronted private networks indistinguishable from public from server's
perspective).
Re-evaluation trigger: any time OLP gains "expose to public internet"
deployment mode (e.g., Cloudflare Tunnel guidance in README), revisit.
References ADR 0007 § 7 (identity classes), ADR 0010 § Phase 4 charter
D68-D70 line, OCP server.mjs:148/1454/1488/1555 (PROXY_ANONYMOUS_KEY
reference).
## Test count
658 → 672 (+14 D68-D70 tests across Suite 34: 5 keys.mjs unit + 6 /health
HTTP integration + 3 CLI integration).
## Scope discipline
NO /v1/messages entry surface (out of Phase 4 per ADR 0010).
NO olp-plugin/ Telegram plugin (D71-D73).
NO docs/integrations/*.md files (D71-D73).
NO CHANGELOG / package.json version bump (Phase 4 close handles versioning;
only package.json bin entry for olp-connect added).
NO new npm deps.
## Authority
- ADR 0010 § Phase 4 D-day plan D68-D70 line
- ADR 0011 (this commit — new ADR)
- ADR 0007 § 4 (manifest forward-compat unknown fields) + § 7 (identity
classes) + § 9 (keygen flow) — extended by D69 plaintext_advertise
- OCP ocp-connect /Users/taodeng/ocp/ocp-connect (port reference)
- OCP server.mjs:148, 1454, 1488, 1555 (PROXY_ANONYMOUS_KEY reference)
- 2026-05-26 brainstorm (Top 5 OCP inheritance candidates, item 3:
/health.anonymousKey + olp-connect zero-config UX)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: D68-D70 reviewer P1 + P2 fold-in — README impact note + listKeys redaction + schema_version note
Reviewer APPROVE WITH MINOR — 0 P0, 1 P1, 2 P2; all three folded in.
P1 — README impact note for new Phase 4 user-visible surfaces.
Per CLAUDE.md release_kit.new_feature_doc_expectations:
- new env / config knob → README § Environment Variables
- new endpoint or response field → README § API Endpoints
- new CLI surface → dedicated §
README now documents:
- /health.anonymousKey optional field (in API Endpoints table) with cross-
ref to ADR 0011 + the three-prereq gate
- streaming.heartbeat_interval_ms config (D61) + auth.advertise_anonymous_key
config (D69) under new "config.json keys introduced at Phase 4" subsection
- Operator CLI surfaces summary: olp / olp-connect / olp-keys keygen
--anonymous --advertise, with cross-refs to ADR 0010 + 0002 Amendment 7
P2-1 — lib/keys.mjs listKeys() now strips plaintext_advertise alongside
token_hash. Callers wanting the advertised plaintext for the /health
publication path MUST go through findAdvertisedKey() — the only sanctioned
read site. Defends against a future caller of listKeys() leaking the
plaintext into logs / HTTP responses / dashboards. Tests still pass
(no in-repo caller of listKeys depends on plaintext_advertise being
present).
P2-2 — ADR 0011 now documents the schema_version-stays-at-1 decision
explicitly. Additive optional fields don't require bump per ADR 0007 § 4,
but a future archaeologist asking "why didn't D69 bump schema_version?"
now has a one-line answer. Same paragraph documents the listKeys()
redaction policy in plain text alongside the manifest-field contract.
672/672 tests still pass.
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>
|
||
|
|
0048481764 |
feat+docs: D60 — Phase 4 charter (ADR 0010) + default OLP_PORT 3456 → 4567 (#40)
* feat+docs: D60 — Phase 4 charter (ADR 0010) + default OLP_PORT 3456 → 4567 Opens Phase 4 (Operator + Client UX) end-to-end. Per release_kit.phase_rolling_mode, the version bump fires at Phase 4 close (v0.4.0), not at this D-day; D60 only ships governance + the port default change. ## ADR 0010 — Phase 4 Charter Phase 4 scope = 5 D-day groups (~13 D-days total): - D60 (this commit): charter + default port - D61-D63: SSE heartbeat + recentErrors[20] ring + /status combined endpoint - D64-D67: olp Node-based CLI scaffold + olp doctor next_action framework - D68-D70: olp-connect zero-config IDE setup + /health.anonymousKey + ADR 0011 - D71-D73: olp-plugin/ OpenClaw gateway plugin + docs/integrations/*.md bundle Charter records the EXPLICIT DECISION to DEFER /v1/messages (Anthropic-shape entry surface) on the rationale: under ADR 0009 P0 failure it provides no billing benefit AND degrades worse on fallback than OpenAI-shape clients (because OpenAI tool schema is the cross-provider lingua franca; Anthropic- specific features cache_control / computer_use / text_editor / thinking blocks have no clean fallback mapping). Re-open trigger: (a) ADR 0009 P0 success AND (b) maintainer-named family CC user. README posture updated: Claude Code listed as NOT SUPPORTED as an OLP client; recommended alternative is "Cline + OLP" (same fallback chain available, better cross-provider compatibility). ## Default port 3456 → 4567 server.mjs:74 default value moves so OLP and OCP (which stays on 3456) can co-host on the same machine without OLP_PORT env override. Existing deployments wanting the pre-D60 default can set OLP_PORT=3456 in launchd plist / shell env. Verified port-change invariants: - All test-features.mjs suites use port: 0 (ephemeral) — 0 test-surface impact - Cache / fallback / provider plugins port-agnostic - Dashboard 30s poll + management endpoints use relative paths - 623/623 tests pass on D60 branch HEAD ## ADR amendments - ADR 0001 § "Decision" port-conflict paragraph: struck + amended (co-host is now possible via 3456 → 4567 + launchd labels dev.olp.proxy vs dev.ocp.proxy) - ADR 0008 § 6.6 default-port reference updated - docs/adr/README.md index gains ADR 0010 row ## Authority - ADR 0010 (this commit) - ADR 0009 (interactive-mode placeholder — /v1/messages defer rationale) - 2026-05-26 brainstorm: OCP comprehensive feature audit (subagent output) + multi-provider proxy / IDE integration prior-art survey (subagent output, both this session) - docs/v1x-roadmap.md (Phase 4 was the named destination) - CLAUDE.md release_kit.phase_rolling_mode (current_phase already Phase 4; this charter formalizes contents) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: D60 reviewer P2-1 — soften ADR 0001 launchd-label assertion to forward-tense Reviewer flagged the ADR 0001 amendment's launchd-label collision claim ("avoided via dev.olp.proxy vs dev.ocp.proxy") as present-tense fact when the OLP plist generator hasn't shipped yet (lands D64-D70 per ADR 0010). Soften to forward-tense with explicit cross-reference. The factual claim ("co-host is possible") still stands because plist label is controlled by the OLP project anyway; this is precision, not correction. P2-2 (README "since v0.4.0" forward-dated branding) explicitly accepted as prior-art-consistent with D44+ Phase 2 mid-window doc conventions — no change. 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> |
||
|
|
179b4707a7 |
docs: ADR 0009 — Anthropic Interactive-Mode Path Placeholder (blocked on OCP P0) (#33)
Records OLP-side decision for the cross-project work OCP started in
ADR 0007 (interactive-mode execution pool to address post-2026-06-15
Anthropic billing split).
OPTION 3 — wait + port:
- No OLP code change to lib/providers/anthropic.mjs until OCP
ADR 0007 P0 experiment outcome lands (>= 2026-07-15).
- Avoid duplicating the P0 risk by running an independent OLP
experiment against the same Anthropic billing pool.
- If P0 confirms Transport A (stdio NDJSON) or Transport B (PTY)
bills as subscription rather than Agent SDK credit, port the
validated pattern to OLP at that time.
- If both transports fail, shelve this ADR; OLP Anthropic users
fall back to Agent SDK $100 / month credit OR shift to multi-
provider routing (Codex / Mistral) per Phase 1 design.
DECISION TREE recorded in § 3 so a future Phase 4 brief can act
mechanically once OCP P0 lands:
Transport A wins → Option 1 (parallel impl) likely
Transport B wins → Option 1 with PTY adapter (node-pty native dep
triggers engines-bump prior PR)
Both fail → Shelve ADR 0009
Unobservable → Extend wait
IMPLEMENTATION LANES (§ 4) — informational, not selected:
Option 1 — OLP parallel implementation in lib/providers/anthropic.mjs
Option 2 — Chain OCP as backend (OLP → OCP → Claude)
Option 3 — Hybrid (prefer OCP backend, fallback to local pool)
NO PHASE 4 D-DAY scheduled. This is a decision-record placeholder
ONLY. Phase 4 standing-autopilot grant ("Phase 4+ requires new
authorization") still applies. When OCP P0 lands, maintainer issues
explicit Phase 4 "go" naming this ADR to trigger implementation
selection + D-day work.
DOCUMENTATION:
- docs/adr/0009-interactive-mode-path-placeholder.md (new, ~200 lines)
- docs/adr/README.md index: ADR 0009 row added
- Cross-machine cc-rules memory (~/.cc-rules/memory/learnings/
ocp_adr_0007_interactive_mode_pool.md, committed in cc-rules
a16b775) bridges OCP ADR 0007 + OLP ADR 0009 so future Phase 4
planning sessions in either repo pull the shared context.
Test count: 601 → 601 (docs-only; no test or .mjs file touched).
AUTHORITY:
- OCP ADR 0007 (~/ocp/docs/adr/0007-interactive-mode-pool.md,
Draft 2026-05-25) — the triggering external work.
- OLP ADR 0001 (Project Founding) — the 2026-06-15 billing-split
motivation that this ADR reaffirms.
- OLP ADR 0006 (Provider Inclusion) — the anthropic plugin's tier
that this ADR would amend if/when implemented.
- CLAUDE.md release_kit overlay phase_rolling_mode (current_phase:
Phase 4) — this ADR explicitly does NOT consume a Phase 4 D-day.
- Standing autopilot grant — Phase 4+ requires new authorization;
this placeholder is a decision-tree pre-record, not Phase 4
implementation.
ALIGNMENT.md scope check: docs-only commit (new ADR + index update).
No provider plugin / entry surface / IR change.
Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
c0b696984f |
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>
|
||
|
|
d253c2b98d |
docs: D43-B — ADR 0007 multi-key auth design draft (design-only) (#19)
* docs: D43-B — ADR 0007 multi-key auth design draft (design-only, no code change) Phase 2 mainline design ADR. Ratifies the storage / token / manifest / atomic-write / owner-gating / bootstrap / Node-baseline decisions ahead of D44+ implementation D-days. Pure design doc — no .mjs / no tests / 4 files touched. Test count 468 → 468. - docs/adr/0007-multi-key-auth.md (new, ~400 lines): 13 sections covering Context / Decision (Option 2 filesystem manifest + opaque token) / Storage layout / Manifest schema / Token format (olp_+32B base64url, SHA-256 hash) / Atomic write & audit append (manifest lifecycle-only atomic via tmpfile+fsync+rename; audit per-request append with warn+1-retry, no memory buffer at Phase 2) / Owner-vs- guest-vs-anonymous gating (config.json auth.allow_anonymous default false, no env auto-detection) / Audit ndjson schema (no PII) / Bootstrap & recovery (minimal keygen command surface + OLP_OWNER_TOKEN env override with stable __env_owner__ keyId) / Acceptance criteria (11 test surfaces) / Node baseline (Option 1 SQLite port rejection rationale citing engines >=18 + CI 20/24 vs node:sqlite v22.5.0/RC) / Out of scope (Dashboard, quota enforcement, audit query, file locking deferred to Phase 3+) / Future forward (Option 3 hybrid migration trigger + preconditions). - docs/adr/README.md index: added ADR 0007 row with one-paragraph summary covering storage choice + rejection rationale. - docs/v1x-roadmap.md #2: marked PHASE 2 ACTIVE (no longer deferred); "Design ADR (NOT YET RATIFIED)" → "Design ADR (ratified) → ADR 0007"; trigger updated to "already fired 2026-05-25"; code anchors pinned to exact line numbers (cache/store.mjs:77-79/:287, server .mjs:502/:531/:392/:1072/:1101). - CHANGELOG.md Unreleased: D43-B entry per release_kit overlay phase_rolling_mode discipline. Authority: - Phase 2 kickoff handoff (~/.cc-rules/memory/handoffs/2026-05-25-phase-2-kickoff.md, cc-rules d9da966) - OLP v0.1 spec § 4.5 (planning authority for ~/.olp/ layout) - OCP keys.mjs (prior-art for opaque-key + per-key isolation model) - Node node:sqlite docs (https://nodejs.org/api/sqlite.html — Option 1 rejection per ADR 0007 § 11) - CC 开发铁律 v1.6 § 10 — fresh-context opus reviewer required for design ADR per Iron Rule 10 ALIGNMENT.md scope check: this PR introduces a new ADR; per ALIGNMENT.md Rule 1 (Cite First), the ADR itself contains the authority citations its decisions rest on (v0.1 spec § 4.5, OCP keys.mjs, Node docs URL). No provider plugin / entry surface / IR change in this commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs: D43-B fold-in — ADR 0007 reviewer findings (2 P2 + 3 P3, all polish) Fresh-context opus reviewer (PR #19) returned APPROVE_WITH_MINOR with 2 P2 load-bearing-but-non-blocking findings + 3 P3 polish findings. All five are accepted as suggested; design contract clarified without semantic change. - § 6.2 step 1 (P2 #1) — pin audit serialization to fire AFTER status_code is determined and latency_ms is measured. Makes acceptance criterion #2 (anonymous-401 audit event records the 401 + latency) testable in the way the criterion was written. - § 6.3.5 (P2 #2, new subsection) — explicit "Token validation MUST hit the manifest on every authenticated request (no in-process validation cache at Phase 2)" rule. The acceptance criterion #6 (post-revoke 401 within the next request) was previously enforced only by the test; the rule now belongs to the design contract. Forward-path note documents when a Phase 3+ amendment may add a cache. - § 6.1 atomic-write step 5 follow-up (P3 #3) — document the deliberate omission of directory fsync after rename. Single-process family-scale deployment accepts the tiny rename-loss window under abrupt host crash; future POSIX-strict deployments know where to add the step. - § 9.4 (P3 #4) — declare token-collision between OLP_OWNER_TOKEN and a filesystem-stored key's plaintext as undefined behaviour. Operators MUST NOT reuse plaintext across both surfaces. Phase MAY add startup collision-detection later. - § 10 criterion #4 (P3 #5) — rephrased to assert against the config- driven owner_only_endpoints predicate rather than a hardcoded trimmed payload shape. The test stays stable if an operator removes /health from owner_only_endpoints. CHANGELOG D43-B entry: fold-in bullet added to summarize the 5 fixes. Test count: 468 → 468 (npm test verified locally after fold-in). Authority: PR #19 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> * docs: D43-B fold-in #2 — maintainer text-review findings (1 P1 + 1 P2 + 1 P3) Maintainer (codex) did final text review of PR #19 against the Phase 2 ADR-ratification checklist. Returned 3 findings; all accepted as suggested. Two are contract-level (P1 safety + P2 factual); one is trivial (P3 line-count drift). No semantic change beyond what the findings called out. P1 — § 6.3 / § 6.4 / § 10 #7 — revoke-dominates-touch safety contract Original § 6.3 said touchLastUsed used the same atomic-write pattern as 6.1; § 6.4 said concurrent CLI revoke + touchLastUsed left "both states valid" with "observability-grade" failure mode. Codex correctly identified the bug: a stale manifest snapshot held by the touch path could overwrite a fresh revoke and silently clear revoked_at back to null, breaking acceptance criterion #6 (post-revoke 401 within next request) under concurrent CLI revoke + in-flight server request. The ADR was promising security-grade behavior on a path that was actually last-write-wins. Fix: - § 6.3 rewritten with explicit read-modify-write discipline: touch MUST re-read latest manifest from disk inside the per-key write-lock, NO-OP if revoked_at is non-null, otherwise merge last_used_at preserving all other fields including revoked_at. - § 6.4 reframed from "both states valid" to "revoke dominates touch" safety frame, citing § 6.3 as the load-bearing discipline. The CLI revoke writer always wins the dimension that matters; touch may lose its last_used_at update if it raced. - § 10 criterion #7 expanded to test all three orderings (revoke -> touch, touch -> revoke, interleaved) with the explicit MUST: revoked_at is non-null and equals the revoke writer's timestamp after any interleaving; FAIL if any path produces revoked_at: null. - Forward-path § 6.4 file-locking note updated to clarify §6.3 already holds the contract single-process; flock adds defense-in- depth for rare multi-writer TOCTOU. P2 — § 11 forward path step (1) — Node baseline version history corrected Original wording "Node v22.5.0+ for unflagged but RC; Node TBD for stable" was wrong. v22.5.0 added with --experimental-sqlite flag; v22.12 still required the flag; the module moved past flag-gating in v22.13.0 (LTS) / v23.4.0 (current); entered Release Candidate at v25.7.0 per current docs. Fix: § 11 forward path step (1) rewritten with accurate versions + two Node release-history URLs cited (https://nodejs.org/download/ release/v22.12.0/docs/api/sqlite.html and https://nodejs.org/api/ sqlite.html). Minimum non-flag-gated baseline is now stated as >=22.13.0 (LTS) / >=23.4.0 (current); stable baseline TBD pending Node v25.x+. The rejection-evidence paragraph earlier in § 11 ("v22.12 still required --experimental-sqlite ... current docs mark RC") was already correct and is untouched. P3 — CHANGELOG D43-B line-count corrected Entry said ADR was "~270 lines"; actual file is 420 lines after both fold-ins. Changed to "~420 lines after fold-ins". Phase 2 fold-in #2 bullet enumerates the 3 fixes in this commit; fold-in #1 bullet retained for the opus reviewer round. Test count: 468 / 468 (npm test verified locally after fold-in; design-only doc changes, no test file touched). Authority: PR #19 maintainer text review findings 2026-05-25; CLAUDE.md release_kit overlay phase_rolling_mode — under Unreleased; Node SQLite docs URLs cited in ADR § 11 forward path. 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> |
||
|
|
dff428f3d0 |
docs(governance): fold in codex round-2 review findings (6 issues)
External Codex CLI review pass 2 surfaced 6 substantive issues that round 1 fold-in missed — the self-consistency trap recurred when fold-in was scoped only to files codex explicitly named in round 1. This commit closes round 2 in full. 1. ADR 0002 contradicted ALIGNMENT.md (P1, codex round 2 finding 1) ADR 0002 still said "three default-enabled (Anthropic, OpenAI Codex, Mistral Vibe)" while ALIGNMENT.md (post round 1) said v0.1 ships zero Enabled Providers. Accepted ADR contradicted constitution. Fix: ADR 0002 + ADR 0001 + docs/adr/README.md index rewritten to Candidate framing. 2. release.yml would publish stale v0.1.0-bootstrap notes (P1, round 2 finding 2) The "Unreleased" amendments would have been silently dropped on tag push because release.yml extracts only the matching version section. Fix: CHANGELOG restructured so the amended state IS the v0.1.0- bootstrap section. Full review history (opus + 2 codex rounds) captured inline. 3. package.json advertised non-existent entrypoints (P2, round 2 finding 3) main/scripts.test/scripts.start pointed to files that do not exist. Local npm test and npm start failed; CI masked. Fix: remove all three from package.json. They return in Phase 1 alongside the real files. test.yml bootstrap-tolerance updated to also skip when scripts.test is absent. 4. models-registry.json missing despite SPOT claim (P2, round 2 finding 4) Fix: minimal stub committed (version + empty providers map). alignment.yml validator now actually runs. 5. alignment.yml commit-citation soft check Bash subshell trap (P2, round 2 finding 5) git log ... while read ... WARN=1 — the while loop ran in a subshell because of the pipe, so WARN never propagated out. The post-loop check always reported "clean" even when warnings fired. Fix: process substitution done less than less than (git log ...). 6. Tier A "permanent" wording inconsistent across ADR 0006 + alignment. yml workflow text (P3, round 2 finding 6) Fix: unified to "Excluded by default with no routine reinstatement path; re-inclusion requires ADR 0006 supersession or amendment with new primary-source evidence." Reviewer: OpenAI Codex CLI (external, fresh-context, pass 2). Iron Rule 10 satisfied — round 2 reviewer was not the implementer of round 1 fold-in. Memory learning updated: the self-consistency trap recurs in the fold-in step. Future fold-ins must grep the entire repo for the concept, not only edit files the reviewer named. See learnings/ai_reviewer_self_ consistency_trap.md in cross-machine memory. Co-Authored-By: Claude Opus 4.7 (noreply@anthropic.com) |
||
|
|
0041fb1017 |
chore: bootstrap OLP v0.1 — multi-provider LLM proxy
Initial release. OLP (Open LLM Proxy) is a personal- and family-scale
multi-provider LLM proxy that supersedes OCP (Open Claude Proxy).
Trigger: Anthropic's 2026-05-14 announcement (effective 2026-06-15)
moves `claude -p` / Agent SDK / third-party agent traffic out of the
Pro/Max subscription pool into a separate fixed monthly Agent SDK
Credit pool. OCP's foundational assumption ("subscription = unlimited
within rate limits") breaks for Anthropic on that date. Spreading
risk across multiple providers is the structural response.
Phase 0 lands:
- ALIGNMENT.md (constitution: 5 Rules, 3 Authorities, 4-tier Risk
Framework, 8-provider inventory)
- AGENTS.md (multi-tool agent guidelines; inherits cc-rules)
- CLAUDE.md (Claude-Code session instructions + release_kit overlay)
- README.md (phase-aware skeleton)
- docs/adr/0001-0006 (Founding ADRs: project founding / plugin
architecture / IR design / fallback engine / cross-provider cache /
provider inclusion + risk-tier framework)
- .github/PULL_REQUEST_TEMPLATE.md (8-radio Change Type + per-type
Authority Evidence + Iron Rule 10 reviewer checklist)
- .github/workflows/alignment.yml (blacklist + Antigravity exclusion
enforcement + models-registry validator + commit-citation soft check)
- .github/workflows/release.yml (auto-release on tag with version
match check per Iron Rule 5)
- .github/workflows/test.yml (Node 20/24 matrix, bootstrap-tolerant)
- package.json, .gitignore, LICENSE (MIT), CHANGELOG.md
Provider inventory at bootstrap:
Tier D (default-enabled): anthropic, openai, mistral
Tier C (opt-in): grok, kimi
Tier B (opt-in + consent): minimax, glm, qwen
Tier A (permanently excluded): google-antigravity
Supersedes OCP ADR 0005 (No Multi-Provider) per OLP ADR 0001. OCP
will enter maintenance mode when OLP v0.1 ships per Phase 7 plan.
Iron Rule 10 gate: fresh-context independent opus reviewer audited
all 15 governance files against OLP v0.1 spec + OCP precedent.
Verdict: APPROVE_WITH_MINOR. Two minor findings folded in:
1. alignment.yml heredoc EOF moved to column 0 (was indented;
bash parse failed silently on real blacklist hits, printing
a cryptic "syntax error" instead of the structured ALIGNMENT
GUARDRAIL FAILURE banner).
2. AGENTS.md clarified that the SPOT discipline for
models-registry.json will be codified by a Phase-1 ADR (OLP
ADR 0003 is currently the IR design, not a SPOT codification;
OCP's ADR 0003 is the precedent but OLP's registry shape
differs and warrants its own ADR).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|