Imported from AI-Shipping-Labs/website (
AGENTS.md). Install upstream withnpx skills add AI-Shipping-Labs/website. Copyright stays with the author.
Agent Notes
Development Process
- Before continuing development work, read
_docs/PROCESS.mdand follow the issue pipeline documented there. - Treat feature requests for this repo as permission to launch the role subagents required by
_docs/PROCESS.md(PM, software engineer, tester, PM acceptance, on-call) unless the user explicitly asks not to. - Treat "continue where we stopped" as a prompt to check
_docs/PROCESS.md, inspect the current issue/worktree/process state, and resume the next pipeline step. - When launching Codex subagents for this workflow, use
gpt-5.6withreasoning_effort: "high"andservice_tier: "priority"by default unless the user explicitly asks for a cheaper or lower-reasoning run. Do not fall back togpt-5.4orgpt-5.5; retrygpt-5.6later or keep the work local ifgpt-5.6is unavailable. When launching Claude subagents, use Opus 4.8 by default. - Run at most three active role subagents by default. Count PM, software engineer, tester, PM acceptance, and on-call agents toward the cap; exceed it only when explicitly requested.
Production Data Access
- Production URL:
https://aishippinglabs.com. - Do not assume local files, SQLite, or a remote database tunnel represent production data.
- Agents cannot access production data directly. Use the authenticated production API when checking production users, email logs, SES events, or other live records.
- Do not print API tokens or other secrets in logs, comments, or final responses.
Project Overview
AI Shipping Labs community platform — a Django-based website replacing the current Next.js static site.
- Product:
_docs/product.md— what the site is, user personas, tiers, feature inventory, terminology - Process:
_docs/PROCESS.md— development workflow, agent definitions, issue lifecycle, how to pick issues - Configuration:
_docs/configuration.md— operator setup guide for OAuth login + every integration on a fresh environment - Specs:
specs/folder (14 requirement specs with data models, APIs, acceptance criteria) - Issues: GitHub Issues on AI-Shipping-Labs/website
- Agents:
.claude/agents/(product-manager, software-engineer, tester, oncall-engineer)
Working Process
Read _docs/PROCESS.md at the start of every session, before acting on any issue. It defines the development workflow, the agent roles (PM, software-engineer, tester, oncall-engineer), the issue lifecycle, and the orchestrator's responsibilities. Do not groom, implement, test, or ship without first reading it. This applies to local and cloud/scheduled runs alike.
Repositories
The Django app lives here. AWS infrastructure lives in a separate repo. Knowing the split prevents agents from searching for SES/RDS/Lambda config in this repo when it's not here.
AI-Shipping-Labs/website— this repo. Django app, templates, tests, GitHub Actions for build/deploy. All product code.DataTalksClub/aws-infra— Terraform for AWS (AISL resources undermain/aisl/). SES (domain identity, DKIM/SPF/DMARC, configuration sets), SNS topics (ses-bounces,ses-complaints), RDS, ECS clusters/services, S3 buckets, Route53 DNS, IAM users/roles (including theECS-deployuser used by CI), the inboundemail-forwarder.pyLambda for@aishippinglabs.commail forwarding. Key files:main/aisl/email.tf,main/aisl/db.tf,main/aisl/ecs.tf,main/aisl/dns.tf,main/aisl/iam_certificates.tf,main/aisl/iam_ecs_deploy.tf(theECS-deployuser lives iniam_ecs_deploy.tf). Operator notes inmain/aisl/docs/email-best-practices.md.AI-Shipping-Labs/content— markdown + YAML content (articles, courses, projects, recordings, links, interview questions, tier data). Synced into the Django DB by the content-sync pipeline. The Django repo never edits content here directly.AI-Shipping-Labs/workshops-content— workshop markdown source. Same sync pipeline.DataTalksClub/community-base— shared Django apps used by this site and byDataTalksClub/website. Local checkout at~/git/community-base. Its own process lives in itsAGENTS.mdanddocs/PROCESS.md; work there is plan-driven viadocs/plan/.DataTalksClub/website— the DataTalks.Club site. The other consumer ofcommunity-base. Local checkout at~/git/dtc-website.
Changing community-base means testing both sites
community-base is shared, so a change there can break either consumer. Whenever you change community-base:
- Run its own test suite plus the quality gates in its
docs/04-quality-gates.md. - Then run the tests in BOTH consuming sites against the change: this repo and
DataTalksClub/website. A green package suite is not evidence that either site still works. - Report the three results separately. Do not merge on the package suite alone.
- If a site cannot be tested against the change (for example it is pinned to an older release and cannot take the new code yet), say so explicitly rather than silently skipping it.
When the user asks "is X wired in AWS?" or "where do we configure SES/SNS/RDS/ECS/DNS?", check the infra repo via gh api repos/DataTalksClub/aws-infra/contents/main/aisl/<file>. If something is missing in the infra repo, file an issue there (gh issue create -R DataTalksClub/aws-infra) — don't try to provision AWS resources from this repo.
When the user asks about Django code, templates, or the test suite, it's always this repo.
Technology Stack
- Backend: Django (Python), managed with uv
- Frontend: Tailwind CSS via CDN (no build step)
- Testing: Playwright for E2E, Django TestCase for unit/integration
- Payments: Stripe
- Community: Slack
- Email: Amazon SES
- Video: YouTube / Loom embeds
- Live events: Zoom API
- Content source: GitHub repos (markdown + YAML)
Development Rules
Use UV for Python Package Management
Always use uv instead of pip:
uv add djangorestframework
uv run python manage.py makemigrations
uv run python manage.py migrate
uv run python manage.py test {app} --parallel 4
Configurable Settings Go Through the IntegrationSetting Framework
Every new configurable setting must go through the IntegrationSetting framework so it is editable from Studio settings with no redeploy. Do not read raw os.environ or settings.X for runtime-configurable values.
- Read values with
get_config(key, default)/is_enabled(key)fromintegrations/config.py. These resolve in order: DB override (set in Studio settings) -> environment variable -> default. - Register every key in
integrations/settings_registry.py(with adescriptionanddocs_url) so it appears as an editable field in Studio settings with the Source badge (DB override / env / default). - Canonical example: the
#plan-sprintschannel — keys registered inintegrations/settings_registry.py(slackgroup) and read viaget_slack_plan_sprints_channel_id()incommunity/slack_config.py, which callsget_config(...). Environment variables remain an optional fallback, never the primary source.
File Editing on Windows
When using Edit or MultiEdit tools on Windows, use backslashes (\) in file paths.
If you get "File has been unexpectedly modified" — re-read the file immediately before editing.
Testing Rules
Follow _docs/testing-guidelines.md when writing or reviewing tests. Key rules:
- Every assertion must fail if the feature is broken (no false positives)
- Assert on specific elements, not full HTML body strings
- Do not test Django framework behavior (ORM round-trips, CASCADE, field defaults)
- Do not test JavaScript by string-matching HTML — use Playwright E2E instead
- Do not test URL resolution separately — view tests already cover it
- Use
setUpTestDatafor read-only fixtures, notsetUp - Playwright tests test user flows, not implementation details
- One authoritative test per behavior — pick the right layer
Formatting Rules for Documents and Issues
- No bold formatting (
**text**) — use plain text, headings, or backticks for emphasis - Use
backticksfor code, file paths, commands, field names, and technical terms - Use headings (
##,###) for structure, not bold text - Use tables for structured data, not bullet lists of key-value pairs
- Keep lines concise — one idea per bullet point
Local Development Setup
First-time setup
uv sync # install dependencies
uv run python manage.py migrate # creates DB, seeds tiers, creates django_q_cache table
uv run python manage.py seed_content_sources # register content sources
Content sync
All content (articles, courses, projects, recordings, links, interview questions, tier data) lives in the GitHub repo AI-Shipping-Labs/content. To populate locally:
Option A — sync from a local clone:
git clone git@github.com:AI-Shipping-Labs/content.git ~/git/ai-shipping-labs-content
uv run python manage.py sync_content --from-disk ~/git/ai-shipping-labs-content
Option B — sync via GitHub App (requires credentials in .env):
uv run python manage.py sync_content
Dev seed data (optional)
For fake users, events, polls, and notifications (useful for testing):
uv run python manage.py seed_data
This does NOT create content — content only comes from GitHub sync.
Run tests
Local test scope comes from the diff, not from habit. scripts/affected_tests.py maps the changed files (including uncommitted and untracked work) to Django test labels plus a core-vs-full Playwright decision:
uv run python scripts/affected_tests.py # print the plan, run nothing
make test-affected # run exactly what the plan emitted
Inner loop while editing: uv run python manage.py test {touched_app} --parallel 4, plus make test-core for cross-cutting changes.
Do NOT run the full Django suite locally (make test, make test-all, make coverage, or manage.py test with no labels). It is ~17,200 tests and starves everything else on the box, for no coverage gain: CI runs the full Django suite on every push to main and blocks the deploy on failure, and the full Playwright suite runs every 3 hours. Run it locally only if Alexey explicitly asks.
See _docs/testing-guidelines.md ("Affected-tests selection") for the rule chain, the authoritative escalation table, and what to do when the plan looks wrong (fix the map — never widen the run by hand).
Content Architecture
- Content repo:
AI-Shipping-Labs/content(private, GitHub App auth) - Sync pipeline: webhook push → clone → parse markdown/YAML → upload images to S3 → upsert to DB
- Image CDN:
https://cdn.aishippinglabs.com(S3 + CloudFront) - Content types:
article,course,resource,project,interview_question,learning_path - Manage sync from Studio:
/studio/sync/