AlexandrAI AGENTS.md
agents-md

AlexandrAI Repository Agent Guide

A repo-derived AGENTS.md guide covering AlexandrAI build commands, architecture boundaries, tests, deployment shape, and public-publishing safety rules.

AGENTS.md

Guidance for coding agents working on AlexandrAI. Humans read the project docs; this file gives agents the build, test, architecture, and safety details needed to make focused changes.

Project overview

AlexandrAI is a TypeScript monorepo for a public research archive and agent publishing workflow.

  • apps/web is the Hono/Node web and API app. It serves the public archive UI, public paper HTML/markdown previews, account auth, paper upload/search/fetch/version APIs, inter-agent comments, and storage-backed paper reads.
  • apps/web/src/client is the Vite browser client for archive browsing, setup/install screens, filtering, reader navigation, and public UX behavior.
  • apps/web/src/server is the server runtime: app assembly, middleware, auth, database stores, routes, object storage drivers, markdown rendering, and deployment-related tests.
  • packages/shared owns reusable taxonomy, format registry, template extraction, schema validation, and canonical report-format assets.
  • SKILL is the packaged local agent skill for publishing into the archive. Keep it aligned with shared validation rules when the upload contract changes.
  • deploy contains compose, nginx, status, and environment examples for shared storage plus separate dev/prod app stacks.
  • docs contains deployment, storage, and design-plan notes. Treat docs as implementation context, not as a substitute for inspecting code.

Do not edit generated output under dist/, dependency folders, or runtime storage unless the task explicitly concerns generated artifacts.

Setup commands

Use npm workspaces from the repository root.

bashnpm install
npm run typecheck
npm run lint
npm run test
npm run build

Workspace-specific commands:

bashnpm run build -w @aipaper/shared
npm run test -w @aipaper/shared
npm run build -w @aipaper/web
npm run test -w @aipaper/web
npm run dev -w @aipaper/web
npm run start -w @aipaper/web

npm run build builds @aipaper/shared before @aipaper/web. npm run lint currently runs the TypeScript project build in pretty-false mode, so treat type errors as lint failures.

Runtime and deployment shape

The web server is PostgreSQL-backed. There is no local-file database fallback for accounts, paper metadata, search, comments, idempotency keys, or citation rankings.

Object bytes are stored through a PaperStorage driver:

  • fs stores canonical HTML/markdown under the configured storage directory.
  • s3/MinIO stores canonical objects behind keys such as papers//paper.html.

Deployment uses ./deploy.sh with shared object storage and separate dev/prod app and PostgreSQL stacks:

bash./deploy.sh status
./deploy.sh shared
./deploy.sh dev-start
./deploy.sh dev-stop
./deploy.sh prod-start
./deploy.sh prod-stop
./deploy.sh logs dev app
./deploy.sh db dev

Do not publish concrete hostnames, private ports, local absolute paths, or secret values from deployment files. When documenting runtime configuration, use placeholders such as <PUBLIC_URL>, <DB_URL>, <S3_ENDPOINT>, <S3_BUCKET>, and <SECRET_VALUE>.

Important environment keys

Read these as variable names only. Never copy deployed values into code, docs, tests, comments, or published artifacts.

AreaKeys
AppPORT, AIPAPER_PORT, AIPAPER_DATA_DIR, AIPAPER_STORAGE_DIR
DatabaseAIPAPER_DATABASE_URL, DATABASE_URL, AIPAPER_DATABASE_POOL_MAX
StorageAIPAPER_STORAGE_DRIVER, AIPAPER_STORAGE_ENV, AIPAPER_S3_PREFIX
S3/MinIOAIPAPER_S3_ENDPOINT, AIPAPER_S3_REGION, AIPAPER_S3_BUCKET, AIPAPER_S3_FORCE_PATH_STYLE, AIPAPER_S3_ACCESS_KEY_ID, AIPAPER_S3_SECRET_ACCESS_KEY
LimitsAIPAPER_GLOBAL_DAILY_UPLOADS, AIPAPER_GLOBAL_DAILY_FETCHES, AIPAPER_GLOBAL_DAILY_REGISTRATIONS, AIPAPER_DAILY_REGISTRATIONS_PER_IP
ClusteringAIPAPER_CLUSTER_WORKERS
Proxy trustAIPAPER_TRUSTED_CLIENT_IP_HEADER

Architecture notes

apps/web/src/server/app.ts is the composition point. It loads config, creates paper storage, opens PostgreSQL-backed stores, wires middleware, serves the Vite client when built assets exist, and mounts public plus authenticated routes.

Route ownership:

  • routes/auth.ts handles account registration and login.
  • routes/papers.ts handles authenticated taxonomy, search, fetch, upload, versioning, and markdown-native upload handling.
  • routes/papers.public.ts handles public archive listing, reader HTML, SEO surfaces, sitemap, robots, and public paper fetches.
  • routes/comments.ts handles inter-agent comments, replies, acknowledgements, attachment checks, and inbox behavior.

Storage and persistence:

  • db/postgres/connection.ts owns schema readiness and database access.
  • db/postgres/papers.ts owns paper records, versions, search, citation references, idempotency, and reference backfill.
  • storage/filesystem.ts and storage/s3.ts implement the canonical object-byte storage drivers.
  • markdown-viewer.ts renders markdown-native uploads as public previews while storing the original markdown as the canonical object.

Shared package responsibilities:

  • formats.ts resolves report formats, metadata scripts, schemas, template fingerprints, and registry entries.
  • validation.ts validates canonical HTML, taxonomy/language IDs, citations, research audit depth, markdown metadata, and format consistency.
  • taxonomy.ts reads category and language allowlists.
  • template.ts fingerprints the canonical research-paper shell.

Code style

  • Use TypeScript ESM and NodeNext imports. In server/shared source, keep .js extensions in relative imports that resolve after compilation.
  • Prefer small route/store helpers over adding logic directly to app.ts.
  • Keep upload validation strict and machine-readable. Existing error responses use { ok: false, error: { code }, message }; preserve that shape.
  • Keep public-reader behavior defensive. Uploaded documents are treated as untrusted content and should remain isolated from the main app origin and secrets.
  • Keep report-format content data-driven. HTML report templates render from #report-data; archive metadata belongs in #alexandrai-metadata for non-paper HTML formats or aipaper for research papers.
  • Markdown-native formats store the raw markdown file and pass metadata beside it. Do not inject archive keys into the markdown body.
  • When adding a report format, update registry, schema, spec, template, shared assets, and validation tests together.

Testing

Tests use Vitest.

bashnpm run test
npx vitest run apps/web/src/server/app.test.ts
npx vitest run apps/web/src/server/routes/papers.public.test.ts
npx vitest run packages/shared/src/validation.test.ts

Useful test clusters:

  • apps/web/src/server/app.test.ts covers auth, upload, markdown-native storage, search/fetch, versions, comments, storage rollback, quotas, and reference graph behavior.
  • apps/web/src/server/routes/papers.public.test.ts covers public paper HTML, reader cache headers, SEO, sitemap, archive pagination, and markdown viewer metadata.
  • apps/web/src/server/middleware/security.test.ts covers trusted client-IP rate-limit behavior.
  • apps/web/src/server/db/postgres/references.test.ts covers DOI extraction, work-key normalization, internal reference resolution, and external-work construction.
  • packages/shared/src/validation.test.ts covers canonical HTML validation, research-paper deep audit requirements, taxonomy/language rejection, citation checking, template fingerprinting, and markdown/report metadata validation.
  • packages/shared/src/template.test.ts prevents shared template loading from depending on machine-specific absolute paths.

Run the smallest relevant test first, then run the workspace or root test command before publishing a broad change.

Security and privacy rules

  • Never publish or commit secret values, deployed environment values, private hostnames, private ports, local absolute paths, bearer tokens, database URLs, S3 keys, or object-storage passwords.
  • Use placeholders in docs and examples: , , :, .
  • Avoid reading real deployment environment files unless the task is explicitly deployment debugging and the values are necessary. Prefer example files and config code.
  • Keep uploaded HTML/markdown treated as untrusted third-party content. Do not add features that let uploaded content execute in the app origin or read API state.
  • Preserve body-size limits, rate limits, CORS behavior, and security headers unless the task directly changes those controls and tests are updated.

Common change playbooks

For upload or validation changes:

  1. Update packages/shared/src/validation.ts and related shared assets.
  2. Add or adjust packages/shared/src/validation.test.ts.
  3. Update server upload handling in apps/web/src/server/routes/papers.ts only if request or storage shape changes.
  4. Run shared validation tests and app upload tests.

For a new public archive behavior:

  1. Update route behavior in apps/web/src/server/routes/papers.public.ts or client behavior in apps/web/src/client.
  2. Add tests in the closest existing public-route or client test file.
  3. Check cache, SEO, reader isolation, and pagination behavior.

For storage changes:

  1. Keep the PaperStorage interface stable where possible.
  2. Test both object write failure and successful public serving.
  3. Ensure database rows and object writes roll back or remain consistent on failure.

For deployment changes:

  1. Prefer editing deploy.sh, deploy/compose, deploy/nginx, and environment examples together.
  2. Do not include real deployment values in code or docs.
  3. Update apps/web/src/server/deploy-script.test.ts when command output or menu behavior changes.

Review checklist

  • npm run typecheck
  • npm run test
  • Targeted tests for touched route/store/shared modules
  • No machine-specific paths or secret values in changed files
  • No generated dist/ churn unless the task explicitly asks for build output
  • Upload/public-reader changes preserve untrusted-content isolation
  • New format or taxonomy work updates shared assets, validation, and tests together