@@ -10,6 +10,17 @@ The adapter is deployment-specific. It is not the canonical Rust worker
1010implementation; it exists so hosted webhook behavior can be reviewed,
1111reproduced, and changed through PRs instead of server-only edits.
1212
13+ Long-running tasks execute outside the HTTP thread so GitHub deliveries are
14+ acknowledged promptly and health endpoints stay responsive. Queued or
15+ interrupted tasks are discovered again when the service starts. Native review
16+ deployments must subscribe the GitHub App to both ` pull_request ` and ` push ` , and
17+ must enable ` pull_request.synchronize ` , ` pull_request.edited ` ,
18+ ` pull_request.reopened ` , and the actionless ` push ` trigger. These deliveries
19+ reconcile stale decisive reviews after head changes, base retargeting, reopening,
20+ or new commits on a PR's base branch. A ` publication.mode=comment ` route that
21+ lacks any of these safety triggers fails closed instead of publishing native PR
22+ reviews.
23+
1324## Files
1425
1526- ` src/adapter.ts ` - webhook handler, task router, task runner, PR evidence
@@ -32,17 +43,60 @@ The deployment expects secrets and mutable state to be supplied outside git:
3243
3344- ` GITHUB_APP_ID `
3445- ` GITHUB_WEBHOOK_SECRET ` or ` WEBHOOK_SECRET `
46+ - ` COVEN_PUBLICATION_SIGNING_SECRET ` - optional dedicated HMAC key for review
47+ identity markers; defaults to the webhook secret for compatibility
48+ - ` COVEN_PUBLICATION_PREVIOUS_SIGNING_SECRETS ` - comma-separated prior marker
49+ keys retained only during rotation/reconciliation
3550- ` GITHUB_APP_PRIVATE_KEY_PATH ` or ` .coven-github-private-key.pem `
3651- ` COVEN_GITHUB_STATE_DIR `
3752- ` COVEN_GITHUB_POLICY_PATH `
38- - ` COVEN_CODE_BIN `
53+ - ` COVEN_RUNTIME_ISOLATION=bwrap ` - required for every non-demo task; unset is
54+ fail-closed and never falls back to direct execution
55+ - ` COVEN_RUNTIME_EXTERNAL_ISOLATION=network-egress-and-resource-limits-verified `
56+ - mandatory declaration that the deployment independently enforces egress,
57+ CPU, memory, PID, and disk/scratch limits
58+ - ` COVEN_GITHUB_REVOCATION_EVENTS=pull-request-and-push-verified ` - set only
59+ after verifying the installed App's live ` pull_request ` and ` push `
60+ subscriptions; native PR publication fails closed without it
61+ - ` COVEN_BWRAP_BIN ` - absolute host path to bubblewrap (defaults to
62+ ` /usr/bin/bwrap ` )
63+ - ` COVEN_RUNTIME_ROOTFS ` - dedicated credential-free runtime rootfs
64+ - ` COVEN_CODE_BIN ` - absolute coven-code path inside that rootfs
65+ - ` COVEN_RUNTIME_NETWORK=shared ` - explicit opt-in required when the Codex
66+ provider needs network access; the default is ` none `
3967- ` COVEN_REVIEW_FIX_LOOPS ` - optional bounded review-fix loop count, clamped
4068 between ` 0 ` and ` 5 ` ; defaults to ` 0 ` so hosted repair loops are opt-in
4169- Codex OAuth tokens under the deployed account's ` .coven-code ` directory
4270
4371Do not commit private keys, webhook secrets, OAuth tokens, generated task state,
4472workspaces, or attempt artifacts.
4573
74+ Real tasks never execute directly as the webhook account. Before minting a
75+ GitHub token, the adapter runs a bubblewrap probe and verifies read-only input,
76+ writable workspace/output mounts, a private PID namespace, no network for
77+ validation, and a dedicated rootfs that does not contain adapter state or
78+ credentials. A missing binary, rootfs, executable, or usable user namespace
79+ records the task as ` runtime_isolation_unavailable ` with no direct fallback.
80+ ` publication.mode=record_only ` is not an isolation control.
81+
82+ The runtime rootfs must contain the configured ` coven-code ` , ` git ` , and shell
83+ executables plus their libraries, CA/DNS files, and approved runtime assets. It
84+ must not contain the GitHub App key, webhook state, policy, parent home, or Codex
85+ token store. The runtime receives only its dedicated model credential; it never
86+ receives a GitHub token or Git askpass helper. Shared networking is not an
87+ egress-confidentiality boundary, so use a dedicated, revocable model credential
88+ and an externally enforced allowlist that blocks loopback, LAN, and metadata
89+ services. The adapter refuses real tasks unless the external network/resource
90+ isolation declaration is present.
91+
92+ The current runtime passes that model credential to ` coven-code ` ; an untrusted
93+ checkout can therefore try to consume or encode it through the model channel
94+ even when ordinary egress is filtered. Treat this release as trusted-repository
95+ only. Public/untrusted pull requests require a separately constrained worker and
96+ a quota-limited credential broker that never exposes a reusable model token to
97+ the repository process. Do not set the external-isolation declaration for that
98+ use case until those controls exist.
99+
46100## Local runtime
47101
48102Install dependencies, build TypeScript, and start the webhook service:
@@ -95,6 +149,16 @@ Deployments should provide `coven-github-policy.json` through
95149` COVEN_GITHUB_POLICY_PATH ` . That file is intentionally ignored because it is
96150environment-specific.
97151
152+ Every route with ` publication.mode=comment ` must include all native-review
153+ safety triggers: ` pull_request.synchronize ` , ` pull_request.edited ` ,
154+ ` pull_request.reopened ` , and ` push ` . The ` push ` key is actionless; do not write
155+ ` push. ` . Both the ` pull_request ` and ` push ` webhook events must also be enabled
156+ on the installed GitHub App. Missing policy coverage is a configuration error
157+ and native publication remains fail closed. After verifying the live App
158+ registration, set
159+ ` COVEN_GITHUB_REVOCATION_EVENTS=pull-request-and-push-verified ` ; this declaration
160+ is required in addition to the policy trigger list.
161+
98162Start from [ ` config/example-policy.json ` ] ( config/example-policy.json ) and the
99163connection guide in
100164[ ` docs/coven-github-connection.md ` ] ( docs/coven-github-connection.md ) .
@@ -114,8 +178,17 @@ connection guide in
114178 remain in the review body. Decisive reviews are bound to the captured commit
115179 and require full changed-file coverage, a clean matching checkout, and
116180 verified passing test evidence. They are created pending, then submitted only
117- after a fresh head check; a concurrent head change causes a COMMENT downgrade
118- or automatic dismissal.
181+ after fresh head and base checks; a concurrent revision change causes a
182+ COMMENT downgrade or automatic dismissal. Passing claims are decisive only
183+ when they match successful host-captured validation receipts. Validation and
184+ post-run Git checks execute in a second credential-free, network-disabled
185+ sandbox.
186+ - Uses repository-scoped installation tokens: parent Git gets only
187+ ` contents:read ` , PR evidence gets read authority, and publication write
188+ authority is minted only after isolated execution has finished.
189+ - Persists ` publication_pending ` before GitHub writes and resumes interrupted
190+ publication on startup or duplicate webhook delivery without rerunning the
191+ agent.
119192- Persists publication identities and review/comment IDs in the configured
120193 state directory, reconciles HMAC-signed App-authored identities with GitHub,
121194 and serializes publication per PR so retries and concurrent runs do not
0 commit comments