diff --git a/.planning/phases/11-architect-agent/11-01-PLAN.md b/.planning/phases/11-architect-agent/11-01-PLAN.md
index 591017c..035b6a6 100644
--- a/.planning/phases/11-architect-agent/11-01-PLAN.md
+++ b/.planning/phases/11-architect-agent/11-01-PLAN.md
@@ -78,63 +78,244 @@ Output: Extended agent schema with mode field, mode-specific output schemas, upd
Task 2: Create mode-specific output schemas
src/agent/schema.ts
-Add mode-specific output schemas following the existing discriminated union pattern:
+Add mode-specific output schemas following the existing discriminated union pattern.
+
+**IMPORTANT:** These schemas define the contract between the agent prompt and the system.
+The prompt tells the agent what format to output; these schemas validate that output.
1. Keep existing agentOutputSchema as 'execute' mode schema (already handles done/questions/error)
-2. Add discussOutputSchema for discussion mode:
+2. Add decisionSchema for reuse:
```typescript
+ /**
+ * A decision captured during discussion.
+ * Prompt instructs: { "topic": "Auth", "decision": "JWT", "reason": "Stateless" }
+ */
+ const decisionSchema = z.object({
+ topic: z.string(),
+ decision: z.string(),
+ reason: z.string(),
+ });
+
+ export type Decision = z.infer;
+ ```
+
+3. Add phaseBreakdownSchema for reuse:
+ ```typescript
+ /**
+ * A phase from breakdown output.
+ * Prompt instructs: { "number": 1, "name": "...", "description": "...", "dependencies": [0] }
+ */
+ const phaseBreakdownSchema = z.object({
+ number: z.number().int().positive(),
+ name: z.string().min(1),
+ description: z.string(),
+ dependencies: z.array(z.number().int()).optional().default([]),
+ });
+
+ export type PhaseBreakdown = z.infer;
+ ```
+
+4. Add discussOutputSchema for discussion mode:
+ ```typescript
+ /**
+ * Discuss mode output schema.
+ * Agent asks questions OR completes with decisions.
+ *
+ * Prompt tells agent:
+ * - Output "questions" status with questions array when needing input
+ * - Output "context_complete" status with decisions array when done
+ */
export const discussOutputSchema = z.discriminatedUnion('status', [
+ // Agent needs more information
z.object({
status: z.literal('questions'),
questions: z.array(questionItemSchema),
- context: z.string().optional(), // Summary of what's been discussed so far
}),
+ // Agent has captured all decisions
z.object({
status: z.literal('context_complete'),
- decisions: z.array(z.object({
- topic: z.string(),
- decision: z.string(),
- reason: z.string(),
- })),
- summary: z.string(),
+ decisions: z.array(decisionSchema),
+ summary: z.string(), // Brief summary of all decisions
}),
+ // Unrecoverable error
z.object({
status: z.literal('unrecoverable_error'),
error: z.string(),
}),
]);
+
+ export type DiscussOutput = z.infer;
```
-3. Add breakdownOutputSchema for breakdown mode:
+5. Add breakdownOutputSchema for breakdown mode:
```typescript
+ /**
+ * Breakdown mode output schema.
+ * Agent asks questions OR completes with phases.
+ *
+ * Prompt tells agent:
+ * - Output "questions" status when needing clarification
+ * - Output "breakdown_complete" status with phases array when done
+ */
export const breakdownOutputSchema = z.discriminatedUnion('status', [
+ // Agent needs clarification
z.object({
status: z.literal('questions'),
questions: z.array(questionItemSchema),
}),
+ // Agent has decomposed initiative into phases
z.object({
status: z.literal('breakdown_complete'),
- phases: z.array(z.object({
- number: z.number(),
- name: z.string(),
- description: z.string(),
- dependencies: z.array(z.number()).optional(), // Phase numbers this depends on
- })),
+ phases: z.array(phaseBreakdownSchema),
}),
+ // Unrecoverable error
z.object({
status: z.literal('unrecoverable_error'),
error: z.string(),
}),
]);
+
+ export type BreakdownOutput = z.infer;
```
-4. Export all schemas and types.
+6. Create JSON schema versions for --json-schema flag:
+ ```typescript
+ /**
+ * JSON Schema for discuss mode (passed to Claude CLI --json-schema)
+ */
+ export const discussOutputJsonSchema = {
+ type: 'object',
+ oneOf: [
+ {
+ properties: {
+ status: { const: 'questions' },
+ questions: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ id: { type: 'string' },
+ question: { type: 'string' },
+ options: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ label: { type: 'string' },
+ description: { type: 'string' },
+ },
+ required: ['label'],
+ },
+ },
+ multiSelect: { type: 'boolean' },
+ },
+ required: ['id', 'question'],
+ },
+ },
+ },
+ required: ['status', 'questions'],
+ },
+ {
+ properties: {
+ status: { const: 'context_complete' },
+ decisions: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ topic: { type: 'string' },
+ decision: { type: 'string' },
+ reason: { type: 'string' },
+ },
+ required: ['topic', 'decision', 'reason'],
+ },
+ },
+ summary: { type: 'string' },
+ },
+ required: ['status', 'decisions', 'summary'],
+ },
+ {
+ properties: {
+ status: { const: 'unrecoverable_error' },
+ error: { type: 'string' },
+ },
+ required: ['status', 'error'],
+ },
+ ],
+ };
-5. Create JSON schema versions for --json-schema flag (discussOutputJsonSchema, breakdownOutputJsonSchema).
+ /**
+ * JSON Schema for breakdown mode (passed to Claude CLI --json-schema)
+ */
+ export const breakdownOutputJsonSchema = {
+ type: 'object',
+ oneOf: [
+ {
+ properties: {
+ status: { const: 'questions' },
+ questions: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ id: { type: 'string' },
+ question: { type: 'string' },
+ options: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ label: { type: 'string' },
+ description: { type: 'string' },
+ },
+ required: ['label'],
+ },
+ },
+ },
+ required: ['id', 'question'],
+ },
+ },
+ },
+ required: ['status', 'questions'],
+ },
+ {
+ properties: {
+ status: { const: 'breakdown_complete' },
+ phases: {
+ type: 'array',
+ items: {
+ type: 'object',
+ properties: {
+ number: { type: 'integer', minimum: 1 },
+ name: { type: 'string', minLength: 1 },
+ description: { type: 'string' },
+ dependencies: {
+ type: 'array',
+ items: { type: 'integer' },
+ },
+ },
+ required: ['number', 'name', 'description'],
+ },
+ },
+ },
+ required: ['status', 'phases'],
+ },
+ {
+ properties: {
+ status: { const: 'unrecoverable_error' },
+ error: { type: 'string' },
+ },
+ required: ['status', 'error'],
+ },
+ ],
+ };
+ ```
+
+7. Export all schemas, types, and JSON schemas.
npm run build passes, new schemas are exported
- Three mode-specific output schemas exist with JSON schema versions
+ Three mode-specific output schemas with JSON schema versions, aligned with agent prompts
@@ -170,6 +351,8 @@ Before declaring plan complete:
- [ ] npm test passes (all existing tests still work)
- [ ] AgentMode type is exported from src/agent/types.ts
- [ ] All three output schemas are exported from src/agent/schema.ts
+- [ ] JSON schemas (discussOutputJsonSchema, breakdownOutputJsonSchema) are exported
+- [ ] Decision and PhaseBreakdown types are exported for use by other modules
- [ ] MockAgentManager handles mode parameter
@@ -177,7 +360,11 @@ Before declaring plan complete:
- All tasks completed
- Agent mode tracking works end-to-end
-- Mode-specific output schemas are validated by Zod
+- Mode-specific output schemas match the prompt output format:
+ - discuss: questions OR context_complete with decisions array
+ - breakdown: questions OR breakdown_complete with phases array
+ - execute: done/questions/unrecoverable_error (existing)
+- JSON schemas can be passed to Claude CLI --json-schema flag
- Existing tests pass (backwards compatible)
- No TypeScript errors