P0.4 — γ Server Lifecycle — Agent Prompts
Copy-paste-ready prompts for agents tackling each task in this group. Canonical spec: task-breakdown.md §P0.4 Master bootstrap prompt: agent-bootstrap.md
Group summary
| Task ID | Title | Depends on | Effort | Unblocks |
|---|---|---|---|---|
| P0.4.1 | Runtime Mode Enum | P0.1.4 | S | P0.4.2, production gates |
| P0.4.2 | Graceful Shutdown | P0.2.3 | S | production-ready runtime |
P0.4.1 — Runtime Mode Enum
Spec source: task-breakdown.md §P0.4.1
Extraction reference: docs/reference/extractions/gamma-server-lifecycle-extraction.md
Worktree: feature/p0-4-1-modes
Branch command: git worktree add .worktrees/claude/p0-4-1-modes -b feature/p0-4-1-modes origin/main
Estimated effort: S (Small — 1-2 hours)
Depends on: P0.1.4 (Environment validation)
Unblocks: P0.4.2 (Shutdown uses mode checks), all capability-gated tools throughout codebase
Files to create
src/modes.ts— 4 Phase 0 runtime modes with capability setstests/modes.test.ts— Mode detection and capability tests
Acceptance criteria
- 4 modes defined:
FULL | READONLY | TEST | MINIMAL(Phase 0 floor —WATCHis deferred with file-watcher work; there is noAMS_WATCH_MODE) detectMode()readsCOLIBRI_MODEenv var, defaults toFULL. Reading anyAMS_*variable is forbidden- Each mode has capability set:
{ canWrite, canRunTests, heavyInit }— nocanSpawnAgents. Agent spawning belongs to Phase 1.5 (there is nosrc/domains/agents/in Phase 0 per CLAUDE.md §9.1) READONLYmode: canWrite=false, all write tools return{ error: "readonly_mode" }MINIMALmode: no heavy init, onlyserver/pingandserver/healthavailable- Test: all 4 modes have correct capability sets
- Test: invalid
COLIBRI_MODEthrows (no silent fallback to FULL)
Pre-flight reading
CLAUDE.md— worktree rulesdocs/guides/implementation/task-breakdown.md§P0.4.1 — full specdocs/reference/extractions/gamma-server-lifecycle-extraction.md— mode patternssrc/config.ts— how config.ts validates env vars (parallel pattern)
Ready-to-paste agent prompt
You are a Phase 0 builder agent for Colibri.
TASK: P0.4.1 — Runtime Mode Enum
Define the 4 Phase 0 runtime modes and their capability sets for gating features.
FILES TO READ FIRST:
1. CLAUDE.md (execution rules)
2. docs/guides/implementation/task-breakdown.md §P0.4.1
3. docs/concepts/γ-server-lifecycle.md
4. docs/reference/extractions/gamma-server-lifecycle-extraction.md (heritage — study, don't copy)
5. src/config.ts (for env var validation pattern)
WORKTREE SETUP:
git fetch origin
git worktree add .worktrees/claude/p0-4-1-modes -b feature/p0-4-1-modes origin/main
cd .worktrees/claude/p0-4-1-modes
FILES TO CREATE:
- src/modes.ts
* Export enum: FULL = "full", READONLY = "readonly", TEST = "test", MINIMAL = "minimal"
* Capability set interface: { canWrite: boolean, canRunTests: boolean, heavyInit: boolean }
(No `canSpawnAgents` — agent runtime is deferred to Phase 1.5; there is no
`src/domains/agents/` in the Phase 0 target tree.)
* FULL: canWrite=true, canRunTests=true, heavyInit=true
* READONLY: canWrite=false, canRunTests=true, heavyInit=true
* TEST: canWrite=true, canRunTests=true, heavyInit=true
* MINIMAL: canWrite=false, canRunTests=false, heavyInit=false
* detectMode(): read COLIBRI_MODE env, default FULL, validate against the 4 enum values
* getCapabilities(mode): return capability set
* isReadonly(mode): shorthand boolean check
- tests/modes.test.ts
* Test detectMode() returns FULL for missing env
* Test detectMode() returns correct mode for each valid COLIBRI_MODE value
* Test detectMode() throws for invalid COLIBRI_MODE (no silent fallback)
* Test detectMode() refuses to read AMS_MODE (donor namespace forbidden)
* Test all 4 modes have expected capability sets
* Test isReadonly returns true only for READONLY mode
ACCEPTANCE CRITERIA (headline):
✓ 4 modes defined with capability sets
✓ detectMode() reads COLIBRI_MODE env, defaults FULL
✓ READONLY mode: canWrite=false
✓ MINIMAL mode: no heavy init
✓ Test all 4 modes + invalid-value case
SUCCESS CHECK:
cd .worktrees/claude/p0-4-1-modes && npm test && npm run lint
WRITEBACK (after success):
task_update(task_id="P0.4.1", status="done", progress=100)
thought_record(task_id="P0.4.1", branch="feature/p0-4-1-modes",
commit_sha=<your-sha>, tests_run=["npm test","npm run lint"],
summary="Implemented 4 Phase 0 runtime modes (FULL, READONLY, TEST, MINIMAL) with capability sets. detectMode() reads COLIBRI_MODE env, defaults FULL. No AMS_* fallback.")
FORBIDDENS:
✗ Do not hardcode capability logic in individual tools (centralize in modes.ts)
✗ Do not skip env validation (invalid COLIBRI_MODE must throw)
✗ Do not read AMS_* variables — donor namespace is not supported
✗ Do not add canSpawnAgents — agent runtime is deferred to Phase 1.5
✗ Do not edit main checkout
NEXT:
P0.4.2 — Graceful Shutdown (uses mode checks, shutdown handlers)
Verification checklist (for reviewer agent)
- 4 modes all defined with correct capability sets (no
WATCH, nocanSpawnAgents) detectMode()validatesCOLIBRI_MODEagainst enum- Invalid
COLIBRI_MODEthrows error (not silent fallback) - Reading any
AMS_*variable is a lint/test failure — donor namespace not supported READONLYhascanWrite=falseMINIMALhas no heavy init and limited tools- Test all 4 modes and their capabilities
npm testandnpm run lintpass
Writeback template
task_update:
task_id: P0.4.1
status: done
progress: 100
thought_record:
task_id: P0.4.1
branch: feature/p0-4-1-modes
commit_sha: <sha>
tests_run: ["npm test", "npm run lint"]
summary: "Implemented 4 Phase 0 runtime modes (FULL, READONLY, TEST, MINIMAL) with capability sets {canWrite, canRunTests, heavyInit}. detectMode() reads COLIBRI_MODE env var, defaults to FULL. No AMS_* fallback. READONLY disables writes; MINIMAL disables heavy initialization and exposes only server/ping + server/health. canSpawnAgents is not a Phase 0 capability — agent runtime is deferred to Phase 1.5."
blockers: []
Common gotchas
- Centralize capability logic in modes.ts — don’t scatter if statements checking READONLY throughout the codebase. Use
getCapabilities(mode)in one place, then all tools can gate on the returned object. COLIBRI_MODEenv validation — if the user sets an invalid value, fail loudly at startup with a clear error listing valid modes. Silent fallback to FULL hides configuration errors.- No
AMS_*fallback — if code readsprocess.env.AMS_MODE, it’s a bug. The donor namespace is explicitly not supported. MINIMALmode is for probes and healthchecks — it should not initialize the database or start long-running services. Only exposeserver/pingandserver/health.WATCHmode is deferred. The donorAMS_WATCH_MODEflag belonged to a file-watcher leader-election subsystem Colibri does not have. Adding aWATCHmode in Phase 0 is a scope drift.
P0.4.2 — Graceful Shutdown
Spec source: task-breakdown.md §P0.4.2
Extraction reference: docs/reference/extractions/gamma-server-lifecycle-extraction.md
Worktree: feature/p0-4-2-shutdown
Branch command: git worktree add .worktrees/claude/p0-4-2-shutdown -b feature/p0-4-2-shutdown origin/main
Estimated effort: S (Small — 1-2 hours)
Depends on: P0.2.3 (Two-phase startup)
Unblocks: Production-ready runtime (no hanging processes, clean DB closes)
Files to create
src/shutdown.ts— Graceful shutdown handler registry and orchestrationtests/shutdown.test.ts— Shutdown sequence tests
Acceptance criteria
registerShutdownHandler(fn)registers a cleanup function- On
SIGINT/SIGTERM: calls all handlers in reverse registration order - DB connection closed before process exit
- In-flight MCP requests allowed to complete (max 5s timeout then force-exit)
- Exit code 0 on clean shutdown, 1 on error during shutdown
- Test: mock SIGTERM → verify DB close + handler called
Pre-flight reading
CLAUDE.md— execution rulesdocs/guides/implementation/task-breakdown.md§P0.4.2 — full specdocs/reference/extractions/gamma-server-lifecycle-extraction.md(shutdown section)src/server.ts— how to integrate shutdown handler registration
Ready-to-paste agent prompt
You are a Phase 0 builder agent for Colibri.
TASK: P0.4.2 — Graceful Shutdown
Handle SIGINT/SIGTERM, close DB, wait for in-flight requests, exit cleanly.
FILES TO READ FIRST:
1. CLAUDE.md (execution rules)
2. docs/guides/implementation/task-breakdown.md §P0.4.2
3. docs/reference/extractions/gamma-server-lifecycle-extraction.md (shutdown section)
4. src/server.ts (entry point integration point)
5. src/db/index.ts (Database instance for closing)
WORKTREE SETUP:
git fetch origin
git worktree add .worktrees/claude/p0-4-2-shutdown -b feature/p0-4-2-shutdown origin/main
cd .worktrees/claude/p0-4-2-shutdown
FILES TO CREATE:
- src/shutdown.ts
* Singleton shutdown manager
* registerShutdownHandler(fn: () => void | Promise<void>): void
- Add handler to stack (LIFO)
* initializeShutdownHandlers(db: Database, server: McpServer)
- Register handler to close DB connection
- Register handler to stop MCP server
- Return function that triggers shutdown sequence
* Shutdown sequence on SIGINT/SIGTERM:
1. Log "Shutdown initiated"
2. Call all handlers in reverse registration order
3. Wait for in-flight requests (max 5s, then force-exit)
4. Exit with code 0 (clean) or 1 (error)
* If any handler throws, log error, continue to next handler, exit with code 1
- tests/shutdown.test.ts
* Test registerShutdownHandler stores handlers in LIFO order
* Test shutdown calls handlers in reverse order
* Test DB connection closed during shutdown (mock db.close())
* Test SIGTERM signal → shutdown called
* Test SIGINT signal → shutdown called
* Test in-flight request timeout (max 5s)
* Test exit code 0 on clean shutdown, 1 on error
ACCEPTANCE CRITERIA (headline):
✓ registerShutdownHandler stores handlers (LIFO)
✓ On SIGINT/SIGTERM: call handlers in reverse order
✓ DB closed before exit
✓ In-flight requests allowed to complete (5s max timeout)
✓ Exit code 0 clean / 1 error
SUCCESS CHECK:
cd .worktrees/claude/p0-4-2-shutdown && npm test && npm run lint
WRITEBACK (after success):
task_update(task_id="P0.4.2", status="done", progress=100)
thought_record(task_id="P0.4.2", branch="feature/p0-4-2-shutdown",
commit_sha=<your-sha>, tests_run=["npm test","npm run lint"],
summary="Implemented graceful shutdown with SIGINT/SIGTERM handlers, reverse-order execution, DB close, 5s timeout for in-flight requests.")
FORBIDDENS:
✗ Do not exit immediately on signal (wait for in-flight requests)
✗ Do not skip DB close (leaves database locked)
✗ Do not use setTimeout(..., 0) for shutdown (use proper async/await)
✗ Do not edit main checkout
NEXT:
P0.5.1 — Intent Scoring Matrix (router uses mode checks from P0.4.1)
Production readiness depends on this task.
Verification checklist (for reviewer agent)
- Shutdown handlers stored in reverse order (LIFO stack)
- SIGINT and SIGTERM both trigger shutdown
- DB close called before process.exit()
- In-flight requests allowed 5s timeout
- Exit code 0 on success, 1 on error
- Test covers all signal types and timeout scenario
- npm test and npm run lint pass
Writeback template
task_update:
task_id: P0.4.2
status: done
progress: 100
thought_record:
task_id: P0.4.2
branch: feature/p0-4-2-shutdown
commit_sha: <sha>
tests_run: ["npm test", "npm run lint"]
summary: "Implemented graceful shutdown handler. registerShutdownHandler() stores cleanup functions in LIFO order. On SIGINT/SIGTERM, calls handlers in reverse registration order, closes DB connection, allows in-flight MCP requests 5s to complete, then exits with code 0 (clean) or 1 (error). Prevents hung processes and database corruption."
blockers: []
Common gotchas
- LIFO handler order — shutdown handlers are registered in startup order, but executed in reverse. Register DB close first, then MCP server stop, so DB is cleaned up last. This ensures no tools try to write to a closed database.
- In-flight request timeout — don’t use a fixed setTimeout. Use a graceful timeout pattern: collect all in-flight promises, wait for them with Promise.race([Promise.all(flights), timeout]), then force-exit if timeout wins.
- Exit code signals — exit(0) means clean shutdown; exit(1) means error. Kubernetes and systemd respect these. Exit without a code defaults to 0, so be explicit.
- Process signal handling — SIGTERM is the normal kill signal; SIGINT is Ctrl+C. Both should shut down gracefully. SIGKILL (cannot be caught) will force-kill immediately, so there’s no recovery.
Next group
p0.5-delta-router.md — δ Model Router (2 tasks: Intent Scoring, 8-Model Fallback Chain)