Skip to content
Merged
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
121 changes: 121 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
# Development (starts all 3 processes: Vite :5001, Express :5000, Python :8001)
scripts/start-dev.sh

# Production build (Vite → dist/public/, esbuild → dist/index.cjs)
npm run build

# TypeScript type checking
npm run check

# Push Drizzle schema to PostgreSQL
npm run db:push

# Re-stamp all files with N:M ratio annotation (required after edits)
python scripts/annotate.py
```

### Tests

```bash
# Install Playwright browser (first time)
npx playwright install chromium

# Run all e2e tests (requires dev server on :5000)
npx playwright test

# Run a single test file
npx playwright test tests/e2e/console-tabs.spec.ts

# Console-tab regression guard (static preflight, no browser needed)
node scripts/check-console-tabs.mjs
```

## Architecture

This is a 3-process autonomous AI agent platform with a metadata-driven console UI.

### Process Topology

```
Browser → Express (:5000) → [proxy /api/*] → Python/FastAPI (:8001, internal only)
↘ [dev] Vite (:5001)
```

- **Express** (`server/`) — Auth, sessions, guest-chat rate limiting, static serving. Adds `x-a0p-internal: <INTERNAL_API_SECRET>` and user identity headers (`x-user-id`, `x-user-email`, `x-user-role`) to every proxied request. Never expose Python port directly.
- **Python/FastAPI** (`python/`) — All AI orchestration, PCNA engine, agent lifecycle, billing, heartbeat scheduler. Validates `x-a0p-internal` on every request.

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc says FastAPI "validates x-a0p-internal on every request", but python/main.py explicitly exempts /api/health and /api/v1/guest/chat via _OPEN_PATHS. Please document these exceptions (or soften the wording) so readers don’t assume all routes require the header.

Suggested change
- **Python/FastAPI** (`python/`) — All AI orchestration, PCNA engine, agent lifecycle, billing, heartbeat scheduler. Validates `x-a0p-internal` on every request.
- **Python/FastAPI** (`python/`) — All AI orchestration, PCNA engine, agent lifecycle, billing, heartbeat scheduler. Validates `x-a0p-internal` on protected/internal routes; the open paths `/api/health` and `/api/v1/guest/chat` are explicitly exempt.

Copilot uses AI. Check for mistakes.
- **Vite** — Dev only; proxied by Express.

### Frontend (Metadata-Driven Console)

`client/src/hooks/use-ui-structure.ts` polls `GET /api/v1/ui/structure`, which aggregates `UI_META` from every Python route module. The console (`client/src/pages/console.tsx`) renders tabs from this structure:

- Tabs listed in `CUSTOM_TAB_RENDERERS` → custom React component
- All other tabs → generic `TabRenderer` (schema-driven via `DATA_SCHEMA`)
Comment on lines +57 to +60

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section states the UI structure "aggregates UI_META from every Python route module" and that non-custom tabs render via TabRenderer "schema-driven via DATA_SCHEMA". In the codebase, GET /api/v1/ui/structure returns sections directly from UI_META (plus WS module UI metas), and the React TabRenderer renders tab.sectionsDATA_SCHEMA isn’t used by the frontend renderer. Please adjust the wording to reflect that UI_META.sections drives the generic tab UI.

Suggested change
`client/src/hooks/use-ui-structure.ts` polls `GET /api/v1/ui/structure`, which aggregates `UI_META` from every Python route module. The console (`client/src/pages/console.tsx`) renders tabs from this structure:
- Tabs listed in `CUSTOM_TAB_RENDERERS` → custom React component
- All other tabs → generic `TabRenderer` (schema-driven via `DATA_SCHEMA`)
`client/src/hooks/use-ui-structure.ts` polls `GET /api/v1/ui/structure`, which returns tab structure assembled from module `UI_META` (including WS module UI metadata). The console (`client/src/pages/console.tsx`) renders tabs from this structure:
- Tabs listed in `CUSTOM_TAB_RENDERERS` → custom React component
- All other tabs → generic `TabRenderer` driven by `tab.sections` from `UI_META.sections`

Copilot uses AI. Check for mistakes.

The **console-tab regression guard** (`scripts/check-console-tabs.mjs`) and e2e test (`tests/e2e/console-tabs.spec.ts`) enforce that every API-declared tab has either a custom renderer or sections. CI blocks deploy on failure.

### Python Route Modules

Each route file in `python/routes/` is self-declaring: it exports a FastAPI `router` and defines `UI_META`/`DATA_SCHEMA` at the top. **Adding a new route requires 4 edits to `python/routes/__init__.py`**:
1. Import the router
2. Add to `ALL_ROUTERS`
Comment on lines +66 to +68

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This claims each python/routes/* file defines UI_META/DATA_SCHEMA and that adding a new route requires 4 edits to python/routes/__init__.py. However, there are registered routes like founders.py, admin.py, and guest.py that do not define UI_META/DATA_SCHEMA, and they are not included in the collect_ui_meta()/collect_doc_meta() lists. Please clarify that the extra registration steps apply only to routes that should appear in the console UI and/or docs aggregation.

Suggested change
Each route file in `python/routes/` is self-declaring: it exports a FastAPI `router` and defines `UI_META`/`DATA_SCHEMA` at the top. **Adding a new route requires 4 edits to `python/routes/__init__.py`**:
1. Import the router
2. Add to `ALL_ROUTERS`
Each route file in `python/routes/` exports a FastAPI `router`. Routes that should appear in the metadata-driven console UI and/or docs aggregation are additionally self-declaring: they define `UI_META`/`DATA_SCHEMA` at the top and are included in the metadata collectors in `python/routes/__init__.py`.
**Adding a new route always requires 2 router-registration edits to `python/routes/__init__.py`**:
1. Import the router
2. Add to `ALL_ROUTERS`
**If the route should also appear in the console UI and/or aggregated docs, make 2 additional metadata-registration edits**:

Copilot uses AI. Check for mistakes.
3. Add filename to `collect_doc_meta()` file list
4. Add module name to `collect_ui_meta()` module list

File naming convention: `{name}.py` = self-contained module; `{name}_api.py` = thin delegate to a service in `python/services/`.

### Key Python Services

- `python/services/inference.py` — Orchestrates LLM calls across registered energy providers; injects tier-specific `prompt_context`
- `python/services/heartbeat.py` — 30-second tick: audit snapshots, memory checkpoints, PCNA propagation, sub-agent cleanup

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heartbeat description implies a 30-second tick that performs specific work like sub-agent cleanup. In python/services/heartbeat.py, the tick interval is 30s, but individual tasks run on longer per-task intervals (e.g., propagate 120s, snapshot 600s, audit 300s, conversation review 21600s), and there’s no explicit “sub-agent cleanup” task listed. Consider updating this bullet to match the actual scheduled tasks/intervals.

Suggested change
- `python/services/heartbeat.py` — 30-second tick: audit snapshots, memory checkpoints, PCNA propagation, sub-agent cleanup
- `python/services/heartbeat.py` — 30-second scheduler tick that runs maintenance tasks on their own intervals, including PCNA propagation, snapshots/checkpoints, audits, and conversation review

Copilot uses AI. Check for mistakes.
- `python/services/tool_executor.py` — Tool invocation with approval gates
- `python/engine/pcna.py` — Six-ring PCNA inference pipeline (Phi/Psi/Omega/Guardian/Memory-L/Memory-S); six steps: Project → Inject → Propagate → PTCA-seed → PTCA-circle → Coherence
- `python/services/edcm.py` — Behavioral directive scoring (CM, DA, DRIFT, DVG, INT, TBF); fires corrective actions (coherence_lock, drift_correction, divergence_dampen, etc.)
- `python/engine/sigma.py` — SigmaCore: encodes the workspace filesystem as a prime-ring tensor; companion to the Psi ring; has its own console tab (`SigmaTab`)

### Database

Schema source of truth is `shared/schema.ts` (Drizzle ORM); applied via `npm run db:push`. Python accesses the same PostgreSQL database via SQLAlchemy async (`python/database.py`, `python/models.py`).

### Auth & Tiers

Auth is handled entirely by Express. Tiers (Free → Seeker → Operator → Patron → Founder Lifetime) are stored on the user record, updated via Stripe webhook (`python/routes/billing.py`), and injected into the LLM system prompt as `prompt_context`.

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tier list here ("Free → Seeker → Operator → Patron → Founder Lifetime") doesn’t match the tiers used in the current codebase (free, supporter, ws, admin), and python/routes/founders.py is marked as retired after tier simplification. Please update this section to reflect the actual tier names and how they’re assigned (Stripe sets supporter; ws may be auto-promoted for specific email domains; admin is role/email based).

Suggested change
Auth is handled entirely by Express. Tiers (Free → Seeker → Operator → Patron → Founder Lifetime) are stored on the user record, updated via Stripe webhook (`python/routes/billing.py`), and injected into the LLM system prompt as `prompt_context`.
Auth is handled entirely by Express. The current user tiers are `free`, `supporter`, `ws`, and `admin`, stored on the user record and injected into the LLM system prompt as `prompt_context`. Stripe billing/webhooks set `supporter` (`python/routes/billing.py`); `ws` may be auto-promoted for specific email domains; and `admin` is assigned via role/email-based checks.

Copilot uses AI. Check for mistakes.

## Conventions

- **File annotation** — Every file opens/closes with `// N:M` or `# N:M` (code:comment ratio). Run `python scripts/annotate.py` after edits.
- **Python route DOC blocks** — Each route file includes `# DOC module:`, `# DOC label:`, `# DOC description:`, `# DOC tier:`, `# DOC endpoint:` headers.
- **No file over 400 lines** — Annotation warns; split before it triggers CI.
- **All frontend `/api/*` calls go through Express on :5000** — never call Python :8001 directly.
- **Dynamic SQL UPDATE** — Use the column allowlist pattern already established in the codebase.

## Key Files

- `replit.md` — Platform overview and user preferences
- `DEPLOYMENT.md` — GCP/Cloud Run setup and secrets
- `spec.md` — Full agent platform spec (PCNA, EDCM, sentinel channels)
- `.agents/skills/a0p-module-doctrine/SKILL.md` — Authoritative module conventions
- `python/routes/__init__.py` — Module registration (edit when adding routes)
- `client/src/pages/console.tsx` — `CUSTOM_TAB_RENDERERS` map and tab rendering logic
- `.github/workflows/deploy.yml` — CI pipeline (regression guard → deploy)

## Environment Variables

Required in production (dev has safe fallbacks except where noted):

```bash
SESSION_SECRET # Express session encryption (no fallback in prod)
INTERNAL_API_SECRET # Express→Python shared secret (random per-process in dev — use start-dev.sh)
DATABASE_URL # PostgreSQL connection string
XAI_API_KEY # Grok 4 Fast (reasoning) — one of the registered energy providers
STRIPE_SECRET_KEY # Stripe billing
STRIPE_WEBHOOK_SECRET # Stripe webhook validation
ADMIN_USER_ID # User ID allowed to write prompt contexts
```
Comment on lines +111 to +121

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Required in production” env var list looks inaccurate/incomplete: the app uses multiple provider keys (e.g., OPENAI_API_KEY, GEMINI_API_KEY, ANTHROPIC_API_KEY, XAI_API_KEY) depending on which energy providers you enable, and Stripe keys are only needed if billing is enabled. Also, ADMIN_USER_ID is declared in python/routes/contexts.py but not used for authorization (admin access is checked via role/email/admin_emails), while ADMIN_EMAIL is used but not listed here. Please update the list and indicate which variables are truly required vs optional/feature-gated.

Copilot uses AI. Check for mistakes.
Loading