Merges feat/agent-project-membership (task 166/152). An agent can finally join many projects: membership routes, per-membership role and optional brain override, chat resolving context from the membership, and CLI attach-agent / detach-agent / get memberships. The legacy Agent.projectId fallback is kept for this release as the schema comment promises. Conflict resolved in main.ts: that branch added its RBAC case to mapUrlToPermission inline, while this branch had extracted the function to middleware/url-permission.ts so it could be tested. Kept the extraction and ported the case into it — joining a team is `edit:agents:<name>`, not `create:agents`, which is the authority to mint a whole agent. Also fixes something the extraction makes possible. security.test.ts contained a hand-copied reproduction of mapUrlToPermission, because main.ts self-invokes main() and nothing in it was importable. A security test asserting against a copy stops testing the system the moment the real one changes, and this copy had already drifted. It now imports the real function; all 18 assertions still pass, against the code that actually runs. Local: build clean, workspace 2550 passed, lint unchanged at 794 errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N4wNHWf7xSwnZCWpJcyv9p
26 lines
1.2 KiB
Markdown
26 lines
1.2 KiB
Markdown
# Task ID: 143
|
|
|
|
**Title:** SessionService for pod provisioning and lifecycle
|
|
|
|
**Status:** pending
|
|
|
|
**Dependencies:** 121, 132, 141, 142
|
|
|
|
**Priority:** high
|
|
|
|
**Description:** Create SessionService handling AgentSession creation, repo-clone init container, credential resolution, and GC sweep
|
|
|
|
**Details:**
|
|
|
|
Create src/mcpd/src/services/session.service.ts:
|
|
1. create(agentId, projectId, taskId?, image, expiresAt): create AgentSession row in pending state
|
|
2. provision(sessionId): resolve project's CodeRepo list, resolve credentials via SecretService (fail on resolution error like InstanceService.attemptStart), build ContainerSpec with init container that clones repos to workspace volume, create pod via orchestrator, transition to running
|
|
3. end(sessionId): stop container, mark ended
|
|
4. getById(), listByFilters()
|
|
5. GC sweep: find sessions where now() > expiresAt, stop containers, mark ended. Run in same style as inference-task sweep in main.ts
|
|
6. Note: assumes single mcpd replica (no leader election)
|
|
|
|
**Test Strategy:**
|
|
|
|
Unit tests: test provision builds correct init container command, test credential resolution failure aborts provision, test GC sweep marks expired sessions ended.
|