diff --git a/.github/ISSUE_TEMPLATE/agent-task.yml b/.github/ISSUE_TEMPLATE/agent-task.yml new file mode 100644 index 00000000..59004201 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/agent-task.yml @@ -0,0 +1,117 @@ +name: Agent implementation task +description: Define a bounded development task for an AI coding agent +title: "[Agent Task]: " +labels: [] +body: + - type: markdown + attributes: + value: | + Read `AGENTS.md` and `docs/AGENT_BUILD_FLOW.md` before implementation. Do not include secrets or real identity documents. + + - type: textarea + id: objective + attributes: + label: Objective + description: State one measurable user or business outcome. + placeholder: A public contact enquiry is stored before the visitor sees a success message. + validations: + required: true + + - type: textarea + id: acceptance + attributes: + label: Acceptance criteria + description: List observable conditions that prove the task is complete. + placeholder: | + - Valid submissions are persisted. + - Invalid input returns 400. + - Storage failure returns 503. + - Tests cover success and failure paths. + validations: + required: true + + - type: textarea + id: scope + attributes: + label: In-scope routes, roles, and files + description: Identify affected user roles, routes, models, or integrations. + validations: + required: true + + - type: textarea + id: exclusions + attributes: + label: Explicit exclusions + description: State what the agent must not change or activate. + placeholder: | + - No paid service activation. + - No production credentials. + - No direct commits to main. + - No sensitive document upload. + validations: + required: true + + - type: dropdown + id: data + attributes: + label: Sensitive-data level + options: + - None or public content + - Account or contact information + - Authentication or authorization + - Identity, financial, legal, or regulated information + validations: + required: true + + - type: dropdown + id: billing + attributes: + label: Billing impact + options: + - None + - Uses an existing free or already-approved service + - May create metered usage + - Requires owner approval before implementation can finish + validations: + required: true + + - type: textarea + id: dependencies + attributes: + label: Manual and provider dependencies + description: List accounts, approvals, provider decisions, or credentials the owner must supply. + placeholder: None, or describe the exact owner-only action. + validations: + required: true + + - type: textarea + id: tests + attributes: + label: Required verification + description: Include unit, authorization, fail-closed, preview, and production checks as applicable. + placeholder: | + - pnpm run verify + - Vercel preview route check + - No external billable calls in tests + validations: + required: true + + - type: textarea + id: rollback + attributes: + label: Rollback expectation + description: Explain how the change can be disabled or reverted safely. + validations: + required: true + + - type: checkboxes + id: guardrails + attributes: + label: Guardrails + options: + - label: I have not placed secrets, passwords, API keys, or real sensitive documents in this issue. + required: true + - label: The task does not authorize billing, legal claims, certifications, or regulated-service activation. + required: true + - label: The agent must use a branch and pull request. + required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..5237f411 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,50 @@ +## Objective + +Closes # + +Describe the single measurable outcome delivered by this pull request. + +## Changes + +- + +## Files and data models affected + +- + +## Trust, security, privacy, and billing review + +- [ ] No secrets or real sensitive documents are included. +- [ ] Public wording does not overstate live, verified, encrypted, certified, guaranteed, or continuous capability. +- [ ] Authorization and validation boundaries were reviewed. +- [ ] Missing provider configuration fails closed. +- [ ] No paid plan, billing, or metered feature was activated. +- [ ] Database changes include compatibility and rollback notes, or no schema change was made. + +## Verification + +- [ ] `pnpm run verify` +- [ ] Relevant authorization and validation failures tested +- [ ] Vercel preview checked +- [ ] Build/runtime logs checked +- [ ] No billable external calls made during testing + +Evidence: + +```text +Paste concise command results or route/status checks here. +``` + +## Manual actions remaining + +State exactly what requires the business owner, provider account, legal approval, or production credential. Write `None` when no manual action remains. + +## Rollback + +Describe how to revert, disable, or fail closed safely. + +## Agent declaration + +- [ ] I read `AGENTS.md` and `docs/AGENT_BUILD_FLOW.md`. +- [ ] This pull request stays within the linked issue scope. +- [ ] I am not claiming completion while a required gate is failing. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2e3867f..1bde4dff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,62 +1,45 @@ -name: CI (Tests & Validation Only - Vercel Handles Deployment) +name: Manual Build Verification on: - pull_request: - branches: [main] + workflow_dispatch: -jobs: - test: - name: Unit Tests - runs-on: ubuntu-22.04 +permissions: + contents: read - steps: - - name: Checkout - uses: actions/checkout@v4 +concurrency: + group: manual-build-verification-${{ github.ref }} + cancel-in-progress: true - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Generate Prisma client - run: pnpm run db:generate - env: - POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost:5432/gem_ci - POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost:5432/gem_ci - - - name: Run unit tests - run: pnpm test - env: - NODE_ENV: test - JWT_SECRET: ci-test-secret-min-32-characters-long-placeholder - POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost:5432/gem_ci - POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost:5432/gem_ci - - lint-and-build: - name: Lint & Build +jobs: + verify: + name: Lint, Typecheck, Test, Build runs-on: ubuntu-22.04 - needs: test + timeout-minutes: 30 + + env: + NODE_ENV: test + JWT_SECRET: ci-test-secret-min-32-characters-long-placeholder + POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost:5432/gem_ci + POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost:5432/gem_ci + NEXT_PUBLIC_APP_URL: https://www.gemcybersecurityassist.com + NEXT_PUBLIC_APP_NAME: GEM Enterprise + NEXT_PUBLIC_AI_DISCLOSURE_TEXT: GEM Concierge is an AI assistant. Responses are informational and require human review for sensitive decisions. + AUDIT_ENABLED: "true" + SMTP_HOST: "" + SMTP_PORT: "587" + SMTP_USER: "" + SMTP_PASS: "" + CRON_SECRET: ci-cron-secret steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 + uses: pnpm/action-setup@v6 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 20 cache: pnpm @@ -64,28 +47,5 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Generate Prisma client - run: pnpm run db:generate - env: - POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost:5432/gem_ci - POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost:5432/gem_ci - - - name: Lint - run: pnpm run lint - - - name: Build - run: pnpm run build - env: - POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost:5432/gem_ci - POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost:5432/gem_ci - JWT_SECRET: ${{ secrets.JWT_SECRET || 'ci-build-secret-min-32-characters-long' }} - NEXT_PUBLIC_APP_URL: https://gem-enterprise.vercel.app - NEXT_PUBLIC_APP_NAME: GEM Enterprise - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - NEXT_PUBLIC_AI_DISCLOSURE_TEXT: ${{ secrets.NEXT_PUBLIC_AI_DISCLOSURE_TEXT || 'GEM Concierge is an AI assistant. Responses are for informational purposes only.' }} - AUDIT_ENABLED: 'true' - SMTP_HOST: '' - SMTP_PORT: '587' - SMTP_USER: '' - SMTP_PASS: '' - CRON_SECRET: ci-cron-secret + - name: Verify repository + run: pnpm run verify diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d6cf71be..d5b6ae4e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,89 +1,44 @@ -# CodeQL Analysis - Runs only on pull requests to avoid deployment interference -name: "CodeQL Advanced" +name: Manual CodeQL Analysis on: - pull_request: - branches: [ "main" ] - schedule: - - cron: '15 6 * * 4' + workflow_dispatch: + +permissions: + contents: read + actions: read + packages: read + security-events: write + +concurrency: + group: manual-codeql-${{ github.ref }} + cancel-in-progress: true jobs: analyze: name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. - runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} - permissions: - # required for all workflows - security-events: write - - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read + runs-on: ubuntu-latest + timeout-minutes: 30 strategy: fail-fast: false matrix: include: - - language: actions - build-mode: none - - language: javascript-typescript - build-mode: none - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages - steps: - - name: Checkout repository - uses: actions/checkout@v4 + - language: actions + build-mode: none + - language: javascript-typescript + build-mode: none - # Add any setup steps before running the `github/codeql-action/init` action. - # This includes steps like installing compilers or runtimes (`actions/setup-node` - # or others). This is typically only required for manual builds. - # - name: Setup runtime (example) - # uses: actions/setup-example@v1 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Run manual build steps - if: matrix.build-mode == 'manual' - shell: bash - run: | - echo 'If you are using a "manual" build mode for one or more of the' \ - 'languages you are analyzing, replace this with the commands to build' \ - 'your code, for example:' - echo ' make bootstrap' - echo ' make release' - exit 1 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: "/language:${{matrix.language}}" + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@v4 + with: + category: /language:${{ matrix.language }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 22264994..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Deploy to Vercel Production - -on: - push: - branches: - - main - workflow_dispatch: - -permissions: - contents: read - -jobs: - deploy: - name: Deploy to Vercel - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - with: - version: 9 - - - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Generate Prisma client - run: pnpm run db:generate - env: - POSTGRES_PRISMA_URL: postgresql://ci:ci@localhost/gem - POSTGRES_URL_NON_POOLING: postgresql://ci:ci@localhost/gem - - - name: Deploy to Vercel Production - run: npx vercel --prod --token $VERCEL_TOKEN --yes - env: - VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} - VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} - VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} diff --git a/.vercelignore b/.vercelignore index 50645e37..31d14123 100644 --- a/.vercelignore +++ b/.vercelignore @@ -1,23 +1,14 @@ -# Development and testing artifacts -src/test/ -*.test.ts -*.test.tsx -*.spec.ts -*.spec.tsx - -# Supabase local tooling is not needed at runtime +# Supabase local tooling is not needed during application builds supabase/ -# Documentation +# Documentation is excluded from deployment bundles *.md DEPLOYMENT.md -# Config files not needed at runtime +# Local environment templates are not deployed .env.example -eslint.config.mjs -vitest.config.ts -# Misc +# Editor and workstation artifacts .idea/ .vscode/ .DS_Store diff --git a/AGENTS.md b/AGENTS.md index b13ac679..42c8344c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,83 +1,142 @@ # GEM Enterprise — Agent Instructions ## Project Overview -GEM Enterprise is a cybersecurity, financial security, asset recovery, and real estate protection platform. -- **Domain**: gemcybersecurityassist.com -- **Repository**: github.com/support371/gem-enterprise -- **Branch**: fix/stabilize-and-finalize-330047221298805619 -- **Deployed on**: Vercel + +GEM Enterprise is a controlled-access platform for cybersecurity, compliance, financial-security coordination, product and service enquiries, and property-risk support. + +- **Production domain:** `https://www.gemcybersecurityassist.com` +- **Repository:** `support371/gem-enterprise` +- **Default branch:** `main` +- **Canonical host:** Vercel project `support371-gem-enterprise` +- **Deployment method:** Vercel Git integration deploys `main`; agents must not run a second `vercel --prod` deployment from CI. +- **Automatic pull-request gate:** canonical Vercel preview builds run lint, type checking, unit tests, and the Next.js production build. +- **GitHub Actions status:** workflows remain available for manual execution; while hosted-runner access is constrained, their absence is not a passing result and Vercel preview verification is required. +- **Current operating mode:** controlled production launch. Sensitive or provider-dependent features fail closed until verified. ## Tech Stack -- **Framework**: Next.js 16 (App Router) -- **Language**: TypeScript (strict mode should be enabled) -- **Database**: PostgreSQL via Prisma 5 ORM -- **Auth**: Custom JWT using `jose` library + `bcryptjs` for password hashing -- **Session**: Cookie-based (`gem_session`), httpOnly, 7-day expiry -- **UI**: Tailwind CSS + shadcn/ui components -- **Charts**: Recharts -- **AI**: Anthropic Claude API via direct integration (NOT Vercel AI SDK) -- **Email**: Resend (when configured) -- **Payments**: Stripe (when configured) -- **Package Manager**: pnpm (NEVER use npm or yarn) -- **Testing**: Vitest (unit) + Playwright (E2E) - -## Architecture Rules — DO NOT VIOLATE -1. **Auth system**: The auth implementation is in `src/lib/auth.ts`. Do NOT replace it with NextAuth, Supabase Auth, Clerk, or any other auth library. Extend the existing JWT implementation. -2. **Database**: All models go in `prisma/schema.prisma`. Use `db` import from `src/lib/db.ts` for all database access. Never use raw SQL. -3. **Package manager**: Use `pnpm` for all commands. Never reference npm or yarn. -4. **API validation**: All API route inputs must be validated with Zod schemas. Never trust raw `req.json()`. -5. **Audit logging**: All admin and sensitive actions must call `emitAuditLog()` from `src/lib/audit.ts`. -6. **Evidence retention**: Compliance-sensitive data follows 7-year retention per `src/lib/evidence.ts`. -7. **Roles**: The system has 5 roles: client, analyst, admin, super_admin, internal. Never allow role escalation to super_admin or internal via API. -8. **AI consent**: All AI interactions require user consent via `ConsentRecord` model before proceeding. -9. **File organization**: Pages go in `src/app/`, API routes in `src/app/api/`, shared libraries in `src/lib/`, React components in `src/components/`, hooks in `src/hooks/`. -10. **Styling**: Match the existing dark theme. Use Tailwind utility classes. Do not add custom CSS files. - -## Key Files Reference -- `src/lib/auth.ts` — JWT sign/verify, session management, KYC-gated routing -- `src/lib/db.ts` — Prisma client singleton -- `src/lib/audit.ts` — Audit logging with `emitAuditLog()` -- `src/lib/evidence.ts` — 7-year evidence retention -- `src/lib/orchestration/orchestrate-support-reply.ts` — AI chat orchestration -- `src/lib/policy/evaluate-policy.ts` — AI policy evaluation engine -- `prisma/schema.prisma` — Database schema (22 models, 9 enums) -- `next.config.js` — Security headers, redirects, image optimization -- `vercel.json` — Vercel deployment configuration - -## Environment Variables -Required env vars are documented in `.env.example`. For development/testing, use these defaults: -- DATABASE_URL=postgresql://test:test@localhost:5432/gem_test -- JWT_SECRET=test-secret-that-is-at-least-32-characters-long-for-dev -- NEXT_PUBLIC_APP_URL=http://localhost:3000 -- NEXT_PUBLIC_APP_NAME=GEM Enterprise -- AUDIT_ENABLED=true - -## Verification Commands — RUN AFTER EVERY CHANGE + +- **Framework:** Next.js 16 App Router +- **Language:** TypeScript +- **Database:** PostgreSQL through Prisma 5 +- **Authentication:** existing JWT/session implementation using `jose` and `bcryptjs` +- **Session:** HTTP-only cookie named `gem_session` +- **UI:** Tailwind CSS and existing shared components +- **Email:** Nodemailer SMTP when production credentials are configured +- **Commerce:** request-only catalogue until payments, fulfilment, refunds, taxes, licensing, and inventory are verified +- **Testing:** Vitest; Playwright is available for end-to-end tests +- **Package manager:** pnpm 10.28.0 only + +## Non-Negotiable Safety and Trust Rules + +1. **Fail closed.** Do not enable KYC uploads, biometrics, automatic approvals, automatic payments, live intelligence, or marketplace transactions without the complete supporting infrastructure and explicit owner approval. +2. **No false operational claims.** Do not describe static, sample, mock, planned, or manually reviewed data as live, continuous, verified, encrypted, certified, guaranteed, monitored, or available 24/7. +3. **No secrets in code, prompts, commits, logs, issues, screenshots, or pull requests.** Use environment-variable names and secret managers only. +4. **No paid service activation.** An agent may build an adapter or sandbox integration, but may not accept pricing, enable billing, purchase a plan, or create financial obligations. +5. **No direct production database mutation from CI.** Schema changes require a migration, compatibility assessment, rollback plan, and owner-approved production execution. +6. **No direct commits to `main`.** Use a focused branch and pull request except for an explicitly documented emergency process. +7. **One canonical deployment.** Vercel Git integration owns production deployment. Do not create duplicate production deploy workflows or attach the domain to another project without a migration plan. +8. **Human review for high-impact decisions.** Identity, eligibility, legal, financial, security-incident, and access decisions must remain reviewable and auditable. + +## Architecture Rules + +1. Extend the authentication implementation in `src/lib/auth.ts`; do not replace it with another auth platform without an approved migration plan. +2. Put Prisma models in `prisma/schema.prisma` and access the database using `db` from `src/lib/db.ts`. +3. Validate API inputs with Zod. +4. Call `emitAuditLog()` from `src/lib/audit.ts` for administrator, reviewer, authorization, verification, and sensitive state changes. +5. Do not trust client-supplied roles, storage paths, scan results, payment states, provider decisions, or redirect URLs. +6. Pages belong in `src/app/`, API routes in `src/app/api/`, shared logic in `src/lib/`, and reusable UI in `src/components/`. +7. Match the existing design system and avoid introducing another styling framework. +8. External providers must be accessed through small adapter interfaces so they can be disabled or replaced. +9. Sensitive files must never be stored in public paths or accepted before private storage, validation, scanning, access control, audit logging, retention, and deletion are working. +10. APIs handling credentials, identity, contact, payments, administration, or recovery must use `no-store` responses and production-appropriate abuse controls. + +## Agent Delivery Flow + +Every implementation task follows this sequence: + +1. **Create or reference one GitHub issue** containing the objective, acceptance criteria, exclusions, risks, and manual dependencies. +2. **Create a focused branch** using `feat/`, `fix/`, `chore/`, `docs/`, `security/`, or `test/`. +3. **Inspect before editing.** Read the affected routes, schema, tests, configuration, and recent related pull requests. +4. **Write a brief implementation plan** in the issue or pull request before broad changes. +5. **Implement the smallest complete vertical slice.** Avoid unrelated refactors and batch related edits before pushing to reduce unnecessary preview builds. +6. **Add or update tests** for success, authorization failure, validation failure, provider failure, and fail-closed behavior. +7. **Run the repository gate locally or in the development agent environment:** + ```bash +corepack enable pnpm install --frozen-lockfile -pnpm run db:generate -pnpm build -pnpm test +pnpm run verify ``` -If any of these fail, fix the errors before committing. - -## Commit Convention -- Use conventional commits: feat:, fix:, chore:, test:, docs: -- Include the prompt number in commits: `feat(prompt-7): wire community hub to database` -- One logical change per commit when possible - -## Testing Standards -- Unit tests go in `src/__tests__/` -- E2E tests go in `e2e/` -- Test files follow pattern: `*.test.ts` or `*.spec.ts` -- Mock external services (Anthropic, Resend, Stripe) — never call real APIs in tests -- Target 70%+ statement coverage - -## PR Description Format -When creating a pull request, include: -1. **Prompt Reference**: Which prompt number this addresses -2. **Changes Summary**: What was added/modified/deleted -3. **Files Changed**: List of key files -4. **Testing**: What tests were added or updated -5. **Verification**: Confirm `pnpm build` and `pnpm test` pass +8. **Open a pull request** with risks, manual dependencies, test evidence, and rollback notes. +9. **Require the canonical Vercel preview to pass.** Preview builds automatically run lint, type checking, unit tests, Prisma generation, and the Next.js production build. Inspect its build logs and affected routes. +10. **Use the manual GitHub verification and CodeQL workflows when hosted-runner access is available.** Do not describe a workflow that never started as passing. +11. **Merge only after the available required gates pass.** Vercel Git integration deploys `main` to production. +12. **Run production smoke checks** without submitting sensitive data or causing billable external actions. + +## Build Gate + +`pnpm run verify` must complete successfully in the agent environment before the pull request is presented as ready. It runs: + +- Prisma client generation +- ESLint +- TypeScript checking +- Unit tests +- Next.js production build + +The canonical Vercel preview independently runs `pnpm run verify:preview` before building the application. This is the automatic hosted gate while GitHub Actions runner access is constrained. + +If verification cannot run because a required dependency or account service is unavailable, the agent must document the exact blocker and must not claim the feature is complete. + +## Free-Tier Development Policy + +Development should preserve useful free operation: + +- Prefer existing infrastructure and open-source libraries. +- Do not add a paid provider merely to complete a demo. +- Build provider-independent interfaces and use local fakes in tests. +- Keep optional integrations disabled by default. +- Batch related commits before pushing so one preview validates one coherent change set. +- Add usage limits, queue boundaries, retention limits, and clear error states before enabling a metered service. +- Treat billing approval, identity-provider contracts, production email credentials, regulated data sources, and external seller verification as owner-only actions. + +## Current Sensitive Feature Gates + +These remain disabled or request-only until their activation requirements pass: + +- Identity and financial document upload +- Biometric and liveness verification +- Automatic KYC/KYB approval +- Automatic payments and subscriptions +- Live threat-intelligence assertions +- Marketplace transactions and verified-member claims +- Guaranteed response times and continuous monitoring + +## Key Files + +- `src/lib/auth.ts` — authentication and session management +- `src/lib/db.ts` — Prisma client +- `src/lib/audit.ts` — audit events +- `src/app/api/contact/route.ts` — durable public enquiry intake +- `src/app/api/kyc/documents/route.ts` — intentionally fail-closed document endpoint +- `src/lib/storefrontPresentation.ts` — truthful request-only commerce presentation +- `prisma/schema.prisma` — database schema +- `next.config.js` — browser security headers and routing +- `scripts/vercel-build.mjs` — Prisma, preview verification, and application build orchestration +- `.github/workflows/ci.yml` — manual full verification fallback +- `.github/workflows/codeql.yml` — manual CodeQL fallback +- `docs/AGENT_BUILD_FLOW.md` — task and release operating procedure + +## Commit and Pull Request Standards + +Use conventional commits such as `feat:`, `fix:`, `security:`, `test:`, `docs:`, and `chore:`. A pull request must include: + +1. Objective and linked issue +2. User-visible and architectural changes +3. Files and data models affected +4. Security, privacy, billing, and operational risks +5. Tests and verification performed +6. Manual actions that remain +7. Rollback method + +An AI agent is an executor, not the approval authority for billing, legal representations, identity decisions, production secrets, or regulated-service activation. diff --git a/docs/AGENT_BUILD_FLOW.md b/docs/AGENT_BUILD_FLOW.md new file mode 100644 index 00000000..61e450ee --- /dev/null +++ b/docs/AGENT_BUILD_FLOW.md @@ -0,0 +1,278 @@ +# GEM Enterprise Agent-First Build Flow + +## Purpose + +This flow lets GEM Enterprise keep building with limited personnel time and minimal billing exposure while preserving a trustworthy production system. + +> Humans define intent and approve high-impact decisions. Agents implement, test, document, and prepare pull requests. Hosted gates verify the work. Sensitive capabilities remain disabled until their infrastructure and owner approvals exist. + +## Current hosted-gate arrangement + +- **Canonical automatic gate:** Vercel preview deployment for project `support371-gem-enterprise` (`prj_VDGqnA7wZt2E65LLvT94ZOpnYc2Z`). +- **Duplicate protection:** `scripts/vercel-ignore.mjs` allows only the canonical project to build. Any non-canonical project ID or recognized duplicate URL is ignored before the build begins. Unknown Vercel projects fail closed. +- **Disconnected duplicates:** `gem-enterprise` (`prj_iT8bNqbTiePiM2SZiWTkOUJXy3o0`) and `project-dtrl6` (`prj_TUZk9mqccnIGSsSpsti7jwg9D3W2`) were disconnected from the repository on 2026-07-09. A fresh commit created no deployments in either project. +- **What the canonical preview runs:** Prisma generation, ESLint, TypeScript checking, Vitest, and the Next.js production build. +- **GitHub Actions:** build verification and CodeQL workflows remain available through manual dispatch. They are not automatic while hosted-runner access is constrained. +- **Production deployment:** Vercel Git integration deploys `main`. No second production deployment workflow is permitted. +- **Important:** a GitHub workflow that never starts is not a passing check. The canonical Vercel preview and the agent's own `pnpm run verify` evidence are required. + +## Roles + +### Business owner + +Responsible for: + +- Business priorities and public claims +- Billing, contracts, and paid plans +- Legal entity and policy approval +- Provider accounts and production credentials +- Final approval for identity, payment, storage, monitoring, and regulated-service activation + +### Lead development agent + +Responsible for: + +- Repository inspection and task planning +- Focused implementation +- Tests and documentation +- Pull-request creation +- Local or agent-environment verification +- Vercel preview verification +- Reporting exact blockers and manual actions + +### Review agent + +Responsible for an independent pass over: + +- Security and authorization boundaries +- Privacy and sensitive-data handling +- False or unsupported public claims +- Database and migration safety +- Test coverage and rollback readiness + +## Canonical workflow + +```text +Owner objective + ↓ +GitHub issue with acceptance criteria + ↓ +Agent branch + ↓ +Inspect current code and related PRs + ↓ +Small vertical implementation + ↓ +Unit, authorization, validation, and fail-closed tests + ↓ +pnpm run verify in the agent environment + ↓ +Pull request + ↓ +Duplicate Vercel projects are ignored + ↓ +Canonical Vercel preview runs lint + typecheck + tests + build + ↓ +Independent review; manual CodeQL when runner access is available + ↓ +Owner-only approval when billing, legal, or provider action exists + ↓ +Merge to main + ↓ +Vercel Git production deployment + ↓ +Production smoke check and rollback watch +``` + +## Work queue + +### P0 — Production safety + +Examples: + +- Authentication bypass +- Data exposure +- Contact submissions being lost +- Broken production deployment +- Unsupported claims that can materially mislead users + +Rules: + +- Stop unrelated feature work. +- Fix in the smallest possible branch. +- Require tests and production verification. + +### P1 — Revenue and customer flow + +Examples: + +- Enquiry intake +- Application status +- Service-request workflow +- Email delivery +- Reviewer queue + +Rules: + +- Build request-and-review flows before automated or paid flows. +- Persist data before showing success. + +### P2 — Trust infrastructure + +Examples: + +- Audit records +- Access controls +- Backups and restore testing +- Rate limiting +- Monitoring +- Privacy and retention controls + +### P3 — Optional expansion + +Examples: + +- Provider adapters +- Live feeds +- Automated payments +- Biometrics +- Marketplace transactions + +Rule: keep these disabled until P0–P2 requirements and owner approvals are complete. + +## Definition of ready + +An issue is ready for an agent only when it contains: + +- User or business outcome +- In-scope routes and roles +- Acceptance criteria +- Explicit exclusions +- Sensitive-data classification +- Billing impact +- Manual/provider dependencies +- Rollback expectation + +## Definition of done + +A task is complete only when: + +- The implementation matches the issue scope. +- Validation and authorization failures are tested. +- Provider failure or missing configuration fails closed. +- `pnpm run verify` passes in the development-agent environment. +- The canonical Vercel preview passes its full preview verification and build. +- Affected preview routes work. +- No secret or real sensitive document was used in testing. +- The PR states what remains manual. +- Production smoke checks pass after merge. + +## Standard agent prompt + +```text +Repository: support371/gem-enterprise + +Read AGENTS.md and docs/AGENT_BUILD_FLOW.md before making changes. + +Objective: + + +Acceptance criteria: +- +- +- + +Explicit exclusions: +- No paid service activation +- No production secrets +- No direct commit to main +- No enabling sensitive uploads or payments unless every required control and owner approval is included + +Required process: +1. Inspect affected code, schema, tests, configuration, and recent related PRs. +2. Post a short plan. +3. Implement the smallest complete vertical slice. +4. Add tests for success, validation failure, authorization failure, and fail-closed behavior. +5. Run pnpm run verify in your environment. +6. Batch related changes before pushing to reduce preview builds. +7. Open a PR with risks, manual dependencies, and rollback steps. +8. Require the canonical Vercel preview to pass. +9. Do not claim completion if any available gate fails. +``` + +## Recommended agent allocation + +### Primary implementation agent: OpenAI Codex + +Use for: + +- Multi-file repository tasks +- Bug diagnosis +- Refactors and migrations +- Test creation +- Pull-request preparation +- Parallel tasks isolated by branch + +Codex must follow `AGENTS.md`, use one issue per task, run repository verification in its environment, and operate through pull requests. + +### Independent review: GitHub Copilot coding agent or a second Codex task + +Use for: + +- Reviewing the PR without sharing the implementation conversation +- Checking authorization, data handling, and regressions +- Finding missing tests + +### Replit Agent + +Use for a visual prototype or isolated experiment. Do not make it the canonical production repository or deployment path. + +### Devin + +Use only for a clearly bounded backlog when paid capacity is approved. It is not required for the current free-first flow. + +## First implementation program: GEM Verify Core + +Build in this order: + +1. Verification application and consent records +2. Manual case-status workflow +3. Reviewer queue and role checks +4. Information-request, approval, rejection, and escalation actions +5. Audit events and immutable decision history +6. Storage-provider interface with a fake test implementation +7. Retention and deletion scheduling model +8. Private upload adapter only after owner-selected storage and scanning are available +9. Optional Veriff or another provider adapter after sandbox approval + +Until step 8 is verified, `/api/kyc/documents` must remain fail closed. + +## Free-tier safeguards + +- Batch related edits before pushing so one preview validates one coherent change set. +- Cancel superseded preview and CI runs where supported. +- Use the canonical Vercel project only. +- Let Vercel Git integration perform the only production deployment. +- Keep `scripts/vercel-ignore.mjs` fail closed for any unknown or non-canonical Vercel project. +- Use local fakes for external providers in tests. +- Do not run scheduled jobs more frequently than required. +- Keep optional integrations disabled by default. +- Record usage and define a hard stop before enabling metered services. +- Never rely on a free plan whose terms prohibit the intended business use. + +## Manual gates + +The agent must stop and request owner action for: + +- Accepting pricing or terms +- Enabling billing +- Creating regulated-data provider accounts +- Entering production secrets +- Selecting retention periods +- Approving public certifications or SLAs +- Naming authorized identity reviewers +- Activating payment collection +- Moving the production domain or database +- Disconnecting duplicate Vercel projects or changing organization-level GitHub billing and Actions settings + +These gates are separation-of-duty controls, not development failures. diff --git a/docs/VERCEL_CANONICAL_PROJECT.md b/docs/VERCEL_CANONICAL_PROJECT.md new file mode 100644 index 00000000..8ad4b241 --- /dev/null +++ b/docs/VERCEL_CANONICAL_PROJECT.md @@ -0,0 +1,41 @@ +# Canonical Vercel Project + +Verified on 2026-07-09 after the dashboard cleanup. + +## Canonical project + +- Name: `support371-gem-enterprise` +- Project ID: `prj_VDGqnA7wZt2E65LLvT94ZOpnYc2Z` +- Production domains: + - `https://www.gemcybersecurityassist.com` + - `https://gemcybersecurityassist.com` + +This is the only Vercel project authorized to build and deploy `support371/gem-enterprise`. + +## Disconnected duplicate projects + +- `gem-enterprise` — `prj_iT8bNqbTiePiM2SZiWTkOUJXy3o0` +- `project-dtrl6` — `prj_TUZk9mqccnIGSsSpsti7jwg9D3W2` + +After their Git connections were removed, neither duplicate created a deployment from subsequent repository activity. The repository-level `scripts/vercel-ignore.mjs` guard remains enabled as defense in depth and fails closed for non-canonical or unknown Vercel projects. + +## Verified preview gate + +Canonical preview deployment `dpl_7zyuXQAuMaVE1ywj6eo4HRoyS2C6` reached `READY` for code commit `41050e0c08449c6bc282c4ead34c4348ca3330a1` after completing: + +- Prisma client generation +- ESLint +- TypeScript checking +- 14 Vitest files and 164 passing tests +- Next.js 16 production compilation and deployment + +This file is documentation-only and excluded from the deployment bundle by `.vercelignore`, so later documentation commits do not change the verified application build. + +## Verification rule + +Before merging a pull request: + +1. Confirm the pull-request code head creates a deployment only in the canonical project. +2. Confirm the canonical preview reaches `READY`. +3. Inspect the canonical build logs for lint, TypeScript, unit-test, Prisma, and Next.js build results. +4. Do not treat historical checks from disconnected projects as current deployment evidence. diff --git a/package.json b/package.json index 63916664..a3fc9a08 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,18 @@ "name": "gem-enterprise", "private": true, "version": "1.0.0", + "packageManager": "pnpm@10.28.0", "scripts": { "dev": "next dev", "build": "node scripts/vercel-build.mjs", "start": "next start", "lint": "eslint src --ext .ts,.tsx --max-warnings=0", + "typecheck": "tsc --noEmit", "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", + "verify:preview": "pnpm run lint && pnpm run typecheck && pnpm run test", + "verify": "pnpm run db:generate && pnpm run verify:preview && pnpm run build", "db:generate": "prisma generate", "db:push": "prisma db push", "db:migrate": "prisma migrate dev", @@ -117,4 +121,4 @@ "typescript": "^5.8.3", "vitest": "^4.1.0" } -} \ No newline at end of file +} diff --git a/scripts/vercel-build.mjs b/scripts/vercel-build.mjs index 21e6d07d..67ba5619 100644 --- a/scripts/vercel-build.mjs +++ b/scripts/vercel-build.mjs @@ -39,6 +39,27 @@ if (directUrl) env.POSTGRES_URL_NON_POOLING = directUrl; console.log("Generating Prisma client..."); run("pnpm", ["exec", "prisma", "generate"], env); +const shouldVerifyPreview = + env.VERCEL_ENV === "preview" || env.RUN_PREVIEW_VERIFICATION === "true"; + +if (shouldVerifyPreview) { + console.log("Running preview verification: lint, typecheck, and unit tests..."); + const verificationEnv = { + ...env, + NODE_ENV: "test", + JWT_SECRET: "preview-verification-secret-min-32-characters", + POSTGRES_PRISMA_URL: "postgresql://ci:ci@localhost:5432/gem_ci", + POSTGRES_URL_NON_POOLING: "postgresql://ci:ci@localhost:5432/gem_ci", + SMTP_HOST: "", + SMTP_PORT: "587", + SMTP_USER: "", + SMTP_PASS: "", + CRON_SECRET: "preview-verification-cron-secret", + AUDIT_ENABLED: "true", + }; + run("pnpm", ["run", "verify:preview"], verificationEnv); +} + if (env.AUTO_DB_PUSH === "true") { if (!pooledUrl) { throw new Error( diff --git a/scripts/vercel-ignore.mjs b/scripts/vercel-ignore.mjs index c42ca396..4a9012c1 100644 --- a/scripts/vercel-ignore.mjs +++ b/scripts/vercel-ignore.mjs @@ -1,15 +1,66 @@ +// Defense-in-depth: only the canonical GEM Vercel project may consume a build. const canonicalProjectId = "prj_VDGqnA7wZt2E65LLvT94ZOpnYc2Z"; -const currentProjectId = process.env.VERCEL_PROJECT_ID?.trim(); +const canonicalMarkers = [ + "support371-gem-enterprise", + "www.gemcybersecurityassist.com", + "gemcybersecurityassist.com", +]; +const knownDuplicateMarkers = [ + "project-dtrl6", + "gem-enterprise-admin-25521151s-projects", + "gem-enterprise-git-", +]; -if (!currentProjectId) { - console.log("VERCEL_PROJECT_ID is unavailable; continue the build safely."); +const projectId = process.env.VERCEL_PROJECT_ID?.trim() || ""; +const deploymentSignals = [ + process.env.VERCEL_PROJECT_PRODUCTION_URL, + process.env.VERCEL_URL, + process.env.VERCEL_BRANCH_URL, + process.env.VERCEL_TARGET_ENV, +] + .filter((value) => typeof value === "string" && value.trim().length > 0) + .map((value) => value.trim().toLowerCase()); + +function continueBuild(reason) { + console.log(`[vercel-ignore] Continue build: ${reason}`); process.exit(1); } -if (currentProjectId === canonicalProjectId) { - console.log(`Canonical Vercel project ${canonicalProjectId}; continue the build.`); - process.exit(1); +function ignoreBuild(reason) { + console.log(`[vercel-ignore] Ignore build: ${reason}`); + process.exit(0); +} + +if (projectId) { + if (projectId === canonicalProjectId) { + continueBuild(`canonical project ID ${canonicalProjectId}`); + } + + ignoreBuild( + `non-canonical project ID ${projectId}; canonical project is ${canonicalProjectId}`, + ); +} + +if ( + deploymentSignals.some((signal) => + canonicalMarkers.some((marker) => signal.includes(marker)), + ) +) { + continueBuild(`canonical project marker detected in ${deploymentSignals.join(", ")}`); +} + +if ( + deploymentSignals.some((signal) => + knownDuplicateMarkers.some((marker) => signal.includes(marker)), + ) +) { + ignoreBuild(`known duplicate marker detected in ${deploymentSignals.join(", ")}`); +} + +if (process.env.VERCEL === "1" || process.env.CI === "1") { + ignoreBuild( + "Vercel project identity could not be verified. Failing closed to prevent an unknown or duplicate project from consuming build capacity.", + ); } -console.log(`Ignoring duplicate Vercel project ${currentProjectId}; canonical project is ${canonicalProjectId}.`); -process.exit(0); +continueBuild("local non-Vercel environment");