[Constitution] Alignment principle + CI guardrails (addresses b87992f drift) (#20)

* docs(constitution): establish OCP alignment constitution + CI guardrails (PR A)

Introduces the OCP project constitution to structurally prevent the kind
of scope drift that produced commit b87992f on 2026-04-11 (the fabricated
"/api/oauth/usage" endpoint, which does not appear in cli.js and broke
the dashboard usage bar for nine days).

This PR is governance-only. It does not modify server.mjs, package.json,
or any runtime code. It is intentionally shipped as one reviewable unit
per Iron Rule 11 (governance is one layer).

Files added:
  - ALIGNMENT.md
      Supreme scope document. Core principle: OCP is a proxy layer for
      Claude Code, not an extension layer. Five binding Rules: grep
      cli.js first; no invention; match the implementation; unalignable
      features are deleted; commits cite cli.js line numbers. Includes
      the 2026-04-11 drift postmortem, the Unalignable Policy, and an
      Annual Alignment Audit fixed to 11 April each year.

  - CLAUDE.md
      Project session instructions. Flags ALIGNMENT.md as required
      reading before any code. Codifies three hard requirements for
      server.mjs changes: cli.js citation, CI blacklist pass, and an
      independent reviewer per Iron Rule 10. References CC 开发铁律
      Rules 10, 11, and 12.

  - .github/PULL_REQUEST_TEMPLATE.md
      Mandatory "Claude Code Alignment Evidence" section. Three author
      checkboxes (cli.js citation, scope justification if cli.js does
      not perform the op, commit-message citations). Reviewer checklist
      requires opening cli.js at the cited lines before approval. A PR
      with this section blank receives request-changes.

  - .github/workflows/alignment.yml
      Hard-fail blacklist on server.mjs for tokens "api/oauth/usage"
      and "api/usage" (scan restricted to server.mjs; ALIGNMENT.md and
      CLAUDE.md may quote them as historical references). Soft check
      over all PR commit messages for "Claude Code uses X" / "cli.js
      uses X" assertions lacking a cli.js:NNNN or cli.js vE4 <fn>
      citation.

Historical reference: b87992f ("fix: use dedicated /api/oauth/usage
endpoint for reliable plan data") asserted the endpoint was used by
Claude Code CLI. The string does not occur in cli.js. Root cause was
LLM hallucination accepted without grep verification. See ALIGNMENT.md
-> Historical Lesson for the full record.

Merge precondition: this PR must be approved by an independent reviewer
(Iron Rule 10). The drafter of this commit may not self-approve.

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

* docs(alignment): pin first audit to 2026-04-20 (cli.js 2.1.89, SHA-256 a9950ef6)

First annual alignment audit pin. Records the cli.js version and content
hash that the current ALIGNMENT.md codified implementations mirror.

- Claude Code version: 2.1.89
- cli.js SHA-256: a9950ef6407fdc750bddb673852485500387e524a99d42385cb81e7d17128e01
- Audit date: 2026-04-20
- Auditor: Tao Deng

Next audit: 2027-04-11 (drift anniversary).

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

* ci(alignment): narrow blacklist to full host+path + strip comments before grep

Two false positives discovered during PR #20 bootstrap CI:
1. /api/usage is a legitimate OCP dashboard route (per-key quota, added
   in v3.8, server.mjs:1472). The bare token "api/usage" was too broad.
2. The ANCHOR warning comment in server.mjs (added by PR #21) references
   /api/oauth/usage as a DO-NOT-USE example, triggering the scanner.

Fix: require full host "api.anthropic.com/api/oauth/usage" to ensure
only real outbound fetch calls trip the guard, and strip line comments
with sed before grep so historical ANCHOR warnings pass.

Amendment procedure (ALIGNMENT.md) still governs future blacklist
changes.

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

---------

Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dtzp555-max
2026-04-20 13:15:34 +10:00
committed by GitHub
co-authored by Oracle Public Cloud User Claude Opus 4.6
parent fd7973addb
commit 2853088261
4 changed files with 312 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
name: Alignment Guardrail
on:
pull_request:
paths:
- 'server.mjs'
- '.github/workflows/alignment.yml'
jobs:
blacklist:
name: server.mjs blacklist (hard fail)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Scan server.mjs for hallucinated tokens
shell: bash
run: |
set -euo pipefail
if [ ! -f server.mjs ]; then
echo "server.mjs not found; nothing to scan."
exit 0
fi
# Known-hallucinated tokens. Extend only via an ALIGNMENT.md amendment PR.
# Each token is matched as a fixed string against server.mjs only.
BLACKLIST=(
"api.anthropic.com/api/oauth/usage"
)
FAIL=0
for token in "${BLACKLIST[@]}"; do
if sed "s|//.*\$||" server.mjs | grep -n -F "$token"; then
echo "::error file=server.mjs::Blacklisted token '$token' detected in server.mjs."
FAIL=1
fi
done
if [ "$FAIL" -ne 0 ]; then
cat <<'EOF'
============================================================
ALIGNMENT GUARDRAIL FAILURE
============================================================
server.mjs contains a token on the OCP alignment blacklist.
These tokens were introduced by LLM hallucinations and do
not appear in cli.js at any shipped Claude Code version.
See ALIGNMENT.md -> "Historical Lesson: The 2026-04-11 Drift"
(commit b87992f) for the full incident record.
Required action:
1. Remove the token from server.mjs.
2. grep the reference cli.js for the operation you
intended and cite the real line numbers.
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 scan clean."
commit-citation:
name: commit message citation (soft check)
runs-on: ubuntu-latest
# Soft check: reports a warning but does not block merge. Reviewers
# are expected to enforce per CLAUDE.md. Escalate to hard-fail via
# an ALIGNMENT.md amendment if drift recurs.
continue-on-error: true
steps:
- name: Checkout full history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Scan PR commits for uncited assertions
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
# Collect commit messages in range.
MSGS="$(git log --format=%B "${BASE_SHA}..${HEAD_SHA}")"
# Look for assertions of the form "Claude Code uses ..." or
# "cli.js uses ..." (case-insensitive). For each hit, require
# a citation in the same commit message in one of the forms:
# cli.js:NNNN (line-number citation)
# cli.js vE4 <name> (version + function-name citation)
# Absence of a citation is a soft finding.
WARN=0
# Split log into per-commit blocks for precise matching.
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 '(claude[[:space:]]+code|cli\.js)[[:space:]]+uses'; then
if echo "$BODY" | grep -E -q '(cli\.js:[0-9]+|cli\.js[[:space:]]+v[A-Za-z0-9]+[[:space:]]+[A-Za-z_][A-Za-z0-9_]*)'; then
echo "OK $sha: assertion cited."
else
echo "::warning::Commit $sha asserts 'Claude Code uses ...' or 'cli.js uses ...' but does not cite a cli.js line number or versioned function name. 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