feat(FN-1269): add Routine Engine Integration and fix PROMPT_KEY_CATALOG

- Add Routine Engine Integration documentation to project memory
- Fix PROMPT_KEY_CATALOG by adding missing executor role to agent-generation-system and workflow-step-refine entries
- Update test to expect 6 executor keys instead of 4
This commit is contained in:
gsxdsm
2026-04-10 13:22:29 -07:00
parent 40676e657c
commit df1ff16519
3 changed files with 36 additions and 3 deletions

View File

@@ -549,3 +549,34 @@ Key learnings from adding integration test coverage for run-audit:
- When moving functions to new modules, update test imports accordingly
- The serve test mocks `./task-lifecycle.js` and `./port-prompt.js` (not dashboard.js)
- The dashboard test imports helpers from `./task-lifecycle.js` and `runDashboard` from `./dashboard.js`
## FN-1269: Routine Engine Integration
The Routine Engine Integration adds scheduled, webhook-triggered, and manual routine execution via the heartbeat system:
**Key components:**
- `RoutineRunner` (`packages/engine/src/routine-runner.ts`) — Executes routines via heartbeat with concurrency policy enforcement (allow/skip/replace/queue)
- `RoutineScheduler` (`packages/engine/src/routine-scheduler.ts`) — Polls for due routines and triggers execution via RoutineRunner
- API endpoints: `POST /api/routines/:id/trigger` (manual), `POST /api/routines/:id/webhook` (webhook with HMAC-SHA256 verification)
**Concurrency policies:**
- `allow` — Run immediately regardless of existing executions
- `skip` — Return failed result without calling heartbeat if already running
- `replace` — Cancel existing execution, then run new one
- `queue` — Wait for existing execution to complete, then run
**Catch-up policy:**
- `skip` — Update `lastTriggeredAt` without additional executions
- `catchUp` — Execute missed intervals up to 10 max (prevents runaway catch-up)
**HMAC signature verification pattern for routine webhooks:**
```typescript
import { createHmac, timingSafeEqual } from "node:crypto";
const signature = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`;
const isValid = timingSafeEqual(Buffer.from(signature), Buffer.from(req.headers["x-webhook-signature"]));
```
**InProcessRuntime lifecycle integration:**
- RoutineScheduler initialized after HeartbeatMonitor/TriggerScheduler
- Graceful degradation if RoutineStore not available (FN-1519 types incomplete)
- `getRoutineScheduler()` and `getRoutineRunner()` getters for testing access

View File

@@ -82,11 +82,13 @@ describe("prompt-overrides", () => {
describe("getPromptKeysForRole", () => {
it("should return all keys for executor role", () => {
const keys = getPromptKeysForRole("executor");
expect(keys).toHaveLength(4);
expect(keys).toHaveLength(6);
expect(keys.map((k) => k.key)).toContain("executor-welcome");
expect(keys.map((k) => k.key)).toContain("executor-guardrails");
expect(keys.map((k) => k.key)).toContain("executor-spawning");
expect(keys.map((k) => k.key)).toContain("executor-completion");
expect(keys.map((k) => k.key)).toContain("agent-generation-system");
expect(keys.map((k) => k.key)).toContain("workflow-step-refine");
});
it("should return all keys for triage role", () => {

View File

@@ -177,7 +177,7 @@ If there are merge conflicts:
"agent-generation-system": {
key: "agent-generation-system",
name: "Agent Generation System",
roles: [],
roles: ["executor"],
description: "System prompt for the AI agent that generates agent specifications from role descriptions",
defaultContent: `You are an agent specification generator for the fn task board system.
@@ -234,7 +234,7 @@ You MUST respond with ONLY valid JSON (no markdown, no explanation):
"workflow-step-refine": {
key: "workflow-step-refine",
name: "Workflow Step Refine",
roles: [],
roles: ["executor"],
description: "System prompt for refining workflow step descriptions into detailed agent prompts",
defaultContent: `You are an expert at creating detailed agent prompts for workflow steps.