Skip to content

Commit fd61c10

Browse files
committed
feat(runtime): harden project file and capability boundaries
Make uploaded files visible and reusable through slash commands. Replace shared internal secrets with scoped service bindings and opaque run capabilities. Remove replay and audit-archive machinery, and derive preview configuration from deployment identity.
1 parent 9ea4b70 commit fd61c10

94 files changed

Lines changed: 1864 additions & 6093 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ CLERK_SECRET_KEY=sk_test_replace_me
1414
# Optional only when receiving Clerk webhooks in local development.
1515
CLERK_WEBHOOK_SIGNING_SECRET=
1616

17-
# Local web routing. The real preview-proxy Worker is service-bound behind the
17+
# Browser-visible local routing configuration; these values are not secrets.
18+
# The real preview-proxy Worker is service-bound behind the
1819
# gateway and serves each sandbox on *.localhost:8787. No second preview domain
1920
# or cloud development deployment is required.
2021
NEXT_PUBLIC_GATEWAY_URL=http://127.0.0.1:8787
21-
NEXT_PUBLIC_PREVIEW_HOSTNAME=localhost
22-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA=development
2322

2423
# Daytona development access.
2524
DAYTONA_API_KEY=
@@ -55,9 +54,4 @@ POLAR_PRODUCT_ID_MAX=
5554
DATABASE_CONTEXT_SIGNING_SECRET_AGENT=replace_with_a_distinct_32_byte_secret
5655
DATABASE_CONTEXT_SIGNING_SECRET_GATEWAY=replace_with_a_distinct_32_byte_secret
5756
DATABASE_CONTEXT_SIGNING_SECRET_WEBHOOKS=replace_with_a_distinct_32_byte_secret
58-
GATEWAY_TO_WEBHOOKS_RESOURCE_DELETION_SECRET=replace_with_a_distinct_32_byte_secret
59-
WEBHOOKS_TO_AGENT_LIFECYCLE_SECRET=replace_with_a_distinct_32_byte_secret
60-
INTERNAL_WEBHOOK_REPLAY_SECRET=replace_with_a_distinct_32_byte_secret
6157
OUTPUT_DOWNLOAD_SIGNING_SECRET=replace_with_a_distinct_32_byte_secret
62-
SKILL_RUNTIME_BASE_URL=https://gateway.trycheatcode.com/skill-runtime
63-
SKILL_RUNTIME_TOKEN_SECRET=replace_with_a_distinct_32_byte_secret

.github/workflows/audit-archive.yml

Lines changed: 0 additions & 177 deletions
This file was deleted.

.github/workflows/static-checks.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,7 @@ jobs:
226226
CLERK_SECRET_KEY: sk_test_static_checks_do_not_authenticate
227227
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: pk_test_c3RhdGljLWNoZWNrcy0wMC5jbGVyay5hY2NvdW50cy5kZXYk
228228
NEXT_PUBLIC_GATEWAY_URL: ${{ vars.NEXT_PUBLIC_GATEWAY_URL }}
229-
NEXT_PUBLIC_PREVIEW_HOSTNAME: trycheatcode.com
230-
NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: ${{ github.sha }}
231-
TURBO_TEAM: cheatcode
232-
TURBO_TOKEN: ${{ github.event_name == 'push' && secrets.TURBO_TOKEN || '' }}
229+
VERCEL_GIT_COMMIT_SHA: ${{ github.sha }}
233230
run: |
234231
set -Eeuo pipefail
235232
filters=()

AGENTS.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ packages/ Shared libraries
5151
5252
skills/ 8 curated Anthropic SKILL.md skills
5353
infra/ Wrangler configs, Supabase migrations, Daytona sandbox Dockerfile
54-
scripts/ Operational helpers only: build skills, local startup, deploy orchestration, migrations, audit archive
54+
scripts/ Operational helpers only: build skills, local startup, deploy orchestration, migrations
5555
```
5656

5757
## Build
@@ -82,7 +82,7 @@ part of the V2 command surface, and source-level `*.test.ts` files are
8282
intentionally absent. Do not generate temporary validation scripts either;
8383
operate the UI directly and check logs, and remove any throwaway product QA
8484
script that appears in the V2 tree. Operational scripts may exist only for
85-
build, migration, audit retention, and local-stack configuration; they are not
85+
build, migration, and local-stack configuration; they are not
8686
product tests and must not simulate UI/user flows. Do not create temporary
8787
testing scripts in `scripts/`, package folders, `/tmp`, or any out-of-tree
8888
location.
@@ -156,15 +156,10 @@ COMPOSIO_API_KEY=
156156
COMPOSIO_AUTH_CONFIGS={"github":"ac_...","gmail":"ac_...","slack":"ac_...","notion":"ac_...","linear":"ac_..."}
157157
COMPOSIO_WEBHOOK_SECRET=
158158
159-
# Internal ops alerts
160-
INTERNAL_ALERT_WEBHOOK_SECRET=
159+
# Signed output capability
160+
OUTPUT_DOWNLOAD_SIGNING_SECRET=
161161
162-
# Capability-scoped ccm2 contracts (three distinct secrets, each at least 32 bytes)
163-
GATEWAY_TO_WEBHOOKS_RESOURCE_DELETION_SECRET=
164-
WEBHOOKS_TO_AGENT_LIFECYCLE_SECRET=
165-
INTERNAL_WEBHOOK_REPLAY_SECRET=
166-
167-
# Gateway
162+
# Browser-visible local routing configuration (not secrets)
168163
NEXT_PUBLIC_GATEWAY_URL=http://127.0.0.1:8787
169164
```
170165

CLAUDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ pnpm turbo db:generate # Generate Drizzle types from schema
8585
pnpm turbo lint # Biome check (fails on warnings in CI)
8686
pnpm turbo typecheck # tsc --noEmit across all packages
8787
pnpm turbo build # Production build
88-
pnpm audit:archive -- --dry-run # Admin-only audit partition archive plan
8988
pnpm --filter @cheatcode/db db:generate # Create new migration
9089
```
9190

README.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,17 @@ Fill every required value in `.env.local`. Keep the following boundaries:
7979
- Each signing secret group in `.env.example` must contain non-placeholder
8080
values of at least 32 UTF-8 bytes. Secrets within a group must be distinct.
8181
The startup runner checks these requirements before launching a Worker.
82-
- Keep `NEXT_PUBLIC_GATEWAY_URL=http://127.0.0.1:8787`,
83-
`NEXT_PUBLIC_PREVIEW_HOSTNAME=localhost`, and
84-
`NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA=development` for the standard local
85-
topology.
82+
- Keep `NEXT_PUBLIC_GATEWAY_URL=http://127.0.0.1:8787` for the standard local
83+
topology. The web app derives `localhost` previews locally and the owned
84+
`trycheatcode.com` preview apex in Vercel. Release identity is derived
85+
automatically from Git in deployments and uses `development` locally.
8686
- `COMPOSIO_API_KEY`, `COMPOSIO_AUTH_CONFIGS`, and
8787
`COMPOSIO_WEBHOOK_SECRET` are required for connected-tool flows.
8888
`COMPOSIO_AUTH_CONFIGS` is the JSON object that maps each supported toolkit
8989
name to its Composio auth-config ID.
9090
- `DEEPSEEK_PLATFORM_API_KEY` is optional because users may rely entirely on
91-
BYOK. `DAYTONA_ORG_ID`, Clerk webhook verification, and internal alert
92-
delivery are optional only when the corresponding account or callback flow
93-
is not being exercised.
91+
BYOK. `DAYTONA_ORG_ID` and Clerk webhook verification are optional only when
92+
the corresponding account or callback flow is not being exercised.
9493

9594
Do not copy `.env.production` into `.env.local`. Do not put database migration
9695
credentials in this file; authorized operators keep those only in the ignored
@@ -261,11 +260,5 @@ Review the emitted immutable snapshot name and commit it in the agent Worker
261260
configuration. Production Daytona credentials and snapshot publication remain
262261
inside that workflow.
263262

264-
Audit retention uses the separate protected `Audit Archive` workflow because it
265-
performs destructive database and R2 maintenance. It accepts exact plan/apply
266-
confirmation, verifies the pinned production database identity, and uses a
267-
dedicated bucket-scoped Cloudflare token. Production audit archival must not run
268-
from a laptop.
269-
270263
The repository contains only the active V2 implementation. The legacy V1 source
271264
tree was permanently removed on July 13, 2026 after explicit user authorization.

apps/agent-worker/README.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,14 @@ run before sandbox deletion, while the sandbox fence drains RPCs admitted by the
215215
After eviction, a deleted or missing Postgres user cannot register the empty object again, so a
216216
late request cannot resurrect Daytona or durable state. Per-project workspace tombstones remain
217217
durable for active accounts in one `STRICT` table whose checks bind each canonical slug to its
218-
project UUID and enforce ordered millisecond timestamps. Every destructive maintenance request uses
219-
the isolated `ccm2` agent-lifecycle capability and the exact `agent.internal` host. Before any
220-
Durable Object or Daytona mutation, the Worker validates the account deletion fence or exact
221-
project/thread soft-delete generation and verifies that every requested run belongs to that
222-
scope. The 30-second signature window is therefore safe to retry and cannot authorize stale or
223-
cross-tenant destruction; no shared key or legacy signature fallback exists.
218+
project UUID and enforce ordered millisecond timestamps. Before any Durable
219+
Object or Daytona mutation, the Worker validates the account deletion fence or
220+
exact project/thread soft-delete generation and verifies that every requested
221+
run belongs to that scope. The operation is not an HTTP route: webhooks holds the
222+
named `AgentLifecycleEntrypoint` Service Binding, and Cloudflare-authenticated
223+
binding properties pin the `webhooks` caller and `agent-lifecycle` capability.
224+
The gateway's default agent binding cannot invoke this entrypoint, and no shared
225+
application secret is required.
224226

225227
Every ProjectSandbox uses the one configured immutable Daytona snapshot and the
226228
one configured shared workspace volume. Existing sandbox identity is accepted
@@ -243,6 +245,7 @@ the same bound while streaming.
243245
## Public exports
244246

245247
- `agentApp`
248+
- `AgentLifecycleEntrypoint`
246249
- `AgentRun`
247250
- `AgentRunWorkflow`
248251
- `ProjectSandbox`
@@ -274,11 +277,18 @@ pnpm --filter @cheatcode/agent-worker typecheck
274277
- `DEEPSEEK_PLATFORM_API_KEY`
275278
- `OUTPUT_DOWNLOAD_SIGNING_SECRET` (Secrets Store binding)
276279
- `OUTPUT_DOWNLOAD_BASE_URL`
277-
- `WEBHOOKS_TO_AGENT_LIFECYCLE_SECRET` (ccm2 `agent-lifecycle` capability shared
278-
only with the webhooks caller)
279280
- `PREVIEW_HOSTNAME`
280281
- `QUOTA_TRACKER`
281282
- `R2_AUDIT`
282283
- `R2_OUTPUTS`
283284
- `SANDBOX_STATE`
284285
- `USER_EVENTS`, `AGENT_METRICS`, `ERROR_EVENTS`, `PERFORMANCE_METRICS`
286+
287+
Sandbox skills call the fixed public
288+
`https://gateway.trycheatcode.com/skill-runtime` surface. The tenant-scoped
289+
`v2_agent_runs` row stores only digests for independently scoped 15-minute
290+
opaque capabilities, allowing local and production Workers to authorize the
291+
same sandbox callback safely. The agent rotates the projected sandbox
292+
configuration every 10 minutes and clears every capability at the terminal run
293+
transition. No deployment-wide skill-runtime signing secret or configurable
294+
backend URL exists.

0 commit comments

Comments
 (0)