Commit Graph
7 Commits
Author SHA1 Message Date
9e25160527 refactor: hoist port literal to lib/constants.mjs + CI gate (v3.16.4) (#98)
Closes the structural side of the port-drift cascade addressed by
v3.16.2/v3.16.3. Those releases reverted the literal line-by-line; this
one removes the invitation to drift.

Changes:
  * NEW lib/constants.mjs — exports DEFAULT_PORT=3456, LOCAL_HOST,
    OPENAI_API_BASE, LOCAL_PROXY_URL.
  * server.mjs / setup.mjs / scripts/upgrade.mjs / scripts/doctor.mjs
    (x2) / scripts/sync-openclaw.mjs all import DEFAULT_PORT from
    lib/constants.mjs instead of hardcoding "3456".
  * .github/workflows/alignment.yml:
    - path filter extended to setup.mjs, scripts/**, lib/**,
      ocp, ocp-connect.
    - NEW job port-spot hard-fails any PR that introduces a hardcoded
      "3478" or "3456" literal outside EXEMPT_REGEX (lib/constants.mjs,
      test-features.mjs, ocp/ocp-connect bash CLIs, docs, the workflow
      itself).
  * Doc-comment rewording so CI grep finds zero hits.

No behavior change for any user. CLAUDE_PROXY_PORT env var still wins
at runtime; only the unset-env fallback now flows through one constant.

ALIGNMENT.md note: server.mjs change is one import + one literal swap,
mechanical. No cli.js operation changed; the citation requirement does
not apply.

cli.js: not applicable — mechanical refactor, no behavior change.

Co-authored-by: dtzp555 <dtzp555@gmail.com>
2026-05-13 06:42:15 +10:00
342a0a44f5 docs(funding): add Buy Me a Coffee link + GitHub FUNDING.yml (#68)
- .github/FUNDING.yml — enables GitHub's native "Sponsor" button on the
  repo page, pointing to buymeacoffee.com/dtzp555. Other platforms
  (GitHub Sponsors, Ko-fi) are commented out and can be enabled later
  by uncommenting + filling in handles.
- README.md § Support OCP — new section just before License. States the
  free-and-open-source commitment, lists the kinds of work that don't
  show up in commits (multi-machine debugging, IDE validation, drift
  incidents, concurrency leaks), and offers a single  link for users
  who want to support continued maintenance. Explicitly disclaims paid
  tiers / premium features so the open-source posture stays unambiguous.

server.mjs is not modified; this commit is doc-only and therefore exempt
from the cli.js citation requirement (ALIGNMENT.md Rule 5 applies only
to commits that touch server.mjs).

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 03:29:27 +10:00
c998d21a4f chore(ci): add gitleaks workflow to scan PRs and pushes to main (#64)
The repo has shipped `.gitleaks.toml` (with project-specific allowlist
entries — public OAuth client ID, README placeholders, an old plan doc)
since the privacy remediation work, but no GitHub Action invoked it.
The config was orphan: real protection only when someone ran gitleaks
locally, never gating merges.

This workflow wires `.gitleaks.toml` into CI:

- Triggers on every `pull_request` (any branch) and `push` to `main`.
- Uses `gitleaks/gitleaks-action@v2`, which auto-detects the repo-root
  `.gitleaks.toml` and applies its allowlist.
- Hard-fails on any leak. No `continue-on-error`. Public repo policy.
- `permissions: contents: read` — minimum required scope.
- `fetch-depth: 0` so the action can scan full history (the action's
  default behavior; explicit here for clarity).

Verification path:
- The workflow runs on this PR itself; if any secret were ever committed
  to the repo, the scan fails here. Prior audit confirmed the tracked
  tree is clean of real secrets, so this PR's own scan should pass.

Refs: audit side-finding 4 of 4.

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 09:54:36 +10:00
0752f666fb test: wire test-features.mjs to npm test + add minimal CI smoke workflow (#60)
`test-features.mjs` shipped at v3.8.0 (per CHANGELOG of the keys.mjs
quota+cache work) and is referenced from AGENTS.md as the project's only
test artifact, but until now nothing actually ran it — no `npm test`
script, no CI step. Wiring it up so it runs on every push and PR.

### Changes

- `package.json`: add `"test": "node test-features.mjs"` to scripts.
- `.github/workflows/test.yml` (new): single-job workflow that runs
  `npm test` on push to main and on every PR. Uses Node 24 because
  `keys.mjs` imports `node:sqlite`, which is stable in Node 23+ (Node
  24 is the current LTS; Node 22 would need `--experimental-sqlite`).
  No `npm install` step — OCP has zero external runtime dependencies
  per `package-lock.json`.
- `AGENTS.md`: note that `test-features.mjs` runs via `npm test` and
  is enforced by `.github/workflows/test.yml`.

### Why this is a hard check, not a soft check

`test-features.mjs` is self-contained — it imports `keys.mjs` and
exercises the SQLite-backed key/quota/cache code paths against a
throwaway test DB at `~/.ocp/ocp-test.db`. It does NOT require:

- a live claude CLI binary
- a running OCP server
- any network access

So CI can run it as a real check; no `continue-on-error` needed.

### Local verification

```
$ npm test
[...]
=== Results: 24 passed, 0 failed ===
```

24 assertions cover createKey / listKeys / quota math / cache hash
determinism / cache TTL / clearCache. Exit code is 1 on any failure
(`process.exit(failed > 0 ? 1 : 0)` at the bottom of test-features.mjs).

### Future expansion

If the suite later grows to include tests that DO require a live claude
CLI or a running OCP, mark those steps `continue-on-error: true` (or
split them into a separate job). The comment in `test.yml` documents
this contract.

Refs: audit (test-features.mjs orphan / unrunnable in CI).

Co-authored-by: dtzp555 <dtzp555@gmail.com>
2026-05-05 09:44:25 +10:00
cff06439fa chore(privacy): remediation follow-up from ocp#44 (#45)
Three-part follow-up from the 2026-04-22 privacy postmortem:

1. OAUTH_CLIENT_ID verified as public Claude Code constant (not a secret).
   Added gitleaks allowlist entry. The value 9d1c250a-e61b-44d9-88ed-5944d1962f5e
   is the public PKCE client ID used by the Claude Code CLI — public clients in
   PKCE flows have no client secret, so the ID itself carries no secret value.
   Introduced in commit b87992f (the 2026-04-11 drift incident); the constant
   mirrors what cli.js embeds for its OAuth token-refresh flow.

2. README.md API key example made clearly fake (ocp_example12345abcde...) to
   avoid gitleaks false-positives and clarify to readers it is not real.
   The ocp_ prefix IS the real prefix (keys.mjs line 80: randomBytes(24).base64url),
   so the prior example could be mistaken for a real truncated key.

3. PR template: added Privacy self-check section for PUBLIC repos below the
   existing 5.3 user-visible change self-check section.

4. .gitleaks.toml: new file with allowlist for the three confirmed non-issues
   (OAUTH_CLIENT_ID constant, README placeholder regex, old plan doc path).

No code or behavior change beyond the docs, README, and new config file.

Closes part of ocp#44.

Co-authored-by: Tao Deng <dtzp555@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 11:40:50 +10:00
497ff1dcd2 chore(governance): add release-kit overlay + PR self-check + auto-release workflow (#35)
Implements cc-rules v1.4's 第五律 5.5 project overlay requirement.

- CLAUDE.md: declare release_kit: YAML block (version_source,
  changelog, release_channel, docs_source, resource_lists,
  new_feature_doc_expectations, bootstrap_quirk_policy)
- .github/PULL_REQUEST_TEMPLATE.md: add 5.3 user-visible-change
  self-check section with reviewer gate instruction
- .github/workflows/release.yml (NEW): auto-create GitHub Release
  from CHANGELOG.md section on v* tag push. Idempotent (checks if
  release already exists). Closes the gap that caused v3.9.0 /
  v3.10.0 / v3.11.0 to each miss their GH Release.

Governance-only change. No code, no user-visible behavior change
(the workflow only fires on future tags). No README update needed.

Co-authored-by: Tao Deng <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 05:16:38 +10:00
2853088261 [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>
2026-04-20 13:15:34 +10:00