Skip to content

Commit c92c1d9

Browse files
bb-connorclaude
andcommitted
Initial public commit
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 parents  commit c92c1d9

19 files changed

Lines changed: 1248 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
self-test:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 20
13+
steps:
14+
- name: Checkout chio-test-harness
15+
uses: actions/checkout@v4
16+
with:
17+
path: chio-test-harness
18+
19+
- name: Checkout arc (chio source)
20+
uses: actions/checkout@v4
21+
with:
22+
# Placeholder: replace owner/arc once the GitHub org is live.
23+
repository: owner/arc
24+
path: arc
25+
ref: main
26+
27+
- name: Setup chio
28+
uses: owner/chio-ci-actions/setup-chio@v0.1.0
29+
with:
30+
mode: build
31+
arc-path: arc
32+
33+
- name: Install hello-mcp deps
34+
working-directory: chio-test-harness/hello-mcp
35+
run: bun install --frozen-lockfile
36+
37+
- name: Start daemons
38+
working-directory: chio-test-harness
39+
run: bash bin/start.sh
40+
41+
- name: Verify READY (idempotent re-invoke)
42+
working-directory: chio-test-harness
43+
run: |
44+
out="$(bash bin/start.sh)"
45+
echo "${out}"
46+
grep -q READY <<<"${out}" || exit 1
47+
48+
- name: Probe env.sh
49+
working-directory: chio-test-harness
50+
run: |
51+
# shellcheck disable=SC1091
52+
source bin/env.sh
53+
: "${CHIO_TRUST_URL:?}"
54+
: "${CHIO_MCP_URL:?}"
55+
: "${CHIO_TOKEN:?}"
56+
: "${CHIO_POLICY:?}"
57+
echo "harness env OK: trust=${CHIO_TRUST_URL} mcp=${CHIO_MCP_URL}"
58+
59+
- name: Health check
60+
working-directory: chio-test-harness
61+
run: |
62+
curl -fsS "http://127.0.0.1:8940/health" >/dev/null
63+
echo "trust plane healthy"
64+
65+
- name: Stop daemons
66+
if: always()
67+
working-directory: chio-test-harness
68+
run: bash bin/stop.sh || true
69+
70+
- name: Upload var/ on failure
71+
if: failure()
72+
uses: actions/upload-artifact@v4
73+
with:
74+
name: harness-var
75+
path: chio-test-harness/var
76+
if-no-files-found: ignore

.github/workflows/release.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: release
2+
3+
# SLSA L3 + Sigstore provenance + reproducible build for @chio/test-harness.
4+
#
5+
# chio-test-harness ships the daemon-boot scripts + hello-mcp reference mcp.
6+
# The published npm tarball is built from a synthesised top-level package
7+
# that vendors `bin/`, `hello-mcp/` (without node_modules), `policy/`,
8+
# LICENSE and README.
9+
#
10+
# Secrets referenced:
11+
# NPM_TOKEN — npm publish auth (skip if using npm Trusted Publishers).
12+
#
13+
# Placeholders:
14+
# owner/chio-ci-actions — swap to your GH org before pushing.
15+
16+
on:
17+
push:
18+
tags:
19+
- "v*.*.*"
20+
workflow_dispatch:
21+
inputs:
22+
tag:
23+
required: false
24+
default: "v0.0.0-dev"
25+
dry-run:
26+
required: false
27+
default: "true"
28+
29+
permissions:
30+
contents: read
31+
id-token: write
32+
attestations: write
33+
34+
jobs:
35+
build:
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 20
38+
outputs:
39+
artifact-name: ${{ steps.hash.outputs.artifact-name }}
40+
hashes: ${{ steps.hash.outputs.hashes }}
41+
steps:
42+
- uses: actions/checkout@v4
43+
with:
44+
fetch-depth: 0
45+
46+
- name: Build + pack + publish
47+
id: publish
48+
uses: owner/chio-ci-actions/publish-chio@v0.1.0
49+
with:
50+
artifact-type: npm
51+
package-name: "@chio/test-harness"
52+
tag: ${{ github.event.inputs.tag || github.ref_name }}
53+
dry-run: ${{ github.event.inputs.dry-run || 'false' }}
54+
# No TypeScript build; harness is plain bash + a tiny MCP.
55+
build-command: "bash scripts/prep-release.sh"
56+
env:
57+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
58+
59+
- name: Compute subjects for SLSA generator
60+
id: hash
61+
run: |
62+
set -euo pipefail
63+
name="$(basename "${{ steps.publish.outputs.artifact-path }}")"
64+
sha="${{ steps.publish.outputs.artifact-sha256 }}"
65+
echo "hashes=$(printf '%s %s\n' "$sha" "$name" | base64 -w0)" >> "$GITHUB_OUTPUT"
66+
echo "artifact-name=$name" >> "$GITHUB_OUTPUT"
67+
68+
provenance:
69+
needs: [build]
70+
permissions:
71+
id-token: write
72+
contents: read
73+
actions: read
74+
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
75+
with:
76+
base64-subjects: ${{ needs.build.outputs.hashes }}
77+
upload-assets: true
78+
provenance-name: "${{ needs.build.outputs.artifact-name }}.intoto.jsonl"

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var/
2+
node_modules/
3+
*.log

COMMITS.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# COMMITS.md — chio-test-harness
2+
3+
Reusable live-daemon fixture. Consumed by `@chio/bridge` live tests and
4+
by every plugin's smoke script (ST.2.x). No mocks — boots real
5+
`chio trust serve` + `chio mcp serve-http` subprocesses. Target first
6+
ship tag: `v0.1.0`.
7+
8+
---
9+
10+
## 1. chore: scaffold harness with bin scripts and gitignore
11+
12+
**Body.** Initial scaffold — `LICENSE`, `.gitignore` (excludes `var/`
13+
runtime state), the `bin/` skeleton. No package.json — harness is
14+
bash-first so smoke tests in any language can source it. Wave 1.
15+
16+
**Files.**
17+
18+
- `LICENSE`
19+
- `.gitignore`
20+
- `bin/` directory layout (empty placeholders committed as part of the
21+
next commit; included here only as the directory reservation).
22+
23+
---
24+
25+
## 2. feat: add start, stop, wait-ready, env scripts backed by real chio
26+
27+
**Body.** `bin/start.sh` idempotently boots `chio trust serve`
28+
(127.0.0.1:8940) + `chio mcp serve-http` (127.0.0.1:8931), waits for
29+
`/health` to go 200 on both. `bin/stop.sh` kills both by pid-file,
30+
retains logs in `var/`. `bin/wait-ready.sh` polls until both services
31+
respond. `bin/env.sh` exports the `CHIO_*` env vars every downstream
32+
smoke script reads. Wave 1.
33+
34+
**Files.**
35+
36+
- `bin/start.sh`
37+
- `bin/stop.sh`
38+
- `bin/wait-ready.sh`
39+
- `bin/env.sh`
40+
41+
---
42+
43+
## 3. feat: add canonical policy fixtures and hello-mcp subprocess
44+
45+
**Body.** Three HushSpec 0.1.0 policies (`canonical.yaml`,
46+
`tiny-budget.yaml`, `extensions.yaml`) covering the happy path, a
47+
velocity-capped variant, and the `extensions.chio.*` passthrough
48+
path. `hello-mcp/server.mjs` is a stdio MCP server exposing `echo`,
49+
`delete_file`, and `paid_action` — the minimum toolset needed to
50+
exercise allow / deny-by-forbidden-path / deny-by-budget. MCP SDK
51+
pinned to `0.6.0` to work around the `capabilities.sampling.tools`
52+
forward-compat bug on `0.7.x`. Wave 1.
53+
54+
**Files.**
55+
56+
- `policy/canonical.yaml`
57+
- `policy/tiny-budget.yaml`
58+
- `policy/extensions.yaml`
59+
- `hello-mcp/server.mjs`
60+
- `hello-mcp/package.json`
61+
- `hello-mcp/bun.lock`
62+
63+
---
64+
65+
## 4. feat: prefer chio over legacy arc binary during harness bootstrap
66+
67+
**Body.** Harness resolves the runtime binary in this order:
68+
explicit `CHIO_BIN`, sibling `chio` next to `CHIO_ARC_BIN`,
69+
`../arc/target/release/chio` fallback, then `chio` on `PATH`.
70+
Mirrors the ladder `@chio/bridge` uses, so harness + bridge never
71+
diverge on which runtime they boot. Wave 5.0.1.
72+
73+
**Files.**
74+
75+
- `bin/env.sh``CHIO_BIN` resolution block.
76+
- `bin/start.sh` — uses `$CHIO_BIN` to launch trust + edge.
77+
78+
---
79+
80+
## 5. ci: smoke-test the harness against a real chio build
81+
82+
**Body.** GitHub Actions workflow: check out arc, run
83+
`setup-chio@v0.1.0`, start the harness, hit `/health` on both
84+
endpoints, run a minimal `chio check` allow/deny round-trip, tear
85+
down. Typecheck is non-blocking per Wave 5.1. Wave 5.1.
86+
87+
**Files.**
88+
89+
- `.github/workflows/ci.yml`
90+
91+
---
92+
93+
## 6. ci: add SLSA L3 release workflow for harness tarball
94+
95+
**Body.** Tag-triggered workflow that packages `bin/`, `policy/`,
96+
and `hello-mcp/package.json` as a GitHub Release asset, signs it
97+
with Sigstore keyless, and attaches a generic SLSA L3 provenance
98+
statement. Harness isn't on npm — it's consumed via
99+
`actions/checkout` from downstream CI. Wave 5.5.
100+
101+
**Files.**
102+
103+
- `.github/workflows/release.yml`
104+
- `scripts/verify-release.sh` — verifies the release asset sha256
105+
matches the attestation subject.
106+
107+
---
108+
109+
## 7. docs: README with usage, caveats, and smoke assertions
110+
111+
**Body.** Documents the prereqs, the six smoke assertions every
112+
ST.2.x plugin must cover, the MCP SDK 0.6.0 pin rationale, and the
113+
two canonical-policy caveats (`human_in_loop.approve_above` and
114+
`rules.velocity.max_spend_per_window` — both require grant shapes
115+
`chio check`'s synthetic grant doesn't provide). Wave 5.2.
116+
117+
**Files.**
118+
119+
- `README.md`

LICENSE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Apache License
2+
Version 2.0, January 2004
3+
http://www.apache.org/licenses/
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.

0 commit comments

Comments
 (0)