# TODO-0 — Foundation (Claude does this BEFORE the three agents start) Goal: put every shared or locked file in its final shape, so the three agents never edit the same file. When this is done, `dev` has a foundation commit and three worktrees exist. Read `docs/plan/PLAN-v2.md` §4–§6 first. Everything here is mechanical; no product logic. ## F1. Environment - [ ] `pnpm install` at root; `pnpm api:venv`; confirm the baseline: `pytest -q`, `ruff`, `mypy`, `pnpm test`, `tsc`. Record the counts. - [ ] Add API deps to `apps/api/pyproject.toml`: `asyncssh`, `aioftp`, `mcp` (official SDK). Install and re-run the baseline. ## F2. DB foundation (`db/models.py` + migration `a0f0e1d2c3b4_v2_foundation.py`, down_revision `d4e5f6a7b8c9`) - [ ] `projects`: add app-profile columns (all nullable or defaulted): `app_type`, `language`, `framework`, `runtime_version`, `package_manager`, `setup_command`, `build_command`, `test_command`, `start_command`, `app_port` (int), `healthcheck_path` (default `/`), `git_source` (`platform|external`, default `platform`), `external_repo_url`, `wizard_completed_at`. - [ ] `projects`: `UniqueConstraint("organization_id", name="uq_project_one_per_org")`. Fix the seed and any test that creates 2 projects in one org. - [ ] New table `project_external_git` (project_id PK/FK, auth_type `token|ssh_key|none`, username, secret_encrypted, known_hosts, updated_at). - [ ] New table `deploy_targets` (id, organization_id, project_id, kind `ssh|sftp|ftp|ftps`, host, port, username, auth_type `password|key`, secret_encrypted, remote_path, post_deploy_command, host_fingerprint, is_active, last_tested_at, last_test_ok, last_test_message, created_at). At most one active target per project. - [ ] New table `org_model_grants` (id, organization_id, ai_model_id, daily_credit_cap nullable, is_active, created_by, created_at; unique org+model). - [ ] At the end of `models.py`, import `models_org`, `models_engine`, `models_delivery` (three empty modules with a docstring naming the owner agent). - [ ] `alembic upgrade head`, `alembic downgrade -1`, `alembic upgrade head`, `alembic check`, all clean. ## F3. Contracts (`app/application/ports/`), exactly as in PLAN-v2 §5 - [ ] `repo_workspace.py` (+ dataclasses `WorkspaceRef`, `WorktreeRef`, `DiffResult`, `MergeOutcome`, `PushOutcome`, `RemoteCredentials`, `RemoteCheck`) and an in-memory `FakeRepoWorkspace` for tests. - [ ] `delivery_hooks.py` + `NullDeliveryHooks` (records calls in a list for tests). - [ ] `deploy_target.py` (`DeployTargetSpec`, `DeployCheck`) + `FakeDeployTargetTester` (ok unless host contains "fail"). - [ ] `memory.py` (`TaskOutcome`) + `NullMemory` (empty context, record returns None). - [ ] `model_grants.py` (`GrantedModel`) + `AllActiveModelsGrants` (today's behaviour: every active model). - [ ] `workforce_bootstrap.py` + `NullWorkforceBootstrap`. - [ ] `app/domain/projects/profile.py`: frozen dataclass `AppProfile` + `AppProfile.from_row(...)`. ## F4. Wiring stubs - [ ] `app/application/container_org.py`, `container_engine.py`, `container_delivery.py`: each holds the builder functions for its port(s), returning the Null/Fake implementations for now. `container.py` re-exports them. - [ ] Empty routers (`router = APIRouter()`) registered in `rpc_app.py`: `app_setup`, `memory`, `mcp_tokens`, `admin_grants`, `delivery`, `admin_domains`. - [ ] `app/workers/delivery.py` stub (one no-op pass) registered in `workers/__main__.py` as `delivery`; `services/delivery-worker/README.md` + `pnpm worker:delivery` script. - [ ] `services/mcp-gateway/README.md` placeholder + `pnpm mcp:dev` script (points at `app.interfaces.mcp.server:main`, stub module that raises a clear "not implemented yet"). - [ ] `config.py` and `.env.example`: three marked blocks `# >>> agent-1 … # <<< agent-1` (likewise 2 and 3). Pre-fill the obvious settings: - agent-3: `SANDBOX_DOCKER_BIN=docker`, `SANDBOX_WORKSPACES_ROOT`, `SANDBOX_DEFAULT_CPUS=1`, `SANDBOX_DEFAULT_MEMORY_MB=1024`, `DEMO_PORT_START=8100`, `DEMO_PORT_END=8999`, `DELIVERY_POLL_SECONDS=60`, `DEPLOY_ALLOW_PRIVATE_HOSTS=false`, `ARTIFACTS_ROOT`. - agent-2: `ENGINE_MAX_TOOL_CALLS_PER_TURN=40`, `ENGINE_TURN_TIMEOUT_SECONDS=900`, `ENGINE_MAX_CYCLES=6`, `ENGINE_MAX_EMPLOYEES=20`, `ENGINE_TICK_SECONDS=10`. - agent-1: `MCP_GATEWAY_HOST=127.0.0.1`, `MCP_GATEWAY_PORT=8765`, `MCP_TOKEN_TTL_DAYS=90`, `MEMORY_ORG_CHAR_CAP=60000`, `PLATFORM_INVITE_TTL_HOURS=72`. ## F5. Web stubs - [ ] `lib/api-org.ts`, `lib/api-engine.ts`, `lib/api-delivery.ts`: each imports `apiRequest` from `./api` and exports an empty object `orgApi` / `engineApi` / `deliveryApi`. - [ ] `nav.ts`: rename the projects entry to `{ href: "/app", label: "اپلیکیشن", hint: "دمو، استقرار، Git" }`, rename knowledge to `{ href: "/memory", label: "حافظهٔ سازمان", ... }`; admin entries `/admin/model-grants` (مدل‌های سازمان‌ها), `/admin/domains` (دامنه‌ها), `/admin/sandbox` (سندباکس‌ها), `/admin/mcp` (MCP). - [ ] Placeholder pages (using `PlaceholderPage`) for `(app)/app`, `(app)/memory`, `(app)/admin/model-grants`, `(app)/admin/domains`, `(app)/admin/sandbox`, `(app)/admin/mcp`. `(app)/projects` keeps working until Agent 3 removes it. ## F6. Finish - [ ] Baseline checks are all green with the same counts as F1 (plus any new tests). - [ ] Commit on `dev`: `v2 foundation: shared contracts, app profile schema, wiring stubs`. - [ ] Create the worktrees from that commit: ```bash git worktree add ../smart-org-wt/agent1 -b agent1/org-platform git worktree add ../smart-org-wt/agent2 -b agent2/ai-workforce git worktree add ../smart-org-wt/agent3 -b agent3/delivery-infra ``` In each one: `pnpm install` and `pnpm api:venv` so the agent can run the checks immediately. - [ ] `mkdir docs/plan/reports` (tracked with a `.gitkeep`).