`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>
Both `CLAUDE.md` (line 25) and `AGENTS.md` (line 46) previously claimed the
`alignment.yml` blacklist included two tokens — `api/oauth/usage` and
`api/usage`. The actual workflow has a single token in `BLACKLIST`:
`api.anthropic.com/api/oauth/usage`.
Doc-vs-CI drift. Fix is doc-side only — `alignment.yml` itself is unchanged
because adding a second blacklist token (`api/usage`) is a constitutional
change that requires an `ALIGNMENT.md` amendment PR per ALIGNMENT.md
Amendment Procedure.
If `api/usage` should be added to the blacklist, that's a separate PR with
ALIGNMENT.md amendment + reviewer sign-off.
Refs: audit findings (governance doc accuracy).
Co-authored-by: dtzp555 <dtzp555@gmail.com>
Integrates OCP with Tao's cross-device development system (Phase 1 L1).
- AGENTS.md: project-level tool-agnostic instructions (read by Cursor,
OpenCode, Copilot, etc. in addition to Claude Code). Inherits from
~/.cc-rules/AGENTS.md.
- CLAUDE.md: prepends @AGENTS.md + @~/.cc-rules/AGENTS.md imports.
- docs/adr/0002-alignment-constitution.md: captures why ALIGNMENT.md
exists (2026-04-11 drift response).
- docs/adr/0003-models-json-spot.md: captures v3.11.0 SPOT refactor.
- docs/adr/0004-openclaw-auto-sync.md: captures v3.11.0 auto-sync design.
ADRs numbered 0002-0004 because an untracked 0001-cross-device-system.md
already exists locally and was out of scope for this PR.
Governance/docs only. No code change. No version bump (not a release).
Co-authored-by: Tao Deng <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>