|
| 1 | +# Reference demo: the operating loop, end to end |
| 2 | + |
| 3 | +This is the ClawSweeper-style reference demo of the coven-github operating |
| 4 | +loop (issue #19): the **real adapter binary**, driven by signed webhook |
| 5 | +deliveries, publishing to an in-memory GitHub API stub through a |
| 6 | +contract-conformant fake `coven-code` runtime. No network, no GitHub App |
| 7 | +registration, no credentials — one command, about a minute, self-verifying. |
| 8 | + |
| 9 | +```bash |
| 10 | +examples/demo/run-demo.sh |
| 11 | +``` |
| 12 | + |
| 13 | +A green exit code *is* the demo's claim: every property below is asserted |
| 14 | +programmatically against the stub's recorded state, not eyeballed. Set |
| 15 | +`KEEP=1` to keep the scratch directory (config, server log, stub log) for |
| 16 | +inspection. |
| 17 | + |
| 18 | +## Why "ClawSweeper-style" |
| 19 | + |
| 20 | +ClawSweeper is the reference pattern for conservative GitHub automation in the |
| 21 | +OpenClaw ecosystem (see [`DESIGN.md`](../DESIGN.md)): narrow promises, durable |
| 22 | +state, marker-backed comments edited in place, explicit maintainer commands, |
| 23 | +and deterministic gates before mutation. This demo shows coven-github honoring |
| 24 | +each of those disciplines with its own machinery. |
| 25 | + |
| 26 | +## What runs |
| 27 | + |
| 28 | +| Piece | Real or stand-in | Role | |
| 29 | +|---|---|---| |
| 30 | +| `coven-github serve` | **Real** — the same binary you self-host | Webhook receiver, command router, worker pool, publication | |
| 31 | +| Webhook deliveries | Real HMAC-SHA256 signatures, GitHub payload shapes | Drive every act | |
| 32 | +| GitHub API | [`github-stub.py`](../examples/demo/github-stub.py) — in-memory stand-in | Records every mutation in an audit trail | |
| 33 | +| `coven-code --headless` | [`fake-coven-code`](../examples/demo/fake-coven-code) — headless contract v2 conformant | Fabricates a familiar-voice fix instead of running a model | |
| 34 | +| App credentials | Throwaway RSA key + random webhook secret, generated per run | Prove the real JWT → installation-token path | |
| 35 | + |
| 36 | +The stub answers exactly the API surface the adapter uses — scoped token |
| 37 | +minting, repo metadata, branch resolution, collaborator permission, Check |
| 38 | +Runs, issue comments, pull requests — and exposes its world state at |
| 39 | +`/_demo/state` and the mutation log at `/_demo/audit`. |
| 40 | + |
| 41 | +## The acts |
| 42 | + |
| 43 | +**Act 1 — issue assigned: the full loop.** `octocat` assigns issue #42 to |
| 44 | +`@coven-cody`. The adapter mints an **orchestration** token, resolves the |
| 45 | +default branch and head SHA from live state, creates a Check Run against that |
| 46 | +immutable SHA, posts the one marker-backed status comment, flips the check to |
| 47 | +`in_progress`, mints a separate **agent-git** token injected only via |
| 48 | +`COVEN_GIT_TOKEN` (the fake runtime verifies the brief itself is tokenless), |
| 49 | +runs the session, then mints a **publication** token and opens a draft PR back |
| 50 | +to the issue — in Cody's voice. Asserted: one comment, edited in place to |
| 51 | +`Status: done`; Check Run concluded `success`; PR is a draft; three distinct |
| 52 | +token scopes minted. |
| 53 | + |
| 54 | +**Act 2 — casual mention.** "thanks @coven-cody, great work on this!" triggers |
| 55 | +*nothing*. Asserted: the audit trail did not grow by a single API call. |
| 56 | + |
| 57 | +**Act 3 — self-trigger loop guard.** The familiar's own comment containing |
| 58 | +`@coven-cody status` is ignored. Asserted: audit unchanged. |
| 59 | + |
| 60 | +**Act 4 — unknown verb.** `@coven-cody explain` is a command-position mention |
| 61 | +with an unknown verb, so the familiar replies with the real command list |
| 62 | +instead of guessing. Asserted: the clarification *edited the same status |
| 63 | +comment* — still exactly one surface. |
| 64 | + |
| 65 | +**Act 5 — steering: `status`.** Answered from the durable task store (the same |
| 66 | +state Cave polls), listing the issue's tasks and their lifecycle states. |
| 67 | + |
| 68 | +**Act 6 — permission gate.** `mallory` (read-only) comments |
| 69 | +`@coven-cody retry`. The worker checks collaborator permission *pre-flight* |
| 70 | +and declines on the status surface. Asserted: `Status: declined` and **no new |
| 71 | +Check Run** — no session was spent below the write-access bar. |
| 72 | + |
| 73 | +**Act 7 — steering: `retry`.** `octocat` (admin) retries. A second full run |
| 74 | +executes: second Check Run to `success`, second draft PR. Asserted: **still |
| 75 | +exactly one status comment** — repeated runs never stack duplicates. |
| 76 | + |
| 77 | +## The closing surfaces |
| 78 | + |
| 79 | +After the acts, the demo prints two oversight views: |
| 80 | + |
| 81 | +- **The audit trail** — every GitHub mutation in order, attributed to the |
| 82 | + token role that performed it. You can watch the authority split from |
| 83 | + issue #4 in action: `orchestration` drives checks and comments, |
| 84 | + `publication` opens the PR, `agent-git` never touches the API at all. |
| 85 | +- **The Cave view** — `GET /api/github/tasks`, the adapter's task API that |
| 86 | + the CovenCave dashboard (issue #18) polls: task ids, branches, PR links, |
| 87 | + Check Run links, session ids, lifecycle status. |
| 88 | + |
| 89 | +Cave *intervention* — pausing or steering a live session from the dashboard — |
| 90 | +lands with #18; today the oversight loop closes through the maintainer |
| 91 | +commands demonstrated above plus the session deep links on every Check Run |
| 92 | +and status comment. |
| 93 | + |
| 94 | +## Sample audit trail |
| 95 | + |
| 96 | +```text |
| 97 | + 1 app-jwt mint orchestration token (repo-scoped: demo-service) |
| 98 | + 2 orchestration read repo metadata OpenCoven/demo-service |
| 99 | + 3 orchestration resolve branch 'main' head SHA |
| 100 | + 4 orchestration create check run 1001 'Cody — Fix issue #42: …' (queued) |
| 101 | + 5 orchestration list #42 comments (0 found) |
| 102 | + 6 orchestration post comment 5001 on #42 |
| 103 | + 7 orchestration check run 1001 -> in_progress ('Running') |
| 104 | + 8 app-jwt mint agent-git token (repo-scoped: demo-service) |
| 105 | + 9 app-jwt mint publication token (repo-scoped: demo-service) |
| 106 | + 10 publication open draft PR #101 (cody/fix-issue-42 -> main) |
| 107 | + 11 orchestration list #42 comments (1 found) |
| 108 | + 12 orchestration edit comment 5001 in place (edit #1: 'Status: done') |
| 109 | + 13 orchestration check run 1001 -> success ('Done') |
| 110 | +``` |
| 111 | + |
| 112 | +## Requirements |
| 113 | + |
| 114 | +`cargo`, `python3` (stdlib only), `openssl`, `curl`. The script builds the |
| 115 | +adapter with `cargo build -p coven-github`, picks free ports, and cleans up |
| 116 | +after itself (scratch dir is kept on failure, or with `KEEP=1`). |
0 commit comments