Engine honours org policy and monthly budget, legacy runner skips engine tasks, sandbox session provisioned on demand, project fallback for threads, reviewer fallback, tenant checks on project ids, memory reflection respects grants, expiry worker, MCP pipeline_status, login redirect, sharing settings, e2e smoke. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
61 lines
6.5 KiB
Markdown
61 lines
6.5 KiB
Markdown
# 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. — open: apps/api/.venv in the main checkout is incomplete (bin/ is empty, no pyvenv.cfg), so `pnpm api:venv` cannot be confirmed there; the foundation-time counts are not written down anywhere in the repo.
|
|
- [x] Add API deps to `apps/api/pyproject.toml`: `asyncssh`, `aioftp`, `mcp` (official SDK). Install and re-run the baseline. (baseline recorded at foundation time)
|
|
|
|
## F2. DB foundation (`db/models.py` + migration `a0f0e1d2c3b4_v2_foundation.py`, down_revision `d4e5f6a7b8c9`)
|
|
- [x] `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`.
|
|
- [x] `projects`: `UniqueConstraint("organization_id", name="uq_project_one_per_org")`. Fix the seed and any test that creates 2 projects in one org.
|
|
- [x] New table `project_external_git` (project_id PK/FK, auth_type `token|ssh_key|none`, username, secret_encrypted, known_hosts, updated_at).
|
|
- [x] 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.
|
|
- [x] New table `org_model_grants` (id, organization_id, ai_model_id, daily_credit_cap nullable, is_active, created_by, created_at; unique org+model).
|
|
- [x] At the end of `models.py`, import `models_org`, `models_engine`, `models_delivery` (three empty modules with a docstring naming the owner agent). (empty at foundation time)
|
|
- [x] `alembic upgrade head`, `alembic downgrade -1`, `alembic upgrade head`, `alembic check`, all clean. (re-run 2026-10-14 at head: upgrade head, downgrade to d4e5f6a7b8c9, upgrade head, check, all clean)
|
|
|
|
## F3. Contracts (`app/application/ports/`), exactly as in PLAN-v2 §5
|
|
- [x] `repo_workspace.py` (+ dataclasses `WorkspaceRef`, `WorktreeRef`, `DiffResult`, `MergeOutcome`, `PushOutcome`, `RemoteCredentials`, `RemoteCheck`) and an in-memory `FakeRepoWorkspace` for tests.
|
|
- [x] `delivery_hooks.py` + `NullDeliveryHooks` (records calls in a list for tests).
|
|
- [x] `deploy_target.py` (`DeployTargetSpec`, `DeployCheck`) + `FakeDeployTargetTester` (ok unless host contains "fail").
|
|
- [x] `memory.py` (`TaskOutcome`) + `NullMemory` (empty context, record returns None).
|
|
- [x] `model_grants.py` (`GrantedModel`) + `AllActiveModelsGrants` (today's behaviour: every active model).
|
|
- [x] `workforce_bootstrap.py` + `NullWorkforceBootstrap`.
|
|
- [x] `app/domain/projects/profile.py`: frozen dataclass `AppProfile` + `AppProfile.from_row(...)`.
|
|
|
|
## F4. Wiring stubs
|
|
- [x] `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. (foundation stubs; the builders now return the real services)
|
|
- [x] Empty routers (`router = APIRouter()`) registered in `rpc_app.py`: `app_setup`, `memory`, `mcp_tokens`, `admin_grants`, `delivery`, `admin_domains`. (routers now hold their endpoints)
|
|
- [x] `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. (the stub is now the real worker pass)
|
|
- [x] `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"). (the module now runs the real gateway)
|
|
- [x] `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
|
|
- [x] `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`. (empty objects at foundation time)
|
|
- [x] `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).
|
|
- [x] 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. (placeholders at foundation time)
|
|
|
|
## F6. Finish
|
|
- [x] Baseline checks are all green with the same counts as F1 (plus any new tests). (baseline recorded at foundation time)
|
|
- [x] Commit on `dev`: `v2 foundation: shared contracts, app profile schema, wiring stubs`. (commit 0cd9194)
|
|
- [x] Create the worktrees from that commit: (worktrees listed by git worktree list)
|
|
```bash
|
|
git worktree add /home/mamad/work/smart-org-wt/agent1 -b agent1/org-platform
|
|
git worktree add /home/mamad/work/smart-org-wt/agent2 -b agent2/ai-workforce
|
|
git worktree add /home/mamad/work/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.
|
|
- [x] `mkdir docs/plan/reports` (tracked with a `.gitkeep`).
|