Add CLAUDE.md with architecture guide and dev commands - #5
Conversation
|
in accurate |
python/pcna.py and python/engine.py don't exist; the engine lives at python/engine/pcna.py. Also corrects "7 phases" to the actual six-ring, six-step pipeline (Phi/Psi/Omega/Guardian/Memory-L/Memory-S). https://claude.ai/code/session_01PJCxiyuxxA5oLGDBBWsEkX
- inference.py: remove "Grok-3 Mini default" — provider is configurable via energy_registry; actual grok model is grok-4-fast-reasoning, not grok-3-mini - edcm.py: remove "guides LLM selection" — EDCM fires behavioral directives (coherence_lock, drift_correction, etc.), not LLM routing - Add SigmaCore to key services — filesystem prime-ring tensor, custom console tab, companion to the Psi ring; was entirely absent - Update XAI_API_KEY comment to reflect actual model (Grok 4 Fast) https://claude.ai/code/session_01PJCxiyuxxA5oLGDBBWsEkX
|
@copilot |
There was a problem hiding this comment.
Pull request overview
Adds a CLAUDE.md repository guide intended for Claude Code instances, describing local dev/build/test commands plus a high-level architecture and conventions overview for the Express + FastAPI + Vite stack.
Changes:
- Add a new
CLAUDE.mddocumenting common dev/build/db/test commands. - Document the 3-process runtime topology and the metadata-driven console UI.
- Describe key Python route/service conventions and required environment variables.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ``` | ||
|
|
||
| - **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. |
There was a problem hiding this comment.
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.
| - **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. |
| `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`) |
There was a problem hiding this comment.
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.sections—DATA_SCHEMA isn’t used by the frontend renderer. Please adjust the wording to reflect that UI_META.sections drives the generic tab UI.
| `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` |
| ### 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 |
There was a problem hiding this comment.
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.
| - `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 |
| 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` |
There was a problem hiding this comment.
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.
| 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**: |
|
|
||
| ### 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`. |
There was a problem hiding this comment.
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).
| 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. |
| 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 | ||
| ``` |
There was a problem hiding this comment.
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.
…-and-lint-sweep Fix Markdown wrapper, persist active provider to DB, improve CLI host resolution, and add tests
$(cat <<'EOF'
Summary
CLAUDE.mdto provide guidance to Claude Code instances working in this repositoryTest plan
https://claude.ai/code/session_01PJCxiyuxxA5oLGDBBWsEkX
EOF
)