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>
This commit is contained in:
2026-05-23 15:46:56 +10:00
co-authored by Claude Opus 4.7
commit 0041fb1017
19 changed files with 1776 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
name: Alignment Guardrail
on:
pull_request:
paths:
- 'server.mjs'
- 'setup.mjs'
- 'lib/**'
- 'scripts/**'
- 'models-registry.json'
- '.github/workflows/alignment.yml'
push:
branches: [main]
paths:
- 'server.mjs'
- 'setup.mjs'
- 'lib/**'
- 'scripts/**'
- 'models-registry.json'
- '.github/workflows/alignment.yml'
jobs:
blacklist:
name: source blacklist (hard fail)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Scan source for hallucinated tokens
shell: bash
run: |
set -euo pipefail
# Known-hallucinated tokens. Extend only via an ALIGNMENT.md amendment PR.
# Each token is matched as a fixed string against the OLP source tree
# (excluding docs/, CHANGELOG, README, this workflow, and tests that
# may legitimately reference the historical token as a guardrail).
#
# Inherited transitively from OCP's 2026-04-11 drift:
# - api.anthropic.com/api/oauth/usage : fabricated Anthropic OAuth
# usage endpoint. Does not appear in any shipped @anthropic-ai/
# claude-code cli.js. Carried forward as a transitive guardrail.
#
# OLP-native entries: added as drift incidents accumulate.
BLACKLIST=(
"api.anthropic.com/api/oauth/usage"
)
# Provider keys that may appear in source (positive list — present in
# ALIGNMENT.md provider inventory). Any provider key in source that
# is NOT in this list is suspicious and flagged below.
KNOWN_PROVIDERS=(
"anthropic"
"openai"
"mistral"
"grok"
"kimi"
"minimax"
"glm"
"qwen"
)
# Source files in scope. Exclude docs, CHANGELOG, README, the
# workflow itself, and the test file (which may pin historical
# strings intentionally).
SOURCE_FILES="$(git ls-files \
| grep -E '\.(mjs|js|ts|json)$' \
| grep -v -E '^(docs/|CHANGELOG\.md|README\.md|test-features\.mjs|\.github/workflows/alignment\.yml)')"
FAIL=0
# 1. Blacklist scan
for token in "${BLACKLIST[@]}"; do
if echo "$SOURCE_FILES" | xargs grep -n -F "$token" 2>/dev/null; then
echo "::error::Blacklisted token '$token' detected in OLP source."
FAIL=1
fi
done
# 2. Excluded-provider scan: Google Antigravity is permanently
# excluded per ADR 0006 / ALIGNMENT.md Risk Tier A. Any reference
# to a `google-antigravity` plugin file or provider key in source
# (outside docs which may discuss the exclusion) is a finding.
FORBIDDEN_PROVIDER_TOKENS=(
"google-antigravity"
"antigravity"
)
for token in "${FORBIDDEN_PROVIDER_TOKENS[@]}"; do
HITS="$(echo "$SOURCE_FILES" | xargs grep -n -F "$token" 2>/dev/null || true)"
if [ -n "$HITS" ]; then
echo "::error::Tier-A-excluded provider token '$token' detected in OLP source. Per ALIGNMENT.md / ADR 0006, this provider is permanently excluded."
echo "$HITS"
FAIL=1
fi
done
if [ "$FAIL" -ne 0 ]; then
cat <<'EOF'
============================================================
ALIGNMENT GUARDRAIL FAILURE
============================================================
OLP source contains a token on the alignment blacklist or
references a permanently excluded provider.
Blacklist tokens were introduced by LLM hallucinations and
do not appear in the relevant authority (provider CLI,
OpenAI spec, or ADR). See ALIGNMENT.md and (where the
token is inherited from OCP) the OCP 2026-04-11 drift
record at https://github.com/dtzp555-max/ocp.
Excluded providers are listed in ALIGNMENT.md § Risk Tier
Framework and ADR 0006. Permanent exclusion means not
bundled, not pluggable, not added via opt-in.
Required action:
1. Remove the token from source.
2. Cite the real authority (provider CLI doc / OpenAI
spec section / ADR) for the operation you intended.
3. See ALIGNMENT.md Rules 1, 2, and 5.
Do not add allowlist entries to this workflow without an
amendment PR to ALIGNMENT.md (see Amendment Procedure).
============================================================
EOF
exit 1
fi
echo "Blacklist + excluded-provider scan clean."
models-registry:
name: models-registry.json sanity (hard fail)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Validate models-registry.json
shell: bash
run: |
set -euo pipefail
if [ ! -f models-registry.json ]; then
echo "models-registry.json not found yet (bootstrap phase). Skipping."
exit 0
fi
# Basic JSON validity.
if ! node -e "JSON.parse(require('fs').readFileSync('models-registry.json','utf8'))"; then
echo "::error::models-registry.json is not valid JSON."
exit 1
fi
# Provider keys in models-registry.json must match the inventory
# in ALIGNMENT.md.
KNOWN_PROVIDERS='["anthropic","openai","mistral","grok","kimi","minimax","glm","qwen"]'
node -e "
const fs = require('fs');
const known = ${KNOWN_PROVIDERS};
const reg = JSON.parse(fs.readFileSync('models-registry.json','utf8'));
const providers = reg.providers || {};
const bad = Object.keys(providers).filter(p => !known.includes(p));
if (bad.length > 0) {
console.error('::error::Unknown provider key(s) in models-registry.json: ' + bad.join(', '));
console.error('Known providers per ALIGNMENT.md: ' + known.join(', '));
process.exit(1);
}
console.log('models-registry.json provider keys OK: ' + Object.keys(providers).join(', '));
"
commit-citation:
name: per-provider commit citation (soft check)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout full history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Scan PR commits for uncited assertions
if: github.event_name == 'pull_request'
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
if [ -z "${BASE_SHA:-}" ] || [ -z "${HEAD_SHA:-}" ]; then
echo "No PR context; skipping."
exit 0
fi
WARN=0
git log --format="%H" "${BASE_SHA}..${HEAD_SHA}" | while read -r sha; do
BODY="$(git log -1 --format=%B "$sha")"
if echo "$BODY" | grep -E -i -q '(provider|claude|codex|vibe|grok|kimi|minimax|glm|qwen|cli)[[:space:]]+(code[[:space:]]+)?uses'; then
if echo "$BODY" | grep -E -i -q '(cli[[:space:]]+v[0-9]+|https?://|ADR[[:space:]]+[0-9]{4})'; then
echo "OK $sha: assertion cited."
else
echo "::warning::Commit $sha asserts 'Provider X uses ...' or '<provider> CLI uses ...' but does not cite a CLI version, docs URL, or ADR number. See CLAUDE.md -> Commit message conventions."
WARN=1
fi
fi
done
if [ "$WARN" -ne 0 ]; then
echo "Soft check raised warnings. Reviewer: please enforce per CLAUDE.md."
else
echo "Commit citation soft check clean."
fi
+73
View File
@@ -0,0 +1,73 @@
name: Auto Release on Tag
on:
push:
tags:
- 'v*.*.*'
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from tag
id: ver
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Verify package.json version matches tag
shell: bash
run: |
set -euo pipefail
if [ ! -f package.json ]; then
echo "::warning::package.json not found; skipping version-match check."
exit 0
fi
PKG_VERSION="$(node -p "require('./package.json').version")"
TAG_VERSION="${{ steps.ver.outputs.version }}"
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
echo "::error::Tag v${TAG_VERSION} does not match package.json version ${PKG_VERSION}. Bump package.json before tagging (Iron Rule 5)."
exit 1
fi
echo "Tag v${TAG_VERSION} matches package.json version ${PKG_VERSION}."
- name: Extract CHANGELOG section
id: notes
shell: bash
run: |
set -euo pipefail
VERSION="${{ steps.ver.outputs.version }}"
if [ ! -f CHANGELOG.md ]; then
echo "No CHANGELOG.md found; using minimal release notes"
echo "Release v${VERSION}" > /tmp/release-notes.md
exit 0
fi
awk -v ver="v${VERSION}" '
$0 ~ "^## " ver { found=1; print; next }
found && /^## v/ { exit }
found { print }
' CHANGELOG.md > /tmp/release-notes.md
if [ ! -s /tmp/release-notes.md ]; then
echo "No matching section in CHANGELOG for v${VERSION}; using minimal notes"
echo "Release v${VERSION}" > /tmp/release-notes.md
fi
- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
VERSION="${{ steps.ver.outputs.version }}"
if gh release view "v${VERSION}" >/dev/null 2>&1; then
echo "Release v${VERSION} already exists - skipping"
exit 0
fi
gh release create "v${VERSION}" \
--title "v${VERSION}" \
--notes-file /tmp/release-notes.md \
--latest
+53
View File
@@ -0,0 +1,53 @@
name: Tests
on:
push:
branches: [main]
pull_request:
jobs:
test-features:
name: test-features.mjs (smoke)
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ['20', '24']
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Detect package-lock
id: detect_lock
shell: bash
run: |
if [ -f package-lock.json ]; then
DEPS="$(node -p "Object.keys(require('./package.json').dependencies || {}).length")"
if [ "$DEPS" -gt 0 ]; then
echo "needs_install=true" >> $GITHUB_OUTPUT
else
echo "needs_install=false" >> $GITHUB_OUTPUT
fi
else
echo "needs_install=false" >> $GITHUB_OUTPUT
fi
- name: npm install (if dependencies present)
if: steps.detect_lock.outputs.needs_install == 'true'
run: npm ci
- name: Run npm test
shell: bash
run: |
if [ ! -f test-features.mjs ] && ! node -e "process.exit(require('./package.json').scripts && require('./package.json').scripts.test ? 0 : 1)" 2>/dev/null; then
echo "::notice::No test-features.mjs or npm test script yet (bootstrap phase). Skipping."
exit 0
fi
npm test