Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 67 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
node-version: "24"
- run: npm install --global pnpm@11.19.0
- run: pnpm install --frozen-lockfile
- name: Configure disposable test environment
Expand All @@ -40,6 +40,71 @@ jobs:
node --input-type=module -e "for(let i=0;i<60;i++){try{const r=await fetch('http://localhost:4317/health/ready');if(r.ok)process.exit(0);}catch{}await new Promise(r=>setTimeout(r,1000));}process.exit(1);"
pnpm test:browser
- run: pnpm scan:secrets
- run: pnpm audit --audit-level=moderate
- run: pnpm audit --audit-level=low
- run: docker build -t cove:ci .
- run: pnpm build
- name: Verify the compiled Sites browser journey
run: |
pnpm exec wrangler d1 execute DB --local --config .sites-runtime/wrangler.json --file drizzle/0000_sticky_juggernaut.sql
pnpm exec wrangler d1 execute DB --local --config .sites-runtime/wrangler.json --file drizzle/0001_sites_auth.sql
pnpm exec wrangler d1 execute DB --local --config .sites-runtime/wrangler.json --file drizzle/0002_integrity.sql
pnpm exec wrangler dev --local --config .sites-runtime/wrangler.json --ip 127.0.0.1 --port 4318 --inspector-port 0 > /tmp/cove-sites.log 2>&1 &
preview_pid=$!
trap 'kill "$preview_pid" || true' EXIT
node --input-type=module -e "for(let i=0;i<60;i++){try{const r=await fetch('http://localhost:4318');if(r.ok)process.exit(0);}catch{}await new Promise(r=>setTimeout(r,1000));}process.exit(1);"
node scripts/verify-sites-browser.mjs
node scripts/verify-sites-mcp.mjs
- uses: actions/upload-artifact@v4
if: always()
with:
name: cove-verification
path: |
docs/sites-browser-verification.json
docs/design/
test-results/
recovery:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "24"
- run: npm install --global pnpm@11.19.0
- run: pnpm install --frozen-lockfile
- run: node scripts/setup-env.mjs
- run: docker compose up -d --wait db mail
- run: pnpm db:migrate
- run: pnpm build:local
- name: Create fictional saved context and an assistant grant
run: |
node --input-type=module <<'NODE'
import { randomUUID } from 'node:crypto';
import { Pool } from 'pg';
import { CoveService } from './dist/packages/domain/service.js';
import { emptyContext } from './dist/packages/shared/context.js';
process.loadEnvFile('.env');
const pool = new Pool({connectionString:process.env.DATABASE_URL});
try {
const userId = randomUUID();
await pool.query('INSERT INTO "user"(id,name,email,"emailVerified") VALUES($1,$2,$3,true)',[userId,'Recovery fixture',`${userId}@example.test`]);
const service = new CoveService(pool,{MAX_PROJECTS:50,MAX_REVISIONS:1000,MAX_STORAGE_BYTES:104857600});
const actor = {userId};
const context = {...emptyContext(),goal:'Preserve this fictional project through backup and restart.'};
const project = await service.createProject(actor,{name:'Recovery fixture',context});
await service.createHandoff(actor,project.id,{expectedVersion:1,requestKey:randomUUID()});
await service.saveConnection(actor,{clientId:'recovery-fixture',label:'Recovery fixture',grants:[{projectId:project.id,capabilities:['read']}]});
} finally { await pool.end(); }
NODE
- run: node scripts/backup-verify.mjs
- run: docker build -t cove:0.1.0 .
- run: node scripts/verify-container.mjs
- uses: actions/upload-artifact@v4
if: always()
with:
name: cove-recovery-verification
path: |
docs/recovery-verification.json
docs/container-verification.json
- name: Remove this disposable CI stack
if: always()
run: docker compose down --volumes --remove-orphans
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Local prerequisites are Node.js 24, pnpm 11.19.0, Git, and Docker with Compose.
| `packages/mcp` and `packages/shared` | MCP tools, validation, comparisons, and handoff formatting |
| `tests` and `scripts` | Automated checks, setup, builds, and recovery tools |

See [GitHub Actions](https://github.com/agammann/cove/actions/workflows/ci.yml) for current automated results and the [documentation index](docs/README.md) for dated verification records and known limits.
See [GitHub Actions](https://github.com/agammann/cove/actions/workflows/ci.yml) for current automated results, [October 2 verification](docs/verification-2026-10-02.md) for the compiled browser and HTTP MCP checks, and the [documentation index](docs/README.md) for dated records and known limits.

## License

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Current automated results are in [GitHub Actions](https://github.com/agammann/co

| Record | Scope |
| --- | --- |
| [October 2 verification](verification-2026-10-02.md) | Dependency updates, compiled browser journey and actual HTTP OAuth/MCP checks |
| [September 19 live acceptance](live-acceptance-2026-09-19.md) | Public browser and mobile journeys, live OAuth/MCP, reproduced issues, fixes, and remaining boundaries |
| [Sites verification](sites.md#verification-on-september-13-2026) | Hosted browser verification, local Worker tests, and remaining external host checks |
| [Original verification](verification.md) | September 10 local PostgreSQL release checks |
Expand Down
4 changes: 3 additions & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ node scripts/verify-sites-browser.mjs

This script exercises desktop/mobile rendering, saving context, handoff copying, and deletion of its synthetic account. It updates `docs/sites-browser-verification.json` and the screenshots in `docs/design`; review those changes before committing. The fixture uses synthetic identity headers and a development secret. Keep it bound to loopback, and never expose it through a tunnel or use its sign in flow against production.

Run `node scripts/verify-sites-mcp.mjs` against the same local Worker to verify all seven tools over actual HTTP. Two independent SDK clients complete PKCE, save and retrieve a pinned handoff, and check read-only grants and live revocation. The check creates and removes its own fictional local account and writes `test-results/cove-sites-mcp.json`. Repeated OAuth registrations are subject to the application's rate limits; wait for the normal cooldown before rerunning. This protocol test does not establish a ChatGPT or Codex host connection.

## Troubleshooting

| Symptom | Resolution |
Expand All @@ -122,7 +124,7 @@ This script exercises desktop/mobile rendering, saving context, handoff copying,

## Maintainer checks

The [CI workflow](../.github/workflows/ci.yml) also builds the Docker image and builds Sites after the local browser journey. Recovery and container exercises are separate:
The [CI workflow](../.github/workflows/ci.yml) builds both distributions and runs the compiled Sites browser/MCP checks. A separate disposable Compose job verifies backup restoration and production container startup. You can repeat those operational checks locally:

```sh
node scripts/backup-verify.mjs
Expand Down
16 changes: 16 additions & 0 deletions docs/verification-2026-10-02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# October 2, 2026 UTC verification

These checks use fictional data. Local environment: Windows, Node 24.19.0, pnpm 11.19.0 and Playwright Chromium 153.0.8010.12.

- Frozen dependency installation, lint, TypeScript and the Sites production build passed.
- Twelve domain, security regression and Sites tests passed. The Sites suite includes two official SDK clients against an in-process Worker fixture.
- The compiled Worker and actual local D1 passed the browser journey: project creation, editing, saved context, concise/full handoff copying, account cleanup and desktop/mobile layout.
- Two independent official MCP SDK 2.0.0 clients completed actual HTTP registration, S256 PKCE, consent and separate project grants against that compiled Worker. All seven tools returned the expected project, revision, handoff, search and change data. A read-only client could not write; the saved revision stayed at version 2. Revoking one live connection rejected further calls without disabling the other client.
- The initial dependency audit reported 24 advisories. Updating Wrangler, Fastify, Nodemailer and compatible transitive packages reduced the audit to zero advisories at all severity levels. The release-age exceptions name only the patched Wrangler and its exact Miniflare dependency.
- The source credential-pattern check passed. Its bounded patterns do not guarantee the absence of secrets.

Run `node scripts/verify-sites-mcp.mjs` against the documented local Sites fixture to repeat the compiled HTTP check. It creates and deletes only its own fictional account and records results in `test-results/cove-sites-mcp.json`. OAuth registration rate limits remain enabled; a cooldown was required after repeated exploratory runs.

GitHub Actions passed 21 tests including actual PostgreSQL and OAuth integration, the email sign-in and recovery browser journey, and the compiled Sites browser and HTTP MCP checks. A separate disposable Compose job restored a fictional saved revision and pinned handoff, compared complete project/history contents, revoked restored grants, and verified persistence after a database restart. The production container passed fresh migration, health and frontend checks, Host validation, non-root/read-only startup, restart, and rejection of insecure demo settings. See [the verified run](https://github.com/agammann/cove/actions/runs/36962954567) and [the workflow](https://github.com/agammann/cove/actions/workflows/ci.yml).

The local sign-in uses synthetic identity headers on loopback. Live ChatGPT sign-in and a native Codex or ChatGPT assistant interaction still require the owner's account connection. SDK protocol checks do not establish those host integrations. Production recovery, off-host backups and participant usability are outside this evidence.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
"@modelcontextprotocol/server": "2.0.0",
"better-auth": "1.7.3",
"drizzle-orm": "0.45.2",
"fastify": "5.12.3",
"fastify": "5.12.5",
"lucide-react": "1.42.0",
"nodemailer": "10.0.1",
"nodemailer": "10.0.9",
"pg": "8.23.0",
"react": "19.2.8",
"react-dom": "19.2.8",
Expand All @@ -62,6 +62,6 @@
"typescript-eslint": "8.70.0",
"vite": "8.2.2",
"vitest": "4.1.11",
"wrangler": "4.131.1"
"wrangler": "4.146.0"
}
}
Loading
Loading