Universal manifest for any AI coding agent working in this repo (Claude Code, Cursor, Codex, Aider, Cline, etc.). Tool-specific extensions live in their own files:
CLAUDE.mdfor Claude Code,.cursorrulesfor Cursor, etc. Don't duplicate this content there — import or link.
POLLMEVALS — open evaluation platform for full LLM stacks (model + agent CLI + skills + memory + validator), not just raw models. Goal: prove with numbers that a cheap model with the right scaffolding often beats an expensive one without it.
Language: code/identifiers/commits in English (Conventional Commits). Russian acceptable in commit body when it adds clarity.
Status: v0.0 pre-launch — documentation + contracts ready, no executable code yet. Next: smoke run (3 tasks × 5 models × 3 seeds = 45 evals) per docs/04-runbook/12-first-smoke-run-playbook.md.
Stack: monorepo (TypeScript product plane + Python eval plane, future Rust sandbox) · pnpm + uv · Vitest + pytest · Moon (workspace) · Node 22+ / Python 3.12+.
- Destructive git (
push --force,reset --hard, branch/tag deletion,rebase -ion shared history) — only after explicit confirmation. Full rules →guides/GIT-FLOW-GUIDE.ru.md§7. - No secrets in git —
.env, tokens, API keys, certificates. Rungit statusbeforegit add..forgeplan/config.yamlmust useapi_key_env: VAR_NAME, never literalapi_key: "sk-...". If a literal key landed: rewrite, revoke the leaked key, force-push only the fix commit (with confirmation). - No bypass of branch protection —
mainmerges only via PR. No direct push. - No
forgeplanartifact direct edits —.forgeplan/{prds,rfcs,adrs,specs,epics,evidence,problems,solutions,refresh,notes,memory}/*.mdand.forgeplan/state/*.yamlare managed by the CLI/MCP only. Useforgeplan update/new/link/activate/deprecate. Direct edit is OK only for non-forgeplan markdown (READMEs, this file, src code). - No mutation of completed run results (ADR-0002 immutability) —
evals[].final_score,artifacts/runs/<hash>/*and DB rows for completedrunsare write-once. Errors → new run +supersedeslink. - No long/expensive operations (deploy, DB migrations, mass network/LLM calls, weekly run trigger) without explicit confirmation. Weekly eval run = $100-200 in inference.
- No rewriting other people's history — if
git logshows commits not yours in a range, norebase/amend/resetover it.
pnpm install && uv sync # install (TS + Python)
moon run :build # build all projects
moon run :test # test all projects
moon run :lint # lint / typecheck all projectsRun the full check (build + test + lint), not the happy path only. Per-project shortcuts → docs/agents/build-config.md.
- Branches:
feat/*/fix/*/chore/*/docs/*→dev(or default branch) →main. No direct commits tomain. - Commits — Conventional Commits (
feat:,fix:,refactor:,test:,docs:,chore:). Body imperative, why over what. Reference artifacts:Refs: prd-<slug>(before merge) orRefs: PRD-NNN(after merge). - PR titles — Conventional Commits + artifact ID where applicable:
feat(scope): add OAuth2 (PRD-042). - Merge strategy — merge commit (preserves history). Squash only for noisy WIP branches when explicitly requested.
- No
git add ./git add -A— stage specific files. Prevents accidentally committing.env, lockfile drift, or stray editor files. - No
--no-verify— fix the underlying issue, never bypass hooks.
Safety table (full version → guides/GIT-FLOW-GUIDE.ru.md §7.1):
| Command | Why dangerous | Safe alternative |
|---|---|---|
git reset --hard |
destroys uncommitted work | git stash or git branch backup/... first |
git push --force |
rewrites remote history | --force-with-lease + own feature branch only |
git branch -D <name> |
deletes unmerged | git branch -d (refuses if unmerged) |
git clean -fd |
nukes untracked | git clean -n (dry-run) first |
git commit --amend after push |
rewrites published | new commit fix: ... |
rm -rf .git |
destroys history | never |
- Naming: files
kebab-case, identifierscamelCase(TS) /snake_case(Python), types/classesPascalCase. - Comments: only where why isn't obvious. No "added for #123" — that belongs in the commit message.
- Tests: every public function gets at least a happy-path test plus edge cases that matter for callers.
- Errors: validate at boundaries (user input, external APIs). Trust internal code — don't add defensive checks for impossible states.
- No premature abstraction: three similar lines beat a wrong abstraction. Wait until you have three real call sites before extracting.
- Strict mode on (
strict: true). Noany— useunknown+ narrowing. Noascasts unless verified at a system boundary.!non-null assertions only after a guard expression.
- Type hints on all public APIs. Pydantic models at boundaries.
mypy --strictclean before commit.ruff format+ruff check.
🔴 Don't write your own from scratch if a library exists. Before implementing any component — evaluator, metric, linter, scanner, parser, formatter, retry logic, queue, cache, validator, etc. — search for an existing solution first.
Pipeline for every "I'll implement X":
- Library lookup first (Context7 / npm / PyPI / WebSearch). Find a battle-tested option.
- Pin version + cite source.
radon>=6,<7, notradon. Mention in commit:feat: cyclomatic eval via radon>=6.0. - Wrap, don't replace. If the library API doesn't fit perfectly — thin adapter under a Protocol seam (e.g.
EvalCaller-style). Don't rewrite functionality. - Custom code only when: library missing / abandoned (>2yr no commit) / incompatible license / trivially wrappable (<20 lines).
Canonical libraries for POLLMEVALS metrics (full table in NOTE-004 §5):
| Metric | Library |
|---|---|
| cyclomatic | radon (Py), lizard (multi), eslint --max-complexity (TS) |
| coverage | coverage (Py), c8 (Node), vitest --coverage |
| lint | ruff (Py), eslint (TS), clippy (Rust) |
| type safety | mypy --strict (Py), tsc --strict (TS) |
| security | bandit, semgrep, trivy, pip-audit, npm audit, gitleaks |
| docstring | interrogate (Py), jsdoc-coverage (TS) |
| profiling | cProfile + pyinstrument (Py), clinic.js (Node) |
| α agreement | krippendorff (PyPI) |
| async retry | tenacity (Py), p-retry (Node) — NOT manual catch+sleep |
| HTTP | httpx (Py), axios/undici (Node) |
| validation | pydantic v2 (Py), zod (TS) |
| LLM eval | Inspect AI (Py, per EVID-004) |
Anti-patterns to refuse:
- "I'll write my own cyclomatic counter — only 50 lines" → NO, use
radon/lizard. - "Custom retry decorator with exponential backoff" → NO, use
tenacity/p-retry. - "Hand-rolled YAML parser" → NO, use
ruamel.yamlorPyYAML. - "My own Krippendorff α impl" → NO, use the
krippendorffPyPI package. - "Hardcoded model pricing dict" → NO, use
litellm.cost_per_token().
Exception: domain-specific orchestration (GridRunner, JudgePanel, JournalWriter manifest immutability) — our uniqueness, custom code justified. Even there — use library primitives inside (httpx, asyncio, pydantic).
- Default to non-destructive operations. When unsure, list intended changes and ask once.
- Refuse red-line actions above, surface the rule.
- When
forgeplan healthreports stubs/orphans/duplicates — note them, don't auto-fix unless that's the explicit task. - Match scope to request: a bug fix doesn't need surrounding cleanup; one-shot operations don't need helpers.
- Don't write feature flags, backwards-compat shims, or "for future use" abstractions unless asked.
- Terminology precision: don't sprinkle specialised terms ("hexagonal", "monadic", "idempotent", "bounded context") unless you can map the meaning to current context. Plain words first; cross-reference official term only if sure.
- Methodology is frozen (
docs/02-methodology/v0.1.0) — changes go through ADR, not direct edits.
moon run :build— clean build, no warnings.moon run :test— all tests pass.moon run :lint— no lint errors.forgeplan health— no new orphans/stubs/duplicates.git status— only intended files staged; no.env, no editor files, no lockfile drift.git diff --stat origin/main..HEAD— diff matches PR scope claim.
If any step fails, fix it. Never --no-verify the pre-commit hook.
.forgeplan/ mixes tracked artifacts (source of truth) with derived / runtime state. Full setup contract → plugins/fpl-skills/skills/bootstrap/resources/guides/FORGEPLAN-SETUP.md (read for the complete reference).
.forgeplan/ ← managed by CLI/MCP, mostly tracked
├── prds/ ← TRACKED — product requirements
├── rfcs/ ← TRACKED — architecture proposals
├── adrs/ ← TRACKED — decisions (with valid_until TTL)
├── specs/ ← TRACKED — API / data-model contracts
├── epics/ ← TRACKED — groupings of PRD[]/RFC[]
├── evidence/ ← TRACKED — measurements / tests / audits
├── problems/ ← TRACKED — problem cards
├── solutions/ ← TRACKED — solution portfolios
├── refresh/ ← TRACKED — re-evaluation of stale ADRs
├── notes/ ← TRACKED — micro-decisions (90-day TTL)
├── memory/ ← TRACKED — typed memory (fact/convention/constraint/observation/procedure)
├── state/ ← TRACKED — lifecycle state machine YAML (one per artifact)
├── config.yaml ← TRACKED — project config (uses api_key_env, never literal keys)
├── .gitignore ← TRACKED — lists what NOT to track
│
├── lance/ ← ❌ gitignored — LanceDB vector index (rebuild via `forgeplan scan-import`)
├── .fastembed_cache/ ← ❌ gitignored — bge-m3 model cache (~600 MB)
├── logs/ ← ❌ gitignored — local audit/ops logs
├── .lock ← ❌ gitignored — runtime mutex
├── session.yaml ← ❌ gitignored — per-machine focus / claim TTLs (NOT shared)
├── trash/ ← ❌ gitignored — soft-deleted artifacts
└── discovery/ ← ❌ gitignored — ephemeral research findings
apps/
├── eval-core-py/ ← Python eval orchestrator (Inspect AI, LiteLLM wrapper)
├── api/ ← Hono TypeScript API
└── site/ ← Next.js 15 public site
packages/
├── contracts/ ← JSON Schemas + TypeScript types
└── db/migrations/ ← SQL migrations (8 tables)
evals/{tasks,task-packs,rubrics,calibration}/
stacks/ ← stack adapter specs
data/ ← sample JSON
infra/scripts/ ← validate-task-specs.py, reproduce-local-run.sh
docs/
├── 00-research/ ← original research (read-only archive)
├── 01-vision/ ← vision, requirements, business
├── 02-methodology/ ← FROZEN v0.1.0 (judge-policy, scoring, sandbox)
├── 03-architecture/ ← system architecture, stack, domain
├── 04-runbook/ ← implementation plan, ops, smoke playbook
├── adr/ ← project ADRs (ADR-0001 hybrid stack, ADR-0002 immutability)
├── visuals/ ← HTML/SVG diagrams
└── agents/ ← per-project metadata read by fpl-skills
CONTEXT.md ← ubiquitous language / domain glossary
.env ← ❌ gitignored — actual secrets
MASTER.md ← linear 151 KB doc, all-in-one navigation
INDEX.md ← file index + migration map
.forgeplan/config.yaml is tracked but contains only the name of the env var holding the API key, never the key itself:
llm:
provider: gemini
model: gemini-2.0-flash-thinking-exp-01-21
api_key_env: GEMINI_API_KEY # ← env var NAME, not the key
max_tokens: 8192
embedding:
model: bge-m3The actual key (GEMINI_API_KEY=AIza...) lives in .env (gitignored), ~/.zshrc, or CI secrets. Forgeplan reads it from process env at runtime.
Pre-commit check — confirm no literal key slipped into config.yaml:
! grep -qE 'api_key:\s*["'"'"']?(sk-|AIza|ant-)[A-Za-z0-9_-]{20,}' .forgeplan/config.yaml \
&& echo "✅ clean" || echo "❌ literal API key — revoke + rewrite to api_key_env"If a literal key was committed: git rm --cached, rewrite to api_key_env, revoke the leaked key (it's already in git history), commit the fix.
FORGEPLAN_LLM_PROVIDER, FORGEPLAN_LLM_MODEL, FORGEPLAN_LLM_BASE_URL, FORGEPLAN_LLM_MAX_TOKENS, FORGEPLAN_LLM_API_KEY_ENV, FORGEPLAN_EMBEDDING_MODEL, FORGEPLAN_STORAGE_DRIVER, FORGEPLAN_STORAGE_PATH, FORGEPLAN_MEMORY_DRIVER.
Priority: env > config.yaml > built-in default.
git clone <repo>
cd pollmevals
forgeplan init -y # creates lance/, .fastembed_cache/, etc.
forgeplan scan-import # rebuilds vector index from markdown
set -a && source .env && set +a # load secrets (or `direnv allow`)
pnpm install && uv sync # install all dependencies (TS + Python)
forgeplan health # verify clean state| Question | File / artifact |
|---|---|
| What we're building as product + CJM (5 stages × 4 personas) + 18 site pages + API contracts | forgeplan get SPEC-002 |
| What's done vs missing from dd.md? Coverage matrix | forgeplan get NOTE-005 |
| Full catalogue: stacks / memory / tools / metrics dimensions | forgeplan get NOTE-004 |
| Anti-gaming + contamination + drift policy | forgeplan get NOTE-006 |
| Original 1785-line TЗ | docs/old/dd.md (read-only seed) |
| Repo file system map | INDEX.md (root) |
| Docs map | docs/INDEX.md |
| Full artifact list | forgeplan list / forgeplan health |
| Domain glossary | CONTEXT.md |
| Artifact | Owns |
|---|---|
| EPIC-001 | v0.1 launch — overall epic ownership, R_eff source-of-truth for project health |
| PRD-001 | Smoke run base — first 45-eval grid contract (3 tasks × 5 models × 3 seeds on raw-llm) |
| PRD-002 | Judge panel methodology — Q1-Q5 decisions (multi_scorer + median + CI gate + degraded + ID probe) |
| PRD-003 | Weekly cadence (draft) — operational reliability, cron, alerting |
| PRD-004 | Public leaderboard MVP (draft) — refined by SPEC-002 |
| PRD-005 | Release pipeline (draft) — assigned_number bot + sync workflow |
| PRD-006 | Tasks catalog expansion — 17 missing tasks roadmap (Waves 1+2+3) |
| RFC-001 | Orchestrator implementation plan on Inspect AI |
| RFC-002 | Judge panel layer implementation (5 Slices A-E) |
| ADR-001 | Concurrency model (semaphore + per-provider rate awareness) |
| ADR-002 | Reproduce semantics — evaluator-only (cached raw_output, never re-fire LLM) |
| ADR-003 | 5-model smoke lineup + provider routing |
| ADR-004 | MoleculerPy as distributed orchestrator (Phase 3+) |
| ADR-005 | Judge score aggregation — median reducer + bootstrap CI lower-bound gate |
| ADR-006 | Phase 1 14-model adoption (Cerebras + Runpod routes + cost matrix) |
| SPEC-001 | Manifest + EvalRow + ArtifactRef contracts |
| SPEC-002 | Product spec + CJM + 18 site pages + API contracts (refines PRD-004) |
| NOTE-001 | Crash recovery (append-only journal + atomic rename) |
| NOTE-002 | Evidence Quality Standard — ADI cycle + Trust Calculus per EVID (mandatory) |
| NOTE-003 | Observability stack seed (LGTM choice for PRD-003+) |
| NOTE-004 | Expanded vision catalog (12 stacks + 9 memory + 4 context + 8 indexing + 10 metrics) |
| NOTE-005 | dd.md ↔ artifacts coverage matrix |
| NOTE-006 | Anti-gaming + contamination program (3 pillars + 3 policy decisions) |
| EVID-001..024 | Per-EVID specifics: prior art audits, Wave EVIDs, smoke run measurements |
Question → Open
─────────────────────────────────────────────────────────────────────
"What are we building as product?" → SPEC-002 (CJM + pages + API)
"What's left to build?" → NOTE-005 (gap matrix)
"Which stacks do we test?" → NOTE-004 §1
"Which models in lineup?" → ADR-003 (smoke 5) + ADR-006 (full 14)
"How do we score quality / cost?" → docs/02-methodology/scoring.md (frozen)
"How does the panel of judges work?" → PRD-002 + RFC-002 + ADR-005
"How do we defend against gaming?" → NOTE-006
"What's the manifest format?" → SPEC-001
"How to reproduce a run?" → ADR-002 + Makefile reproduce target
"What does a specific site page hit?" → SPEC-002 § "API Contracts"
POLLMEVALS evaluates whole scaffolding stacks, not isolated models. The full catalog of agent CLIs (Claude Code, Codex, Aider, Gemini CLI, Cursor, Cline, Pi, Hermes, OpenHands, Plandex, Goose, forgeplan-framework), memory variants (file CLAUDE.md/AGENTS.md, mem0, Letta, Zep, Hindsight, GraphRAG, RAFLOW), context tools (Context7 axis), codebase indexing (Serena, Aider repo-map, Sourcegraph, Cody), and extended metrics dimensions (6 existing + 4 new — docstring_coverage, profile_score, dep_selection_quality, vulnerability_scan_score) is captured in NOTE-004.
Cite NOTE-004, don't repeat the catalog in new artifacts. forgeplan get NOTE-004 is the source of truth. Promote to PRD-006 when 5+ stacks implemented + extended metrics design proven viable.
Phase numbering disambiguation (NOTE-004 §6): codebase uses "Phase 0-5" (infra phases — what to build), research uses "Фаза 1-5" (experiment phases — what to measure). They are different axes — always be explicit which one you mean.
forgeplanCLI — installed at/opt/homebrew/bin/forgeplan(v0.32.1).brew install ForgePlan/tap/forgeplanorcargo install --git https://github.com/ForgePlan/forgeplan forgeplan-cli.- Project decisions —
.forgeplan/adrs/(open*.mdfor context; mutate via CLI/MCP only) +docs/adr/(ADR-0001 hybrid stack, ADR-0002 run immutability). - Methodology canon —
docs/02-methodology/(frozen v0.1.0). Source of truth for scoring formulas, judge policy, sandbox specs. - Implementation playbook —
docs/04-runbook/12-first-smoke-run-playbook.md. Start here for the v0.1 smoke run. - Master doc —
MASTER.md(151 KB, linear). Usedocs/{01..04}/subfolders for targeted reading.
- No human eval in v0.1 — automatic metrics + LLM judges only.
- No paid API until methodology has 2+ public runs with α ≥ 0.70.
- No sponsored evals in v0.x — disclosure policy lands in v1.0.
- No public community proposal flow until v1.0 — adding model/stack/task requires maintainer review.
- No enterprise white-label in v0.x.
- No Rust rewrite of orchestrator before eval protocol stabilises (per ADR-0001).
- No multilingual tasks in v0.x — English only.
CLAUDE.md— Claude Code-specific extensions: session start protocol, forgeplan MCP tooling, fpl-skills slash commands, subagent packs, Hindsight memory,.claude/settings.CONTEXT.md— domain glossary (ubiquitous language).guides/GIT-FLOW-GUIDE.ru.md— full Git Flow + safety rules.guides/CLAUDE-MD-GUIDE.ru.md— how to keep this file andCLAUDE.mdhealthy (U-curve, cry-wolf, dilution).docs/agents/{issue-tracker,build-config,paths,domain}.md— per-area metadata.